Skip to main content

Hi,

I want to execute a custom logic when the user click the Release button, but only if the Release process completes successfully. How I can get the error message from the release process? This is my code. 

>PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
baseMethod(adapter);
_inservice.UpdateItemLocation(Base, itemloc.Cache, AddOrSubstract.Add, Base.transactions.Cache);
Base.Save.PressButton();
return adapter.Get();
}

 

Thanks,

EV

Hi @edsonvelez64 

 

Just wrap all in a try catch block

 

sPXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
try {
baseMethod(adapter);

// Wait until it ends because a new thread is created when releasing
PXLongOperation.WaitCompletion(Base.UID);

_inservice.UpdateItemLocation(Base, itemloc.Cache, AddOrSubstract.Add,
Base.transactions.Cache);
Base.Save.PressButton();
return adapter.Get();
}
catch(PXException ex)
{
// Your code here
}
}

 


Hi @edsonvelez64 

 

Just wrap all in a try catch block

 

cPXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
try {
baseMethod(adapter);

// Wait until it ends because a new thread is created when releasing
PXLongOperation.WaitCompletion(Base.UID);

_inservice.UpdateItemLocation(Base, itemloc.Cache, AddOrSubstract.Add,
Base.transactions.Cache);
Base.Save.PressButton();
return adapter.Get();
}
catch(PXException ex)
{
// Your code here
}
}

 

Hi,

Is not working, the process do not throw an exception, but the page still display the error message. 

Thanks,

EV


@edsonvelez64 

 

Did you add the WaitCompletion part?


@edsonvelez64

 

Did you add the WaitCompletion part?

Hi,

Yes. 

 

 "PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
try
{
baseMethod(adapter);
bool rvalue = PXLongOperation.WaitCompletion(Base.UID);

_inservice.UpdateItemLocation(Base, itemloc.Cache, AddOrSubstract.Add, Base.transactions.Cache);
Base.Save.PressButton();
return adapter.Get();
}
catch (PXException ex)
{

}
return adapter.Get();
}

 


@edsonvelez64 

Well, I think you have to go down to the StartOperation call. Try this:

>PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{

// baseMethod not invoked as we are doing the code ourselves

PXCache cache = Base.INRegisterDataMember.Cache;
var list = new List<INRegister>();
foreach (INRegister indoc in adapter.Get<INRegister>())
{
if (indoc.Hold == false && indoc.Released == false)
{
cache.Update(indoc);
list.Add(indoc);
}
}
if (list.Count == 0)
{
throw new PXException(PX.Objects.IN.Messages.Document_Status_Invalid);
}
Save.Press();
PXLongOperation.StartOperation(this, delegate ()
{
try
{
INDocumentRelease.ReleaseDoc(list, false, adapter.QuickProcessFlow);
}
catch(PXException ex)
{
// Your code here

throw ex; // required
}
});
return list;
}

 


@edsonvelez64

Well, I think you have to go down to the StartOperation call. Try this:

[PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{

// baseMethod not invoked as we are doing the code ourselves

PXCache cache = Base.INRegisterDataMember.Cache;
var list = new List<INRegister>();
foreach (INRegister indoc in adapter.Get<INRegister>())
{
if (indoc.Hold == false && indoc.Released == false)
{
cache.Update(indoc);
list.Add(indoc);
}
}
if (list.Count == 0)
{
throw new PXException(PX.Objects.IN.Messages.Document_Status_Invalid);
}
Save.Press();
PXLongOperation.StartOperation(this, delegate ()
{
try
{
INDocumentRelease.ReleaseDoc(list, false, adapter.QuickProcessFlow);
}
catch(PXException ex)
{
// Your code here

throw ex; // required
}
});
return list;
}

 

Hi,

I achieved what I want using this code. Thanks for the help. 

sPXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{

baseMethod(adapter);
bool rValue = PXLongOperation.WaitCompletion(Base.UID);
Base.SelectTimeStamp();

if (rValue)
{
if (INRegister.PK.Find(Base, Base.CurrentDocument.Current.DocType, Base.CurrentDocument.Current.RefNbr).Status == INDocStatus.Released)
{
_inservice.UpdateItemLocation(Base, itemloc.Cache, AddOrSubstract.Add, Base.transactions.Cache);
Base.Save.PressButton();
}
}

return adapter.Get();
}

 


@edsonvelez64 Cool!

 

Yes the key its wait for the operation to complete. However, It’s sometimes desirable to manage the error itself as you were attempting.

 

Glad I could help.


@edsonvelez64  I’d actually suggest you to double check that you really need this custom logic as a part of release process. 

If it’s not ‘absolutely must happen at the same time as release’ type of process, I’d suggest to move it to a separate process. 

 

E.g. have a process that runs every minute, picks up released Adjustments, and does whatever you need with them. 

 


@edsonvelez64  I’d actually suggest you to double check that you really need this custom logic as a part of release process. 

If it’s not ‘absolutely must happen at the same time as release’ type of process, I’d suggest to move it to a separate process. 

 

E.g. have a process that runs every minute, picks up released Adjustments, and does whatever you need with them. 

 

 

@Dmitrii Naumov  - Can you explain the logic behind this recommendation? I ask because I’m pretty quick to tap into existing actions.


@edsonvelez64  I’d actually suggest you to double check that you really need this custom logic as a part of release process. 

If it’s not ‘absolutely must happen at the same time as release’ type of process, I’d suggest to move it to a separate process. 

 

E.g. have a process that runs every minute, picks up released Adjustments, and does whatever you need with them. 

 

 

@Dmitrii Naumov 

Thanks for your suggestion, but this need to be part of the release process because I’m working on an interface that manage catchweight and I need to track by site and location the quantity cases for those items. This calculation need to be accurate. 

 

Thanks,

EV


@darylbowman generally it’s easier to maintain/troubleshoot processes when they are separate. 

Also, considering that the release code can be changed in base Acumatica, it’ll be easier to have custom code as a separate process to not depend on specific version of Acumatica. 

 

Also, customizing one specific place in the code (e.g. IN Adjustment release) does not mean that you have covered all possible places. Maybe there is another process that generates IN transactions somewhere in the system (or even a custom one). By ‘subscribing’ to the result (e.g. INTran records) instead of subscribing to the specific process, you guarantee that you process all of them not depending on a way they appeared in the system.


@Dmitrii Naumov - Unless the action signature changes (return type or parameters, the Action extension should continue to work, correct?


@darylbowman yes, but I don’t really like the idea of overriding the action because the release method may be actually called from some other place, e.g. mass processing screen that has its own action. 


Reply