diff --git a/addons/purchase_stock/tests/test_create_picking.py b/addons/purchase_stock/tests/test_create_picking.py index 271f25686e7..cd6f472c818 100644 --- a/addons/purchase_stock/tests/test_create_picking.py +++ b/addons/purchase_stock/tests/test_create_picking.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from datetime import datetime, timedelta -from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT +from datetime import date, datetime, timedelta + from odoo.addons.product.tests import common from odoo.tests import Form +from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT class TestCreatePicking(common.TestProductCommon): @@ -470,6 +471,46 @@ class TestCreatePicking(common.TestProductCommon): self.assertNotEqual(purchase_order_line.date_planned, delivery_order.scheduled_date, 'Delivery order schedule date should not changed.') + def test_07_differed_schedule_date(self): + warehouse = self.env['stock.warehouse'].search([], limit=1) + + # mark all rules as propagate_date so that push rules will use it + self.env['stock.rule'].search([]).write({ + 'propagate_date': True, + 'propagate_date_minimum_delta': 5, + }) + + with Form(warehouse) as w: + w.reception_steps = 'three_steps' + po_form = Form(self.env['purchase.order']) + po_form.partner_id = self.partner_id + with po_form.order_line.new() as line: + line.product_id = self.product_id_1 + line.date_planned = datetime.today() + line.product_qty = 1.0 + with po_form.order_line.new() as line: + line.product_id = self.product_id_1 + line.date_planned = datetime.today() + timedelta(days=7) + line.product_qty = 1.0 + po = po_form.save() + + # mark the po line as propagate_date so that the created moves will use it + po.order_line.write({ + 'propagate_date': True, + 'propagate_date_minimum_delta': 5, + }) + + po.button_approve() + + po.picking_ids.move_line_ids.write({ + 'qty_done': 1.0 + }) + po.picking_ids.button_validate() + + pickings = self.env['stock.picking'].search([('group_id', '=', po.group_id.id)]) + for picking in pickings: + self.assertEqual(picking.scheduled_date.date(), date.today()) + def test_update_quantity_and_return(self): po = self.env['purchase.order'].create(self.po_vals) diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 5436057cad8..127111035a0 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -433,7 +433,10 @@ class StockMove(models.Model): delta_days = (new_date - move.date_expected).total_seconds() / 86400 if move.propagate_date and abs(delta_days) >= move.propagate_date_minimum_delta and move_dest_ids: for move_dest in move_dest_ids: - move_dest.date_expected += relativedelta.relativedelta(days=delta_days) + # We want to propagate a negative delta, but not propagate an expected date + # in the past. + new_move_date = max(move_dest.date_expected + relativedelta.relativedelta(days=delta_days or 0), fields.Datetime.now()) + move_dest.date_expected = new_move_date move_dest_ids.filtered(lambda m: m.delay_alert)._propagate_date_log_activity(move) if move.delay_alert: move._delay_alert_check(new_date) diff --git a/addons/stock/models/stock_rule.py b/addons/stock/models/stock_rule.py index 0326644bf14..564c32e3337 100644 --- a/addons/stock/models/stock_rule.py +++ b/addons/stock/models/stock_rule.py @@ -209,6 +209,8 @@ class StockRule(models.Model): 'picking_id': False, 'picking_type_id': self.picking_type_id.id, 'propagate_cancel': self.propagate_cancel, + 'propagate_date': self.propagate_date, + 'propagate_date_minimum_delta': self.propagate_date_minimum_delta, 'warehouse_id': self.warehouse_id.id, 'delay_alert': self.delay_alert, 'procure_method': 'make_to_order',