# Payroll Process: Old System vs New System Plan

## 1. Old System (from spec / promt)

### Tables (from spec)
- **payrolls** – Monthly payroll records per employee
- **payroll_components** – Line items (allowances/deductions) per payroll
- **salary_components** – Master list of earnings/deductions (e.g. Basic, HRA, PF, ESI)
- **salary_groups** – Grouping of employees for salary structure
- **salary_group_components** – Which components (and amounts/formula) apply to a salary group
- **salary_group_users** – Assignment of users to salary groups *(in new system: `users.salary_group_id`)*
- **basic_salary_details** – Per-employee or per-group basic salary
- **pre_payments** – Advance/loan deductions
- **expenses** – Expense deductions

### Features (from spec)
- **Monthly payroll generation** – Run for a month/year; create payroll rows per employee
- **Salary structure** – Allowances (e.g. HRA, DA) and deductions (PF, ESI, PT, tax)
- **Allowances** – Add earnings from salary components
- **Deductions** – Subtract deduction components (statutory + custom)
- **Expense deductions** – Deduct from payroll if linked to expenses
- **Payslip generation** – View/print/PDF per employee per month
- **Queues** – Payroll generation can run in background (spec)

---

## 2. Current New System – What Exists

### Database
| Item | Status | Notes |
|------|--------|--------|
| **payrolls** | ✅ Exists | company_id, user_id, month, year, basic_salary, salary_amount, pre_payment_amount, expense_amount, net_salary, total_days, working_days, present_days, total_office_time, total_worked_time, half_days, late_days, paid_leaves, unpaid_leaves, holiday_count, payment_date, status |
| **payroll_components** | ✅ Exists | payroll_id, salary_component_id, name, value_type, amount, is_earning, type |
| **salary_components** | ✅ Exists | company_id, name, type (earning/deduction), value_type (fixed/percentage), default_amount, is_taxable |
| **salary_groups** | ✅ Exists | company_id, name, description |
| **users.salary_group_id** | ✅ Exists | Links user to one salary group |
| **salary_group_components** | ❌ Missing | Which components + default/amount per group |
| **basic_salary_details** | ❌ Missing | Basic salary per user or per group (no column on User) |
| **pre_payments** (table) | ❌ Missing | Only column on payrolls; no standalone pre-payment records |
| **company_settings** | ✅ Used | PF/ESI/PT toggles stored here |

### Controllers & routes
- **PayrollController**
  - `index` – List payrolls (filter by year/month), shows employee, period, basic, net, status ✅
  - `settingsIndex` / `settingsStore` – PF, ESI, PT checkboxes ✅
  - **Generate payroll** – ❌ Not implemented (route points to placeholder view)
  - **Payslips** – ❌ Not implemented (placeholder view)
  - **Download payslip PDF** – ❌ No route
- **SalaryGroupController** – CRUD + assign users to group ✅
- **SalaryComponentController** – Create/store (index/create/store) ✅

### Views
- **payroll/index** – Table of payrolls with filters ✅
- **payroll/settings** – PF/ESI/PT toggles ✅
- **payroll/generate** – Placeholder only ❌
- **payroll/payslips** – Placeholder only ❌
- **salary-groups** – Index, create, edit (with user assignment) ✅
- **salary-components** – Index, create, store ✅

### Logic gaps
1. **No source for basic salary** – Payroll has `basic_salary` but User/SalaryGroup has no basic amount; need either `users.basic_salary` or `salary_group_components` (e.g. component “Basic” with amount per group) or `basic_salary_details`.
2. **No link between salary group and components** – Cannot say “Group A has Basic 50000, HRA 20%, PF 12%”; only global salary_components exist.
3. **No payroll generation** – No service or job that creates `payrolls` + `payroll_components` from attendance, leaves, salary structure.
4. **No payslip** – No view/PDF for a single payroll record with earnings/deductions breakdown.
5. **PF/ESI/PT** – Only toggles; no calculation or component creation during generate.
6. **Pre-payments / expenses** – No tables or flow to link advances or expenses to payroll deduction.

---

## 3. Recommended Phased Plan for New System

### Phase 1 – Foundation (minimal to run payroll once)
1. **Basic salary source**
   - Add `basic_salary` (nullable decimal) to **users** table (per-employee basic), **or**
   - Add **salary_group_components** table: salary_group_id, salary_component_id, amount (or percentage), and treat “Basic” as first component per group.
   - Recommendation: add **users.basic_salary** for simplicity; later can move to group-based if needed.
2. **Payroll generation (core)**
   - Add **PayrollService** (e.g. `App\Services\PayrollService`):
     - Input: company_id, year, month.
     - Get all staff (user_type = staff_members) for company with basic_salary (or from group) and salary_group_id.
     - For each user: compute working_days (from calendar/holidays), present_days (from attendances), paid_leaves, unpaid_leaves (from leaves), half_days, late_days if needed.
     - Create one **Payroll** per user: basic_salary, salary_amount (e.g. basic for now), net_salary (after deductions), total_days, working_days, present_days, status = 'generated'.
     - Create **PayrollComponent** rows for “Basic” (earning) and optionally one row for “LOP” (loss of pay, deduction) if present_days < working_days.
   - **PayrollController**: add `getGenerate` (form month/year), `postGenerate` (call PayrollService, then redirect to index with success). Replace placeholder generate view with form.
3. **Payslips list**
   - Reuse payroll index filtered by month/year; or add **payroll/payslips** that lists payrolls with “View payslip” link.
4. **Single payslip view (HTML)**
   - New route: `GET payroll/payslips/{payroll}`.
   - Load payroll with user and payrollComponents; blade view showing earnings, deductions, net. No PDF yet.

### Phase 2 – Salary structure and deductions
1. **Salary group components (optional but recommended)**
   - Migration: **salary_group_components** (salary_group_id, salary_component_id, amount, percentage, display_order).
   - UI: In salary-group edit, add “Salary structure” section: select component, enter amount/%, add to group. Store in salary_group_components.
   - PayrollService: when building payroll, for each user get salary_group_id → salary_group_components → create payroll_components from template (earnings + deductions). Basic can come from first “Basic” component or from users.basic_salary.
2. **Statutory deductions (PF, ESI, PT)**
   - Use existing company_settings (payroll_pf_enabled, etc.).
   - In PayrollService, if PF enabled: add deduction component (e.g. “PF Employee”) with calculated amount (e.g. 12% of basic up to cap); similarly ESI, PT from rules.
   - Either create salary_components for “PF”, “ESI”, “PT” per company or create them on-the-fly in payroll_components.
3. **Payroll settings**
   - Extend settings form: PF rate/cap, ESI rate/cap, PT slab if needed (or keep simple flat rules).

### Phase 3 – Payslip PDF and extras
1. **Payslip PDF**
   - Use Laravel DomPDF or Snappy: render same payslip view (or a compact “print” view) to PDF; download as `payslip-{employee_id}-{year}-{month}.pdf`.
   - Route: `GET payroll/payslips/{payroll}/download` or `payroll/payslip/download?payroll_id=...`.
2. **Pre-payments**
   - Migration: **pre_payments** (company_id, user_id, amount, month, year, status, notes). When generating payroll, sum pre_payments for that user/month and set payroll.pre_payment_amount, add deduction line “Advance” in payroll_components.
3. **Expense deductions**
   - If expenses are per-user: link expenses to user and period; in PayrollService deduct from net and add expense_amount + component “Expense deduction”.
4. **Mark as paid**
   - Add action “Mark as paid” (and set payment_date) on payroll index or on single payroll view. Optional: bulk “Mark all as paid” for a month.

### Phase 4 – Queue and reporting (optional)
1. **Queue**
   - Move PayrollService::generate() into a Job (e.g. `GeneratePayrollJob`). Route “Generate” dispatches job; show “Payroll generation started. We’ll notify when done.” or poll status.
2. **Reporting**
   - Payroll summary report (by month: total gross, total deductions, total net, headcount). Export CSV/Excel if needed.

---

## 4. Summary Table

| Feature | Old system | New system current | Plan (phase) |
|--------|------------|--------------------|--------------|
| payrolls table | ✅ | ✅ | – |
| payroll_components table | ✅ | ✅ | – |
| salary_components | ✅ | ✅ | – |
| salary_groups | ✅ | ✅ | – |
| salary_group_components | ✅ | ❌ | Phase 2 |
| basic_salary / basic_salary_details | ✅ | ❌ | Phase 1 (users.basic_salary or group components) |
| pre_payments table | ✅ | ❌ | Phase 3 |
| Payroll list + filter | ✅ | ✅ | – |
| Payroll settings (PF/ESI/PT) | ✅ | ✅ (toggles only) | Phase 2 (calculation) |
| Monthly payroll generation | ✅ | ❌ | Phase 1 |
| Payslip view (HTML) | ✅ | ❌ | Phase 1 |
| Payslip PDF download | ✅ | ❌ | Phase 3 |
| Queue for generation | ✅ | ❌ | Phase 4 |

---

## 5. Next Steps (implementation order)

1. **Migration**: Add `basic_salary` to `users` (nullable, decimal 12,2).
2. **PayrollService**: Implement `generate(company_id, year, month)` with basic_salary + present_days + working_days + simple LOP; create Payroll + PayrollComponent rows.
3. **PayrollController**: `postGenerate` action; replace generate view with month/year form.
4. **Payslip view**: New route + view for single payroll (employee, period, earnings, deductions, net).
5. Then Phase 2 (salary_group_components + PF/ESI/PT calculation), Phase 3 (PDF, pre_payments), Phase 4 (queue) as needed.
