Skip to content

Commit f65390d

Browse files
committed
[MIG] sale_blanket_order to 18.0
- Replace `analytic_account_id` on `blanket.order.line` by using the new `analitic.mixin` from Odoo 18.0. - In `_get_display_price`, fall back to simply using price calculation from `product.pricelist`, triggered by the fact that `product.pricelist` no longer has a `discount_policy` field. - Removed `_get_real_price_currency` method as it is now dead code. - Removed logic in report template for conditionally including/excluding taxes from line subtotals (`account.group_show_line_subtotals_tax_excluded` no longer exists).
1 parent 86434e2 commit f65390d

File tree

10 files changed

+41
-149
lines changed

10 files changed

+41
-149
lines changed

sale_blanket_order/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"category": "Sale",
66
"license": "AGPL-3",
77
"author": "Acsone SA/NV, Odoo Community Association (OCA)",
8-
"version": "17.0.2.0.0",
8+
"version": "18.0.1.0.0",
99
"website": "https://github.com/OCA/sale-workflow",
1010
"summary": "Blanket Orders",
1111
"depends": ["uom", "sale_management"],

sale_blanket_order/data/ir_cron.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
name="nextcall"
1111
eval="(DateTime.now() + relativedelta(hour=00, minute=1, second=0)).strftime('%Y-%m-%d %H:%M:%S')"
1212
/>
13-
<field name="numbercall">-1</field>
14-
<field name="doall" eval="False" />
1513
<field name="model_id" ref="model_sale_blanket_order" />
1614
<field name="state">code</field>
1715
<field name="code">model.expire_orders()</field>

sale_blanket_order/models/blanket_orders.py

Lines changed: 11 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ def _compute_amount_all(self):
6262
required=True,
6363
)
6464
currency_id = fields.Many2one("res.currency", related="pricelist_id.currency_id")
65-
analytic_account_id = fields.Many2one(
66-
comodel_name="account.analytic.account",
67-
string="Analytic Account",
68-
copy=False,
69-
check_company=True,
70-
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
71-
)
7265
payment_term_id = fields.Many2one(
7366
"account.payment.term",
7467
string="Payment Terms",
@@ -243,10 +236,10 @@ def onchange_partner_id(self):
243236
._get_fiscal_position(self.partner_id),
244237
}
245238

246-
if self.partner_id.user_id:
239+
if user := self.partner_id.user_id:
247240
values["user_id"] = self.partner_id.user_id.id
248-
if self.partner_id.team_id:
249-
values["team_id"] = self.partner_id.team_id.id
241+
if user.sale_team_id:
242+
values["team_id"] = user.sale_team_id.id
250243
self.update(values)
251244

252245
def unlink(self):
@@ -273,7 +266,7 @@ def _validate(self):
273266
assert len(order.line_ids) > 0, _("Must have some lines")
274267
order.line_ids._validate()
275268
except AssertionError as e:
276-
raise UserError(e) from e
269+
raise UserError(e)
277270

278271
def set_to_draft(self):
279272
for order in self:
@@ -322,7 +315,7 @@ def action_view_sale_orders(self):
322315

323316
def action_view_sale_blanket_order_line(self):
324317
action = self.env["ir.actions.act_window"]._for_xml_id(
325-
"sale_blanket_order.act_open_sale_blanket_order_lines_view_tree"
318+
"sale_blanket_order.act_open_sale_blanket_order_lines_view_list"
326319
)
327320
lines = self.mapped("line_ids")
328321
if len(lines) > 0:
@@ -387,7 +380,9 @@ def _search_remaining_uom_qty(self, operator, value):
387380
class BlanketOrderLine(models.Model):
388381
_name = "sale.blanket.order.line"
389382
_description = "Blanket Order Line"
390-
_inherit = ["mail.thread", "mail.activity.mixin", "analytic.mixin"]
383+
_inherit = ["analytic.mixin"]
384+
_order = "order_id, sequence, id"
385+
_check_company_auto = True
391386

