########################################
# INVENTORY MODULE ENHANCEMENTS (المخزون)
########################################

We want to enhance the Inventory module as follows:

1) Improve product definition:
   - Add product usage type (sale / consumption / both).
   - Enforce sell price only when relevant.
   - Handle expiry date requirement.

2) Add an "Employee Custody" module:
   - Items taken from stock as custody for an employee.
   - Cost recorded and shown in employee profile.
   - Linked to stock movements.

3) Add improved inventory reports:
   - Stock movement & quantities by date.
   - Near-expiry products.

4) Implement moving weighted average cost for products purchased at different prices.


========================================
# A) PRODUCT TYPE & EXPIRY LOGIC
========================================

We already have a `products` table and stock/inventory logic.

We need to add a field to classify each product as:

- "sale"               → مبيع فقط
- "consume"            → استهلاك/صرف فقط
- "sale_and_consume"   → مبيع + استهلاك

### A.1 Update products table

Add new field:

- usage_type (string, not null, default "sale")
  // allowed values: "sale", "consume", "sale_and_consume"
  // Arabic meaning:
  // "sale"             = منتج مخصص للبيع فقط
  // "consume"          = منتج للصرف/الاستهلاك فقط (مواد خام، بن، شامبو داخلي، الخ)
  // "sale_and_consume" = منتج يمكن بيعه واستهلاكه داخليًا

Validation:
- On create/update product:
  - usage_type must be one of the three values.

### A.2 Sell price rules

We already have: `default_sell_price`.

Behavior:

- If usage_type is "sale" or "sale_and_consume":
  - default_sell_price is REQUIRED (not null).
  - If missing, return error:
    - "سعر البيع مطلوب لهذا المنتج لأنه مخصص للبيع".

- If usage_type is "consume":
  - There should be NO sell price shown in the UI for this product.
  - Backend:
    - Either store default_sell_price as null
    - And ignore any sell price in requests.
  - Do not allow this product to appear in normal sales lines (unless later explicitly allowed).

### A.3 Expiry date

We already have `has_expiry_date` on products and `expiry_date` on stock_batches/purchase lines.

Enforce:

- If product.has_expiry_date = true:
  - When creating purchase invoice lines / stock_batches for that product:
    - expiry_date is REQUIRED.
    - If missing, return:
      - "تاريخ الانتهاء مطلوب لهذا الصنف".
- If product.has_expiry_date = false:
  - expiry_date can be null.

UI:
- On product form:
  - If "تاريخ الانتهاء" (has_expiry_date) is checked:
    - Show a note that expiry_date will be required on purchases for this product.


========================================
# B) EMPLOYEE CUSTODY MODULE (عهدة الموظف)
========================================

We want a module to create "custody" records for employees:

- Take items from stock (products of usage_type = "consume" or "sale_and_consume").
- Quantity and cost are recorded.
- Shown under the employee profile as an active custody.
- The stock is reduced accordingly.

### B.1 Table: employee_custodies (عهدة الموظف)

Create new table:

- id (integer, primary key, auto increment)
- employee_id (integer, foreign key to employees.id, not null)
- product_id (integer, foreign key to products.id, not null)
- quantity (real, not null)
- unit_cost (real, not null)           // تكلفة الوحدة (بناءً على متوسط التكلفة الحالي)
- total_cost (real, not null)          // = quantity * unit_cost
- custody_date (date, not null)        // تاريخ إنشاء العهدة
- created_by_employee_id (integer, nullable, foreign key to employees.id) // المستخدم الذي أنشأ العهدة
- status (string, not null, default "open")
  // "open"            = عهدة مفتوحة
  // "returned"        = تم إرجاع العهدة بالكامل
  // "consumed"        = استهلاك داخلي بالكامل
  // "partially_returned" (optional)
  // "lost" or "damaged" (optional)
- notes (string, nullable)
- created_at (datetime)
- updated_at (datetime)

Rules:

- Only products with usage_type = "consume" or "sale_and_consume" can be used in custody.
  - If usage_type = "sale" only → return error:
    - "لا يمكن إنشاء عهدة من منتج مخصص للبيع فقط".

### B.2 Stock impact & movements

When creating a custody:

- Determine the current unit_cost:
  - Use the moving average cost for the product (see Section D below),
    or the product's current average cost.
- unit_cost = current average cost at the time of custody.
- total_cost = unit_cost * quantity.

Stock movements:

- Insert a new record into `stock_movements`:

  - product_id = custody.product_id
  - movement_date = custody_date
  - movement_type = "custody_issue"
  - quantity_in = 0
  - quantity_out = quantity
  - unit_cost = unit_cost
  - reference_type = "EmployeeCustody"
  - reference_id = employee_custodies.id
  - batch_id = null or appropriate batch if you implement batch-level deduction

- Reduce stock quantities accordingly.

Later (optional):
- If custody items are returned, create a "custody_return" stock_movement with quantity_in.

