From a1fc6bdc0b11c531f642d34953951dc6ff06d7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Fri, 14 Apr 2023 11:39:10 +0200 Subject: [PATCH 1/5] :art: specify line item version --- mindee/documents/financial/financial_document_v1.py | 6 +++--- mindee/documents/invoice/invoice_v4.py | 6 +++--- mindee/documents/invoice/{line_item.py => line_item_v4.py} | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename mindee/documents/invoice/{line_item.py => line_item_v4.py} (98%) diff --git a/mindee/documents/financial/financial_document_v1.py b/mindee/documents/financial/financial_document_v1.py index aec34ec3..c37d412c 100644 --- a/mindee/documents/financial/financial_document_v1.py +++ b/mindee/documents/financial/financial_document_v1.py @@ -1,7 +1,7 @@ from typing import List, Optional, TypeVar from mindee.documents.base import Document, TypeApiPrediction, clean_out_string -from mindee.documents.invoice.line_item import InvoiceLineItem +from mindee.documents.invoice.line_item_v4 import InvoiceLineItemV4 from mindee.fields.amount import AmountField from mindee.fields.company_registration import CompanyRegistrationField from mindee.fields.date import DateField @@ -44,7 +44,7 @@ class FinancialDocumentV1(Document): """Customer company registration numbers""" supplier_payment_details: List[PaymentDetails] """Payment details""" - line_items: List[InvoiceLineItem] + line_items: List[InvoiceLineItemV4] """Details of line items""" tip: AmountField """Total amount of tip and gratuity.""" @@ -126,7 +126,7 @@ def _build_from_api_prediction( for payment_detail in api_prediction["supplier_payment_details"] ] self.line_items = [ - InvoiceLineItem(prediction=line_item, page_n=page_n) + InvoiceLineItemV4(prediction=line_item, page_n=page_n) for line_item in api_prediction["line_items"] ] self.total_amount = AmountField(api_prediction["total_amount"], page_n=page_n) diff --git a/mindee/documents/invoice/invoice_v4.py b/mindee/documents/invoice/invoice_v4.py index 27603d5c..1e719a30 100644 --- a/mindee/documents/invoice/invoice_v4.py +++ b/mindee/documents/invoice/invoice_v4.py @@ -2,7 +2,7 @@ from mindee.documents.base import Document, TypeApiPrediction, clean_out_string from mindee.documents.invoice import checks, reconstruct -from mindee.documents.invoice.line_item import InvoiceLineItem +from mindee.documents.invoice.line_item_v4 import InvoiceLineItemV4 from mindee.fields.amount import AmountField from mindee.fields.company_registration import CompanyRegistrationField from mindee.fields.date import DateField @@ -45,7 +45,7 @@ class InvoiceV4(Document): """Customer company registration numbers""" supplier_payment_details: List[PaymentDetails] """Payment details""" - line_items: List[InvoiceLineItem] + line_items: List[InvoiceLineItemV4] """Details of line items""" def __init__( @@ -116,7 +116,7 @@ def _build_from_api_prediction( for payment_detail in api_prediction["supplier_payment_details"] ] self.line_items = [ - InvoiceLineItem(prediction=line_item, page_n=page_n) + InvoiceLineItemV4(prediction=line_item, page_n=page_n) for line_item in api_prediction["line_items"] ] self.total_amount = AmountField(api_prediction["total_amount"], page_n=page_n) diff --git a/mindee/documents/invoice/line_item.py b/mindee/documents/invoice/line_item_v4.py similarity index 98% rename from mindee/documents/invoice/line_item.py rename to mindee/documents/invoice/line_item_v4.py index 1a084b77..b6e134f8 100644 --- a/mindee/documents/invoice/line_item.py +++ b/mindee/documents/invoice/line_item_v4.py @@ -3,7 +3,7 @@ from mindee.fields.base import FieldPositionMixin, TypePrediction, float_to_string -class InvoiceLineItem(FieldPositionMixin): +class InvoiceLineItemV4(FieldPositionMixin): product_code: Optional[str] """The product code referring to the item.""" description: Optional[str] From 104f8c00369b082160501afef72d3f970662aee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Fri, 14 Apr 2023 13:53:39 +0200 Subject: [PATCH 2/5] :sparkles: support for receipt v5 --- mindee/cli.py | 2 +- mindee/client.py | 5 + mindee/documents/__init__.py | 9 +- mindee/documents/receipt/__init__.py | 1 + mindee/documents/receipt/line_item_v5.py | 58 +++++++++ mindee/documents/receipt/receipt_v5.py | 156 +++++++++++++++++++++++ tests/data | 2 +- tests/documents/test_receipt_v5.py | 64 ++++++++++ 8 files changed, 294 insertions(+), 3 deletions(-) create mode 100644 mindee/documents/receipt/line_item_v5.py create mode 100644 mindee/documents/receipt/receipt_v5.py create mode 100644 tests/documents/test_receipt_v5.py diff --git a/mindee/cli.py b/mindee/cli.py index 8b4c6114..e273aed7 100644 --- a/mindee/cli.py +++ b/mindee/cli.py @@ -28,7 +28,7 @@ class CommandConfig(Generic[TypeDoc]): ), "receipt": CommandConfig( help="Expense Receipt", - doc_class=documents.TypeReceiptV4, + doc_class=documents.TypeReceiptV5, ), "passport": CommandConfig( help="Passport", diff --git a/mindee/client.py b/mindee/client.py index 8f1b63f0..2e177d4e 100644 --- a/mindee/client.py +++ b/mindee/client.py @@ -221,6 +221,11 @@ def _init_default_endpoints(self) -> None: url_name="expense_receipts", version="4", ), + ConfigSpec( + doc_class=documents.ReceiptV5, + url_name="expense_receipts", + version="5", + ), ConfigSpec( doc_class=documents.FinancialDocumentV1, url_name="financial_document", diff --git a/mindee/documents/__init__.py b/mindee/documents/__init__.py index 0780112f..c84fb1cb 100644 --- a/mindee/documents/__init__.py +++ b/mindee/documents/__init__.py @@ -11,7 +11,14 @@ from mindee.documents.invoice import InvoiceV3, InvoiceV4, TypeInvoiceV3, TypeInvoiceV4 from mindee.documents.passport import PassportV1, TypePassportV1 from mindee.documents.proof_of_address import ProofOfAddressV1, TypeProofOfAddressV1 -from mindee.documents.receipt import ReceiptV3, ReceiptV4, TypeReceiptV3, TypeReceiptV4 +from mindee.documents.receipt import ( + ReceiptV3, + ReceiptV4, + ReceiptV5, + TypeReceiptV3, + TypeReceiptV4, + TypeReceiptV5, +) from mindee.documents.shipping_container import ( ShippingContainerV1, TypeShippingContainerV1, diff --git a/mindee/documents/receipt/__init__.py b/mindee/documents/receipt/__init__.py index cfe41678..b5962b91 100644 --- a/mindee/documents/receipt/__init__.py +++ b/mindee/documents/receipt/__init__.py @@ -1,2 +1,3 @@ from .receipt_v3 import ReceiptV3, TypeReceiptV3 from .receipt_v4 import ReceiptV4, TypeReceiptV4 +from .receipt_v5 import ReceiptV5, TypeReceiptV5 diff --git a/mindee/documents/receipt/line_item_v5.py b/mindee/documents/receipt/line_item_v5.py new file mode 100644 index 00000000..7f07e3c3 --- /dev/null +++ b/mindee/documents/receipt/line_item_v5.py @@ -0,0 +1,58 @@ +from typing import Optional + +from mindee.fields.base import FieldPositionMixin, TypePrediction, float_to_string + + +class ReceiptV5LineItem(FieldPositionMixin): + description: Optional[str] + """The item description.""" + quantity: Optional[float] + """The item quantity""" + unit_price: Optional[float] + """The item unit price.""" + total_amount: Optional[float] + """The item total amount.""" + confidence: float = 0.0 + """Confidence score""" + page_n: int + """The document page on which the information was found.""" + + def __init__( + self, + prediction: TypePrediction, + page_n: Optional[int] = None, + ): + self._set_position(prediction) + + if page_n is None: + self.page_n = prediction["page_id"] + else: + self.page_n = page_n + + try: + self.confidence = float(prediction["confidence"]) + except (KeyError, TypeError): + pass + + def to_opt_float(key: str) -> Optional[float]: + try: + return float(prediction[key]) + except TypeError: + return None + + self.description = prediction["description"] + self.quantity = to_opt_float("quantity") + self.unit_price = to_opt_float("unit_price") + self.total_amount = to_opt_float("total_amount") + + def __str__(self) -> str: + description = self.description or "" + if len(description) > 32: + description = description[:32] + "..." + row = [ + float_to_string(self.quantity), + float_to_string(self.unit_price), + float_to_string(self.total_amount), + description, + ] + return "{:<9} {:<9} {:<10} {}".format(*row) diff --git a/mindee/documents/receipt/receipt_v5.py b/mindee/documents/receipt/receipt_v5.py new file mode 100644 index 00000000..29257f13 --- /dev/null +++ b/mindee/documents/receipt/receipt_v5.py @@ -0,0 +1,156 @@ +from typing import List, Optional, TypeVar + +from mindee.documents.base import Document, TypeApiPrediction, clean_out_string +from mindee.documents.receipt.line_item_v5 import ReceiptV5LineItem +from mindee.fields.amount import AmountField +from mindee.fields.company_registration import CompanyRegistrationField +from mindee.fields.date import DateField +from mindee.fields.locale import LocaleField +from mindee.fields.tax import TaxField +from mindee.fields.text import TextField + + +class ReceiptV5(Document): + locale: LocaleField + """locale information""" + total_amount: AmountField + """The total amount paid including taxes, discounts, fees, tips, and gratuity.""" + date: DateField + """The date the purchase was made.""" + time: TextField + """Time of purchase with 24 hours formatting (HH:MM).""" + category: TextField + """The receipt category among predefined classes.""" + subcategory: TextField + """The receipt sub category among predefined classes for transport and food.""" + document_type: TextField + """Whether the document is an expense receipt or a credit card receipt.""" + supplier_name: TextField + """The name of the supplier or merchant.""" + supplier_phone_number: TextField + """The Phone number of the supplier or merchant.""" + supplier_address: TextField + """The address of the supplier or merchant.""" + supplier_company_registrations: List[CompanyRegistrationField] + """List of supplier company registrations or identifiers.""" + taxes: List[TaxField] + """List of tax lines information including: Amount, tax rate, tax base amount and tax code.""" + total_tax: AmountField + """The total amount of taxes.""" + total_net: AmountField + """The total amount excluding taxes.""" + tip: AmountField + """The total amount of tip and gratuity.""" + line_items: List[ReceiptV5LineItem] + """Full extraction of lines, including: description, quantity, unit price and total.""" + + def __init__( + self, + api_prediction=None, + input_source=None, + page_n: Optional[int] = None, + ): + """ + Receipt document. + + :param api_prediction: Raw prediction from HTTP response + :param input_source: Input object + :param page_n: Page number for multi pages pdf input + """ + super().__init__( + input_source=input_source, + document_type="receipt", + api_prediction=api_prediction, + page_n=page_n, + ) + self._build_from_api_prediction(api_prediction["prediction"], page_n=page_n) + + def _build_from_api_prediction( + self, api_prediction: TypeApiPrediction, page_n: Optional[int] = None + ) -> None: + """ + Build the document from an API response JSON. + + :param api_prediction: Raw prediction from HTTP response + :param page_n: Page number for multi pages pdf input + """ + self.locale = LocaleField(api_prediction["locale"], page_n=page_n) + self.total_amount = AmountField(api_prediction["total_amount"], page_n=page_n) + self.total_net = AmountField(api_prediction["total_net"], page_n=page_n) + self.total_tax = AmountField(api_prediction["total_tax"], page_n=page_n) + self.tip = AmountField(api_prediction["tip"], page_n=page_n) + self.date = DateField(api_prediction["date"], page_n=page_n) + self.category = TextField(api_prediction["category"], page_n=page_n) + self.subcategory = TextField(api_prediction["subcategory"], page_n=page_n) + self.document_type = TextField(api_prediction["document_type"], page_n=page_n) + self.supplier_name = TextField( + api_prediction["supplier_name"], value_key="value", page_n=page_n + ) + self.supplier_phone_number = TextField( + api_prediction["supplier_phone_number"], value_key="value", page_n=page_n + ) + self.supplier_address = TextField( + api_prediction["supplier_address"], value_key="value", page_n=page_n + ) + self.supplier_company_registrations = [ + CompanyRegistrationField(field_dict, page_n=page_n) + for field_dict in api_prediction["supplier_company_registrations"] + ] + self.time = TextField(api_prediction["time"], value_key="value", page_n=page_n) + self.taxes = [ + TaxField( + tax_prediction, + page_n=page_n, + value_key="value", + rate_key="rate", + code_key="code", + ) + for tax_prediction in api_prediction["taxes"] + ] + self.line_items = [ + ReceiptV5LineItem(prediction=line_item, page_n=page_n) + for line_item in api_prediction["line_items"] + ] + + def __str__(self) -> str: + taxes = "\n ".join(f"{t}" for t in self.taxes) + supplier_company_registrations = "; ".join( + [str(n.value) for n in self.supplier_company_registrations] + ) + line_items = "\n" + if self.line_items: + line_items = ( + "\n ========= ========= ========== ====================================" + "\n Quantity Price Amount Description" + "\n ========= ========= ========== ====================================" + ) + for item in self.line_items: + line_items += f"\n {item}" + line_items += "\n ========= ========= ========== ====================================\n" + + return clean_out_string( + "Receipt V5 Prediction\n=====================\n" + f":Filename: {self.filename or ''}\n" + f":Expense Locale: {self.locale}\n" + f":Total Amount: {self.total_amount}\n" + f":Total Excluding Taxes: {self.total_net}\n" + f":Tip and Gratuity: {self.tip}\n" + f":Purchase Date: {self.date}\n" + f":Purchase Time: {self.time}\n" + f":Expense Category: {self.category}\n" + f":Expense Sub Category: {self.subcategory}\n" + f":Document Type: {self.document_type}\n" + f":Supplier Name: {self.supplier_name}\n" + f":Supplier Phone Number: {self.supplier_phone_number}\n" + f":Supplier Address: {self.supplier_address}\n" + f":Supplier Company Registrations: {supplier_company_registrations}\n" + f":Line Items: {line_items}" + f":Taxes: {taxes}\n" + f":Total Taxes: {self.total_tax}\n" + ) + + def _checklist(self) -> None: + pass + + +TypeReceiptV5 = TypeVar("TypeReceiptV5", bound=ReceiptV5) diff --git a/tests/data b/tests/data index b1aa082d..aa93f14c 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit b1aa082d2719e8f766b0a59847316b9569f0097e +Subproject commit aa93f14c68568557241923724e3a7888bdc1256b diff --git a/tests/documents/test_receipt_v5.py b/tests/documents/test_receipt_v5.py new file mode 100644 index 00000000..60f9a88e --- /dev/null +++ b/tests/documents/test_receipt_v5.py @@ -0,0 +1,64 @@ +import json + +import pytest + +from mindee.documents.receipt.receipt_v5 import ReceiptV5 +from tests import RECEIPT_DATA_DIR + +FILE_PATH_RECEIPT_V5_COMPLETE = f"{RECEIPT_DATA_DIR}/response_v5/complete.json" +FILE_PATH_RECEIPT_V5_EMPTY = f"{RECEIPT_DATA_DIR}/response_v5/empty.json" + + +@pytest.fixture +def receipt_v5_doc_object(): + json_data = json.load(open(FILE_PATH_RECEIPT_V5_COMPLETE)) + return ReceiptV5(api_prediction=json_data["document"]["inference"], page_n=None) + + +@pytest.fixture +def receipt_v5_doc_object_empty(): + json_data = json.load(open(FILE_PATH_RECEIPT_V5_EMPTY)) + return ReceiptV5(api_prediction=json_data["document"]["inference"], page_n=None) + + +@pytest.fixture +def receipt_v5_page_object(): + json_data = json.load(open(FILE_PATH_RECEIPT_V5_COMPLETE)) + return ReceiptV5( + api_prediction=json_data["document"]["inference"]["pages"][0], page_n=0 + ) + + +def test_doc_constructor(receipt_v5_doc_object: ReceiptV5): + assert receipt_v5_doc_object.date.value == "2016-02-26" + assert receipt_v5_doc_object.total_tax.value == 1.7 + doc_str = open(f"{RECEIPT_DATA_DIR}/response_v5/doc_to_string.rst").read() + assert receipt_v5_doc_object.orientation is None + assert receipt_v5_doc_object.date.page_n == 0 + assert str(receipt_v5_doc_object) == doc_str + + +def test_page_constructor(receipt_v5_page_object: ReceiptV5): + assert receipt_v5_page_object.date.value == "2016-02-26" + assert receipt_v5_page_object.total_tax.value == 1.7 + doc_str = open(f"{RECEIPT_DATA_DIR}/response_v5/page0_to_string.rst").read() + assert receipt_v5_page_object.orientation.value == 0 + assert receipt_v5_page_object.date.page_n == 0 + assert str(receipt_v5_page_object) == doc_str + assert len(receipt_v5_page_object.cropper) == 0 + + +def test_all_na(receipt_v5_doc_object_empty: ReceiptV5): + assert receipt_v5_doc_object_empty.locale.value is None + assert receipt_v5_doc_object_empty.total_amount.value is None + assert receipt_v5_doc_object_empty.date.value is None + assert receipt_v5_doc_object_empty.supplier_name.value is None + assert receipt_v5_doc_object_empty.time.value is None + assert receipt_v5_doc_object_empty.orientation is None + assert receipt_v5_doc_object_empty.total_tax.value is None + assert len(receipt_v5_doc_object_empty.taxes) == 0 + + +def test_checklist_on_empty(receipt_v5_doc_object_empty): + for check in receipt_v5_doc_object_empty.checklist.values(): + assert check is False From c60e3cddb85fd26fe044cfd5c05593c5f7ffecc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Fri, 14 Apr 2023 14:07:16 +0200 Subject: [PATCH 3/5] :bug: fix docs location for FE --- .../{fr => }/bank_account_details_v1.txt | 0 docs/extras/code_samples/{us => }/bank_check_v1.txt | 0 .../extras/code_samples/{fr => }/carte_grise_v1.txt | 0 .../code_samples/{fr => }/carte_vitale_v1.txt | 0 .../{receipt_v3.txt => expense_receipts_v3.txt} | 0 .../{receipt_v4.txt => expense_receipts_v4.txt} | 0 docs/extras/code_samples/expense_receipts_v5.txt | 13 +++++++++++++ docs/extras/code_samples/{fr => }/id_card_v1.txt | 0 .../code_samples/{eu => }/license_plate_v1.txt | 0 .../standard/documents/eu/license_plate_v1.rst | 2 +- .../documents/fr/bank_account_details_v1.rst | 2 +- .../standard/documents/fr/carte_grise_v1.rst | 2 +- .../standard/documents/fr/carte_vitale_v1.rst | 2 +- .../standard/documents/fr/id_card_v1.rst | 2 +- docs/predictions/standard/documents/receipt_v3.rst | 6 +++--- docs/predictions/standard/documents/receipt_v4.rst | 2 +- docs/predictions/standard/documents/receipt_v5.rst | 10 ++++++++++ .../standard/documents/us/bank_check_v1.rst | 2 +- docs/predictions/standard/international.rst | 8 +++++--- 19 files changed, 38 insertions(+), 13 deletions(-) rename docs/extras/code_samples/{fr => }/bank_account_details_v1.txt (100%) rename docs/extras/code_samples/{us => }/bank_check_v1.txt (100%) rename docs/extras/code_samples/{fr => }/carte_grise_v1.txt (100%) rename docs/extras/code_samples/{fr => }/carte_vitale_v1.txt (100%) rename docs/extras/code_samples/{receipt_v3.txt => expense_receipts_v3.txt} (100%) rename docs/extras/code_samples/{receipt_v4.txt => expense_receipts_v4.txt} (100%) create mode 100644 docs/extras/code_samples/expense_receipts_v5.txt rename docs/extras/code_samples/{fr => }/id_card_v1.txt (100%) rename docs/extras/code_samples/{eu => }/license_plate_v1.txt (100%) create mode 100644 docs/predictions/standard/documents/receipt_v5.rst diff --git a/docs/extras/code_samples/fr/bank_account_details_v1.txt b/docs/extras/code_samples/bank_account_details_v1.txt similarity index 100% rename from docs/extras/code_samples/fr/bank_account_details_v1.txt rename to docs/extras/code_samples/bank_account_details_v1.txt diff --git a/docs/extras/code_samples/us/bank_check_v1.txt b/docs/extras/code_samples/bank_check_v1.txt similarity index 100% rename from docs/extras/code_samples/us/bank_check_v1.txt rename to docs/extras/code_samples/bank_check_v1.txt diff --git a/docs/extras/code_samples/fr/carte_grise_v1.txt b/docs/extras/code_samples/carte_grise_v1.txt similarity index 100% rename from docs/extras/code_samples/fr/carte_grise_v1.txt rename to docs/extras/code_samples/carte_grise_v1.txt diff --git a/docs/extras/code_samples/fr/carte_vitale_v1.txt b/docs/extras/code_samples/carte_vitale_v1.txt similarity index 100% rename from docs/extras/code_samples/fr/carte_vitale_v1.txt rename to docs/extras/code_samples/carte_vitale_v1.txt diff --git a/docs/extras/code_samples/receipt_v3.txt b/docs/extras/code_samples/expense_receipts_v3.txt similarity index 100% rename from docs/extras/code_samples/receipt_v3.txt rename to docs/extras/code_samples/expense_receipts_v3.txt diff --git a/docs/extras/code_samples/receipt_v4.txt b/docs/extras/code_samples/expense_receipts_v4.txt similarity index 100% rename from docs/extras/code_samples/receipt_v4.txt rename to docs/extras/code_samples/expense_receipts_v4.txt diff --git a/docs/extras/code_samples/expense_receipts_v5.txt b/docs/extras/code_samples/expense_receipts_v5.txt new file mode 100644 index 00000000..7130a4f2 --- /dev/null +++ b/docs/extras/code_samples/expense_receipts_v5.txt @@ -0,0 +1,13 @@ +from mindee import Client, documents + +# Init a new client +mindee_client = Client(api_key="my-api-key") + +# Load a file from disk +input_doc = mindee_client.doc_from_path("/path/to/the/file.ext") + +# Parse the Receipt by passing the appropriate type +result = input_doc.parse(documents.TypeReceiptV5) + +# Print a brief summary of the parsed data +print(result.document) diff --git a/docs/extras/code_samples/fr/id_card_v1.txt b/docs/extras/code_samples/id_card_v1.txt similarity index 100% rename from docs/extras/code_samples/fr/id_card_v1.txt rename to docs/extras/code_samples/id_card_v1.txt diff --git a/docs/extras/code_samples/eu/license_plate_v1.txt b/docs/extras/code_samples/license_plate_v1.txt similarity index 100% rename from docs/extras/code_samples/eu/license_plate_v1.txt rename to docs/extras/code_samples/license_plate_v1.txt diff --git a/docs/predictions/standard/documents/eu/license_plate_v1.rst b/docs/predictions/standard/documents/eu/license_plate_v1.rst index 8f398aa8..4b453e61 100644 --- a/docs/predictions/standard/documents/eu/license_plate_v1.rst +++ b/docs/predictions/standard/documents/eu/license_plate_v1.rst @@ -3,7 +3,7 @@ License Plate V1 **Sample Code:** -.. literalinclude:: /extras/code_samples/eu/license_plate_v1.txt +.. literalinclude:: /extras/code_samples/license_plate_v1.txt :language: Python .. autoclass:: mindee.documents.eu.LicensePlateV1 diff --git a/docs/predictions/standard/documents/fr/bank_account_details_v1.rst b/docs/predictions/standard/documents/fr/bank_account_details_v1.rst index 59d776ba..785944d3 100644 --- a/docs/predictions/standard/documents/fr/bank_account_details_v1.rst +++ b/docs/predictions/standard/documents/fr/bank_account_details_v1.rst @@ -3,7 +3,7 @@ Bank Account Details V1 **Sample Code:** -.. literalinclude:: /extras/code_samples/fr/bank_account_details_v1.txt +.. literalinclude:: /extras/code_samples/bank_account_details_v1.txt :language: Python .. autoclass:: mindee.documents.fr.BankAccountDetailsV1 diff --git a/docs/predictions/standard/documents/fr/carte_grise_v1.rst b/docs/predictions/standard/documents/fr/carte_grise_v1.rst index 7b1c141e..781bb985 100644 --- a/docs/predictions/standard/documents/fr/carte_grise_v1.rst +++ b/docs/predictions/standard/documents/fr/carte_grise_v1.rst @@ -3,7 +3,7 @@ Carte Grise V1 **Sample Code:** -.. literalinclude:: /extras/code_samples/fr/carte_grise_v1.txt +.. literalinclude:: /extras/code_samples/carte_grise_v1.txt :language: Python .. autoclass:: mindee.documents.fr.CarteGriseV1 diff --git a/docs/predictions/standard/documents/fr/carte_vitale_v1.rst b/docs/predictions/standard/documents/fr/carte_vitale_v1.rst index a6c0208d..77805c31 100644 --- a/docs/predictions/standard/documents/fr/carte_vitale_v1.rst +++ b/docs/predictions/standard/documents/fr/carte_vitale_v1.rst @@ -3,7 +3,7 @@ Carte Vitale V1 **Sample Code:** -.. literalinclude:: /extras/code_samples/fr/carte_vitale_v1.txt +.. literalinclude:: /extras/code_samples/carte_vitale_v1.txt :language: Python .. autoclass:: mindee.documents.fr.CarteVitaleV1 diff --git a/docs/predictions/standard/documents/fr/id_card_v1.rst b/docs/predictions/standard/documents/fr/id_card_v1.rst index f9b58d24..cf6ecd26 100644 --- a/docs/predictions/standard/documents/fr/id_card_v1.rst +++ b/docs/predictions/standard/documents/fr/id_card_v1.rst @@ -3,7 +3,7 @@ Carte Nationale d'Identité V1 **Sample Code:** -.. literalinclude:: /extras/code_samples/fr/id_card_v1.txt +.. literalinclude:: /extras/code_samples/id_card_v1.txt :language: Python .. autoclass:: mindee.documents.fr.IdCardV1 diff --git a/docs/predictions/standard/documents/receipt_v3.rst b/docs/predictions/standard/documents/receipt_v3.rst index 021cc776..11b9d8d8 100644 --- a/docs/predictions/standard/documents/receipt_v3.rst +++ b/docs/predictions/standard/documents/receipt_v3.rst @@ -1,10 +1,10 @@ -Receipt V3 +Receipt V4 ---------- **Sample Code:** -.. literalinclude:: /extras/code_samples/receipt_v3.txt +.. literalinclude:: /extras/code_samples/expense_receipts_v3.txt :language: Python -.. autoclass:: mindee.documents.ReceiptV3 +.. autoclass:: mindee.documents.ReceiptV4 :members: diff --git a/docs/predictions/standard/documents/receipt_v4.rst b/docs/predictions/standard/documents/receipt_v4.rst index 864be2c8..2087e72e 100644 --- a/docs/predictions/standard/documents/receipt_v4.rst +++ b/docs/predictions/standard/documents/receipt_v4.rst @@ -3,7 +3,7 @@ Receipt V4 **Sample Code:** -.. literalinclude:: /extras/code_samples/receipt_v4.txt +.. literalinclude:: /extras/code_samples/expense_receipts_v4.txt :language: Python .. autoclass:: mindee.documents.ReceiptV4 diff --git a/docs/predictions/standard/documents/receipt_v5.rst b/docs/predictions/standard/documents/receipt_v5.rst new file mode 100644 index 00000000..65d06cf5 --- /dev/null +++ b/docs/predictions/standard/documents/receipt_v5.rst @@ -0,0 +1,10 @@ +Receipt V5 +---------- + +**Sample Code:** + +.. literalinclude:: /extras/code_samples/expense_receipts_v5.txt + :language: Python + +.. autoclass:: mindee.documents.ReceiptV5 + :members: diff --git a/docs/predictions/standard/documents/us/bank_check_v1.rst b/docs/predictions/standard/documents/us/bank_check_v1.rst index 4cc50436..a297b8b9 100644 --- a/docs/predictions/standard/documents/us/bank_check_v1.rst +++ b/docs/predictions/standard/documents/us/bank_check_v1.rst @@ -3,7 +3,7 @@ Bank Check V1 **Sample Code:** -.. literalinclude:: /extras/code_samples/us/bank_check_v1.txt +.. literalinclude:: /extras/code_samples/bank_check_v1.txt :language: Python .. autoclass:: mindee.documents.us.BankCheckV1 diff --git a/docs/predictions/standard/international.rst b/docs/predictions/standard/international.rst index 538d539d..e4849498 100644 --- a/docs/predictions/standard/international.rst +++ b/docs/predictions/standard/international.rst @@ -1,10 +1,12 @@ International ============= -.. include:: ./documents/financial_document_v1.rst -.. include:: ./documents/passport_v1.rst -.. include:: ./documents/shipping_container_v1.rst .. include:: ./documents/invoice_v3.rst .. include:: ./documents/invoice_v4.rst .. include:: ./documents/receipt_v3.rst .. include:: ./documents/receipt_v4.rst +.. include:: ./documents/receipt_v5.rst +.. include:: ./documents/financial_document_v1.rst +.. include:: ./documents/passport_v1.rst +.. include:: ./documents/shipping_container_v1.rst +.. include:: ./documents/proof_of_address_v1.rst From 782f10ca7a6d203548ada6c872e63041da1aedd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Mon, 17 Apr 2023 11:11:14 +0200 Subject: [PATCH 4/5] fix PR --- docs/predictions/standard/documents/receipt_v3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/predictions/standard/documents/receipt_v3.rst b/docs/predictions/standard/documents/receipt_v3.rst index 11b9d8d8..4bb7cf6b 100644 --- a/docs/predictions/standard/documents/receipt_v3.rst +++ b/docs/predictions/standard/documents/receipt_v3.rst @@ -1,4 +1,4 @@ -Receipt V4 +Receipt V3 ---------- **Sample Code:** From d59d112fc0a140a0f62cc169e0ac89428a0a7118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Mon, 17 Apr 2023 11:29:04 +0200 Subject: [PATCH 5/5] use full RST table in receipt v5 --- mindee/documents/receipt/line_item_v5.py | 2 +- mindee/documents/receipt/receipt_v5.py | 14 ++++++++------ tests/data | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mindee/documents/receipt/line_item_v5.py b/mindee/documents/receipt/line_item_v5.py index 7f07e3c3..365cb8c1 100644 --- a/mindee/documents/receipt/line_item_v5.py +++ b/mindee/documents/receipt/line_item_v5.py @@ -55,4 +55,4 @@ def __str__(self) -> str: float_to_string(self.total_amount), description, ] - return "{:<9} {:<9} {:<10} {}".format(*row) + return "| {:<8} | {:<8} | {:<9} | {:<34} |".format(*row) diff --git a/mindee/documents/receipt/receipt_v5.py b/mindee/documents/receipt/receipt_v5.py index 29257f13..b6cb37bb 100644 --- a/mindee/documents/receipt/receipt_v5.py +++ b/mindee/documents/receipt/receipt_v5.py @@ -120,13 +120,15 @@ def __str__(self) -> str: line_items = "\n" if self.line_items: line_items = ( - "\n ========= ========= ========== ====================================" - "\n Quantity Price Amount Description" - "\n ========= ========= ========== ====================================" + "\n +----------+----------+-----------+------------------------------------+" + "\n | Quantity | Price | Amount | Description |" + "\n +==========+==========+===========+====================================+" ) for item in self.line_items: - line_items += f"\n {item}" - line_items += "\n ========= ========= ========== ====================================\n" + line_items += ( + f"\n {item}" + "\n +----------+----------+-----------+------------------------------------+" + ) return clean_out_string( "Receipt V5 Prediction\n=====================\n" @@ -144,7 +146,7 @@ def __str__(self) -> str: f":Supplier Phone Number: {self.supplier_phone_number}\n" f":Supplier Address: {self.supplier_address}\n" f":Supplier Company Registrations: {supplier_company_registrations}\n" - f":Line Items: {line_items}" + f":Line Items: {line_items}\n" f":Taxes: {taxes}\n" f":Total Taxes: {self.total_tax}\n" ) diff --git a/tests/data b/tests/data index aa93f14c..d4d2b65e 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit aa93f14c68568557241923724e3a7888bdc1256b +Subproject commit d4d2b65e9e858d9887e64576afcc9495a4faa1e8