From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- addons/l10n_multilang/models/__init__.py | 5 + addons/l10n_multilang/models/account.py | 93 +++++++++++++ addons/l10n_multilang/models/l10n_multilang.py | 176 +++++++++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 addons/l10n_multilang/models/__init__.py create mode 100644 addons/l10n_multilang/models/account.py create mode 100644 addons/l10n_multilang/models/l10n_multilang.py (limited to 'addons/l10n_multilang/models') diff --git a/addons/l10n_multilang/models/__init__.py b/addons/l10n_multilang/models/__init__.py new file mode 100644 index 00000000..c57ec139 --- /dev/null +++ b/addons/l10n_multilang/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import account +from . import l10n_multilang diff --git a/addons/l10n_multilang/models/account.py b/addons/l10n_multilang/models/account.py new file mode 100644 index 00000000..2237207c --- /dev/null +++ b/addons/l10n_multilang/models/account.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +from odoo import fields, models + +#in this file, we mostly add the tag translate=True on existing fields that we now want to be translated + +class AccountAccountTag(models.Model): + _inherit = 'account.account.tag' + + name = fields.Char(translate=True) + +class AccountAccountTemplate(models.Model): + _inherit = 'account.account.template' + + name = fields.Char(translate=True) + + +class AccountAccount(models.Model): + _inherit = 'account.account' + + name = fields.Char(translate=True) + +class AccountGroupTemplate(models.Model): + _inherit = 'account.group.template' + + name = fields.Char(translate=True) + +class AccountGroup(models.Model): + _inherit = 'account.group' + + name = fields.Char(translate=True) + +class AccountTax(models.Model): + _inherit = 'account.tax' + + name = fields.Char(translate=True) + description = fields.Char(translate=True) + + +class AccountTaxTemplate(models.Model): + _inherit = 'account.tax.template' + + name = fields.Char(translate=True) + description = fields.Char(translate=True) + + +class AccountChartTemplate(models.Model): + _inherit = 'account.chart.template' + _order = 'name' + + name = fields.Char(translate=True) + spoken_languages = fields.Char(string='Spoken Languages', help="State here the languages for which the translations of templates could be loaded at the time of installation of this localization module and copied in the final object when generating them from templates. You must provide the language codes separated by ';'") + + +class AccountFiscalPosition(models.Model): + _inherit = 'account.fiscal.position' + + name = fields.Char(translate=True) + note = fields.Text(translate=True) + + +class AccountFiscalPositionTemplate(models.Model): + _inherit = 'account.fiscal.position.template' + + name = fields.Char(translate=True) + note = fields.Text(translate=True) + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + name = fields.Char(translate=True) + + +class AccountAnalyticAccount(models.Model): + _inherit = 'account.analytic.account' + + name = fields.Char(translate=True) + + +class AccountTaxReportLine(models.Model): + _inherit = 'account.tax.report.line' + + name = fields.Char(translate=True) + tag_name = fields.Char(translate=True) + + +class ResCountryState(models.Model): + _inherit = 'res.country.state' + + name = fields.Char(translate=True) diff --git a/addons/l10n_multilang/models/l10n_multilang.py b/addons/l10n_multilang/models/l10n_multilang.py new file mode 100644 index 00000000..07b8e7f9 --- /dev/null +++ b/addons/l10n_multilang/models/l10n_multilang.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from collections import defaultdict +import logging + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class AccountChartTemplate(models.Model): + _inherit = 'account.chart.template' + + def _load(self, sale_tax_rate, purchase_tax_rate, company): + res = super(AccountChartTemplate, self)._load(sale_tax_rate, purchase_tax_rate, company) + # Copy chart of account translations when loading chart of account + for chart_template in self.filtered('spoken_languages'): + external_id = self.env['ir.model.data'].search([ + ('model', '=', 'account.chart.template'), + ('res_id', '=', chart_template.id), + ], order='id', limit=1) + module = external_id and self.env.ref('base.module_' + external_id.module) + if module and module.state == 'installed': + langs = chart_template._get_langs() + if langs: + chart_template._process_single_company_coa_translations(company.id, langs) + return res + + def process_translations(self, langs, in_field, in_ids, out_ids): + """ + This method copies translations values of templates into new Accounts/Taxes/Journals for languages selected + + :param langs: List of languages to load for new records + :param in_field: Name of the translatable field of source templates + :param in_ids: Recordset of ids of source object + :param out_ids: Recordset of ids of destination object + + :return: True + """ + xlat_obj = self.env['ir.translation'] + #find the source from Account Template + for lang in langs: + #find the value from Translation + value = xlat_obj._get_ids(in_ids._name + ',' + in_field, 'model', lang, in_ids.ids) + counter = 0 + for element in in_ids.with_context(lang=None): + if value[element.id]: + #copy Translation from Source to Destination object + xlat_obj._set_ids( + out_ids._name + ',' + in_field, + 'model', + lang, + out_ids[counter].ids, + value[element.id], + element[in_field] + ) + else: + _logger.info('Language: %s. Translation from template: there is no translation available for %s!' % (lang, element[in_field])) + counter += 1 + return True + + def process_coa_translations(self): + company_obj = self.env['res.company'] + for chart_template_id in self: + langs = chart_template_id._get_langs() + if langs: + company_ids = company_obj.search([('chart_template_id', '=', chart_template_id.id)]) + for company in company_ids: + chart_template_id._process_single_company_coa_translations(company.id, langs) + return True + + def _process_single_company_coa_translations(self, company_id, langs): + # write account.account translations in the real COA + self._process_accounts_translations(company_id, langs, 'name') + # write account.group translations + self._process_account_group_translations(company_id, langs, 'name') + # copy account.tax name translations + self._process_taxes_translations(company_id, langs, 'name') + # copy account.tax description translations + self._process_taxes_translations(company_id, langs, 'description') + # copy account.fiscal.position translations + self._process_fiscal_pos_translations(company_id, langs, 'name') + + def _get_langs(self): + if not self.spoken_languages: + return [] + + installed_langs = dict(self.env['res.lang'].get_installed()) + langs = [] + for lang in self.spoken_languages.split(';'): + if lang not in installed_langs: + # the language is not installed, so we don't need to load its translations + continue + else: + langs.append(lang) + return langs + + def _process_accounts_translations(self, company_id, langs, field): + in_ids, out_ids = self._get_template_from_model(company_id, 'account.account') + return self.process_translations(langs, field, in_ids, out_ids) + + def _process_account_group_translations(self, company_id, langs, field): + in_ids, out_ids = self._get_template_from_model(company_id, 'account.group') + return self.process_translations(langs, field, in_ids, out_ids) + + def _process_taxes_translations(self, company_id, langs, field): + in_ids, out_ids = self._get_template_from_model(company_id, 'account.tax') + return self.process_translations(langs, field, in_ids, out_ids) + + def _process_fiscal_pos_translations(self, company_id, langs, field): + in_ids, out_ids = self._get_template_from_model(company_id, 'account.fiscal.position') + return self.process_translations(langs, field, in_ids, out_ids) + + def _get_template_from_model(self, company_id, model): + """ Find the records and their matching template """ + # generated records have an external id with the format _