From 7b4715a6db8bd0a7de04b1b2ca2b659784acaca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 28 Mar 2020 14:25:57 +0100 Subject: [PATCH] Add contact and invoice party issue8992 review274701003 --- CHANGELOG | 1 + doc/index.rst | 2 ++ party.py | 1 + sale.py | 55 ++++++++++++++++++++++++++++++++++------------ view/sale_form.xml | 13 +++++++++-- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ecbb961646..a0c6723788 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add contact and invoice party on sale * Add salable products menu entry Version 5.4.0 - 2019-11-04 diff --git a/doc/index.rst b/doc/index.rst index efcb4b72e1..f28ba27c3b 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -13,6 +13,8 @@ quantity. Here is the extensive list of the fields, most of them are optional or completed with sensible default values: - Party: The customer. +- Contact: The contact who placed the order. +- Invoice Party: An optional different party to invoice. - Invoice Address: The invoice address of the customer. - Shipment Party: An optional different party where the shipment will be sent. - Shipment Address: The address where the shipment will be sent. diff --git a/party.py b/party.py index ba82115b69..62380203bd 100644 --- a/party.py +++ b/party.py @@ -13,6 +13,7 @@ class Replace(metaclass=PoolMeta): def fields_to_replace(cls): return super().fields_to_replace() + [ ('sale.sale', 'party'), + ('sale.sale', 'invoice_party'), ('sale.sale', 'shipment_party'), ] diff --git a/sale.py b/sale.py index 0e80209f4a..815b119bf5 100644 --- a/sale.py +++ b/sale.py @@ -101,11 +101,27 @@ class Sale(Workflow, ModelSQL, ModelView, TaxableMixin): depends=['state']) party_lang = fields.Function(fields.Char('Party Language'), 'on_change_with_party_lang') + contact = fields.Many2One( + 'party.contact_mechanism', "Contact", + search_context={ + 'related_party': Eval('party'), + }, + depends=['party']) + invoice_party = fields.Many2One('party.party', "Invoice Party", + states={ + 'readonly': ((Eval('state') != 'draft') + | Eval('lines', [0])), + }, + depends=['state']) invoice_address = fields.Many2One('party.address', 'Invoice Address', - domain=[('party', '=', Eval('party'))], states={ + domain=[ + ('party', '=', If(Bool(Eval('invoice_party')), + Eval('invoice_party'), Eval('party'))), + ], + states={ 'readonly': Eval('state') != 'draft', 'required': ~Eval('state').in_(['draft', 'quotation', 'cancel']), - }, depends=['state', 'party']) + }, depends=['party', 'invoice_party', 'state']) shipment_party = fields.Many2One('party.party', 'Shipment Party', states={ 'readonly': (Eval('state') != 'draft'), @@ -354,19 +370,29 @@ class Sale(Workflow, ModelSQL, ModelView, TaxableMixin): def default_shipment_state(): return 'none' - @fields.depends('party', 'shipment_party', 'payment_term') + @fields.depends('party', 'invoice_party', 'shipment_party', 'payment_term') def on_change_party(self): - self.invoice_address = None + if not self.invoice_party: + self.invoice_address = None if not self.shipment_party: self.shipment_address = None self.payment_term = self.default_payment_term() if self.party: - self.invoice_address = self.party.address_get(type='invoice') + if not self.invoice_party: + self.invoice_address = self.party.address_get(type='invoice') if not self.shipment_party: self.shipment_address = self.party.address_get(type='delivery') if self.party.customer_payment_term: self.payment_term = self.party.customer_payment_term + @fields.depends('party', 'invoice_party') + def on_change_invoice_party(self): + if self.invoice_party: + self.invoice_address = self.invoice_party.address_get( + type='invoice') + elif self.party: + self.invoice_address = self.party.address_get(type='invoice') + @fields.depends('party', 'shipment_party') def on_change_shipment_party(self): if self.shipment_party: @@ -715,13 +741,14 @@ class Sale(Workflow, ModelSQL, ModelView, TaxableMixin): 'Return invoice' pool = Pool() Invoice = pool.get('account.invoice') + party = self.invoice_party or self.party invoice = Invoice( company=self.company, type='out', - party=self.party, + party=party, invoice_address=self.invoice_address, currency=self.currency, - account=self.party.account_receivable_used, + account=party.account_receivable_used, ) invoice.on_change_type() invoice.payment_term = self.payment_term @@ -773,10 +800,9 @@ class Sale(Workflow, ModelSQL, ModelView, TaxableMixin): def _get_shipment_sale(self, Shipment, key): values = { - 'customer': (self.shipment_party.id if self.shipment_party - else self.party.id), - 'delivery_address': self.shipment_address.id, - 'company': self.company.id, + 'customer': self.shipment_party or self.party, + 'delivery_address': self.shipment_address, + 'company': self.company, } values.update(dict(key)) return Shipment(**values) @@ -1150,7 +1176,8 @@ class SaleLine(sequence_ordered(), ModelSQL, ModelView): context['taxes'] = [t.id for t in self.taxes or []] return context - @fields.depends('product', 'unit', 'sale', '_parent_sale.party', + @fields.depends('product', 'unit', 'sale', + '_parent_sale.party', '_parent_sale.invoice_party', methods=['compute_taxes', 'compute_unit_price', 'on_change_with_amount']) def on_change_product(self): @@ -1158,8 +1185,8 @@ class SaleLine(sequence_ordered(), ModelSQL, ModelView): return party = None - if self.sale and self.sale.party: - party = self.sale.party + if self.sale: + party = self.sale.invoice_party or self.sale.party # Set taxes before unit_price to have taxes in context of sale price self.taxes = self.compute_taxes(party) diff --git a/view/sale_form.xml b/view/sale_form.xml index fa882eb17c..e6f1e54bcc 100644 --- a/view/sale_form.xml +++ b/view/sale_form.xml @@ -4,19 +4,28 @@ this repository contains the full copyright notices and license terms. -->