changeset dd06c21bc0a6 in modules/sale:default
details: https://hg.tryton.org/modules/sale?cmd=changeset&node=dd06c21bc0a6
description:
Define default invoice and shipment methods by party
issue10161
review316991002
diffstat:
CHANGELOG | 1 +
__init__.py | 2 +
party.py | 73 ++++++++++++++++++++++++++++++++-
party.xml | 24 ++++++++++
sale.py | 10 ++++
tests/scenario_sale_default_methods.rst | 37 ++++++++++++++++
tests/test_sale.py | 5 ++
view/party_form.xml | 4 +
8 files changed, 155 insertions(+), 1 deletions(-)
diffs (235 lines):
diff -r b804b5645619 -r dd06c21bc0a6 CHANGELOG
--- a/CHANGELOG Mon Oct 11 17:19:03 2021 +0200
+++ b/CHANGELOG Mon Oct 11 22:40:54 2021 +0200
@@ -1,3 +1,4 @@
+* Define default invoice and shipment methods by party
* Split process method
* Add general reporting
* Add reporting per customer category
diff -r b804b5645619 -r dd06c21bc0a6 __init__.py
--- a/__init__.py Mon Oct 11 17:19:03 2021 +0200
+++ b/__init__.py Mon Oct 11 22:40:54 2021 +0200
@@ -21,6 +21,8 @@
sale.SaleLineTax,
sale.SaleLineIgnoredMove,
sale.SaleLineRecreatedMove,
+ party.Party,
+ party.PartySaleMethod,
product.Configuration,
product.DefaultLeadTime,
product.Template,
diff -r b804b5645619 -r dd06c21bc0a6 party.py
--- a/party.py Mon Oct 11 17:19:03 2021 +0200
+++ b/party.py Mon Oct 11 22:40:54 2021 +0200
@@ -1,9 +1,80 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.i18n import gettext
+from trytond.model import ModelSQL, fields
from trytond.pool import PoolMeta, Pool
+from trytond.pyson import Eval
+from trytond.transaction import Transaction
+
+from trytond.modules.company.model import (
+ CompanyMultiValueMixin, CompanyValueMixin)
+from trytond.modules.party.exceptions import EraseError
+
+
+def get_sale_methods(field_name):
+ @classmethod
+ def func(cls):
+ pool = Pool()
+ Sale = pool.get('sale.sale')
+ return Sale.fields_get([field_name])[field_name]['selection'] + [
+ (None, '')]
+ return func
+
+
+class Party(CompanyMultiValueMixin, metaclass=PoolMeta):
+ __name__ = 'party.party'
+
+ sale_invoice_method = fields.MultiValue(fields.Selection(
+ 'get_sale_invoice_method', "Invoice Method",
+ help="The default sale invoice method for the customer.\n"
+ "Leave empty to use the default value from the configuration."))
+ sale_shipment_method = fields.MultiValue(fields.Selection(
+ 'get_sale_shipment_method', "Shipment Method",
+ help="The default sale shipment method for the customer.\n"
+ "Leave empty to use the default value from the configuration."))
+ sale_methods = fields.One2Many(
+ 'party.party.sale_method', 'party', "Sale Methods")
-from trytond.modules.party.exceptions import EraseError
+ @classmethod
+ def multivalue_model(cls, field):
+ pool = Pool()
+ if field in {'sale_invoice_method', 'sale_shipment_method'}:
+ return pool.get('party.party.sale_method')
+ return super().multivalue_model(field)
+
+ get_sale_invoice_method = get_sale_methods('invoice_method')
+ get_sale_shipment_method = get_sale_methods('shipment_method')
+
+ @classmethod
+ def copy(cls, parties, default=None):
+ context = Transaction().context
+ default = default.copy() if default else {}
+ if context.get('_check_access'):
+ fields = [
+ 'sale_methods', 'sale_invoice_method', 'sale_shipment_method']
+ default_values = cls.default_get(fields, with_rec_name=False)
+ for fname in fields:
+ default.setdefault(fname, default_values.get(fname))
+ return super().copy(parties, default=default)
+
+
+class PartySaleMethod(ModelSQL, CompanyValueMixin):
+ "Party Sale Method"
+ __name__ = 'party.party.sale_method'
+
+ party = fields.Many2One(
+ 'party.party', "Party", ondelete='CASCADE', select=True,
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends=['company'])
+ sale_invoice_method = fields.Selection(
+ 'get_sale_invoice_method', "Sale Invoice Method")
+ sale_shipment_method = fields.Selection(
+ 'get_sale_shipment_method', "Sale Shipment Method")
+
+ get_sale_invoice_method = get_sale_methods('invoice_method')
+ get_sale_shipment_method = get_sale_methods('shipment_method')
class Replace(metaclass=PoolMeta):
diff -r b804b5645619 -r dd06c21bc0a6 party.xml
--- a/party.xml Mon Oct 11 17:19:03 2021 +0200
+++ b/party.xml Mon Oct 11 22:40:54 2021 +0200
@@ -22,5 +22,29 @@
<field name="action" ref="act_sale_form2"/>
<field name="group" ref="group_sale"/>
</record>
+
+ <record model="ir.model.field.access"
id="access_party_sale_invoice_method">
+ <field name="field" search="[('model.model', '=', 'party.party'),
('name', '=', 'sale_invoice_method')]"/>
+ <field name="perm_read" eval="True"/>
+ <field name="perm_write" eval="False"/>
+ </record>
+ <record model="ir.model.field.access"
id="access_party_sale_invoice_method_group_sale">
+ <field name="field" search="[('model.model', '=', 'party.party'),
('name', '=', 'sale_invoice_method')]"/>
+ <field name="group" ref="group_sale"/>
+ <field name="perm_read" eval="True"/>
+ <field name="perm_write" eval="True"/>
+ </record>
+
+ <record model="ir.model.field.access"
id="access_party_sale_shipment_method">
+ <field name="field" search="[('model.model', '=', 'party.party'),
('name', '=', 'sale_shipment_method')]"/>
+ <field name="perm_read" eval="True"/>
+ <field name="perm_write" eval="False"/>
+ </record>
+ <record model="ir.model.field.access"
id="access_party_sale_shipment_method_group_sale">
+ <field name="field" search="[('model.model', '=', 'party.party'),
('name', '=', 'sale_shipment_method')]"/>
+ <field name="group" ref="group_sale"/>
+ <field name="perm_read" eval="True"/>
+ <field name="perm_write" eval="True"/>
+ </record>
</data>
</tryton>
diff -r b804b5645619 -r dd06c21bc0a6 sale.py
--- a/sale.py Mon Oct 11 17:19:03 2021 +0200
+++ b/sale.py Mon Oct 11 22:40:54 2021 +0200
@@ -433,8 +433,16 @@
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.sale_shipment_method:
+ self.shipment_method = self.party.sale_shipment_method
+ else:
+ self.shipment_method = self.default_shipment_method()
if self.party.customer_payment_term:
self.payment_term = self.party.customer_payment_term
+ if self.party.sale_invoice_method:
+ self.invoice_method = self.party.sale_invoice_method
+ else:
+ self.invoice_method = self.default_invoice_method()
@fields.depends('party', 'invoice_party')
def on_change_invoice_party(self):
@@ -451,6 +459,8 @@
type='delivery')
elif self.party:
self.shipment_address = self.party.address_get(type='delivery')
+ if self.party.sale_shipment_method:
+ self.shipment_method = self.party.sale_shipment_method
@fields.depends('party', 'company')
def _get_tax_context(self):
diff -r b804b5645619 -r dd06c21bc0a6 tests/scenario_sale_default_methods.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/scenario_sale_default_methods.rst Mon Oct 11 22:40:54 2021 +0200
@@ -0,0 +1,37 @@
+=============================
+Sale Default Methods Scenario
+=============================
+
+Imports::
+
+ >>> from proteus import Model, Wizard, Report
+ >>> from trytond.tests.tools import activate_modules, set_user
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+
+Activate modules::
+
+ >>> config = activate_modules('sale')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create a party and set their default methods::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.sale_shipment_method = 'invoice'
+ >>> customer.sale_invoice_method = 'shipment'
+ >>> customer.save()
+
+Create a sale to to check default methods::
+
+ >>> Sale = Model.get('sale.sale')
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.shipment_method
+ 'invoice'
+ >>> sale.invoice_method
+ 'shipment'
diff -r b804b5645619 -r dd06c21bc0a6 tests/test_sale.py
--- a/tests/test_sale.py Mon Oct 11 17:19:03 2021 +0200
+++ b/tests/test_sale.py Mon Oct 11 22:40:54 2021 +0200
@@ -88,4 +88,9 @@
tearDown=doctest_teardown, encoding='utf-8',
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE,
checker=doctest_checker))
+ suite.addTests(doctest.DocFileSuite(
+ 'scenario_sale_default_methods.rst',
+ tearDown=doctest_teardown, encoding='utf-8',
+ optionflags=doctest.REPORT_ONLY_FIRST_FAILURE,
+ checker=doctest_checker))
return suite
diff -r b804b5645619 -r dd06c21bc0a6 view/party_form.xml
--- a/view/party_form.xml Mon Oct 11 17:19:03 2021 +0200
+++ b/view/party_form.xml Mon Oct 11 22:40:54 2021 +0200
@@ -7,6 +7,10 @@
</xpath>
<xpath expr="/form/notebook" position="inside">
<page id="sale" string="Sale">
+ <label name="sale_invoice_method"/>
+ <field name="sale_invoice_method"/>
+ <label name="sale_shipment_method"/>
+ <field name="sale_shipment_method"/>
</page>
</xpath>
</data>