gst
This commit is contained in:
@@ -3,430 +3,369 @@
|
||||
@section('page-title', 'Edit Invoice')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
/* World-Class UI Design System - No Blur Effects */
|
||||
/* --------------------------------------------------
|
||||
GLOBAL VARIABLES
|
||||
-------------------------------------------------- */
|
||||
:root {
|
||||
--primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
--success-gradient: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
--glass-bg: #ffffff;
|
||||
--glass-border: rgba(255, 255, 255, 0.2);
|
||||
--shadow-soft: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
--shadow-medium: 0 12px 48px rgba(0, 0, 0, 0.15);
|
||||
--shadow-strong: 0 20px 60px rgba(0, 0, 0, 0.2);
|
||||
--primary-gradient: linear-gradient(135deg,#667eea,#764ba2);
|
||||
--success-gradient: linear-gradient(135deg,#10b981,#059669);
|
||||
--glass-bg: #fff;
|
||||
--shadow-soft: 0 8px 32px rgba(0,0,0,0.1);
|
||||
--shadow-medium: 0 12px 48px rgba(0,0,0,0.15);
|
||||
--shadow-strong: 0 20px 60px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* Enhanced Card - No Blur */
|
||||
/* --------------------------------------------------
|
||||
CARD DESIGN
|
||||
-------------------------------------------------- */
|
||||
.card {
|
||||
background: var(--glass-bg);
|
||||
border-radius: 24px;
|
||||
box-shadow: var(--shadow-strong);
|
||||
border-radius: 12px;
|
||||
border: 1px solid #e4e6ef;
|
||||
animation: cardEntrance 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
box-shadow: var(--shadow-strong);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
animation: fadeUp 0.8s ease;
|
||||
}
|
||||
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(45deg,
|
||||
rgba(102, 126, 234, 0.03) 0%,
|
||||
rgba(118, 75, 162, 0.03) 50%,
|
||||
rgba(16, 185, 129, 0.03) 100%);
|
||||
pointer-events: none;
|
||||
content:"";
|
||||
position:absolute; inset:0;
|
||||
background:linear-gradient(45deg,
|
||||
rgba(102,126,234,.03),
|
||||
rgba(118,75,162,.03) 50%,
|
||||
rgba(16,185,129,.03));
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
@keyframes cardEntrance {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(30px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
@keyframes fadeUp {
|
||||
0% {opacity:0; transform:translateY(30px) scale(.95);}
|
||||
100% {opacity:1; transform:translateY(0) scale(1);}
|
||||
}
|
||||
|
||||
/* Premium Card Header */
|
||||
/* --------------------------------------------------
|
||||
CARD HEADER
|
||||
-------------------------------------------------- */
|
||||
.card-header {
|
||||
background: var(--primary-gradient);
|
||||
color: white;
|
||||
border-bottom: none;
|
||||
padding: 28px 35px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background:var(--primary-gradient);
|
||||
color:#fff;
|
||||
padding:11px 19px;
|
||||
border:none;
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.card-header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg,
|
||||
transparent 0%,
|
||||
rgba(255, 255, 255, 0.1) 50%,
|
||||
transparent 100%);
|
||||
animation: headerShimmer 6s infinite linear;
|
||||
transform: rotate(45deg);
|
||||
content:"";
|
||||
position:absolute;
|
||||
top:-50%; left:-50%;
|
||||
width:200%; height:200%;
|
||||
background:linear-gradient(45deg,transparent,
|
||||
rgba(255,255,255,.1) 50%,transparent);
|
||||
animation: shimmer 6s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes headerShimmer {
|
||||
0% { transform: translateX(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(100%) rotate(45deg); }
|
||||
@keyframes shimmer {
|
||||
from {transform:translateX(-100%) rotate(45deg);}
|
||||
to {transform:translateX(100%) rotate(45deg);}
|
||||
}
|
||||
|
||||
.card-header h4 {
|
||||
margin: 0;
|
||||
font-weight: 800;
|
||||
font-size: 1.6rem;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
margin:0; font-weight:800; font-size:1.6rem;
|
||||
display:flex; align-items:center; gap:12px;
|
||||
text-shadow:0 2px 4px rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
.card-header h4::before {
|
||||
content: '✨';
|
||||
font-size: 1.4rem;
|
||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
|
||||
content:"✨"; font-size:1.4rem;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 35px;
|
||||
background: #f8fafc;
|
||||
position: relative;
|
||||
}
|
||||
/* --------------------------------------------------
|
||||
BODY + FORM ELEMENTS
|
||||
-------------------------------------------------- */
|
||||
.card-body { padding:15px; background:#f8fafc; }
|
||||
|
||||
/* World-Class Form Elements - No Blur */
|
||||
.form-label {
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 10px;
|
||||
font-size: 0.95rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
position: relative;
|
||||
font-weight:700; color:#1e293b;
|
||||
margin-bottom:10px; font-size:.95rem;
|
||||
letter-spacing:.5px; text-transform:uppercase;
|
||||
display:flex; align-items:center; gap:8px;
|
||||
}
|
||||
|
||||
.form-label::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background: var(--primary-gradient);
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
content:""; width:4px; height:16px;
|
||||
background:var(--primary-gradient);
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
.form-control, .form-select {
|
||||
border: 2px solid #e2e8f0;
|
||||
border-radius: 16px;
|
||||
padding: 16px 20px;
|
||||
padding: 8px 15px;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
font-size: 1rem;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
transition: .4s;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
.form-control:focus, .form-select:focus {
|
||||
border-color: #667eea;
|
||||
box-shadow:
|
||||
0 0 0 4px rgba(102, 126, 234, 0.15),
|
||||
0 8px 24px rgba(102, 126, 234, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
background: #ffffff;
|
||||
transform: translateY(-2px) scale(1.02);
|
||||
animation: inputGlow 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes inputGlow {
|
||||
0%, 100% { box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.15), 0 8px 24px rgba(102, 126, 234, 0.2); }
|
||||
50% { box-shadow: 0 0 0 6px rgba(102, 126, 234, 0.1), 0 12px 32px rgba(102, 126, 234, 0.25); }
|
||||
border-color:#667eea;
|
||||
box-shadow:
|
||||
0 0 0 4px rgba(102,126,234,.15),
|
||||
0 8px 24px rgba(102,126,234,.2);
|
||||
transform:translateY(-2px) scale(1.02);
|
||||
}
|
||||
|
||||
/* hover */
|
||||
.form-control:hover, .form-select:hover {
|
||||
border-color: #cbd5e1;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
|
||||
border-color:#cbd5e1;
|
||||
transform:translateY(-2px);
|
||||
box-shadow:0 6px 20px rgba(0,0,0,.08);
|
||||
}
|
||||
|
||||
/* Enhanced Grid System */
|
||||
.row.g-3 {
|
||||
margin: -15px;
|
||||
}
|
||||
|
||||
.row.g-3 > [class*="col-"] {
|
||||
padding: 15px;
|
||||
animation: formElementEntrance 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
||||
}
|
||||
|
||||
@keyframes formElementEntrance {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(25px) scale(0.9);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Staggered Animation Delays */
|
||||
.row.g-3 > [class*="col-"]:nth-child(1) { animation-delay: 0.1s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(2) { animation-delay: 0.2s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(3) { animation-delay: 0.3s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(4) { animation-delay: 0.4s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(5) { animation-delay: 0.5s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(6) { animation-delay: 0.6s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(7) { animation-delay: 0.7s; }
|
||||
.row.g-3 > [class*="col-"]:nth-child(8) { animation-delay: 0.8s; }
|
||||
|
||||
/* Premium Textarea */
|
||||
/* textarea */
|
||||
textarea.form-control {
|
||||
height: 65px;
|
||||
resize: vertical;
|
||||
min-height: 120px;
|
||||
line-height: 1.6;
|
||||
background: #ffffff;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
textarea.form-control:focus {
|
||||
transform: translateY(-2px) scale(1.01);
|
||||
box-shadow:
|
||||
0 0 0 4px rgba(102, 126, 234, 0.15),
|
||||
0 12px 32px rgba(102, 126, 234, 0.2);
|
||||
}
|
||||
|
||||
/* World-Class Button Design - No Blur */
|
||||
/* --------------------------------------------------
|
||||
BUTTON STYLING
|
||||
-------------------------------------------------- */
|
||||
.btn-success {
|
||||
background: var(--success-gradient);
|
||||
border: none;
|
||||
padding: 18px 45px;
|
||||
border-radius: 16px;
|
||||
color: white;
|
||||
padding: 10px 25px;
|
||||
border-radius: 7px;
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
color: #fff;
|
||||
transition: .4s;
|
||||
box-shadow: var(--shadow-medium);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-success::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.4),
|
||||
transparent);
|
||||
transition: left 0.6s ease;
|
||||
}
|
||||
|
||||
.btn-success:hover::before {
|
||||
left: 100%;
|
||||
content:"";
|
||||
position:absolute; left:-100%; top:0;
|
||||
width:100%; height:100%;
|
||||
background:linear-gradient(90deg,transparent,
|
||||
rgba(255,255,255,.4),transparent);
|
||||
transition:.6s;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
transform: translateY(-4px) scale(1.05);
|
||||
box-shadow:
|
||||
0 16px 40px rgba(16, 185, 129, 0.4),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
background: var(--success-gradient);
|
||||
transform:translateY(-4px) scale(1.05);
|
||||
box-shadow:0 16px 40px rgba(16,185,129,.4);
|
||||
}
|
||||
|
||||
.btn-success:active {
|
||||
transform: translateY(-1px) scale(1.02);
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
.btn-success:hover::before { left:100%; }
|
||||
|
||||
/* Enhanced Select Styling */
|
||||
.form-select {
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%23667eea' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
||||
background-position: right 20px center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px;
|
||||
padding-right: 50px;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
/* Advanced Loading Animation */
|
||||
.btn-success.loading {
|
||||
pointer-events: none;
|
||||
padding-right: 60px;
|
||||
pointer-events:none; padding-right:60px;
|
||||
}
|
||||
|
||||
.btn-success.loading::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
border: 2px solid transparent;
|
||||
border-top: 2px solid white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
|
||||
content:"";
|
||||
position:absolute; right:20px; top:50%;
|
||||
width:20px; height:20px; margin-top:-10px;
|
||||
border-radius:50%;
|
||||
border:2px solid transparent;
|
||||
border-top-color:#fff;
|
||||
animation:spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
@keyframes spin {to{transform:rotate(360deg);}}
|
||||
|
||||
/* --------------------------------------------------
|
||||
RESPONSIVE
|
||||
-------------------------------------------------- */
|
||||
@media(max-width:768px){
|
||||
.card-body{padding:25px 20px;}
|
||||
.card-header{padding:22px 25px;}
|
||||
.card-header h4{font-size:1.4rem;}
|
||||
.btn-success{width:100%; padding:16px 30px;}
|
||||
.form-control,.form-select{padding:14px 16px;}
|
||||
}
|
||||
|
||||
/* Premium Focus States */
|
||||
.form-control:focus-visible,
|
||||
.form-select:focus-visible,
|
||||
.btn-success:focus-visible {
|
||||
outline: 3px solid #667eea;
|
||||
outline-offset: 2px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* Advanced Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.card-body {
|
||||
padding: 25px 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 22px 25px;
|
||||
}
|
||||
|
||||
.card-header h4 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
width: 100%;
|
||||
padding: 16px 30px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.form-control, .form-select {
|
||||
padding: 14px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Micro-interactions for Enhanced UX */
|
||||
.form-control:valid {
|
||||
border-left: 3px solid #10b981;
|
||||
}
|
||||
|
||||
.form-control:invalid:not(:focus):not(:placeholder-shown) {
|
||||
border-left: 3px solid #ef4444;
|
||||
animation: shake 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% { transform: translateX(0); }
|
||||
25% { transform: translateX(-5px); }
|
||||
75% { transform: translateX(5px); }
|
||||
}
|
||||
|
||||
/* Smooth scrolling for better UX */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Performance optimized animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
/* Only animation reduction */
|
||||
@media(prefers-reduced-motion:reduce){
|
||||
*{animation:none!important; transition:none!important;}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
|
||||
|
||||
{{-- Invoice Preview Section --}}
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header bg-light">
|
||||
<h4 class="fw-bold mb-0">
|
||||
<i class="fas fa-file-invoice me-2"></i> Invoice Details
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
@include('admin.popup_invoice', [
|
||||
'invoice' => $invoice,
|
||||
'shipment' => $shipment,
|
||||
'embedded' => true
|
||||
])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------
|
||||
HTML CONTENT (UNCHANGED)
|
||||
-------------------------------------------------- -->
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<h4>Edit Invoice</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form action="{{ route('admin.invoices.update', $invoice->id) }}" method="POST">
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Invoice Date</label>
|
||||
<input type="date" class="form-control" name="invoice_date"
|
||||
value="{{ $invoice->invoice_date }}" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Due Date</label>
|
||||
<input type="date" class="form-control" name="due_date"
|
||||
value="{{ $invoice->due_date }}" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Final Amount (₹)</label>
|
||||
<input type="number" step="0.01" class="form-control" name="final_amount"
|
||||
value="{{ $invoice->final_amount }}" required>
|
||||
</div>
|
||||
|
||||
<!-- ✅ TAX TYPE -->
|
||||
<div class="col-md-4">
|
||||
<label class="form-label d-block">Tax Type</label>
|
||||
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="tax_type" value="gst"
|
||||
@checked($invoice->tax_type === 'gst')>
|
||||
<label class="form-check-label">GST (CGST+SGST)</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="tax_type" value="igst"
|
||||
@checked($invoice->tax_type === 'igst')>
|
||||
<label class="form-check-label">IGST</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ✅ One unified input -->
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Tax Percentage (%)</label>
|
||||
<input type="number" step="0.01" min="0" max="28"
|
||||
class="form-control"
|
||||
name="tax_percent"
|
||||
value="{{ old('tax_percent',
|
||||
$invoice->tax_type == 'gst'
|
||||
? $invoice->cgst_percent + $invoice->sgst_percent
|
||||
: $invoice->igst_percent
|
||||
) }}"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Status</label>
|
||||
<select class="form-select" name="status" required>
|
||||
<option value="pending" @selected($invoice->status=='pending')>Pending</option>
|
||||
<option value="paid" @selected($invoice->status=='paid')>Paid</option>
|
||||
<option value="overdue" @selected($invoice->status=='overdue')>Overdue</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<label class="form-label">Notes</label>
|
||||
<textarea class="form-control" rows="3" name="notes">{{ $invoice->notes }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 text-end mt-3">
|
||||
<button type="submit" class="btn btn-success">Update Invoice</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$totalPaid = $invoice->installments->sum('amount');
|
||||
$remaining = $invoice->final_amount_with_gst - $totalPaid;
|
||||
@endphp
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 class="fw-bold mb-0">Installment Payments</h3>
|
||||
|
||||
@if($remaining > 0)
|
||||
<button id="toggleInstallmentForm" class="btn btn-success">
|
||||
+ Add Installment
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Installment Form -->
|
||||
<div id="installmentForm" class="card shadow-sm d-none mb-4">
|
||||
<div class="card-header">
|
||||
<h4>Add Installment</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form id="installmentSubmitForm">
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Invoice Date</label>
|
||||
<input type="date" class="form-control"
|
||||
name="invoice_date"
|
||||
value="{{ $invoice->invoice_date }}" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Due Date</label>
|
||||
<input type="date" class="form-control"
|
||||
name="due_date"
|
||||
value="{{ $invoice->due_date }}" required>
|
||||
<label class="form-label">Installment Date</label>
|
||||
<input type="date" name="installment_date" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Payment Method</label>
|
||||
<input type="text" class="form-control"
|
||||
name="payment_method"
|
||||
value="{{ $invoice->payment_method }}">
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Reference No</label>
|
||||
<input type="text" class="form-control"
|
||||
name="reference_no"
|
||||
value="{{ $invoice->reference_no }}">
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Final Amount (Editable)</label>
|
||||
<input type="number" step="0.01" class="form-control"
|
||||
name="final_amount"
|
||||
value="{{ $invoice->final_amount }}" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">GST Percentage</label>
|
||||
<input type="number" step="0.01" class="form-control"
|
||||
name="gst_percent"
|
||||
value="{{ $invoice->gst_percent }}" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Status</label>
|
||||
<select class="form-select" name="status" required>
|
||||
<option value="pending" @selected($invoice->status=='pending')>Pending</option>
|
||||
<option value="paid" @selected($invoice->status=='paid')>Paid</option>
|
||||
<option value="overdue" @selected($invoice->status=='overdue')>Overdue</option>
|
||||
<select name="payment_method" class="form-select" required>
|
||||
<option value="cash">Cash</option>
|
||||
<option value="bank">Bank Transfer</option>
|
||||
<option value="upi">UPI</option>
|
||||
<option value="cheque">Cheque</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<label class="form-label">Notes</label>
|
||||
<textarea class="form-control" rows="3" name="notes">
|
||||
{{ $invoice->notes }}
|
||||
</textarea>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Reference No (optional)</label>
|
||||
<input type="text" name="reference_no" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 text-end mt-3">
|
||||
<button type="submit" class="btn btn-success">
|
||||
Update Invoice
|
||||
<div class="col-md-12">
|
||||
<label class="form-label">Amount</label>
|
||||
<input type="number" name="amount" id="installmentAmount" class="form-control"
|
||||
step="0.01" min="1" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 text-end mt-2">
|
||||
<button type="submit" class="btn btn-success" id="installmentSubmitBtn">
|
||||
Submit Installment
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -435,47 +374,229 @@ html {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-body">
|
||||
|
||||
<div class="d-flex justify-content-between fs-5 fw-bold">
|
||||
<span>Total Amount (Before Tax):</span>
|
||||
<span>₹{{ number_format($invoice->final_amount, 2) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between text-primary fs-5 fw-bold">
|
||||
<span>Tax Type:</span>
|
||||
<span>
|
||||
@if($invoice->tax_type === 'gst')
|
||||
GST (CGST + SGST)
|
||||
@else
|
||||
IGST
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between text-primary fs-5 fw-bold">
|
||||
<span>Tax Percentage:</span>
|
||||
<span>
|
||||
@if($invoice->tax_type === 'gst')
|
||||
{{ $invoice->cgst_percent + $invoice->sgst_percent }}%
|
||||
@else
|
||||
{{ $invoice->igst_percent }}%
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between text-warning fs-5 fw-bold">
|
||||
<span>GST Amount:</span>
|
||||
<span>₹{{ number_format($invoice->gst_amount, 2) }}</span>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="d-flex justify-content-between fs-4 fw-bold text-dark">
|
||||
<span>Total Invoice Amount (Including GST):</span>
|
||||
<span>₹{{ number_format($invoice->final_amount_with_gst, 2) }}</span>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="d-flex justify-content-between text-success fs-5 fw-bold">
|
||||
<span>Total Paid:</span>
|
||||
<span id="paidAmount">₹{{ number_format($totalPaid, 2) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between text-danger fs-5 fw-bold">
|
||||
<span>Remaining:</span>
|
||||
<span id="remainingAmount">₹{{ number_format($remaining, 2) }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Installment History -->
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<h4>Installment History</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-hover mb-0" id="installmentTable">
|
||||
<thead style="background:#f1f5f9;">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Date</th>
|
||||
<th>Payment Method</th>
|
||||
<th>Reference No</th>
|
||||
<th>Amount</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($invoice->installments as $i)
|
||||
<tr data-id="{{ $i->id }}">
|
||||
<td>{{ $loop->iteration }}</td>
|
||||
<td>{{ $i->installment_date }}</td>
|
||||
<td>{{ ucfirst($i->payment_method) }}</td>
|
||||
<td>{{ $i->reference_no }}</td>
|
||||
<td class="fw-bold text-success">₹{{ number_format($i->amount, 2) }}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-sm deleteInstallment">
|
||||
❌ Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
// World-Class Interactive Enhancements - No Parallax
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.querySelector('form');
|
||||
const submitBtn = document.querySelector('.btn-success');
|
||||
const inputs = document.querySelectorAll('input, select, textarea');
|
||||
|
||||
// Enhanced form submission
|
||||
form.addEventListener('submit', function(e) {
|
||||
submitBtn.classList.add('loading');
|
||||
submitBtn.innerHTML = 'Updating Invoice...';
|
||||
|
||||
// Add a small delay to show loading state
|
||||
setTimeout(() => {
|
||||
if (!form.checkValidity()) {
|
||||
submitBtn.classList.remove('loading');
|
||||
submitBtn.innerHTML = 'Update Invoice';
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Real-time validation with visual feedback
|
||||
inputs.forEach(input => {
|
||||
input.addEventListener('input', function() {
|
||||
if (this.checkValidity()) {
|
||||
this.style.borderLeftColor = '#10b981';
|
||||
} else {
|
||||
this.style.borderLeftColor = '#ef4444';
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
// ✅ Toggle Installment Form
|
||||
const toggleBtn = document.getElementById("toggleInstallmentForm");
|
||||
const formBox = document.getElementById("installmentForm");
|
||||
|
||||
if (toggleBtn) {
|
||||
toggleBtn.addEventListener("click", () => formBox.classList.toggle("d-none"));
|
||||
}
|
||||
|
||||
// ✅ Add Installment
|
||||
const submitForm = document.getElementById("installmentSubmitForm");
|
||||
const submitBtn = document.getElementById("installmentSubmitBtn");
|
||||
|
||||
const formatINR = amt =>
|
||||
"₹" + Number(amt).toLocaleString("en-IN", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
});
|
||||
|
||||
// Add focus effects
|
||||
input.addEventListener('focus', function() {
|
||||
this.parentElement.style.transform = 'translateY(-2px)';
|
||||
});
|
||||
|
||||
input.addEventListener('blur', function() {
|
||||
this.parentElement.style.transform = 'translateY(0)';
|
||||
|
||||
submitForm.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
submitBtn.textContent = "Processing...";
|
||||
submitBtn.disabled = true;
|
||||
|
||||
fetch("{{ route('admin.invoice.installment.store', $invoice->id) }}", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": submitForm.querySelector("input[name=_token]").value,
|
||||
"Accept": "application/json"
|
||||
},
|
||||
body: new FormData(submitForm)
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
submitBtn.textContent = "Submit Installment";
|
||||
submitBtn.disabled = false;
|
||||
|
||||
if (data.status === "error") {
|
||||
alert(data.message);
|
||||
return;
|
||||
}
|
||||
|
||||
const table = document.querySelector("#installmentTable tbody");
|
||||
const index = table.rows.length + 1;
|
||||
|
||||
table.insertAdjacentHTML("beforeend", `
|
||||
<tr data-id="${data.installment.id}">
|
||||
<td>${index}</td>
|
||||
<td>${data.installment.installment_date}</td>
|
||||
<td>${data.installment.payment_method.toUpperCase()}</td>
|
||||
<td>${data.installment.reference_no ?? ""}</td>
|
||||
<td class="fw-bold text-success">${formatINR(data.installment.amount)}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-sm deleteInstallment">❌ Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
`);
|
||||
|
||||
// ✅ Update totals (Gst included)
|
||||
document.getElementById("paidAmount").textContent = formatINR(data.totalPaid);
|
||||
document.getElementById("remainingAmount").textContent = formatINR(data.remaining);
|
||||
|
||||
submitForm.reset();
|
||||
|
||||
// ✅ If fully paid — hide Add Installment button & form
|
||||
if (data.isCompleted) {
|
||||
toggleBtn?.remove();
|
||||
formBox.classList.add("d-none");
|
||||
}
|
||||
|
||||
alert(data.message);
|
||||
})
|
||||
.catch(() => {
|
||||
submitBtn.textContent = "Submit Installment";
|
||||
submitBtn.disabled = false;
|
||||
alert("Something went wrong");
|
||||
});
|
||||
});
|
||||
|
||||
// ✅ Delete Installment (event delegation)
|
||||
document.addEventListener("click", function (e) {
|
||||
if (!e.target.classList.contains("deleteInstallment")) return;
|
||||
|
||||
if (!confirm("Are you sure you want to delete this installment?")) return;
|
||||
|
||||
const row = e.target.closest("tr");
|
||||
const id = row.getAttribute("data-id");
|
||||
|
||||
fetch("{{ url('/admin/installment') }}/" + id, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": "{{ csrf_token() }}",
|
||||
"Accept": "application/json"
|
||||
}
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.status === "success") {
|
||||
row.remove();
|
||||
|
||||
document.getElementById("paidAmount").textContent = formatINR(data.totalPaid);
|
||||
document.getElementById("remainingAmount").textContent = formatINR(data.remaining);
|
||||
|
||||
// ✅ If remaining exists but Add Installment button disappeared → reload UI
|
||||
if (data.remaining > 0 && !toggleBtn) {
|
||||
location.reload();
|
||||
}
|
||||
|
||||
// ✅ Remove entire card if no installments left
|
||||
if (data.isZero) {
|
||||
document.getElementById("installmentTable").closest(".card").remove();
|
||||
}
|
||||
|
||||
alert(data.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
|
||||
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
padding: 18px 16px 0 16px;
|
||||
padding: 18px 16px 16px 16px;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -1,207 +1,280 @@
|
||||
<div class="p-4">
|
||||
<!-- Invoice Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<h2 class="fw-bold text-primary mb-1">
|
||||
<i class="fas fa-file-invoice me-2"></i>INVOICE
|
||||
</h2>
|
||||
<h4 class="fw-bold text-dark mb-0">{{ $invoice->invoice_number }}</h4>
|
||||
</div>
|
||||
<div class="col-md-6 text-end">
|
||||
<div class="d-inline-block bg-light rounded-3 p-3">
|
||||
<span class="badge
|
||||
@if($invoice->status=='paid') bg-success
|
||||
@elseif($invoice->status=='overdue') bg-danger
|
||||
@elseif($invoice->status=='pending') bg-warning text-dark
|
||||
@else bg-secondary @endif
|
||||
fs-6 px-3 py-2">
|
||||
<i class="fas
|
||||
@if($invoice->status=='paid') fa-check-circle
|
||||
@elseif($invoice->status=='overdue') fa-exclamation-circle
|
||||
@elseif($invoice->status=='pending') fa-clock
|
||||
@else fa-question-circle @endif me-1"></i>
|
||||
{{ ucfirst($invoice->status) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- INVOICE CONTENT (NO POPUP WRAPPERS HERE) --}}
|
||||
|
||||
<!-- Dates - Compact Professional Layout -->
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body py-2">
|
||||
<div class="row align-items-center text-center">
|
||||
<div class="col-md-5">
|
||||
<div class="mb-0">
|
||||
<div class="text-muted fw-semibold small">INVOICE DATE</div>
|
||||
</div>
|
||||
<div class="fw-bold text-dark" style="font-size: 0.95rem;">
|
||||
{{ \Carbon\Carbon::parse($invoice->invoice_date)->format('M d, Y') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="date-connector">
|
||||
<i class="fas fa-arrow-right text-muted small"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div class="mb-0">
|
||||
<div class="text-muted fw-semibold small">DUE DATE</div>
|
||||
</div>
|
||||
<div class="fw-bold @if($invoice->status == 'overdue') text-danger @else text-dark @endif" style="font-size: 0.95rem;">
|
||||
{{ \Carbon\Carbon::parse($invoice->due_date)->format('M d, Y') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ============================
|
||||
INVOICE HEADER
|
||||
============================ -->
|
||||
<div class="mb-4">
|
||||
|
||||
<!-- Customer Details -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-light py-2">
|
||||
<h6 class="mb-0 fw-bold text-dark">
|
||||
<i class="fas fa-user me-2"></i>Customer Details
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6 class="fw-bold text-primary mb-1">{{ $invoice->customer_name }}</h6>
|
||||
@if($invoice->company_name)
|
||||
<p class="mb-1">
|
||||
<strong>Company:</strong> {{ $invoice->company_name }}
|
||||
</p>
|
||||
@endif
|
||||
<p class="mb-1">
|
||||
<strong>Mobile:</strong> {{ $invoice->customer_mobile }}
|
||||
</p>
|
||||
<p class="mb-1">
|
||||
<strong>Email:</strong> {{ $invoice->customer_email }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p class="mb-0">
|
||||
<strong>Address:</strong><br>
|
||||
{{ $invoice->customer_address }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Invoice Items -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-light py-2">
|
||||
<h6 class="mb-0 fw-bold text-dark">
|
||||
<i class="fas fa-list me-2"></i>Invoice Items
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th class="text-center">#</th>
|
||||
<th>Description</th>
|
||||
<th class="text-center">CTN</th>
|
||||
<th class="text-center">QTY</th>
|
||||
<th class="text-center">TTL/QTY</th>
|
||||
<th class="text-center">Unit</th>
|
||||
<th class="text-center">Price</th>
|
||||
<th class="text-center">TTL Amount</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-center">Shop No</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($invoice->items as $i => $item)
|
||||
<tr>
|
||||
<td class="text-center fw-bold text-muted">{{ $i+1 }}</td>
|
||||
<td class="fw-semibold">{{ $item->description }}</td>
|
||||
<td class="text-center">{{ $item->ctn }}</td>
|
||||
<td class="text-center">{{ $item->qty }}</td>
|
||||
<td class="text-center fw-bold">{{ $item->ttl_qty }}</td>
|
||||
<td class="text-center">{{ $item->unit }}</td>
|
||||
<td class="text-center text-success fw-bold">₹{{ number_format($item->price,2) }}</td>
|
||||
<td class="text-center text-primary fw-bold">₹{{ number_format($item->ttl_amount,2) }}</td>
|
||||
<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 bg-light text-dark border">{{ $item->shop_no }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Final Summary -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-6">
|
||||
<div class="card border-0 bg-light">
|
||||
<div class="card-header bg-dark text-white py-2">
|
||||
<h6 class="mb-0 fw-bold">
|
||||
<i class="fas fa-calculator me-2"></i>Final Summary
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2 pb-1 border-bottom">
|
||||
<span class="fw-semibold">Amount:</span>
|
||||
<span class="fw-bold text-dark">₹{{ number_format($invoice->final_amount,2) }}</span>
|
||||
<div class="col-md-6">
|
||||
|
||||
<h2 class="fw-bold text-primary mb-1">
|
||||
<i class="fas fa-file-invoice me-2"></i> INVOICE
|
||||
</h2>
|
||||
|
||||
<h4 class="fw-bold text-dark mb-0">{{ $invoice->invoice_number }}</h4>
|
||||
|
||||
{{-- ORDER + SHIPMENT INFO --}}
|
||||
<div class="mt-2 small">
|
||||
|
||||
{{-- ORDER ID --}}
|
||||
@if($invoice->order_id)
|
||||
<div>
|
||||
<strong>Order ID:</strong>
|
||||
{{ $invoice->order->order_id ?? $invoice->order_id }}
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-2 pb-1 border-bottom">
|
||||
<span class="fw-semibold">GST ({{ $invoice->gst_percent }}%):</span>
|
||||
<span class="fw-bold text-danger">₹{{ number_format($invoice->gst_amount,2) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center pt-1">
|
||||
<span class="fw-bold text-dark">Total With GST:</span>
|
||||
<span class="fw-bold text-success">₹{{ number_format($invoice->final_amount_with_gst,2) }}</span>
|
||||
@endif
|
||||
|
||||
{{-- SHIPMENT ID --}}
|
||||
@if(isset($shipment) && $shipment)
|
||||
<div>
|
||||
<strong>Shipment ID:</strong> {{ $shipment->shipment_id }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 text-end">
|
||||
|
||||
<span class="badge fs-6 px-3 py-2
|
||||
@if($invoice->status=='paid') bg-success
|
||||
@elseif($invoice->status=='overdue') bg-danger
|
||||
@elseif($invoice->status=='pending') bg-warning text-dark
|
||||
@else bg-secondary @endif">
|
||||
|
||||
<i class="fas
|
||||
@if($invoice->status=='paid') fa-check-circle
|
||||
@elseif($invoice->status=='overdue') fa-exclamation-circle
|
||||
@elseif($invoice->status=='pending') fa-clock
|
||||
@else fa-question-circle @endif me-1"></i>
|
||||
|
||||
{{ ucfirst($invoice->status) }}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================
|
||||
DATES SECTION
|
||||
============================ -->
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
<div class="card-body py-3">
|
||||
|
||||
<div class="row text-center align-items-center">
|
||||
|
||||
<div class="col-md-5">
|
||||
<small class="text-muted fw-semibold">INVOICE DATE</small>
|
||||
<div class="fw-bold text-dark">
|
||||
{{ \Carbon\Carbon::parse($invoice->invoice_date)->format('M d, Y') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2">
|
||||
<i class="fas fa-arrow-right text-muted"></i>
|
||||
</div>
|
||||
|
||||
<div class="col-md-5">
|
||||
<small class="text-muted fw-semibold">DUE DATE</small>
|
||||
<div class="fw-bold {{ $invoice->status=='overdue' ? 'text-danger' : 'text-dark' }}">
|
||||
{{ \Carbon\Carbon::parse($invoice->due_date)->format('M d, Y') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.date-connector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: #6c757d;
|
||||
|
||||
<!-- ============================
|
||||
CUSTOMER DETAILS
|
||||
============================ -->
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
|
||||
<div class="card-header bg-light py-2">
|
||||
<h6 class="fw-bold mb-0"><i class="fas fa-user me-2"></i> Customer Details</h6>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6">
|
||||
<h6 class="fw-bold text-primary">{{ $invoice->customer_name }}</h6>
|
||||
|
||||
@if($invoice->company_name)
|
||||
<p class="mb-1"><strong>Company:</strong> {{ $invoice->company_name }}</p>
|
||||
@endif
|
||||
|
||||
<p class="mb-1"><strong>Mobile:</strong> {{ $invoice->customer_mobile }}</p>
|
||||
<p class="mb-1"><strong>Email:</strong> {{ $invoice->customer_email }}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p class="mb-1"><strong>Address:</strong><br>{{ $invoice->customer_address }}</p>
|
||||
<p class="mb-1"><strong>Pincode:</strong> {{ $invoice->pincode }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================
|
||||
INVOICE ITEMS
|
||||
============================ -->
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
|
||||
<div class="card-header bg-light py-2">
|
||||
<h6 class="fw-bold mb-0"><i class="fas fa-list me-2"></i> Invoice Items</h6>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
<table class="table table-bordered table-hover align-middle mb-0">
|
||||
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Description</th>
|
||||
<th>CTN</th>
|
||||
<th>QTY</th>
|
||||
<th>TTL/QTY</th>
|
||||
<th>Unit</th>
|
||||
<th>Price</th>
|
||||
<th>TTL Amount</th>
|
||||
<th>CBM</th>
|
||||
<th>TTL CBM</th>
|
||||
<th>KG</th>
|
||||
<th>TTL KG</th>
|
||||
<th>Shop No</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach($invoice->items as $i => $item)
|
||||
<tr>
|
||||
<td class="text-center fw-bold">{{ $i + 1 }}</td>
|
||||
<td>{{ $item->description }}</td>
|
||||
<td class="text-center">{{ $item->ctn }}</td>
|
||||
<td class="text-center">{{ $item->qty }}</td>
|
||||
<td class="text-center">{{ $item->ttl_qty }}</td>
|
||||
<td class="text-center">{{ $item->unit }}</td>
|
||||
<td class="text-center">₹{{ number_format($item->price,2) }}</td>
|
||||
<td class="text-center fw-bold text-primary">₹{{ number_format($item->ttl_amount,2) }}</td>
|
||||
<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">{{ $item->shop_no }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================
|
||||
FINAL SUMMARY
|
||||
============================ -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-6">
|
||||
|
||||
<div class="card border-0 bg-light">
|
||||
|
||||
<div class="card-header bg-dark text-white py-2">
|
||||
<h6 class="fw-bold mb-0"><i class="fas fa-calculator me-2"></i> Final Summary</h6>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="d-flex justify-content-between mb-2 border-bottom pb-1">
|
||||
<span class="fw-semibold">Amount:</span>
|
||||
<span class="fw-bold">₹{{ number_format($invoice->final_amount, 2) }}</span>
|
||||
</div>
|
||||
|
||||
@if($invoice->tax_type === 'gst')
|
||||
{{-- CGST --}}
|
||||
<div class="d-flex justify-content-between mb-2 border-bottom pb-1">
|
||||
<span class="fw-semibold">CGST ({{ $invoice->cgst_percent }}%):</span>
|
||||
<span class="fw-bold text-danger">₹{{ number_format($invoice->gst_amount/2, 2) }}</span>
|
||||
</div>
|
||||
|
||||
{{-- SGST --}}
|
||||
<div class="d-flex justify-content-between mb-2 border-bottom pb-1">
|
||||
<span class="fw-semibold">SGST ({{ $invoice->sgst_percent }}%):</span>
|
||||
<span class="fw-bold text-danger">₹{{ number_format($invoice->gst_amount/2, 2) }}</span>
|
||||
</div>
|
||||
|
||||
@elseif($invoice->tax_type === 'igst')
|
||||
{{-- IGST --}}
|
||||
<div class="d-flex justify-content-between mb-2 border-bottom pb-1">
|
||||
<span class="fw-semibold">IGST ({{ $invoice->igst_percent }}%):</span>
|
||||
<span class="fw-bold text-danger">₹{{ number_format($invoice->gst_amount, 2) }}</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="d-flex justify-content-between pt-1">
|
||||
<span class="fw-bold text-dark">Total Payable:</span>
|
||||
<span class="fw-bold text-success">₹{{ number_format($invoice->final_amount_with_gst, 2) }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================
|
||||
FOOTER — DOWNLOAD & SHARE
|
||||
============================ -->
|
||||
<div class="modal-footer">
|
||||
|
||||
@if($invoice->pdf_path)
|
||||
<a href="{{ asset($invoice->pdf_path) }}" class="btn btn-primary" download>
|
||||
<i class="bi bi-download me-1"></i> Download PDF
|
||||
</a>
|
||||
|
||||
<button class="btn btn-success" onclick="shareInvoice()">
|
||||
<i class="bi bi-share me-1"></i> Share
|
||||
</button>
|
||||
@endif
|
||||
|
||||
<!-- <button class="btn btn-secondary" data-bs-dismiss="modal">Close</button> -->
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================
|
||||
SHARE SCRIPT
|
||||
============================ -->
|
||||
<script>
|
||||
function shareInvoice() {
|
||||
const shareData = {
|
||||
title: "Invoice {{ $invoice->invoice_number }}",
|
||||
text: "Sharing invoice {{ $invoice->invoice_number }}",
|
||||
url: "{{ asset($invoice->pdf_path) }}"
|
||||
};
|
||||
|
||||
if (navigator.share) {
|
||||
navigator.share(shareData).catch(() => {});
|
||||
} else {
|
||||
navigator.clipboard.writeText(shareData.url);
|
||||
alert("Link copied! Sharing not supported on this browser.");
|
||||
}
|
||||
}
|
||||
.date-connector i {
|
||||
background: #f8f9fa;
|
||||
padding: 4px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
.card {
|
||||
border-radius: 6px;
|
||||
}
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.table > :not(caption) > * > * {
|
||||
padding: 10px 6px;
|
||||
}
|
||||
</style>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user