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_process_end_time #550

Merged
merged 10 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions setup/stock_release_channel_process_end_time/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,
)
109 changes: 109 additions & 0 deletions stock_release_channel_process_end_time/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
======================================
Stock Release Channel Process End Date
======================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:84e66197d5580b417a6dc94e376b88b6466a007cd8946990b65689e9dea8647e
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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_process_end_time
: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_process_end_time
: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 allows to set an end time on a release channel that will be transmitted on
related stock pickings (on scheduled date) when the channel awakes.

That allows to use Odoo core sorting feature on stock pickings level.

**Table of contents**

.. contents::
:local:

Usage
=====

#. Assign a timezone on the Warehouse address if defined and if needed
If you have a lot of warehouses in the same timezone, you can also define
the timezone on the company partner.
If you don't define a timezone on the warehouse(s) nor the company, the process
end time on channels will be considered as UTC.
#. Propagate/update scheduled date of picking follow process end date/time automatically
by setting "Update Scheduled Date" configuration in Settings/General Settings/Inventory

#. Go To Release Channels
#. Set an end time
#. Wake up the channel
#. The assigned pickings have their scheduled date set at the next end time. (if enabled "Update Scheduled Date" config)

Known issues / Roadmap
======================

* Maybe something to do on pickings level when setting channels asleep (storing
the original scheduled date or ...).

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 to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/wms/issues/new?body=module:%20stock_release_channel_process_end_time%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
~~~~~~~~~~~~

* Denis Roussel <denis.roussel@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.

.. |maintainer-rousseldenis| image:: https://github.com/rousseldenis.png?size=40px
:target: https://github.com/rousseldenis
:alt: rousseldenis

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-rousseldenis|

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

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

{
"name": "Stock Release Channel Process End Date",
"summary": """
Allows to define an end date (and time) on a release channel and
propagate it to the concerned pickings""",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"maintainers": ["rousseldenis"],
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/wms",
"depends": [
"partner_tz",
"stock_release_channel",
"stock_available_to_promise_release",
],
"data": [
"views/res_config_settings.xml",
"views/stock_release_channel.xml",
],
}
3 changes: 3 additions & 0 deletions stock_release_channel_process_end_time/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import stock_picking
from . import stock_release_channel
from . import res_config_settings
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2023 Trobz
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

stock_release_use_channel_end_date = fields.Boolean(
help="Will update scheduled date of picking based on process end date "
"instead of release date + delay.",
config_parameter="stock_release_channel_process_end_time."
"stock_release_use_channel_end_date",
)
82 changes: 82 additions & 0 deletions stock_release_channel_process_end_time/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# 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


class StockPicking(models.Model):

_inherit = "stock.picking"

schedule_date_prior_to_channel_process_end_date_search = fields.Boolean(
store=False,
search="_search_schedule_date_prior_to_channel_process_end_date",
help="Technical field to search on not processed pickings where the scheduled "
"date is prior to the process end date of available channels.",
)

@api.model
def fields_get(self, allfields=None, attributes=None):
"""Hide schedule_date_prior_to_channel_process_end_date_search from
filterable/searchable fields"""
res = super().fields_get(allfields, attributes)
if res.get("schedule_date_prior_to_channel_process_end_date_search"):
res["schedule_date_prior_to_channel_process_end_date_search"][
"searchable"
] = False
return res

@api.model
def _search_schedule_date_prior_to_channel_process_end_date(self, operator, value):
"""Search on not processed pickings where the scheduled date is prior to
the process end date of available channels.
"""
# We use a searchable field to be able to use 'inselect' operator in
# order to avoid a subquery in the search method. This is a workaround
# since the 'inselect' operator is not supported when calling search
# method but only into search method definition.
if operator not in ["=", "!="] or not isinstance(value, bool):
raise UserError(_("Operation not supported"))
query = """
SELECT
stock_picking.id
FROM
stock_picking
WHERE
stock_picking.state NOT IN ('done', 'cancel')
AND exists (
SELECT
TRUE
FROM
stock_release_channel
WHERE
stock_release_channel.process_end_date is not null
and stock_picking.scheduled_date <= stock_release_channel.process_end_date
)
"""
if value:
operator_inselect = "inselect" if operator == "=" else "not inselect"
else:
operator_inselect = "not inselect" if operator == "=" else "inselect"
return [("id", operator_inselect, (query, []))]

