Symfonia Handel

<< Pokaż spis treści >>

Nawigacja:  Wtyczki importu faktur >

Symfonia Handel

Opis

Plugin do importu faktur z plików eksportu programu Sage Symfonia Handel. Obsługuje format tekstowy z sekcjami DokumentSp oraz DokumentSp_oddział w nawiasach klamrowych { }.

Obsługiwane formaty

Plugin automatycznie rozpoznaje i parsuje oba typy sekcji dokumentów z jednego pliku eksportu.

UWAGA: Ze względu ma niejednoznaczność danych źródłowych nie są obsługiwane faktury zaliczkowe i faktury rozliczające zaliczki, a także korekty takich dokumentów, które wymagają innej struktury danych dla KSeF.

Format DokumentSp (klasyczny)

Standardowa sekcja dokumentu w eksporcie Symfonia Handel:

DokumentSp{
    numer =26-FVS/03/3355
    typDk =FVS
    nazwa =Faktura
    dataWystawienia =2026-03-02
    dataSprzedazy =2026-03-02
    czyKorekta =0
    czyAnulowany =0
    netto =98.890000000000
    vat =22.740000000000
    brutto =121.630000000000
    waluta =
    kurs =1.000000000000
   
    daneKh{
        KhNIP =8992732867
        KhNazwa =FIRMA PRZYKŁADOWA
        KhUlica =Główna
        KhDomu =10
        KhLokal =5
        KhMiasto =Warszawa
        KhKodPocz =00-001
        kraj{
            symbol =PL
        }
    }
   
    Pozycja dokumentu{
        lp =1
        kod =TOWAR001
        Nazwa_Dl{
            opis =Nazwa towaru
        }
        ilosc =1.000000000000
        jednostkaMiary =szt
        cena =25.000000000000
        netto =23.810000000000
        VAT =1.190000000000
        stVAT{
            typ =10
            wartosc =0.0500
        }
        brutto =25.000000000000
        PKWiU =
    }
}

Format DokumentSp_oddział (z obsługą oddziałów)

Sekcja dokumentu generowana przy eksporcie z oddziałami. Różni się od DokumentSp następującymi elementami:

Element

DokumentSp

DokumentSp_oddział

Nazwa sekcji dokumentu

DokumentSp{}

DokumentSp_oddział{}

Sekcja pozycji

Pozycja dokumentu{}

pozycja{}

Sekcja opisu pozycji

Nazwa_Dl{ opis =... }

opis{ opis =... }

Kod pocztowy kontrahenta

KhKodPocz

KhPoczta

DokumentSp_oddział{
    numer =0457/2026/FVS
    typDk =FVS
    nazwa =Faktura VAT
    dataWystawienia =2026-03-25
    dataSprzedazy =2026-03-03
    czyAnulowany =0
    waluta =
    kurs =1.000000000000
    netto =3845.290000
    vat =884.420000
    brutto =4729.710000
   
    daneKh{
        KhNIP =9661461820
        KhNazwa =FERMA DROBIU KRZYSZTOF WYSOCKI
        KhUlica =Ryboły
        KhDomu =1028/8
        KhLokal =
        KhMiasto =Zabłudów
        KhPoczta =16-080
        kraj{
            symbol =PL
        }
    }
   
    pozycja{
        lp =1
        kod =KLEIB C26 Beton B-30/25
        opis{
            opis =KLEIB C26 Beton B-30 suchą miesz. cement. do betonu...
        }
        ilosc =216.000000
        jednostkaMiary =szt
        cena =17.350000
        netto =3747.600000
        VAT =861.950000
        brutto =4609.550000
        stVAT{
            typ =10
            wartosc =0.2300
        }
        PKWiU =
    }
}

Obsługiwane typy dokumentów

Plugin importuje wszystkie typy dokumentów bez filtrowania po typie — różne firmy mogą mieć różne konfiguracje typów w Symfonia.

Dokumenty z flagą czyAnulowany=1 są pomijane. Dokumenty korygujące (RodzajFaktury=KOR) są wykrywane na podstawie flagi czyKorekta=1 (DokumentSp) lub niepustego pola kodDokKoryg albo typDk=FKS (DokumentSp_oddział) i wzbogacane danymi korygowanego dokumentu. Jeśli dokument zawiera sekcję daneOd{}, dane odbiorcy są mapowane na element Podmiot3 z rolą odbiorca.

