ajax update

This commit is contained in:
Abhishek Mali
2026-03-12 11:48:42 +05:30
parent ff4c006ca4
commit 43b1a64911
4 changed files with 100 additions and 219 deletions

View File

@@ -429,8 +429,10 @@ class AdminInvoiceController extends Controller
'grand_total_with_charges'=> $invoice->grand_total_with_charges, 'grand_total_with_charges'=> $invoice->grand_total_with_charges,
]); ]);
return redirect() return response()->json([
->back() 'success' => true,
->with('success', 'Charge group saved successfully.'); 'message' => 'Charge group saved successfully.',
'group_id' => $group->id,
]);
} }
} }

View File

@@ -0,0 +1,23 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddChargeColumnsToInvoicesTable extends Migration
{
public function up()
{
Schema::table('invoices', function (Blueprint $table) {
$table->decimal('charge_groups_total', 15, 2)->nullable()->after('final_amount_with_gst');
$table->decimal('grand_total_with_charges', 15, 2)->nullable()->after('charge_groups_total');
});
}
public function down()
{
Schema::table('invoices', function (Blueprint $table) {
$table->dropColumn(['charge_groups_total', 'grand_total_with_charges']);
});
}
}

Binary file not shown.

View File

@@ -476,47 +476,6 @@
gap: 0.5rem; gap: 0.5rem;
} }
/* ── SUMMARY ── */
/* .summary-wrap {
padding: 0 2.5rem 2rem;
}
.summary-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
box-shadow: var(--shadow);
}
.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;
}
.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;
}
.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; } */
.summary-card-compact { .summary-card-compact {
margin: 1.5rem 2.5rem 1.5rem; margin: 1.5rem 2.5rem 1.5rem;
border: 1px solid var(--border); border: 1px solid var(--border);
@@ -724,105 +683,6 @@
</div> </div>
</div> </div>
<!-- ═══════════════════════════ ID BOXES ═══════════════════════════ -->
<!-- <div class="id-grid">
<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 ═══════════════════════════ -->
<!-- ═══════════════════════════ ID + DATES (ONE ROW) ═══════════════════════════ -->
<!-- <div class="date-strip">
<div class="date-row">
{{-- Container ID --}}
<div class="date-card" style="flex: 1.2;">
<div class="date-icon-wrap" style="background:#ecfeff;color:#0e7490;">
<i class="fas fa-box"></i>
</div>
<div>
<div class="date-label">Container ID</div>
<div class="date-value">
@if($invoice->container && $invoice->container->container_number)
{{ $invoice->container->container_number }}
@elseif($invoice->container_id)
{{ $invoice->container_id }}
@else
N/A
@endif
</div>
</div>
</div>
{{-- छोटा arrow --}}
<div class="date-arrow">
<i class="fas fa-arrow-right"></i>
</div>
{{-- Invoice Date --}}
<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>
{{-- दुसरा arrow --}}
<div class="date-arrow">
<i class="fas fa-arrow-right"></i>
</div>
{{-- Due Date --}}
<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') }}
</div>
</div>
</div>
</div>
</div>
-->
<!-- ═══════════════════════════ CONTAINER + INVOICE DATE + DUE DATE (ONE ROW) ═══════════════════════════ --> <!-- ═══════════════════════════ CONTAINER + INVOICE DATE + DUE DATE (ONE ROW) ═══════════════════════════ -->
<div class="date-strip"> <div class="date-strip">
<div class="date-row"> <div class="date-row">
@@ -920,12 +780,6 @@
<i class="fas fa-list"></i> Invoice Items <i class="fas fa-list"></i> Invoice Items
</div> </div>
<!-- @if($isEmbedded)
<form action="{{ route('admin.invoices.items.update', $invoice->id) }}" method="POST">
@csrf
@method('PUT')
@endif -->
<div class="table-responsive"> <div class="table-responsive">
<table class="invoice-table items-table"> <table class="invoice-table items-table">
<thead> <thead>
@@ -1180,10 +1034,10 @@
<th>Basis</th> <th>Basis</th>
<th class="text-end">Basis Value</th> <th class="text-end">Basis Value</th>
<th class="text-end">Rate</th> <th class="text-end">Rate</th>
<th class="text-end">GST %</th>
<th class="text-end">Total Charge</th> <th class="text-end">Total Charge</th>
<th class="text-end">Total With GST</th> <th class="text-end">GST %</th>
<th class="text-center">Tax Type</th> <th class="text-center">Tax Type</th>
<th class="text-end">Total With GST</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
</thead> </thead>
@@ -1224,27 +1078,29 @@
{{ number_format($group->rate, 2) }} {{ number_format($group->rate, 2) }}
</td> </td>
{{-- Base total without GST --}}
<td class="text-end price-blue">
{{ number_format($groupBaseTotal, 2) }}
</td>
{{-- GST % --}} {{-- GST % --}}
<td class="text-end" <td class="text-end"
style="font-family:'JetBrains Mono',monospace;font-size:0.82rem;"> style="font-family:'JetBrains Mono',monospace;font-size:0.82rem;">
{{ number_format($groupGstPercent, 2) }}% {{ number_format($groupGstPercent, 2) }}%
</td> </td>
{{-- Base total without GST --}} {{-- Group tax type --}}
<td class="text-end price-blue"> <td class="text-center">
{{ number_format($groupBaseTotal, 2) }} {{ $group->tax_type ?? '-' }}
</td> </td>
{{-- Group total with GST --}} {{-- Group total with GST --}}
<td class="text-end" style="font-weight:700;color:#16a34a;"> <td class="text-end" style="font-weight:700;color:#16a34a;">
{{ number_format($groupTotalWithGst, 2) }} {{ number_format($groupTotalWithGst, 2) }}
</td> </td>
{{-- Group tax type --}}
<td class="text-center">
{{ $group->tax_type ?? '-' }}
</td>
<td class="text-center"> <td class="text-center">
<button type="button" <button type="button"
class="cg-toggle-btn cg-toggle-items" class="cg-toggle-btn cg-toggle-items"
@@ -1376,51 +1232,6 @@
</div> </div>
@endif @endif
<!-- ═══════════════════════════ 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>
@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
<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>
</div>
</div>
</div> -->
{{-- ===== FINAL SUMMARY (POPUP) ===== --}} {{-- ===== FINAL SUMMARY (POPUP) ===== --}}
<div class="summary-card-compact mt-3"> <div class="summary-card-compact mt-3">
<div class="summary-header-compact"> <div class="summary-header-compact">
@@ -1745,8 +1556,12 @@ document.addEventListener('DOMContentLoaded', function () {
// normal form submit, फक्त hidden item_ids तयार करतो // normal form submit, फक्त hidden item_ids तयार करतो
if (cgForm) { if (cgForm) {
cgForm.addEventListener('submit', function () { cgForm.addEventListener('submit', function (e) {
e.preventDefault(); // 🚀 STOP PAGE REFRESH
const selectedIds = []; const selectedIds = [];
itemCheckboxes.forEach(cb => { itemCheckboxes.forEach(cb => {
if (cb.checked && !cb.disabled) { if (cb.checked && !cb.disabled) {
selectedIds.push(cb.value); selectedIds.push(cb.value);
@@ -1755,37 +1570,78 @@ document.addEventListener('DOMContentLoaded', function () {
if (selectedIds.length === 0) { if (selectedIds.length === 0) {
alert('Please select at least one item for this charge group.'); alert('Please select at least one item for this charge group.');
return false; return;
} }
if (!cgBasisSelect || !cgBasisSelect.value) { if (!cgBasisSelect || !cgBasisSelect.value) {
alert('Please select a basis for this charge group.'); alert('Please select a basis for this charge group.');
return false; return;
} }
if (!cgTotalChargeInput || if (!cgTotalChargeInput ||
!cgTotalChargeInput.value || !cgTotalChargeInput.value ||
parseFloat(cgTotalChargeInput.value) <= 0 parseFloat(cgTotalChargeInput.value) <= 0) {
) {
alert('Please enter total charges for this group.'); alert('Please enter total charges for this group.');
return false; return;
} }
// submit आधी latest GST total कॅलक्युलेट करणे सुरक्षित
refreshChargeGroupGst(); refreshChargeGroupGst();
const oldHidden = cgForm.querySelectorAll('input[name="itemids[]"]'); const formData = new FormData(cgForm);
oldHidden.forEach(el => el.remove());
selectedIds.forEach(id => { selectedIds.forEach(id => {
const input = document.createElement('input'); formData.append('itemids[]', id);
input.type = 'hidden'; });
input.name = 'itemids[]';
input.value = id; fetch(cgForm.action, {
cgForm.appendChild(input); method: "POST",
headers: {
"X-CSRF-TOKEN": document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content")
},
body: formData
})
.then(async res => {
const data = await res.json();
if (!res.ok) {
// Laravel validation errors
if (data.errors) {
let msg = "";
Object.values(data.errors).forEach(errArr => {
msg += errArr.join("\n") + "\n";
});
throw new Error(msg);
}
throw new Error(data.message || "Something went wrong");
}
return data;
})
.then(data => {
if (data.success) {
alert("Charge group created successfully!");
location.reload();
}
})
.catch(err => {
alert("Check Group details again");
}); });
return true; // normal submit
}); });
} }