# Woo 5E Shipping — Dokumentacija

## Pregled

Woo 5E Shipping povezuje WooCommerce sa 5Element shipping API‑jem kako bi trgovac mogao da preuzme kurirske službe vezane za svoje kredencijale i svaku od njih prikaže kao opciju dostave na prodavnici (u korpi i na checkout stranici).  
Plugin obezbeđuje:

- Administrativna podešavanja za čuvanje 5E kredencijala i izbor kurira/okruženja koja će biti dostupna kupcima.
- Matricu cena po kurirskoj službi (težinski rasponi + neto/PDV/bruto vrednosti) koja direktno utiče na kalkulaciju svake stope.
- Automatsko otkrivanje aktivnog API endpoint‑a na staging 5E okruženju, uključujući podršku za novi `/company-courier-lists/get-by-credentials/{fiveEId}` koji zahteva `X-Auth-Key` header.
- Generisanje WooCommerce stopa tako da svaki omogućeni kurir postaje zasebna stopa, pri čemu je izabrani podrazumevani kurir unapred čekiran, ali kupac može da promeni izbor.
- Automatizovano prosleđivanje porudžbina ka Last Mile/5E API‑ju (`/orders/process/{clientId}`) čim order pređe u jedan od izabranih statusa (*Processing*, *Completed* po difoltu) ili ručno putem Order actions dugmeta “Send to 5E / Last Mile”.

## Zahtevi

- WordPress sa aktivnim WooCommerce‑om.
- Aktivan 5Element nalog sa validnim 5E ID‑om i API Auth Key‑jem.
- Izlazni HTTPS pristup sa web servera prema `https://api-staging.5element.concordsofttest.com`.

## Stranica sa podešavanjima

Podešavanja se sada nalaze unutar WooCommerce ekrana: **WooCommerce → Settings → Shipping → 5E Shipping**.  
Nova sekcija učitava standardni WooCommerce obrazac, tako da sve informacije ostaju u istom „Save changes“ toku:

1. Unesi **5E ID** i **API Auth Key** i izaberi okruženje (`staging` ili `production`).  
2. (Opciono) Postavi rezervnu flat cenu koja se koristi ako nijedan kurir nije omogućen.  
3. U sekciji **Courier pricing matrix** kreiraj/rediguj matricu cena za svaku kurirsku službu (po želji dodaj i napomene). Po difoltu je popunjen BEX cenovnik koji možeš da menjaš ili proširiš.  
4. Klikni **Fetch couriers from 5E** kako bi se API pozvao i osvežio keš (`w5e_couriers_cache`).  
5. Kada se tabela pojavi, čekiraj kurire/okruženja koja želiš da ponudiš i izaberi jednog kao **Default**.  
6. Klikni **Save changes** da bi WooCommerce sačuvao vrednosti, matricu i obradio listu kurira.

### Order forwarding ka Last Mile

- U okviru sekcije **Order forwarding (5E)** uključi opciju *Enable order forwarding* kako bi se porudžbine automatski slale na `/orders/process/{Client 5E ID}` endpoint.
- Izaberi statuse koji treba da triggeruju izvoz (multiselect polje “Trigger on statuses”).
- Podesi podatke koje API zahteva (Client warehouse ID, Created/edited by user ID, Buy-out račun, izbor ko plaća dostavu, pre-notifikaciju primaocu itd.).
- Plugin koristi WooCommerce podatke (adresu, telefon, email, sadržaj korpe, ukupnu cenu, cenu dostave, težину artikala) i mapira kurira na osnovу izabrane 5E rate (BEX, DExpress, AKS, PostExpress, City, GLS). ParcelType se automatski izračunava prema ukupnoj težini.
- U auto režimu ručno slanje možeš pokrenuti iz Order actions dropdown‑a → **Send to 5E / Last Mile**. U manual režimu to dugme se nalazi u meta box‑u **5E Import** na ekranu porudžbine. Meta podaci (`_w5e_order_exported`, `_w5e_order_export_payload`, `_w5e_order_export_error`) ostaju na porudžbini radi dijagnostike, a WP logger (`source: woo-5e`) beleži svaki pokušaj.
- Ako hosting ne može da razreši `api-staging.lastmile.rs`, popuni polje **Custom order API URL** (npr. `https://api.lastmile.rs/`) kako bi ručno definisao bazni domenski naziv za `/orders/process` pozive.

### Manual import režim (ručno slanje)

- Kada je **Import mode** podešen na `manual`, porudžbine se ne šalju automatski: u adminu se pojavljuje meta box **5E Import** sa izborom magacina i dugmetom za slanje.
- U manual režimu nove 5E porudžbine ostaju u statusu **Čeka odabir magacina** dok se ne odabere magacin i ručno pošalju u 5E; nakon uspešnog slanja status prelazi u **U obradi**.
- Ako je izabrana opcija plaćanja **Direktna bankovna transakcija (BACS)**, porudžbina dobija status **Čeka se uplata/proknjiženje** i slanje u magacin je blokirano dok uplata nije potvrđena (promena statusa).
- U admin listi porudžbina ljubičasto je obojen samo status **Čeka odabir magacina** radi jasnog razlikovanja.

