Błędy podczas obsługi e-deklaracji – jak to ugryźć?

0

Zweracam się z prośbą o (pomoc - korektę) moich poczynań. Chodzi mi o e-deklaracje i TurboDelphi.

Po przegrzebaniu tematu w Google i innych forach, odnośnie SOAP doszedłem już do tego że należy:

  • użyć XMLDocumnet z zakładki "Internet",
  • poprawić pliki odpowiadające za parsowanie SOAP.

Czytając o e-daklaracjach znalazłem:

  • pobrać za strony ministrarstwa (http://www.e-deklaracje.gov.pl/index.php?page=do_pobrania) dokumentacje (aktualnie w wersji 1.6 [1.6.test])
  • użyć File->New->Other: WebSerwices->WSDL Importer: aby zaciągnąć plik WSDL ze (strony ministerstwa lub dokumentacji). Nazwę go UnitWSDL;
  • użyć File->New->Other: XML->XML Data Binding: aby zaciągnąć plik XSD ze (strony ministerstwa lub dokumentacji). Nazwę go UnitXSD;

Tutaj pojawia mi sie pierwszy problem. Podczas importu XSD Delphi daje komunikat że Document element type not specified i czy kontynuować. Jeżeli dam żeby kontunuował to nie tworzy mi funkcji globalnych.

Jeżeli zanzaczę pole "Document Element Type" to potem muszę pozmieniać w UnitWSDL nazwy klas z (np. sendDocument na IXMLSendDocument lub TXMLSendDocument itd), bo inaczej nie chce się kompilować. oczywiście do UnitWSDL muszę dodać w sekcji uses UnitXSD;

Niestety nie bardzo wiem jak to dalej ugryźć.

Na razie próbuje na różne sposoby wywołać funkcje "sendUnsignDocument" ale mi nie wychodzi i nie wiem jak się tym posłużyć. Kombinuję na różne sposoby i dostaję różne komunikaty o błędach. Nie wiem czy posługuję się dobrymi klasami i czy mam dobre deklaracje obiektów.

procedure TfrmDeklaracje.btnSendClick(Sender: TObject);
var
  WebAPI  : GateServicePortType;          // SOAP port
  part1   : IXMLSendUnsignDocument;          // Dokument do wysłania
  resp1   : IXMLSendUnsignDocumentResponse;  // Odpowiedz serwera
  xmlDoku : TXMLDocument;                 // Dokument XML - deklaracja np.pit-11
  s64     : string;                       // zmienna do zakodowania base64 (z zakładki "indy misc")
  fnDok   : string;                       //  scieżka do pliku z deklaracją
begin
  fnDok := ExtractFilePath(Application.ExeName)+'deklaracja.xml'; // Ustawiam scieżkę do pliku.

  WebAPI := GetGateServicePortType(true,'',HTTPRIO1); // Ustawiam połączenia SOAP

  xmlDoku := TXMLDocument.Create(Application); // tworze kontrolkę do deklaracji
  xmlDoku.LoadFromFile(fnDok);   // wczytuje z pliku deklarację w formacji XML
  xmlDoku.Active:=true;
  s64 := IdEncoderMIME1.Encode( xmlDoku.XML.Text ); // koduję deklarację w base64
  xmlDoku.XML.Text := s64;               // podstawiam do dokumentu zakodowaną deklarację

  try
    part1 := GetsendUnsignDocument(xmlDoku);    <-- //  BŁĄD 
    resp1 := WebAPI.sendUnsignDocument(part1); <-- // lub tutaj błąd
  finally
    //resp1 := GetsendUnsignDocumentResponse(xmlDoku);
    //Memo1.Lines.Add(resp1.StatusOpis);
  end;

  WebAPI._Release;
end;

Dostaję błąd :

Invalid at the top level of the document. Line1: PD94bWwgdm........

lub

Interface not supported

w zależności czy zaremuję kodowanie czy nie

 // s64 := IdEncoderMIME1.Encode( xmlDoku.XML.Text ); // koduję deklarację w base64
 // xmlDoku.XML.Text := s64; 

Czy możecie wskazać mi kierunek poszukiwań lub jakieś informacje poza oficjalną stroną MF ?

0

Częściowo udało mi się wykonać krok do przodu.
Pomocna okazała się strona http://www.drbob42.com/examines/examinA2.htm z której dowiedziałem się że trzeba pobrać ze strony CodeGear poprawkę (http://cc.embarcadero.com/Item/24535). Uwaga: aby ją pobrać należy być zarejestrowanym użytkownikiem borlanda.

W poprawce dołączony jest między innymi plik WSDLImp.exe, który poprawnie importuje pliki WSDL. Po tej korekcie plik wynikowy faktycznie mocno się różnił od dotychczasowego. (To był mój pierwszy błąd - myślałem że mój wynikowy plik po imporcie WSDL jest poprawny)

Po tej zmianie mój kod wygląda trochę inaczej.

procedure TfrmDeklaracje.btnSendClick(Sender: TObject);
var
  WebAPI  : GateServicePortType;          // SOAP port
  part1   : sendDocument;                 // Dokument do wysłania
  resp1   : sendDocumentResponse;         // Odpowiedz serwera
  xmlDoku : TXMLDocument;                 // Dokument XML - deklaracja np.pit-11
  s64     : string;                       // zmienna do zakodowania base64 (z zakładki "indy misc")
  fnDok   : string;                       //  scieżka do pliku z deklaracją
  i       : Integer;
  ArrDok  : TByteDynArray;
begin
  Memo1.Clear;
  fnDok := ExtractFilePath(Application.ExeName)+'deklaracja.xml'; // Ustawiam scieżkę do pliku.

  xmlDoku := TXMLDocument.Create(Application);        // tworze kontrolkę do deklaracji
  xmlDoku.LoadFromFile(fnDok);                        // wczytuje z pliku deklarację w formacji XML
  s64 := IdEncoderMIME1.Encode( xmlDoku.XML.Text );   // koduję deklarację w base64

  SetLength(ArrDok,length(s64));                      // Ustawiam wielkość tablicy bajtów
  for I := 1 to length(s64) do arrdok[i-1] := ord(s64[i]);

  WebAPI := GetGateServicePortType(true,'',HTTPRIO1); // Ustawiam połączenia SOAP
  part1 := sendDocument.Create;
  resp1 := sendDocumentResponse.Create;
  try
    part1.document := ArrDok;             // przypisuje do dokumentu tablicę z deklaracją wBase64
    resp1 := WebAPI.sendDocument(part1);  // błąd ESOAPHTTPException ,ale  nie jest napisane jaki błąd !!!
  finally
    Memo1.Lines.Add(IntToStr(resp1.status));
    Memo1.Lines.Add(resp1.StatusOpis);
    Memo1.Lines.Add(resp1.refId);
  end;
end;

Co prawda dalej daje błąd ale teraz już, krzyczy z bramki że autoryzacja jest niepoprawna. Więc jest to jakiś krok naprzód.

**EDIT: **
Okazało się, że niepotrzebnie wsadziłem tam kodowanie base64. Funkcja sendDocument sama to robi.
więc zamiast
s64 := IdEncoderMIME1.Encode( xmlDoku.XML.Text );
wystarczy
s64 := xmlDoku.XML.Text;

Rozwiązaniem problemu z błędem w którym nie było informacji (w czym ten błąd jest ) okazało się zainstalowanie certyfikatu.
http://www.cenzus.legat.com.pl/edward/konfiguracjaserweramf.pdf
Mam nadzieję że moja tygodniowa wojna z tym tematem ułatwi komuś innemu życie.

Mam pytanie odnośnie plików WSDL.
Czy lepiej podawać lokalizację pliku WSDL jako adres URL czy może zawartość takiego pliku jest na tyle stała że lepiej ładować go lokalnie i uaktualniać w razie potrzeby ?

0

Witam
Bardzo mnie interesuje jak poradziłeś sobie z importem schemy do delphi i poprawnym wygenerowaniem klas metod itd

Pozdrawiam

1

e-deklaracje generalnie zachowują się podobnie do eWUŚia i pojawia się ten sam problem z importem WSDLa w Delphi.

Ja bym ci radził zrobić tak jak każdy, kto próbował importować tego WSDLa (generowanego bodaj w Visual Studio) - olej go.

Na podstawie dokumentacji połącz się z odpowiednim serwerem SOAPa, a następnie ręcznie generuj pliki XML i ręcznie interpretuj odpowiedzi.

Wszystkie te mechanizmy niby używają zaawansowanej technologii - typu SOAP, SSL i XML, ale jak dojdziesz do sedna - okazuje się, że kluczowe informacje (jak wygasanie hasła do systemu eWUŚ) przekazywane są w postaci tekstowej, jako wartość komunikatu o poprawnym logowaniu. W efekcie i tak musisz parsować ręcznie te dane. Nie minie cię to, a na pewno zaoszczędzi sporo czasu i nerwów.

EDIT: Jeszcze jedno - nie używaj komponentu TXMLDocument - nie wrappuje całości biblioteki MSXML - nie masz możliwości puszczania zapytań XPath na pobranym dokumencie XML. Ja bym ci radził zaimportować bibliotekę typów - i to najlepiej z MS XML 6.0 - tak, żeby mieć obsługę XPatha. W wersji co prawda 1.0, a nie 2.0 (2.0 ma dużo przydatnych funkcji, których możesz użyć bezpośrednio w zapytaniu - oszczędza to czas na dalszym przetwarzaniu danych).

Pamiętaj też, że po utworzeniu obiektu DOMDocument z zaimportowanej biblioteki typów - musisz zrobić SetProperty i ustawić Xpath jako metodę przeszukiwania: tu np. masz to opisane: http://support.microsoft.com/kb/288913

P.S. Zdawaj relację z postępów - bardzo interesuje mnie ten temat.

0

Dzięki za odpowiedź, jednak w moim wypadku po wyciągnięciu danych z bazy muszę w "jakiś" w miarę prosty i bezbolesny sposób zaimportować do formularza w pdf skąd albo deklaracja zostanie wydrukowana albo wysłana

0

Tym prostym sposobem będzie zbindowanie danych na podstawie pliku XML, który albo wysyłasz, albo otrzymujesz w odpowiedzi. XML Data Binding wygeneruje ci ładną klasę (trzeba uważać na to co i jak generuje, oraz jakie typy podstawia, ale i tak odwali 90% roboty z tworzeniem klasy opakowującej dla danego XMLa).

0

Opiszę krótko co zrobiłem.

Import schemy xsd do Delphi nie do końca się udaje więc przy użyciu http://www.xsd2xml.com/ zapisuję do xml i to importuje do Delphi (Xml data binding).
Po utworzeniu nowego unita tworzę xml dla konkretnej deklaracji następnie przy użyciu formularza np Vat7 importuje to do niego. Na razie nie do końca mi się to udaje bo formularz zgłasza błąd nagłówka
ale potem pojawiają się tylko komunikaty o nie właściwym sposobie wypełnienia danych tylu: "jesli wartość pola x jest większa od wartości pola y to w pole z należy wpisać 0" finalnie mam wypełniony formularz.

Kolejnym problemem z którym się spotkałem to to jak zmusić Adobe Readera żeby załadował pdf-a i wczytał do niego dane, ręcznie oczywiście mogę to zrobić ale chciałbym żeby wygladało to mniej więcej tak:
klikam "oblicz deklaracke Vat7 za dany miesiąc - program dokonuje stosownych obliczeń - otwiera się formularz aktywny z wyliczoymi wartościami - drukuję lub wysyłam"

Próbowałem dobrac sie doReadera przez kontrolke ActiveX ale niestety opcji wczytania danych wprost nie ma są za to dwie metody które teoretycznie mogłyby to wykonać

procedure TAcroPDF.postMessage(strArray: OleVariant);
begin
  DefaultInterface.postMessage(strArray);
end;

procedure TAcroPDF.execCommand(strArray: OleVariant);
begin
  DefaultInterface.execCommand(strArray);
end;

niestety nie dogrzebałem się jak dokładnie ich użyć.
Innym pomysłem jest napisanie plugina do Acrobata który po załadowaniu formularza wczytałby dane z określonego xml-a (temat do rozpoznania) przeglądałem API i możliwości jest sporo

Wszelkie pytania/sugestie/pomoc mile widziane :)

dodanie znacznika <code class="delphi"> - fp

1

Dla potomnych:

Po ściągnięciu poprawki, należy użyć polecenia (dla wersji testowej):
WSDLImp.exe -p https://test-bramka.edeklaracje.gov.pl/uslugi/dokumenty?wsdl

A oto wygenerowany plik, jeżeli komuś nie pójdzie.

// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : https://test-bramka.edeklaracje.gov.pl/uslugi/dokumenty?wsdl
//  >Import : https://test-bramka.edeklaracje.gov.pl/uslugi/dokumenty?wsdl:0
//  >Import : https://test-bramka.edeklaracje.gov.pl/uslugi/GateService?xsd=GateService.xsd
// Encoding : UTF-8
// Version  : 1.0
// (2014-06-10 13:30:51 - - $Rev: 10138 $)
// ************************************************************************ //

unit GateService_test;

interface

uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;

const
  IS_OPTN = $0001;
  IS_REF  = $0080;


type

  // ************************************************************************ //
  // The following types, referred to in the WSDL document are not being represented
  // in this file. They are either aliases[@] of other types represented or were referred
  // to but never[!] declared in the document. The types from the latter category
  // typically map to predefined/known XML or Borland types; however, they could also 
  // indicate incorrect WSDL documents that failed to declare or import a schema type.
  // ************************************************************************ //
  // !:base64Binary    - "http://www.w3.org/2001/XMLSchema"[Gbl]
  // !:string          - "http://www.w3.org/2001/XMLSchema"[Gbl]
  // !:int             - "http://www.w3.org/2001/XMLSchema"[Gbl]

  sendDocument         = class;                 { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  sendDocumentResponse = class;                 { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  sendUnsignDocument   = class;                 { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  sendUnsignDocumentResponse = class;           { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  sendDocumentWithAttachment = class;           { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  sendDocumentWithAttachmentResponse = class;   { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  requestUPO           = class;                 { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }
  requestUPOResponse   = class;                 { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Lit][GblElm] }

  { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Smpl] }
  language = (de, en, pl);

  { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Smpl] }
  signatureType = (PIT, MPO);

  { "https://bramka.e-deklaracje.mf.gov.pl/xsd"[Smpl] }
  language2 = (de2, en2, pl2);



  // ************************************************************************ //
  // XML       : sendDocument, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  sendDocument = class(TRemotable)
  private
    Fdocument: TByteDynArray;
  public
    constructor Create; override;
  published
    property document: TByteDynArray  read Fdocument write Fdocument;
  end;



  // ************************************************************************ //
  // XML       : sendDocumentResponse, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  sendDocumentResponse = class(TRemotable)
  private
    FrefId: WideString;
    FrefId_Specified: boolean;
    Fstatus: Integer;
    FstatusOpis: WideString;
    procedure SetrefId(Index: Integer; const AWideString: WideString);
    function  refId_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property refId:      WideString  Index (IS_OPTN) read FrefId write SetrefId stored refId_Specified;
    property status:     Integer     read Fstatus write Fstatus;
    property statusOpis: WideString  read FstatusOpis write FstatusOpis;
  end;



  // ************************************************************************ //
  // XML       : sendUnsignDocument, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  sendUnsignDocument = class(TRemotable)
  private
    Fdocument: TByteDynArray;
    Flanguage: language;
    Flanguage_Specified: boolean;
    FsignatureType: signatureType;
    FsignatureType_Specified: boolean;
    procedure Setlanguage(Index: Integer; const Alanguage: language);
    function  language_Specified(Index: Integer): boolean;
    procedure SetsignatureType(Index: Integer; const AsignatureType: signatureType);
    function  signatureType_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property document:      TByteDynArray  read Fdocument write Fdocument;
    property language:      language       Index (IS_OPTN) read Flanguage write Setlanguage stored language_Specified;
    property signatureType: signatureType  Index (IS_OPTN) read FsignatureType write SetsignatureType stored signatureType_Specified;
  end;



  // ************************************************************************ //
  // XML       : sendUnsignDocumentResponse, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  sendUnsignDocumentResponse = class(TRemotable)
  private
    FrefId: WideString;
    FrefId_Specified: boolean;
    Fstatus: Integer;
    FstatusOpis: WideString;
    procedure SetrefId(Index: Integer; const AWideString: WideString);
    function  refId_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property refId:      WideString  Index (IS_OPTN) read FrefId write SetrefId stored refId_Specified;
    property status:     Integer     read Fstatus write Fstatus;
    property statusOpis: WideString  read FstatusOpis write FstatusOpis;
  end;



  // ************************************************************************ //
  // XML       : sendDocumentWithAttachment, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  sendDocumentWithAttachment = class(TRemotable)
  private
    Fattachment: TByteDynArray;
    Fattachment_Specified: boolean;
    Fdocument: TByteDynArray;
    procedure Setattachment(Index: Integer; const ATByteDynArray: TByteDynArray);
    function  attachment_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property attachment: TByteDynArray  Index (IS_OPTN) read Fattachment write Setattachment stored attachment_Specified;
    property document:   TByteDynArray  read Fdocument write Fdocument;
  end;



  // ************************************************************************ //
  // XML       : sendDocumentWithAttachmentResponse, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  sendDocumentWithAttachmentResponse = class(TRemotable)
  private
    FrefId: WideString;
    FrefId_Specified: boolean;
    Fstatus: Integer;
    FstatusOpis: WideString;
    procedure SetrefId(Index: Integer; const AWideString: WideString);
    function  refId_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property refId:      WideString  Index (IS_OPTN) read FrefId write SetrefId stored refId_Specified;
    property status:     Integer     read Fstatus write Fstatus;
    property statusOpis: WideString  read FstatusOpis write FstatusOpis;
  end;



  // ************************************************************************ //
  // XML       : requestUPO, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  requestUPO = class(TRemotable)
  private
    FrefId: WideString;
    Flanguage: language2;
    Flanguage_Specified: boolean;
    procedure Setlanguage(Index: Integer; const Alanguage2: language2);
    function  language_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property refId:    WideString  read FrefId write FrefId;
    property language: language2   Index (IS_OPTN) read Flanguage write Setlanguage stored language_Specified;
  end;



  // ************************************************************************ //
  // XML       : requestUPOResponse, global, <element>
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/xsd
  // Serializtn: [xoLiteralParam]
  // Info      : Wrapper
  // ************************************************************************ //
  requestUPOResponse = class(TRemotable)
  private
    Fupo: WideString;
    Fupo_Specified: boolean;
    Fstatus: Integer;
    FstatusOpis: WideString;
    procedure Setupo(Index: Integer; const AWideString: WideString);
    function  upo_Specified(Index: Integer): boolean;
  public
    constructor Create; override;
  published
    property upo:        WideString  Index (IS_OPTN) read Fupo write Setupo stored upo_Specified;
    property status:     Integer     read Fstatus write Fstatus;
    property statusOpis: WideString  read FstatusOpis write FstatusOpis;
  end;


  // ************************************************************************ //
  // Namespace : https://bramka.e-deklaracje.mf.gov.pl/
  // soapAction: urn:%operationName%
  // transport : http://schemas.xmlsoap.org/soap/http
  // style     : document
  // binding   : GateServiceSOAP11Binding
  // service   : GateService
  // port      : GateServiceSOAP11port
  // URL       : https://test-bramka.edeklaracje.gov.pl/uslugi/dokumenty/
  // ************************************************************************ //
  GateServicePortType = interface(IInvokable)
  ['{58886444-F106-2A9D-2B76-CAAFE9477074}']

    // Cannot unwrap: 
    //     - More than one strictly out element was found
    function  sendDocument(const part1: sendDocument): sendDocumentResponse; stdcall;

    // Cannot unwrap: 
    //     - More than one strictly out element was found
    function  sendUnsignDocument(const part1: sendUnsignDocument): sendUnsignDocumentResponse; stdcall;

    // Cannot unwrap: 
    //     - More than one strictly out element was found
    function  sendDocumentWithAttachment(const part1: sendDocumentWithAttachment): sendDocumentWithAttachmentResponse; stdcall;

    // Cannot unwrap: 
    //     - More than one strictly out element was found
    function  requestUPO(const part1: requestUPO): requestUPOResponse; stdcall;
  end;

function GetGateServicePortType(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): GateServicePortType;


implementation
  uses SysUtils;

function GetGateServicePortType(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): GateServicePortType;
const
  defWSDL = 'https://test-bramka.edeklaracje.gov.pl/uslugi/dokumenty?wsdl';
  defURL  = 'https://test-bramka.edeklaracje.gov.pl/uslugi/dokumenty/';
  defSvc  = 'GateService';
  defPrt  = 'GateServiceSOAP11port';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as GateServicePortType);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;


constructor sendDocument.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

constructor sendDocumentResponse.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure sendDocumentResponse.SetrefId(Index: Integer; const AWideString: WideString);
begin
  FrefId := AWideString;
  FrefId_Specified := True;
end;

function sendDocumentResponse.refId_Specified(Index: Integer): boolean;
begin
  Result := FrefId_Specified;
end;

constructor sendUnsignDocument.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure sendUnsignDocument.Setlanguage(Index: Integer; const Alanguage: language);
begin
  Flanguage := Alanguage;
  Flanguage_Specified := True;
end;

function sendUnsignDocument.language_Specified(Index: Integer): boolean;
begin
  Result := Flanguage_Specified;
end;

procedure sendUnsignDocument.SetsignatureType(Index: Integer; const AsignatureType: signatureType);
begin
  FsignatureType := AsignatureType;
  FsignatureType_Specified := True;
end;

function sendUnsignDocument.signatureType_Specified(Index: Integer): boolean;
begin
  Result := FsignatureType_Specified;
end;

constructor sendUnsignDocumentResponse.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure sendUnsignDocumentResponse.SetrefId(Index: Integer; const AWideString: WideString);
begin
  FrefId := AWideString;
  FrefId_Specified := True;
end;

function sendUnsignDocumentResponse.refId_Specified(Index: Integer): boolean;
begin
  Result := FrefId_Specified;
end;

constructor sendDocumentWithAttachment.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure sendDocumentWithAttachment.Setattachment(Index: Integer; const ATByteDynArray: TByteDynArray);
begin
  Fattachment := ATByteDynArray;
  Fattachment_Specified := True;
end;

function sendDocumentWithAttachment.attachment_Specified(Index: Integer): boolean;
begin
  Result := Fattachment_Specified;
end;

constructor sendDocumentWithAttachmentResponse.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure sendDocumentWithAttachmentResponse.SetrefId(Index: Integer; const AWideString: WideString);
begin
  FrefId := AWideString;
  FrefId_Specified := True;
end;

function sendDocumentWithAttachmentResponse.refId_Specified(Index: Integer): boolean;
begin
  Result := FrefId_Specified;
end;

constructor requestUPO.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure requestUPO.Setlanguage(Index: Integer; const Alanguage2: language2);
begin
  Flanguage := Alanguage2;
  Flanguage_Specified := True;
end;

function requestUPO.language_Specified(Index: Integer): boolean;
begin
  Result := Flanguage_Specified;
end;

constructor requestUPOResponse.Create;
begin
  inherited Create;
  FSerializationOptions := [xoLiteralParam];
end;

procedure requestUPOResponse.Setupo(Index: Integer; const AWideString: WideString);
begin
  Fupo := AWideString;
  Fupo_Specified := True;
end;

function requestUPOResponse.upo_Specified(Index: Integer): boolean;
begin
  Result := Fupo_Specified;
end;

initialization
  InvRegistry.RegisterInterface(TypeInfo(GateServicePortType), 'https://bramka.e-deklaracje.mf.gov.pl/', 'UTF-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(GateServicePortType), 'urn:%operationName%');
  InvRegistry.RegisterInvokeOptions(TypeInfo(GateServicePortType), ioDocument);
  InvRegistry.RegisterInvokeOptions(TypeInfo(GateServicePortType), ioLiteral);
  InvRegistry.RegisterExternalParamName(TypeInfo(GateServicePortType), 'sendDocument', 'part11', 'part1');
  InvRegistry.RegisterExternalParamName(TypeInfo(GateServicePortType), 'sendUnsignDocument', 'part11', 'part1');
  InvRegistry.RegisterExternalParamName(TypeInfo(GateServicePortType), 'sendDocumentWithAttachment', 'part11', 'part1');
  InvRegistry.RegisterExternalParamName(TypeInfo(GateServicePortType), 'requestUPO', 'part11', 'part1');
  RemClassRegistry.RegisterXSClass(sendDocument, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'sendDocument');
  RemClassRegistry.RegisterSerializeOptions(sendDocument, [xoLiteralParam]);
  RemClassRegistry.RegisterXSClass(sendDocumentResponse, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'sendDocumentResponse');
  RemClassRegistry.RegisterSerializeOptions(sendDocumentResponse, [xoLiteralParam]);
  RemClassRegistry.RegisterXSInfo(TypeInfo(language), 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'language');
  RemClassRegistry.RegisterXSInfo(TypeInfo(signatureType), 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'signatureType');
  RemClassRegistry.RegisterXSClass(sendUnsignDocument, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'sendUnsignDocument');
  RemClassRegistry.RegisterSerializeOptions(sendUnsignDocument, [xoLiteralParam]);
  RemClassRegistry.RegisterXSClass(sendUnsignDocumentResponse, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'sendUnsignDocumentResponse');
  RemClassRegistry.RegisterSerializeOptions(sendUnsignDocumentResponse, [xoLiteralParam]);
  RemClassRegistry.RegisterXSClass(sendDocumentWithAttachment, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'sendDocumentWithAttachment');
  RemClassRegistry.RegisterSerializeOptions(sendDocumentWithAttachment, [xoLiteralParam]);
  RemClassRegistry.RegisterXSClass(sendDocumentWithAttachmentResponse, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'sendDocumentWithAttachmentResponse');
  RemClassRegistry.RegisterSerializeOptions(sendDocumentWithAttachmentResponse, [xoLiteralParam]);
  RemClassRegistry.RegisterXSInfo(TypeInfo(language2), 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'language2', 'language');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(language2), 'de2', 'de');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(language2), 'en2', 'en');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(language2), 'pl2', 'pl');
  RemClassRegistry.RegisterXSClass(requestUPO, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'requestUPO');
  RemClassRegistry.RegisterSerializeOptions(requestUPO, [xoLiteralParam]);
  RemClassRegistry.RegisterXSClass(requestUPOResponse, 'https://bramka.e-deklaracje.mf.gov.pl/xsd', 'requestUPOResponse');
  RemClassRegistry.RegisterSerializeOptions(requestUPOResponse, [xoLiteralParam]);

