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:
@@ -6,7 +6,7 @@ from fastapi import APIRouter, HTTPException, Request, Response
|
||||
from ..core import db
|
||||
from ..core.auth import client_ip, owner, new_session, rate_limit
|
||||
from ..core.limits import upload_limit_bytes
|
||||
from ..core.models import Freight
|
||||
from ..core.models import FreightEstimate
|
||||
from ..runtime import (ENVIRONMENT, GUEST_SESSION_LIMIT, PART_BYTES, freight, payment,
|
||||
require_delivery_available, storage)
|
||||
|
||||
@@ -37,12 +37,14 @@ def session(request: Request, response: Response):
|
||||
return {'environment': ENVIRONMENT, 'cart_scope': str(session_id), 'part_bytes': PART_BYTES,
|
||||
'max_upload_bytes': upload_limit_bytes(), 'payment_provider': payment.name,
|
||||
# Public by design: Mercado Pago's card form needs it in the browser.
|
||||
'payment_public_key': os.environ.get('MP_PUBLIC_KEY', '') if payment.name == 'mercadopago' else ''}
|
||||
'payment_public_key': os.environ.get('MP_PUBLIC_KEY', '') if payment.name == 'mercadopago' else '',
|
||||
# The delivery service the cart quotes, or none: pickup only.
|
||||
'freight_service': 'jadlog' if freight.name == 'jadlog' else 'mock-standard' if ENVIRONMENT == 'local' else None}
|
||||
|
||||
@router.post('/api/freight')
|
||||
def quote_freight(body: Freight):
|
||||
def quote_freight(body: FreightEstimate):
|
||||
require_delivery_available(body.service)
|
||||
try:
|
||||
return freight.quote(body.service, body.postal_code)
|
||||
return freight.quote(body.service, body.postal_code, body.metres, body.declared_cents)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(422, str(exc))
|
||||
|
||||
@@ -10,6 +10,7 @@ from psycopg.types.json import Jsonb
|
||||
from ..core import db
|
||||
from ..core.auth import owner
|
||||
from ..core.models import QuoteRequest
|
||||
from ..core.pricing import price
|
||||
from .. import quote_review
|
||||
from ..runtime import freight, quote_view, require_delivery_available, upload_row
|
||||
from ..scanning import require_clean
|
||||
@@ -24,10 +25,15 @@ def create_quote(body: QuoteRequest, session_id=Depends(owner)):
|
||||
require_delivery_available(body.freight.service)
|
||||
draft = body.model_dump(mode='json', exclude={'request_key'})
|
||||
digest = hashlib.sha256(json.dumps(draft, sort_keys=True).encode()).hexdigest()
|
||||
try:
|
||||
freight.quote(body.freight.service, body.freight.postal_code)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(422, str(exc))
|
||||
reason = quote_review.review_reason(draft)
|
||||
if reason is not None:
|
||||
# Waits for review: check the delivery now, priced at approval.
|
||||
try:
|
||||
priced = [price(item.mode, str(item.metres), item.grade) for item in body.items]
|
||||
freight.quote(body.freight.service, body.freight.postal_code,
|
||||
sum(Decimal(i['billed_metres']) for i in priced), sum(i['total_cents'] for i in priced))
|
||||
except ValueError as exc:
|
||||
raise HTTPException(422, str(exc))
|
||||
with db.connect() as c:
|
||||
for item in body.items:
|
||||
for uid in item.uploads:
|
||||
@@ -41,7 +47,6 @@ def create_quote(body: QuoteRequest, session_id=Depends(owner)):
|
||||
row = c.execute('SELECT * FROM dtf_local.quotes WHERE owner=%s AND request_key=%s FOR UPDATE', (session_id, body.request_key)).fetchone()
|
||||
if row['request_hash'] != digest:
|
||||
raise HTTPException(409, 'Request key already used for a different cart')
|
||||
reason = quote_review.review_reason(draft)
|
||||
if row['id'] == uid and reason is None:
|
||||
quote_review.approve(c, row, body.items, quote_review.AUTO)
|
||||
return {'id': row['id'], 'status': 'approved'}
|
||||
|
||||
Reference in New Issue
Block a user