Skip to main content
Solved

How to populate multiple SOs on one shipment through code?

  • September 24, 2024
  • 4 replies
  • 66 views

Forum|alt.badge.img

Hello Community! I had a question on how to create a shipment with multiple SOs attached through code in a processing screen. My main processing table is SOLine and the code I am attempting is below. This is for a transfer shipment which is why I have no customer ID. The shipment gets created without issue but no line items populate. My trace shows the loop through SOShipmentPlan finding the SOs I am selecting to add but I seem to be missing something. 

 

      public static string TransferShipment(SOOrderEntry orderEntry, SOShipmentEntry shipment, List<SOLine> lines, string sOShipmentType, string operation)
      {
          PXTrace.WriteInformation("1: Building shipment");
          string shipNo = String.Empty;
          List<SOShipmentPlan> plan = new List<SOShipmentPlan>();
          PXTrace.WriteInformation("0: ");
          SOShipment trShipment = new SOShipment()
          {
              ShipmentType = sOShipmentType
          };

          trShipment = shipment.Document.Insert(trShipment);
          trShipment.SiteID = 862;
          trShipment.DestinationSiteID = 900;
          trShipment.Operation = operation;
          try
          {
              shipment.Document.Update(trShipment);
              //shipment.Actions.PressSave();
          }
          catch (Exception e)
          {
              PXFilteredProcessing<SOLine, RecertificationFilter>.SetError(e);
          }
          shipNo = shipment.Document.Current.ShipmentNbr;
          foreach (SOLine s in lines)
          {
              foreach (PXResult<SOShipmentPlan, SOLineSplit, PX.Objects.SO.SOOrderShipment, SOOrder> res in
                   PXSelectJoin<SOShipmentPlan,
                       InnerJoin<SOLineSplit,
                           On<SOLineSplit.planID, Equal<SOShipmentPlan.planID>>,
                       LeftJoin<PX.Objects.SO.SOOrderShipment,
                           On<PX.Objects.SO.SOOrderShipment.orderType, Equal<SOShipmentPlan.orderType>,
                               And<PX.Objects.SO.SOOrderShipment.orderNbr, Equal<SOShipmentPlan.orderNbr>,
                               And<PX.Objects.SO.SOOrderShipment.operation, Equal<SOLineSplit.operation>,
                               And<PX.Objects.SO.SOOrderShipment.siteID, Equal<SOShipmentPlan.siteID>,
                               And<PX.Objects.SO.SOOrderShipment.confirmed, Equal<boolFalse>,
                               And<PX.Objects.SO.SOOrderShipment.shipmentNbr, NotEqual<Current<SOShipment.shipmentNbr>>>>>>>>,
                       InnerJoin<SOOrder,
                           On<SOOrder.orderType, Equal<SOShipmentPlan.orderType>,
                               And<SOOrder.orderNbr, Equal<SOShipmentPlan.orderNbr>,
                               And<SOOrder.cancelled, Equal<boolFalse>,
                               And<SOOrder.completed, Equal<boolFalse>,
                               And<SOOrder.hold, Equal<False>,
                               And<SOOrder.creditHold, Equal<False>>>>>>>>>>,
                       Where<SOShipmentPlan.orderType, Equal<Required<SOShipmentPlan.orderType>>,
                           And<SOShipmentPlan.siteID, Equal<Current<SOShipment.siteID>>,
                           And<SOShipmentPlan.inventoryID, Equal<Required<SOLine.inventoryID>>,
                           And<SOShipmentPlan.orderNbr, Equal<Required<SOLine.orderNbr>>,
                           And<PX.Objects.SO.SOOrderShipment.shipmentNbr, IsNull,
                           And<SOLineSplit.operation, Equal<Required<SOLineSplit.operation>>
                           >>>>>>>
                       .Select(shipment, SOOrderTypeConstants.TransferOrder, s.InventoryID, sExt.UsrSOTransferNbr, operation))
              {
                  PXTrace.WriteInformation("2 (1): Searching for " + sExt.UsrSOTransferNbr + " to add to shipment.");
                  var planLine = (SOShipmentPlan)res;
                  plan.Add(planLine);
              }
          }
            foreach(SOShipmentPlan p in plan)
            {
                PXTrace.WriteInformation("3: Adding " + p.OrderNbr + " to shipment.");
                p.Selected = true;
                shipment.soshipmentplan.Update(p);

                PXTrace.WriteInformation("3.1: Saving Shipment");
                try
                {
                    shipment.addSO.Press();
                    shipment.Transactions.Update(shipment.Transactions.Current);
                }
                catch (Exception e)
                {
                    PXFilteredProcessing<SOLine, RecertificationFilter>.SetError(e);
                }
            }

            shipment.Document.Update(shipment.Document.Current);
            shipment.Actions.PressSave();
            return shipNo;
        }