end.
0

A jak rozwiązaliście etap wcześniej czyli walidację pliku xml na podstawie xsd ??

0

W opcjach w ustawieniach internetowych przeglądarki Internet Explorer w zakładce zaawansowane:
zaznacz

  • "użyj TLS 1.x",
  • "użyj SSL 3.0".
Decho napisał(a):

Zweracam się z prośbą o (pomoc - korektę) moich poczynań.
Chodzi mi o e-deklaracje i TurboDelphi.

Po przegrzebaniu tematu w Google i innych forach, odnośnie SOAP doszedłem już do tego że należy:
#- użyć XMLDocumnet z zakładki "Internet",
#- poprawić pliki odpowiadające za parsowanie SOAP.

Czytając o e-daklaracjach znalazłem:
#- pobrać za strony ministrarstwa (http://www.e-deklaracje.gov.pl/index.php?page=do_pobrania) dokumentacje (aktualnie w wersji 1.6 [1.6.test])
#- użyć File->New->Other: WebSerwices->WSDL Importer: aby zaciągnąć plik WSDL ze (strony ministerstwa lub dokumentacji). Nazwę go UnitWSDL;
#- użyć File->New->Other: XML->XML Data Binding: aby zaciągnąć plik XSD ze (strony ministerstwa lub dokumentacji). Nazwę go UnitXSD;

Tutaj pojawia mi sie pierwszy problem. Podczas importu XSD Delphi daje komunikat że Document element type not specified i czy kontynuować.
Jeżeli dam żeby kontunuował to nie tworzy mi funkcji globalnych.
Jeżeli zanzaczę pole "Document Element Type" to potem muszę pozmieniać w UnitWSDL nazwy klas z (np. sendDocument na IXMLSendDocument lub TXMLSendDocument itd), bo inaczej nie chce się kompilować. oczywiście do UnitWSDL muszę dodać w sekcji uses UnitXSD;

Niestety nie bardzo wiem jak to dalej ugryźć.
Na razie próbuje na różne sposoby wywołać funkcje "sendUnsignDocument" ale mi nie wychodzi i nie wiem jak się tym posłużyć. Kombinuję na różne sposoby i dostaję różne komunikaty o błędach. Nie wiem czy posługuję się dobrymi klasami i czy mam dobre deklaracje obiektów.

procedure TfrmDeklaracje.btnSendClick(Sender: TObject);
var
  WebAPI  : GateServicePortType;          // SOAP port
  part1   : IXMLSendUnsignDocument;          // Dokument do wysłania
  resp1   : IXMLSendUnsignDocumentResponse;  // Odpowiedz serwera
  xmlDoku : TXMLDocument;                 // Dokument XML - deklaracja np.pit-11
  s64     : string;                       // zmienna do zakodowania base64 (z zakładki "indy misc")
  fnDok   : string;                       //  scieżka do pliku z deklaracją
begin
  fnDok := ExtractFilePath(Application.ExeName)+'deklaracja.xml'; // Ustawiam scieżkę do pliku.

  WebAPI := GetGateServicePortType(true,'',HTTPRIO1); // Ustawiam połączenia SOAP

  xmlDoku := TXMLDocument.Create(Application); // tworze kontrolkę do deklaracji
  xmlDoku.LoadFromFile(fnDok);   // wczytuje z pliku deklarację w formacji XML
  xmlDoku.Active:=true;
  s64 := IdEncoderMIME1.Encode( xmlDoku.XML.Text ); // koduję deklarację w base64
  xmlDoku.XML.Text := s64;               // podstawiam do dokumentu zakodowaną deklarację

  try
    part1 := GetsendUnsignDocument(xmlDoku);    <-- //  BŁĄD 
    resp1 := WebAPI.sendUnsignDocument(part1); <-- // lub tutaj błąd
  finally
    //resp1 := GetsendUnsignDocumentResponse(xmlDoku);
    //Memo1.Lines.Add(resp1.StatusOpis);
  end;

  WebAPI._Release;
end;

Dostaję błąd :
Invalid at the top level of the document. Line1: PD94bWwgdm........ lub Interface not supported
w zależności czy zaremuję kodowanie czy nie