392387
@api.depends(
393388
"original_uom_qty",
@@ -505,106 +500,19 @@ def _compute_display_name(self):
505500
else:
506501
return super()._compute_display_name()
507502

508-
def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id):
509-
"""Retrieve the price before applying the pricelist
510-
:param obj product: object of current product record
511-
:param float qty: total quentity of product
512-
:param tuple price_and_rule: tuple(price, suitable_rule) coming
513-
from pricelist computation
514-
:param obj uom: unit of measure of current order line
515-
:param integer pricelist_id: pricelist id of sale order"""
516-
# Copied and adapted from the sale module
517-
PricelistItem = self.env["product.pricelist.item"]
518-
field_name = "lst_price"
519-
currency_id = None
520-
product_currency = None
521-
if rule_id:
522-
pricelist_item = PricelistItem.browse(rule_id)
523-
if pricelist_item.pricelist_id.discount_policy == "without_discount":
524-
while (
525-
pricelist_item.base == "pricelist"
526-
and pricelist_item.base_pricelist_id
527-
and pricelist_item.base_pricelist_id.discount_policy
528-
== "without_discount"
529-
):
530-
price, rule_id = pricelist_item.base_pricelist_id.with_context(
531-
uom=uom.id
532-
)._get_product_price_rule(product, qty, uom)
533-
pricelist_item = PricelistItem.browse(rule_id)
534-
535-
if pricelist_item.base == "standard_price":
536-
field_name = "standard_price"
537-
if pricelist_item.base == "pricelist" and pricelist_item.base_pricelist_id:
538-
field_name = "price"
539-
product = product.with_context(
540-
pricelist=pricelist_item.base_pricelist_id.id
541-
)
542-
product_currency = pricelist_item.base_pricelist_id.currency_id
543-
currency_id = pricelist_item.pricelist_id.currency_id
544-
545-
product_currency = (
546-
product_currency
547-
or (product.company_id and product.company_id.currency_id)
548-
or self.env.company.currency_id
549-
)
550-
if not currency_id:
551-
currency_id = product_currency
552-
cur_factor = 1.0
553-
else:
554-
if currency_id.id == product_currency.id:
555-
cur_factor = 1.0
556-
else:
557-
cur_factor = currency_id._get_conversion_rate(
558-
product_currency, currency_id
559-
)
560-
561-
product_uom = product.uom_id.id
562-
if uom and uom.id != product_uom:
563-
# the unit price is in a different uom
564-
uom_factor = uom._compute_price(1.0, product.uom_id)
565-
else:
566-
uom_factor = 1.0
567-
568-
return product[field_name] * uom_factor * cur_factor, currency_id.id
569-
570503
def _get_display_price(self):
571-
# Copied and adapted from the sale module
504+
# Compute the display price for blanket order lines
572505
self.ensure_one()
573506
self.product_id.ensure_one()
574507

