feat: price home delivery with Jadlog
All checks were successful
Build and deploy / Validate source (push) Successful in 1m18s
Build and deploy / Integration suite on a real stack (push) Successful in 2m33s
Build and deploy / Secret scan and release gate (push) Successful in 9s
Build and deploy / Publish images (push) Successful in 1m42s
All checks were successful
Build and deploy / Validate source (push) Successful in 1m18s
Build and deploy / Integration suite on a real stack (push) Successful in 2m33s
Build and deploy / Secret scan and release gate (push) Successful in 9s
Build and deploy / Publish images (push) Successful in 1m42s
FREIGHT_ADAPTER=jadlog prices "Receber em casa" through Jadlog's Simulador de Frete from the order's billed metres and value, adding production days to Jadlog's delivery time. The package weight is a base plus a weight per metre from the client, with no default: the adapter refuses to start without it and without the credentials. The cart re-quotes when the package changes, and approval quotes again from the server-priced items. The production stack takes the Jadlog settings, so the read-only probe runs from the worker's console. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,8 +7,10 @@ unlike Tiny it can be tried on the real account as often as needed.
|
||||
|
||||
The client's contract: origin CEP 14402-310, service .PACKAGE (modalidade 3),
|
||||
home delivery. Jadlog prices by weight in kg and expects the larger of the
|
||||
real and the cubed weight; the weight per metre of film is still to come from
|
||||
the client, so nothing here decides it.
|
||||
real and the cubed weight. The package weight comes from the client (a base
|
||||
plus a weight per billed metre) and has no default: FREIGHT_ADAPTER=jadlog
|
||||
refuses to start without it, so a guessed weight never prices a customer's
|
||||
freight.
|
||||
"""
|
||||
import os
|
||||
from decimal import ROUND_HALF_UP, Decimal
|
||||
@@ -18,6 +20,8 @@ import httpx
|
||||
QUOTE_URL = 'https://www.jadlog.com.br/embarcador/api/frete/valor'
|
||||
PACKAGE = 3
|
||||
ORIGIN = '14402310'
|
||||
SERVICE = 'jadlog'
|
||||
WEIGHT_SETTINGS = ('JADLOG_PESO_BASE_KG', 'JADLOG_PESO_POR_METRO_KG')
|
||||
|
||||
|
||||
class JadlogError(Exception):
|
||||
@@ -72,3 +76,42 @@ class JadlogQuotes:
|
||||
total = Decimal(str(items[0]['vltotal']))
|
||||
return {'total_cents': int((total * 100).quantize(Decimal('1'), ROUND_HALF_UP)),
|
||||
'days': items[0].get('prazo'), 'raw': items[0]}
|
||||
|
||||
|
||||
def required_settings():
|
||||
return ('JADLOG_TOKEN', 'JADLOG_CNPJ') + WEIGHT_SETTINGS
|
||||
|
||||
|
||||
class JadlogFreight:
|
||||
"""The Site's delivery option: Jadlog's price for the order's package."""
|
||||
name = 'jadlog'
|
||||
|
||||
def __init__(self, quotes=None):
|
||||
self.quotes = quotes or JadlogQuotes()
|
||||
self.base_kg = Decimal(os.environ['JADLOG_PESO_BASE_KG'])
|
||||
self.per_metre_kg = Decimal(os.environ['JADLOG_PESO_POR_METRO_KG'])
|
||||
# Jadlog's time counts from collection; the order is printed first.
|
||||
self.production_days = int(os.environ.get('FREIGHT_PRODUCTION_DAYS') or 0)
|
||||
if self.base_kg < 0 or self.per_metre_kg <= 0 or self.production_days < 0:
|
||||
raise RuntimeError('Jadlog package weight and production days must be positive')
|
||||
|
||||
def weight_kg(self, metres):
|
||||
return (self.base_kg + self.per_metre_kg * Decimal(str(metres))).quantize(Decimal('0.001'))
|
||||
|
||||
def quote(self, service, postal_code, metres=None, declared_cents=0):
|
||||
if service == 'pickup':
|
||||
return {'provider': self.name, 'service': 'pickup', 'total_cents': 0, 'postal_code': ''}
|
||||
if service != SERVICE or len(postal_code) != 8 or not postal_code.isascii() or not postal_code.isdigit():
|
||||
raise ValueError('Select pickup or Jadlog delivery with an eight-digit CEP')
|
||||
if metres is None or Decimal(str(metres)) <= 0:
|
||||
raise ValueError('The order length is required to quote freight')
|
||||
weight = self.weight_kg(metres)
|
||||
try:
|
||||
result = self.quotes.quote(postal_code, weight, int(declared_cents))
|
||||
except (JadlogError, httpx.HTTPError) as error:
|
||||
raise ValueError(f'Não foi possível cotar o frete na Jadlog agora: {error}') from None
|
||||
days = result['days']
|
||||
return {'provider': self.name, 'service': SERVICE, 'postal_code': postal_code,
|
||||
'total_cents': result['total_cents'], 'weight_kg': str(weight),
|
||||
'days': None if days is None else int(days) + self.production_days,
|
||||
'description': 'Jadlog .PACKAGE'}
|
||||
|
||||
Reference in New Issue
Block a user