Skip to content

Commit

Permalink
SEPADirectDebit / Lastschrift added
Browse files Browse the repository at this point in the history
  • Loading branch information
landrix committed Aug 1, 2024
1 parent 70c1355 commit 493d1b3
Show file tree
Hide file tree
Showing 7 changed files with 390 additions and 194 deletions.
3 changes: 2 additions & 1 deletion Samples/XRechnungUnit1.dfm
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ object Form1: TForm1
'Titel/Positionsgruppen'
'Gutschrift'
'Minimalrechnung B2B'
'Preiseinheit')
'Preiseinheit'
'Lastschrift')
TabOrder = 16
end
object cbValidateWithJava: TCheckBox
Expand Down
1 change: 1 addition & 0 deletions Samples/XRechnungUnit1.pas
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ procedure TForm1.Button9Click(Sender: TObject);
5 : TInvoiceTestCases.Gutschrift(inv);
6 : TInvoiceTestCases.MinimalbeispielB2BOhneLeitwegID(inv);
7 : TInvoiceTestCases.PreiseinheitGroesser1(inv);
8 : TInvoiceTestCases.Lastschrift(inv);
end;

Generate(inv);
Expand Down
113 changes: 99 additions & 14 deletions Samples/XRechnungUnit2TestCases.pas
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ TInvoiceTestCases = class(TObject)
class procedure MinimalbeispielB2BOhneLeitwegID(inv : TInvoice);
class procedure Gutschrift(inv : TInvoice);
class procedure PreiseinheitGroesser1(inv : TInvoice);
class procedure Lastschrift(inv : TInvoice);
end;

implementation
Expand Down Expand Up @@ -90,8 +91,8 @@ class procedure TInvoiceTestCases.Austauschteilesteuer(inv: TInvoice);

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';
//inv.PayeeFinancialInstitutionBranch := 'DEU...'; //BIC

inv.PaymentTermsType := iptt_Net;
Expand Down Expand Up @@ -237,8 +238,8 @@ class procedure TInvoiceTestCases.Differenzbesteuerung(inv: TInvoice);

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';
//inv.PayeeFinancialInstitutionBranch := 'DEU...'; //BIC