Konfiguracja

Parametry

Parametr

Typ

Domyślna wartość

Opis

SourcePath

string

C:\KSef\Symfonia

Ścieżka do katalogu z plikami eksportu

FilePattern

string

*.txt

Wzorzec nazwy plików do przetworzenia

CheckDuplicates

string

Block

Sposób obsługi duplikatów faktur (faktur o numerze już istniejącym w bazie). Dopuszczalne wartości: Allow, Block, Skip. Zachowana jest wsteczna zgodność z wartościami logicznymi: true działa jak Block, false działa jak Allow.

Wartości parametru CheckDuplicates:

Wartość

Zachowanie

Allow

Duplikaty są dozwolone — brak sprawdzania w bazie. Faktura zostanie zaimportowana nawet jeśli jej numer już istnieje.

Block

Wykrycie duplikatu blokuje przetworzenie całego pliku — żadna faktura z danego pliku nie zostanie zaimportowana. Plik trafia do katalogu Failed.

Skip

Duplikat jest pomijany — pozostałe faktury z pliku są przetwarzane normalnie. Pominięta faktura nie jest traktowana jako błąd i nie pojawia się w raporcie błędów. Zdarzenie jest odnotowywane jedynie w dzienniku zdarzeń (log poziom Information).

Przykładowa konfiguracja

{
  "SourcePath": "C:\\Symfonia\\Export",
  "FilePattern": "export_*.txt",
  "CheckDuplicates": "Block"
}

Działanie

1.Skanowanie — Plugin szuka plików pasujących do wzorca w katalogu źródłowym

2.Parsowanie — Każdy plik jest parsowany w poszukiwaniu sekcji DokumentSp{} oraz DokumentSp_oddział{}

3.Filtrowanie — Wybierane są tylko dokumenty będące fakturami sprzedaży (pomijane anulowane)

4.Walidacja — Sprawdzanie poprawności danych i duplikatów

5.Import — Konwersja do formatu KSeF XML i zapis do bazy

6.Archiwizacja — Przeniesienie pliku do podkatalogu Processed lub Failed

Szczegółowe zasady przetwarzania danych na format KSeF XML

Rozpoznawanie sekcji

Parser szuka sekcji DokumentSp{...} i DokumentSp_oddział{...} na najwyższym poziomie pliku — z każdej z nich powstaje jeden dokument faktury.

Sekcje Dokument{...} są parsowane pomocniczo w celu pobrania danych płatności (forma_platnosci, terminPlatnosci, dozaplaty) i powiązane z dokumentami sprzedaży przez numer faktury (FK nazwa lub kod). Pobierany jest też identyfikator kontrahenta (khid z podsekcji Dane nabywcy{}) jako fallback do powiązania z sekcją Kontrahent{}.

Sekcje Kontrahent{...} są parsowane w celu pobrania adresu email nabywcy — budowany jest słownik id → email, który służy do wzbogacenia danych faktury.

Pozostałe sekcje (INFO{}, towar{}, Kraj{} itp.) są ignorowane.

Jeden plik może zawierać wiele sekcji dokumentów — każda jest parsowana niezależnie.

Parsowanie pól klucz-wartość

Pola mają format: klucz =wartość (spacja przed znakiem = jest opcjonalna).

Parsowane są tylko pola na pierwszym poziomie danej sekcji — zagnieżdżone sekcje (np. daneKh{}, stVAT{}) są pomijane przy odczytywaniu pól nadrzędnych i parsowane oddzielnie.

Wartości liczbowe są zapisywane z precyzją do 12 miejsc po przecinku (np. 98.890000000000). Przecinki i kropki są obsługiwane przy parsowaniu.

Puste wartości (np. waluta =) traktowane są jako brak wartości — stosowana jest wartość domyślna.

Cudzysłowy na początku/końcu wartości są usuwane.

Mapowanie nagłówka faktury → XML KSeF

Pole źródłowe

Element XML KSeF

Zasada przetwarzania

numer

Fa > P_2

Kopiowany dosłownie jako numer faktury.

dataWystawienia

Naglowek > DataWytworzeniaFa, Fa > P_1

