--- phase: 126-invoice-gus-field-mapping plan: 01 type: execute wave: 1 depends_on: [] files_modified: - src/Core/Http/MfWhitelistApiClient.php - src/Modules/Accounting/InvoiceController.php - resources/views/accounting/invoice_form.php autonomous: true delegation: off --- ## Goal Naprawić mapowanie pól po kliknięciu "Pobierz z GUS" na `/orders/{id}/invoice/create` tak, aby dane z MF Białej Listy trafiały do właściwych pól zależnie od typu podmiotu (JDG vs spółka z KRS). ## Purpose Operator wystawiający fakturę dla JDG widzi obecnie efekt zamiany pól: pole "Imię i nazwisko" pokazuje pełną nazwę firmy z zamówienia (np. "Project-Pro Pyziak Jacek"), a "Nazwa firmy" jest nadpisywane samym imieniem i nazwiskiem z MF (np. "JACEK PYZIAK"). Przyczyna: MF Biała Lista dla JDG zwraca w `subject.name` osobę fizyczną (nie nazwę firmy), a JS bezwarunkowo wpisuje tę wartość do "Nazwa firmy". Po fixie operator nie musi już ręcznie korygować pól po lookupie. ## Output - `MfWhitelistApiClient::lookupByNip()` zwraca dodatkowo flagę `is_jdg` (true gdy `subject.krs` jest null/pusty). - `InvoiceController::nipLookup` propaguje flagę w odpowiedzi JSON. - JS w `invoice_form.php` dla `is_jdg=true` wpisuje MF `name` do `#buyer_name`, a dla `is_jdg=false` do `#buyer_company_name`; drugiego pola nie nadpisuje. Adres (ulica/kod/miasto/NIP) nadpisywany jak dotychczas. - **Objaw buga** — Co dokładnie pokazuje formularz po kliknięciu "Pobierz z GUS" dla zam. 1090? → Odpowiedź: Imię/nazw.=nazwa firmy z zamówienia ("Project-Pro Pyziak Jacek"); Nazwa firmy=imię i nazwisko klienta z MF ("JACEK PYZIAK"). - **Typ podmiotu** — Jaki typ podmiotu zwraca MF dla NIP 5170167517? → Odpowiedź: Zweryfikowane bezpośrednio — JDG, `subject.krs=null`, `subject.name="JACEK PYZIAK"`. - **Mapowanie GUS** — Które mapowanie ma realizować GUS lookup? → Odpowiedź: Heurystyka po KRS — `krs=null` (JDG) → name do "Imię i nazwisko"; `krs!=null` (spółka) → name do "Nazwa firmy". - **Pole osobowe** — Czy zostawiamy "Imię i nazwisko" jako oddzielne pole? → Odpowiedź: Tak — dla spółki = pre-fill z zamówienia (osoba kontaktowa); dla JDG = nazwisko z MF. ## Project Context @.paul/PROJECT.md @.paul/STATE.md @.paul/codebase/architecture.md ## Source Files @src/Core/Http/MfWhitelistApiClient.php @src/Modules/Accounting/InvoiceController.php @resources/views/accounting/invoice_form.php ## AC-1: JDG (krs=null) — name z MF trafia w "Imię i nazwisko", "Nazwa firmy" niezmieniona ```gherkin Given otwarte /orders/1090/invoice/create And w polu "NIP nabywcy" wpisany "5170167517" And pole "Imię i nazwisko" zawiera "Project-Pro Pyziak Jacek" (pre-fill z zamówienia) And pole "Nazwa firmy" zawiera "Project-Pro Pyziak Jacek" (pre-fill z zamówienia) When operator klika "Pobierz z GUS" Then pole "Imię i nazwisko" ma wartość "JACEK PYZIAK" (z MF) And pole "Nazwa firmy" zachowuje wartość "Project-Pro Pyziak Jacek" And pola adres (ulica/kod/miejscowość) są nadpisane danymi z MF ``` ## AC-2: Spółka z KRS — name z MF trafia w "Nazwa firmy", "Imię i nazwisko" niezmieniona ```gherkin Given otwarte /orders/{id}/invoice/create dla zamówienia ze spółką (NIP z aktywnym KRS) And pole "Imię i nazwisko" zawiera np. "Jan Kowalski" (osoba kontaktowa z zamówienia) When operator klika "Pobierz z GUS" Then pole "Nazwa firmy" otrzymuje legal name z MF (np. "ACME Sp. z o.o.") And pole "Imię i nazwisko" zachowuje wartość "Jan Kowalski" And pola adresowe są nadpisane danymi z MF ``` ## AC-3: Response JSON z /api/nip/lookup zawiera flagę is_jdg ```gherkin Given autoryzowane GET /api/nip/lookup?nip=5170167517 When request zwraca 200 OK Then JSON.data.is_jdg === true And JSON.data.company_name === "JACEK PYZIAK" And dla NIP-u spółki z aktywnym KRS JSON.data.is_jdg === false ``` Task 1: MfWhitelistApiClient — eksponowanie flagi is_jdg src/Core/Http/MfWhitelistApiClient.php W `lookupByNip()` po wczytaniu `$subject`: - Wyciągnąć `$krs = trim((string) ($subject['krs'] ?? ''));` - W zwracanym array dodać klucz `'is_jdg' => $krs === '',` (oraz opcjonalnie `'krs' => $krs` dla debugowalności). - Zaktualizować docblock `@return array{...}` o `is_jdg: bool, krs: string`. Unikać: zmiany pozostałych pól / kontraktu (`name`, `tax_no`, address, regon, status_vat). Manualnie: w PHP REPL `(new MfWhitelistApiClient(new SslCertificateResolver()))->lookupByNip('5170167517')` zwraca `is_jdg=true`; dla NIP-u spółki z aktywnym KRS zwraca `is_jdg=false`. AC-3 satisfied (kontrakt klienta). Task 2: InvoiceController::nipLookup — propagacja is_jdg do JSON src/Modules/Accounting/InvoiceController.php W `nipLookup()` w bloku `data` rozszerzyć payload o `'is_jdg' => (bool) ($data['is_jdg'] ?? false),`. Zachować pozostałe klucze (`company_name`, `tax_number`, `street`, `postal_code`, `city`, `country`, `regon`, `status_vat`). Unikać: zmiany walidacji NIP, kontraktu błędów (422/502). `curl -s -H "X-Requested-With: XMLHttpRequest" "https://orderpro.projectpro.pl/api/nip/lookup?nip=5170167517"` zwraca JSON z `data.is_jdg=true`. AC-3 satisfied (kontrakt endpointu). Task 3: invoice_form.php — JS warunkowe mapowanie name w zależności od is_jdg resources/views/accounting/invoice_form.php W bloku `