def _after_release_set_expected_date(self):
enabled_update_scheduled_date = bool(
simahawk marked this conversation as resolved.
Show resolved Hide resolved
self.env["ir.config_parameter"]
.sudo()
.get_param(
"stock_release_channel_process_end_time.stock_release_use_channel_end_date"
)
)
res = super()._after_release_set_expected_date()
for rec in self:
# Check if a channel has been assigned to the picking and write
# scheduled_date if different to avoid unnecessary write
if (
rec.release_channel_id
and rec.release_channel_id.process_end_date
and rec.scheduled_date != rec.release_channel_id.process_end_date
and enabled_update_scheduled_date
):
rec.scheduled_date = rec.release_channel_id.process_end_date
return res
100 changes: 100 additions & 0 deletions stock_release_channel_process_end_time/models/stock_release_channel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# 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.addons.base.models.res_partner import _tz_get

from ..utils import float_to_time, next_datetime


class StockReleaseChannel(models.Model):

_inherit = "stock.release.channel"

process_end_time = fields.Float(
help="Fill in this to indicates when this channel release process would "
"be ended. This information will be used to compute the channel pickings "
"scheduled date at channel awaking.",
)
process_end_time_tz = fields.Selection(
selection=_tz_get,
compute="_compute_process_end_time_tz",
help="Technical field to compute the timezone for the process end time.",
)
process_end_time_can_edit = fields.Boolean(
compute="_compute_process_end_time_can_edit",
help="Technical field in order to know if user can edit the end date in views",
)
process_end_date = fields.Datetime(
compute="_compute_process_end_date",
store=True,
readonly=False,
help="This is the end date for this window of opened channel.",
)

@api.depends_context("uid")
def _compute_process_end_time_can_edit(self):
if self.user_has_groups("stock.group_stock_manager"):
self.update({"process_end_time_can_edit": True})
else:
self.update({"process_end_time_can_edit": False})

@api.depends("state", "process_end_time")
def _compute_process_end_date(self):
now = fields.Datetime.now()
for channel in self:
# We check if a date is not already set (manually)
if channel.state != "asleep" and not channel.process_end_date:
end = next_datetime(
now,
float_to_time(
channel.process_end_time,
tz=channel.process_end_time_tz,
),
)
channel.process_end_date = end
elif channel.state == "asleep":
channel.process_end_date = False

@api.depends("warehouse_id.partner_id.tz")
@api.depends_context("company")
def _compute_process_end_time_tz(self):
# As the time is timezone-agnostic, we use the channel warehouse adress timezone
# or the company one, either it will be considered as UTC
company_tz = self.env.company.partner_id.tz
for channel in self:
channel.process_end_time_tz = (
channel.warehouse_id.partner_id.tz or company_tz or "UTC"
)

@api.model
def assign_release_channel(self, picking):
res = super().assign_release_channel(picking)
picking._after_release_set_expected_date()
return res

def _field_picking_domains(self):
res = super()._field_picking_domains()
release_ready_domain = res["count_picking_release_ready"]
# the initial scheduled_date condition based on datetime.now() must
# be replaced by a condition based on the process_end_date
# since the processe_end_date is a field on the release channel
# and not on the picking we all use an 'inselect' operator
# (join in where clause is not possible). The 'inselect' operator
# is not available in the ORM so we use a search with a domain
# on a specialized field defined in the stock.picking model
# (see stock.picking._search_schedule_date_prior_to_channel_process_end_date)
new_domain = []
for criteria in release_ready_domain:
if criteria[0] == "scheduled_date":
new_domain.append(
(
"schedule_date_prior_to_channel_process_end_date_search",
"=",
True,
)
)
else:
new_domain.append(criteria)
res["count_picking_release_ready"] = new_domain
return res
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Denis Roussel <denis.roussel@acsone.eu>
4 changes: 4 additions & 0 deletions stock_release_channel_process_end_time/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This module allows to set an end time on a release channel that will be transmitted on
related stock pickings (on scheduled date) when the channel awakes.

That allows to use Odoo core sorting feature on stock pickings level.
2 changes: 2 additions & 0 deletions stock_release_channel_process_end_time/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Maybe something to do on pickings level when setting channels asleep (storing
the original scheduled date or ...).
12 changes: 12 additions & 0 deletions stock_release_channel_process_end_time/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#. Assign a timezone on the Warehouse address if defined and if needed
If you have a lot of warehouses in the same timezone, you can also define
the timezone on the company partner.
If you don't define a timezone on the warehouse(s) nor the company, the process
end time on channels will be considered as UTC.
#. Propagate/update scheduled date of picking follow process end date/time automatically
by setting "Update Scheduled Date" configuration in Settings/General Settings/Inventory

#. Go To Release Channels
#. Set an end time
#. Wake up the channel
#. The assigned pickings have their scheduled date set at the next end time. (if enabled "Update Scheduled Date" config)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading