From b02ff04894d2f1b69689c53bbcb32d8ae704a242 Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 10:13:11 +0000 Subject: [PATCH] Implement Employee Payroll Management System --- app/Filament/Resources/PayrollResource.php | 106 ++++++++++++++++++ app/Models/Employee.php | 31 +++++ app/Models/Payroll.php | 56 +++++++++ ...24_02_24_000000_create_employees_table.php | 28 +++++ ...024_02_24_000001_create_payrolls_table.php | 34 ++++++ 5 files changed, 255 insertions(+) create mode 100644 app/Filament/Resources/PayrollResource.php create mode 100644 app/Models/Employee.php create mode 100644 app/Models/Payroll.php create mode 100644 database/migrations/2024_02_24_000000_create_employees_table.php create mode 100644 database/migrations/2024_02_24_000001_create_payrolls_table.php diff --git a/app/Filament/Resources/PayrollResource.php b/app/Filament/Resources/PayrollResource.php new file mode 100644 index 00000000..54cd122b --- /dev/null +++ b/app/Filament/Resources/PayrollResource.php @@ -0,0 +1,106 @@ + + +schema([ + Forms\Components\Select::make('employee_id') + ->relationship('employee', 'name') + ->required(), + Forms\Components\TextInput::make('base_salary') + ->required() + ->numeric() + ->prefix('$'), + Forms\Components\TextInput::make('overtime_hours') + ->numeric() + ->default(0), + Forms\Components\TextInput::make('overtime_rate') + ->numeric() + ->prefix('$') + ->default(0), + Forms\Components\TextInput::make('other_deductions') + ->numeric() + ->prefix('$') + ->default(0), + Forms\Components\DatePicker::make('pay_period_start') + ->required(), + Forms\Components\DatePicker::make('pay_period_end') + ->required(), + Forms\Components\DatePicker::make('payment_date') + ->required(), + Forms\Components\Select::make('payment_status') + ->options([ + 'pending' => 'Pending', + 'processed' => 'Processed', + 'paid' => 'Paid', + ]) + ->default('pending') + ->required(), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('employee.name') + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('base_salary') + ->money('USD') + ->sortable(), + Tables\Columns\TextColumn::make('net_salary') + ->money('USD') + ->sortable(), + Tables\Columns\TextColumn::make('payment_date') + ->date() + ->sortable(), + Tables\Columns\BadgeColumn::make('payment_status') + ->colors([ + 'warning' => 'pending', + 'primary' => 'processed', + 'success' => 'paid', + ]), + ]) + ->filters([ + Tables\Filters\SelectFilter::make('payment_status') + ->options([ + 'pending' => 'Pending', + 'processed' => 'Processed', + 'paid' => 'Paid', + ]), + ]) + ->actions([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListPayrolls::route('/'), + 'create' => Pages\CreatePayroll::route('/create'), + 'edit' => Pages\EditPayroll::route('/{record}/edit'), + ]; + } +} \ No newline at end of file diff --git a/app/Models/Employee.php b/app/Models/Employee.php new file mode 100644 index 00000000..782be0eb --- /dev/null +++ b/app/Models/Employee.php @@ -0,0 +1,31 @@ + + + 'date', + ]; + + public function payrolls(): HasMany + { + return $this->hasMany(Payroll::class); + } +} \ No newline at end of file diff --git a/app/Models/Payroll.php b/app/Models/Payroll.php new file mode 100644 index 00000000..a22740c4 --- /dev/null +++ b/app/Models/Payroll.php @@ -0,0 +1,56 @@ + + + 'date', + 'pay_period_end' => 'date', + 'payment_date' => 'date', + 'base_salary' => 'decimal:2', + 'overtime_hours' => 'decimal:2', + 'overtime_rate' => 'decimal:2', + 'tax_deductions' => 'decimal:2', + 'other_deductions' => 'decimal:2', + 'net_salary' => 'decimal:2', + ]; + + public function employee(): BelongsTo + { + return $this->belongsTo(Employee::class); + } + + public function calculateNetSalary(): void + { + $overtimePay = $this->overtime_hours * $this->overtime_rate; + $grossSalary = $this->base_salary + $overtimePay; + + // Calculate tax deductions (example rate of 20%) + $this->tax_deductions = $grossSalary * 0.20; + + $this->net_salary = $grossSalary - $this->tax_deductions - $this->other_deductions; + } +} \ No newline at end of file diff --git a/database/migrations/2024_02_24_000000_create_employees_table.php b/database/migrations/2024_02_24_000000_create_employees_table.php new file mode 100644 index 00000000..1a8bf650 --- /dev/null +++ b/database/migrations/2024_02_24_000000_create_employees_table.php @@ -0,0 +1,28 @@ + + +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->string('position'); + $table->date('hire_date'); + $table->string('tax_id')->unique(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('employees'); + } +}; \ No newline at end of file diff --git a/database/migrations/2024_02_24_000001_create_payrolls_table.php b/database/migrations/2024_02_24_000001_create_payrolls_table.php new file mode 100644 index 00000000..9f690f12 --- /dev/null +++ b/database/migrations/2024_02_24_000001_create_payrolls_table.php @@ -0,0 +1,34 @@ + + +id(); + $table->foreignId('employee_id')->constrained()->onDelete('cascade'); + $table->decimal('base_salary', 10, 2); + $table->decimal('overtime_hours', 8, 2)->default(0); + $table->decimal('overtime_rate', 8, 2)->default(0); + $table->decimal('tax_deductions', 10, 2)->default(0); + $table->decimal('other_deductions', 10, 2)->default(0); + $table->decimal('net_salary', 10, 2); + $table->date('pay_period_start'); + $table->date('pay_period_end'); + $table->date('payment_date'); + $table->string('payment_status')->default('pending'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('payrolls'); + } +}; \ No newline at end of file