Skip to Content
Menu
This question has been flagged
3 Replies
5153 Views

Hii,

On sales invoice pdf report, I show amount in words, both English and Arabic. SAR is local currency.

Amount is translated except Currency Unit and Subunit for Arabic only. here is an example.

Two Thousand, Four Hundred And Thirty-Five Dollars and Forty Cents
ألفين، أربعة مئة و خمسة وثلاثين Dollars و أربعين Cents
Four Hundred And Seventy-Eight Riyal and Ninety-One Halala

أربعة مئة و ثمانية وسبعين Riyal و واحد وتسعين Halala
- Dollar and Cents not translated in Arabic

- Riyal and Halala not Translated in Arabic


Here is my function that translate function

class TccAccountInvoice(models.Model):
    _inherit = 'account.invoice'

    def invoice_amount_in_words(self, lang, amount):
        return self.currency_id.with_context(lang=lang).amount_to_text(amount)

XML Call

<t t-esc="o.invoice_amount_in_words('en_US', o.amount_total)"/>
<t t-esc="o.invoice_amount_in_words('ar_AA', o.amount_total)"/> 

Where to add the translation for Currency Unit and Subunit for Arabic saudi.

Version: Odoo 12 EE

Avatar
Discard
Author Best Answer

This is how I did it by overriding amount_to_text in res.currency.py

Please give your answer, if there is better way to solve it. Thanks.

class TccResCurrency(models.Model):
    _inherit = 'res.currency'

    @api.multi
    def amount_to_text(self, amount):
        self.ensure_one()

        def _num2words(number, lang):
            try:
                return num2words(number, lang=lang).title()
            except NotImplementedError:
                return num2words(number, lang='en').title()

        if num2words is None:
            logging.getLogger(__name__).warning("The library 'num2words' is missing, cannot render textual amounts.")
            return ""

        formatted = "%.{0}f".format(self.decimal_places) % amount
        parts = formatted.partition('.')
        integer_value = int(parts[0])
        fractional_value = int(parts[2] or 0)

        lang_code = self.env.context.get('lang') or self.env.user.lang
        lang = self.env['res.lang'].with_context(active_test=False).search([('code', '=', lang_code)])

        if lang_code == 'ar_AA':
            amount_words = tools.ustr('{amt_value} {amt_word}').format(
                amt_value=_num2words(integer_value, lang=lang.iso_code),
                amt_word='ريال',
            )
            if not self.is_zero(amount - integer_value):
                amount_words += ' ' + _('and') + tools.ustr(' {amt_value} {amt_word}').format(
                    amt_value=_num2words(fractional_value, lang=lang.iso_code),
                    amt_word='هللة',
                )
        else:
            amount_words = tools.ustr('{amt_value} {amt_word}').format(
                amt_value=_num2words(integer_value, lang=lang.iso_code),
                amt_word=self.currency_unit_label,
            )
            if not self.is_zero(amount - integer_value):
                amount_words += ' ' + _('and') + tools.ustr(' {amt_value} {amt_word}').format(
                    amt_value=_num2words(fractional_value, lang=lang.iso_code),
                    amt_word=self.currency_subunit_label,
                )

        return amount_words


Avatar
Discard
Best Answer

Hello, 

Instead of calling method multiple time you can also achieve the same part by creating a char field. 

Like that,


Python


class TccAccountInvoice(models.Model):

    _inherit = 'account.invoice'


    amount_in_word = fields.Char('Amount in word')


    def invoice_amount_in_words(self, lang, amount):

        return self.currency_id.with_context(lang=lang).amount_to_text(amount)


    @api.depends(

    'line_ids.debit',

    'line_ids.credit',

    'line_ids.currency_id',

    'line_ids.amount_currency',

    'line_ids.amount_residual',

    'line_ids.amount_residual_currency',

    'line_ids.payment_id.state')

    def _compute_amount(self):

        res = super(TccAccountInvoice, self)._compute_amount()

        for inv in self:

            amount = inv.amount_total

            inv.amount_to_word = inv.currency_id.with_context(lang='en_US').amount_to_text(amount)

            inv.amount_to_word = inv.currency_id.with_context(lang='ar_AA').amount_to_text(amount)

XML Call


<t t-esc="o.with_context(lang='en_US').amount_to_word"/>

<t t-esc="o.with_context(lang='ar_AA').amount_to_word"/>

Thanks

Anisha Bahukhandi

Avatar
Discard
Best Answer

Just change the prefixes on the Currency Record:

Then it looks something like this:

Note: Since I don't happen to read or write Arabic, I am not suggesting this is THE solution, I just used Google Translate to get values for the prefix.  The Invoice I tested on was for 478.91 SR.  I also set Odoo to Syrian Arabic, which is defaulted to right-to-left formatting.


Avatar
Discard
Author

Thanks Ray for your reply.

I changed Currency Unit and Subunit for SAR to Arabic as you said.

In this case Arabic translation is ok, but in English translation it shows Unit and Subunit in Arabic like following.

Eight Thousand, Two Hundred And Forty-Seven ريال and Sixty هللة

ثمانية ألف، مئتين و سبعة وأربعين ريال و ستين هللة

Because we need to show amount in words both in English and Arabic together (side by side on the same report).

So, my solution i.e. overriding amount_to_text() in my answer is working good for me. Tested for Sales Order and Invoicing Report.