I’ve gone through a few other iterations without much luck. Below is another version I did that successfully created multiple shipments for each individual sales order selected and one blank shipment for some reason. But I need them on one individual shipment.

      public static string TransferShipment(SOOrderEntry orderEntry, SOShipmentEntry shipment, List<SOLine> lines, string sOShipmentType, string operation)
      {
          PXTrace.WriteInformation("1: Building shipment");
          string shipNo = String.Empty;
          List<SOShipmentPlan> plan = new List<SOShipmentPlan>();
          PXTrace.WriteInformation("0: ");
          SOShipment trShipment = new SOShipment()
          {
              ShipmentType = sOShipmentType
          };

          trShipment = shipment.Document.Insert(trShipment);
          trShipment.SiteID = 862;
          trShipment.DestinationSiteID = 900;
          trShipment.Operation = operation;
          try
          {
              shipment.Document.Update(trShipment);
              //shipment.Actions.PressSave();
          }
          catch (Exception e)
          {
              PXFilteredProcessing<SOLine, RecertificationFilter>.SetError(e);
          }
          shipNo = shipment.Document.Current.ShipmentNbr;
            foreach (SOLine s in lines)
            {
                SOLineExt sExt = PXCache<SOLine>.GetExtension<SOLineExt>(s);
                //orderEntry.Document.Current = orderEntry.Document.Search<SOOrder.orderNbr>(s.OrderNbr, s.OrderType);
                //orderEntry.Transactions.Current = s;
                shipment.addsofilter.Cache.Clear();
                //SOLineSplit serialLine = PXSelect<SOLineSplit,
                //    Where<SOLineSplit.orderNbr, Equal<Required<SOLine.orderNbr>>,
                //    And<SOLineSplit.orderType, Equal<Required<SOLine.orderType>>,
                //    And<SOLineSplit.inventoryID, Equal<Required<SOLine.inventoryID>>,
                //    And<SOLineSplit.lineNbr, Equal<Required<SOLine.lineNbr>>>>>>>.Select(new PXGraph(), s.OrderNbr, s.OrderType, s.InventoryID, s.LineNbr);
                if (operation.Equals(SOOperation.Issue) && sOShipmentType.Equals(SOShipmentType.Transfer))
                {
                    PXTrace.WriteInformation("2 (1): Searching for " + sExt.UsrSOTransferNbr + " to add to shipment.");
                    //orderEntry.Document.Current = orderEntry.Document.Search<SOOrder.orderNbr>(sExt.UsrSOTransferNbr, SOOrderTypeConstants.TransferOrder);
                    shipment.addsofilter.Current.OrderType = SOOrderTypeConstants.TransferOrder;
                    shipment.addsofilter.Current.OrderNbr = sExt.UsrSOTransferNbr;                    
                }
                else
                {
                    PXTrace.WriteInformation("2 (2): Searching for " + s.OrderNbr + " to add to shipment.");
                    shipment.addsofilter.Current.OrderType = s.OrderType;
                    shipment.addsofilter.Current.OrderType = s.OrderNbr;
                }

                shipment.addsofilter.Current.AddAllLines = true;
                shipment.addsofilter.Update(shipment.addsofilter.Current);
                foreach (SOShipmentPlan line in shipment.soshipmentplan.Select())
                {
                    line.Selected = true;
                    shipment.soshipmentplan.Update(line);
                }
                PXTrace.WriteInformation("3.1: Saving Shipment");
                try
                {
                    shipment.addSO.Press();
                }
                catch (Exception e)
                {
                    PXFilteredProcessing<SOLine, RecertificationFilter>.SetError(e);
                }

            }
            try
            {
                trShipment = shipment.Document.Update(trShipment);
                shipment.Actions.PressSave();
            }
            catch (Exception e)
            {
                PXFilteredProcessing<SOLine, RecertificationFilter>.SetError(e);
            }

            return shipment.Document.Current.ShipmentNbr;
        }

