changes of invoice and shipment
This commit is contained in:
@@ -26,13 +26,11 @@ class AdminInvoiceController extends Controller
|
||||
// -------------------------------------------------------------
|
||||
public function popup($id)
|
||||
{
|
||||
$invoice = Invoice::with(['items', 'order'])->findOrFail($id);
|
||||
$invoice = Invoice::with(['items', 'order', 'installments'])->findOrFail($id);
|
||||
|
||||
// Find actual Shipment record
|
||||
$shipment = \App\Models\Shipment::whereHas('items', function ($q) use ($invoice) {
|
||||
$q->where('order_id', $invoice->order_id);
|
||||
})
|
||||
->first();
|
||||
})->first();
|
||||
|
||||
return view('admin.popup_invoice', compact('invoice', 'shipment'));
|
||||
}
|
||||
@@ -145,6 +143,22 @@ class AdminInvoiceController extends Controller
|
||||
$invoice->update(['pdf_path' => 'invoices/' . $fileName]);
|
||||
}
|
||||
|
||||
public function downloadInvoice($id)
|
||||
{
|
||||
$invoice = Invoice::findOrFail($id);
|
||||
|
||||
// Generate PDF if missing
|
||||
if (
|
||||
!$invoice->pdf_path ||
|
||||
!file_exists(public_path($invoice->pdf_path))
|
||||
) {
|
||||
$this->generateInvoicePDF($invoice);
|
||||
$invoice->refresh();
|
||||
}
|
||||
|
||||
return response()->download(public_path($invoice->pdf_path));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// INSTALLMENTS (ADD/DELETE)
|
||||
// -------------------------------------------------------------
|
||||
|
||||
Binary file not shown.
BIN
public/invoices/invoice-INV-2025-000031.pdf
Normal file
BIN
public/invoices/invoice-INV-2025-000031.pdf
Normal file
Binary file not shown.
@@ -550,46 +550,71 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============================
|
||||
SIMPLIFIED INVOICE SUMMARY
|
||||
============================ -->
|
||||
@php
|
||||
$totalAmount = $invoice->final_amount;
|
||||
$gstAmount = $invoice->gst_amount;
|
||||
$totalPayable = $invoice->final_amount_with_gst;
|
||||
|
||||
$paidAmount = $invoice->totalPaid();
|
||||
$remaining = $invoice->remainingAmount();
|
||||
@endphp
|
||||
|
||||
<div class="summary-container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<!-- Subtotal -->
|
||||
<div class="amount-row mb-2">
|
||||
<span>Subtotal Amount</span>
|
||||
<span class="fw-bold">₹{{ number_format($invoice->final_amount,2) }}</span>
|
||||
|
||||
<div class="amount-row">
|
||||
<span>Total Amount</span>
|
||||
<span class="fw-bold">₹{{ number_format($totalAmount,2) }}</span>
|
||||
</div>
|
||||
|
||||
<!-- GST -->
|
||||
<div class="amount-row mb-2">
|
||||
<div class="amount-row">
|
||||
<span>GST Amount</span>
|
||||
<span class="fw-bold text-danger">₹{{ number_format($invoice->gst_amount, 2) }}</span>
|
||||
<span class="fw-bold text-danger">
|
||||
+ ₹{{ number_format($gstAmount,2) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="amount-row border-top pt-2">
|
||||
<span class="fw-bold">Total Payable</span>
|
||||
<span class="fw-bold text-success">
|
||||
₹{{ number_format($totalPayable,2) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="amount-row">
|
||||
<span>Paid Amount</span>
|
||||
<span class="fw-bold text-primary">
|
||||
− ₹{{ number_format($paidAmount,2) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="amount-row border-top pt-2">
|
||||
<span class="fw-bold text-danger">Remaining Amount</span>
|
||||
<span class="fw-bold text-danger fs-5">
|
||||
₹{{ number_format($remaining,2) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Total Payable -->
|
||||
<div class="amount-row mb-2 pt-2 border-top">
|
||||
<span class="fw-bold">Total Payable Amount</span>
|
||||
<span class="fw-bold text-success fs-5">₹{{ number_format($invoice->final_amount_with_gst,2) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================
|
||||
FOOTER — DOWNLOAD & SHARE
|
||||
============================ -->
|
||||
<div class="mt-4 pt-3 border-top text-center">
|
||||
@if($invoice->pdf_path)
|
||||
<a href="{{ asset($invoice->pdf_path) }}" class="btn btn-primary me-2" download>
|
||||
|
||||
<a href="{{ route('admin.invoices.download', $invoice->id) }}"
|
||||
class="btn btn-primary me-2">
|
||||
<i class="fas fa-download me-1"></i> Download PDF
|
||||
</a>
|
||||
|
||||
<button class="btn btn-success" onclick="shareInvoice()">
|
||||
<i class="fas fa-share me-1"></i> Share
|
||||
</button>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -604,7 +629,7 @@
|
||||
const shareData = {
|
||||
title: "Invoice {{ $invoice->invoice_number }}",
|
||||
text: "Sharing invoice {{ $invoice->invoice_number }}",
|
||||
url: "{{ asset($invoice->pdf_path) }}"
|
||||
url: "{{ route('admin.invoices.download', $invoice->id) }}"
|
||||
};
|
||||
|
||||
if (navigator.share) {
|
||||
@@ -615,5 +640,6 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -741,6 +741,13 @@
|
||||
margin: 1vh auto !important;
|
||||
}
|
||||
|
||||
/* UPDATED: Shipment Order Details Modal - ALSO EDGE-TO-EDGE */
|
||||
.modal-xl.edge-to-edge.order-details-modal {
|
||||
max-width: 95vw !important;
|
||||
width: 95vw !important;
|
||||
margin: 1vh auto !important;
|
||||
}
|
||||
|
||||
.shipment-details-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
@@ -1135,6 +1142,12 @@
|
||||
margin: 2vh auto !important;
|
||||
}
|
||||
|
||||
.modal-xl.edge-to-edge.order-details-modal {
|
||||
max-width: 96vw !important;
|
||||
width: 96vw !important;
|
||||
margin: 2vh auto !important;
|
||||
}
|
||||
|
||||
.shipment-totals-row {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 15px;
|
||||
@@ -1148,6 +1161,12 @@
|
||||
margin: 2.5vh auto !important;
|
||||
}
|
||||
|
||||
.modal-xl.edge-to-edge.order-details-modal {
|
||||
max-width: 95vw !important;
|
||||
width: 95vw !important;
|
||||
margin: 2.5vh auto !important;
|
||||
}
|
||||
|
||||
.shipment-details-body {
|
||||
padding: 20px 25px;
|
||||
}
|
||||
@@ -1176,6 +1195,14 @@
|
||||
max-height: 100vh !important;
|
||||
}
|
||||
|
||||
.modal-xl.edge-to-edge.order-details-modal {
|
||||
max-width: 100vw !important;
|
||||
width: 100vw !important;
|
||||
margin: 0 !important;
|
||||
height: 100vh !important;
|
||||
max-height: 100vh !important;
|
||||
}
|
||||
|
||||
.shipment-details-body {
|
||||
padding: 15px 20px;
|
||||
}
|
||||
@@ -1210,6 +1237,15 @@
|
||||
.shipment-total-value {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Order details modal specific responsive styles */
|
||||
.order-details-content {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.order-details-table {
|
||||
min-width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
@@ -1224,10 +1260,42 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal-xl.edge-to-edge.order-details-modal .modal-content {
|
||||
border-radius: 0;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.shipment-details-header {
|
||||
padding: 20px 25px 15px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.order-details-header {
|
||||
padding: 20px 15px 10px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.order-details-body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.modal-xl.edge-to-edge,
|
||||
.modal-xl.edge-to-edge.order-details-modal {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.shipment-details-body,
|
||||
.order-details-body {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1849,7 +1917,11 @@ function openShipmentDetails(id) {
|
||||
html += `
|
||||
<tr>
|
||||
<td class="fw-bold">
|
||||
<a href="javascript:void(0)"
|
||||
class="text-primary fw-bold"
|
||||
onclick="openShipmentOrderDetails(${order.id})">
|
||||
${order.order_id}
|
||||
</a>
|
||||
</td>
|
||||
<td>${order.origin || 'N/A'}</td>
|
||||
<td>${order.destination || 'N/A'}</td>
|
||||
@@ -1962,6 +2034,46 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
function openShipmentOrderDetails(orderId) {
|
||||
const modal = new bootstrap.Modal(
|
||||
document.getElementById('shipmentOrderDetailsModal')
|
||||
);
|
||||
|
||||
const body = document.getElementById('shipmentOrderDetailsBody');
|
||||
body.innerHTML = "<p class='text-center text-muted'>Loading...</p>";
|
||||
|
||||
modal.show();
|
||||
|
||||
fetch(`/admin/orders/view/${orderId}`)
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
body.innerHTML = html;
|
||||
})
|
||||
.catch(() => {
|
||||
body.innerHTML =
|
||||
"<p class='text-danger text-center'>Failed to load order details.</p>";
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- SHIPMENT ORDER DETAILS MODAL - UPDATED TO EDGE-TO-EDGE -->
|
||||
<div class="modal fade" id="shipmentOrderDetailsModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-xl edge-to-edge order-details-modal modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header shipment-details-header order-details-header">
|
||||
<h5 class="modal-title fw-bold"><i class="bi bi-file-text me-2"></i>Order Details</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body shipment-details-body order-details-body" id="shipmentOrderDetailsBody">
|
||||
<p class="text-center text-muted">Loading order details...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -219,6 +219,10 @@ Route::prefix('admin')
|
||||
Route::post('/invoices/{id}/installment', [AdminInvoiceController::class, 'storeInstallment'])
|
||||
->name('admin.invoice.installment.store');
|
||||
|
||||
Route::get(
|
||||
'/admin/invoices/{id}/download',
|
||||
[AdminInvoiceController::class, 'downloadInvoice']
|
||||
)->name('admin.invoices.download');
|
||||
|
||||
|
||||
Route::delete('/installment/{id}', [AdminInvoiceController::class, 'deleteInstallment'])
|
||||
|
||||
Reference in New Issue
Block a user