acumatica
Расчет фрахта
Поиск…
Вступление
Acumatica ERP позволяет управлять фрахтом, чтобы лучше контролировать любые дополнительные затраты и доходы от транзакций продаж. Сумма фрахта, взимаемая с ваших клиентов, может включать в себя не только фрахт, взимаемый вашей компанией перевозчиками, но также страховые, транспортные и упаковочные сборы, определенные условиями доставки и премиальным грузом.
Переопределение суммы фрахта при отгрузке и счете-фактуре
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 рассчитывает сумму фрахта на экране « Отгрузки», я FreightCalculatorCst
класс FreightCalculatorCst
унаследованный от FreightCalculator
и переопределит метод 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);
}
}
После этого я реализую расширение для BLC SOShipmentEntry
и переопределяю метод CreateFreightCalculator
чтобы заменить FreightCalculator
своим пользовательским классом FreightCalculatorCst
на экране « Отгрузки» :
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 заказ. Если одна партия выполняет несколько заказов, нам нужно будет следить за поведением базового продукта и рассчитать сумму фрахта на основе суммы отправления. Чтобы проверить количество заказов пересылка отрабатывает, я использовал SelectWindowed
метод на OrderList
просмотра данных и просил первые 2 заказов выполняются текущей отгрузкой. Я мог бы запросить все заказы, выполненные по отгрузке, но для выполнения и возврата пути к многим записям потребуется гораздо больше времени, чем необходимо для проверки того, можно ли использовать сумму заказа клиента вместо суммы отправления для расчета фрахта.