Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnitCodes updated with full PEPPOL list as of 2025-01-06 #538

Closed

Conversation

tobitege
Copy link
Contributor

@tobitege tobitege commented Jan 6, 2025

Resolves #493

  • Took the current PEPPOL list as of today from the official website and converted it appropriately
    into a full enum list including comments (used a small Python script to automate that). 😄
  • Removed an old comment referencing a 3rd party website which is irrelevant now.

@stephanstapel
Copy link
Owner

The component intentionally not covers all available codes since this makes creating or processing invoices almost impossible as you can't find anything.

@tobitege
Copy link
Contributor Author

tobitege commented Jan 6, 2025

Moin Stephan,
da musst du mich mal abholen, was du mit "as you can't find anything" meinst? 😄
Die Komponente ist ja nicht da, um zu beurteilen, ob ein Code einem gefällt, sondern muss alle gültigen erlauben.
Alles Andere ist m.E. Sache der Programmlogik des anwendenden Entwicklers.
Wir haben in der Vergangenheit auch immer wieder die Erfahrung machen müssen, dass auch wenn die
eigene Software für vielleicht eine bestimmte Branche ist, es plötzlich doch entweder Kunden oder auch
Lieferanten gibt, die halt doch "unerwartete" Codes (für unsere Lösung zu dem Zeitpunkt) verwenden.
Die Rechnung muss ja trotzdem eingelesen werden mit dem Code. 🤔

@stephanstapel
Copy link
Owner

Moin Stephan, da musst du mich mal abholen, was du mit "as you can't find anything" meinst? 😄 Die Komponente ist ja nicht da, um zu beurteilen, ob ein Code einem gefällt, sondern muss alle gültigen erlauben. Alles Andere ist m.E. Sache der Programmlogik des anwendenden Entwicklers. Wir haben in der Vergangenheit auch immer wieder die Erfahrung machen müssen, dass auch wenn die eigene Software für vielleicht eine bestimmte Branche ist, es plötzlich doch entweder Kunden oder auch Lieferanten gibt, die halt doch "unerwartete" Codes (für unsere Lösung zu dem Zeitpunkt) verwenden. Die Rechnung muss ja trotzdem eingelesen werden mit dem Code. 🤔

ja, das ist richtig. Sollten Codes fehlen, ergänze ich die jederzeit gerne oder nehme den Pull Request an. An einem schlüssigen Konzept, wie die enums übersichtlich bleiben aber man trotzdem alles verarbeiten kann, arbeite ich aktuell.

@tobitege
Copy link
Contributor Author

tobitege commented Jan 6, 2025

Was hältst du von der Idee, im Source oberhalb vom Enum einfach einen längeren Kommentarblock mit den gängigsten Codes mit deren deutschen Beschreibung aufzuführen (pro Zeile ein Code + Kurzbeschreibung)?
Dies könnte dann immer noch der Orientierung und "Schnellsuche" dienen, aber technisch den Standard abdecken, ohne irgendwas "herum" zu entwickeln.

@stephanstapel
Copy link
Owner

das ist eine gute Idee. Auch die gleiche Beschreibung auf der readme-Seite wäre sicher sinnvoll.
Dieser Ansatz ist ein ziemlicher Missbrauch bzw. eher eine Missachtung von eleganteren Konstrukten, bietet dafür aber neue Möglichkeiten:

public class TaxCategoryCode
{
    public string Code { get; }
    public string Description { get; }

    private TaxCategoryCode(string code, string description)
    {
        Code = code;
        Description = description;
    }

    // Vordefinierte Werte
    public static readonly TaxCategoryCode Unknown = new TaxCategoryCode("Unknown", "Default value, not specified");
    public static readonly TaxCategoryCode A = new TaxCategoryCode("A", "Mixed tax rate");
    public static readonly TaxCategoryCode AA = new TaxCategoryCode("AA", "Lower rate");
    public static readonly TaxCategoryCode AB = new TaxCategoryCode("AB", "Exempt for resale");
    public static readonly TaxCategoryCode AC = new TaxCategoryCode("AC", "Value Added Tax (VAT) not now due for payment");
    public static readonly TaxCategoryCode AD = new TaxCategoryCode("AD", "Value Added Tax (VAT) due from a previous invoice");

bestehender Code wäre weiterverwendbar und man könnte einen Umgang finden mit Kategorien, die nicht als static readonly-Variable vorhanden sind.

@tobitege
Copy link
Contributor Author

tobitege commented Jan 6, 2025

Ich finde, dass Enums für diese Werte z.T. kaum hilfreich sind, es sei denn man programmiert mit expliziten Werten,
damit der Compiler die Prüfung für uns macht.
Aber realistischer ist, dass mein Programm "irgendeinen" Wert liest und nun rausfinden muss, ob der existiert oder nicht.

Hier wäre eine Alternative zu der obigen TaxCategoryCode Klasse, die ich einfach mal o1 habe schreiben lassen:

using System;

public static class TaxCategoryCodeExtensions
{
    /// <summary>
    /// Prüft, ob der übergebene Code ein gültiger TaxCategoryCode ist.
    /// </summary>
    /// <param name="code">Der Code, z.B. "AA" oder "AB".</param>
    /// <returns>true, wenn vorhanden, sonst false.</returns>
    public static bool IsValidTaxCategory(this string code)
    {
        return TaxCategoryCodes.IsValidCode(code);
    }

    /// <summary>
    /// Ruft die Beschreibung eines bestimmten Codes ab,
    /// oder "Unknown Code", falls nicht vorhanden.
    /// </summary>
    /// <param name="code">Der Code, z.B. "AA" oder "AB".</param>
    /// <returns>Die Beschreibung des Codes oder "Unknown Code".</returns>
    public static string GetTaxCategoryDescription(this string code)
    {
        return TaxCategoryCodes.GetDescription(code);
    }
}

public static class TaxCategoryCodes
{
    // Beispiel-Inhalte aus dem vorigen Beitrag
    private static readonly SortedDictionary<string, string> _codes 
        = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase)
    {
        { "Unknown", "Default value, not specified" },
        { "A",       "Mixed tax rate" },
        { "AA",      "Lower rate" },
        { "AB",      "Exempt for resale" },
        { "AC",      "VAT not now due for payment" },
        { "AD",      "VAT due from a previous invoice" }
    };

    public static IReadOnlyDictionary<string, string> Codes => _codes;

    public static bool IsValidCode(string code) => _codes.ContainsKey(code);

    public static string GetDescription(string code)
    {
        return _codes.TryGetValue(code, out var description)
            ? description
            : "Unknown Code";
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine("AA".IsValidTaxCategory());              // true
        Console.WriteLine("ZZZZ".IsValidTaxCategory());            // false
        Console.WriteLine("AA".GetTaxCategoryDescription());       // "Lower rate"
        Console.WriteLine("ZZZZ".GetTaxCategoryDescription());     // "Unknown Code"
    }
}

In deiner Variante fände ich es schwierig, einen gültigen Code zu finden/suchen, wenn du einen Wert gelesen hast.

Aber das ist jetzt nicht als Änderungswunsch von mir zu verstehen, einfach nur eine Idee.

@tobitege
Copy link
Contributor Author

tobitege commented Jan 6, 2025

Ich habe mal "Most commonly used codes" als Kommentar hinzugefügt im Code.
Wenn ich diese Liste mit in das README einarbeiten soll, sag einfach Bescheid.

@tobitege
Copy link
Contributor Author

tobitege commented Jan 7, 2025

Closing for now.

@tobitege tobitege closed this Jan 7, 2025
@tobitege tobitege deleted the issue-493-quantitycodes branch January 19, 2025 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants