From 3509ea9a89cb70e8f24325aa35f010a913f6be6b Mon Sep 17 00:00:00 2001 From: AbleKSaju <126228406+AbleKSaju@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:59:10 +0530 Subject: [PATCH] feat: display grand total amount in words --- src/utils/printTemplates.ts | 111 +++++++++++++++++++++++++++++++ templates/Business.template.html | 4 ++ 2 files changed, 115 insertions(+) diff --git a/src/utils/printTemplates.ts b/src/utils/printTemplates.ts index 94f63471..a2837fba 100644 --- a/src/utils/printTemplates.ts +++ b/src/utils/printTemplates.ts @@ -12,6 +12,7 @@ import { getSavePath, showExportInFolder, } from './ui'; +import { Money } from 'pesa'; export type PrintTemplateHint = { [key: string]: string | PrintTemplateHint | PrintTemplateHint[]; @@ -63,6 +64,10 @@ export async function getPrintTemplatePropValues( (values.doc as PrintTemplateData).showHSN = showHSN(doc); } + (values.doc as PrintTemplateData).grandTotalInWords = getGrandTotalInWords( + (doc.grandTotal as Money).float + ); + return values; } @@ -95,6 +100,112 @@ export function getPrintTemplatePropHints(schemaName: string, fyo: Fyo) { return hints; } +function getGrandTotalInWords(total: number) { + const formattedTotal = total.toFixed(2); + + const [integerPart, decimalPart] = formattedTotal.split('.'); + + const ones = [ + '', + t`One`, + t`Two`, + t`Three`, + t`Four`, + t`Five`, + t`Six`, + t`Seven`, + t`Eight`, + t`Nine`, + ]; + + const teens = [ + t`Ten`, + t`Eleven`, + t`Twelve`, + t`Thirteen`, + t`Fourteen`, + t`Fifteen`, + t`Sixteen`, + t`Seventeen`, + t`Eighteen`, + t`Nineteen`, + ]; + + const tens = [ + '', + '', + t`Twenty`, + t`Thirty`, + t`Forty`, + t`Fifty`, + t`Sixty`, + t`Seventy`, + t`Eighty`, + t`Ninety`, + ]; + + const scales = ['', t`Thousand`, t`Million`, t`Billion`]; + + function convertThreeDigitNumber(num: number) { + let result = ''; + + const hundredDigit = Math.floor(num / 100); + const remainder = num % 100; + + if (hundredDigit > 0) { + result += ones[hundredDigit] + ` ${t`Hundred`}`; + } + + if (remainder > 0) { + if (hundredDigit > 0) { + result += ` ${t`And`} `; + } + + if (remainder < 10) { + result += ones[remainder]; + } else if (remainder < 20) { + result += teens[remainder - 10]; + } else { + const tensDigit = Math.floor(remainder / 10); + const onesDigit = remainder % 10; + result += tens[tensDigit]; + if (onesDigit > 0) { + result += ' ' + ones[onesDigit]; + } + } + } + + return result; + } + + let spelledOutInteger = ''; + const integerGroups = integerPart.match(/(\d{1,3})(?=(\d{3})*$)/g) || []; + const groupCount = integerGroups.length; + + integerGroups.forEach((group, index) => { + const groupValue = parseInt(group); + + if (groupValue > 0) { + const groupText = convertThreeDigitNumber(groupValue); + const groupSuffix = scales[groupCount - index - 1]; + spelledOutInteger += + groupText + (groupSuffix ? ' ' + groupSuffix : '') + ' '; + } + }); + + spelledOutInteger = spelledOutInteger.trim() || t`Zero`; + + let spelledOutDecimal = ''; + const decimalCents = parseInt(decimalPart); + + if (decimalCents !== 0) { + spelledOutDecimal = + ` ${t`and`} ` + convertThreeDigitNumber(decimalCents) + ` ${t`Paisa`}`; + } + + return `${spelledOutInteger}${spelledOutDecimal} ${t`only`}`; +} + function showHSN(doc: Doc): boolean { const items = doc.items; if (!Array.isArray(items)) { diff --git a/templates/Business.template.html b/templates/Business.template.html index ae3138a0..890fa4cb 100644 --- a/templates/Business.template.html +++ b/templates/Business.template.html @@ -126,5 +126,9 @@

Notes

{{ doc.terms }}

+
+

Grand Total In Words:

+

{{doc.grandTotalInWords}}

+