stephanstapel / ZUGFeRD-csharp

C# assembly for creating and reading ZUGFeRD invoices
Apache License 2.0
170 stars 93 forks source link

Problem beim Auslesen der Mengeneinheiten in einer Position #311

Closed landrix closed 2 months ago

landrix commented 2 months ago

Hallo, ich schreibe mal auf Deutsch. In einem TradelineItem gibt es mehrere Stellen mit der Angabe einer Mengeneinheit. Ich denke, hier geht die Bibliothek falsch damit um

https://github.com/stephanstapel/ZUGFeRD-csharp/blob/0a8669d8e882f1a26d5b40ef491474039cf1c214/ZUGFeRD/InvoiceDescriptor22CIIReader.cs#L441

Da wären die Mengeneinheit der Bruttoeinzelpreis-Preiseinheit, der Nettoeinzelpreis-Preiseinheit und die eigentliche Mengeneinheit der Position. ZUGFeRD-charp liest die Mengeneinheit UnitCode aus der Preiseinheit des Einzelpreises, je nachdem welcher vorhanden ist

UnitCode = default(QuantityCodes).FromString(_nodeAsString(tradeLineItem, ".//ram:BasisQuantity/@unitCode", nsmgr)),

Richtiger wäre die Mengeneinheit aus ram:BilledQuantity auszulesen

<ram:BilledQuantity unitCode="C62">1</ram:BilledQuantity>

Da eine Änderung hier aber zu einem breaking change führen würde, wäre es die beste Option UnitCode in BilledQuantityUnitCode umzubenennen und korrekt auszulesen und die Mengeneinheiten der Preiseinheiten separat abzubilden.

Was meint ihr?

Hier mal ein Beispiel mit allen Optionen:

    <ram:IncludedSupplyChainTradeLineItem>
                                      <ram:AssociatedDocumentLineDocument>
                                                    <ram:LineID>200</ram:LineID>
                                                    <ram:IncludedNote>
                                                                   <ram:Content>123123123-001-200</ram:Content>
                                                    </ram:IncludedNote>
                                      </ram:AssociatedDocumentLineDocument>
                                      <ram:SpecifiedTradeProduct>
                                                <ram:SellerAssignedID>991992993</ram:SellerAssignedID>
                                                    <ram:Name>Betätigungsleiter f. WC-Kasten</ram:Name>
                                      </ram:SpecifiedTradeProduct>
                                      <ram:SpecifiedLineTradeAgreement>
                                                    <ram:AdditionalReferencedDocument>
                                                              <ram:IssuerAssignedID>123123123-001</ram:IssuerAssignedID>
                                                              <ram:TypeCode>380</ram:TypeCode>
                                                              <ram:ReferenceTypeCode>AAJ</ram:ReferenceTypeCode>
                                                    </ram:AdditionalReferencedDocument>
                                                    <ram:GrossPriceProductTradePrice>
                                                              <ram:ChargeAmount>12.6</ram:ChargeAmount>
                                                                   <ram:BasisQuantity unitCode="C62">1</ram:BasisQuantity>
                                                              <ram:AppliedTradeAllowanceCharge>
                                                                                 <ram:ChargeIndicator>
                                                                                           <udt:Indicator>false</udt:Indicator>
                                                                                 </ram:ChargeIndicator>
                                                                             <ram:CalculationPercent>45</ram:CalculationPercent>
                                                                             <ram:ActualAmount>5.67</ram:ActualAmount>
                                                                             <ram:Reason>Rabatt1</ram:Reason>
                                                              </ram:AppliedTradeAllowanceCharge>
                                                    </ram:GrossPriceProductTradePrice>
                                                    <ram:NetPriceProductTradePrice>
                                                              <ram:ChargeAmount>6.93</ram:ChargeAmount>
                                                                   <ram:BasisQuantity unitCode="C62">1</ram:BasisQuantity>
                                                    </ram:NetPriceProductTradePrice>
                                      </ram:SpecifiedLineTradeAgreement>
                                      <ram:SpecifiedLineTradeDelivery>
                                                    <ram:BilledQuantity unitCode="C62">1</ram:BilledQuantity>
                                                <ram:DeliveryNoteReferencedDocument>
                                                              <ram:IssuerAssignedID>123123123-001</ram:IssuerAssignedID>
                                                                   <ram:LineID>200</ram:LineID>
                                                                   <ram:FormattedIssueDateTime>
                                                                                 <qdt:DateTimeString format="102">20240620/qdt:DateTimeString>
                                                                   </ram:FormattedIssueDateTime>
                                                </ram:DeliveryNoteReferencedDocument>
                                      </ram:SpecifiedLineTradeDelivery>
                                      <ram:SpecifiedLineTradeSettlement>
                                                    <ram:ApplicableTradeTax>
                                                              <ram:TypeCode>VAT</ram:TypeCode>
                                                              <ram:CategoryCode>S</ram:CategoryCode>
                                                              <ram:RateApplicablePercent>19</ram:RateApplicablePercent>
                                                    </ram:ApplicableTradeTax>
                                                <ram:SpecifiedTradeSettlementLineMonetarySummation>
                                                              <ram:LineTotalAmount>6.93</ram:LineTotalAmount>
                                                </ram:SpecifiedTradeSettlementLineMonetarySummation>
                                      </ram:SpecifiedLineTradeSettlement>
                          </ram:IncludedSupplyChainTradeLineItem>
stephanstapel commented 2 months ago

Gerne. Kennst Du einen realen Fall, in dem sich die Mengeneinheiten voneinander unterscheiden? Das wäre interessant kennenzulernen.

landrix commented 2 months ago
  <ram:IncludedSupplyChainTradeLineItem>
      <ram:AssociatedDocumentLineDocument>
        <ram:LineID>1</ram:LineID>
      </ram:AssociatedDocumentLineDocument>
      <ram:SpecifiedSupplyChainTradeAgreement>
        <ram:BuyerOrderReferencedDocument>
          <ram:IssueDateTime>2022-08-26T00:00:00</ram:IssueDateTime>
          <ram:ID>B111111</ram:ID>
        </ram:BuyerOrderReferencedDocument>
        <ram:AdditionalReferencedDocument>
          <ram:LineID>1</ram:LineID>
          <ram:ID>123455</ram:ID>
          <ram:ReferenceTypeCode>AER</ram:ReferenceTypeCode>
        </ram:AdditionalReferencedDocument>
        <ram:GrossPriceProductTradePrice>
          <ram:ChargeAmount currencyID="EUR">30.4000</ram:ChargeAmount>
          <ram:BasisQuantity unitCode="MTR">100.0000</ram:BasisQuantity>
          <ram:AppliedTradeAllowanceCharge>
            <ram:ChargeIndicator>
              <udt:Indicator>true</udt:Indicator>
            </ram:ChargeIndicator>
            <ram:BasisAmount currencyID="EUR">0.5000</ram:BasisAmount>
            <ram:BasisQuantity unitCode="MTR">100.0000</ram:BasisQuantity>
            <ram:ActualAmount currencyID="EUR">50.0000</ram:ActualAmount>
            <ram:Reason>Kupferzuschlag</ram:Reason>
          </ram:AppliedTradeAllowanceCharge>
        </ram:GrossPriceProductTradePrice>
        <ram:NetPriceProductTradePrice>
          <ram:ChargeAmount currencyID="EUR">80.1200</ram:ChargeAmount>
          <ram:BasisQuantity unitCode="MTR">100.0000</ram:BasisQuantity>
        </ram:NetPriceProductTradePrice>
      </ram:SpecifiedSupplyChainTradeAgreement>
      <ram:SpecifiedSupplyChainTradeDelivery>
        <ram:BilledQuantity unitCode="MTR">50.0000</ram:BilledQuantity>
        <ram:DeliveryNoteReferencedDocument>
          <ram:IssueDateTime>2022-08-26T00:00:00</ram:IssueDateTime>
          <ram:ID>2271222</ram:ID>
        </ram:DeliveryNoteReferencedDocument>
      </ram:SpecifiedSupplyChainTradeDelivery>
      <ram:SpecifiedSupplyChainTradeSettlement>
        <ram:ApplicableTradeTax>
          <ram:TypeCode>VAT</ram:TypeCode>
          <ram:CategoryCode>S</ram:CategoryCode>
          <ram:ApplicablePercent>19.00</ram:ApplicablePercent>
        </ram:ApplicableTradeTax>
        <ram:SpecifiedTradeSettlementMonetarySummation>
          <ram:LineTotalAmount currencyID="EUR">40.06</ram:LineTotalAmount>
        </ram:SpecifiedTradeSettlementMonetarySummation>
      </ram:SpecifiedSupplyChainTradeSettlement>
      <ram:SpecifiedTradeProduct>
        <ram:SellerAssignedID>12312311</ram:SellerAssignedID>
        <ram:Name>NYM-J  5x1,5 050</ram:Name>
        <ram:Description>NYM-J  5x1,5 050</ram:Description>
        <ram:ApplicableProductCharacteristic>
          <ram:TypeCode>COMMISSION</ram:TypeCode>
          <ram:Description>Kommissionstext</ram:Description>
          <ram:Value>123456 Meier</ram:Value>
        </ram:ApplicableProductCharacteristic>
        <ram:ApplicableProductCharacteristic>
          <ram:TypeCode>COMMISSION</ram:TypeCode>
          <ram:Description>Kommissionsnummer</ram:Description>
          <ram:Value>123456 Wiese</ram:Value>
        </ram:ApplicableProductCharacteristic>
        <ram:ApplicableProductCharacteristic>
          <ram:TypeCode>TRADING_UNIT</ram:TypeCode>
          <ram:Description>Kupferzuschlag</ram:Description>
          <ram:Value>24,86</ram:Value>
        </ram:ApplicableProductCharacteristic>
      </ram:SpecifiedTradeProduct>
    </ram:IncludedSupplyChainTradeLineItem>
