diff --git a/account_move_line_sale_info/__manifest__.py b/account_move_line_sale_info/__manifest__.py index 98fc7507..c9604302 100644 --- a/account_move_line_sale_info/__manifest__.py +++ b/account_move_line_sale_info/__manifest__.py @@ -4,13 +4,17 @@ { "name": "Account Move Line Sale Info", "summary": "Introduces the purchase order line to the journal items", - "version": "11.0.1.0.0", + "version": "13.0.1.0.0", "author": "ForgeFlow S.L., " "Odoo Community Association (OCA)", "website": "http://www.github.com/OCA/account-financial-tools", "category": "Generic", - "depends": ["account_move_line_stock_info", "sale"], + "depends": [ + "account_move_line_stock_info", + "sale_stock", + "stock_account_prepare_anglo_saxon_out_lines_hook", + ], "license": "AGPL-3", - "data": ["security/account_security.xml", "views/account_move_view.xml",], + "data": ["security/account_security.xml", "views/account_move_view.xml"], "installable": True, "post_init_hook": "post_init_hook", } diff --git a/account_move_line_sale_info/hooks.py b/account_move_line_sale_info/hooks.py index f47a472f..46c9f0eb 100644 --- a/account_move_line_sale_info/hooks.py +++ b/account_move_line_sale_info/hooks.py @@ -1,8 +1,5 @@ # Copyright 2019 ForgeFlow S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import ast - -from odoo import SUPERUSER_ID, api def post_init_hook(cr, registry): @@ -11,7 +8,7 @@ def post_init_hook(cr, registry): # FOR stock moves cr.execute( """ - update account_move_line aml set sale_line_id = sm.sale_line_id + UPDATE account_move_line aml SET sale_line_id = sm.sale_line_id FROM account_move_line aml2 INNER JOIN stock_move sm ON aml2.stock_move_id = sm.id @@ -21,14 +18,12 @@ def post_init_hook(cr, registry): # FOR invoices cr.execute( """ - update account_move_line aml set sale_line_id = sol.id + UPDATE account_move_line aml SET sale_line_id = sol.id FROM account_move_line aml2 - INNER JOIN account_invoice ai ON - ai.id = aml2.invoice_id - INNER JOIN account_invoice_line ail ON - ail.invoice_id = ai.id + INNER JOIN account_move am ON + am.id = aml2.move_id INNER JOIN sale_order_line_invoice_rel rel ON - rel.invoice_line_id = ail.id + rel.invoice_line_id = aml2.id INNER JOIN sale_order_line sol ON rel.order_line_id = sol.id AND sol.product_id = aml2.product_id @@ -40,7 +35,7 @@ def post_init_hook(cr, registry): cr.execute( """ UPDATE account_move_line aml - SET sale_id = sol.order_id + SET sale_order_id = sol.order_id FROM sale_order_line AS sol WHERE aml.sale_line_id = sol.id RETURNING aml.move_id @@ -53,10 +48,10 @@ def post_init_hook(cr, registry): cr.execute( """ UPDATE account_move_line aml - SET sale_id = so.id - FROM sale_order_line so + SET sale_order_id = so.id + FROM sale_order so LEFT JOIN account_move_line aml2 - ON aml2.sale_id = so.id + ON aml2.sale_order_id = so.id WHERE aml2.move_id = aml.move_id """ ) @@ -66,7 +61,7 @@ def post_init_hook(cr, registry): update account_move_line aml set sale_line_id = sol.id FROM account_move_line aml2 INNER JOIN sale_order so ON - so.id = aml2.sale_id + so.id = aml2.sale_order_id INNER JOIN sale_order_line sol ON so.id = sol.order_id AND sol.product_id = aml2.product_id diff --git a/account_move_line_sale_info/migrations/13.0.1.0.0/pre-migration.py b/account_move_line_sale_info/migrations/13.0.1.0.0/pre-migration.py new file mode 100644 index 00000000..a3055dc5 --- /dev/null +++ b/account_move_line_sale_info/migrations/13.0.1.0.0/pre-migration.py @@ -0,0 +1,12 @@ +# Copyright 2020 ForgeFlow +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade + +_field_renames = [ + ("account.move.line", "account_move_line", "sale_id", "sale_order_id",), +] + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.rename_fields(env, _field_renames) diff --git a/account_move_line_sale_info/models/__init__.py b/account_move_line_sale_info/models/__init__.py index f4c1f16e..c8dea955 100644 --- a/account_move_line_sale_info/models/__init__.py +++ b/account_move_line_sale_info/models/__init__.py @@ -1,6 +1,5 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import account_move -from . import account_invoice from . import sale_order_line from . import stock_move diff --git a/account_move_line_sale_info/models/account_invoice.py b/account_move_line_sale_info/models/account_invoice.py deleted file mode 100644 index 73d8a555..00000000 --- a/account_move_line_sale_info/models/account_invoice.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2020 ForgeFlow S.L. -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). - -from odoo import api, models - - -class AccountInvoice(models.Model): - - _inherit = "account.invoice" - - @api.model - def invoice_line_move_line_get(self): - res = super(AccountInvoice, self).invoice_line_move_line_get() - - invoice_line_model = self.env["account.invoice.line"] - for move_line_dict in res: - if "invl_id" in move_line_dict: - line = invoice_line_model.browse(move_line_dict["invl_id"]) - if line.sale_line_ids and len(line.sale_line_ids) == 1: - move_line_dict["sale_line_id"] = line.sale_line_ids[0].id - return res - - @api.model - def line_get_convert(self, line, part): - res = super(AccountInvoice, self).line_get_convert(line, part) - if line.get("sale_line_id", False): - res["sale_line_id"] = line.get("sale_line_id") - return res - - @api.model - def _anglo_saxon_sale_move_lines(self, i_line): - """ - We need to add the sale_line to those entries too - """ - res = super()._anglo_saxon_sale_move_lines(i_line) - for aml in res: - if i_line.sale_line_ids and len(i_line.sale_line_ids) == 1: - aml["sale_line_id"] = i_line.sale_line_ids[0].id - return res diff --git a/account_move_line_sale_info/models/account_move.py b/account_move_line_sale_info/models/account_move.py index d84d53cc..6e1bff1b 100644 --- a/account_move_line_sale_info/models/account_move.py +++ b/account_move_line_sale_info/models/account_move.py @@ -4,6 +4,49 @@ from odoo import fields, models +class AccountMove(models.Model): + + _inherit = "account.move" + + def _prepare_interim_account_line_vals(self, line, move, debit_interim_account): + res = super()._prepare_interim_account_line_vals( + line, move, debit_interim_account + ) + if ( + not res.get("move_id", False) + or not res.get("product_id", False) + or not res.get("quantity", False) + ): + return res + am = self.env["account.move"].browse(res["move_id"]) + sale_line_id = am.invoice_line_ids.filtered( + lambda il: il.product_id.id == res["product_id"] + and il.quantity == res["quantity"] + ).mapped("sale_line_id") + if sale_line_id and len(sale_line_id) == 1: + res["sale_line_id"] = sale_line_id.id + return res + + def _prepare_expense_account_line_vals(self, line, move, debit_interim_account): + res = super()._prepare_expense_account_line_vals( + line, move, debit_interim_account + ) + if ( + not res.get("move_id", False) + or not res.get("product_id", False) + or not res.get("quantity", False) + ): + return res + am = self.env["account.move"].browse(res["move_id"]) + sale_line_id = am.invoice_line_ids.filtered( + lambda il: il.product_id.id == res["product_id"] + and il.quantity == res["quantity"] + ).mapped("sale_line_id") + if sale_line_id and len(sale_line_id) == 1: + res["sale_line_id"] = sale_line_id.id + return res + + class AccountMoveLine(models.Model): _inherit = "account.move.line" @@ -15,7 +58,7 @@ class AccountMoveLine(models.Model): index=True, ) - sale_id = fields.Many2one( + sale_order_id = fields.Many2one( comodel_name="sale.order", related="sale_line_id.order_id", string="Sales Order", diff --git a/account_move_line_sale_info/models/sale_order_line.py b/account_move_line_sale_info/models/sale_order_line.py index fc103cc4..75f7eeee 100644 --- a/account_move_line_sale_info/models/sale_order_line.py +++ b/account_move_line_sale_info/models/sale_order_line.py @@ -1,19 +1,25 @@ # Copyright 2020 ForgeFlow S.L. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import api, models +from odoo import models class SaleOrderLine(models.Model): _inherit = "sale.order.line" - @api.multi def name_get(self): result = [] orig_name = dict(super(SaleOrderLine, self).name_get()) for line in self: name = orig_name[line.id] if self.env.context.get("so_line_info", False): - name = "[{}] {} ({})".format(line.order_id.name, name, line.order_id.state) + name = "[{}] {} - ({})".format( + line.order_id.name, line.product_id.name, line.order_id.state + ) result.append((line.id, name)) return result + + def _prepare_invoice_line(self): + res = super(SaleOrderLine, self)._prepare_invoice_line() + res["sale_line_id"] = self.id + return res diff --git a/account_move_line_sale_info/models/stock_move.py b/account_move_line_sale_info/models/stock_move.py index 07b1bb0b..4f522e11 100644 --- a/account_move_line_sale_info/models/stock_move.py +++ b/account_move_line_sale_info/models/stock_move.py @@ -8,10 +8,10 @@ class StockMove(models.Model): @api.model def _prepare_account_move_line( - self, qty, cost, credit_account_id, debit_account_id + self, qty, cost, credit_account_id, debit_account_id, description ): res = super(StockMove, self)._prepare_account_move_line( - qty, cost, credit_account_id, debit_account_id + qty, cost, credit_account_id, debit_account_id, description ) for line in res: line[2]["sale_line_id"] = self.sale_line_id.id diff --git a/account_move_line_sale_info/security/account_security.xml b/account_move_line_sale_info/security/account_security.xml index bd3f7e6d..ab6f92cc 100644 --- a/account_move_line_sale_info/security/account_security.xml +++ b/account_move_line_sale_info/security/account_security.xml @@ -3,6 +3,6 @@ Sale info in Journal Items - + diff --git a/account_move_line_sale_info/tests/test_account_move_line_sale_info.py b/account_move_line_sale_info/tests/test_account_move_line_sale_info.py index 29f62d44..7d14e8ce 100644 --- a/account_move_line_sale_info/tests/test_account_move_line_sale_info.py +++ b/account_move_line_sale_info/tests/test_account_move_line_sale_info.py @@ -1,6 +1,5 @@ # Copyright 2020 ForgeFlow S.L. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import fields from odoo.tests import common @@ -9,8 +8,6 @@ class TestAccountMoveLineSaleInfo(common.TransactionCase): super(TestAccountMoveLineSaleInfo, self).setUp() self.sale_model = self.env["sale.order"] self.sale_line_model = self.env["sale.order.line"] - self.invoice_model = self.env["account.invoice"] - self.invoice_line_model = self.env["account.invoice.line"] self.product_model = self.env["product.product"] self.product_ctg_model = self.env["product.category"] self.acc_type_model = self.env["account.account.type"] @@ -58,6 +55,15 @@ class TestAccountMoveLineSaleInfo(common.TransactionCase): self.account_manager = self._create_user( "account_manager", [self.group_account_manager], self.company ) + self.JournalObj = self.env["account.journal"] + self.journal_sale = self.JournalObj.create( + { + "name": "Test journal sale", + "code": "TST-JRNL-S", + "type": "sale", + "company_id": self.company.id, + } + ) def _create_user(self, login, groups, company): """ Create a user.""" @@ -75,8 +81,10 @@ class TestAccountMoveLineSaleInfo(common.TransactionCase): ) return user.id - def _create_account_type(self, name, type): - acc_type = self.acc_type_model.create({"name": name, "type": type}) + def _create_account_type(self, name, atype): + acc_type = self.acc_type_model.create( + {"name": name, "type": atype, "internal_group": name} + ) return acc_type def _create_account(self, acc_type, name, code, company): @@ -124,10 +132,9 @@ class TestAccountMoveLineSaleInfo(common.TransactionCase): line_values = { "name": product.name, "product_id": product.id, - "product_qty": qty, + "product_uom_qty": qty, "product_uom": product.uom_id.id, "price_unit": 500, - "date_planned": fields.datetime.now(), } lines.append((0, 0, line_values)) return self.sale_model.create( @@ -168,55 +175,70 @@ class TestAccountMoveLineSaleInfo(common.TransactionCase): account move line and to the invoice line. """ sale = self._create_sale([(self.product, 1)]) - po_line = False + so_line = False for line in sale.order_line: - po_line = line + so_line = line break - sale.button_confirm() + sale.action_confirm() picking = sale.picking_ids[0] - picking.force_assign() picking.move_lines.write({"quantity_done": 1.0}) picking.button_validate() - expected_balance = 1.0 + expected_balance = -1.0 self._check_account_balance( self.account_inventory.id, - sale_line=po_line, + sale_line=so_line, expected_balance=expected_balance, ) - - invoice = self.invoice_model.create( - { - "partner_id": self.partner1.id, - "sale_id": sale.id, - "account_id": sale.partner_id.property_account_payable_id.id, - } + self.context = { + "active_model": "sale.order", + "active_ids": [sale.id], + "active_id": sale.id, + "default_journal_id": self.journal_sale.id, + } + payment = ( + self.env["sale.advance.payment.inv"] + .with_context(self.context) + .create({"advance_payment_method": "delivered"}) ) - invoice.sale_order_change() - invoice.action_invoice_open() + payment.create_invoices() + invoice = sale.invoice_ids[0] + invoice.post() - for aml in invoice.move_id.line_ids: - if aml.product_id == po_line.product_id and aml.invoice_id: + for aml in invoice.line_ids: + if aml.product_id == so_line.product_id and aml.move_id: self.assertEqual( aml.sale_line_id, - po_line, + so_line, "sale Order line has not been copied " "from the invoice to the account move line.", ) def test_name_get(self): sale = self._create_sale([(self.product, 1)]) - po_line = sale.order_line[0] - name_get = po_line.with_context({"po_line_info": True}).name_get() + so_line = sale.order_line[0] + name_get = so_line.with_context({"so_line_info": True}).name_get() self.assertEqual( name_get, [ ( - po_line.id, - "[%s] %s (%s)" - % (po_line.order_id.name, po_line.name, po_line.order_id.state,), + so_line.id, + "[%s] %s - (%s)" + % ( + so_line.order_id.name, + so_line.product_id.name, + so_line.order_id.state, + ), + ) + ], + ) + name_get_no_ctx = so_line.with_context({}).name_get() + self.assertEqual( + name_get_no_ctx, + [ + ( + so_line.id, + "{} - {}".format(so_line.order_id.name, so_line.product_id.name), ) ], ) - name_get_no_ctx = po_line.name_get() - self.assertEqual(name_get_no_ctx, [(po_line.id, po_line.name)]) diff --git a/account_move_line_sale_info/views/account_move_view.xml b/account_move_line_sale_info/views/account_move_view.xml index 47541062..984543f7 100644 --- a/account_move_line_sale_info/views/account_move_view.xml +++ b/account_move_line_sale_info/views/account_move_view.xml @@ -7,7 +7,7 @@ - + - + @@ -80,7 +82,7 @@ groups="account_move_line_sale_info.group_account_move_sale_info" />