mirror of
https://github.com/myronblair/parkerslingshot
synced 2026-06-30 17:50:22 -05:00
Swap steps 5/6 (license before deposit), charge balance guard, refund cancels booking
This commit is contained in:
+111
-86
@@ -198,7 +198,7 @@ if ($isAjax) {
|
|||||||
if (!$pid) { echo json_encode(['error'=>'No payment on file']); exit; }
|
if (!$pid) { echo json_encode(['error'=>'No payment on file']); exit; }
|
||||||
$resp = squareApi('POST', "/payments/{$pid}/cancel");
|
$resp = squareApi('POST', "/payments/{$pid}/cancel");
|
||||||
if (($resp['payment']['status'] ?? '') === 'CANCELED') {
|
if (($resp['payment']['status'] ?? '') === 'CANCELED') {
|
||||||
db()->prepare("UPDATE bookings SET square_payment_status='CANCELED' WHERE id=?")->execute([$id]);
|
db()->prepare("UPDATE bookings SET square_payment_status='CANCELED', status='cancelled' WHERE id=?")->execute([$id]);
|
||||||
echo json_encode(['ok'=>true,'status'=>'CANCELED']);
|
echo json_encode(['ok'=>true,'status'=>'CANCELED']);
|
||||||
} else {
|
} else {
|
||||||
echo json_encode(['error' => $resp['errors'][0]['detail'] ?? 'Void failed']);
|
echo json_encode(['error' => $resp['errors'][0]['detail'] ?? 'Void failed']);
|
||||||
@@ -221,7 +221,7 @@ if ($isAjax) {
|
|||||||
'reason' => 'Security deposit refund — booking returned in good condition',
|
'reason' => 'Security deposit refund — booking returned in good condition',
|
||||||
]);
|
]);
|
||||||
if (!empty($resp['refund']['id'])) {
|
if (!empty($resp['refund']['id'])) {
|
||||||
db()->prepare("UPDATE bookings SET square_payment_status='REFUNDED', square_refund_id=?, deposit_paid=0 WHERE id=?")
|
db()->prepare("UPDATE bookings SET square_payment_status='REFUNDED', square_refund_id=?, deposit_paid=0, status='cancelled' WHERE id=?")
|
||||||
->execute([$resp['refund']['id'], $id]);
|
->execute([$resp['refund']['id'], $id]);
|
||||||
echo json_encode(['ok'=>true,'status'=>'REFUNDED']);
|
echo json_encode(['ok'=>true,'status'=>'REFUNDED']);
|
||||||
} else {
|
} else {
|
||||||
@@ -686,12 +686,12 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="dots" title="Confirmed / Waiver / Insurance / Deposit / License / Helmet / Safety / Ops / Returned">
|
<div class="dots" title="Confirmed / Waiver / Insurance / License / Deposit / Helmet / Safety / Ops / Returned">
|
||||||
<div class="dot <?= $dotClass($stepConfirmed) ?>" title="Confirmed"></div>
|
<div class="dot <?= $dotClass($stepConfirmed) ?>" title="Confirmed"></div>
|
||||||
<div class="dot <?= $dotClass($stepWaiver) ?>" title="Waiver Signed"></div>
|
<div class="dot <?= $dotClass($stepWaiver) ?>" title="Waiver Signed"></div>
|
||||||
<div class="dot <?= $dotClass($stepInsurance) ?>" title="Insurance" id="dot-<?= $bid ?>-insurance_verified"></div>
|
<div class="dot <?= $dotClass($stepInsurance) ?>" title="Insurance" id="dot-<?= $bid ?>-insurance_verified"></div>
|
||||||
<div class="dot <?= $dotClass($stepDeposit) ?>" title="Deposit" id="dot-<?= $bid ?>-deposit_received"></div>
|
|
||||||
<div class="dot <?= $dotClass($stepLicense) ?>" title="License" id="dot-<?= $bid ?>-license_verified"></div>
|
<div class="dot <?= $dotClass($stepLicense) ?>" title="License" id="dot-<?= $bid ?>-license_verified"></div>
|
||||||
|
<div class="dot <?= $dotClass($stepDeposit) ?>" title="Deposit" id="dot-<?= $bid ?>-deposit_received"></div>
|
||||||
<div class="dot <?= $dotClass($stepHelmet) ?>" title="Helmet" id="dot-<?= $bid ?>-helmet_provided"></div>
|
<div class="dot <?= $dotClass($stepHelmet) ?>" title="Helmet" id="dot-<?= $bid ?>-helmet_provided"></div>
|
||||||
<div class="dot <?= $dotClass($stepSafety) ?>" title="Safety Course" id="dot-<?= $bid ?>-safety_course"></div>
|
<div class="dot <?= $dotClass($stepSafety) ?>" title="Safety Course" id="dot-<?= $bid ?>-safety_course"></div>
|
||||||
<div class="dot <?= $dotClass($stepOps) ?>" title="Ops Course" id="dot-<?= $bid ?>-operational_course"></div>
|
<div class="dot <?= $dotClass($stepOps) ?>" title="Ops Course" id="dot-<?= $bid ?>-operational_course"></div>
|
||||||
@@ -812,7 +812,29 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Step 5: Deposit (Square-aware) -->
|
<!-- Step 5: License -->
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="flow-icon <?= $stepLicense?'done':($cancelled?'skip':'pending') ?>" id="icon-<?= $bid ?>-license_verified">
|
||||||
|
<?= $stepLicense?'✓':($cancelled?'—':'5') ?>
|
||||||
|
</div>
|
||||||
|
<div class="flow-body">
|
||||||
|
<span class="flow-label">Driver's License Verified</span>
|
||||||
|
<span class="flow-meta" id="meta-<?= $bid ?>-license_verified">
|
||||||
|
<?= $stepLicense?'License verified':($cancelled?'N/A':'Verify at pickup') ?>
|
||||||
|
</span>
|
||||||
|
<?php if (!$cancelled): ?>
|
||||||
|
<div class="flow-action">
|
||||||
|
<button class="flow-toggle <?= $stepLicense?'active':'' ?>"
|
||||||
|
id="btn-<?= $bid ?>-license_verified"
|
||||||
|
onclick="toggleReq(<?= $bid ?>,'license_verified',this)">
|
||||||
|
<?= $stepLicense?'✓ License Verified':'Mark License Verified' ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Step 6: Deposit (Square-aware) -->
|
||||||
<?php
|
<?php
|
||||||
$sqStatus = $b['square_payment_status'] ?? '';
|
$sqStatus = $b['square_payment_status'] ?? '';
|
||||||
$sqId = $b['square_payment_id'] ?? '';
|
$sqId = $b['square_payment_id'] ?? '';
|
||||||
@@ -820,10 +842,11 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
$cardLast4 = $b['card_last4'] ?? '';
|
$cardLast4 = $b['card_last4'] ?? '';
|
||||||
$cardBrand = $b['card_brand'] ?? '';
|
$cardBrand = $b['card_brand'] ?? '';
|
||||||
$depositIcon = 'pending';
|
$depositIcon = 'pending';
|
||||||
$depositLabel = '5';
|
$depositLabel = '6';
|
||||||
if ($cancelled) { $depositIcon='skip'; $depositLabel='—'; }
|
if ($cancelled) { $depositIcon='skip'; $depositLabel='—'; }
|
||||||
elseif ($stepDeposit ||
|
elseif ($stepDeposit ||
|
||||||
in_array($sqStatus,['COMPLETED','BAL_COMPLETED'])) { $depositIcon='done'; $depositLabel='✓'; }
|
in_array($sqStatus,['COMPLETED','BAL_COMPLETED'])) { $depositIcon='done'; $depositLabel='✓'; }
|
||||||
|
$priorStepsDone = $stepConfirmed && $stepWaiver && $stepInsurance && $stepLicense;
|
||||||
?>
|
?>
|
||||||
<div class="flow-step">
|
<div class="flow-step">
|
||||||
<div class="flow-icon <?= $depositIcon ?>" id="icon-<?= $bid ?>-deposit_received">
|
<div class="flow-icon <?= $depositIcon ?>" id="icon-<?= $bid ?>-deposit_received">
|
||||||
@@ -853,14 +876,18 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
<div class="flow-action" id="deposit-actions-<?= $bid ?>">
|
<div class="flow-action" id="deposit-actions-<?= $bid ?>">
|
||||||
<?php if ($sqStatus === 'APPROVED' || $sqStatus === 'PENDING'): ?>
|
<?php if ($sqStatus === 'APPROVED' || $sqStatus === 'PENDING'): ?>
|
||||||
<button class="flow-toggle" onclick="squareAction(<?= $bid ?>,'square_capture',this)" style="margin-right:4px">Capture $<?= number_format(DEPOSIT_AMOUNT,0) ?></button>
|
<button class="flow-toggle" onclick="squareAction(<?= $bid ?>,'square_capture',this)" style="margin-right:4px">Capture $<?= number_format(DEPOSIT_AMOUNT,0) ?></button>
|
||||||
<button class="flow-toggle" onclick="squareAction(<?= $bid ?>,'square_void',this)" style="border-color:#dc2626;color:#dc2626">Void Hold</button>
|
<button class="flow-toggle" onclick="squareAction(<?= $bid ?>,'square_void',this)" style="border-color:#dc2626;color:#dc2626">Void & Cancel Booking</button>
|
||||||
<?php if ($sqCardId): ?>
|
<?php if ($sqCardId && $priorStepsDone): ?>
|
||||||
<button class="flow-toggle" onclick="chargeBalance(<?= $bid ?>,this)" style="margin-left:4px;border-color:#16a34a;color:#16a34a">Charge Balance $<?= number_format($b['amount']-DEPOSIT_AMOUNT,2) ?></button>
|
<button class="flow-toggle" onclick="chargeBalance(<?= $bid ?>,this)" style="margin-left:4px;border-color:#16a34a;color:#16a34a">Charge Balance $<?= number_format($b['amount']-DEPOSIT_AMOUNT,2) ?></button>
|
||||||
|
<?php elseif ($sqCardId): ?>
|
||||||
|
<button class="flow-toggle" disabled style="margin-left:4px;border-color:#9ca3af;color:#9ca3af;opacity:.55;cursor:not-allowed" title="Complete steps 1–5 before charging balance">Charge Balance $<?= number_format($b['amount']-DEPOSIT_AMOUNT,2) ?></button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php elseif ($sqStatus === 'COMPLETED'): ?>
|
<?php elseif ($sqStatus === 'COMPLETED'): ?>
|
||||||
<button class="flow-toggle" onclick="squareAction(<?= $bid ?>,'square_refund',this)" style="border-color:#2563eb;color:#2563eb">Refund $<?= number_format((float)($b['deposit_paid']??DEPOSIT_AMOUNT),2) ?></button>
|
<button class="flow-toggle" onclick="squareAction(<?= $bid ?>,'square_refund',this)" style="border-color:#2563eb;color:#2563eb">Refund & Cancel Booking</button>
|
||||||
<?php if ($sqCardId): ?>
|
<?php if ($sqCardId && $priorStepsDone): ?>
|
||||||
<button class="flow-toggle" onclick="chargeBalance(<?= $bid ?>,this)" style="margin-left:4px;border-color:#16a34a;color:#16a34a">Charge Balance $<?= number_format($b['amount']-DEPOSIT_AMOUNT,2) ?></button>
|
<button class="flow-toggle" onclick="chargeBalance(<?= $bid ?>,this)" style="margin-left:4px;border-color:#16a34a;color:#16a34a">Charge Balance $<?= number_format($b['amount']-DEPOSIT_AMOUNT,2) ?></button>
|
||||||
|
<?php elseif ($sqCardId): ?>
|
||||||
|
<button class="flow-toggle" disabled style="margin-left:4px;border-color:#9ca3af;color:#9ca3af;opacity:.55;cursor:not-allowed" title="Complete steps 1–5 before charging balance">Charge Balance $<?= number_format($b['amount']-DEPOSIT_AMOUNT,2) ?></button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php elseif (!$sqId || $sqStatus === 'DECLINED'): ?>
|
<?php elseif (!$sqId || $sqStatus === 'DECLINED'): ?>
|
||||||
<button class="flow-toggle <?= $stepDeposit?'active':'' ?>"
|
<button class="flow-toggle <?= $stepDeposit?'active':'' ?>"
|
||||||
@@ -874,28 +901,6 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Step 6: License -->
|
|
||||||
<div class="flow-step">
|
|
||||||
<div class="flow-icon <?= $stepLicense?'done':($cancelled?'skip':'pending') ?>" id="icon-<?= $bid ?>-license_verified">
|
|
||||||
<?= $stepLicense?'✓':($cancelled?'—':'6') ?>
|
|
||||||
</div>
|
|
||||||
<div class="flow-body">
|
|
||||||
<span class="flow-label">Driver's License Verified</span>
|
|
||||||
<span class="flow-meta" id="meta-<?= $bid ?>-license_verified">
|
|
||||||
<?= $stepLicense?'License verified':($cancelled?'N/A':'Verify at pickup') ?>
|
|
||||||
</span>
|
|
||||||
<?php if (!$cancelled): ?>
|
|
||||||
<div class="flow-action">
|
|
||||||
<button class="flow-toggle <?= $stepLicense?'active':'' ?>"
|
|
||||||
id="btn-<?= $bid ?>-license_verified"
|
|
||||||
onclick="toggleReq(<?= $bid ?>,'license_verified',this)">
|
|
||||||
<?= $stepLicense?'✓ License Verified':'Mark License Verified' ?>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (!$cancelled): ?>
|
<?php if (!$cancelled): ?>
|
||||||
<!-- ── Pre-departure checklist (admin only, after deposit confirmed) ── -->
|
<!-- ── Pre-departure checklist (admin only, after deposit confirmed) ── -->
|
||||||
<div style="margin:.6rem 0 .2rem;padding:.4rem .5rem;background:#fff7ed;border-radius:6px;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#92400e">
|
<div style="margin:.6rem 0 .2rem;padding:.4rem .5rem;background:#fff7ed;border-radius:6px;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#92400e">
|
||||||
@@ -1010,14 +1015,14 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
<input type="checkbox" value="insurance" <?= !$stepInsurance?'checked':'' ?>>
|
<input type="checkbox" value="insurance" <?= !$stepInsurance?'checked':'' ?>>
|
||||||
Bring proof of insurance
|
Bring proof of insurance
|
||||||
</label>
|
</label>
|
||||||
<label>
|
|
||||||
<input type="checkbox" value="deposit" <?= !$stepDeposit?'checked':'' ?>>
|
|
||||||
Security deposit info
|
|
||||||
</label>
|
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" value="license" <?= !$stepLicense?'checked':'' ?>>
|
<input type="checkbox" value="license" <?= !$stepLicense?'checked':'' ?>>
|
||||||
Bring driver's license
|
Bring driver's license
|
||||||
</label>
|
</label>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" value="deposit" <?= !$stepDeposit?'checked':'' ?>>
|
||||||
|
Security deposit info
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="send-btn" id="remind-btn-<?= $bid ?>" onclick="sendReminder(<?= $bid ?>)">
|
<button class="send-btn" id="remind-btn-<?= $bid ?>" onclick="sendReminder(<?= $bid ?>)">
|
||||||
Send Reminder Email
|
Send Reminder Email
|
||||||
@@ -1292,9 +1297,29 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="flow-icon <?= $stepLicense?'done':($cancelled?'skip':'pending') ?>" id="cv-icon-<?= $bid ?>-license_verified">
|
||||||
|
<?= $stepLicense?'✓':($cancelled?'—':'5') ?>
|
||||||
|
</div>
|
||||||
|
<div class="flow-body">
|
||||||
|
<span class="flow-label">Driver's License Verified</span>
|
||||||
|
<span class="flow-meta" id="cv-meta-<?= $bid ?>-license_verified">
|
||||||
|
<?= $stepLicense?'Verified — on file':($cancelled?'N/A':'Verify at pickup') ?>
|
||||||
|
</span>
|
||||||
|
<?php if (!$cancelled): ?>
|
||||||
|
<div class="flow-action">
|
||||||
|
<button class="flow-toggle <?= $stepLicense?'active':'' ?>" id="cv-btn-<?= $bid ?>-license_verified"
|
||||||
|
onclick="cvToggleReq(<?= $bid ?>,'license_verified',this)">
|
||||||
|
<?= $stepLicense?'✓ License Verified':'Mark License Verified' ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$cvDepIcon = $cancelled ? 'skip' : (($stepDeposit||$sqStatus==='COMPLETED') ? 'done' : 'pending');
|
$cvDepIcon = $cancelled ? 'skip' : (($stepDeposit||$sqStatus==='COMPLETED') ? 'done' : 'pending');
|
||||||
$cvDepLabel = $cancelled ? '—' : (($stepDeposit||$sqStatus==='COMPLETED') ? '✓' : '5');
|
$cvDepLabel = $cancelled ? '—' : (($stepDeposit||$sqStatus==='COMPLETED') ? '✓' : '6');
|
||||||
?>
|
?>
|
||||||
<div class="flow-step">
|
<div class="flow-step">
|
||||||
<div class="flow-icon <?= $cvDepIcon ?>" id="cv-icon-<?= $bid ?>-deposit_received">
|
<div class="flow-icon <?= $cvDepIcon ?>" id="cv-icon-<?= $bid ?>-deposit_received">
|
||||||
@@ -1316,9 +1341,9 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
<div class="flow-action" id="cv-dep-actions-<?= $bid ?>">
|
<div class="flow-action" id="cv-dep-actions-<?= $bid ?>">
|
||||||
<?php if ($sqStatus==='APPROVED'||$sqStatus==='PENDING'): ?>
|
<?php if ($sqStatus==='APPROVED'||$sqStatus==='PENDING'): ?>
|
||||||
<button class="flow-toggle" onclick="cvSquareAction(<?= $bid ?>,'square_capture',this)" style="margin-right:4px">Capture $<?= number_format(DEPOSIT_AMOUNT,0) ?></button>
|
<button class="flow-toggle" onclick="cvSquareAction(<?= $bid ?>,'square_capture',this)" style="margin-right:4px">Capture $<?= number_format(DEPOSIT_AMOUNT,0) ?></button>
|
||||||
<button class="flow-toggle" onclick="cvSquareAction(<?= $bid ?>,'square_void',this)" style="border-color:#dc2626;color:#dc2626">Void Hold</button>
|
<button class="flow-toggle" onclick="cvSquareAction(<?= $bid ?>,'square_void',this)" style="border-color:#dc2626;color:#dc2626">Void & Cancel Booking</button>
|
||||||
<?php elseif ($sqStatus==='COMPLETED'): ?>
|
<?php elseif ($sqStatus==='COMPLETED'): ?>
|
||||||
<button class="flow-toggle" onclick="cvSquareAction(<?= $bid ?>,'square_refund',this)" style="border-color:#2563eb;color:#2563eb">Refund $<?= number_format((float)($cb['deposit_paid']??DEPOSIT_AMOUNT),2) ?></button>
|
<button class="flow-toggle" onclick="cvSquareAction(<?= $bid ?>,'square_refund',this)" style="border-color:#2563eb;color:#2563eb">Refund & Cancel Booking</button>
|
||||||
<?php elseif (!$sqId): ?>
|
<?php elseif (!$sqId): ?>
|
||||||
<button class="flow-toggle <?= $stepDeposit?'active':'' ?>" id="cv-btn-<?= $bid ?>-deposit_received"
|
<button class="flow-toggle <?= $stepDeposit?'active':'' ?>" id="cv-btn-<?= $bid ?>-deposit_received"
|
||||||
onclick="cvToggleReq(<?= $bid ?>,'deposit_received',this)">
|
onclick="cvToggleReq(<?= $bid ?>,'deposit_received',this)">
|
||||||
@@ -1330,26 +1355,6 @@ textarea.notes-ta:focus{border-color:#f97316}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flow-step">
|
|
||||||
<div class="flow-icon <?= $stepLicense?'done':($cancelled?'skip':'pending') ?>" id="cv-icon-<?= $bid ?>-license_verified">
|
|
||||||
<?= $stepLicense?'✓':($cancelled?'—':'6') ?>
|
|
||||||
</div>
|
|
||||||
<div class="flow-body">
|
|
||||||
<span class="flow-label">Driver's License Verified</span>
|
|
||||||
<span class="flow-meta" id="cv-meta-<?= $bid ?>-license_verified">
|
|
||||||
<?= $stepLicense?'Verified — on file':($cancelled?'N/A':'Verify at pickup') ?>
|
|
||||||
</span>
|
|
||||||
<?php if (!$cancelled): ?>
|
|
||||||
<div class="flow-action">
|
|
||||||
<button class="flow-toggle <?= $stepLicense?'active':'' ?>" id="cv-btn-<?= $bid ?>-license_verified"
|
|
||||||
onclick="cvToggleReq(<?= $bid ?>,'license_verified',this)">
|
|
||||||
<?= $stepLicense?'✓ License Verified':'Mark License Verified' ?>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (!$cancelled): ?>
|
<?php if (!$cancelled): ?>
|
||||||
<div style="margin:.4rem 0 .1rem;padding:.3rem .5rem;background:#fff7ed;border-radius:5px;font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#92400e">Pre-Departure</div>
|
<div style="margin:.4rem 0 .1rem;padding:.3rem .5rem;background:#fff7ed;border-radius:5px;font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#92400e">Pre-Departure</div>
|
||||||
|
|
||||||
@@ -1532,7 +1537,7 @@ function toggleReq(id, field, btn) {
|
|||||||
const icon = document.getElementById('icon-'+id+'-'+field);
|
const icon = document.getElementById('icon-'+id+'-'+field);
|
||||||
if (icon) {
|
if (icon) {
|
||||||
icon.className = 'flow-icon ' + (on ? 'done' : 'pending');
|
icon.className = 'flow-icon ' + (on ? 'done' : 'pending');
|
||||||
const stepNums = {insurance_verified:'4', deposit_received:'5', license_verified:'6', helmet_provided:'7', safety_course:'8', operational_course:'9'};
|
const stepNums = {insurance_verified:'4', license_verified:'5', deposit_received:'6', helmet_provided:'7', safety_course:'8', operational_course:'9'};
|
||||||
icon.textContent = on ? '✓' : (stepNums[field] || '?');
|
icon.textContent = on ? '✓' : (stepNums[field] || '?');
|
||||||
}
|
}
|
||||||
// Update meta text
|
// Update meta text
|
||||||
@@ -1624,8 +1629,8 @@ function squareAction(id, action, btn) {
|
|||||||
const [orig, working, done] = labels[action];
|
const [orig, working, done] = labels[action];
|
||||||
const confirmMsg = {
|
const confirmMsg = {
|
||||||
square_capture: 'Charge the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold to this card?',
|
square_capture: 'Charge the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold to this card?',
|
||||||
square_void: 'Void the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold? The customer will NOT be charged.',
|
square_void: 'Void the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold and CANCEL this booking? The customer will NOT be charged.',
|
||||||
square_refund: 'Refund the deposit to this card?',
|
square_refund: 'Refund the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit and CANCEL this booking? This cannot be undone.',
|
||||||
}[action];
|
}[action];
|
||||||
if (!confirm(confirmMsg)) return;
|
if (!confirm(confirmMsg)) return;
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
@@ -1650,19 +1655,31 @@ function squareAction(id, action, btn) {
|
|||||||
if (dot) dot.className='dot dot-done';
|
if (dot) dot.className='dot dot-done';
|
||||||
// Replace action area with refund button
|
// Replace action area with refund button
|
||||||
const area = document.getElementById('deposit-actions-'+id);
|
const area = document.getElementById('deposit-actions-'+id);
|
||||||
if (area) area.innerHTML = '<button class="flow-toggle" onclick="squareAction('+id+',\'square_refund\',this)" style="border-color:#2563eb;color:#2563eb">Refund Deposit</button>';
|
if (area) area.innerHTML = '<button class="flow-toggle" onclick="squareAction('+id+',\'square_refund\',this)" style="border-color:#2563eb;color:#2563eb">Refund & Cancel Booking</button>';
|
||||||
} else if (d.status === 'CANCELED') {
|
} else if (d.status === 'CANCELED' || d.status === 'REFUNDED') {
|
||||||
if (meta) meta.textContent = 'Hold voided — no charge';
|
const t = d.status === 'CANCELED' ? 'Hold voided — booking cancelled' : 'Refunded — booking cancelled';
|
||||||
|
if (meta) meta.textContent = t;
|
||||||
if (icon) { icon.className='flow-icon skip'; icon.textContent='—'; }
|
if (icon) { icon.className='flow-icon skip'; icon.textContent='—'; }
|
||||||
if (dot) dot.className='dot dot-skip';
|
if (dot) dot.className='dot dot-skip';
|
||||||
const area = document.getElementById('deposit-actions-'+id);
|
const area = document.getElementById('deposit-actions-'+id);
|
||||||
if (area) area.innerHTML = '';
|
if (area) area.innerHTML = '';
|
||||||
} else if (d.status === 'REFUNDED') {
|
// Update booking status selects and row data-status
|
||||||
if (meta) meta.textContent = 'Refunded — deposit returned';
|
document.querySelectorAll('select.status-sel[data-id="'+id+'"]').forEach(sel => {
|
||||||
if (icon) { icon.className='flow-icon pending'; icon.textContent='↩'; }
|
sel.value = 'cancelled';
|
||||||
if (dot) dot.className='dot dot-skip';
|
});
|
||||||
const area = document.getElementById('deposit-actions-'+id);
|
document.querySelectorAll('tr.booking-row, tr.detail-row').forEach(row => {
|
||||||
if (area) area.innerHTML = '';
|
const s = row.querySelector('select[data-id="'+id+'"]');
|
||||||
|
if (s) row.dataset.status = 'cancelled';
|
||||||
|
});
|
||||||
|
// Update confirmed step icon
|
||||||
|
['icon','cv-icon'].forEach(p => {
|
||||||
|
const el = document.getElementById(p+'-'+id+'-confirmed');
|
||||||
|
if (el) { el.className='flow-icon skip'; el.textContent='—'; }
|
||||||
|
});
|
||||||
|
['meta','cv-meta'].forEach(p => {
|
||||||
|
const el = document.getElementById(p+'-'+id+'-confirmed');
|
||||||
|
if (el) el.textContent = 'Cancelled';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
btn.textContent = orig;
|
btn.textContent = orig;
|
||||||
@@ -1830,8 +1847,8 @@ function cvSquareAction(bid, action, btn) {
|
|||||||
const [orig, working] = labels[action];
|
const [orig, working] = labels[action];
|
||||||
const confirmMsg = {
|
const confirmMsg = {
|
||||||
square_capture: 'Charge the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold to this card?',
|
square_capture: 'Charge the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold to this card?',
|
||||||
square_void: 'Void the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold? The customer will NOT be charged.',
|
square_void: 'Void the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit hold and CANCEL this booking? The customer will NOT be charged.',
|
||||||
square_refund: 'Refund the deposit to this card?',
|
square_refund: 'Refund the $<?= number_format(DEPOSIT_AMOUNT,2) ?> deposit and CANCEL this booking? This cannot be undone.',
|
||||||
}[action];
|
}[action];
|
||||||
if (!confirm(confirmMsg)) return;
|
if (!confirm(confirmMsg)) return;
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
@@ -1853,13 +1870,13 @@ function cvSquareAction(bid, action, btn) {
|
|||||||
const t = 'Captured — deposit charged';
|
const t = 'Captured — deposit charged';
|
||||||
if (cvMeta) cvMeta.textContent = t;
|
if (cvMeta) cvMeta.textContent = t;
|
||||||
if (cvIcon) { cvIcon.className='flow-icon done'; cvIcon.textContent='✓'; }
|
if (cvIcon) { cvIcon.className='flow-icon done'; cvIcon.textContent='✓'; }
|
||||||
if (cvArea) cvArea.innerHTML = '<button class="flow-toggle" onclick="cvSquareAction('+bid+',\'square_refund\',this)" style="border-color:#2563eb;color:#2563eb">Refund Deposit</button>';
|
if (cvArea) cvArea.innerHTML = '<button class="flow-toggle" onclick="cvSquareAction('+bid+',\'square_refund\',this)" style="border-color:#2563eb;color:#2563eb">Refund & Cancel Booking</button>';
|
||||||
if (meta) meta.textContent = t;
|
if (meta) meta.textContent = t;
|
||||||
if (icon) { icon.className='flow-icon done'; icon.textContent='✓'; }
|
if (icon) { icon.className='flow-icon done'; icon.textContent='✓'; }
|
||||||
if (dot) dot.className='dot dot-done';
|
if (dot) dot.className='dot dot-done';
|
||||||
if (area) area.innerHTML = '<button class="flow-toggle" onclick="squareAction('+bid+',\'square_refund\',this)" style="border-color:#2563eb;color:#2563eb">Refund Deposit</button>';
|
if (area) area.innerHTML = '<button class="flow-toggle" onclick="squareAction('+bid+',\'square_refund\',this)" style="border-color:#2563eb;color:#2563eb">Refund & Cancel Booking</button>';
|
||||||
} else if (d.status === 'CANCELED') {
|
} else if (d.status === 'CANCELED' || d.status === 'REFUNDED') {
|
||||||
const t = 'Hold voided — no charge';
|
const t = d.status === 'CANCELED' ? 'Hold voided — booking cancelled' : 'Refunded — booking cancelled';
|
||||||
if (cvMeta) cvMeta.textContent = t;
|
if (cvMeta) cvMeta.textContent = t;
|
||||||
if (cvIcon) { cvIcon.className='flow-icon skip'; cvIcon.textContent='—'; }
|
if (cvIcon) { cvIcon.className='flow-icon skip'; cvIcon.textContent='—'; }
|
||||||
if (cvArea) cvArea.innerHTML = '';
|
if (cvArea) cvArea.innerHTML = '';
|
||||||
@@ -1867,15 +1884,23 @@ function cvSquareAction(bid, action, btn) {
|
|||||||
if (icon) { icon.className='flow-icon skip'; icon.textContent='—'; }
|
if (icon) { icon.className='flow-icon skip'; icon.textContent='—'; }
|
||||||
if (dot) dot.className='dot dot-skip';
|
if (dot) dot.className='dot dot-skip';
|
||||||
if (area) area.innerHTML = '';
|
if (area) area.innerHTML = '';
|
||||||
} else if (d.status === 'REFUNDED') {
|
// Update booking status selects and row data-status
|
||||||
const t = 'Refunded — deposit returned';
|
document.querySelectorAll('select.status-sel[data-id="'+bid+'"]').forEach(sel => {
|
||||||
if (cvMeta) cvMeta.textContent = t;
|
sel.value = 'cancelled';
|
||||||
if (cvIcon) { cvIcon.className='flow-icon pending'; cvIcon.textContent='↩'; }
|
});
|
||||||
if (cvArea) cvArea.innerHTML = '';
|
document.querySelectorAll('tr.booking-row, tr.detail-row').forEach(row => {
|
||||||
if (meta) meta.textContent = t;
|
const s = row.querySelector('select[data-id="'+bid+'"]');
|
||||||
if (icon) { icon.className='flow-icon pending'; icon.textContent='↩'; }
|
if (s) row.dataset.status = 'cancelled';
|
||||||
if (dot) dot.className='dot dot-skip';
|
});
|
||||||
if (area) area.innerHTML = '';
|
// Update confirmed step icon
|
||||||
|
['icon','cv-icon'].forEach(p => {
|
||||||
|
const el = document.getElementById(p+'-'+bid+'-confirmed');
|
||||||
|
if (el) { el.className='flow-icon skip'; el.textContent='—'; }
|
||||||
|
});
|
||||||
|
['meta','cv-meta'].forEach(p => {
|
||||||
|
const el = document.getElementById(p+'-'+bid+'-confirmed');
|
||||||
|
if (el) el.textContent = 'Cancelled';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
btn.textContent = orig;
|
btn.textContent = orig;
|
||||||
|
|||||||
Reference in New Issue
Block a user