1
votes

Imagine you want to fill a field in the sale.order form with a default value, the same text will be used for each company that is being used in Odoo. Sometimes the usual way to proceed is to use a common field in the res.company model. Other option is to add a field that is filled with some other content in the res.partner form, when the customer is selected.

But the problem I found is: if I want to get the translations for that field, which are already in the original one, I would have to do it manually, inheriting the create method of ir.translation. When the field is copied to the sale.order form a record for the current used language is created, so I took advantage of it to create the rest of records. Is there a better way to do this?

Also, I would like to add that after saving the record I press the world icon to translate the text again, new translations are created with the current text. So I would need to translate everything again on every sale.order record.

I did this in the ir.translation model for a simple text field in order to create the translations of the rest of languages. The field field_to_translate is translatable on both sides:

@api.model
def create(self, vals):
    record = super(IrTranslation, self).create(vals)
    name = vals.get('name', False)  # name of the field to translate
    lang = vals.get('lang', False)  # creating record for this language
    if 'context' in dir(self.env):
        cur_lang = self.env.context.get('lang', False)  # current used language
        if name == 'sale.order,field_to_translate' and lang == cur_lang:
            langs = self.env['ir.translation']._get_languages()
            langs = [l[0] for l in langs if l[0] != cur_lang]   # installed languages

            for l in langs:
                if self.env.user.company_id.field_to_translate:
                    t = self.env['ir.translation'].search([
                        ('lang', '=', l),
                        ('type', '=', 'model'),
                        ('name', '=', 'res.company,field_to_translate')
                    ])
                    if t:
                        self.env['ir.translation'].create({
                            'lang': l,
                            'type': 'model',
                            'name': 'sale.order,field_to_translate',
                            'res_id': record.res_id,
                            'src': record.src,
                            'value': t.value,
                            'state': 'translated',
                        })

Ah, and I want to do this because I want to print them on different reports. The language of these report will depend on the customer lang field.

In short, how can I set a translatable field in res.company as a default value in other field in the sale.order model? The translations to other languages should be copied as well. My above proposal is kind of cumbersome

1
You over explained what you need could you explain what you need in a more simple wayCharif DZ
@CharifDZ thanks for your interest. I have added a new paragraph to sum up my question. Let me know if you understand it. If not I could add some gif or try to write a better explanation of what's happening.ChesuCR
I think this explains all, now does the user have permission to change that value in sale.order or it's only changeable in the res.company model? You have a lot of sinario that need to be handle if he has this rightCharif DZ
@CharifDZ yes, it is supposed that the user should be able to edit both fields in both models, and its translations as wellChesuCR
So I think when you create a sale.order you should copy all translations available at that point. But if he changes the value then another translation was added in res.company what should we do then, copy it even if the value in original language are not equal? As I told you you have a lot of senario what if a translation is added from the sale.order should we copied in res.company too. And if the value in original language are not equal should we copy or ignore it?Charif DZ

1 Answers

0
votes

Well, finally I have created the translations in the create method of sale.order. I have used a customized translate_fields method of the ir.translation model in order to create the translations automatically and then I update all their values manually with the correct language translation.

On the other hand I found this class in the l10n_multilang module that can be useful for other people that may find the same problem:

class AccountChartTemplate(models.Model):
    _inherit = 'account.chart.template'

    @api.multi
    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

    @api.multi
    def process_coa_translations(self):
        installed_langs = dict(self.env['res.lang'].get_installed())
        company_obj = self.env['res.company']
        for chart_template_id in self:
            langs = []
            if chart_template_id.spoken_languages:
                for lang in chart_template_id.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)
                if langs:
                    company_ids = company_obj.search([('chart_template_id', '=', chart_template_id.id)])
                    for company in company_ids:
                        # write account.account translations in the real COA
                        chart_template_id._process_accounts_translations(company.id, langs, 'name')
                        # copy account.tax name translations
                        chart_template_id._process_taxes_translations(company.id, langs, 'name')
                        # copy account.tax description translations
                        chart_template_id._process_taxes_translations(company.id, langs, 'description')
                        # copy account.fiscal.position translations
                        chart_template_id._process_fiscal_pos_translations(company.id, langs, 'name')
        return True

    @api.multi
    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)

    @api.multi
    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)

    @api.multi
    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):
        out_data = self.env['ir.model.data'].search([('model', '=', model), ('name', '=like', str(company_id)+'\_%')])
        out_ids = self.env[model].search([('id', 'in', out_data.mapped('res_id'))], order='id')
        in_xml_id_names = [xml_id.partition(str(company_id) + '_')[-1] for xml_id in out_data.mapped('name')]
        in_xml_ids = self.env['ir.model.data'].search([('model', '=', model+'.template'), ('name', 'in', in_xml_id_names)])
        in_ids = self.env[model+'.template'].search([('id', 'in', in_xml_ids.mapped('res_id'))], order='id')
        return (in_ids, out_ids)