From 48f90c7b41421c5f669b5964bdda715ec8554603 Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Tue, 10 Mar 2026 09:05:23 +0530 Subject: [PATCH] Added stock data master importer and exporter pages --- .../Exports/StockDataMasterExporter.php | 89 +++++++ .../Imports/StockDataMasterImporter.php | 245 ++++++++++++++++++ 2 files changed, 334 insertions(+) create mode 100644 app/Filament/Exports/StockDataMasterExporter.php create mode 100644 app/Filament/Imports/StockDataMasterImporter.php diff --git a/app/Filament/Exports/StockDataMasterExporter.php b/app/Filament/Exports/StockDataMasterExporter.php new file mode 100644 index 0000000..93f7878 --- /dev/null +++ b/app/Filament/Exports/StockDataMasterExporter.php @@ -0,0 +1,89 @@ +label('NO') + ->state(function ($record) use (&$rowNumber) { + // Increment and return the row number + return ++$rowNumber; + }), + ExportColumn::make('plant.code') + ->label('PLANT CODE'), + ExportColumn::make('stickerMaster.item.code') + ->label('ITEM CODE'), + ExportColumn::make('type') + ->label('TYPE') + ->formatStateUsing(fn ($state) => match ($state) { + '0' => 'FG', + '1' => 'SFG', + default => '-', + }), + ExportColumn::make('location') + ->label('LOCATION'), + ExportColumn::make('bin') + ->label('BIN'), + ExportColumn::make('serial_number') + ->label('SERIAL NUMBER'), + ExportColumn::make('batch') + ->label('BATCH'), + ExportColumn::make('quantity') + ->label('QUANTITY'), + ExportColumn::make('doc_no') + ->label('DOCUMENT NUMBER'), + ExportColumn::make('motor_scanned_status') + ->label('MOTOR SCANNED STATUS'), + ExportColumn::make('pump_scanned_status') + ->label('PUMP SCANNED STATUS'), + ExportColumn::make('capacitor_scanned_status') + ->label('CAPACITOR SCANNED STATUS'), + ExportColumn::make('scanned_status_set') + ->label('SCANNED STATUS SET'), + ExportColumn::make('panel_box_item_code') + ->label('PANEL BOX ITEM CODE'), + ExportColumn::make('panel_box_supplier') + ->label('PANEL BOX SUPPLIER'), + ExportColumn::make('panel_box_sno') + ->label('PANEL BOX SNO'), + ExportColumn::make('scanned_status') + ->label('SCANNED STATUS'), + ExportColumn::make('scanned_count') + ->label('SCANNED COUNT'), + ExportColumn::make('created_at') + ->label('CREATED AT'), + ExportColumn::make('updated_at') + ->label('UPDATED AT'), + ExportColumn::make('created_by') + ->label('CREATED BY'), + ExportColumn::make('updated_by') + ->label('UPDATED BY'), + ExportColumn::make('deleted_at') + ->label('DELETED AT') + ->enabledByDefault(false), + ]; + } + + public static function getCompletedNotificationBody(Export $export): string + { + $body = 'Your stock data master export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.'; + + if ($failedRowsCount = $export->getFailedRowsCount()) { + $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.'; + } + + return $body; + } +} diff --git a/app/Filament/Imports/StockDataMasterImporter.php b/app/Filament/Imports/StockDataMasterImporter.php new file mode 100644 index 0000000..ed5bcfb --- /dev/null +++ b/app/Filament/Imports/StockDataMasterImporter.php @@ -0,0 +1,245 @@ +requiredMapping() + ->exampleHeader('PLANT CODE') + ->example('1000') + ->label('PLANT CODE') + ->relationship(resolveUsing: 'code') + ->rules(['required']), + ImportColumn::make('type') + ->requiredMapping() + ->exampleHeader('TYPE') + ->example('FG/SFG') + ->label('TYPE'), + ImportColumn::make('location') + ->requiredMapping() + ->exampleHeader('LOCATION') + ->example('2001') + ->label('LOCATION') + ->rules(['required']), + ImportColumn::make('item_reference')// stickerMaster + ->requiredMapping() + ->exampleHeader('ITEM CODE') + ->example('123456') + ->label('ITEM CODE') + ->rules(['required']), + ImportColumn::make('serial_number') + ->requiredMapping() + ->exampleHeader('SERIAL NUMBER') + ->example('200235236622') + ->label('SERIAL NUMBER'), + ImportColumn::make('batch') + ->requiredMapping() + ->exampleHeader('BATCH') + ->example('20102') + ->label('BATCH'), + ImportColumn::make('quantity') + ->requiredMapping() + ->exampleHeader('QUANTITY') + ->example('1') + ->label('QUANTITY'), + ImportColumn::make('doc_no') + ->requiredMapping() + ->exampleHeader('DOCUMENT NUMBER') + ->example('156566') + ->label('DOCUMENT NUMBER'), + ]; + } + + public function resolveRecord(): ?StockDataMaster + { + $warnMsg = []; + $plantId = null; + $stickId = null; + + $plantCod = $this->data['plant']; + $typeValue = $this->data['type']; + $iCode = trim($this->data['item_reference']) ?? null; + $location = trim($this->data['location']) ?? null; + $serialNumber = trim($this->data['serial_number']) ?? null; + $batch = trim($this->data['batch']) ?? null; + $quantity = trim($this->data['quantity']) ?? null; + $docNo = trim($this->data['doc_no']) ?? null; + + $user = Filament::auth()->user(); + + $operatorName = $user->name; + + + if ($plantCod == null || $plantCod == '') { + $warnMsg[] = "Plant code can't be empty!"; + } + else if ($typeValue == null || $typeValue == '') { + $warnMsg[] = "Type can't be empty!"; + } + else if ($iCode == null || $iCode == '') { + $warnMsg[] = "Item code can't be empty!"; + } + else if ($location == null || $location == '') { + $warnMsg[] = "Location can't be empty!"; + } + else if ($serialNumber == null || $serialNumber == '') { + $warnMsg[] = "Serial number can't be empty!"; + } + // else if ($batch == null || $batch == '') { + // $warnMsg[] = "Batch can't be empty!"; + // } + else if ($quantity == null || $quantity == '') { + $warnMsg[] = "Quantity can't be empty!"; + } + // else if ($docNo == null || $docNo == '') { + // $warnMsg[] = "Doc No can't be empty!"; + // } + + if (Str::length($plantCod) > 0 && (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod))) { + $warnMsg[] = 'Invalid plant code found!'; + } elseif (Str::length($plantCod) > 0) { + $plant = Plant::where('code', $plantCod)->first(); + if (! $plant) { + $warnMsg[] = 'Plant code not found!'; + } else { + $plantId = $plant->id; + } + } + + if (Str::length($iCode) > 0 && (Str::length($iCode) < 6 || ! ctype_alnum($iCode))) { + $warnMsg[] = 'Invalid item code found!'; + } elseif ($plantId) { + $itemCode = Item::where('code', $iCode)->first(); + if (! $itemCode) { + $warnMsg[] = 'Item code not found in item master!'; + } else { + $itemCode = Item::where('code', $iCode)->where('plant_id', $plantId)->first(); + if (! $itemCode) { + $warnMsg[] = 'Item code not found in item master for the given plant!'; + } else { + $itemId = $itemCode->id; + $itemCode = StickerMaster::where('item_id', $itemId)->first(); + if (! $itemCode) { + $warnMsg[] = 'Item code not found in sticker master!'; + } else { + if ($plantId) { + $itemCode = StickerMaster::where('item_id', $itemId)->where('plant_id', $plantId)->first(); + if (! $itemCode) { + $warnMsg[] = 'Item code not found in sticker master for the given plant!'; + } + } + } + } + } + } + + $typeValue = strtoupper($typeValue); + + if (! in_array($typeValue, ['FG', 'SFG'])) { + $warnMsg[] = 'Invalid type found! It should be either FG or SFG and fg/sfg.'; + } + else if (Str::length($location) < 4) { + $warnMsg[] = 'Location should contain minimum 4 digits!'; + } + else if (! ctype_digit((string) $location)) { + $warnMsg[] = 'Location must be an integer!'; + } + else if (Str::length($serialNumber) < 9) { + $warnMsg[] = 'Serial number should contain minimum 9 digits!'; + } + else if (!ctype_alnum($serialNumber)) { + $warnMsg[] = 'Serial number should contain alpha-numeric values!'; + } + + else if (! ctype_digit((string) $quantity) || (int) $quantity <= 0) { + $warnMsg[] = 'Quantity must be an integer and greater than 0!'; + } + + if($batch){ + if (Str::length($batch) < 5) { + $warnMsg[] = 'Batch should contain minimum 5 digits!'; + } + } + + if($docNo){ + if (Str::length($docNo) < 5) { + $warnMsg[] = 'Document number contain minimum 5 digits!'; + } + } + + if (! empty($warnMsg)) { + throw new RowImportFailedException(implode(', ', $warnMsg)); + } + + $type = match ($typeValue) { + 'FG' => '0', + 'SFG' => '1', + default => null, + }; + + $stickId = $itemCode->id; + + $record = StockDataMaster::where([ + 'plant_id' => $plantId, + 'sticker_master_id' => $stickId, + 'serial_number' => $serialNumber + ])->first(); + + if ($record) { + + $record->update([ + 'type' => $type, + 'location' => $location ?? null, + 'batch' => $batch ?? null, + 'quantity' => $quantity ?? null, + 'doc_no' => $docNo ?? null, + 'updated_by' => $operatorName, + ]); + + } else { + + StockDataMaster::create([ + 'plant_id' => $plantId, + 'sticker_master_id' => $stickId, + 'type' => $type, + 'location' => $location ?? null, + 'serial_number' => $serialNumber ?? null, + 'batch' => $batch ?? null, + 'quantity' => $quantity ?? null, + 'doc_no' => $docNo ?? null, + 'created_by' => $operatorName, + 'updated_by' => $operatorName, + ]); + } + + return null; + } + + public static function getCompletedNotificationBody(Import $import): string + { + $body = 'Your stock data master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.'; + + if ($failedRowsCount = $import->getFailedRowsCount()) { + $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.'; + } + + return $body; + } +} -- 2.49.1