// s64 := IdEncoderMIME1.Encode( xmlDoku.XML.Text ); // koduję deklarację w base64
// xmlDoku.XML.Text := s64;

> 
> 
> Czy możecie wskazać mi kierunek poszukiwań lub jakieś informacje poza oficjalną stroną MF ?
0

Witam,

Przetestowałem to rozwiązanie. Otrzymuję komunikat z serwera testowego M.F. następującej treści:

**"301
Dokument w trakcie przetwarzania, sprawdź wynik następnej weryfikacji dokumentu
1d219be22778caa03e10790a52b91eef"
**
Ale co dalej ? Jak otrzymać dokument potwierdzający złożenie np. deklaracji VAT-7 ?

Krzysztof

0

na testowym tu się kończy przetwarzanie. UPO otrzymasz jedynie z serwera produkcyjnego

0

@abrakadaber:
serwery testowe ministerstwa finansów zwracają UPO. Czasami niezbyt chętnie i nie zawsze , ale zdarza się że zwracają UPO ...

0

@grzegorz_so: racja, to JPK testowy nie przetwarza dokumentu. Czyli pozostaje czekać.

0

@abrakadaber: JPK testowy również zwraca UPO, ale nie zawsze, a czas oczekiwania też bywa różny, od kilkunastu minut do nieskończoności :) nie wiem z czego to wynika

