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:
@@ -81,7 +81,8 @@
|
||||
const rows = approved.items.map(item => linha(
|
||||
(MODOS[item.mode]?.tit || item.mode)+' · '+fmtM(Number(item.billed_metres))+' m', rs(item.total_cents/100)));
|
||||
const pickup = approved.freight.service === 'pickup';
|
||||
rows.push(linha(pickup ? 'Retirada em Franca' : 'Frete',
|
||||
const prazo = approved.freight.days ? ' · até '+approved.freight.days+' dias úteis' : '';
|
||||
rows.push(linha(pickup ? 'Retirada em Franca' : 'Frete'+prazo,
|
||||
approved.freight.total_cents ? rs(approved.freight.total_cents/100) : 'Grátis'));
|
||||
rows.push(linha('Total', rs(approved.total_cents/100), 'tot'));
|
||||
resumo.replaceChildren(node('h4','Resumo do pedido'), ...rows);
|
||||
@@ -96,17 +97,40 @@
|
||||
const session=await ready;
|
||||
return window.dtfUpload(file,{api,progress:message,scope:session.cart_scope});
|
||||
}
|
||||
// The cart's package: billed metres and value. The charged freight is
|
||||
// quoted again by the server from the approved items.
|
||||
const pacote = () => {
|
||||
const items=[...pedido,...(itemAtual?[itemAtual]:[])];
|
||||
return {metres:items.reduce((t,it)=>t+(it.cob||0),0), cents:Math.round(items.reduce((t,it)=>t+(it.total||0),0)*100)};
|
||||
};
|
||||
let freightQuoted = null;
|
||||
window.dtfFreight = async () => {
|
||||
const cep = entrega.cep;
|
||||
const service = (await ready).freight_service;
|
||||
if (!service) {
|
||||
$('cepMsg').textContent = 'A entrega ainda não está disponível. Escolha a retirada em Franca.';
|
||||
return;
|
||||
}
|
||||
const {metres, cents} = pacote();
|
||||
if (!metres) { $('cepMsg').textContent = 'Adicione um item ao pedido para cotar o frete.'; return; }
|
||||
$('cepMsg').textContent = 'Cotando o frete…';
|
||||
try {
|
||||
const result = await api('/freight',{service:'mock-standard',postal_code:cep});
|
||||
const result = await api('/freight',{service,postal_code:cep,metres:metres.toFixed(2),declared_cents:cents});
|
||||
if (entrega.cep !== cep || entrega.tipo !== 'frete') return;
|
||||
entrega.valor = result.total_cents/100;
|
||||
entrega.cotado = true;
|
||||
$('cepMsg').textContent = 'Frete estimado: '+rs(entrega.valor)+'.';
|
||||
freightQuoted = JSON.stringify(pacote());
|
||||
$('cepMsg').textContent = 'Frete: '+rs(entrega.valor)+
|
||||
(result.days ? ' · entrega em até '+result.days+' dias úteis.' : '.');
|
||||
pintaEntrega();
|
||||
} catch(error) { $('cepMsg').textContent = error.message; }
|
||||
};
|
||||
// A different package is a different freight: quote it again.
|
||||
window.addEventListener('dtf-cart-changed',()=>{
|
||||
if (entrega.tipo==='frete' && entrega.cotado && freightQuoted && freightQuoted!==JSON.stringify(pacote())) {
|
||||
entrega.cotado=false; freightQuoted=null; window.dtfFreight();
|
||||
}
|
||||
});
|
||||
window.dtfCheckout = async () => {
|
||||
if (busy) return;
|
||||
// The cart that was sent goes straight to its payment; a changed cart is sent again.
|
||||
@@ -135,7 +159,9 @@
|
||||
upload_id:uploads[index],...source}))},
|
||||
quality_status:item.qualityStatus,quality_acknowledged:item.qualityAcknowledged});
|
||||
}
|
||||
const content = {customer:{...cliente},items,freight:{service:entrega.tipo==='retira'?'pickup':'mock-standard',postal_code:entrega.tipo==='retira'?'':entrega.cep}};
|
||||
const service = entrega.tipo==='retira' ? 'pickup' : (await ready).freight_service;
|
||||
if (!service) throw new Error('A entrega ainda não está disponível. Escolha a retirada em Franca.');
|
||||
const content = {customer:{...cliente},items,freight:{service,postal_code:entrega.tipo==='retira'?'':entrega.cep}};
|
||||
const destination = destinoApi();
|
||||
if (destination) content.destination = destination;
|
||||
if (cartSnapshot()!==initialCart) throw new Error('O carrinho mudou durante o envio. Confira os itens e envie de novo.');
|
||||
|
||||
Reference in New Issue
Block a user