stephanstapel commented 2 months ago

Ich verstehe das leider nicht ganz. Alle UnitCodes in dem Beispiel sind MTR. D.h. es hätte keine Auswirkung, wenn ein anderes Element ausgelesen würde, oder?

Die richtige Alternative wäre ansonsten die Einführung einer Quantity-Klasse, die sowohl den Wert als auch die Einheit enthält inklusive Operator-Überladung für Addition, Subtraktion, Größer/ Kleiner/ Gleichheits-Vergleich.

landrix commented 2 months ago

Ich hab mal nachgeschaut, beim Schreiben wird die gelesene Mengeneinheit bei allen drei Teilen geschrieben. Gelesen wird sie wie gesagt aus GrossPriceProductTradePrice. Wenn GrossPriceProductTradePrice nicht vorhanden ist, dann fehlt UnitCode komplett. Ich würde deshalb den Wert aus 1</ram:BilledQuantity> lesen. Der sollte immer da sein.

Der Fall mit unterschiedlichen Mengeneinheiten müsste man mal weiter beobachten. Theoretisch ist es ja möglich. Hab jetzt aber auch noch kein Beispiel gesehen.

stephanstapel commented 2 months ago

ah, ok. Den Wert aus einem anderen Feld auslesen halte ich für kein besonders großes Problem. Mehrere Mengeneinheiten an einer Position zu haben, fände ich ziemlich unglücklich. Da muss es ja dann vor allem erst einmal jemanden geben, der dagegen programmiert und sich überlegt, was man in einem solchen Fall macht.