Print Amount in Words

Hi! I’m creating a custom template for Check Printing under Payment Entry and i could not find a way to print paid amount in words. Can anyone help? Thanks!

2 Likes

Got my answer from the forums.

{{ frappe.utils.money_in_words(doc.base_paid_amount or doc.base_received_amount) }}

4 Likes

https://frappe.github.io/erpnext/current/api/utils/frappe.utils.data#frappe.utils.data.money_in_words

I would like to highlight a problem in this code in case of multicurrency
suggested code:
{{ frappe.utils.money_in_words(doc.base_paid_amount or doc.base_received_amount) }}

i think this is a generic code, where in my case i should use
{{ frappe.utils.money_in_words(doc.base_paid_amount) }}

our system base currency is USD. when paid amount is in USD, this is working fine. however, when paid amount is in another currency, such as 200,000 LBP = 132.67USD, the above code is saying USD One Hundred And Thirty Two and Sixty Seven Cent only.
while it should say, LBP Two Hundred Thousand only.

i also tried following code {{ frappe.utils.money_in_words(doc.paid_amount) }}
it gave following, the number spelling is correct but the currency is wrong as follows:
USD Two Hundred Thousand only.

Please need the right code or fix in the Payment Entry form and print format, to show the correct in-words of the paid amount, that works correct in case of multicurrency.

@rohit_w can you please help on this? What one should do to get Amount in Words in the non-default / customer currency?

Hi

Is there now a solution to get Amount in Words in the non-default/customer currency?

Kind regards,

Made a Custom Print format for this. Got a friend to do it for me.

<script>
    // uncomment this line for English Number System
    var th = ['','thousand','million', 'milliard','billion'];
    var dg = ['zero','one','two','three','four', 'five','six','seven','eight','nine'];
    var tn = ['ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'];
    var tw = ['twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];

    function toWords(s){
debugger;
        s = s.toString(); s = s.replace(/[\, ]/g,'');
        if (s != parseFloat(s))
            return 'not a number';
        var x = s.indexOf('.');
        if (x == -1) x = s.length;
        if (x > 15) return 'too big';
        var n = s.split('');
        var str = '';
        var sk = 0;
        for (var i=0; i < x; i++) {
            if ((x-i)%3==2) {
                if (n[i] == '1') {
                    str += tn[Number(n[i+1])] + ' '; i++; sk=1;
                }else if (n[i]!=0) {
                    str += tw[n[i]-2] + ' ';sk=1;}
            }
            else if (n[i]!=0) {str += dg[n[i]] +' ';
            if ((x-i)%3==0) str += 'hundred ';sk=1;}
            if ((x-i)%3==1) {if (sk) str += th[(x-i-1)/3] + ' ';sk=0;}
        }
        str += 'pesos ';
        if (x != s.length) {
            var y = s.length;
            var centStr = 'and ';
            var hasNonZero = false;
            for (var i=x+1; i<y; i++) {
                if (!hasNonZero && n[i] != 0) {
                    hasNonZero = true;
                }
                centStr += n[i];
            }

            if (hasNonZero) {
                str += centStr + '/100 ';
            }
        }
        str += 'only';

        return str.replace(/\s+/g,' ');
    }

    function ucfirst(str) {
        str += '';
        var f = str.charAt(0).toUpperCase();
        return f + str.substr(1);
    }

    function number_format( number, decimals, dec_point, thousands_sep ) {
        var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
        var d = dec_point == undefined ? "," : dec_point;
        var t = thousands_sep == undefined ? "." : thousands_sep, s = n < 0 ? "-" : "";
        var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
        return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    }
</script>

<style>
.print-format table, .print-format tr,
.print-format td, .print-format div, .print-format p {
font-family: Monospace;
line-height: 15px;
vertical-align: middle;
}
@media screen {
.print-format {
width: 8in;
padding: 0 0 0 0;
min-height: 3in;
border: 1px;
border-style: dashed;
border-color: red;
}
}

        .headerrow {
              margin-top: 0.07in;
              font-weight: bold;
              width: 100%;
        }

        .headerrow td {
              font-size: 10pt;
              font-weight: bold;
        }

        .footerrow {
              width: 100%;
        }

        .footerrow td {
            padding: 0px 0px 15px !important;
            font-size: 11pt;
            font-weight: bold;
        }

        .wordsrow {
            width: 100%;
            margin-left: 1in;
        }

        td.payto{
            padding-left: 1.5in !important;
        }

</style>

<table class="headerrow">

  <tr>
    <td class="col-md-4"></td>
    <td class="col-md-6"></td>
    <td class="col-md-2 text-left" style="width: 20%;">{{ frappe.utils.get_datetime(doc.cheque_date).strftime('%b %d, %Y') }}</td>
  </tr>
</table>
<br>

<table class="footerrow">
  <tr>
    <td class="text-left payto" style="width: 70%;">{{  doc.get_formatted("pay_to_recd_from") }}</td>
    <td class="text-left" style="width: 20%;">{{  doc.get_formatted("total_debit") }}</td>
</tr>
</table>

<table class="wordsrow">

  <tr>
    <td class="text-left">
    <span id="txtAmount" style="font-size: 11pt; font-weight: bold;"></span>
        <script> document.getElementById("txtAmount").textContent = ucfirst(toWords(number_format({{doc.total_debit}}, 2, '.', ',')));</script>
    </td>
</tr>

</table>

This is what i did under Validations custom using the lang

company_currency = erpnext.get_company_currency(doc.company)
print company_currency
if (company_currency =='KZ'):
	doc.in_words = num2words(doc.rounded_total, lang='pt_BR').title() + ' Kwanzas.'
else:
	doc.in_words = money_in_words(doc.rounded_total, company_currency)
2 Likes

Hi,

Where exactly do you add this code?

Thanks

1 Like

More specifically, I’d like to know if there’s a way to do this using an HTML field…

Kind regards,

Okay, I tried it and it does work in an HTML field… just to be clear, Im referring to a field within the print format

Cheers!

Hi @umair

Trust you’re doing great. This issue is still not fixed. Could you please help look into it?

Thanks

Hi @umair

I posted an issue for this in the Frappe Issues list on Github. Is this the right place or should I have posted it in the ERPNext issues list?

https://github.com/frappe/frappe/issues/4350

Thanks

please add it in the ERPNext Issues list. You can also consider some sponsoring to fast-track it’s resolution.

This goes in the Custom print template, amongst html tags to format it accordingly

The above page is not found

Can this code also work in journal entry print format also?

Can you please point out where to implement this custom code?

You should add under your custom py file and on validation Def.

Have a look at the solution for on the top of this conversation…

Hello,

Thank you for your reply.

Where to find the py file to add this validation?

I am new to erpnext. Basically what I am trying to accomplish here:

  1. I created HTML custom print format and I want to display in words in own language.

  2. I want to make in words default to use my own language (if possible).

Num2words has my language listed.