Ana içeriğe atla

Odoo Rapor Çevirileri Eksik — 2026'da Nasıl Düzeltilir?

18.17.2019 tarihinde müşteri İngilizce bilmediğinde Odoo raporu İngilizce olarak mı yazdırılıyor? Artık üretimde güvenli bir şekilde dil bağlamı, t-translate ve PO dosyası yükleme işlemlerini teşhis edin.

E
ECOSIRE Research and Development Team
|4 Mayıs 20266 dk okuma1.2k Kelime|

Bu makale şu anda yalnızca İngilizce olarak mevcuttur. Çeviri yakında eklenecektir.

A French customer receives an Odoo invoice. The customer is set to French. The browser renders the invoice form in French. But the PDF lands in their inbox in English. Or some labels are translated, others are not. There is no error — just the wrong language.

A French customer receives an Odoo invoice. The customer is set to French. The browser renders the invoice form in French. But the PDF lands in their inbox in English. Or some labels are translated, others are not. There is no error — just the wrong language. This is one of the most embarrassing customer-facing bugs and applies to Odoo 17.0/18.0/19.0.

Quick Fix

The report renderer needs the customer's language in context. Verify the report action picks it up:

# In the model, override _get_report_values to set lang from partner
class SaleOrder(models.Model):
    _inherit = 'sale.order'

    def action_invoice_send(self):
        for order in self:
            lang = order.partner_id.lang or 'en_US'
            report = self.env.ref('account.account_invoices')
            pdf = report.with_context(lang=lang)._render_qweb_pdf(
                report.report_name, [order.invoice_ids.ids[0]]
            )
            # send pdf...

For most use cases, Odoo handles this automatically when the report is invoked through the standard mail/print flow. If your custom code triggers reports, always set the lang context explicitly.

Why This Happens

Odoo translations live in PO files inside each module's i18n/ directory. At runtime, Odoo loads them into ir.translation and resolves _("text") strings against the active language. The five common failures:

  1. No lang in context. The report renders in the user's language (admin English) instead of the recipient's (customer French).
  2. PO files not installed. The language is enabled in Settings > Languages but the PO files for the relevant modules were never imported.
  3. Hardcoded English in the template. <t t-esc="'Invoice'"/> is a literal string, untranslatable. The right form is <span>Invoice</span> or t-translate.
  4. Field-level translations not loaded for the active language. Some fields (name on product.product, description on sale.order.line) are translatable per record; the right translation may not exist.
  5. Cache. The translation cache is per-process; recently-imported translations may not appear until restart.

Step-by-Step Diagnosis

1. Check the language is installed.

SELECT id, code, name, active FROM res_lang
WHERE  code IN ('fr_FR', 'es_ES', 'de_DE');

active = true means installed. If false, install via Settings → Languages.

2. Check translations exist for the relevant modules.

SELECT lang, count(*)
FROM   ir_translation
WHERE  module = 'sale' GROUP BY lang;

fr_FR row should have thousands of entries. If much less, PO files were not imported.

3. Check the customer's lang.

SELECT id, name, lang FROM res_partner WHERE id = <pid>;

If lang is empty, Odoo falls back to the system default. Set the partner's language to fix.

4. Test report rendering with explicit lang.

report = env.ref('sale.action_report_saleorder')
pdf = report.with_context(lang='fr_FR')._render_qweb_pdf(
    report.report_name, [14]
)
print(len(pdf[0]))  # PDF bytes; should be non-zero

If this returns French content, the lang flow works — your earlier render was just missing the lang in context.

5. Check field-level translations.

SELECT res_id, lang, value
FROM   ir_translation
WHERE  name = 'product.template,name'
  AND  res_id = <product_id>;

If only en_US exists, the product name has no French translation.

Permanent Fix

Always set lang from the recipient on outbound communications:

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    def action_send_quote(self):
        self.ensure_one()
        lang = self.partner_id.lang or self.env.user.lang
        # The mail template handles lang automatically when partner_ids are set,
        # but custom RPC flows must be explicit.
        compose = self.env['mail.compose.message'].with_context(
            default_model='sale.order',
            default_res_id=self.id,
            default_use_template=True,
            default_template_id=self.env.ref('sale.email_template_edi_sale').id,
            mail_post_autofollow=True,
            force_email=True,
            lang=lang,
        ).create({})
        compose.send_mail()

