PyCheval 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pycheval/__init__.py ADDED
@@ -0,0 +1,15 @@
1
+ from typing import Final
2
+
3
+ from .exc import * # noqa: F403
4
+ from .format import format_invoice_as_text as format_invoice_as_text
5
+ from .generate import (
6
+ generate as generate,
7
+ generate_et as generate_et,
8
+ )
9
+ from .model import * # noqa: F403
10
+ from .money import Money as Money
11
+ from .parse import parse_xml as parse_xml
12
+ from .pdf_parse import parse_pdf as parse_pdf
13
+
14
+ FACTURX_VERSION: Final = "1.0.07"
15
+ ZUGFERD_VERSION: Final = "2.3"
pycheval/_locale.py ADDED
@@ -0,0 +1,20 @@
1
+ import gettext
2
+ from collections.abc import Callable
3
+ from pathlib import Path
4
+
5
+ LOCALE_PATH = Path(__file__).parent / "locale"
6
+
7
+
8
+ def setup_locale() -> Callable[[str], str]:
9
+ """Setup the gettext translation function in a module.
10
+
11
+ Usage:
12
+
13
+ from ._locale import setup_locale
14
+ _ = setup_locale()
15
+
16
+ print(_("Hello, World!"))
17
+ """
18
+
19
+ t = gettext.translation("pycheval", localedir=LOCALE_PATH, fallback=True)
20
+ return t.gettext
pycheval/const.py ADDED
@@ -0,0 +1,18 @@
1
+ """
2
+ XML Utilities for PyCheval
3
+ """
4
+
5
+ URN_MINIMUM_PROFILE = "urn:factur-x.eu:1p0:minimum"
6
+ URN_BASIC_WL_PROFILE = "urn:factur-x.eu:1p0:basicwl"
7
+ URN_BASIC_PROFILE = (
8
+ "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic"
9
+ )
10
+ URN_EN16931_PROFILE = "urn:cen.eu:en16931:2017"
11
+ URN_EXTENDED_PROFILE = (
12
+ "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended"
13
+ )
14
+ URN_XRECHNUNG_PROFILE = "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.1" # noqa: E501
15
+
16
+ NS_CII = "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
17
+ NS_RAM = "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" # noqa: E501
18
+ NS_UDT = "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
pycheval/countries.py ADDED
@@ -0,0 +1,6 @@
1
+ import re
2
+
3
+
4
+ def validate_iso_3166_1_alpha_2(code: str) -> bool:
5
+ """Validate an ISO 3166-1 country code in ALPHA-2 format."""
6
+ return re.match(r"^[A-Z]{2}$", code) is not None
pycheval/exc.py ADDED
@@ -0,0 +1,46 @@
1
+ class FacturXError(Exception):
2
+ """Base class for Factur-X exceptions."""
3
+
4
+
5
+ class PDFError(FacturXError):
6
+ """Base class for PDF processing exceptions."""
7
+
8
+
9
+ class PDFParseError(FacturXError):
10
+ """Raise when a PDF file cannot be processed."""
11
+
12
+
13
+ class NoFacturXError(PDFParseError):
14
+ """Raised when a PDF file does not contain a Factur-X XML file."""
15
+
16
+
17
+ class ModelError(FacturXError):
18
+ """Raised when a Factur-X model is invalid."""
19
+
20
+
21
+ class FacturXParseError(FacturXError):
22
+ """Base class for Factur-X parsing exceptions."""
23
+
24
+
25
+ class XMLParseError(FacturXParseError):
26
+ """Raised when an XML file cannot be parsed."""
27
+
28
+
29
+ class NotFacturXError(FacturXParseError):
30
+ """Raised when an XML file is not a Factur-X file."""
31
+
32
+
33
+ class UnsupportedProfileError(FacturXParseError):
34
+ """Raised when a Factur-X file uses an unsupported profile."""
35
+
36
+
37
+ class InvalidXMLError(FacturXParseError):
38
+ """Raised when a Factur-X XML file has the wrong structure."""
39
+
40
+
41
+ class InvalidProfileError(FacturXParseError):
42
+ """Raised when a Factur-X file is invalid for the specified profile."""
43
+
44
+ def __init__(self, profile_name: str, message: str) -> None:
45
+ super().__init__(message)
46
+ self.profile_name = profile_name