Поиск…


Вступление

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 заказов выполняются текущей отгрузкой. Я мог бы запросить все заказы, выполненные по отгрузке, но для выполнения и возврата пути к многим записям потребуется гораздо больше времени, чем необходимо для проверки того, можно ли использовать сумму заказа клиента вместо суммы отправления для расчета фрахта.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow