acumatica
Cálculo de fletes
Buscar..
Introducción
Acumatica ERP le permite administrar el flete para controlar mejor los costos e ingresos adicionales en las transacciones de ventas. La cantidad de flete que cobra a sus clientes puede incluir no solo el flete que su compañía cobra a los transportistas, sino también las tarifas de seguro, manejo y embalaje definidas por sus términos de envío y flete premium.
Monto de flete anulado en el envío y la factura
Fuera de la caja, Acumatica permite crear y mantener la lista de términos de envío en el sistema. Los términos de envío se utilizan para definir los costos de envío, embalaje y manejo, según el monto del envío.
En este ejemplo, mostraré cómo calcular el monto de flete para un envío según el monto de la orden de venta, lo que permitiría a los usuarios crear múltiples envíos por orden de venta con los mismos términos de envío que se aplican automáticamente a todos los envíos.
FreightCalculator
La clase FreightCalculator
es responsable del cálculo del costo de flete y los términos de flete. A los efectos de este ejemplo, nuestro interés se centrará únicamente en el método 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);
}
...
}
Tanto las pantallas de pedidos de venta como las de envío utilizan la clase FreightCalculator
para calcular el monto de flete según el monto del pedido de venta y del envío, respectivamente:
Ordenes de venta
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);
...
}
...
}
Envíos
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);
...
}
...
}
Importe de flete anulado
Para personalizar cómo Acumatica calcula el monto del flete en la pantalla Envíos , declararé la clase FreightCalculatorCst
heredada de FreightCalculator
y GetFreightTerms
método 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);
}
}
Después de eso, implementaré una extensión para el BLC de SOShipmentEntry
y CreateFreightCalculator
método CreateFreightCalculator
para reemplazar FreightCalculator
con mi clase personalizada FreightCalculatorCst
en la pantalla de Envíos :
public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
[PXOverride]
public FreightCalculator CreateFreightCalculator()
{
return new FreightCalculatorCst(Base);
}
}
Comprensión de la implementación de la clase FreightCalculatorCst en el ejemplo anterior
En el método GetFreightTerms
anulado, GetFreightTerms
monto del pedido de venta en lugar del monto del envío para invocar el método GetFreightTerms
básico y recibiré los términos del envío:
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;
}
Obviamente, solo es posible utilizar el importe del pedido de ventas para calcular el importe del flete para los envíos, que solo cumplen 1 pedido. Si un envío cumple con varios pedidos, tendríamos que seguir el comportamiento del producto base y calcular el monto de flete según el monto del envío. Para verificar el número de pedidos que cumple el envío, SelectWindowed
método SelectWindowed
en la vista de datos de OrderList
y OrderList
los primeros 2 pedidos realizados por el envío actual. Podría haber solicitado todos los pedidos cumplidos por el envío, pero esto llevaría mucho más tiempo para ejecutar y devolver muchos registros de los necesarios para verificar si se puede usar el monto del pedido de venta en lugar del monto del envío para calcular el flete.