Skip to content

Commit

Permalink
[FIX] repair_picking: fix migration
Browse files Browse the repository at this point in the history
* Adapt to new repair line type "recycle".
* Propoerly integrate with the other modules in the repo (like `repair_stock` and `repair_type`).
* Simplify logic and make it a bit more robust.
* Add more test lines to make tests more useful.
  • Loading branch information
LoisRForgeFlow committed Feb 20, 2025
1 parent c17ad80 commit de7b0f5
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 130 deletions.
4 changes: 2 additions & 2 deletions repair_picking/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The main features are:

- Customize repair steps: Choose between a 1-step, 2-step, or 3-step
repair process.
- Add and remove components during the repair process using separate
- Add and recycle components during the repair process using separate
picking types.
- Associate repair orders with pickings for improved traceability.
- Automatic creation of pickings and procurement routes based on the
Expand All @@ -60,7 +60,7 @@ Configuration
component, repair", or "Pick component, repair, store removed
component" to define the repair process.
3. Define the "Repair Location", "Add Component to Repair" picking type,
"Remove component from Repair" picking type, and "Repair Route" as
"Recycle component from Repair" picking type, and "Repair Route" as
needed.

Usage
Expand Down
25 changes: 25 additions & 0 deletions repair_picking/migrations/17.0.1.0.0/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (C) 2025 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)

from openupgradelib import openupgrade # pylint: disable=W7936

_field_renames = [
("stock.warehouse", "stock_warehouse", "remove_c_type_id", "recycle_c_type_id"),
]


@openupgrade.migrate()
def migrate(env, version):
cr = env.cr
# Rename operation types
for wh in env["stock.warehouse"].search([]):
if hasattr(wh, "remove_c_type_id") and wh.remove_c_type_id:
wh.recycle_c_type_id.name = wh.recycle_c_type_id.name.replace(
"Remove", "Recycle"
)
# Rename fields
for field in _field_renames:
if openupgrade.table_exists(cr, field[1]) and openupgrade.column_exists(
cr, field[1], field[2]
):
openupgrade.rename_fields(env, _field_renames)
1 change: 0 additions & 1 deletion repair_picking/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from . import stock_warehouse
from . import repair
from . import stock_rule
from . import procurement_group
from . import stock_move
70 changes: 31 additions & 39 deletions repair_picking/models/repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,6 @@
class RepairOrder(models.Model):
_inherit = "repair.order"

@api.model
def _get_default_location_id(self):
warehouse = self.env["stock.warehouse"].search(
[("company_id", "=", self.env.company.id)], limit=1
)
return (
warehouse.repair_location_id.id
if warehouse and warehouse.repair_location_id
else False
)

# Changing default value on existing field
location_id = fields.Many2one(
default=_get_default_location_id,
)
procurement_group_id = fields.Many2one(
"procurement.group", "Procurement Group", copy=False
)
Expand All @@ -36,7 +21,15 @@ def action_repair_cancel(self):

def _action_launch_stock_rule(self, repair_lines):
for line in repair_lines:
self.with_context(should_be_assigned=True)._run_procurement_repair(line)
warehouse = line.repair_id.location_id.warehouse_id
if (
warehouse.repair_steps in ["2_steps", "3_steps"]
and line.repair_line_type == "add"
) or (
warehouse.repair_steps == "3_steps"
and line.repair_line_type == "recycle"
):
self.with_context(should_be_assigned=True)._run_procurement_repair(line)
return True

def _run_procurement_repair(self, line):
Expand Down Expand Up @@ -69,11 +62,11 @@ def _get_procurement_data_repair(self, line):
"company_id": self.company_id,
"warehouse_id": warehouse,
"repair_line_id": line.id,
"repair_id": line.repair_id.id,
"related_repair_id": line.repair_id.id,
}
if line.restrict_lot_id:
procurement_data["restrict_lot_id"] = line.restrict_lot_id.id

Check warning on line 68 in repair_picking/models/repair.py

View check run for this annotation

Codecov / codecov/patch

repair_picking/models/repair.py#L68

