在發貨和發票中覆蓋運費金額

開箱即用 Acumatica 允許建立和維護系統中的運輸條款列表。裝運條款用於定義運輸,包裝和處理成本,具體取決於裝運量。

在此示例中,我將展示如何根據銷售訂單金額計算貨件的運費金額,這將允許使用者為每個銷售訂單建立多個貨件,並自動將相同的運輸條款應用於所有貨件。

FreightCalculator

FreightCalculator 類負責計算運費和運費條款。出於此示例的目的,我們只關注 GetFreightTerms 方法:

public class FreightCalculator
{
    ...

    protected virtual ShipTermsDetail GetFreightTerms(string shipTermsID, decimal? lineTotal)
    {
        return PXSelect<ShipTermsDetail,
            Where<ShipTermsDetail.shipTermsID, Equal<Required<SOOrder.shipTermsID>>,
            And<ShipTermsDetail.breakAmount, LessEqual<Required<SOOrder.lineTotal>>>>,
            OrderBy<Desc<ShipTermsDetail.breakAmount>>>.Select(graph, shipTermsID, lineTotal);
    }

    ...
}

無論是銷售訂單出貨量的螢幕採用 FreightCalculator 類來計算分別基於銷售訂單的出貨的量運費金額:

銷售訂單

public class SOOrderEntry : PXGraph<SOOrderEntry, SOOrder>, PXImportAttribute.IPXPrepareItems
{
    ...

    public virtual FreightCalculator CreateFreightCalculator()
    {
        return new FreightCalculator(this);
    }

    ...

    protected virtual void SOOrder_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
    {
        ...

        PXResultset<SOLine> res = Transactions.Select();
        FreightCalculator fc = CreateFreightCalculator();
        fc.CalcFreight<SOOrder, SOOrder.curyFreightCost, SOOrder.curyFreightAmt>(sender, (SOOrder)e.Row, res.Count);

        ...
    }

    ...
}

出貨量

public class SOShipmentEntry : PXGraph<SOShipmentEntry, SOShipment>
{
    ...

    protected virtual FreightCalculator CreateFreightCalculator()
    {
        return new FreightCalculator(this);
    }

    ...

    protected virtual void SOShipment_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
    {
        ...

        PXResultset<SOShipLine> res = Transactions.Select();
        ...
        FreightCalculator fc = CreateFreightCalculator();
        fc.CalcFreight<SOShipment, SOShipment.curyFreightCost, SOShipment.curyFreightAmt>(sender, (SOShipment)e.Row, res.Count);

        ...
    }

    ...
}

覆蓋運費金額

要自定義 Acumatica 如何在“ 貨件” 螢幕上計算運費金額,我將宣告從 FreightCalculator 繼承的 FreightCalculatorCst 類並覆蓋 GetFreightTerms 方法:

public class FreightCalculatorCst : FreightCalculator
{
    public FreightCalculatorCst(PXGraph graph)
        : base(graph)
    {
    }

    protected override ShipTermsDetail GetFreightTerms(string shipTermsID, decimal? lineTotal)
    {
        if (graph is SOShipmentEntry)
        {
            var shipmentEntry = graph as SOShipmentEntry;
            int orderCount = 0;
            decimal? lineTotalTemp = null;

            foreach (PXResult<SOOrderShipment, SOOrder, CurrencyInfo, SOAddress, SOContact, SOOrderType> orderRec in 
                shipmentEntry.OrderList.SelectWindowed(0, 2))
            {
                orderCount++;
                SOOrder order = (SOOrder)orderRec;
                if (orderCount == 1)
                    lineTotalTemp = order.LineTotal;
                else
                    break;
            }

            if (orderCount == 1)
            {
                lineTotal = lineTotalTemp;
            }
        }

        return base.GetFreightTerms(shipTermsID, lineTotal);
    }
}

之後,我將實施 SOShipmentEntry BLC 的擴充套件,並覆蓋 CreateFreightCalculator 方法,在發貨螢幕上用我的自定義 FreightCalculatorCst 類替換 FreightCalculator

public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
    [PXOverride]
    public FreightCalculator CreateFreightCalculator()
    {
        return new FreightCalculatorCst(Base);
    }
}

瞭解上面示例中的 FreightCalculatorCst 類的實現

在重寫的 GetFreightTerms 方法中,我將使用銷售訂單中的金額而不是裝運金額來呼叫基礎 GetFreightTerms 方法並接收裝運條款:

foreach (PXResult<SOOrderShipment, SOOrder, CurrencyInfo, SOAddress, SOContact, SOOrderType> orderRec in 
    shipmentEntry.OrderList.SelectWindowed(0, 2))
{
    orderCount++;
    SOOrder order = (SOOrder)orderRec;
    if (orderCount == 1)
        lineTotalTemp = order.LineTotal;
    else
        break;
}

if (orderCount == 1)
{
    lineTotal = lineTotalTemp;
}

顯然,只能使用銷售訂單金額來計算貨件的運費,這隻能滿足 1 個訂單。如果一批貨物滿足多個訂單,我們必須遵循基本產品行為並根據裝運量計算運費。為了檢查裝運完成的訂單數量,我在 OrderList 資料檢視中使用了 SelectWindowed 方法,並請求當前裝運完成的前 2 個訂單。我本來可以請求裝運完成的所有訂單,但這需要更多的時間來執行並返回多個記錄所需的資料,以驗證是否可以使用銷售訂單金額而不是裝運金額來計算運費。