details: https://code.tryton.org/tryton/commit/ecfa1fa3eabf
branch: default
user: Cédric Krier <[email protected]>
date: Fri Oct 31 11:57:19 2025 +0100
description:
Add a default Incoterm to web shops
The default Incoterm is set by default to sale from web shop for which
it is
required.
And the shipment address is also set by default as Incoterm location
when it is
required.
Closes #14337
diffstat:
modules/incoterm/CHANGELOG | 1 +
modules/incoterm/sale.py | 27 ++++++++++++++++++++++++++-
modules/incoterm/setup.py | 1 +
modules/incoterm/tests/test_module.py | 2 +-
modules/incoterm/tryton.cfg | 7 +++++++
modules/incoterm/view/web_shop_form.xml | 10 ++++++++++
modules/incoterm/web.py | 32 ++++++++++++++++++++++++++++++++
modules/incoterm/web.xml | 12 ++++++++++++
8 files changed, 90 insertions(+), 2 deletions(-)
diffs (169 lines):
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/CHANGELOG
--- a/modules/incoterm/CHANGELOG Thu Oct 30 10:23:35 2025 +0100
+++ b/modules/incoterm/CHANGELOG Fri Oct 31 11:57:19 2025 +0100
@@ -1,3 +1,4 @@
+* Add a default Incoterm to web shops
* Allow modifications of incoterm until customer's shipments has been shipped
Version 7.6.0 - 2025-04-28
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/sale.py
--- a/modules/incoterm/sale.py Thu Oct 30 10:23:35 2025 +0100
+++ b/modules/incoterm/sale.py Fri Oct 31 11:57:19 2025 +0100
@@ -2,7 +2,7 @@
# this repository contains the full copyright notices and license terms.
from trytond.i18n import gettext
-from trytond.model import fields
+from trytond.model import ModelView, Workflow, fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
@@ -105,6 +105,31 @@
self._set_default_incoterm()
+class Sale_WebShop(metaclass=PoolMeta):
+ __name__ = 'sale.sale'
+
+ @property
+ @fields.depends('web_shop')
+ def _party_incoterms(self):
+ incoterms = super()._party_incoterms
+ if self.web_shop:
+ incoterms = []
+ return incoterms
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('quotation')
+ def quote(cls, sales):
+ for sale in sales:
+ if sale.web_shop and sale._incoterm_required:
+ if not sale.incoterm:
+ sale.incoterm = sale.web_shop.default_incoterm
+ if sale.incoterm and sale.incoterm.location:
+ sale.incoterm_location = sale.shipment_address
+ cls.save(sales)
+ super().quote(sales)
+
+
class Opportunity(IncotermMixin, metaclass=PoolMeta):
__name__ = 'sale.opportunity'
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/setup.py
--- a/modules/incoterm/setup.py Thu Oct 30 10:23:35 2025 +0100
+++ b/modules/incoterm/setup.py Fri Oct 31 11:57:19 2025 +0100
@@ -63,6 +63,7 @@
get_require_version('trytond_sale_opportunity'),
get_require_version('trytond_sale_shipment_grouping'),
get_require_version('trytond_stock'),
+ get_require_version('trytond_web_shop'),
]
setup(name=name,
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/tests/test_module.py
--- a/modules/incoterm/tests/test_module.py Thu Oct 30 10:23:35 2025 +0100
+++ b/modules/incoterm/tests/test_module.py Fri Oct 31 11:57:19 2025 +0100
@@ -15,7 +15,7 @@
'carrier', 'company', 'purchase', 'purchase_request_quotation',
'sale', 'sale_shipment_cost', 'sale_opportunity',
'sale_shipment_grouping', 'stock', 'account_invoice',
- 'account_invoice_stock']
+ 'account_invoice_stock', 'web_shop']
@with_transaction()
def test_shipment_grouping(self):
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/tryton.cfg
--- a/modules/incoterm/tryton.cfg Thu Oct 30 10:23:35 2025 +0100
+++ b/modules/incoterm/tryton.cfg Fri Oct 31 11:57:19 2025 +0100
@@ -17,6 +17,7 @@
sale_shipment_grouping
stock
stock_package_shipping
+ web_shop
xml:
incoterm.xml
company.xml
@@ -25,6 +26,7 @@
purchase.xml
sale.xml
stock.xml
+ web.xml
message.xml
[register]
@@ -75,3 +77,8 @@
stock.ShipmentInReturn
stock.ShipmentOut
stock.ShipmentOutReturn
+
+[register web_shop]
+model:
+ sale.Sale_WebShop
+ web.Shop
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/view/web_shop_form.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/incoterm/view/web_shop_form.xml Fri Oct 31 11:57:19 2025 +0100
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<data>
+ <xpath expr="//field[@name='guest_party']" position="after">
+ <newline/>
+ <label name="default_incoterm"/>
+ <field name="default_incoterm"/>
+ </xpath>
+</data>
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/web.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/incoterm/web.py Fri Oct 31 11:57:19 2025 +0100
@@ -0,0 +1,32 @@
+# 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.model import fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+
+
+class Shop(metaclass=PoolMeta):
+ __name__ = 'web.shop'
+
+ default_incoterm = fields.Many2One(
+ 'incoterm.incoterm', "Default Incoterm",
+ domain=[
+ ('carrier', '=', 'seller'),
+ ('id', 'in', Eval('available_incoterms', [])),
+ ],
+ help="Used to fill incoterm on sales that require it.")
+ available_incoterms = fields.Function(fields.Many2Many(
+ 'incoterm.incoterm', None, None, "Available Incoterms"),
+ 'on_change_with_available_incoterms')
+
+ @fields.depends('company', methods=['_get_incoterm_pattern'])
+ def on_change_with_available_incoterms(self, name=None):
+ pool = Pool()
+ Incoterm = pool.get('incoterm.incoterm')
+ pattern = self._get_incoterm_pattern()
+ return Incoterm.get_incoterms(self.company, pattern)
+
+ @fields.depends()
+ def _get_incoterm_pattern(self):
+ return {}
diff -r 741a31ec9455 -r ecfa1fa3eabf modules/incoterm/web.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/incoterm/web.xml Fri Oct 31 11:57:19 2025 +0100
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<tryton>
+ <data depends="web_shop">
+ <record model="ir.ui.view" id="web_shop_view_form">
+ <field name="model">web.shop</field>
+ <field name="inherit" ref="web_shop.shop_view_form"/>
+ <field name="name">web_shop_form</field>
+ </record>
+ </data>
+</tryton>