1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon
from odoo.addons.sale.tests.common import TestSaleCommon
from odoo import fields
from odoo.tests import tagged
from datetime import timedelta
@tagged('post_install', '-at_install')
class TestSaleStockLeadTime(TestSaleCommon, ValuationReconciliationTestCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
# Update the product_1 with type and Customer Lead Time
cls.test_product_order.sale_delay = 5.0
def test_00_product_company_level_delays(self):
""" In order to check schedule date, set product's Customer Lead Time
and company's Sales Safety Days."""
# Update company with Sales Safety Days
self.env.company.security_lead = 3.00
# Create sale order of product_1
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'partner_invoice_id': self.partner_a.id,
'partner_shipping_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
'order_line': [(0, 0, {'name': self.test_product_order.name,
'product_id': self.test_product_order.id,
'product_uom_qty': 10,
'product_uom': self.env.ref('uom.product_uom_unit').id,
'customer_lead': self.test_product_order.sale_delay})]})
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Picking should be created.")
# Check schedule date of picking
out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=self.env.company.security_lead)
min_date = fields.Datetime.from_string(order.picking_ids[0].scheduled_date)
self.assertTrue(abs(min_date - out_date) <= timedelta(seconds=1), 'Schedule date of picking should be equal to: order date + Customer Lead Time - Sales Safety Days.')
def test_01_product_route_level_delays(self):
""" In order to check schedule dates, set product's Customer Lead Time
and warehouse route's delay."""
# Update warehouse_1 with Outgoing Shippings pick + pack + ship
self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'})
# Set delay on pull rule
for pull_rule in self.company_data['default_warehouse'].delivery_route_id.rule_ids:
pull_rule.write({'delay': 2})
# Create sale order of product_1
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'partner_invoice_id': self.partner_a.id,
'partner_shipping_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
'order_line': [(0, 0, {'name': self.test_product_order.name,
'product_id': self.test_product_order.id,
'product_uom_qty': 5,
'product_uom': self.env.ref('uom.product_uom_unit').id,
'customer_lead': self.test_product_order.sale_delay})]})
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Pickings should be created.")
# Check schedule date of ship type picking
out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id)
out_min_date = fields.Datetime.from_string(out.scheduled_date)
out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay)
self.assertTrue(abs(out_min_date - out_date) <= timedelta(seconds=1), 'Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.')
# Check schedule date of pack type picking
pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id)
pack_min_date = fields.Datetime.from_string(pack.scheduled_date)
pack_date = out_date - timedelta(days=pack.move_lines[0].rule_id.delay)
self.assertTrue(abs(pack_min_date - pack_date) <= timedelta(seconds=1), 'Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.')
# Check schedule date of pick type picking
pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id)
pick_min_date = fields.Datetime.from_string(pick.scheduled_date)
pick_date = pack_date - timedelta(days=pick.move_lines[0].rule_id.delay)
self.assertTrue(abs(pick_min_date - pick_date) <= timedelta(seconds=1), 'Schedule date of pick type picking should be equal to: Schedule date of pack type picking - pull rule delay.')
def test_02_delivery_date_propagation(self):
""" In order to check deadline date propagation, set product's Customer Lead Time
and warehouse route's delay in stock rules"""
# Example :
# -> Set Warehouse with Outgoing Shipments : pick + pack + ship
# -> Set Delay : 5 days on stock rules
# -> Set Customer Lead Time on product : 30 days
# -> Set Sales Safety Days : 2 days
# -> Create an SO and confirm it with confirmation Date : 12/18/2018
# -> Pickings : OUT -> Scheduled Date : 01/12/2019, Deadline Date: 01/14/2019
# PACK -> Scheduled Date : 01/07/2019, Deadline Date: 01/09/2019
# PICK -> Scheduled Date : 01/02/2019, Deadline Date: 01/04/2019
# -> Now, change commitment_date in the sale order = out_deadline_date + 5 days
# -> Deadline Date should be changed and Scheduled date should be unchanged:
# OUT -> Deadline Date : 01/19/2019
# PACK -> Deadline Date : 01/14/2019
# PICK -> Deadline Date : 01/09/2019
# Update company with Sales Safety Days
self.env.company.security_lead = 2.00
# Update warehouse_1 with Outgoing Shippings pick + pack + ship
self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'})
# Set delay on pull rule
self.company_data['default_warehouse'].delivery_route_id.rule_ids.write({'delay': 5})
# Update the product_1 with type and Customer Lead Time
self.test_product_order.write({'type': 'product', 'sale_delay': 30.0})
# Now, create sale order of product_1 with customer_lead set on product
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'partner_invoice_id': self.partner_a.id,
'partner_shipping_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
'order_line': [(0, 0, {'name': self.test_product_order.name,
'product_id': self.test_product_order.id,
'product_uom_qty': 5,
'product_uom': self.env.ref('uom.product_uom_unit').id,
'customer_lead': self.test_product_order.sale_delay})]})
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Pickings should be created.")
# Check schedule/deadline date of ship type picking
out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id)
deadline_date = order.date_order + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay)
self.assertAlmostEqual(
out.date_deadline, deadline_date, delta=timedelta(seconds=1),
msg='Deadline date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.')
out_scheduled_date = deadline_date - timedelta(days=self.env.company.security_lead)
self.assertAlmostEqual(
out.scheduled_date, out_scheduled_date, delta=timedelta(seconds=1),
msg='Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay - security_lead')
# Check schedule/deadline date of pack type picking
pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id)
pack_scheduled_date = out_scheduled_date - timedelta(days=pack.move_lines[0].rule_id.delay)
self.assertAlmostEqual(
pack.scheduled_date, pack_scheduled_date, delta=timedelta(seconds=1),
msg='Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.')
deadline_date -= timedelta(days=pack.move_lines[0].rule_id.delay)
self.assertAlmostEqual(
pack.date_deadline, deadline_date, delta=timedelta(seconds=1),
msg='Deadline date of pack type picking should be equal to: Deadline date of ship type picking - pull rule delay.')
# Check schedule/deadline date of pick type picking
pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id)
pick_scheduled_date = pack_scheduled_date - timedelta(days=pick.move_lines[0].rule_id.delay)
self.assertAlmostEqual(
pick.scheduled_date, pick_scheduled_date, delta=timedelta(seconds=1),
msg='Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.')
deadline_date -= timedelta(days=pick.move_lines[0].rule_id.delay)
self.assertAlmostEqual(
pick.date_deadline, deadline_date, delta=timedelta(seconds=1),
msg='Deadline date of pack type picking should be equal to: Deadline date of ship type picking - pull rule delay.')
# Now change the commitment date (Delivery Date) of the sale order
new_deadline = deadline_date + timedelta(days=5)
order.write({'commitment_date': new_deadline})
# Now check date_deadline of pick, pack and out are forced
# TODO : add note in case of change of deadline and check
self.assertEqual(out.date_deadline, new_deadline)
new_deadline -= timedelta(days=pack.move_lines[0].rule_id.delay)
self.assertEqual(pack.date_deadline, new_deadline)
new_deadline -= timedelta(days=pick.move_lines[0].rule_id.delay)
self.assertEqual(pick.date_deadline, new_deadline)
|