details:   https://code.tryton.org/tryton/commit/225fbc061f26
branch:    default
user:      Cédric Krier <[email protected]>
date:      Mon Feb 17 19:01:11 2025 +0100
description:
        Support UPS international invoice form
diffstat:

 modules/stock_package_shipping_ups/CHANGELOG                                   
                |    1 +
 modules/stock_package_shipping_ups/carrier.py                                  
                |    5 +
 modules/stock_package_shipping_ups/customs.py                                  
                |   11 +
 modules/stock_package_shipping_ups/customs.xml                                 
                |   18 +
 modules/stock_package_shipping_ups/product.py                                  
                |   56 ++
 modules/stock_package_shipping_ups/product.xml                                 
                |   41 ++
 modules/stock_package_shipping_ups/setup.py                                    
                |    3 +
 modules/stock_package_shipping_ups/stock.py                                    
                |  124 ++++++
 modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst             
                |    3 +-
 
modules/stock_package_shipping_ups/tests/scenario_stock_package_shipping_ups_international.rst
 |  187 ++++++++++
 modules/stock_package_shipping_ups/tests/test_module.py                        
                |    1 +
 modules/stock_package_shipping_ups/tests/test_scenario.py                      
                |    5 +-
 modules/stock_package_shipping_ups/tryton.cfg                                  
                |   15 +
 modules/stock_package_shipping_ups/view/customs_agent_form.xml                 
                |   10 +
 modules/stock_package_shipping_ups/view/customs_agent_list.xml                 
                |    8 +
 modules/stock_package_shipping_ups/view/product_uom_form.xml                   
                |   10 +
 modules/stock_package_shipping_ups/view/ups_credential_form.xml                
                |    2 +
 17 files changed, 497 insertions(+), 3 deletions(-)

diffs (650 lines):

diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/CHANGELOG
--- a/modules/stock_package_shipping_ups/CHANGELOG      Sat Feb 15 22:24:49 
2025 +0100
+++ b/modules/stock_package_shipping_ups/CHANGELOG      Mon Feb 17 19:01:11 
2025 +0100
@@ -1,3 +1,4 @@
+* Support international invoice form
 * Use "General Merchandise" as fallback shipping description
 
 Version 7.6.0 - 2025-04-28
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/carrier.py
--- a/modules/stock_package_shipping_ups/carrier.py     Sat Feb 15 22:24:49 
2025 +0100
+++ b/modules/stock_package_shipping_ups/carrier.py     Mon Feb 17 19:01:11 
2025 +0100
@@ -22,6 +22,7 @@
     client_secret = fields.Char("Client Secret", required=True)
     account_number = fields.Char('Account Number', required=True)
     use_metric = fields.Boolean('Use Metric')
