Solved

How do I reference SOOrder when trying to default a field in SOShipmentEntry?

  • 19 February 2022
  • 2 replies
  • 212 views

Userlevel 5
Badge +1

I am trying to get the unpaid balance to automatically be entered by default when adding a new package on the Shipments screen.  We need to do this only for records where Payment type is COD.  How do I reference SOOrder when modifying the value in SOPackageDetailEx?

I have the following code:

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.Serialization;
using System.Text;
using PX.Data;
using PX.Data.BQL;
using PX.Data.BQL.Fluent;
using PX.Data.WorkflowAPI;
using PX.Common;
using PX.Objects.AR;
using PX.Objects.CM;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.EP;
using PX.Objects.GL;
using PX.Objects.IN;
using PX.SM;
using PX.Objects.IN.Overrides.INDocumentRelease;
using POLineType = PX.Objects.PO.POLineType;
using POReceiptLine = PX.Objects.PO.POReceiptLine;
using PX.CarrierService;
using PX.Data.DependencyInjection;
using PX.LicensePolicy;
using PX.Objects.SO.Services;
using PX.Objects.PO;
using PX.Objects.AR.MigrationMode;
using PX.Objects.Common;
using PX.Objects.Common.Discount;
using PX.Objects.Common.Extensions;
using PX.Common.Collection;
using PX.Objects.SO.GraphExtensions.CarrierRates;
using PX.Api;
using LocationStatus = PX.Objects.IN.Overrides.INDocumentRelease.LocationStatus;
using ShipmentActions = PX.Objects.SO.SOShipmentEntryActionsAttribute;
using PX.Objects;
using PX.Objects.SO;

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

protected void SOPackageDetailEx_COD_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e, PXFieldDefaulting InvokeBaseHandler)
{
if(InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (SOPackageDetailEx)e.Row;

if (row == null) return;

e.NewValue = Convert.ToDecimal(20.0); // This is a test value to be replaced by
} // SOOrder.CuryUnpaidBalance for COD payments
#endregion
}
}

Basically we just need the bit where I am inserting 20.0 to be changed to insert the value held in SOOrder.UnpaidBalance instead if SOOrder.PaymentMethodID = ‘COD’. I’m not sure how to reference SOOrder from here. I have been going through the Acumatica training regarding customizations but this is still beyond me.

 

Thanks for any help,

 

Phil

 

icon

Best answer by jinin 21 February 2022, 07:38

View original

2 replies

Userlevel 7
Badge +11

Hi @ppowell 

The unpaid balance is a calculated field on the soscreen and the value is not stored in DB. We need to write logic and get the unpaid balance.

Please try like below and check the value you are getting correctly. If not working, adjust the code based on your requirement.

        #region Event Handlers

        protected void SOPackageDetailEx_COD_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e, PXFieldDefaulting InvokeBaseHandler)
        {
            if (InvokeBaseHandler != null)
                InvokeBaseHandler(cache, e);
            var row = (SOPackageDetailEx)e.Row;
            if (row == null) return;

            SOShipLine item = Base.Transactions.Select().FirstOrDefault();
            if (item != null)
            {
                SOOrder order = PXSelect<SOOrder, Where<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>, And<SOOrder.orderType, Equal<Required<SOOrder.orderType>>>>>.Select(Base, item.OrigOrderNbr, item.OrigOrderType);
                e.NewValue = GetUnpaidBalance(order);
            }
        }
 

        public decimal? GetUnpaidBalance( SOOrder order)
        {
            decimal? creditMemo = 0;
            decimal? payment = 0;

            foreach (SOAdjust objSoadjust in PXSelectJoin<SOAdjust, InnerJoin<ARPayment, On<ARPayment.docType, Equal<SOAdjust.adjgDocType>, And<ARPayment.refNbr, Equal<SOAdjust.adjgRefNbr>>>>,
                                        Where<SOAdjust.adjdOrderNbr, Equal<Required<SOAdjust.adjdOrderNbr>>, And<SOAdjust.adjdOrderType, Equal<Required<SOAdjust.adjdOrderType>>>>>.Select(Base, order.OrderNbr, order.OrderType))
            {
                if (objSoadjust.AdjgDocType == ARDocType.Payment)
                {
                    payment += objSoadjust.CuryAdjdAmt + objSoadjust.CuryAdjdBilledAmt;
                }
                if (objSoadjust.AdjgDocType == ARDocType.CreditMemo)
                {
                    creditMemo += objSoadjust.CuryAdjdAmt + objSoadjust.CuryAdjdBilledAmt;
                }
            }

            foreach (ARAdjust objARAdjust in PXSelectJoin<ARAdjust,
                               InnerJoin<ARPayment, On<ARPayment.docType, Equal<ARAdjust.adjgDocType>, And<ARPayment.refNbr, Equal<ARAdjust.adjgRefNbr>>>,
                               InnerJoin<SOOrderShipment, On<SOOrderShipment.invoiceType, Equal<ARAdjust.adjdDocType>, And<SOOrderShipment.invoiceNbr, Equal<ARAdjust.adjdRefNbr>>>>>,
                               Where<SOOrderShipment.orderNbr, Equal<Required<SOOrderShipment.orderNbr>>, And<SOOrderShipment.orderType, Equal<Required<SOOrderShipment.orderType>>,
                               And<ARAdjust.adjdOrderNbr, IsNull, And<ARAdjust.adjdOrderType, IsNull>>>>>
                              .Select(Base, order.OrderNbr, order.OrderType))
            {

                if (objARAdjust.AdjgDocType == ARDocType.Payment)
                {
                    payment += objARAdjust.CuryAdjdAmt;
                }
                if (objARAdjust.AdjgDocType == ARDocType.CreditMemo)
                {
                    creditMemo += objARAdjust.CuryAdjdAmt;
                }
            }

            return order.OrderTotal - creditMemo - payment;
        }

        #endregion

