Update DPD API to Shipment Service 4.5

This commit is contained in:
Cédric Krier
2026-06-24 11:01:19 +02:00
parent 4ddc5340b8
commit 899ecc39e9
4 changed files with 69 additions and 28 deletions
@@ -1,3 +1,4 @@
* Update to Shipment Service 4.5
Version 8.0.0 - 2026-04-20
--------------------------
@@ -13,7 +13,7 @@ SERVER_URLS = {
}
LOGIN_SERVICE = 'LoginService/V2_0/?wsdl'
SHIPMENT_SERVICE = 'ShipmentService/V4_4/?wsdl'
SHIPMENT_SERVICE = 'ShipmentService/V4_5/?wsdl'
def get_client(server, service):
@@ -6,7 +6,7 @@ using the DPD webservices.
DPD has many different web services, the module supports:
- `LoginService 2.0 <https://esolutions.dpd.com/dokumente/LoginService_V2_0.pdf>`_
- `ShipmentService 4.4 <https://esolutions.dpd.com/dokumente/ShipmentService_V4_4.pdf>`_
- `ShipmentService 4.5 <https://esolutions.dpd.com/dokumente/ShipmentService_V4_5.pdf>`_
Carrier Credential
******************
+66 -26
View File
@@ -234,6 +234,9 @@ class CreateDPDShipping(Wizard):
mobile = address.contact_mechanism_get('mobile', usage=usage)
if mobile and len(mobile.value) <= 30:
shipping_party['mobile'] = mobile.value
fax = address.contact_mechanism_get('fax', usage=usage)
if fax and len(fax.value) <= 30:
shipping_party['fax'] = fax.value
email = address.contact_mechanism_get('email', usage=usage)
if email and 5 <= len(email.value) <= 100:
shipping_party['email'] = email.value
@@ -376,25 +379,30 @@ class CreateDPDShipping_Customs(metaclass=PoolMeta):
'customsAmount': int(
amount.quantize(Decimal('.01')) * Decimal(100)),
'customsCurrency': currency.code,
'customsTerms': self.get_customs_terms(shipment),
'customsPaper': 'A',
'customsInvoice': shipment.number[:20],
'customsInvoiceDate': invoice_date.strftime('%Y%m%d'),
'reasonForExport': self.get_international_form_invoice_reason(
shipment),
}
if customs_agent := shipment.customs_agent:
international.update({
'commercialInvoiceConsigneeVatNumber': (
customs_agent.tax_identifier.code_compact)[:20],
'commercialInvoiceConsignee': self.shipping_party(
customs_agent.party,
customs_agent.address,
with_contact=True),
})
if shipment.tax_identifier:
international['commercialInvoiceConsignorVatNumber'] = (
shipment.tax_identifier.code_compact[:17])
international['commercialInvoiceConsignor'] = self.shipping_party(
shipment.company.party, shipment.customs_from_address)
consignee = self.shipping_party(
customs_agent.party,
customs_agent.address,
with_contact=True)
consignee['vatNumber'] = (
customs_agent.tax_identifier.code_compact[:20])
international['commercialInvoiceConsignee'] = consignee
if company_party := shipment.company_party:
consignor = self.shipping_party(
company_party,
shipment.customs_from_address,
with_contact=True)
if (shipment.tax_identifier
and shipment.tax_identifier.type == 'eu_vat'):
consignor['eori'] = (
shipment.tax_identifier.code_compact[:20])
international['commercialInvoiceConsignor'] = consignor
international['additionalInvoiceLines'] = [
{'customsInvoicePosition': i,
**self.get_international_invoice_line(shipment, *k, **v)}
@@ -402,26 +410,47 @@ class CreateDPDShipping_Customs(metaclass=PoolMeta):
shipment.customs_products.items(), 1)]
international['numberOfArticle'] = len(
international['additionalInvoiceLines'])
international['clearanceCleared'] = 'F'
if shipment.incoterm:
international['incoterm'] = shipment.incoterm.code
if shipment.incoterm_location:
if shipment.incoterm_location.city:
international['incotermLocationTown'] = (
shipment.incoterm_location.city)
if shipment.incoterm_location.country:
international['incotermLocationCountryCode'] = (
shipment.incoterm_location.country.code)
international['paymentTerm'] = self.get_payment_terms(shipment)
product_and_service['international'] = international
return product_and_service
def get_customs_terms(self, shipment):
def get_payment_terms(self, shipment):
if shipment and shipment.incoterm:
if shipment.incoterm.code == 'DAP':
return '01'
elif shipment.incoterm.code == 'DDP':
return '03'
elif shipment.incoterm.code == 'EXW':
return '05'
if shipment.incoterm.import_duties == 'buyer':
return 'A'
elif shipment.incoterm.import_duties == 'seller':
return 'B'
def get_international_form_invoice_reason(self, shipment):
return {
'stock.shipment.out': '01',
'stock.shipment.in.return': '02',
}.get(shipment.__class__.__name__)
def get_international_invoice_line(
self, shipment, product, price, currency, unit, quantity, weight):
tariff_code = product.get_tariff_code({
recipient_tarrif_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),
})
sender_tarrif_code = product.get_tariff_code({
'date': shipment.effective_date or shipment.planned_date,
'country': (
shipment.customs_from_country.id
if shipment.customs_from_country else None),
})
weight = round(weight, 2)
@@ -429,14 +458,25 @@ class CreateDPDShipping_Customs(metaclass=PoolMeta):
if not quantity.is_integer():
quantity = 1
quantity = int(quantity)
amount = int(
value.quantize(Decimal('.01')) * Decimal(100))
unit_price = amount // quantity
return {
'quantityItems': int(quantity),
'quantityItems': quantity,
'customsContent': product.name[:200],
'customsTarif': tariff_code.code if tariff_code else None,
'customsAmountLine': int(
value.quantize(Decimal('.01')) * Decimal(100)),
'customsAmountLine': amount,
'customsOrigin': (
product.country_of_origin.code_numeric
if product.country_of_origin else None),
'customsOriginAlphanumeric': (
product.country_of_origin.code
if product.country_of_origin else None),
'customsGrossWeight': int(weight * 100),
'recipientCountryTarif': (
recipient_tarrif_code.code if recipient_tarrif_code else None),
'senderCountryTarif': (
sender_tarrif_code.code if sender_tarrif_code else None),
'unitPrice': unit_price,
}