diff --git a/tests/browser_test.mjs b/tests/browser_test.mjs index 2f2bdda..2751901 100644 --- a/tests/browser_test.mjs +++ b/tests/browser_test.mjs @@ -100,6 +100,12 @@ try{ await site.fill('#fZap','11999999999'); await site.fill('#fMail','local-browser@example.test'); assert.equal(await site.eval('pedido[0].localFiles[0].name'),'local-test.cdr'); + // An unchecked item stays in the cart but is not paid for now. + await site.click('[data-sel="0"]'); + assert.deepEqual(await site.eval(`({marcado:pedido[0].marcado,pagar:itensAPagar().length,zero:$('carrTot').textContent.includes('0,00'),row:document.querySelector('.item').classList.contains('fora')})`), + {marcado:false,pagar:0,zero:true,row:true}); + await site.click('[data-sel="0"]'); + assert.equal(await site.eval('pedido[0].marcado===true && itensAPagar().length===1'),true); assert.equal(await site.eval('pedido[0].total'),21.89); assert.equal(await site.eval('document.getElementById("bPagar").disabled'),false); await site.click('#bPagar'); diff --git a/web/cart.js b/web/cart.js index 430b0c2..e826179 100644 --- a/web/cart.js +++ b/web/cart.js @@ -18,7 +18,7 @@ try{ if(!items.length){await transaction('readwrite',store=>store.delete(scope));return;} await transaction('readwrite',store=>store.put({items,expires:Date.now()+86400000},scope)); - notice.textContent='Carrinho salvo neste navegador por 24 horas. Você pode remover itens e adicionar outros após recarregar.'; + notice.textContent=''; }catch(error){notice.textContent='Não foi possível salvar o carrinho neste navegador. Mantenha esta página aberta até enviar o pedido.';} } window.dtfClearCart=async()=>{clearTimeout(timer);if(database&&scope)await transaction('readwrite',store=>store.delete(scope));notice.textContent='';}; diff --git a/web/checkout.js b/web/checkout.js index 5382f6d..fd7940c 100644 --- a/web/checkout.js +++ b/web/checkout.js @@ -15,7 +15,7 @@ let quotedCart = localStorage.getItem('dtf-quote-cart'); let refreshVersion = 0; function cartSnapshot() { - const items=[...pedido,...(itemAtual?[itemAtual]:[])]; + const items=itensAPagar(); return JSON.stringify({customer:cliente,delivery:entrega,items:items.map(item=>({ mode:item.modo,metres:item.metros,grade:item.nota,production:item.production, quality:item.qualityStatus, @@ -127,7 +127,7 @@ arquivos.forEach(f=>enviar(f).catch(()=>{})); pintaEnvio(); } - const arquivosDoCarrinho=()=>[...pedido,...(busy&&itemAtual?[itemAtual]:[])].flatMap(it=>it.localFiles||[]); + const arquivosDoCarrinho=()=>[...pedido.filter(it=>it.marcado!==false),...(busy&&itemAtual?[itemAtual]:[])].flatMap(it=>it.localFiles||[]); const gb=n=>(n/1073741824).toLocaleString('pt-BR',{maximumFractionDigits:1})+' GB'; const mb=n=>n>=1073741824 ? gb(n) : Math.round(n/1048576)+' MB'; // Where the uploads stand, and roughly how long is left from the recent speed. @@ -208,7 +208,7 @@ // 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]:[])]; + const items=itensAPagar(); 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; @@ -247,7 +247,7 @@ if (!clienteOk() || !entrega.cotado) return; if (!enderecoOk()) return message('Preencha o endereço de entrega.'); if (!cartPodeEnviar()) return message('Revise a qualidade e confirme a ressalva de cada item antes de enviar o pedido.'); - const cart = [...pedido,...(itemAtual?[itemAtual]:[])]; + const cart = itensAPagar(); if (!cart.length) return message('Adicione um item ao pedido.'); const initialCart=cartSnapshot(); busy = true; @@ -333,8 +333,7 @@ event.target.disabled=true; try { const order=await api('/orders/dev-paid',{quote_id:draftId}); - pedido=[]; itemAtual=null; limpaPaineis(); - await window.dtfClearCart?.(); + await pagos(); message('Pedido #'+order.number+' criado e disponível no Kanban.'); await refresh(); } catch(error) { message(error.message); event.target.disabled=false; } @@ -360,8 +359,7 @@ const quote=await api('/quotes/'+draftId); if (quote.status==='paid') { clearInterval(waitTimer); - pedido=[]; itemAtual=null; limpaPaineis(); - await window.dtfClearCart?.(); + await pagos(); await refresh(); } else if (quote.payment?.status==='rejected') { // Refused after the bank's confirmation or the provider's review. @@ -397,6 +395,11 @@ actions.append(box); } const cartOk=()=>!!quotedCart && quotedCart===cartSnapshot(); + // What was paid leaves the cart; unchecked items stay for another order. + async function pagos() { + pedido=pedido.filter(it=>it.marcado===false); itemAtual=null; limpaPaineis(); + if (pedido.length) pintaPedido(); else await window.dtfClearCart?.(); + } // Paying: card (the default, paid on this page) or PIX (paid on its own page). async function escolhaPagamento(quote, version) { diff --git a/web/index.html b/web/index.html index 78a29fe..44aeb23 100644 --- a/web/index.html +++ b/web/index.html @@ -1094,8 +1094,6 @@ footer a:hover{color:var(--laranja2)}
A conta nasce aqui, no pagamento. O CNPJ é o mesmo da nota fiscal, - e é por ele que suas artes ficam guardadas para o próximo pedido.