### Mapiranje statusa (Woo ↔ 5E)

Woo → 5E (`OrderStatus` u payload‑u):

- `w5e_waiting_payme`, `w5e_processing`, `processing`, `completed`, `pending`, `on-hold` → `Pending`
- `cancelled`, `canceled`, `refunded`, `failed` → `Canceled`
- `in-progress`, `in_progress` → `In Progress`
- ostalo → `Pending`

5E → Woo (webhook):

- `pending`, `awaiting_confirmation`, `in_progress`, `processed` → `processing`
- `processing` → `completed`
- `delivered` → `completed`
- `with_courier` → `wc-w5e_in_transit` (labela: “5E u isporuci”)
- `returned_to_sender` → `wc-w5e_returned` (labela: “5E vraćena”)
- `cancelled`/`canceled` → `cancelled`
- `deleted` → nema promene statusa

### Matrica cena (Courier pricing matrix)

- Svaka kartica predstavlja jednu kurirsku službu i sadrži dva dela: **Standard shipments** (rasponi u kg sa neto/PDV/bruto cenama) i **Additional services** (fiksne ili procentualne dodatne usluge).  
- Polje *Slug/identifier* mora da bude jedinstveno i treba da se poklapa sa „slug-om“ kurira (npr. `bex`, `partner-123`, `delivery-x`). Ako se polje ostavi prazno koristi se automatski slug formiran od naziva kurira.  
- WooCommerce kalkulacija koristi bruto cenu iz prvog reda koji pokriva težinu paketa. Ako se ne pronađe odgovarajući red, primenjuje se fallback red sa `slug` vrednošću `default` ili `generic`, a tek onda flat cena.  
- Tipke **Add courier pricing**, **Add row/service/note** i dugmad za uklanjanje rade direktno u formi; podaci se trajno čuvaju tek nakon “Save changes”.

### Automatsko vezivanje shipping metode

Svaki put kada se stranica sa podešavanjima učita ili sačuva, `W5E_Settings::ensure_shipping_method_linked()` proverava da li je 5E shipping metoda (`w5e`) vezana za sve WooCommerce shipping zone, uključujući zonu “Locations not covered by your other zones”. Nema potrebe za ručnim podešavanjem zona.

## Integracija sa API‑jem

- `W5E_API::get_company_couriers_by_credentials()` prolazi kroz više kombinacija metoda/putanja/parametara dok ne dobije uspešan JSON odgovor.  
- Uspešna kombinacija se kesira u opciji `w5e_couriers_endpoint` kako bi se preskočilo ponovno detektovanje.
- Primarni obrazac koristi staging GET endpoint:  
  `GET /company-courier-lists/get-by-credentials/{fiveEId}` uz header `X-Auth-Key: {apiKey}`.
- Ako kesirani obrazac prestane da radi (npr. promena API‑ja), metoda se vraća na autodetekciju i nastavlja sa fallback varijantama, a greške prikazuje u admin interfejsu.
- `W5E_API::process_order()` koristi `https://api-staging.lastmile.rs/` ili `https://api.lastmile.rs/` (u zavisnosti od podešene okoline) i poziva `POST /orders/process/{ClientID}` sa JSON payload‑om koji se gradi iz WooCommerce ordera + dodatnih polja iz podešavanja. Neuspešni pokušaji bacaju izuzetак и loguju se. `W5E_Orders` detektuje statusne promene (podesivo) i registruje ručnu radnju “Send to 5E / Last Mile”.

## Ponašanje na prodavnici

### Address directory (checkout)

Kada je uključena opcija **Address directory** (`w5e_use_address_directory = yes`), plugin utiče na sledeća polja na checkoutu (billing + shipping, classic i blocks):

- **City** (`#billing_city`, `#shipping_city`, `#billing-city`, `#shipping-city`): autocomplete za grad; popup se zatvara nakon izbora i otvara se ponovo tek na klik; pri promeni grada briše se ulica.
- **Address 1** (`#billing_address_1`, `#shipping_address_1`, `#billing-address_1`, `#shipping-address_1`): autocomplete za ulicu; polje je disabled dok nije izabran grad.
- **Address 2** (`#billing_address_2`, `#shipping_address_2`, `#billing-address_2`, `#shipping-address_2`): samo se pozicionira ispod address_1 (nema autocomplete).
- **Postcode** (`#billing_postcode`, `#shipping_postcode`, `#billing-postcode`, `#shipping-postcode`): readonly; automatski se popunjava pri izboru grada; pozicionira se pored City (billing/shipping).
- **State/District** (`#billing_state`, `#shipping_state`, `#billing-state`, `#shipping-state`): upisuje opštinu iz izbora grada.

