E-faktura i plik JPK FA_VAT — dlaczego walidator zgłasza błąd?

0

Witam wszystkich. Wiem, że jeszcze jest dużo czasu dla nowego obowiązku JPK FA_VAT, ale postanowiłem się powoli przygotować. Ściągnąłem schemat Schemat_FA_VAT(1)_v1-0E.xsd, wygenerowałem unit Schemat_FA_VAT1_v10E.pas, napisałem z grubsza swoją procedurę i mam jeden problem. Walidator zgłasza mi błąd. Nie jestem wirtuozem programowania i nie rozumiem o co chodzi. Bardzo proszę o pomoc. Chojeś.
Moja procedura:

![walidacja.jpg](https://4programmers.net/uploads/35764/ChLOE3DBFH1yMFSKTa06cxzcQExcPJ8vvWs29kL7.jpg)![walidacja.jpg](https://4programmers.net/uploads/35764/ChLOE3DBFH1yMFSKTa06cxzcQExcPJ8vvWs29kL7.jpg)![walidacja.jpg](https://4programmers.net/uploads/35764/ChLOE3DBFH1yMFSKTa06cxzcQExcPJ8vvWs29kL7.jpg)![walidacja.jpg](https://4programmers.net/uploads/35764/ChLOE3DBFH1yMFSKTa06cxzcQExcPJ8vvWs29kL7.jpg)![walidacja.jpg](https://4programmers.net/uploads/35764/uQnG9kNiCaJRtaR2Y4AHXcbnaAj2LivyWKMdsfGj.jpg)[Schemat_FA_VAT1_v10E.pas](https://4programmers.net/assets/41169/KRyVR4oa8SJ5pzOwgsIK9WCeS2b9oJ1fZ2vZW5Ln.txt)procedure TForm17.Plik_FA_VAT;
var faktura:Schemat_FA_VAT1_v10E.IXMLFaktura;
    xml:IXMLDocument;
    i:integer;
    plik, s:string;

begin
 xml:=NewXMLDocument;
 xml.encoding:='utf-8';
 xml.options:=xml.options+[doNodeAutoIndent];
 Faktura:=Schemat_FA_VAT1_v10E.GetFaktura(xml);

 with datamodule1, faktura do
 begin
  with Naglowek do // ok
  begin
   KodFormularza.WersjaSchemy:='1-0E';
   KodFormularza.KodSystemowy:='FA (1)';
   KodFormularza.Text:='FA';
   WariantFormularza:=1;
   DataWytworzeniaFa:=datetostr(date)+'T'+timetostr(time);
   SystemInfo:=application.title;
  end; // with Naglowek

  with Podmiot1 do //
  begin
   with DaneIdentyfikacyjne do
   begin
    NIP:=table12['po_nip'];
    PelnaNazwa:=table12['po_nazwa1'];
    if table12['po_nazwa2']<>null then PelnaNazwa:=PelnaNazwa+' '+table12['po_nazwa2'];
   end; // with DaneIdentyfikacyjne

   with Adres do
   begin
    KodKraju:='PL';
    Miejscowosc:=table12['po_miejsce'];
    Ulica:=table12['po_adres'];
    NrDomu:=table12['po_nrdomu'];
    KodPocztowy:=table12['po_kodpocz'];
   end; // with Adres

   Email:=table12['po_mail'];
   telefon.Add(table12['po_tel']);
  end; // with Podmiot1

  with Podmiot2 do // jeśli dobrze rozumiem, to Nabywca
  begin
   table4.locate('ko_nr',table14['do_nrko'],[]);
   s:=table4['ko_nazwa1'];
   with DaneIdentyfikacyjne do
   begin
    if table4['ko_typ1'] then
    begin
     BrakID:=1;
     ImiePierwsze:=copy(s,pos(#32,s)+1,length(s)-pos(#32,s));
     Nazwisko:=copy(s,1,pos(#32,s)-1);
    end else
    begin
     NIP:=table4['ko_nip'];
     PelnaNazwa:=table4['ko_nazwa1'];
     if table4['ko_nazwa2']<>null then PelnaNazwa:=PelnaNazwa+' '+table4['ko_nazwa2'];
    end;
   end; // with DaneIdentyfikacyjne

   with Adres do
   begin
    KodKraju:='PL';
    Miejscowosc:=table4['ko_miejsce'];
    Ulica:=table4['ko_adres'];
    NrDomu:='Brak';
    KodPocztowy:=table4['ko_kodpocz'];
   end; // with Adres

  end; // with Podmiot2

  if table4['ko_nazwa5']<>'' then
  with Podmiot3.Add do // jeśli dobrze rozumiem, to Odbiorca
  begin
   with DaneIdentyfikacyjne do
   begin
    BrakID:=1;
    PelnaNazwa:=table4['ko_nazwa5'];
   end; // with DaneIdentyfikacyjne

   with Adres do
   begin
    KodKraju:='PL';
    Miejscowosc:=table4['ko_miasto2'];
    Ulica:=table4['ko_ulica2'];
    //NrDomu:=table4['ko_nrdomu'];
    KodPocztowy:=table4['ko_kod2'];
   end; // with Adres

   Rola:='2';
  end; // with Podmiot3

  with Fa do
  begin
   KodWaluty:='PLN';
   P_1:=datetostr(DateTimePicker1.date);
   P_1M:=table12['po_miejsce'];
   P_2:=edit1.text;
   //P_6
   if suma[3,1]>0 then
   begin
    P_13_1:=p_k(floattostrf(suma[1,1],fffixed,9,2)); // Suma wartości sprzedaży netto ze stawką 23% albo 22%.
    P_14_1:=p_k(floattostrf(suma[2,1],fffixed,9,2)); // Kwota podatku od sumy wartości sprzedaży netto ze stawką 23% albo 22%.
   end;
   if suma[3,2]>0 then
   begin
    P_13_2:=p_k(floattostrf(suma[1,2],fffixed,9,2)); // Suma wartości sprzedaży netto ze stawką 8 % albo 7%.
    P_14_2:=p_k(floattostrf(suma[2,2],fffixed,9,2)); // Kwota podatku od sumy wartości sprzedaży netto ze stawką 8% albo 7%.
   end;
   if suma[3,3]>0 then
   begin
    P_13_3:=p_k(floattostrf(suma[1,3],fffixed,9,2)); // Suma wartości sprzedaży netto ze stawką 5%.
    P_14_3:=p_k(floattostrf(suma[2,3],fffixed,9,2)); // Kwota podatku od sumy wartości sprzedaży netto ze stawką 5%.
   end;
   if suma[3,4]>0 then
   begin
    P_13_4:=p_k(floattostrf(suma[1,4],fffixed,9,2)); // Suma wartości sprzedaży netto ze stawką 5%.
    P_14_4:=p_k(floattostrf(suma[2,4],fffixed,9,2)); // Kwota podatku od sumy wartości sprzedaży netto ze stawką 5%.
   end;
   if suma[3,5]>0 then
   begin
    P_13_5:=p_k(floattostrf(suma[1,5],fffixed,9,2));
    P_14_5:=p_k(floattostrf(suma[2,5],fffixed,9,2));
   end;
   if suma[3,6]>0 then P_13_6:=p_k(floattostrf(suma[1,6],fffixed,9,2)); // Suma wartości sprzedaży netto ze stawką 0%.
   if suma[3,7]>0 then P_13_7:=p_k(floattostrf(suma[1,7],fffixed,9,2)); // Suma wartości sprzedaży zwolnionej.
   P_15:=p_k(floattostrf(suma[3,0],fffixed,9,2)); // Kwota (brutto) należności ogółem lub w przypadku faktur zaliczkowych, otrzymana kwota zapłaty. W przypadku faktur korygujących, korekta kwoty należności ogółem

   with Adnotacje do
   begin
    P_16:=1; // 1 - metoda kasowa
    P_17:=2;
    P_18:=2;
    P_18A:=2;
    P_19:=2;
    P_22:=2;
    P_23:=2;
    P_PMarzy:=2;
   end; // with Adnotacje

   if typ_dokumentu=1 then RodzajFaktury:='VAT';
   if typ_dokumentu=2 then
   begin
    Rodzajfaktury:='KOR';
    PrzyczynaKorekty:='Bo miałem taką ochotę'; // jeśli nic nie zmienię to :=combobox4.text
    TypKorekty:='3'; // nie wiem czy dobra wartość
    DataWystFaKorygowanej.Add({label_06.caption} '2021-10-01' ); // tu można chyba dodać wiele
    NrFaKorygowanej.Add({label_04.caption} 'FS 0123/2021' ); // tu można chyba dodać wiele
    NrKSeFFaKorygowanej.Add('1010000000-20200101-000000-000000-00'); // tu można chyba dodać wiele
   end;

   with FaWiersze, stringgrid1 do
   begin
    LiczbaWierszyFaktury:=inttostr(rowcount-1); //
    //WartoscWierszyFaktury1:=p_k(floattostrf(suma[1,0],fffixed,9,2));  // suma netto wszystkich stawek (P_13_1 do P_13_7)
    WartoscWierszyFaktury2:=p_k(floattostrf(suma[3,0],fffixed,9,2));  // suma brutto wszystkich stawek (P_13_1 do P_13_7)

    for i:=1 to rowcount-1 do
    with FaWiersz do
    begin
     Add;
     with Items[i-1] do
     begin
      NrWierszaFa:=cells[0,i];
      //UU_ID // Uniwersalny unikalny numer wiersza faktury
      table1.locate('to_nr',cells[10,i],[]);
      P_7:=table1['to_nazwa2'];
      if table1['to_pkwiu']<>null then PKWiU:=table1['to_pkwiu'];
      P_8A:=cells[2,i]; // j.m.
      P_8B:=p_k(cells[3,i]); // ilość
      //P_9A:=cells[6,i]; // cena netto pozycji faktury
      P_9B:=p_k(cells[6,i]); // Cena brutto, w przypadku zastosowania art. 106e ust. 7 i 8 ustawy
      //P_11 // Wartość netto
      P_11A:=p_k(cells[7,i]); // Wartość brutto
      P_12:=inttostr(trunc(strtofloat(cells[8,i])));
     end; // with Items[i-1]
    end; // with FaWiersz
   end; // with FaWiersze

   with Platnosc do
   begin
    if strtofloat(edit7.text)>0 then FormaPlatnosci:='1';
    if strtofloat(edit8.text)>0 then FormaPlatnosci:='2';
    if strtofloat(edit9.text)>0 then FormaPlatnosci:='5';
    if strtofloat(edit10.text)>0 then FormaPlatnosci:='6';
    if strtofloat(edit10.text)>0 then TerminPlatnosci.Add(datetostr(datetimepicker3.date));
    with RachunekBankowy.Add do
    begin
     NrRBPL:=table12['po_rach'];
     NazwaBanku:=table12['po_bank'];
    end;
   end; // with Platnosc
  end; // with Fa
  Stopka.Add.StopkaFaktury:=form4.combobox1.items[cg[24]];
 end; // with Faktura

 xml.DocumentElement:=faktura;
 if not directoryexists(path_1+'\Faktury VAT.xml\') then createdir(path_1+'\Faktury VAT.xml\');
 plik:=path_1+'\Faktury VAT.xml\'+edit1.text+'.xml';
 plik[pos('/',plik)]:='_';
 xml.SaveToFile(plik);
 walidacja(plik);
end;

Fragment wygenerowanego pliku xml:

<Podmiot1>
    <DaneIdentyfikacyjne>
      <NIP>9999999999</NIP>
      <PelnaNazwa>ABC AGD sp. z o. o.</PelnaNazwa>
    </DaneIdentyfikacyjne>
    <Adres>
      <KodKraju>PL</KodKraju>
      <Miejscowosc>Puławy</Miejscowosc>
      <Ulica>Lubelska 16</Ulica>
      <NrDomu>16</NrDomu>
      <KodPocztowy>24-100</KodPocztowy>
    </Adres>
    <Email>[email protected]</Email>
    <Telefon>602173170</Telefon>
  </Podmiot1>

powinno być:

<Podmiot1>
		<DaneIdentyfikacyjne>
			<NIP>9999999999</NIP>
			<PelnaNazwa>ABC AGD sp. z o. o.</PelnaNazwa>
		</DaneIdentyfikacyjne>
		<Adres xsi:type="tns:TAdresPolski">
			<KodKraju>PL</KodKraju>
			<Miejscowosc>Warszawa</Miejscowosc>
			<Ulica>Kwiatowa</Ulica>
			<NrDomu>1</NrDomu>
			<NrLokalu>2</NrLokalu>
			<KodPocztowy>00-001</KodPocztowy>
		</Adres>
		<Email>[email protected]</Email>
		<Telefon>667444555</Telefon>		
	</Podmiot1>

W załączniku unit ze schematu i okno mojego walidatora.

1

Walidator zgłasza mi błąd.

Pokaż co Ci zgłasza.

Z takich rzeczy które zauważyłem, to:
Masz: <Adres>
A powinno być: <Adres xsi:type="tns:TAdresPolski">

W ulicy też masz numer lokalu: <Ulica>Lubelska 16</Ulica>

0

Tak, ale dlaczego tak mi generuje?

0

W przeszłości jak miałem problem z 1-szą wersją JPK_V7M, a konkretnie moje Delphi źle robiło moduł ze schematu, to pomógł mi robertz68, za co jeszcze raz dzięki. Przesłał mi skompilowany u siebie schemat. Może i tym razem jest tutaj problem. Po walidacji wszystko inne jest w porządku. Jedynie ten adres, zamiast <Adres `xsi:type="tns:TAdresPolski"> mam <Adres>

0

<Adres xsi:type="tns:TAdresPolski">

To raczej powinno być:

<Adres xsi:type="TAdresPolski"> bo z xmla wynika że przestrzeń nazw: http://ksef.mf.gov.pl/wzor/2021/08/05/08051/" masz jako xmlns, a nie xmlns:tns

Dlaczego tak generuje: przegladając kod wstawia Adres na podstawie TAdres który jest typem abstrakcyjnym, nie znam sie na delphi więc nie wiem jak poprawić

0

To, że powinno być <Adres xsi:type="tns:TAdresPolski"> wynika z przykładów zamieszczonych przez Ministerstwo. Jak wygenerowanego przez siebie xml-a (z <Adres">) zmienię na piechotę na <Adres xsi:type="tns:TAdresPolski">, to walidacja przechodzi. Przechodzi także bez tns:

0

To nie jest zależne od tego jak opublikowało to ministerstwo tylko jak masz zdefiniowane przestrzenie nazw w samym xmlu.

Jeżeli masz tak:

<?xml version="1.0" encoding="utf-8"?>
<Faktura xmlns="http://ksef.mf.gov.pl/wzor/2021/08/05/08051/"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

i adres zdefiniujesz tak:

<Adres xsi:type="tns:TAdresPolski">

To dostaniesz błąd: Element 'tns' nie ma zadeklarowanego obszaru nazw

0

W ślad za przykładem Ministerstwa u siebie w wygenerowanym pliku też mam:

<?xml version="1.0" encoding="utf-8"?>
<Faktura xmlns="http://ksef.mf.gov.pl/wzor/2021/08/05/08051/" xmlns:schemaLocation="http://ksef.mf.gov.pl/wzor/2021/08/05/08051/ Schemat_FA_VAT(1)_v1-0E.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://ksef.mf.gov.pl/wzor/2021/08/05/08051/">
0

Pierwszy raz podałeś jak masz zdefiniowane przestrzenia nazw, zwróć uwagę, ze w moim przykładzie nie definiowałem przestrzeni tns, tylko domyslną, ty w nagłówku masz domyślną i zdublowaną jako tns...

0

Dopisałem z rozpędu, bo tak mam w przykładzie MF. Jednak, gdy w kodzie swojego programu piszę:

with Podmiot1 do //
  begin
   with DaneIdentyfikacyjne do
   begin
    NIP:=table12['po_nip'];
    PelnaNazwa:=table12['po_nazwa1'];
    if table12['po_nazwa2']<>null then PelnaNazwa:=PelnaNazwa+' '+table12['po_nazwa2'];
   end; // with DaneIdentyfikacyjne

   with Adres do            
   begin
    KodKraju:='PL';
    Miejscowosc:=table12['po_miejsce'];
    Ulica:=table12['po_adres'];
    NrDomu:=table12['po_nrdomu'];
    KodPocztowy:=table12['po_kodpocz'];
   end; // with Adres

   Email:=table12['po_mail'];
   telefon.Add(table12['po_tel']);
  end; // with Podmiot1

to w xml-u otrzymuję:

<Podmiot1>
    <DaneIdentyfikacyjne>
      <NIP>7160011105</NIP>
      <PelnaNazwa>P.P.U.H. "ELGOS" Chojecki Sławomir</PelnaNazwa>
    </DaneIdentyfikacyjne>
    <Adres>
      <KodKraju>PL</KodKraju>
      <Miejscowosc>Puławy</Miejscowosc>
      <Ulica>Lubelska 16</Ulica>
      <NrDomu>16</NrDomu>
      <KodPocztowy>24-100</KodPocztowy>
    </Adres>
    <Email>[email protected]</Email>
    <Telefon>602173170</Telefon>
  </Podmiot1>

Jestem za chudy w uszach, ale co z linią 6 ?

0

To jest moja opinia.
Olej klasy generowane przez automat. W tym wypadku (generalnie pliki JPK) olej XMLDocument. Te XMLe są na tyle proste, że składanie ich "ręcznie" (np. używając TStringList) jest banalne. Ja się rozbiłem przy generowaniu plików JPK_FA - przy dużej ilości faktur, generowanie tego przez XMLDocument, w porównaniu do składania "ręcznie" trwa wieki.

0

Może to abrakadaber i racja. Muszę spróbować. Pewnie i program będzie "lżejszy". Co do pliku JPK_FA to wprawdzie nigdy go nie wysyłałem (wszak jest na żądanie), ale mam przygotowany. W moim przypadku do pozycji faktur sięgam do oddzielnych plików. Zanim to się policzy, to faktycznie trwa dość długo, ale z samym utworzeniem nie miałem problemów. Do powstania obowiązku jest trochę czasu, to będę próbował.

Mam jeszcze drugą sprawę. Z wysyłaniem utworzonych plików JPK zdaję się dotychczas na aplikację Ministerstwa. Chciałbym sprawę tego całego szyfrowania, podpisywania i wysyłania móc dołączyć do swojego programu. Czy ktoś mógłby mnie tu jakoś nakierunkować?

0

jest tu gdzieś cały wątek o podpisywaniu

0

Czyli gdzie?

0

Jeszcze raz witam. To nikt mi nie podpowie co zrobić, aby mieć <Adres xsi:type="tns:TAdresPolski"> a nie <adres> ?

0

@Chojeś:
Kiedyś walczyłem z takim problemem i doszedłem do wniosku że interfejs utworzony przy pomocy XmlDataBindig nie odsługuje prefiksów z identyfikatorami przestrzeni nazw

2

tak to można zrobić przy pomocy klas TXmldocument oraz IXmldocument

var
  newNode: IXMLNode;
  XMLDoc: IXmldocument;
begin
  XMLDoc := TXMLDocument.create(nil);
  XMLDoc.Active := true;
  newNode := XMLDoc.AddChild('adres');
  newNode.DeclareNamespace('xsi', 'tns:TAdresPolski');
  newNode.Text := 'xxxxxxxxxx';
  XMLDoc.SaveToFile('c:\!\jpkxml.xml');
end;

rezultat

<adres xmlns:xsi="tns:TAdresPolski">xxxxxxxxxx</adres>
0

Przeanalizuję wieczorem. Póki co serdeczne dzięki za odzew. Pozdrawiam.

0

Ja potrzebuję mieć: <adres xsi="tns:TAdresPolski"> czyli bez xmlns

2

@Chojeś:
teraz zauważyłem, obecnie obowiązjue wariant nr 3 a Ty zajmujesz się wariantem 1

   KodFormularza.WersjaSchemy:='1-0E';
   KodFormularza.KodSystemowy:='FA (1)';
<Naglowek>
    <KodFormularza kodSystemowy="JPK_FA (3)" wersjaSchemy="1-0">JPK_FA</KodFormularza>
    <WariantFormularza>3</WariantFormularza>
    <CelZlozenia>1</CelZlozenia>
    <DataWytworzeniaJPK>2020-02-10T17:06:55</DataWytworzeniaJPK>
    <DataOd>2020-01-01</DataOd>
    <DataDo>2020-01-31</DataDo>
    <KodUrzedu>xxxx</KodUrzedu>
  </Naglowek>
var
  newNode: IXMLNode;
  XMLDoc: IXmldocument;

begin
  XMLDoc := TXMLDocument.create(nil);
  XMLDoc.Active := true;
  newNode := XMLDoc.AddChild('adres');
  newNode.Text := 'xxxxxxxxxx';
  newNode.SetAttributeNS('xsi','','tns:TAdresPolski');
  XMLDoc.SaveToFile('c:\!\jpkxml.xml');

rezultat

<adres xsi="tns:TAdresPolski">xxxxxxxxxx</adres>
0

Dzięki serdeczne grzegorz_so.

1

rozwiązanie przy pomocy interfejsu IXMLFaktura wygenerowanego ze schemy Schemat_FA_VAT(1)_v1-0E (1).xsd

var 
  xml: ixmldocument;
  faXml: IXMLFaktura;
begin
  xml := txmldocument.Create(nil);
  xml.Options := xml.Options + [doNodeautoindent]; 
  faXml := GetFaktura(xml);
  //....... 
  faXml.Podmiot1.adres.Attributes['xsi:type'] := 'tns:TAdresPolski';
  //......
end;

rezultat

 <Adres xsi:type="tns:TAdresPolski">

1 użytkowników online, w tym zalogowanych: 0, gości: 1