mirror of
https://github.com/frappe/books.git
synced 2024-11-14 09:24:04 +00:00
Merge pull request #974 from AbleKSaju/feat-grandtotal-in-words
feat: display grand total amount in words
This commit is contained in:
commit
cb48742d63
@ -11,5 +11,6 @@ export class PrintSettings extends Doc {
|
|||||||
color?: string;
|
color?: string;
|
||||||
font?: string;
|
font?: string;
|
||||||
displayLogo?: boolean;
|
displayLogo?: boolean;
|
||||||
|
amountInWords?: boolean;
|
||||||
override hidden: HiddenMap = {};
|
override hidden: HiddenMap = {};
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,12 @@
|
|||||||
"label": "Display Logo in Invoice",
|
"label": "Display Logo in Invoice",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"section": "Customizations"
|
"section": "Customizations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "amountInWords",
|
||||||
|
"label": "Display Amount In Words",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"section": "Customizations"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
getSavePath,
|
getSavePath,
|
||||||
showExportInFolder,
|
showExportInFolder,
|
||||||
} from './ui';
|
} from './ui';
|
||||||
|
import { Money } from 'pesa';
|
||||||
|
|
||||||
export type PrintTemplateHint = {
|
export type PrintTemplateHint = {
|
||||||
[key: string]: string | PrintTemplateHint | PrintTemplateHint[];
|
[key: string]: string | PrintTemplateHint | PrintTemplateHint[];
|
||||||
@ -28,6 +29,7 @@ const printSettingsFields = [
|
|||||||
'phone',
|
'phone',
|
||||||
'address',
|
'address',
|
||||||
'companyName',
|
'companyName',
|
||||||
|
'amountInWords',
|
||||||
];
|
];
|
||||||
const accountingSettingsFields = ['gstin', 'taxId'];
|
const accountingSettingsFields = ['gstin', 'taxId'];
|
||||||
|
|
||||||
@ -63,6 +65,10 @@ export async function getPrintTemplatePropValues(
|
|||||||
(values.doc as PrintTemplateData).showHSN = showHSN(doc);
|
(values.doc as PrintTemplateData).showHSN = showHSN(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(values.doc as PrintTemplateData).grandTotalInWords = getGrandTotalInWords(
|
||||||
|
(doc.grandTotal as Money).float
|
||||||
|
);
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +101,112 @@ export function getPrintTemplatePropHints(schemaName: string, fyo: Fyo) {
|
|||||||
return hints;
|
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 {
|
function showHSN(doc: Doc): boolean {
|
||||||
const items = doc.items;
|
const items = doc.items;
|
||||||
if (!Array.isArray(items)) {
|
if (!Array.isArray(items)) {
|
||||||
|
@ -126,5 +126,9 @@
|
|||||||
<h3 class="text-lg font-semibold">Notes</h3>
|
<h3 class="text-lg font-semibold">Notes</h3>
|
||||||
<p class="mt-4 text-lg whitespace-pre-line">{{ doc.terms }}</p>
|
<p class="mt-4 text-lg whitespace-pre-line">{{ doc.terms }}</p>
|
||||||
</section>
|
</section>
|
||||||
|
<div v-if="print.amountInWords" class="flex justify-end mt-10">
|
||||||
|
<h3 class="text-lg font-semibold mr-2">Grand Total In Words:</h3>
|
||||||
|
<p>{{doc.grandTotalInWords}}</p>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</main>
|
</main>
|
||||||
|
Loading…
Reference in New Issue
Block a user