From a760bee91807845fe033a79222ef598415079baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Tue, 31 Jan 2023 13:34:05 +0100 Subject: [PATCH] :sparkles: add support for: financial document v1 --- mindee/client.py | 14 +- mindee/documents/__init__.py | 7 +- mindee/documents/financial/__init__.py | 1 + mindee/documents/financial/financial_v0.py | 219 ++++++++++++++++ mindee/documents/financial/financial_v1.py | 254 ++++++++---------- tests/__init__.py | 1 + tests/data | 2 +- tests/documents/test_financial_v0.py | 285 ++++++++++++++++++++ tests/documents/test_financial_v1.py | 290 +++------------------ tests/test_response.py | 3 +- 10 files changed, 676 insertions(+), 400 deletions(-) create mode 100644 mindee/documents/financial/financial_v0.py create mode 100644 tests/documents/test_financial_v0.py diff --git a/mindee/client.py b/mindee/client.py index 47a56f37..f4e93e22 100644 --- a/mindee/client.py +++ b/mindee/client.py @@ -4,6 +4,7 @@ from mindee.documents import ( CropperV1, CustomV1, + FinancialV0, FinancialV1, InvoiceV3, InvoiceV4, @@ -228,9 +229,9 @@ def _init_default_endpoints(self) -> None: ) ], ), - (OTS_OWNER, FinancialV1.__name__): DocumentConfig( + (OTS_OWNER, FinancialV0.__name__): DocumentConfig( document_type="financial_doc", - document_class=FinancialV1, + document_class=FinancialV0, endpoints=[ StandardEndpoint( url_name="invoices", version="3", api_key=self.api_key @@ -240,6 +241,15 @@ def _init_default_endpoints(self) -> None: ), ], ), + (OTS_OWNER, FinancialV1.__name__): DocumentConfig( + document_type="financial_doc", + document_class=FinancialV1, + endpoints=[ + StandardEndpoint( + url_name="financial_document", version="1", api_key=self.api_key + ), + ], + ), (OTS_OWNER, PassportV1.__name__): DocumentConfig( document_type="passport_v1", document_class=PassportV1, diff --git a/mindee/documents/__init__.py b/mindee/documents/__init__.py index 45846bf0..24840f83 100644 --- a/mindee/documents/__init__.py +++ b/mindee/documents/__init__.py @@ -1,7 +1,12 @@ from mindee.documents import fr, us from mindee.documents.cropper import CropperV1, TypeCropperV1 from mindee.documents.custom import CustomV1, TypeCustomV1 -from mindee.documents.financial import FinancialV1, TypeFinancialV1 +from mindee.documents.financial import ( + FinancialV0, + FinancialV1, + TypeFinancialV0, + TypeFinancialV1, +) from mindee.documents.invoice import InvoiceV3, InvoiceV4, TypeInvoiceV3, TypeInvoiceV4 from mindee.documents.passport import PassportV1, TypePassportV1 from mindee.documents.receipt import ReceiptV3, ReceiptV4, TypeReceiptV3, TypeReceiptV4 diff --git a/mindee/documents/financial/__init__.py b/mindee/documents/financial/__init__.py index f1fcf793..da4ccdc2 100644 --- a/mindee/documents/financial/__init__.py +++ b/mindee/documents/financial/__init__.py @@ -1 +1,2 @@ +from .financial_v0 import FinancialV0, TypeFinancialV0 from .financial_v1 import FinancialV1, TypeFinancialV1 diff --git a/mindee/documents/financial/financial_v0.py b/mindee/documents/financial/financial_v0.py new file mode 100644 index 00000000..40d37cd8 --- /dev/null +++ b/mindee/documents/financial/financial_v0.py @@ -0,0 +1,219 @@ +from typing import List, Optional, TypeVar + +from mindee.documents.base import Document, TypeApiPrediction, clean_out_string +from mindee.documents.invoice.invoice_v3 import InvoiceV3 +from mindee.documents.receipt.receipt_v3 import ReceiptV3 +from mindee.endpoints import Endpoint +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.payment_details import PaymentDetails +from mindee.fields.tax import TaxField +from mindee.fields.text import TextField +from mindee.input.sources import InputSource + + +class FinancialV0(Document): + locale: LocaleField + """locale information""" + total_incl: AmountField + """Total including taxes""" + total_excl: AmountField + """Total excluding taxes""" + date: DateField + """Date the document was issued""" + time: TextField + """Time the document was issued""" + invoice_number: TextField + """Invoice number""" + due_date: DateField + """Date the invoice is due""" + taxes: List[TaxField] + """List of all taxes""" + merchant_name: TextField + """Merchant/Supplier's name""" + supplier_address: TextField + """Merchant/Supplier's address""" + customer_name: TextField + """Customer's name""" + customer_address: TextField + """Customer's address""" + customer_company_registration: List[CompanyRegistrationField] + """Customer company registration numbers""" + payment_details: List[PaymentDetails] + """Payment details""" + company_number: List[CompanyRegistrationField] + """Company numbers""" + total_tax: AmountField + """Sum total of all taxes""" + + def __init__( + self, + api_prediction=None, + input_source=None, + page_n: Optional[int] = None, + document_type="financial_doc", + ): + """ + Union of `Invoice` and `Receipt`. + + :param api_prediction: Raw prediction from HTTP response + :param input_source: Input object + :param page_n: Page number for multi-page PDF input + """ + # need this for building from prediction + self.input_file = input_source + + super().__init__( + input_source=input_source, + document_type=document_type, + api_prediction=api_prediction, + page_n=page_n, + ) + self._build_from_api_prediction(api_prediction, page_n=page_n) + self._checklist() + + 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 + """ + if "invoice_number" in api_prediction["prediction"].keys(): + invoice = InvoiceV3(api_prediction, self.input_file, page_n=page_n) + self.locale = invoice.locale + self.total_incl = invoice.total_incl + self.total_excl = invoice.total_excl + self.date = invoice.invoice_date + self.invoice_number = invoice.invoice_number + self.due_date = invoice.due_date + self.taxes = invoice.taxes + self.merchant_name = invoice.supplier + self.payment_details = invoice.payment_details + self.company_number = invoice.company_number + self.orientation = invoice.orientation + self.total_tax = invoice.total_tax + self.time = TextField({"value": None, "confidence": 0.0}) + self.supplier_address = invoice.supplier_address + self.customer_name = invoice.customer_name + self.customer_company_registration = invoice.customer_company_registration + self.customer_address = invoice.customer_address + else: + receipt = ReceiptV3(api_prediction, self.input_file, page_n=page_n) + self.orientation = receipt.orientation + self.date = receipt.date + self.due_date = receipt.date + self.taxes = receipt.taxes + self.locale = receipt.locale + self.total_incl = receipt.total_incl + self.total_excl = receipt.total_excl + self.merchant_name = receipt.merchant_name + self.time = receipt.time + self.total_tax = receipt.total_tax + self.customer_company_registration = [] + self.company_number = [] + self.payment_details = [] + self.invoice_number = TextField({"value": None, "confidence": 0.0}) + self.supplier_address = TextField({"value": None, "confidence": 0.0}) + self.customer_name = TextField({"value": None, "confidence": 0.0}) + self.customer_address = TextField({"value": None, "confidence": 0.0}) + + def __str__(self) -> str: + return clean_out_string( + "-----Financial Document data-----\n" + f"Filename: {self.filename or ''}\n" + f"Invoice number: {self.invoice_number.value}\n" + f"Total amount including taxes: {self.total_incl.value}\n" + f"Total amount excluding taxes: {self.total_excl.value}\n" + "Date: %s\n" + "Invoice due date: %s\n" + "Supplier name: %s\n" + f"Supplier address: {self.supplier_address}\n" + f"Customer name: {self.customer_name}\n" + f"Customer company registration: {self.customer_company_registration}\n" + f"Customer address: {self.customer_address}\n" + "Taxes: %s\n" + "Total taxes: %s\n" + "----------------------" + % ( + self.date.value, + self.due_date.value, + self.merchant_name.value, + ",".join([str(t.value) + " " + str(t.rate) + "%" for t in self.taxes]), + self.total_tax.value, + ) + ) + + @staticmethod + def request( + endpoints: List[Endpoint], + input_source: InputSource, + include_words: bool = False, + close_file: bool = True, + cropper: bool = False, + ): + """ + Make request to prediction endpoint. + + :param input_source: Input object + :param endpoints: Endpoints config + :param include_words: Include Mindee vision words in http_response + :param close_file: Whether to `close()` the file after parsing it. + :param cropper: Including Mindee cropper results. + """ + if "pdf" in input_source.file_mimetype: + # invoices is index 0, receipts 1 (this should be cleaned up) + index = 0 + else: + index = 1 + return endpoints[index].predict_req_post( + input_source, include_words, close_file, cropper=cropper + ) + + def _checklist(self) -> None: + """Set the validation rules.""" + self.checklist = {"taxes_match_total_incl": self.__taxes_match_total_incl()} + + # Checks + def __taxes_match_total_incl(self) -> bool: + """ + Check invoice rule of matching between taxes and total_incl. + + :return: True if rule matches, False otherwise + """ + # Check taxes and total_incl exist + if len(self.taxes) == 0 or self.total_incl.value is None: + return False + + # Reconstruct total_incl from taxes + total_vat = 0.0 + reconstructed_total = 0.0 + for tax in self.taxes: + if tax.rate is not None and tax.rate != 0 and tax.value is not None: + total_vat += tax.value + reconstructed_total += tax.value + 100 * tax.value / tax.rate + + # Sanity check + if total_vat <= 0: + return False + + # Crate epsilon + eps = 1 / (100 * total_vat) + if ( + self.total_incl.value * (1 - eps) - 0.02 + <= reconstructed_total + <= self.total_incl.value * (1 + eps) + 0.02 + ): + for tax in self.taxes: + tax.confidence = 1.0 + self.total_tax.confidence = 1.0 + self.total_incl.confidence = 1.0 + return True + return False + + +TypeFinancialV0 = TypeVar("TypeFinancialV0", bound=FinancialV0) diff --git a/mindee/documents/financial/financial_v1.py b/mindee/documents/financial/financial_v1.py index 68dfde1c..122ad9f0 100644 --- a/mindee/documents/financial/financial_v1.py +++ b/mindee/documents/financial/financial_v1.py @@ -1,9 +1,7 @@ from typing import List, Optional, TypeVar from mindee.documents.base import Document, TypeApiPrediction, clean_out_string -from mindee.documents.invoice.invoice_v3 import InvoiceV3 -from mindee.documents.receipt.receipt_v3 import ReceiptV3 -from mindee.endpoints import Endpoint +from mindee.documents.invoice.line_item import InvoiceLineItem from mindee.fields.amount import AmountField from mindee.fields.company_registration import CompanyRegistrationField from mindee.fields.date import DateField @@ -11,42 +9,53 @@ from mindee.fields.payment_details import PaymentDetails from mindee.fields.tax import TaxField from mindee.fields.text import TextField -from mindee.input.sources import InputSource class FinancialV1(Document): locale: LocaleField """locale information""" - total_incl: AmountField + total_amount: AmountField """Total including taxes""" - total_excl: AmountField + total_net: AmountField """Total excluding taxes""" date: DateField - """Date the document was issued""" - time: TextField - """Time the document was issued""" + """Date the invoice was issued""" invoice_number: TextField """Invoice number""" + reference_numbers: List[TextField] + """List of Reference numbers including PO number.""" due_date: DateField """Date the invoice is due""" - taxes: List[TaxField] + taxes: List[TaxField] = [] """List of all taxes""" - merchant_name: TextField - """Merchant/Supplier's name""" + total_tax: AmountField + """Sum total of all taxes""" + supplier_name: TextField + """Supplier 's name""" supplier_address: TextField - """Merchant/Supplier's address""" + """Supplier's address""" + supplier_company_registrations: List[CompanyRegistrationField] + """Company numbers""" customer_name: TextField """Customer's name""" customer_address: TextField """Customer's address""" - customer_company_registration: List[CompanyRegistrationField] + customer_company_registrations: List[CompanyRegistrationField] """Customer company registration numbers""" - payment_details: List[PaymentDetails] + supplier_payment_details: List[PaymentDetails] """Payment details""" - company_number: List[CompanyRegistrationField] - """Company numbers""" - total_tax: AmountField - """Sum total of all taxes""" + line_items: List[InvoiceLineItem] + """Details of line items""" + tip: AmountField + """Total amount of tip and gratuity.""" + time: TextField + """Time as seen on the receipt in HH:MM format.""" + document_type: TextField + """A classification field, among predefined classes.""" + category: TextField + """The invoice or receipt category among predefined classes.""" + subcategory: TextField + """The invoice or receipt sub-category among predefined classes.""" def __init__( self, @@ -71,8 +80,7 @@ def __init__( api_prediction=api_prediction, page_n=page_n, ) - self._build_from_api_prediction(api_prediction, page_n=page_n) - self._checklist() + 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 @@ -83,137 +91,101 @@ def _build_from_api_prediction( :param api_prediction: Raw prediction from HTTP response :param page_n: Page number for multi pages pdf input """ - if "invoice_number" in api_prediction["prediction"].keys(): - invoice = InvoiceV3(api_prediction, self.input_file, page_n=page_n) - self.locale = invoice.locale - self.total_incl = invoice.total_incl - self.total_excl = invoice.total_excl - self.date = invoice.invoice_date - self.invoice_number = invoice.invoice_number - self.due_date = invoice.due_date - self.taxes = invoice.taxes - self.merchant_name = invoice.supplier - self.payment_details = invoice.payment_details - self.company_number = invoice.company_number - self.orientation = invoice.orientation - self.total_tax = invoice.total_tax - self.time = TextField({"value": None, "confidence": 0.0}) - self.supplier_address = invoice.supplier_address - self.customer_name = invoice.customer_name - self.customer_company_registration = invoice.customer_company_registration - self.customer_address = invoice.customer_address - else: - receipt = ReceiptV3(api_prediction, self.input_file, page_n=page_n) - self.orientation = receipt.orientation - self.date = receipt.date - self.due_date = receipt.date - self.taxes = receipt.taxes - self.locale = receipt.locale - self.total_incl = receipt.total_incl - self.total_excl = receipt.total_excl - self.merchant_name = receipt.merchant_name - self.time = receipt.time - self.total_tax = receipt.total_tax - self.customer_company_registration = [] - self.company_number = [] - self.payment_details = [] - self.invoice_number = TextField({"value": None, "confidence": 0.0}) - self.supplier_address = TextField({"value": None, "confidence": 0.0}) - self.customer_name = TextField({"value": None, "confidence": 0.0}) - self.customer_address = TextField({"value": None, "confidence": 0.0}) + self.supplier_company_registrations = [ + CompanyRegistrationField(field_dict, page_n=page_n) + for field_dict in api_prediction["supplier_company_registrations"] + ] + self.date = DateField(api_prediction["date"], page_n=page_n) + self.due_date = DateField(api_prediction["due_date"], page_n=page_n) + self.invoice_number = TextField(api_prediction["invoice_number"], page_n=page_n) + self.reference_numbers = [ + TextField(reference_number, page_n=page_n) + for reference_number in api_prediction["reference_numbers"] + ] + self.locale = LocaleField( + api_prediction["locale"], value_key="language", page_n=page_n + ) + self.supplier_name = TextField(api_prediction["supplier_name"], page_n=page_n) + self.supplier_address = TextField( + api_prediction["supplier_address"], page_n=page_n + ) + self.customer_name = TextField(api_prediction["customer_name"], page_n=page_n) + self.customer_company_registrations = [ + CompanyRegistrationField(field_dict, page_n=page_n) + for field_dict in api_prediction["customer_company_registrations"] + ] + self.customer_address = TextField( + api_prediction["customer_address"], page_n=page_n + ) + + self.taxes = [ + TaxField(tax_prediction, page_n=page_n, value_key="value") + for tax_prediction in api_prediction["taxes"] + ] + self.supplier_payment_details = [ + PaymentDetails(payment_detail, page_n=page_n) + for payment_detail in api_prediction["supplier_payment_details"] + ] + self.line_items = [ + InvoiceLineItem(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) + 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.time = TextField(api_prediction["time"], page_n=page_n) + self.document_type = TextField(api_prediction["document_type"], page_n=page_n) + self.category = TextField(api_prediction["category"], page_n=page_n) + self.subcategory = TextField(api_prediction["subcategory"], page_n=page_n) def __str__(self) -> str: + supplier_company_registrations = "; ".join( + [str(n.value) for n in self.supplier_company_registrations] + ) + customer_company_registrations = "; ".join( + [str(n.value) for n in self.customer_company_registrations] + ) + reference_numbers = ", ".join([str(n.value) for n in self.reference_numbers]) + payment_details = "\n ".join( + [str(p) for p in self.supplier_payment_details] + ) + taxes = "\n ".join(f"{t}" for t in self.taxes) + line_items = "\n" + if self.line_items: + line_items = "\n Code | QTY | Price | Amount | Tax (Rate) | Description\n" + for item in self.line_items: + line_items += f" {item}\n" return clean_out_string( - "-----Financial Document data-----\n" + "----- Financial Document V1 -----\n" f"Filename: {self.filename or ''}\n" - f"Invoice number: {self.invoice_number.value}\n" - f"Total amount including taxes: {self.total_incl.value}\n" - f"Total amount excluding taxes: {self.total_excl.value}\n" - "Date: %s\n" - "Invoice due date: %s\n" - "Supplier name: %s\n" + f"Document type: {self.document_type}\n" + f"Category: {self.category}\n" + f"Subcategory: {self.subcategory}\n" + f"Locale: {self.locale}\n" + f"Invoice number: {self.invoice_number}\n" + f"Reference numbers: {reference_numbers}\n" + f"Date: {self.date}\n" + f"Due date: {self.due_date}\n" + f"Time: {self.time}\n" + f"Supplier name: {self.supplier_name}\n" f"Supplier address: {self.supplier_address}\n" + f"Supplier company registrations: {supplier_company_registrations}\n" + f"Supplier payment details: {payment_details}\n" f"Customer name: {self.customer_name}\n" - f"Customer company registration: {self.customer_company_registration}\n" f"Customer address: {self.customer_address}\n" - "Taxes: %s\n" - "Total taxes: %s\n" + f"Customer company registrations: {customer_company_registrations}\n" + f"Tip: {self.tip}\n" + f"Taxes: {taxes}\n" + f"Total tax: {self.total_tax}\n" + f"Total net: {self.total_net}\n" + f"Total amount: {self.total_amount}\n" + f"Line Items: {line_items}" "----------------------" - % ( - self.date.value, - self.due_date.value, - self.merchant_name.value, - ",".join([str(t.value) + " " + str(t.rate) + "%" for t in self.taxes]), - self.total_tax.value, - ) - ) - - @staticmethod - def request( - endpoints: List[Endpoint], - input_source: InputSource, - include_words: bool = False, - close_file: bool = True, - cropper: bool = False, - ): - """ - Make request to prediction endpoint. - - :param input_source: Input object - :param endpoints: Endpoints config - :param include_words: Include Mindee vision words in http_response - :param close_file: Whether to `close()` the file after parsing it. - :param cropper: Including Mindee cropper results. - """ - if "pdf" in input_source.file_mimetype: - # invoices is index 0, receipts 1 (this should be cleaned up) - index = 0 - else: - index = 1 - return endpoints[index].predict_req_post( - input_source, include_words, close_file, cropper=cropper ) def _checklist(self) -> None: - """Set the validation rules.""" - self.checklist = {"taxes_match_total_incl": self.__taxes_match_total_incl()} - - # Checks - def __taxes_match_total_incl(self) -> bool: - """ - Check invoice rule of matching between taxes and total_incl. - - :return: True if rule matches, False otherwise - """ - # Check taxes and total_incl exist - if len(self.taxes) == 0 or self.total_incl.value is None: - return False - - # Reconstruct total_incl from taxes - total_vat = 0.0 - reconstructed_total = 0.0 - for tax in self.taxes: - if tax.rate is not None and tax.rate != 0 and tax.value is not None: - total_vat += tax.value - reconstructed_total += tax.value + 100 * tax.value / tax.rate - - # Sanity check - if total_vat <= 0: - return False - - # Crate epsilon - eps = 1 / (100 * total_vat) - if ( - self.total_incl.value * (1 - eps) - 0.02 - <= reconstructed_total - <= self.total_incl.value * (1 + eps) + 0.02 - ): - for tax in self.taxes: - tax.confidence = 1.0 - self.total_tax.confidence = 1.0 - self.total_incl.confidence = 1.0 - return True - return False + pass TypeFinancialV1 = TypeVar("TypeFinancialV1", bound=FinancialV1) diff --git a/tests/__init__.py b/tests/__init__.py index 577c3204..b3ca09f8 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,6 @@ RECEIPT_DATA_DIR = "./tests/data/receipt" INVOICE_DATA_DIR = "./tests/data/invoice" +FINANCIAL_DOC_DATA_DIR = "./tests/data/financial_document" PASSPORT_DATA_DIR = "./tests/data/passport" US_BANK_CHECK_DATA_DIR = "./tests/data/us/bank_check" FR_CARTE_GRISE_DATA_DIR = "./tests/data/fr/carte_grise" diff --git a/tests/data b/tests/data index e29d9e4f..3bcb6372 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit e29d9e4f1b7253f6189599826e4387201a70316b +Subproject commit 3bcb6372262ab2fb090ed1a57b734cb080143878 diff --git a/tests/documents/test_financial_v0.py b/tests/documents/test_financial_v0.py new file mode 100644 index 00000000..cd583c34 --- /dev/null +++ b/tests/documents/test_financial_v0.py @@ -0,0 +1,285 @@ +import json + +import pytest + +from mindee.documents.financial.financial_v0 import FinancialV0 +from tests.documents.test_invoice_v3 import ( + FILE_PATH_INVOICE_V3_COMPLETE, + FILE_PATH_INVOICE_V3_EMPTY, +) +from tests.documents.test_receipt_v3 import ( + FILE_PATH_RECEIPT_V3_COMPLETE, + FILE_PATH_RECEIPT_V3_EMPTY, +) + + +@pytest.fixture +def financial_doc_from_invoice_object(): + json_data = json.load(open(FILE_PATH_INVOICE_V3_COMPLETE)) + return FinancialV0(api_prediction=json_data["document"]["inference"], page_n=None) + + +@pytest.fixture +def financial_doc_from_receipt_object(): + json_data = json.load(open(FILE_PATH_RECEIPT_V3_COMPLETE)) + return FinancialV0(api_prediction=json_data["document"]["inference"], page_n=None) + + +@pytest.fixture +def financial_doc_from_receipt_object_all_na(): + json_data = json.load(open(FILE_PATH_RECEIPT_V3_EMPTY)) + return FinancialV0(api_prediction=json_data["document"]["inference"]["pages"][0]) + + +@pytest.fixture +def financial_doc_from_invoice_object_all_na(): + json_data = json.load(open(FILE_PATH_INVOICE_V3_EMPTY)) + return FinancialV0(api_prediction=json_data["document"]["inference"]["pages"][0]) + + +@pytest.fixture +def receipt_pred(): + return json.load(open(FILE_PATH_RECEIPT_V3_EMPTY))["document"]["inference"][ + "pages" + ][0] + + +@pytest.fixture +def invoice_pred(): + return json.load(open(FILE_PATH_INVOICE_V3_EMPTY))["document"]["inference"][ + "pages" + ][0] + + +def test_constructor_1(financial_doc_from_invoice_object): + assert financial_doc_from_invoice_object.date.value == "2020-02-17" + assert ( + financial_doc_from_invoice_object.supplier_address.value + == "156 University Ave, Toronto ON, Canada M5H 2H7" + ) + + +def test_constructor_2(financial_doc_from_receipt_object): + assert financial_doc_from_receipt_object.date.value == "2016-02-26" + assert financial_doc_from_receipt_object.supplier_address.value is None + + +def test_all_na_receipt(financial_doc_from_receipt_object_all_na): + assert financial_doc_from_receipt_object_all_na.orientation is None + assert financial_doc_from_receipt_object_all_na.locale.value is None + assert financial_doc_from_receipt_object_all_na.total_incl.value is None + assert financial_doc_from_receipt_object_all_na.date.value is None + assert financial_doc_from_receipt_object_all_na.merchant_name.value is None + assert financial_doc_from_receipt_object_all_na.total_tax.value is None + assert len(financial_doc_from_receipt_object_all_na.taxes) == 0 + + +def test_all_na_invoice(financial_doc_from_invoice_object_all_na): + assert financial_doc_from_invoice_object_all_na.orientation is None + assert financial_doc_from_invoice_object_all_na.locale.value is None + assert financial_doc_from_invoice_object_all_na.total_incl.value is None + assert financial_doc_from_invoice_object_all_na.date.value is None + assert financial_doc_from_invoice_object_all_na.merchant_name.value is None + assert financial_doc_from_invoice_object_all_na.total_tax.value is None + assert len(financial_doc_from_invoice_object_all_na.taxes) == 0 + + +def test__str__invoice(financial_doc_from_invoice_object): + assert type(financial_doc_from_invoice_object.__str__()) == str + + +def test__str__receipt(financial_doc_from_receipt_object): + assert type(financial_doc_from_receipt_object.__str__()) == str + + +# Business tests from receipt +def test__receipt_reconstruct_total_excl_from_total_and_taxes_1(receipt_pred): + # no incl implies no reconstruct for total excl + receipt_pred["prediction"]["total_incl"] = {"value": "N/A", "confidence": 0.0} + receipt_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 9.5, "confidence": 0.9} + ] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.total_excl.value is None + + +def test__receipt_reconstruct_total_excl_from_total_and_taxes_2(receipt_pred): + # no taxes implies no reconstruct for total excl + receipt_pred["prediction"]["total_incl"] = {"value": 12.54, "confidence": 0.0} + receipt_pred["prediction"]["taxes"] = [] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.total_excl.value is None + + +def test__receipt_reconstruct_total_excl_from_total_and_taxes_3(receipt_pred): + # working example + receipt_pred["prediction"]["total_incl"] = {"value": 12.54, "confidence": 0.5} + receipt_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 0.5, "confidence": 0.1}, + {"rate": 10, "value": 4.25, "confidence": 0.6}, + ] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.total_excl.confidence == 0.03 + assert financial_doc.total_excl.value == 7.79 + + +def test__receipt_reconstruct_total_tax_1(receipt_pred): + # no taxes implies no reconstruct for total tax + receipt_pred["prediction"]["taxes"] = [] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.total_tax.value is None + + +def test__receipt_reconstruct_total_tax_2(receipt_pred): + # working example + receipt_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 10.2, "confidence": 0.5}, + {"rate": 10, "value": 40.0, "confidence": 0.1}, + ] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.total_tax.value == 50.2 + assert financial_doc.total_tax.confidence == 0.05 + + +def test__receipt_taxes_match_total_incl_1(receipt_pred): + # matching example + receipt_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + receipt_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 10.99, "confidence": 0.5}, + {"rate": 10, "value": 40.12, "confidence": 0.1}, + ] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is True + assert financial_doc.total_incl.confidence == 1.0 + for tax in financial_doc.taxes: + assert tax.confidence == 1.0 + + +def test__receipt_taxes_match_total_incl_2(receipt_pred): + # not matching example with close error + receipt_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + receipt_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 10.9, "confidence": 0.5}, + {"rate": 10, "value": 40.12, "confidence": 0.1}, + ] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is False + + +def test__receipt_taxes_match_total_incl_3(receipt_pred): + # sanity check with null tax + receipt_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + receipt_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 0.0, "confidence": 0.5} + ] + financial_doc = FinancialV0(receipt_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is False + + +# Business tests from invoice +def test__invoice_reconstruct_total_excl_from_total_and_taxes_1(invoice_pred): + # no incl implies no reconstruct for total excl + invoice_pred["prediction"]["total_incl"] = {"amount": "N/A", "confidence": 0.0} + invoice_pred["prediction"]["taxes"] = [ + {"rate": 20, "amount": 9.5, "confidence": 0.9} + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.total_excl.value is None + + +def test__invoice_reconstruct_total_excl_from_total_and_taxes_2(invoice_pred): + # no taxes implies no reconstruct for total excl + invoice_pred["prediction"]["total_incl"] = {"amount": 12.54, "confidence": 0.0} + invoice_pred["prediction"]["taxes"] = [] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.total_excl.value is None + + +def test__invoice_reconstruct_total_excl_from_total_and_taxes_3(invoice_pred): + # working example + invoice_pred["prediction"]["total_incl"] = {"value": 12.54, "confidence": 0.5} + invoice_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 0.5, "confidence": 0.1}, + {"rate": 10, "value": 4.25, "confidence": 0.6}, + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.total_excl.confidence == 0.03 + assert financial_doc.total_excl.value == 7.79 + + +def test__invoice_reconstruct_total_tax_1(invoice_pred): + # no taxes implies no reconstruct for total tax + invoice_pred["prediction"]["taxes"] = [] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.total_tax.value is None + + +def test__invoice_reconstruct_total_tax_2(invoice_pred): + # working example + invoice_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 10.2, "confidence": 0.5}, + {"rate": 10, "value": 40.0, "confidence": 0.1}, + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.total_tax.value == 50.2 + assert financial_doc.total_tax.confidence == 0.05 + + +def test__invoice_taxes_match_total_incl_1(invoice_pred): + # matching example + invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + invoice_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 10.99, "confidence": 0.5}, + {"rate": 10, "value": 40.12, "confidence": 0.1}, + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is True + assert financial_doc.total_incl.confidence == 1.0 + for tax in financial_doc.taxes: + assert tax.confidence == 1.0 + + +def test__invoice_taxes_match_total_incl_2(invoice_pred): + # not matching example with close error + invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + invoice_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 10.9, "confidence": 0.5}, + {"rate": 10, "value": 40.12, "confidence": 0.1}, + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is False + + +def test__invoice_taxes_match_total_incl_3(invoice_pred): + # sanity check with null tax + invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + invoice_pred["prediction"]["taxes"] = [ + {"rate": 20, "value": 0.0, "confidence": 0.5} + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is False + + +def test__shouldnt_raise_when_tax_rate_none(invoice_pred): + # sanity check with null tax + invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} + invoice_pred["prediction"]["taxes"] = [ + {"rate": "N/A", "value": 0.0, "confidence": 0.5} + ] + financial_doc = FinancialV0(invoice_pred) + assert financial_doc.checklist["taxes_match_total_incl"] is False + + +def test_invoice_or_receipt_get_same_field_types(receipt_pred, invoice_pred): + financial_doc_from_receipt = FinancialV0(receipt_pred) + financial_doc_from_invoice = FinancialV0(invoice_pred) + assert set(dir(financial_doc_from_invoice)) == set(dir(financial_doc_from_receipt)) + for key in dir(financial_doc_from_receipt): + if key.startswith("_"): + continue + receipt_attr = getattr(financial_doc_from_receipt, key) + invoice_attr = getattr(financial_doc_from_invoice, key) + print(key) + assert isinstance( + receipt_attr, type(invoice_attr) + ), f"Types do not match for: {key}" diff --git a/tests/documents/test_financial_v1.py b/tests/documents/test_financial_v1.py index e3b1ec35..9597ba4a 100644 --- a/tests/documents/test_financial_v1.py +++ b/tests/documents/test_financial_v1.py @@ -3,283 +3,65 @@ import pytest from mindee.documents.financial.financial_v1 import FinancialV1 -from tests.documents.test_invoice_v3 import ( - FILE_PATH_INVOICE_V3_COMPLETE, - FILE_PATH_INVOICE_V3_EMPTY, +from tests import FINANCIAL_DOC_DATA_DIR + +FILE_PATH_FINANCIAL_DOC_V1_INVOICE = ( + f"{FINANCIAL_DOC_DATA_DIR}/response_v1/complete_invoice.json" ) -from tests.documents.test_receipt_v3 import ( - FILE_PATH_RECEIPT_V3_COMPLETE, - FILE_PATH_RECEIPT_V3_EMPTY, +FILE_PATH_FINANCIAL_DOC_V1_RECEIPT = ( + f"{FINANCIAL_DOC_DATA_DIR}/response_v1/complete_receipt.json" ) +FILE_PATH_FINANCIAL_DOC_V1_EMPTY = f"{FINANCIAL_DOC_DATA_DIR}/response_v1/empty.json" @pytest.fixture def financial_doc_from_invoice_object(): - json_data = json.load(open(FILE_PATH_INVOICE_V3_COMPLETE)) + json_data = json.load(open(FILE_PATH_FINANCIAL_DOC_V1_INVOICE)) return FinancialV1(api_prediction=json_data["document"]["inference"], page_n=None) @pytest.fixture def financial_doc_from_receipt_object(): - json_data = json.load(open(FILE_PATH_RECEIPT_V3_COMPLETE)) + json_data = json.load(open(FILE_PATH_FINANCIAL_DOC_V1_RECEIPT)) return FinancialV1(api_prediction=json_data["document"]["inference"], page_n=None) @pytest.fixture -def financial_doc_from_receipt_object_all_na(): - json_data = json.load(open(FILE_PATH_RECEIPT_V3_EMPTY)) +def financial_doc_object_all_na(): + json_data = json.load(open(FILE_PATH_FINANCIAL_DOC_V1_EMPTY)) return FinancialV1(api_prediction=json_data["document"]["inference"]["pages"][0]) -@pytest.fixture -def financial_doc_from_invoice_object_all_na(): - json_data = json.load(open(FILE_PATH_INVOICE_V3_EMPTY)) - return FinancialV1(api_prediction=json_data["document"]["inference"]["pages"][0]) - - -@pytest.fixture -def receipt_pred(): - return json.load(open(FILE_PATH_RECEIPT_V3_EMPTY))["document"]["inference"][ - "pages" - ][0] - - -@pytest.fixture -def invoice_pred(): - return json.load(open(FILE_PATH_INVOICE_V3_EMPTY))["document"]["inference"][ - "pages" - ][0] - - -def test_constructor_1(financial_doc_from_invoice_object): - assert financial_doc_from_invoice_object.date.value == "2020-02-17" +def test_doc_constructor_invoice(financial_doc_from_invoice_object): + assert financial_doc_from_invoice_object.date.value == "2019-02-11" assert ( financial_doc_from_invoice_object.supplier_address.value - == "156 University Ave, Toronto ON, Canada M5H 2H7" + == "4490 Oak Drive Albany, NY 12210" ) + doc_str = ( + open(f"{FINANCIAL_DOC_DATA_DIR}/response_v1/invoice_to_string.txt") + .read() + .strip() + ) + assert str(financial_doc_from_invoice_object) == doc_str -def test_constructor_2(financial_doc_from_receipt_object): - assert financial_doc_from_receipt_object.date.value == "2016-02-26" +def test_doc_constructor_receipt(financial_doc_from_receipt_object): + assert financial_doc_from_receipt_object.date.value == "2014-07-07" assert financial_doc_from_receipt_object.supplier_address.value is None + doc_str = ( + open(f"{FINANCIAL_DOC_DATA_DIR}/response_v1/receipt_to_string.txt") + .read() + .strip() + ) + assert str(financial_doc_from_receipt_object) == doc_str -def test_all_na_receipt(financial_doc_from_receipt_object_all_na): - assert financial_doc_from_receipt_object_all_na.orientation is None - assert financial_doc_from_receipt_object_all_na.locale.value is None - assert financial_doc_from_receipt_object_all_na.total_incl.value is None - assert financial_doc_from_receipt_object_all_na.date.value is None - assert financial_doc_from_receipt_object_all_na.merchant_name.value is None - assert financial_doc_from_receipt_object_all_na.total_tax.value is None - assert len(financial_doc_from_receipt_object_all_na.taxes) == 0 - - -def test_all_na_invoice(financial_doc_from_invoice_object_all_na): - assert financial_doc_from_invoice_object_all_na.orientation is None - assert financial_doc_from_invoice_object_all_na.locale.value is None - assert financial_doc_from_invoice_object_all_na.total_incl.value is None - assert financial_doc_from_invoice_object_all_na.date.value is None - assert financial_doc_from_invoice_object_all_na.merchant_name.value is None - assert financial_doc_from_invoice_object_all_na.total_tax.value is None - assert len(financial_doc_from_invoice_object_all_na.taxes) == 0 - - -def test__str__invoice(financial_doc_from_invoice_object): - assert type(financial_doc_from_invoice_object.__str__()) == str - - -def test__str__receipt(financial_doc_from_receipt_object): - assert type(financial_doc_from_receipt_object.__str__()) == str - - -# Business tests from receipt -def test__receipt_reconstruct_total_excl_from_total_and_taxes_1(receipt_pred): - # no incl implies no reconstruct for total excl - receipt_pred["prediction"]["total_incl"] = {"value": "N/A", "confidence": 0.0} - receipt_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 9.5, "confidence": 0.9} - ] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.total_excl.value is None - - -def test__receipt_reconstruct_total_excl_from_total_and_taxes_2(receipt_pred): - # no taxes implies no reconstruct for total excl - receipt_pred["prediction"]["total_incl"] = {"value": 12.54, "confidence": 0.0} - receipt_pred["prediction"]["taxes"] = [] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.total_excl.value is None - - -def test__receipt_reconstruct_total_excl_from_total_and_taxes_3(receipt_pred): - # working example - receipt_pred["prediction"]["total_incl"] = {"value": 12.54, "confidence": 0.5} - receipt_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 0.5, "confidence": 0.1}, - {"rate": 10, "value": 4.25, "confidence": 0.6}, - ] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.total_excl.confidence == 0.03 - assert financial_doc.total_excl.value == 7.79 - - -def test__receipt_reconstruct_total_tax_1(receipt_pred): - # no taxes implies no reconstruct for total tax - receipt_pred["prediction"]["taxes"] = [] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.total_tax.value is None - - -def test__receipt_reconstruct_total_tax_2(receipt_pred): - # working example - receipt_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 10.2, "confidence": 0.5}, - {"rate": 10, "value": 40.0, "confidence": 0.1}, - ] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.total_tax.value == 50.2 - assert financial_doc.total_tax.confidence == 0.05 - - -def test__receipt_taxes_match_total_incl_1(receipt_pred): - # matching example - receipt_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - receipt_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 10.99, "confidence": 0.5}, - {"rate": 10, "value": 40.12, "confidence": 0.1}, - ] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is True - assert financial_doc.total_incl.confidence == 1.0 - for tax in financial_doc.taxes: - assert tax.confidence == 1.0 - - -def test__receipt_taxes_match_total_incl_2(receipt_pred): - # not matching example with close error - receipt_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - receipt_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 10.9, "confidence": 0.5}, - {"rate": 10, "value": 40.12, "confidence": 0.1}, - ] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is False - - -def test__receipt_taxes_match_total_incl_3(receipt_pred): - # sanity check with null tax - receipt_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - receipt_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 0.0, "confidence": 0.5} - ] - financial_doc = FinancialV1(receipt_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is False - - -# Business tests from invoice -def test__invoice_reconstruct_total_excl_from_total_and_taxes_1(invoice_pred): - # no incl implies no reconstruct for total excl - invoice_pred["prediction"]["total_incl"] = {"amount": "N/A", "confidence": 0.0} - invoice_pred["prediction"]["taxes"] = [ - {"rate": 20, "amount": 9.5, "confidence": 0.9} - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.total_excl.value is None - - -def test__invoice_reconstruct_total_excl_from_total_and_taxes_2(invoice_pred): - # no taxes implies no reconstruct for total excl - invoice_pred["prediction"]["total_incl"] = {"amount": 12.54, "confidence": 0.0} - invoice_pred["prediction"]["taxes"] = [] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.total_excl.value is None - - -def test__invoice_reconstruct_total_excl_from_total_and_taxes_3(invoice_pred): - # working example - invoice_pred["prediction"]["total_incl"] = {"value": 12.54, "confidence": 0.5} - invoice_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 0.5, "confidence": 0.1}, - {"rate": 10, "value": 4.25, "confidence": 0.6}, - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.total_excl.confidence == 0.03 - assert financial_doc.total_excl.value == 7.79 - - -def test__invoice_reconstruct_total_tax_1(invoice_pred): - # no taxes implies no reconstruct for total tax - invoice_pred["prediction"]["taxes"] = [] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.total_tax.value is None - - -def test__invoice_reconstruct_total_tax_2(invoice_pred): - # working example - invoice_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 10.2, "confidence": 0.5}, - {"rate": 10, "value": 40.0, "confidence": 0.1}, - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.total_tax.value == 50.2 - assert financial_doc.total_tax.confidence == 0.05 - - -def test__invoice_taxes_match_total_incl_1(invoice_pred): - # matching example - invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - invoice_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 10.99, "confidence": 0.5}, - {"rate": 10, "value": 40.12, "confidence": 0.1}, - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is True - assert financial_doc.total_incl.confidence == 1.0 - for tax in financial_doc.taxes: - assert tax.confidence == 1.0 - - -def test__invoice_taxes_match_total_incl_2(invoice_pred): - # not matching example with close error - invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - invoice_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 10.9, "confidence": 0.5}, - {"rate": 10, "value": 40.12, "confidence": 0.1}, - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is False - - -def test__invoice_taxes_match_total_incl_3(invoice_pred): - # sanity check with null tax - invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - invoice_pred["prediction"]["taxes"] = [ - {"rate": 20, "value": 0.0, "confidence": 0.5} - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is False - - -def test__shouldnt_raise_when_tax_rate_none(invoice_pred): - # sanity check with null tax - invoice_pred["prediction"]["total_incl"] = {"value": 507.25, "confidence": 0.6} - invoice_pred["prediction"]["taxes"] = [ - {"rate": "N/A", "value": 0.0, "confidence": 0.5} - ] - financial_doc = FinancialV1(invoice_pred) - assert financial_doc.checklist["taxes_match_total_incl"] is False - - -def test_invoice_or_receipt_get_same_field_types(receipt_pred, invoice_pred): - financial_doc_from_receipt = FinancialV1(receipt_pred) - financial_doc_from_invoice = FinancialV1(invoice_pred) - assert set(dir(financial_doc_from_invoice)) == set(dir(financial_doc_from_receipt)) - for key in dir(financial_doc_from_receipt): - if key.startswith("_"): - continue - receipt_attr = getattr(financial_doc_from_receipt, key) - invoice_attr = getattr(financial_doc_from_invoice, key) - print(key) - assert isinstance( - receipt_attr, type(invoice_attr) - ), f"Types do not match for: {key}" +def test_all_na(financial_doc_object_all_na): + assert financial_doc_object_all_na.orientation is None + assert financial_doc_object_all_na.locale.value is None + assert financial_doc_object_all_na.total_amount.value is None + assert financial_doc_object_all_na.date.value is None + assert financial_doc_object_all_na.supplier_name.value is None + assert financial_doc_object_all_na.total_tax.value is None + assert len(financial_doc_object_all_na.taxes) == 0 diff --git a/tests/test_response.py b/tests/test_response.py index 547145d0..9e93d189 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -12,6 +12,7 @@ from mindee.endpoints import OTS_OWNER from mindee.input.sources import PathInput from mindee.response import PredictResponse +from tests.documents.test_financial_v1 import FILE_PATH_FINANCIAL_DOC_V1_RECEIPT from tests.documents.test_invoice_v3 import FILE_PATH_INVOICE_V3_COMPLETE from tests.documents.test_passport_v1 import FILE_PATH_PASSPORT_V1_COMPLETE from tests.documents.test_receipt_v3 import FILE_PATH_RECEIPT_V3_COMPLETE @@ -78,7 +79,7 @@ def test_response_receipt_v4(dummy_file_input, dummy_config): def test_response_financial_doc_with_receipt(dummy_file_input, dummy_config): - response = json.load(open(FILE_PATH_RECEIPT_V3_COMPLETE)) + response = json.load(open(FILE_PATH_FINANCIAL_DOC_V1_RECEIPT)) parsed_response = PredictResponse[FinancialV1]( doc_config=dummy_config[(OTS_OWNER, FinancialV1.__name__)], http_response=response,