575-
pricelist_price = self.pricelist_item_id._compute_price(
508+
return self.pricelist_item_id._compute_price(
576509
product=self.product_id,
577510
quantity=self.original_uom_qty or 1.0,
578511
uom=self.product_uom,
579512
date=fields.Date.today(),
580513
currency=self.currency_id,
581514
)
582515

583-
if self.order_id.pricelist_id.discount_policy == "with_discount":
584-
return pricelist_price
585-
586-
if not self.pricelist_item_id:
587-
# No pricelist rule found => no discount from pricelist
588-
return pricelist_price
589-
590-
base_price = self._get_pricelist_price_before_discount()
591-
592-
# negative discounts (= surcharge) are included in the display price
593-
return max(base_price, pricelist_price)
594-
595-
def _get_pricelist_price_before_discount(self):
596-
# Copied and adapted from the sale module
597-
self.ensure_one()
598-
self.product_id.ensure_one()
599-
600-
return self.pricelist_item_id._compute_price_before_discount(
601-
product=self.product_id,
602-
quantity=self.product_uom_qty or 1.0,
603-
uom=self.product_uom,
604-
date=fields.Date.today(),
605-
currency=self.currency_id,
606-
)
607-
608516
@api.onchange("product_id", "original_uom_qty")
609517
def onchange_product(self):
610518
precision = self.env["decimal.precision"].precision_get(
@@ -687,7 +595,7 @@ def _validate(self):
687595
not line.display_type and line.original_uom_qty > 0.0
688596
) or line.display_type, _("Quantity must be greater than zero")
689597
except AssertionError as e:
690-
raise UserError(e) from e
598+
raise UserError(str(e)) from e
691599

692600
@api.model_create_multi
693601
def create(self, vals_list):

sale_blanket_order/report/templates.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,6 @@
5454
<t
5555
t-set="current_subtotal"
5656
t-value="current_subtotal + l.price_subtotal"
57-
groups="account.group_show_line_subtotals_tax_excluded"
58-
/>
59-
<t
60-
t-set="current_subtotal"
61-
t-value="current_subtotal + l.price_total"
62-
groups="account.group_show_line_subtotals_tax_included"
6357
/>
6458
<tr
6559
t-att-class="'bg-200 fw-bold o_line_section' if l.display_type == 'line_section' else 'fst-italic o_line_note' if l.display_type == 'line_note' else ''"

sale_blanket_order/tests/test_blanket_orders.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,8 @@ def test_01_create_blanket_order(self):
143143
}
144144
)
145145
blanket_order.sudo().onchange_partner_id()
146-
blanket_order.pricelist_id.discount_policy = "without_discount"
147146
blanket_order.line_ids[0].sudo().onchange_product()
148147
self.assertEqual(blanket_order.line_ids[0].taxes_id, self.tax1)
149-
blanket_order.pricelist_id.discount_policy = "with_discount"
150148
blanket_order.line_ids[0].sudo().onchange_product()
151149
blanket_order.line_ids[0].sudo()._get_display_price()
152150

sale_blanket_order/views/sale_blanket_order_line_views.xml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<odoo>
33
<!-- VIEWS -->
44

5-
<record id="sale_blanket_order_line_tree" model="ir.ui.view">
6-
<field name="name">sale.blanket.order.line.tree</field>
5+
<record id="sale_blanket_order_line_list" model="ir.ui.view">
6+
<field name="name">sale.blanket.order.line.list</field>
77
<field name="model">sale.blanket.order.line</field>
88
<field name="arch" type="xml">
9-
<tree create="false">
9+
<list create="false">
1010
<field name="sequence" widget="handle" />
1111
<field name="name" invisible="1" />
1212
<field name="order_id" />
@@ -27,7 +27,7 @@
2727
<field name="delivered_uom_qty" />
2828
<field name="remaining_uom_qty" />
2929
<field name="company_id" invisible="1" />
30-
</tree>
30+
</list>
3131
</field>
3232
</record>
3333

@@ -121,24 +121,29 @@
121121
readonly="1"
122122
/>
123123
</div>
124+
<field
125+
name="analytic_distribution"
126+
widget="analytic_distribution"
127+
groups="analytic.group_analytic_accounting"
128+
options="{
129+
'product_field': 'product_id',
130+
'business_domain': 'sale_order'
131+
}"
132+
/>
124133
</group>
125134
</group>
126135
<notebook>
127136
<page name="sale_lines" string="Sale Order Lines">
128137
<field
129138
name="sale_lines"
130-
mode="tree"
139+
mode="list"
131140
readonly="1"
132141
domain="[('product_id', '=', product_id)]"
133142
/>
134143
</page>
135144
</notebook>
136145
</sheet>
137-
<div class="oe_chatter">
138-
<field name="message_follower_ids" widget="mail_followers" />
139-
<field name="activity_ids" widget="mail_activity" />
140-
<field name="message_ids" widget="mail_thread" />
141-
</div>
146+
<chatter/>
142147
</form>
143148
</field>
144149
</record>
@@ -158,20 +163,20 @@
158163
<!-- ACTIONS (SERVER) -->
159164

160165
<record
161-
id="act_open_sale_blanket_order_lines_view_tree"
166+
id="act_open_sale_blanket_order_lines_view_list"
162167
model="ir.actions.act_window"
163168
>
164169
<field name="name">Blanket Order Lines</field>
165170
<field name="type">ir.actions.act_window</field>
166171
<field name="res_model">sale.blanket.order.line</field>
167-
<field name="view_mode">tree,form</field>
172+
<field name="view_mode">list,form</field>
168173
<field name="search_view_id" ref="sale_blanket_order_line_search" />
169174
</record>
170175

