Skip to content

Commit 2c24f7e

Browse files
[MIG] purchase_manual_delivery: Migration to 18.0
* Move models and views into their own model file * Integrate with purchase_order_line_menu
1 parent 28b6bb3 commit 2c24f7e

9 files changed

+132
-154
lines changed

purchase_manual_delivery/__manifest__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
and adds the ability to manually generate them as the supplier confirms
99
the different purchase order lines.
1010
""",
11-
"version": "17.0.1.0.0",
11+
"version": "18.0.1.0.0",
1212
"license": "AGPL-3",
1313
"author": "ForgeFlow S.L.," "Odoo Community Association (OCA)",
1414
"website": "https://github.com/OCA/purchase-workflow",
15-
"depends": ["purchase_stock"],
15+
"depends": ["purchase_stock", "purchase_order_line_menu"],
1616
"data": [
1717
"security/ir.model.access.csv",
1818
"wizard/create_manual_stock_picking.xml",
19+
"views/purchase_order_line_views.xml",
1920
"views/purchase_order_views.xml",
2021
"views/res_config_view.xml",
2122
],

purchase_manual_delivery/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
from . import res_company
33
from . import res_config
44
from . import purchase_order
5+
from . import purchase_order_line

purchase_manual_delivery/models/purchase_order.py

-73
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33

44
from odoo import api, fields, models
5-
from odoo.tools import float_compare
65

76

87
class PurchaseOrder(models.Model):
@@ -47,75 +46,3 @@ def _create_picking(self):
4746
# if it comes from manual confirmation
4847
return
4948
return super()._create_picking()
50-
51-
52-
class PurchaseOrderLine(models.Model):
53-
_inherit = "purchase.order.line"
54-
55-
qty_in_receipt = fields.Float(
56-
compute="_compute_qty_in_receipt",
57-
store=True,
58-
digits="Product Unit of Measure",
59-
help="Quantity for which there are pending stock moves",
60-
)
61-
pending_to_receive = fields.Boolean(
62-
compute="_compute_qty_in_receipt",
63-
store=True,
64-
string="Pending Qty to Receive",
65-
help="There is pending quantity to receive not yet planned",
66-
)
67-
68-
@api.depends(
69-
"move_ids",
70-
"move_ids.state",
71-
"move_ids.location_id",
72-
"move_ids.location_dest_id",
73-
"product_uom_qty",
74-
"qty_received",
75-
"state",
76-
)
77-
def _compute_qty_in_receipt(self):
78-
for line in self:
79-
precision_digits = self.env["decimal.precision"].precision_get(
80-
"Product Unit of Measure"
81-
)
82-
total = 0.0
83-
for move in line.move_ids:
84-
if move.state not in ["cancel", "done"]:
85-
if (
86-
move.location_id
87-
== self.order_id.picking_type_id.default_location_dest_id
88-
):
89-
# This is a return to vendor
90-
if move.to_refund:
91-
total -= move.product_uom._compute_quantity(
92-
move.quantity, line.product_uom
93-
)
94-
elif (
95-
move.origin_returned_move_id
96-
and move.origin_returned_move_id._is_dropshipped()
97-
and not move._is_dropshipped_returned()
98-
):
99-
# Edge case: the dropship is returned to the stock,
100-
# no to the supplier.
101-
# In this case, the received quantity on the PO is
102-
# set although we didn't receive the product
103-
# physically in our stock. To avoid counting the
104-
# quantity twice, we do nothing.
105-
pass
106-
else:
107-
total += move.product_uom._compute_quantity(
108-
move.quantity, line.product_uom
109-
)
110-
line.qty_in_receipt = total
111-
if (
112-
float_compare(
113-
line.product_qty,
114-
line.qty_in_receipt + line.qty_received,
115-
precision_digits=precision_digits,
116-
)
117-
== 1
118-
):
119-
line.pending_to_receive = True
120-
else:
121-
line.pending_to_receive = False
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Copyright 2019 ForgeFlow S.L.
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo import api, fields, models
5+
from odoo.tools import float_compare
6+
7+
8+
class PurchaseOrderLine(models.Model):
9+
_inherit = "purchase.order.line"
10+
11+
qty_in_receipt = fields.Float(
12+
compute="_compute_qty_in_receipt",
13+
store=True,
14+
digits="Product Unit of Measure",
15+
help="Quantity for which there are pending stock moves",
16+
)
17+
pending_to_receive = fields.Boolean(
18+
compute="_compute_qty_in_receipt",
19+
store=True,
20+
string="Pending Qty to Receive",
21+
help="There is pending quantity to receive not yet planned",
22+
)
23+
24+
@api.depends(
25+
"move_ids",
26+
"move_ids.state",
27+
"move_ids.location_id",
28+
"move_ids.location_dest_id",
29+
"product_uom_qty",
30+
"qty_received",
31+
"state",
32+
)
33+
def _compute_qty_in_receipt(self):
34+
for line in self:
35+
precision_digits = self.env["decimal.precision"].precision_get(
36+
"Product Unit of Measure"
37+
)
38+
total = 0.0
39+
for move in line.move_ids:
40+
if move.state not in ["cancel", "done"]:
41+
if (
42+
move.location_id
43+
== self.order_id.picking_type_id.default_location_dest_id
44+
):
45+
# This is a return to vendor
46+
if move.to_refund:
47+
total -= move.product_uom._compute_quantity(
48+
move.quantity, line.product_uom
49+
)
50+
elif (
51+
move.origin_returned_move_id
52+
and move.origin_returned_move_id._is_dropshipped()
53+
and not move._is_dropshipped_returned()
54+
):
55+
# Edge case: the dropship is returned to the stock,
56+
# no to the supplier.
57+
# In this case, the received quantity on the PO is
58+
# set although we didn't receive the product
59+
# physically in our stock. To avoid counting the
60+
# quantity twice, we do nothing.
61+
pass
62+
else:
63+
total += move.product_uom._compute_quantity(
64+
move.quantity, line.product_uom
65+
)
66+
line.qty_in_receipt = total
67+
if (
68+
float_compare(
69+
line.product_qty,
70+
line.qty_in_receipt + line.qty_received,
71+
precision_digits=precision_digits,
72+
)
73+
== 1
74+
):
75+
line.pending_to_receive = True
76+
else:
77+
line.pending_to_receive = False

purchase_manual_delivery/tests/test_purchase_manual_delivery.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from odoo import fields
55
from odoo.exceptions import UserError
6-
from odoo.tests.common import Form, TransactionCase
6+
from odoo.tests import Form, TransactionCase
77

88
from odoo.addons.mail.tests.common import mail_new_test_user
99

@@ -207,7 +207,7 @@ def test_01_purchase_order_manual_delivery(self):
207207
"to_refund": False,
208208
}
209209
)
210-
return_wiz.create_returns()
210+
return_wiz.action_create_returns()
211211

212212
# The refund line is open to re-receive the returned item
213213
self.assertTrue(self.po1_line1.pending_to_receive)
@@ -369,7 +369,7 @@ def test_05_purchase_order_in_progress(self):
369369
product_in_progress = self.env["product.product"].create(
370370
{
371371
"name": "Test product pending",
372-
"type": "product",
372+
"type": "consu",
373373
"list_price": 1,
374374
"standard_price": 1,
375375
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo>
3+
4+
<record id="purchase_order_line_tree" model="ir.ui.view">
5+
<field name="model">purchase.order.line</field>
6+
<field name="inherit_id" ref="purchase.purchase_order_line_tree" />
7+
<field name="arch" type="xml">
8+
<xpath expr="/list" position="attributes">
9+
<attribute
10+
name="decoration-info"
11+
>state == 'purchase' and pending_to_receive</attribute>
12+
</xpath>
13+
<field name="product_qty" position="after">
14+
<field name="qty_in_receipt" />
15+
</field>
16+
<field name="date_planned" position="after">
17+
<field name="pending_to_receive" optional="hide" />
18+
</field>
19+
</field>
20+
</record>
21+
22+
<record id="purchase_order_line_search" model="ir.ui.view">
23+
<field name="model">purchase.order.line</field>
24+
<field name="inherit_id" ref="purchase.purchase_order_line_search" />
25+
<field name="arch" type="xml">
26+
<group position="before">
27+
<separator />
28+
<filter
29+
string="Reception confirmed"
30+
name="received"
31+
domain="[('pending_to_receive','=', False), ('state', '=', 'purchase')]"
32+
help="Purchase Order Lines that are confirmed or done and an incoming shipment is created to satisfy them"
33+
/>
34+
<filter
35+
string="Pending to receive"
36+
name="unreceived"
37+
domain="[('pending_to_receive','=', True), ('state', '=', 'purchase')]"
38+
help="Purchase Order Lines that are confirmed or done and no incoming shipment is created to satisfy them"
39+
/>
40+
</group>
41+
</field>
42+
</record>
43+
44+
</odoo>

purchase_manual_delivery/views/purchase_order_views.xml

+1-74
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
column_invisible="parent.state not in ('purchase', 'done')"
5050
/>
5151
</field>
52-
<xpath expr="//field[@name='order_line']/tree" position="attributes">
52+
<xpath expr="//field[@name='order_line']/list" position="attributes">
5353
<attribute
5454
name="decoration-info"
5555
>state == 'purchase' and pending_to_receive</attribute>
@@ -63,77 +63,4 @@
6363
</field>
6464
</record>
6565

66-
<record id="purchase_order_line_tree" model="ir.ui.view">
67-
<field name="model">purchase.order.line</field>
68-
<field name="inherit_id" ref="purchase.purchase_order_line_tree" />
69-
<field name="arch" type="xml">
70-
<xpath expr="/tree" position="attributes">
71-
<attribute
72-
name="decoration-info"
73-
>state == 'purchase' and pending_to_receive</attribute>
74-
</xpath>
75-
<field name="product_qty" position="after">
76-
<field name="qty_in_receipt" />
77-
</field>
78-
<field name="date_planned" position="after">
79-
<field name="pending_to_receive" optional="hide" />
80-
<field name="state" invisible="1" />
81-
</field>
82-
</field>
83-
</record>
84-
85-
<record id="view_purchase_order_unreceived_line_filter" model="ir.ui.view">
86-
<field name="name">purchase.order.unreceived.line</field>
87-
<field name="model">purchase.order.line</field>
88-
<field name="arch" type="xml">
89-
<search string="Search Undelivered Lines">
90-
<field name="order_id" />
91-
<separator />
92-
<filter
93-
string="Reception confirmed"
94-
name="received"
95-
domain="[('pending_to_receive','=', False), ('state', '=', 'purchase')]"
96-
help="Purchase Order Lines that are confirmed or done and an incoming shipment is created to satisfy them"
97-
/>
98-
<filter
99-
string="Pending to receive"
100-
name="unreceived"
101-
domain="[('pending_to_receive','=', True), ('state', '=', 'purchase')]"
102-
help="Purchase Order Lines that are confirmed or done and no incoming shipment is created to satisfy them"
103-
/>
104-
<group expand="0" string="Group By">
105-
<filter
106-
name="purchase"
107-
string="Purchase Order"
108-
context="{'group_by':'order_id'}"
109-
/>
110-
</group>
111-
</search>
112-
</field>
113-
</record>
114-
115-
<record id="action_order_line_delivery_tree" model="ir.actions.act_window">
116-
<field name="name">Purchase Manual Receipt</field>
117-
<field name="type">ir.actions.act_window</field>
118-
<field name="res_model">purchase.order.line</field>
119-
<field name="view_mode">tree,form</field>
120-
<field name="search_view_id" ref="view_purchase_order_unreceived_line_filter" />
121-
<field
122-
name="context"
123-
>{"search_default_unreceived":0, "search_default_received":0}</field>
124-
<field name="filter" eval="True" />
125-
<field name="help" type="html">
126-
<p>
127-
Here is a list of each purchase order line to be received.
128-
</p>
129-
</field>
130-
</record>
131-
132-
<menuitem
133-
id="menu_delivery_purchase_order_lines"
134-
parent="purchase.menu_procurement_management"
135-
action="action_order_line_delivery_tree"
136-
sequence="7"
137-
/>
138-
13966
</odoo>

purchase_manual_delivery/wizard/create_manual_stock_picking.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
/>
2525
</group>
2626
<field name="line_ids" nolabel="1">
27-
<tree create="false" editable="bottom">
27+
<list create="false" editable="bottom">
2828
<field name="purchase_order_line_id" column_invisible="1" />
2929
<field name="product_id" />
3030
<field name="partner_id" />
@@ -36,7 +36,7 @@
3636
<field name="remaining_qty" string="Remaining Qty" />
3737
<field name="qty" string="Quantity" />
3838
<field name="product_uom" groups="uom.group_uom" />
39-
</tree>
39+
</list>
4040
</field>
4141
<footer>
4242
<button

test-requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
git+https://github.com/stefanrijnhart/[email protected]_order_line_menu#subdirectory=purchase_order_line_menu

0 commit comments

Comments
 (0)