Skip to content

Commit

Permalink
[IMP] shipment_advice: Auto close incoming advice
Browse files Browse the repository at this point in the history
If a move is done or cancelled the related incoming shipment advice
will be set to done if all planned moves are done or cancelled

Co-authored-by: vnikolayev1 <[email protected]>
  • Loading branch information
mt-software-de and vnikolayev1 committed Jul 9, 2024
1 parent 80f612f commit cdfcf6d
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 3 deletions.
9 changes: 9 additions & 0 deletions shipment_advice/models/res_company.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields, models
Expand All @@ -23,3 +24,11 @@ class ResCompany(models.Model):
"deliveries will be shipped by several trucks."
),
)
shipment_advice_auto_close_incoming = fields.Boolean(
string="Shipment Advice: Auto Close Incoming Advices",
help=(
"This flag indicates if an incoming shipment advice "
"will be automatically set to done "
"if all related moves are done or cancelled"
),
)
4 changes: 4 additions & 0 deletions shipment_advice/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields, models
Expand All @@ -10,3 +11,6 @@ class ResConfigSettings(models.TransientModel):
shipment_advice_outgoing_backorder_policy = fields.Selection(
related="company_id.shipment_advice_outgoing_backorder_policy", readonly=False
)
shipment_advice_auto_close_incoming = fields.Boolean(
related="company_id.shipment_advice_auto_close_incoming", readonly=False
)
33 changes: 31 additions & 2 deletions shipment_advice/models/shipment_advice.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import _, api, fields, models
Expand Down Expand Up @@ -381,6 +382,8 @@ def _lock_records(self, records):

def action_done(self):
wiz_model = self.env["stock.backorder.confirmation"]
shipment_advice_ids_to_validate = []
self = self.with_context(shipment_advice_ignore_auto_close=True)
for shipment in self:
if shipment.state != "in_progress":
raise UserError(
Expand Down Expand Up @@ -432,10 +435,36 @@ def action_done(self):
lambda m: m.state not in ("cancel", "done") and not m.quantity_done
)
moves_to_unplan.shipment_advice_id = False
shipment.departure_date = fields.Datetime.now()
shipment.state = "done"
shipment_advice_ids_to_validate.append(shipment.id)
if shipment_advice_ids_to_validate:
self.browse(shipment_advice_ids_to_validate)._action_done()
return True

def _action_done(self):
self.write({"departure_date": fields.Datetime.now(), "state": "done"})

def _is_fully_done(self):
self.ensure_one()
if any(move.state not in ["cancel", "done"] for move in self.planned_move_ids):
return False
return True

def auto_close_incoming_shipment_advices(self):
"""Set incoming shipment advices to done when they all moves done or cancelled"""
if self.env.context.get("shipment_advice_ignore_auto_close"):
return
shipment_ids_to_close = []
for shipment_advice in self:
if (
shipment_advice.shipment_type != "incoming"
or not shipment_advice.company_id.shipment_advice_auto_close_incoming
or not shipment_advice._is_fully_done()
):
continue
shipment_ids_to_close.append(shipment_advice.id)
if shipment_ids_to_close:
self.browse(shipment_ids_to_close)._action_done()

def action_cancel(self):
for shipment in self:
if shipment.state not in ("confirmed", "in_progress"):
Expand Down
11 changes: 11 additions & 0 deletions shipment_advice/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields, models
Expand All @@ -23,3 +24,13 @@ def _prepare_merge_moves_distinct_fields(self):
# Avoid having stock move assign to different shipment merged together
res.append("shipment_advice_id")
return res

def _action_done(self, cancel_backorder=False):
res = super()._action_done(cancel_backorder=cancel_backorder)
res.shipment_advice_id.auto_close_incoming_shipment_advices()
return res

def _action_cancel(self):
res = super()._action_cancel()
self.shipment_advice_id.auto_close_incoming_shipment_advices()
return res
1 change: 1 addition & 0 deletions shipment_advice/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Simone Orsi <[email protected]>
* `Trobz <https://trobz.com>`_:
* Dung Tran <[email protected]>
* Michael Tietz (MT Software) <[email protected]>

