在发货和发票中覆盖运费金额
开箱即用 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 个订单。我本来可以请求装运完成的所有订单,但这需要更多的时间来执行并返回多个记录所需的数据,以验证是否可以使用销售订单金额而不是装运金额来计算运费。