Skip to content

Commit 7fd29f4

Browse files
committed
[MIG] purchase_invoice_new_picking_line: Migration to 16.0
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
1 parent f9d8def commit 7fd29f4

File tree

5 files changed

+93
-88
lines changed

5 files changed

+93
-88
lines changed

purchase_invoice_new_picking_line/__manifest__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{
55
"name": "Purchase Invoice New Picking Line",
66
"summary": "When creating an invoice from incoming picking, also adds invoice lines for product that were not in the purchase order",
7-
"version": "15.0.1.0.0",
7+
"version": "16.0.1.0.0",
88
"author": "Coop IT Easy SCRLfs, Odoo Community Association (OCA)",
99
"category": "Purchase",
1010
"license": "AGPL-3",
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from . import account_invoice
1+
from . import purchase_order

purchase_invoice_new_picking_line/models/account_invoice.py

-79
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# SPDX-FileCopyrightText: 2024 Coop IT Easy
2+
#
3+
# SPDX-License-Identifier: AGPL-3.0-or-later
4+
5+
from odoo import api, fields, models
6+
from odoo.fields import Command
7+
from odoo.tools.float_utils import float_compare, float_round
8+
9+
10+
class PurchaseOrder(models.Model):
11+
_inherit = "purchase.order"
12+
13+
def _prepare_account_move_lines_from_stock_move(
14+
self, stock_move_id, account_move_id
15+
):
16+
self.ensure_one()
17+
18+
qty = max(stock_move_id.quantity_done, 0)
19+
date = stock_move_id.date or fields.Date.today()
20+
supplierinfo = self.env["product.supplierinfo"]
21+
price_unit = 0.0
22+
if self.partner_id:
23+
supplierinfo = stock_move_id.product_id._select_seller(
24+
partner_id=self.partner_id,
25+
quantity=qty,
26+
date=date,
27+
uom_id=stock_move_id.product_uom,
28+
params={"order_id": self},
29+
)
30+
if supplierinfo:
31+
price_unit = supplierinfo.price
32+
else:
33+
price_unit = stock_move_id.product_id.lst_price
34+
taxes = stock_move_id.product_id.supplier_taxes_id.filtered(
35+
lambda tax: tax.company_id == self.company_id
36+
)
37+
tax_ids = self.fiscal_position_id.map_tax(taxes) # TODO not sure about this
38+
39+
data = {
40+
"display_type": "product",
41+
# Normally the name is '{order_name}: {order_line_name}'.
42+
"name": "%s: %s" % (stock_move_id.picking_id.name, stock_move_id.name),
43+
"product_id": stock_move_id.product_id.id,
44+
"product_uom_id": stock_move_id.product_uom.id,
45+
"quantity": qty,
46+
"price_unit": self.currency_id._convert(
47+
price_unit,
48+
self.company_id.currency_id,
49+
self.company_id,
50+
date,
51+
round=False,
52+
),
53+
"tax_ids": [Command.set(tax_ids.ids)],
54+
}
55+
56+
return data
57+
58+
def add_missing_picking_products_to_account_move(self, account_move_id):
59+
stock_moves = self.env["stock.move"]
60+
for picking in self.picking_ids.filtered(lambda x: x.state == "done"):
61+
stock_moves |= picking.move_ids.filtered(
62+
lambda move: move.state == "done" and not move.purchase_line_id
63+
)
64+
new_lines_data = [
65+
self._prepare_account_move_lines_from_stock_move(
66+
stock_move, account_move_id
67+
)
68+
for stock_move in stock_moves
69+
]
70+
account_move_id.write(
71+
{"invoice_line_ids": [Command.create(line) for line in new_lines_data]}
72+
)
73+
74+
def action_create_invoice(self):
75+
result = super().action_create_invoice()
76+
res_id = result.get("res_id")
77+
if not res_id:
78+
return result
79+
invoice_id = self.env["account.move"].browse(res_id)
80+
self.add_missing_picking_products_to_account_move(invoice_id)
81+
return result

purchase_invoice_new_picking_line/tests/test_invoice.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def test_move_line_product_is_added_to_invoice(self):
1818
purchase_order.button_confirm()
1919
picking = purchase_order.picking_ids
2020
moves = picking.move_ids_without_package
21-
self.assertEquals(len(purchase_order.order_line), len(moves))
21+
self.assertEqual(len(purchase_order.order_line), len(moves))
2222

2323
moves[0].quantity_done = moves[0].product_qty
2424
moves[1].quantity_done = moves[1].product_qty
@@ -37,17 +37,20 @@ def test_move_line_product_is_added_to_invoice(self):
3737
)
3838

3939
wizard = picking.button_validate()
40-
backorder_confirmation = self.env[wizard["res_model"]].browse(
41-
wizard["res_id"]
40+
# TODO: this doesn't seem right to me. Previously, button_validate()
41+
# created a stock.backorder.confirmation. Now, only the defaults are put
42+
# in the context, meaning we have to manually create it.
43+
backorder_confirmation = (
44+
self.env[wizard["res_model"]].with_context(wizard["context"]).create({})
4245
)
4346
backorder_confirmation.process_cancel_backorder()
4447

45-
res = purchase_order.with_context(
46-
create_bill=True
47-
).action_view_invoice()
48+
res = purchase_order.with_context(create_bill=True).action_view_invoice()
49+
# TODO: There is no key 'context' here. In fact, res is empty, because
50+
# purchase_order.invoice_ids is an empty recordset.
4851
ctx = res.get("context")
4952
f = Form(
50-
self.env["account.invoice"].with_context(ctx),
53+
self.env["account.move"].with_context(ctx),
5154
view="account.invoice_supplier_form",
5255
)
5356
invoice = f.save()

0 commit comments

Comments
 (0)