########################################
# 9) EMPLOYEES, ROLES & BASIC HR (الموظفون والموارد البشرية)
########################################

We now want to define the core HR module:
- Employees master data
- Roles (for system access and permissions later)
- Employee tasks (مهام)
- Basic payroll generation (توليد الرواتب)

This module must be designed to be extensible, because later we will add:
- Attendance
- Shifts
- Overtime
- Commissions from services/products/cafeteria
- Integration with accounting journal entries


########################################
# 9.1 ROLES (الأدوار)
########################################

### Table: roles
Defines high-level roles in the system (e.g., Admin, Receptionist, Stylist, Accountant).

Fields:
- id (integer, primary key, auto increment)
- name_ar (string, not null, unique)     // مثال: "مدير النظام", "الاستقبال", "محاسبة", "فنية تجميل"
- code (string, nullable, unique)        // مثال: "ADMIN", "RECEP", "ACCOUNTANT"
- description_ar (string, nullable)
- is_active (boolean, default true)
- created_at (datetime)
- updated_at (datetime)

Notes:
- Later, we can add a separate permissions table.
- For now, we can assume that the frontend will decide which pages to show per role code.


### Roles APIs

1) GET /roles
   - List all roles (with optional filter ?is_active=true/false).

2) POST /roles
   - Create a new role.
   - Request JSON example:
   {
     "name_ar": "مدير النظام",
     "code": "ADMIN",
     "description_ar": "صلاحيات كاملة على النظام",
     "is_active": true
   }

3) GET /roles/:id
   - Get a single role.

4) PUT /roles/:id
   - Update role fields.

5) DELETE /roles/:id
   - Soft delete or set is_active = false.


########################################
# 9.2 EMPLOYEES (الموظفون)
########################################

Employees will later be linked to user accounts for login and role-based access.
For now, we define the full employee profile with HR data.

### Table: employees
Fields:
- id (integer, primary key, auto increment)
- full_name_ar (string, not null)                   // اسم الموظف
- phone_country_code (string, not null, default "966") // كود الدولة (مثال: 966)
- phone_number (string, not null)                   // رقم الجوال (10 أرقام، يبدأ بـ 0) - validation in code
- email (string, not null, unique)
- fingerprint_employee_no (string, nullable, unique) // Employee No (Fingerprint device)
- profile_image_url (string, nullable)              // صورة الملف الشخصي
- job_title_ar (string, not null)                   // الوظيفة (مثال: "أخصائية شعر", "مشرفة فرع")
- role_id (integer, foreign key to roles.id, not null) // الدور في النظام
- city_name_ar (string, nullable)                   // المدينة (أو لاحقاً نربط بجدول مدن)
- branch_id (integer, nullable)                     // الفرع (from branches table later)
- nationality_name_ar (string, not null)            // الجنسية (أو لاحقاً نربط بجدول جنسيات)
- birth_date (date, nullable)                       // يوم الميلاد
- hire_date (date, nullable)                        // بدأ العمل
- iqama_number (string, nullable)                   // رقم الإقامة
- iqama_expiry_date (date, nullable)                // انتهاء صلاحية الإقامة
- insurance_company (string, nullable)              // شركة التأمين
- insurance_number (string, nullable)               // رقم التأمين
- insurance_expiry_date (date, nullable)            // انتهاء التأمين
- insurance_card_expiry_date (date, nullable)       // انتهاء صلاحية بطاقة التأمين
- health_number (string, nullable)                  // Health Number
- passport_number (string, nullable)                // رقم الجواز
- passport_expiry_date (date, nullable)             // انتهاء الجواز
- annual_leave_days (integer, not null, default 0)  // عدد أيام الإجازة السنوية المستحقة
- weekly_off_day (string, nullable)                 // العطلة الأسبوعية (e.g. "friday", "saturday", "friday_saturday")
- is_active (boolean, default true)
- created_at (datetime)
- updated_at (datetime)

Notes:
- We assume that city, branch, nationality will be either free-text or linked to other tables later.
- Later, we can add a separate "users" table for login credentials linked to employees.id.


### Employees APIs

1) GET /employees
   - List employees with optional filters:
     - ?is_active=true/false
     - ?branch_id=
     - ?role_id=
     - ?search= (by name, phone, email)
   - Return:
     - id, full_name_ar, phone_country_code, phone_number, email, job_title_ar, role_id, role_name_ar, branch_id, nationality_name_ar, is_active.

2) POST /employees
   - Create a new employee.
   - Request JSON example:
   {
     "full_name_ar": "سارة محمد",
     "phone_country_code": "966",
     "phone_number": "0551234567",
     "email": "sara@example.com",
     "fingerprint_employee_no": "E123",
     "profile_image_url": null,
     "job_title_ar": "أخصائية تجميل",
     "role_id": 2,
     "city_name_ar": "جدة",
     "branch_id": 1,
     "nationality_name_ar": "سعودية",
     "birth_date": "1995-05-10",
     "hire_date": "2023-01-01",
     "iqama_number": null,
     "iqama_expiry_date": null,
     "insurance_company": "شركة بوبا",
     "insurance_number": "INS-12345",
     "insurance_expiry_date": "2025-01-01",
     "insurance_card_expiry_date": "2024-12-31",
     "health_number": "H123",
     "passport_number": null,
     "passport_expiry_date": null,
     "annual_leave_days": 21,
     "weekly_off_day": "friday",
     "is_active": true
   }

   Validation examples:
   - full_name_ar, phone_number, email, job_title_ar, role_id, nationality_name_ar are required.
   - phone_number must be 10 digits and start with "0".
   - Return Arabic error messages, e.g.:
     - "اسم الموظف مطلوب"
     - "رقم الجوال غير صحيح"
     - "البريد الإلكتروني مطلوب"
     - "الدور الوظيفي غير موجود"

3) GET /employees/:id
   - Return full employee profile, including role name and basic HR fields.

4) PUT /employees/:id
   - Update employee fields.

5) DELETE /employees/:id
   - Soft delete (set is_active = false).


########################################
# 9.3 EMPLOYEE TASKS (مهام الموظفين)
########################################

Supervisors should be able to assign tasks to employees.
When an employee logs in (later), he/she will see assigned tasks and can update their status.

### Table: employee_tasks
Fields:
- id (integer, primary key, auto increment)
- title (string, not null)                         // عنوان المهمة
- description (string, nullable)                   // تفاصيل المهمة
- assigned_to_employee_id (integer, not null)      // الموظف المكلّف بالمهمة
- assigned_by_employee_id (integer, nullable)      // المشرف أو المسؤول الذي كلف بالمهمة
- due_date (date, nullable)                        // تاريخ الاستحقاق
- status (string, not null)                        // "new", "in_progress", "completed", "canceled", "overdue"
- priority (string, nullable)                      // "low", "medium", "high"
- created_at (datetime)
- updated_at (datetime)
- completed_at (datetime, nullable)

Behavior:
- If due_date is in the past and status is not "completed" or "canceled", the system may treat it as "overdue" in reports.


### Employee Tasks APIs

1) GET /employee-tasks
   - List tasks with filters:
     - ?assigned_to_employee_id=
     - ?status=
     - ?due_date=YYYY-MM-DD
   - Used by supervisors and employees.

2) POST /employee-tasks
   - Create a new task.
   - Request JSON example:
   {
     "title": "ترتيب مخزن المنتجات",
     "description": "مراجعة الكميات وتنظيف الرفوف",
     "assigned_to_employee_id": 7,
     "assigned_by_employee_id": 3,
     "due_date": "2025-10-05",
     "status": "new",
     "priority": "medium"
   }

3) GET /employee-tasks/:id
   - Get single task details.

4) PUT /employee-tasks/:id
   - Update task fields, including status.
   - If status becomes "completed", set completed_at = now.

5) DELETE /employee-tasks/:id
   - Optional: soft delete or physical delete (you can choose and document).


########################################
# 9.4 PAYROLL (الرواتب وتوليد الرواتب)
########################################

We now define basic payroll structures.
Later, this will be integrated with:
- Attendance (حضور وانصراف)
- Overtime (عمل إضافي)
- Commissions from services/products/cafeteria/targets
- Accounting journal entries

For now, we will:
- Define a salary profile for each employee
- Define a payroll run (for a given month)
- Store calculated payroll amounts per employee


### Table: salary_profiles
Defines base salary structure for each employee.

Fields:
- id (integer, primary key, auto increment)
- employee_id (integer, foreign key to employees.id, unique)
- basic_salary (real, not null, default 0)            // الراتب الأساسي
- housing_allowance (real, not null, default 0)       // بدل سكن
- transport_allowance (real, not null, default 0)     // بدل مواصلات
- other_fixed_allowances (real, not null, default 0)  // بدلات ثابتة أخرى
- target_amount (real, not null, default 0)           // التارجت الشهري (إن وجد)
- commission_percent_services (real, not null, default 0)   // نسبة من خدمات
- commission_percent_products (real, not null, default 0)   // نسبة من منتجات
- commission_percent_cafeteria (real, not null, default 0)  // نسبة من مبيعات الكافتيريا
- is_active (boolean, default true)
- created_at (datetime)
- updated_at (datetime)

Notes:
- Later, we can calculate commissions automatically from sales/orders modules.
- For now, we may allow manual input of commission_amount in payroll_lines.


### Table: payroll_runs
Represents a payroll period (e.g., monthly payroll).

Fields:
- id (integer, primary key, auto increment)
- period_name (string, not null)          // مثال: "Payroll 2025-10"
- period_start_date (date, not null)
- period_end_date (date, not null)
- status (string, not null)               // "draft", "approved", "paid"
- notes (string, nullable)
- created_at (datetime)
- updated_at (datetime)

Rules:
- We should not allow overlapping periods with status != "canceled" (optional validation).


### Table: payroll_lines
Payroll calculation per employee in a given payroll_run.

Fields:
- id (integer, primary key, auto increment)
- payroll_run_id (integer, foreign key to payroll_runs.id)
- employee_id (integer, foreign key to employees.id)
- basic_salary (real, not null, default 0)
- fixed_allowances (real, not null, default 0)     // housing + transport + other_fixed
- overtime_amount (real, not null, default 0)      // عمل إضافي
- commission_amount (real, not null, default 0)    // عمولة (خدمات/منتجات/كافتيريا) – يمكن أن تكون محسوبة يدويًا أو لاحقًا من النظام
- other_earnings (real, not null, default 0)       // مكافآت أخرى
- deduction_late (real, not null, default 0)       // خصومات تأخير / غياب
- deduction_other (real, not null, default 0)      // خصومات أخرى
- gross_salary (real, not null, default 0)         // إجمالي المستحق قبل الخصومات
- total_deductions (real, not null, default 0)     // مجموع الخصومات
- net_salary (real, not null, default 0)           // صافي الراتب
- notes (string, nullable)
- created_at (datetime)
- updated_at (datetime)

Calculation rule:
- gross_salary = basic_salary + fixed_allowances + overtime_amount + commission_amount + other_earnings
- total_deductions = deduction_late + deduction_other
- net_salary = gross_salary - total_deductions


### Payroll APIs

1) POST /salary-profiles
   - Create or update a salary profile for an employee.
   - Request JSON example:
   {
     "employee_id": 7,
     "basic_salary": 4000,
     "housing_allowance": 1000,
     "transport_allowance": 500,
     "other_fixed_allowances": 0,
     "target_amount": 12000,
     "commission_percent_services": 10,
     "commission_percent_products": 5,
     "commission_percent_cafeteria": 3,
     "is_active": true
   }

2) GET /salary-profiles/:employee_id
   - Get salary profile for a specific employee.

3) POST /payroll-runs
   - Create a new payroll period in "draft" status.
   - Request JSON example:
   {
     "period_name": "Payroll 2025-10",
     "period_start_date": "2025-10-01",
     "period_end_date": "2025-10-31",
     "notes": "رواتب شهر أكتوبر 2025"
   }

   Behavior:
   - Initialize empty payroll_lines; frontend or another endpoint will populate lines.

4) POST /payroll-runs/:id/generate-lines
   - (Basic implementation) Generate payroll_lines based on salary_profiles for all active employees.
   - For now:
     - Fill basic_salary and fixed_allowances from salary_profiles.
     - Set overtime_amount, commission_amount, other_earnings, deductions to 0 initially.
   - The aim is to create a draft that HR can edit manually.

5) PUT /payroll-lines/:id
   - Update a specific payroll line (e.g., enter overtime_amount, commission_amount, deductions, notes).
   - Recalculate gross_salary, total_deductions, net_salary according to the formula.

6) GET /payroll-runs/:id
   - Return:
     - payroll_run header
     - payroll_lines with employee names and net_salary.

7) POST /payroll-runs/:id/approve
   - Change status from "draft" to "approved".

8) POST /payroll-runs/:id/mark-paid
   - Change status from "approved" to "paid".
   - Later, we can add automatic journal entries on this step.


### Validation & Arabic messages

- If employee_id not found when creating salary profile:
  - Return: "الموظف غير موجود".
- When creating a payroll_run with invalid dates:
  - Return: "تاريخ الفترة غير صحيح".
- When updating payroll_lines:
  - Ensure net_salary is calculated server-side, not trusted from client.
- Return Arabic error messages where possible, for example:
  - "لا يمكن اعتماد الرواتب قبل توليد بنود الرواتب للموظفين"
  - "لا يمكن تغيير حالة الرواتب بعد وسمها كمدفوعة"
