diff --git a/modules/sale_supply/CHANGELOG b/modules/sale_supply/CHANGELOG index ccfcea9b43..62be66a37f 100644 --- a/modules/sale_supply/CHANGELOG +++ b/modules/sale_supply/CHANGELOG @@ -1,3 +1,5 @@ +* Notify when product is supplied on sale and has purchase order point + Version 6.6.0 - 2022-10-31 -------------------------- * Bug fixes (see mercurial logs for details) diff --git a/modules/sale_supply/__init__.py b/modules/sale_supply/__init__.py index c5c21fb081..bdb0dfb946 100644 --- a/modules/sale_supply/__init__.py +++ b/modules/sale_supply/__init__.py @@ -19,3 +19,6 @@ def register(): Pool.register( purchase.HandlePurchaseCancellationException, module='sale_supply', type_='wizard') + Pool.register( + stock.OrderPoint, + module='sale_supply', type_='model', depends=['stock_supply']) diff --git a/modules/sale_supply/message.xml b/modules/sale_supply/message.xml new file mode 100644 index 0000000000..6ed9fb317f --- /dev/null +++ b/modules/sale_supply/message.xml @@ -0,0 +1,13 @@ + + + + + + The product "%(product)s" is supplied on sale. + + + The product has purchase order points "%(order_points)s" defined. + + + diff --git a/modules/sale_supply/product.py b/modules/sale_supply/product.py index 08537ed277..c369bcf061 100644 --- a/modules/sale_supply/product.py +++ b/modules/sale_supply/product.py @@ -1,7 +1,9 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. + +from trytond.i18n import gettext from trytond.model import fields -from trytond.pool import PoolMeta +from trytond.pool import Pool, PoolMeta from trytond.pyson import Eval @@ -13,6 +15,33 @@ class Template(metaclass=PoolMeta): 'invisible': ~Eval('purchasable') | ~Eval('salable'), }) + @fields.depends(methods=['_notify_order_point']) + def on_change_notify(self): + notifications = super().on_change_notify() + notifications.extend(self._notify_order_point()) + return notifications + + @fields.depends('id', 'supply_on_sale') + def _notify_order_point(self): + pool = Pool() + try: + OrderPoint = pool.get('stock.order_point') + except KeyError: + return + if self.supply_on_sale and self.id is not None and self.id >= 0: + order_points = OrderPoint.search([ + ('product.template.id', '=', self.id), + ('type', '=', 'purchase'), + ], limit=6) + if order_points: + names = ', '.join(o.rec_name for o in order_points[:5]) + if len(order_points) > 5: + names + '...' + yield ('warning', gettext( + 'sale_supply' + '.msg_template_supply_on_sale_order_point', + order_points=names)) + class Product(metaclass=PoolMeta): __name__ = 'product.product' diff --git a/modules/sale_supply/setup.py b/modules/sale_supply/setup.py index eac89b0d62..f7d5a0bf79 100755 --- a/modules/sale_supply/setup.py +++ b/modules/sale_supply/setup.py @@ -47,7 +47,10 @@ for dep in info.get('depends', []): requires.append(get_require_version('trytond_%s' % dep)) requires.append(get_require_version('trytond')) -tests_require = [get_require_version('proteus')] +tests_require = [ + get_require_version('proteus'), + get_require_version('trytond_stock_supply'), + ] setup(name=name, version=version, diff --git a/modules/sale_supply/stock.py b/modules/sale_supply/stock.py index 2dda3b319e..08d2858990 100644 --- a/modules/sale_supply/stock.py +++ b/modules/sale_supply/stock.py @@ -2,7 +2,8 @@ # this repository contains the full copyright notices and license terms. from collections import defaultdict -from trytond.model import Model, ModelView, Workflow +from trytond.i18n import gettext +from trytond.model import Model, ModelView, Workflow, fields from trytond.pool import Pool, PoolMeta @@ -56,3 +57,22 @@ class ShipmentIn(metaclass=PoolMeta): for sale_line in sale_lines: sale_line.assign_supplied( pbl[sale_line.product], grouping=grouping) + + +class OrderPoint(metaclass=PoolMeta): + __name__ = 'stock.order_point' + + @fields.depends(methods=['_notify_product_supply_on_sale']) + def on_change_notify(self): + notifications = super().on_change_notify() + notifications.extend(self._notify_product_supply_on_sale()) + return notifications + + @fields.depends('type', 'product') + def _notify_product_supply_on_sale(self): + if (self.type == 'purchase' + and self.product and self.product.supply_on_sale): + yield ('warning', gettext( + 'sale_supply' + '.msg_order_point_product_supply_on_sale', + product=self.product.rec_name)) diff --git a/modules/sale_supply/tests/scenario_sale_supply_notifications.rst b/modules/sale_supply/tests/scenario_sale_supply_notifications.rst new file mode 100644 index 0000000000..10e28461f9 --- /dev/null +++ b/modules/sale_supply/tests/scenario_sale_supply_notifications.rst @@ -0,0 +1,58 @@ +========================= +Sale Supply Notifications +========================= + +Imports:: + + >>> from proteus import Model + + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import create_company + +Activate modules:: + + >>> config = activate_modules(['sale_supply', 'stock_supply']) + + >>> Location = Model.get('stock.location') + >>> OrderPoint = Model.get('stock.order_point') + >>> ProductTemplate = Model.get('product.template') + >>> UoM = Model.get('product.uom') + +Create company:: + + >>> _ = create_company() + +Get locations:: + + >>> warehouse_location, = Location.find([('type', '=', 'warehouse')]) + +Create product:: + + >>> unit, = UoM.find([('name', '=', "Unit")]) + + >>> product_template = ProductTemplate() + >>> product_template.name = "Product" + >>> product_template.type = 'goods' + >>> product_template.default_uom = unit + >>> product_template.purchasable = True + >>> product_template.salable = True + >>> product_template.supply_on_sale = True + >>> product_template.save() + >>> product, = product_template.products + +Create order point:: + + >>> order_point = OrderPoint() + >>> order_point.product = product + >>> order_point.warehouse_location = warehouse_location + >>> order_point.type = 'purchase' + >>> order_point.min_quantity = 0 + >>> order_point.target_quantity = 5 + >>> order_point.save() + +Check notifications:: + + >>> len(product_template.notifications()) + 1 + >>> len(order_point.notifications()) + 1 diff --git a/modules/sale_supply/tests/test_module.py b/modules/sale_supply/tests/test_module.py index a26dafb443..384e4252da 100644 --- a/modules/sale_supply/tests/test_module.py +++ b/modules/sale_supply/tests/test_module.py @@ -7,6 +7,7 @@ from trytond.tests.test_tryton import ModuleTestCase class SaleSupplyTestCase(ModuleTestCase): 'Test SaleSupply module' module = 'sale_supply' + extras = ['stock_supply'] del ModuleTestCase diff --git a/modules/sale_supply/tryton.cfg b/modules/sale_supply/tryton.cfg index 1c54bdf9a3..c9b1e79107 100644 --- a/modules/sale_supply/tryton.cfg +++ b/modules/sale_supply/tryton.cfg @@ -6,6 +6,9 @@ depends: purchase_request sale stock +extras_depend: + stock_supply xml: product.xml sale.xml + message.xml