Implantação da função d adicionar entregas por fora da operação
This commit is contained in:
118
app/javascript/controllers/apontamento_controller.js
Normal file
118
app/javascript/controllers/apontamento_controller.js
Normal file
@@ -0,0 +1,118 @@
|
||||
// app/javascript/controllers/apontamento_controller.js
|
||||
// Stimulus controller — Apontamento manual de entrega na consolidação.
|
||||
// Busca a NF na base de rastreio (SimpleRoute), exibe os dados para conferência
|
||||
// e cria o apontamento com o tipo (pilar) escolhido.
|
||||
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["modal", "nf", "erro", "resultados", "confirmar", "tipo"]
|
||||
static values = { buscarUrl: String, apontarUrl: String }
|
||||
|
||||
// ── Modal ──────────────────────────────────────────────────
|
||||
abrir() {
|
||||
this.reset()
|
||||
this.modalTarget.classList.remove("hidden")
|
||||
this.nfTarget.focus()
|
||||
}
|
||||
|
||||
fechar() {
|
||||
this.modalTarget.classList.add("hidden")
|
||||
}
|
||||
|
||||
// Fecha ao clicar no fundo (fora do card)
|
||||
fundo(event) {
|
||||
if (event.target === this.modalTarget) this.fechar()
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.nfTarget.value = ""
|
||||
this.erroTarget.classList.add("hidden")
|
||||
this.resultadosTarget.innerHTML = ""
|
||||
this.confirmarTarget.classList.add("hidden")
|
||||
}
|
||||
|
||||
// ── Busca da NF ────────────────────────────────────────────
|
||||
async buscar(event) {
|
||||
event?.preventDefault()
|
||||
const nf = this.nfTarget.value.trim()
|
||||
if (!nf) { this.mostrarErro("Informe o número da nota."); return }
|
||||
|
||||
this.erroTarget.classList.add("hidden")
|
||||
this.resultadosTarget.innerHTML = `<p class="text-gray-400 text-sm">Buscando…</p>`
|
||||
this.confirmarTarget.classList.add("hidden")
|
||||
|
||||
try {
|
||||
const url = `${this.buscarUrlValue}?nf=${encodeURIComponent(nf)}`
|
||||
const resp = await fetch(url, { headers: { "Accept": "application/json" } })
|
||||
const data = await resp.json()
|
||||
|
||||
if (!data.ok) {
|
||||
this.resultadosTarget.innerHTML = ""
|
||||
this.mostrarErro(data.erro || "Nota não encontrada.")
|
||||
return
|
||||
}
|
||||
this.renderResultados(data.entregas)
|
||||
} catch (e) {
|
||||
this.resultadosTarget.innerHTML = ""
|
||||
this.mostrarErro("Erro ao buscar a nota. Tente novamente.")
|
||||
}
|
||||
}
|
||||
|
||||
renderResultados(entregas) {
|
||||
const cards = entregas.map((e, i) => {
|
||||
const pago = e.pago
|
||||
? `<span class="text-green-400">paga</span>`
|
||||
: `<span class="text-yellow-400">${e.status || "pendente"}</span>`
|
||||
return `
|
||||
<label class="flex gap-3 items-start bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg p-3 cursor-pointer hover:border-orange-500">
|
||||
<input type="radio" name="apontamento_entrega" value="${e.tracking_id}" ${i === 0 ? "checked" : ""} class="mt-1 accent-orange-500">
|
||||
<div class="text-sm">
|
||||
<p class="text-white font-bold">NF ${e.nf || "—"} · ${e.motorista || "sem motorista"}</p>
|
||||
<p class="text-gray-400">${e.veiculo || "—"} · ${e.local || "—"}</p>
|
||||
<p class="text-gray-500 text-xs">${e.data || "—"} · ${pago}</p>
|
||||
</div>
|
||||
</label>`
|
||||
}).join("")
|
||||
|
||||
this.resultadosTarget.innerHTML = cards
|
||||
this.confirmarTarget.classList.remove("hidden")
|
||||
}
|
||||
|
||||
// ── Criar apontamento ──────────────────────────────────────
|
||||
async apontar(event) {
|
||||
event?.preventDefault()
|
||||
const selecionado = this.resultadosTarget.querySelector('input[name="apontamento_entrega"]:checked')
|
||||
if (!selecionado) { this.mostrarErro("Selecione uma entrega."); return }
|
||||
|
||||
const btn = event.currentTarget
|
||||
btn.disabled = true
|
||||
try {
|
||||
const resp = await fetch(this.apontarUrlValue, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
"X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
|
||||
},
|
||||
body: JSON.stringify({ tracking_id: selecionado.value, tipo: this.tipoTarget.value })
|
||||
})
|
||||
const data = await resp.json()
|
||||
if (!resp.ok || data.ok === false) {
|
||||
this.mostrarErro(data.erro || "Não foi possível adicionar o apontamento.")
|
||||
return
|
||||
}
|
||||
// Recarrega para refletir motorista/valores atualizados.
|
||||
window.location.reload()
|
||||
} catch (e) {
|
||||
this.mostrarErro("Erro ao adicionar o apontamento. Tente novamente.")
|
||||
} finally {
|
||||
btn.disabled = false
|
||||
}
|
||||
}
|
||||
|
||||
mostrarErro(msg) {
|
||||
this.erroTarget.textContent = msg
|
||||
this.erroTarget.classList.remove("hidden")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user