lbx-invoice
Version:
Provides functionality around generating invoices.
116 lines (107 loc) • 5.59 kB
text/typescript
import { BigNumber, BigNumberUtilities } from './big-number.utilities';
import { BaseInvoice, InvoiceItem, Vat } from '../models';
/**
* Provides functionality around calculating invoices/prices.
*/
export abstract class InvoiceCalcUtilities {
/**
* Gets the total price of an item before tax.
* @param item - The invoice item to get the price from.
* @returns The amount of the item times its price.
*/
static getItemTotalPriceBeforeTax(item: InvoiceItem): BigNumber {
return BigNumberUtilities.multiply(item.amount, item.price);
}
/**
* Gets the total price of an item after tax.
* @param item - The invoice item to get the price from.
* @returns The total price before tax times 1 + tax/100.
*/
static getItemTotalPriceAfterTax(item: InvoiceItem): BigNumber {
const itemTotalBeforeTax: BigNumber = InvoiceCalcUtilities.getItemTotalPriceBeforeTax(item);
const taxMultiplier: BigNumber = BigNumberUtilities.add(1, BigNumberUtilities.divide(item.vat.rate, 100));
return BigNumberUtilities.multiply(itemTotalBeforeTax, taxMultiplier);
}
/**
* Gets the total tax for the given item.
* @param item - The item to get the total tax from.
* @returns The total price before tax times tax/100.
*/
static getItemTotalTax(item: InvoiceItem): BigNumber {
const itemTotalBeforeTax: BigNumber = InvoiceCalcUtilities.getItemTotalPriceBeforeTax(item);
return BigNumberUtilities.multiply(itemTotalBeforeTax, BigNumberUtilities.divide(item.vat.rate, 100));
}
/**
* Gets the total price of an invoice before tax.
* @param invoice - The invoice to get the price from.
* @returns The addition of the total price before tax of all items in the invoice. If this would be negative this returns 0.
*/
static getTotalBeforeTax<Invoice extends BaseInvoice>(invoice: Invoice): BigNumber {
let res: BigNumber = BigNumberUtilities.new(0);
for (const item of invoice.items) {
res = BigNumberUtilities.add(res, InvoiceCalcUtilities.getItemTotalPriceBeforeTax(item));
}
return res.lt(0) ? BigNumberUtilities.new(0) : res;
}
/**
* Gets the total price of an invoice after tax.
* @param invoice - The invoice to get the price from.
* @returns The addition of the total price before tax and the total tax of the invoice.
*/
static getTotalAfterTax<Invoice extends BaseInvoice>(invoice: Invoice): BigNumber {
const totalBeforeTax: BigNumber = InvoiceCalcUtilities.getTotalBeforeTax(invoice);
const totalTax: BigNumber = InvoiceCalcUtilities.getTotalTax(invoice);
return BigNumberUtilities.add(totalBeforeTax, totalTax);
}
/**
* Gets the total tax of the invoice.
* @param invoice - The invoice to get the total tax from.
* @returns The addition of the tax of all items of the invoice.
*/
static getTotalTax<Invoice extends BaseInvoice>(invoice: Invoice): BigNumber {
let res: BigNumber = BigNumberUtilities.new(0);
for (const item of invoice.items) {
res = BigNumberUtilities.add(res, InvoiceCalcUtilities.getItemTotalTax(item));
}
return res;
}
/**
* Gets the total tax for a specific tax group (eg. 19%).
* @param invoice - The invoice to get the total tax from.
* @param group - The tax group for which the total tax should be calculated.
* @param groupOnlyByRate - Whether or not VAT groups are only determined by rate and not by category code.
* @returns The addition of the tax of all items that are in the provided tax group.
*/
static getTotalTaxForTaxGroup<Invoice extends BaseInvoice>(invoice: Invoice, group: Vat, groupOnlyByRate: boolean): BigNumber {
const itemsInTaxGroup: InvoiceItem[] = this.getItemsForTaxGroup(invoice, group, groupOnlyByRate);
let res: BigNumber = BigNumberUtilities.new(0);
for (const item of itemsInTaxGroup) {
res = BigNumberUtilities.add(res, InvoiceCalcUtilities.getItemTotalTax(item));
}
return res;
}
/**
* Gets the total price of an invoice before tax.
* @param invoice - The invoice to get the price from.
* @param group - The tax group to get the total before from.
* @param groupOnlyByRate - Whether or not VAT groups are only determined by rate and not by category code.
* @returns The addition of the total price before tax of all items in the invoice. If this would be negative this returns 0.
*/
static getTotalBeforeTaxForTaxGroup<Invoice extends BaseInvoice>(invoice: Invoice, group: Vat, groupOnlyByRate: boolean): BigNumber {
const itemsInTaxGroup: InvoiceItem[] = this.getItemsForTaxGroup(invoice, group, groupOnlyByRate);
let res: BigNumber = BigNumberUtilities.new(0);
for (const item of itemsInTaxGroup) {
res = BigNumberUtilities.add(res, InvoiceCalcUtilities.getItemTotalPriceBeforeTax(item));
}
return res.lt(0) ? BigNumberUtilities.new(0) : res;
}
private static getItemsForTaxGroup<Invoice extends BaseInvoice>(invoice: Invoice, group: Vat, groupOnlyByRate: boolean): InvoiceItem[] {
const itemsInTaxGroup: InvoiceItem[] = invoice.items.filter(item => {
if (groupOnlyByRate) {
return item.vat.rate === group.rate;
}
return item.vat.categoryCode === group.categoryCode && item.vat.rate === group.rate;
});
return itemsInTaxGroup;
}
}