# Plan wdrożenia: zakładka „Scrap Confirmation"

**Data:** 2026-04-08  
**Status:** Do zatwierdzenia — kod NIE został jeszcze wprowadzony  
**Moduły:** `scrap` (główny) + `scanstation` (migracja SQL)

---

## 1. Problem i cel

### Obecna sytuacja
Operatorzy na kiosku ScanStation zgłaszają scrap przyciskiem **REPORT SCRAP**.  
Dane trafiają do:
- `llx_scanstation_log` (scan_type = `'scrap'`) — ilość, powód, numer sztuki, stanowisko, MO
- `llx_scanstation_job_tracking` — numery sztuk oznaczonych jako złom

**Problem:** żaden z tych zapisów **nie tworzy ruchu magazynowego** w Dolibarr ani wpisu w `llx_scrap`.  
Scrap istnieje tylko w bazie ScanStation — system ERP o nim nie wie.

### Cel
Dać managerowi/quality możliwość **weryfikacji** każdego zgłoszenia scrapa z kiosku, a następnie zatwierdzenia go do systemu (bookowanie = tworzenie ruchu magazynowego + wpis w `llx_scrap`).

---

## 2. Gdzie pojawia się nowa zakładka

Menu Dolibarr: **Quality → Scrap Management → Scrap Confirmation**

```
Quality (top menu)
└── Scrap Management (sekcja lewa)
    ├── Add Scrap          (poz. 111)
    ├── Scrap List         (poz. 112)
    ├── Audit Log          (poz. 113)
    └── Scrap Confirmation (poz. 114) ← NOWE
```

Zakładka widoczna tylko gdy oba moduły (`scrap` i `scanstation`) są włączone.  
Uprawnienie wymagane: `scrap->write` (managerowie i quality mają je domyślnie).

---

## 3. Zmiany w bazie danych

### 3.1 Nowa kolumna w `llx_scanstation_log`

Plik: `scanstation/sql/migrate_add_booked_scrap.sql`

```sql
ALTER TABLE llx_scanstation_log
  ADD COLUMN IF NOT EXISTS booked_scrap_id  INT     DEFAULT NULL
    COMMENT 'NULL = oczekuje potwierdzenia | > 0 = zaksięgowany (rowid w llx_scrap) | -1 = odrzucony',
  ADD COLUMN IF NOT EXISTS confirmation_note VARCHAR(255) DEFAULT NULL
    COMMENT 'Notatka managera przy odrzuceniu lub zatwierdzeniu';
```

Znaczenie wartości `booked_scrap_id`:

| Wartość | Stan |
|---------|------|
| `NULL` | Oczekuje na weryfikację managera |
| `> 0` | Zaksięgowany — nr to `rowid` w `llx_scrap` |
| `-1` | Odrzucony przez managera (nie jest bookowany) |

> **Ważne:** `scan_action.php` (kiosk) nie jest modyfikowany — operatorzy pracują bez zmian.

---

## 4. Nowe menu — `scrap/core/modules/modScrap.class.php`

Dodajemy jeden wpis tablicy `$this->menu[]` przy pozycji 114, pod `fk_leftmenu=scrap_mgmt`:

```php
$this->menu[] = array(
    'fk_menu'  => 'fk_mainmenu=quality,fk_leftmenu=scrap_mgmt',
    'type'     => 'left',
    'titre'    => 'Scrap Confirmation',
    'mainmenu' => 'quality',
    'leftmenu' => 'scrap_confirmation',
    'url'      => '/custom/scrap/scrap_confirmation.php',
    'langs'    => 'scrap@scrap',
    'position' => 114,
    'enabled'  => '$conf->scrap->enabled && $conf->scanstation->enabled',
    'perms'    => '$user->rights->scrap->write',
    'target'   => '',
    'user'     => 2,
);
```

---

## 5. Nowa strona — `scrap/scrap_confirmation.php`

### 5.1 Widok domyślny — lista oczekujących (`booked_scrap_id IS NULL`)

Tabela z kolumnami:

| Data zgłoszenia | MO Ref | Job # | Part (ref + label) | Stanowisko | Operacja (op_rank) | Ilość | Powód / Notatka | Operator | Akcje |
|---|---|---|---|---|---|---|---|---|---|

Zapytanie SQL łączy:
- `llx_scanstation_log` (scan_type=`'scrap'`, booked_scrap_id IS NULL)
- `llx_mrp_mo` → ref MO
- `llx_product` → ref + label produktu + fk_product (potrzebne do bookowania)
- `llx_user` → imię i nazwisko operatora
- `llx_workstation_workstation` → nazwa stanowiska

Filtry nad tabelą: **zakres dat**, **wyszukiwarka** (MO ref / part ref / job number).

### 5.2 Akcja: „Book to system" (zielony przycisk)

Otwiera formularz inline (lub prosty POST) z polami:
- **Magazyn** (select z `llx_entrepot`) — wymagany
- **Koszt jednostkowy** — prefill z `product_extrafields` lub `product.cost_price`, edytowalny
- **Data scrapa** — prefill z `date_scan`, edytowalna

Po zatwierdzeniu:
1. Wywołuje `Scrap->create($user)` → tworzy wpis w `llx_scrap` + ruch magazynowy (MouvementStock)
2. `UPDATE llx_scanstation_log SET booked_scrap_id = {nowe_id_llx_scrap} WHERE rowid = {log_rowid}`
3. Przekierowanie z komunikatem sukcesu

### 5.3 Akcja: „Reject" (szary przycisk)

Opcjonalne pole tekstowe z powodem odrzucenia, a następnie:
```sql
UPDATE llx_scanstation_log
   SET booked_scrap_id = -1, confirmation_note = '{powód}'
 WHERE rowid = {log_rowid}
```
Wiersz znika z listy oczekujących.

### 5.4 Widok „Booked / Rejected" (przełącznik lub zakładka na tej samej stronie)

Parametr URL `?status=booked` lub `?status=rejected` pokazuje odpowiednio zaksięgowane/odrzucone wpisy z linkiem do `edit_scrap.php?id={booked_scrap_id}`.

---

## 6. Pliki do zmiany / stworzenia

| Plik | Akcja | Opis |
|---|---|---|
| `scanstation/sql/migrate_add_booked_scrap.sql` | **UTWÓRZ** | ALTER TABLE z nową kolumną |
| `scrap/core/modules/modScrap.class.php` | **EDYTUJ** | Dodaj wpis menu poz. 114 |
| `scrap/scrap_confirmation.php` | **UTWÓRZ** | Cała nowa strona (lista + akcje) |

### Pliki NIE zmieniane
- `scanstation/ajax/scan_action.php` — kiosk bez zmian
- `scanstation/scan_station.php` — kiosk bez zmian
- `llx_scrap` — tabela bez zmian (Scrap->create() wystarczy)

---

## 7. Decyzje wymagające potwierdzenia przed implementacją

| # | Pytanie | Domyślna propozycja |
|---|---|---|
| A | Czy magazyn ma być **wymagany** w formularzu bookowania, czy może być prefillowany z konfiguracji modułu (stały magazyn scrapa)? | Wymagany (select) |
| B | Czy „Reject" wymaga wpisania powodu, czy wystarczy sam klik? | Opcjonalny powód (textarea) |
| C | Czy status `booked/rejected` pokazujemy na tej samej stronie (toggle), czy jako osobną stronę? | Toggle na tej samej stronie |
| D | Czy potrzebna nowa osobna uprawnienie `scrap->confirm` (oddzielna od `write`)? | Nie — phase 1 używa `write` |

---

## 8. Czego NIE robimy (poza zakresem)

- Nie zmieniamy UX kiosku ScanStation
- Nie tworzymy automatycznego bookowania (np. po N minutach bez odrzucenia)
- Nie wysyłamy powiadomień email do managera (może być phase 2)
- Nie tworzymy raportów ani wykresów dla tej zakładki (są już w Scrap Dashboard)
