OBS/Makros und Scripting/Anwendungsbereiche/ZUGFERD: Unterschied zwischen den Versionen

Aus OBS Wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „From convenience stores to workplace supply facilities, the 5 Hour energy shot is in style. Beneath the changes, Monster mentioned sales; product, advertising…“)
 
(Die Seite wurde neu angelegt: „{{Makros und Scripting}} Hier finden Sie eine Übersicht zu Makros und Funktionen die für die Artikelpflege gedacht sind. =ZUGFERD= Es gibt die Möglichkeit d…“)
Zeile 1: Zeile 1:
From convenience stores to workplace supply facilities, the 5 Hour energy shot is in styleBeneath the changes, Monster mentioned sales; product, advertising and customer [http://monsterlegendshackx.beep.com/monster-legends-hack-secrets-2016-09-05.htm comida monster legends] service; expertise; finance; and human assets will probably be consolidated across the complete firm, as opposed to break up between North American and [http://search.un.org/search?ie=utf8&site=un_org&output=xml_no_dtd&client=UN_Website_en&num=10&lr=lang_en&proxystylesheet=UN_Website_en&oe=utf8&q=worldwide&Submit=Go worldwide] executives previously taken.<br><br>Loch Ness in Scotland is known primarily as the abode of the famous Nessie, a legendary monster that is the descendant of the dinosaurs, which, in accordance [http://monster-legends-hack-tips.inube.com/blog/5253697/monster-legends-cheats-that-s-the-way-they-do-it/ free monster legends] with the legend, lives within the depths of the lake and typically appears on the surface.<br><br>But, I bet that if you happen to researched the origins of the concept of an amphibious, lagoon-dwelling, reptilian-looking monster you'll find that there is a lot of folklore around the world that's related - every little thing from Mermaids to David Icke's Reptilians.<br><br>Thus, since Trump has change into to many the essence of a [https://kidblog.org/class/monster-legends-cheats-test/posts/akvhqjaq8syi1ttkg3plbcrc2 monster high ps2 game] who threatens to not only destroy the Republican occasion, however the nation as a whole, I thought it becoming to see how Trump might evaluate to other monsters by conventional myth and legend.<br><br>There are already a whole lot of tutorials and textbooks on the market that train Javascript programming by explaining what a variable is, what variable scope is, what the syntax of an if assertion looks like, how every of the operators work, and so forth. If you would like that, there are various choices accessible, a lot of which are excellent dietary supplements to Code Monster.
{{Makros und Scripting}}
Hier finden Sie eine Übersicht zu Makros und Funktionen die für die Artikelpflege gedacht sind.
=ZUGFERD=
Es gibt die Möglichkeit den Import und Export von ZUGFERD Dateien per Scripting zu ändern, falls der OBS-Standard nicht ausreichen sollte.
==Import==
Wenn es einen aktiven Eintrag in der [[OBS/Makros_und_Scripting/Allgemeines/Script_Library|Script Libary]]  mit dem Namen ''IMPORT_ZUGFERD'' gibt wird der Import über die Pax Funktion ausgeführt.   
===Felder/Strukturen===
<source lang="Delphi">
    TZugPerson = class(TObject)
        cZUG_PsNr          : String;
        cZUG_Bemerkung    : String;
        cZUG_Name          : String;
        cZUG_Zeile1        : String;
        cZUG_Zeile2        : String;
        cZUG_Zeile3        : String;
        cZUG_Ort          : String;
        cZUG_PLZ          : String;
        cZUG_Land          : String;
        cZUG_AnspName      : String;
        cZUG_AnspTel      : String;
        cZUG_AnspEMail    : String;
        aFinanzIDs        : TxFinazID;
 
        Procedure AddFinanzID(cTmp1:String; cTmp2:String);
 
----------------------------------------
 
    TZugPosition = class(TObject)
        cZUP_UID          : String;
        cZUP_PosTyp      : String;
        cZUP_PosNr        : String;
        cZUP_ArtNr        : String;
        cZUP_ArtNrLief    : String;
        cZUP_ArtNrPsNr    : String;
        cZUP_ArtTyp      : String;
        cZUP_Bez1        : String;
        cZUP_Bez2        : String;
        cZUP_WGRName      : String;
        cZUP_LiefNr      : String;
        cZUP_Einheit      : String;
        cZUP_Text        : String;
        nZUP_Menge        : Double;
        nZUP_ENetto      : Double;
        nZUP_GNetto      : Double;
        nZUP_EBrutto      : Double;
        nZUP_MwstBetrag  : Double;
        nZUP_MwstSatz    : Double;
        cZUP_MWSTTyp      : String;
        cZUP_OBS_ERLKTO  : String;
        cZUP_OBS_Einheit  : String;
        cZUP_OBS_ArtNr    : String;
        cZUP_OBS_LiefNr  : String;
        cZUP_OBS_MwstSchl : String;
        cZUP_Fehler      : String;
 
----------------------------------------
 
    TZugHeaderFinanzen = class(TObject)
        oParent            : TZugFerd;
        cZUG_Waehrung      : String;
        nZUG_Netto        : Double;
        nZUG_Brutto        : Double;
        nZUG_MwstBetrag    : Double;
        nZUG_Netto1        : Double;
        nZUG_Netto2        : Double;
        nZUG_Netto3        : Double;
        nZUG_Brutto1      : Double;
        nZUG_Brutto2      : Double;
        nZUG_Brutto3      : Double;
        nZUG_MwstBetrag1  : Double;
        nZUG_MwstBetrag2  : Double;
        nZUG_MwstBetrag3  : Double;
        nZUG_MwstSatz1    : Double;
        nZUG_MwstSatz2    : Double;
        nZUG_MwstSatz3    : Double;
        cZUG_MwstSchl1    : String;
        cZUG_MwstSchl2    : String;
        cZUG_MwstSchl3    : String;
        cZUG_Zahlbed      : String;
        dZUG_FDatum        : TDateTime;
 
----------------------------------------
 
    TxZugPosition = Class(TObjectList<TZugPosition>);
 
    TZugFerd = class(TObject)
        oMyDB            : TxDB;
        oPersonen        : TZugHeaderPersonen;
        oFinanzen        : TZugHeaderFinanzen;
        oLieferung      : TZugHeaderLieferung;
        oPositionen      : TxZugPosition;
        cError          : String;
        lError          : Boolean;
 
        cZUG_UID        : String;
        oZUG_XML        : TStringList;
        cZUG_PDFName    : String;
        cZUG_DMSTyp      : String;
        cZUG_MD5        : String;
        cZUG_Nr          : String;
        cZUG_PDFData    : String;
        cZUG_Schema      : String;
        cZUG_TypCode    : String;
 
        cZUG_Fehler      : String;
        cZUG_Bestaetigt  : String;
        cZUG_SB          : String;
        cZUG_SysUID      : String;
 
        dZUG_RDatum      : TDateTime;
        dZUG_SDatum      : TDateTime;
        dZUG_ADatum      : TDateTime;
 
        function  InsertToPositionen    (nPos:Integer; oPos:TZugPosition):integer;
        function  AddToPositionen        (oPos:TZugPosition):integer;
        function  nPosCnt                ():Integer;
        function  GetPosition            (nPos:Integer):TZugPosition;
        function  AddProto              (const cMessage:String):Boolean;
        function  AddFile                (const cFileName:String; const cDMSType:String):Boolean;
</source>
===Beispiel Script Import===
<source lang="Delphi">
//------------------------------------------------------------------------------
// Unit Name: IMPORT_ZUGFERD
// Author:    JB
// Date:      09-12-2021
//------------------------------------------------------------------------------
 
var oZugFerd : TZugFerd;
    oCW      : TfrmCW;
 
//------------------------------------------------------------------------------
//  Procedure: PersonHeader_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------
 
function PersonHeader_Import_XML(oZugPersHeader:TZugPerson; cTradePartyXML:String):Boolean;
var nPos  : Integer;
    nStart : integer;
    cTemp1 : String;
    cTemp2 : String;
    cTemp3 : String;
begin
    CWPrintn(oCW, 'Importiere Header');
    GetXMLToken(cTradePartyXML,'ram:Name', oZugPersHeader.cZUG_Name);
 
    if (GetXMLToken(cTradePartyXML,'ram:PostalTradeAddress',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:LineOne'    , oZugPersHeader.cZUG_Zeile1);
        GetXMLToken(cTemp1,'ram:CityName'    , oZugPersHeader.cZUG_Ort);
        GetXMLToken(cTemp1,'ram:PostcodeCode', oZugPersHeader.cZUG_PLZ);
        GetXMLToken(cTemp1,'ram:CountryID'  , oZugPersHeader.cZUG_Land);
    end;
   
    CWPrintn(oCW, 'Importiere Tax');
 
    nPos := 1;
    while (GetXMLToken(cTradePartyXML,'ram:SpecifiedTaxRegistration', nPos, cTemp1, False)) do begin
        nStart := 1;
        GetXMLTokenValue(cTemp1,'ram:ID', nStart, cTemp2, cTemp3); // value, key
        oZugPersHeader.AddFinanzID(cTemp3, cTemp2);
    end;
end;
 
//------------------------------------------------------------------------------
//  Procedure: Personen_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------
 
function Personen_Import_XML(cXMLTradeAgreement:String):Boolean;
var cTemp1 : String;
begin
    CWPrintn(oCW, 'Importiere Auftragsnummer Kunde');
 
    GetXMLToken(cXMLTradeAgreement,'ram:BuyerReference',oZugFerd.oPersonen.cAufNrKu);
 
    if (GetXMLToken(cXMLTradeAgreement,'ram:BuyerTradeParty',cTemp1)) then begin
        PersonHeader_Import_XML(oZugFerd.oPersonen.oZUG_Buyer, cTemp1);
    end;
 
    if (GetXMLToken(cXMLTradeAgreement,'ram:SellerTradeParty',cTemp1)) then begin
        PersonHeader_Import_XML(oZugFerd.oPersonen.oZUG_Seller,cTemp1);
    end;
end;
 
//------------------------------------------------------------------------------
//  Procedure: Lieferung_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------
 
function Lieferung_Import_XML(cXML:String):Boolean;
begin
    //Wenn Benötigt
    CWPrintn(oCW, 'Importiere Lieferung');
end;
 
//------------------------------------------------------------------------------
//  Procedure: Positionen_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------
 
function Positionen_Import_XML(oPos:TZugPosition; cXMLTradeLineItem:String):Boolean;
var cTemp1    : String;
    cTemp2    : String;
    cValue    : String;
    nPos      : integer;
begin
 
    nPos := 1;
   
    CWPrintn(oCW, 'Importiere Positionen');
 
    if (GetXMLToken(cXMLTradeLineItem,'ram:AssociatedDocumentLineDocument',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:LineID',oPos.cZUP_PosNr);
    end;
 
    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedTradeProduct',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:Name'            , oPos.cZUP_Bez1 );
        GetXMLToken(cTemp1,'ram:SellerAssignedID' , oPos.cZUP_ArtNrLief);
        GetXMLTokenValue(cTemp1, 'ram:GlobalID'  , nPos, oPos.cZUP_ArtNr, oPos.cZUP_ArtTyp);
        GetXMLToken(cTemp1,'ram:Description'      , oPos.cZUP_Text);
 
        //Warengruppe
 
        if GetXMLToken(cTemp1,'ram:DesignatedProductClassification', cTemp2) then begin
            //nPos := 1;
            GetXMLToken(cTemp2,'ram:ClassName', oPos.cZUP_WGRName);
        end;
    end;
 
    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedLineTradeAgreement',cTemp1)) then begin
        if (GetXMLToken(cTemp1,'ram:GrossPriceProductTradePrice',cTemp2)) then begin
            GetXMLToken(cTemp2,'ram:ChargeAmount', cValue);
            oPos.nZUP_EBrutto := fVAl(cValue);
        end;
        if (GetXMLToken(cTemp1,'ram:NetPriceProductTradePrice',cTemp2)) then begin
            GetXMLToken(cTemp2,'ram:ChargeAmount', cValue);
            oPos.nZUP_ENetto := fVAl(cValue);
        end;
    end;
 
    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedLineTradeDelivery', cTemp1)) then begin
        GetXMLTokenValue(cTemp1,'ram:BilledQuantity', nPos, cValue, oPos.cZUP_Einheit);
        oPos.nZUP_Menge := fVAl(cValue);
    end;
 
    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedLineTradeSettlement',cTemp1)) then begin
        if (GetXMLToken(cTemp1,'ram:ApplicableTradeTax',cTemp2)) then begin
            GetXMLToken(cTemp2,'ram:RateApplicablePercent', cValue);
            oPos.nZUP_MwstSatz := fVAl(cValue);
            GetXMLToken(cTemp2,'ram:TypeCode', oPos.cZUP_MWSTTyp );
        end;
 
        GetXMLToken(cTemp1,'ram:LineTotalAmount', cValue);
        oPos.nZUP_GNetto := fVAl(cValue);
    end;
 
    if (oPos.nZUP_ENetto > 0) and (oPos.nZUP_MwstSatz > 0) then begin
        oPos.nZUP_MwstBetrag := oPos.nZUP_ENetto * (oPos.nZUP_MwstSatz / 100);
    end;
 
    oPos.cZUP_Fehler      := '';
end;
 
//------------------------------------------------------------------------------
//  Procedure: Finanzen_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------
 
function Finanzen_Import_XML(oFinanzen:TZugHeaderFinanzen; cXMLTradeSettlement:String):Boolean;
var cTemp1    : String;
    cTemp2    : String;
    cTemp3    : String;
    cTemp4    : String;
    nPos      : Integer;
    oPos      : TZugPosition;
    oPosTmp    : TZugPosition;
    cIndikator : String;
    lIndikator : Boolean;
    cText      : String;
    nPosNr    : Integer;
    cPosNr    : String;
    i          : integer;
begin
 
    CWPrintn(oCW, 'Importiere Finanzen');
 
    lIndikator := false;
   
    if (GetXMLToken(cXMLTradeSettlement,'ram:InvoiceCurrencyCode',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:InvoiceCurrencyCode', oFinanzen.cZUG_Waehrung);
    end;
 
    if (GetXMLToken(cXMLTradeSettlement,'ram:SpecifiedTradeSettlementPaymentMeans',cTemp1)) then begin
   
        oPos            := TZugPosition.Create();
        oPos.cZUP_UID    :=  TZugFerd(oFinanzen.oParent).cZUG_UID;
        oPos.cZUP_PosTyp := ZUG_POSTYP_MEMO;
       
        if (GetXMLToken(cTemp1,'ram:PayeePartyCreditorFinancialAccount',cTemp2)) then begin
            if (GetXMLToken(cTemp2,'ram:IBANID',cTemp3)) then begin
                cText := 'Betrag zu überweisen an:' + CRLF + 'IBAN ' + cTemp3;
            end;
        end;
 
        oPos.cZUP_Text := cText;
        //TObjectList(TZugFerd(oFinanzen.oParent).oPositionen).Insert(0, oPos);
        TZugFerd(oFinanzen.oParent).InsertToPositionen(0, oPos);
    end;
 
    if (GetXMLToken(cXMLTradeSettlement,'ram:SpecifiedTradeSettlementHeaderMonetarySummation',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:TaxBasisTotalAmount', cTemp2);
        oZugFerd.oFinanzen.nZUG_Netto := fVal(cTemp2);
        GetXMLToken(cTemp1,'ram:TaxTotalAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag := fVal(cTemp2);
        GetXMLToken(cTemp1,'ram:GrandTotalAmount', cTemp2);
        oFinanzen.nZUG_Brutto := fVal(cTemp2);
    end;
 
    if (GetXMLToken(cXMLTradeSettlement,'ram:SpecifiedTradePaymentTerms',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:Description', oFinanzen.cZUG_Zahlbed);
        if (GetXMLToken(cTemp1,'ram:DueDateDateTime',cTemp2, False)) then begin
            GetXMLTokenValue(cTemp2,'udt:DateTimeString', nPos,cTemp4, cTemp3);
            oFinanzen.dZUG_FDatum := SToD(cTemp4);
        end;
    end;
 
    nPos := 1;
    if (GetXMLToken(cXMLTradeSettlement,'ram:ApplicableTradeTax', nPos, cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:CalculatedAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag1 := fVal(cTemp2);
 
        GetXMLToken(cTemp1,'ram:BasisAmount', cTemp2);
        oFinanzen.nZUG_Netto1  := fVal(cTemp2);
        oFinanzen.nZUG_Brutto1 := oFinanzen.nZUG_Netto1 + oFinanzen.nZUG_MwstBetrag1;
 
        GetXMLToken(cTemp1,'ram:RateApplicablePercent', cTemp2);
        oFinanzen.nZUG_MwstSatz1 := fVal(cTemp2);
    end;
 
    if (GetXMLToken(cXMLTradeSettlement,'ram:ApplicableTradeTax', nPos, cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:CalculatedAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag2 := fVal(cTemp2);
 
        GetXMLToken(cTemp1,'ram:BasisAmount', cTemp2);
        oFinanzen.nZUG_Netto2  := fVal(cTemp2);
        oFinanzen.nZUG_Brutto2 := oFinanzen.nZUG_Netto2 + oFinanzen.nZUG_MwstBetrag2;
 
        GetXMLToken(cTemp1,'ram:RateApplicablePercent', cTemp2);
        oFinanzen.nZUG_MwstSatz2 := fVal(cTemp2);
    end;
 
    if (GetXMLToken(cXMLTradeSettlement,'ram:ApplicableTradeTax', nPos, cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:CalculatedAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag3 := fVal(cTemp2);
 
        GetXMLToken(cTemp1,'ram:BasisAmount', cTemp2);
        oFinanzen.nZUG_Netto3  := fVal(cTemp2);
        oFinanzen.nZUG_Brutto3 := oFinanzen.nZUG_Netto3 + oFinanzen.nZUG_MwstBetrag3;
 
        GetXMLToken(cTemp1,'ram:RateApplicablePercent', cTemp2);
        oFinanzen.nZUG_MwstSatz3 := fVal(cTemp2);
    end;
 
    if (oFinanzen.nZUG_MWSTBetrag = 0) then begin
        oFinanzen.nZUG_MWSTBetrag := oFinanzen.nZUG_MwstBetrag1 + oFinanzen.nZUG_MwstBetrag2 + oFinanzen.nZUG_MwstBetrag3;
    end;
 
    CWPrintn(oCW, 'Importiere Rabatte und Zusatzkosten');
 
    // Rabatte und Zusatzkosten als Positionen erfassen
    nPos := 1;
    while (GetXMLToken(cXMLTradeSettlement, 'ram:SpecifiedTradeAllowanceCharge', nPos, cTemp1)) do begin
 
        // Höchste Positionsnummer ermitteln, damit Zusatzkosten mit
        // aufsteigender Pos-Nr erfasst werden können
        nPosNr := 0;
       
        //for i:=0 to TObjectList(TZugFerd(oFinanzen.oParent).oPositionen).Count do begin
        for i:=0 to TZugFerd(oFinanzen.oParent).nPosCnt()-1 do begin
          oPosTmp := TZugFerd(oFinanzen.oParent).GetPosition(i);
          cPosNr  := oPosTmp.cZUP_PosNr;     
          nPosNr  := Max(nPosNr, iVal(cPosNr));
          CWPrintn(oCW, 'MaxNr ' + cPosNr);
        end;
       
        oPos := TZugPosition.Create( TZugFerd(oFinanzen.oParent).cZUG_UID);
        oPos            := TZugPosition.Create();
        oPos.cZUP_UID    := TZugFerd(oFinanzen.oParent).cZUG_UID;       
        oPos.cZUP_PosNr  := TStr(nPosNr + 1, 0, 0);
        cText := '';
 
        if (GetXMLToken(cTemp1,'ram:ChargeIndicator',cTemp2)) then begin
            GetXMLToken(cTemp1,'udt:Indicator', cIndikator);
            lIndikator := lower(cIndikator) = 'true';
            if (lIndikator) then begin
                cText := cText + 'Zusatzkosten' + CRLF;
            end else begin
                cText := cText + 'Rabatt' + CRLF;
            end;
        end;
 
        GetXMLToken(cTemp1,'ram:Reason',oPos.cZUP_Bez1);
 
        if (GetXMLToken(cTemp1,'ram:BasisAmount',cTemp2)) then begin
            cText := cText + 'Grundlage: ' + cTemp2;
        end;
 
        if (GetXMLToken(cTemp1,'ram:ActualAmount',cTemp2)) then begin
            oPos.nZUP_ENetto := fVal(cTemp2);
            if (lIndikator) then begin // Rabatt
                oPos.nZUP_Menge := 1;
            end else begin
                oPos.nZUP_Menge := -1;
            end;
        end;
 
        if (GetXMLToken(cTemp1,'ram:CategoryTradeTax',cTemp2)) then begin
            if (GetXMLToken(cTemp2,'ram:RateApplicablePercent',cTemp3)) then begin
                opos.nZUP_MwstSatz := fVal(cTemp3);
            end;
        end;
 
        oPos.cZUP_Text := cText;
        oPos.nZUP_GNetto := oPos.nZUP_Menge * oPos.nZUP_ENetto;
 
        TZugFerd(oFinanzen.oParent).AddToPositionen(oPos);
        //TObjectList(TZugFerd(oFinanzen.oParent).oPositionen).Add(oPos);
    end;
end;
 
//------------------------------------------------------------------------------
//  Procedure: Startproc
//  Author:    JB
//  Date:      09-12-2021
//  Comment:  Startfunction
//------------------------------------------------------------------------------
 
function  Startproc(oOBJ:TZugFerd; cXMLData:String):Boolean;
var cTemp1  : String;
    cTemp2  : String;
    cTemp3  : String;
    nPos    : Integer;
    oPos    : TZugPosition;
    lImport  : Boolean;
begin
  Result  := False;
  oZugFerd := oOBJ;
 
    oCW := CWOpen(20, 80, 'Importiere XML Zugferddaten');
   
    try
        if (GetXMLToken(cXMLData, 'ram:GuidelineSpecifiedDocumentContextParameter', cTemp1)) then begin
            GetXMLToken(cTemp1,'ram:ID', oZugFerd.cZUG_Schema);
        end;
 
        if (GetXMLToken(cXMLData, 'rsm:ExchangedDocument', cTemp1)) then begin
   
            nPos := 1;
         
            GetXMLTokenValue(cTemp1,'udt:DateTimeString', nPos, cTemp2, cTemp3);
            oZugFerd.dZUG_RDatum := SToD(cTemp2);
 
            nPos := 1;
 
            GetXMLToken(cTemp1,'ram:ID', oZugFerd.cZUG_Nr);
            GetXMLToken(cTemp1,'ram:TypeCode', oZugFerd.cZUG_TypCode);
 
            CWPrintn(oCW, 'Importiere Positionen Freitext');
 
            while (GetXMLToken(cTemp1, 'ram:IncludedNote', nPos, cTemp2)) do begin
                oPos := TZugPosition.Create(oZugFerd.cZUG_UID);
 
                oPos.cZUP_PosTyp := ZUG_POSTYP_MEMO;
                oPos.cZUP_Bez1  := 'Freitext';
                GetXMLToken(cTemp2, 'ram:Content', oPos.cZUP_Text);
                GetXMLToken(cTemp2, 'ram:SubjectCode', oPos.cZUP_Bez2);
 
                oZugFerd.AddToPositionen(oPos);
            end;
        end;
 
        if (GetXMLToken(cXMLData, 'rsm:SupplyChainTradeTransaction', cTemp1)) then begin
 
            lImport := False;
 
            if (GetXMLToken(cTemp1, 'ram:ApplicableHeaderTradeDelivery', cTemp2)) then begin
                CWPrintn(oCW, 'Importiere Lieferung');
                Lieferung_Import_XML(cTemp2);     
                lImport := True;
            end;
 
            if (GetXMLToken(cTemp1, 'ram:ApplicableHeaderTradeAgreement', cTemp2)) then begin
                CWPrintn(oCW, 'Importiere Personen');
                Personen_Import_XML(cTemp2);
                lImport := True;
            end;
 
            if (not lImport) then begin
                oZugFerd.AddProto('Kein Token ApplicableHeaderTradeDelivery vorhanden!');
                oZugFerd.AddProto('Kein Token ApplicableHeaderTradeAgreement vorhanden!');
                Result := False;
            end;
 
            nPos := 1;
 
            while (GetXMLToken(cTemp1, 'ram:IncludedSupplyChainTradeLineItem', nPos, cTemp2)) do begin
                oPos := TZugPosition.Create(oZugFerd.cZUG_UID);
                Positionen_Import_XML(oPos, cTemp2);
           
                oZugFerd.AddToPositionen(oPos);
            end;
 
            // Beträge nach den Positionen, damit Rabatte und Zusatzkosten als Positionen am Ende erfasst werden
            if (GetXMLToken(cTemp1, 'ram:ApplicableHeaderTradeSettlement', cTemp2)) then begin
                Finanzen_Import_XML(oZugFerd.oFinanzen, cTemp2);
            end;
 
            Result := True;
        end;
    finally
        CWClose(oCW);
    end;
end;
 
//------------------------------------------------------------------------------
 
</source>
==Export==
Wenn es einen aktiven Eintrag in der [[OBS/Makros_und_Scripting/Allgemeines/Script_Library|Script Libary]] mit dem Namen ''EXPORT_ZUGFERD'' gibt wird die Erstellung der XML-Datei über die Pax Funktion ausgeführt.
===Beispiel Script Export===
<source lang="Delphi">
//------------------------------------------------------------------------------
// Unit Name: EXPORT_ZUGFERD
// Author:    JB
// Date:      09-12-2021
//------------------------------------------------------------------------------
 
var oXML        : TXMLWriter;
    cRechnungsNr : String;
    qRech        : TxFQuery;
    qKonst      : TxFQuery;
    qStamm      : TxFQuery;
    qPerson      : TxFQuery;
    dLiefDat    : TDateTime;
    nMWST        : Double;
    nMwstTotal  : Double;
    oFormat      : TFormatSettings;
       
//------------------------------------------------------------------------------
//  Procedure: _Format
//  Author:    JB
//  Date:      09-12-2021
//  Comment:  Zahlenausgabe für XML
//------------------------------------------------------------------------------   
   
function _Format(nVal : Double): String;
begin
    Result := ZugFerd_FormatDouble(nVal);
end;
 
//------------------------------------------------------------------------------
//  Procedure: OBSRechnungsart_To_ZUGInvoiceTypeCode(
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   
//------------------------------------------------------------------------------
 
function OBSRechnungsart_To_ZUGInvoiceTypeCode(const cOBSRechArt : String): String;
begin
    Result := '';
    if          (cOBSRechArt = '1') then begin // Standardrechnung
        Result := ZUG_RECHTYP_COMMERCIAL;
    end else if (cOBSRechArt = '2') then begin // Abschlagsrechnung
        Result := ZUG_RECHTYP_ABSCHLAG;
    end else if (cOBSRechArt = '3') then begin // Schlussrechnung
        Result := ZUG_RECHTYP_COMMERCIAL;
    end else if (cOBSRechArt = '4') then begin // Proformarechnung
        Result := ZUG_RECHTYP_PROFORMA;
    end else if (cOBSRechArt = '5') then begin // Gutschrift
        Result := ZUG_RECHTYP_GUTSCHRIFT;
    end else if (cOBSRechArt = '6') then begin // Stornorechnung
        Result := ZUG_RECHTYP_GUTSCHRIFT;
    end else if (cOBSRechArt = '7') then begin // Anzahlungsrechnung
        Result := ZUG_RECHTYP_PARTIAL;
    end;
end;
 
//------------------------------------------------------------------------------
//  Procedure: OBSMwstSchl_To_ZUGCategoryCode((
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   
//------------------------------------------------------------------------------
 
function  OBSMwstSchl_To_ZUGCategoryCode(const cOBSMWST : String): String;
var nMwst : Integer;
begin
    nMWST := iVal(cOBSMWST);
 
    if (nMWST < 10) then begin
        Result := ZUG_MWSTTYP_STANDARD;
    end;
end;
 
//------------------------------------------------------------------------------
//  Procedure: GetVersandTyp(
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   
//------------------------------------------------------------------------------
 
function GetVersandTyp(oMyDB: TxDB; cPerson: String): Integer;
begin
    Result := iVal(DB_ReadSQLValue(oMyDB,'ZUGFERD_PERSONEN','zp_versand','zp_psnr = '+DB_SQLVal(cPerson)));
end;
 
//------------------------------------------------------------------------------
//  Procedure: ZugFerd_Positionen
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   
//------------------------------------------------------------------------------
 
procedure ZugFerd_Positionen(var oXML : TXMLWriter);
var cSQL : String;
    qPos : TxFQuery;
begin
 
    cSQL := 'SELECT * FROM RECHPOS'+
            ' LEFT JOIN s_mwst ON az_mwstsch = mw_nr' +
            ' WHERE az_nr = ' + DB_SQLVal(cRechnungsNr) +
            ' AND az_typ = 0';
 
    if (DB_SOpen(oDB, cSQL, qPos)) then begin
 
        dLiefDat := CToD(DB_ReadSQLValue(oDB,'LIEFSTA LEFT JOIN LIEFPOS ON a_nr = az_nr','a_datum','az_aufnr = '+DB_SQLVal(qPos.A2C('az_aufnr'))));
        if (empty(dLiefDat)) then begin
            dLiefDat := qRech.A2D('a_facdatum');
            if (empty(dLiefdat)) then begin
                dLiefDat := qRech.A2D('a_datum');
            end;
        end;
 
        while not qPos.eof do begin
            with oXML do begin
                OpenElement('ram:IncludedSupplyChainTradeLineItem');
                    OpenElement('ram:AssociatedDocumentLineDocument');
                        AddElement('ram:LineID', qPos.A2C('az_posnr')); // Positionsnummer // BR-21
                    CloseElement; // ram:AssociatedDocumentLineDocument
 
                    OpenElement('ram:SpecifiedTradeProduct');
                        AddElement('ram:SellerAssignedID', qPos.A2C('az_artnr')); //BT-155 Artikelnummer des Verkäufers
                        AddElement('ram:Name', qPos.A2C('az_bez1')); // Positionsname // BR-25
                    CloseElement; // ram:SpecifiedTradeProduct
 
                    OpenElement('ram:SpecifiedLineTradeAgreement');
                        OpenElement('ram:NetPriceProductTradePrice');
                            AddElement('ram:ChargeAmount', _Format(qPos.A2F('az_epreis'))); // Netto Einzelpreis // BR-26, BR-27
                        CloseElement; // ram:NetPriceProductTradePrice
                    CloseElement; // ram:SpecifiedLineTradeAgreement
 
                    OpenElement('ram:SpecifiedLineTradeDelivery');
                        AddAttrElement('ram:BilledQuantity', 'unitCode', 'H87', _Format(qPos.A2F('az_menge'))); // Einheit und Menge // BR-22, BR-23
                    CloseElement; // ram:SpecifiedLineTradeDelivery
 
                    OpenElement('ram:SpecifiedLineTradeSettlement');
                        OpenElement('ram:ApplicableTradeTax');
                            OpenElement('ram:TypeCode');
                                SetContent('VAT'); // Steuerart, im Standard immer VAT
                            CloseElement; // ram:TypeCode
                            OpenElement('ram:CategoryCode');
                                // Andere: (100 - 199)
                                // AE:    $13b Reverse Charge (200 - 299)
                                // K:      Innereuropäisch (400 - 499)
                                SetContent('S');
                            CloseElement; // ram:CategoryCode
                            OpenElement('ram:RateApplicablePercent');
                                SetContent(_Format(qPos.A2F('mw_satz')));
                            CloseElement; // ram:RateApplicablePercent
                        CloseElement; // ram:ApplicableTradeTax
 
                        if (qPos.A2F('az_rabatt') > 0) or (qPos.A2F('az_grabatt') > 0) then begin
                        OpenElement('ram:SpecifiedTradeAllowanceCharge');
                            OpenElement('ram:ChargeIndicator');
                                AddElement('udt:Indicator','false'); // false = Abschlag, true = Zuschlag
                            CloseElement; // ram:ChargeIndicator
 
                            if (qPos.A2F('az_rabatt') > 0) then begin
                                AddElement('ram:CalculationPercent', qPos.A2C('az_rabatt'));
                            end;
 
                            AddElement('ram:BasisAmount', _Format(qPos.A2F('az_menge')*qPos.A2F('az_epreis')));
 
                            if (qPos.A2F('az_rabatt') > 0) then begin // BR-41
                                AddElement('ram:ActualAmount', _Format(qPos.A2F('az_menge')*qPos.A2F('az_epreis')*(qPos.A2F('az_rabatt')/100)));
                            end else if (qPos.A2F('az_grabatt') > 0) then begin
                                AddElement('ram:ActualAmount', _Format(qPos.A2F('az_grabatt')));
                            end;
                            AddElement('ram:ReasonCode', '95');
                            AddElement('ram:Reason', 'Discount'); // BR-42
                        CloseElement; // ram:SpecifiedTradeAllowanceCharge
                        end;
 
                        OpenElement('ram:SpecifiedTradeSettlementLineMonetarySummation');
                            AddElement('ram:LineTotalAmount', _Format(qPos.A2F('az_gpreis'))); // Netto Gesampreis // BR-24
                        CloseElement; // ram:SpecifiedTradeSettlementLineMonetarySummation
                    CloseElement; // ram:SpecifiedLineTradeSettlement
                CloseElement; // ram:IncludedSupplyChainTradeLineItem
            end;
            qPos.next();
        end;
    end;
    DB_Close(qPos);
end;
 
//------------------------------------------------------------------------------
//  Procedure: StartProc
//  Author:    JB
//  Date:      09-12-2021
//  Comment:  Start Procwedure
//------------------------------------------------------------------------------
 
function StartProc(xoXML        : TXMLWriter;
                  xcRechnungsNr : String;
                  xqRech        : TxFQuery;
                  xqKonst      : TxFQuery;
                  xqStamm      : TxFQuery;
                  xqPerson    : TxFQuery):Boolean;
begin
    Result        := True;
    oXML          := xoXML;               
    cRechnungsNr  := xcRechnungsNr;
    qRech        := xqRech;     
    qKonst        := xqKonst;     
    qStamm        := xqStamm;     
    qPerson      := xqPerson;   
 
    oFormat.DecimalSeparator := '.';
    oFormat.CurrencyDecimals := 2;
   
    oXML.OpenElement('rsm:CrossIndustryInvoice');
        oXML.SetAttribute('xmlns:a',   'urn:un:unece:uncefact:data:standard:QualifiedDataType:100');
        oXML.SetAttribute('xmlns:rsm', 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100');
        oXML.SetAttribute('xmlns:qdt', 'urn:un:unece:uncefact:data:standard:QualifiedDataType:10');
        oXML.SetAttribute('xmlns:ram', 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100');
        oXML.SetAttribute('xmlns:xs',  'http://www.w3.org/2001/XMLSchema');
        oXML.SetAttribute('xmlns:udt', 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100');
        oXML.OpenElement('rsm:ExchangedDocumentContext');
            oXML.OpenElement('ram:GuidelineSpecifiedDocumentContextParameter');
                oXML.AddElement('ram:ID', ZUG_COMPLIANCE_XRECHNUNG_2_0); // BR-1
            oXML.CloseElement; // ram:GuidelineSpecifiedDocumentContextParameter
        oXML.CloseElement; // rsm:ExchangedDocumentContext
 
        oXML.OpenElement('rsm:ExchangedDocument');
            oXML.AddElement('ram:ID', qRech.A2C('a_nr')); // Rechnungsnummer  // BR-2
            oXML.AddElement('ram:TypeCode', OBSRechnungsart_To_ZUGInvoiceTypeCode(qRech.A2C('a_art'))); // Rechnungstyp // BR-4
            oXML.OpenElement('ram:IssueDateTime');
                oXML.AddAttrElement('udt:DateTimeString','format', '102', DToS(qRech.A2D('a_datum'))); // Datum // BR-3
            oXML.CloseElement; // ram:IssueDateTime
           
            //Wenn Postgut
            //oXML.OpenElement('ram:IncludedNote');
            //    oXML.AddElement('ram:Content',qRech.A2C('a_aufnrku'));
            //    oXML.AddElement('ram:SubjectCode','INV');
            //oXML.CloseElement; //ram:IncludedNote
           
        oXML.CloseElement; // rsm:ExchangedDocument
 
        oXML.OpenElement('rsm:SupplyChainTradeTransaction');
       
            ZugFerd_positionen(oXML); // ram:IncludedSupplyChainTradeLineItem
 
            oXML.OpenElement('ram:ApplicableHeaderTradeAgreement');
                oXML.AddElement('ram:BuyerReference',qPerson.A2C('zp_leitwegid')); // Leitweg-ID für XRechnung
 
                oXML.OpenElement('ram:SellerTradeParty');
                    oXML.AddElement('ram:ID', qPerson.A2C('zp_kreditorennr')); // BT-29: Kreditorennummer beim Kunden
                    oXML.AddElement('ram:Name', qKonst.A2C('k_name')); // BR-6
 
                    oXML.OpenElement('ram:DefinedTradeContact'); // BG-6, BR-DE-5, BR-DE-6, BR-DE-7
                        oXML.AddElement('ram:PersonName', qPerson.A2C('zp_apname')); // BT-41 Name
 
                        oXML.OpenElement('ram:TelephoneUniversalCommunication'); // BT-42 Telefon
                            oXML.AddElement('ram:CompleteNumber', qPerson.A2C('zp_aptel'));
                        oXML.CloseElement();  // ram:TelephoneUniversalCommunication
 
                        oXML.OpenElement('ram:EmailURIUniversalCommunication'); // BT-43 E-Mail
                            oXML.AddElement('ram:URIID', qPerson.A2C('zp_apmail'));
                        oXML.CloseElement();  // ram:EmailURIUniversalCommunication
                    oXML.CloseElement();  // ram:DefinedTradeContact
 
                    oXML.OpenElement('ram:PostalTradeAddress'); // BR-8
                        oXML.AddElement('ram:PostcodeCode', qKonst.A2C('k_plz'));
                        oXML.AddElement('ram:LineOne', qKonst.A2C('k_strasse'));
                        oXML.AddElement('ram:CityName', qKonst.A2C('k_ort'));
                        oXML.AddElement('ram:CountryID', 'DE'); // BR-9
                    oXML.CloseElement; // ram:PostalTradeAddress
 
                    oXML.OpenElement('ram:SpecifiedTaxRegistration');
                        oXML.AddAttrElement('ram:ID', 'schemeID', 'VA', qKonst.A2C('k_ustid')); //
                    oXML.CloseElement; // ram:SpecifiedTaxRegistration
                oXML.CloseElement; // ram:SellerTradeParty
 
                oXML.OpenElement('ram:BuyerTradeParty');
                    oXML.AddElement('ram:Name',qRech.A2C('a_name')); // BR-7
                    oXML.OpenElement('ram:PostalTradeAddress'); // BR-10
                        oXML.AddElement('ram:PostcodeCode', qRech.A2C('a_plz'));
                        oXML.AddElement('ram:LineOne', qRech.A2C('a_strasse'));
                        oXML.AddElement('ram:CityName', qRech.A2C('a_ort'));
                        oXML.AddElement('ram:CountryID', 'DE'); // BR-11
                    oXML.CloseElement; // ram:PostalTradeAddress
                oXML.CloseElement; // ram:BuyerTradeParty
 
                oXML.OpenElement('ram:BuyerOrderReferencedDocument');
                    oXML.AddElement('ram:IssuerAssignedID',qRech.A2C('a_aufnrku'));
                oXML.CloseElement(); //ram:BuyerOrderReferencedDocument
 
            oXML.CloseElement; // ram:ApplicableHeaderTradeAgreement
 
            oXML.OpenElement('ram:ApplicableHeaderTradeDelivery'); // Tag muss vorhanden sein
 
                if (not empty(qRech.A2C('a_vstrasse'))) then begin
                    oXML.OpenElement('ram:ShipToTradeParty'); // Abweichender Warenempfänger
                        oXML.OpenElement('ram:PostalTradeAddress'); // BR-57
                            oXML.AddElement('ram:PostcodeCode', qRech.A2C('a_vplz'));
                            oXML.AddElement('ram:LineOne', qRech.A2C('a_vstrasse'));
                            oXML.AddElement('ram:CityName', qRech.A2C('a_vort'));
                            oXML.AddElement('ram:CountryID', 'DE'); // BR-11
                        oXML.CloseElement; // ram:PostalTradeAddress
                    oXML.CloseElement;
                end;
 
                oXML.OpenElement('ram:ActualDeliverySupplyChainEvent');
                    oXML.OpenElement('ram:OccurrenceDateTime');
                        oXML.AddAttrElement('udt:DateTimeString','format', '102', DToS(dLiefDat)); // Datum // BT-72
                    oXML.CloseElement;
                oXML.CloseElement;
 
            oXML.CloseElement;
 
            oXML.OpenElement('ram:ApplicableHeaderTradeSettlement');
                oXML.AddElement('ram:InvoiceCurrencyCode', 'EUR'); // Währungscode nach ISO 4217 // BR-5
 
                // BR-49, BR-50, BR-51
                if (not empty(qStamm.A2C('zus_iban1'))) then begin
                    oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                        oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                        oXML.AddElement('ram:Information', qStamm.A2C('zus_bank1'));
                        oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                            oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban1'));
                        oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                    oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban2'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank2'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban2'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban3'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank3'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban3'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban4'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank4'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban4'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban5'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank5'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban5'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
 
                nMWSTTotal := 0;
                if (not empty(qRech.A2C('a_mwstschl1'))) then begin
                oXML.OpenElement('ram:ApplicableTradeTax');
                    nMWST := qRech.A2F('a_net1') * (qRech.A2F('a_mwst1') / 100);
                    nMWSTTotal := nMWSTTotal + nMWST;
                    oXML.AddElement('ram:CalculatedAmount',_Format(nMWST)); // BR-46
                    oXML.AddElement('ram:TypeCode', 'VAT');
                    oXML.AddElement('ram:BasisAmount', _Format(qRech.A2F('a_net1'))); // BR-45
                    oXML.AddElement('ram:CategoryCode', OBSMwstSchl_To_ZUGCategoryCode(qRech.A2C('a_art'))); // BR-47
                    oXML.AddElement('ram:RateApplicablePercent', _Format(qRech.A2F('a_mwst1'))); // BR-48
                oXML.CloseElement; // ram:ApplicableTradeTax
                end;
                if (not empty(qRech.A2C('a_mwstschl2'))) then begin
                oXML.OpenElement('ram:ApplicableTradeTax');
                    nMWST := qRech.A2F('a_net2') * (qRech.A2F('a_mwst2') / 100);
                    nMWSTTotal := nMWSTTotal + nMWST;
                    oXML.AddElement('ram:CalculatedAmount',_Format(nMWST)); // BR-46
                    oXML.AddElement('ram:TypeCode', 'VAT');
                    oXML.AddElement('ram:BasisAmount', _Format(qRech.A2F('a_net2'))); // BR-45
                    oXML.AddElement('ram:CategoryCode', OBSMwstSchl_To_ZUGCategoryCode(qRech.A2C('a_art'))); // BR-47
                    oXML.AddElement('ram:RateApplicablePercent', _Format(qRech.A2F('a_mwst2'))); // BR-48
                oXML.CloseElement; // ram:ApplicableTradeTax
                end;
                if (not empty(qRech.A2C('a_mwstschl3'))) then begin
                oXML.OpenElement('ram:ApplicableTradeTax');
                    nMWST := qRech.A2F('a_net3') * (qRech.A2F('a_mwst3') / 100);
                    nMWSTTotal := nMWSTTotal + nMWST;
                    oXML.AddElement('ram:CalculatedAmount',_Format(nMWST)); // BR-46
                    oXML.AddElement('ram:TypeCode', 'VAT');
                    oXML.AddElement('ram:BasisAmount', _Format(qRech.A2F('a_net3'))); // BR-45
                    oXML.AddElement('ram:CategoryCode', OBSMwstSchl_To_ZUGCategoryCode(qRech.A2C('a_art'))); // BR-47
                    oXML.AddElement('ram:RateApplicablePercent', _Format(qRech.A2F('a_mwst3'))); // BR-48
                oXML.CloseElement; // ram:ApplicableTradeTax
                end;
 
                oXML.OpenElement('ram:SpecifiedTradePaymentTerms');
                    // Fälligkeitsdatum
                    oXML.OpenElement('ram:DueDateDateTime');
                        oXML.AddAttrElement('udt:DateTimeString','format', '102', DToS(qRech.A2D('a_faellig'))); // Datum // BT-9, BR-CO-25
                    oXML.CloseElement; // ram:DueDateDateTime
                oXML.CloseElement; // ram:SpecifiedTradePaymentTerms
 
                oXML.OpenElement('ram:SpecifiedTradeSettlementHeaderMonetarySummation');
                    oXML.AddElement('ram:LineTotalAmount', _Format(qRech.A2F('a_nbetrag'))); // BR-12
                    oXML.AddElement('ram:TaxBasisTotalAmount', _Format(qRech.A2F('a_nbetrag'))); // BR-13
                    oXML.AddAttrElement('ram:TaxTotalAmount','currencyID','EUR',_Format(nMWSTTotal)); // BR-53
                    oXML.AddElement('ram:GrandTotalAmount', _Format(qRech.A2F('a_bbetrag'))); // BR-14
                    oXML.AddElement('ram:DuePayableAmount', _Format(qRech.A2F('a_bbetrag'))); // BR-15
                oXML.CloseElement(); // ram:SpecifiedTradeSettlementHeaderMonetarySummation
 
            oXML.CloseElement; // ram:ApplicableHeaderTradeSettlement
 
        oXML.CloseElement; // rsm:SupplyChainTradeTransaction
 
    oXML.CloseElement; // rsm:CrossIndustryInvoice
   
end;                 
</source>

Version vom 10. Dezember 2021, 15:43 Uhr


Hier finden Sie eine Übersicht zu Makros und Funktionen die für die Artikelpflege gedacht sind.

ZUGFERD

Es gibt die Möglichkeit den Import und Export von ZUGFERD Dateien per Scripting zu ändern, falls der OBS-Standard nicht ausreichen sollte.

Import

Wenn es einen aktiven Eintrag in der Script Libary mit dem Namen IMPORT_ZUGFERD gibt wird der Import über die Pax Funktion ausgeführt.

Felder/Strukturen

    TZugPerson = class(TObject)
        cZUG_PsNr          : String;
        cZUG_Bemerkung     : String;
        cZUG_Name          : String;
        cZUG_Zeile1        : String;
        cZUG_Zeile2        : String;
        cZUG_Zeile3        : String;
        cZUG_Ort           : String;
        cZUG_PLZ           : String;
        cZUG_Land          : String;
        cZUG_AnspName      : String;
        cZUG_AnspTel       : String;
        cZUG_AnspEMail     : String;
        aFinanzIDs         : TxFinazID;

        Procedure AddFinanzID(cTmp1:String; cTmp2:String);

----------------------------------------

    TZugPosition = class(TObject)
        cZUP_UID          : String;
        cZUP_PosTyp       : String;
        cZUP_PosNr        : String;
        cZUP_ArtNr        : String;
        cZUP_ArtNrLief    : String;
        cZUP_ArtNrPsNr    : String;
        cZUP_ArtTyp       : String;
        cZUP_Bez1         : String;
        cZUP_Bez2         : String;
        cZUP_WGRName      : String;
        cZUP_LiefNr       : String;
        cZUP_Einheit      : String;
        cZUP_Text         : String;
        nZUP_Menge        : Double;
        nZUP_ENetto       : Double;
        nZUP_GNetto       : Double;
        nZUP_EBrutto      : Double;
        nZUP_MwstBetrag   : Double;
        nZUP_MwstSatz     : Double;
        cZUP_MWSTTyp      : String;
        cZUP_OBS_ERLKTO   : String;
        cZUP_OBS_Einheit  : String;
        cZUP_OBS_ArtNr    : String;
        cZUP_OBS_LiefNr   : String;
        cZUP_OBS_MwstSchl : String;
        cZUP_Fehler       : String;

----------------------------------------

    TZugHeaderFinanzen = class(TObject)
        oParent            : TZugFerd;
        cZUG_Waehrung      : String;
        nZUG_Netto         : Double;
        nZUG_Brutto        : Double;
        nZUG_MwstBetrag    : Double;
        nZUG_Netto1        : Double;
        nZUG_Netto2        : Double;
        nZUG_Netto3        : Double;
        nZUG_Brutto1       : Double;
        nZUG_Brutto2       : Double;
        nZUG_Brutto3       : Double;
        nZUG_MwstBetrag1   : Double;
        nZUG_MwstBetrag2   : Double;
        nZUG_MwstBetrag3   : Double;
        nZUG_MwstSatz1     : Double;
        nZUG_MwstSatz2     : Double;
        nZUG_MwstSatz3     : Double;
        cZUG_MwstSchl1     : String;
        cZUG_MwstSchl2     : String;
        cZUG_MwstSchl3     : String;
        cZUG_Zahlbed       : String;
        dZUG_FDatum        : TDateTime;

----------------------------------------

    TxZugPosition = Class(TObjectList<TZugPosition>);

    TZugFerd = class(TObject)
        oMyDB            : TxDB;
        oPersonen        : TZugHeaderPersonen;
        oFinanzen        : TZugHeaderFinanzen;
        oLieferung       : TZugHeaderLieferung;
        oPositionen      : TxZugPosition;
        cError           : String;
        lError           : Boolean;

        cZUG_UID         : String;
        oZUG_XML         : TStringList;
        cZUG_PDFName     : String;
        cZUG_DMSTyp      : String;
        cZUG_MD5         : String;
        cZUG_Nr          : String;
        cZUG_PDFData     : String;
        cZUG_Schema      : String;
        cZUG_TypCode     : String;

        cZUG_Fehler      : String;
        cZUG_Bestaetigt  : String;
        cZUG_SB          : String;
        cZUG_SysUID      : String;

        dZUG_RDatum      : TDateTime;
        dZUG_SDatum      : TDateTime;
        dZUG_ADatum      : TDateTime;

        function  InsertToPositionen     (nPos:Integer; oPos:TZugPosition):integer;
        function  AddToPositionen        (oPos:TZugPosition):integer;
        function  nPosCnt                ():Integer;
        function  GetPosition            (nPos:Integer):TZugPosition;
        function  AddProto               (const cMessage:String):Boolean;
        function  AddFile                (const cFileName:String; const cDMSType:String):Boolean;

Beispiel Script Import

//------------------------------------------------------------------------------
// Unit Name: IMPORT_ZUGFERD
// Author:    JB
// Date:      09-12-2021
//------------------------------------------------------------------------------

var oZugFerd : TZugFerd;
    oCW      : TfrmCW;

//------------------------------------------------------------------------------
//  Procedure: PersonHeader_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------

function PersonHeader_Import_XML(oZugPersHeader:TZugPerson; cTradePartyXML:String):Boolean;
var nPos   : Integer;
    nStart : integer;
    cTemp1 : String;
    cTemp2 : String;
    cTemp3 : String;
begin
    CWPrintn(oCW, 'Importiere Header');
    GetXMLToken(cTradePartyXML,'ram:Name', oZugPersHeader.cZUG_Name);

    if (GetXMLToken(cTradePartyXML,'ram:PostalTradeAddress',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:LineOne'     , oZugPersHeader.cZUG_Zeile1);
        GetXMLToken(cTemp1,'ram:CityName'    , oZugPersHeader.cZUG_Ort);
        GetXMLToken(cTemp1,'ram:PostcodeCode', oZugPersHeader.cZUG_PLZ);
        GetXMLToken(cTemp1,'ram:CountryID'   , oZugPersHeader.cZUG_Land);
    end;
    
    CWPrintn(oCW, 'Importiere Tax');

    nPos := 1;
    while (GetXMLToken(cTradePartyXML,'ram:SpecifiedTaxRegistration', nPos, cTemp1, False)) do begin
        nStart := 1;
        GetXMLTokenValue(cTemp1,'ram:ID', nStart, cTemp2, cTemp3); // value, key
        oZugPersHeader.AddFinanzID(cTemp3, cTemp2);
    end;
end;

//------------------------------------------------------------------------------
//  Procedure: Personen_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------

function Personen_Import_XML(cXMLTradeAgreement:String):Boolean;
var cTemp1 : String;
begin
    CWPrintn(oCW, 'Importiere Auftragsnummer Kunde');

    GetXMLToken(cXMLTradeAgreement,'ram:BuyerReference',oZugFerd.oPersonen.cAufNrKu);

    if (GetXMLToken(cXMLTradeAgreement,'ram:BuyerTradeParty',cTemp1)) then begin
        PersonHeader_Import_XML(oZugFerd.oPersonen.oZUG_Buyer, cTemp1);
    end;

    if (GetXMLToken(cXMLTradeAgreement,'ram:SellerTradeParty',cTemp1)) then begin
        PersonHeader_Import_XML(oZugFerd.oPersonen.oZUG_Seller,cTemp1);
    end;
end;

//------------------------------------------------------------------------------
//  Procedure: Lieferung_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------

function Lieferung_Import_XML(cXML:String):Boolean;
begin
    //Wenn Benötigt
    CWPrintn(oCW, 'Importiere Lieferung');
end;

//------------------------------------------------------------------------------
//  Procedure: Positionen_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------

function Positionen_Import_XML(oPos:TZugPosition; cXMLTradeLineItem:String):Boolean;
var cTemp1    : String;
    cTemp2    : String;
    cValue    : String;
    nPos      : integer;
begin

    nPos := 1;
    
    CWPrintn(oCW, 'Importiere Positionen');

    if (GetXMLToken(cXMLTradeLineItem,'ram:AssociatedDocumentLineDocument',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:LineID',oPos.cZUP_PosNr);
    end;

    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedTradeProduct',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:Name'             , oPos.cZUP_Bez1 );
        GetXMLToken(cTemp1,'ram:SellerAssignedID' , oPos.cZUP_ArtNrLief);
        GetXMLTokenValue(cTemp1, 'ram:GlobalID'   , nPos, oPos.cZUP_ArtNr, oPos.cZUP_ArtTyp);
        GetXMLToken(cTemp1,'ram:Description'      , oPos.cZUP_Text);

        //Warengruppe

        if GetXMLToken(cTemp1,'ram:DesignatedProductClassification', cTemp2) then begin
            //nPos := 1;
            GetXMLToken(cTemp2,'ram:ClassName', oPos.cZUP_WGRName);
        end;
    end;

    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedLineTradeAgreement',cTemp1)) then begin
        if (GetXMLToken(cTemp1,'ram:GrossPriceProductTradePrice',cTemp2)) then begin
            GetXMLToken(cTemp2,'ram:ChargeAmount', cValue);
            oPos.nZUP_EBrutto := fVAl(cValue);
        end;
        if (GetXMLToken(cTemp1,'ram:NetPriceProductTradePrice',cTemp2)) then begin
            GetXMLToken(cTemp2,'ram:ChargeAmount', cValue);
            oPos.nZUP_ENetto := fVAl(cValue);
        end;
    end;

    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedLineTradeDelivery', cTemp1)) then begin
        GetXMLTokenValue(cTemp1,'ram:BilledQuantity', nPos, cValue, oPos.cZUP_Einheit);
        oPos.nZUP_Menge := fVAl(cValue);
    end;

    if (GetXMLToken(cXMLTradeLineItem,'ram:SpecifiedLineTradeSettlement',cTemp1)) then begin
        if (GetXMLToken(cTemp1,'ram:ApplicableTradeTax',cTemp2)) then begin
            GetXMLToken(cTemp2,'ram:RateApplicablePercent', cValue);
            oPos.nZUP_MwstSatz := fVAl(cValue);
            GetXMLToken(cTemp2,'ram:TypeCode', oPos.cZUP_MWSTTyp );
        end;

        GetXMLToken(cTemp1,'ram:LineTotalAmount', cValue);
        oPos.nZUP_GNetto := fVAl(cValue);
    end;

    if (oPos.nZUP_ENetto > 0) and (oPos.nZUP_MwstSatz > 0) then begin
        oPos.nZUP_MwstBetrag := oPos.nZUP_ENetto * (oPos.nZUP_MwstSatz / 100);
    end;

    oPos.cZUP_Fehler      := '';
end;

//------------------------------------------------------------------------------
//  Procedure: Finanzen_Import_XML
//  Author:    JB
//  Date:      09-12-2021
//  Comment:
//------------------------------------------------------------------------------

function Finanzen_Import_XML(oFinanzen:TZugHeaderFinanzen; cXMLTradeSettlement:String):Boolean;
var cTemp1     : String;
    cTemp2     : String;
    cTemp3     : String;
    cTemp4     : String;
    nPos       : Integer;
    oPos       : TZugPosition;
    oPosTmp    : TZugPosition;
    cIndikator : String;
    lIndikator : Boolean;
    cText      : String;
    nPosNr     : Integer;
    cPosNr     : String;
    i          : integer;
begin

    CWPrintn(oCW, 'Importiere Finanzen');

    lIndikator := false;
    
    if (GetXMLToken(cXMLTradeSettlement,'ram:InvoiceCurrencyCode',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:InvoiceCurrencyCode', oFinanzen.cZUG_Waehrung);
    end;

    if (GetXMLToken(cXMLTradeSettlement,'ram:SpecifiedTradeSettlementPaymentMeans',cTemp1)) then begin
    
        oPos             := TZugPosition.Create();
        oPos.cZUP_UID    :=  TZugFerd(oFinanzen.oParent).cZUG_UID;
        oPos.cZUP_PosTyp := ZUG_POSTYP_MEMO;
        
        if (GetXMLToken(cTemp1,'ram:PayeePartyCreditorFinancialAccount',cTemp2)) then begin
            if (GetXMLToken(cTemp2,'ram:IBANID',cTemp3)) then begin
                cText := 'Betrag zu überweisen an:' + CRLF + 'IBAN ' + cTemp3;
            end;
        end;

        oPos.cZUP_Text := cText;
        //TObjectList(TZugFerd(oFinanzen.oParent).oPositionen).Insert(0, oPos);
        TZugFerd(oFinanzen.oParent).InsertToPositionen(0, oPos);
    end;

    if (GetXMLToken(cXMLTradeSettlement,'ram:SpecifiedTradeSettlementHeaderMonetarySummation',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:TaxBasisTotalAmount', cTemp2);
        oZugFerd.oFinanzen.nZUG_Netto := fVal(cTemp2);
        GetXMLToken(cTemp1,'ram:TaxTotalAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag := fVal(cTemp2);
        GetXMLToken(cTemp1,'ram:GrandTotalAmount', cTemp2);
        oFinanzen.nZUG_Brutto := fVal(cTemp2);
    end;

    if (GetXMLToken(cXMLTradeSettlement,'ram:SpecifiedTradePaymentTerms',cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:Description', oFinanzen.cZUG_Zahlbed);
        if (GetXMLToken(cTemp1,'ram:DueDateDateTime',cTemp2, False)) then begin
            GetXMLTokenValue(cTemp2,'udt:DateTimeString', nPos,cTemp4, cTemp3);
            oFinanzen.dZUG_FDatum := SToD(cTemp4);
        end;
    end;

    nPos := 1;
    if (GetXMLToken(cXMLTradeSettlement,'ram:ApplicableTradeTax', nPos, cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:CalculatedAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag1 := fVal(cTemp2);

        GetXMLToken(cTemp1,'ram:BasisAmount', cTemp2);
        oFinanzen.nZUG_Netto1  := fVal(cTemp2);
        oFinanzen.nZUG_Brutto1 := oFinanzen.nZUG_Netto1 + oFinanzen.nZUG_MwstBetrag1;

        GetXMLToken(cTemp1,'ram:RateApplicablePercent', cTemp2);
        oFinanzen.nZUG_MwstSatz1 := fVal(cTemp2);
    end;

    if (GetXMLToken(cXMLTradeSettlement,'ram:ApplicableTradeTax', nPos, cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:CalculatedAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag2 := fVal(cTemp2);

        GetXMLToken(cTemp1,'ram:BasisAmount', cTemp2);
        oFinanzen.nZUG_Netto2  := fVal(cTemp2);
        oFinanzen.nZUG_Brutto2 := oFinanzen.nZUG_Netto2 + oFinanzen.nZUG_MwstBetrag2;

        GetXMLToken(cTemp1,'ram:RateApplicablePercent', cTemp2);
        oFinanzen.nZUG_MwstSatz2 := fVal(cTemp2);
    end;

    if (GetXMLToken(cXMLTradeSettlement,'ram:ApplicableTradeTax', nPos, cTemp1)) then begin
        GetXMLToken(cTemp1,'ram:CalculatedAmount', cTemp2);
        oFinanzen.nZUG_MwstBetrag3 := fVal(cTemp2);

        GetXMLToken(cTemp1,'ram:BasisAmount', cTemp2);
        oFinanzen.nZUG_Netto3  := fVal(cTemp2);
        oFinanzen.nZUG_Brutto3 := oFinanzen.nZUG_Netto3 + oFinanzen.nZUG_MwstBetrag3;

        GetXMLToken(cTemp1,'ram:RateApplicablePercent', cTemp2);
        oFinanzen.nZUG_MwstSatz3 := fVal(cTemp2);
    end;

    if (oFinanzen.nZUG_MWSTBetrag = 0) then begin
        oFinanzen.nZUG_MWSTBetrag := oFinanzen.nZUG_MwstBetrag1 + oFinanzen.nZUG_MwstBetrag2 + oFinanzen.nZUG_MwstBetrag3;
    end;

    CWPrintn(oCW, 'Importiere Rabatte und Zusatzkosten');

    // Rabatte und Zusatzkosten als Positionen erfassen
    nPos := 1;
    while (GetXMLToken(cXMLTradeSettlement, 'ram:SpecifiedTradeAllowanceCharge', nPos, cTemp1)) do begin

        // Höchste Positionsnummer ermitteln, damit Zusatzkosten mit
        // aufsteigender Pos-Nr erfasst werden können
        nPosNr := 0;
        
        //for i:=0 to TObjectList(TZugFerd(oFinanzen.oParent).oPositionen).Count do begin
        for i:=0 to TZugFerd(oFinanzen.oParent).nPosCnt()-1 do begin
           oPosTmp := TZugFerd(oFinanzen.oParent).GetPosition(i);
           cPosNr  := oPosTmp.cZUP_PosNr;      
           nPosNr  := Max(nPosNr, iVal(cPosNr));
           CWPrintn(oCW, 'MaxNr ' + cPosNr);
        end;
        
        oPos := TZugPosition.Create( TZugFerd(oFinanzen.oParent).cZUG_UID);
        oPos             := TZugPosition.Create();
        oPos.cZUP_UID    := TZugFerd(oFinanzen.oParent).cZUG_UID;        
        oPos.cZUP_PosNr  := TStr(nPosNr + 1, 0, 0);
        cText := '';

        if (GetXMLToken(cTemp1,'ram:ChargeIndicator',cTemp2)) then begin
            GetXMLToken(cTemp1,'udt:Indicator', cIndikator);
            lIndikator := lower(cIndikator) = 'true';
            if (lIndikator) then begin
                cText := cText + 'Zusatzkosten' + CRLF;
            end else begin
                cText := cText + 'Rabatt' + CRLF;
            end;
        end;

        GetXMLToken(cTemp1,'ram:Reason',oPos.cZUP_Bez1);

        if (GetXMLToken(cTemp1,'ram:BasisAmount',cTemp2)) then begin
            cText := cText + 'Grundlage: ' + cTemp2;
        end;

        if (GetXMLToken(cTemp1,'ram:ActualAmount',cTemp2)) then begin
            oPos.nZUP_ENetto := fVal(cTemp2);
            if (lIndikator) then begin // Rabatt
                oPos.nZUP_Menge := 1;
            end else begin
                oPos.nZUP_Menge := -1;
            end;
        end;

        if (GetXMLToken(cTemp1,'ram:CategoryTradeTax',cTemp2)) then begin
            if (GetXMLToken(cTemp2,'ram:RateApplicablePercent',cTemp3)) then begin
                opos.nZUP_MwstSatz := fVal(cTemp3);
            end;
        end;

        oPos.cZUP_Text := cText;
        oPos.nZUP_GNetto := oPos.nZUP_Menge * oPos.nZUP_ENetto;

         TZugFerd(oFinanzen.oParent).AddToPositionen(oPos);
         //TObjectList(TZugFerd(oFinanzen.oParent).oPositionen).Add(oPos);
    end;
end;

//------------------------------------------------------------------------------
//  Procedure: Startproc
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   Startfunction 
//------------------------------------------------------------------------------

function  Startproc(oOBJ:TZugFerd; cXMLData:String):Boolean;
var cTemp1   : String;
    cTemp2   : String;
    cTemp3   : String;
    nPos     : Integer;
    oPos     : TZugPosition;
    lImport  : Boolean;
begin
   Result   := False;
   oZugFerd := oOBJ;

    oCW := CWOpen(20, 80, 'Importiere XML Zugferddaten');
    
    try
        if (GetXMLToken(cXMLData, 'ram:GuidelineSpecifiedDocumentContextParameter', cTemp1)) then begin
            GetXMLToken(cTemp1,'ram:ID', oZugFerd.cZUG_Schema);
        end;

        if (GetXMLToken(cXMLData, 'rsm:ExchangedDocument', cTemp1)) then begin
    
            nPos := 1;
          
            GetXMLTokenValue(cTemp1,'udt:DateTimeString', nPos, cTemp2, cTemp3);
            oZugFerd.dZUG_RDatum := SToD(cTemp2);

            nPos := 1;

            GetXMLToken(cTemp1,'ram:ID', oZugFerd.cZUG_Nr);
            GetXMLToken(cTemp1,'ram:TypeCode', oZugFerd.cZUG_TypCode);

            CWPrintn(oCW, 'Importiere Positionen Freitext');

            while (GetXMLToken(cTemp1, 'ram:IncludedNote', nPos, cTemp2)) do begin
                oPos := TZugPosition.Create(oZugFerd.cZUG_UID);

                oPos.cZUP_PosTyp := ZUG_POSTYP_MEMO;
                oPos.cZUP_Bez1   := 'Freitext';
                GetXMLToken(cTemp2, 'ram:Content', oPos.cZUP_Text);
                GetXMLToken(cTemp2, 'ram:SubjectCode', oPos.cZUP_Bez2);

                oZugFerd.AddToPositionen(oPos);
            end;
        end;

        if (GetXMLToken(cXMLData, 'rsm:SupplyChainTradeTransaction', cTemp1)) then begin

            lImport := False;

            if (GetXMLToken(cTemp1, 'ram:ApplicableHeaderTradeDelivery', cTemp2)) then begin
                CWPrintn(oCW, 'Importiere Lieferung');
                Lieferung_Import_XML(cTemp2);       
                lImport := True;
            end;

            if (GetXMLToken(cTemp1, 'ram:ApplicableHeaderTradeAgreement', cTemp2)) then begin
                CWPrintn(oCW, 'Importiere Personen');
                Personen_Import_XML(cTemp2);
                lImport := True;
            end;

            if (not lImport) then begin
                oZugFerd.AddProto('Kein Token ApplicableHeaderTradeDelivery vorhanden!');
                oZugFerd.AddProto('Kein Token ApplicableHeaderTradeAgreement vorhanden!');
                Result := False;
            end;

            nPos := 1;

            while (GetXMLToken(cTemp1, 'ram:IncludedSupplyChainTradeLineItem', nPos, cTemp2)) do begin
                oPos := TZugPosition.Create(oZugFerd.cZUG_UID);
                Positionen_Import_XML(oPos, cTemp2);
            
                oZugFerd.AddToPositionen(oPos);
            end;

            // Beträge nach den Positionen, damit Rabatte und Zusatzkosten als Positionen am Ende erfasst werden
            if (GetXMLToken(cTemp1, 'ram:ApplicableHeaderTradeSettlement', cTemp2)) then begin
                Finanzen_Import_XML(oZugFerd.oFinanzen, cTemp2);
            end;

            Result := True;
        end;
    finally
        CWClose(oCW);
    end;
end;

//------------------------------------------------------------------------------

Export

Wenn es einen aktiven Eintrag in der Script Libary mit dem Namen EXPORT_ZUGFERD gibt wird die Erstellung der XML-Datei über die Pax Funktion ausgeführt.

Beispiel Script Export

//------------------------------------------------------------------------------
// Unit Name: EXPORT_ZUGFERD
// Author:    JB
// Date:      09-12-2021
//------------------------------------------------------------------------------

var oXML         : TXMLWriter;
    cRechnungsNr : String;
    qRech        : TxFQuery;
    qKonst       : TxFQuery;
    qStamm       : TxFQuery;
    qPerson      : TxFQuery;
    dLiefDat     : TDateTime;
    nMWST        : Double;
    nMwstTotal   : Double;
    oFormat      : TFormatSettings;
        
//------------------------------------------------------------------------------
//  Procedure: _Format
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   Zahlenausgabe für XML 
//------------------------------------------------------------------------------    
    
function _Format(nVal : Double): String;
 begin
     Result := ZugFerd_FormatDouble(nVal);
 end;

//------------------------------------------------------------------------------
//  Procedure: OBSRechnungsart_To_ZUGInvoiceTypeCode(
//  Author:    JB
//  Date:      09-12-2021
//  Comment:    
//------------------------------------------------------------------------------ 

function OBSRechnungsart_To_ZUGInvoiceTypeCode(const cOBSRechArt : String): String;
begin
    Result := '';
    if          (cOBSRechArt = '1') then begin // Standardrechnung
        Result := ZUG_RECHTYP_COMMERCIAL;
    end else if (cOBSRechArt = '2') then begin // Abschlagsrechnung
        Result := ZUG_RECHTYP_ABSCHLAG;
    end else if (cOBSRechArt = '3') then begin // Schlussrechnung
        Result := ZUG_RECHTYP_COMMERCIAL;
    end else if (cOBSRechArt = '4') then begin // Proformarechnung
        Result := ZUG_RECHTYP_PROFORMA;
    end else if (cOBSRechArt = '5') then begin // Gutschrift
        Result := ZUG_RECHTYP_GUTSCHRIFT;
    end else if (cOBSRechArt = '6') then begin // Stornorechnung
        Result := ZUG_RECHTYP_GUTSCHRIFT;
    end else if (cOBSRechArt = '7') then begin // Anzahlungsrechnung
        Result := ZUG_RECHTYP_PARTIAL;
    end;
end;

//------------------------------------------------------------------------------
//  Procedure: OBSMwstSchl_To_ZUGCategoryCode((
//  Author:    JB
//  Date:      09-12-2021
//  Comment:    
//------------------------------------------------------------------------------ 

function  OBSMwstSchl_To_ZUGCategoryCode(const cOBSMWST : String): String;
var nMwst : Integer;
begin
    nMWST := iVal(cOBSMWST);

    if (nMWST < 10) then begin
        Result := ZUG_MWSTTYP_STANDARD;
    end;
end;

//------------------------------------------------------------------------------
//  Procedure: GetVersandTyp(
//  Author:    JB
//  Date:      09-12-2021
//  Comment:    
//------------------------------------------------------------------------------ 

function GetVersandTyp(oMyDB: TxDB; cPerson: String): Integer;
begin
    Result := iVal(DB_ReadSQLValue(oMyDB,'ZUGFERD_PERSONEN','zp_versand','zp_psnr = '+DB_SQLVal(cPerson)));
end;

//------------------------------------------------------------------------------
//  Procedure: ZugFerd_Positionen
//  Author:    JB
//  Date:      09-12-2021
//  Comment:    
//------------------------------------------------------------------------------ 

procedure ZugFerd_Positionen(var oXML : TXMLWriter);
 var cSQL : String;
     qPos : TxFQuery;
 begin

     cSQL := 'SELECT * FROM RECHPOS'+
             ' LEFT JOIN s_mwst ON az_mwstsch = mw_nr' +
             ' WHERE az_nr = ' + DB_SQLVal(cRechnungsNr) +
             ' AND az_typ = 0';

     if (DB_SOpen(oDB, cSQL, qPos)) then begin

         dLiefDat := CToD(DB_ReadSQLValue(oDB,'LIEFSTA LEFT JOIN LIEFPOS ON a_nr = az_nr','a_datum','az_aufnr = '+DB_SQLVal(qPos.A2C('az_aufnr'))));
         if (empty(dLiefDat)) then begin
             dLiefDat := qRech.A2D('a_facdatum');
             if (empty(dLiefdat)) then begin
                 dLiefDat := qRech.A2D('a_datum');
             end;
         end;

         while not qPos.eof do begin
             with oXML do begin
                 OpenElement('ram:IncludedSupplyChainTradeLineItem');
                     OpenElement('ram:AssociatedDocumentLineDocument');
                         AddElement('ram:LineID', qPos.A2C('az_posnr')); // Positionsnummer // BR-21
                     CloseElement; // ram:AssociatedDocumentLineDocument

                     OpenElement('ram:SpecifiedTradeProduct');
                         AddElement('ram:SellerAssignedID', qPos.A2C('az_artnr')); //BT-155 Artikelnummer des Verkäufers
                         AddElement('ram:Name', qPos.A2C('az_bez1')); // Positionsname // BR-25
                     CloseElement; // ram:SpecifiedTradeProduct

                     OpenElement('ram:SpecifiedLineTradeAgreement');
                         OpenElement('ram:NetPriceProductTradePrice');
                             AddElement('ram:ChargeAmount', _Format(qPos.A2F('az_epreis'))); // Netto Einzelpreis // BR-26, BR-27
                         CloseElement; // ram:NetPriceProductTradePrice
                     CloseElement; // ram:SpecifiedLineTradeAgreement

                     OpenElement('ram:SpecifiedLineTradeDelivery');
                         AddAttrElement('ram:BilledQuantity', 'unitCode', 'H87', _Format(qPos.A2F('az_menge'))); // Einheit und Menge // BR-22, BR-23
                     CloseElement; // ram:SpecifiedLineTradeDelivery

                     OpenElement('ram:SpecifiedLineTradeSettlement');
                         OpenElement('ram:ApplicableTradeTax');
                             OpenElement('ram:TypeCode');
                                 SetContent('VAT'); // Steuerart, im Standard immer VAT
                             CloseElement; // ram:TypeCode
                             OpenElement('ram:CategoryCode');
                                 // Andere: (100 - 199)
                                 // AE:     $13b Reverse Charge (200 - 299)
                                 // K:      Innereuropäisch (400 - 499)
                                 SetContent('S');
                             CloseElement; // ram:CategoryCode
                             OpenElement('ram:RateApplicablePercent');
                                 SetContent(_Format(qPos.A2F('mw_satz')));
                             CloseElement; // ram:RateApplicablePercent
                         CloseElement; // ram:ApplicableTradeTax

                         if (qPos.A2F('az_rabatt') > 0) or (qPos.A2F('az_grabatt') > 0) then begin
                         OpenElement('ram:SpecifiedTradeAllowanceCharge');
                             OpenElement('ram:ChargeIndicator');
                                 AddElement('udt:Indicator','false'); // false = Abschlag, true = Zuschlag
                             CloseElement; // ram:ChargeIndicator

                             if (qPos.A2F('az_rabatt') > 0) then begin
                                 AddElement('ram:CalculationPercent', qPos.A2C('az_rabatt'));
                             end;

                             AddElement('ram:BasisAmount', _Format(qPos.A2F('az_menge')*qPos.A2F('az_epreis')));

                             if (qPos.A2F('az_rabatt') > 0) then begin // BR-41
                                 AddElement('ram:ActualAmount', _Format(qPos.A2F('az_menge')*qPos.A2F('az_epreis')*(qPos.A2F('az_rabatt')/100)));
                             end else if (qPos.A2F('az_grabatt') > 0) then begin
                                 AddElement('ram:ActualAmount', _Format(qPos.A2F('az_grabatt')));
                             end;
                             AddElement('ram:ReasonCode', '95');
                             AddElement('ram:Reason', 'Discount'); // BR-42
                         CloseElement; // ram:SpecifiedTradeAllowanceCharge
                         end;

                         OpenElement('ram:SpecifiedTradeSettlementLineMonetarySummation');
                             AddElement('ram:LineTotalAmount', _Format(qPos.A2F('az_gpreis'))); // Netto Gesampreis // BR-24
                         CloseElement; // ram:SpecifiedTradeSettlementLineMonetarySummation
                     CloseElement; // ram:SpecifiedLineTradeSettlement
                 CloseElement; // ram:IncludedSupplyChainTradeLineItem
             end;
             qPos.next();
         end;
     end;
     DB_Close(qPos);
 end;

//------------------------------------------------------------------------------
//  Procedure: StartProc
//  Author:    JB
//  Date:      09-12-2021
//  Comment:   Start Procwedure 
//------------------------------------------------------------------------------ 

function StartProc(xoXML         : TXMLWriter;
                   xcRechnungsNr : String;
                   xqRech        : TxFQuery;
                   xqKonst       : TxFQuery;
                   xqStamm       : TxFQuery;
                   xqPerson     : TxFQuery):Boolean;
begin
    Result        := True;
    oXML          := xoXML;                
    cRechnungsNr  := xcRechnungsNr;
    qRech         := xqRech;       
    qKonst        := xqKonst;      
    qStamm        := xqStamm;      
    qPerson       := xqPerson;     

    oFormat.DecimalSeparator := '.';
    oFormat.CurrencyDecimals := 2;
    
    oXML.OpenElement('rsm:CrossIndustryInvoice');
        oXML.SetAttribute('xmlns:a',   'urn:un:unece:uncefact:data:standard:QualifiedDataType:100');
        oXML.SetAttribute('xmlns:rsm', 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100');
        oXML.SetAttribute('xmlns:qdt', 'urn:un:unece:uncefact:data:standard:QualifiedDataType:10');
        oXML.SetAttribute('xmlns:ram', 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100');
        oXML.SetAttribute('xmlns:xs',  'http://www.w3.org/2001/XMLSchema');
        oXML.SetAttribute('xmlns:udt', 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100');
        oXML.OpenElement('rsm:ExchangedDocumentContext');
            oXML.OpenElement('ram:GuidelineSpecifiedDocumentContextParameter');
                oXML.AddElement('ram:ID', ZUG_COMPLIANCE_XRECHNUNG_2_0); // BR-1
            oXML.CloseElement; // ram:GuidelineSpecifiedDocumentContextParameter
        oXML.CloseElement; // rsm:ExchangedDocumentContext

        oXML.OpenElement('rsm:ExchangedDocument');
            oXML.AddElement('ram:ID', qRech.A2C('a_nr')); // Rechnungsnummer  // BR-2
            oXML.AddElement('ram:TypeCode', OBSRechnungsart_To_ZUGInvoiceTypeCode(qRech.A2C('a_art'))); // Rechnungstyp // BR-4
            oXML.OpenElement('ram:IssueDateTime');
                oXML.AddAttrElement('udt:DateTimeString','format', '102', DToS(qRech.A2D('a_datum'))); // Datum // BR-3
            oXML.CloseElement; // ram:IssueDateTime
            
            //Wenn Postgut
            //oXML.OpenElement('ram:IncludedNote');
            //    oXML.AddElement('ram:Content',qRech.A2C('a_aufnrku'));
            //    oXML.AddElement('ram:SubjectCode','INV');
            //oXML.CloseElement; //ram:IncludedNote
            
        oXML.CloseElement; // rsm:ExchangedDocument

        oXML.OpenElement('rsm:SupplyChainTradeTransaction');
        
            ZugFerd_positionen(oXML); // ram:IncludedSupplyChainTradeLineItem

            oXML.OpenElement('ram:ApplicableHeaderTradeAgreement');
                oXML.AddElement('ram:BuyerReference',qPerson.A2C('zp_leitwegid')); // Leitweg-ID für XRechnung

                oXML.OpenElement('ram:SellerTradeParty');
                    oXML.AddElement('ram:ID', qPerson.A2C('zp_kreditorennr')); // BT-29: Kreditorennummer beim Kunden
                    oXML.AddElement('ram:Name', qKonst.A2C('k_name')); // BR-6

                    oXML.OpenElement('ram:DefinedTradeContact'); // BG-6, BR-DE-5, BR-DE-6, BR-DE-7
                        oXML.AddElement('ram:PersonName', qPerson.A2C('zp_apname')); // BT-41 Name

                        oXML.OpenElement('ram:TelephoneUniversalCommunication'); // BT-42 Telefon
                            oXML.AddElement('ram:CompleteNumber', qPerson.A2C('zp_aptel'));
                        oXML.CloseElement();  // ram:TelephoneUniversalCommunication

                        oXML.OpenElement('ram:EmailURIUniversalCommunication'); // BT-43 E-Mail
                            oXML.AddElement('ram:URIID', qPerson.A2C('zp_apmail'));
                        oXML.CloseElement();  // ram:EmailURIUniversalCommunication
                    oXML.CloseElement();  // ram:DefinedTradeContact

                    oXML.OpenElement('ram:PostalTradeAddress'); // BR-8
                        oXML.AddElement('ram:PostcodeCode', qKonst.A2C('k_plz'));
                        oXML.AddElement('ram:LineOne', qKonst.A2C('k_strasse'));
                        oXML.AddElement('ram:CityName', qKonst.A2C('k_ort'));
                        oXML.AddElement('ram:CountryID', 'DE'); // BR-9
                    oXML.CloseElement; // ram:PostalTradeAddress

                    oXML.OpenElement('ram:SpecifiedTaxRegistration');
                        oXML.AddAttrElement('ram:ID', 'schemeID', 'VA', qKonst.A2C('k_ustid')); //
                    oXML.CloseElement; // ram:SpecifiedTaxRegistration
                oXML.CloseElement; // ram:SellerTradeParty

                oXML.OpenElement('ram:BuyerTradeParty');
                    oXML.AddElement('ram:Name',qRech.A2C('a_name')); // BR-7
                    oXML.OpenElement('ram:PostalTradeAddress'); // BR-10
                        oXML.AddElement('ram:PostcodeCode', qRech.A2C('a_plz'));
                        oXML.AddElement('ram:LineOne', qRech.A2C('a_strasse'));
                        oXML.AddElement('ram:CityName', qRech.A2C('a_ort'));
                        oXML.AddElement('ram:CountryID', 'DE'); // BR-11
                    oXML.CloseElement; // ram:PostalTradeAddress
                oXML.CloseElement; // ram:BuyerTradeParty

                oXML.OpenElement('ram:BuyerOrderReferencedDocument');
                    oXML.AddElement('ram:IssuerAssignedID',qRech.A2C('a_aufnrku'));
                oXML.CloseElement(); //ram:BuyerOrderReferencedDocument

            oXML.CloseElement; // ram:ApplicableHeaderTradeAgreement

            oXML.OpenElement('ram:ApplicableHeaderTradeDelivery'); // Tag muss vorhanden sein

                if (not empty(qRech.A2C('a_vstrasse'))) then begin
                    oXML.OpenElement('ram:ShipToTradeParty'); // Abweichender Warenempfänger
                        oXML.OpenElement('ram:PostalTradeAddress'); // BR-57
                            oXML.AddElement('ram:PostcodeCode', qRech.A2C('a_vplz'));
                            oXML.AddElement('ram:LineOne', qRech.A2C('a_vstrasse'));
                            oXML.AddElement('ram:CityName', qRech.A2C('a_vort'));
                            oXML.AddElement('ram:CountryID', 'DE'); // BR-11
                        oXML.CloseElement; // ram:PostalTradeAddress
                    oXML.CloseElement;
                end;

                oXML.OpenElement('ram:ActualDeliverySupplyChainEvent');
                    oXML.OpenElement('ram:OccurrenceDateTime');
                        oXML.AddAttrElement('udt:DateTimeString','format', '102', DToS(dLiefDat)); // Datum // BT-72
                    oXML.CloseElement;
                oXML.CloseElement;

            oXML.CloseElement;

            oXML.OpenElement('ram:ApplicableHeaderTradeSettlement');
                oXML.AddElement('ram:InvoiceCurrencyCode', 'EUR'); // Währungscode nach ISO 4217 // BR-5

                // BR-49, BR-50, BR-51
                if (not empty(qStamm.A2C('zus_iban1'))) then begin
                    oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                        oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                        oXML.AddElement('ram:Information', qStamm.A2C('zus_bank1'));
                        oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                            oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban1'));
                        oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                    oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban2'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank2'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban2'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban3'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank3'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban3'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban4'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank4'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban4'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;
                if (not empty(qStamm.A2C('zus_iban5'))) then begin
                oXML.OpenElement('ram:SpecifiedTradeSettlementPaymentMeans');
                    oXML.AddElement('ram:TypeCode', '30'); // 30 = Überweisung // BR-49
                    oXML.AddElement('ram:Information', qStamm.A2C('zus_bank5'));
                    oXML.OpenElement('ram:PayeePartyCreditorFinancialAccount');
                        oXML.AddElement('ram:IBANID', qStamm.A2C('zus_iban5'));
                    oXML.CloseElement; // ram:PayeePartyCreditorFinancialAccount
                oXML.CloseElement; // ram:SpecifiedTradeSettlementPaymentMeans
                end;

                nMWSTTotal := 0;
                if (not empty(qRech.A2C('a_mwstschl1'))) then begin
                oXML.OpenElement('ram:ApplicableTradeTax');
                    nMWST := qRech.A2F('a_net1') * (qRech.A2F('a_mwst1') / 100);
                    nMWSTTotal := nMWSTTotal + nMWST;
                    oXML.AddElement('ram:CalculatedAmount',_Format(nMWST)); // BR-46
                    oXML.AddElement('ram:TypeCode', 'VAT');
                    oXML.AddElement('ram:BasisAmount', _Format(qRech.A2F('a_net1'))); // BR-45
                    oXML.AddElement('ram:CategoryCode', OBSMwstSchl_To_ZUGCategoryCode(qRech.A2C('a_art'))); // BR-47
                    oXML.AddElement('ram:RateApplicablePercent', _Format(qRech.A2F('a_mwst1'))); // BR-48
                oXML.CloseElement; // ram:ApplicableTradeTax
                end;
                if (not empty(qRech.A2C('a_mwstschl2'))) then begin
                oXML.OpenElement('ram:ApplicableTradeTax');
                    nMWST := qRech.A2F('a_net2') * (qRech.A2F('a_mwst2') / 100);
                    nMWSTTotal := nMWSTTotal + nMWST;
                    oXML.AddElement('ram:CalculatedAmount',_Format(nMWST)); // BR-46
                    oXML.AddElement('ram:TypeCode', 'VAT');
                    oXML.AddElement('ram:BasisAmount', _Format(qRech.A2F('a_net2'))); // BR-45
                    oXML.AddElement('ram:CategoryCode', OBSMwstSchl_To_ZUGCategoryCode(qRech.A2C('a_art'))); // BR-47
                    oXML.AddElement('ram:RateApplicablePercent', _Format(qRech.A2F('a_mwst2'))); // BR-48
                oXML.CloseElement; // ram:ApplicableTradeTax
                end;
                if (not empty(qRech.A2C('a_mwstschl3'))) then begin
                oXML.OpenElement('ram:ApplicableTradeTax');
                    nMWST := qRech.A2F('a_net3') * (qRech.A2F('a_mwst3') / 100);
                    nMWSTTotal := nMWSTTotal + nMWST;
                    oXML.AddElement('ram:CalculatedAmount',_Format(nMWST)); // BR-46
                    oXML.AddElement('ram:TypeCode', 'VAT');
                    oXML.AddElement('ram:BasisAmount', _Format(qRech.A2F('a_net3'))); // BR-45
                    oXML.AddElement('ram:CategoryCode', OBSMwstSchl_To_ZUGCategoryCode(qRech.A2C('a_art'))); // BR-47
                    oXML.AddElement('ram:RateApplicablePercent', _Format(qRech.A2F('a_mwst3'))); // BR-48
                oXML.CloseElement; // ram:ApplicableTradeTax
                end;

                oXML.OpenElement('ram:SpecifiedTradePaymentTerms');
                    // Fälligkeitsdatum
                    oXML.OpenElement('ram:DueDateDateTime');
                        oXML.AddAttrElement('udt:DateTimeString','format', '102', DToS(qRech.A2D('a_faellig'))); // Datum // BT-9, BR-CO-25
                    oXML.CloseElement; // ram:DueDateDateTime
                oXML.CloseElement; // ram:SpecifiedTradePaymentTerms

                oXML.OpenElement('ram:SpecifiedTradeSettlementHeaderMonetarySummation');
                    oXML.AddElement('ram:LineTotalAmount', _Format(qRech.A2F('a_nbetrag'))); // BR-12
                    oXML.AddElement('ram:TaxBasisTotalAmount', _Format(qRech.A2F('a_nbetrag'))); // BR-13
                    oXML.AddAttrElement('ram:TaxTotalAmount','currencyID','EUR',_Format(nMWSTTotal)); // BR-53
                    oXML.AddElement('ram:GrandTotalAmount', _Format(qRech.A2F('a_bbetrag'))); // BR-14
                    oXML.AddElement('ram:DuePayableAmount', _Format(qRech.A2F('a_bbetrag'))); // BR-15
                oXML.CloseElement(); // ram:SpecifiedTradeSettlementHeaderMonetarySummation

            oXML.CloseElement; // ram:ApplicableHeaderTradeSettlement

        oXML.CloseElement; // rsm:SupplyChainTradeTransaction

    oXML.CloseElement; // rsm:CrossIndustryInvoice
    
end;