Refactor Invoice Validation Logic and Update UI for Serial and Material Invoices

- Improved conditional checks for invoice processing in InvoiceValidationResource on completion (or pending).
- Enhanced notifications for completed scanning processes for both serial and material invoices.
- Updated CreateInvoiceValidation page to pass invoice type to serial and material invoice on completion (or pending).
- Modified InvoiceDataTable to include a new property for serial/material invoice handling.
- Adjusted Blade view to dynamically display the correct title and messages based on invoice type (serial/material).
This commit is contained in:
dhanabalan
2025-08-05 12:00:26 +05:30
parent d6c77bd6c3
commit 197184e2ed
4 changed files with 255 additions and 132 deletions

View File

@@ -148,16 +148,16 @@ class InvoiceValidationResource extends Resource
->reactive()
->hidden(fn (callable $get) => ($get('invoice_number') == null || $get('update_invoice') == '0') || !empty($get('serial_number')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
if(!$get('plant_id'))
if (!$get('plant_id'))
{
$set('update_invoice', null);
return;
}
if($get('update_invoice') === "1")
if ($get('update_invoice') == "1")
{
$totQuan = InvoiceValidation::where('invoice_number', $get('invoice_number'))->where('plant_id', $get('plant_id'))->count();
if($totQuan <= 0)
if ($totQuan <= 0)
{
$set('update_invoice', null);
return;
@@ -167,9 +167,9 @@ class InvoiceValidationResource extends Resource
$scanMQuan = InvoiceValidation::where('invoice_number', $get('invoice_number'))->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $get('plant_id'))->count();
$scanSQuan = InvoiceValidation::where('invoice_number', $get('invoice_number'))->where('scanned_status', 'Scanned')->where('plant_id', $get('plant_id'))->count();
if($totMQuan > 0)
if ($totMQuan > 0)
{
if ($totQuan === $scanMQuan)
if ($totQuan == $scanMQuan)
{
$set('update_invoice', null);
return;
@@ -177,7 +177,7 @@ class InvoiceValidationResource extends Resource
}
else
{
if ($totQuan === $scanSQuan)
if ($totQuan == $scanSQuan)
{
$set('update_invoice', null);
return;
@@ -343,15 +343,57 @@ class InvoiceValidationResource extends Resource
$fullPath = Storage::disk('local')->path($path);
// /home/iot-dev/projects/pds/storage/app/private/uploads/temp/3RA0018735.xlsx
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->count();
if ($totQuan > 0)
{
$scanSQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('scanned_status', 'Scanned')->count();
if ($totQuan == $scanSQuan)
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
Notification::make()
->title("Serial invoice number : '$originalNameOnly' already completed the scanning process for plant : '$plantName'.")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
else
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
// $plantCode = $invoiceFirst ? (String)$invoiceFirst->plant->code : null;
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
$invoicePlantId = $invoiceFirst->plant_id;
if ($plantId != $invoicePlantId)
{
Notification::make()
->title("Serial invoice number : '$originalNameOnly' already exists for plant : '$plantName'.<br>Choose the valid 'Plant' to proceed!")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
}
}
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('plant_id', $plantId)->count();
$scanSQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
if($totQuan == $scanSQuan && $totQuan > 0)
if ($totQuan > 0 && $totQuan == $scanSQuan)
{
Notification::make()
->title('Serial invoice already completed the scanning process for selected plant.')
->danger()
->send();
->title('Serial invoice already completed the scanning process for selected plant.')
->danger()
->send();
if ($disk->exists($path))
{
@@ -364,7 +406,7 @@ class InvoiceValidationResource extends Resource
{
$rows = Excel::toArray(null, $fullPath)[0];
if((count($rows) - 1) <= 0)
if ((count($rows) - 1) <= 0)
{
Notification::make()
->title('Records Not Found')
@@ -388,7 +430,7 @@ class InvoiceValidationResource extends Resource
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
@@ -399,19 +441,17 @@ class InvoiceValidationResource extends Resource
if (!empty($materialCode))
{
if(Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
if (Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
{
$invalidMatCodes[] = $materialCode;
}
else
{
if (empty($serialNumber)) {
$missingSerials[] = $materialCode;
}
else if(Str::length($serialNumber) < 9 || !ctype_alnum($serialNumber))
else if (Str::length($serialNumber) < 9 || !ctype_alnum($serialNumber))
{
$invalidSerialCodes[] = $serialNumber;
}
@@ -453,7 +493,6 @@ class InvoiceValidationResource extends Resource
}
return;
}
else if (!empty($uniqueMissingSerials)) {
Notification::make()
->title('Missing Serial Numbers')
@@ -479,7 +518,7 @@ class InvoiceValidationResource extends Resource
else if (!empty($duplicateSerialCodes)) {
Notification::make()
->title('Duplicate Serial Numbers')
->body('The following serial numbers are already exist in database:<br>' . implode(', ', $duplicateSerialCodes))
->body('The following serial numbers are already exist in imported excel:<br>' . implode(', ', $duplicateSerialCodes))
->danger()
->send();
if ($disk->exists($path)) {
@@ -532,30 +571,30 @@ class InvoiceValidationResource extends Resource
// Check which codes have a material_type set (not null)
$invalidCodes = $matchedItems
->filter(fn ($sticker) => !empty($sticker->material_type)) //filter invalid
->pluck('item.code')
->toArray();
->filter(fn ($sticker) => !empty($sticker->material_type)) //filter invalid
->pluck('item.code')
->toArray();
if (count($invalidCodes) > 10)
{
Notification::make()
->title('Invalid item codes found')
->body('' . count($invalidCodes) . 'item codes found have material type.')
->danger()
->send();
->title('Invalid item codes found')
->body('' . count($invalidCodes) . 'item codes found have material type.')
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
else if(count($invalidCodes) > 0)
else if (count($invalidCodes) > 0)
{
Notification::make()
->title('Invalid item codes found')
->body('Material invoice Item Codes found : ' . implode(', ', $invalidCodes))
->danger()
->send();
->title('Invalid item codes found')
->body('Material invoice Item Codes found : ' . implode(', ', $invalidCodes))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
@@ -567,7 +606,7 @@ class InvoiceValidationResource extends Resource
// Save full file path to session
session(['uploaded_invoice_path' => $fullPath]);
Notification::make()
->title('Serial invoice imported successfully.')
->title('Serial invoice imported successfully.')
->success()
->send();
}
@@ -603,7 +642,6 @@ class InvoiceValidationResource extends Resource
->visible(fn (Get $get) => !empty($get('plant_id')))
->directory('uploads/temp'),
])
->action(function (array $data) {
$uploadedFile = $data['invoice_material'];
@@ -620,10 +658,52 @@ class InvoiceValidationResource extends Resource
$fullPath = Storage::disk('local')->path($path);
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->count();
if ($totQuan > 0)
{
$scanMQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->whereNotNull('serial_number')->where('serial_number', '!=', '')->count();
if ($totQuan == $scanMQuan)
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
Notification::make()
->title("Material invoice number : '$originalNameOnly' already completed the scanning process for plant : '$plantName'.")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
else
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
// $plantCode = $invoiceFirst ? (String)$invoiceFirst->plant->code : null;
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
$invoicePlantId = $invoiceFirst->plant_id;
if ($plantId != $invoicePlantId)
{
Notification::make()
->title("Material invoice number : '$originalNameOnly' already exists for plant : '$plantName'.<br>Choose the valid 'Plant' to proceed!")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
}
}
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('plant_id', $plantId)->count();
$scanMQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
if($totQuan == $scanMQuan && $totQuan > 0)
if ($totQuan > 0 && $totQuan == $scanMQuan)
{
Notification::make()
->title('Material invoice already completed the scanning process for selected plant.')
@@ -639,7 +719,7 @@ class InvoiceValidationResource extends Resource
{
$rows = Excel::toArray(null, $fullPath)[0];
if((count($rows) - 1) <= 0)
if ((count($rows) - 1) <= 0)
{
Notification::make()
->title('Records Not Found')
@@ -662,7 +742,7 @@ class InvoiceValidationResource extends Resource
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$materialQuantity = trim($row[1]);
@@ -672,13 +752,13 @@ class InvoiceValidationResource extends Resource
}
if (!empty($materialCode)) {
if(Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
if (Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
{
$invalidMatCodes[] = $materialCode;
}
else
{
if($materialQuantity == 0)
if ($materialQuantity == 0)
{
$invalidMaterialQuan[] = $materialCode;
}
@@ -686,7 +766,7 @@ class InvoiceValidationResource extends Resource
{
$missingQuantities[] = $materialCode;
}
else if(!is_numeric($materialQuantity))
else if (!is_numeric($materialQuantity))
{
$invalidMatQuan[] = $materialCode;
}
@@ -821,7 +901,7 @@ class InvoiceValidationResource extends Resource
}
return;
}
else if(count($invalidCodes) > 0)
else if (count($invalidCodes) > 0)
{
$invalidCodes = array_unique($invalidCodes);
Notification::make()
@@ -852,29 +932,29 @@ class InvoiceValidationResource extends Resource
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
if ($totalExcelQty === 0) {
if ($totalExcelQty == 0) {
$zeroQtyCodes[] = $code;
} elseif (!is_numeric($totalExcelQty)) {
$nonNumericQtyCodes[] = $code; // Here you may want to check divisibility condition too
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty !== 0) {
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty != 0) {
$notDivisibleCodes[] = $code;
}
}
}
$showValidationNotification = function(array $codes, string $message) {
if (count($codes) === 0) return;
if (count($codes) == 0) return;
$uniqueCodes = array_unique($codes);
$codeList = implode(', ', $uniqueCodes);
@@ -1013,7 +1093,7 @@ class InvoiceValidationResource extends Resource
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['invoice_type']) || (empty($data['Plant']) && empty($data['invoice_number']) && empty($data['serial_number']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['operator_id']) && empty($data['scanned_status']) && empty($data['sticker_master_id']))) {
if(empty($data['invoice_type']))
if (empty($data['invoice_type']))
{
Notification::make()
->title('Please, choose invoice type to filter.')