Acumatica - Copy custom field contents from SO to IN - acumatica

I have a similar type of issue as in
Acumatica refer custom field to another custom field on different screen
except that I am using custom source fields.
I created and added 2 fields to the SO Line to capture EDI data needed for invoicing. I created 2 new fields on the invoice line with the same name (different data class of course) on the SO Invoice form. Below is the code for 1 field on each of the forms:
SO301000 (Sales Orders):
[PXDBString(3)]
[PXUIField(DisplayName="Cust.Invoice Line Nbr.")]
[PXFormula(typeof(Selector<SOLineExt.usrCInvLine, ARTranExt.usrCInvLine>))]
SO303000 (Invoices):
[PXDBString(3)]
[PXUIField(DisplayName="Cust.Invoice Line Nbr.")]
It compiles but the data is not being copied to the invoice when created from shipment. I also added 1 of the fields to the shipment form for testing purposes but it does nit capture that value either.
Do I have this backwards?

After reviewing it into more details, you could override the Prepare Invoice method on SOOrderEntry graph (and also anywhere else is needed).
By overriding the PrepareInvoice Method of SOOrderEntry graph you could add a Handler(RowInserting) to SOInvoiceEntry graph to populate your new Custom field with the value on SOOrder.
See sample below where I'm doing similar action copying value from SOOrder(Header) to ARTran(details).
You can use this sample to achieve your goal: (In your case you could use ARInvoice instead of ARTran)
SOOrderEntry:
public class SOOrderEntry_Extension:PXGraphExtension<SOOrderEntry>
{
public PXAction<SOOrder> prepareInvoice;
[PXUIField(DisplayName = "Prepare Invoice", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = false)]
[PXButton]
public virtual IEnumerable PrepareInvoice(PXAdapter adapter)
{
PXGraph.InstanceCreated.AddHandler<SOInvoiceEntry>((graph) =>
{
graph.RowInserting.AddHandler<ARTran>((sender, e) =>
{
//Custom logic goes here
var row = (ARTran)e.Row;
if (row == null)
return;
SOOrder order = Base.Document.Current;
if (order != null)
{
var tranExt = PXCache<ARTran>.GetExtension<ARTranExt>(row);
//Below to be change to your needs
//Here you can look for the SOLine of the SOOrder instead
var orderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(order);
if (orderExt != null && tranExt != null)
{
tranExt.UsrContactID = orderExt.UsrContactID;
}
//END
}
});
});
return Base.prepareInvoice.Press(adapter);
}
}
You could also find more information and instructions provided by my colleague on the stackoverflow link below:
Acumatica custom field SOLine transferred to ARTran

Related

Why is my hyperlink / button in the grid to launch a screen disabled?

