Solution suggested by Brendan will definitely work, however it doesn’t seem to be bullet-proof agains possible changes in base SOOrderEntry BLC and can possible increase maintenance cost in future.
On the Sales Orders screen, none of the original aggregated values get duplicated thanks to SOOrder_RowSelected handler implemented in the BLC - it makes sure to always set Enabled property of the PXUIFieldAttribute to False for all base aggregated fields. This is the only additional required step because of PXUIFieldAttribute.SetEnabled(cache, doc, true);
method invoked in the middle of the SOOrder_RowSelected handler:
public class SOOrderEntry : PXGraph<SOOrderEntry, SOOrder>, PXImportAttribute.IPXPrepareItems
{
...
protected virtual void SOOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
SOOrder doc = e.Row as SOOrder;
if (doc == null)
{
return;
}
...
bool allowAllocation = soordertype.Current != null && soordertype.Current.RequireAllocation != true
|| PXAccess.FeatureInstalled<FeaturesSet.warehouseLocation>()
|| PXAccess.FeatureInstalled<FeaturesSet.lotSerialTracking>()
|| PXAccess.FeatureInstalled<FeaturesSet.subItem>()
|| PXAccess.FeatureInstalled<FeaturesSet.replenishment>()
|| PXAccess.FeatureInstalled<FeaturesSet.sOToPOLink>();
if (doc == null || doc.Completed == true || doc.Cancelled == true || !allowAllocation)
{
PXUIFieldAttribute.SetEnabled(cache, doc, false);
cache.AllowDelete = false;
cache.AllowUpdate = allowAllocation;
...
}
else
{
...
PXUIFieldAttribute.SetEnabled(cache, doc, true);
PXUIFieldAttribute.SetEnabled<SOOrder.refTranExtNbr>(cache, doc, (doc.CreatePMInstance == true || doc.PMInstanceID.HasValue) && isCCPayment && isCashReturn && !isCCRefunded);
PXUIFieldAttribute.SetEnabled<SOOrder.status>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.orderQty>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.orderWeight>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.orderVolume>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.packageWeight>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyOrderTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyUnpaidBalance>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyLineTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyMiscTot>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyFreightCost>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.freightCostIsValid>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyFreightAmt>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyTaxTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.openOrderQty>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyOpenOrderTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyOpenLineTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyOpenTaxTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.unbilledOrderQty>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyUnbilledOrderTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyUnbilledLineTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyUnbilledTaxTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyPaymentTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyID>(cache, doc, curyenabled);
PXUIFieldAttribute.SetEnabled<SOOrder.preAuthTranNumber>(cache, doc, enableCCAuthEntering);
PXUIFieldAttribute.SetEnabled<SOOrder.cCPaymentStateDescr>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.cCAuthExpirationDate>(cache, doc, enableCCAuthEntering && String.IsNullOrEmpty(doc.PreAuthTranNumber) == false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyCCPreAuthAmount>(cache, doc, enableCCAuthEntering && String.IsNullOrEmpty(doc.PreAuthTranNumber) == false);
PXUIFieldAttribute.SetEnabled<SOOrder.pCResponseReasonText>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.captureTranNumber>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyCCCapturedAmt>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.origOrderType>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.origOrderNbr>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyVatExemptTotal>(cache, doc, false);
PXUIFieldAttribute.SetEnabled<SOOrder.curyVatTaxableTotal>(cache, doc, false);
...
}
...
}
...
}
With that said, to resolve the issue with doubled custom aggregated field value, you should follow 2 steps listed below. Those are necessary to exclude custom aggregated field from template used when pasting the document.
Implement RowSelected handler for the SOOrder DAC in the SOOrderEntry BLC extension to also set Enabled property of the PXUIFieldAttribute to False for your custom field:
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
public void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
var doc = e.Row as SOOrder;
if (doc == null) return;
if (doc != null && doc.Completed != true && doc.Cancelled != true && sender.AllowUpdate)
{
PXUIFieldAttribute.SetEnabled<SOOrderExt.usrTotalRevenue>(sender, doc, false);
}
}
}
For custom aggregated field input control, set Enabled property to False in Aspx page:
<px:PXNumberEdit DataField=“UsrTotalRevenue” Enabled="False" runat="server" ID="CstPXNumberEdit19" />
Regarding concerns shared by @Dmitry Kasatsky: on Friday evening Peter sent me his customization via email, which I used to verify the 2-step approach described above. Based on reported scenario, there were NO issues identified with the PXFormulaAttribute and custom fields. If you concern about the PXFormulaAttribute and Copy-Paste feature, set enabled property to True (equal to the default property value) for base OrderQty field input control:
<px:PXNumberEdit ID="edOrderQty" runat="server" DataField="OrderQty" Enabled="True" />
and implement RowSelected handler for the SOOrder DAC in the SOOrderEntry BLC extension to undo PXUIFieldAttribute.SetEnabled<SOOrder.orderQty>(cache, doc, false);
command from the SOOrderEntry BLC:
protected virtual void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SOOrder soorder = (SOOrder)e.Row;
if (soorder == null) return;
if (soorder != null && soorder.Completed != true && soorder.Cancelled != true && sender.AllowUpdate)
{
PXUIFieldAttribute.SetEnabled<SOOrder.orderQty>(sender, soorder, true);
}
}
This will enable Ordered Qty. field and eventually result in duplicated value in copy-pasted documents:
For future reference, to check if document template includes custom field:
Restart IIS or recycle app pool to clear previously cached Acumatica ScreenInfo
Select Save as Template… option from Clipboard menu and verify if custom field exists in generated document template:
Please note: fields with Null values will always be excluded from document template