How to add condition for process buttons on Recognize Input VAT TX503500 - acumatica

I have to add a description field that is mandatory, so that the action of processing can be carried out, however I am a little confused, due to the fact that the field is in the filter area, to be copied later in the descriptions to be processed.
How can I customize the actions Process, ProcessAll?
I don't find these actions in Override Methods
thanks for helping me, I'm really new to this
sorry if my english is not so good

Basically, the Process/Process All actions are mapped to one method which is using the SetProcessDelegate method of the processing data view.
What you need to do is for first locating to the Graph(ProcessInputSVAT) of the Recognize Input VAT screen(TX503500). After opening the source code for that graph you can see that it's derived from the ProcessSVATBase class. And when you'll enter that class you'll see the mentioned SetProcessDelegate function called by Data View:
protected virtual void SVATTaxFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SVATTaxFilter filter = (SVATTaxFilter)e.Row;
if (filter == null)
{
return;
}
this.SVATDocuments.SetProcessDelegate(delegate(List<SVATConversionHistExt> list)
{
ProcessSVATBase.ProcessPendingVATProc(list, filter);
});
}
So we've figured out which graph extension we should create. Now, it's necessary to override the RowSelected event of the SVATTaxFilter DAC in the extension graph.
public class ProcessSVATBaseExt : PXGraphExtension<ProcessSVATBase>
{
public virtual void SVATTaxFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SVATTaxFilter filter = e.Row as SVATTaxFilter;
if (filter != null)
{
Base.SVATDocuments.SetProcessDelegate(delegate (List<SVATConversionHistExt> list)
{
// Here you can manage the list items and then call the base method
// ...
ProcessSVATBase.ProcessPendingVATProc(list, filter); // the base method
// Here you can manage the list items after the base method
// ...
});
}
}
}

Related

How can I keep a user field from coming through on a Journal Entry release function?

I have a customization to the Journal Transactions screen where I've added a user field to the grid (GLTran). When the Release function is initiated, it adds lines as it should - but it populates the user field with the values I had in the original lines, and I don't want this to happen. How can I intercept this process (I've looked at the source code and I can't see any functions I can use) to prevent this from happening?
I've tried the RowInserting / RowInserted events to set the field to null or blank, but this does nothing.
Thanks much -
From Acumatica support - an override of the Release process needs to be added to the Journal Entry BLC extension code, adding Event handlers as follows:
public delegate IEnumerable ReleaseDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
PXGraph.InstanceCreated.AddHandler<PostGraph>((graph) =>
{
graph.RowPersisting.AddHandler<GLTran>((sender, e) =>
{
var gltran = e.Row as GLTran;
if (gltran != null)
{
var gltranext = PXCache<GLTran>.GetExtension<GLTranExt>(gltran);
gltranext.UsrProject = null;
}
});
});
return baseMethod(adapter);
}
Thanks much, Cesar!

While deleting the customer, how can i set null value for the custom field for the assigned contacts in Acumatica

I have tried multiple ways, but getting Another process error in the default version of Acumatica 19.106.0020
On top of it i have a customized code on both customer and contact screen, my requirement to clear the value of the custom field that is created in contact table when customer is deleting from the screen AR303000 i need to set null value of the custom field for the deleted contact from the customer.
i have tried by setting value on Customer_RowDeleting event but continuously getting Another process error, below is the screenshot error
Below is the code that i was tried
protected virtual void Customer_RowDeleting(PXCache sender, PXRowDeletingEventArgs e, PXRowDeleting BaseEvent)
{
BaseEvent?.Invoke(sender, e);
Customer rows = e.Row as Customer;
if (rows == null)
return;
if (Base.BAccount.Cache.GetStatus(Base.BAccount.Current) == PXEntryStatus.Deleted)
{
foreach (Contact BACT in PXSelectReadonly<Contact,
Where<Contact.bAccountID, Equal<Required<Contact.bAccountID>>,
And<Contact.contactType, NotEqual<ContactTypesAttribute.bAccountProperty>>>>.Select(Base, rows.BAccountID))
{
ContactMaint congraph = PXGraph.CreateInstance<ContactMaint>();
Contact CTData = PXSelectReadonly<Contact,
Where<Contact.contactID, Equal<Required<Contact.contactID>>>>.Select(Base, BACT.ContactID);
if (CTData != null)
{
congraph.Contact.Current = CTData;
if (congraph.Contact.Current != null)
{
congraph.Contact.SetValueExt<ContactExt.usrKWBAccountId>(congraph.Contact.Current, null);
congraph.Contact.Update(congraph.Contact.Current);
congraph.Save.Press();
}
}
}
}
}
Thanks in advance.
Hi Chris, please find the attached image here
I don't recommend to create graphs during RowDeleting event. If you have Acuminator installed, you will see a warning about creating graphs in event handlers.
Instead, call your custom code during the Persist method. Persist method is called during Delete operation. After the Base persist is finished, your custom code can perform it's work. Try something like this
public class CustomerMaint_Extension : PXGraphExtension<CustomerMaint>
{
public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
Customer currentCustomer = Base.CurrentCustomer.Current; //get the customer record before it's deleted, i.e. Customer.bAccountID
baseMethod(); //let the base delete process happen first
if (Base.CurrentCustomer.Cache.GetStatus(currentCustomer) == PXEntryStatus.Deleted)
{
using (PXTransactionScope ts = new PXTransactionScope())
{
//here is where you add your code to delete other records
ts.Complete(); //be sure to complete the transaction scope
}
}
}
}
Also you might want to unpublish other customization packages, and see if the error continues without those packages. That is one way to determine the source of the error...by process of elimination.