I have a customization to the Sales Orders screen, where I've added a user field (non-bound / [PXString] to hold the value of a PO Receipt Nbr. I populate it with the RowSelected event, and I'm trying to launch the Purchase Receipts screen from that field with a PXAction tied to that field's Linked Command:
The Field:
public abstract class usrPOReceiptNbr : BqlString.Field<usrPOReceiptNbr> { }
[PXString(15, IsUnicode = true)]
[PXUIField(DisplayName = "PO Receipt Nbr", Enabled = true)]
public virtual string UsrPOReceiptNbr { get; set; }
The RowSelected event code to populate the field:
var soordershipment = e.Row as SOOrderShipment;
using (new PXConnectionScope())
{
//get the extension
var soordershipmentext = PXCache<SOOrderShipment>.GetExtension<SOOrderShipmentExt>(soordershipment);
//Get the soorder cache...
SOOrder soorder = Base.Document.Current;
if (soorder != null)
{
//Now get the POReceiptLine record:
PXResultset<POReceiptLine> res = PXSelectJoin<POReceiptLine,
InnerJoin<SOOrder,
On<SOOrder.orderNbr, Equal<POReceiptLine.sOOrderNbr>,
And<SOOrder.orderType, Equal<POReceiptLine.sOOrderType>>>>,
Where<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>>,
OrderBy<Desc<POReceiptLine.receiptNbr>>>.Select(Base, soorder.OrderNbr);
foreach (PXResult<POReceiptLine> rec in res)
{
POReceiptLine porl = (POReceiptLine)rec;
soordershipmentext.UsrPOReceiptNbr = porl.ReceiptNbr;
break; //Stop after the first record, since I only want the highest sorted field
}
}
}
The code to launch the Purchase Receipts screen is as follows:
public PXAction<SOOrder> LaunchPurchaseReceipts;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Launch Purchase Receipts", Enabled = true)]
protected virtual IEnumerable launchPurchaseReceipts(PXAdapter adapter)
{
var soorder = (SOOrder)Base.Document.Current;
POReceiptEntry graph = PXGraph.CreateInstance<POReceiptEntry>();
var soordershipment = (SOOrderShipment)Base.shipmentlist.Current;
var soordershipmentext = PXCache<SOOrderShipment>.GetExtension<SOOrderShipmentExt>(soordershipment);
graph.Document.Current = graph.Document.Search<POReceipt.receiptNbr, POReceipt.receiptType>(soordershipmentext.UsrPOReceiptNbr, soordershipment.ShipmentType);
throw new PXRedirectRequiredException(graph, "Purchase Receipts")
{
Mode = PXBaseRedirectException.WindowMode.NewWindow
};
}
The problem is that I continue to get this error when launching the hyperlink on the PO Receipt Nbr field for that screen (it never even gets to the code to launch the screen):
...and here's the error...
I've tried forcing the field to enabled with the RowSelected event, using:
PXUIFieldAttribute.SetEnabled<SOOrderShipmentExt.usrPOReceiptNbr>(e.Cache, null, true);
But that doesn't do anything.
Any ideas?
This issue has been resolved with a suggestion from Brendan (thanks much) by using the RowSelected event to set the method's enabled property to true:
LaunchPurchaseReceipts.SetEnabled(true);

Create new Note on POLine during po creation based on value of custom field

Suppose I have a custom field SOLineExt.UsrCustomField that allows text entry, accessible from SO301000. If I'm creating a PO from PO505000 screen based off this SOLine, I want to automatically create a note on the new POLine and insert the value of SOLineExt.UsrCustomField as the NoteText, but only if SOLineExt.UsrCustomField != null.
The custom field is also accessible as POFixedDemandExt.UsrCustomField (it is populated with fixedDemand IEnumerable override in POCreate), so I can feed it through an override of FillPOLineFromDemand() in POOrderEntry if I need to.
1) do I need to create the new Note in FillPOLineFromDemand() or in POLine_RowInserted(), or somewhere else?
2) what code will create a note and insert the value of UsrCustomField into NoteText? Do I need to create and populate a Note DAC?
You can set a text note using the SetNote static method of PXNoteAttribute class.
There are some unexpected issues when calling that method on a POLine object in the context of FillPOLineFromDemand method. Presumably because the POLine object is not properly initialized in cache at that point.
You can use POLine_RowInserted, I tested this solution:
public void POLine_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
POLine row = e.Row as POLine;
POLinkSO.DAC.POLineExt rowExt = row != null ? row.GetExtension<POLinkSO.DAC.POLineExt>() : null;
if (rowExt != null)
{
SOLine line = PXSelectReadonly<SOLine,
Where<SOLine.orderNbr, Equal<Required<SOLine.orderNbr>>,
And<SOLine.orderType, Equal<Required<SOLine.orderType>>,
And<SOLine.lineNbr, Equal<Required<SOLine.lineNbr>>,
And<SOLineExt.usrCustomField, IsNotNull>>>>>.Select(Base,
rowExt.UsrPOLinkSOOrderNbr,
rowExt.UsrPOLinkSOOrderType,
rowExt.UsrPOLinkSOLineNbr);
SOLineExt lineExt = line != null ? line.GetExtension<SOLineExt>() : null;
if (lineExt != null)
{
PXNoteAttribute.SetNote(sender, row, lineExt.UsrCustomField);
}
}
}

Custom Print Invoice Action on Process Screen

