# ChangeLog – Planning Module

All notable changes to this module are documented here.

---

## [2.1.0] – 2026-04-05

### Added
- **Shift-aware downtime tooltip** — `shift_code` column added to `llx_planning_downtime`; planning grid downtime tooltip shows `[shift_code] category: Nm` per entry (newline-separated via `GROUP_CONCAT`)

### Changed
- **MO Timeline bar start** now uses `date_start_planned` from `llx_mrp_mo` as primary source (falls back to `MIN(schedule_date)` from planning schedule); bar position matches the locked/planned start date

### Fixed
- **Downtime badge** — a single downtime entry was rendering its badge on every MO row that had hours on the same day; fixed with `$dtBadgeShownForDate` tracker (badge shown once per day, on the first MO row)
- **Lock transfer on drag** — when dragging a locked MO down past another MO, the lock flag and `date_start_planned` are now correctly transferred to the MO that takes the original position; skip transfer when the target MO is already locked (two locked MOs swap positions without overwriting either lock)

---

## [2.0.0] – 2026-04-01

### Added
- **Planning Grid** (`planning.php`) — FM4-style day-allocation grid: MO rows × day columns, grouped by customer, with week headers
- `llx_planning_schedule` SQL table — stores planned hours per MO per day per workstation
- `llx_planning_capacity_override` table — per-date capacity overrides
- Click-to-edit cells with inline `<input>` + AJAX save (`ajax/schedule_save.php`)
- Capacity override row — editable footer row per column (`ajax/capacity_save.php`)
- Cell colour logic: green (OK) / yellow (overloaded) / red (late MO)
- Progress bar + remaining hours in MO row header
- **Calc engine** (`ajax/calc.php`) — full auto-scheduling: fills `llx_planning_schedule` from today forward per workstation capacity; respects `date_start_planned_locked`
- `calc_all.php` — recalculate all workstations in one call
- `date_start_planned_locked` flag on MOs — Calc preserves user-set start dates when locked
- **Timeline sync** — Calc writes `date_start_planned` / `date_end_planned` back to `llx_mrp_mo`; MOs with no schedule slots get NULL (cleared)
- Excel-style cell range selection with sum/avg status bar
- Drag-drop MO reorder with `ajax/reorder_mos.php`; transfers locked flag and date_start_planned to new position
- **Shift config admin** (`admin/planning_setup.php`) — per-workstation weekday hours (Mon–Sun + shift_start), UPSERT via form POST
- Weekend enable flags `use_sat` / `use_sun` per workstation; Sat/Sun toggles persist via `ajax/toggle_weekend.php`
- Runtime migration helper `lib/planning_migrate.php` for environments without manual SQL access
- **MO Timeline** view (`mo_gantt.php`) — Gantt-like per-MO bars with progress; renamed from "MO Gantt"
- **Completed** view (`completed.php`) — list of completed/produced MOs
- **Order Book** view (`order_book.php`) — monthly bar chart (Open vs Delivered qty) + grouped table from `openorderbook` module
- **Board cards** enriched: "Starts in" time-to-start badge, remaining hours, cumulative queue logic
- **Worker animation** (`js/worker.js`) — chubby SVG walking figure on Planning grid; enable/disable checkbox (default off), state persisted in `localStorage`
- `search_materials.php`, `search_products.php` AJAX endpoints for job creation modal

### Changed
- Nav bar: "Planning Board" renamed to **"Board"**; "MO Gantt" renamed to **"MO Timeline"** across all 5 views and menu entry
- Nav bar buttons: uniform `min-width`, consistent spacing and height across all pages
- Board cards: "Starts in" / remaining shown right-aligned per card
- Calc respects `date_start_planned` as scheduling start point when set in future; no-date MOs start after previous MO ends

### Fixed
- Calc: no-date MO starts after previous MO ends (not from global calcStart)
- Gantt progress uses last confirmed op (`qty_delta > 0`), not last planned op
- Reorder: reset auto-calc guard on drag-drop; transfer locked flag to new pos-1 MO
- Show Draft toggle shows only draft MOs (not include-draft)
- Section header hidden when all columns empty under Late-only filter
- Empty workstation columns hidden under Late-only filter
- Missing optracking table in `mo_gantt_data` handled gracefully (soft DB error)
- Smart empty state: auto-select first non-empty workstation

---

## [1.7.0] – 2026-03-29

### Added
- Weekend enable flags per workstation: `use_sat` and `use_sun` in `planning_ws_config`
- Runtime migration helper `lib/planning_migrate.php` to ensure weekend columns exist on environments without manual SQL access
- New AJAX endpoint `ajax/toggle_weekend.php` to persist Sat/Sun toggle state to DB

### Changed
- Planning toolbar Sat/Sun toggles now initialize from DB state and persist changes via AJAX (instead of local display-only state)
- Calc flow updated so weekend toggle state is part of scheduling rules per workstation

### Fixed
- Recalculation no longer schedules work on Saturday/Sunday when the respective day is disabled, even if `hrs_sat` / `hrs_sun` is set
- Cross-workstation weekend-state bleed removed during global calc
- Fatal error in migration bootstrap on environments where `$conf->global` is an object (`stdClass`) instead of an array
- Overdue MO filled cells now use the same highlight tone as the overdue row hover state for clearer visual feedback

---

## [1.6.0] – 2026-03-24

### Added
- **Shadow cards** — parallel / advanced optracking operations render as additional cards alongside the main MO card on the board
- **Configurable ghost TTL** — admin constant `PLANNING_GHOST_TTL_HOURS` controls how long Produced MO ghost cards stay visible (default: 24 h)
- Settings gear icon (⚙) in the Planning Board header links directly to `admin/setup.php`
- Admin setup page (`admin/setup.php`) with ghost TTL input