I’ve found some articles online but most of them appear to be outdated and I didnt have much luck. Any ideas?

Thanks,

Adam

Best answer by AJohnson

@hdussa Thanks for the code there and sorry for the delay. I tried that but it didnt seem to be showing any errors or anything. I’ve had my head down working on the project and did end up coming up with a solution. Instead of using addSO() I went with the following:

 shipment.CreateShipment(new CreateShipmentArgs
 {
     MassProcess = false,
     Order = order,
     SiteID = trShipment.SiteID,
     ShipDate = trShipment.ShipDate,
     UseOptimalShipDate = false,
     Operation = operation,
     ShipmentList = shipment.addsofilter.Current.AddAllLines == true ? new DocumentList<SOShipment>(shipment) : null,
 });

This worked and combined everything into one shipment for me. Again thanks for that code though, I have that in my code as well to help trace errors during the process. 

View original
Did this topic help you find an answer to your question?

4 replies

hdussa
Jr Varsity I
Forum|alt.badge.img
  • Jr Varsity I
  • 99 replies
  • September 25, 2024

Hello @AJohnson ,

 

I suspect there may be UI errors on selecting the lines before calling “addSO.Press()”. Try calling the below function after ShipmentPlan cache update and see if it throws any errors.

protected void AssertNoErrors(PXCache cache, object current)
{
	var errors = PXUIFieldAttribute.GetErrors(cache, current);
	if (errors.Count == 0)
		return;

	throw new InvalidOperationException(string.Join("\n", errors.Select(p => p.Key + ": " + p.Value)));
}
p.Selected = true;
shipment.soshipmentplan.Update(p);
AssertNoErrors(shipment.soshipmentplan.Cache, p);

 

Hope this helps!


hdussa
Jr Varsity I
Forum|alt.badge.img
  • Jr Varsity I
  • 99 replies
  • September 26, 2024

Hi @AJohnson ,

Assuming you got a chance to try the code, let me know if it worked to figure out the issue.

Thanks!


Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • 23 replies
  • Answer
  • September 30, 2024

@hdussa Thanks for the code there and sorry for the delay. I tried that but it didnt seem to be showing any errors or anything. I’ve had my head down working on the project and did end up coming up with a solution. Instead of using addSO() I went with the following:

 shipment.CreateShipment(new CreateShipmentArgs
 {
     MassProcess = false,
     Order = order,
     SiteID = trShipment.SiteID,
     ShipDate = trShipment.ShipDate,
     UseOptimalShipDate = false,
     Operation = operation,
     ShipmentList = shipment.addsofilter.Current.AddAllLines == true ? new DocumentList<SOShipment>(shipment) : null,
 });

This worked and combined everything into one shipment for me. Again thanks for that code though, I have that in my code as well to help trace errors during the process. 


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • 2757 replies
  • September 30, 2024

Thank you for sharing your solution with the community @AJohnson!


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings