I was implemented a delegate process of InvoiceShipment to validate the updated inventory after creating an invoice, in version 6.1 of acumatica, but in version 18.117.0016 the method isn't executed
I tried in two different forms, but the method isn't executed
1.
public delegate void InvoiceShipmentDelegate(SOInvoiceEntry docgraph, SOShipment shiporder, DateTime invoiceDate, DocumentList<ARInvoice, SOInvoice> list);
[PXOverride]
public void InvoiceShipment(SOInvoiceEntry docgraph, SOShipment shiporder, DateTime invoiceDate, DocumentList<ARInvoice, SOInvoice> list, InvoiceShipmentDelegate baseMethod)
{
SOOrderShipment envio = PXSelect<SOOrderShipment, Where<SOOrderShipment.shipmentNbr, Equal<Required<SOOrderShipment.shipmentNbr>>>>.Select(Base, shiporder.ShipmentNbr);
if (string.IsNullOrEmpty(envio.InvtRefNbr))
{
throw new PXException("No se puede preparar la factura, el inventario no ha sido actualizado");
}
baseMethod?.Invoke(docgraph, shiporder, invoiceDate, list);
}
2.
public void InvoiceShipment(SOInvoiceEntry docgraph, SOShipment shiporder, DateTime invoiceDate, DocumentList<ARInvoice, SOInvoice> list,
Action<SOInvoiceEntry, SOShipment, DateTime, DocumentList<ARInvoice, SOInvoice>> baseInvoiceShipment)
{
SOOrderShipment envio = PXSelect<SOOrderShipment, Where<SOOrderShipment.shipmentNbr, Equal<Required<SOOrderShipment.shipmentNbr>>>>.Select(Base, shiporder.ShipmentNbr);
if (string.IsNullOrEmpty(envio.InvtRefNbr))
{
throw new PXException("No se puede preparar la factura, el inventario no ha sido actualizado");
}
baseInvoiceShipment(docgraph, shiporder, invoiceDate, list);
}
How I can Execute this delegate method
It looks like the signature of that method changed (added PXQuickProcess.ActionFlow). Because you are overriding the old unused signature it does not get called. Use this signature and it should call into your override:
public virtual void InvoiceShipment(SOInvoiceEntry docgraph, SOShipment shiporder, DateTime invoiceDate, DocumentList<ARInvoice, SOInvoice> list, PXQuickProcess.ActionFlow quickProcessFlow)
{ //... }
You can look at the SOShipmentEntry source code for any reference to InvoiceShipment to see this change. I am looking at 18.120.0006 for this example.
Related
I have an MVC application in which I have to update the view with the current value of a stream.
In the model I have this method:
public Observable<Integer> getStreamInstance(){
if(stream == null){
this.stream = Observable.create((Subscriber<? super Integer> subscriber) -> {
new HeartbeatStream(frequence,subscriber).start();
});
}
return stream;
}
which I use in the controller to get the stream. Then, in the controller I have these two methods:
public void start(){
this.sb = stream.subscribe((Integer v) -> {
view.updateCurrValue(v);
});
}
public void stop(){
this.sb.unsubscribe();
}
With the start method I simply update a label in the view with the current value.
This works fine until I try to stop the updating with the unsubscribing; infact, when I press the button "stop" in the view, the label keeps updating with the current value and, if I press "start" again, the label shows the values from two different streams, the one that I first created with the first "start" and the second that seems has been created with the second pressing of "start".
Where am I wrong?
EDIT:
public class HeartbeatStream extends Thread{
private Subscriber<? super Integer> subscriber;
private int frequence;
private HeartbeatSensor sensor;
public HeartbeatStream(int freq, Subscriber<? super Integer> subscriber){
this.frequence = freq;
this.subscriber = subscriber;
sensor = new HeartbeatSensor();
}
public void run(){
while(true){
try {
subscriber.onNext(sensor.getCurrentValue());
Thread.sleep(frequence);
} catch (Exception e) {
subscriber.onError(e);
}
}
}
This is the HeartbeatStream class. HeartbeatSensor is a class that periodically generates a value that simulates the heartbeat frequence.
I'm guessing you tried to periodically signal some event that triggers the screen update. There is an operator for that:
Observable<Long> timer = Observable.interval(period, TimeUnit.MILLISECONDS,
AndroidSchedulers.mainThread());
SerialSubscription serial = new SerialSubscription();
public void start() {
serial.set(timer.subscribe(v -> view.updateCurrValue(v)));
}
public void stop() {
serial.set(Subscriptions.unsubscribed());
}
public void onDestroy() {
serial.unsubscribe();
}
Observable by design unsubscribe your observer once that all items are emitted and onComplete callback is invoked.
Look this example https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/creating/ObservableSubscription.java
I guess you're not handling the unsubscribe - although I can't see what's going on in your HeartbeatStream class.
If you're creating an Observable with Observable.create then you need to handle unsubscribing explicitly with subscriber.isUnsubscribed().
Where possible use some of the utility methods to create an Observable - they handle this all for you eg Observable.just() or Observable.from().
If this doesn't help, please post your HeartbeatStream class.
See the the docs for more details:
https://github.com/ReactiveX/RxJava/wiki/Creating-Observables
https://github.com/ReactiveX/RxJava/wiki/Async-Operators
///first I have crated Popular class for storing values
public class Popular
{
public string trk_mnetid,trk_title , art_mnetid, art_name, image_url;
}
/// create popularplaylist class
public partial class PopularPlaylist : PhoneApplicationPage
{
Popular popobj = new Popular();
List<Popular> pop = new List<Popular>();
/* call json parsing it and show only "titles" in List form when i m click on perticular title i need to show details in next screen which i paser and store in popular popularplaylist class.
i use navigationservice call new screen
*/
NavigationService.Navigate(new Uri("/Popular_Module/PopularPlaylist.xaml", System.UriKind.Relative));
}
// plz tell me how to get list data in next screen
Use querystring.
Passing Value: In MainPage.xaml.cs add the following
The easiest way to pass a parameter is just to use a string, something like:
private void btnNavigate_Click(object sender, RoutedEventArgs e)
{
string url=String.Format("/Page1.xaml?parameter={0}",popular);
NavigationService.Navigate(new Uri(url, UriKind.Relative));
}
Getting Value: In Page.xaml.cs add the following
Note: It is important to override the OnNavigatedTo and after that you can use the NavigationContext to get the passed parameter.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
List<string> parameterValue = NavigationContext.QueryString["parameter"];
}
Another popular syntax to get the value of the parameter is:
List<string> parameter = string.Empty;
if (NavigationContext.QueryString.TryGetValue("parameter", out parameter))
{
//do something with the parameter
}
i hace a class named "Conexion" an i keep all the info of my app there, what i want its to save the object of the class to a file when the user presses the windows key, but the app crashes because it says the obect "delegado" has a problem reflecting his type. The type of this object is "PhoneApplicationPage" , it seems it cannot be serialized. The object keeps track of what page did the request.
so im requesting your help to see if theres a solution, that doesn make me redo the app, because i dont have time.
heres the code of the methods i use to save and load the data.
public void save() {
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream stream = storage.CreateFile(fileName);
DateTime currTime = DateTime.Now;
this.timeOff = currTime.ToString();
XmlSerializer xml = new XmlSerializer(this.GetType());
xml.Serialize(stream, this);
stream.Close();
stream.Dispose();
}
public Conexion load() {
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
Conexion conn;
if (storage.FileExists(fileName))
{
IsolatedStorageFileStream stream = storage.OpenFile(fileName, System.IO.FileMode.Open);
XmlSerializer xml = new XmlSerializer(typeof(Conexion));
conn = xml.Deserialize(stream) as Conexion;
stream.Close();
DateTime currTime = DateTime.Now;
DateTime checkTime = DateTime.Parse(timeOff).AddMinutes(lapso);
if (DateTime.Compare(checkTime, currTime) >= 0)
{
Console.WriteLine("sesion valida");
}
else {
conn.reseteaSingletonConexion();
}
stream.Dispose();
}
else
{
conn= new Conexion();
}
return conn;
}
thanks in advance
Edit:
Well ignoring the object "delegado" stopped the app from crashing, but now , when i load the info , the object cannot be deserialized , it seems it marks 2 details in the same error:
There is an error in XML document (2, 2).
Conexion cannot be serialized because it does not have a parameterless constructor.
but the class does have a parameterless constructor.
any idea?
You could use the [XmlIgnore] attribute against the objects that won't serialize (chances are you don't want to serialize the entire XAML page.
Place this attribute above a property in your Conexion class. Eg,
public class Conexion
{
public string MyPropertyToSerialize { get;set; }
[XmlIgnore]
public string MyPropertyToIgnore { get;set; }
}
Hope that helps.
I have written a Hive UDF that does decryption using an in-house API as follows:
public Text evaluate(String customer) {
String result = new String();
if (customer == null) { return null; }
try {
result = com.voltage.data.access.Data.decrypt(customer.toString(), "name");
} catch (Exception e) {
return new Text(e.getMessage());
}
return new Text(result);
}
and Data.decrypt does:
public static String decrypt(String data, String type) throws Exception {
configure();
String FORMAT = new String();
if (type.equals("ccn")) {
FORMAT = "CC";
} else if (type.equals("ssn")) {
FORMAT = "SSN";
} else if (type.equals("name")) {
FORMAT = "AlphaNumeric";
}
return library.FPEAccess(identity, LibraryContext.getFPE_FORMAT_CUSTOM(),String.format("formatName=%s", FORMAT),authMethod, authInfo, data);
}
where configure() creates a pretty expensive context object.
My question is: Does Hive execute this UDF once for every row returned by the query? i.e. If I'm selecting 10,000 rows, does the evaluate method get run 10,000 times?
My gut instinct tells me yes. And if so, then here's a second question:
Is there any way I can do one of the following:
a) run configure() once when the query first starts, then share the context object
b) instead of the UDF returning a decrypted string, it aggregates the encrypted string into some Set, then I do a bulk decrypt on the set?
Thanks in advance
Is configure() something that needs to be called once per JVM, or once per instance of the UDF class?
If once per JVM, just put it in a static block in the class, like so:
static {
configure();
}
If once per instance, put it in the constructor:
public [class name]() {
super();
configure();
}
I am using spring 3.0 and I am using the JqGrid plugin. I am working on the search feature which sends a json string with all the search criteria. Here is what the string can look like.
{"groupOp":"AND","rules":[{"field":"firstName","op":"bw","data":"John"},{"field":"lastName","op":"cn","data":"Doe"},{"field":"gender","op":"eq","data":"Male"}]}
If you look at the "op" property inside the rules array, you will see the operation which must be executed. The Jq-grid has the following operations
['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
which corresponds with
['equal','not equal', 'less', 'less or equal','greater','greater or equal', 'begins with','does not begin with','is in','is not in','ends with','does not end with','contains','does not contain']
I plan to use hibernate criteria searching to enable the search feature. For this I am using Jackson's ObjectMapper to convert the incoming JSON into Java. This is all well and good. Here is my code that converts the json.
public class JsonJqgridSearchModel {
public String groupOp;
public ArrayList<JqgridSearchCriteria> rules;
}
public class JqgridSearchCriteria {
public String field;
public String op;
public String data;
public SimpleExpression getRestriction(){
if(op.equals("cn")){
return Restrictions.like(field, data);
}else if(op.equals("eq")){
return Restrictions.eq(field, data);
}else if(op.equals("ne")){
return Restrictions.ne(field, data);
}else if(op.equals("lt")){
return Restrictions.lt(field, data);
}else if(op.equals("le")){
return Restrictions.le(field, data);
}else if(op.equals("gt")){
return Restrictions.gt(field, data);
}else if(op.equals("ge")){
return Restrictions.ge(field, data);
}else{
return null;
}
}
}
#RequestMapping(value = "studentjsondata", method = RequestMethod.GET)
public #ResponseBody String studentjsondata(#RequestParam("_search") Boolean search ,HttpServletRequest httpServletRequest) {
StringBuilder sb = new StringBuilder();
Format formatter = new SimpleDateFormat("MMMM dd, yyyy");
if(search){
ObjectMapper mapper = new ObjectMapper();
try {
JsonJqgridSearchModel searchModel= mapper.readValue(httpServletRequest.getParameter("filters"), JsonJqgridSearchModel.class);
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Criteria criteria = session.createCriteria(Person.class);
Iterator<JqgridSearchCriteria> iterator = searchModel.rules.iterator();
while(iterator.hasNext()){
System.out.println("before");
criteria.add(iterator.next().getRestriction());
System.out.println("after");
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{//do other stuff here}
This is where the problem comes in. How do I transalate the jqGrid operation into the equivelent hibernate command ? For example
"cn" should correspond with
criteria.add(Restrictions.like("firstName", myJsonJqgridSearchModel.data));
Interestingly, I've just written almost identical code to what you have above (mine doesn't use JqGrid however). I'm wondering if your problem is specifically related to the "cn" - LIKE condition? I had problems with this - I had to specify the MatchMode to get the "contains" like I wanted:
return Restrictions.ilike(
searchCriterion.getPropertyName(),
searchCriterion.getValue().toString(),
MatchMode.ANYWHERE);
I found that without specifying the MatchMode, it was generating SQL as:
WHERE property LIKE 'value'
By specifying the MatchMode.ANYWHERE, it generated SQL as:
WHERE property LIKE '%value%'
which is the "contains" operation that I was expecting. Perhaps this is your issue as well?