+    use_international_forms = fields.Boolean("Use International Forms")
     server = fields.Selection([
             ('testing', 'Testing'),
             ('production', 'Production'),
@@ -42,6 +43,10 @@
         return True
 
     @classmethod
+    def default_use_international_forms(cls):
+        return False
+
+    @classmethod
     def default_server(cls):
         return 'testing'
 
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/customs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/customs.py     Mon Feb 17 19:01:11 
2025 +0100
@@ -0,0 +1,11 @@
+# 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 PoolMeta
+
+
+class Agent(metaclass=PoolMeta):
+    __name__ = 'customs.agent'
+
+    ups_account_number = fields.Char("UPS Account Number")
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/customs.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/customs.xml    Mon Feb 17 19:01:11 
2025 +0100
@@ -0,0 +1,18 @@
+<?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="customs">
+        <record model="ir.ui.view" id="customs_agent_view_form">
+            <field name="model">customs.agent</field>
+            <field name="inherit" ref="customs.customs_agent_view_form"/>
+            <field name="name">customs_agent_form</field>
+        </record>
+
+        <record model="ir.ui.view" id="customs_agent_view_list">
+            <field name="model">customs.agent</field>
+            <field name="inherit" ref="customs.customs_agent_view_list"/>
+            <field name="name">customs_agent_list</field>
+        </record>
+    </data>
+</tryton>
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/product.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/product.py     Mon Feb 17 19:01:11 
2025 +0100
@@ -0,0 +1,56 @@
+# 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 PoolMeta
+
+
+class UoM(metaclass=PoolMeta):
+    __name__ = 'product.uom'
+
+    ups_code = fields.Selection([
+            ('BA', "Barrel"),
+            ('BE', "Bundle"),
+            ('BG', "Bag"),
+            ('BH', "Bunch"),
+            ('BOX', "Box"),
+            ('BT', "Bolt"),
+            ('BU', "Butt"),
+            ('CI', "Canister"),
+            ('CM', "Centimeter"),
+            ('CON', "Container"),
+            ('CR', "Crate"),
+            ('CS', "Case"),
+            ('CT', "Carton"),
+            ('CY', "Cylinder"),
+            ('DOZ', "Dozen"),
+            ('EA', "Each"),
+            ('EN', "Envelope"),
+            ('FT', "Feet"),
+            ('KG', "Kilogram"),
+            ('KGS', "Kilograms"),
+            ('LB', "Pound"),
+            ('LBS', "Pounds"),
+            ('L', "Liter"),
+            ('M', "Meter"),
+            ('NMB', "Number"),
+            ('PA', "Packet"),
+            ('PAL', "Pallet"),
+            ('PC', "Piece"),
+            ('PCS', "Pieces"),
+            ('PF', "Proof Liters"),
+            ('PKG', "Package"),
+            ('PR', "Pair"),
+            ('PRS', "Pairs"),
+            ('RL', "Roll"),
+            ('SET', "Set"),
+            ('SME', "Square Meters"),
+            ('SYD', "Square Yards"),
+            ('TU', "Tube"),
+            ('YD', "Yard"),
+            ('OTH', "Other"),
+            ], "UPS Code", required=True)
+
+    @classmethod
+    def default_ups_code(cls):
+        return 'OTH'
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/product.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/product.xml    Mon Feb 17 19:01:11 
2025 +0100
@@ -0,0 +1,41 @@
+<?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>
+        <record model="ir.ui.view" id="product_uom_view_form">
+            <field name="model">product.uom</field>
+            <field name="inherit" ref="product.uom_view_form"/>
+            <field name="name">product_uom_form</field>
+        </record>
+    </data>
+    <data noupdate="1">
+        <record model="product.uom" id="product.uom_unit">
+            <field name="ups_code">PC</field>
+        </record>
+        <record model="product.uom" id="product.uom_kilogram">
+            <field name="ups_code">KG</field>
+        </record>
+        <record model="product.uom" id="product.uom_pound">
+            <field name="ups_code">LB</field>
+        </record>
+        <record model="product.uom" id="product.uom_meter">
+            <field name="ups_code">M</field>
+        </record>
+        <record model="product.uom" id="product.uom_centimeter">
+            <field name="ups_code">CM</field>
+        </record>
+        <record model="product.uom" id="product.uom_yard">
+            <field name="ups_code">YD</field>
+        </record>
+        <record model="product.uom" id="product.uom_liter">
+            <field name="ups_code">L</field>
+        </record>
+        <record model="product.uom" id="product.uom_square_meter">
+            <field name="ups_code">SME</field>
+        </record>
+        <record model="product.uom" id="product.uom_square_yard">
+            <field name="ups_code">SYD</field>
+        </record>
+    </data>
+</tryton>
diff -r 6c34c538d4aa -r 225fbc061f26 modules/stock_package_shipping_ups/setup.py
--- a/modules/stock_package_shipping_ups/setup.py       Sat Feb 15 22:24:49 
2025 +0100
+++ b/modules/stock_package_shipping_ups/setup.py       Mon Feb 17 19:01:11 
2025 +0100
@@ -52,8 +52,11 @@
 
 tests_require = [
     get_require_version('proteus'),
+    get_require_version('trytond_customs'),
+    get_require_version('trytond_incoterm'),
     get_require_version('trytond_sale'),
     get_require_version('trytond_sale_shipment_cost'),
+    get_require_version('trytond_stock_shipment_customs'),
     ]
 
 setup(name=name,
diff -r 6c34c538d4aa -r 225fbc061f26 modules/stock_package_shipping_ups/stock.py
--- a/modules/stock_package_shipping_ups/stock.py       Sat Feb 15 22:24:49 
2025 +0100
+++ b/modules/stock_package_shipping_ups/stock.py       Mon Feb 17 19:01:11 
2025 +0100
@@ -5,6 +5,7 @@
 import re
 import ssl
 import urllib.parse
+from decimal import Decimal
 from itertools import zip_longest
 from math import ceil
 
@@ -396,3 +397,126 @@
                     }
                 },
             }