171176
<!-- MENU'S -->
172177

173178
<menuitem
174-
action="act_open_sale_blanket_order_lines_view_tree"
179+
action="act_open_sale_blanket_order_lines_view_list"
175180
id="menu_sale_blanket_order_line"
176181
groups="sales_team.group_sale_salesman"
177182
sequence="21"

sale_blanket_order/views/sale_blanket_order_views.xml

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<odoo>
33
<!-- VIEWS -->
44

5-
<record id="view_blanket_order_tree" model="ir.ui.view">
6-
<field name="name">sale.blanket.order.tree</field>
5+
<record id="view_blanket_order_list" model="ir.ui.view">
6+
<field name="name">sale.blanket.order.list</field>
77
<field name="model">sale.blanket.order</field>
88
<field name="arch" type="xml">
9-
<tree
9+
<list
1010
decoration-info="state == 'draft'"
1111
decoration-muted="state == 'expired'"
1212
>
@@ -21,7 +21,7 @@
2121
optional="show"
2222
readonly="1"
2323
/>
24-
</tree>
24+
</list>
2525
</field>
2626
</record>
2727

@@ -121,7 +121,7 @@
121121
readonly="state in ['open', 'done', 'expired']"
122122
widget="section_and_note_one2many"
123123
>
124-
<tree editable="bottom">
124+
<list editable="bottom">
125125
<control>
126126
<create
127127
name="add_product_control"
@@ -215,7 +215,7 @@
215215
invisible="display_type"
216216
/>
217217
<field name="company_id" invisible="1" />
218-
</tree>
218+
</list>
219219
</field>
220220
<group class="oe_subtotal_footer oe_right">
221221
<field
@@ -273,16 +273,6 @@
273273
groups="base.group_multi_company"
274274
/>
275275
</group>
276-
<group name="invoicing" string="Invoicing">
277-
<t groups="base.group_multi_company">
278-
<field
279-
name="analytic_account_id"
280-
readonly="sale_count != 0 and state != 'draft'"
281-
groups="analytic.group_analytic_accounting"
282-
force_save="1"
283-
/>
284-
</t>
285-
</group>
286276
</group>
287277
</page>
288278
</notebook>
@@ -347,7 +337,7 @@
347337
<field name="name">Blanket Orders</field>
348338
<field name="type">ir.actions.act_window</field>
349339
<field name="res_model">sale.blanket.order</field>
350-
<field name="view_mode">tree,form</field>
340+
<field name="view_mode">list,form</field>
351341
<field name="search_view_id" ref="view_blanket_order_search" />
352342
<field name="domain">[]</field>
353343
<field name="context">{}</field>

sale_blanket_order/views/sale_order_views.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<field name="blanket_order_id" invisible="1" />
1010
</field>
1111
<xpath
12-
expr="//field[@name='order_line']//tree/field[@name='product_id']"
12+
expr="//field[@name='order_line']//list/field[@name='product_id']"
1313
position="after"
1414
>
1515
<field
@@ -28,7 +28,7 @@
2828
<field name="model">sale.order</field>
2929
<field name="inherit_id" ref="sale.view_order_form" />
3030
<field name="arch" type="xml">
31-
<xpath expr="//field[@name='order_line']//tree" position="attributes">
31+
<xpath expr="//field[@name='order_line']//list" position="attributes">
3232
<t groups="sale_blanket_order.blanket_orders_disable_adding_lines">
3333
<attribute name="create">blanket_order_id==False</attribute>
3434
</t>

sale_blanket_order/wizard/create_sale_orders.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ def _prepare_so_vals(
125125
"pricelist_id": pricelist_id,
126126
"payment_term_id": payment_term_id,
127127
"order_line": order_lines_by_customer[customer],
128-
"analytic_account_id": self.blanket_order_id.analytic_account_id.id,
129128
"client_order_ref": client_order_ref,
130129
"tag_ids": [(6, 0, tag_ids.ids)] if tag_ids else False,
131130
}

0 commit comments

Comments
 (0)