I have created a custom checkbox field on SO Invoice screen (SO303000) which needs to updated even after Invoice is released and payments are fully paid.
However for now I am not able to do as it is is getting disabled once invoice is Released and fully paid.
I tried to do it with Automation Steps but it is not working. I have added the custom field on Fields tab to make it enable on Closed step of SO Invoices.
Please suggest.
To enable custom fields on the SO Invoices top-level form and Transactions grid after Invoice is released and/or closed, you should create an extension for SOInvoiceEntry and subscribe to the ARInvoice_RowSelected and ARTran_RowSelected events following the sample below:
public class SOInvoiceEntryExt : PXGraphExtension<SOInvoiceEntry>
{
private bool IsDisabled(ARInvoice doc)
{
return doc.Released == true
|| doc.Voided == true
|| doc.DocType == ARDocType.SmallCreditWO
|| doc.PendingPPD == true
|| doc.DocType == ARDocType.FinCharge
&& !Base.IsProcessingMode
&& Base.Document.Cache.GetStatus(doc) == PXEntryStatus.Inserted;
}
public void ARInvoice_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
ARInvoice doc = e.Row as ARInvoice;
if (doc == null) return;
if (IsDisabled(doc))
{
PXUIFieldAttribute.SetEnabled<ARInvoiceExt.usrCustomTextField>(
sender, doc, true);
Base.Transactions.Cache.AllowUpdate = true;
}
}
public void ARTran_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
var doc = Base.Document.Current;
ARTran row = e.Row as ARTran;
if (row != null && doc != null && IsDisabled(doc))
{
PXUIFieldAttribute.SetEnabled(sender, row, false);
PXUIFieldAttribute.SetEnabled<ARTranExt.usrCustomTextField>(
sender, row, true);
}
}
}
Additionally, you need to enable custom field added onto the top-level form in the Closed automation step:
This is how the SO Invoices screen should work after you apply the changes described above:
Related
I need to enable fields on the Sales Order screen when the Status of the Sales Order is Completed.
I found a few other posts with solutions on older versions of Acumatica where you need to also change things in the Automation steps but in Version 21.207 Automation steps has been replaced with Workflows and I can't seem to edit them for the Sales Order screen.
My Code:
protected void SOOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
var row = (SOOrder)e.Row;
if (row == null) return;
if (Condition1 != null && Condition2 == true)
{
cache.AllowUpdate = true;
Base.Document.Cache.AllowUpdate = true;
PXUIFieldAttribute.SetEnabled<SOOrder.salesPersonID>(cache, e.Row, true);
}
}
The Old Posts:
Enable SOLine field after Order Completed
How to enable CustomerOrderNbr field in Sales Order screen?
Update
Tried the answer from
Kyle Vanderstoep
But unfortunately the cache.AllowUpdate = true; stays False after stepping over it in debugging mode.
Update 2
The Solution from Kyle Vanderstoep did work in the end, after I remade the customization. Acumatica and my code was just acting up the first time round.
Two steps, override in workflow and in row selected. This one is for CustomerRefNbr
public override void Configure(PXScreenConfiguration configuration)
{
var context = configuration.GetScreenConfigurationContext<SOOrderEntry, SOOrder>();
context.UpdateScreenConfigurationFor(
c => c.WithFlows(flowContainer =>
{
flowContainer
.Update(SOBehavior.SO, df => df
.WithFlowStates(fls =>
{
fls.Update<SOOrderStatus.completed>(flsc => flsc
.WithFieldStates(fs => fs.AddField<SOOrder.customerRefNbr>()));
}));
}));
}
public virtual void SOOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected baseN)
{
baseN(cache, e);
SOOrder doc = e.Row as SOOrder;
if (doc == null)
{
return;
}
cache.AllowUpdate = true;
PXUIFieldAttribute.SetEnabled<SOOrder.customerRefNbr>(cache, null, true);
}
Below is the code that i tried in ShipmentEntry graph extension but save button is not not enabled to save the new entry of tracking number also due to this code the entire row fields got enabled.
protected virtual void SOShipment_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected BaseEvent)
{
if (BaseEvent != null)
BaseEvent(sender, e);
SOShipment row = e.Row as SOShipment;
if (row == null)
return;
PXUIFieldAttribute.SetEnabled<SOPackageDetailEx.trackNumber>(sender, row, true);
Base.Document.Cache.AllowUpdate = true;
Base.Packages.Cache.AllowUpdate = true;
}
protected virtual void SOPackageDetailEx_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected BaseEvent)
{
if (BaseEvent != null)
BaseEvent(sender, e);
SOPackageDetail row = e.Row as SOPackageDetail;
if (row == null) return;
PXUIFieldAttribute.SetEnabled<SOPackageDetailEx.trackNumber>(sender, row, true);
}
Thanks in advance for your help.
The code below edits and saves the tracking number field's value to the database even when the shipment is invoiced:
sOPackageDetailEx.TrackNumber = "Some Value";
Base.Packages.Update(sOPackageDetailEx);
Base.Caches[typeof(SOPackageDetailEx)].PersistUpdated(sOPackageDetailEx);
This code must be written in the SOShipmentEntry extension class, where sOPackageDetailEx is an instance of the 'SOPackageDetailEx' class.
I am trying to enable a certain field when POOrder status is on "Pending Approval" like Description field but when I override it on POOrder_RowSelected event it still doesn't enable the field.
protected void POOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
if(InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
POOrder row = (POOrder)e.Row;
if (row != null)
{
if (row.Hold == false && row.Status == POOrderStatus.Balanced) // Balance is indicated on Pending appoval
{
PXUIFieldAttribute.SetEnabled<POOrder.orderDesc>(cache, row, true);
}
}
}
You can accomplish this by using Automation Steps.
Select your Purchase Order screen, and on Step ID select "NL Pending Approval". (See below)
Then locate "Purchase Order" TableName with FieldName "*" and unchecked the Disabled box. Then Save your changes.
Then you can extend the POOrderEntry graph and on RowSelected event handler add your custom logic(and set enable the desired fields):
public void POOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
if(InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
POOrder order= (POOrder)e.Row;
if (order == null || Base.IsExport) return;
if (order.Status == POOrderStatus.Balanced)
{
PXUIFieldAttribute.SetEnabled<POLine.orderDesc>(sender, order, true);
}
}
Sample above would enable Description field when POOrder is with Balanced Status. Here is another link to similar question involving Custom User Fields: How to enable a custom field on PO301000 when the PO is in Open status?
In Sales Order screen, I'm trying to enable the CustomerOrderNbr field if the status is completed
protected void SOOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
SOOrder doc = e.Row as SOOrder;
if (doc == null)
{
return;
}
if (doc.Completed == true )
{
PXUIFieldAttribute.SetEnabled(cache, doc , true);
PXUIFieldAttribute.SetEnabled<SOOrder.customerOrderNbr>(cache, doc, true);
}
}
however, it remains disabled and not doing what it's supposed to do. So what am I doing wrong ? Am I on the right event to override at all ?
Or is the screen really locked in once the Sales Order is Completed ?
Thanks for any answers.
Since Sales Orders screen is heavily driven by Automation Steps, in addition to extended RowSelected handler for the SOOrder DAC, it's an absolute must to modify automation steps for Completed orders that disable entire SOOrder :
In addition to the automation step change shown above, you should keep SOOrder_RowSelected handler:
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
public void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SOOrder order = e.Row as SOOrder;
if (order == null) return;
if (order.Completed == true)
{
PXUIFieldAttribute.SetEnabled<SOOrder.customerOrderNbr>(sender, order, true);
}
}
}
With those 2 changes in place, Customer Order will stay enabled for SO Orders with Completed status:
I need to make Salesperson ID on SOLine as a required field. But as Transfer orders do not have Salesperson, hence it should only validate when I create orders other than Transfer orders.
I tried with below code but it seems it is not working. Might be it is overrided with some existing code. Let me know if anyone has any suggestions.
public PXSetup<SOOrderTypeOperation,
Where<SOOrderTypeOperation.orderType, Equal<Optional<SOOrderType.orderType>>,
And<SOOrderTypeOperation.operation, Equal<Optional<SOOrderType.defaultOperation>>>>> sooperation;
protected bool IsTransferOrder
{
get
{
return (sooperation.Current.INDocType == INTranType.Transfer);
}
}
protected virtual void SOLine_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
{
var row = (SOLine)e.Row;
if (row == null) return;
PXDefaultAttribute.SetPersistingCheck<SOLine.salesPersonID>(sender, row, IsTransferOrder ? PXPersistingCheck.Nothing : PXPersistingCheck.Null);
}
I usually thrown an appropriate exception in Row Persisting when the condition exists.
Here is an example from SOShipmentEntry checking for transfer and checking the null value of a field:
protected virtual void SOShipment_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
{
SOShipment doc = (SOShipment)e.Row;
if (doc.ShipmentType == SOShipmentType.Transfer && doc.DestinationSiteID == null)
{
throw new PXRowPersistingException(typeof(SOOrder.destinationSiteID).Name, null, ErrorMessages.FieldIsEmpty, typeof(SOOrder.destinationSiteID).Name);
}
}
I have also called RaiseExceptionHandling similar to this example within RowPersisting
// sender = PXCache
if (row.OrderQty == Decimal.Zero)
sender.RaiseExceptionHandling<POLine.orderQty>(row, row.OrderQty, new PXSetPropertyException(Messages.POLineQuantityMustBeGreaterThanZero, PXErrorLevel.Error));
Both examples should stop the page from the save. calling the Raise Exception handling should point out the field with the Red X which is the better approach and easier for the user to find the field in question.
For your example:
protected virtual void SOLine_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
{
SOLine row = (SOLine)e.Row;
if (row == null)
{
return;
}
if (!IsTransferOrder && row.SalesPersonID == null)
{
sender.RaiseExceptionHandling<SOLine.salesPersonID>(row, row.SalesPersonID, new PXSetPropertyException(ErrorMessages.FieldIsEmpty, PXErrorLevel.Error));
}
}