Skip to content

Commit

Permalink
[17.0][MIG] stock_reserve_sale: migration to V17
Browse files Browse the repository at this point in the history
  • Loading branch information
astirpe committed Apr 22, 2024
1 parent e29646f commit f9e092d
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 108 deletions.
2 changes: 1 addition & 1 deletion stock_reserve_sale/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Stock Reserve Sales
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:c8bff29850116b499cd76c5813113489be840f32653162635c18d9a691dbf78e
!! source digest: sha256:0252821802e05031e45ee21a476cc66bcbac1af5de9e9d01fe240cd460e49ea2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion stock_reserve_sale/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Stock Reserve Sales",
"version": "16.0.1.0.0",
"version": "17.0.1.0.0",
"author": "Camptocamp, Odoo Community Association (OCA)",
"category": "Warehouse",
"license": "AGPL-3",
Expand Down
49 changes: 14 additions & 35 deletions stock_reserve_sale/model/sale.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.exceptions import UserError
from odoo.osv import expression
from odoo.tools.translate import _

_LINE_KEYS = ["product_id", "product_uom_qty"]
Expand Down Expand Up @@ -31,50 +30,34 @@ def _compute_stock_reservation(self):
has_stock_reservation = fields.Boolean(
compute="_compute_stock_reservation",
readonly=True,
multi="stock_reservation",
store=True,
string="Has Stock Reservations",
)
is_stock_reservable = fields.Boolean(
compute="_compute_stock_reservation",
readonly=True,
multi="stock_reservation",
store=True,
string="Can Have Stock Reservations",
)
reserves_count = fields.Integer(compute="_compute_reserves_count")
all_lines_reserved = fields.Boolean(
compute="_compute_reserves_count", store=True, default=False
)
all_lines_reserved = fields.Boolean(compute="_compute_reserves_count", store=False)

def release_all_stock_reservation(self):
line_ids = [line.id for order in self for line in order.order_line]
lines = self.order_line.browse(line_ids)
lines = self.mapped("order_line")
lines.release_stock_reservation()
return True

