================================================================================
MPUMALANGA PVC - SUPPLIERS MODULE
================================================================================
Last Updated: 2026-03-26
Path: /app/suppliers/
================================================================================

WHAT THIS SECTION DOES
-----------------------
Manages supplier (vendor) records. Suppliers are linked to stock items and
to supplier orders. The supplier code is especially important - it forms the
prefix of all supplier order numbers (e.g. supplier code "EDPVC" produces
order numbers "EDPVC_1", "EDPVC_2", etc.).

DATABASE TABLE: suppliers
  record_id       int   - Primary key (NO AUTO_INCREMENT)
  name            text
  code            text  - Short code (e.g. EDPVC) used in order numbers
  address         text
  email           text
  contact_person  text
  contact_number  text

================================================================================
FILES
================================================================================

home.php
--------
Lists all suppliers with an Edit button.
Uses: new table("suppliers") + add_action_button("edit_suppliers.php")
Note: Title says "JOB CARDS".

add_suppliers.php
-----------------
Form with fields: Name, Code, Address, Email, Contact Person, Contact Number.
Note on Code field:  Label says "first letter of each word" - e.g. for
"Elegant Designs PVC" the code would be "EDPVC".
Saves to save_suppliers.php.

save_suppliers.php
------------------
Inserts new supplier. Has same "if ($client_id > 0)" redirect bug as clients
module - the redirect may not fire because suppliers table has no AUTO_INCREMENT.

update_suppliers.php
--------------------
Updates supplier record. Same redirect bug.

edit_suppliers.php
------------------
Pre-filled edit form. Shows a WARNING message in red:
"CHANGING THE CODE AFTER SUPPLIER ORDERS HAS BEEN CREATED COULD CAUSE PROBLEMS"
This is because the supplier code is embedded directly in supplier_order_no
strings (e.g. "EDPVC_3") and the get_supplier_order AJAX uses it as a LIKE
pattern. Changing the code after orders exist will break the order number
sequence lookup.

================================================================================
KNOWN ISSUES
================================================================================
1. Title says "JOB CARDS".
2. Redirect bug on save/update (same as clients).
3. No stock item count visible on the supplier list.

================================================================================




================================================================================
MPUMALANGA PVC - STOCK MODULE
================================================================================
Last Updated: 2026-03-26
Path: /app/stock/
================================================================================

WHAT THIS SECTION DOES
-----------------------
Manages the product/stock catalogue. Stock items appear in quotes, invoices,
delivery notes, and supplier orders via the datalist system.

DATABASE TABLE: stock
  record_id        int   - Primary key (NO AUTO_INCREMENT)
  name             text  - Product description
  code             text  - Short product code (e.g. WH8F, DLVR)
  cost             text  - Cost/buy price
  retail           text  - Retail/sell price (used in quotes and invoices)
  contractors      text  - Contractor price
  shops            text  - Shop price
  unit_of_measure  text  - e.g. M2, LM, EACH
  status           int   - 1=active, 0=inactive (0 hides from datalists)
  supplier_id      int   - FK to suppliers.record_id
  stock_categories text  - Category name (free text, existing values shown as datalist)

SPECIAL STOCK CODES:
  DLVR  - Delivery fee item. This code is explicitly excluded from display
          in the work schedule table and the delivery PDF line items.
          Always check: if ($stock['code'] == "DLVR") { continue; }
  DISCOUNT - Special case in datalists. When selected, price is set to
             "-R 0.00" and qty to 1. User manually enters the discount amount.

================================================================================
FILES
================================================================================

home.php
--------
Lists all stock items with an Edit button.
Uses: new table("stock") + add_action_button("edit_stock.php")
Note: Title says "JOB CARDS".

add_stock.php
-------------
Form fields: Code, Name, Cost Price, Retail Price, Contractor Price,
Shop Price, Unit of Measure, Category (datalist from existing categories),
Status (dropdown), Supplier (dropdown).

Categories datalist:
  - Queries DISTINCT stock_categories from stock table.
  - Allows typing a new category or selecting an existing one.

save_stock.php
--------------
Inserts new stock item.
  - If cost/retail/contractors/shops are empty, defaults them to 0.0.
  - Uses number_to_save() to clean price values before saving.
  - Has same "if ($client_id > 0)" redirect bug.

edit_stock.php
--------------
Pre-filled edit form. Same layout as add.
Note: The retail price field uses type="email" (a bug - it works but shows
an email keyboard on mobile).

update_stock.php
----------------
Updates stock record.
  - Uses number_to_save(number_format(str_replace(...))) to clean price fields.
  - Has same redirect bug.