+
+
+class CreateShippingUPS_Customs_Incoterm(metaclass=PoolMeta):
+    __name__ = 'stock.shipment.create_shipping.ups'
+
+    def get_request(self, shipment, packages, credential):
+        request = super().get_request(shipment, packages, credential)
+        if (shipment.customs_international
+                and credential.use_international_forms):
+            international_form = self.get_international_form(
+                shipment, credential)
+            request['ShipmentRequest']['Shipment'].setdefault(
+                'ShipmentServiceOptions', {})['InternationalForms'] = (
+                    international_form)
+        return request
+
+    def get_international_form(self, shipment, credential):
+        form_type = self.get_international_form_type(shipment, credential)
+        return getattr(self, f'get_international_form_{form_type}')(
+            credential.use_metric, shipment)
+
+    def get_international_form_type(self, shipment, credential):
+        return 'invoice'
+
+    def get_international_form_invoice(self, use_metric, shipment):
+        pool = Pool()
+        Date = pool.get('ir.date')
+
+        with Transaction().set_context(company=shipment.company.id):
+            today = Date.today()
+
+        if customs_agent := shipment.customs_agent:
+            sold_to_party = customs_agent.party
+            sold_to_address = customs_agent.address
+        else:
+            sold_to_party = shipment.shipping_to
+            sold_to_address = shipment.shipping_to_address
+
+        invoice_date = shipment.effective_date or today
+        currency, = {m.currency for m in shipment.customs_moves}
+        sold_to = self.get_shipping_party(sold_to_party, sold_to_address)
+        if customs_agent:
+            sold_to['AccountNumber'] = customs_agent.ups_account_number
+        return {
+            'FormType': '01',  # Invoice
+            'Contacts': {
+                'SoldTo': sold_to,
+                },
+            'Product': [
+                self.get_international_form_invoice_product(
+                    use_metric, shipment, *k, **v)
+                for k, v in shipment.customs_products.items()],
+            'InvoiceNumber': shipment.number[-35:],
+            'InvoiceDate': invoice_date.strftime('%Y%m%d'),
+            'TermsOfShipment': (
+                shipment.incoterm.code if shipment.incoterm else None),
+            'ReasonForExport': self.get_international_form_invoice_reason(
+                shipment),
+            'CurrencyCode': currency.code,
+            }
+
+    def get_international_form_invoice_product(
+            self, use_metric, shipment, product, price, currency, unit,
+            quantity, weight):
+        pool = Pool()
+        UoM = pool.get('product.uom')
+        ModelData = pool.get('ir.model.data')
+
+        kg = UoM(ModelData.get_id('product', 'uom_kilogram'))
+        lb = UoM(ModelData.get_id('product', 'uom_pound'))
+
+        tariff_code = product.get_tariff_code({
+                'date': shipment.effective_date or shipment.planned_date,
+                'country': (
+                    shipment.customs_to_country.id
+                    if shipment.customs_to_country else None),
+                })
+        weight = UoM.compute_qty(
+            kg, weight, kg if use_metric else lb, round=False)
+        if len(str(weight)) > 5:
+            weight = ceil(weight)
+
+        if not quantity.is_integer():
+            value = price * Decimal(str(quantity))
+            quantity = 1
+            unit_code = 'OTH'
+        else:
+            value = price
+            unit_code = unit.ups_code
+
+        for i in range(6, -1, -1):
+            value = str(price.quantize(Decimal(10) ** -i)).rstrip('0')
+            if len(value) <= 19:
+                break
+        return {
+            'Description': product.name[:35],
+            'Unit': {
+                'Number': '%i' % quantity,
+                'UnitOfMeasurement': {
+                    'Code': unit_code,
+                    'Description': (
+                        unit.ups_code if unit.ups_code != 'OTH'
+                        else unit.name)[:3],
+                    },
+                'Value': value,
+                },
+            'CommodityCode': tariff_code.code if tariff_code else None,
+            'OriginCountryCode': (
+                product.country_of_origin.code if product.country_of_origin
+                else None),
+            'ProductWeight': {
+                'UnitOfMeasurement': {
+                    'Code': 'KGS' if use_metric else 'LBS',
+                    },
+                'Weight': str(weight),
+                },
+            }
+
+    def get_international_form_invoice_reason(self, shipment):
+        return {
+            'stock.shipment.out': 'SALE',
+            'stock.shipment.in.return': 'RETURN',
+            }.get(shipment.__class__.__name__)
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst
--- a/modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst        
Sat Feb 15 22:24:49 2025 +0100
+++ b/modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst        
Mon Feb 17 19:01:11 2025 +0100
@@ -175,7 +175,7 @@
     >>> carrier.party = ups
     >>> carrier.carrier_product = carrier_product
     >>> carrier.shipping_service = 'ups'
