feat: add backend pricing calculation RPC and refactor create_lead function

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
LagoESP
2026-04-29 20:18:07 +02:00
parent 4c1931cdf4
commit b0bea0bef1
5 changed files with 238 additions and 57 deletions
+23 -40
View File
@@ -351,7 +351,7 @@ function calcWeekendDays(from, to) {
return count;
}
function updateSidebar() {
async function updateSidebar() {
const v = state.vehicles.find(x => x.id === bpfCar.value);
const { from, to } = getBpfDates();
if (!v || !from || !to) {
@@ -364,18 +364,25 @@ function updateSidebar() {
if (!fromD || !toD) return;
if (toD <= fromD) return;
const totalDays = Math.ceil((toD - fromD) / (1000 * 60 * 60 * 24));
const weekendDays = bpfDurationMode === "weekend" ? 2 : calcWeekendDays(from, to);
const weekdays = bpfDurationMode === "weekend" ? 0 : (totalDays - weekendDays);
// Fetch price from backend RPC
const { data: price, error } = await supabase.rpc("calculate_price", {
p_vehicle_id: v.id,
p_date_from: from,
p_date_to: to,
});
if (error || !price) { console.error("calculate_price error:", error, "data:", price); return; }
const weekdayCost = weekdays * v.daily_price_eur;
const weekendCost = weekendDays * (v.weekend_price_eur || v.daily_price_eur);
const subtotal = weekdayCost + weekendCost;
const vat = Math.round(subtotal * 0.20);
const total = subtotal + vat;
const deposit = v.kaution_eur || 5000;
const kmPerWeekendDay = v.max_km_weekend || v.max_daily_km || 150;
const kmPerWeekday = v.max_daily_km || 150;
const totalDays = price.total_days;
const weekdays = price.weekday_count;
const weekendDays = price.weekend_day_count;
const weekdayCost = price.daily_subtotal;
const weekendCost = price.weekend_subtotal;
const subtotal = price.subtotal_eur;
const vat = price.vat_eur;
const total = price.total_eur;
const deposit = price.deposit_eur;
const kmPerWeekday = price.max_daily_km;
const kmPerWeekendDay = price.max_km_weekend;
const includedKm = (weekdays * kmPerWeekday) + (weekendDays * kmPerWeekendDay);
bpfSidebarPlaceholder.style.display = "none";
@@ -383,8 +390,8 @@ function updateSidebar() {
bpfSidebarContent.innerHTML = `
<h4>${t("bpfPriceOverview")}</h4>
<div class="bpf-price-row"><span>${v.brand} ${v.model} · ${totalDays} ${t("bpfDays")}</span></div>
${weekdays > 0 ? `<div class="bpf-price-row"><span>${t("bpfWeekdays")} (${weekdays} ×${v.daily_price_eur})</span><span>€ ${weekdayCost.toLocaleString("de-DE")}</span></div>` : ""}
${weekendDays > 0 ? `<div class="bpf-price-row"><span>${t("bpfWeekendDays")} (${weekendDays} ×${v.weekend_price_eur || v.daily_price_eur})</span><span>€ ${weekendCost.toLocaleString("de-DE")}</span></div>` : ""}
${weekdays > 0 ? `<div class="bpf-price-row"><span>${t("bpfWeekdays")} (${weekdays} ×${price.daily_price_eur})</span><span>€ ${weekdayCost.toLocaleString("de-DE")}</span></div>` : ""}
${weekendDays > 0 ? `<div class="bpf-price-row"><span>${t("bpfWeekendDays")} (${weekendDays} ×${price.weekend_price_eur})</span><span>€ ${weekendCost.toLocaleString("de-DE")}</span></div>` : ""}
<div class="bpf-price-row"><span>${t("bpfSubtotal")}</span><span>€ ${subtotal.toLocaleString("de-DE")}</span></div>
<div class="bpf-price-row muted"><span>${t("bpfVat")}</span><span>€ ${vat.toLocaleString("de-DE")}</span></div>
<div class="bpf-price-row total"><span>${t("bpfTotal")}</span><span>€ ${total.toLocaleString("de-DE")}</span></div>
@@ -411,40 +418,16 @@ document.querySelector("#bpfSubmit").addEventListener("click", async () => {
const vehicle = state.vehicles.find(v => v.id === bpfCar.value);
const { from, to } = getBpfDates();
const vFrom = parseYmdLocal(from);
const vTo = parseYmdLocal(to);
let weekdayCost = 0, weekendCost = 0, subtotal = 0, vat = 0, total = 0, deposit = 0;
let totalDays = 0, weekdays = 0, weekendDays = 0;
if (vehicle && vFrom && vTo && vTo > vFrom) {
totalDays = Math.ceil((vTo - vFrom) / (1000 * 60 * 60 * 24));
weekendDays = bpfDurationMode === "weekend" ? 2 : calcWeekendDays(from, to);
weekdays = bpfDurationMode === "weekend" ? 0 : (totalDays - weekendDays);
weekdayCost = weekdays * vehicle.daily_price_eur;
weekendCost = weekendDays * (vehicle.weekend_price_eur || vehicle.daily_price_eur);
subtotal = weekdayCost + weekendCost;
vat = Math.round(subtotal * 0.20);
total = subtotal + vat;
deposit = vehicle.kaution_eur || 5000;
}
const payload = {
p_name: bpfName.value,
p_email: bpfEmail.value,
p_phone: bpfPhone.value || "",
p_vehicle_id: bpfCar.value || null,
p_vehicle_label: vehicle ? `${vehicle.brand} ${vehicle.model}` : "",
p_date_from: bpfFrom.value || null,
p_date_to: bpfTo.value || null,
p_date_from: from || null,
p_date_to: to || null,
p_message: bpfMessage.value || "",
p_source: "website",
p_daily_subtotal: weekdayCost,
p_weekend_subtotal: weekendCost,
p_subtotal_eur: subtotal,
p_vat_eur: vat,
p_total_eur: total,
p_deposit_eur: deposit,
p_total_days: totalDays,
p_weekday_count: weekdays,
p_weekend_day_count: weekendDays,
};
// Create lead via RPC (returns inserted id without anon SELECT privileges)