def _compute_reserves_count(self):
reserve_ids = self.env["stock.reservation"]._read_group(
domain=expression.AND(
[
[("sale_id", "in", self.ids)],
]
),
fields=["sale_id"],
groupby=["sale_id"],
)
lines = self.order_line.filtered(
lambda l: l.product_id.detailed_type != "service"
reserves = self.env["stock.reservation"].search(
[("sale_id", "in", self.ids)],
)
for order in self:
if reserve_ids:
order.reserves_count = reserve_ids[0]["sale_id_count"]
else:
order.reserves_count = 0
if order.reserves_count == len(lines):
order.all_lines_reserved = True
else:
order.all_lines_reserved = False
lines = order.order_line.filtered(
lambda ln: ln.product_id.detailed_type != "service"
)
reserves_count = len(reserves.filtered(lambda rsv, order: rsv.sale_id == order))
order.reserves_count = reserves_count
order.all_lines_reserved = bool(reserves_count == len(lines))

def action_view_reserves_products(self):
action = self.env["ir.actions.act_window"]._for_xml_id(
Expand All @@ -85,14 +68,11 @@ def action_view_reserves_products(self):
return action

def action_view_reserves_stock_picking(self):
stock_picking = ""
action = self.env["ir.actions.actions"]._for_xml_id(
"stock.action_picking_tree_all"
)
stock_picking = (
self.env["stock.picking"]
.search([("origin", "=", self.name)])
.filtered(lambda a: a.state not in "cancel")
stock_picking = self.env["stock.picking"].search(
[("origin", "=", self.name), ("state", "!=", "cancel")], limit=1
)
if stock_picking:
view_id = self.env.ref("stock.view_picking_form").id
Expand Down Expand Up @@ -133,7 +113,7 @@ def get_message(self, old_vals, new_vals):
old_product = old_vals["product_id"].display_name
new_product = ProductProduct.browse(new_vals["product_id"]).display_name
body += _("<div> <b>Product</b>: ")
body += "{} → {}</div>".format(old_product, new_product)
body += f"{old_product}{new_product}</div>"
if "product_uom_qty" in new_vals:
if "product_id" not in new_vals:
body += _("<div> <b>Product</b>: %s") % (
Expand All @@ -152,9 +132,8 @@ def unlink(self):
if order.has_stock_reservation:
raise UserError(
_(
"Sale Order %s has some reserved lines.\n"
f"Sale Order {order.name} has some reserved lines.\n"
"Please unreserve this lines before delete the order."
)
% (order.name)
)
return super().unlink()
43 changes: 17 additions & 26 deletions stock_reserve_sale/model/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,45 @@
# Copyright 2023 - Hugo Córdoba - FactorLibre - (hugo.cordoba@factorlibre.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.exceptions import UserError, except_orm
from odoo.exceptions import UserError
from odoo.tools.translate import _


class SaleOrderLine(models.Model):
_inherit = "sale.order.line"

reservation_ids = fields.One2many(
"stock.reservation", "sale_line_id", string="Stock Reservation", copy=False
)
is_stock_reservable = fields.Boolean(
compute="_compute_is_stock_reservable", readonly=True, string="Can be reserved"
)
is_readonly = fields.Boolean(compute="_compute_is_readonly", store=False)

def _get_line_rule(self):
"""Get applicable rule for this product
Reproduce get suitable rule from procurement
to predict source location
"""
StockRule = self.env["stock.rule"]
product = self.product_id
product_route_ids = [
x.id for x in product.route_ids + product.categ_id.total_route_ids
]
product_route_ids = (product.route_ids + product.categ_id.total_route_ids).ids
rules = StockRule.search(
[("route_id", "in", product_route_ids)],
order="route_sequence, sequence",
limit=1,
)
if not rules:
warehouse = self.order_id.warehouse_id
wh_routes = warehouse.route_ids
wh_route_ids = [route.id for route in wh_routes]
wh_route_ids = warehouse.route_ids.ids
domain = [
"|",
("warehouse_id", "=", warehouse.id),
("warehouse_id", "=", False),
("route_id", "in", wh_route_ids),
]
rules = StockRule.search(domain, order="route_sequence, sequence")
if rules:
fields.first(rules)
return False
rules = StockRule.search(domain, order="route_sequence, sequence", limit=1)
return rules

def _get_procure_method(self):
"""Get procure_method depending on product routes"""
Expand Down Expand Up @@ -69,17 +72,8 @@ def _compute_is_readonly(self):
len(line.reservation_ids) > 0 or line.order_id.state != "draft"
)

reservation_ids = fields.One2many(
"stock.reservation", "sale_line_id", string="Stock Reservation", copy=False
)
is_stock_reservable = fields.Boolean(
compute="_compute_is_stock_reservable", readonly=True, string="Can be reserved"
)
is_readonly = fields.Boolean(compute="_compute_is_readonly", store=False)

def release_stock_reservation(self):
reserv_ids = [reserv.id for line in self for reserv in line.reservation_ids]
reservations = self.env["stock.reservation"].browse(reserv_ids)
reservations = self.reservation_ids
reservations.release_reserve()
return True

Expand All @@ -93,8 +87,7 @@ def write(self, vals):
for line in self:
if not line.reservation_ids:
continue
raise except_orm(
_("Error"),
raise UserError(
_(
"You cannot change the product or unit of measure "
"of lines with a stock reservation. "
Expand All @@ -108,8 +101,7 @@ def write(self, vals):
if not line.reservation_ids:
continue
if len(line.reservation_ids) > 1:
raise except_orm(
_("Error"),
raise UserError(
_(
"Several stock reservations are linked with the "
"line. Impossible to adjust their quantity. "
Expand All @@ -130,10 +122,9 @@ def unlink(self):
if line.reservation_ids:
raise UserError(
_(
"Sale order line '['%(order_name)s'] '%(line_name)s'' has a "
f"Sale order line '['{line.order_id.name}'] '{line.name}' has a "
"related reservation.\n"
"Please unreserve this line before delete the line"
)
% {"order_name": line.order_id.name, "line_name": line.name}
)
return super().unlink()
13 changes: 5 additions & 8 deletions stock_reserve_sale/model/stock_reserve.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,19 @@ class StockReservation(models.Model):
)

def release_reserve(self):
for rec in self:
rec.sale_line_id = False
self.update({"sale_line_id": False})
return super().release_reserve()

def action_view_reserves_stock_picking_reservation(self):
stock_picking = ""
stock_picking = self.env["stock.picking"]
action = self.env["ir.actions.actions"]._for_xml_id(
"stock.action_picking_tree_all"
)
if self.sale_id:
stock_picking = (
self.env["stock.picking"]
.search([("origin", "=", self.sale_id.name)])
.filtered(lambda a: a.state not in "cancel")
stock_picking = self.env["stock.picking"].search(
[("origin", "=", self.sale_id.name), ("state", "!=", "cancel")], limit=1
)
if stock_picking:
view_id = self.env.ref("stock.view_picking_form").id
action.update(views=[(view_id, "form")], res_id=stock_picking.id)
return action
return action
2 changes: 1 addition & 1 deletion stock_reserve_sale/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Stock Reserve Sales</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:c8bff29850116b499cd76c5813113489be840f32653162635c18d9a691dbf78e
!! source digest: sha256:0252821802e05031e45ee21a476cc66bcbac1af5de9e9d01fe240cd460e49ea2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-warehouse/tree/17.0/stock_reserve_sale"><img alt="OCA/stock-logistics-warehouse" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-warehouse-17-0/stock-logistics-warehouse-17-0-stock_reserve_sale"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Allows to create stock reservations for quotation lines before the
Expand Down
36 changes: 14 additions & 22 deletions stock_reserve_sale/view/sale.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
type="object"
name="action_view_reserves_products"
icon="fa-lock"
attrs="{'invisible': [('reserves_count', '=', 0)]}"
invisible="reserves_count == 0"
>
<field string="Reserved" name="reserves_count" widget="statinfo" />
<field name="reserves_count" invisible="1" />
Expand All @@ -24,7 +24,7 @@
type="object"
name="action_view_reserves_stock_picking"
icon="fa-truck"
attrs="{'invisible': ['|', ('reserves_count', '=', 0),('state', '!=', 'draft')]}"
invisible="reserves_count == 0 or state != 'draft'"
/>
</xpath>
<button name="action_quotation_send" position="before">
Expand All @@ -34,7 +34,7 @@
type="action"
string="Reserve Stock"
help="Pre-book products from stock"
attrs="{'invisible': ['|', ('all_lines_reserved', '=', True), ('state', '!=', 'draft')]}"
invisible="all_lines_reserved or state != 'draft'"
/>
</button>
<field name="order_line" position="attributes">
Expand All @@ -49,15 +49,13 @@
name="%(action_sale_stock_reserve)d"
type="action"
string="Reserve Stock"
attrs="{'invisible': ['|', ('reservation_ids', '!=', []),
('state', '!=', 'draft')]}"
invisible="reservation_ids or state != 'draft'"
/>
<button
name="release_stock_reservation"
type="object"
string="Release Reservation"
attrs="{'invisible': ['|', ('reservation_ids', '=', []),
('state', '!=', 'draft')]}"
invisible="not reservation_ids or state != 'draft'"
/>
</xpath>
<xpath
Expand All @@ -69,14 +67,16 @@
<button
name="%(action_sale_stock_reserve)d"
type="action"
title="Reserve Stock"
icon="fa-lock"
attrs="{'invisible': [('is_stock_reservable', '=', False)]}"
invisible="not is_stock_reservable"
/>
<button
name="release_stock_reservation"
type="object"
title="Release Stock Reservation"
icon="fa-undo"
attrs="{'invisible': [('reservation_ids', '=', [])]}"
invisible="not reservation_ids"
/>
</xpath>
<field name="user_id" position="before">
Expand All @@ -87,7 +87,7 @@
name="release_all_stock_reservation"
string="Cancell all reserve"
type="object"
attrs="{'invisible': [('has_stock_reservation', '=', False)]}"
invisible="not has_stock_reservation"
/>
</xpath>
<!-- Make readonly the fields quantity and product_id when they are reserved -->
Expand All @@ -101,17 +101,13 @@
expr="//field[@name='order_line']/form//field[@name='product_uom_qty']"
position="attributes"
>
<attribute
name="attrs"
>{'readonly': [('is_readonly', '=', True)]}</attribute>
<attribute name="readonly">is_readonly</attribute>
</xpath>
<xpath
expr="//field[@name='order_line']/form//field[@name='product_id']"
position="attributes"
>
<attribute
name="attrs"
>{'readonly': [('is_readonly', '=', True)]}</attribute>
<attribute name="readonly">is_readonly</attribute>
</xpath>
<xpath
expr="//field[@name='order_line']/tree/field[@name='product_id']"
Expand All @@ -123,17 +119,13 @@
expr="//field[@name='order_line']/tree/field[@name='product_uom_qty']"
position="attributes"
>
<attribute
name="attrs"
>{'readonly': [('is_readonly', '=', True)]}</attribute>
<attribute name="readonly">is_readonly</attribute>
</xpath>
<xpath
expr="//field[@name='order_line']/tree/field[@name='product_id']"
position="attributes"
>
<attribute
name="attrs"
>{'readonly': [('is_readonly', '=', True)]}</attribute>
<attribute name="readonly">is_readonly</attribute>
</xpath>
</field>
</record>
Expand Down
Loading

0 comments on commit f9e092d

Please sign in to comment.