Files
ERP-core/Frontend/erp-system/lib/po-tax.ts
T
Dhananjaya99 e7b1f270a5 feat: add vendor optional fields and configuration hooks
- Implemented VendorOptionalFields component to handle optional vendor details (mobile, email, address) with validation.
- Created useCustomerConfig hook to load optional customer field settings from Sales configuration.
- Developed useProcurementConfig hook to manage Procurement configuration flags.
- Introduced accessConfigApi for managing access configuration settings.
- Added openingBalancesApi for handling opening balances operations.
- Created procurementConfigApi for managing procurement configuration settings.
- Implemented nav-routes for permission-based routing.
- Developed PDF generation for purchase orders with dynamic vendor and item details.
- Added purchase-order tax helpers for tax calculations and formatting.
- Defined types for opening balances and related operations.
2026-10-18 12:46:31 +05:30

34 lines
1.4 KiB
TypeScript

// Purchase-order tax helpers. The UI works in percent (18 for 18%) because that is how an item's
// tax rate is stored (`taxRatePercentage`) and how people say it; the PO API carries the rate as a
// fraction 0..1 (0.18) and a stored amount. The server recomputes and stores the amount itself, so
// these figures are for display and live totals only.
/** 18 -> 0.18. Four decimals, the precision the API stores. */
export function pctToRate(pct: number): number {
if (!Number.isFinite(pct) || pct <= 0) return 0
return Math.round(pct * 100) / 10000
}
/** 0.18 -> 18. */
export function rateToPct(rate: number): number {
if (!Number.isFinite(rate) || rate <= 0) return 0
return Math.round(rate * 10000) / 100
}
/**
* Tax amount for a line: qty x unit price x pct%, rounded half-up to 2 dp like the server
* (`PurchaseOrderService.TaxAmountFor`). The epsilon keeps 1.005-style products from rounding down.
*/
export function lineTaxAmount(qty: number, unitPrice: number, pct: number): number {
const q = Number(qty)
const p = Number(unitPrice)
const t = Number(pct)
if (![q, p, t].every(Number.isFinite) || q <= 0 || p < 0 || t <= 0) return 0
return Math.round(q * p * t + 1e-9) / 100
}
/** The text of a percent for an input box: 18 -> "18", 8.25 -> "8.25", 0 -> "0". */
export function pctText(pct: number | null | undefined): string {
return pct === null || pct === undefined || !Number.isFinite(pct) ? "0" : String(pct)
}