Added line #L68 was not covered by tests
if line.repair_line_type == "remove":
if line.repair_line_type == "recycle":
procurement_data[
"source_repair_location_id"
] = line.repair_id.location_id.id
Expand All @@ -86,7 +79,7 @@ def _prepare_procurement_repair(self, line):
location = (
self.location_id
if line.repair_line_type == "add"
else warehouse.remove_c_type_id.default_location_dest_id
else warehouse.recycle_c_type_id.default_location_dest_id
)
procurement = self.env["procurement.group"].Procurement(
line.product_id,
Expand All @@ -101,13 +94,23 @@ def _prepare_procurement_repair(self, line):
return procurement

def _update_stock_moves_and_picking_state(self):
self._compute_picking_ids()
for repair in self:
if repair.move_ids:
add_source_location = repair.move_ids._get_repair_locations("add")[0]
recycle_dest_location = repair.move_ids._get_repair_locations(
"recycle"
)[1]
else:
add_source_location = repair.location_id
recycle_dest_location = repair.location_id
for picking in repair.picking_ids:
if picking.location_dest_id.id == self.location_id.id:
if picking.location_dest_id == add_source_location:
for move_line in picking.move_ids_without_package:
stock_moves = repair.move_ids.filtered(
lambda m: m.repair_line_type == "add"
and m.location_id.id == self.location_id.id
lambda m, asl=add_source_location: m.repair_line_type
== "add"
and m.location_id.id == asl.id
)
if stock_moves:
stock_moves[0].write(
Expand All @@ -116,11 +119,12 @@ def _update_stock_moves_and_picking_state(self):
"state": "waiting",
}
)
if picking.location_id.id == self.location_id.id:
if picking.location_id.id == recycle_dest_location.id:
for move_line in picking.move_ids_without_package:
stock_moves = repair.move_ids.filtered(
lambda m: m.repair_line_type == "remove"
and m.location_dest_id.id == self.location_id.id
lambda m, rdl=recycle_dest_location: m.repair_line_type
== "recycle"
and m.location_dest_id.id == rdl.id
)
if stock_moves:
move_line.write(
Expand All @@ -138,19 +142,7 @@ def _update_stock_moves_and_picking_state(self):
def _action_repair_confirm(self):
res = super()._action_repair_confirm()
for repair in self:
warehouse = repair.location_id.warehouse_id
if warehouse.repair_steps in ["2_steps", "3_steps"]:
repair._action_launch_stock_rule(
repair.move_ids.filtered(
lambda move: move.repair_line_type == "add"
),
)
if warehouse.repair_steps == "3_steps":
repair._action_launch_stock_rule(
repair.move_ids.filtered(
lambda move: move.repair_line_type == "remove"
),
)
repair._action_launch_stock_rule(repair.move_ids)
repair._update_stock_moves_and_picking_state()
return res

Expand All @@ -161,7 +153,7 @@ def _onchange_location_id(self):
if line.repair_line_type == "add":
line.location_id = self.location_id

Check warning on line 154 in repair_picking/models/repair.py

View check run for this annotation

Codecov / codecov/patch

repair_picking/models/repair.py#L154

Added line #L154 was not covered by tests
elif (
line.repair_line_type == "remove"
line.repair_line_type == "recycle"
and warehouse.repair_steps == "3_steps"
):
line.location_dest_id = self.location_id

Check warning on line 159 in repair_picking/models/repair.py

View check run for this annotation

Codecov / codecov/patch

repair_picking/models/repair.py#L159

Added line #L159 was not covered by tests
9 changes: 6 additions & 3 deletions repair_picking/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ class StockMove(models.Model):
_inherit = "stock.move"

def _should_be_assigned(self):
if self.repair_id and self._context.get("should_be_assigned", False):
if (self.related_repair_id or self.repair_id) and self._context.get(
"should_be_assigned", False
):
return True
return super()._should_be_assigned()

Expand All @@ -17,6 +19,7 @@ def create(self, vals_list):
moves = super().create(vals_list)
if not self._context.get("should_be_assigned", False):
for move in moves:
if move.repair_id.state in ["confirmed", "under_repair"]:
move.repair_id._action_launch_stock_rule(move)
repair = move.related_repair_id or move.repair_id
if repair.state in ["confirmed", "under_repair"]:
repair._action_launch_stock_rule(move)
return moves
15 changes: 0 additions & 15 deletions repair_picking/models/stock_rule.py

This file was deleted.

49 changes: 34 additions & 15 deletions repair_picking/models/stock_warehouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ class StockWarehouse(models.Model):
default="1_step",
)
add_c_type_id = fields.Many2one(
"stock.picking.type", string="Add Component to Repair"
comodel_name="stock.picking.type",
string="Add Component to Repair",
help="This operation will be used to move components to repair location "
"when needed by repair lines of type 'Add'.",
)
remove_c_type_id = fields.Many2one(
"stock.picking.type", string="Remove component from Repair"
recycle_c_type_id = fields.Many2one(
comodel_name="stock.picking.type",
string="Recycle component from Repair",
help="This operation will be used to move components out of the repair "
"location when needed by repair lines of type 'Recycle'.",
)
repair_route_id = fields.Many2one("stock.route", string="Repair Route")
repair_location_id = fields.Many2one("stock.location", string="Repair Location")
Expand All @@ -30,12 +36,25 @@ def update_picking_types(self, repair_steps, repair_location_id):
if repair_steps == "1_step":
self.add_c_type_id.active = False
if repair_steps == "3_steps":
self.remove_c_type_id.active = True
self.recycle_c_type_id.active = True
if repair_steps in ["1_step", "2_steps"]:
self.remove_c_type_id.active = False
self.recycle_c_type_id.active = False
if repair_location_id:
self.add_c_type_id.write({"default_location_dest_id": repair_location_id})
self.remove_c_type_id.write({"default_location_src_id": repair_location_id})
self.recycle_c_type_id.write(
{"default_location_src_id": repair_location_id}
)
rep_type_vals = {
"default_recycle_location_dest_id": repair_location_id,
}
if "default_add_location_src_id" in self.repair_type_id._fields:
# Integrate with module `repair_type`.
rep_type_vals.update(
{
"default_add_location_src_id": repair_location_id,
}
)
self.repair_type_id.write(rep_type_vals)

def update_repair_routes(self, repair_steps, repair_location_id):
if repair_steps == "2_steps" or repair_steps == "3_steps":
Expand All @@ -61,11 +80,11 @@ def update_repair_routes(self, repair_steps, repair_location_id):
lambda r: r.picking_type_id == self.add_c_type_id
).write({"location_dest_id": repair_location_id})
self.repair_route_id.rule_ids.filtered(
lambda r: r.picking_type_id == self.remove_c_type_id
lambda r: r.picking_type_id == self.recycle_c_type_id
).write({"location_src_id": repair_location_id})
if repair_steps in ["1_step", "2_steps"]:
self.repair_route_id.rule_ids.filtered(
lambda r: r.picking_type_id == self.remove_c_type_id
lambda r: r.picking_type_id == self.recycle_c_type_id
).active = False

