package com.alexanderlogistics.einvoice; import org.imixs.workflow.exceptions.PluginException; /** * Single source of truth for the mapping between CargoSoft VAT codes and the * Polish KSeF FA(3) XML schema fields. *

* Each enum constant maps a CargoSoft VAT code (as it appears in the * {@code cargosoft.vat.code} item of an invoice line) to: *

*

* The mapping is derived from the field-mapping document provided by the * Polish tax advisor of AGLP sp. z o.o. and reflects the requirements of the * Polish VAT act (UStG-PL) and the SAF-T reporting (JPK_V7). *

* Note on Java identifiers: The enum constants are prefixed with * {@code CARGO_} because plain numeric names like {@code 8} or {@code 23} are * not valid Java identifiers. The CargoSoft code itself is held as a String * field and matches the original code unchanged ({@code "8"}, {@code "23"}). *

* Mixed code "023": The CargoSoft code {@code 023} is intentionally * NOT defined here. It is a CargoSoft-internal mixed code (either 0% or 23%) * for which no deterministic mapping exists. Such codes will trigger a * {@link PluginException} via {@link #fromCargosoftCode(String)}. * * @see FA(3) XSD * schema */ public enum TaxCode { /** Standard tax rate 23% (Art. 41 sec. 1 / Art. 146ef UStG-PL). */ CARGO_23("23", "23", "P_13_1", "P_14_1", "2"), /** First reduced tax rate 8% (Art. 41 sec. 2 UStG-PL). */ CARGO_8("8", "8", "P_13_2", "P_14_2", "2"), /** * Domestic 0% rate, services in Polish seaports (Art. 83 sec. 1 no. 9 UStG-PL). */ CARGO_0("0", "0 KR", "P_13_6_1", null, "2"), /** * Domestic 0% rate, shipping agency services (Art. 83 sec. 1 no. 17 UStG-PL). */ CARGO_01("01", "0 KR", "P_13_6_1", null, "2"), /** * Domestic 0% rate, forwarding services for export of goods (Art. 83 sec. 1 no. * 19 UStG-PL). */ CARGO_0E("0%E", "0 KR", "P_13_6_1", null, "2"), /** * Domestic 0% rate, other maritime transport services (Art. 83 sec. 1 no. 17 or * 20 UStG-PL). */ CARGO_0MR("0MR", "0 KR", "P_13_6_1", null, "2"), /** * Art. 83 ust. 1 pkt 23 ustawy o VAT — usługi transportu międzynarodowego (z * definicją z ust. 3) */ CARGO_023("023", "0 KR", "P_13_6_1", null, "2"), /** * Not subject to Polish VAT, B2B service to an EU taxable person * (Art. 28b + Art. 100 sec. 1 no. 4 UStG-PL). * Reportable in the EU recapitulative statement (VAT-UE / ZM). */ CARGO_NP("NP", "np II", "P_13_9", null, "1"), /** * Not subject to Polish VAT, customer outside the EU or transit * (Art. 28b UStG-PL, excluding Art. 100 sec. 1 no. 4). * NOT reportable in VAT-UE. */ CARGO_NPT("NPT", "np I", "P_13_8", null, "1"), CARGO_NP3("NP3", "np I", "P_13_8", null, "1"); private final String cargosoftCode; private final String p12Value; private final String netSummaryField; private final String vatSummaryField; private final String p18Value; TaxCode(String cargosoftCode, String p12Value, String netSummaryField, String vatSummaryField, String p18value) { this.cargosoftCode = cargosoftCode; this.p12Value = p12Value; this.netSummaryField = netSummaryField; this.vatSummaryField = vatSummaryField; this.p18Value = p18value; } /** * @return the original CargoSoft VAT code (e.g. "23", "0%E", "NP") */ public String getCargosoftCode() { return cargosoftCode; } /** * @return the value to be written into the {@code } element of a * {@code } block (e.g. "23", "0 KR", "np II") */ public String getP12Value() { return p12Value; } /** * @return the name of the target net summary tag in the {@code } * block (e.g. "P_13_1", "P_13_6_1", "P_13_9") */ public String getNetSummaryField() { return netSummaryField; } /** * @return the name of the target VAT summary tag in the {@code } * block (e.g. "P_14_1") or {@code null} for 0% / non-taxable codes */ public String getVatSummaryField() { return vatSummaryField; } public String getP18Value() { return p18Value; } /** * @return {@code true} if this code carries a non-zero VAT amount * (i.e. a VAT summary field exists); {@code false} otherwise */ public boolean hasVat() { return vatSummaryField != null; } /** * Resolves a CargoSoft VAT code string to the corresponding {@link TaxCode} * enum constant. *

* Throws a {@link PluginException} if the code is unknown, blank or * {@code null}. This is by design: an unmapped code MUST stop processing, * because writing the wrong summary field would silently produce an * invalid JPK_V7 entry while still passing KSeF XSD validation. * * @param cargosoftCode the value of {@code cargosoft.vat.code} from a * CargoSoft invoice line (e.g. "23", "NP") * @return the matching {@link TaxCode} enum constant * @throws PluginException if the code is unknown, blank or {@code null} */ public static TaxCode fromCargosoftCode(String cargosoftCode) throws PluginException { if (cargosoftCode == null || cargosoftCode.isBlank()) { throw new PluginException( TaxCode.class.getSimpleName(), "TAX_CODE_ERROR", "CargoSoft VAT code is null or blank - cannot map to KSeF tax field"); } for (TaxCode tc : values()) { if (tc.cargosoftCode.equals(cargosoftCode)) { return tc; } } throw new PluginException( TaxCode.class.getSimpleName(), "TAX_CODE_ERROR", "Unknown CargoSoft VAT code: '" + cargosoftCode + "' - no mapping to a KSeF FA(3) tax field defined"); } }