Fix BR-DEX-02 not working (false negatives) if only a few InvoiceLines have SubInvoiceLines
As reported on GitHub,
https://github.com/itplr-kosit/validator-configuration-xrechnung/issues/48
This example should give true, but gives false:
<?xml version="1.0" encoding="UTF-8"?>
<!--
1. 10000.00
2. 1942.50
2.1. 840.00
2.2. 1102.50
3. 300.00
4. 330.00
4.1. 220.00
4.2. 110.00
-->
<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0#conformant#urn:xoev-de:kosit:extension:xrechnung_2.0</cbc:CustomizationID>
<cbc:ID>Entwurf</cbc:ID>
<cbc:IssueDate>2020-12-02</cbc:IssueDate>
<cbc:InvoiceTypeCode>875</cbc:InvoiceTypeCode>
<cbc:Note>Aktenzeichen/Kostenstelle</cbc:Note>
<cbc:Note>Leistungsempfänger:
Mustermann GmbH
Musterstr. 36
80584 Musterstadt
</cbc:Note>
<cbc:Note>Nicht unternehmerische (private) Leistungsempfänger bzw. Unternehmer, die Leistungen für ihren Privatbereich beziehen, sind gesetzlich verpflichtet, diese Rechnung zwei Jahre lang aufzubewahren. Die Aufbewahrungsfrist beginnt mit dem 31.12. des Kalenderjahres, in dem die Rechnung ausgestellt wurde.Nicht unternehmerische (private) Leistungsempfänger bzw. Unternehmer, die Leistungen für ihren Privatbereich beziehen, sind gesetzlich verpflichtet, diese Rechnung zwei Jahre lang aufzubewahren. Die Aufbewahrungsfrist beginnt mit dem 31.12. des Kalenderjahres, in dem die Rechnung ausgestellt wurde.</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>123</cbc:BuyerReference>
<cac:InvoicePeriod>
<cbc:StartDate>2020-11-01</cbc:StartDate>
<cbc:EndDate>2020-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderReference>
<cbc:ID>456</cbc:ID>
<cbc:SalesOrderID>Auftragsnummer C1</cbc:SalesOrderID>
</cac:OrderReference>
<cac:ProjectReference>
<cbc:ID>204IS070CS - Tiefgaragensanierung Schmorellstraße 6, 8 und 10, Unteraching</cbc:ID>
</cac:ProjectReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID>456</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Mustermann Contractor GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterstr. 36</cbc:StreetName>
<cbc:CityName>Musterstadt</cbc:CityName>
<cbc:PostalZone>80584</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE/12/345/67890</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Mustermann Contractor GmbH</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Mustermann Contractor GmbH</cbc:Name>
<cbc:Telephone>+49823451620</cbc:Telephone>
<cbc:ElectronicMail>mail@example.org</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cac:PartyName>
<cbc:Name>Mustermann GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterstr. 36</cbc:StreetName>
<cbc:CityName>Musterstadt</cbc:CityName>
<cbc:PostalZone>80584</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Mustermann Contractor GmbH</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cbc:PaymentID>Entwurf</cbc:PaymentID>
<cac:PayeeFinancialAccount>
<cbc:ID>DE12345678912345678900</cbc:ID>
<cbc:Name>Mustermann Contractor GmbH</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>DEUXXXXXXXX</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>Zahlbar innerhalb von 14 Tagen nach Rechnungseingang ohne Abzug.</cbc:Note>
</cac:PaymentTerms>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>104</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Sicherheitseinbehalt</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>0.05</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">628.63</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">12572.50</cbc:BaseAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">2269.34</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">11943.87</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">2269.34</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">12572.50</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">11943.87</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">14213.21</cbc:TaxInclusiveAmount>
<cbc:AllowanceTotalAmount currencyID="EUR">628.63</cbc:AllowanceTotalAmount>
<cbc:PrepaidAmount currencyID="EUR">4760.00</cbc:PrepaidAmount>
<cbc:PayableAmount currencyID="EUR">9453.21</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">10000.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Honorar gem. Anlage I</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10000.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>2</cbc:ID>
<cbc:InvoicedQuantity unitCode="XPP">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1942.50</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Honorar besondere Leistungen/nach Stunden (inkl. 5% Nebenkosten)</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">1850.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">92.50</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1850.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
<cac:SubInvoiceLine>
<cbc:ID>2.1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">10.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">840.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Dipl.-Ing / M.Sc. (inkl. 5% Nebenkosten)</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">80.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">40.00</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">800.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
</cac:SubInvoiceLine>
<cac:SubInvoiceLine>
<cbc:ID>2.2</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">10.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1102.50</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>BEratender Ingenieur (inkl. 5% Nebenkosten)</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">105.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">52.50</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1050.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
</cac:SubInvoiceLine>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>3</cbc:ID>
<cbc:InvoicedQuantity unitCode="XPP">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">300.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Honorar pauschal</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">300.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>4</cbc:ID>
<cbc:InvoicedQuantity unitCode="XPP">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">330.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Rechnungen Nachunternehmerleistungen (inkl. 10% Nachunternehmerzuschlag)</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">300.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">30.00</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">300.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
<cac:SubInvoiceLine>
<cbc:ID>4.1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">220.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>xxxx vom 01.03.2020 (inkl. 10% Nachunternehmerzuschlag)</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">200.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">20.00</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">200.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
</cac:SubInvoiceLine>
<cac:SubInvoiceLine>
<cbc:ID>4.2</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">110.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>xxxx vom 01.02.2020 (inkl. 10% Nachunternehmerzuschlag)</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">10.00</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">100.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
</cac:SubInvoiceLine>
</cac:InvoiceLine>
</ubl:Invoice>
Need to include this in tests and correct the rule.
Pre-Work is:
count(//cac:SubInvoiceLine),
'should be true!!!',
count(//cac:SubInvoiceLine) > 0 or (sum(./cac:InvoiceLine/xs:decimal(cbc:LineExtensionAmount)) = sum(child::cac:InvoiceLine/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))) and (count(//cac:SubInvoiceLine[xs:decimal(cbc:LineExtensionAmount) = sum(child::cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))]) = count(//cac:SubInvoiceLine[count(cac:SubInvoiceLine) > 0]))
,
'test 1',
/ubl:Invoice/cac:InvoiceLine[ exists (./cac:SubInvoiceLine) ] ,
'zeige betrag jeder invoiceline, die (eine) subinvoiceline hat',
/ubl:Invoice//cac:InvoiceLine[ 2 ]/xs:decimal(cbc:LineExtensionAmount) ,
'die summer al der subinvoicelines',
sum(/ubl:Invoice/cac:InvoiceLine[2]/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount)),
'ist das gleich?',
/ubl:Invoice/cac:InvoiceLine[ 2 ]/xs:decimal(cbc:LineExtensionAmount) = sum(/ubl:Invoice/cac:InvoiceLine[2]/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount)),
'part 1 ',
every $invoiceline in /ubl:Invoice/cac:InvoiceLine[ exists (./cac:SubInvoiceLine) ] satisfies
$invoiceline/xs:decimal(cbc:LineExtensionAmount)
=
sum($invoiceline/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))
,
'part 2',
sum(/ubl:Invoice/child::cac:InvoiceLine/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount)),
'part 3',
count(//cac:SubInvoiceLine[xs:decimal(cbc:LineExtensionAmount)]),
'part 4: yaehle alle subinvo deren amounts = der summer der amounts der kinder ist',
count( //cac:SubInvoiceLine [
xs:decimal(cbc:LineExtensionAmount) =
sum(child::cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))
]
),
'part 5',
count(
//cac:SubInvoiceLine [
count(cac:SubInvoiceLine) > 0
])