diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index 83aa46b8e0d..e33f18260a1 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -76,14 +76,11 @@ class AccountReconcileModel(models.Model): ('fixed', 'Fixed'), ('percentage', 'Percentage of balance') ], required=True, default='percentage') - is_tax_price_included = fields.Boolean(string='Is Tax Included in Price', related='tax_id.price_include', - help='Technical field used inside the view to make the force_tax_included field readonly if the tax is already price included.') - tax_amount_type = fields.Selection(string='Tax Amount Type', related='tax_id.amount_type', - help='Technical field used inside the view to make the force_tax_included field invisible if the tax is a group.') + show_force_tax_included = fields.Boolean(store=False, help='Technical field used to show the force tax included button') force_tax_included = fields.Boolean(string='Tax Included in Price', help='Force the tax to be managed as a price included tax.') amount = fields.Float(string='Write-off Amount', digits=0, required=True, default=100.0, help="Fixed amount will count as a debit if it is negative, as a credit if it is positive.") - tax_id = fields.Many2one('account.tax', string='Tax', ondelete='restrict') + tax_ids = fields.Many2many('account.tax', string='Taxes', ondelete='restrict') analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', ondelete='set null') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags', relation='account_reconcile_model_analytic_tag_rel') @@ -97,14 +94,11 @@ class AccountReconcileModel(models.Model): ('fixed', 'Fixed'), ('percentage', 'Percentage of amount') ], string="Second Amount type",required=True, default='percentage') - is_second_tax_price_included = fields.Boolean(string='Is Second Tax Included in Price', related='second_tax_id.price_include', - help='Technical field used inside the view to make the force_second_tax_included field readonly if the tax is already price included.') - second_tax_amount_type = fields.Selection(string='Second Tax Amount Type', related='second_tax_id.amount_type', - help='Technical field used inside the view to make the force_second_tax_included field invisible if the tax is a group.') + show_second_force_tax_included = fields.Boolean(store=False, help='Technical field used to show the force tax included button') force_second_tax_included = fields.Boolean(string='Second Tax Included in Price', help='Force the second tax to be managed as a price included tax.') second_amount = fields.Float(string='Second Write-off Amount', digits=0, required=True, default=100.0, help="Fixed amount will count as a debit if it is negative, as a credit if it is positive.") - second_tax_id = fields.Many2one('account.tax', string='Second Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'purchase')]) + second_tax_ids = fields.Many2many('account.tax', relation='account_reconcile_model_account_tax_bis_rel', string='Second Taxes', ondelete='restrict') second_analytic_account_id = fields.Many2one('account.analytic.account', string='Second Analytic Account', ondelete='set null') second_analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Second Analytic Tags', relation='account_reconcile_model_second_analytic_tag_rel') @@ -131,15 +125,21 @@ class AccountReconcileModel(models.Model): def onchange_name(self): self.label = self.name - @api.onchange('tax_id') - def _onchange_tax_id(self): - if self.tax_id: - self.force_tax_included = self.tax_id.price_include + @api.onchange('tax_ids') + def _onchange_tax_ids(self): + # Multiple taxes with force_tax_included results in wrong computation, so we + # only allow to set the force_tax_included field if we have one tax selected + self.show_force_tax_included = False if len(self.tax_ids) != 1 else True + if len(self.tax_ids) != 1: + self.force_tax_included = False - @api.onchange('second_tax_id') - def _onchange_second_tax_id(self): - if self.second_tax_id: - self.force_second_tax_included = self.second_tax_id.price_include + @api.onchange('second_tax_ids') + def _onchange_second_tax_ids(self): + # Multiple taxes with force_tax_included results in wrong computation, so we + # only allow to set the force_tax_included field if we have one tax selected + self.show_second_force_tax_included = False if len(self.second_tax_ids) != 1 else True + if len(self.second_tax_ids) != 1: + self.force_second_tax_included = False @api.onchange('match_total_amount_param') def _onchange_match_total_amount_param(self): @@ -221,11 +221,13 @@ class AccountReconcileModel(models.Model): } new_aml_dicts.append(writeoff_line) - if self.tax_id: - writeoff_line['tax_ids'] = [(6, None, [self.tax_id.id])] - tax = self.tax_id + if self.tax_ids: + writeoff_line['tax_ids'] = [(6, None, self.tax_ids.ids)] + tax = self.tax_ids + # Multiple taxes with force_tax_included results in wrong computation, so we + # only allow to set the force_tax_included field if we have one tax selected if self.force_tax_included: - tax = tax.with_context(force_price_include=True) + tax = tax[0].with_context(force_price_include=True) new_aml_dicts += self._get_taxes_move_lines_dict(tax, writeoff_line) # Second write-off line. @@ -241,11 +243,13 @@ class AccountReconcileModel(models.Model): } new_aml_dicts.append(second_writeoff_line) - if self.second_tax_id: - second_writeoff_line['tax_ids'] = [(6, None, [self.second_tax_id.id])] - tax = self.second_tax_id + if self.second_tax_ids: + second_writeoff_line['tax_ids'] = [(6, None, self.second_tax_ids.ids)] + tax = self.second_tax_ids + # Multiple taxes with force_tax_included results in wrong computation, so we + # only allow to set the force_tax_included field if we have one tax selected if self.force_second_tax_included: - tax = tax.with_context(force_price_include=True) + tax = tax[0].with_context(force_price_include=True) new_aml_dicts += self._get_taxes_move_lines_dict(tax, second_writeoff_line) return new_aml_dicts diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py index 108538368b8..dc339adc005 100644 --- a/addons/account/models/chart_template.py +++ b/addons/account/models/chart_template.py @@ -684,13 +684,12 @@ class AccountChartTemplate(models.Model): 'amount_type': account_reconcile_model.amount_type, 'force_tax_included': account_reconcile_model.force_tax_included, 'amount': account_reconcile_model.amount, - 'tax_id': account_reconcile_model.tax_id and tax_template_ref[account_reconcile_model.tax_id.id] or False, + 'tax_ids': [[4, tax_template_ref[tax.id], 0] for tax in account_reconcile_model.tax_ids], 'second_account_id': account_reconcile_model.second_account_id and acc_template_ref[account_reconcile_model.second_account_id.id] or False, 'second_label': account_reconcile_model.second_label, 'second_amount_type': account_reconcile_model.second_amount_type, 'force_second_tax_included': account_reconcile_model.force_second_tax_included, 'second_amount': account_reconcile_model.second_amount, - 'second_tax_id': account_reconcile_model.second_tax_id and tax_template_ref[account_reconcile_model.second_tax_id.id] or False, 'rule_type': account_reconcile_model.rule_type, 'auto_reconcile': account_reconcile_model.auto_reconcile, 'match_journal_ids': [(6, None, account_reconcile_model.match_journal_ids.ids)], @@ -706,6 +705,7 @@ class AccountChartTemplate(models.Model): 'match_partner': account_reconcile_model.match_partner, 'match_partner_ids': [(6, None, account_reconcile_model.match_partner_ids.ids)], 'match_partner_category_ids': [(6, None, account_reconcile_model.match_partner_category_ids.ids)], + 'second_tax_ids': [[4, tax_template_ref[tax.id], 0] for tax in account_reconcile_model.second_tax_ids], } @api.multi @@ -1041,10 +1041,9 @@ class AccountReconcileModelTemplate(models.Model): amount = fields.Float(string='Write-off Amount', digits=0, required=True, default=100.0, help="Fixed amount will count as a debit if it is negative, as a credit if it is positive.") force_tax_included = fields.Boolean(string='Tax Included in Price', help='Force the tax to be managed as a price included tax.') - tax_id = fields.Many2one('account.tax.template', string='Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'purchase')]) - # Second part fields. has_second_line = fields.Boolean(string='Add a second line', default=False) + tax_ids = fields.Many2many('account.tax.template', string='Taxes', ondelete='restrict') second_account_id = fields.Many2one('account.account.template', string='Second Account', ondelete='cascade', domain=[('deprecated', '=', False)]) second_label = fields.Char(string='Second Journal Item Label') second_amount_type = fields.Selection([ @@ -1054,6 +1053,5 @@ class AccountReconcileModelTemplate(models.Model): second_amount = fields.Float(string='Second Write-off Amount', digits=0, required=True, default=100.0, help="Fixed amount will count as a debit if it is negative, as a credit if it is positive.") force_second_tax_included = fields.Boolean(string='Second Tax Included in Price', help='Force the second tax to be managed as a price included tax.') - second_tax_id = fields.Many2one('account.tax.template', string='Second Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'purchase')]) - number_entries = fields.Integer(string='Number of entries related to this model', compute='_compute_number_entries') + second_tax_ids = fields.Many2many('account.tax.template', relation='account_reconcile_model_tmpl_account_tax_bis_rel', string='Second Taxes', ondelete='restrict') diff --git a/addons/account/static/src/js/reconciliation/reconciliation_model.js b/addons/account/static/src/js/reconciliation/reconciliation_model.js index 11dbd804420..601f4cec773 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_model.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_model.js @@ -74,7 +74,7 @@ var _t = core._t; * id: integer * display_name: string * } - * tax_id: { + * tax_ids: { * id: integer * display_name: string * } @@ -95,7 +95,7 @@ var _t = core._t; */ var StatementModel = BasicModel.extend({ avoidCreate: false, - quickCreateFields: ['account_id', 'amount', 'analytic_account_id', 'label', 'tax_id', 'force_tax_included', 'analytic_tag_ids', 'to_check'], + quickCreateFields: ['account_id', 'amount', 'analytic_account_id', 'label', 'tax_ids', 'force_tax_included', 'analytic_tag_ids', 'to_check'], /** * @override @@ -461,17 +461,18 @@ var StatementModel = BasicModel.extend({ var self = this; self.taxes = {}; return this._rpc({ - model: 'account.tax', - method: 'search_read', - fields: ['price_include', 'amount_type'], - }).then(function (taxes) { - _.each(taxes, function(tax){ - self.taxes[tax.id] = { - price_include: tax.price_include, - amount_type: tax.amount_type, - }; + model: 'account.tax', + method: 'search_read', + fields: ['price_include', 'name'], + }).then(function (taxes) { + _.each(taxes, function(tax){ + self.taxes[tax.id] = { + price_include: tax.price_include, + display_name: tax.name, + }; + }); + return taxes; }); - }); }, /** * Add lines into the propositions from the reconcile model @@ -488,9 +489,8 @@ var StatementModel = BasicModel.extend({ quickCreateProposition: function (handle, reconcileModelId) { var line = this.getLine(handle); var reconcileModel = _.find(this.reconcileModels, function (r) {return r.id === reconcileModelId;}); - var fields = ['account_id', 'amount', 'amount_type', 'analytic_account_id', 'journal_id', 'label', 'force_tax_included', 'tax_id', 'analytic_tag_ids', 'to_check']; + var fields = ['account_id', 'amount', 'amount_type', 'analytic_account_id', 'journal_id', 'label', 'force_tax_included', 'tax_ids', 'analytic_tag_ids', 'to_check']; this._blurProposition(handle); - var focus = this._formatQuickCreate(line, _.pick(reconcileModel, fields)); focus.reconcileModelId = reconcileModelId; if (!line.reconciliation_proposition.every(function(prop) {return prop.to_check == focus.to_check;})) { @@ -501,7 +501,6 @@ var StatementModel = BasicModel.extend({ return Promise.resolve(); } line.reconciliation_proposition.push(focus); - if (reconcileModel.has_second_line) { var second = {}; _.each(fields, function (key) { @@ -648,7 +647,26 @@ var StatementModel = BasicModel.extend({ }); break; } - } else { + } + else if (fieldName === 'tax_ids') { + switch(value.operation) { + case "ADD_M2M": + prop.__tax_to_recompute = true; + if (!_.findWhere(prop.tax_ids, {id: value.ids.id})) { + value.ids.price_include = self.taxes[value.ids.id] ? self.taxes[value.ids.id].price_include : false; + prop.tax_ids.push(value.ids); + } + break; + case "FORGET": + prop.__tax_to_recompute = true; + var id = self.localData[value.ids[0]].ref; + prop.tax_ids = _.filter(prop.tax_ids, function (val) { + return val.id !== id; + }); + break; + } + } + else { prop[fieldName] = values[fieldName]; } }); @@ -661,21 +679,19 @@ var StatementModel = BasicModel.extend({ this._computeReconcileModels(handle, prop.reconcileModelId); } } - if ('account_id' in values || 'amount' in values || 'tax_id' in values || 'force_tax_included' in values) { + if ('force_tax_included' in values || 'amount' in values || 'account_id' in values) { prop.__tax_to_recompute = true; - - if(values.tax_id){ - values.tax_id.amount_type = this.taxes[values.tax_id.id].amount_type; - values.tax_id.price_include = prop.force_tax_included = this.taxes[values.tax_id.id].price_include; - }else if('tax_id' in values && prop.base_amount && prop.base_amount != prop.amount) - // When removing a price_included tax, reset the amount to the base_amount. - prop.amount = prop.base_amount; } line.createForm = _.pick(prop, this.quickCreateFields); // If you check/uncheck the force_tax_included box, reset the createForm amount. if(prop.base_amount) line.createForm.amount = prop.base_amount; + if (prop.tax_ids.length !== 1 ) { + // When we have 0 or more than 1 taxes, reset the base_amount and force_tax_included, otherwise weird behavior can happen + prop.amount = prop.base_amount; + line.createForm.force_tax_included = false; + } return this._computeLine(line); }, /** @@ -832,7 +848,7 @@ var StatementModel = BasicModel.extend({ /** * Calculates the balance; format each proposition amount_str and mark as * invalid the line with empty account_id, amount or label - * Check the taxes server side for each updated propositions with tax_id + * Check the taxes server side for each updated propositions with tax_ids * * @private * @param {Object} line @@ -860,14 +876,13 @@ var StatementModel = BasicModel.extend({ } reconciliation_proposition.push(prop); - if (prop.tax_id && prop.__tax_to_recompute && prop.base_amount) { - line.reconciliation_proposition = _.filter(line.reconciliation_proposition, function (p) { + if (prop.tax_ids && prop.tax_ids.length && prop.__tax_to_recompute && prop.base_amount) { + reconciliation_proposition = _.filter(reconciliation_proposition, function (p) { return !p.is_tax || p.link !== prop.id; }); - - var args = [[prop.tax_id.id], prop.base_amount, formatOptions.currency_id]; + var args = [prop.tax_ids.map(function(el){return el.id;}), prop.base_amount, formatOptions.currency_id]; var add_context = {'round': true}; - if(line.createForm.force_tax_included && prop.tax_id.amount_type !== "group") + if(prop.tax_ids.length === 1 && line.createForm.force_tax_included) add_context.force_price_include = true; tax_defs.push(self._rpc({ model: 'account.tax', @@ -879,7 +894,7 @@ var StatementModel = BasicModel.extend({ _.each(result.taxes, function(tax){ var tax_prop = self._formatQuickCreate(line, { 'link': prop.id, - 'tax_id': [tax.id, null], + 'tax_ids': [tax.id], 'amount': tax.amount, 'label': tax.name, 'date': prop.date, @@ -982,6 +997,13 @@ var StatementModel = BasicModel.extend({ } return res; }, + _formatMany2ManyTagsTax: function(value) { + var res = []; + for (var i=0; i 1) { + $('.create_force_tax_included').addClass('d-none'); + } + else { + $('.create_force_tax_included').removeClass('d-none'); + var price_include = state.createForm[fieldName][0].price_include; + self.$('.create_force_tax_included input').prop('checked', price_include); + self.$('.create_force_tax_included input').prop('disabled', price_include); + } + } + }); + return true; }); }); - if(state.createForm.tax_id){ - // Set the 'Tax Include' field editable or not depending of the 'price_include' value. - self.$('.create_force_tax_included input').attr('disabled', state.createForm.tax_id.price_include); - } - }); } this.$('.create .add_line').toggle(!!state.balance.amount_currency); }, @@ -513,7 +526,7 @@ var LineRenderer = Widget.extend(FieldManagerMixin, { }, /** - * create account_id, tax_id, analytic_account_id, analytic_tag_ids, label and amount fields + * create account_id, tax_ids, analytic_account_id, analytic_tag_ids, label and amount fields * * @private * @param {object} state - statement line @@ -533,8 +546,8 @@ var LineRenderer = Widget.extend(FieldManagerMixin, { domain: [['company_id', '=', state.st_line.company_id]], }, { relation: 'account.tax', - type: 'many2one', - name: 'tax_id', + type: 'many2many', + name: 'tax_ids', domain: [['company_id', '=', state.st_line.company_id]], }, { relation: 'account.analytic.account', @@ -573,8 +586,8 @@ var LineRenderer = Widget.extend(FieldManagerMixin, { self.fields.journal_id = new relational_fields.FieldMany2One(self, 'journal_id', record, {mode: 'edit'}); - self.fields.tax_id = new relational_fields.FieldMany2One(self, - 'tax_id', record, {mode: 'edit', additionalContext: {append_type_to_tax_name: true}}); + self.fields.tax_ids = new relational_fields.FieldMany2ManyTags(self, + 'tax_ids', record, {mode: 'edit', additionalContext: {append_type_to_tax_name: true}}); self.fields.analytic_account_id = new relational_fields.FieldMany2One(self, 'analytic_account_id', record, {mode: 'edit'}); @@ -601,7 +614,7 @@ var LineRenderer = Widget.extend(FieldManagerMixin, { self.fields.account_id.appendTo($create.find('.create_account_id .o_td_field')) .then(addRequiredStyle.bind(self, self.fields.account_id)); self.fields.journal_id.appendTo($create.find('.create_journal_id .o_td_field')); - self.fields.tax_id.appendTo($create.find('.create_tax_id .o_td_field')); + self.fields.tax_ids.appendTo($create.find('.create_tax_id .o_td_field')); self.fields.analytic_account_id.appendTo($create.find('.create_analytic_account_id .o_td_field')); self.fields.analytic_tag_ids.appendTo($create.find('.create_analytic_tag_ids .o_td_field')); self.fields.force_tax_included.appendTo($create.find('.create_force_tax_included .o_td_field')); diff --git a/addons/account/static/src/xml/account_reconciliation.xml b/addons/account/static/src/xml/account_reconciliation.xml index 139ce73c402..d76ef05e917 100644 --- a/addons/account/static/src/xml/account_reconciliation.xml +++ b/addons/account/static/src/xml/account_reconciliation.xml @@ -188,7 +188,7 @@ - Tax + Taxes diff --git a/addons/account/static/tests/reconciliation_tests.js b/addons/account/static/tests/reconciliation_tests.js index 053d18c1659..87fbddd31eb 100644 --- a/addons/account/static/tests/reconciliation_tests.js +++ b/addons/account/static/tests/reconciliation_tests.js @@ -170,24 +170,24 @@ var db = { label: {string: "Journal Item Label", type: 'char'}, amount_type: {string: 'amount_type', type: 'selection', selection: [['fixed', 'Fixed'], ['percentage', 'Percentage of balance']], default:'percentage'}, amount: {string: "Amount", type: 'float', digits:0, help:"Fixed amount will count as a debit if it is negative, as a credit if it is positive.", default:100.0}, - tax_id: {string: "Tax", type: 'many2one', relation:'account.tax', domain:[('type_tax_use', '=', 'purchase')]}, + tax_ids: {string: "Tax", type: 'many2many', relation:'account.tax'}, analytic_account_id: {string: "Analytic Account", type: 'many2one', relation:'account.analytic.account'}, second_account_id: {string: "Second Account", type: 'many2one', relation:'account.account', domain:[('deprecated', '=', false)]}, second_journal_id: {string: "Second Journal", type: 'many2one', relation:'account.journal', help:"This field is ignored in a bank statement reconciliation."}, second_label: {string: "Second Journal Item Label", type: 'char'}, second_amount_type: {string: "Second amount_type", type: 'selection', selection: [['fixed', 'Fixed'], ['percentage', 'Percentage of balance']], default:'percentage'}, second_amount: {string: "Second Amount", type: 'float', digits:0, help:"Fixed amount will count as a debit if it is negative, as a credit if it is positive.", default:100.0}, - second_tax_id: {string: "Second Tax", type: 'many2one', relation:'account.tax', domain:[('type_tax_use', '=', 'purchase')]}, + second_tax_ids: {string: "Second Tax", type: 'many2many', relation: 'account.tax'}, second_analytic_account_id: {string: "Second Analytic Account", type: 'many2one', relation:'account.analytic.account'}, match_journal_ids: {string: "Journal Ids", type: 'many2many', relation: 'account.journal'} }, records: [ - {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 4, 'analytic_account_id': false, 'display_name': "Int\u00e9rrets", 'rule_type': 'writeoff_button', 'second_tax_id': false, 'has_second_line': false, 'journal_id': false, 'label': false, 'second_label': false, 'second_account_id': false, 'account_id': 282, 'company_id': [1, "Demo SPRL"], 'tax_id': false, 'amount_type': "fixed", 'name': "Int\u00e9rrets", 'amount': 0.0, 'second_amount': 100.0, 'match_journal_ids': []}, - {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 2, 'analytic_account_id': false, 'display_name': "Perte et Profit", 'rule_type': 'writeoff_button', 'second_tax_id': false, 'has_second_line': false, 'journal_id': false, 'label': false, 'second_label': false, 'second_account_id': false, 'account_id': 283, 'company_id': [1, "Demo SPRL"], 'tax_id': false, 'amount_type': "percentage", 'name': "Perte et Profit", 'amount': 100.0, 'second_amount': 100.0, 'match_journal_ids': []}, - {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 5, 'analytic_account_id': false, 'display_name': "Fs bank", 'rule_type': 'writeoff_button', 'second_tax_id': false, 'has_second_line': false, 'journal_id': false, 'label': false, 'second_label': false, 'second_account_id': false, 'account_id': 284, 'company_id': [1, "Demo SPRL"], 'tax_id': false, 'amount_type': "percentage", 'name': "Fs bank", 'amount': 100.0, 'second_amount': 100.0}, - {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 8, 'analytic_account_id': false, 'display_name': "Caisse Sand.", 'rule_type': 'writeoff_button', 'second_tax_id': false, 'has_second_line': false, 'journal_id': false, 'label': "Caisse Sand.", 'second_label': false, 'second_account_id': false, 'account_id': 308, 'company_id': [1, "Demo SPRL"], 'tax_id': false, 'amount_type': "percentage", 'name': "Caisse Sand.", 'amount': 100.0, 'second_amount': 100.0, 'match_journal_ids': []}, - {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 3, 'analytic_account_id': false, 'display_name': "ATOS", 'rule_type': 'writeoff_button', 'second_tax_id': 7, 'has_second_line': true, 'journal_id': false, 'label': "ATOS Banque", 'second_label': "ATOS Frais", 'second_account_id': 286, 'account_id': 285, 'company_id': [1, "Demo SPRL"], 'tax_id': 6, 'amount_type': "percentage", 'name': "ATOS", 'amount': 97.5, 'second_amount': 2.5}, - {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 10, 'analytic_account_id': false, 'display_name': "Double", 'rule_type': 'writeoff_button', 'second_tax_id': false, 'has_second_line': true, 'journal_id': false, 'label': "Double Banque", 'second_label': "Double Frais", 'second_account_id': 286, 'account_id': 285, 'company_id': [1, "Demo SPRL"], 'tax_id': false, 'amount_type': "percentage", 'name': "Double", 'amount': 97.5, 'second_amount': 2.5, 'match_journal_ids': []}, + {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 4, 'analytic_account_id': false, 'display_name': "Int\u00e9rrets", 'rule_type': 'writeoff_button', 'second_tax_ids': [], 'has_second_line': false, 'journal_id': false, 'label': false, 'second_label': false, 'second_account_id': false, 'account_id': 282, 'company_id': [1, "Demo SPRL"], 'tax_ids': [], 'amount_type': "fixed", 'name': "Int\u00e9rrets", 'amount': 0.0, 'second_amount': 100.0, 'match_journal_ids': []}, + {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 2, 'analytic_account_id': false, 'display_name': "Perte et Profit", 'rule_type': 'writeoff_button', 'second_tax_ids': [], 'has_second_line': false, 'journal_id': false, 'label': false, 'second_label': false, 'second_account_id': false, 'account_id': 283, 'company_id': [1, "Demo SPRL"], 'tax_ids': [], 'amount_type': "percentage", 'name': "Perte et Profit", 'amount': 100.0, 'second_amount': 100.0, 'match_journal_ids': []}, + {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 5, 'analytic_account_id': false, 'display_name': "Fs bank", 'rule_type': 'writeoff_button', 'second_tax_ids': [], 'has_second_line': false, 'journal_id': false, 'label': false, 'second_label': false, 'second_account_id': false, 'account_id': 284, 'company_id': [1, "Demo SPRL"], 'tax_ids': [], 'amount_type': "percentage", 'name': "Fs bank", 'amount': 100.0, 'second_amount': 100.0}, + {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 8, 'analytic_account_id': false, 'display_name': "Caisse Sand.", 'rule_type': 'writeoff_button', 'second_tax_ids': [], 'has_second_line': false, 'journal_id': false, 'label': "Caisse Sand.", 'second_label': false, 'second_account_id': false, 'account_id': 308, 'company_id': [1, "Demo SPRL"], 'tax_ids': [], 'amount_type': "percentage", 'name': "Caisse Sand.", 'amount': 100.0, 'second_amount': 100.0, 'match_journal_ids': []}, + {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 3, 'analytic_account_id': false, 'display_name': "ATOS", 'rule_type': 'writeoff_button', 'second_tax_ids': [7], 'has_second_line': true, 'journal_id': false, 'label': "ATOS Banque", 'second_label': "ATOS Frais", 'second_account_id': 286, 'account_id': 285, 'company_id': [1, "Demo SPRL"], 'tax_ids': [6], 'amount_type': "percentage", 'name': "ATOS", 'amount': 97.5, 'second_amount': 2.5}, + {'second_analytic_account_id': false, 'second_amount_type': "percentage", 'second_journal_id': false, 'id': 10, 'analytic_account_id': false, 'display_name': "Double", 'rule_type': 'writeoff_button', 'second_tax_ids': [], 'has_second_line': true, 'journal_id': false, 'label': "Double Banque", 'second_label': "Double Frais", 'second_account_id': 286, 'account_id': 285, 'company_id': [1, "Demo SPRL"], 'tax_ids': [], 'amount_type': "percentage", 'name': "Double", 'amount': 97.5, 'second_amount': 2.5, 'match_journal_ids': []}, ] }, 'account.reconciliation.widget': { @@ -1249,7 +1249,8 @@ QUnit.module('account', { assert.strictEqual(widget.$('.accounting_view tfoot .cell_right').text(), "$\u00a075.00", "should display 'Open Balance' with 75.00 in right column"); assert.strictEqual(widget.$('.accounting_view tfoot .cell_left').text(), "", "should display 'Open Balance' without any value in left column"); assert.containsN(widget, '.accounting_view tbody tr', 2, "should have 2 created reconcile lines"); - + await testUtils.dom.click(widget.$('[name="tax_ids"] a.o_delete')); + widget.$('.create .create_tax_id input').val('').trigger('keyup').trigger('blur'); await testUtils.dom.click(widget.$('.create .create_tax_id input')); $('.ui-autocomplete .ui-menu-item a:contains(20.00%)').trigger('mouseenter').trigger('click'); await testUtils.nextTick(); diff --git a/addons/account/tests/test_templates_consistency.py b/addons/account/tests/test_templates_consistency.py index af22640de95..015eb5f46ad 100644 --- a/addons/account/tests/test_templates_consistency.py +++ b/addons/account/tests/test_templates_consistency.py @@ -17,7 +17,7 @@ class AccountingTestTemplConsistency(HttpCase): def get_fields(model, extra_domain=None): # Retrieve fields to compare domain = [('model', '=', model), ('state', '=', 'base'), ('related', '=', False), - ('compute', '=', False)] + ('compute', '=', False), ('store', '=', True)] if extra_domain: domain += extra_domain return self.env['ir.model.fields'].search(domain) diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml index 018d21ffbaf..2793b605e79 100644 --- a/addons/account/views/account_view.xml +++ b/addons/account/views/account_view.xml @@ -885,14 +885,14 @@ - - - + context="{'append_type_to_tax_name': True}" + widget="many2many_tags"/> + + attrs="{'invisible': [('show_force_tax_included', '=', False)]}" force_save="1"/> @@ -918,15 +918,14 @@ - - - + + attrs="{'invisible': [('show_second_force_tax_included', '=', False)]}" force_save="1"/> diff --git a/addons/l10n_be/data/account_reconcile_model_template.xml b/addons/l10n_be/data/account_reconcile_model_template.xml index aef848d99dd..36b013ab0f7 100644 --- a/addons/l10n_be/data/account_reconcile_model_template.xml +++ b/addons/l10n_be/data/account_reconcile_model_template.xml @@ -21,7 +21,7 @@ Frais bancaires TVA21 percentage - + 100 Frais bancaires TVA21 diff --git a/addons/l10n_de_skr03/data/account_reconcile_model_template.xml b/addons/l10n_de_skr03/data/account_reconcile_model_template.xml index 50d2945d4ee..779b5d3a776 100644 --- a/addons/l10n_de_skr03/data/account_reconcile_model_template.xml +++ b/addons/l10n_de_skr03/data/account_reconcile_model_template.xml @@ -5,7 +5,7 @@ Skonto-EK-7% percentage - + 100 Skonto-EK-7% @@ -14,7 +14,7 @@ Skonto-EK-19% percentage - + 100 Skonto-EK-19% @@ -23,7 +23,7 @@ Skonto-VK-7% percentage - + 100 Skonto-VK-7% @@ -32,7 +32,7 @@ Skonto-VK-19% percentage - + 100 Skonto-VK-19% @@ -41,7 +41,7 @@ Forderungsverlust-7% percentage - + 100 Forderungsverlust-7% @@ -50,7 +50,7 @@ Forderungsverlust-19% percentage - + 100 Forderungsverlust-19% diff --git a/addons/l10n_de_skr04/data/account_reconcile_model_template.xml b/addons/l10n_de_skr04/data/account_reconcile_model_template.xml index 3a5138b9c59..09025543fad 100644 --- a/addons/l10n_de_skr04/data/account_reconcile_model_template.xml +++ b/addons/l10n_de_skr04/data/account_reconcile_model_template.xml @@ -5,7 +5,7 @@ Skonto-EK-7% percentage - + 100 Skonto-EK-7% @@ -14,7 +14,7 @@ Skonto-EK-19% percentage - + 100 Skonto-EK-19% @@ -23,7 +23,7 @@ Skonto-VK-7% percentage - + 100 Skonto-VK-7% @@ -32,7 +32,7 @@ Skonto-VK-19% percentage - + 100 Skonto-VK-19% @@ -41,7 +41,7 @@ Forderungsverlust-7% percentage - + 100 Forderungsverlust-7% @@ -50,7 +50,7 @@ Forderungsverlust-19% percentage - + 100 Forderungsverlust-19%