0

Szanowni Koledzy,

Mam jeszcze jedno pytanie. Czy jeżeli wysłałem dokument np. deklarację VAT-7 w postaci pliku .xml i otrzymałem (tak jak wcześniej napisałem) odpowiedź z bramki testowej M.F. w postaci:

"301
Dokument w trakcie przetwarzania, sprawdź wynik następnej weryfikacji dokumentu
1d219be22778caa03e10790a52b91eef"

Czy to oznacza, że (jak piszecie) serwer M.F. bramki testowej może nie zwrócić kodu "200" i UPO z jakiegoś tam powodu, czy też należy w/w numer referencyjny wysłać ponownie
z zastosowaniem:

  1. requestUPO
  2. requestUPOresponse

Jestem początkującym w tej dziedzinie, a informacji w necie jak na lekarstwo (praktycznie nie ma).

Poza tym, czy to oznacza, że jak zaryzykuję z bramką tzw. "produkcyjną" i wyślę rzeczywistą deklarację VAT-7, to otrzymam zwrotną informację "200" oraz UPO - wysyłając tylko raz deklarację i nic więcej nie czyniąc ?

Od początku tego roku mam obowiązek wysyłać deklarację w postaci elektronicznej, więc zostało mi czasu do końca tygodnia aby rozwiązać problem.

POMOCY !

Krzysztof

0

301 oznacza dokładnie to co pisze - dokument w trakcie przetwarzania i nic nie trzeba robić. Dosłownie oznacza to, że urzędowi informatycy kręcą korbą ażeby to wszystko zaczęło szybciej działać. Infolinia podaje, że "przetwarzanie" może trwać do 24h (to oficjalna wersja), nieoficjalnie wiem, że może dłużej :p

Jak już przetworzą to albo dostaniesz 200, jeśli wszystko OK albo inny z informacją o błędzie

0

Dziękuje za odpowiedź.
Czyli chcąc uzyskać w późniejszym czasie potwierdzenie UPO lub potwierdzający kod "200", muszę wysłać numer referencyjny, który otrzymałem zaraz po wysłaniu deklaracji.

Czyli mam skorzystać w takim razie z :

  1. RequestUPO
  2. RequestUPOResponse

czy to jest poprawny zapis ? (w uproszczeniu)

procedure TForm2.Button3Click(Sender: TObject);
var
  WebAPI  : GateServicePortType;  

  part1   : requestUPO;     

  resp1   : requestUPOResponse; 

begin

WebAPI := GetGateServicePortType(true,'',HTTPRIO1); 

  part1 := requestUPO.Create;
  resp1 := requestUPOResponse.Create;

try
    part1.   {NIE WIEM CO TUTAJ ?}   := ArrDok;              
    resp1 := WebAPI.requestUPO(part1);  

finally
    AdvMemo2.Lines.Add(IntToStr(resp1.status));
    AdvMemo2.Lines.Add(resp1.StatusOpis);

end;
end;

Krzysztof

0

Tak wygląda sprawdzanie UPO u mnie.

var
  ubd: GateServicePortType;
  pytanie: requestUPO;
  odpowiedz: requestUPOResponse;