Userlevel 5
Badge +1

I am trying to get the unpaid balance to automatically be entered by default when adding a new package on the Shipments screen.  We need to do this only for records where Payment type is COD.  How do I reference SOOrder when modifying the value in SOPackageDetailEx?

I have the following code:

<Code snipped>

Basically we just need the bit where I am inserting 20.0 to be changed to insert the value held in SOOrder.UnpaidBalance instead if SOOrder.PaymentMethodID = ‘COD’. I’m not sure how to reference SOOrder from here. I have been going through the Acumatica training regarding customizations but this is still beyond me.

 

Thanks for any help,

 

Phil

 

Hi @ppowell 

The unpaid balance is a calculated field on the soscreen and the value is not stored in DB. We need to write logic and get the unpaid balance.

Please try like below and check the value you are getting correctly. If not working, adjust the code based on your requirement.

        #region Event Handlers

        protected void SOPackageDetailEx_COD_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e, PXFieldDefaulting InvokeBaseHandler)
        {
            if (InvokeBaseHandler != null)
                InvokeBaseHandler(cache, e);
            var row = (SOPackageDetailEx)e.Row;
            if (row == null) return;

            SOShipLine item = Base.Transactions.Select().FirstOrDefault();
            if (item != null)
            {
                SOOrder order = PXSelect<SOOrder, Where<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>, And<SOOrder.orderType, Equal<Required<SOOrder.orderType>>>>>.Select(Base, item.OrigOrderNbr, item.OrigOrderType);
                e.NewValue = GetUnpaidBalance(order);
            }
        }
 

        public decimal? GetUnpaidBalance( SOOrder order)
        {
            decimal? creditMemo = 0;
            decimal? payment = 0;

            foreach (SOAdjust objSoadjust in PXSelectJoin<SOAdjust, InnerJoin<ARPayment, On<ARPayment.docType, Equal<SOAdjust.adjgDocType>, And<ARPayment.refNbr, Equal<SOAdjust.adjgRefNbr>>>>,
                                        Where<SOAdjust.adjdOrderNbr, Equal<Required<SOAdjust.adjdOrderNbr>>, And<SOAdjust.adjdOrderType, Equal<Required<SOAdjust.adjdOrderType>>>>>.Select(Base, order.OrderNbr, order.OrderType))
            {
                if (objSoadjust.AdjgDocType == ARDocType.Payment)
                {
                    payment += objSoadjust.CuryAdjdAmt + objSoadjust.CuryAdjdBilledAmt;
                }
                if (objSoadjust.AdjgDocType == ARDocType.CreditMemo)
                {
                    creditMemo += objSoadjust.CuryAdjdAmt + objSoadjust.CuryAdjdBilledAmt;
                }
            }

            foreach (ARAdjust objARAdjust in PXSelectJoin<ARAdjust,
                               InnerJoin<ARPayment, On<ARPayment.docType, Equal<ARAdjust.adjgDocType>, And<ARPayment.refNbr, Equal<ARAdjust.adjgRefNbr>>>,
                               InnerJoin<SOOrderShipment, On<SOOrderShipment.invoiceType, Equal<ARAdjust.adjdDocType>, And<SOOrderShipment.invoiceNbr, Equal<ARAdjust.adjdRefNbr>>>>>,
                               Where<SOOrderShipment.orderNbr, Equal<Required<SOOrderShipment.orderNbr>>, And<SOOrderShipment.orderType, Equal<Required<SOOrderShipment.orderType>>,
                               And<ARAdjust.adjdOrderNbr, IsNull, And<ARAdjust.adjdOrderType, IsNull>>>>>
                              .Select(Base, order.OrderNbr, order.OrderType))
            {

                if (objARAdjust.AdjgDocType == ARDocType.Payment)
                {
                    payment += objARAdjust.CuryAdjdAmt;
                }
                if (objARAdjust.AdjgDocType == ARDocType.CreditMemo)
                {
                    creditMemo += objARAdjust.CuryAdjdAmt;
                }
            }

            return order.OrderTotal - creditMemo - payment;
        }

        #endregion

I was struggling to see how to get this to work and didn’t really understand how to use PXSelect but this really clarifies things.  It’s really helped to be able to work through the code and break it down to understand how to do this in future.

I really appreciate it,

 

Phil

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved