199 lines
7.3 KiB
Markdown
199 lines
7.3 KiB
Markdown
# HR Management System
|
|
|
|
Internal admin application for managing employee records, leave requests, disciplinary reports, bonuses, gifts, and document storage. Built on Laravel with a Filament admin panel.
|
|
|
|
**Stack:** Laravel 13, PHP 8.3+, Filament 5, SQLite (default) or MySQL, Vite + Tailwind 4.
|
|
|
|
**Key packages:** Filament Shield (RBAC), Language Switch, Spatie Activity Log, Maatwebsite Excel, DomPDF.
|
|
|
|
## Requirements
|
|
|
|
- PHP 8.3+, Composer, Node.js/npm
|
|
- SQLite extension (default) or MySQL/PostgreSQL if configured in `.env`
|
|
- Queue worker required for Excel imports (`ProcessImportJob`)
|
|
|
|
## Installation
|
|
|
|
### Quick setup (recommended)
|
|
|
|
```bash
|
|
composer setup
|
|
php artisan db:seed
|
|
```
|
|
|
|
`composer setup` runs: `composer install`, copies `.env`, `key:generate`, `migrate`, `npm install`, and `npm run build`.
|
|
|
|
### Manual setup
|
|
|
|
1. `composer install`
|
|
2. `cp .env.example .env` and configure the database if not using SQLite
|
|
3. `touch database/database.sqlite` (SQLite only)
|
|
4. `php artisan key:generate`
|
|
5. `php artisan migrate`
|
|
6. `php artisan db:seed`
|
|
7. `npm install && npm run build`
|
|
|
|
### Development
|
|
|
|
```bash
|
|
composer dev
|
|
```
|
|
|
|
Runs the HTTP server, queue listener, log tail (Pail), and Vite concurrently. The queue worker is required for Excel imports and full local development.
|
|
|
|
### Default admin credentials
|
|
|
|
- URL: `http://localhost:8000/admin`
|
|
- Email: `admin@company.com`
|
|
- Password: `password`
|
|
|
|
### Optional configuration
|
|
|
|
Set these in `.env` or see [`config/hr.php`](config/hr.php):
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `HR_COMPANY_NAME` | HR Management System | Company name shown in the panel |
|
|
| `HR_ANNUAL_LEAVE_DAYS` | 24 | Annual paid leave allowance per employee |
|
|
| `HR_LEAVE_CALCULATION` | `calendar` | Day counting mode: `calendar` or `business` |
|
|
|
|
## Application Structure
|
|
|
|
```
|
|
app/
|
|
├── Filament/ # Admin UI: Resources, Pages, Widgets, Concerns
|
|
│ ├── Resources/ # One resource per entity (Employee, Vacation, etc.)
|
|
│ ├── Pages/ # Dashboard, ImportWizard
|
|
│ └── Widgets/ # Stats, charts, upcoming birthdays/leaves
|
|
├── Models/ # Eloquent models + LogsHrActivity concern
|
|
├── Policies/ # Authorization (ScopedByDepartment concern)
|
|
├── Services/ # Business logic (leave calc, import, export, vacation balance)
|
|
├── Observers/ # Side effects on leave/report/document save
|
|
├── Imports/Exports/ # Excel import/export
|
|
└── Jobs/ # Async import processing
|
|
|
|
config/hr.php # Company settings, locales, file upload paths
|
|
lang/{en,tk,ru}/ # App translations (hr.php, enums.php, etc.)
|
|
database/seeders/ # Org data, roles, admin user, demo data
|
|
```
|
|
|
|
### Filament resource pattern
|
|
|
|
Each resource splits into dedicated subdirectories:
|
|
|
|
- `Schemas/` — form and infolist configuration
|
|
- `Tables/` — table columns, filters, actions
|
|
- `Pages/` — list, create, edit, view pages
|
|
- `RelationManagers/` — optional nested CRUD (e.g. Employee has 8 relation managers for vacations, leave, reports, bonuses, gifts, and documents)
|
|
|
|
### Navigation groups
|
|
|
|
| Group | Resources |
|
|
|-------|-----------|
|
|
| Organization | Departments, Positions, Shifts |
|
|
| Employees | Employee (central hub record) |
|
|
| Leave Management | Vacations, Sick Leave, Unpaid Leave |
|
|
| Records | Disciplinary Reports, Explanations, Bonuses, Gifts, Documents |
|
|
| System | Users, Activity Log, Shield roles |
|
|
|
|
## Domain Model and Relationships
|
|
|
|
**Employee** is the central entity — most HR records belong to an employee. **Department** scopes both employees and admin users. **User** (admin login) is separate from **Employee** (HR record); they are linked only by department for authorization scoping.
|
|
|
|
Organization tables (Department, Position, Shift) use soft deletes. Department auto-generates a unique `code` from its name on save.
|
|
|
|
```mermaid
|
|
erDiagram
|
|
Department ||--o{ Employee : has
|
|
Department ||--o{ User : has
|
|
Position ||--o{ Employee : has
|
|
Shift ||--o{ Employee : has
|
|
Employee ||--o{ Vacation : has
|
|
Employee ||--o{ SickLeave : has
|
|
Employee ||--o{ UnpaidLeave : has
|
|
Employee ||--o{ DisciplinaryReport : has
|
|
Employee ||--o{ Explanation : has
|
|
Employee ||--o{ Bonus : has
|
|
Employee ||--o{ Gift : has
|
|
Employee ||--o{ EmployeeDocument : has
|
|
User ||--o{ Vacation : approves
|
|
```
|
|
|
|
## Application Logic
|
|
|
|
### Entry points
|
|
|
|
- `/` — public welcome page only
|
|
- `/admin` — all HR functionality lives in the Filament admin panel
|
|
|
|
### Request and authorization flow
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
UserLogin[Admin login] --> FilamentPanel[Filament /admin]
|
|
FilamentPanel --> Shield[Filament Shield roles]
|
|
Shield --> Policy[Model Policy]
|
|
Policy --> ScopedByDept[ScopedByDepartment]
|
|
ScopedByDept --> Resource[Filament Resource CRUD]
|
|
Resource --> Service[Service layer]
|
|
Service --> Model[Eloquent Model]
|
|
Model --> Observer[Observer hooks]
|
|
Model --> ActivityLog[Spatie Activity Log]
|
|
```
|
|
|
|
### Authorization
|
|
|
|
Three layers work together:
|
|
|
|
1. **Filament Shield** — role and permission management UI; `super_admin` bypasses all checks
|
|
2. **Policies** — 13 model policies registered in [`AppServiceProvider`](app/Providers/AppServiceProvider.php) enforce per-model CRUD rules
|
|
3. **`ScopedByDepartment`** — shared policy concern that scopes access by role:
|
|
- `administrator` / `hr_manager` — full access
|
|
- `supervisor` — read all records
|
|
- `department_manager` — scoped to own `department_id`
|
|
- `viewer` — read-only
|
|
|
|
Seeded roles: `super_admin`, `administrator`, `hr_manager`, `supervisor`, `department_manager`, `viewer`, `panel_user`.
|
|
|
|
### Leave workflow
|
|
|
|
- Vacations, sick leave, and unpaid leave use the `ApprovalStatus` enum (pending → approved/rejected)
|
|
- [`LeaveDaysCalculator`](app/Services/Leave/LeaveDaysCalculator.php) computes leave days using calendar or business-day mode from `config/hr.php`
|
|
- Observers on leave models handle status transitions and day calculations on save
|
|
- [`VacationBalanceService`](app/Services/Vacation/VacationBalanceService.php) tracks remaining annual leave against `HR_ANNUAL_LEAVE_DAYS`
|
|
|
|
### Import pipeline
|
|
|
|
1. **Import Wizard** (Filament page) accepts an Excel upload
|
|
2. Dispatches `ProcessImportJob` to the queue
|
|
3. Type-specific transformers in `app/Services/Import/` process employees, vacations, bonuses, or reports
|
|
4. Requires a running queue worker (`composer dev` starts one automatically)
|
|
|
|
### Audit trail
|
|
|
|
- The `LogsHrActivity` concern on HR models logs changes to fillable fields via Spatie Activity Log
|
|
- The **Activity Log** resource provides a read-only audit viewer in the admin panel
|
|
|
|
### Localization
|
|
|
|
- Supported locales: `en`, `tk`, `ru` ([`config/hr.php`](config/hr.php))
|
|
- User preference stored on `users.locale`; Language Switch persists the choice on change
|
|
- Labels come from `lang/*/hr.php`, `enums.php`, and the `HasHrResourceLabels` trait on Filament resources
|
|
|
|
### File uploads
|
|
|
|
Employee documents are stored on the `local` disk under `storage/app/hr/` (configurable in `config/hr.php`).
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
composer test
|
|
# or: php artisan test
|
|
```
|
|
|
|
Tests live under `tests/Feature/` and include localization, model behavior (e.g. Department), and other feature coverage.
|
|
|
|
## License
|
|
|
|
Open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|