Format YYYY-MM-DD. Uzupełniany też jako data wygenerowania.

dataSprzedazy

Fa > Item (data dostawy)

Format YYYY-MM-DD. Ustawiany gdy pole jest obecne i niepuste.

typDk

Fa > RodzajFaktury

Mapowanie: FVS/FVX/FS/FV/FAK → VAT; KOR/FK → KOR; ZAL → ZAL; ROZ → ROZ; inne → VAT.

czyKorekta

Fa > RodzajFaktury

Gdy =1, wymusza RodzajFaktury = KOR (nadpisuje mapowanie z typDk).

czyAnulowany

(pomijany)

Gdy =1, cały dokument jest pomijany — nie trafia do wyjścia XML.

waluta

Fa > KodWaluty

Próba parsowania na enum TKodWaluty. Gdy puste lub nierozpoznane → PLN.

netto, vat, brutto

(obliczane z pozycji)

Wartości z nagłówka nie są bezpośrednio mapowane do XML — sumy są obliczane z pozycji faktury pogrupowanych wg stawki VAT.

Mapowanie danych nabywcy (Podmiot2) → XML KSeF

Dane nabywcy pochodzą z zagnieżdżonej sekcji daneKh{}.

Pole źródłowe

Element XML KSeF

Zasada przetwarzania

KhNIP

Podmiot2 > DaneIdentyfikacyjne > NIP

Usuwane są myślniki i spacje. NIP jest walidowany i ustawiany jako identyfikator podmiotu.

KhNazwa

Podmiot2 > DaneIdentyfikacyjne > Nazwa

Kopiowana dosłownie. Cudzysłowy na początku/końcu są usuwane.

KhKodPocz / KhPoczta + KhMiasto

Podmiot2 > Adres > AdresL1

Łączone spacją: "{KhKodPocz} {KhMiasto}". W DokumentSp_oddział pole kodu pocztowego to KhPoczta.

KhUlica + KhDomu + KhLokal

Podmiot2 > Adres > AdresL2

Łączone spacją: "{KhUlica} {KhDomu}". Jeśli KhLokal jest niepuste, dodawane jako "lok. {KhLokal}".

kraj > symbol

Podmiot2 > Adres > KodKraju

Parsowany na enum TKodKraju. Domyślnie PL.

Kontrahent{} > email (powiązany przez KhID)

Podmiot2 > DaneKontaktowe > Email

Pobierany z sekcji Kontrahent{} powiązanej przez daneKh.KhID = Kontrahent.id. Gdy pole email zawiera wiele adresów rozdzielonych przecinkiem lub średnikiem, używany jest pierwszy z nich. Gdy email nie jest dostępny, element DaneKontaktowe nie jest generowany.

Zasada pobierania adresu email nabywcy:

Sekcja daneKh{} dokumentu nie zawiera bezpośrednio adresu email. Email pobierany jest pośrednio:

1.Z sekcji daneKh{} pobierany jest identyfikator kontrahenta (pole KhID).

2.Jeśli KhID nie występuje w daneKh{}, jako fallback używane jest pole khid z podsekcji Dane nabywcy{} wewnątrz powiązanej sekcji Dokument{} (powiązanie przez numer faktury).

3.Znaleziony identyfikator jest wyszukiwany w słowniku id → email zbudowanym z sekcji Kontrahent{} całego pliku (pole id = klucz, pole email = wartość).

4.Jeśli znaleziono email — jest zapisywany w elemencie Podmiot2 > DaneKontaktowe > Email, co umożliwia automatyczne wysłanie faktury emailem do nabywcy po jej wystawieniu w KSeF.

Mapowanie pozycji faktury → XML KSeF

Pozycje pochodzą z sekcji Pozycja dokumentu{} (DokumentSp) lub pozycja{} (DokumentSp_oddział).

Pole źródłowe

Element XML KSeF

Zasada przetwarzania

lp

FaWiersz > NrWierszaFa

Numer porządkowy. Jeśli brak — autonumerowanie od 1.

Opis pozycji

FaWiersz > P_7

Priorytet: 1) Nazwa_Dl > opis lub opis > opis (zależy od formatu), 2) pole opis na poziomie pozycji, 3) pole kod.

jednostkaMiary

FaWiersz > P_8A

