Skip to main content

Hi,

I need to implement such logic that is executed eternally and without user’s actions, after I will

 deploy my project package for client’s Acumatica.

Previously, the extension of functionality was achieved via events, which required the user interaction (By pressing SAVE button).

Now, I need to define a code which will be always executed, without any actions,

One important moment - is should work if Acumatica IIS process is running, so even if we have not authorized in Acumatica the code inside package that was imported to Acumatica customization must work.

Can you. please, provide instruction, where I must locate my code in order to work at any time ?

Hi, @Ivan  Below inputs may help you, please find the details below.

  • Create a new processing screen
  • Written a logic in processing screen graph
  • schedule this screen for every 10/20/30 minutes

Once you schedule, this screen will run and execute your logic for every periodic time.

 

Hope this helps!


Hi, @Ivan  Below inputs may help you, please find the details below.

  • Create a new processing screen
  • Written a logic in processing screen graph
  • schedule this screen for every 10/20/30 minutes

Once you schedule, this screen will run and execute your logic for every periodic time.

 

Hope this helps!

Hi @Naveen B 

I have created new Screen

After that Acumatica generated code for my solution 

Where exactly I need to define a code that will be always been executed ?


Hi, @Ivan  Please go through the below link for the creation of Processing screens.

https://openuni.acumatica.com/courses/development/t240-development-processing-forms/

 


Hi, @Ivan  Please go through the below link for the creation of Processing screens.

https://openuni.acumatica.com/courses/development/t240-development-processing-forms/

 

Hi @Naveen B 

Thanks for tutorial.

I am watching it know and at 35.09 it seems that it is what I need to do according to my last question

So, I just need to define a constructor of my new screen where I can locate my logic that need to be executed eternally, am I right ?


Yes @Ivan  That is correct. You are almost done with your requirement now.

Thanks for following the suggestions :)


Yes @Ivan  That is correct. You are almost done with your requirement now.

Thanks for following the suggestions :)

@Naveen B I added just generation of file with current tie in order to check that it will be called every time.

You have mentioned in first comment that I need to schedule the screen 

So, I wen to Automation Schedules tab, but received null errors in every tab inside. 

Can you, please, suggest what must be added to screen to fix it ?

Basically I need to perform two steps : write my logic inside the new screen constructor and define the schedule for it, am I right ?


Yes @Ivan  That is correct.

Here is the sample Processing screen code for your reference. You need to add your code try block and schedule this to run every specific periodic time.

 

 public class SOProcess : PXGraph<SOProcess>
{
public PXCancel<SOOrder> Cancel;

public PXProcessing<SOOrder> KNSOProcessView;

#region Constructor

public SOProcess()
{
KNSOProcessView.SetProcessCaption("Process");
KNSOProcessView.SetProcessAllCaption("ProcessAll");
KNSOProcessView.SetProcessDelegate(
delegate (List<SOOrder> list)
{
GetOpenSSaaSOrders(list);
});
}
#endregion

public static void GetOpenSSaaSOrders(List<SOOrder> list)
{
SOProcess graph = PXGraph.CreateInstance<SOProcess>();
graph.AMISSaaSProcessOrders(list);
}

public virtual void AMISSaaSProcessOrders(List<SOOrder> list)
{
if (list.Count <= 0) return;

foreach (SOOrder currentOrder in list)
{
SOOrderEntry SOOrderGraph = PXGraph.CreateInstance<SOOrderEntry>();
try
{
//Code here.

PXProcessing<SOOrder>.SetInfo(list.IndexOf(currentOrder), "Records Processed Successfully");
}
Catch(Exception Ex)
{
PXProcessing<SOOrder>.SetError(list.IndexOf(currentOrder), Ex.Message);
throw new PXOperationCompletedWithErrorException(Ex.Message);
}
}
}
}
}

 


Yes @Ivan  That is correct.

