在Odoo系统中如何为打印发票添加印度卢比(INR)金额的英文文本格式?
Hey there, I’ve solved this exact requirement for Odoo invoices before. Let’s walk through how to implement a clean solution that converts your INR numerical amounts to English word text (e.g., turning 1500 into one thousand five hundred) for your printed invoices:
Step 1: Create a Custom Module (Best Practice)
First, avoid modifying Odoo’s core code — build a small custom module to add this functionality. This keeps your upgrade path smooth and avoids breaking core features.
Step 2: Add the INR-to-Word Conversion Function
In your module’s models directory, create a Python file with the conversion logic. This function handles the Indian numbering system (including lakhs, crores) and works for all positive INR amounts:
def amount_to_text_inr(amount): # Word mappings for Indian numbering system ones = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'] teens = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'] tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'] thousands = ['', 'thousand', 'lakh', 'crore'] # Convert amount to integer (adjust if you need to handle paisa/decimals) amount_int = int(round(amount)) if amount_int == 0: return 'zero' words = [] chunk_index = 0 while amount_int > 0: # Extract 3-digit chunks (adapted for Indian numbering) chunk = amount_int % 1000 amount_int = amount_int // 1000 if chunk != 0: chunk_words = [] hundreds = chunk // 100 remainder = chunk % 100 # Handle hundreds place if hundreds != 0: chunk_words.append(f"{ones[hundreds]} hundred") if remainder != 0: chunk_words.append('and') # Handle tens and ones if remainder >= 10 and remainder < 20: chunk_words.append(teens[remainder - 10]) else: ten = remainder // 10 one = remainder % 10 if ten != 0: chunk_words.append(tens[ten]) if one != 0: chunk_words.append(ones[one]) # Add the thousand/lakh/crore suffix if thousands[chunk_index] != '': chunk_words.append(thousands[chunk_index]) # Insert chunk at the start of the words list words.insert(0, ' '.join(chunk_words)) chunk_index += 1 return ' '.join(words).capitalize()
Step 3: Integrate the Function with the Invoice/Move Model
Next, extend Odoo’s invoice model (use account.move for Odoo 13+; use account.invoice for older versions) to compute the worded amount:
from odoo import models, fields, api class AccountMove(models.Model): _inherit = 'account.move' @api.depends('amount_total', 'currency_id') def _compute_amount_in_words(self): for move in self: # Only apply for INR currency if move.currency_id.name == 'INR': move.amount_in_words = amount_to_text_inr(move.amount_total) else: # Fallback for other currencies (customize as needed) move.amount_in_words = '' amount_in_words = fields.Char( string='Amount in English Words', compute='_compute_amount_in_words', store=True, readonly=True )
Step 4: Update the QWeb Invoice Template
Now, modify your printed invoice template to display the worded amount. Find your invoice template (e.g., account.report_invoice) and add this snippet in a suitable section (like below the total amount):
<div class="invoice-amount-words" style="margin-top: 20px;"> <p><strong>Total Amount in Words:</strong> <span t-esc="doc.amount_in_words"/> Only</p> </div>
Key Notes to Test
- Decimal Handling: If your invoices include paisa (e.g., INR 1500.50), extend the function to handle the fractional part (add logic for "fifty paisa" at the end).
- Edge Cases: Test amounts like
0,1,99,1000,100000(one lakh),10000000(one crore) to ensure the function works correctly. - Template Customization: Adjust the styling (font, alignment) in the QWeb snippet to match your invoice’s design.
Give this a spin with your sample amount (INR 1500) — it should output one thousand five hundred exactly as you need! If you hit any kinks with edge cases or module setup, feel free to tweak the function or iterate on the logic.
内容的提问来源于stack exchange,提问作者Ajay Balachandran

