diff options
| author | Cedric Snauwaert <csn@openerp.com> | 2018-09-13 14:23:43 +0000 |
|---|---|---|
| committer | Cedric Snauwaert <csn@openerp.com> | 2019-03-12 09:25:15 +0000 |
| commit | 4d7f0526122084e7be08212bd5ef9935603605ff (patch) | |
| tree | 065b8186a5b4e15c6a4e31bfbfc5804a802e5db9 /addons | |
| parent | 3b9483f170d6280f6e39ad0acd4a39dbcb112f55 (diff) | |
[FIX] account: change reconciliation widget m2o tax_id to a m2m tax_ids
closes odoo/odoo#26990
Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
Diffstat (limited to 'addons')
11 files changed, 170 insertions, 144 deletions
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('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('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_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<value.length; i++) { + res.push({id: value[i], display_name: this.taxes[value[i]] ? this.taxes[value[i]].display_name : ''}); + } + return res; + }, /** * Format each propositions (amount, label, account_id) * @@ -1121,10 +1143,11 @@ var StatementModel = BasicModel.extend({ 'analytic_account_id': this._formatNameGet(values.analytic_account_id), 'analytic_tag_ids': this._formatMany2ManyTags(values.analytic_tag_ids || []), 'journal_id': this._formatNameGet(values.journal_id), - 'tax_id': this._formatNameGet(values.tax_id), + 'tax_ids': this._formatMany2ManyTagsTax(values.tax_ids || []), 'debit': 0, 'credit': 0, 'date': values.date ? values.date : field_utils.parse.date(today, {}, {isUTC: true}), + 'force_tax_included': values.force_tax_included || false, 'base_amount': values.amount_type !== "percentage" ? (amount) : line.balance.amount * values.amount / 100, 'percent': values.amount_type === "percentage" ? values.amount : null, @@ -1143,18 +1166,6 @@ var StatementModel = BasicModel.extend({ prop.base_amount = sign * field_utils.parse.monetary(amount, {}, formatOptions); } - if(prop.tax_id){ - // Set the amount_type value. - prop.tax_id.amount_type = this.taxes[prop.tax_id.id].amount_type; - // Set the price_include value. - prop.tax_id.price_include = this.taxes[prop.tax_id.id].price_include; - } - - // Set the force_tax_included value. - if(prop.tax_id && values.force_tax_included !== undefined) - prop.force_tax_included = values.force_tax_included; - else if(prop.tax_id && this.taxes[prop.tax_id.id].price_include) - prop.force_tax_included = this.taxes[prop.tax_id.id].price_include; prop.amount = prop.base_amount; return prop; }, @@ -1264,9 +1275,9 @@ var StatementModel = BasicModel.extend({ } if (!isNaN(prop.id)) result.counterpart_aml_id = prop.id; if (prop.analytic_account_id) result.analytic_account_id = prop.analytic_account_id.id; - if (prop.tax_id && !prop.is_tax) result.tax_ids = [[4, prop.tax_id.id, null]]; - if (prop.tax_id && prop.is_tax) result.tax_line_id = prop.tax_id.id; - if (prop.reconcileModelId) result.reconcile_model_id = prop.reconcileModelId; + if (prop.tax_ids && prop.tax_ids.length && !prop.is_tax) result.tax_ids = [[6, null, _.pluck(prop.tax_ids, 'id')]]; + if (prop.tax_ids && prop.tax_ids.length && prop.is_tax) result.tax_line_id = prop.tax_ids[0].id; + if (prop.reconcileModelId) result.reconcile_model_id = prop.reconcileModelId return result; }, /** @@ -1288,7 +1299,7 @@ var StatementModel = BasicModel.extend({ * datas allowing manual reconciliation */ var ManualModel = StatementModel.extend({ - quickCreateFields: ['account_id', 'journal_id', 'amount', 'analytic_account_id', 'label', 'tax_id', 'force_tax_included', 'analytic_tag_ids', 'date', 'to_check'], + quickCreateFields: ['account_id', 'journal_id', 'amount', 'analytic_account_id', 'label', 'tax_ids', 'force_tax_included', 'analytic_tag_ids', 'date', 'to_check'], //-------------------------------------------------------------------------- // Public diff --git a/addons/account/static/src/js/reconciliation/reconciliation_renderer.js b/addons/account/static/src/js/reconciliation/reconciliation_renderer.js index 1887102522f..7e432a0e0a5 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_renderer.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_renderer.js @@ -428,38 +428,51 @@ var LineRenderer = Widget.extend(FieldManagerMixin, { } Promise.resolve(createPromise).then(function(){ var data = self.model.get(self.handleCreateRecord).data; - self.model.notifyChanges(self.handleCreateRecord, state.createForm).then(function () { + return self.model.notifyChanges(self.handleCreateRecord, state.createForm) + .then(function () { // FIXME can't it directly written REPLACE_WITH ids=state.createForm.analytic_tag_ids - self.model.notifyChanges(self.handleCreateRecord, {analytic_tag_ids: {operation: 'REPLACE_WITH', ids: []}}).then(function (){ + return self.model.notifyChanges(self.handleCreateRecord, {analytic_tag_ids: {operation: 'REPLACE_WITH', ids: []}}) + }) + .then(function (){ var defs = []; _.each(state.createForm.analytic_tag_ids, function (tag) { defs.push(self.model.notifyChanges(self.handleCreateRecord, {analytic_tag_ids: {operation: 'ADD_M2M', ids: tag}})); }); - Promise.all(defs).then(function () { - var record = self.model.get(self.handleCreateRecord); - _.each(self.fields, function (field, fieldName) { - if (self._avoidFieldUpdate[fieldName]) return; - if (fieldName === "partner_id") return; - if ((data[fieldName] || state.createForm[fieldName]) && !_.isEqual(state.createForm[fieldName], data[fieldName])) { - field.reset(record); + return Promise.all(defs); + }) + .then(function () { + return self.model.notifyChanges(self.handleCreateRecord, {tax_ids: {operation: 'REPLACE_WITH', ids: []}}) + }) + .then(function (){ + var defs = []; + _.each(state.createForm.tax_ids, function (tag) { + defs.push(self.model.notifyChanges(self.handleCreateRecord, {tax_ids: {operation: 'ADD_M2M', ids: tag}})); + }); + return Promise.all(defs); + }) + .then(function () { + var record = self.model.get(self.handleCreateRecord); + _.each(self.fields, function (field, fieldName) { + if (self._avoidFieldUpdate[fieldName]) return; + if (fieldName === "partner_id") return; + if ((data[fieldName] || state.createForm[fieldName]) && !_.isEqual(state.createForm[fieldName], data[fieldName])) { + field.reset(record); + } + if (fieldName === 'tax_ids') { + if (!state.createForm[fieldName].length || state.createForm[fieldName].length > 1) { + $('.create_force_tax_included').addClass('d-none'); } - if (fieldName === 'tax_id') { - if (!state.createForm[fieldName] || state.createForm[fieldName].amount_type === "group") { - $('.create_force_tax_included').addClass('d-none'); - } - else { - $('.create_force_tax_included').removeClass('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 @@ <td class="o_td_field"></td> </tr> <tr class="create_tax_id"> - <td class="o_td_label">Tax</td> + <td class="o_td_label">Taxes</td> <td class="o_td_field"></td> </tr> <tr class="create_analytic_account_id" groups="analytic.group_analytic_accounting"> 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 @@ <field name="account_id" domain="[('company_id', '=', company_id)]" attrs="{'required': ['|', ('rule_type', '!=', 'invoice_matching'), '&', '&', ('rule_type', '=', 'invoice_matching'), ('match_total_amount', '=', True), ('match_total_amount_param', '!=', 100.0)]}"/> <field name="amount_type"/> - <field name="tax_id" + <field name="tax_ids" domain="[('company_id', '=', company_id)]" options="{'no_create': True}" - context="{'append_type_to_tax_name': True}"/> - <field name="is_tax_price_included" invisible="1"/> - <field name="tax_amount_type" invisible="1"/> + context="{'append_type_to_tax_name': True}" + widget="many2many_tags"/> + <field name="show_force_tax_included" invisible="1"/> <field name="force_tax_included" - attrs="{'invisible': ['|', ('tax_id', '=', False), ('tax_amount_type', '=', 'group')], 'readonly': [('is_tax_price_included', '=', True)]}" force_save="1"/> + attrs="{'invisible': [('show_force_tax_included', '=', False)]}" force_save="1"/> <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/> <field name="analytic_tag_ids" groups="analytic.group_analytic_tags" widget="many2many_tags"/> <field name="company_id" groups="base.group_multi_company"/> @@ -918,15 +918,14 @@ <field name="second_account_id" string="Account" domain="[('company_id', '=', company_id)]" attrs="{'required': [('has_second_line', '=', True), '|', ('rule_type', '!=', 'invoice_matching'), '&', '&', ('rule_type', '=', 'invoice_matching'), ('match_total_amount', '=', True), ('match_total_amount_param', '!=', 100.0)]}"/> <field name="second_amount_type" string="Amount type"/> - <field name="second_tax_id" - string="Tax" + <field name="second_tax_ids" + string="Taxes" domain="[('company_id', '=', company_id)]" - widget="selection" + widget="many2many_tags" context="{'append_type_to_tax_name': True}"/> - <field name="is_second_tax_price_included" invisible="1"/> - <field name="second_tax_amount_type" invisible="1"/> + <field name="show_second_force_tax_included" invisible="1"/> <field name="force_second_tax_included" - attrs="{'invisible': ['|', ('second_tax_id', '=', False), ('second_tax_amount_type', '=', 'group')], 'readonly': [('is_second_tax_price_included', '=', True)]}" force_save="1"/> + attrs="{'invisible': [('show_second_force_tax_included', '=', False)]}" force_save="1"/> <field name="second_analytic_account_id" string="Analytic Account" groups="analytic.group_analytic_accounting"/> <field name="second_analytic_tag_ids" groups="analytic.group_analytic_tags" widget="many2many_tags"/> </group> 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 @@ <field name="name">Frais bancaires TVA21</field> <field name="account_id" ref="a656"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="attn_TVA-21-inclus-dans-prix"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_be.attn_TVA-21-inclus-dans-prix')])]"/> <field name="amount">100</field> <field name="label">Frais bancaires TVA21</field> </record> 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 @@ <field name="name">Skonto-EK-7%</field> <field name="account_id" ref="account_3731"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_vst_7_taxinclusive_skr03"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr03.tax_vst_7_taxinclusive_skr03')])]"/> <field name="amount">100</field> <field name="label">Skonto-EK-7%</field> <field name="chart_template_id" ref="l10n_de_chart_template"/> @@ -14,7 +14,7 @@ <field name="name">Skonto-EK-19%</field> <field name="account_id" ref="account_3736"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_vst_19_taxinclusive_skr03"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr03.tax_vst_19_taxinclusive_skr03')])]"/> <field name="amount">100</field> <field name="label">Skonto-EK-19%</field> <field name="chart_template_id" ref="l10n_de_chart_template"/> @@ -23,7 +23,7 @@ <field name="name">Skonto-VK-7%</field> <field name="account_id" ref="account_8731"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_7_taxinclusive_skr03"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr03.tax_ust_7_taxinclusive_skr03')])]"/> <field name="amount">100</field> <field name="label">Skonto-VK-7%</field> <field name="chart_template_id" ref="l10n_de_chart_template"/> @@ -32,7 +32,7 @@ <field name="name">Skonto-VK-19%</field> <field name="account_id" ref="account_8736"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_19_taxinclusive_skr03"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr03.tax_ust_19_taxinclusive_skr03')])]"/> <field name="amount">100</field> <field name="label">Skonto-VK-19%</field> <field name="chart_template_id" ref="l10n_de_chart_template"/> @@ -41,7 +41,7 @@ <field name="name">Forderungsverlust-7%</field> <field name="account_id" ref="account_2401"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_7_taxinclusive_skr03"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr03.tax_ust_7_taxinclusive_skr03')])]"/> <field name="amount">100</field> <field name="label">Forderungsverlust-7%</field> <field name="chart_template_id" ref="l10n_de_chart_template"/> @@ -50,7 +50,7 @@ <field name="name">Forderungsverlust-19%</field> <field name="account_id" ref="account_2406"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_19_taxinclusive_skr03"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr03.tax_ust_19_taxinclusive_skr03')])]"/> <field name="amount">100</field> <field name="label">Forderungsverlust-19%</field> <field name="chart_template_id" ref="l10n_de_chart_template"/> 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 @@ <field name="name">Skonto-EK-7%</field> <field name="account_id" ref="chart_skr04_5731"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_vst_7_taxinclusive_skr04"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr04.tax_vst_7_taxinclusive_skr04')])]"/> <field name="amount">100</field> <field name="label">Skonto-EK-7%</field> <field name="chart_template_id" ref="l10n_chart_de_skr04"/> @@ -14,7 +14,7 @@ <field name="name">Skonto-EK-19%</field> <field name="account_id" ref="chart_skr04_5736"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_vst_19_taxinclusive_skr04"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr04.tax_vst_19_taxinclusive_skr04')])]"/> <field name="amount">100</field> <field name="label">Skonto-EK-19%</field> <field name="chart_template_id" ref="l10n_chart_de_skr04"/> @@ -23,7 +23,7 @@ <field name="name">Skonto-VK-7%</field> <field name="account_id" ref="chart_skr04_4731"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_7_taxinclusive_skr04"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr04.tax_ust_7_taxinclusive_skr04')])]"/> <field name="amount">100</field> <field name="label">Skonto-VK-7%</field> <field name="chart_template_id" ref="l10n_chart_de_skr04"/> @@ -32,7 +32,7 @@ <field name="name">Skonto-VK-19%</field> <field name="account_id" ref="chart_skr04_4736"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_19_taxinclusive_skr04"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr04.tax_ust_19_taxinclusive_skr04')])]"/> <field name="amount">100</field> <field name="label">Skonto-VK-19%</field> <field name="chart_template_id" ref="l10n_chart_de_skr04"/> @@ -41,7 +41,7 @@ <field name="name">Forderungsverlust-7%</field> <field name="account_id" ref="chart_skr04_6931"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_7_taxinclusive_skr04"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr04.tax_ust_7_taxinclusive_skr04')])]"/> <field name="amount">100</field> <field name="label">Forderungsverlust-7%</field> <field name="chart_template_id" ref="l10n_chart_de_skr04"/> @@ -50,7 +50,7 @@ <field name="name">Forderungsverlust-19%</field> <field name="account_id" ref="chart_skr04_6936"/> <field name="amount_type">percentage</field> - <field name="tax_id" ref="tax_ust_19_taxinclusive_skr04"/> + <field name="tax_ids" eval="[(6, 0, [ref('l10n_de_skr04.tax_ust_19_taxinclusive_skr04')])]"/> <field name="amount">100</field> <field name="label">Forderungsverlust-19%</field> <field name="chart_template_id" ref="l10n_chart_de_skr04"/> |