inv.PaymentTermsType := iptt_Net;
Expand Down Expand Up @@ -355,8 +356,8 @@ class procedure TInvoiceTestCases.Gesamtbeispiel(inv: TInvoice;

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';
//inv.PayeeFinancialInstitutionBranch := 'DEU...'; //BIC

//verschiedene Zahlungsbedingungen, Verzugszinsen fehlt noch
Expand Down Expand Up @@ -674,8 +675,8 @@ class procedure TInvoiceTestCases.Gutschrift(inv: TInvoice);

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';

inv.PaymentTermsType := iptt_Net;
inv.PaymentTermNetNote := Format('Zahlbar bis zum %s ohne Abzug.',[DateToStr(inv.InvoiceIssueDate)]);
Expand Down Expand Up @@ -764,8 +765,8 @@ class procedure TInvoiceTestCases.Kleinunternehmerregelung(inv: TInvoice);

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';

inv.PaymentTermsType := iptt_Net;
inv.PaymentTermNetNote := Format('Zahlbar bis zum %s ohne Abzug.',[DateToStr(inv.InvoiceIssueDate)]);
Expand Down Expand Up @@ -804,6 +805,90 @@ class procedure TInvoiceTestCases.Kleinunternehmerregelung(inv: TInvoice);
inv.PayableAmount := 5000.00; //Summe Zahlbar MwSt
end;

class procedure TInvoiceTestCases.Lastschrift(inv: TInvoice);
var
suc : Boolean;
begin
inv.InvoiceNumber := 'R2020-0815';
inv.InvoiceIssueDate := Date; //Rechnungsdatum
inv.InvoiceDueDate := Date+30; //Fälligkeitsdatum
inv.InvoicePeriodStartDate := Date-30;
inv.InvoicePeriodEndDate := Date-1;
inv.InvoiceTypeCode := TInvoiceTypeCode.itc_CommercialInvoice; //Schlussrechnung
inv.InvoiceCurrencyCode := 'EUR';
inv.TaxCurrencyCode := 'EUR';
inv.BuyerReference := TInvoiceEmptyLeitwegID.NON_EXISTENT; //B2B ohne Leitweg-ID

inv.AccountingSupplierParty.Name := 'Verkaeufername';
inv.AccountingSupplierParty.RegistrationName := 'Verkaeufername'; //Sollte ausgefüllt werden
inv.AccountingSupplierParty.CompanyID := '';
inv.AccountingSupplierParty.Address.StreetName := 'Verkaeuferstraße 1';
inv.AccountingSupplierParty.Address.City := 'Verkaeuferstadt';
inv.AccountingSupplierParty.Address.PostalZone := '01234';
inv.AccountingSupplierParty.Address.CountryCode := 'DE';
inv.AccountingSupplierParty.VATCompanyID := 'DE12345678';
inv.AccountingSupplierParty.VATCompanyNumber := '222/111/4444';
inv.AccountingSupplierParty.ContactName := 'Meier';
inv.AccountingSupplierParty.ContactTelephone := '030 0815';
inv.AccountingSupplierParty.ContactElectronicMail := 'meier@company.com';
//BT-34 Gibt die elektronische Adresse des Verkäufers an, an die die Antwort auf eine Rechnung gesendet werden kann.
//Aktuell nur Unterstuetzung fuer schemeID=EM ElectronicMail
//Weitere Codes auf Anfrage
//https://www.xrepository.de/details/urn:xoev-de:kosit:codeliste:eas_4#version
inv.AccountingSupplierParty.ElectronicAddressSellerBuyer := 'antwortaufrechnung@company.com';

inv.AccountingCustomerParty.Name := 'Kaeufername';
inv.AccountingCustomerParty.RegistrationName := 'Kaeufername'; //Sollte ausgefüllt werden
inv.AccountingCustomerParty.CompanyID := 'HRB 456';
inv.AccountingCustomerParty.Address.StreetName := 'Kaeuferstraße 1';
inv.AccountingCustomerParty.Address.City := 'Kaeuferstadt';
inv.AccountingCustomerParty.Address.PostalZone := '05678';
inv.AccountingCustomerParty.Address.CountryCode := 'DE';
inv.AccountingCustomerParty.VATCompanyID := 'DE12345678';
inv.AccountingCustomerParty.VATCompanyNumber := '222/111/4444';
inv.AccountingCustomerParty.ElectronicAddressSellerBuyer := 'antwortaufrechnung@kunde.de'; //BT-49

inv.PaymentMeansCode := ipmc_SEPADirectDebit; //Lastschrift
inv.PaymentID := 'Verwendungszweck der Lastschrift...R2020-0815';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentMandateID := 'MANDATID'; //Mandats-ID
inv.AccountingSupplierParty.BankAssignedCreditorIdentifier := '111111'; //Gläubiger-ID

inv.PaymentTermsType := iptt_None;

with inv.InvoiceLines.AddInvoiceLine do
begin
ID := '01'; //Positionsnummer
Name := 'Kurzinfo Artikel 1'; //Kurztext
Description := 'Langtext Artikel'+#13#10+'Zeile 2'+#13#10+'Zeile 3'; //Laengere Beschreibung
Quantity := 1; //Menge
UnitCode := TInvoiceUnitCodeHelper.MapUnitOfMeasure('Stk',suc); //Mengeneinheit
TaxPercent := 19.0; //MwSt
TaxCategory := TInvoiceDutyTaxFeeCategoryCode.idtfcc_S_StandardRate;
GrossPriceAmount := 360; //Brutto-Einzelpreis
DiscountOnTheGrossPrice := 0;
NetPriceAmount := 360; //Netto-Einzelpreis
BaseQuantity := 0; //Preiseinheit
BaseQuantityUnitCode := TInvoiceUnitCode.iuc_None; //Preiseinheit Mengeneinheit
LineAmount := 360;
end;

inv.TaxAmountTotal := 68.40; //Summe der gesamten MwSt
SetLength(inv.TaxAmountSubtotals,1); //1 MwSt-Saetze
inv.TaxAmountSubtotals[0].TaxPercent := 19.0;
inv.TaxAmountSubtotals[0].TaxCategory := TInvoiceDutyTaxFeeCategoryCode.idtfcc_S_StandardRate;
inv.TaxAmountSubtotals[0].TaxableAmount := 360.0;
inv.TaxAmountSubtotals[0].TaxAmount := 68.40;

inv.LineAmount := 360.0; //Summe
inv.TaxExclusiveAmount := 360.00; //Summe ohne MwSt
inv.TaxInclusiveAmount := 428.40; //Summe inkl MwSt
inv.AllowanceTotalAmount := 0; //Abzuege
inv.ChargeTotalAmount := 0; //Zuschlaege
inv.PrepaidAmount := 0; //Anzahlungen
inv.PayableAmount := 428.40; //Summe Zahlbar MwSt
end;

class procedure TInvoiceTestCases.MinimalbeispielB2BOhneLeitwegID(
inv: TInvoice);
var
Expand Down Expand Up @@ -935,8 +1020,8 @@ class procedure TInvoiceTestCases.Paragr13b(inv: TInvoice);

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';
//inv.PayeeFinancialInstitutionBranch := 'DEU...'; //BIC

inv.PaymentTermsType := iptt_Net;
Expand Down Expand Up @@ -1109,8 +1194,8 @@ class procedure TInvoiceTestCases.TitelPositionsgruppen(inv: TInvoice);

inv.PaymentMeansCode := ipmc_SEPACreditTransfer; //Ueberweisung
inv.PaymentID := 'Verwendungszweck der Ueberweisung...R2020-0815';
inv.PayeeFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PayeeFinancialAccountName := 'Fa. XY';
inv.PaymentFinancialAccount := 'DE75512108001245126199'; //dies ist eine nicht existerende aber valide IBAN als test dummy
inv.PaymentFinancialAccountName := 'Fa. XY';
//inv.PayeeFinancialInstitutionBranch := 'DEU...'; //BIC

inv.PaymentTermsType := iptt_Net;
Expand Down
10 changes: 6 additions & 4 deletions intf.Invoice.pas
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ TInvoiceAccountingParty = record
Address : TInvoiceAddress;

IdentifierSellerBuyer : String; //Kreditor-Nr AccountingSupplierParty / Debitor-Nr AccountingCustomerParty
BankAssignedCreditorIdentifier : String; //Gläubiger-ID (BT-90)

VATCompanyID : String; //BT-31
VATCompanyNumber: String;//BT-32
Expand Down Expand Up @@ -511,10 +512,11 @@ TInvoice = class(TObject)
//TODO weitere Zahlungswege, als Liste
//TODO Auch 0 prüfen
PaymentMeansCode : TInvoicePaymentMeansCode;
PaymentID : String; //Verwendungszweck der Ueberweisung, optional
PayeeFinancialAccount : String;
PayeeFinancialAccountName : String;
PayeeFinancialInstitutionBranch : String; //BIC
PaymentID : String; //Verwendungszweck der Ueberweisung/Lastschrift
PaymentFinancialAccount : String; //sowohl Payee (Überweisung 58) als auch Payer (Lastschrift 59)
PaymentFinancialAccountName : String; //sowohl Payee (Überweisung 58) als auch Payer (Lastschrift 59)
PaymentFinancialInstitutionBranch : String; //BIC sowohl Payee (Überweisung 58) als auch Payer (Lastschrift 59)
PaymentMandateID : String; //Lastschrift (59) Mandatsreferenz BT-89

//Infos unter
//https://www.e-rechnung-bund.de/wp-content/uploads/2023/04/Angabe-Skonto-Upload.pdf
Expand Down
23 changes: 13 additions & 10 deletions intf.XRechnung.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1295,35 +1295,38 @@ class function TZUGFeRDInvoiceAdapter.LoadFromInvoiceDescriptor(
_Invoice.DeliveryInformation.ActualDeliveryDate := _InvoiceDescriptor.ActualDeliveryDate.GetValueOrDefault(0);

case _InvoiceDescriptor.PaymentMeans.TypeCode of
InCash: _Invoice.PaymentMeansCode := ipmc_InCash;
Cheque: _Invoice.PaymentMeansCode := ipmc_Cheque;
CreditTransfer: _Invoice.PaymentMeansCode := ipmc_CreditTransfer;
//Fehlt : _Invoice.PaymentMeansCode := ipmc_CreditCard; 54
SEPACreditTransfer: _Invoice.PaymentMeansCode := ipmc_SEPACreditTransfer;
SEPADirectDebit: _Invoice.PaymentMeansCode := ipmc_SEPADirectDebit;
NotDefined: _Invoice.PaymentMeansCode := ipmc_InstrumentNotDefined;
else _Invoice.PaymentMeansCode := ipmc_NotImplemented;
// Unknown: ;
// AutomatedClearingHouseDebit: ;
// InCash: ;
// Cheque: ;
// CreditTransfer: ;
// DebitTransfer: ;
// PaymentToBankAccount: ;
// BankCard: ;
// DirectDebit: ;
// BankCard: 48
// StandingAgreement: ;
// SEPADirectDebit: ;
// ClearingBetweenPartners: ;
end;
_Invoice.PaymentID := _InvoiceDescriptor.PaymentReference;
if _InvoiceDescriptor.PaymentMeans <> nil then
_Invoice.AccountingSupplierParty.BankAssignedCreditorIdentifier := _InvoiceDescriptor.PaymentMeans.SEPACreditorIdentifier;
//TODO Mehrere Bankverbindungen
if _InvoiceDescriptor.CreditorBankAccounts.Count > 0 then
begin
_Invoice.PayeeFinancialAccount := _InvoiceDescriptor.CreditorBankAccounts[0].IBAN;
_Invoice.PayeeFinancialAccountName := _InvoiceDescriptor.CreditorBankAccounts[0].Name;
_Invoice.PayeeFinancialInstitutionBranch := _InvoiceDescriptor.CreditorBankAccounts[0].BIC;
_Invoice.PaymentFinancialAccount := _InvoiceDescriptor.CreditorBankAccounts[0].IBAN;
_Invoice.PaymentFinancialAccountName := _InvoiceDescriptor.CreditorBankAccounts[0].Name;
_Invoice.PaymentFinancialInstitutionBranch := _InvoiceDescriptor.CreditorBankAccounts[0].BIC;
end;

//TODO #SKONTO Type
_Invoice.PaymentTermsType := iptt_None;
for i := 0 to _InvoiceDescriptor.PaymentTermsList.Count-1 do
begin
if _InvoiceDescriptor.PaymentTermsList[i].DirectDebitMandateID <> '' then //Könnte Probleme bei mehrere Einträgen der Art geben
_Invoice.PaymentMandateID := _InvoiceDescriptor.PaymentTermsList[i].DirectDebitMandateID;
if (_InvoiceDescriptor.PaymentTermsList[i].ApplicableTradePaymentDiscountTerms.CalculationPercent = 0) and
(_InvoiceDescriptor.PaymentTermsList[i].ApplicableTradePaymentDiscountTerms.BasisAmount = 0) then
begin
Expand Down
Loading

0 comments on commit 493d1b3

Please sign in to comment.