Skip to main content
Solved

Create SO Through Graph Extension

  • 26 July 2024
  • 4 replies
  • 101 views

Hello Community, 

I am working on a project to create a sales order based off of a receipt (RMA) of a shipment. I am relatively new to Acumatica Development side and just had a few questions. I believe I have my action added and code that will create the SO document and I am ready to populate those objects, however, I am unsure on how to reference the data in the shipment record. I essentially need to copy the line items to a sales order with the transfer type. How would I reference the shipment record in the code below? Thanks in advance. I understand the code below may not be accurate, but I am mostly just noodling through this as I learn much better through doing and then fixing my mistakes as I go. 

    public class SOShipmentEntry_Extension : PXGraphExtension<PX.Objects.SO.SOShipmentEntry>
{
#region Event Handlers

public PXAction<PX.Objects.SO.SOShipment> CreateTransferSO;

PXButton(CommitChanges = true)]
PXUIField(DisplayName = "Create Transfer")]
protected void createTransferSO()
{
SOOrderEntry graph = PXGraph.CreateInstance<SOOrderEntry>();

SOOrder Sorder = new SOOrder();
SOLine sOLine = new SOLine();

Sorder.OrderType = SOOrderTypeConstants.TransferOrder;

Sorder = graph.Document.Insert(Sorder);
sOLine = graph.Transactions.Insert(sOLine);

Sorder.OrderDate = DateTime.Now;
Sorder.RequestDate = DateTime.Now;
Sorder.DestinationSiteID = 900;

graph.Document.Update(Sorder);
graph.Actions.PressSave();

}

#endregion
}

Thanks,

Adam

4 replies

Userlevel 6
Badge +2

Hi @AJohnson.

You can create a shipment with a code like this:

var warehouseID = 0; // replace it with the logic which will get the real ID of a warehouse!
var shipDate = PXTimeZoneInfo.Now; // replace with your logic

graph.CreateShipmentIssue(adapter, shipDate, warehouseID);
graph.CreateShipmentReceipt(adapter, shipDate, warehouseID);

Please note that warehouseID and shipDate have no real values. They are placeholders. Usually, user sets these values in the popup dialog at the Sales Orders screen when they click the “Create Shipment” button. You will need to create a logic to find those values (you can go the same way and show a popup).

Also worth mentioning that both CreateShipmentIssue and CreateShipmentReceipt are using SOShipmentEntry.CreateShipment, which is a Base for your extension. The only reason I suggest looking at those methods in SOOrderEntry is because the SOShipmentEntry original method is a bit finicky and you can look at the SOOrderEntry example in the CodeRepository folder of your instance for reference.

You also use DateTime.Now. It’s a regular thing to use in the .Net code, however, for Acumatica, due to additional logic created in the app, you can have different time zones set in your instance.

DateTime.Now will provide you with machine time.

PXTimeZoneInfo.Now will provide you the time set in the Acumatica. graph.Accessinfo.BusinessDate is a common alternative (used even more often than the 1st option actually), but it does not provide you with time - only date. The time part is set to 12:00 AM.

Generally, we don’t create DAC instances using their constructors. We use var record = graph.View.insert(); and then fill the said record with the data.

I’d also urge you to go through the process of creating the shipment manually - most of the time, you can fill the same data in the code as you do manually in the browser to make sure it’s properly set up.

I’d also suggest that you first try to fill an order, save it, and only then proceed to the next step. This way you will ensure the order is properly set up before you add transactions/shipment records. Using your code:

var soOrder = graph.Document.Insert();

soOrder.OrderType = SOOrderTypeConstants.TransferOrder;
soOrder.OrderDate = DateTime.Now;
soOrder.RequestDate = DateTime.Now;
soOrder.DestinationSiteID = 900;

var soLine = graph.Transactions.Insert();

I didn’t have to do orders and shipments through the code, but it looks like your code is missing some key fields before this soOrder can be saved. Try to create an order manually and pay attention to the required fields - you need to set them in the code as well.

Userlevel 2
Badge

@andriitkachenko Thanks! Tips are much appreciated. Still had some things to fill in but I am actually trying to create another Sales Order of the transfer type based off a Shipment record. I’m not sure how to reference the data on the Shipment screen through my graph extension. I see the below code in the “Create Shipment” button on the sales order. Is the orderEntry variable auto populated with the data in the screen with that line? The goal is to use a shipping variable to populate my soOrder with the line-item info from the shipment. 

var orderEntry = PXGraph.CreateInstance<SOOrderEntry>();
var shipmentEntry = CreateInstance<SOShipmentEntry>();
var created = new DocumentList<SOShipment>(shipmentEntry);

Thanks,

Adam

Userlevel 6
Badge +2

Some things are auto-populated, and some aren’t. I’d check them at the debug to ensure you have all the values. I personally don’t count on it during my development,  and write additional queries to retrieve everything I need.

In your case - after you create the SOShipmentEntry instance, you need to find the SOShipment record you need to work with (you might have it in a variable already, then you can pass it using shipmentEntry.Document.Current = shipment;). The way to find it depends on your task, maybe you need to create some kind of BQL query to find it. It’s hard to say something more specific.

You can find out which view is responsible for which element on the UI using Inspect Element (in the top right corner of the page, Customisation → Inspect Element; or Ctrl+Alt+Click).

Userlevel 2
Badge

@andriitkachenko Thanks for all the tips! This definitely got me further along and answered the original question. I will make another post if I run into anything else. Much appreciated!

Reply