Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][ADD] stock_release_channel_shipment_advice #560

Closed
Closed
6 changes: 6 additions & 0 deletions setup/stock_release_channel_shipment_advice/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
1 change: 0 additions & 1 deletion stock_dynamic_routing/models/stock_routing_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def _constrains_picking_type_location(self):
not record.location_dest_id
or not record.location_dest_id.is_sublocation_of(base_location)
):

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not be part of this PR

raise exceptions.ValidationError(
_(
"Operation type of a rule used as 'push' must have '{}'"
Expand Down
88 changes: 88 additions & 0 deletions stock_release_channel_shipment_advice/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
=====================================
Stock Release Channel Shipment Advice
=====================================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github
:target: https://github.com/OCA/wms/tree/16.0/stock_release_channel_shipment_advice
:alt: OCA/wms
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_shipment_advice
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/wms&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module is used to plan the shipment advices for released pickings in a
stock release channel.

As this is the base module, it only provides a simple planning mode.
All the ready pickings of a release channel are grouped together to result
in a single shipping advice per warehouse.

**Table of contents**

.. contents::
:local:

Usage
=====

To use this module, you need to:

#. Go to Inventory>Release Channels.
#. Select a channel with released picking.
#. Click on "Plan shipment" button.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/wms/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/wms/issues/new?body=module:%20stock_release_channel_shipment_advice%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* ACSONE SA/NV

Contributors
~~~~~~~~~~~~

* Souheil Bejaoui <souheil.bejaoui@acsone.eu>
* Laurent Mignon <laurent.mignon@acsone.eu>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/wms <https://github.com/OCA/wms/tree/16.0/stock_release_channel_shipment_advice>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions stock_release_channel_shipment_advice/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizards
18 changes: 18 additions & 0 deletions stock_release_channel_shipment_advice/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Stock Release Channel Shipment Advice",
"summary": """Plan shipment advices for ready and released pickings""",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/wms",
"depends": ["shipment_advice_planner", "stock_release_channel"],
"data": [
"wizards/shipment_advice_planner.xml",
"views/shipment_advice.xml",
"views/stock_release_channel.xml",
],
"demo": [],
}
2 changes: 2 additions & 0 deletions stock_release_channel_shipment_advice/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import stock_release_channel
from . import shipment_advice
15 changes: 15 additions & 0 deletions stock_release_channel_shipment_advice/models/shipment_advice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ShipmentAdvice(models.Model):
_inherit = "shipment.advice"

release_channel_id = fields.Many2one(
comodel_name="stock.release.channel",
string="Release Channel",
states={"draft": [("readonly", False)]},
readonly=True,
)
133 changes: 133 additions & 0 deletions stock_release_channel_shipment_advice/models/stock_release_channel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.models import NewId


class StockReleaseChannel(models.Model):
_inherit = "stock.release.channel"

shipment_planning_method = fields.Selection(
sbejaoui marked this conversation as resolved.
Show resolved Hide resolved
selection=[("none", "None"), ("simple", "Simple")],
required=True,
default="none",
)
picking_to_plan_ids = fields.Many2many(
comodel_name="stock.picking", compute="_compute_picking_to_plan_ids"
)
can_plan_shipment = fields.Boolean(compute="_compute_can_plan_shipment")
shipment_advice_ids = fields.One2many(
comodel_name="shipment.advice",
inverse_name="release_channel_id",
string="Shipment Advices",
readonly=True,
)
dock_id = fields.Many2one(
sbejaoui marked this conversation as resolved.
Show resolved Hide resolved
comodel_name="stock.dock", domain='[("warehouse_id", "=", warehouse_id)]'
)
warehouse_id = fields.Many2one(inverse="_inverse_warehouse_id")

def button_show_shipment_advice(self):
self.ensure_one()
context = dict(self.env.context, search_default_today=1)
return {
"type": "ir.actions.act_window",
"name": _("Shipment Advice"),
"view_mode": "tree,calendar,form",
"res_model": self.shipment_advice_ids._name,
"domain": [("release_channel_id", "=", self.id)],
"context": context,
}

@api.depends("shipment_planning_method", "picking_to_plan_ids")
def _compute_can_plan_shipment(self):
for rec in self:
rec.can_plan_shipment = (
rec.shipment_planning_method != "none" and rec.picking_to_plan_ids
)

@api.depends("picking_ids", "picking_ids.can_be_planned_in_shipment_advice")
def _compute_picking_to_plan_ids(self):
groups = self.env["stock.picking"].read_group(
domain=[
("release_channel_id", "in", self.ids),
("can_be_planned_in_shipment_advice", "=", True),
],
fields=["release_channel_id", "picking_ids:array_agg(id)"],
groupby=["release_channel_id"],
)
result = {
group["release_channel_id"][0]: group["picking_ids"] for group in groups
}
for rec in self:
channel_id = rec._origin.id if isinstance(rec.id, NewId) else rec.id
if channel_id not in result:
rec.picking_to_plan_ids = False
continue
picking_ids = result.get(channel_id)
can_be_planned_pickings = (
self.env["stock.picking"]
.browse(picking_ids)
.filtered(
lambda p, wh=rec.warehouse_id: not wh
or p.picking_type_id.warehouse_id == wh
)
)
rec.picking_to_plan_ids = can_be_planned_pickings

def button_plan_shipments(self):
self.ensure_one()
if not self.can_plan_shipment:
raise UserError(_("Shipment planning not allowed"))
shipment_advices = self._plan_shipments()
if not shipment_advices:
return {}
return {
"type": "ir.actions.act_window",
"name": _("Shipment Advice"),
"view_mode": "tree,form",
"res_model": shipment_advices._name,
"domain": [("id", "in", shipment_advices.ids)],
"context": self.env.context,
}

def _get_new_planner(self):
self.ensure_one()
sbejaoui marked this conversation as resolved.
Show resolved Hide resolved
sbejaoui marked this conversation as resolved.
Show resolved Hide resolved
planner = self.env["shipment.advice.planner"].new({})
planner.shipment_planning_method = self.shipment_planning_method
planner.release_channel_id = self
planner.warehouse_id = self.warehouse_id
planner.dock_id = self.dock_id
return planner

def _plan_shipments(self):
shipment_advices = self.env["shipment.advice"]
can_plan_channels = self.filtered("can_plan_shipment")
for channel in can_plan_channels:
planner = channel._get_new_planner()
shipment_advices |= planner._plan_shipments_for_method()
return shipment_advices

@api.onchange("warehouse_id")
def _onchange_warehouse_unset_dock(self):
self.update({"dock_id": False})
sbejaoui marked this conversation as resolved.
Show resolved Hide resolved

def _inverse_warehouse_id(self):
self.filtered(lambda c: not c.warehouse_id).update({"dock_id": False})

@api.constrains("warehouse_id", "dock_id")
def _check_warehouse(self):
for rec in self:
if not rec.warehouse_id:
continue
if rec.dock_id and rec.dock_id.warehouse_id != rec.warehouse_id:
raise ValidationError(
_("The dock doesn't belong to the selected warehouse.")
)

@api.onchange("warehouse_id", "dock_id", "picking_to_plan_ids")
def _onchange_check_warehouse(self):
self.ensure_one()
self._check_warehouse()
2 changes: 2 additions & 0 deletions stock_release_channel_shipment_advice/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Souheil Bejaoui <souheil.bejaoui@acsone.eu>
* Laurent Mignon <laurent.mignon@acsone.eu>
6 changes: 6 additions & 0 deletions stock_release_channel_shipment_advice/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
This module is used to plan the shipment advices for released pickings in a
stock release channel.

As this is the base module, it only provides a simple planning mode.
All the ready pickings of a release channel are grouped together to result
in a single shipping advice per warehouse.
5 changes: 5 additions & 0 deletions stock_release_channel_shipment_advice/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
To use this module, you need to:

#. Go to Inventory>Release Channels.
#. Select a channel with released picking.
#. Click on "Plan shipment" button.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.