diff --git a/app/Filament/Resources/SerialValidationResource.php b/app/Filament/Resources/SerialValidationResource.php new file mode 100644 index 0000000..a8c3e62 --- /dev/null +++ b/app/Filament/Resources/SerialValidationResource.php @@ -0,0 +1,1230 @@ +schema([ + Section::make('') + ->schema([ + Forms\Components\Select::make('plant_id') + ->relationship('plant', 'name') + ->required() + ->reactive() + ->columnSpan(1) + ->options(function (callable $get) { + $userHas = Filament::auth()->user()->plant_id; + return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray(); + }) + ->default(function () { + return optional(SerialValidation::latest()->first())->plant_id; + }) + ->disabled(fn (Get $get) => !empty($get('id'))) + // ->afterStateUpdated(fn ($set) => $set('block_id', null) & $set('name', null) & $set('start_time', null) & $set('duration', null) & $set('end_time', null)) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $plantId = $get('plant_id'); + $set('update_invoice', null); + // Ensure `linestop_id` is not cleared + if (!$plantId) { + $set('invoice_number', null); + $set('serial_number', null); + $set('total_quantity', null); + $set('scanned_quantity', null); + $set('ivPlantError', 'Please select a plant first.'); + return; + } + else + { + $set('ivPlantError', null); + } + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('ivPlantError') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('ivPlantError') ? $get('ivPlantError') : null) + ->hintColor('danger'), + + Forms\Components\TextInput::make('invoice_number') + ->label('Invoice Number') + // ->required() + ->reactive() + ->disabled() + ->columnSpan(1) + //->readOnly(fn (callable $get) => !empty($get('serial_number'))) + //->disabled(fn (Get $get) => !empty($get('serial_number'))) + ->extraAttributes([ + 'x-data' => '{ value: "" }', + 'x-model' => 'value', + 'x-on:keydown.enter.prevent' => '$wire.processInvoice(value)', + ]) + // ->afterStateHydrated(function (TextInput $component, string $state) { + // $component->state(ucwords($state)); + // }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $invNo = $get('invoice_number'); + $set('serial_number', null); + $set('update_invoice', null); + // if (!$invNo) { return; } else { } + }), + + Forms\Components\TextInput::make('serial_number') + ->label('Serial Number') + ->reactive() + // ->readOnly(fn (callable $get) => empty($get('invoice_number'))) + //->disabled(fn (Get $get) => empty($get('invoice_number'))) + ->extraAttributes([ + 'id' => 'serial_number_input', + 'x-data' => '{ value: "" }', + 'x-model' => 'value', + 'wire:keydown.enter.prevent' => 'processSerialNumber(value)', // Using wire:keydown + ]) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('update_invoice', 0); + // $this->dispatch('focus-serial-number'); + // if (!$invNo) { return; } else { } + }) + ->columnSpan(1), + Forms\Components\TextInput::make('total_quantity') + ->label('Total Quantity') + ->readOnly(true) + ->columnSpan(1), + Forms\Components\TextInput::make('scanned_quantity') + ->label('Scanned Quantity') + ->readOnly(true) + ->columnSpan(1), + ToggleButtons::make('update_invoice') + ->label('Update Invoice?') + ->boolean() + ->grouped() + ->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')) + { + $set('update_invoice', null); + return; + } + + if ($get('update_invoice') == "1") + { + $totQuan = SerialValidation::where('invoice_number', $get('invoice_number'))->where('plant_id', $get('plant_id'))->count(); + if ($totQuan <= 0) + { + $set('update_invoice', null); + return; + } + + $totMQuan = SerialValidation::where('invoice_number', $get('invoice_number'))->whereNotNull('quantity')->where('plant_id', $get('plant_id'))->count(); + $scanMQuan = SerialValidation::where('invoice_number', $get('invoice_number'))->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $get('plant_id'))->count(); + $scanSQuan = SerialValidation::where('invoice_number', $get('invoice_number'))->where('scanned_status', 'Scanned')->where('plant_id', $get('plant_id'))->count(); + + if ($totMQuan > 0) + { + if ($totQuan == $scanMQuan) + { + $set('update_invoice', null); + return; + } + } + else + { + if ($totQuan == $scanSQuan) + { + $set('update_invoice', null); + return; + } + } + } + }) + ->disabled(fn (Get $get) => empty($get('invoice_number'))), + Forms\Components\TextInput::make('id') + ->hidden() + ->readOnly(true), + ]) + ->columns(5), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('No.') + ->label('No.') + ->getStateUsing(function ($record, $livewire, $column, $rowLoop) { + $paginator = $livewire->getTableRecords(); + $perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10; + $currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1; + return ($currentPage - 1) * $perPage + $rowLoop->iteration; + }), + Tables\Columns\TextColumn::make('invoice_number') + ->label('Invoice Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('stickerMaster.item.code') + ->label('Item Code') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('serial_number') + ->label('Serial Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('motor_scanned_status') + ->label('Motor Scanned Status') + ->alignCenter(), + Tables\Columns\TextColumn::make('pump_scanned_status') + ->label('Pump Scanned Status') + ->alignCenter(), + Tables\Columns\TextColumn::make('scanned_status_set') + ->label('Pump Set Scanned Status') + ->alignCenter(), + Tables\Columns\TextColumn::make('capacitor_scanned_status') + ->label('Capacitor Scanned Status') + ->alignCenter(), + Tables\Columns\TextColumn::make('scanned_status') + ->label('Scanned Status') + ->alignCenter(), + Tables\Columns\TextColumn::make('panel_box_supplier') + ->label('Panel Box Supplier') + ->alignCenter(), + Tables\Columns\TextColumn::make('panel_box_serial_number') + ->label('Panel Box Serial Number') + ->alignCenter(), + Tables\Columns\TextColumn::make('load_rate') + ->label('Load Rate') + ->numeric() + ->alignCenter(), + Tables\Columns\TextColumn::make('upload_status') + ->label('Upload Status') + ->alignCenter(), + Tables\Columns\TextColumn::make('batch_number') + ->label('Batch Number') + ->alignCenter(), + Tables\Columns\TextColumn::make('quantity') + ->label('Quantity') + ->alignCenter() + ->numeric(), + Tables\Columns\TextColumn::make('plant.name') + ->label('Plant') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->label('Created At') + ->dateTime() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('updated_at') + ->label('Updated At') + ->dateTime() + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('deleted_at') + ->label('Deleted At') + ->dateTime() + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('operator_id') + ->label('Operator ID') + ->alignCenter() + ->sortable(), + ]) + ->headerActions([ + + // Action::make('plant_id') + // ->label('Select Plant') + // ->form([ + // Select::make('plant_id') + // ->options(Plant::pluck('name', 'id')->toArray()) // Fetch plant names and IDs + // ->label('Select Plant') + // ->required() + // ->reactive() + // ]), + + Tables\Actions\Action::make('Import Serial Number') + ->label('Import Serial Invoice') + ->form([ + Select::make('plant_id') + ->options(Plant::pluck('name', 'id')->toArray()) // Fetch plant names and IDs + ->label('Select Plant') + ->required() + ->default(function () { + return optional(SerialValidation::latest()->first())->plant_id; + }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('invoice_serial_number', null); + }) + ->reactive(), + + FileUpload::make('invoice_serial_number') + ->label('Invoice Serial Number') + // ->required() + ->preserveFilenames() // <- this keeps the original filename + ->storeFiles(false) // prevent auto-storing, we will store manually + ->reactive() + ->required() + ->disk('local') //'local' refers to the local storage disk defined in config/filesystems.php, typically pointing to storage/app. + ->visible(fn (Get $get) => !empty($get('plant_id'))) + ->directory('uploads/temp'), + ]) + ->action(function (array $data) { + $uploadedFile = $data['invoice_serial_number']; + + $disk = Storage::disk('local'); + + $plantId = $data['plant_id']; + + // Get original filename + $originalName = $uploadedFile->getClientOriginalName(); // e.g. 3RA0018732.xlsx + + $originalNameOnly = pathinfo($originalName, PATHINFO_FILENAME); + + // Store manually using storeAs to keep original name + $path = $uploadedFile->storeAs('uploads/temp', $originalName, 'local'); // returns relative path + // uploads/temp/3RA0018735.xlsx + + $fullPath = Storage::disk('local')->path($path); + // /home/iot-dev/projects/pds/storage/app/private/uploads/temp/3RA0018735.xlsx + + $totQuan = SerialValidation::where('invoice_number', $originalNameOnly)->count(); + if ($totQuan > 0) + { + $scanSQuan = SerialValidation::where('invoice_number', $originalNameOnly)->where('scanned_status', 'Scanned')->count(); + if ($totQuan == $scanSQuan) + { + $invoiceFirst = SerialValidation::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 = SerialValidation::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'.
Choose the valid 'Plant' to proceed!") + ->danger() + ->send(); + + if ($disk->exists($path)) + { + $disk->delete($path); + } + return; + } + } + } + + $totQuan = SerialValidation::where('invoice_number', $originalNameOnly)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $originalNameOnly)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + if ($totQuan > 0 && $totQuan == $scanSQuan) + { + Notification::make() + ->title('Serial invoice already completed the scanning process for selected plant.') + ->danger() + ->send(); + + if ($disk->exists($path)) + { + $disk->delete($path); + } + return; + } + + if ($fullPath && file_exists($fullPath)) + { + $rows = Excel::toArray(null, $fullPath)[0]; + + if ((count($rows) - 1) <= 0) + { + Notification::make() + ->title('Records Not Found') + ->body("Import the valid 'Serial Invoice' file to proceed..!") + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + $invalidMatCodes = []; + $invalidSerialCodes = []; + $materialCodes = []; + $missingSerials = []; + $duplicateSerials = []; + $seenSerialNumbers = []; + $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; + } + else + { + if (empty($serialNumber)) { + $missingSerials[] = $materialCode; + + } + else if (Str::length($serialNumber) < 9 || !ctype_alnum($serialNumber)) + { + $invalidSerialCodes[] = $serialNumber; + } + else + { + if (in_array($serialNumber, $seenSerialNumbers)) { + $duplicateSerials[] = $serialNumber; + } else { + $seenSerialNumbers[] = $serialNumber; + $materialCodes[] = $materialCode; + $validRowsFound = true; + } + } + } + } + else + { + continue; + } + } + + $uniqueInvalidCodes = array_unique($invalidMatCodes); + + $uniqueMissingSerials = array_unique($missingSerials); + + $uniqueSerialCodes = array_unique($invalidSerialCodes); + + $duplicateSerialCodes = array_unique($duplicateSerials); + + if (!empty($uniqueInvalidCodes)) { + Notification::make() + ->title('Invalid Item Codes') + ->body('The following item codes should contain minimum 6 digit alpha numeric values:
' . implode(', ', $uniqueInvalidCodes)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + else if (!empty($uniqueMissingSerials)) { + Notification::make() + ->title('Missing Serial Numbers') + ->body("The following item codes doesn't have valid serial number:
" . implode(', ', $uniqueMissingSerials)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + else if (!empty($uniqueSerialCodes)) { + Notification::make() + ->title('Invalid Serial Number') + ->body('The following serial numbers should contain minimum 9 digit alpha numeric values:
' . implode(', ', $uniqueSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + else if (!empty($duplicateSerialCodes)) { + Notification::make() + ->title('Duplicate Serial Numbers') + ->body('The following serial numbers are already exist in imported excel:
' . implode(', ', $duplicateSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + 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
contains no valid data.') + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + 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:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown Item Codes') + ->body($message) + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + // 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(); + + if (count($invalidCodes) > 10) + { + Notification::make() + ->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) + { + Notification::make() + ->title('Invalid item codes found') + ->body('Material invoice Item Codes found : ' . implode(', ', $invalidCodes)) + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + else + { + // Save full file path to session + session(['uploaded_invoice_path' => $fullPath]); + Notification::make() + ->title('Serial invoice imported successfully.') + ->success() + ->send(); + } + } + }) + ->visible(function() { + return Filament::auth()->user()->can('view import serial invoice'); + }), + // Tables\Actions\Action::make('Import Invoice Material') + // ->label('Import Material Invoice') + // ->form([ + + // Select::make('plant_id') + // ->options(Plant::pluck('name', 'id')->toArray()) // Fetch plant names and IDs + // ->label('Select Plant') + // ->required() + // ->default(function () { + // return optional(SerialValidation::latest()->first())->plant_id; + // }) + // ->afterStateUpdated(function ($state, callable $set, callable $get) { + // $set('invoice_material', null); + // }) + // ->reactive(), + + // FileUpload::make('invoice_material') + // ->label('Invoice Material') + // ->required() + // ->preserveFilenames() + // ->reactive() // <- this keeps the original filename + // ->storeFiles(false) // prevent auto-storing + // ->disk('local') + // ->visible(fn (Get $get) => !empty($get('plant_id'))) + // ->directory('uploads/temp'), + // ]) + // ->action(function (array $data) { + // $uploadedFile = $data['invoice_material']; + + // $plantId = $data['plant_id']; // Access the selected plant_id + + // $disk = Storage::disk('local'); + + // // Get original filename + // $originalName = $uploadedFile->getClientOriginalName(); + + // $originalNameOnly = pathinfo($originalName, PATHINFO_FILENAME); + + // $path = $uploadedFile->storeAs('uploads/temp', $originalName, 'local'); + + // $fullPath = Storage::disk('local')->path($path); + + // $totQuan = SerialValidation::where('invoice_number', $originalNameOnly)->count(); + // if ($totQuan > 0) + // { + // $scanMQuan = SerialValidation::where('invoice_number', $originalNameOnly)->whereNotNull('serial_number')->where('serial_number', '!=', '')->count(); + // if ($totQuan == $scanMQuan) + // { + // $invoiceFirst = SerialValidation::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 = SerialValidation::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'.
Choose the valid 'Plant' to proceed!") + // ->danger() + // ->send(); + + // if ($disk->exists($path)) + // { + // $disk->delete($path); + // } + // return; + // } + // } + // } + + // $totQuan = SerialValidation::where('invoice_number', $originalNameOnly)->where('plant_id', $plantId)->count(); + // $scanMQuan = SerialValidation::where('invoice_number', $originalNameOnly)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count(); + + // if ($totQuan > 0 && $totQuan == $scanMQuan) + // { + // Notification::make() + // ->title('Material invoice already completed the scanning process for selected plant.') + // ->danger() + // ->send(); + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + + // if ($fullPath && file_exists($fullPath)) + // { + // $rows = Excel::toArray(null, $fullPath)[0]; + + // if ((count($rows) - 1) <= 0) + // { + // Notification::make() + // ->title('Records Not Found') + // ->body("Import the valid 'Material Invoice' file to proceed..!") + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + + // $invalidMatCodes = []; + // $materialCodes = []; + // $missingQuantities = []; + // $invalidMatQuan = []; + // $invalidMaterialQuan = []; + // $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 ($materialQuantity == 0) + // { + // $invalidMaterialQuan[] = $materialCode; + // } + // else if (empty($materialQuantity)) + // { + // $missingQuantities[] = $materialCode; + // } + // else if (!is_numeric($materialQuantity)) + // { + // $invalidMatQuan[] = $materialCode; + // } + // else + // { + // $materialCodes[] = $materialCode; + // $validRowsFound = true; + // } + // } + // } + // else + // { + // continue; + // } + // } + + // $uniqueInvalidCodes = array_unique($invalidMatCodes); + // $uniqueaplhaMat = array_unique($invalidMatQuan); + // $uniqueZeroMat = array_unique($invalidMaterialQuan); + // $uniqueEmptyMat = array_unique($missingQuantities); + + // if (!empty($uniqueInvalidCodes)) { + // Notification::make() + // ->title('Invalid Item Codes') + // ->body('The following item codes should contain minimum 6 digit alpha numeric values:
' . implode(', ', $uniqueInvalidCodes)) + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + // if (!empty($uniqueaplhaMat)) { + // Notification::make() + // ->title('Invalid Material Quantity') + // ->body("The following item codes material quantity must be a numeric values :
" . implode(', ', $uniqueaplhaMat)) + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + // if (!empty($uniqueZeroMat)) { + // Notification::make() + // ->title('Invalid Material Quantity') + // ->body("The following item codes material quantity should be greater than 0:
" . implode(', ', $uniqueZeroMat)) + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + + // if (!empty($uniqueEmptyMat)) { + // Notification::make() + // ->title('Missing Material Quantity') + // ->body("The following item codes doesn't have valid material quantity:
" . implode(', ', $uniqueEmptyMat)) + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + + // 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
contains no valid data.') + // ->send(); + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // 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 sticker master." + // : 'Item Codes are not found in sticker master:
' . implode(', ', $missingCodes); + + // Notification::make() + // ->title('Unknown Item Codes') + // ->body($message) + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + + // $invalidCodes = $matchedItems + // ->filter(fn ($sticker) => empty($sticker->material_type)) //filter invalid + // ->pluck('item.code') + // ->toArray(); + + // if (count($invalidCodes) > 10) + // { + // $invalidCodes = array_unique($invalidCodes); + // Notification::make() + // ->title('Invalid item codes found') + // ->body('' . count($invalidCodes) . 'invalid item codes found have serial number.') + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // return; + // } + // else if (count($invalidCodes) > 0) + // { + // $invalidCodes = array_unique($invalidCodes); + // Notification::make() + // ->title('Invalid item codes found') + // ->body('Serial invoice Item Codes found : ' . implode(', ', $invalidCodes)) + // ->danger() + // ->send(); + + // if ($disk->exists($path)) { + // $disk->delete($path); + // } + // 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
$codeList") + // ->danger() + // ->send(); + // }; + + // $nonNumericQtyCodes = array_unique($nonNumericQtyCodes); + // $zeroQtyCodes = array_unique($zeroQtyCodes); + // $notDivisibleCodes = array_unique($notDivisibleCodes); + + // $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($path)) + // { + // $disk->delete($path); + // } + // return; + // } + // else + // { + // // Save full file path to session + // session(['uploaded_material_invoice' => $fullPath]); + // Notification::make() + // ->title('Material invoice imported successfully.') + // ->success() + // ->send(); + // } + + // } + // }) + // ->visible(function() { + // return Filament::auth()->user()->can('view import material invoice'); + // }), + ExportAction::make() + ->label('Export Invoices') + ->color('warning') + ->exporter(SerialValidationExporter::class) + ->visible(function() { + return Filament::auth()->user()->can('view export invoice'); + }), + ]) + // ->filters([ + // Tables\Filters\TrashedFilter::make(), + // ]) + ->filters([ + Tables\Filters\TrashedFilter::make(), + Filter::make('advanced_filters') + ->label('Advanced Filters') + ->form([ + Radio::make('invoice_type') + ->label('Type ?') + ->boolean() + ->options([ + 'Serial' => 'Serial', + 'Material' => 'Material' + ]) + ->default('Serial') + ->inlineLabel(false) + ->inline(), + Select::make('Plant') + ->label('Select Plant') + ->nullable() + ->options(function () { + return Plant::pluck('name', 'id'); + }) + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get): void { + $set('sticker_master_id', null); + $set('operator_id', null); + }), + TextInput::make('invoice_number') + ->label('Invoice Number') + // ->readOnly() + ->placeholder(placeholder: 'Enter Invoice Number'), + TextInput::make('serial_number') + ->label('Serial Number') + ->placeholder(placeholder: 'Enter Serial Number'), + Select::make('sticker_master_id') + ->label('Search by Item Code') + ->nullable() + ->options(function (callable $get) { + $pId = $get('Plant'); + // if (empty($pId)) { + // return []; + // } + return Item::whereHas('stickerMasters', function ($query) use ($pId) { + if ($pId) { + $query->where('plant_id', $pId); + } + $query->whereHas('invoiceValidations'); + })->pluck('code', 'id'); + }) + ->searchable() + ->reactive(), + Select::make('scanned_status') + ->label('Scanned Status') + ->nullable() + ->options([ + 'Scanned' => 'Scanned', + 'Pending' => 'Pending', + ]) + ->searchable() + ->reactive(), + Select::make('operator_id') + ->label('Created By') + ->nullable() + ->options(function (callable $get) { + $plantId = $get('Plant'); + if (!$plantId) + { + return SerialValidation::whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id'); + } + else + { + return SerialValidation::where('plant_id', $plantId)->whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id'); + } + }) + ->searchable() + ->reactive(), + DateTimePicker::make(name: 'created_from') + ->label('Created From') + ->placeholder(placeholder: 'Select From DateTime') + ->reactive() + ->native(false), + DateTimePicker::make('created_to') + ->label('Created To') + ->placeholder(placeholder: 'Select To DateTime') + ->reactive() + ->native(false), + ]) + ->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'])) + { + Notification::make() + ->title('Please, choose invoice type to filter.') + ->danger() + ->send(); + } + return $query->whereRaw('1 = 0'); + } + + if ($data['invoice_type'] == 'Serial') { + $query->whereNull('quantity'); + + if (!empty($data['scanned_status'])) { + if ($data['scanned_status'] == 'Scanned') { + $query->whereNotNull('scanned_status')->where('scanned_status', '!=', ''); + } elseif ($data['scanned_status'] == 'Pending') { + //$query->whereNull('scanned_status')->orWhere('scanned_status', ''); + $query->where(function ($query) use ($data) { + // if (empty($data['scanned_status']) || $data['scanned_status'] == 'Pending') { + $query->whereNull('scanned_status')->orWhere('scanned_status', '!=', 'Scanned'); + // } + }); + } + } + } elseif ($data['invoice_type'] == 'Material') { + $query->whereNotNull('quantity');//->where('quantity', '>', 0) + + if (!empty($data['scanned_status'])) { + if ($data['scanned_status'] == 'Scanned') { + $query->whereNotNull('serial_number')->where('serial_number', '!=', ''); + } elseif ($data['scanned_status'] == 'Pending') { + $query->where(function ($query) use ($data) { + $query->whereNull('serial_number')->orWhere('serial_number', '=', ''); + }); + } + } + } + + if (!empty($data['Plant'])) { //$plant = $data['Plant'] ?? null + $query->where('plant_id', $data['Plant']); + } + + if (!empty($data['invoice_number'])) { + $query->where('invoice_number', 'like', '%' . $data['invoice_number'] . '%'); + } + + if (!empty($data['serial_number'])) { + $query->where('serial_number', 'like', '%' . $data['serial_number'] . '%'); + } + + if (!empty($data['created_from'])) { + $query->where('created_at', '>=', $data['created_from']); + } + + if (!empty($data['created_to'])) { + $query->where('created_at', '<=', $data['created_to']); + } + + if (!empty($data['operator_id'])) { + $query->where('operator_id', $data['operator_id']); + } + + if (!empty($data['sticker_master_id'])) { + $stickerMasterIds = StickerMaster::where('item_id', $data['sticker_master_id']) + ->pluck('id') + ->toArray(); + + if (!empty($stickerMasterIds)) { + $query->whereIn('sticker_master_id', $stickerMasterIds); + } + } + }) + ->indicateUsing(function (array $data) { + $indicators = []; + + if (!empty($data['Plant'])) { + $indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name'); + } + + if (!empty($data['invoice_number'])) { + $indicators[] = 'Invoice Number: ' . $data['invoice_number']; + } + + if (!empty($data['serial_number'])) { + $indicators[] = 'Serial Number: ' . $data['serial_number']; + } + + if (!empty($data['sticker_master_id'])) { + $itemCode = Item::find($data['sticker_master_id'])->code ?? 'Unknown'; + $indicators[] = 'Item Code: ' . $itemCode; + } + + if (!empty($data['operator_id'])) { + $indicators[] = 'Created By: ' . $data['operator_id']; + } + + if (!empty($data['created_from'])) { + $indicators[] = 'From: ' . $data['created_from']; + } + + if (!empty($data['created_to'])) { + $indicators[] = 'To: ' . $data['created_to']; + } + + if (!empty($data['scanned_status'])) { + $indicators[] = 'Scanned Status: ' . $data['scanned_status']; + } + + return $indicators; + }) + ]) + ->filtersFormMaxHeight('280px') + ->actions([ + Tables\Actions\ViewAction::make(), + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\ForceDeleteBulkAction::make(), + Tables\Actions\RestoreBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListSerialValidations::route('/'), + 'create' => Pages\CreateSerialValidation::route('/create'), + 'view' => Pages\ViewSerialValidation::route('/{record}'), + 'edit' => Pages\EditSerialValidation::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/SerialValidationResource/Pages/CreateSerialValidation.php b/app/Filament/Resources/SerialValidationResource/Pages/CreateSerialValidation.php new file mode 100644 index 0000000..15eea23 --- /dev/null +++ b/app/Filament/Resources/SerialValidationResource/Pages/CreateSerialValidation.php @@ -0,0 +1,2958 @@ +getCancelFormAction(), + ]; + } + + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('create'); + } + + public function processInvoice($invoiceNumber) + { + $invoiceNumber = trim($invoiceNumber); + + $this->showCapacitorInput = false; + + $user = Filament::auth()->user(); + + $operatorName = $user->name; + + $plantId = $this->form->getState()['plant_id']; + + $this->plantId = $plantId; + + $plant = Plant::find($plantId); + + if ($plant) + { + $plantCode = $plant->code; + } + else + { + $plantCode = null; + } + + //..GET SERIAL INVOICE API + + + //.. + + $updateStatus = $this->form->getState()['update_invoice'] ?? null; + + $this->invoiceNumber = trim($this->form->getState()['invoice_number']) ?? $invoiceNumber; + + $invoiceType = null; + //$this->invoiceNumber = $this->invoiceNumber ?? $invoiceNumber; + + $invoiceExist = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->exists(); + + if (!$invoiceExist) { + Notification::make() + ->title("New invoice detected.") + ->info() + ->seconds(1) + ->send(); + $this->dispatch('playNotificationSound'); + + $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); + } + else + { + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + $totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '') + $scanMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count(); + + if($totMQuan > 0) + { + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'scanned_quantity'=> $scanMQuan, + ]); + + if ($totQuan == $scanMQuan) + { + Notification::make() + ->title("Completed: Material Invoice") + ->body("Material invoice '$invoiceNumber' completed the scanning process.
Scan the next 'Material Invoice' to proceed!") + ->warning() + ->seconds(2) + ->send(); + $this->dispatch('playNotificationSound'); + + $filename = $invoiceNumber . '.xlsx'; + $directory = 'uploads/temp'; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + //$fullPath = null; + if ($disk->exists($filePath)) { + //$fullPath = $disk->path($filePath); + $disk->delete($filePath); + } + $this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: false); + } + else + { + Notification::make() + ->title("Start the scanning process!") + ->info() + ->seconds(1) + ->send(); + $this->dispatch('playNotificationSound'); + // $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('refreshMaterialInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + + if($updateStatus == '1') + { + //'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() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $invalidMatCodes = []; + $materialCodes = []; + $missingQuantities = []; + $invalidMatQuan = []; + $hasQuanTypIds = []; + $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
contains no valid data.') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + 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:
' . implode(', ', $uniqueInvalidCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $uniqueMissingQuanCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $uniqueInvalidMatQuan)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $uniqueCodes = array_unique($materialCodes); + + //itemNotFound + $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:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + //plantNotFound + $matchedItems = StickerMaster::with('item') + ->whereHas('item', function ($query) use ($uniqueCodes, $plantId) { + $query->whereIn('code', $uniqueCodes)->where('plant_id', $plantId); + }) + ->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 for choosed plant." : 'The following item codes are not found in database for choosed plant:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $invalidCodes); + + Notification::make() + ->title('Invalid: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $nonNumericQtyCodes = []; + $zeroQtyCodes = []; + $notDivisibleCodes = []; + $hasQuanTyp = false; + + 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 (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + 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; + } + } + else if ($materialType == 3) + { + $hasQuanTyp = true; + $hasQuanTypIds[] = $sticker->id; + } + } + + $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
$codeList") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + }; + + $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 = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $newQuan = -1; + + $inserted = 0; + foreach ($matchedItems as $sticker) + { + if ($newQuan == -1 && !$hasQuanTyp) + { + SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) { + $query->whereNull('serial_number')->orWhere('serial_number', ''); + }) + ->forceDelete(); //->delete(); + + $newQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + } + else if ($newQuan == -1 && $hasQuanTyp) + { + SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) { + $query->whereNull('serial_number')->orWhere('serial_number', ''); + })->whereNotIn('sticker_master_id', $hasQuanTypIds) + ->forceDelete(); //->delete(); + + $newQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + } + + $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 (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + if ($excelCode == $code && is_numeric($excelMatQty)) { + $totalExcelQty += $excelMatQty; // Sum up the quantities + } + } + + $existQty = SerialValidation::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) { + SerialValidation::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 (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + if ($excelCode == $code && is_numeric($excelMatQty)) { + $totalExcelQty += $excelMatQty; // Sum up the quantities + } + } + + $existQty = SerialValidation::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) { + SerialValidation::create([ + 'sticker_master_id' => $sticker->id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'quantity' => $bundleQty, + 'operator_id'=> $operatorName, + ]); + $inserted++; + } + } + } + } + else if ($materialType == 3) + { + $totalExcelQty = 0; + + foreach ($rows as $index => $row) + { + if ($index == 0) continue; // Skip header + + $excelCode = trim($row[0]); + $excelMatQty = trim($row[1]); + + if (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + if ($excelCode == $code && is_numeric($excelMatQty)) { + $totalExcelQty += $excelMatQty; + } + } + + $existEmpRecQty = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) { + $query->whereNull('serial_number')->orWhere('serial_number', ''); + })->where('sticker_master_id', $sticker->id)->first(); + $existEmpQty = $existEmpRecQty ? $existEmpRecQty->quantity : 0; + + $existComQty = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) { + $query->whereNotNull('serial_number')->where('serial_number', '!=', ''); + }) + ->where('sticker_master_id', $sticker->id) + ->sum(column: 'quantity'); + $existComQty = $existComQty ? $existComQty : 0; + + // 8 = 3 + 5 // 8 = 5 + 3 // 8 = 0 + 8 // 8 = 8 + 0 + // 8 = 3 + 5 // 8 = 5 + 3 // 8 = 0 + 8 // 8 = 8 + 0 + // 0 = 0 + 0 + $existQty = $existEmpQty + $existComQty; + + // 8 <= 11 // 8 <= 8 // 8 <= 11 // 8 <= 9 + // 8 <= 7 // 8 <= 7 // 8 <= 7 // 8 <= 7 + // 0 <= 5 + + if ($existQty <= $totalExcelQty) + { + // 6 = 11 - 5 // 5 = 8 - 3 // 3 = 11 - 8 // 9 = 9 - 0 + // 5 = 5 - 0 + $newInsQty = $totalExcelQty - $existComQty; + + // 3 > 0 // 5 > 0 // 0 > 0 // 8 > 0 + // 0 > 0 + if($existEmpQty > 0) // update + { + // 3 = 6 // 5 = 5 // 0 = 3 // 8 = 9 + // 0 = 5 + if($existEmpQty == $newInsQty) { continue; } + // $existEmpRecQty->delete(); + $existEmpRecQty->update([ + 'quantity' => $newInsQty, + 'operator_id'=> $operatorName, + 'updated_at' => now(), + ]); + $newQuan--; + $inserted++; + } + else if ($newInsQty > 0) // if ($sticker) // create + { + SerialValidation::create([ + 'sticker_master_id' => $sticker->id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'quantity' => $newInsQty, + 'operator_id'=> $operatorName, + ]); + $inserted++; + } + } + // 8 > 7 // 8 > 7 // 8 > 7 // 8 > 7 + else + { + // 2 = 7 - 5 // 4 = 7 - 3 // -1 = 7 - 8 // 7 = 7 - 0 + $newInsQty = $totalExcelQty - $existComQty; + + // 3 > 0 // 5 > 0 // 0 > 0 // 8 > 0 + if($existEmpQty > 0) // update + { + // 3 = 2 // 5 = 4 // 0 = -1 // 8 = 7 + if($existEmpQty == $newInsQty) { continue; } + // $existEmpRecQty->delete(); + $existEmpRecQty->update([ + 'quantity' => $newInsQty, + 'operator_id'=> $operatorName, + 'updated_at' => now(), + ]); + $newQuan--; + $inserted++; + } + else if ($newInsQty > 0) // create + { + SerialValidation::create([ + 'sticker_master_id' => $sticker->id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'quantity' => $newInsQty, + 'operator_id'=> $operatorName, + ]); + $inserted++; + } + } + + } + } + + if ($inserted > 0 || $oldQuan != $newQuan) + { + Notification::make() + ->title("Material invoice successfully updatad.") + ->success() + ->seconds(1) + ->send(); + + Notification::make() + ->title("Start the scanning process!") + ->body("'$inserted' new material invoice records were inserted.") + ->info() + // ->success() + ->seconds(1) + ->send(); + $this->dispatch('playNotificationSound'); + + // Update total quantity in the form + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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, isSerial: false); + } + 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() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + $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; + } + else + { + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'scanned_quantity'=> $scanSQuan, + ]); + //$hasRecords = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->first()->stickerMasterRelation->material_type ?? null; + // $this->dispatch('refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + + if ($totQuan == $scanSQuan) + { + Notification::make() + ->title("Completed: Serial Invoice") + ->body("Serial invoice '$invoiceNumber' completed the scanning process.
Scan the next 'Serial Invoice' to proceed.!") + ->warning() + ->seconds(2) + ->send(); + $this->dispatch('playNotificationSound'); + + $filename = $invoiceNumber . '.xlsx'; + $directory = 'uploads/temp'; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + //$fullPath = null; + if ($disk->exists($filePath)) { + //$fullPath = $disk->path($filePath); + $disk->delete($filePath); + } + $this->dispatch('playNotificationSound'); + $this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true); + } + else + { + Notification::make() + ->title("Start the scanning process!") + ->info() + ->seconds(1) + ->send(); + $this->dispatch('playNotificationSound'); + $this->dispatch('refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + + if($updateStatus == '1') + { + $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 + // '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() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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
contains no valid data.') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
' . implode(', ', $uniqueInvalidCodes)) + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $uniqueCodes = array_unique($materialCodes); + + //itemNotFound + $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:
' . implode(', ', $missingCodes); //->where('plant_id', $plantId) + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + //plantNotFound + $matchedItems = StickerMaster::with('item') + ->whereHas('item', function ($query) use ($uniqueCodes, $plantId) { + $query->whereIn('code', $uniqueCodes)->where('plant_id', $plantId); + }) + ->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 for choosed plant." : 'The following item codes are not found in database for choosed plant:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $invalidCodes); + + Notification::make() + ->title('Invalid: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $missPackCodes = $matchedItems + ->filter(fn ($sticker) => empty($sticker->tube_sticker_motor) && empty($sticker->pack_slip_motor) && empty($sticker->tube_sticker_pump) && empty($sticker->pack_slip_pump) && empty($sticker->tube_sticker_pumpset) && empty($sticker->pack_slip_pumpset) && empty($sticker->panel_box_code)) //filter invalid + ->pluck('item.code') + ->toArray(); + + if (!empty($missPackCodes)) + { + $missingCount = count($missPackCodes); + + $message = $missingCount > 10 ? "'$missingCount' item codes doesn't have valid package type to proceed!" : "The following 'Item Code' doesn't have valid package type:
" . implode(', ', $missPackCodes); + + Notification::make() + ->title('Invalid: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $uniqueMissingSerials)) + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + 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:
' . implode(', ', $uniqueInvalidSerCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
' . implode(', ', $uniqueDupSerCodes)) + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $oldQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $newQuan = 0; + + $inserted = 0; + foreach ($rows as $index => $row) + { + if ($index == 0) // Skip header; + { + SerialValidation::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', ''); + }) + ->forceDelete(); //->delete(); + + $newQuan = SerialValidation::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 = SerialValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->exists(); //->pluck('serial_number') + + 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) { + SerialValidation::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() + ->seconds(1) + ->send(); + + Notification::make() + ->title("Start the scanning process!") + ->body("'$inserted' new serial invoice records were inserted.") + ->info() + // ->success() + ->seconds(1) + ->send(); + + $this->dispatch('playNotificationSound'); + + // Update total quantity in the form + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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, isSerial: true); + } + 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() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $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; + } + } + + $filename = $invoiceNumber . '.xlsx'; + $directory = 'uploads/temp'; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + $fullPath = null; //$fullPath = $disk->path($filePath); + + // Check if file exists + if ($disk->exists($filePath)) { + $fullPath = $disk->path($filePath); + //$fullPath = session('uploaded_invoice_path'); + // Notification::make() + // ->title('File exists.') + // ->success() + // ->seconds(2) + // ->send(); + } else { + Notification::make() + ->title('Invoice Not Found') + ->body("Import the scanned 'Invoice' file to proceed..!") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + $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; + } + + if (!file_exists($fullPath)) + { + Notification::make() + ->title('Invoice file doesn\'t exist.') + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + return; + + } + + // Extract filename without extension (e.g., "3RA0018732") + $uploadedFilename = pathinfo($fullPath, PATHINFO_FILENAME); + + // Compare with invoice number + if ($uploadedFilename != $invoiceNumber) { + Notification::make() + ->title("Uploaded file name does not match the invoice number.") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + return; + } + + if ($fullPath && file_exists($fullPath)) + { + // Now you can read/process the file here + $rows = Excel::toArray(null, $fullPath)[0]; + // $collection = Excel::toCollection(null, $fullPath); + // $rows = $collection[0]->toArray(); + + // $collection = Excel::toCollection(new ExcelImport, $fullPath); + // // Convert the collection to an array + // $rows = $collection->toArray(); + + // $excelImport = new ExcelImport(); + // // Import the Excel file + // Excel::import($excelImport, $fullPath); + // // Get the rows + // $rows = $excelImport->getRows(); + + if((count($rows) - 1) <= 0) + { + Notification::make() + ->title('Records Not Found') + ->body("Import the valid 'Invoice' file to proceed..!") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + foreach ($rows as $index => $row) + { + if ($index == 0) continue; + + $materialCode = trim($row[0]); + + if (!empty($materialCode)) { + if(Str::length($materialCode) < 6) + { + continue; + } + else + { + $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 + }); + if($sticker->exists()) + { + if($sticker->first()->material_type && !empty($sticker->first()->material_type)) + { + $invoiceType = "M"; + break; + } + else + { + $invoiceType = "S"; + break; + } + } + else + { + continue; + } + } + } + else + { + continue; + } + } + + if($invoiceType == 'M') + { + $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
contains no valid data.') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + 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:
' . implode(', ', $uniqueInvalidCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $uniqueMissingQuanCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $uniqueInvalidMatQuan)) + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $uniqueCodes = array_unique($materialCodes); + + //itemNotFound + $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:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + //plantNotFound + $matchedItems = StickerMaster::with('item') + ->whereHas('item', function ($query) use ($uniqueCodes, $plantId) { + $query->whereIn('code', $uniqueCodes)->where('plant_id', $plantId); + }) + ->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 for choosed plant." : 'The following item codes are not found in database for choosed plant:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + 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:
" . implode(', ', $invalidCodes); + + Notification::make() + ->title('Invalid: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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 (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + 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
$codeList") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + }; + + $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 + { + $inserted = 0; + foreach ($matchedItems as $sticker) + { + $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 (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + if ($excelCode == $code && is_numeric($excelMatQty)) { + $totalExcelQty += $excelMatQty; // Sum up the quantities + } + } + + for ($i = 0; $i < $totalExcelQty; $i++) + { + if ($sticker) { + SerialValidation::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 (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + if ($excelCode == $code && is_numeric($excelMatQty)) { + $totalExcelQty += $excelMatQty; // Sum up the quantities + } + } + + for ($i = 0; $i < ($totalExcelQty/$bundleQty); $i++) + { + if ($sticker) { + SerialValidation::create([ + 'sticker_master_id' => $sticker->id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'quantity' => $bundleQty, + 'operator_id'=> $operatorName, + ]); + $inserted++; + } + } + } + else if ($materialType == 3) + { + $totalExcelQty = 0; + + foreach ($rows as $index => $row) + { + if ($index == 0) continue; // Skip header + + $excelCode = trim($row[0]); + $excelMatQty = trim($row[1]); + + if (empty($excelCode) || empty($excelMatQty)) { + continue; + } + + if ($excelCode == $code && is_numeric($excelMatQty)) { + $totalExcelQty += $excelMatQty; // Sum up the quantities + } + } + + if ($sticker) { + SerialValidation::create([ + 'sticker_master_id' => $sticker->id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'quantity' => $totalExcelQty, + 'operator_id'=> $operatorName, + ]); + $inserted++; + } + } + } + + if ($inserted > 0) + { + Notification::make() + ->title("Start the scanning process!") + ->body("'$inserted' material invoice records were inserted.") + ->info() + // ->success() + ->seconds(1) + ->send(); + + // Update total quantity in the form + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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, isSerial: false); + } + 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('refreshMaterialInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + } + } + else + { + Notification::make() + ->title("Import Failed: Material Invoice") + ->body("No new records were inserted for Material Invoice: '$invoiceNumber'.") + ->danger() + ->seconds(2) + ->send(); + + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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 if($invoiceType == 'S') + { + $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
contains no valid data.') + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
' . implode(', ', $uniqueInvalidCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $uniqueCodes = array_unique($materialCodes); + + //itemNotFound + $matchedItems = StickerMaster::with('item') + ->whereHas('item', function ($query) use ($uniqueCodes) { + $query->whereIn('code', $uniqueCodes); + }) + ->get(); + + // // Get all codes that exist in the database for the given plant_id + // $existingCodes = StickerMaster::where('plant_id', $plantId) + // ->whereHas('item', function ($query) use ($uniqueCodes) { + // $query->whereIn('code', $uniqueCodes); + // }) + // ->with('item') // Eager load for performance + // ->get() + // ->pluck('item.code') + // ->toArray(); + + $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:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + //plantNotFound + $matchedItems = StickerMaster::with('item') + ->whereHas('item', function ($query) use ($uniqueCodes, $plantId) { + $query->whereIn('code', $uniqueCodes)->where('plant_id', $plantId); + }) + ->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 for choosed plant." : 'The following item codes are not found in database for choosed plant:
' . implode(', ', $missingCodes); + + Notification::make() + ->title('Unknown: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $invalidCodes); + + Notification::make() + ->title('Invalid: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + + // $missPackCodes = $matchedItems + // ->filter(fn ($sticker) => empty($sticker->tube_sticker_motor) && empty($sticker->pack_slip_motor) && empty($sticker->tube_sticker_pump) && empty($sticker->pack_slip_pump) && empty($sticker->tube_sticker_pumpset) && empty($sticker->pack_slip_pumpset) && empty($sticker->panel_box_code)) + // ->pluck('item.code') + // ->toArray(); + + $missPackCodes = $matchedItems + ->filter(fn ($sticker) => empty($sticker->pack_slip_motor) && empty($sticker->pack_slip_pump) && empty($sticker->pack_slip_pumpset) && empty($sticker->panel_box_code)) + ->pluck('item.code') + ->toArray(); + + if (!empty($missPackCodes)) + { + $missingCount = count($missPackCodes); + + $message = $missingCount > 10 ? "'$missingCount' item codes doesn't have valid package type to proceed!" : "The following 'Item Code' doesn't have valid package type:
" . implode(', ', $missPackCodes); + + Notification::make() + ->title('Invalid: Item Codes') + ->body($message) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
" . implode(', ', $uniqueMissingSerials)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
' . implode(', ', $uniqueInvalidSerCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + 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:
' . implode(', ', $uniqueDupSerCodes)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $existingSerialNumbers = SerialValidation::whereIn('serial_number', $serialNumbers)->where('plant_id', $plantId)->pluck('serial_number')->toArray(); + + // If there are duplicates, notify and stop the process + if (!empty($existingSerialNumbers)) { + Notification::make() + ->title('Duplicate Serial Numbers') + ->body('The following serial numbers are already exist in database:
' . implode(', ', $existingSerialNumbers)) + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + + $inserted = 0; + foreach ($rows as $index => $row) + { + if ($index == 0) continue; + + $materialCode = trim($row[0]); + $serialNumber = trim($row[1]); + + if (empty($materialCode) || empty($serialNumber)) { + 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) { + SerialValidation::create([ + 'sticker_master_id' => $sticker->id, + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => $serialNumber, + 'operator_id'=> $operatorName, + ]); + $inserted++; + } + } + + if ($inserted > 0) + { + Notification::make() + ->title("Start the scanning process!") + ->body("'$inserted' serial invoice records were inserted.") + ->info() + // ->success() + ->seconds(1) + ->send(); + $this->dispatch('playNotificationSound'); + + // Update total quantity in the form + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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, isSerial: true); + } + 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("Import Failed: Serial Invoice") + ->body("No new records were inserted for Serial Invoice : '$invoiceNumber'.") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $totalQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scannedQuantity = SerialValidation::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('Invoice Type Not Found') + ->body("Import the valid 'Invoice' file to proceed..!") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + return; + } + } + } + + protected function refreshInvoiceTable() + { + $this->plantId = $this->form->getState()['plant_id'] ?? ''; + $this->invoiceNumber = $this->form->getState()['invoice_number'] ?? ''; + + if (!empty($this->invoiceNumber)) { + $hasInvoice = SerialValidation::where('invoice_number', $this->invoiceNumber)->where('plant_id', $this->plantId)->first(); + + if (empty($hasInvoice) || !$hasInvoice) + { + $this->dispatch('refreshEmptyInvoice', invoiceNumber: $this->invoiceNumber, plantId: $this->plantId); + } + else + { + $totalQuantity = SerialValidation::where('invoice_number', $this->invoiceNumber)->where('plant_id', $this->plantId)->count(); + $scannedQuantity = SerialValidation::where('invoice_number', $this->invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $this->plantId)->count(); + if ($totalQuantity == $scannedQuantity) + { + $this->dispatch('refreshCompletedInvoice', invoiceNumber: $this->invoiceNumber, plantId: $this->plantId, isSerial: true); + } + else + { + $hasRecords = $hasInvoice->stickerMasterRelation->material_type ?? null; + $this->dispatch( (!empty($hasRecords) && $hasRecords) ? 'refreshMaterialInvoiceData' : 'refreshInvoiceData', invoiceNumber: $this->invoiceNumber, plantId: $this->plantId); + } + } + } + } + + public function processSerialNumber($serNo) + { + $serNo = trim($serNo); + $user = Filament::auth()->user(); + $operatorName = $user->name; + + $serialNumber = null; + $plantId = $this->form->getState()['plant_id']; + $this->plantId = $plantId; + + if (!preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})(?:\/[MmPpCc])?$/', $serNo, $matches)) + { + Notification::make() + ->danger() + ->title('Invalid Serial QR Format') + ->body('Scan valid Serial QR code proceed!
Sample formats are:
123456|1234567890123/M (or)
123456|1234567890123/P (or)
123456|1234567890123/C (or)
123456|1234567890123') + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => null, + 'serial_number' => null, + // 'total_quantity' => $totQuan, + // 'update_invoice' => false, + // 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + + if (preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})(?:\/[MmPpCc])?$/', $serNo, $matches)) + { + $itemCode = $matches[1]; + $serialNumber = $matches[2]; + + // // Check if it ends with /M, /P, /C etc. + // $isMarkM = preg_match('/\/[Mm]$/', $serialNumber); + // $isMarkP = preg_match('/\/[Pp]$/', $serialNumber); + // $isMarkC = preg_match('/\/[Cc]$/', $serialNumber); + $isMarkM = preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})\/[Mm]?$/', $serNo) ? true : false; + $isMarkP = preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})\/[Pp]?$/', $serNo) ? true : false; + $isMarkC = preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})\/[Cc]?$/', $serNo) ? true : false; + $isMarkPs = (!$isMarkM && !$isMarkP && !$isMarkC) ? true : false; + //dd($serialNumber, $isMarkM, $isMarkP, $isMarkC, $isMarkPs); + + $serialNumber = preg_replace('/\/[MmPpCc]$/', '', $serialNumber); + + $record = SerialValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->first(); + + if (!$record) { + Notification::make() + ->title('Serial Number Not Found
Serial \''.$serialNumber.'\' not found in database for choosed plant.
') + // ->body("Serial '$serialNumber' not found in database for choosed plant.").......... + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('play-warn-sound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => null, + 'serial_number' => null, + // 'total_quantity' => $totQuan, + // 'update_invoice' => false, + // 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + + $invoiceNumber = $record->invoice_number; + + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + + $record = SerialValidation::where('serial_number', $serialNumber) + ->where('plant_id', $plantId) + ->whereHas('stickerMasterRelation.item', function ($query) use ($itemCode) { + $query->where('plant_id', $this->plantId)->where('code', $itemCode); + }) + ->first(); + + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + if (!$record) { + Notification::make() + ->title('Unknown: Item Code') + ->body("Item code '$itemCode' with serial number '$serialNumber' not found.") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => null, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + + // $hasMotorQr = $record->stickerMasterRelation->tube_sticker_motor ?? null; + // $hasPumpQr = $record->stickerMasterRelation->tube_sticker_pump ?? null; + // $hasPumpSetQr = $record->stickerMasterRelation->tube_sticker_pumpset ?? null; + + + // if (!$hasMotorQr && !$hasPumpQr && !$hasPumpSetQr && !$hasCapacitorQr) + // { + + // } + + $hasMotorQr = $record->stickerMasterRelation->pack_slip_motor ?? null; + $hasPumpQr = $record->stickerMasterRelation->pack_slip_pump ?? null; + $hasPumpSetQr = $record->stickerMasterRelation->pack_slip_pumpset ?? null; + $hasCapacitorQr = $record->stickerMasterRelation->panel_box_code ?? null; + + $hadMotorQr = $record->motor_scanned_status ?? null; + $hadPumpQr = $record->pump_scanned_status ?? null; + $hadPumpSetQr = $record->scanned_status_set ?? null; + $hadCapacitorQr = $record->capacitor_scanned_status ?? null; + + if (!$hasMotorQr && !$hasPumpQr && !$hasPumpSetQr && !$hasCapacitorQr) + { + Notification::make() + ->title('Invalid: Item Code') + ->body("Scanned 'Item Code' doesn't have valid package type to proceed!") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => null, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + + if ($isMarkM) { + + // $record = SerialValidation::where('serial_number', $serialNumber) + // ->where('plant_id', $plantId) + // ->first(); + // $invoiceNumber = $record->invoice_number; + + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + if (!$hasMotorQr) + { + Notification::make() + ->title('Unknown: Motor QR') + ->body("Scanned 'Item Code' doesn't have 'Motor' QR to proceed!") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + return; + } + else if($hadMotorQr == $hasMotorQr) + { + Notification::make() + ->title('Duplicate: Motor QR') + ->body("Scanned 'Motor' serial number already completed the scanning process.") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + return; + } + + $packCnt = 1; + $scanCnt = 1; + $record->motor_scanned_status = 1; + //if($hadPumpQr == $hasPumpQr && $hadPumpSetQr == $hasPumpSetQr) + if($hasPumpQr || $hasPumpSetQr || $hasCapacitorQr) + { + $packCnt = $hasPumpQr ? $packCnt + 1 : $packCnt; + $packCnt = $hasPumpSetQr ? $packCnt + 1 : $packCnt; + $packCnt = $hasCapacitorQr ? $packCnt + 1 : $packCnt; + + $scanCnt = $hadPumpQr ? $scanCnt + 1: $scanCnt; + $scanCnt = $hadPumpSetQr ? $scanCnt + 1: $scanCnt; + $scanCnt = $hadCapacitorQr ? $scanCnt + 1: $scanCnt; + + if($packCnt == $scanCnt) + { + $record->scanned_status = 'Scanned'; + } + } + else + { + $record->scanned_status = 'Scanned'; + } + $record->operator_id = $operatorName; + $record->save(); + + // Notification::make() + // ->title('Success: Motor QR') + // ->body("'Motor' QR scanned status updated, Scan next QR.") + // ->success() // commented + // ->seconds(2) + // ->send(); + + $scannedQuantity = SerialValidation::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' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scannedQuantity, + ]); + + // $invoiceNumber = $this->form->getState()['invoice_number']; + // $this->invoiceNumber = $invoiceNumber; + + + + // $totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '') + // $scanMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count(); + + if($totQuan == $scannedQuantity) + { + Notification::make() + ->title('Completed: Serial Invoice') + ->body("Serial invoice '$invoiceNumber' completed the scanning process.
Scan the next 'Serial Invoice' to proceed!") + ->success() + ->seconds(2) + ->send(); + $this->dispatch('playNotificationSound'); + + + $filename = $invoiceNumber . '.xlsx'; + $directory = 'uploads/temp'; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + //$fullPath = null; + if ($disk->exists($filePath)) { + //$fullPath = $disk->path($filePath); + $disk->delete($filePath); + } + $this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true); + } + else + { + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + // $this->refreshInvoiceTable(); + } + return; + } + else if ($isMarkP) { + + // $record = SerialValidation::where('serial_number', $serialNumber) + // ->where('plant_id', $plantId) + // ->first(); + // $invoiceNumber = $record->invoice_number; + + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + if (!$hasPumpQr) + { + Notification::make() + ->title('Unknown: Pump QR') + ->body("Scanned 'Item Code' doesn't have 'Pump' QR to proceed!") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + else if($hadPumpQr == $hasPumpQr) + { + Notification::make() + ->title('Duplicate: Pump QR') + ->body("Scanned 'Pump' serial number already completed the scanning process.") + ->danger() + ->seconds(2) + ->send(); + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + + $packCnt = 1; + $scanCnt = 1; + $record->pump_scanned_status = 1; + // if($hadMotorQr == $hasMotorQr && $hadPumpSetQr == $hasPumpSetQr && ($hadCapacitorQr == '1' && $hasCapacitorQr)) + if($hasMotorQr || $hasPumpSetQr || $hasCapacitorQr) + { + $packCnt = $hasMotorQr ? $packCnt + 1 : $packCnt; + $packCnt = $hasPumpSetQr ? $packCnt + 1 : $packCnt; + $packCnt = $hasCapacitorQr ? $packCnt + 1 : $packCnt; + + $scanCnt = $hadMotorQr ? $scanCnt + 1: $scanCnt; + $scanCnt = $hadPumpSetQr ? $scanCnt + 1: $scanCnt; + $scanCnt = $hadCapacitorQr ? $scanCnt + 1: $scanCnt; + + if($packCnt == $scanCnt) + { + $record->scanned_status = 'Scanned'; + } + } + else + { + $record->scanned_status = 'Scanned'; + } + $record->operator_id = $operatorName; + $record->save(); + + // Notification::make() + // ->title('Success: Pump QR') + // ->body("'Pump' QR scanned status updated, Scan next QR.") + // ->success() // commented + // ->seconds(2) + // ->send(); + + $scannedQuantity = SerialValidation::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' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scannedQuantity, + ]); + + if($totQuan == $scannedQuantity) + { + Notification::make() + ->title('Completed: Serial Invoice') + ->body("Serial invoice '$invoiceNumber' completed the scanning process.
Scan the next 'Serial Invoice' to proceed!") + ->success() + ->seconds(2) + ->send(); + + $this->dispatch('playNotificationSound'); + + $filename = $invoiceNumber . '.xlsx'; + $directory = 'uploads/temp'; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + //$fullPath = null; + if ($disk->exists($filePath)) { + //$fullPath = $disk->path($filePath); + $disk->delete($filePath); + } + $this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true); + } + else + { + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + // $this->refreshInvoiceTable(); + } + return; + } + elseif ($isMarkC) { + // $record = SerialValidation::where('serial_number', $serialNumber) + // ->where('plant_id', $plantId) + // ->first(); + // $invoiceNumber = $record->invoice_number; + + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + if (!$hasCapacitorQr) + { + Notification::make() + // ->title('Unknown: Capacitor QR') + ->title('Missing: Panel Box Code') + // ->body("Panel Box Code is not available for Item Code : '$itemCode'.") + ->body("Scanned 'Item Code' doesn't have 'Panel Box Code' to proceed!") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + return; + } + else if($hadCapacitorQr == '1' && $hasCapacitorQr) + { + Notification::make() + ->title('Duplicate: Capacitor QR') + ->body("Scanned 'Capacitor' serial number already completed the scanning process.") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + return; + } + + //hereToUpdate + //$this->dispatch('openCapacitorModal'); + $this->dispatch('openCapacitorModal', itemCode: $itemCode, serialNumber: $serialNumber, plantId: $plantId); + + $scannedQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + // $invoiceNumber = $this->form->getState()['invoice_number']; + // $this->invoiceNumber = $invoiceNumber; + + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + $totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '') + $scanMQuan = SerialValidation::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' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scannedQuantity, + ]); + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + // $this->refreshInvoiceTable(); + return; + } + elseif ($isMarkPs) + { + // $record = SerialValidation::where('serial_number', $serialNumber) + // ->where('plant_id', $plantId) + // ->first(); + // $invoiceNumber = $record->invoice_number; + $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + + if (!$hasPumpSetQr) + { + Notification::make() + ->title('Unknown: Pump Set QR') + ->body("Scanned 'Item Code' doesn't have 'Pump Set' QR to proceed!") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + $this->dispatch('refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + return; + } + else if($hadPumpSetQr == $hasPumpSetQr) + { + Notification::make() + ->title('Duplicate: Pump Set QR') + ->body("Scanned 'Pump Set' serial number already completed the scanning process.") + ->danger() + ->seconds(2) + ->send(); + + $this->dispatch('playWarnSound'); + + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scanSQuan, + ]); + return; + } + + // Fill the invoice_number field in the form immediately + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => $serialNumber, + 'total_quantity' => $totQuan, + 'update_invoice' => false, + ]); + + $packCnt = 1; + $scanCnt = 1; + $record->scanned_status_set = 1; + // if($hadMotorQr == $hasMotorQr && $hadPumpQr == $hasPumpQr && ($hadCapacitorQr == '1' && $hasCapacitorQr)) + if($hasMotorQr || $hasPumpQr || $hasCapacitorQr) + { + $packCnt = $hasMotorQr ? $packCnt + 1 : $packCnt; + $packCnt = $hasPumpQr ? $packCnt + 1 : $packCnt; + $packCnt = $hasCapacitorQr ? $packCnt + 1 : $packCnt; + + $scanCnt = $hadMotorQr ? $scanCnt + 1: $scanCnt; + $scanCnt = $hadPumpQr ? $scanCnt + 1: $scanCnt; + $scanCnt = $hadCapacitorQr ? $scanCnt + 1: $scanCnt; + + if($packCnt == $scanCnt) + { + $record->scanned_status = 'Scanned'; + } + } + else + { + $record->scanned_status = 'Scanned'; + } + $record->operator_id = $operatorName; + $record->save(); + + // Notification::make() + // ->title('Success: Pump Set QR') + // ->body("'Pump Set' QR scanned status updated, Scan next QR.") + // ->success() // commented + // ->seconds(2) + // ->send(); + + + $scannedQuantity = SerialValidation::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' => $totQuan, + 'update_invoice' => false, + 'scanned_quantity'=> $scannedQuantity, + ]); + // $invoiceNumber = $this->form->getState()['invoice_number']; + // $this->invoiceNumber = $invoiceNumber; + + $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + $totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '') + $scanMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count(); + + if($totQuan == $scannedQuantity) + { + Notification::make() + ->title('Completed: Serial Invoice') + ->body("Serial invoice '$invoiceNumber' completed the scanning process.
Scan the next 'Serial Invoice' to proceed!") + ->success() + ->seconds(2) + ->send(); + + $this->dispatch('playNotificationSound'); + + $filename = $invoiceNumber . '.xlsx'; + $directory = 'uploads/temp'; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + //$fullPath = null; + if ($disk->exists($filePath)) { + //$fullPath = $disk->path($filePath); + $disk->delete($filePath); + } + $this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true); + } + else + { + $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); + // $this->refreshInvoiceTable(); + } + return; + } + } + + // $invoiceNumber = $this->form->getState()['invoice_number']; + // $this->invoiceNumber = $invoiceNumber; + + // $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count(); + // $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count(); + // $totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '') + // $scanMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count(); + + //.. + + + } + + public function getHeading(): string + { + return 'Scan Serial Validation'; + } +} diff --git a/app/Filament/Resources/SerialValidationResource/Pages/EditSerialValidation.php b/app/Filament/Resources/SerialValidationResource/Pages/EditSerialValidation.php new file mode 100644 index 0000000..5de6c51 --- /dev/null +++ b/app/Filament/Resources/SerialValidationResource/Pages/EditSerialValidation.php @@ -0,0 +1,22 @@ +