### B.3 Employee profile view

Add a section in the employee API and UI:

- GET /employees/:id/custodies

Return:

- active_custodies: [
    {
      "id": ...,
      "product_id": ...,
      "product_name_ar": ...,
      "quantity": ...,
      "unit_cost": ...,
      "total_cost": ...,
      "custody_date": ...,
      "created_by_employee_name": ...
    },
    ...
  ]

- Optionally, past_custodies (status != "open").

Show in employee details page something like:
- "عهدة حالية: 3 قطع من منتج X بتاريخ 2025-10-01 أنشأها المستخدم Y".


========================================
# C) INVENTORY REPORTS ENHANCEMENT
========================================

We already have some inventory reports. We need:

1) A report for stock movement and quantities over time.
2) A report for near-expiry products.


----------------------------------------
## C.1 Stock movements & quantities report
----------------------------------------

Create endpoint:

### GET /reports/stock-movement-summary

Query params:
- ?from_date=YYYY-MM-DD
- ?to_date=YYYY-MM-DD
- ?product_id= (optional)
- ?branch_id= (optional if branches exist)

For each product, return:

- product_id
- product_name_ar
- opening_quantity      // quantity at from_date (before movements in this period)
- quantity_in_period    // sum of quantity_in between from_date and to_date
- quantity_out_period   // sum of quantity_out between from_date and to_date
- closing_quantity      // quantity at to_date

Implementation concept:
- Use stock_movements table.
- opening_quantity = sum(quantity_in - quantity_out) for all movements before from_date.
- quantity_in_period = sum(quantity_in) for movements between from_date and to_date.
- quantity_out_period = sum(quantity_out) for same period.
- closing_quantity = opening_quantity + quantity_in_period - quantity_out_period.

This endpoint will support a UI report that can filter by date and product.


----------------------------------------
## C.2 Near-expiry products report
----------------------------------------

Create endpoint:

### GET /reports/stock-expiry

Query params:
- ?days=30 (default 30 days)

Return list of stock batches that will expire within the next X days:

For each row:
- product_id
- product_name_ar
- batch_id
- expiry_date
- quantity_on_hand
- unit_cost
- total_cost = quantity_on_hand * unit_cost
- days_to_expiry

Logic:

- current_date = today
- target_date = today + days
- Select from stock_batches where:
  - expiry_date IS NOT NULL
  - expiry_date >= today
  - expiry_date <= target_date
  - quantity_on_hand > 0


========================================
# D) MOVING AVERAGE COST (متوسط التكلفة)
========================================

We want to handle the case when the same product is purchased multiple times at different prices.

Rule:

- The cost of the product in inventory should be calculated using the moving weighted average method.

### D.1 Concept

For each product:

- Keep track of:
  - current_quantity_on_hand
  - current_average_unit_cost

Whenever a purchase comes in:

- Let:
  - Q_prev = previous quantity_on_hand
  - C_prev = previous average_unit_cost
  - Q_new  = quantity coming from the purchase (in sell units)
  - C_new  = unit cost of the new purchase (per sell unit)

Then:

- total_cost_prev = Q_prev * C_prev
- total_cost_new  = Q_new  * C_new
- Q_total = Q_prev + Q_new

- If Q_total > 0:
  - new_average_cost = (total_cost_prev + total_cost_new) / Q_total

Store:
- Update `products` table with:
  - average_unit_cost (new field)
- And use this average_unit_cost for:

  - unit_cost in stock_movements for sales/consumption/custody
  - valuation reports
  - employee custody unit_cost

### D.2 Implementation details

1) Add field to `products` table:

- average_unit_cost (real, nullable)
  // متوسط تكلفة المنتج بوحدة البيع

2) When processing purchase invoice lines:

- We already compute:
  - quantity_sell_unit
  - purchase_price_per_sell_unit (unit_cost)

For each line:

- Fetch current product.average_unit_cost and current stock quantity (sum of stock_batches.quantity_on_hand for this product).
- Use the formula above to compute new_average_cost.
- Update products.average_unit_cost to this value.
- Use this average_unit_cost as reference cost for future movements (sales, consumption, custody).

Note:
- Stock_batches.unit_cost can still store the actual invoice cost per batch if needed, but reports and movements should use the moving average where appropriate.


========================================
# GENERAL NOTES
========================================

- Use Arabic error messages such as:
  - "نوع المنتج مطلوب"
  - "سعر البيع مطلوب لهذا النوع من المنتجات"
  - "لا يمكن إنشاء عهدة من منتج مخصص للبيع فقط"
  - "تاريخ الانتهاء مطلوب لهذا الصنف"
- Keep the structure modular:
  - inventory-related routes in `src/routes/inventory` or similar.
  - custody-related routes in `src/routes/hr` or `src/routes/inventory` depending on current design.

- Do NOT break existing inventory endpoints; only extend them with the new fields and logic.
