export interface ReverseCalculationInput { total: number; qty: number; discount: number; overallDiscount: number; totalTaxRate: number; isIndependentTax: boolean; } export interface TaxTotalOptions { includeTaxInTotal: boolean; } export declare class TransactionCalculationEngine { /** * Summarizes a taxes array. * * Supported row shapes (case-tolerant): * - `{ Amt: number }` (preferred for totals) * - `{ Rate: number }` (preferred for reverse calc if Amt not present) */ static getTaxesSummary(taxes: any): { taxAmount: number; taxRate: number; }; static sumTaxAmountFromRows(rows: unknown): number; static calculateTotalFromTaxRows(input: { baseAmount: number; taxRows: unknown; options: TaxTotalOptions; }): number; static calculateSubtotalFromTotalUsingTaxes(input: { total: number; taxRows: unknown; includeTaxInTotal: boolean; qty?: number; }): number; static reverseCalculateAmountAndUnitPriceFromTotal(input: { qty: number; total: number; disc: number; perc?: string; recDisc: number; noDisc: boolean; taxRows: unknown; includeTaxInTotal: boolean; }): { amount: number; unitPrice: number; }; static calculatePriceFromTotal(input: ReverseCalculationInput): number; /** * Returns the sum of all component rates for a tax code id. * * Safe for missing inputs: * - empty TaxCodes * - TCode not found * - empty Components */ static getGSTRateSumByTaxCode(TCode: any, TaxCodes: any[]): number; /** * Calculates the raw base amount for an item: * unAmt = qty * unpr * * Returns a shallow copy of the item with `unAmt` set. */ static calculateItemAmount(item: any): any; /** * Calculates the item-level (record-level) discount applied to a single item. * * Rules: * - If `NoDisc` is true → recDisc = 0 * - Else if `perc` exists → recDisc = qty * unpr * (perc / 100) * - Else → recDisc = disc (flat amount) * * Returns a shallow copy of the item with `recDisc` set. */ static calculateItemDiscount(item: any): any; /** * Calculates subtotal, tax amount, and total for an item using forward logic * (price/qty → total). * * subtotal = (qty * unpr) − recDisc * taxAmount = subtotal * (tax / 100) * total = subtotal + taxAmount * * Returns a shallow copy of the item with `subtotal`, `taxAmount`, and * `total` set. */ static calculateItemForwardTotal(item: any): any; /** * Calculates subtotal, taxAmount, and total for an item using a `Taxes` array. * * Rules: * - subtotal = (qty * unpr) − recDisc * - taxAmount = Σ Taxes[].Amt (if missing/0, falls back to Σ Taxes[].Rate %) * - total = subtotal + taxAmount (when includeTaxInTotal = true) * * Notes: * - If you want a "pre-tax total" line, pass includeTaxInTotal = false. */ static calculateItemForwardTotalUsingTaxes(item: any, options?: { includeTaxInTotal?: boolean; }): any; /** * Reverse-calculates `unpr` from a manually entered `total`. * * Steps: * subtotal = total / (1 + tax / 100) [strips tax] * baseAmt = subtotal + recDisc [adds back discount] * unpr = baseAmt / qty [per-unit price] * * Guards: * - If `qty` is 0 the calculation is skipped and the item is returned unchanged. * - If `tax` is 0 the divisor reduces to 1 (safe). * * Returns a shallow copy of the item with `unpr` (and derived `unAmt`) updated. */ static calculateReverseFromTotal(item: any): any; /** * Reverse-calculates `unpr` from a manually entered `total`, supporting the * same `disc`/`perc` semantics as `calculateItemDiscount`. * * This is intentionally tolerant of existing calling conventions: * - `item.extraDisc` can be provided to represent an additional discount * amount that should be added on top of the row discount (e.g. overall / * record-level discount allocation). It is ignored when `NoDisc` is true. * - When `tax` is 0, tax stripping becomes a no-op. * * Returns a shallow copy of the item with `unpr`, `unAmt`, and `recDisc` set. */ static calculateReverseFromTotalUsingDiscPerc(item: any): any; /** * Reverse-calculates `unpr` from a manually entered `total` using a `Taxes` array. * * When taxes contain `Amt` rows, the reverse "strips tax" by subtracting the * summed tax amount. If tax `Amt` is 0/missing, it falls back to stripping by * summed tax `Rate` (same as `calculateReverseFromTotalUsingDiscPerc`). * * Inputs: * - qty, total, disc, perc, extraDisc, NoDisc * - Taxes: array of `{ Amt?, Rate? }` */ static calculateReverseFromTotalUsingDiscPercAndTaxes(item: any, options?: { includeTaxInTotal?: boolean; }): any; /** * Applies an item-only discount (`PDisc` / `PPerc`) to an array of items. * * Rules: * - Items with `NoDisc = true` are skipped. * - If `PPerc` is provided: each item's share = its netAmt * (PPerc / 100) * - Otherwise: `PDisc` is distributed proportionally by each item's `unAmt`. * * The `recDisc` on each item is **added to** any existing item-level discount * so that both record-level and overall PDisc coexist correctly. * * Returns a new array of updated item objects. */ static applyPDiscountToItems(items: any[], PDisc: any, PPerc: any): any[]; /** * Applies an ops-only discount (`LDisc` / `LPerc`) to an array of ops. * * Rules: * - If `LPerc` is provided: each op's share = its `amount` * (LPerc / 100) * - Otherwise: `LDisc` is distributed proportionally by each op's `amount`. * * Returns a new array of updated ops objects. */ static applyLDiscountToOps(ops: any[], LDisc: any, LPerc: any): any[]; /** * Applies a cross-line discount (`Disc` / `Prec`) proportionally across * both items and ops. * * Rules: * - Items with `NoDisc = true` are excluded from the base but returned unchanged. * - If `Prec` is provided: share = row's base * (Prec / 100) * - Otherwise: `Disc` is distributed proportionally across the combined base * (items by `unAmt`, ops by `amount`). * * Returns `{ items, ops }` with updated `recDisc` values. */ static applyCommonDiscount(items: any[], ops: any[], Disc: any, Prec: any): { items: any[]; ops: any[]; }; /** * Orchestration method that applies all transaction-level discounts in the * correct order: * * 1. applyPDiscountToItems (PDisc / PPerc) * 2. applyLDiscountToOps (LDisc / LPerc) * 3. applyCommonDiscount (Disc / Prec) * * The `recDisc` on each line starts fresh from its item-level discount * (already computed by `calculateItemDiscount`) before overall discounts * are stacked on top. * * Returns `{ items, ops }`. */ static distributeRecordDiscount(items: any[], ops: any[], transaction: any): { items: any[]; ops: any[]; }; /** * Master recalculation method. * * Call whenever any value in the transaction changes: * qty | unpr | disc | perc | tax | PDisc | PPerc | LDisc | LPerc | Disc | Prec * or when items / ops are added or removed. * * Processing pipeline: * For each item: * a. calculateItemAmount → unAmt * b. calculateItemDiscount → item-level recDisc * → distributeRecordDiscount → stacks overall discounts onto recDisc * For each item: * c. calculateItemForwardTotal → subtotal, taxAmount, total * For each op: * d. recalculate op total → amount − recDisc * → computeTransactionTotals → subTotal, taxTotal, grandTotal * * Returns a new transaction object (shallow-copied) with updated * `Items`, `Ops`, and summary totals (`SubTotal`, `TaxTotal`, `Total`). * * The original transaction object is never mutated. * * ⚠️ When writing results back to Reactive Form controls always use * `{ emitEvent: false }` to prevent triggering another recalculation. */ static recalculateTransaction(transaction: any): any; /** * Computes summary totals from already-calculated items and ops. * * subTotal = Σ item.subtotal + Σ op.total * taxTotal = Σ item.taxAmount * grandTotal = subTotal + taxTotal * * Returns `{ subTotal, taxTotal, grandTotal }`. */ static computeTransactionTotals(items: any[], ops: any[]): { subTotal: number; taxTotal: number; grandTotal: number; }; }