Design
~~~~~~
Expand Down
1 change: 1 addition & 0 deletions shipment_advice/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from . import test_shipment_advice_picking_values
from . import test_shipment_advice_unload
from . import test_shipment_advice_stock_user
from . import test_shipment_advice_auto_close
16 changes: 15 additions & 1 deletion shipment_advice/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields
from odoo.tests.common import SavepointCase, new_test_user
from odoo.tests.common import Form, SavepointCase, new_test_user


class Common(SavepointCase):
Expand Down Expand Up @@ -202,3 +202,17 @@ def _unload_records_from_shipment(cls, shipment_advice, records):
wiz = wiz_model.create({})
wiz.action_unload()
return wiz

@classmethod
def _validate_picking(cls, picking, qty_done=None):
picking.ensure_one()
for ml in picking.move_line_ids:
ml.qty_done = qty_done or ml.product_uom_qty
action_data = picking.button_validate()
if action_data is True:
return cls.env["stock.picking"]
backorder_wizard = Form(

Check warning on line 214 in shipment_advice/tests/common.py

View check run for this annotation

Codecov / codecov/patch

shipment_advice/tests/common.py#L214

Added line #L214 was not covered by tests
cls.env["stock.backorder.confirmation"].with_context(action_data["context"])
).save()
backorder_wizard.process()
return cls.env["stock.picking"].search([("backorder_id", "=", picking.id)])

Check warning on line 218 in shipment_advice/tests/common.py

View check run for this annotation

Codecov / codecov/patch

shipment_advice/tests/common.py#L217-L218

Added lines #L217 - L218 were not covered by tests
46 changes: 46 additions & 0 deletions shipment_advice/tests/test_shipment_advice_auto_close.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from .common import Common


class TestShipmentAdviceAutoClose(Common):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.shipment_advice_in.company_id.shipment_advice_auto_close_incoming = True
cls.picking1 = cls.move_product_in1.picking_id
group = cls.env["procurement.group"].create({})
cls.move_product_in21 = cls._create_move(
cls.picking_type_in, cls.product_in, 5, group
)
cls.picking2 = cls.move_product_in21.picking_id
cls.pickings = cls.picking1 | cls.picking2
cls._plan_records_in_shipment(cls.shipment_advice_in, cls.pickings)
cls._in_progress_shipment_advice(cls.shipment_advice_in)

def test_auto_close_incoming_on_done(self):
self._validate_picking(self.picking1)
self.assertEqual(self.shipment_advice_in.state, "in_progress")
self._validate_picking(self.picking2)
self.assertEqual(self.shipment_advice_in.state, "done")

def test_auto_close_incoming_on_cancel(self):
self._validate_picking(self.picking1)
self.assertEqual(self.shipment_advice_in.state, "in_progress")
self.picking2.action_cancel()
self.assertEqual(self.shipment_advice_in.state, "done")

def test_no_auto_close_on_outgoing(self):
picking = self.move_product_out1.picking_id
self._plan_records_in_shipment(self.shipment_advice_out, picking)
self._in_progress_shipment_advice(self.shipment_advice_out)
self._validate_picking(picking)
self.assertEqual(picking.state, "done")
self.assertEqual(self.shipment_advice_out.state, "in_progress")

def test_no_auto_close_context(self):
pickings = self.pickings.with_context(shipment_advice_ignore_auto_close=True)
for picking in pickings:
self._validate_picking(picking)
self.assertEqual(self.shipment_advice_in.state, "in_progress")
14 changes: 14 additions & 0 deletions shipment_advice/views/res_config_settings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2021 Camptocamp SA
Copyright 2024 Michael Tietz (MT Software) <[email protected]>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
Expand Down Expand Up @@ -27,6 +28,19 @@
<field name="shipment_advice_outgoing_backorder_policy" />
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="shipment_advice_auto_close_incoming" />
</div>
<div class="o_setting_right_pane">
<label for="shipment_advice_auto_close_incoming" />
<div class="text-muted">
This flag indicates if an incoming shipment advice
will be automatically set to done
if all related moves are done or cancelled
</div>
</div>
</div>
</xpath>
</field>
</record>
Expand Down

0 comments on commit cdfcf6d

Please sign in to comment.