acumatica
Fraktberäkning
Sök…
Introduktion
Med Acumatica ERP kan du hantera frakt för att bättre kontrollera eventuella extra kostnader och intäkter på försäljningstransaktioner. Fraktbeloppet du debiterar dina kunder kan innehålla inte bara den frakt som ditt företag debiteras av transportörer, utan också försäkrings-, hanterings- och förpackningsavgifter definierade av dina leveransvillkor och premiumfrakt.
Överträffar fraktbelopp vid leverans och faktura
Acumatica gör det möjligt att skapa och underhålla listan över leveransvillkor i systemet. Fraktvillkor används för att definiera leverans-, förpacknings- och hanteringskostnader, beroende på leveransbeloppet.
I det här exemplet kommer jag att visa hur man beräknar fraktbeloppet för en sändning baserat på försäljningsorderbeloppet, vilket gör det möjligt för användare att skapa flera transporter per försäljningsorder med samma leveransvillkor som automatiskt tillämpas på alla leveranser.
FreightCalculator
FreightCalculator
klassen ansvarar för beräkningen av fraktkostnader och fraktvillkor. I det här exemplet syftar vårt intresse endast till GetFreightTerms
metoden:
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);
}
...
}
Både försäljningsorder och sändningsskärmar använder FreightCalculator
klassen för att beräkna fraktbelopp baserat på försäljningsorder respektive leveransbelopp:
Försäljningsorder
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);
...
}
...
}
transporter
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);
...
}
...
}
Överväga godsbelopp
För att anpassa hur Acumatica beräknar fraktbeloppet på skärmen Sändningar kommer jag att förklara FreightCalculatorCst
klass som ärvts från FreightCalculator
och åsidosätter GetFreightTerms
metoden:
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);
}
}
Efter det kommer jag att implementera en anknytning för SOShipmentEntry
BLC och åsidosätta metoden CreateFreightCalculator
för att ersätta FreightCalculator
med min anpassade FreightCalculatorCst
klass på skärmen Sändningar :
public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
[PXOverride]
public FreightCalculator CreateFreightCalculator()
{
return new FreightCalculatorCst(Base);
}
}
Förstå implementeringen av FreightCalculatorCst-klassen i exemplet ovan
I den åsidosatta GetFreightTerms
metoden kommer jag att använda belopp från försäljningsorder istället för leveransbelopp för att åberopa bas GetFreightTerms
metoden och få leveransvillkor:
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;
}
Uppenbarligen är det bara möjligt att använda försäljningsorder för att beräkna fraktbeloppet för leveranser, som bara uppfyller en beställning. Om en sändning uppfyller flera beställningar, måste vi följa basproduktens beteende och beräkna fraktbeloppet baserat på leveransbeloppet. För att kontrollera antalet beställningar som sändningen uppfyller, använde SelectWindowed
metoden SelectWindowed
i OrderList
och begärde de första två beställningarna som uppfylldes av den aktuella sändningen. Jag kunde ha begärt alla beställningar som har utförts av leveransen, men det skulle ta betydligt mer tid att utföra och återgå till många poster än vad som behövs för att kontrollera om försäljningsorderbeloppet kan användas istället för leveransbeloppet för att beräkna frakt.