How to Count records in a related table and allow user to override

I have a custom field on the CRActivity table in which I need to store the number of records in a related table. I am trying to set the field to the value when screen CR306030 opens. The user needs to be able to override the calculated number so, I'm thinking that I need logic on the calculation to check if the custom field is > 0, in which case, don't populate the custom field and assume it's already been set.
Previously, I've tried to do this in the Field_Selecting events but, this is not working. I'm thinking I might be able to use a PXFormula attribute. Any suggestions?
I tried making a custom attribute which is close but, it won't save the values to the db. The save button enables, I can click it and it looks like it saves but, no dice. Some mundane detail, I'm sure.....
Here's my custom attribute:
public class CFCountIfZeroAttribute : PXIntAttribute
{
public override void FieldSelecting(PXCache cache, PXFieldSelectingEventArgs e)
{
if (e.Row == null)
return;
CRActivity activity = (CRActivity)e.Row;
CRActivityExt activityExt = activity.GetExtension<CRActivityExt>();
if (activityExt.usrCustomField <= 0)
{
int aggregateValue = BQLToFind();
e.ReturnValue = aggregateValue;
cache.SetValue<CRActivityExt.usrCustomField>(e.Row, aggregateValue);
cache.IsDirty = true;
}
}
}
Thanks!
I don't think I've ever done a count within a PXFormula, but what if you created a custom attribute?
[DBUIInt()]
[EditableCount()]
public virtual int? CountField
public class EditableCountAttribute
{
public override void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
if (e.Row != null)
{
//if CountField is 0, lookup the count from another table
}
}
}
This is just off the top of my head. You could pass the field you're counting into the attribute if you wanted to do this elsewhere.

How to customize the Process button on the AP505200 screen. Acumatica

What method should I use to customize the "process" button on the AP 505200 screen.
I need to record records in a certain table when I press the Process button
Many thanks in advance!
The method is mapped to the Process/Process All actions using the SetProcessDelegate method of the processing data view.
First locate the Graph of the AP505200 screen (APReleaseChecks):
In the Source Code screen search for APReleaseChecks graph and find the SetProcessDelegate method:
APPaymentList.SetProcessDelegate(list => ReleasePayments(list, action));
The process delegate ReleasePayments method is static so you can't easily override it.
Try using SetProcessDelegate to call your own process delegate that will in turn call the base one.
public class APReleaseChecks_Extension : PXGraphExtension<APReleaseChecks>
{
public virtual void ReleaseChecksFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
ReleaseChecksFilter filter = e.Row as ReleaseChecksFilter;
if (filter != null)
{
Base.APPaymentList.SetProcessDelegate(delegate (List<APPayment> list)
{
// Do processing on list items before base process delegate
// [...]
// Call base process delegate
APReleaseChecks.ReleasePayments(list, filter.Action);
// Do processing on list items after base process delegate
// [...]
});
}
}
}

Intercept process on Run Project Billing screen