begin
  try
    ubd := GetGateServicePortType(False);
    pytanie := requestUPO.Create;
    try
      pytanie.refId := tu_nr_referencyjny_ktory_dostales_po_wyslaniu_deklaracji;
      pytanie.language := pl2;
      odpowiedz := ubd.requestUPO(pytanie);
      if odpowiedz.Status = 200 then
      begin
        dlgSave1.FileName := 'UPO  ' + tu_nr_referencyjny_ktory_dostales_po_wyslaniu_deklaracji + '.xml';
        if (MessageBox(Handle, PChar(odpowiedz.StatusOpis + #13#10 + 'Czy zapisać UPO (Urzędowe Potwierdzenie Odbioru) na dysku?'), PChar(Factory.ProgramFullName), MB_ICONQUESTION + MB_YESNO) = mrYes) and dlgSave1.Execute then
        begin
          fs := TFileStream.Create(ChangeFileExt(dlgSave1.FileName, '.xml'), fmCreate or fmOpenWrite);
          try
            fs.WriteBuffer(odpowiedz.Upo[1], Length(odpowiedz.Upo));
          finally
            fs.Free;
          end;         
        end;
      end
      else
        ShowMessage(odpowiedz.StatusOpis);
    finally
      pytanie.Free;
      odpowiedz.Free;
    end;
  except
    ShowMessage('Błąd podczas pobierania UPO. Spróbuj ponownie.');
  end;
end;

GetGateServicePortType, requestUPO to jest z WSDLa, który się automatycznie wygenerował.

Postaraj się też po pierwsze formatować swój kod a po drugie używać znaczników do jego kolorowania.

0

Wzorując się na @Decho napisałem poniższą procedurę i próbuję
wysłać PIT-11 na testowe e-Deklaracje.

procedure TGlowna.btWyslijClick(Sender: TObject);
var
  WebAPI:GateServicePortType;               
  pyt:sendDocument;   
  odp:sendDocumentResponse; 
  xmlDoku:TXMLDocument;                 // Dokument XML - deklaracja np.pit-11
  s64:string;                           
  fnDok:string;                         //  scieżka do pliku z deklaracją
  i:Integer;
  ArrDok:TByteDynArray;
begin
  Memo1.Clear;
  fnDok:=ExtractFilePath(Application.ExeName)+'DEKLARACJE/p11.XML.XAdES'; 

  xmlDoku:= TXMLDocument.Create(Application);       // kontrolka do deklaracji
  xmlDoku.LoadFromFile(fnDok);                     
  s64:=xmlDoku.XML.Text;                            // zrzuca do string

  SetLength(ArrDok,length(s64));        // Przepisuje do tablicy bajtów
  for i:=1 to length(s64) do arrdok[i-1]:=ord(s64[i]);

  WebAPI:= GetGateServicePortType(true,'',HTTPRIO1);     // Ustawiam połączenia 
  pyt:= sendDocument.Create;
  odp:= sendDocumentResponse.Create;
  try
    pyt.document:= ArrDok;                        
    odp:= WebAPI.sendDocument(pyt);       // wysłanie deklaracji
  finally
    Memo1.Lines.Add(IntToStr(odp.status));
    Memo1.Lines.Add(odp.StatusOpis);
    Memo1.Lines.Add(odp.refId);
    ident:=odp.refId;
  end;
end;

Niezmiennie dostaję odpowiedź "403 - dokument z niepoprawnym podpisem".
Wysłałem zapytanie do pomocy technicznej. Dostałem odpowiedź:

Centrum Kompetencyjne Usług Elektronicznych uprzejmie informuje, że zgłoszony problem z nieprawidłową zawartością podpisanego XAdES dokumentu (szczegóły poniżej) wskazują na błędne działanie oprogramowania kodującego i wysyłającego dane do bramki testowej UBD.

Przed wysłaniem prosimy o sprawdzenie (weryfikacja) podpisanego pliku w aplikacji do podpisu otrzymanej z centrum certyfikacji.

Szczegóły błędu weryfikacji:

Wystąpił błąd podczas weryfikacji - błąd podpisu XAdES. Walidacja (reference) nie udała się (sygnatura: ID-fb3e9215-bdfc-421f-a382-5a7e5098e79d; referencja: ID-5ed66dcc-80e9-4f49-8f1d-adddb54fd428) - prawdopodobnie dane zostały zmienione.

Pozdrawiamy

Oczywiście plik jest w porządku.
Podpisuję i weryfikuję podpis Szafir-em - jest OK.
Wysyłam ten sam plik innym programem (PPUS) - też jest OK.
Męczę się z tym już kilku miesięcy.
Czy ktoś mógłby mi coś podpowiedzieć ?
Może przy "WSDL-importer" trzeba coś dodatkowo ustawić ?
Może w HTTPRIO coś brakuje (gdy próbuję ustawić "service"
daje mi komunikat "interface not supported") ?
Jeżeli próbuję na na innych usługach, ale bez SSL, - jest OK.
Używam Delphi 2007. Może powinienem przejść na coś nowszego ?
Bardzo proszę o pomoc.

1

działa na produkcyjnej bramce

var
  gsp: GateServicePortType;
  pytanie: sendDocument;
  odp: sendDocumentResponse;
  fs: TFileStream;
  ba: TByteDynArray;
begin
  pytanie := sendDocument.Create;
    try
      fs := TFileStream.Create(dlgOpen1.FileName, fmOpenRead);
      try
        SetLength(ba, fs.Size);
        fs.Seek(0, soFromBeginning);
        fs.Read(ba[0], fs.Size);
      finally
        fs.Free;
      end;
      pytanie.document := ba;

      gsp := GetGateServicePortType();
      odp := gsp.sendDocument(pytanie);

      ShowMessage(odp.statusOpis);

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