From 32def0e7af71d9195e4973f25548cd0fc1491536 Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Mon, 14 Sep 2026 16:11:15 +0530 Subject: [PATCH] Added meter pattern in invoice validation --- .../Pages/CreateInvoiceValidation.php | 397 +++++++++++++++++- 1 file changed, 383 insertions(+), 14 deletions(-) diff --git a/app/Filament/Resources/InvoiceValidationResource/Pages/CreateInvoiceValidation.php b/app/Filament/Resources/InvoiceValidationResource/Pages/CreateInvoiceValidation.php index 70a4c92..433ed63 100644 --- a/app/Filament/Resources/InvoiceValidationResource/Pages/CreateInvoiceValidation.php +++ b/app/Filament/Resources/InvoiceValidationResource/Pages/CreateInvoiceValidation.php @@ -6,6 +6,7 @@ use App\Filament\Resources\InvoiceValidationResource; use App\Imports\ExcelImport; use App\Mail\InvalidSerialMail; use App\Models\AlertMailRule; +use App\Models\CoilPacking; use App\Models\InvoiceValidation; use App\Models\Item; use App\Models\Plant; @@ -2551,19 +2552,90 @@ class CreateInvoiceValidation extends CreateRecord $this->dispatch('refreshMaterialInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); } + + $pattern6 = '/^(?[^|]+)\|(?[^|]+)\|(?[^|]+)\|(?[^|]+)\|(?[^|]+)$/i'; $pattern0 = '/^(?[^|]+)\|(?[^|]+)\|(?[^|]+)\|(?[0-9]+(?:\.[0-9]+)?)\s?kg$/i'; $pattern1 = '/^(?[^|]+)\|(?[^|]+)\|(?[^|]+)\|(?[^|]+)\/(?.+)$/i'; $pattern2 = '/^(?[^|]+)\|(?[^|]+)\|(?[^|]+)\|(?.+)$/i'; $pattern3 = '/^(?[^|]+)\|(?[^|]+)-(?.+)$/i'; $pattern4 = '/^MP-(?.+)$/i'; + $pattern5 = '/^CP-(?.+)$/i'; $itemCode = ''; $batchNumber = ''; $curScanQty = ''; $wirePallet = ''; + $coilPallet = ''; $curMaterialQty = ''; $curMaterialSer = ''; - if (preg_match($pattern0, $serNo, $matches)) { + if (preg_match($pattern6, $serNo, $matches) && substr_count($serNo, '|') == 4) { + $itemCode = $matches['item_code']; + $this->currentItemCode = $itemCode; + $batchNumber = $matches['batch_number']; + $curScanQty = trim($matches['batch_quantity']); + $serialNumber = $matches['batch_id'].'-'.$matches['batch_count']; + $serNo = null; + + if (empty($matches['batch_number']) || ! $matches['batch_number']) { + Notification::make() + ->danger() + ->title('Invalid Material QR Format') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totMatQuan, + 'update_invoice' => false, + 'scanned_quantity' => $scanMatQuan, + ]); + + return; + } elseif (empty($matches['batch_id']) || ! $matches['batch_id']) { + Notification::make() + ->danger() + ->title('Invalid Material QR Format') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totMatQuan, + 'update_invoice' => false, + 'scanned_quantity' => $scanMatQuan, + ]); + + return; + } + elseif (empty($matches['batch_count']) || ! $matches['batch_count']) { + Notification::make() + ->danger() + ->title('Invalid Material QR Format') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totMatQuan, + 'update_invoice' => false, + 'scanned_quantity' => $scanMatQuan, + ]); + + return; + } + } elseif (preg_match($pattern0, $serNo, $matches)) { $itemCode = $matches['item_code']; $this->currentItemCode = $itemCode; $curScanQty = trim($matches['batch_quantity']); @@ -2574,8 +2646,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') - ->seconds(2) + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->send(); $this->dispatch('playWarnSound'); @@ -2593,7 +2664,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2621,7 +2692,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2655,7 +2726,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2689,7 +2760,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2734,7 +2805,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2767,7 +2838,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2800,7 +2871,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2840,7 +2911,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -2874,7 +2945,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(2) ->send(); $this->dispatch('playWarnSound'); @@ -3197,7 +3268,305 @@ class CreateInvoiceValidation extends CreateRecord ]); return; - } else { + } elseif (preg_match($pattern5, $serNo, $matches)) { + $coilPallet = 'CP-'.$matches['code']; + $coilPattern = '/^CP-(?\d+)$/i'; + + if (! preg_match($coilPattern, $serNo, $matches)) { + Notification::make() + ->title('Invalid Coil Packing QR Format') + ->body("Scan valid Coil Packing QR code proceed!
Sample format : 'CP-2601001'") + ->danger() + ->seconds(1) + ->send(); + + return; + } + + $coilMaster = CoilPacking::where('plant_id', $plantId)->where('coil_packing_number', $coilPallet)->first(); + + if (! $coilMaster) { + Notification::make() + ->title('Master Pallet Not Found') + ->body("No record found for this Master Packing QR $coilPallet") + ->danger() + ->seconds(2) + ->send(); + + return; + } + + $coilItemCodes = CoilPacking::join('items', 'items.id', '=', 'coil_packings.item_id') + ->where('coil_packings.plant_id', $plantId) + ->where('coil_packings.coil_packing_number', $wirePallet) + ->pluck('items.code') + ->unique() + ->toArray(); + + $invoiceItemCodes = InvoiceValidation::join( + 'sticker_masters', + 'sticker_masters.id', + '=', + 'invoice_validations.sticker_master_id' + ) + ->join( + 'items', + 'items.id', + '=', + 'sticker_masters.item_id' + ) + ->where('invoice_validations.plant_id', $plantId) + ->where('invoice_validations.invoice_number', $this->invoiceNumber) + ->pluck('items.code') + ->unique() + ->toArray(); + + $missedCodes = array_diff($coilItemCodes, $invoiceItemCodes); + + if (! empty($missedCodes)) { + + Notification::make() + ->title('Items Missing in Invoice') + ->body('Item codes are missing in invoice: '.implode(', ', $missedCodes)) + ->danger() + ->seconds(3) + ->send(); + + return; + } + + $duplicateSerial = []; + $weightExceeded = []; + $invalidMaterialItems = []; + + $coilItems1 = CoilPacking::join('items', 'items.id', '=', 'coil_packings.item_id') + ->where('coil_packings.plant_id', $plantId) + ->where('coil_packings.coil_packing_number', $wirePallet) + ->select( + 'items.code as item_code', + 'coil_packings.process_order', + DB::raw('COUNT(*) as pallet_weight') + ) + ->groupBy('items.code', 'coil_packings.process_order') + ->get(); + + foreach ($coilItems1 as $coilItem) { + $processOrder = $coilItem->process_order; + $palletWeight = $coilItem->pallet_weight; + $itemCode = $coilItem->item_code; + + $duplicate = InvoiceValidation::where('plant_id', $this->plantId) + ->where('invoice_number', $this->invoiceNumber) + ->where('serial_number', $processOrder) + ->exists(); + + if ($duplicate) { + $duplicateSerial[] = $processOrder; + + continue; + } + + $materialType = StickerMaster::where('item_id', function ($q) use ($itemCode) { + $q->select('id')->from('items')->where('code', $itemCode); + })->value('material_type'); + + if ($materialType != 3) { + if (! in_array($itemCode, $invalidMaterialItems)) { + $invalidMaterialItems[] = $itemCode; + } + } + + $scannedQty = InvoiceValidation::join('sticker_masters', 'sticker_masters.id', '=', 'invoice_validations.sticker_master_id') + ->join('items', 'items.id', '=', 'sticker_masters.item_id') + ->where('invoice_validations.plant_id', $plantId) + ->where('invoice_validations.invoice_number', $this->invoiceNumber) + ->where('items.code', $itemCode) + ->sum(DB::raw('invoice_validations.quantity::numeric')); + + if ($palletWeight > $scannedQty) { + $weightExceeded[] = $itemCode; + } + } + + if (! empty($invalidMaterialItems)) { + $uniqueInvalidItems = array_unique($invalidMaterialItems); + Notification::make() + ->title('Invalid Material Type') + ->body(implode(', ', $uniqueInvalidItems)."
Invalid material type found for the invoice '$invoiceNumber'.") + ->danger() + ->seconds(4) + ->send(); + + return; + } elseif (! empty($weightExceeded)) { + Notification::make() + ->title('Item Code Limit') + ->body(implode(', ', $weightExceeded)."
Master pallet weight exceeds the remaining quantity in invoice '$invoiceNumber'.") + ->danger() + ->seconds(4) + ->send(); + + return; + } elseif (! empty($duplicateSerial)) { + Notification::make() + ->title('Duplicate Serial Number') + ->body(implode(', ', $duplicateSerial)."
Duplicate Serial numbers found for the invoice '$invoiceNumber'.") + ->danger() + ->seconds(4) + ->send(); + + return; + } + + $itemExceeded = []; + + $invoiceRows = InvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->whereNull('serial_number') + ->get(); + + $palletItems = CoilPacking::where('coil_packings.plant_id', $plantId) + ->where('coil_packings.coil_packing_number', $coilPallet) + ->join('items', 'items.id', '=', 'coil_packings.item_id') + ->select( + 'items.code as item_code', + DB::raw('COUNT(*) as pallet_weight') + ) + ->groupBy('items.code') + ->get(); + + foreach ($invoiceRows as $row) { + $itemCode = $row->stickerMaster->item->code ?? null; + + if (! $itemCode) { + continue; + } + + $pallet = $palletItems->firstWhere('item_code', $itemCode); + $palletWeight = $pallet->pallet_weight ?? 0; + + $remainingQty = $row->quantity; + + if ($palletWeight > $remainingQty) { + $itemExceeded[] = $itemCode; + } + } + + $items = implode(', ', $itemExceeded); + + if (! empty($itemExceeded)) { + Notification::make() + ->title('Item Code Limit') + ->body("Pallet coil count exceeds remaining quantity for invoice number '$invoiceNumber'for below item codes
$items") + ->danger() + ->seconds(5) + ->send(); + + return; + } + + $wireItems = CoilPacking::join('items', 'items.id', '=', 'coil_packings.item_id') + ->where('coil_packings.coil_packing_number', $coilPallet) + ->select( + 'items.code as item_code', + 'coil_packings.process_order', + DB::raw('COUNT(*) as pallet_weight') + ) + ->groupBy( + 'items.code', + 'coil_packings.process_order' + ) + ->get(); + + foreach ($wireItems as $wireItem) { + + $itemCode = $wireItem->item_code; + $palletWeight = $wireItem->pallet_weight; + $processOrder = $wireItem->process_order; + + if (! $processOrder || $palletWeight <= 0) { + continue; + } + + $records = InvoiceValidation::join('sticker_masters', 'sticker_masters.id', '=', 'invoice_validations.sticker_master_id') + ->join('items', 'items.id', '=', 'sticker_masters.item_id') + ->where('invoice_validations.invoice_number', $invoiceNumber) + ->where('invoice_validations.plant_id', $plantId) + ->where('items.code', $itemCode) + ->whereNull('invoice_validations.serial_number') + ->where('invoice_validations.quantity', '>', 0) + ->orderBy('invoice_validations.created_at') + ->select('invoice_validations.*') + ->get(); + + if ($records->isEmpty()) { + continue; + } + + foreach ($records as $record) { + + if ($palletWeight <= 0) { + break; + } + + $usedQty = min($record->quantity, $palletWeight); + + $record->quantity -= $usedQty; + + if ($usedQty == $record->quantity + $usedQty) { + $record->serial_number = $processOrder; + $record->quantity = $palletWeight; + $record->save(); + } else { + $record->save(); + + InvoiceValidation::create([ + 'sticker_master_id' => $record->sticker_master_id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => $processOrder, + 'quantity' => $usedQty, + 'operator_id' => $operatorName, + 'created_by' => $operatorName, + 'updated_by' => $operatorName, + ]); + } + + $palletWeight -= $usedQty; + + // if ($record->quantity <= 0) { + // $records->forget($key); + // } + } + + } + + $this->dispatch('refreshMaterialInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + + $totQuan = InvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->count(); + $scanMQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count(); + + $checkMat = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->latest('updated_at')->first(); // ->where('quantity', '!=', '') + if (($checkMat?->stickerMaster->material_type ?? 0) == 3) { + $totMatQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->whereNull('serial_number')->where('plant_id', $plantId)->latest('updated_at')->first()?->invoice_quantity ?? 0; + $scanMatQuan = number_format($totMatQuan - (InvoiceValidation::where('invoice_number', $invoiceNumber)->whereNull('serial_number')->where('plant_id', $plantId)->latest('updated_at')->first()?->quantity ?? 0), 3, '.', ''); // ('updated_at', 'desc') + } else { + $totMatQuan = $totQuan; + $scanMatQuan = $scanMQuan; + } + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totMatQuan, + 'update_invoice' => false, + 'scanned_quantity' => $scanMatQuan, + ]); + + return; + } + else { $itemCode = null; $this->currentItemCode = ''; $batchNumber = null; @@ -3207,7 +3576,7 @@ class CreateInvoiceValidation extends CreateRecord Notification::make() ->danger() ->title('Invalid Material QR Format') - ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1') + ->body('Scan valid Material QR code to proceed!
Sample formats are:
123456|123456789|001|5kg (or)
123456|12345|12345678|1/1 (or)
123456|12345|12345678|1 (or)
123456|12345678-1 (or)
657204|26091200|200000266831|001|650.000') ->seconds(1) ->send();