diff --git a/modules/incoterm/CHANGELOG b/modules/incoterm/CHANGELOG
index f5a22d9323..cf843a0f70 100644
--- a/modules/incoterm/CHANGELOG
+++ b/modules/incoterm/CHANGELOG
@@ -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 --git a/modules/incoterm/sale.py b/modules/incoterm/sale.py
index 2bd03d44f8..780740fe75 100644
--- a/modules/incoterm/sale.py
+++ b/modules/incoterm/sale.py
@@ -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 @@ class Sale_Carrier(metaclass=PoolMeta):
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 --git a/modules/incoterm/setup.py b/modules/incoterm/setup.py
index d5459bcca4..19d1b81156 100755
--- a/modules/incoterm/setup.py
+++ b/modules/incoterm/setup.py
@@ -63,6 +63,7 @@ tests_require = [
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 --git a/modules/incoterm/tests/test_module.py b/modules/incoterm/tests/test_module.py
index a345f83746..c80e896ffb 100644
--- a/modules/incoterm/tests/test_module.py
+++ b/modules/incoterm/tests/test_module.py
@@ -15,7 +15,7 @@ class IncotermTestCase(CompanyTestMixin, ModuleTestCase):
'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 --git a/modules/incoterm/tryton.cfg b/modules/incoterm/tryton.cfg
index 0524dc8ff2..26d5157962 100644
--- a/modules/incoterm/tryton.cfg
+++ b/modules/incoterm/tryton.cfg
@@ -17,6 +17,7 @@ extras_depend:
sale_shipment_grouping
stock
stock_package_shipping
+ web_shop
xml:
incoterm.xml
company.xml
@@ -25,6 +26,7 @@ xml:
purchase.xml
sale.xml
stock.xml
+ web.xml
message.xml
[register]
@@ -75,3 +77,8 @@ model:
stock.ShipmentInReturn
stock.ShipmentOut
stock.ShipmentOutReturn
+
+[register web_shop]
+model:
+ sale.Sale_WebShop
+ web.Shop
diff --git a/modules/incoterm/view/web_shop_form.xml b/modules/incoterm/view/web_shop_form.xml
new file mode 100644
index 0000000000..656d03b9fc
--- /dev/null
+++ b/modules/incoterm/view/web_shop_form.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/incoterm/web.py b/modules/incoterm/web.py
new file mode 100644
index 0000000000..86c14cc731
--- /dev/null
+++ b/modules/incoterm/web.py
@@ -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 --git a/modules/incoterm/web.xml b/modules/incoterm/web.xml
new file mode 100644
index 0000000000..dd97840ecf
--- /dev/null
+++ b/modules/incoterm/web.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ web.shop
+
+ web_shop_form
+
+
+