Here is the sample Processing screen code for your reference. You need to add your code try block and schedule this to run every specific periodic time.

 

 public class SOProcess : PXGraph<SOProcess>
{
public PXCancel<SOOrder> Cancel;

public PXProcessing<SOOrder> KNSOProcessView;

#region Constructor

public SOProcess()
{
KNSOProcessView.SetProcessCaption("Process");
KNSOProcessView.SetProcessAllCaption("ProcessAll");
KNSOProcessView.SetProcessDelegate(
delegate (List<SOOrder> list)
{
GetOpenSSaaSOrders(list);
});
}
#endregion

public static void GetOpenSSaaSOrders(List<SOOrder> list)
{
SOProcess graph = PXGraph.CreateInstance<SOProcess>();
graph.AMISSaaSProcessOrders(list);
}

public virtual void AMISSaaSProcessOrders(List<SOOrder> list)
{
if (list.Count <= 0) return;

foreach (SOOrder currentOrder in list)
{
SOOrderEntry SOOrderGraph = PXGraph.CreateInstance<SOOrderEntry>();
try
{
//Code here.

PXProcessing<SOOrder>.SetInfo(list.IndexOf(currentOrder), "Records Processed Successfully");
}
Catch(Exception Ex)
{
PXProcessing<SOOrder>.SetError(list.IndexOf(currentOrder), Ex.Message);
throw new PXOperationCompletedWithErrorException(Ex.Message);
}
}
}
}
}

 

@Naveen B  thanks for the provided sample

I added screen with Name SOProcess in Acumatica, added code to the project

and still receive null errors 

schedule of the screen must be done in this tab ?


Hi @Ivan  Are you working with any Sales Orders in your requirement?

If NOT, why are you using Sales Orders?

In the above, I just shared a sample code snippet using Sales Orders, you need to modify it according to your requirement and verify. You can not use the same code, which I shared.


Hi @Naveen B 

In previous comment you mentioned “You need to add your code try block”, I thought it should done is such way

In my case it is now required to interact with any other entity. The only target is to create an independent code that will be always executed.

I need to clarify some moment

The first one : during creating new screen - is it enough to generate new one screen without adding anything here (fields, other elements) at stat step (I do not need to use anything from this entity, no new fields, I just new to create independent code as mentioned above). If it is enough - good

Second moment - the code that you have provided launches the new entity as I understand. According to your last response instead of SOProcess, it should be modified with ArtsylPay type that is depicted on the first screen, am I right ? If it so, what should be written here instead of soentry,  soorder?

As I wrote above I do not need to use any fields, elements with my new entity, I will only generate files, so what should obligatory be defined in my code?

 

public class ArtsylPay : PXGraph<ArtsylPay>
    {
        public PXSave<MasterTable> Save;
        public PXCancel<MasterTable> Cancel;
        public PXProcessing<MasterTable> KNSOProcessView;
        public PXFilter<MasterTable> MasterView;
        public PXFilter<DetailsTable> DetailsView;
        gSerializable]
        public class MasterTable : IBqlTable
        {

        }
        Serializable]
        public class DetailsTable : IBqlTable
        {

        }
        public ArtsylPay()
        {
            KNSOProcessView.SetProcessCaption("Process");
            KNSOProcessView.SetProcessAllCaption("ProcessAll");
            KNSOProcessView.SetProcessDelegate(
                delegate (List<SOOrder> list)
                {
                    GetOpenSSaaSOrders(list);
                });
        }
        public static void GetOpenSSaaSOrders(List<SOOrder> list)
        {
            ArtsylPay graph = PXGraph.CreateInstance<ArtsylPay>();
            graph.AMISSaaSProcessOrders(list);
        }
        public virtual void AMISSaaSProcessOrders(List<SOOrder> list)
        {
            if (list.Count <= 0) return;

            foreach (SOOrder currentOrder in list)
            {
                SOOrderEntry SOOrderGraph = PXGraph.CreateInstance<SOOrderEntry>();
                try
                {
                    DateTime time = DateTime.Now;
                    string path = $@"C:\Temp\File{time:MMddyyyy}.{time:HHMMssffff}" + ".txt";
                    using (StreamWriter writer = new StreamWriter(new FileStream(path, FileMode.Create, FileAccess.Write)))
                    {
                        writer.WriteLine("It works");
                    }
                    PXProcessing<SOOrder>.SetInfo(list.IndexOf(currentOrder), "Records Processed Successfully");
                }
                catch (Exception Ex)

                {
                    PXProcessing<SOOrder>.SetError(list.IndexOf(currentOrder), Ex.Message);
                    throw new PXOperationCompletedWithErrorException(Ex.Message);
                }
            }
        }

    }


Reply