Files
Kent-logistics-Laravel/resources/views/admin/popup_invoice.blade.php

1370 lines
57 KiB
PHP
Raw Normal View History

2025-11-26 23:07:12 +05:30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Professional Invoice</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
2026-02-27 10:51:26 +05:30
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
2025-11-26 23:07:12 +05:30
<style>
:root {
2026-02-27 10:51:26 +05:30
--primary: #0f172a;
--secondary: #3b82f6;
--accent: #f59e0b;
--success: #10b981;
--danger: #ef4444;
--warning: #f59e0b;
--light: #f8fafc;
--surface: #ffffff;
--surface2: #f1f5f9;
--border: #e2e8f0;
--text-muted: #64748b;
--text-secondary: #475569;
--radius: 12px;
--radius-sm: 8px;
--shadow: 0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.1);
}
* { box-sizing: border-box; }
2025-11-26 23:07:12 +05:30
body {
2026-02-27 10:51:26 +05:30
font-family: 'Plus Jakarta Sans', sans-serif;
background: linear-gradient(135deg, #e0f2fe 0%, #f0fdf4 50%, #fef9c3 100%);
min-height: 100vh;
color: var(--primary);
padding: 2rem 1rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* ── CONTAINER ── */
2025-11-26 23:07:12 +05:30
.invoice-container {
2026-02-27 10:51:26 +05:30
max-width: 1400px;
margin: 0 auto;
background: var(--surface);
border-radius: 20px;
box-shadow: var(--shadow-lg);
2025-11-26 23:07:12 +05:30
overflow: hidden;
2026-02-27 10:51:26 +05:30
border: 1px solid var(--border);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* ── TOP ACCENT BAR ── */
.invoice-accent-bar {
height: 5px;
background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 40%, #10b981 70%, #f59e0b 100%);
}
/* ── HEADER ── */
2025-11-26 23:07:12 +05:30
.invoice-header {
2026-02-27 10:51:26 +05:30
padding: 2rem 2.5rem 1.5rem;
background: var(--surface);
border-bottom: 1px solid var(--border);
position: relative;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
2025-11-26 23:07:12 +05:30
.invoice-title {
2026-02-27 10:51:26 +05:30
font-size: 2rem;
font-weight: 800;
letter-spacing: -0.03em;
2025-11-26 23:07:12 +05:30
color: var(--primary);
2026-02-27 10:51:26 +05:30
line-height: 1;
margin-bottom: 0.25rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.invoice-number {
font-family: 'JetBrains Mono', monospace;
font-size: 0.9rem;
font-weight: 600;
color: var(--text-muted);
letter-spacing: 0.04em;
}
2025-11-26 23:07:12 +05:30
.status-badge {
2026-02-27 10:51:26 +05:30
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-size: 0.8rem;
font-weight: 700;
padding: 0.5rem 1.1rem;
2025-11-26 23:07:12 +05:30
border-radius: 50px;
2026-02-27 10:51:26 +05:30
text-transform: uppercase;
letter-spacing: 0.06em;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.status-paid { background: #dcfce7; color: #166534; }
.status-overdue { background: #fee2e2; color: #991b1b; }
.status-pending { background: #fef3c7; color: #92400e; }
.status-default { background: #f1f5f9; color: #475569; }
/* ── ID BOXES ── */
.id-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
padding: 1.5rem 2.5rem;
background: var(--surface2);
border-bottom: 1px solid var(--border);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
2025-11-26 23:07:12 +05:30
.id-box {
2026-02-27 10:51:26 +05:30
background: var(--surface);
border-radius: var(--radius);
padding: 1.1rem 1.25rem;
border: 1px solid var(--border);
box-shadow: 0 1px 4px rgba(0,0,0,0.05);
display: flex;
align-items: center;
gap: 1rem;
2026-02-27 10:51:26 +05:30
transition: box-shadow 0.2s;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.id-box:hover { box-shadow: var(--shadow); }
.id-icon-wrap {
width: 42px;
height: 42px;
border-radius: 10px;
2025-11-26 23:07:12 +05:30
display: flex;
align-items: center;
justify-content: center;
2026-02-27 10:51:26 +05:30
font-size: 1rem;
flex-shrink: 0;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.id-icon-blue { background: #eff6ff; color: #3b82f6; }
.id-icon-green { background: #f0fdf4; color: #10b981; }
.id-label {
font-size: 0.68rem;
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: 0.2rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.id-value {
font-family: 'JetBrains Mono', monospace;
font-size: 0.92rem;
font-weight: 600;
color: var(--primary);
}
/* ── DATES ── */
.date-strip {
padding: 1.5rem 2.5rem;
border-bottom: 1px solid var(--border);
}
.date-row {
display: flex;
align-items: center;
gap: 1rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.date-card {
flex: 1;
2026-02-27 10:51:26 +05:30
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 1rem 1.25rem;
display: flex;
align-items: center;
gap: 0.85rem;
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.date-icon-wrap {
width: 38px;
height: 38px;
border-radius: 9px;
background: #eff6ff;
color: #3b82f6;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
flex-shrink: 0;
}
.date-label {
font-size: 0.68rem;
font-weight: 700;
2025-11-26 23:07:12 +05:30
text-transform: uppercase;
2026-02-27 10:51:26 +05:30
letter-spacing: 0.07em;
color: var(--text-muted);
margin-bottom: 0.2rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.date-value {
font-weight: 700;
2025-11-26 23:07:12 +05:30
font-size: 0.95rem;
2026-02-27 10:51:26 +05:30
color: var(--primary);
}
.date-value.overdue { color: #ef4444; }
.date-arrow {
width: 36px;
height: 36px;
border-radius: 50%;
background: var(--surface2);
border: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
font-size: 0.8rem;
flex-shrink: 0;
}
/* ── SECTION PANEL ── */
.panel {
margin: 1.5rem 2.5rem;
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.panel-header {
background: var(--surface2);
padding: 0.85rem 1.25rem;
border-bottom: 1px solid var(--border);
2025-11-26 23:07:12 +05:30
font-weight: 700;
2026-02-27 10:51:26 +05:30
font-size: 0.88rem;
2025-11-26 23:07:12 +05:30
color: var(--primary);
2026-02-27 10:51:26 +05:30
display: flex;
align-items: center;
gap: 0.5rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.panel-header i {
color: var(--secondary);
font-size: 0.85rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.panel-body {
padding: 1.25rem;
background: var(--surface);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* ── CUSTOMER ── */
.customer-name {
font-size: 1.05rem;
font-weight: 700;
color: var(--secondary);
margin-bottom: 0.4rem;
}
.customer-detail {
font-size: 0.85rem;
color: var(--text-secondary);
margin-bottom: 0.3rem;
2025-11-26 23:07:12 +05:30
display: flex;
2026-02-27 10:51:26 +05:30
gap: 0.4rem;
}
.customer-detail strong { color: var(--primary); font-weight: 600; }
/* ── TABLE ── */
.invoice-table {
width: 100%;
min-width: 1100px;
border-collapse: collapse;
font-size: 0.83rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* Items table specifically even wider */
.items-table {
min-width: 1300px;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.invoice-table thead tr {
background: var(--surface2);
}
.invoice-table thead th {
padding: 0.85rem 1rem;
font-size: 0.71rem;
2025-11-26 23:07:12 +05:30
font-weight: 700;
2026-02-27 10:51:26 +05:30
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
border-bottom: 2px solid var(--border);
white-space: nowrap;
}
.invoice-table tbody tr {
border-bottom: 1px solid var(--border);
transition: background 0.15s;
}
.invoice-table tbody tr:hover { background: #f0f7ff; }
.invoice-table tbody tr:last-child { border-bottom: none; }
.invoice-table tbody td {
padding: 0.85rem 1rem;
color: var(--text-secondary);
white-space: nowrap;
}
/* Description column can wrap */
.invoice-table tbody td.desc-col {
white-space: normal;
min-width: 180px;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.invoice-table tbody tr.grouped-item-row {
background: #f8f9ff;
}
.badge-shop {
display: inline-block;
padding: 0.2rem 0.55rem;
border-radius: 5px;
background: var(--surface2);
border: 1px solid var(--border);
font-family: 'JetBrains Mono', monospace;
font-size: 0.72rem;
font-weight: 600;
color: var(--text-secondary);
}
.price-green { color: #10b981; font-weight: 700; }
.price-blue { color: #3b82f6; font-weight: 700; }
/* ── ACTION BAR ── */
.action-bar {
2025-11-26 23:07:12 +05:30
display: flex;
2026-02-27 10:51:26 +05:30
justify-content: space-between;
2025-11-26 23:07:12 +05:30
align-items: center;
padding: 0.75rem 1.25rem;
2026-02-27 10:51:26 +05:30
border-top: 1px solid var(--border);
background: var(--surface2);
}
.action-bar small { color: var(--text-muted); font-size: 0.8rem; }
.action-bar span { font-weight: 700; color: var(--secondary); }
/* ── BUTTONS ── */
.btn-create-group {
display: inline-flex;
align-items: center;
gap: 0.4rem;
background: var(--secondary);
color: white;
border: none;
border-radius: 8px;
padding: 0.45rem 1rem;
font-size: 0.8rem;
2025-11-26 23:07:12 +05:30
font-weight: 600;
2026-02-27 10:51:26 +05:30
cursor: pointer;
transition: background 0.2s, opacity 0.2s;
}
.btn-create-group:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-create-group:not(:disabled):hover { background: #2563eb; }
/* ── CHARGE GROUP FORM PANEL ── */
.cg-panel {
margin: 0 2.5rem 1.5rem;
border: 2px solid #3b82f6;
border-radius: var(--radius);
overflow: hidden;
box-shadow: 0 0 0 4px rgba(59,130,246,0.08);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.cg-panel-header {
background: linear-gradient(135deg, #1d4ed8, #3b82f6);
padding: 0.9rem 1.25rem;
color: white;
font-weight: 700;
2025-11-26 23:07:12 +05:30
font-size: 0.9rem;
2026-02-27 10:51:26 +05:30
display: flex;
align-items: center;
gap: 0.5rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.cg-body { padding: 1.25rem; background: var(--surface); }
.form-label-custom {
font-size: 0.72rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--text-muted);
margin-bottom: 0.35rem;
display: block;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.form-control-custom,
.form-select-custom {
width: 100%;
padding: 0.55rem 0.85rem;
border: 1.5px solid var(--border);
border-radius: 8px;
2025-11-26 23:07:12 +05:30
font-size: 0.85rem;
2026-02-27 10:51:26 +05:30
font-family: 'Plus Jakarta Sans', sans-serif;
color: var(--primary);
background: var(--surface);
transition: border-color 0.15s, box-shadow 0.15s;
outline: none;
}
.form-control-custom:focus,
.form-select-custom:focus {
border-color: var(--secondary);
box-shadow: 0 0 0 3px rgba(59,130,246,0.12);
}
.basis-box {
background: var(--surface2);
border: 1px solid var(--border);
border-radius: 9px;
padding: 1rem;
height: 100%;
}
.basis-box-label {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--text-muted);
margin-bottom: 0.5rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.basis-value-display {
font-family: 'JetBrains Mono', monospace;
font-size: 1.2rem;
font-weight: 700;
color: var(--secondary);
}
.basis-label-display {
font-size: 0.75rem;
color: var(--text-muted);
margin-left: 0.5rem;
}
.basis-hint { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.35rem; }
.suggested-total {
font-family: 'JetBrains Mono', monospace;
font-weight: 700;
color: #10b981;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* ── CHARGE GROUPS TABLE ── */
.cg-groups-panel {
margin: 0 2.5rem 1.5rem;
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.cg-groups-header {
background: var(--primary);
color: white;
padding: 0.85rem 1.25rem;
font-weight: 700;
font-size: 0.88rem;
display: flex;
align-items: center;
2026-02-27 10:51:26 +05:30
gap: 0.5rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* ── SUMMARY ── */
.summary-wrap {
padding: 0 2.5rem 2rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.summary-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
box-shadow: var(--shadow);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.summary-header-row {
background: var(--primary);
color: white;
padding: 0.85rem 1.25rem;
font-weight: 700;
font-size: 0.88rem;
display: flex;
align-items: center;
gap: 0.5rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.summary-body { padding: 1.25rem; }
.summary-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.6rem 0;
border-bottom: 1px solid var(--border);
font-size: 0.88rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.summary-row:last-child { border-bottom: none; padding-top: 0.85rem; }
.summary-row .label { color: var(--text-secondary); font-weight: 500; }
.summary-row .value { font-weight: 700; color: var(--primary); }
.summary-row.total .label { font-size: 1rem; font-weight: 700; color: var(--primary); }
.summary-row.total .value { font-size: 1.15rem; color: #10b981; }
.summary-row .value.red { color: #ef4444; }
/* ── FOOTER ── */
.invoice-footer {
padding: 1.5rem 2.5rem;
border-top: 1px solid var(--border);
text-align: center;
background: var(--surface2);
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.btn-download {
display: inline-flex;
align-items: center;
gap: 0.45rem;
background: var(--secondary);
color: white;
border: none;
border-radius: 9px;
padding: 0.65rem 1.4rem;
font-size: 0.88rem;
font-weight: 600;
text-decoration: none;
transition: background 0.2s;
margin-right: 0.5rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.btn-download:hover { background: #2563eb; color: white; }
.btn-share {
display: inline-flex;
align-items: center;
2026-02-27 10:51:26 +05:30
gap: 0.45rem;
background: #10b981;
color: white;
border: none;
border-radius: 9px;
padding: 0.65rem 1.4rem;
font-size: 0.88rem;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
.btn-share:hover { background: #059669; }
.footer-note {
margin-top: 1.25rem;
color: var(--text-muted);
font-size: 0.82rem;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
/* ── CHECKBOX STYLE ── */
input[type="checkbox"] {
width: 15px;
height: 15px;
accent-color: var(--secondary);
cursor: pointer;
}
/* ── RESPONSIVE ── */
2025-11-26 23:07:12 +05:30
@media (max-width: 768px) {
2026-02-27 10:51:26 +05:30
body { padding: 0.75rem 0.5rem; }
.invoice-header,
.date-strip,
.summary-wrap,
.invoice-footer { padding-left: 1.25rem; padding-right: 1.25rem; }
.id-grid { grid-template-columns: 1fr; padding: 1rem 1.25rem; }
.date-row { flex-direction: column; }
.panel, .cg-panel, .cg-groups-panel { margin-left: 1.25rem; margin-right: 1.25rem; }
.invoice-table { font-size: 0.75rem; }
}
2026-02-27 10:51:26 +05:30
/* ── GROUP ITEMS HIDDEN ROW ── */
.cg-items-row { background: #f8faff; }
.cg-toggle-btn {
display: inline-flex;
align-items: center;
gap: 0.3rem;
padding: 0.3rem 0.75rem;
border: 1.5px solid #3b82f6;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 600;
color: #3b82f6;
background: transparent;
cursor: pointer;
transition: all 0.15s;
2025-11-26 23:07:12 +05:30
}
2026-02-27 10:51:26 +05:30
.cg-toggle-btn:hover { background: #eff6ff; }
/* ── DIVIDER ── */
.section-divider { height: 1px; background: var(--border); margin: 0 2.5rem; }
2025-11-26 23:07:12 +05:30
</style>
</head>
<body>
2026-02-27 10:51:26 +05:30
<div class="invoice-container">
2025-11-25 13:14:53 +05:30
2026-02-27 10:51:26 +05:30
<!-- ACCENT BAR -->
<div class="invoice-accent-bar"></div>
@php
$showActions = $showActions ?? true;
@endphp
<!-- ═══════════════════════════ HEADER ═══════════════════════════ -->
<div class="invoice-header">
<div class="d-flex justify-content-between align-items-start flex-wrap gap-3">
<div>
<div class="invoice-title">
<i class="fas fa-file-invoice" style="color:#3b82f6;font-size:1.5rem;vertical-align:middle;margin-right:0.4rem;"></i>INVOICE
2025-11-26 23:07:12 +05:30
</div>
2026-02-27 10:51:26 +05:30
<div class="invoice-number mt-1">{{ $invoice->invoice_number }}</div>
2025-11-25 13:14:53 +05:30
</div>
2026-02-27 10:51:26 +05:30
<div>
@if($invoice->status == 'paid')
<span class="status-badge status-paid">
<i class="fas fa-check-circle"></i> Paid
</span>
@elseif($invoice->status == 'overdue')
<span class="status-badge status-overdue">
<i class="fas fa-exclamation-circle"></i> Overdue
</span>
@elseif($invoice->status == 'pending')
<span class="status-badge status-pending">
<i class="fas fa-clock"></i> Pending
</span>
@else
<span class="status-badge status-default">
<i class="fas fa-question-circle"></i> {{ ucfirst($invoice->status) }}
</span>
@endif
</div>
</div>
</div>
2025-11-25 13:14:53 +05:30
2026-02-27 10:51:26 +05:30
<!-- ═══════════════════════════ ID BOXES ═══════════════════════════ -->
<div class="id-grid">
<!-- Invoice ID -->
<div class="id-box">
<div class="id-icon-wrap id-icon-blue">
<i class="fas fa-receipt"></i>
</div>
<div>
<div class="id-label">Invoice ID</div>
<div class="id-value">{{ $invoice->invoice_number }}</div>
</div>
</div>
<!-- Container ID -->
<div class="id-box">
<div class="id-icon-wrap id-icon-green">
<i class="fas fa-box"></i>
</div>
<div>
<div class="id-label">Container ID</div>
<div class="id-value">
@if($invoice->container && $invoice->container->container_number)
{{ $invoice->container->container_number }}
@elseif($invoice->container_id)
{{ $invoice->container_id }}
@else
@include('admin.popup_invoice', ['invoice' => $invoice, 'shipment' => $shipment])
N/A
@endif
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════ DATES ═══════════════════════════ -->
<div class="date-strip">
<div class="date-row">
<div class="date-card">
<div class="date-icon-wrap">
<i class="fas fa-calendar-alt"></i>
</div>
<div>
<div class="date-label">Invoice Date</div>
<div class="date-value">{{ \Carbon\Carbon::parse($invoice->invoice_date)->format('M d, Y') }}</div>
</div>
</div>
<div class="date-arrow">
<i class="fas fa-arrow-right"></i>
</div>
<div class="date-card">
<div class="date-icon-wrap" style="background:#fff7ed;color:#f59e0b;">
<i class="fas fa-clock"></i>
</div>
<div>
<div class="date-label">Due Date</div>
<div class="date-value {{ $invoice->status == 'overdue' ? 'overdue' : '' }}">
{{ \Carbon\Carbon::parse($invoice->due_date)->format('M d, Y') }}
2025-11-26 23:07:12 +05:30
</div>
</div>
2025-11-25 13:14:53 +05:30
</div>
2026-02-27 10:51:26 +05:30
</div>
</div>
2025-11-25 13:14:53 +05:30
2026-02-27 10:51:26 +05:30
<!-- ═══════════════════════════ CUSTOMER ═══════════════════════════ -->
<div class="panel">
<div class="panel-header">
<i class="fas fa-user-circle"></i> Customer Details
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<div class="customer-name">{{ $invoice->customer_name }}</div>
@if($invoice->company_name)
<div class="customer-detail"><strong>Company:</strong> {{ $invoice->company_name }}</div>
@endif
<div class="customer-detail"><strong>Mobile:</strong> {{ $invoice->customer_mobile }}</div>
<div class="customer-detail"><strong>Email:</strong> {{ $invoice->customer_email }}</div>
2025-11-26 23:07:12 +05:30
</div>
2026-02-27 10:51:26 +05:30
<div class="col-md-6">
<div class="customer-detail"><strong>Address:</strong></div>
<div class="customer-detail">{{ $invoice->customer_address }}</div>
<div class="customer-detail"><strong>Pincode:</strong> {{ $invoice->pincode }}</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════ ITEMS TABLE ═══════════════════════════ -->
@php
$isEmbedded = isset($embedded) && $embedded;
@endphp
<div class="panel">
<div class="panel-header">
<i class="fas fa-list"></i> Invoice Items
</div>
<!-- @if($isEmbedded)
<form action="{{ route('admin.invoices.items.update', $invoice->id) }}" method="POST">
@csrf
@method('PUT')
@endif -->
<div class="table-responsive">
<table class="invoice-table items-table">
<thead>
<tr>
<th class="text-center" style="width:44px;">
<input type="checkbox" id="selectAllItems">
</th>
<th class="text-center" style="min-width:50px;">#</th>
<th style="min-width:200px;">Description</th>
<th class="text-center" style="min-width:75px;">CTN</th>
<th class="text-center" style="min-width:75px;">QTY</th>
<th class="text-center" style="min-width:95px;">TTL/QTY</th>
<th class="text-center" style="min-width:75px;">Unit</th>
<th class="text-center" style="min-width:110px;">Price</th>
<th class="text-center" style="min-width:125px;">TTL Amount</th>
<th class="text-center" style="min-width:85px;">CBM</th>
<th class="text-center" style="min-width:95px;">TTL CBM</th>
<th class="text-center" style="min-width:80px;">KG</th>
<th class="text-center" style="min-width:95px;">TTL KG</th>
<th class="text-center" style="min-width:95px;">Shop No</th>
</tr>
</thead>
<tbody>
@foreach($invoice->items as $i => $item)
@php
$alreadyGrouped = in_array($item->id, $groupedItemIds ?? []);
@endphp
<tr class="{{ $alreadyGrouped ? 'grouped-item-row' : '' }}">
<td class="text-center">
<input type="checkbox"
class="item-select-checkbox"
value="{{ $item->id }}"
{{ $alreadyGrouped ? 'disabled' : '' }}>
</td>
<td class="text-center" style="font-weight:600;color:var(--text-muted);">{{ $i + 1 }}</td>
<td class="desc-col" style="font-weight:600;color:var(--primary);">{{ $item->description }}</td>
<td class="text-center">{{ $item->ctn }}</td>
<td class="text-center">{{ $item->qty }}</td>
<td class="text-center" style="font-weight:700;">{{ $item->ttl_qty }}</td>
<td class="text-center">{{ $item->unit }}</td>
@if($isEmbedded)
<td class="text-center" style="min-width:120px;">
<input type="number" step="0.01" min="0"
name="items[{{ $item->id }}][price]"
value="{{ old('items.' . $item->id . '.price', $item->price) }}"
class="form-control form-control-sm text-end">
</td>
<td class="text-center" style="min-width:140px;">
<input type="number" step="0.01" min="0"
name="items[{{ $item->id }}][ttl_amount]"
value="{{ old('items.' . $item->id . '.ttl_amount', $item->ttl_amount) }}"
class="form-control form-control-sm text-end">
</td>
@else
<td class="text-center price-green">{{ number_format($item->price, 2) }}</td>
<td class="text-center price-blue">{{ number_format($item->ttl_amount, 2) }}</td>
2025-11-26 23:07:12 +05:30
@endif
2026-02-27 10:51:26 +05:30
<td class="text-center">{{ $item->cbm }}</td>
<td class="text-center">{{ $item->ttl_cbm }}</td>
<td class="text-center">{{ $item->kg }}</td>
<td class="text-center">{{ $item->ttl_kg }}</td>
<td class="text-center"><span class="badge-shop">{{ $item->shop_no }}</span></td>
</tr>
@endforeach
@if($invoice->items->isEmpty())
<tr>
<td colspan="15" class="text-center py-4" style="color:var(--text-muted);font-weight:600;">
<i class="fas fa-inbox me-2" style="font-size:1.3rem;opacity:.4;"></i><br>No invoice items found.
</td>
</tr>
@endif
</tbody>
</table>
</div>
<!-- ACTION BAR -->
<div class="action-bar">
<small>Selected items for charge group: <span id="selectedItemsCount">0</span></small>
<button type="button" id="btnCreateChargeGroup" class="btn-create-group" disabled>
<i class="fas fa-layer-group"></i> Create Charge Group
</button>
</div>
@if($isEmbedded)
<div class="text-end p-3" style="border-top:1px solid var(--border);">
<button type="submit" class="btn btn-primary btn-sm">
<i class="fas fa-save me-1"></i> Update Items & Recalculate
</button>
</div>
</form>
@endif
</div>
<!-- ═══════════════════════════ CHARGE GROUP FORM ═══════════════════════════ -->
<div id="chargeGroupBox" class="cg-panel d-none">
<div class="cg-panel-header">
<i class="fas fa-layer-group"></i> Create Charge Group for Selected Items
</div>
<div class="cg-body">
<form method="POST" id="chargeGroupForm"
action="{{ route('admin.invoices.charge-group.store', $invoice->id) }}">
@csrf
<div class="row g-3 mb-3">
<div class="col-md-4">
<label class="form-label-custom">Group Name</label>
<input type="text" class="form-control-custom" id="cgGroupName"
name="group_name" placeholder="e.g. Group #1">
</div>
<div class="col-md-4">
<label class="form-label-custom">Price based on</label>
<select class="form-select-custom" id="cgBasis">
<option value="" selected disabled>Select basis</option>
<option value="ttl_qty">TTL/QTY</option>
<option value="amount">AMOUNT</option>
<option value="ttl_cbm">TTL CBM</option>
<option value="ttl_kg">TTL KG</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label-custom">Rate per selected basis</label>
<input type="number" step="0.0001" class="form-control-custom"
id="cgRate" placeholder="Enter rate">
</div>
</div>
<input type="hidden" name="basis_type" id="cgBasisTypeInput">
<input type="hidden" name="basis_value" id="cgBasisValueInput">
<input type="hidden" name="rate" id="cgRateHidden">
<input type="hidden" name="auto_total" id="cgAutoTotal">
<div class="row g-3 mb-3">
<!-- LEFT: Total basis value -->
<div class="col-md-6">
<div class="basis-box">
<div class="basis-box-label">Total basis value</div>
<div style="display:flex;align-items:baseline;gap:0.4rem;">
<span class="basis-value-display" id="cgBasisValue">0</span>
<span class="basis-label-display" id="cgBasisLabel"></span>
</div>
<div class="basis-hint" id="cgBasisHint">
Select basis to see total TTLQTY, CBM, KG or Amount.
</div>
</div>
2025-11-26 23:07:12 +05:30
</div>
2026-02-27 10:51:26 +05:30
<!-- RIGHT: Total charges (admin input) -->
2025-11-26 23:07:12 +05:30
<div class="col-md-6">
2026-02-27 10:51:26 +05:30
<div class="basis-box">
<div class="basis-box-label">Total charges (admin input)</div>
<input type="number"
step="0.01"
class="form-control-custom"
id="cgTotalChargeInput"
name="totalcharge"
placeholder="Enter total charges"
readonly>
<div class="basis-hint" style="margin-top:0.5rem">
Suggested Rate × basis:
<span class="suggested-total" id="cgSuggestedTotal">0</span>
</div>
</div>
2025-11-26 23:07:12 +05:30
</div>
</div>
2025-11-25 13:14:53 +05:30
2026-02-27 10:51:26 +05:30
<div class="mb-3">
<label class="form-label-custom" style="margin-bottom:0.5rem;">Selected items in this group</label>
<div class="table-responsive" style="border:1px solid var(--border);border-radius:9px;overflow:hidden;">
<table class="invoice-table">
<thead>
2025-11-26 23:07:12 +05:30
<tr>
2026-02-27 10:51:26 +05:30
<th>#</th>
2025-11-26 23:07:12 +05:30
<th>Description</th>
<th class="text-center">QTY</th>
2026-02-27 10:51:26 +05:30
<th class="text-center">TTL QTY</th>
2025-11-26 23:07:12 +05:30
<th class="text-center">CBM</th>
<th class="text-center">TTL CBM</th>
<th class="text-center">KG</th>
<th class="text-center">TTL KG</th>
2026-02-27 10:51:26 +05:30
<th class="text-center">TTL Amount</th>
2025-11-26 23:07:12 +05:30
</tr>
</thead>
2026-02-27 10:51:26 +05:30
<tbody id="cgItemsTableBody"></tbody>
2025-11-26 23:07:12 +05:30
</table>
</div>
</div>
2025-12-23 00:30:18 +05:30
2026-02-27 10:51:26 +05:30
<div class="d-flex justify-content-end gap-2">
<button type="button" id="cgCancelBtn"
style="padding:0.5rem 1.1rem;border:1.5px solid var(--border);border-radius:8px;background:transparent;font-size:0.85rem;font-weight:600;cursor:pointer;color:var(--text-secondary);">
Cancel
</button>
<button type="submit" id="cgSaveBtn"
style="display:inline-flex;align-items:center;gap:0.4rem;padding:0.5rem 1.25rem;border:none;border-radius:8px;background:#10b981;color:white;font-size:0.85rem;font-weight:700;cursor:pointer;">
<i class="fas fa-save"></i> Save Charge Group
</button>
</div>
</form>
</div>
</div>
2025-12-23 00:30:18 +05:30
2026-02-27 10:51:26 +05:30
<!-- ═══════════════════════════ CHARGE GROUPS LIST ═══════════════════════════ -->
@if($invoice->chargeGroups->isNotEmpty())
<div class="cg-groups-panel">
<div class="cg-groups-header">
<i class="fas fa-layer-group"></i> Charge Groups
2025-12-23 00:30:18 +05:30
</div>
2026-02-27 10:51:26 +05:30
<div class="table-responsive">
<table class="invoice-table">
<thead>
<tr>
<th>#</th>
<th>Group Name</th>
<th>Basis</th>
<th class="text-end">Basis Value</th>
<th class="text-end">Rate</th>
<th class="text-end">Total Charge</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
@foreach($invoice->chargeGroups as $index => $group)
<tr>
<td>{{ $index + 1 }}</td>
<td style="font-weight:600;">{{ $group->group_name ?? 'Group '.$group->id }}</td>
<td><span style="text-transform:uppercase;font-size:0.75rem;font-weight:700;color:var(--text-muted);">{{ $group->basis_type }}</span></td>
<td class="text-end" style="font-family:'JetBrains Mono',monospace;font-size:0.82rem;">{{ number_format($group->basis_value, 3) }}</td>
<td class="text-end" style="font-family:'JetBrains Mono',monospace;font-size:0.82rem;">{{ number_format($group->rate, 2) }}</td>
<td class="text-end price-blue">{{ number_format($group->total_charge, 2) }}</td>
<td class="text-center">
<button type="button" class="cg-toggle-btn cg-toggle-items"
data-group-id="{{ $group->id }}">
<i class="fas fa-eye"></i> View
</button>
</td>
</tr>
<tr class="cg-items-row d-none" data-group-id="{{ $group->id }}">
<td colspan="7">
<div style="padding:1rem;background:#f8faff;border-radius:8px;margin:0.25rem 0;">
<div style="font-weight:700;font-size:0.8rem;margin-bottom:0.6rem;color:var(--primary);">Items in this group:</div>
@if($group->items->isEmpty())
<div style="color:var(--text-muted);font-size:0.82rem;">No items linked.</div>
@else
<div class="table-responsive">
<table class="invoice-table">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th class="text-center">QTY</th>
<th class="text-center">TTL QTY</th>
<th class="text-center">CBM</th>
<th class="text-center">TTL CBM</th>
<th class="text-center">KG</th>
<th class="text-center">TTL KG</th>
<th class="text-end">TTL Amount</th>
<th class="text-end">Rate</th>
<th class="text-end">Total Charge</th>
</tr>
</thead>
<tbody>
@foreach($group->items as $giIndex => $gi)
@php
$it = $gi->item;
$rate = $group->rate;
$itemBasis = 0;
switch ($group->basis_type) {
case 'ttl_qty': $itemBasis = $it->ttl_qty ?? 0; break;
case 'amount': $itemBasis = $it->ttl_amount ?? 0; break;
case 'ttl_cbm': $itemBasis = $it->ttl_cbm ?? 0; break;
case 'ttl_kg': $itemBasis = $it->ttl_kg ?? 0; break;
}
$itemTotal = $itemBasis * $rate;
@endphp
<tr>
<td>{{ $giIndex + 1 }}</td>
<td>{{ $it->description }}</td>
<td class="text-center">{{ $it->qty }}</td>
<td class="text-center">{{ $it->ttl_qty }}</td>
<td class="text-center">{{ $it->cbm }}</td>
<td class="text-center">{{ $it->ttl_cbm }}</td>
<td class="text-center">{{ $it->kg }}</td>
<td class="text-center">{{ $it->ttl_kg }}</td>
<td class="text-end">{{ number_format($it->ttl_amount, 2) }}</td>
<td class="text-end">{{ number_format($rate, 2) }}</td>
<td class="text-end" style="color:#06b6d4;font-weight:700;">{{ number_format($itemTotal, 2) }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
2025-11-25 13:14:53 +05:30
</div>
2026-02-27 10:51:26 +05:30
</div>
@endif
2025-12-23 00:30:18 +05:30
2026-02-27 10:51:26 +05:30
<!-- ═══════════════════════════ SUMMARY ═══════════════════════════ -->
<div class="summary-wrap">
<div class="row justify-content-end">
<div class="col-md-5">
<div class="summary-card">
<div class="summary-header-row">
<i class="fas fa-calculator"></i> Final Summary
</div>
<div class="summary-body">
<div class="summary-row">
<span class="label">Amount</span>
<span class="value">{{ number_format($invoice->final_amount, 2) }}</span>
</div>
2025-12-23 00:30:18 +05:30
2026-02-27 10:51:26 +05:30
@if($invoice->tax_type === 'gst')
<div class="summary-row">
<span class="label">CGST ({{ $invoice->cgst_percent ?? ($invoice->gst_percent / 2) }}%)</span>
<span class="value red">{{ number_format($invoice->gst_amount / 2, 2) }}</span>
</div>
<div class="summary-row">
<span class="label">SGST ({{ $invoice->sgst_percent ?? ($invoice->gst_percent / 2) }}%)</span>
<span class="value red">{{ number_format($invoice->gst_amount / 2, 2) }}</span>
</div>
@elseif($invoice->tax_type === 'igst')
<div class="summary-row">
<span class="label">IGST ({{ $invoice->igst_percent ?? $invoice->gst_percent }}%)</span>
<span class="value red">{{ number_format($invoice->gst_amount, 2) }}</span>
</div>
@else
<div class="summary-row">
<span class="label">GST ({{ $invoice->gst_percent }}%)</span>
<span class="value red">{{ number_format($invoice->gst_amount, 2) }}</span>
</div>
@endif
2025-12-23 00:30:18 +05:30
2026-02-27 10:51:26 +05:30
<div class="summary-row total">
<span class="label">Total Payable</span>
<span class="value">{{ number_format($invoice->final_amount_with_gst, 2) }}</span>
</div>
</div>
</div>
2025-12-23 00:30:18 +05:30
</div>
</div>
</div>
2026-02-27 10:51:26 +05:30
<!-- ═══════════════════════════ FOOTER ═══════════════════════════ -->
<div class="invoice-footer">
@if($invoice->pdf_path && $showActions)
<a href="{{ asset($invoice->pdf_path) }}" class="btn-download" download>
<i class="fas fa-download"></i> Download PDF
</a>
<button class="btn-share" onclick="shareInvoice()">
<i class="fas fa-share"></i> Share
</button>
@endif
<div class="footer-note">
<p style="margin-bottom:0.25rem;">Thank you for your business!</p>
<p style="margin:0;">For any inquiries, contact us at support@Kent Logistic</p>
2025-11-25 13:14:53 +05:30
</div>
</div>
2026-02-27 10:51:26 +05:30
</div>
2025-11-25 13:14:53 +05:30
2026-02-27 10:51:26 +05:30
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script>
2025-11-26 23:07:12 +05:30
function shareInvoice() {
const shareData = {
title: "Invoice {{ $invoice->invoice_number }}",
text: "Sharing invoice {{ $invoice->invoice_number }}",
2026-02-27 10:51:26 +05:30
url: "{{ asset($invoice->pdf_path) }}"
2025-11-26 23:07:12 +05:30
};
if (navigator.share) {
navigator.share(shareData).catch(() => {});
} else {
navigator.clipboard.writeText(shareData.url);
alert("Link copied! Sharing not supported on this browser.");
}
2025-11-25 13:14:53 +05:30
}
2025-12-23 00:30:18 +05:30
2026-02-27 10:51:26 +05:30
document.addEventListener('DOMContentLoaded', function () {
const selectAll = document.getElementById('selectAllItems');
const itemCheckboxes = document.querySelectorAll('.item-select-checkbox');
const countSpan = document.getElementById('selectedItemsCount');
const btnCreate = document.getElementById('btnCreateChargeGroup');
const chargeGroupBox = document.getElementById('chargeGroupBox');
const cgCancelBtn = document.getElementById('cgCancelBtn');
const cgItemsTableBody = document.getElementById('cgItemsTableBody');
const cgBasisSelect = document.getElementById('cgBasis');
const cgRateInput = document.getElementById('cgRate');
const cgBasisValueSpan = document.getElementById('cgBasisValue');
const cgBasisLabelSpan = document.getElementById('cgBasisLabel');
const cgSuggestedTotalSpan = document.getElementById('cgSuggestedTotal');
const cgTotalChargeInput = document.getElementById('cgTotalChargeInput');
const cgAutoTotalInput = document.getElementById('cgAutoTotal');
const cgBasisTypeInput = document.getElementById('cgBasisTypeInput');
const cgBasisValueInput = document.getElementById('cgBasisValueInput');
const cgRateHidden = document.getElementById('cgRateHidden');
const cgForm = document.getElementById('chargeGroupForm');
function updateSelectionState() {
let selectedCount = 0;
itemCheckboxes.forEach(cb => {
if (cb.checked && !cb.disabled) selectedCount++;
});
if (countSpan) countSpan.textContent = selectedCount;
if (btnCreate) btnCreate.disabled = (selectedCount === 0);
if (selectedCount === 0 && chargeGroupBox) {
chargeGroupBox.classList.add('d-none');
}
}
function getSelectedItemsDataBasic() {
const items = [];
itemCheckboxes.forEach(cb => {
if (cb.checked && !cb.disabled) {
const row = cb.closest('tr');
if (!row) return;
const cellText = (n) =>
row.querySelector(`td:nth-child(${n})`)?.textContent.trim() ?? '';
items.push({
description: cellText(3),
qty: cellText(5),
ttlqty: cellText(6),
cbm: cellText(10),
ttlcbm: cellText(11),
kg: cellText(12),
ttlkg: cellText(13),
amount: cellText(9),
});
}
});
return items;
}
function parseNumber(str) {
if (!str) return 0;
const cleaned = str.replace(/[,\s]/g, '');
const val = parseFloat(cleaned);
return isNaN(val) ? 0 : val;
}
function fillChargeGroupItemsTable() {
if (!cgItemsTableBody) return;
const items = getSelectedItemsDataBasic();
cgItemsTableBody.innerHTML = '';
items.forEach((it, index) => {
cgItemsTableBody.insertAdjacentHTML('beforeend', `
<tr>
<td>${index + 1}</td>
<td>${it.description}</td>
<td class="text-center">${it.qty}</td>
<td class="text-center">${it.ttlqty}</td>
<td class="text-center">${it.cbm}</td>
<td class="text-center">${it.ttlcbm}</td>
<td class="text-center">${it.kg}</td>
<td class="text-center">${it.ttlkg}</td>
<td class="text-center">${it.amount}</td>
</tr>
`);
});
}
function refreshBasisSummaryAndSuggestion() {
if (!chargeGroupBox || chargeGroupBox.classList.contains('d-none')) return;
const items = getSelectedItemsDataBasic();
const basis = cgBasisSelect ? cgBasisSelect.value : '';
let totalBasis = 0;
let label = '';
if (basis === 'ttl_qty') {
totalBasis = items.reduce((sum, it) => sum + parseNumber(it.ttlqty), 0);
label = 'Total TTL/QTY';
} else if (basis === 'amount') {
totalBasis = items.reduce((sum, it) => sum + parseNumber(it.amount), 0);
label = 'Total Amount';
} else if (basis === 'ttl_cbm') {
totalBasis = items.reduce((sum, it) => sum + parseNumber(it.ttlcbm), 0);
label = 'Total TTL CBM';
} else if (basis === 'ttl_kg') {
totalBasis = items.reduce((sum, it) => sum + parseNumber(it.ttlkg), 0);
label = 'Total TTL KG';
}
if (cgBasisValueSpan) cgBasisValueSpan.textContent = totalBasis ? totalBasis.toFixed(3) : '0';
if (cgBasisLabelSpan) cgBasisLabelSpan.textContent = label || '';
const rate = parseNumber(cgRateInput ? cgRateInput.value : '0');
const suggested = rate * totalBasis;
if (cgSuggestedTotalSpan) cgSuggestedTotalSpan.textContent = suggested ? suggested.toFixed(2) : '0';
if (cgBasisTypeInput) cgBasisTypeInput.value = basis || '';
if (cgBasisValueInput) cgBasisValueInput.value = totalBasis || 0;
if (cgRateHidden && cgRateInput) cgRateHidden.value = cgRateInput.value || 0;
if (cgAutoTotalInput) cgAutoTotalInput.value = suggested || 0;
if (cgTotalChargeInput) {
cgTotalChargeInput.value = suggested ? suggested.toFixed(2) : '0';
}
}
itemCheckboxes.forEach(cb => {
cb.addEventListener('change', function () {
updateSelectionState();
const total = itemCheckboxes.length;
const checked = Array.from(itemCheckboxes).filter(c => c.checked && !c.disabled).length;
if (selectAll) {
selectAll.checked = (checked > 0 && checked === total);
selectAll.indeterminate = (checked > 0 && checked < total);
}
if (!chargeGroupBox.classList.contains('d-none')) {
fillChargeGroupItemsTable();
refreshBasisSummaryAndSuggestion();
}
});
});
if (selectAll) {
selectAll.addEventListener('change', function () {
itemCheckboxes.forEach(cb => { if (!cb.disabled) cb.checked = selectAll.checked; });
updateSelectionState();
if (!chargeGroupBox.classList.contains('d-none')) {
fillChargeGroupItemsTable();
refreshBasisSummaryAndSuggestion();
}
});
}
if (cgBasisSelect) cgBasisSelect.addEventListener('change', refreshBasisSummaryAndSuggestion);
if (cgRateInput) cgRateInput.addEventListener('input', refreshBasisSummaryAndSuggestion);
if (btnCreate && chargeGroupBox) {
btnCreate.addEventListener('click', function () {
const hasSelection = Array.from(itemCheckboxes).some(cb => cb.checked && !cb.disabled);
if (!hasSelection) return;
chargeGroupBox.classList.remove('d-none');
fillChargeGroupItemsTable();
refreshBasisSummaryAndSuggestion();
chargeGroupBox.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
}
if (cgCancelBtn && chargeGroupBox) {
cgCancelBtn.addEventListener('click', function () {
chargeGroupBox.classList.add('d-none');
itemCheckboxes.forEach(cb => { if (!cb.disabled) cb.checked = false; });
if (selectAll) { selectAll.checked = false; selectAll.indeterminate = false; }
updateSelectionState();
});
}
if (cgForm) {
cgForm.addEventListener('submit', function (e) {
const selectedIds = [];
itemCheckboxes.forEach(cb => { if (cb.checked && !cb.disabled) selectedIds.push(cb.value); });
if (selectedIds.length === 0) {
e.preventDefault();
alert('Please select at least one item for this charge group.');
return;
}
if (!cgBasisSelect || !cgBasisSelect.value) {
e.preventDefault();
alert('Please select a basis for this charge group.');
return;
}
if (!cgTotalChargeInput || !cgTotalChargeInput.value || parseFloat(cgTotalChargeInput.value) <= 0) {
e.preventDefault();
alert('Please enter total charges for this group.');
return;
}
const oldHidden = cgForm.querySelectorAll('input[name="item_ids[]"]');
oldHidden.forEach(el => el.remove());
selectedIds.forEach(id => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'item_ids[]';
input.value = id;
cgForm.appendChild(input);
});
if (chargeGroupBox) chargeGroupBox.classList.add('d-none');
itemCheckboxes.forEach(cb => { if (!cb.disabled) cb.checked = false; });
if (selectAll) { selectAll.checked = false; selectAll.indeterminate = false; }
updateSelectionState();
});
}
updateSelectionState();
});
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('click', function (e) {
if (!e.target.classList.contains('cg-toggle-items') &&
!e.target.closest('.cg-toggle-items')) return;
const btn = e.target.closest('.cg-toggle-items') || e.target;
const groupId = btn.getAttribute('data-group-id');
const row = document.querySelector('.cg-items-row[data-group-id="' + groupId + '"]');
if (!row) return;
row.classList.toggle('d-none');
const isHidden = row.classList.contains('d-none');
btn.innerHTML = isHidden
? '<i class="fas fa-eye"></i> View'
: '<i class="fas fa-eye-slash"></i> Hide';
});
});
</script>
2025-11-26 23:07:12 +05:30
</body>
</html>