Tom Butcher 1f679825df Add tax calculation helpers and integrate into existing schemas
This commit introduces a new `tax.js` module containing functions for tax rate resolution and amount calculation with tax. The `amountWithTax` and `resolveTaxRate` functions are integrated into various schemas, including `invoice`, `orderitem`, `shipment`, `courierservice`, `filament`, `part`, and `product`, enhancing their ability to compute amounts with applicable taxes. Additionally, corresponding tests are added to ensure the correctness of the new tax-related functionalities.
2026-09-01 17:39:12 +01:00

55 lines
1.4 KiB
JavaScript

/**
* Tax calculation helpers mirroring farmcontrol-ui model value functions.
*/
export function isPopulatedTaxRate(taxRate) {
return taxRate != null && taxRate.rateType != null;
}
export async function resolveTaxRate(taxRateRef, getObject, taxRateModel) {
if (!taxRateRef) {
return null;
}
if (isPopulatedTaxRate(taxRateRef)) {
return taxRateRef;
}
const id = taxRateRef._id ?? taxRateRef;
if (!id) {
return null;
}
if (
typeof taxRateRef === 'object' &&
taxRateRef._id &&
Object.keys(taxRateRef).length === 1
) {
return await getObject({ model: taxRateModel, id, cached: true });
}
return await getObject({ model: taxRateModel, id, cached: true });
}
export function amountWithTax(amount, taxRate) {
const base = Number.parseFloat(amount) || 0;
if (!base) {
return 0;
}
if (!taxRate) {
return Number.parseFloat(base.toFixed(2));
}
const rate = Number.parseFloat(taxRate.rate) || 0;
if (taxRate.rateType === 'percentage') {
return Number.parseFloat((base * (1 + rate / 100)).toFixed(2));
}
if (taxRate.rateType === 'amount' || taxRate.rateType === 'fixed') {
return Number.parseFloat((base + rate).toFixed(2));
}
return Number.parseFloat(base.toFixed(2));
}
export function effectiveMarginPrice({ priceMode, price, cost, margin }) {
if (priceMode === 'margin' && margin != null && cost != null) {
return cost * (1 + margin / 100);
}
return price;
}