---

## [1.5.0] – 2026-03-23

### Added
- Produced MOs (status=3) remain visible on the Planning Board as ghost cards for 24 h after production
- `No dates set` placeholder card rendered for MOs that have no scheduled dates
- Ghost card countdown display showing remaining visibility time

### Fixed
- Produced MOs (status=3) were being excluded from the board query — now explicitly included for ghost rendering
- Top menu icons corrected for Planning Board and Timeline entries

---

## [1.4.0] – 2026-03-17

### Added
- **Per-section Complete badge** — each workstation section shows total qty produced, sourced from `llx_mrp_mo_optracking`; badge auto-hides 24 h after last produced MO in section
- **Ghost cards** — completed MOs render as faded ghost cards with countdown timer, disappearing after TTL expires
- **Dynamic sections** — workstations are grouped into sections automatically from the first word of the workstation label (e.g. `FORMING-1` → section `FORMING`); replaces hardcoded `forming` / `trimming` groups
- `data-section` attribute on board cards for JS-driven section filtering
- Tooltip helper functions extracted to shared lib

### Changed
- `qty_done` now sourced from `UNIX_TIMESTAMP`-based query on `llx_mrp_mo_optracking.qty_delta` rather than `llx_mrp_mo.qty_produced`
- Board query uses `UNIX_TIMESTAMP()` for optracking date comparisons (timezone-safe)

---

## [1.3.0] – 2026-02-01

### Added
- **Create MO** — AJAX action to create a new Manufacturing Order directly from the Timeline modal
- Create MO button in the Timeline header opens pre-filled modal

### Fixed
- Gantt bar height fills the full row height (previously clipped)
- Gantt bar alignment edge cases at day boundaries

### Improved
- Reduced header padding in Timeline for better use of vertical space

---

## [1.2.0] – 2026-01-31

### Added
- **Material field** on Timeline job cards
- **Pack number** field on Timeline job cards
- **Job prefill** — clicking an empty day cell in the Timeline pre-fills workstation and start date (06:30) in the Add Job modal
- **Gantt bars** rendered in timeline cells proportional to estimated hours vs. daily capacity
- **Schedule badge** on job detail card showing planned vs. elapsed status
- **Weekday labels** in timeline header columns
- **Works Order** reference displayed on job cards
- **More details** section in job detail panel — enriched job info from linked MO
- **Create MO** button and modal scaffold in Timeline (action wired in v1.3.0)

### Improved
- Job detail panel populated via AJAX on card click, replacing static server-rendered panel

---

## [1.1.0] – 2026-01-29

### Added
- `PlanningTimelineService` class (`class/PlanningTimelineService.class.php`) — server-side data layer for Timeline view
- Standardised AJAX JSON response format across all timeline endpoints
- Module roadmap file (`CLAUDE.md`) with architectural constraints

### Changed
- Performance: removed unused legacy query code paths from board rendering
- AJAX endpoints return consistent `{success, data, error}` envelope

---

## [1.0.0] – 2026-01-17

### Added
- Planning Board (Kanban) view grouped by workstation
- Fullscreen mode with dark theme and auto-refresh countdown
- Hidden scrollbars in fullscreen (scroll preserved)
- Sticky workstation headers
- Late / overdue indicator on MO cards with tooltip (planned end date)
- Frontend **Late only** filter
- Planning table view grouped by workstation
- Completed MOs view
- Planning Timeline — two-panel layout (left: job detail card, right: scrollable grid)
- Sticky machine column on horizontal scroll; sticky header row on vertical scroll
- Dynamic day column width (55–110 px based on viewport) with compact mode for narrow columns
- Add Job modal (`planning->addjob` permission) with AJAX submission and CSRF validation
- Edit Job panel (`planning->editjob` permission) — inline edit via AJAX

### Changed
- Planning Board set as default entry point from Dolibarr top menu
- Unified MO card rendering between `board.php` and `board_data.php`

- Clear error messages in modal

### ETAP 3.2a — Add Job from Timeline Cell Click (CLOSED)

- Day cells in machine rows are clickable
- Click opens Add Job modal with prefilled values:
  - Workstation: from clicked row
  - Start date: clicked day at 06:30 (planning day boundary)
  - End date: auto-calculated from estimated hours
- Added `date_start` and `date_end` columns to `llx_planning_job`
- Job positioning based on `date_start` using planning day logic (06:30 → 06:30)
- Migration script: `sql/llx_planning_job_add_dates.sql`

### ETAP 3.2 — Edit Job via Timeline (CLOSED)

- Added `planning->editjob` permission
- Edit button in job card (view mode)
- Edit mode with form fields: workstation, group, status, estimated hours, start, end, notes
- Save/Cancel actions
- AJAX submission to `ajax/update_job.php`
- Timeline refresh on successful save

---

## Known Limitations / Technical Notes

- The Planning Board uses **server-rendered HTML** with AJAX DOM replacement.
  This is intentional and aligned with Dolibarr architecture.
  Do not refactor to a JSON-only renderer unless explicitly required.

- Auto-refresh replaces board HTML entirely.
  Any UI state must be explicitly restored in JavaScript if persistence is required.

- Workstation information comes from `llx_mrp_mo_extrafields.working_station`
  and may be either an ID or free-text value, depending on data quality.

- Timeline uses **capacity-based positioning**, not true Gantt.
  Jobs are shown per day based on hours consumed, not precise time slots.

- Planning day boundary is **06:30 → 06:30**.
  A datetime at 04:00 belongs to the previous planning day.

- Sticky headers rely on a single scroll container.
  Introducing additional nested scroll areas may break expected behavior.

- The module is designed for **desktop-first usage**.
  Mobile usage is supported but simplified.

---