================================================================================
KNOWN ISSUES
================================================================================
1. Titles say "JOB CARDS".
2. Redirect bug on save/update.
3. edit_stock.php uses type="email" for retail price field.
4. Changing a stock code after it's been used in quotes/invoices will break
   those records since invoice_list stores stock_id (not code), but delivery
   notes store the code as a text string - delivery note PDFs would show the
   old code.

================================================================================




================================================================================
MPUMALANGA PVC - WORK SCHEDULE MODULE
================================================================================
Last Updated: 2026-03-26
Path: /app/work_schedule/
================================================================================

WHAT THIS SECTION DOES
-----------------------
Manages installation work schedules (job cards) for client installations.
A work schedule is created from an invoice via convert_to_order.php.
It shows what stock items need to be installed, has a job description field,
a customisable checklist, and a clause/terms section. It generates a PDF
work schedule document for the installation team.

DATABASE TABLES
---------------
orders:
  record_id    int   - Primary key (NO AUTO_INCREMENT)
  order_date   varchar - Installation date
  date_created varchar - When the record was created
  invoice_id   int   - FK to invoices.record_id
  description  text  - Job description
  clause       text  - Legal clause (pre-filled with satisfaction statement)
  user_id      int   - FK to users

order_list:
  record_id    int
  order_id     int   - FK to orders.record_id
  stock_id     int   - FK to stock.record_id
  qty          text
  size_m       text

order_checklist:
  record_id  int
  order_id   int   - FK to orders.record_id
  text       text  - One checklist item

================================================================================
FILES
================================================================================

home.php
--------
Lists all work schedule orders with an Edit button.
Uses: new table("orders") + add_action_button("edit_work_schedule.php")

Note: The quick_bar path is set to "/app/orders/" - this means the quick bar
looks for a folder called "orders" which does not exist in the app. It will
show an empty nav bar. Should be "/app/work_schedule/".

--------------------------------------------------------------------------------
edit_work_schedule.php
----------------------
What it does:
  The main work schedule form. Shows the installation date, a read-only list
  of stock items from the order (what needs to be installed), a job description
  textarea, a dynamic checklist table, and a clause textarea.

How it works:
  On load:
    - Loads order by $_GET['record_id'].
    - Loads order_list JOIN stock to show the items.
    - Loads order_checklist to pre-fill existing checklist items.

  Stock items table (top):
    - READ ONLY. Shows Code, Stock Code (actually the stock code again - same
      field used twice, minor bug), Qty, Size M.
    - Skips items with stock code "DLVR".
    - User cannot edit or add to this table.

  Checklist table (bottom):
    - EDITABLE. User can add and delete checklist items.
    - add_row() adds a textarea row with name="list[]".
    - delete_row() removes a row.

  Saves to update_orders.php.

Note: The quick_bar path is "/app/invoices/" - so this page shows the invoices
nav bar, not the work schedule nav bar.

JS Functions:
  add_row()       - Adds a new checklist textarea row.
  delete_row(el)  - Removes a checklist row.
  save(url)       - Collects all inputs and submits POST form.

--------------------------------------------------------------------------------
update_orders.php
-----------------
What it does:
  Updates the order record (date, description, clause) and rebuilds
  the checklist items.

How it works:
  - Sanitises clause and description (strips quotes and double-quotes).
  - Updates orders table (user_id, clause, description, order_date).
  - DELETEs all order_checklist rows for this order.
  - Re-inserts each non-empty checklist item from $_POST['list'].
  - Redirects to home.php.

Note: order_list (the stock items) is NOT updated here. The items are fixed
to what was on the invoice when the order was created.

--------------------------------------------------------------------------------
save_orders.php
---------------
This file appears to be old/unused. It references "root.class.php" and
a "db_safeguard" class which do not exist in the current codebase. It also
uses a different form structure (order_no, counter, color_code_N etc).
DO NOT USE. Left in place but effectively dead code.

--------------------------------------------------------------------------------
order.pdf.php
-------------
What it does:
  Generates a PDF work schedule for the installation team (?record_id=X).

PDF contents:
  - "WORK SCHEDULE" title.
  - Client and company details.
  - Today's date.
  - Stock items table: Code, Description, Size, Quantity, Tick column.
    Skips DLVR items.
  - Job Description block.
  - Checklist table: Description, Tick column.
  - Signature lines: Site Manager and Client.
  - Clause text.

================================================================================
KNOWN ISSUES SUMMARY
================================================================================
1. edit_work_schedule.php quick_bar path is "/app/invoices/" (wrong section bar).
2. home.php quick_bar path is "/app/orders/" (folder doesn't exist, empty bar).
3. Stock items table shows stock code twice instead of code + name (display bug).
4. save_orders.php is dead code with references to non-existent classes.
5. The order_list items cannot be edited from the work schedule - only via
   re-running convert_to_order.php from the invoice.

================================================================================