-    >>> carrier.ups_service_type = '65'
+    >>> carrier.ups_service_type = '11'
     >>> carrier.ups_label_image_format = 'GIF'
     >>> carrier.ups_notifications = ['5', '7', '012']
     >>> carrier.save()
@@ -204,7 +204,6 @@
 
     >>> Package = Model.get('stock.package')
     >>> shipment, = sale.shipments
-    >>> shipment.shipping_description = 'Football Players'
     >>> shipment.click('assign_try')
     >>> shipment.click('pick')
     >>> pack = shipment.packages.new()
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/tests/scenario_stock_package_shipping_ups_international.rst
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ 
b/modules/stock_package_shipping_ups/tests/scenario_stock_package_shipping_ups_international.rst
    Mon Feb 17 19:01:11 2025 +0100
@@ -0,0 +1,187 @@
+======================================================
+Stock Package Shipping with UPS International Scenario
+======================================================
+
+Imports::
+
+    >>> import os
+    >>> from decimal import Decimal
+
+    >>> from proteus import Model
+    >>> from trytond.modules.company.tests.tools import create_company, 
get_company
+    >>> from trytond.tests.tools import activate_modules, assertEqual
+
+Activate modules::
+
+    >>> config = activate_modules(
+    ...     ['stock_package_shipping_ups', 'stock_shipment_customs'],
+    ...     create_company)
+
+    >>> Agent = Model.get('customs.agent')
+    >>> AgentSelection = Model.get('customs.agent.selection')
+    >>> Address = Model.get('party.address')
+    >>> Carrier = Model.get('carrier')
+    >>> Country = Model.get('country.country')
+    >>> Location = Model.get('stock.location')
+    >>> Package = Model.get('stock.package')
+    >>> PackageType = Model.get('stock.package.type')
+    >>> Party = Model.get('party.party')
+    >>> ProductTemplate = Model.get('product.template')
+    >>> Shipment = Model.get('stock.shipment.out')
+    >>> UPSCredential = Model.get('carrier.credential.ups')
+    >>> UoM = Model.get('product.uom')
+
+Get company::
+
+    >>> company = get_company()
+
+Create countries::
+
+    >>> belgium = Country(code='BE', name="Belgium")
+    >>> belgium.save()
+    >>> switzerland = Country(code='CH', name="Switerland")
+    >>> switzerland.save()
+    >>> taiwan = Country(code='TW', name="Taiwan")
+    >>> taiwan.save()
+
+Create parties::
+
+    >>> customer = Party(name="Customer")
+    >>> customer_address, = customer.addresses
+    >>> customer_address.street = "Pfistergasse 17"
+    >>> customer_address.postal_code = "6003"
+    >>> customer_address.city = "Lucerna"
+    >>> customer_address.country = switzerland
+    >>> customer_phone = customer.contact_mechanisms.new()
+    >>> customer_phone.type = 'phone'
+    >>> customer_phone.value = "+(41) (041) 410-62-66"
+    >>> customer_email = customer.contact_mechanisms.new()
+    >>> customer_email.type = 'email'
+    >>> customer_email.value = '[email protected]'
+    >>> customer.save()
+
+    >>> agent_party = Party(name="Agent")
+    >>> agent_address, = agent_party.addresses
+    >>> agent_address.street = "Gerechtigkeitsgasse 53"
+    >>> agent_address.postal_code = "3011"
+    >>> agent_address.city = "Berna"
+    >>> agent_address.country = switzerland
+    >>> agent_identifier = agent_party.identifiers.new()
+    >>> agent_identifier.type = 'ch_vat'
+    >>> agent_identifier.code = "CHE-123.456.788 IVA"
+    >>> agent_party.save()
+    >>> agent = Agent(party=agent_party)
+    >>> agent.save()
+    >>> AgentSelection(to_country=switzerland, agent=agent).save()
+
+Set the warehouse address::
+
+    >>> warehouse, = Location.find([('type', '=', 'warehouse')])
+    >>> company_address = Address()
+    >>> company_address.party = company.party
+    >>> company_address.street = '2 rue de la Centrale'
+    >>> company_address.postal_code = '4000'
+    >>> company_address.city = 'Sclessin'
+    >>> company_address.country = belgium
+    >>> company_address.save()
+    >>> company_phone = company.party.contact_mechanisms.new()
+    >>> company_phone.type = 'phone'
+    >>> company_phone.value = '+32 4 2522122'
+    >>> company_phone.save()
+    >>> warehouse.address = company_address
+    >>> warehouse.save()
+
+Get some units::
+
+    >>> unit, = UoM.find([('name', '=', "Unit")], limit=1)
+    >>> cm, = UoM.find([('name', '=', "Centimeter")], limit=1)
+    >>> gram, = UoM.find([('name', '=', "Gram")], limit=1)
+
+Create product::
+
+    >>> template = ProductTemplate()
+    >>> template.name = "Product"
+    >>> template.default_uom = unit
+    >>> template.type = 'goods'
+    >>> template.weight = 100
+    >>> template.weight_uom = gram
+    >>> template.list_price = Decimal('10.0000')
+    >>> template.country_of_origin = taiwan
+    >>> template.save()
+    >>> product, = template.products
+
+Create Package Type::
+
+    >>> ups_box = PackageType(
+    ...     name='UPS Box', ups_code='02',
+    ...     length=10, length_uom=cm,
+    ...     height=8, height_uom=cm,
+    ...     width=1, width_uom=cm)
+    >>> ups_box.save()
+
+Create a UPS Carrier and the related credential::
+
+    >>> credential = UPSCredential()
+    >>> credential.company = company
+    >>> credential.client_id = os.getenv('UPS_CLIENT_ID')
+    >>> credential.client_secret = os.getenv('UPS_CLIENT_SECRET')
+    >>> credential.account_number = os.getenv('UPS_ACCOUNT_NUMBER')
+    >>> credential.server = 'testing'
+    >>> credential.use_international_forms = True
+    >>> credential.save()
+
+    >>> carrier_product_template = ProductTemplate()
+    >>> carrier_product_template.name = 'UPS Ground'
+    >>> carrier_product_template.default_uom = unit
+    >>> carrier_product_template.type = 'service'
+    >>> carrier_product_template.list_price = Decimal(20)
+    >>> carrier_product_template.save()
+    >>> carrier_product, = carrier_product_template.products
+
+    >>> ups = Party(name='UPS')
+    >>> ups.save()
+
+    >>> carrier = Carrier()
+    >>> carrier.party = ups
+    >>> carrier.carrier_product = carrier_product
+    >>> carrier.shipping_service = 'ups'
+    >>> carrier.ups_service_type = '65'
+    >>> carrier.ups_label_image_format = 'GIF'
+    >>> carrier.ups_notifications = ['5', '7', '012']
+    >>> carrier.save()
+
+Create a shipment::
+
+    >>> shipment = Shipment()
+    >>> shipment.customer = customer
+    >>> shipment.carrier = carrier
+    >>> shipment.shipping_description = "Shipping description"
+    >>> move = shipment.outgoing_moves.new()
+    >>> move.product = product
+    >>> move.unit = unit
+    >>> move.quantity = 2
+    >>> move.from_location = shipment.warehouse_output
+    >>> move.to_location = shipment.customer_location
+    >>> move.unit_price = Decimal('50.0000')
+    >>> move.currency = company.currency
+    >>> shipment.click('wait')
+    >>> assertEqual(shipment.customs_agent, agent)
+    >>> shipment.click('assign_force')
+    >>> shipment.click('pick')
+    >>> shipment.state
+    'picked'
+
+Create the packs and ship the shipment::
+
+    >>> pack = shipment.packages.new()
+    >>> pack.type = ups_box
+    >>> pack_move, = pack.moves.find([])
+    >>> pack.moves.append(pack_move)
+    >>> shipment.click('pack')
+    >>> shipment.state
+    'packed'
+
+    >>> create_shipping = shipment.click('create_shipping')
+    >>> shipment.reload()
+    >>> bool(shipment.shipping_reference)
+    True
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/tests/test_module.py
--- a/modules/stock_package_shipping_ups/tests/test_module.py   Sat Feb 15 
22:24:49 2025 +0100
+++ b/modules/stock_package_shipping_ups/tests/test_module.py   Mon Feb 17 
19:01:11 2025 +0100
@@ -7,6 +7,7 @@
 class ShippingUpsTestCase(ModuleTestCase):
     'Test Shipping Ups module'
     module = 'stock_package_shipping_ups'
