2016-08-04 01:19:48 +02:00
|
|
|
exporting patch:
|
|
|
|
# HG changeset patch
|
|
|
|
# User Cédric Krier <ced@b2ck.com>
|
|
|
|
# Date 1466498284 -7200
|
|
|
|
# Tue Jun 21 10:38:04 2016 +0200
|
|
|
|
# Node ID 2debb3c826595328cfe844ebcf6c19339a548831
|
|
|
|
# Parent 2755f1104ac029ea8f01fee42fa3ffa3177e99c8
|
|
|
|
Manage lead time when generating internal shipments
|
|
|
|
|
|
|
|
issue5587
|
|
|
|
review25331003
|
|
|
|
|
|
|
|
diff -r 2755f1104ac0 -r 2debb3c82659 __init__.py
|
|
|
|
--- a/trytond/trytond/modules/stock_supply/__init__.py Tue Jun 21 10:11:57 2016 +0200
|
|
|
|
+++ b/trytond/trytond/modules/stock_supply/__init__.py Tue Jun 21 10:38:04 2016 +0200
|
|
|
|
@@ -18,6 +18,7 @@
|
2016-06-22 17:08:17 +02:00
|
|
|
ShipmentInternal,
|
|
|
|
CreateShipmentInternalStart,
|
|
|
|
Location,
|
|
|
|
+ LocationLeadTime,
|
|
|
|
module='stock_supply', type_='model')
|
|
|
|
Pool.register(
|
|
|
|
CreatePurchaseRequest,
|
2016-08-04 01:19:48 +02:00
|
|
|
diff -r 2755f1104ac0 -r 2debb3c82659 location.py
|
|
|
|
--- a/trytond/trytond/modules/stock_supply/location.py Tue Jun 21 10:11:57 2016 +0200
|
|
|
|
+++ b/trytond/trytond/modules/stock_supply/location.py Tue Jun 21 10:38:04 2016 +0200
|
2016-06-22 17:08:17 +02:00
|
|
|
@@ -1,11 +1,13 @@
|
|
|
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
|
|
# this repository contains the full copyright notices and license terms.
|
|
|
|
+import datetime
|
|
|
|
+
|
|
|
|
from trytond.pool import PoolMeta
|
|
|
|
from trytond.model import fields
|
|
|
|
from trytond.pyson import Eval
|
|
|
|
|
|
|
|
|
|
|
|
-__all__ = ['Location']
|
|
|
|
+__all__ = ['Location', 'LocationLeadTime']
|
|
|
|
|
|
|
|
|
|
|
|
class Location:
|
|
|
|
@@ -23,3 +25,17 @@
|
|
|
|
],
|
|
|
|
depends=['type', 'active'],
|
|
|
|
help='Leave empty for no default provisioning')
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class LocationLeadTime:
|
|
|
|
+ __metaclass__ = PoolMeta
|
|
|
|
+ __name__ = 'stock.location.lead_time'
|
|
|
|
+
|
|
|
|
+ @classmethod
|
|
|
|
+ def get_max_lead_time(cls):
|
|
|
|
+ 'Return the biggest lead time'
|
|
|
|
+ lead_times = cls.search([])
|
|
|
|
+ if lead_times:
|
2016-08-04 01:19:48 +02:00
|
|
|
+ return max(r.lead_time for r in lead_times)
|
2016-06-22 17:08:17 +02:00
|
|
|
+ else:
|
|
|
|
+ return datetime.timedelta(0)
|
2016-08-04 01:19:48 +02:00
|
|
|
diff -r 2755f1104ac0 -r 2debb3c82659 shipment.py
|
|
|
|
--- a/trytond/trytond/modules/stock_supply/shipment.py Tue Jun 21 10:11:57 2016 +0200
|
|
|
|
+++ b/trytond/trytond/modules/stock_supply/shipment.py Tue Jun 21 10:38:04 2016 +0200
|
2016-06-22 17:08:17 +02:00
|
|
|
@@ -1,5 +1,7 @@
|
2016-08-04 01:19:48 +02:00
|
|
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
|
|
# this repository contains the full copyright notices and license terms.
|
2016-06-22 17:08:17 +02:00
|
|
|
+import datetime
|
|
|
|
+
|
|
|
|
from sql import Table
|
|
|
|
from sql.functions import Overlay, Position
|
|
|
|
|
2016-08-04 01:19:48 +02:00
|
|
|
@@ -50,8 +52,11 @@
|
2016-06-22 17:08:17 +02:00
|
|
|
Date = pool.get('ir.date')
|
|
|
|
User = pool.get('res.user')
|
|
|
|
Move = pool.get('stock.move')
|
|
|
|
+ LeadTime = pool.get('stock.location.lead_time')
|
|
|
|
+
|
|
|
|
user_record = User(Transaction().user)
|
|
|
|
today = Date.today()
|
|
|
|
+ lead_time = LeadTime.get_max_lead_time()
|
|
|
|
# fetch quantities on order points
|
|
|
|
order_points = OrderPoint.search([
|
|
|
|
('type', '=', 'internal'),
|
2016-08-04 01:19:48 +02:00
|
|
|
@@ -79,61 +84,68 @@
|
2016-06-22 17:08:17 +02:00
|
|
|
else:
|
|
|
|
product_ids = id2product.keys()
|
|
|
|
product_ids.sort()
|
|
|
|
- # TODO Allow to compute for other future date
|
|
|
|
- with Transaction().set_context(forecast=True, stock_date_end=today):
|
|
|
|
- pbl = Product.products_by_location(id2location.keys(),
|
|
|
|
- product_ids, with_childs=True)
|
|
|
|
|
|
|
|
- # Create a list of move to create
|
|
|
|
- moves = {}
|
|
|
|
- for location in id2location.itervalues():
|
|
|
|
- for product_id in product_ids:
|
|
|
|
- qty = pbl.get((location.id, product_id), 0)
|
|
|
|
- op = product2op.get((location.id, product_id))
|
|
|
|
- if op:
|
|
|
|
- min_qty, max_qty = op.min_quantity, op.max_quantity
|
|
|
|
- provisioning_location = op.provisioning_location
|
|
|
|
- elif location and location.provisioning_location:
|
|
|
|
- min_qty, max_qty = 0, 0
|
|
|
|
- provisioning_location = location.provisioning_location
|
|
|
|
- else:
|
|
|
|
- continue
|
|
|
|
- if qty < min_qty:
|
|
|
|
- key = (provisioning_location.id, location.id, product_id)
|
|
|
|
- moves[key] = max_qty - qty
|
|
|
|
+ shipments = []
|
|
|
|
+ date = today
|
|
|
|
+ end_date = date + lead_time
|
|
|
|
+ while date <= end_date:
|
|
|
|
+ with Transaction().set_context(forecast=True, stock_date_end=date):
|
|
|
|
+ pbl = Product.products_by_location(id2location.keys(),
|
|
|
|
+ product_ids, with_childs=True)
|
|
|
|
|
|
|
|
- # Group moves by {from,to}_location
|
|
|
|
- to_create = {}
|
|
|
|
- for key, qty in moves.iteritems():
|
|
|
|
- from_location, to_location, product = key
|
|
|
|
- to_create.setdefault(
|
|
|
|
- (from_location, to_location), []).append((product, qty))
|
|
|
|
- # Create shipments and moves
|
|
|
|
- shipments = []
|
|
|
|
- for locations, moves in to_create.iteritems():
|
|
|
|
- from_location, to_location = locations
|
|
|
|
- shipment = cls(
|
|
|
|
- from_location=from_location,
|
|
|
|
- to_location=to_location,
|
|
|
|
- planned_date=today,
|
|
|
|
- )
|
2016-08-04 01:19:48 +02:00
|
|
|
- shipment_moves = []
|
2016-06-22 17:08:17 +02:00
|
|
|
- for move in moves:
|
|
|
|
- product_id, qty = move
|
|
|
|
- product = id2product.setdefault(
|
|
|
|
- product_id, Product(product_id))
|
2016-08-04 01:19:48 +02:00
|
|
|
- shipment_moves.append(Move(
|
2016-06-22 17:08:17 +02:00
|
|
|
- from_location=from_location,
|
|
|
|
- to_location=to_location,
|
|
|
|
- planned_date=today,
|
|
|
|
- product=product,
|
|
|
|
- quantity=qty,
|
|
|
|
- uom=product.default_uom,
|
|
|
|
- company=user_record.company,
|
|
|
|
- ))
|
2016-08-04 01:19:48 +02:00
|
|
|
- shipment.moves = shipment_moves
|
2016-06-22 17:08:17 +02:00
|
|
|
- shipment.save()
|
|
|
|
- shipments.append(shipment)
|
|
|
|
+ # Create a list of moves to create
|
|
|
|
+ moves = {}
|
|
|
|
+ for location in id2location.itervalues():
|
|
|
|
+ for product_id in product_ids:
|
|
|
|
+ qty = pbl.get((location.id, product_id), 0)
|
|
|
|
+ op = product2op.get((location.id, product_id))
|
|
|
|
+ if op:
|
|
|
|
+ min_qty, max_qty = op.min_quantity, op.max_quantity
|
|
|
|
+ provisioning_location = op.provisioning_location
|
|
|
|
+ elif location and location.provisioning_location:
|
|
|
|
+ min_qty, max_qty = 0, 0
|
|
|
|
+ provisioning_location = location.provisioning_location
|
|
|
|
+ else:
|
|
|
|
+ continue
|
|
|
|
+ if qty < min_qty:
|
|
|
|
+ key = (
|
|
|
|
+ provisioning_location.id, location.id, product_id)
|
|
|
|
+ moves[key] = max_qty - qty
|
|
|
|
+
|
|
|
|
+ # Group moves by {from,to}_location
|
|
|
|
+ to_create = {}
|
|
|
|
+ for key, qty in moves.iteritems():
|
|
|
|
+ from_location, to_location, product = key
|
|
|
|
+ to_create.setdefault(
|
|
|
|
+ (from_location, to_location), []).append((product, qty))
|
|
|
|
+ # Create shipments and moves
|
|
|
|
+ for locations, moves in to_create.iteritems():
|
|
|
|
+ from_location, to_location = locations
|
|
|
|
+ shipment = cls(
|
|
|
|
+ from_location=from_location,
|
|
|
|
+ to_location=to_location,
|
|
|
|
+ planned_date=date,
|
|
|
|
+ )
|
|
|
|
+ shipment_moves = []
|
|
|
|
+ for move in moves:
|
|
|
|
+ product_id, qty = move
|
|
|
|
+ product = id2product.setdefault(
|
|
|
|
+ product_id, Product(product_id))
|
|
|
|
+ shipment_moves.append(Move(
|
|
|
|
+ from_location=from_location,
|
|
|
|
+ to_location=to_location,
|
|
|
|
+ planned_date=date,
|
|
|
|
+ product=product,
|
|
|
|
+ quantity=qty,
|
|
|
|
+ uom=product.default_uom,
|
|
|
|
+ company=user_record.company,
|
|
|
|
+ ))
|
|
|
|
+ shipment.moves = shipment_moves
|
|
|
|
+ shipment.planned_start_date = (
|
|
|
|
+ shipment.on_change_with_planned_start_date())
|
|
|
|
+ shipments.append(shipment)
|
|
|
|
+ date += datetime.timedelta(1)
|
2016-08-04 01:19:48 +02:00
|
|
|
+ cls.save(shipments)
|
2016-06-22 17:08:17 +02:00
|
|
|
cls.wait(shipments)
|
|
|
|
return shipments
|
|
|
|
|