feat: Add manual email sending workflow and related database changes
- Implemented a new n8n workflow for manual email sending, including webhook trigger, order data fetching, email building, and sending. - Added logic to format email content with customer and order details. - Introduced new columns in the sales_orders table to track email sending status. - Updated database functions to handle new rental types and email status. - Created new RPCs for updating email status and retrieving email details for sales orders.
This commit is contained in:
+43
-27
@@ -1,5 +1,5 @@
|
||||
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.45.4";
|
||||
import { translations, REVIEWS, getLang, setLang, t, applyI18n } from "./i18n.js";
|
||||
import { translations, REVIEWS, getLang, setLang, t, applyI18n } from "./i18n.js?v=3";
|
||||
|
||||
const SUPA_URL = window.MCCARS_CONFIG?.SUPABASE_URL ?? "";
|
||||
const SUPA_KEY = window.MCCARS_CONFIG?.SUPABASE_ANON_KEY || "";
|
||||
@@ -212,11 +212,11 @@ function openDetails(id) {
|
||||
<div><strong>${v.top_speed_kmh}</strong><span>${t("kmh")}</span></div>
|
||||
<div><strong>${escapeHtml(v.acceleration)}</strong><span>${t("accel")}</span></div>
|
||||
</div>
|
||||
<div class="spec-row" style="margin:1rem 0;">
|
||||
<div><strong>${v.seats}</strong><span>${t("seats")}</span></div>
|
||||
<div><strong>€ ${v.weekend_price_eur || v.daily_price_eur}</strong><span>${t("bpfWeekendRate")}</span></div>
|
||||
<div><strong>${v.max_daily_km || 150}</strong><span>${t("bpfMaxKm")}</span></div>
|
||||
</div>
|
||||
<div class="spec-row" style="margin:1rem 0;">
|
||||
<div><strong>${v.seats}</strong><span>${t("seats")}</span></div>
|
||||
<div><strong>€ ${v.weekend_price_eur || v.daily_price_eur}</strong><span>${t("bpfWeekendRate")}</span></div>
|
||||
<div><strong>${v.included_km_per_day || 150}</strong><span>${t("bpfInclKmPerDay")}</span></div>
|
||||
</div>
|
||||
<div class="spec-row" style="margin:1rem 0;grid-template-columns:1fr;">
|
||||
<div><strong>€ ${(v.kaution_eur || 5000).toLocaleString("de-DE")}</strong><span>${t("bpfDeposit")}</span></div>
|
||||
</div>
|
||||
@@ -398,29 +398,45 @@ async function updateSidebar() {
|
||||
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);
|
||||
const includedKmPerDay = price.included_km_per_day || 150;
|
||||
const includedKm = totalDays * includedKmPerDay;
|
||||
const photoUrl = optimizedVehiclePhotoUrl(v.photo_url);
|
||||
|
||||
bpfSidebarPlaceholder.style.display = "none";
|
||||
bpfSidebarContent.style.display = "block";
|
||||
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} × € ${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>
|
||||
<div class="bpf-price-row muted" style="margin-top:0.8rem;"><span>${t("bpfDeposit")}</span><span>€ ${deposit.toLocaleString("de-DE")}</span></div>
|
||||
<div class="bpf-price-row muted"><span>${t("bpfIncludedKm")}</span><span>${includedKm} km</span></div>
|
||||
<div class="bpf-price-row muted"><span>${t("bpfExtraKm")}</span><span>€ 1,50${t("bpfPerKm")}</span></div>
|
||||
<div class="bpf-car-preview" style="background-image:url('${escapeAttr(photoUrl)}');"></div>
|
||||
<p class="bpf-car-name">${escapeHtml(v.brand)} ${escapeHtml(v.model)}</p>
|
||||
<p class="bpf-car-specs">${v.power_hp} ${t("hp")} • ${v.top_speed_kmh} ${t("kmh")} • ${escapeHtml(v.acceleration)}</p>
|
||||
`;
|
||||
}
|
||||
if (totalDays > 2) {
|
||||
// Individuell mode: show info banner instead of pricing
|
||||
bpfSidebarPlaceholder.style.display = "none";
|
||||
bpfSidebarContent.style.display = "block";
|
||||
bpfSidebarContent.innerHTML = `
|
||||
<h4>${t("bpfPriceOverview")}</h4>
|
||||
<div class="bpf-info-banner">
|
||||
<p><strong>${t("bpfIndividuellTitle")}</strong></p>
|
||||
<p>${t("bpfIndividuellDesc")}</p>
|
||||
</div>
|
||||
<div class="bpf-car-preview" style="background-image:url('${escapeAttr(photoUrl)}');"></div>
|
||||
<p class="bpf-car-name">${escapeHtml(v.brand)} ${escapeHtml(v.model)}</p>
|
||||
<p class="bpf-car-specs">${v.power_hp} ${t("hp")} • ${v.top_speed_kmh} ${t("kmh")} • ${escapeHtml(v.acceleration)}</p>
|
||||
`;
|
||||
} else {
|
||||
bpfSidebarPlaceholder.style.display = "none";
|
||||
bpfSidebarContent.style.display = "block";
|
||||
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} × € ${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>
|
||||
<div class="bpf-price-row muted" style="margin-top:0.8rem;"><span>${t("bpfDeposit")}</span><span>€ ${deposit.toLocaleString("de-DE")}</span></div>
|
||||
<div class="bpf-price-row muted"><span>${t("bpfIncludedKm")}</span><span>${includedKm} km</span></div>
|
||||
<div class="bpf-price-row muted"><span>${t("bpfExtraKm")}</span><span>€ ${(price.price_per_km_eur || 1.50).toFixed(2).replace('.', ',')}${t("bpfPerKm")}</span></div>
|
||||
<div class="bpf-car-preview" style="background-image:url('${escapeAttr(photoUrl)}');"></div>
|
||||
<p class="bpf-car-name">${escapeHtml(v.brand)} ${escapeHtml(v.model)}</p>
|
||||
<p class="bpf-car-specs">${v.power_hp} ${t("hp")} • ${v.top_speed_kmh} ${t("kmh")} • ${escapeHtml(v.acceleration)}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bpfCar.addEventListener("change", updateSidebar);
|
||||
bpfFrom.addEventListener("change", updateSidebar);
|
||||
|
||||
Reference in New Issue
Block a user