[FIX] purchase_stock: add POL to existing PO if draft
To reproduce the issue:
1. In Settings:
- Days to Purchase: 10
2. Create two products P01, P02:
- Storable
- With the same seller
- Delivery Lead Time: 1.0
3. On replenishment page, create a new line:
- Product: P01
- Min Qty: 1.0
4. Order once
- a RfQ is created and the order deadline is in ten days
5. Time travel to the next day
6. Repeat steps 3-4 with P02
Error: a second RfQ has been generated. However, as the first one is
still in draft state, the POL of P02 should be added to that first RfQ
When processing the orderpoint of P02, at some point, we try to find
an existing RfQ with its order deadline equal to `today + 10 days`.
Since we are the next day (step 5), the order deadline of the first
RfQ is `today + 9 days`, so we don't find it.
OPW-3047931
closes odoo/odoo#113982
X-original-commit: 8bf7f9038915be520488b2602c20929ca115a033
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
@@ -305,9 +305,10 @@ class StockRule(models.Model):
|
||||
('company_id', '=', company_id.id),
|
||||
('user_id', '=', False),
|
||||
)
|
||||
if values.get('orderpoint_id'):
|
||||
delta_days = self.env['ir.config_parameter'].sudo().get_param('purchase_stock.delta_days_merge')
|
||||
if values.get('orderpoint_id') and delta_days is not False:
|
||||
procurement_date = fields.Date.to_date(values['date_planned']) - relativedelta(days=int(values['supplier'].delay))
|
||||
delta_days = int(self.env['ir.config_parameter'].sudo().get_param('purchase_stock.delta_days_merge') or 0)
|
||||
delta_days = int(delta_days)
|
||||
domain += (
|
||||
('date_order', '<=', datetime.combine(procurement_date + relativedelta(days=delta_days), datetime.max.time())),
|
||||
('date_order', '>=', datetime.combine(procurement_date - relativedelta(days=delta_days), datetime.min.time()))
|
||||
|
||||
@@ -344,7 +344,8 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
|
||||
delivery_moves._action_confirm()
|
||||
self.env['procurement.group'].run_scheduler()
|
||||
po_line = self.env['purchase.order.line'].search([('product_id', '=', product.id)])
|
||||
self.assertEqual(fields.Date.to_date(po_line.order_id.date_order), fields.Date.today() + timedelta(days=2))
|
||||
expected_date_order = fields.Date.today() + timedelta(days=2)
|
||||
self.assertEqual(fields.Date.to_date(po_line.order_id.date_order), expected_date_order)
|
||||
self.assertEqual(len(po_line), 1)
|
||||
self.assertEqual(po_line.product_uom_qty, 25.0)
|
||||
self.assertEqual(len(po_line.order_id), 1)
|
||||
@@ -354,12 +355,10 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
|
||||
self.mock_date.today.return_value = fields.Date.today() + timedelta(days=2)
|
||||
orderpoint._compute_qty()
|
||||
self.env['procurement.group'].run_scheduler()
|
||||
po_line = self.env['purchase.order.line'].search([('product_id', '=', product.id)])
|
||||
self.assertEqual(len(po_line), 2)
|
||||
self.assertEqual(len(po_line.order_id), 2)
|
||||
new_order = po_line.order_id.sorted('date_order')[-1]
|
||||
self.assertEqual(fields.Date.to_date(new_order.date_order), fields.Date.today() + timedelta(days=2))
|
||||
self.assertEqual(new_order.order_line.product_uom_qty, 5.0)
|
||||
po_line02 = self.env['purchase.order.line'].search([('product_id', '=', product.id)])
|
||||
self.assertEqual(po_line02, po_line, 'The orderpoint execution should not create a new POL')
|
||||
self.assertEqual(fields.Date.to_date(po_line.order_id.date_order), expected_date_order, 'The Order Deadline should not change')
|
||||
self.assertEqual(po_line.product_uom_qty, 30.0, 'The existing POL should be updated with the quantity of the last execution')
|
||||
|
||||
def test_supplier_lead_time(self):
|
||||
""" Basic stock configuration and a supplier with a minimum qty and a lead time """
|
||||
|
||||
@@ -824,3 +824,89 @@ class TestReorderingRule(TransactionCase):
|
||||
{'location_id': supplier_location_id, 'location_dest_id': input_location_id, 'product_qty': 1},
|
||||
{'location_id': input_location_id, 'location_dest_id': stock_location_id, 'product_qty': 1},
|
||||
])
|
||||
|
||||
def test_add_line_to_existing_draft_po(self):
|
||||
"""
|
||||
Days to purchase = 10
|
||||
Two products P1, P2 from the same supplier
|
||||
Several use cases, each time we run the RR one by one. Then, according
|
||||
to the dates and the configuration, it should use the existing PO or not
|
||||
"""
|
||||
warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
|
||||
|
||||
self.env.company.days_to_purchase = 10
|
||||
expected_order_date = dt.combine(dt.today() + td(days=10), dt.min.time())
|
||||
expected_delivery_date = expected_order_date + td(days=1.0)
|
||||
# expected_delivery_date = expected_delivery_date.replace(hour=12, minute=0, second=0)
|
||||
|
||||
product_02 = self.env['product.product'].create({
|
||||
'name': 'Super Product',
|
||||
'type': 'product',
|
||||
'seller_ids': [(0, 0, {'partner_id': self.partner.id})],
|
||||
})
|
||||
|
||||
op_01, op_02 = self.env['stock.warehouse.orderpoint'].create([{
|
||||
'warehouse_id': warehouse.id,
|
||||
'location_id': warehouse.lot_stock_id.id,
|
||||
'product_id': p.id,
|
||||
'product_min_qty': 1,
|
||||
'product_max_qty': 0,
|
||||
} for p in [self.product_01, product_02]])
|
||||
|
||||
op_01.action_replenish()
|
||||
po01 = self.env['purchase.order'].search([], order='id desc', limit=1)
|
||||
self.assertEqual(po01.date_order, expected_order_date)
|
||||
|
||||
op_02.action_replenish()
|
||||
self.assertEqual(po01.date_order, expected_order_date)
|
||||
self.assertRecordValues(po01.order_line, [
|
||||
{'product_id': self.product_01.id, 'date_planned': expected_delivery_date},
|
||||
{'product_id': product_02.id, 'date_planned': expected_delivery_date},
|
||||
])
|
||||
|
||||
# Reset and try another flow
|
||||
po01.button_cancel()
|
||||
op_01.action_replenish()
|
||||
po02 = self.env['purchase.order'].search([], order='id desc', limit=1)
|
||||
self.assertNotEqual(po02, po01)
|
||||
|
||||
with freeze_time(dt.today() + td(days=1)):
|
||||
op_02.invalidate_recordset(fnames=['lead_days_date'])
|
||||
op_02.action_replenish()
|
||||
self.assertEqual(po02.date_order, expected_order_date)
|
||||
self.assertRecordValues(po02.order_line, [
|
||||
{'product_id': self.product_01.id, 'date_planned': expected_delivery_date},
|
||||
{'product_id': product_02.id, 'date_planned': expected_delivery_date + td(days=1)},
|
||||
])
|
||||
|
||||
# Restrict the merge with POs that have their order deadline in [today - 2 days, today + 2 days]
|
||||
self.env['ir.config_parameter'].set_param('purchase_stock.delta_days_merge', '2')
|
||||
|
||||
# Reset and try with a second RR executed in the dates range (-> should still use the existing PO)
|
||||
po02.button_cancel()
|
||||
op_01.action_replenish()
|
||||
po03 = self.env['purchase.order'].search([], order='id desc', limit=1)
|
||||
self.assertNotEqual(po03, po02)
|
||||
|
||||
with freeze_time(dt.today() + td(days=2)):
|
||||
op_02.invalidate_recordset(fnames=['lead_days_date'])
|
||||
op_02.action_replenish()
|
||||
self.assertEqual(po03.date_order, expected_order_date)
|
||||
self.assertRecordValues(po03.order_line, [
|
||||
{'product_id': self.product_01.id, 'date_planned': expected_delivery_date},
|
||||
{'product_id': product_02.id, 'date_planned': expected_delivery_date + td(days=2)},
|
||||
])
|
||||
|
||||
# Reset and try with a second RR executed after the dates range (-> should not use the existing PO)
|
||||
po03.button_cancel()
|
||||
op_01.action_replenish()
|
||||
po04 = self.env['purchase.order'].search([], order='id desc', limit=1)
|
||||
self.assertNotEqual(po04, po03)
|
||||
|
||||
with freeze_time(dt.today() + td(days=3)):
|
||||
op_02.invalidate_recordset(fnames=['lead_days_date'])
|
||||
op_02.action_replenish()
|
||||
self.assertEqual(po04.order_line.product_id, self.product_01, 'There should be only a line for product 01')
|
||||
po05 = self.env['purchase.order'].search([], order='id desc', limit=1)
|
||||
self.assertNotEqual(po05, po04, 'A new PO should be generated')
|
||||
self.assertEqual(po05.order_line.product_id, product_02)
|
||||
|
||||
Reference in New Issue
Block a user