For direct PDF generation, always:

pdf, _ext = report.with_context(lang=recipient_lang)._render_qweb_pdf(...)

For untranslated PO content, import:

sudo -u odoo /opt/odoo/odoo-bin -c odoo.conf \
  -d <db> --i18n-import=/opt/odoo/addons/sale/i18n/fr.po \
  --language=fr_FR --stop-after-init

Or programmatically:

env['base.language.import'].create({
    'name': 'French',
    'code': 'fr_FR',
    'overwrite': True,
}).import_lang()

For hardcoded strings in templates, use proper translation markers:

<!-- WRONG — literal string, untranslatable -->
<h2>Invoice</h2>

<!-- RIGHT — translatable -->
<h2><span>Invoice</span></h2>

<!-- Or in Python -->
title = _("Invoice")

QWeb auto-translates content within tags. Inline literals via t-esc='"text"' are NOT translatable.

For translatable field values, ensure each record has translations populated:

product = env['product.template'].browse(45)
product.with_context(lang='fr_FR').name = 'Produit prioritaire'

Or import via PO files for the model.

How to Prevent It

  • Always set lang in mail flows. Make this part of the team's checklist for any outbound email or PDF send. Audit existing custom send-mail code regularly.
  • CI test that reports render in non-default language. A test that generates a PDF for a French customer and asserts French strings appear catches lang-context regressions.
  • Import PO files in CI. When deploying, run --i18n-import for all enabled languages. Without this, your production stays at English even if the source has translations.
  • No literal English in templates. A regex check in CI for t-esc='"..."' patterns catches literal-string mistakes.
  • Lang fallback chain. When partner_id.lang is empty, fall back to company.partner_id.lang, then the system lang. Always have an explicit fallback so you do not silently render in the user's language.
  • Translatable fields convention. Document which model fields are translatable. New custom fields default to non-translatable; flip explicitly when needed.

Frequently Asked Questions

Why does my email render in the right language but the PDF attachment in English?

Different code paths. Email body uses the mail template's language resolution, which respects the partner. The PDF attachment is generated separately and may not pick up the lang context. Always pass lang when generating the PDF for an email send.

How do I add translations for a custom field?

Mark the field translatable in the Python definition:

description = fields.Text(translate=True)

Then export the PO file (Settings → Translations → Export), have it translated, import. Each record can also have language-specific translations stored directly via with_context(lang='...').write().

My non-English language is installed but reports still print English. What's wrong?

Two common causes. First, the partner does not have lang set — Odoo falls back to user lang. Second, the report action does not pass through partner.lang to its render context. Override _get_report_values to inject lang if needed.

Can I render a single report in two languages?

Yes, but it requires two render calls — there is no single render that produces a bilingual document. For dual-language reports (common in EU shipping documents), build a QWeb template that conditionally shows both languages by reading both translations and rendering side by side.

How do I export translations for review?

Settings → Translations → Export Translations. Choose the language and module, get a PO file. Send it to a translator. Re-import via Settings → Translations → Import Translation. The PO format is industry-standard; any translation tool handles it.

Why are some report strings translated and others not?

Three causes. First, the string was not marked translatable in the source — wrap with _("..."). Second, the PO file does not have a translation for that key — add one. Third, the cache holds a stale translation — restart Odoo. Verify with the SQL query in step 2 of the diagnosis.


Need help with a tricky Odoo error? ECOSIRE's Odoo experts have shipped 215+ modules — get expert help.

Paylaş:
E

Yazan

ECOSIRE Research and Development Team

Teknik Yazarlık

ECOSIRE teknik yazarlık ekibi Odoo ERP, Shopify ile e-ticaret, yapay zekâ ajanları, Power BI ile analitik, GoHighLevel ile otomasyon ve kurumsal yazılımda en iyi uygulamalar hakkında yazar. Rehberlerimiz işletmelerin bilinçli teknoloji kararları vermesine yardımcı olur.

ECOSIRE

Odoo ERP ile İşinizi Dönüştürün

Operasyonlarınızı kolaylaştırmak için uzman Odoo uygulaması, özelleştirme ve destek.