1
0
forked from poc/pds

trim invoice number and update invoice functionality added

This commit is contained in:
dhanabalan
2025-04-23 14:49:58 +05:30
parent 701cc43283
commit 34972c1422

View File

@@ -53,7 +53,6 @@ class CreateInvoiceValidation extends CreateRecord
public function getFormActions(): array public function getFormActions(): array
{ {
// return parent::getFormActions(); //return [];
return [ return [
$this->getCancelFormAction(), $this->getCancelFormAction(),
]; ];
@@ -61,6 +60,8 @@ class CreateInvoiceValidation extends CreateRecord
public function processInvoice($invoiceNumber) public function processInvoice($invoiceNumber)
{ {
$invoiceNumber = trim($invoiceNumber);
$this->showCapacitorInput = false; $this->showCapacitorInput = false;
$user = Filament::auth()->user(); $user = Filament::auth()->user();
@@ -73,7 +74,7 @@ class CreateInvoiceValidation extends CreateRecord
$updateStatus = $this->form->getState()['update_invoice'] ?? null; $updateStatus = $this->form->getState()['update_invoice'] ?? null;
$this->invoiceNumber = $this->form->getState()['invoice_number'] ?? $invoiceNumber; $this->invoiceNumber = trim($this->form->getState()['invoice_number']) ?? $invoiceNumber;
$invoiceType = null; $invoiceType = null;
//$this->invoiceNumber = $this->invoiceNumber ?? $invoiceNumber; //$this->invoiceNumber = $this->invoiceNumber ?? $invoiceNumber;
@@ -143,7 +144,438 @@ class CreateInvoiceValidation extends CreateRecord
if($updateStatus === '1') if($updateStatus === '1')
{ {
dd('Material invoice update in progress...'); //dd('Material invoice update in progress...');
$filename = $invoiceNumber . '.xlsx';
$directory = 'uploads/temp';
$disk = Storage::disk('local');
$filePath = $directory . '/' . $filename;
$fullPath = $disk->path($filePath);
if ($fullPath && file_exists($fullPath))
{
// Now you can read/process the file here
$rows = Excel::toArray(null, $fullPath)[0];
if((count($rows) - 1) <= 0)
{
Notification::make()
->title('Records Not Found')
->body("Import the valid updated 'Material Invoice' file to proceed..!")
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$invalidMatCodes = [];
$materialCodes = [];
$missingQuantities = [];
$invalidMatQuan = [];
$validRowsFound = false;
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
$materialCode = trim($row[0]);
$materialQuantity = trim($row[1]);
if (empty($materialCode) && empty($materialQuantity)) {
continue;
}
if (!empty($materialCode)) {
if(Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
{
$invalidMatCodes[] = $materialCode;
}
else
{
if (empty($materialQuantity)) {
$missingQuantities[] = $materialCode;
}
else if(!is_numeric($materialQuantity))
{
$invalidMatQuan[] = $materialCode;
}
else if($materialQuantity == 0)
{
$invalidMatQuan[] = $materialCode;
}
else
{
$materialCodes[] = $materialCode;
$validRowsFound = true;
}
}
}
else
{
continue;
}
}
if (!$validRowsFound) {
Notification::make()
->title('Invalid Material Invoice')
->danger() // This makes the notification red to indicate an error
->body('Uploaded Excel sheet is empty or<br>contains no valid data.')
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueInvalidCodes = array_unique($invalidMatCodes);
if (!empty($uniqueInvalidCodes)) {
Notification::make()
->title('Invalid Item Codes')
->body('The following item codes should contain minimum 6 digit alpha numeric values:<br>' . implode(', ', $uniqueInvalidCodes))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueMissingQuanCodes = array_unique($missingQuantities);
if (!empty($uniqueMissingQuanCodes)) {
Notification::make()
->title('Missing Material Quantity')
->body("The following item codes doesn't have valid material quantity:<br>" . implode(', ', $uniqueMissingQuanCodes))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueInvalidMatQuan = array_unique($invalidMatQuan);
if (!empty($uniqueInvalidMatQuan)) {
Notification::make()
->title('Invalid Material Quantity')
->body("The following item codes doesn't have valid material quantity:<br>" . implode(', ', $uniqueInvalidMatQuan))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueCodes = array_unique($materialCodes);
$matchedItems = StickerMaster::with('item')
->whereHas('item', function ($query) use ($uniqueCodes) {
$query->whereIn('code', $uniqueCodes);
})
->get();
$matchedCodes = $matchedItems->pluck('item.code')->toArray();
$missingCodes = array_diff($uniqueCodes, $matchedCodes);
if (!empty($missingCodes))
{
$missingCount = count($missingCodes);
$message = $missingCount > 10 ? "'$missingCount' item codes are not found in database." : 'The following item codes are not found in database:<br>' . implode(', ', $missingCodes);
Notification::make()
->title('Unknown Item Codes')
->body($message)
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$invalidCodes = $matchedItems
->filter(fn ($sticker) => empty($sticker->material_type)) //filter invalid
->pluck('item.code')
->toArray();
if (!empty($invalidCodes))
{
$missingCount = count($invalidCodes);
$message = $missingCount > 10 ? "'$missingCount' Serial Invoice item codes found." : "'Serial Invoice' item codes found:<br>" . implode(', ', $invalidCodes);
Notification::make()
->title('Invalid Item Codes')
->body($message)
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$nonNumericQtyCodes = [];
$zeroQtyCodes = [];
$notDivisibleCodes = [];
foreach ($matchedItems as $sticker)
{
$code = $sticker->item->code;
$materialType = $sticker->material_type;
if ($materialType == 2)
{
$bundleQty = $sticker->bundle_quantity ?? 0;
$totalExcelQty = 0;
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
if ($excelCode === $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
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) {
$notDivisibleCodes[] = $code;
}
}
}
$showValidationNotification = function(array $codes, string $message) {
if (count($codes) === 0) return;
$uniqueCodes = array_unique($codes);
$codeList = implode(', ', $uniqueCodes);
Notification::make()
->title('Invalid Bundle Quantity')
->body("$message<br>$codeList")
->danger()
->send();
};
$showValidationNotification($nonNumericQtyCodes, "The following item codes contains invalid bundle quantity:");
$showValidationNotification($zeroQtyCodes, "The following item codes quantity should be greater than '0':");
$showValidationNotification($notDivisibleCodes, "The following item codes quantity is not divisible by bundle quantity.");
if ($nonNumericQtyCodes || $zeroQtyCodes || $notDivisibleCodes) {
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
else
{
$oldQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$newQuan = -1;
$inserted = 0;
foreach ($matchedItems as $sticker)
{
if ($newQuan === -1)
{
InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) {
$query->whereNull('serial_number')->orWhere('serial_number', '');
})
->delete();
$newQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
continue;
}
$code = $sticker->item->code;
$materialType = $sticker->material_type;
// $sticker = StickerMaster::where('plant_id', $plantId)->whereHas('item', function ($query) use ($code) { $query->where('plant_id', $this->plantId)->where('code', $code); })->first();
if ($materialType == 1)
{
$totalExcelQty = 0;
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
if ($excelCode === $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
$existQty = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where('sticker_master_id', $sticker->id)->count();
if ($existQty < $totalExcelQty)
{
$newQty = $totalExcelQty - $existQty;
for ($i = 0; $i < $newQty; $i++)
{
if ($sticker) {
InvoiceValidation::create([
'sticker_master_id' => $sticker->id,
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'quantity' => 1,
'operator_id'=> $operatorName,
]);
$inserted++;
}
}
}
}
else if ($materialType == 2)
{
$bundleQty = $sticker->bundle_quantity;
$totalExcelQty = 0;
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
if ($excelCode === $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
$existQty = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where('sticker_master_id', $sticker->id)->count();
//for ($i = 0; $i < ($totalExcelQty/$bundleQty); $i++)
$newTotQty = $totalExcelQty/$bundleQty;
if ($existQty < $newTotQty)
{
$newQty = $newTotQty - $existQty;
for ($i = 0; $i < $newQty; $i++)
{
if ($sticker) {
InvoiceValidation::create([
'sticker_master_id' => $sticker->id,
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'quantity' => $bundleQty,
'operator_id'=> $operatorName,
]);
$inserted++;
}
}
}
}
}
if ($inserted > 0 || $oldQuan !== $newQuan)
{
Notification::make()
->title("Material invoice successfully updatad.")
->success()
->send();
Notification::make()
->title("Start the scanning process!")
->body("'$inserted' new material invoice records were inserted.")
->info()
// ->success()
->send();
// Update total quantity in the form
$totalQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$scannedQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totalQuantity,
'scanned_quantity'=> $scannedQuantity,
]);
if ($totalQuantity === $scannedQuantity)
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
}
else
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshMaterialInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
}
}
else
{
Notification::make()
->title("Update Failed: Material Invoice")
->body("No new records were inserted for Material Invoice : '$invoiceNumber'.")
->danger()
->send();
$totalQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$scannedQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totalQuantity,
'scanned_quantity'=> $scannedQuantity,
]);
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshEmptyInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
return;
}
}
}
else
{
Notification::make()
->title('Updated Invoice Not Found')
->body("Import the updated 'Material Invoice' file to proceed..!")
->danger()
->send();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => 0,
'scanned_quantity'=> 0,
]);
$this->dispatch('refreshEmptyInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
return;
}
} }
} }
return; return;
@@ -189,7 +621,362 @@ class CreateInvoiceValidation extends CreateRecord
if($updateStatus === '1') if($updateStatus === '1')
{ {
dd('Serial invoice update in progress...'); $filename = $invoiceNumber . '.xlsx';
$directory = 'uploads/temp';
$disk = Storage::disk('local');
$filePath = $directory . '/' . $filename;
$fullPath = $disk->path($filePath);
// Check if file exists //$disk->exists($filePath)
if ($fullPath && file_exists($fullPath))
{
// /home/iot-dev/projects/pds/storage/app/private/uploads/temp/3RA0018735.xlsx
// dd('Serial invoice update in progress...');
// Now you can read/process the file here
$rows = Excel::toArray(null, $fullPath)[0];
if((count($rows) - 1) <= 0)
{
Notification::make()
->title('Records Not Found')
->body("Import the valid updated 'Serial Invoice' file to proceed..!")
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$invalidMatCodes = [];
$materialCodes = [];
$missingSerials = [];
$invalidSerCodes = [];
$duplicateSerials = [];
$serialNumbers = [];
$validRowsFound = false;
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
if (empty($materialCode) && empty($serialNumber))
{
continue;
}
if (!empty($materialCode))
{
if(Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
{
$invalidMatCodes[] = $materialCode;
continue;
}
else
{
if(empty($serialNumber)) {
$missingSerials[] = $materialCode;
}
else if(Str::length($serialNumber) < 9 || !ctype_alnum($serialNumber))
{
$invalidSerCodes[] = $serialNumber;
}
else
{
if (in_array($serialNumber, $serialNumbers))
{
$duplicateSerials[] = $serialNumber;
}
else
{
$serialNumbers[] = $serialNumber;
$materialCodes[] = $materialCode;
$validRowsFound = true;
}
}
}
}
else
{
continue;
}
}
if (!$validRowsFound) {
Notification::make()
->title('Invalid Serial Invoice')
->danger() // This makes the notification red to indicate an error
->body('Uploaded excel sheet is empty or<br>contains no valid data.')
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueInvalidCodes = array_unique($invalidMatCodes);
if (!empty($uniqueInvalidCodes)) {
Notification::make()
->title('Invalid Item Codes')
->body('The following item codes should contain minimum 6 digit alpha numeric values:<br>' . implode(', ', $uniqueInvalidCodes))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueCodes = array_unique($materialCodes);
$matchedItems = StickerMaster::with('item')
->whereHas('item', function ($query) use ($uniqueCodes) {
$query->whereIn('code', $uniqueCodes);
})
->get();
$matchedCodes = $matchedItems->pluck('item.code')->toArray();
$missingCodes = array_diff($uniqueCodes, $matchedCodes);
if (!empty($missingCodes))
{
$missingCount = count($missingCodes);
$message = $missingCount > 10 ? "'$missingCount' item codes are not found in database." : 'The following item codes are not found in database:<br>' . implode(', ', $missingCodes);
Notification::make()
->title('Unknown Item Codes')
->body($message)
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$invalidCodes = $matchedItems
->filter(fn ($sticker) => !empty($sticker->material_type)) //filter invalid
->pluck('item.code')
->toArray();
if (!empty($invalidCodes))
{
$missingCount = count($invalidCodes);
$message = $missingCount > 10 ? "'$missingCount' Material Invoice item codes found." : "'Material Invoice' item codes found:<br>" . implode(', ', $invalidCodes);
Notification::make()
->title('Invalid Item Codes')
->body($message)
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueMissingSerials = array_unique($missingSerials);
if (!empty($uniqueMissingSerials)) {
Notification::make()
->title('Missing Serial Numbers')
->body("The following item codes doesn't have valid serial number:<br>" . implode(', ', $uniqueMissingSerials))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueInvalidSerCodes = array_unique($invalidSerCodes);
if (!empty($uniqueInvalidSerCodes)) {
Notification::make()
->title('Invalid Serial Numbers')
->body('The following serial numbers should contain minimum 9 digit alpha numeric values:<br>' . implode(', ', $uniqueInvalidSerCodes))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$uniqueDupSerCodes = array_unique($duplicateSerials);
if (!empty($uniqueDupSerCodes)) {
Notification::make()
->title('Duplicate Serial Numbers')
->body('The following serial numbers are already exist in invoice excel:<br>' . implode(', ', $uniqueDupSerCodes))
->danger()
->send();
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
return;
}
$oldQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$newQuan = 0;
$inserted = 0;
foreach ($rows as $index => $row)
{
if ($index === 0) // Skip header;
{
InvoiceValidation::where('invoice_number', $invoiceNumber)
->where(function($query) {
$query->whereNull('motor_scanned_status')->orWhere('motor_scanned_status', '');
})
->where(function($query) {
$query->whereNull('pump_scanned_status')->orWhere('pump_scanned_status', '');
})
->where(function($query) {
$query->whereNull('capacitor_scanned_status')->orWhere('capacitor_scanned_status', '');
})
->where(function($query) {
$query->whereNull('scanned_status_set')->orWhere('scanned_status_set', '');
})
->where(function($query) {
$query->whereNull('scanned_status')->orWhere('scanned_status', '');
})
->delete();
$newQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
continue;
}
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
if (empty($materialCode) || empty($serialNumber)) {
continue;
}
$sNoExist = InvoiceValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->pluck('serial_number')->first()->exists();
if($sNoExist) { continue; }
$sticker = StickerMaster::where('plant_id', $plantId)->whereHas('item', function ($query) use ($materialCode) {
$query->where('plant_id', $this->plantId)->where('code', $materialCode); //Check if item.code matches Excel's materialCode
})->first();
if ($sticker) {
InvoiceValidation::create([
'sticker_master_id' => $sticker->id,
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => $serialNumber,
'operator_id'=> $operatorName,
]);
$inserted++;
}
}
if ($inserted > 0 || $oldQuan !== $newQuan)
{
Notification::make()
->title("Serial invoice successfully updated.")
->success()
->send();
Notification::make()
->title("Start the scanning process!")
->body("'$inserted' new serial invoice records were inserted.")
->info()
// ->success()
->send();
// Update total quantity in the form
$totalQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$scannedQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totalQuantity,
'scanned_quantity'=> $scannedQuantity,
]);
if ($totalQuantity === $scannedQuantity)
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
}
else
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
// $hasRecords = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->first()->stickerMasterRelation->material_type ?? null;
// $this->dispatch( (!empty($hasRecords) && $hasRecords) ? 'refreshMaterialInvoiceData' : 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); //$this->invoiceNumber
$this->dispatch('refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
}
}
else
{
Notification::make()
->title("Update Failed: Serial Invoice")
->body("No new records were inserted for Serial Invoice : '$invoiceNumber'.")
->danger()
->send();
$totalQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$scannedQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totalQuantity,
'scanned_quantity'=> $scannedQuantity,
]);
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshEmptyInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
return;
}
}
else
{
Notification::make()
->title('Updated Invoice Not Found')
->body("Import the updated 'Serial Invoice' file to proceed..!")
->danger()
->send();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => 0,
'scanned_quantity'=> 0,
]);
$this->dispatch('refreshEmptyInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
return;
}
} }
} }
return; return;