# 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).