Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e82c232b44 | |||
| 6893676a93 | |||
| 625fadd4eb | |||
| a1941e8acf |
@@ -291,35 +291,6 @@ const [showRefundDialog, setShowRefundDialog] = useState(false);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function issueRefund() {
|
|
||||||
const amountCents = refundType === "partial"
|
|
||||||
? Math.round(parseFloat(refundAmount) * 100)
|
|
||||||
: undefined;
|
|
||||||
if (refundType === "partial" && (!amountCents || amountCents <= 0)) {
|
|
||||||
setError("Enter a valid refund amount");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSaving(true);
|
|
||||||
setError(null);
|
|
||||||
try {
|
|
||||||
const res = await fetch(`/api/invoices/${invoice.id}/refund`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify(amountCents ? { amountCents } : {}),
|
|
||||||
});
|
|
||||||
if (!res.ok) {
|
|
||||||
const err = (await res.json()) as { error?: string };
|
|
||||||
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
||||||
}
|
|
||||||
setShowRefundDialog(false);
|
|
||||||
onUpdated();
|
|
||||||
} catch (e: unknown) {
|
|
||||||
setError(e instanceof Error ? e.message : "Failed to issue refund");
|
|
||||||
} finally {
|
|
||||||
setSaving(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loading) return <Modal onClose={onClose}><p style={{ padding: "1rem" }}>Loading…</p></Modal>;
|
if (loading) return <Modal onClose={onClose}><p style={{ padding: "1rem" }}>Loading…</p></Modal>;
|
||||||
|
|
||||||
const tipCentsCalc = Math.round(parseFloat(tipStr) * 100) || 0;
|
const tipCentsCalc = Math.round(parseFloat(tipStr) * 100) || 0;
|
||||||
|
|||||||
+1
-1
Submodule infra updated: d9486dbfb1...b667a3f005
+1
-10
@@ -883,7 +883,6 @@ async function seed() {
|
|||||||
let appointmentCount = 0;
|
let appointmentCount = 0;
|
||||||
let invoiceCount = 0;
|
let invoiceCount = 0;
|
||||||
let visitLogCount = 0;
|
let visitLogCount = 0;
|
||||||
let paidInvoiceCounter = 0;
|
|
||||||
|
|
||||||
// Process in batches per client to keep memory manageable
|
// Process in batches per client to keep memory manageable
|
||||||
const apptBatchSize = 100;
|
const apptBatchSize = 100;
|
||||||
@@ -978,10 +977,6 @@ async function seed() {
|
|||||||
|
|
||||||
const invoiceStatus = rand() < 0.95 ? "paid" as const : "pending" as const;
|
const invoiceStatus = rand() < 0.95 ? "paid" as const : "pending" as const;
|
||||||
const paidAt = invoiceStatus === "paid" ? new Date(endTime.getTime() + randInt(5, 30) * 60 * 1000) : null;
|
const paidAt = invoiceStatus === "paid" ? new Date(endTime.getTime() + randInt(5, 30) * 60 * 1000) : null;
|
||||||
paidInvoiceCounter++;
|
|
||||||
const stripePaymentIntentId = invoiceStatus === "paid"
|
|
||||||
? `pi_test_seed_${String(paidInvoiceCounter).padStart(6, "0")}`
|
|
||||||
: null;
|
|
||||||
|
|
||||||
invoiceBatch.push({
|
invoiceBatch.push({
|
||||||
id: invoiceId,
|
id: invoiceId,
|
||||||
@@ -994,7 +989,6 @@ async function seed() {
|
|||||||
status: invoiceStatus,
|
status: invoiceStatus,
|
||||||
paymentMethod: invoiceStatus === "paid" ? pick(["cash", "card", "card", "card", "check"]) as "cash" | "card" | "check" : null,
|
paymentMethod: invoiceStatus === "paid" ? pick(["cash", "card", "card", "card", "check"]) as "cash" | "card" | "check" : null,
|
||||||
paidAt,
|
paidAt,
|
||||||
stripePaymentIntentId,
|
|
||||||
notes: rand() < 0.05 ? "Added extra service at checkout" : null,
|
notes: rand() < 0.05 ? "Added extra service at checkout" : null,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1098,16 +1092,13 @@ async function seed() {
|
|||||||
const taxCents = Math.round(effectivePrice * 0.08);
|
const taxCents = Math.round(effectivePrice * 0.08);
|
||||||
const totalCents = effectivePrice + taxCents + tipCents;
|
const totalCents = effectivePrice + taxCents + tipCents;
|
||||||
const paidAt = new Date(endTime.getTime() + randInt(5, 30) * 60 * 1000);
|
const paidAt = new Date(endTime.getTime() + randInt(5, 30) * 60 * 1000);
|
||||||
paidInvoiceCounter++;
|
|
||||||
|
|
||||||
invoiceBatch.push({
|
invoiceBatch.push({
|
||||||
id: invoiceId, appointmentId: apptId, clientId,
|
id: invoiceId, appointmentId: apptId, clientId,
|
||||||
subtotalCents: effectivePrice, taxCents, tipCents, totalCents,
|
subtotalCents: effectivePrice, taxCents, tipCents, totalCents,
|
||||||
status: "paid" as const,
|
status: "paid" as const,
|
||||||
paymentMethod: pick(["cash", "card", "card", "card", "check"]) as "cash" | "card" | "check",
|
paymentMethod: pick(["cash", "card", "card", "card", "check"]) as "cash" | "card" | "check",
|
||||||
paidAt,
|
paidAt, notes: null,
|
||||||
stripePaymentIntentId: `pi_test_seed_${String(paidInvoiceCounter).padStart(6, "0")}`,
|
|
||||||
notes: null,
|
|
||||||
});
|
});
|
||||||
lineItemBatch.push({
|
lineItemBatch.push({
|
||||||
id: uuid(), invoiceId, description: svc.name, quantity: 1,
|
id: uuid(), invoiceId, description: svc.name, quantity: 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user