def write(self, vals):
Expand Down Expand Up @@ -106,10 +125,10 @@ def _create_repair_picking_types(self):
warehouse.add_c_type_id.write(
{"default_location_dest_id": repair_location_id}
)
if not warehouse.remove_c_type_id:
if not warehouse.recycle_c_type_id:
par_type = self.env["stock.picking.type"].create(
{
"name": "Remove component from Repair",
"name": "Recycle component from Repair",
"code": "internal",
"sequence_code": "RCR",
"warehouse_id": warehouse.id,
Expand All @@ -118,9 +137,9 @@ def _create_repair_picking_types(self):
"company_id": warehouse.company_id.id,
}
)
warehouse.remove_c_type_id = par_type.id
warehouse.recycle_c_type_id = par_type.id
else:
warehouse.remove_c_type_id.write(
warehouse.recycle_c_type_id.write(
{"default_location_src_id": repair_location_id}
)

Expand Down Expand Up @@ -158,7 +177,7 @@ def _create_remove_rule(self):
.with_context(active_test=False)
.search(
[
("picking_type_id", "=", warehouse.remove_c_type_id.id),
("picking_type_id", "=", warehouse.recycle_c_type_id.id),
("route_id", "=", warehouse.repair_route_id.id),
],
limit=1,
Expand All @@ -167,8 +186,8 @@ def _create_remove_rule(self):
if not existing_rule:
self.env["stock.rule"].create(
{
"name": "Remove component from Repair",
"picking_type_id": warehouse.remove_c_type_id.id,
"name": "Recycle component from Repair",
"picking_type_id": warehouse.recycle_c_type_id.id,
"route_id": warehouse.repair_route_id.id,
"location_src_id": warehouse.repair_location_id.id
or warehouse.view_location_id.id,
Expand Down
2 changes: 1 addition & 1 deletion repair_picking/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
component, repair", or "Pick component, repair, store removed
component" to define the repair process.
3. Define the "Repair Location", "Add Component to Repair" picking
type, "Remove component from Repair" picking type, and "Repair
type, "Recycle component from Repair" picking type, and "Repair
Route" as needed.
2 changes: 1 addition & 1 deletion repair_picking/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The main features are:

- Customize repair steps: Choose between a 1-step, 2-step, or 3-step
repair process.
- Add and remove components during the repair process using separate
- Add and recycle components during the repair process using separate
picking types.
- Associate repair orders with pickings for improved traceability.
- Automatic creation of pickings and procurement routes based on the
Expand Down
4 changes: 2 additions & 2 deletions repair_picking/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ <h1 class="title">Repair Picking</h1>
<ul class="simple">
<li>Customize repair steps: Choose between a 1-step, 2-step, or 3-step
repair process.</li>
<li>Add and remove components during the repair process using separate
<li>Add and recycle components during the repair process using separate
picking types.</li>
<li>Associate repair orders with pickings for improved traceability.</li>
<li>Automatic creation of pickings and procurement routes based on the
Expand Down Expand Up @@ -409,7 +409,7 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
component, repair”, or “Pick component, repair, store removed
component” to define the repair process.</li>
<li>Define the “Repair Location”, “Add Component to Repair” picking type,
Remove component from Repair” picking type, and “Repair Route” as
Recycle component from Repair” picking type, and “Repair Route” as
needed.</li>
</ol>
</div>
Expand Down
Loading

0 comments on commit de7b0f5

Please sign in to comment.