+    extras = ['customs', 'incoterm', 'stock_shipment_customs']
 
 
 del ModuleTestCase
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/tests/test_scenario.py
--- a/modules/stock_package_shipping_ups/tests/test_scenario.py Sat Feb 15 
22:24:49 2025 +0100
+++ b/modules/stock_package_shipping_ups/tests/test_scenario.py Mon Feb 17 
19:01:11 2025 +0100
@@ -11,5 +11,8 @@
             or not (os.getenv('UPS_CLIENT_ID')
                 and os.getenv('UPS_CLIENT_SECRET')
                 and os.getenv('UPS_ACCOUNT_NUMBER'))):
-        kwargs.setdefault('skips', set()).add('scenario_shipping_ups.rst')
+        kwargs.setdefault('skips', set()).update([
+                'scenario_shipping_ups.rst',
+                'scenario_stock_package_shipping_ups_international.rst',
+                ])
     return load_doc_tests(__name__, __file__, *args, **kwargs)
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/tryton.cfg
--- a/modules/stock_package_shipping_ups/tryton.cfg     Sat Feb 15 22:24:49 
2025 +0100
+++ b/modules/stock_package_shipping_ups/tryton.cfg     Mon Feb 17 19:01:11 
2025 +0100
@@ -10,13 +10,20 @@
     stock_shipment_measurements
     stock_package
     stock_package_shipping