We're using the Run Project Billing screen to create records in AR / Invoice and Memo.
In the Invoice & Memo screen, we need the process to populate the header Customer Ord. number, along with a user field that has been added to the grid section on the 'Document Details' tab. At the moment, the process is not doing this.
I'd like to intercept the processing action on the screen using a technique I'm familiar with, namely using an 'AddHandler':
[PXOverride]
protected virtual IEnumerable Items (PXAdapter adapter)
{
PXGraph.InstanceCreated.AddHandler<BillingProcess>((graph) =>
{
graph.RowInserting.AddHandler<BillingProcess.ProjectsList>((sender, e) =>
{
//Custom logic goes here
});
});
return Base.action.Press(adapter);
}
I see no Base.Actions that remotely resembles 'Bill' or 'Bill All'.
This is obviously not exactly the code I need, but I would think this is the general place to start.
After reviewing the source business logic, I don't see any 'Bill' or 'Bill All' Actions - or any 'Actions' at all (baffling). I see an IEnumerable method called 'items', so that's what I started with above.
Is this the correct way to go about this?
Update: 2/14/2017
Using the answer provided re: the overridden method InsertTransaction(...) I've tried to set our ARTran user field (which is required) using the following logic:
PMProject pmproj = PXSelect<PMProject, Where<PMProject.contractID, Equal<Required<PMProject.contractID>>>>.Select(Base, tran.ProjectID);
if (pmproj == null) return;
PMProjectExt pmprojext = PXCache<PMProject>.GetExtension<PMProjectExt>(pmproj);
if (pmprojext == null) return;
ARTranExt tranext = PXCache<ARTran>.GetExtension<ARTranExt>(tran);
if (tranext == null) return;
tranext.UsrContractID = pmprojext.UsrContractID;
Even though this sets the user field to the correct value, it still gives me an error that the required field is empty when the process finishes. My limited knowledge prevents me from understanding why.
On the Run Project Billing screen, captions of Process and Process All buttons were changed to Bill and Bill All respectively in BLC constructor.
Process delegate is set for Items data view within the BillingFilter_RowSelected handler:
public class BillingProcess : PXGraph<BillingProcess>
{
...
public BillingProcess()
{
Items.SetProcessCaption(PM.Messages.ProcBill);
Items.SetProcessAllCaption(PM.Messages.ProcBillAll);
}
...
protected virtual void BillingFilter_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
BillingFilter filter = Filter.Current;
Items.SetProcessDelegate<PMBillEngine>(
delegate (PMBillEngine engine, ProjectsList item)
{
if (!engine.Bill(item.ProjectID, filter.InvoiceDate, filter.InvFinPeriodID))
{
throw new PXSetPropertyException(Warnings.NothingToBill, PXErrorLevel.RowWarning);
}
});
}
...
}
As code snippet above confirms, all records in the AR Invoice and Memos screen are created by instance of the PMBillEngine class. Below is code snippet showing how to override InsertNewInvoiceDocument and InsertTransaction methods within the PMBillEngine BLC extension:
public class PMBillEngineExt : PXGraphExtension<PMBillEngine>
{
public delegate ARInvoice InsertNewInvoiceDocumentDel(string finPeriod, string docType, Customer customer,
PMProject project, DateTime billingDate, string docDesc);
[PXOverride]
public ARInvoice InsertNewInvoiceDocument(string finPeriod, string docType, Customer customer, PMProject project,
DateTime billingDate, string docDesc, InsertNewInvoiceDocumentDel del)
{
var result = del(finPeriod, docType, customer, project, billingDate, docDesc);
// custom logic goes here
return result;
}
[PXOverride]
public void InsertTransaction(ARTran tran, string subCD, string note, Guid[] files)
{
// the system will automatically invoke base method prior to the customized one
// custom logic goes here
}
}
Run Project Billing process invokes InsertNewInvoiceDocument method to create new record on the AR Invoice and Memos screen and InsertTransaction method to add new invoice transaction.
One important thing to mention: overridden InsertNewInvoiceDocument and InsertTransaction methods will be invoked when a user launches Run Project Billing operation either from the processing Run Project Billing screen or from the data entry Projects screen.
For more information on how to override virtual BLC methods, see Help -> Customization -> Customizing Business Logic -> Graph -> To Override a Virtual Method available in every Acumatica ERP 6.1 website

Resources