diff --git a/account_invoice_update_wizard/__manifest__.py b/account_invoice_update_wizard/__manifest__.py index e5cf433..f133e87 100644 --- a/account_invoice_update_wizard/__manifest__.py +++ b/account_invoice_update_wizard/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Account Invoice Update Wizard', - 'version': '12.0.1.0.0', + 'version': '14.0.1.0.0', 'category': 'Accounting & Finance', 'license': 'AGPL-3', 'summary': 'Wizard to update non-legal fields of an open/paid invoice', @@ -14,8 +14,9 @@ 'account', ], 'data': [ - 'wizard/account_invoice_update_view.xml', - 'views/account_invoice.xml', - ], - 'installable': False, + 'security/ir.model.access.csv', + 'wizard/account_move_update_view.xml', + 'views/account_move.xml', + ], + 'installable': True, } diff --git a/account_invoice_update_wizard/models/__init__.py b/account_invoice_update_wizard/models/__init__.py index 8e072db..9c0a421 100644 --- a/account_invoice_update_wizard/models/__init__.py +++ b/account_invoice_update_wizard/models/__init__.py @@ -1 +1 @@ -from . import account_invoice +from . import account_move diff --git a/account_invoice_update_wizard/models/account_invoice.py b/account_invoice_update_wizard/models/account_move.py similarity index 60% rename from account_invoice_update_wizard/models/account_invoice.py rename to account_invoice_update_wizard/models/account_move.py index 04a285e..47b5d8c 100644 --- a/account_invoice_update_wizard/models/account_invoice.py +++ b/account_invoice_update_wizard/models/account_move.py @@ -1,17 +1,15 @@ -# Copyright 2019 Camptocamp +# Copyright 2019-2022 Camptocamp # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models, fields, api, _ -from odoo.exceptions import UserError -import odoo.addons.decimal_precision as dp +from odoo import models -class AccountInvoice(models.Model): - _inherit = 'account.invoice' - +class AccountMove(models.Model): + _inherit = 'account.move' + def prepare_update_wizard(self): self.ensure_one() - wizard = self.env['account.invoice.update'] + wizard = self.env['account.move.update'] res = wizard._prepare_default_get(self) action = self.env.ref( 'account_invoice_update_wizard.account_invoice_update_action' @@ -19,4 +17,3 @@ class AccountInvoice(models.Model): action['name'] = "Update Wizard" action['res_id'] = wizard.create(res).id return action - diff --git a/account_invoice_update_wizard/security/ir.model.access.csv b/account_invoice_update_wizard/security/ir.model.access.csv new file mode 100644 index 0000000..329fdda --- /dev/null +++ b/account_invoice_update_wizard/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_move_update,account.move.update.user,model_account_move_update,account.group_account_invoice,1,1,1,1 +access_account_move_line_update,account.move.line.update.user,model_account_move_line_update,account.group_account_invoice,1,1,1,1 diff --git a/account_invoice_update_wizard/tests/__init__.py b/account_invoice_update_wizard/tests/__init__.py index 09720fb..4e3d9df 100644 --- a/account_invoice_update_wizard/tests/__init__.py +++ b/account_invoice_update_wizard/tests/__init__.py @@ -1 +1 @@ -from . import test_account_invoice_update_wizard +from . import test_account_move_update_wizard diff --git a/account_invoice_update_wizard/tests/test_account_invoice_update_wizard.py b/account_invoice_update_wizard/tests/test_account_invoice_update_wizard.py deleted file mode 100644 index ec75d48..0000000 --- a/account_invoice_update_wizard/tests/test_account_invoice_update_wizard.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2018-2019 Camptocamp -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.tests.common import SavepointCase -from odoo.exceptions import UserError - - -class TestAccountInvoiceUpdateWizard(SavepointCase): - - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.customer12 = cls.env.ref('base.res_partner_12') - cls.product16 = cls.env.ref('product.product_product_16') - cls.product24 = cls.env.ref('product.product_product_24') - uom_unit = cls.env.ref('uom.product_uom_categ_unit') - - cls.invoice1 = cls.env['account.invoice'].create({ - 'name': 'Test invoice', - 'partner_id': cls.customer12.id, - }) - cls.inv_line1 = cls.env['account.invoice.line'].create({ - 'invoice_id': cls.invoice1.id, - 'name': "Line1", - 'product_id': cls.product16.id, - 'product_uom_id': uom_unit.id, - 'account_id': cls.invoice1.account_id.id, - 'price_unit': 42.0, - }) - cls.inv_line2 = cls.env['account.invoice.line'].create({ - 'invoice_id': cls.invoice1.id, - 'name': "Line2", - 'product_id': cls.product24.id, - 'product_uom_id': uom_unit.id, - 'account_id': cls.invoice1.account_id.id, - 'price_unit': 1111.1, - }) - - cls.aa1 = cls.env.ref('analytic.analytic_partners_camp_to_camp') - cls.aa2 = cls.env.ref('analytic.analytic_nebula') - cls.atag1 = cls.env.ref('analytic.tag_contract') - cls.atag2 = cls.env['account.analytic.tag'].create({ - 'name': 'の', - }) - - def create_wizard(self, invoice): - res = self.invoice1.prepare_update_wizard() - self.wiz = self.env['account.invoice.update'].browse(res['res_id']) - - def test_add_analytic_account_line1(self): - """ Add analytic account on an invoice line - after the invoice has been approved. - - This will: - - update the move line - - create a new analytic line. - """ - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - wiz_line = self.wiz.line_ids.filtered( - lambda rec: rec.invoice_line_id == self.inv_line1) - wiz_line.account_analytic_id = self.aa1 - self.wiz.run() - - related_ml = self.invoice1.move_id.line_ids.filtered( - lambda rec: rec.product_id == self.product16) - self.assertEqual(related_ml.analytic_account_id, self.aa1) - self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1) - - def test_change_analytic_account_line1(self): - """ Change analytic account on an invoice line - after the invoice has been approved. - - This will: - - update the move line - - update the existing analytic line.""" - self.inv_line1.account_analytic_id = self.aa2 - - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - wiz_line = self.wiz.line_ids.filtered( - lambda rec: rec.invoice_line_id == self.inv_line1) - wiz_line.account_analytic_id = self.aa1 - self.wiz.run() - - related_ml = self.invoice1.move_id.line_ids.filtered( - lambda rec: rec.product_id == self.product16) - self.assertEqual(related_ml.analytic_account_id, self.aa1) - self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1) - - def test_error_grouped_move_lines(self): - """ Change analytic account on an invoice line - after the invoice has been approved where both - lines were grouped in the same move line. - - This will raise an error. - """ - self.invoice1.journal_id.group_invoice_lines = True - - self.inv_line2.product_id = self.product16 - self.inv_line2.unit_price = 42.0 - - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - line1 = self.wiz.line_ids[0] - line1.account_analytic_id = self.aa1 - with self.assertRaises(UserError): - self.wiz.run() - - def test_add_analytic_tags_line1(self): - """ Add analytic tags on an invoice line - after the invoice has been approved. - - This will update move line. - """ - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - wiz_line = self.wiz.line_ids.filtered( - lambda rec: rec.invoice_line_id == self.inv_line1) - wiz_line.analytic_tag_ids = self.atag2 - self.wiz.run() - - related_ml = self.invoice1.move_id.line_ids.filtered( - lambda rec: rec.product_id == self.product16) - self.assertEqual(related_ml.analytic_tag_ids, self.atag2) - self.assertFalse(related_ml.analytic_line_ids) - - def test_change_analytic_tags_line1(self): - """ Change analytic tags on an invoice line - after the invoice has been approved. - - It will update move line and analytic line - """ - self.inv_line1.account_analytic_id = self.aa2 - self.inv_line1.analytic_tag_ids = self.atag1 - - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - wiz_line = self.wiz.line_ids.filtered( - lambda rec: rec.invoice_line_id == self.inv_line1) - wiz_line.analytic_tag_ids = self.atag2 - self.wiz.run() - - related_ml = self.invoice1.move_id.line_ids.filtered( - lambda rec: rec.product_id == self.product16) - self.assertEqual(related_ml.analytic_tag_ids, self.atag2) - self.assertEqual(related_ml.analytic_line_ids.tag_ids, self.atag2) - - def test_add_analytic_info_line1(self): - """ Add analytic account and tags on an invoice line - after the invoice has been approved. - - This will: - - update move line - - create an analytic line - """ - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - wiz_line = self.wiz.line_ids.filtered( - lambda rec: rec.invoice_line_id == self.inv_line1) - wiz_line.account_analytic_id = self.aa1 - wiz_line.analytic_tag_ids = self.atag2 - self.wiz.run() - - related_ml = self.invoice1.move_id.line_ids.filtered( - lambda rec: rec.product_id == self.product16) - self.assertEqual(related_ml.analytic_account_id, self.aa1) - self.assertEqual(related_ml.analytic_tag_ids, self.atag2) - self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1) - self.assertEqual(related_ml.analytic_line_ids.tag_ids, self.atag2) - - def test_empty_analytic_account_line1(self): - """ Remove analytic account - after the invoice has been approved. - - This will raise an error as it is not implemented. - """ - self.inv_line1.account_analytic_id = self.aa2 - - self.invoice1.action_invoice_open() - self.create_wizard(self.invoice1) - - wiz_line = self.wiz.line_ids.filtered( - lambda rec: rec.invoice_line_id == self.inv_line1) - wiz_line.account_analytic_id = False - self.wiz.run() - related_ml = self.invoice1.move_id.line_ids.filtered( - lambda rec: rec.product_id == self.product16) - self.assertFalse(related_ml.analytic_account_id) - self.assertFalse(related_ml.analytic_line_ids) diff --git a/account_invoice_update_wizard/tests/test_account_move_update_wizard.py b/account_invoice_update_wizard/tests/test_account_move_update_wizard.py new file mode 100644 index 0000000..ec6171e --- /dev/null +++ b/account_invoice_update_wizard/tests/test_account_move_update_wizard.py @@ -0,0 +1,173 @@ +# Copyright 2018-2022 Camptocamp +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import SavepointCase + + +class TestAccountInvoiceUpdateWizard(SavepointCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.customer12 = cls.env.ref('base.res_partner_12') + cls.product16 = cls.env.ref('product.product_product_16') + uom_unit = cls.env.ref('uom.product_uom_categ_unit') + + cls.move1 = cls.env['account.move'].create({ + 'name': 'Test invoice', + 'partner_id': cls.customer12.id, + 'move_type': 'out_invoice', + 'invoice_line_ids': [ + [0, None, { + 'name': 'Line1', + 'product_id': cls.product16.id, + 'product_uom_id': uom_unit.id, + 'quantity': 1, + 'price_unit': 42.0, + 'credit': 42.0, + 'debit': 0 + }], + ], + }) + + cls.aa1 = cls.env.ref('analytic.analytic_partners_camp_to_camp') + cls.aa2 = cls.env.ref('analytic.analytic_nebula') + cls.atag1 = cls.env.ref('analytic.tag_contract') + cls.atag2 = cls.env['account.analytic.tag'].create({ + 'name': 'の', + }) + + def create_wizard(self, move): + res = move.prepare_update_wizard() + self.wiz = self.env['account.move.update'].browse(res['res_id']) + + def test_add_analytic_account_line1(self): + """ Add analytic account on a move line + after the move has been approved. + + This will: + - update the move line + - create a new analytic line. + """ + self.move1._post() + self.create_wizard(self.move1) + + wiz_line = self.wiz.line_ids.filtered( + lambda rec: rec.invoice_line_id.product_id.id == self.product16.id) + wiz_line.analytic_account_id = self.aa1 + self.wiz.run() + + related_ml = self.move1.invoice_line_ids.filtered( + lambda rec: rec.product_id == self.product16) + self.assertEqual(related_ml.analytic_account_id, self.aa1) + self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1) + + def test_change_analytic_account_line1(self): + """ Change analytic account on a move line + after the move has been approved. + + This will: + - update the move line + - update the existing analytic line.""" + move_line1 = self.move1.invoice_line_ids.filtered(lambda rec: rec.product_id == self.product16) + move_line1.analytic_account_id = self.aa2 + + self.move1._post() + self.create_wizard(self.move1) + + wiz_line = self.wiz.line_ids.filtered( + lambda rec: rec.invoice_line_id.product_id.id == self.product16.id) + wiz_line.analytic_account_id = self.aa1 + self.wiz.run() + + related_ml = self.move1.invoice_line_ids.filtered( + lambda rec: rec.product_id == self.product16) + self.assertEqual(related_ml.analytic_account_id, self.aa1) + self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1) + + def test_add_analytic_tags_line1(self): + """ Add analytic tags on a move line + after the move has been approved. + + This will update move line. + """ + self.move1._post() + self.create_wizard(self.move1) + + wiz_line = self.wiz.line_ids.filtered( + lambda rec: rec.invoice_line_id.product_id.id == self.product16.id) + wiz_line.analytic_tag_ids = self.atag2 + self.wiz.run() + + related_ml = self.move1.invoice_line_ids.filtered( + lambda rec: rec.product_id == self.product16) + self.assertEqual(related_ml.analytic_tag_ids, self.atag2) + self.assertFalse(related_ml.analytic_line_ids) + + def test_change_analytic_tags_line1(self): + """ Change analytic tags on a move line + after the move has been approved. + + It will update move line and analytic line + """ + move_line1 = self.move1.invoice_line_ids.filtered(lambda rec: rec.product_id == self.product16) + move_line1.analytic_account_id = self.aa2 + move_line1.analytic_tag_ids = self.atag1 + + self.move1._post() + self.create_wizard(self.move1) + + wiz_line = self.wiz.line_ids.filtered( + lambda rec: rec.invoice_line_id.product_id.id == self.product16.id) + wiz_line.analytic_tag_ids = self.atag2 + self.wiz.run() + + related_ml = self.move1.invoice_line_ids.filtered( + lambda rec: rec.product_id == self.product16) + self.assertEqual(related_ml.analytic_tag_ids, self.atag2) + self.assertEqual(related_ml.analytic_line_ids.tag_ids, self.atag2) + + def test_add_analytic_info_line1(self): + """ Add analytic account and tags on a move line + after the move has been approved. + + This will: + - update move line + - create an analytic line + """ + self.move1._post() + self.create_wizard(self.move1) + + wiz_line = self.wiz.line_ids.filtered( + lambda rec: rec.invoice_line_id.product_id.id == self.product16.id) + wiz_line.analytic_account_id = self.aa1 + wiz_line.analytic_tag_ids = self.atag2 + self.wiz.run() + + related_ml = self.move1.invoice_line_ids.filtered( + lambda rec: rec.product_id == self.product16) + self.assertEqual(related_ml.analytic_account_id, self.aa1) + self.assertEqual(related_ml.analytic_tag_ids, self.atag2) + self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1) + self.assertEqual(related_ml.analytic_line_ids.tag_ids, self.atag2) + + def test_empty_analytic_account_line1(self): + """ Remove analytic account + after the move has been approved. + + This will raise an error as it is not implemented. + """ + move_line1 = self.move1.invoice_line_ids.filtered(lambda rec: rec.product_id == self.product16) + move_line1.analytic_account_id = self.aa2 + + self.move1._post() + self.create_wizard(self.move1) + + wiz_line = self.wiz.line_ids.filtered( + lambda rec: rec.invoice_line_id.product_id.id == self.product16.id) + wiz_line.analytic_account_id = False + self.wiz.run() + related_ml = self.move1.invoice_line_ids.filtered( + lambda rec: rec.product_id == self.product16) + self.assertFalse(related_ml.analytic_account_id) + self.assertFalse(related_ml.analytic_line_ids) diff --git a/account_invoice_update_wizard/views/account_invoice.xml b/account_invoice_update_wizard/views/account_invoice.xml deleted file mode 100644 index ad44634..0000000 --- a/account_invoice_update_wizard/views/account_invoice.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - account.invoice - - - - - - - - account.invoice - - - - - - - diff --git a/account_invoice_update_wizard/views/account_move.xml b/account_invoice_update_wizard/views/account_move.xml new file mode 100644 index 0000000..b142b8b --- /dev/null +++ b/account_invoice_update_wizard/views/account_move.xml @@ -0,0 +1,19 @@ + + + + + + + account.move + + + + + + + diff --git a/account_invoice_update_wizard/wizard/__init__.py b/account_invoice_update_wizard/wizard/__init__.py index 9a89518..ecfa4a4 100644 --- a/account_invoice_update_wizard/wizard/__init__.py +++ b/account_invoice_update_wizard/wizard/__init__.py @@ -1 +1 @@ -from . import account_invoice_update +from . import account_move_update diff --git a/account_invoice_update_wizard/wizard/account_invoice_update.py b/account_invoice_update_wizard/wizard/account_move_update.py similarity index 72% rename from account_invoice_update_wizard/wizard/account_invoice_update.py rename to account_invoice_update_wizard/wizard/account_move_update.py index e3f8f58..cae7176 100644 --- a/account_invoice_update_wizard/wizard/account_invoice_update.py +++ b/account_invoice_update_wizard/wizard/account_move_update.py @@ -1,5 +1,5 @@ # Copyright 2017 Akretion (Alexis de Lattre ) -# Copyright 2018-2019 Camptocamp +# Copyright 2018-2022 Camptocamp # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields, api, _ @@ -7,38 +7,37 @@ from odoo.exceptions import UserError import odoo.addons.decimal_precision as dp -class AccountInvoiceUpdate(models.TransientModel): - _name = 'account.invoice.update' +class AccountMoveUpdate(models.TransientModel): + _name = 'account.move.update' _description = 'Wizard to update non-legal fields of invoice' invoice_id = fields.Many2one( - 'account.invoice', string='Invoice', required=True, + 'account.move', string='Invoice', required=True, readonly=True) - type = fields.Selection(related='invoice_id.type', readonly=True) + type = fields.Selection(related='invoice_id.move_type', readonly=True) company_id = fields.Many2one( related='invoice_id.company_id', readonly=True) partner_id = fields.Many2one( related='invoice_id.partner_id', readonly=True) user_id = fields.Many2one('res.users', string='Salesperson') - payment_term_id = fields.Many2one( + invoice_payment_term_id = fields.Many2one( 'account.payment.term', string='Payment Term') - reference = fields.Char(string='Invoice Reference') + ref = fields.Char(string='Invoice Reference') name = fields.Char(string='Reference/Description') - origin = fields.Char(string='Source Document') - comment = fields.Text('Additional Information') + invoice_origin = fields.Char(string='Source Document') partner_bank_id = fields.Many2one( 'res.partner.bank', string='Bank Account') line_ids = fields.One2many( - 'account.invoice.line.update', 'parent_id', string='Invoice Lines') + 'account.move.line.update', 'parent_id', string='Invoice Lines') @api.model def _simple_fields2update(self): '''List boolean, date, datetime, char, text fields''' - return ['reference', 'name', 'origin', 'comment'] + return ['ref', 'name', 'invoice_origin'] @api.model def _m2o_fields2update(self): - return ['payment_term_id', 'user_id', 'partner_bank_id'] + return ['invoice_payment_term_id', 'user_id', 'partner_bank_id'] @api.model def _prepare_default_get(self, invoice): @@ -55,7 +54,7 @@ class AccountInvoiceUpdate(models.TransientModel): 'name': line.name, 'quantity': line.quantity, 'price_subtotal': line.price_subtotal, - 'account_analytic_id': line.account_analytic_id.id, + 'analytic_account_id': line.analytic_account_id.id, 'analytic_tag_ids': aa_tags, 'display_type': line.display_type, }]) @@ -72,7 +71,6 @@ class AccountInvoiceUpdate(models.TransientModel): "[('partner_id', '=', partner_id)]" return res - @api.multi def _prepare_invoice(self): vals = {} inv = self.invoice_id @@ -82,8 +80,8 @@ class AccountInvoiceUpdate(models.TransientModel): for m2ofield in self._m2o_fields2update(): if self[m2ofield] != inv[m2ofield]: vals[m2ofield] = self[m2ofield].id or False - if 'payment_term_id' in vals: - pterm_list = self.payment_term_id.compute( + if 'invoice_payment_term_id' in vals: + pterm_list = self.invoice_payment_term_id.compute( value=1, date_ref=inv.date_invoice)[0] if pterm_list: vals['date_due'] = max(line[0] for line in pterm_list) @@ -91,15 +89,15 @@ class AccountInvoiceUpdate(models.TransientModel): @api.model def _line_simple_fields2update(self): - return ["name",] + return ["name"] @api.model def _line_m2o_fields2update(self): - return ["account_analytic_id",] + return ["analytic_account_id"] @api.model def _line_m2m_fields2update(self): - return ["analytic_tag_ids",] + return ["analytic_tag_ids"] @api.model def _prepare_invoice_line(self, line): @@ -115,87 +113,45 @@ class AccountInvoiceUpdate(models.TransientModel): vals[field] = [(6, 0, line[field].ids)] return vals - @api.multi - def _prepare_move(self): - mvals = {} - inv = self.invoice_id - ini_ref = inv.move_id.ref - ref = inv.reference or inv.name - if ini_ref != ref: - mvals['ref'] = ref - return mvals - - @api.multi - def _get_matching_inv_line(self, move_line): - """ Find matching invoice line by product """ - # TODO make it accept more case as lines won't - # be grouped unless journal.group_invoice_line is True - inv_line = self.invoice_id.invoice_line_ids.filtered( - lambda rec: rec.product_id == move_line.product_id) - if len(inv_line) != 1: - raise UserError( - "Cannot match a single invoice line to move line %s" % - move_line.name) - return inv_line - - @api.multi - def _prepare_move_line(self, inv_line): + def _prepare_move_line_and_analytic_line(self, inv_line): mlvals = {} - inv_line_upd = self.line_ids.filtered( - lambda rec: rec.invoice_line_id == inv_line) - - ini_aa = inv_line.account_analytic_id - new_aa = inv_line_upd.account_analytic_id - - if ini_aa != new_aa: - mlvals['analytic_account_id'] = new_aa.id - - ini_aa_tags = inv_line.analytic_tag_ids - new_aa_tags = inv_line_upd.analytic_tag_ids - - if ini_aa_tags != new_aa_tags: - mlvals['analytic_tag_ids'] = [(6, None, new_aa_tags.ids)] - return mlvals - - @api.multi - def _prepare_analytic_line(self, inv_line): alvals = {} inv_line_upd = self.line_ids.filtered( lambda rec: rec.invoice_line_id == inv_line) - ini_aa = inv_line.account_analytic_id - new_aa = inv_line_upd.account_analytic_id + ini_aa = inv_line.analytic_account_id + new_aa = inv_line_upd.analytic_account_id if ini_aa != new_aa: + mlvals['analytic_account_id'] = new_aa.id alvals['account_id'] = new_aa.id ini_aa_tags = inv_line.analytic_tag_ids new_aa_tags = inv_line_upd.analytic_tag_ids if ini_aa_tags != new_aa_tags: + mlvals['analytic_tag_ids'] = [(6, None, new_aa_tags.ids)] alvals['tag_ids'] = [(6, None, new_aa_tags.ids)] - return alvals + return mlvals, alvals - @api.multi def _update_payment_term_move(self): self.ensure_one() inv = self.invoice_id if ( - self.payment_term_id and - self.payment_term_id != inv.payment_term_id and - inv.move_id): + self.invoice_payment_term_id and + self.invoice_payment_term_id != inv.invoice_payment_term_id): # I don't update pay term when the invoice is partially (or fully) # paid because if you have a payment term with several lines # of the same amount, you would also have to take into account # the reconcile marks to put the new maturity date on the right # lines - if inv.payment_ids: + if inv.payment_id: raise UserError(_( "This wizard doesn't support the update of payment " "terms on an invoice which is partially or fully " "paid.")) prec = self.env['decimal.precision'].precision_get('Account') - term_res = self.payment_term_id.compute( + term_res = self.invoice_payment_term_id.compute( inv.amount_total, inv.date_invoice)[0] new_pterm = {} # key = int(amount * 100), value = [date1, date2] for entry in term_res: @@ -220,11 +176,10 @@ class AccountInvoiceUpdate(models.TransientModel): "new payment term '%s'. You can only switch to a " "payment term that has the same number of terms " "with the same amount.") % ( - inv.payment_term_id.name, self.payment_term_id.name)) + inv.invoice_payment_term_id.name, self.invoice_payment_term_id.name)) for line in lines: line.date_maturity = new_pterm[iamount].pop() - @api.multi def run(self): self.ensure_one() inv = self.invoice_id @@ -235,28 +190,24 @@ class AccountInvoiceUpdate(models.TransientModel): if ivals: updated = True inv.write(ivals) - if inv.move_id: - mvals = self._prepare_move() - if mvals: - inv.move_id.write(mvals) - for ml in inv.move_id.line_ids.filtered( + if inv: + for ml in inv.line_ids.filtered( # we are only interested in invoice lines, not tax lines lambda rec: bool(rec.product_id) ): if ml.credit == 0.0: continue - inv_line = self._get_matching_inv_line(ml) - mlvals = self._prepare_move_line(inv_line) + analytic_account = ml.analytic_account_id + mlvals, alvals = self._prepare_move_line_and_analytic_line(ml) if mlvals: updated = True ml.write(mlvals) aalines = ml.analytic_line_ids - alvals = self._prepare_analytic_line(inv_line) if aalines and alvals: updated = True if ('account_id' in alvals and alvals['account_id'] is False): - former_aa = inv_line.account_analytic_id + former_aa = analytic_account to_remove_aalines = aalines.filtered( lambda rec: rec.account_id == former_aa) # remove existing analytic line @@ -279,14 +230,14 @@ class AccountInvoiceUpdate(models.TransientModel): return True -class AccountInvoiceLineUpdate(models.TransientModel): - _name = 'account.invoice.line.update' +class AccountMoveLineUpdate(models.TransientModel): + _name = 'account.move.line.update' _description = 'Update non-legal fields of invoice lines' parent_id = fields.Many2one( - 'account.invoice.update', string='Wizard', ondelete='cascade') + 'account.move.update', string='Wizard', ondelete='cascade') invoice_line_id = fields.Many2one( - 'account.invoice.line', string='Invoice Line', readonly=True) + 'account.move.line', string='Invoice Line', readonly=True) name = fields.Text(string='Description', required=True) display_type = fields.Selection([ ('line_section', "Section"), @@ -296,7 +247,7 @@ class AccountInvoiceLineUpdate(models.TransientModel): readonly=True) price_subtotal = fields.Float( string='Amount', readonly=True, digits=dp.get_precision('Account')) - account_analytic_id = fields.Many2one( + analytic_account_id = fields.Many2one( 'account.analytic.account', string='Analytic Account') analytic_tag_ids = fields.Many2many( 'account.analytic.tag', string='Analytic Tags') diff --git a/account_invoice_update_wizard/wizard/account_invoice_update_view.xml b/account_invoice_update_wizard/wizard/account_move_update_view.xml similarity index 83% rename from account_invoice_update_wizard/wizard/account_invoice_update_view.xml rename to account_invoice_update_wizard/wizard/account_move_update_view.xml index 78eb2bb..31ca6e9 100644 --- a/account_invoice_update_wizard/wizard/account_invoice_update_view.xml +++ b/account_invoice_update_wizard/wizard/account_move_update_view.xml @@ -7,7 +7,7 @@ - account.invoice.update + account.move.update
@@ -15,13 +15,12 @@ - - + + - + - @@ -31,7 +30,7 @@ - + @@ -46,7 +45,7 @@ Invoice Update Wizard - account.invoice.update + account.move.update form new