Skip to main content
Question

SOOrderEntry CreateShipmentIssue fails with CuryID cannot be empty

  • July 13, 2026
  • 5 replies
  • 78 views

Forum|alt.badge.img+1

I’m trying to programatically created Sales Shipments: given a despatch message from the third-party warehouse, I locate the sales order and then use CreateShipmentIssue to construct the shipment.

This works fine when I run the action as a user. But fails every time when running as a Process via the automation scheduler.

My code simplifies to:

orderGraph.Clear();
orderGraph.Document.Current = PXSelect<SOOrder,Where<SOOrder.orderNbr,Equal<Required<SOOrder.orderNbr>>>>.Select(orderGraph, orderNbr);

PXAdapter adapter = new PXAdapter(PXView.Dummy.For<SOOrder>(orderGraph)) { AllowRedirect = false, MassProcess = false };
var orders = orderGraph.CreateShipmentIssue(adapter, receivedItem.ShippedDate, siteID, DateTime.UtcNow);

The error is:

PX.Data.PXRowPersistingException: Error: 'CuryID' cannot be empty.
   at PX.Data.PXDefaultAttribute.RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
   at PX.Data.PXCache.AttributeHandlersSquasher`1.<>c__DisplayClass2_0`1.<To>b__0(PXCache cache, TArgs args)
   at PX.Data.PXCache.OnRowPersisting(Object item, PXDBOperation operation)
   at PX.Data.PXCache`1.PersistInserted(Object row, Boolean bypassInterceptor)
   at PX.Data.PXCache`1.Persist(PXDBOperation operation)
..

   at Wrapper.PX.Objects.SO.Cst_SOOrderEntry.CreateShipment(PXAdapter adapter, Nullable`1 shipDate, Nullable`1 siteID, Nullable`1 endDate, String operation)
   at PX.Objects.SO.SOOrderEntry.CreateShipmentIssue(PXAdapter adapter, Nullable`1 shipDate, Nullable`1 siteID, Nullable`1 endDate)
 

 

What might I have missed? (I know that when the process runs it’s as the admin user and the Branch won’t get set from the user default, but surely the Branch would be taken from the Sales Order?)

5 replies

Forum|alt.badge.img+1
  • Semi-Pro II
  • July 13, 2026

Hello ​@allisterchambers48 ,

Recommended Code Fix
To resolve this, you must explicitly set the graph's branch context to match the branch of the Sales Order before calling the shipment creation logic.
 


orderGraph.Clear();
// Select the Sales Order
SOOrder order = PXSelect<SOOrder, Where<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>>>.Select(orderGraph, orderNbr);
orderGraph.Document.Current = order;

// EXPLICIT FIX: Set the session branch ID in the graph context to match the order
if (order != null)
{
orderGraph.AccessInfo.BranchID = order.BranchID;
}

PXAdapter adapter = new PXAdapter(PXView.Dummy.For<SOOrder>(orderGraph)) { AllowRedirect = false, MassProcess = false };
var orders = orderGraph.CreateShipmentIssue(adapter, receivedItem.ShippedDate, siteID, DateTime.UtcNow);

Additional Troubleshooting Steps

  • Assign a Default Branch to the Admin user to ensure scheduled processes have a valid branch context.
  • Verify that the selected Branch has a Base Currency configured (if Multi-Currency Accounting is enabled).
  • Confirm that the Customer has a default Currency ID configured on the Financial tab.

Forum|alt.badge.img+1

Simply setting BranchID hasn’t resolved it.

Will try again with:

PX.Objects.GL.Branch branch = PX.Objects.GL.Branch.PK.Find(orderGraph, current.BranchID);

orderGraph.Accessinfo.BranchID = current.BranchID;
orderGraph.Accessinfo.BaseCuryID = branch.BaseCuryID;

 


Forum|alt.badge.img+1

Even setting Accessinfo didn’t suffice.

I also needed to set CuryID and CuryInfoID from both RowInserting<SOShipment>() and RowPersisting<SOShipment>()

It feels like I missed the simple solution somewhere as it seems that it shouldn’t need to be quite so hacky.


arpine08
Jr Varsity I
Forum|alt.badge.img+1
  • Jr Varsity I
  • July 15, 2026

Hi @allisterchambers48,

I tested your initial code through an Automation Schedule configured for my custom screen with several orders, and the shipments were created successfully (2025 R2).

I also tested CreateShipmentIssue using a different PXAdapter implementation, as well as a direct call to CreateShipmentExtension.CreateShipment, but I could not reproduce the issue.

The problem may be related to another part of the customization rather than the shipment creation logic itself, or to the graph state prior to shipment creation.

 public virtual void CreateShipmentIssue(string orderType, string orderNbr, int? siteID,  DateTime? shipDate)
{
SOOrderEntry orderGraph = PXGraph.CreateInstance<SOOrderEntry>();
orderGraph.Clear(PXClearOption.ClearAll);

SOOrder order = orderGraph.Document.Current = orderGraph.Document.Search<SOOrder.orderNbr>(orderNbr, orderType);
if (order == null)
{
return;
}

PXAdapter adapter = new PXAdapter(orderGraph.CurrentDocument)
{
AllowRedirect = false,
MassProcess = false
};

PXTrace.WriteInformation(
"Invoking CreateShipmentIssue. " +
"OrderType={0}, OrderNbr={1}, BranchID={2}, " +
"CuryID={3}, SiteID={4}, ShipDate={5}",
order.OrderType,
order.OrderNbr,
order.BranchID,
order.CuryID,
siteID,
shipDate);

orderGraph.CreateShipmentIssue(adapter, shipDate, siteID, DateTime.UtcNow);
}
 public virtual void CreateShipment(string orderType, string orderNbr, int? siteID, DateTime? shipDate)
{
SOOrderEntry soOrderEntry = PXGraph.CreateInstance<SOOrderEntry>();
SOShipmentEntry shipmentEntry = PXGraph.CreateInstance<SOShipmentEntry>();
DocumentList<SOShipment> createdShipments = new DocumentList<SOShipment>(shipmentEntry);

soOrderEntry.Clear(PXClearOption.ClearAll);
shipmentEntry.Clear(PXClearOption.ClearAll);

SOOrder order = soOrderEntry.Document.Current = soOrderEntry.Document.Search<SOOrder.orderNbr>(orderNbr, orderType);
if (order != null)
{
shipmentEntry.GetExtension<CreateShipmentExtension>().CreateShipment(new CreateShipmentArgs
{
Graph = soOrderEntry,
MassProcess = false,
Order = order,
SiteID = siteID,
ShipDate = shipDate,
UseOptimalShipDate = false,
Operation = SOOperation.Issue,
ShipmentList = createdShipments,
QuickProcessFlow = PXQuickProcess.ActionFlow.NoFlow,
});
}

}

 


Forum|alt.badge.img+1

Thanks ​@arpine08 and ​@Vard03.

I don’t have time to try out these other suggestions. I’ll have to live with the ugly code I’ve got.