diff --git a/app/Filament/Resources/InvoiceInTransitResource.php b/app/Filament/Resources/InvoiceInTransitResource.php new file mode 100644 index 0000000..a29d56f --- /dev/null +++ b/app/Filament/Resources/InvoiceInTransitResource.php @@ -0,0 +1,613 @@ +schema([ + Forms\Components\Select::make('plant_id') + ->relationship('plant', 'name') + ->required(), + Forms\Components\TextInput::make('receiving_plant') + ->label('Receiving Plant'), + Forms\Components\TextInput::make('receiving_plant_name') + ->label('Receiving Plant Name'), + Forms\Components\TextInput::make('invoice_number') + ->label('Invoice Number'), + Forms\Components\TextInput::make('invoice_date') + ->label('Invoice Date'), + Forms\Components\TextInput::make('item_code') + ->label('Item Code'), + Forms\Components\TextInput::make('description') + ->label('Description'), + Forms\Components\TextInput::make('quantity') + ->label('Quantity') + ->numeric() + ->default(null), + Forms\Components\TextInput::make('transport_name') + ->label('Transport Name'), + Forms\Components\TextInput::make('lr_bl_aw_number') + ->label('LR/BL/AW Number'), + Forms\Components\TextInput::make('lr_bl_aw_date') + ->label('LR/BL/AW Date'), + Forms\Components\TextInput::make('pending_days') + ->label('Pending Days'), + Forms\Components\TextInput::make('obd_number') + ->label('OBD Number'), + Forms\Components\TextInput::make('obd_date') + ->label('OBD Date'), + Forms\Components\TextInput::make('shipment_weight') + ->label('Shipment Weight'), + Forms\Components\TextInput::make('unit_price') + ->label('Unit Price'), + Forms\Components\TextInput::make('net_value') + ->label('Net value'), + Forms\Components\TextInput::make('total_item_amount') + ->label('Total Item Amount'), + Forms\Components\TextInput::make('tax_amount') + ->label('Tax Amount'), + Forms\Components\TextInput::make('transport_mode') + ->label('Transport Mode'), + Forms\Components\TextInput::make('vehicle_number') + ->label('Vehicle Number'), + Forms\Components\TextInput::make('e_waybill_number') + ->label('E Way Bill Number'), + 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('plant.name') + ->label('Plant') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('receiving_plant') + ->label('Receiving Plant') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('receiving_plant_name') + ->label('Receiving Plant Name') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('invoice_number') + ->label('Invoice Number') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('invoice_date') + ->label('Invoice Date') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('item_code') + ->label('Item Code') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('description') + ->label('Description') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('quantity') + ->label('Quantity') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('transport_name') + ->label('Transport Name') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('lr_bl_aw_number') + ->label('LR/BL/AW Number') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('lr_bl_aw_date') + ->label('LR/BL/AW Date') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('pending_days') + ->label('Pending Days') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('obd_number') + ->label('OBD Number') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('obd_date') + ->label('OBD Date') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('shipment_weight') + ->label('Shipment Weight') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('unit_price') + ->label('Unit Price') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('net_value') + ->label('Net value') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('total_item_amount') + ->label('Total Item Amount') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('tax_amount') + ->label('Tax Amount') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('transport_mode') + ->label('Transport Mode') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('vehicle_number') + ->label('Vehicle Number') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('e_waybill_number') + ->label('E Way Bill Number') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('deleted_at') + ->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 Invoice In Transit') + ->label('Import Invoice In Transit') + ->form([ + FileUpload::make('invoice_in_transit_file') + ->label('Import Invoice In Transit') + ->preserveFilenames() + ->storeFiles(false) + ->reactive() + ->required() + ->disk('local') + ->directory('uploads/temp'), + ]) + ->action(function (array $data) { + $uploadedFile = $data['invoice_in_transit_file']; + + $disk = Storage::disk('local'); + + $user = Filament::auth()->user(); + + $operatorName = $user->name; + + // Get original filename + $originalName = $uploadedFile->getClientOriginalName(); + + $path = $uploadedFile->storeAs('uploads/temp', $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 'Invoice Master Data' file to proceed..!") + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + + return; + } + + $invalidPlantCode = []; + $invalidPlantCo = []; + $invalidPlaCoFound = []; + $invalidRecPlant = []; + $invalidRecPlantName = []; + $invalidInvNo = []; + $invalidInvDt = []; + $invalidICode = []; + $invalidDesc = []; + $invalidQty = []; + $invalidTransportName = []; + $invalidLRBLAWNo = []; + $invalidLRBLAWDt = []; + $invalidPenDay = []; + + + foreach ($rows as $index => $row) { + if ($index == 0) { + continue; + } + + $plantCode = trim($row[0]); + $receivingPlant = trim($row[2]); + $receivingPlantName = trim($row[3]); + $invoiceNo = trim($row[4]); + $invoiceDt = trim($row[5]); + $itemCode = trim($row[6]); + $des = trim($row[7]); + $quantity = trim($row[8]); + $transportName = trim($row[9]); + $LRBAWNo = trim($row[10]); + $LRBAWDt = trim($row[11]); + $pendingDays = trim($row[12]); + + if (empty($plantCode)) { + $invalidPlantCode[] = "Row {$index}"; + } + if (empty($receivingPlant)) { + $invalidRecPlant[] = "Row {$index}"; + } + if (empty($receivingPlantName)) { + $invalidRecPlantName[] = "Row {$index}"; + } + if (empty($invoiceNo)) { + $invalidInvNo[] = "Row {$index}"; + } + if (empty($invoiceDt)) { + $invalidInvDt[] = "Row {$index}"; + } + if (empty($itemCode)) { + $invalidICode[] = "Row {$index}"; + } + if (empty($des)) { + $invalidDesc[] = "Row {$index}"; + } + if (empty($quantity)) { + $invalidQty[] = "Row {$index}"; + } + if (empty($transportName)) { + $invalidTransportName[] = "Row {$index}"; + } + if (empty($LRBAWNo)) { + $invalidLRBLAWNo[] = "Row {$index}"; + } + if (empty($LRBAWDt)) { + $invalidLRBLAWDt[] = "Row {$index}"; + } + if (empty($pendingDays)) { + $invalidPenDay[] = "Row {$index}"; + } + + if (strlen($plantCode) < 4) { + $invalidPlantCo[] = $plantCode; + } elseif (! Plant::where('code', $plantCode)->first()) { + $invalidPlaCoFound[] = $plantCode; + } + + $plant = Plant::where('code', $plantCode)->first(); + + //$plantId = $plant->id; + + } + + if (! empty($invalidPlantCode) || ! empty($invalidRecPlant) || ! empty($invalidRecPlantName) || ! empty($invalidInvNo) || ! empty($invalidInvDt) || ! empty($invalidICode) || ! empty($invalidDesc) || ! empty($invalidQty) || ($invalidTransportName) || ! empty($invalidLRBLAWNo) || ! empty($invalidLRBLAWDt) || ! empty($invalidPenDay)) { + $errorMsg = ''; + + if (! empty($invalidPlantCode)) { + $errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidPlantCode).'
'; + } + if (! empty($invalidRecPlant)) { + $errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidRecPlant).'
'; + } + if (! empty($invalidRecPlantName)) { + $errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidRecPlantName).'
'; + } + if (! empty($invalidInvNo)) { + $errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidInvNo).'
'; + } + if (! empty($invalidInvDt)) { + $errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidInvDt).'
'; + } + if (! empty($invalidICode)) { + $errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidICode).'
'; + } + if (! empty($invalidDesc)) { + $errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidDesc).'
'; + } + if (! empty($invalidQty)) { + $errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidQty).'
'; + } + if (! empty($invalidTransportName)) { + $errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidTransportName).'
'; + } + if (! empty($invalidLRBLAWNo)) { + $errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidLRBLAWNo).'
'; + } + if (! empty($invalidLRBLAWDt)) { + $errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidLRBLAWDt).'
'; + } + if (! empty($invalidPenDay)) { + $errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidPenDay).'
'; + } + + Notification::make() + ->title('Missing Mandatory Fields') + ->body($errorMsg) + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + + return; + } + + if (! empty($invalidPlantCo)) { + $invalidPlantCode = array_unique($invalidPlantCo); + Notification::make() + ->title('Invalid Plant Codes') + ->body('The following plant codes should contain minimum 4 digits:
'.implode(', ', $invalidPlantCode)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + + return; + } + + if (! empty($invalidPlaCoFound)) { + $invalidPlaCoFound = array_unique($invalidPlaCoFound); + Notification::make() + ->title('Invalid Plant Codes') + ->body('The following plant codes not found in plants:
'.implode(', ', $invalidPlaCoFound)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + + return; + } + + foreach ($rows as $index => $row) + { + if ($index == 0) { + continue; + } + + $plantCode = trim($row[0]); + $receivingPlant = trim($row[2]); + $receivingPlantName = trim($row[3]); + $invoiceNo = trim($row[4]); + $invoiceDt = trim($row[5]); + $itemCode = trim($row[6]); + $des = trim($row[7]); + $quantity = trim($row[8]); + $transportName = trim($row[9]); + $LRBAWNo = trim($row[10]); + $LRBAWDt = trim($row[11]); + $pendingDays = trim($row[12]); + $OBDNumber = trim($row[13]); + $OBDDate = trim($row[14]); + $ShipmentWeight = trim($row[15]); + $UnitPrice = trim($row[16]); + $NetValue = trim($row[17]); + $TotalItemAmount = trim($row[18]); + $TaxAmount = trim($row[19]); + $TransportMode = trim($row[20]); + $VehicleNumber = trim($row[21]); + $EWayBillNumber = trim($row[22]); + + $plant = Plant::where('code', $plantCode)->first(); + if (! $plant) { + throw new \Exception("Invalid plant code : '{$plantCode}'"); + } + + if (! empty($invoiceDt)) + { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $invoiceDt)) { + [$day, $month, $year] = preg_split('/[-\/]/', $invoiceDt); + $formattedDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($invoiceDt)) { + $formattedDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($invoiceDt)->format('Y-m-d'); + } else { + $formattedDate = date('Y-m-d', strtotime($invoiceDt)); + } + } else { + $formattedDate = null; + } + if (! empty($LRBAWDt)) + { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $LRBAWDt)) { + [$day, $month, $year] = preg_split('/[-\/]/', $LRBAWDt); + $formattedDt = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($LRBAWDt)) { + $formattedDt = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($LRBAWDt)->format('Y-m-d'); + } else { + $formattedDt = date('Y-m-d', strtotime($LRBAWDt)); + } + } else { + $formattedDt = null; + } + if (! empty($OBDDate)) + { + if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $OBDDate)) { + [$day, $month, $year] = preg_split('/[-\/]/', $OBDDate); + $formattedDate = "{$year}-{$month}-{$day}"; + } elseif (is_numeric($OBDDate)) { + $formatted = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($OBDDate)->format('Y-m-d'); + } else { + $formatted = date('Y-m-d', strtotime($OBDDate)); + } + } else { + $formatted = null; + } + + $inserted = InvoiceInTransit::create([ + 'plant_id' => $plant->id, + 'receiving_plant' => $receivingPlant, + 'receiving_plant_name' => $receivingPlantName, + 'invoice_number' => $invoiceNo, + 'invoice_date' => $formattedDate, + 'item_code' => $itemCode, + 'description' => $des, + 'quantity' => $quantity, + 'transport_name' => $transportName, + 'lr_bl_aw_number' => $LRBAWNo, + 'lr_bl_aw_date' => $formattedDt, + 'pending_days' => $pendingDays, + 'obd_number' => $OBDNumber, + 'obd_date' => $formatted, + 'shipment_weight' => $ShipmentWeight, + 'unit_price' => $UnitPrice, + 'net_value' => $NetValue, + 'total_item_amount' => $TotalItemAmount, + 'tax_amount' => $TaxAmount, + 'transport_mode' => $TransportMode, + 'vehicle_number' => $VehicleNumber, + 'e_waybill_number' => $EWayBillNumber, + 'created_at' => now(), + 'created_by' => $operatorName, + ]); + } + if ($inserted) { + Notification::make() + ->title('Upload Success') + ->body('Invoice in transit uploaded successfully!') + ->success() + ->send(); + return; + } + else + { + Notification::make() + ->title('Insertion Failed') + ->body('Invoice in transit upload failed!') + ->success() + ->send(); + return; + } + } + }) + ->visible(function () { + return Filament::auth()->user()->can('view import invoice in transit'); + }), + ExportAction::make() + ->label('Export Invoice In Transit') + ->color('warning') + ->exporter(InvoiceInTransitExporter::class) + ->visible(function () { + return Filament::auth()->user()->can('view export invoice master'); + }), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListInvoiceInTransits::route('/'), + 'create' => Pages\CreateInvoiceInTransit::route('/create'), + 'view' => Pages\ViewInvoiceInTransit::route('/{record}'), + 'edit' => Pages\EditInvoiceInTransit::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/InvoiceInTransitResource/Pages/CreateInvoiceInTransit.php b/app/Filament/Resources/InvoiceInTransitResource/Pages/CreateInvoiceInTransit.php new file mode 100644 index 0000000..ccaf607 --- /dev/null +++ b/app/Filament/Resources/InvoiceInTransitResource/Pages/CreateInvoiceInTransit.php @@ -0,0 +1,12 @@ +