- `WC_Shipping_5E::calculate_shipping()` čita opcije `w5e_enabled_partners` **i** `w5e_pricing_matrix`, izračunava težinu paketa i za svaku stopu pronalazi odgovarajući raspon iz matrice.  
  - Svaka stopa dobija meta podatke (`w5e_key`, `w5e_partner_id`, `w5e_env`, opcioni `w5e_default`, `w5e_cost_source`) da bi checkout filteri mogli da prepoznaju podrazumevanu stopu i da li je cena došla iz matrice ili rezervne flat vrednosti.  
  - Ako nema omogućenih kurira, dodaje se jedna generička stopa “Dostava (5E)” i na nju se primenjuje ista logika: prvo matrica (`generic`/`default` slug), zatim flat iznos.
- Filteri registrovani putem `WC_Shipping_5E::register_filters()` prilagođavaju checkout iskustvo:
  - `woocommerce_package_rates`: postavlja podrazumevanog kurira na prvo mesto, ali ostavlja sve ostale kurire vidljive.
  - `woocommerce_shipping_chosen_method`: zadržava izbor kupca kada promeni kurira; ako nema izbora, vraća se na podrazumevanu stopu.
- Rezultat je lista radio dugmadi u korpi i na checkoutu koja prikazuje sve omogućene kurire, sa default kurirskom službom koja je inicijalno izabrana.

## Skladištene opcije

| Naziv opcije             | Svrha                                                           |
|--------------------------|-----------------------------------------------------------------|
| `w5e_id`                 | Sačuvani 5E ID iz forme.                                        |
| `w5e_api_key`            | Sačuvani API Auth Key.                                          |
| `w5e_env`                | Izabrano okruženje (`staging`/`production`).                    |
| `w5e_flat_price`         | Flat cena (string).                                             |
| `w5e_couriers_cache`     | Poslednja lista kurira/okruženja dobijena sa API‑ja.            |
| `w5e_couriers_endpoint`  | Kesirani podatak o pronađenom endpointu (metod/putanja/mod).    |
| `w5e_enabled_partners`   | Lista omogućenih kurira sa metapodacima i oznakom defaulta.     |
| `w5e_pricing_matrix`     | Matrica cena po kuriru (težinski rasponi + dodatne usluge).     |
| `w5e_order_forwarding_enabled`, `w5e_order_export_statuses`, `w5e_client_*`, `w5e_orders_base_url`… | Konfiguracija automatskog (i ručnog) prosleđivanja porudžbina ka Last Mile API‑ju. |

Sve opcije se kreiraju prilikom aktivacije plugina, a kasnije se ažuriraju preko forme sa podešavanjima.

## Saveti za rešavanje problema

1. **Fetch vraća HTTP grešku**  
   - Proveri da li su 5E kredencijali tačni. Kodovi 401/403 znače pogrešne podatke.  
   - Pogledaj poruku na stranici – sadrži URL i raw body odgovora.

2. **Kuriri se ne pojavljuju na checkoutu**  
   - Uveri se da su kuriri čekirani u tabeli i da `w5e_enabled_partners` sadrži stavke.  
   - Posle čekiranja obavezno klikni “Save changes” u okviru **WooCommerce → Settings → Shipping → 5E Shipping** da bi plugin ponovo povezao shipping metodu.  
   - Na korpi/checkoutu klikni “Recalculate shipping” kako bi WooCommerce povukao nove stope.

3. **Vidljiv je samo default kurir**  
   - Proveri da li keširanje (WordPress cache, WooCommerce transients, CDN) služi stara shipping data. Plugin ionako ostavlja sve stope, pa keš može da sakrije nove.

4. **Treba resetovati autodetekciju endpointa**  
   - Obrisi opciju `w5e_couriers_endpoint` (WP‑CLI, baza). Sledeći fetch ponovo prolazi kroz sve kombinacije.

## Struktura fajlova (osnovno)

```
woo-5e/
├── woo-5e.php                        # Bootstrap plugina
├── languages/
│   └── woo-5e.pot                    # Referentni prevod (Text Domain: woo-5e)
├── includes/
│   ├── class-w5e-api.php             # Klijent za 5E API + autodetekcija
│   ├── class-w5e-settings.php        # Admin UI, AJAX fetch, rukovanje opcijama
│   ├── class-w5e-orders.php          # Automatski export WooCommerce porudžbina ka Last Mile
│   └── class-w5e-shipping.php        # WooCommerce shipping metoda i filteri
└── assets/
    └── admin.js                      # AJAX helper + builder za matricu cena
```

## Internacionalizacija

- Sve korisničke poruke prolaze kroz WordPress i18n funkcije sa text domain‑om `woo-5e`, pa prevodi rade i u Loco Translate okruženju.
- `languages/woo-5e.pot` se generiše komandnom `wp i18n make-pot …` i može da se koristi kao osnova za `.po/.mo` fajlove.
- WPML i Polylang automatski registruju dinamički naslov 5E shipping metode zahvaljujući klasi `W5E_I18n`, tako da svaka instanca metode može da dobije sopstveni prevod.
- JavaScript status poruke (fetch couriers dugme) takođe stižu iz PHP‑a putem `wp_localize_script`, pa su vidljive prevodilačkim alatima.

Ova dokumentacija opisuje trenutno stanje plugina. Dopuni je ukoliko dodaješ nove funkcionalnosti (nove endpoint‑e, drugačiji obračun cena, dodatna okruženja, i sl.).