Kopiowana dosłownie. Domyślnie "szt".

ilosc

FaWiersz > P_8B

Zaokrąglana do 4 miejsc po przecinku. Domyślnie 1.

netto / ilosc

FaWiersz > P_9A

Cena jednostkowa netto = netto / ilosc. Zaokrąglana do 4 miejsc. Fallback: pole cena.

netto

FaWiersz > P_11

Wartość netto pozycji. Zaokrąglana do 2 miejsc.

VAT

FaWiersz > P_11Vat

Wartość VAT pozycji. Zaokrąglana do 2 miejsc.

stVAT > wartosc

FaWiersz > P_12

Stawka VAT jako ułamek (np. 0.2300 = 23%). Mnożona × 100, zaokrąglana do 2 miejsc, następnie mapowana na TStawkaPodatku.

Obliczanie stawki VAT (fallback)

Jeśli sekcja stVAT{} jest nieobecna, stawka VAT jest obliczana ze wzoru:

StawkaVat = round(VAT / netto × 100, 0)

Jeśli netto = 0, przyjmowana jest stawka domyślna 23%.

Mapowanie stawki VAT na kody KSeF

Wartość (%)

Tolerancja

Kod KSeF (TStawkaPodatku)

23

22.5–23.5

Item23

22

Item22

8

7.5–8.5

Item8

7

Item7

5

4.5–5.5

Item5

0

Item0KR

inna

Item23 (domyślny)

Mapowanie płatności (Platnosc) → XML KSeF

Dane płatności pochodzą z dwóch źródeł w zależności od formatu pliku:

Format

Źródło formy płatności

Źródło terminu i dozaplaty

DokumentSp

pole forma_platnosci bezpośrednio w sekcji

pola terminPlatnosci, dozaplaty bezpośrednio w sekcji

DokumentSp_oddział

sekcja formaPl{ nazwa }

pole terminPlatnosci w sekcji; dozaplaty z powiązanej sekcji Dokument{}

Zasady mapowania na element Fa > Platnosc:

Pole źródłowe

Element XML KSeF

Zasada przetwarzania

forma_platnosci / formaPl.nazwa

Platnosc > PlatnoscInna + Platnosc > OpisPlatnosci

Zawsze mapowana jako forma "inna" (PlatnoscInna=1) z opisem tekstowym.

terminPlatnosci

Platnosc > TerminPlatnosci > Termin

Ustawiany tylko gdy faktura nie jest zapłacona (dozaplaty ≠ 0).

dozaplaty = 0

Platnosc > Zaplacono + Platnosc > DataZaplaty

Faktura uznawana za zapłaconą: Zaplacono=1, DataZaplaty = terminPlatnosci (lub dataWystawienia gdy termin brak). Termin płatności nie jest wtedy podawany.

dozaplaty ≠ 0 lub brak

(bez znacznika zapłaty)

Faktura niezapłacona — tylko termin i forma płatności (jeśli dostępne).

Sekcja Platnosc nie jest tworzona gdy brak wszystkich trzech danych: formy płatności, terminu i informacji o zapłacie.

Mapowanie faktur korygowanych → XML KSeF

Gdy czyKorekta=1, parser szuka zagnieżdżonych sekcji dokumentZKorektami{} zawierających dane korygowanego dokumentu:

dokumentZKorektami{
    numer =26-FVS/03/3355
    data  =2026-03-02
    wartosc =121.630000
}

Pole źródłowe

Element XML KSeF

Zasada przetwarzania

dokumentZKorektami.numer

Fa > DaneFaKorygowanej > NrFaKorygowanej

Numer korygowanej faktury.

dokumentZKorektami.data

Fa > DaneFaKorygowanej > DataWystFaKorygowanej

Data wystawienia korygowanej faktury. Gdy brak — używana dataWystawienia bieżącej faktury.

Dla każdej sekcji dokumentZKorektami{} tworzony jest osobny element DaneFaKorygowanej w XML. Numer KSeF korygowanej faktury ustawiany jest jako nieznany (NrKSeFN=1).

Wykrywanie korekty

Plugin rozpoznaje faktury korygujące w różny sposób, zależnie od formatu dokumentu:

Format

Warunek wykrycia korekty

Źródło numeru korygowanej faktury

DokumentSp

pole czyKorekta =1

sekcja dokumentZKorektami{} → pole numer

DokumentSp_oddział

pole kodDokKoryg niepuste lub typDk =FKS

sekcja dokumentZKorektami{} → pole numer; gdy sekcja nieobecna — wartość pola kodDokKoryg

Pozycje faktury korygującej — wariant przed/po

W formacie DokumentSp_oddział każda sekcja pozycja{} może zawierać podsekcje przedKorekta{} i poKorekcie{}, opisujące stan pozycji przed i po korekcie:

pozycja{
    przedKorekta{
        ilosc =192.000000
        netto =2435.120000
        VAT =560.080000
        brutto =2995.200000
    }
    poKorekcie{
        ilosc =190.000000
        netto =2409.750000
        VAT =554.250000
        brutto =2964.000000
    }
}

Gdy obie podsekcje są obecne, plugin tworzy dwa wiersze KSeF dla jednej pozycji źródłowej:

Wiersz KSeF

Źródło wartości

Pole StanPrzed

1 — stan przed korektą

podsekcja przedKorekta{}

StanPrzed =1

2 — stan po korekcie

podsekcja poKorekcie{}

(brak — wiersz normalny)

Gdy podsekcje są nieobecne, pozycja zawiera wartość różnicy bezpośrednio jako pola płaskie — tworzony jest wtedy jeden wiersz KSeF. Pozycje, w których wszystkie wartości (ilość, netto, VAT, brutto) są identyczne przed i po korekcie, są pomijane.

Przy obliczaniu sum podatkowych (P_13/P_14 i P_15) wiersze z StanPrzed=1 są odejmowane — wynik odpowiada faktycznej różnicy korekty (np. 2409,75 − 2435,12 = −25,37).

Dane odbiorcy (Podmiot3) — sekcja daneOd{}

Jeśli w dokumencie (DokumentSp lub DokumentSp_oddział) występuje sekcja daneOd{}, jej dane są mapowane na element Podmiot3 z rolą odbiorca (rola=2). Stosuje się to w przypadkach, gdy towar jest dostarczany do podmiotu innego niż nabywca (Podmiot2).

Pole źródłowe (daneOd{})

Element XML KSeF

Zasada przetwarzania

KhNIP

Podmiot3 > DaneIdentyfikacyjne > NIP

Usuwane są myślniki i spacje.

KhNazwa

Podmiot3 > DaneIdentyfikacyjne > Nazwa

Wymagana — brak nazwy oznacza brak Podmiot3. Cudzysłowy są usuwane.

KhKodPocz / KhPoczta + KhMiasto

Podmiot3 > Adres > AdresL1

Łączone spacją. W DokumentSp_oddział pole kodu pocztowego to KhPoczta.

KhUlica + KhDomu + KhLokal

Podmiot3 > Adres > AdresL2

Łączone spacją. Gdy KhLokal niepuste — dodawane jako "lok. {wartość}".

kraj > symbol

Podmiot3 > Adres > KodKraju

Parsowany na enum TKodKraju. Domyślnie PL.

Jeśli sekcja daneOd{} jest nieobecna lub pole KhNazwa jest puste, element Podmiot3 nie jest tworzony.

Obliczanie sum podatkowych (P_13/P_14)

Są obliczane dynamicznie jako suma wartości pozycji (FaWiersz), pogrupowanych wg stawki VAT:

Stawka

Pole netto

Pole VAT

23%

P_13_1

P_14_1

8%

P_13_2

P_14_2

5%

P_13_3

P_14_3

0%

P_13_4

P_14_4

zw

P_13_5

P_14_5

Kwota brutto faktury (P_15) = suma (P_11 + P_11Vat) ze wszystkich pozycji.

Mapowanie rodzaju faktury

Wartość typDk

RodzajFaktury XML

FVS, FVX, FS, FV, FAK, VAT

VAT

KOR, FK

KOR

ZAL

ZAL

ROZ

ROZ

inna wartość

VAT (domyślny)

Wyjątek: jeśli pole czyKorekta =1, rodzaj jest wymuszony na KOR niezależnie od typDk.

Mapowanie kodu waluty

Puste pole waluta → PLN

Wartość parsowana na enum TKodWaluty (case-insensitive)

Nierozpoznana wartość → PLN

Mapowanie kodu kraju

Puste pole kraj > symbol → PL

Wartość parsowana na enum TKodKraju (case-insensitive)

Nierozpoznana wartość → PL

Mapowanie pól — podsumowanie

Nagłówek faktury

Pole Symfonia

Pole KSeF

Opis

numer

P_2

Numer faktury

dataWystawienia

P_1

Data wystawienia

dataSprzedazy

P_6

Data sprzedaży/dostawy

waluta

KodWaluty

Kod waluty (domyślnie PLN)

typDk

RodzajFaktury

Rodzaj faktury

czyKorekta

RodzajFaktury

Gdy =1, faktura traktowana jako KOR

forma_platnosci / formaPl.nazwa

Platnosc > PlatnoscInna + OpisPlatnosci

Forma płatności jako "inna" z opisem

terminPlatnosci

Platnosc > TerminPlatnosci

Termin płatności (tylko gdy faktura niezapłacona)

dozaplaty = 0

Platnosc > Zaplacono + DataZaplaty

Oznaczenie faktury jako zapłaconej

Dane nabywcy (Podmiot2) — sekcja daneKh{}

Pole Symfonia

Pole KSeF

Opis

daneKh.KhNIP

NIP

NIP nabywcy

daneKh.KhNazwa

Nazwa

Nazwa nabywcy

daneKh.KhKodPocz / daneKh.KhPoczta + daneKh.KhMiasto

AdresL1

Kod pocztowy i miasto

daneKh.KhUlica + daneKh.KhDomu + daneKh.KhLokal

AdresL2

Ulica, numer domu i lokalu

daneKh.kraj.symbol

KodKraju

Kod kraju (domyślnie PL)

Pozycje faktury

Pole Symfonia

Pole KSeF

Opis

lp

NrWierszaFa

Numer pozycji

Nazwa_Dl.opis / opis.opis / kod

P_7

Nazwa towaru/usługi

jednostkaMiary

P_8A

Jednostka miary

ilosc

P_8B

Ilość

netto / ilosc

P_9A

Cena jednostkowa netto

netto

P_11

Wartość netto

VAT

P_11Vat

Wartość VAT

stVAT.wartosc

P_12

Stawka VAT (0.2300 = 23%)

Obsługiwane stawki VAT

Stawka

Kod KSeF

23%

Item23

22%

Item22

8%

Item8

7%

Item7

5%

Item5

0%

Item0KR

Kodowanie plików

Plugin odczytuje pliki z kodowaniem Windows-1250 (CP1250), które jest standardowym kodowaniem dla polskich aplikacji Windows.

Obsługa błędów

Przetwarzanie transakcyjne

Wszystkie faktury z jednego pliku są przetwarzane transakcyjnie:

Jeśli którakolwiek faktura zawiera błąd, wszystkie faktury z tego pliku są odrzucane

Plik z błędami jest przenoszony do podkatalogu Failed

Typowe błędy

Błąd

Przyczyna

Rozwiązanie

"Faktura już istnieje w bazie danych"

Duplikat numeru faktury

Wyłącz sprawdzanie duplikatów lub usuń istniejącą fakturę

"Brak danych nabywcy"

Pusta sekcja kontrahenta

Uzupełnij dane nabywcy w Symfonia

"Faktura musi zawierać co najmniej jedną pozycję"

Brak pozycji dokumentu

Sprawdź czy eksport zawiera pozycje

Archiwizacja

Po przetworzeniu pliki są przenoszone do:

{SourcePath}/Processed/ - pliki przetworzone pomyślnie

{SourcePath}/Failed/ - pliki z błędami

Nazwa pliku jest uzupełniana o znacznik czasu: 20251203_143022_export.txt

Przykład użycia

1.Skonfiguruj eksport w Symfonia Handel do katalogu np. C:\Symfonia\Export

2.Włącz plugin w KT KSeF Sender

3.Ustaw SourcePath na C:\Symfonia\Export

4.Plugin automatycznie skanuje katalog i importuje nowe faktury

Wymagania

Sage Symfonia Handel 2014 lub nowszy

Eksport w formacie tekstowym (domyślny format Symfonia)

Pliki z rozszerzeniem .txt