diff --git a/CHANGELOG b/CHANGELOG index a0a3c571e8..8eb6fd573f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add default lead time to supplier * Allow product supplier to be deactivated * Add summary to purchase line list * Set payment term and invoice method from last party's purchases diff --git a/__init__.py b/__init__.py index fa5abbef51..fbd0bb7d92 100644 --- a/__init__.py +++ b/__init__.py @@ -36,6 +36,7 @@ def register(): stock.Location, party.Party, party.CustomerCode, + party.SupplierLeadTime, purchase.ReturnPurchaseStart, module='purchase', type_='model') Pool.register( diff --git a/party.py b/party.py index 81ac657158..b2c05c159a 100644 --- a/party.py +++ b/party.py @@ -16,6 +16,12 @@ class Party(CompanyMultiValueMixin, metaclass=PoolMeta): " as customer.")) customer_codes = fields.One2Many( 'party.party.customer_code', 'party', "Customer Codes") + supplier_lead_time = fields.MultiValue(fields.TimeDelta("Lead Time", + help="The time from confirming the purchase order to receiving " + "the goods from the party when used as a supplier.\n" + "Used if no lead time is set on the product supplier.")) + supplier_lead_times = fields.One2Many( + 'party.party.supplier_lead_time', 'party', "Lead Times") @classmethod def multivalue_model(cls, field): @@ -33,6 +39,14 @@ class CustomerCode(ModelSQL, CompanyValueMixin): customer_code = fields.Char('Customer Code') +class SupplierLeadTime(ModelSQL, CompanyValueMixin): + "Supplier Lead Time" + __name__ = 'party.party.supplier_lead_time' + party = fields.Many2One( + 'party.party', "Party", ondelete='CASCADE', select=True) + supplier_lead_time = fields.TimeDelta("Lead Time") + + class PartyReplace(metaclass=PoolMeta): __name__ = 'party.replace' diff --git a/product.py b/product.py index fe313d5f0c..454f2a5728 100644 --- a/product.py +++ b/product.py @@ -276,7 +276,10 @@ class ProductSupplier( ('id', If(Eval('context', {}).contains('company'), '=', '!='), Eval('context', {}).get('company', -1)), ]) - lead_time = fields.TimeDelta('Lead Time') + lead_time = fields.TimeDelta('Lead Time', + help="The time from confirming the purchase order to receiving the " + "products.\n" + "If empty the lead time of the supplier is used.") currency = fields.Many2One('currency.currency', 'Currency', required=True, ondelete='RESTRICT') uom = fields.Function( @@ -381,6 +384,15 @@ class ProductSupplier( if self.template.purchase_uom: return self.template.purchase_uom.id + @property + def lead_time_used(self): + # Use getattr because it can be called with an unsaved instance + lead_time = getattr(self, 'lead_time', None) + party = getattr(self, 'party', None) + if lead_time is None and party: + lead_time = party.get_multivalue('supplier_lead_time') + return lead_time + def compute_supply_date(self, date=None): ''' Compute the supply date for the Product Supplier at the given date @@ -389,9 +401,9 @@ class ProductSupplier( if not date: date = Date.today() - if self.lead_time is None: + if self.lead_time_used is None: return datetime.date.max - return date + self.lead_time + return date + self.lead_time_used def compute_purchase_date(self, date): ''' @@ -399,9 +411,9 @@ class ProductSupplier( ''' Date = Pool().get('ir.date') - if self.lead_time is None: + if self.lead_time_used is None: return Date.today() - return date - self.lead_time + return date - self.lead_time_used @staticmethod def get_pattern(): diff --git a/purchase.py b/purchase.py index 71590c377c..6766119d79 100644 --- a/purchase.py +++ b/purchase.py @@ -1405,27 +1405,32 @@ class Line(sequence_ordered(), ModelSQL, ModelView): @fields.depends('product_supplier', 'quantity', 'moves', 'purchase', '_parent_purchase.purchase_date', 'delivery_date_edit', 'delivery_date_store', - '_parent_purchase.delivery_date') + '_parent_purchase.delivery_date', '_parent_purchase.party') def on_change_with_delivery_date(self, name=None): pool = Pool() Date = pool.get('ir.date') + ProductSupplier = pool.get('purchase.product_supplier') if self.moves: dates = filter( None, (m.effective_date or m.planned_date for m in self.moves if m.state != 'cancelled')) return min(dates, default=None) + product_supplier = self.product_supplier + if not product_supplier: + product_supplier = ProductSupplier() + if self.purchase: + product_supplier.party = self.purchase.party delivery_date = None if self.delivery_date_edit: delivery_date = self.delivery_date_store elif self.purchase and self.purchase.delivery_date: delivery_date = self.purchase.delivery_date - elif (self.product_supplier + elif (product_supplier and self.quantity is not None and self.quantity > 0 and self.purchase): date = self.purchase.purchase_date if self.purchase else None - delivery_date = self.product_supplier.compute_supply_date( - date=date) + delivery_date = product_supplier.compute_supply_date(date=date) if delivery_date == datetime.date.max: delivery_date = None if delivery_date and delivery_date < Date.today(): diff --git a/view/party_form.xml b/view/party_form.xml index f4b187fd20..d298c896f6 100644 --- a/view/party_form.xml +++ b/view/party_form.xml @@ -9,6 +9,8 @@ this repository contains the full copyright notices and license terms. -->