diff --git a/app/Filament/Resources/ImportTransitResource.php b/app/Filament/Resources/ImportTransitResource.php new file mode 100644 index 0000000..be1b71c --- /dev/null +++ b/app/Filament/Resources/ImportTransitResource.php @@ -0,0 +1,637 @@ +schema([ + Forms\Components\TextInput::make('cri_rfq_number') + ->label('CRI/RFQ Number') + ->disabled(fn ($operation) => $operation == 'edit') + ->unique(ignoreRecord: true), + Forms\Components\DatePicker::make('mail_received_date') + ->label('Mail Received Date') + ->required(), + Forms\Components\TextInput::make('pricol_ref_number') + ->label('Pricol Ref Number') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('requester') + ->label('Requester') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('shipper') + ->label('Shipper') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('shipper_location') + ->label('Shipper Location') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('shipper_invoice') + ->label('Shipper Invoice') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\DatePicker::make('shipper_invoice_date') + ->label('Shipper Invoice Date') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('customs_agent_name') + ->label('Customs Agent Name') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\DatePicker::make('eta_date') + ->label('ETA Date') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\Select::make('status') + ->label('Status') + ->options([ + 'Completed' => 'Completed', + 'InTransit' => 'InTransit', + 'Booked' => 'Booked', + ]) + ->reactive() + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('delivery_location') + ->label('Delivery Location') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\DatePicker::make('etd_date') + ->label('ETD Date') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('mode') + ->label('Mode') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('inco_terms') + ->label('Inco Terms') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('port_of_loading') + ->label('Port of Loading') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('port_of_discharge') + ->label('Port of Discharge') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('delivery_city') + ->label('Delivery City') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('packages') + ->label('Packages') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('type_of_package') + ->label('Type of Package') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('gross_weight') + ->label('Gross Weight') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('volume') + ->label('Volume') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('bill_number') + ->label('Bill Number') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\DatePicker::make('bill_received_date') + ->label('Bill Received Date') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('vessel_number') + ->label('Vessel Number') + ->afterStateUpdated(function (callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\Hidden::make('created_by') + ->label('Created By') + ->default(Filament::auth()->user()?->name), + Forms\Components\Hidden::make('updated_by') + ->label('Updated By') + ->default(Filament::auth()->user()?->name), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('No.') + ->label('No.') + ->alignCenter() + ->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('cri_rfq_number') + ->label('CRI/RFQ Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('mail_received_date') + ->label('Mail Received Date') + ->date() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('pricol_ref_number') + ->label('Pricol Ref Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('requester') + ->label('Requester') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('shipper') + ->label('Shipper') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('shipper_location') + ->label('Shipper Location') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('shipper_invoice') + ->label('Shipper Invoice') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('shipper_invoice_date') + ->label('Shipper Invoice Date') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('customs_agent_name') + ->label('Customs Agent Name') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('eta_date') + ->label('ETA Date') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('status') + ->label('Status') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('delivery_location') + ->label('Delivery Location') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('etd_date') + ->label('ETD Date') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('mode') + ->label('Mode') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('inco_terms') + ->label('Inco Terms') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('port_of_loading') + ->label('Port of Loading') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('port_of_discharge') + ->label('Port of Discharge') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('delivery_city') + ->label('Delivery City') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('packages') + ->label('Packages') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('type_of_package') + ->label('Type of Package') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('gross_weight') + ->label('Gross Weight') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('volume') + ->label('Volume') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('bill_number') + ->label('Bill Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('bill_received_date') + ->label('Bill Received Date') + ->alignCenter() + ->date() + ->sortable(), + Tables\Columns\TextColumn::make('vessel_number') + ->label('Vessel Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->label('Created At') + ->alignCenter() + ->dateTime() + ->sortable(), + Tables\Columns\TextColumn::make('created_by') + ->label('Created By') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('updated_at') + ->label('Updated At') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_by') + ->label('Updated By') + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('deleted_at') + ->label('Deleted At') + ->alignCenter() + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + Tables\Filters\TrashedFilter::make(), + ]) + ->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(), + ]), + ]) + ->headerActions([ + Tables\Actions\Action::make('Import Transit') + ->label('Import Transit') + ->form([ + FileUpload::make('import_transit_file') + ->label('Import Transit') + // ->required() + ->preserveFilenames() + ->storeFiles(false) + ->reactive() + ->required() + ->disk('local') + // ->visible(fn (Get $get) => !empty($get('plant_id'))) + ->directory('uploads/ImportTransit'), + ]) + ->action(function (array $data) { + $uploadedFile = $data['import_transit_file']; + + $disk = Storage::disk('local'); + + $user = Filament::auth()->user(); + + $operatorName = $user->name; + + // 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/ImportTransit', $originalName, 'local'); // returns relative path + + $fullPath = Storage::disk('local')->path($path); + + 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 'Import Transit' file to proceed..!") + ->danger() + ->send(); + + if ($disk->exists($path)) + { + $disk->delete($path); + } + + return; + } + + $invalidCriNo = []; + + foreach ($rows as $index => $row) + { + if ($index == 0) { + continue; + } + + $rowNumber = $index + 1; + + $criRfqNo = trim($row[1] ?? ''); + $mailRcvdDate = trim($row[2] ?? ''); + $pricolRefNo = trim($row[3] ?? ''); + $requester = trim($row[4] ?? ''); + $shipper = trim($row[5] ?? ''); + $shipperLocation = trim($row[6] ?? ''); + $shipperInv = trim($row[7] ?? ''); + $shipperInvDate = trim($row[8] ?? ''); + $cha = trim($row[9] ?? ''); + $eta = trim($row[10] ?? ''); + $status = trim($row[11] ?? ''); + $dlyLoc = trim($row[12] ?? ''); + $etd = trim($row[13] ?? ''); + $mode = trim($row[14] ?? ''); + $incoTerms = trim($row[15] ?? ''); + $portOfLoading = trim($row[16] ?? ''); + $portOfDischarge = trim($row[17] ?? ''); + $deliveryCity = trim($row[18] ?? ''); + $packages = trim($row[19] ?? ''); + $typeOfPkg = trim($row[20] ?? ''); + $grossWeight = trim($row[21] ?? ''); + $volumeWeight = trim($row[22] ?? ''); + $blNo = trim($row[23] ?? ''); + $blRcvdDate = trim($row[24] ?? ''); + $vesselNo = trim($row[25] ?? ''); + + if (empty($criRfqNo)) { + $invalidCriNo[] = $rowNumber; + } + } + + if (! empty($invalidCriNo)){ + + $errorMsg = ''; + + if (! empty($invalidCriNo)) { + $errorMsg .= 'Missing CRI Rfq No in rows: '.implode(', ', $invalidCriNo).'
'; + } + + Notification::make() + ->title('Missing Mandatory Fields') + ->body($errorMsg) + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + + return; + + } + + + try + { + foreach ($rows as $index => $row) + { + if ($index == 0) { + continue; + } + + $rowNumber = $index + 1; + + try + { + $criRfqNo = trim($row[1] ?? ''); + $mailRcvdDate = trim($row[2] ?? ''); + $pricolRefNo = trim($row[3] ?? ''); + $requester = trim($row[4] ?? ''); + $shipper = trim($row[5] ?? ''); + $shipperLocation = trim($row[6] ?? ''); + $shipperInv = trim($row[7] ?? ''); + $shipperInvDate = trim($row[8] ?? ''); + $cha = trim($row[9] ?? ''); + $eta = trim($row[10] ?? ''); + $status = trim($row[11] ?? ''); + $dlyLoc = trim($row[12] ?? ''); + $etd = trim($row[13] ?? ''); + $mode = trim($row[14] ?? ''); + $incoTerms = trim($row[15] ?? ''); + $portOfLoading = trim($row[16] ?? ''); + $portOfDischarge = trim($row[17] ?? ''); + $deliveryCity = trim($row[18] ?? ''); + $packages = trim($row[19] ?? ''); + $typeOfPkg = trim($row[20] ?? ''); + $grossWeight = trim($row[21] ?? ''); + $volumeWeight = trim($row[22] ?? ''); + $blNo = trim($row[23] ?? ''); + $blRcvdDate = trim($row[24] ?? ''); + $vesselNo = trim($row[25] ?? ''); + + + if (! empty($mailRcvdDate)) { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $mailRcvdDate)) { + [$day, $month, $year] = preg_split('/[-\/]/', $mailRcvdDate); + $formattedDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($mailRcvdDate)) { + $formattedDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($mailRcvdDate)->format('Y-m-d'); + } else { + $formattedDate = date('Y-m-d', strtotime($mailRcvdDate)); + } + } + if (! empty($shipperInvDate)) { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $shipperInvDate)) { + [$day, $month, $year] = preg_split('/[-\/]/', $shipperInvDate); + $formattedShipperDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($shipperInvDate)) { + $formattedShipperDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($shipperInvDate)->format('Y-m-d'); + } else { + $formattedShipperDate = date('Y-m-d', strtotime($shipperInvDate)); + } + } + if (! empty($eta)) { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $eta)) { + [$day, $month, $year] = preg_split('/[-\/]/', $eta); + $etaDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($eta)) { + $etaDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($eta)->format('Y-m-d'); + } else { + $etaDate = date('Y-m-d', strtotime($eta)); + } + } + if (! empty($etd)) { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $etd)) { + [$day, $month, $year] = preg_split('/[-\/]/', $etd); + $etdDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($etd)) { + $etdDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($etd)->format('Y-m-d'); + } else { + $etdDate = date('Y-m-d', strtotime($etd)); + } + } + if (! empty($blRcvdDate)) { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $blRcvdDate)) { + [$day, $month, $year] = preg_split('/[-\/]/', $blRcvdDate); + $formattedBlRcvdDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($blRcvdDate)) { + $formattedBlRcvdDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($blRcvdDate)->format('Y-m-d'); + } else { + $formattedBlRcvdDate = date('Y-m-d', strtotime($blRcvdDate)); + } + } + + $inserted = ImportTransit::updateOrCreate( + [ + 'cri_rfq_number' => $criRfqNo, + ], + [ + 'mail_received_date' => $formattedDate ?? null, + 'pricol_ref_number' => $pricolRefNo ?? null, + 'requester' => $requester ?? null, + 'shipper' => $shipper ?? null, + 'shipper_location' => $shipperLocation ?? null, + 'shipper_invoice' => $shipperInv ?? null, + 'shipper_invoice_date' => $formattedShipperDate ?? null, + 'customs_agent_name' => $cha ?? null, + 'eta_date' => $etaDate ?? null, + 'status' => $status ?? null, + 'delivery_location' => $dlyLoc ?? null, + 'etd_date' => $etdDate ?? null, + 'mode' => $mode ?? null, + 'inco_terms' => $incoTerms ?? null, + 'port_of_loading' => $portOfLoading ?? null, + 'port_of_discharge' => $portOfDischarge ?? null, + 'delivery_city' => $deliveryCity ?? null, + 'packages' => $packages ?? null, + 'type_of_package' => $typeOfPkg ?? null, + 'gross_weight' => $grossWeight ?? null, + 'volume' => $volumeWeight ?? null, + 'bill_number' => $blNo ?? null, + 'bill_received_date' => $formattedBlRcvdDate ?? null, + 'vessel_number' => $vesselNo ?? null, + 'created_by' => $operatorName, + ] + ); + } + catch (\Exception $e) { + Notification::make() + ->title('Import Failed') + ->body("Error occurred while processing row. Error : {$e->getMessage()}") + ->danger() + ->send(); + } + } + if (! $inserted) { + Notification::make() + ->title('Failed') + ->body("Records insertion failed!") + ->success() + ->send(); + } + else{ + Notification::make() + ->title('Success') + ->body("Records inserted successfully!") + ->success() + ->send(); + } + } + catch (\Exception $e) { + Notification::make() + ->title('Import Failed') + ->body("No records were inserted. Error : {$e->getMessage()}") + ->danger() + ->send(); + } + } + }) + ->visible(function () { + return Filament::auth()->user()->can('view import transit'); + }), + ExportAction::make() + ->label('Export Import Transit') + ->color('warning') + ->exporter(ImportTransitExporter::class) + ->visible(function () { + return Filament::auth()->user()->can('view export import transit'); + }), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListImportTransits::route('/'), + 'create' => Pages\CreateImportTransit::route('/create'), + 'view' => Pages\ViewImportTransit::route('/{record}'), + 'edit' => Pages\EditImportTransit::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/ImportTransitResource/Pages/CreateImportTransit.php b/app/Filament/Resources/ImportTransitResource/Pages/CreateImportTransit.php new file mode 100644 index 0000000..8d3c17f --- /dev/null +++ b/app/Filament/Resources/ImportTransitResource/Pages/CreateImportTransit.php @@ -0,0 +1,12 @@ +