I am trying to have a print invoice Action on my new process screen which points to new custom report taking Customer Ref Nbr as a parameter. Any help on how to start with this?
In Acumatica redirection to another page (points to new custom report) is done by throwing redirection exceptions. For redirecting to a report page the exception you should use is 'PXReportRequiredException'.
Code for launching your custom report with parameter:
public PXAction<Customer> printInvoice;
[PXUIField(DisplayName = "Print Invoice", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
public virtual IEnumerable PrintInvoice(PXAdapter adapter)
{
Customer customer = [fetch desired customer record here];
if (customer != null && customer.RefNbr != null)
{
// Add your report parameters to a Dictionary<string, string> collection.
// The dictionary key is the parameter name as shown in the report editor.
// The dictionary value is the value you assign to that parameter.
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["RefNbr"] = customer.RefNbr;
// Provide your custom report ReportID
string reportID = "AR641000";
// Provide a title name for your report page
string reportName = "Customer Invoice"
// Redirect to report page by throwing a PXReportRequiredException object
throw new PXReportRequiredException(parameters, reportID, reportName);
}
return adapter.Get();
}
You can look up the parameter names in the Parameters tab of the Schema Builder dialog of Acumatica Report Designer:

BQL on custom DAC referencing SOOrder.orderNbr not reflecting current Order Nbr

We have a test DAC called UsrNonRelatedScanField with two fields : OrderNbr and ScanStatus.
Here's our simple query to grab the correct ordernbr and assign it to a SOOrderExt field:
NonRelatedScanField lastScan = PXSelect<NonRelatedScanField,
Where<NonRelatedScanField.orderNbr,
Equal<Required<SOOrder.orderNbr>>>>.Select(Base, row.OrderNbr);
if(lastScan != null)
{
rowExt.UsrNonRelatedScanField = lastScan.ScanStatus;
}
This logic is held in a SOOrder_RowSelecting() method.
Full Method implementation:
protected virtual void SOOrder_RowSelecting(PXCache sender, PXRowSelectingEventArgs e)
{
SOOrder row = (SOOrder)e.Row;
if (row == null) return;
SOOrderExt rowExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(row);
NonRelatedScanField lastScan = PXSelect<NonRelatedScanField,
Where<NonRelatedScanField.orderNbr,
Equal<Required<SOOrder.orderNbr>>>>.Select(Base, row.OrderNbr);
if (lastScan != null)
{
rowExt.UsrNonRelatedScanField = lastScan.ScanStatus;
}
}
Expected Results : Get the current Orders scan status from lastScan DAC
Actual Results: Will populate correctly only on the initial order opened. When selecting other orders the old value is persisting unless I manually refresh the page. When manually refreshed the correct data comes in.
I haven't had any issues in the past with BQL queries, this specific query is not behaving as expected.
Thank you

Set Field Value during Email Sales Order process under Slaes Order Entry Actions

I created a new field, UsrAcknowledged, boolean, checkbox, and placed it on the SOLine details grid. I want every line on the details grid to be checked when the Email Sales Order/Quote process is run under Actions for SOOrder. My code is as follows under the SOOrderEntry_Extension:PXGraphExtension
public CRActivityList<SOOrder> Activity;
public PXAction<SOOrder> notification;
[PXUIField(DisplayName = "Notifications", Visible = false)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntryF)]
protected virtual IEnumerable Notification(PXAdapter adapter,
[PXString]
string notificationCD
)
{
foreach (SOOrder order in adapter.Get<SOOrder>())
{
var parameters = new Dictionary<string, string>();
parameters["SOOrder.OrderType"] = order.OrderType;
parameters["SOOrder.OrderNbr"] = order.OrderNbr;
Activity.SendNotification(ARNotificationSource.Customer, notificationCD, order.BranchID, parameters);
//order.OrderDesc = "Desc";
foreach (SOLine line in PXSelect<SOLine>.Select(Base, order.OrderNbr))
{
SOLineExt rowExt = line.GetExtension<SOLineExt>();
rowExt.UsrAcknowledged = true;
line.OrderQty = 5;
}
yield return order;
}
}
//order.Desc = "Desc" was an initial simple test just to see if my code was achieving the desired results and the proder desciption was changed as planned.
My code compiles and the email process runs as planned with a green check for successful, but neither the Acknowledged check box nor the Order Quantity are changed. I don't really care about the ord qty, it was just another test.
Any suggestions for what I can change to update the Acknowledged checkbox to checked during the Email Sales Order/Quote under Actions on the SO Order Entry screen would be appreciated
I would say you need to call Base.Transactions.Update(line) after you update your row values inside your foreach.

Resources