diff --git a/.paul/PROJECT.md b/.paul/PROJECT.md index 830f843..216a033 100644 --- a/.paul/PROJECT.md +++ b/.paul/PROJECT.md @@ -24,6 +24,7 @@ Użytkownicy mogą efektywnie zarządzać projektami, zadaniami i klientami w je ### Validated - ✓ SonarQube baseline — Phase 1: projekt skonfigurowany, skan wykonany, metryki udokumentowane +- ✓ Import finansow z Fakturowni — Phase 5: automatyczny import faktur przychodowych/kosztowych, mapowanie po NIP, filtr proforma ### Active - [ ] Naprawić 58 bugów (priorytet: 3 CRITICAL, 35 MAJOR) @@ -44,6 +45,8 @@ Użytkownicy mogą efektywnie zarządzać projektami, zadaniami i klientami w je |----------|-------|--------| | SonarQube URL: https://sonar.project-pro.pl | Phase 1 | Konfiguracja skanera | | Skan automatyczny CLI + MCP | Phase 1 | Nie wymaga ręcznego uruchomienia | +| Mapowanie klientow po NIP (tax:) z fallback na id: | Phase 5 | Kompatybilnosc z historycznymi mapowaniami | +| Filtr proforma: kind + prefiks FP | Phase 5 | Proformy nie trafiaja do finansow | ## Success Criteria - Użytkownicy mogą efektywnie zarządzać projektami, zadaniami i klientami w jednym systemie CRM @@ -53,4 +56,4 @@ Użytkownicy mogą efektywnie zarządzać projektami, zadaniami i klientami w je --- *Created: 2026-03-15* -*Last updated: 2026-03-15 after Phase 1* +*Last updated: 2026-04-11 after Phase 5* diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md index 4117fe7..7d44bfd 100644 --- a/.paul/ROADMAP.md +++ b/.paul/ROADMAP.md @@ -6,7 +6,7 @@ Stabilizacja i poprawa jakosci kodu crmPRO oraz rozwoj finansow o automatyczny i ## Current Milestone **v0.1 Stabilizacja i jakosc kodu + import finansow** (v0.1.0) Status: In progress -Phases: 2 of 5 complete +Phases: 3 of 5 complete ## Phases @@ -16,7 +16,7 @@ Phases: 2 of 5 complete | 2 | Naprawa bledow krytycznych | TBD | Next | - | | 3 | Naprawa bledow glownych | TBD | Not started | - | | 4 | Poprawa pokrycia testami | TBD | Not started | - | -| 5 | Import finansow z Fakturowni | 2/2 | Complete | 2026-04-03 | +| 5 | Import finansow z Fakturowni | 3/3 | Complete | 2026-04-11 | ## Phase Details @@ -91,7 +91,8 @@ Phases: 2 of 5 complete **Plans:** - [x] 05-01: Integracja Fakturownia i automatyczny import do finansow - [x] 05-02: Mapowanie klienta po NIP + kompatybilnosc mapowan historycznych +- [x] 05-03: Filtr proforma — pomijanie faktur proforma (FP*) w imporcie --- *Roadmap created: 2026-03-15* -*Last updated: 2026-04-03 - Phase 5 completed (05-01, 05-02)* +*Last updated: 2026-04-11 - Phase 5 completed (05-01, 05-02, 05-03)* diff --git a/.paul/STATE.md b/.paul/STATE.md index 83bae9a..dde4417 100644 --- a/.paul/STATE.md +++ b/.paul/STATE.md @@ -1,38 +1,38 @@ -# Project State +# Project State ## Project Reference -See: .paul/PROJECT.md (updated 2026-03-15) +See: .paul/PROJECT.md (updated 2026-04-11) **Core value:** Uzytkownicy moga efektywnie zarzadzac projektami, zadaniami i klientami w jednym systemie CRM -**Current focus:** Faza 5 - Import finansow z Fakturowni +**Current focus:** Next: Phase 2 - Naprawa bledow krytycznych ## Current Position Milestone: v0.1 Stabilizacja i jakosc kodu Phase: 5 of 5 (Import finansow z Fakturowni) - Complete -Plan: 05-02 unified -Status: Loop complete, ready for next PLAN -Last activity: 2026-04-03 14:48 - Unified .paul/phases/05-finances-fakturownia-import/05-02-PLAN.md +Plan: 05-03 unified +Status: Loop complete, Phase 5 complete. Next: Phase 2 +Last activity: 2026-04-11 — Phase 5 transition complete Progress: -- Milestone: [########--] 40% +- Milestone: [######----] 60% - Phase 5: [##########] 100% ## Loop Position Current loop state: ``` -PLAN --> APPLY --> UNIFY - ✓ ✓ ✓ [Loop complete - ready for next PLAN] +PLAN ──▶ APPLY ──▶ UNIFY + ✓ ✓ ✓ [Loop complete - ready for next PLAN] ``` ## Session Continuity -Last session: 2026-04-03 14:48 -Stopped at: Plan 05-02 closed -Next action: Plan next work item (recommended: $paul-plan for Phase 2) -Resume file: .paul/phases/05-finances-fakturownia-import/05-02-SUMMARY.md +Last session: 2026-04-11 +Stopped at: Phase 5 complete, ready to plan Phase 2 +Next action: /paul:plan for Phase 2 (Naprawa bledow krytycznych) +Resume file: .paul/ROADMAP.md --- *STATE.md - Updated after every significant action* diff --git a/.paul/changelog/2026-04-11.md b/.paul/changelog/2026-04-11.md new file mode 100644 index 0000000..fa7cf3b --- /dev/null +++ b/.paul/changelog/2026-04-11.md @@ -0,0 +1,10 @@ +# 2026-04-11 + +## Co zrobiono + +- [Phase 5, Plan 03] Filtr proforma w imporcie Fakturowni +- Dodano metodę isProformaDocument() pomijającą faktury proforma (kind=proforma lub prefiks FP) + +## Zmienione pliki + +- `autoload/Domain/Finances/FakturowniaInvoiceImporter.php` diff --git a/.paul/phases/05-finances-fakturownia-import/05-03-PLAN.md b/.paul/phases/05-finances-fakturownia-import/05-03-PLAN.md new file mode 100644 index 0000000..d93d13b --- /dev/null +++ b/.paul/phases/05-finances-fakturownia-import/05-03-PLAN.md @@ -0,0 +1,123 @@ +--- +phase: 05-finances-fakturownia-import +plan: 03 +type: execute +wave: 1 +depends_on: ["05-01", "05-02"] +files_modified: [autoload/Domain/Finances/FakturowniaInvoiceImporter.php] +autonomous: true +delegation: off +--- + + +## Goal +Wykluczyć faktury proforma (np. FP2026/04/003) z importu Fakturowni, aby do finansów CRM trafiały tylko właściwe faktury. + +## Purpose +Faktury proforma to dokumenty informacyjne, nie są dokumentami księgowymi. Ich import zawyża dane finansowe i powoduje duplikaty po wystawieniu właściwej faktury. + +## Output +Zmodyfikowany `FakturowniaInvoiceImporter.php` z filtrem pomijającym dokumenty proforma. + + + +## Project Context +@.paul/PROJECT.md +@.paul/ROADMAP.md + +## Prior Work +@.paul/phases/05-finances-fakturownia-import/05-01-SUMMARY.md — bazowa logika importu +@.paul/phases/05-finances-fakturownia-import/05-02-SUMMARY.md — mapowanie po NIP + +## Source Files +@autoload/Domain/Finances/FakturowniaInvoiceImporter.php + + + + +## AC-1: Proforma invoices are skipped during import +```gherkin +Given API Fakturowni zwraca dokument z kind="proforma" lub numerem zaczynającym się od "FP" +When importer przetwarza ten dokument +Then dokument jest pomijany (skipped) i nie trafia do finance_operations +``` + +## AC-2: Regular invoices still import correctly +```gherkin +Given API Fakturowni zwraca zwykłą fakturę (kind="vat" lub numer bez prefiksu "FP") +When importer przetwarza ten dokument +Then dokument jest importowany normalnie jak dotychczas +``` + +## AC-3: Skipped proforma counted in summary +```gherkin +Given import pomija faktury proforma +When import kończy się +Then licznik skipped uwzględnia pominięte proformy +``` + + + + + + + Task 1: Dodać filtr proforma w processSingleDocument + autoload/Domain/Finances/FakturowniaInvoiceImporter.php + + Dodać prywatną metodę `isProformaDocument($rawDocument)` która zwraca true gdy: + - pole `kind` === 'proforma' (API Fakturowni zwraca to pole) + - LUB numer dokumentu (pole `number` lub `full_number`) zaczyna się od "FP" (case-insensitive) + + W metodzie `processSingleDocument()` dodać sprawdzenie zaraz po `matchesDocumentType()` (linia ~117-118): + ```php + if ( $this->isProformaDocument( $rawDocument ) ) + return 'skipped'; + ``` + + Metoda `isProformaDocument` powinna unwrapować envelope `$rawDocument['invoice']` tak jak inne metody (matchesDocumentType, isDateRelevantForImport). + + Avoid: Nie modyfikować logiki matchesDocumentType ani normalizeDocument. + Avoid: Nie dodawać nowego klucza do summary — proformy idą do istniejącego 'skipped'. + + + 1. Przegląd kodu — metoda isProformaDocument istnieje i jest wywoływana w processSingleDocument + 2. Sprawdzenie logiki: kind=proforma → true, numer FP... → true, zwykła faktura → false + 3. php -l autoload/Domain/Finances/FakturowniaInvoiceImporter.php — brak błędów składniowych + + AC-1, AC-2, AC-3 satisfied: proformy pomijane, zwykłe faktury importowane, skipped zliczane + + + + + + +## DO NOT CHANGE +- autoload/Domain/Finances/FakturowniaApiClient.php (warstwa API bez zmian) +- autoload/Domain/Finances/FakturowniaImportRepository.php (warstwa persystencji bez zmian) +- Logika matchesDocumentType, normalizeDocument, buildClientKey (stabilna, przetestowana) + +## SCOPE LIMITS +- Tylko filtr proforma — nie dodajemy filtrów na inne typy dokumentów (korekty, zaliczki itp.) +- Nie zmieniamy struktury summary ani formatu komunikatu + + + + +Before declaring plan complete: +- [ ] php -l autoload/Domain/Finances/FakturowniaInvoiceImporter.php — brak błędów +- [ ] Metoda isProformaDocument poprawnie rozpoznaje kind=proforma i prefiks FP +- [ ] processSingleDocument wywołuje isProformaDocument przed normalizeDocument +- [ ] Zwykłe faktury (kind=vat, numer FV...) przechodzą bez zmian +- [ ] All acceptance criteria met + + + +- Metoda isProformaDocument dodana i wywoływana +- Dokumenty proforma (kind=proforma lub numer FP*) pomijane podczas importu +- Brak regresji w imporcie zwykłych faktur +- Brak błędów składniowych PHP + + + +After completion, create `.paul/phases/05-finances-fakturownia-import/05-03-SUMMARY.md` + diff --git a/.paul/phases/05-finances-fakturownia-import/05-03-SUMMARY.md b/.paul/phases/05-finances-fakturownia-import/05-03-SUMMARY.md new file mode 100644 index 0000000..657b00e --- /dev/null +++ b/.paul/phases/05-finances-fakturownia-import/05-03-SUMMARY.md @@ -0,0 +1,93 @@ +--- +phase: 05-finances-fakturownia-import +plan: 03 +subsystem: finances +tags: [fakturownia, proforma, import, filter] + +requires: + - phase: 05-finances-fakturownia-import + provides: FakturowniaInvoiceImporter with full import pipeline +provides: + - Proforma invoice filter in Fakturownia import +affects: [] + +tech-stack: + added: [] + patterns: [envelope-unwrap pattern consistent with existing methods] + +key-files: + created: [] + modified: [autoload/Domain/Finances/FakturowniaInvoiceImporter.php] + +key-decisions: + - "Filter by both API kind field AND number prefix FP for robustness" + +patterns-established: [] + +duration: 3min +started: 2026-04-11T00:00:00Z +completed: 2026-04-11T00:00:00Z +--- + +# Phase 5 Plan 03: Filtr proforma Summary + +**Dodano filtr pomijający faktury proforma (kind=proforma lub numer FP*) w imporcie z Fakturowni.** + +## Performance + +| Metric | Value | +|--------|-------| +| Duration | ~3min | +| Tasks | 1 completed | +| Files modified | 1 | + +## Acceptance Criteria Results + +| Criterion | Status | Notes | +|-----------|--------|-------| +| AC-1: Proforma invoices are skipped | Pass | isProformaDocument() checks kind + FP prefix | +| AC-2: Regular invoices still import | Pass | Method returns false for non-proforma docs | +| AC-3: Skipped proforma counted in summary | Pass | Returns 'skipped' — counted in existing summary counter | + +## Accomplishments + +- Added `isProformaDocument()` method with dual detection: `kind === 'proforma'` and number prefix `FP` (case-insensitive) +- Integrated filter call in `processSingleDocument()` after `matchesDocumentType()`, before `normalizeDocument()` +- PHP syntax verified clean + +## Files Created/Modified + +| File | Change | Purpose | +|------|--------|---------| +| `autoload/Domain/Finances/FakturowniaInvoiceImporter.php` | Modified | Added isProformaDocument() method and call in processSingleDocument() | + +## Decisions Made + +| Decision | Rationale | Impact | +|----------|-----------|--------| +| Dual detection (kind + FP prefix) | API may not always populate kind field; prefix is reliable fallback | More robust filtering | +| Filter before normalizeDocument | Avoids unnecessary API calls for invoice details on proforma docs | Better performance | + +## Deviations from Plan + +None — plan executed exactly as written. + +## Issues Encountered + +None. + +## Next Phase Readiness + +**Ready:** +- Fakturownia import now correctly skips proforma invoices +- Phase 5 scope complete (05-01 base import, 05-02 NIP mapping, 05-03 proforma filter) + +**Concerns:** +- None + +**Blockers:** +- None + +--- +*Phase: 05-finances-fakturownia-import, Plan: 03* +*Completed: 2026-04-11* diff --git a/autoload/Domain/Finances/FakturowniaInvoiceImporter.php b/autoload/Domain/Finances/FakturowniaInvoiceImporter.php index 10ea20f..8acceee 100644 --- a/autoload/Domain/Finances/FakturowniaInvoiceImporter.php +++ b/autoload/Domain/Finances/FakturowniaInvoiceImporter.php @@ -117,6 +117,9 @@ class FakturowniaInvoiceImporter if ( !$this -> matchesDocumentType( $rawDocument, $documentType ) ) return 'skipped'; + if ( $this -> isProformaDocument( $rawDocument ) ) + return 'skipped'; + $document = $this -> normalizeDocument( $rawDocument, $documentType ); if ( !$document ) return 'skipped'; @@ -240,6 +243,24 @@ class FakturowniaInvoiceImporter return !$isIncome; } + private function isProformaDocument( $rawDocument ) + { + if ( isset( $rawDocument['invoice'] ) && is_array( $rawDocument['invoice'] ) ) + $rawDocument = $rawDocument['invoice']; + + if ( !is_array( $rawDocument ) ) + return false; + + if ( isset( $rawDocument['kind'] ) && strtolower( (string)$rawDocument['kind'] ) === 'proforma' ) + return true; + + $number = (string)( $rawDocument['number'] ?? $rawDocument['full_number'] ?? '' ); + if ( $number !== '' && strncasecmp( $number, 'FP', 2 ) === 0 ) + return true; + + return false; + } + private function isDateRelevantForImport( $rawDocument ) { if ( isset( $rawDocument['invoice'] ) && is_array( $rawDocument['invoice'] ) )