Skip to content

Podatki i VAT (Silnik kalkulacji) ​

Moduł podatków stanowi centralny, wysoce precyzyjny silnik obliczeniowy i konfiguracyjny w platformie Ammonly. Odpowiada za automatyczną determinację stawek podatkowych, wielopoziomowe przeliczanie kwot netto/brutto, obsługę procedur specjalnych (VAT Marża, WHT, OSS, Reverse Charge) oraz generowanie niezmiennych snapshotów fiskalnych dla dokumentów handlowych.

Architektura Domain-Driven & API-First

Silnik podatkowy został zaprojektowany w oparciu o czystą domenę (App\Modules\Tax\Domain), pozbawioną zależności od frameworka i bazy danych. Wszystkie kalkulacje są deterministyczne, audytowalne i dostępne zarówno przez REST API (/api/v1/tax/*), jak i reaktywny interfejs HTMX w panelu administracyjnym.


Spis treści ​


1. Architektura i kluczowe zasady ​

W nowoczesnym systemie ERP/CRM zarządzanie podatkami nie może ograniczać się do prostego mnożenia ceny przez 0.23. Różnice w przepisach międzynarodowych, wymagania transakcji transgranicznych, sprzedaż towarów używanych oraz podatki u źródła wymagają zunifikowanego, elastycznego modelu danych:

Kluczowe założenia projektowe: ​

  1. Niezmienność historyczna (Immutability): Zmiana stawek VAT lub usunięcie stawki w konfiguracji systemu nie wpływa na wcześniej wystawione oferty, zamówienia czy faktury. Dokument przechowuje kompletny zrzut JSON.
  2. Precyzja matematyczna: Wszystkie operacje arytmetyczne operują na wysokiej precyzji zmiennoprzecinkowej, a zaokrąglenie do 2 miejsc po przecinku (groszy) odbywa się ściśle według wybranej strategii biznesowej.
  3. Separacja profilowa (Multi-Tenant): Konfiguracja podatków jest autonomiczna dla każdej instancji klienta (App Client), przy jednoczesnym dostępie centralnym z poziomu panelu App Admin.

2. Cztery tryby kalkulacji podatku ​

Silnik Ammonly natywnie obsługuje 4 odrębne algorytmy wyliczania podatku, definiowane na poziomie stawki (calculation_mode):

2.1. Exclusive — Od netto (Standard B2B) ​

Podstawowy tryb stosowany w transakcjach pomiędzy przedsiębiorstwami. Wprowadzana cena jednostkowa jest ceną netto, a podatek jest doliczany do wartości pozycji:

Kwota Podatku=Kwota Netto×Stawka%100Kwota Brutto=Kwota Netto+Kwota Podatku

Przykład:

  • Cena netto: 100,00 PLN, Stawka VAT: 23%
  • Podatek VAT: 23,00 PLN, Kwota brutto: 123,00 PLN

2.2. Inclusive — Od brutto (Standard B2C) ​

Tryb dedykowany dla sprzedaży konsumenckiej (detalicznej), cenników konsumenckich oraz e-commerce, gdzie prezentowana cena zawiera już podatek VAT (kalkulacja metodą "w stu"):

Kwota Netto=Kwota Brutto1+Stawka%100Kwota Podatku=Kwota Brutto−Kwota Netto

Przykład:

  • Cena brutto: 123,00 PLN, Stawka VAT: 23%
  • Kwota netto: 100,00 PLN, Podatek VAT: 23,00 PLN

2.3. Procedura Marży — VAT Marża (art. 120) ​

Zgodnie z art. 120 ustawy o VAT, w przypadku dostawy towarów używanych, dzieł sztuki, przedmiotów kolekcjonerskich oraz usług turystycznych (biura podróży), podstawą opodatkowania jest wyłącznie marża handlowa (różnica między ceną sprzedaży a ceną nabycia), pomniejszona o kwotę podatku:

Marża Brutto=max(0,Cena Sprzedaży−Koszt Nabycia)Podstawa Netto Marży=Marża Brutto1+Stawka%100Kwota Podatku=Marża Brutto−Podstawa Netto MarżyŁączna Kwota Brutto do zapłaty=Cena Sprzedaży

Zasada marży ujemnej

Jeżeli cena sprzedaży jest niższa lub równa kosztowi nabycia (Marża≤0), podstawa opodatkowania oraz kwota podatku VAT wynoszą dokładnie 0,00 PLN. Nabywca płaci cenę sprzedaży, a na dokumencie nie wykazuje się kwoty podatku dla nabywcy.

Przykład:

  • Cena sprzedaży samochodu używanego: 50000,00 PLN, Cena nabycia (zakupu): 40000,00 PLN
  • Marża brutto: 10000,00 PLN
  • Podstawa netto marży przy stawce 23%: 8130,08 PLN
  • Podatek VAT z marży: 1869,92 PLN
  • Kwota do zapłaty na fakturze: 50000,00 PLN (z adnotacją procedura marży - towary używane, kod fiskalny P_106E_3).

2.4. Podatek u źródła — WHT (Withholding Tax) ​

Mechanizm stosowany w transakcjach zakupu usług niematerialnych (np. doradczych, prawnych, marketingowych, licencji oprogramowania, hostingu) od podmiotów zagranicznych (nierezydentów podatkowych). Zgodnie z ustawami o CIT/PIT, płatnik w Polsce potrąca podatek u źródła (np. 20%) i odprowadza go do polskiego urzędu skarbowego, wypłacając kontrahentowi kwotę pomniejszoną o ten podatek:

Kwota WHT=Kwota Netto×Stawka WHT%100Kwota do wypłaty dla dostawcy=Kwota Brutto−Kwota WHT

Przykład:

  • Zakup licencji IT z USA o wartości: 10000,00 PLN (stawka WHT 20%)
  • Kwota podatku WHT potrącona dla US: 2000,00 PLN
  • Kwota wypłacona dostawcy zagranicznemu: 8000,00 PLN

3. Statusy prawne i integracja fiskalna (JPK_V7 / KSeF) ​

Każda stawka podatkowa w systemie posiada przypisany status prawny (tax_status) oraz kod fiskalny (fiscal_code), które gwarantują bezbłędne mapowanie do struktur logicznych JPK_V7 oraz Krajowego Systemu e-Faktur (KSeF):

Status prawny (tax_status)Kod fiskalny KSeF/JPKStawka %Zastosowanie biznesowePodstawa prawna / Klauzula
standardP_13_123.00%Podstawowa stawka VAT na towary i usługiArt. 41 ust. 1
standardP_13_28.00%Stawka obniżona (budownictwo, gastronomia)Art. 41 ust. 2
standardP_13_35.00%Stawka obniżona (żywność, książki)Art. 41 ust. 2a
zero_ratedP_13_6_10.00%Eksport towarów poza UE oraz WDT wewnątrz UEArt. 41 ust. 4, Art. 42
exemptP_13_6_20.00%Zwolnienie przedmiotowe lub podmiotowe (ZW)Zwolnienie na podst. art. 43 ust. 1
reverse_chargeP_13_6_30.00%Odwrotne obciążenie (NP / OO) dla usług B2B UEOdwrotne obciążenie - art. 28b
out_of_scope—0.00%Transakcje niepodlegające ustawie o VATPoza zakresem ustawy o podatku VAT

4. Matryca determinacji podatków (Determination Matrix) ​

Matryca determinacji eliminuje błędy ludzkie operatorów, automatycznie dobierając właściwą stawkę podatku w oparciu o reguły decyzyjne oceniane według priorytetu (priority, gdzie niższa liczba = wyższy priorytet):

Kryteria ewaluacji: ​

  1. Typ kontrahenta (customer_type):
    • all — dotyczy wszystkich kontrahentów,
    • b2b — przedsiębiorcy zarejestrowani z numerem identyfikacji podatkowej (NIP / Tax ID),
    • b2c — konsumenci i osoby fizyczne nieprowadzące działalności gospodarczej.
  2. Strefa geograficzna (geo_zone):
    • domestic — transakcja krajowa (Polska),
    • eu_vat — kontrahent z kraju Unii Europejskiej z aktywnym numerem VAT-UE (VIES),
    • eu_consumer — konsument z kraju UE (obsługa procedury One Stop Shop — OSS),
    • export_world — kontrahent z kraju trzeciego poza obszarem celnym UE (eksport).
  3. Klasyfikacja pozycji (item_type):
    • all — wszystkie pozycje asortymentowe,
    • product — towary fizyczne i materiały,
    • service — usługi niematerialne, programistyczne, doradcze, licencje,
    • margin_goods — towary używane rozliczane w procedurze marży.

5. Grupy wielopodatkowe (Tax Groups) ​

Dla złożonych transakcji system pozwala na grupowanie wielu podatków w pojedynczą wybieralną encję (TaxGroup):

  1. Podatki równoległe (Parallel Taxes):
    • Każdy składnik grupy naliczany jest niezależnie od podstawowej kwoty netto.
    • Przykład: Podatek podstawowy VAT 23% + Opłata Cukrowa 5%.
  2. Podatki kaskadowe / złożone (Compound Taxes — is_compound = 1):
    • Składnik podatkowy naliczany jest od kwoty netto powiększonej o wartość wcześniej naliczonych podatków w grupie.
    • Stosowane m.in. w kanadyjskim systemie podatkowym (GST + PST) oraz przy akcyzach.

6. Strategie zaokrągleń i precyzja finansowa ​

System Ammonly oferuje pełną kontrolę nad miejscem i metodą zaokrąglania kwot podatków:

Poziom strategii zaokrąglania (RoundingStrategy): ​

  • Line Level (Row-by-Row) — Standard: Podatek jest obliczany i zaokrąglany do 2 miejsc po przecinku na każdej pojedynczej pozycji dokumentu. Suma podatku na dokumencie stanowi sumę zaokrąglonych pozycji.
  • Header Level (Summary Table): Na poziomie pozycji zachowywana jest pełna precyzja ułamkowa. W podsumowaniu dokumentu sumowane są dokładne bazy netto dla każdej stawki, a zaokrąglenie do groszy odbywa się jednorazowo na zagregowanej sumie.

Algorytmy zaokrąglania: ​

  • Half-Up: Standardowa metoda handlowa — jeśli trzecia cyfra po przecinku wynosi ≥5, zaokrąglenie następuje w górę (np. 10,005→10,01).
  • Half-Even (Banker's Rounding): Zaokrąglenie do najbliższej cyfry parzystej — eliminuje statystyczne przeszacowanie sum przy setkach tysięcy operacji rozliczeniowych.

7. Niezmienny zrzut podatkowy dokumentu (Snapshot JSON) ​

Każdy zatwierdzony dokument handlowy (oferta, zamówienie, faktura) utrwala w bazie danych pełen zrzut kalkulacji podatkowej w formacie JSON (tax_snapshot).

json
{
  "currency": "PLN",
  "defaultPriceMode": "exclusive",
  "roundingStrategy": "line_level",
  "totalNet": 100.00,
  "totalTax": 23.00,
  "totalGross": 123.00,
  "totalWht": 0.00,
  "totalPaymentDue": 123.00,
  "items": [
    {
      "id": "item-1",
      "name": "Konsultacje IT / Wdrożenie",
      "quantity": 1.00,
      "unitPrice": 100.00,
      "netAmount": 100.00,
      "taxAmount": 23.00,
      "grossAmount": 123.00,
      "taxRate": {
        "taxCode": "VAT_23",
        "taxName": "VAT 23% (Standard)",
        "ratePercent": 23.00,
        "calculationMode": "exclusive",
        "taxStatus": "standard",
        "fiscalCode": "P_13_1"
      }
    }
  ],
  "taxBreakdown": [
    {
      "taxCode": "VAT_23",
      "taxName": "VAT 23% (Standard)",
      "ratePercent": 23.00,
      "netBase": 100.00,
      "taxAmount": 23.00,
      "grossAmount": 123.00,
      "legalClause": null
    }
  ]
}

Gwarancja audytowa

Taki format zapisu gwarantuje, że wydruk faktury po 5 latach będzie w 100% zgodny z pierwotnymi wyliczeniami, nawet jeśli stawki VAT w państwie ulegną zmianie.


8. Symulator podatków (Live Tester) oraz REST API ​

Live Tax Tester w interfejsie ​

W zakładce Live Tax Tester (/settings/taxes#tab-simulator) administratorzy mogą w czasie rzeczywistym wprowadzać parametry transakcji (cena, ilość, rabat, marża, strefa geo, typ klienta) i diagnozować:

  • Która reguła matrycy decyzyjnej została zastosowana,
  • Jakie kwoty netto, VAT, brutto i WHT zostały wygenerowane,
  • Dokładną tabelę rozbicia stawek oraz podgląd snapshotu JSON.

REST API Endpoints ​

Wszystkie operacje kalkulacyjne są dostępne programistycznie przez REST API:

  • POST /api/v1/tax/calculate: Przelicza przekazany koszyk pozycji, zwracając podsumowanie, rozbicie stawek i snapshot JSON.
  • GET /api/v1/tax/rates: Pobiera listę aktywnych stawek podatkowych dla bieżącego kontekstu.
  • GET /api/v1/tax/rules: Pobiera listę zdefiniowanych reguł matrycy determinacji.

Ammonly Documentation System