+extras_depend:
+    customs
+    incoterm
+    stock_shipment_customs
 xml:
+    product.xml
     carrier.xml
+    customs.xml
     stock.xml
     message.xml
 
 [register]
 model:
+    product.UoM
     carrier.CredentialUPS
     carrier.Carrier
     stock.PackageType
@@ -25,5 +32,13 @@
     stock.CreateShipping
     stock.CreateShippingUPS
 
+[register customs]
+model:
+    customs.Agent
+
+[register incoterm stock_shipment_customs]
+wizard:
+    stock.CreateShippingUPS_Customs_Incoterm
+
 [register_mixin]
 stock.ShippingUPSMixin: 
trytond.modules.stock_package_shipping.stock.ShippingMixin
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/view/customs_agent_form.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/view/customs_agent_form.xml    Mon Feb 
17 19:01:11 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='tax_identifier']" position="after">
+        <label name="ups_account_number"/>
+        <field name="ups_account_number"/>
+        <newline/>
+    </xpath>
+</data>
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/view/customs_agent_list.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/view/customs_agent_list.xml    Mon Feb 
17 19:01:11 2025 +0100
@@ -0,0 +1,8 @@
+<?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='tax_identifier']" position="after">
+        <field name="ups_account_number" optional="1"/>
+    </xpath>
+</data>
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/view/product_uom_form.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_package_shipping_ups/view/product_uom_form.xml      Mon Feb 
17 19:01:11 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='digits']" position="after">
+        <label name="ups_code"/>
+        <field name="ups_code"/>
+        <newline/>
+    </xpath>
+</data>
diff -r 6c34c538d4aa -r 225fbc061f26 
modules/stock_package_shipping_ups/view/ups_credential_form.xml
--- a/modules/stock_package_shipping_ups/view/ups_credential_form.xml   Sat Feb 
15 22:24:49 2025 +0100
+++ b/modules/stock_package_shipping_ups/view/ups_credential_form.xml   Mon Feb 
17 19:01:11 2025 +0100
@@ -14,6 +14,8 @@
 
     <label name="use_metric"/>
     <field name="use_metric"/>
+    <label name="use_international_forms"/>
+    <field name="use_international_forms"/>
 
     <separator string="Credential Information" colspan="4" 
id="credential_info"/>
     <label name="client_id"/>

Reply via email to