diff --git a/mindee/documents/financial/financial_document_v1.py b/mindee/documents/financial/financial_document_v1.py index b5760928..5869a0f7 100644 --- a/mindee/documents/financial/financial_document_v1.py +++ b/mindee/documents/financial/financial_document_v1.py @@ -8,7 +8,7 @@ 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.tax import Taxes from mindee.fields.text import TextField @@ -27,7 +27,7 @@ class FinancialDocumentV1(Document): """List of Reference numbers including PO number.""" due_date: DateField """Date the invoice is due""" - taxes: List[TaxField] = [] + taxes: Taxes """List of all taxes""" total_tax: AmountField """Sum total of all taxes""" @@ -117,11 +117,7 @@ def _build_from_api_prediction( 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.taxes = Taxes(api_prediction["taxes"], page_id=page_n) self.supplier_payment_details = [ PaymentDetails(payment_detail, page_n=page_n) for payment_detail in api_prediction["supplier_payment_details"] @@ -143,6 +139,15 @@ def _build_from_api_prediction( api_prediction["subcategory"], page_n=page_n ) + @staticmethod + def _line_items_separator(char: str): + out_str = " " + out_str += f"+{char * 38}" + out_str += f"+{char * 10}" + out_str += f"+{char * 14}" + out_str += f"+{char * 12}" + return out_str + "+" + def __str__(self) -> str: supplier_company_registrations = "; ".join( [str(n.value) for n in self.supplier_company_registrations] @@ -154,38 +159,38 @@ def __str__(self) -> str: 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 V1 -----\n" - f"Filename: {self.filename or ''}\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 address: {self.customer_address}\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}" - "----------------------" + "Financial Document V1 Prediction\n" + "================================\n" + f":Filename: {self.filename or ''}\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 address: {self.customer_address}\n" + f":Customer company registrations: {customer_company_registrations}\n" + f":Tip: {self.tip}\n" + f":Taxes: {self.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}" ) def _checklist(self) -> None: diff --git a/mindee/documents/invoice/invoice_v3.py b/mindee/documents/invoice/invoice_v3.py index 854db291..f09eaf3e 100644 --- a/mindee/documents/invoice/invoice_v3.py +++ b/mindee/documents/invoice/invoice_v3.py @@ -8,7 +8,7 @@ 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.tax import Taxes from mindee.fields.text import TextField @@ -27,7 +27,7 @@ class InvoiceV3(Document): """Invoice number""" due_date: DateField """Date the invoice is due""" - taxes: List[TaxField] = [] + taxes: Taxes """List of all taxes""" total_tax: AmountField """Sum total of all taxes""" @@ -103,11 +103,7 @@ def _build_from_api_prediction( 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.taxes = Taxes(api_prediction["taxes"], page_id=page_n) self.payment_details = [ PaymentDetails(payment_detail, page_n=page_n) for payment_detail in api_prediction["payment_details"] @@ -142,27 +138,26 @@ def __str__(self) -> str: payment_details = "\n ".join( [str(p) for p in self.payment_details] ) - taxes = "\n ".join(f"{t}" for t in self.taxes) return clean_out_string( - "----- Invoice V3 -----\n" - f"Filename: {self.filename or ''}\n" - f"Invoice number: {self.invoice_number}\n" - f"Total amount including taxes: {self.total_amount}\n" - f"Total amount excluding taxes: {self.total_net}\n" - f"Invoice date: {self.invoice_date}\n" - f"Invoice due date: {self.due_date}\n" - f"Supplier name: {self.supplier}\n" - f"Supplier address: {self.supplier_address}\n" - f"Customer name: {self.customer_name}\n" - f"Customer company registration: {customer_company_registration}\n" - f"Customer address: {self.customer_address}\n" - f"Payment details: {payment_details}\n" - f"Company numbers: {company_numbers}\n" - f"Taxes: {taxes}\n" - f"Total taxes: {self.total_tax}\n" - f"Locale: {self.locale}\n" - "----------------------" + "Invoice V3 Prediction\n" + "=====================\n" + f":Filename: {self.filename or ''}\n" + f":Invoice number: {self.invoice_number}\n" + f":Total amount: {self.total_amount}\n" + f":Total net: {self.total_net}\n" + f":Invoice date: {self.invoice_date}\n" + f":Invoice due date: {self.due_date}\n" + f":Supplier name: {self.supplier}\n" + f":Supplier address: {self.supplier_address}\n" + f":Customer name: {self.customer_name}\n" + f":Customer company registration: {customer_company_registration}\n" + f":Customer address: {self.customer_address}\n" + f":Payment details: {payment_details}\n" + f":Company numbers: {company_numbers}\n" + f":Taxes: {self.taxes}\n" + f":Total tax: {self.total_tax}\n" + f":Locale: {self.locale}" ) def _reconstruct(self) -> None: diff --git a/mindee/documents/invoice/invoice_v4.py b/mindee/documents/invoice/invoice_v4.py index 14f07c4a..6421b520 100644 --- a/mindee/documents/invoice/invoice_v4.py +++ b/mindee/documents/invoice/invoice_v4.py @@ -9,7 +9,7 @@ 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.tax import Taxes from mindee.fields.text import TextField @@ -30,7 +30,7 @@ class InvoiceV4(Document): """List of Reference numbers including PO number.""" due_date: DateField """Date the invoice is due""" - taxes: List[TaxField] = [] + taxes: Taxes """List of all taxes""" total_tax: AmountField """Sum total of all taxes""" @@ -113,10 +113,7 @@ def _build_from_api_prediction( 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.taxes = Taxes(api_prediction["taxes"], page_id=page_n) self.supplier_payment_details = [ PaymentDetails(payment_detail, page_n=page_n) for payment_detail in api_prediction["supplier_payment_details"] @@ -140,7 +137,6 @@ def __str__(self) -> str: 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" @@ -148,26 +144,26 @@ def __str__(self) -> str: line_items += f" {item}\n" return clean_out_string( - "----- Invoice V4 -----\n" - f"Filename: {self.filename or ''}\n" - f"Locale: {self.locale}\n" - f"Invoice number: {self.invoice_number}\n" - f"Reference numbers: {reference_numbers}\n" - f"Invoice date: {self.invoice_date}\n" - f"Invoice due date: {self.due_date}\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 registrations: {customer_company_registrations}\n" - f"Customer address: {self.customer_address}\n" - f"Line Items: {line_items}" - f"Taxes: {taxes}\n" - f"Total taxes: {self.total_tax}\n" - f"Total amount excluding taxes: {self.total_net}\n" - f"Total amount including taxes: {self.total_amount}\n" - "----------------------" + "Invoice V4 Prediction\n" + "=====================\n" + f":Filename: {self.filename or ''}\n" + f":Locale: {self.locale}\n" + f":Invoice number: {self.invoice_number}\n" + f":Reference numbers: {reference_numbers}\n" + f":Invoice date: {self.invoice_date}\n" + f":Invoice due date: {self.due_date}\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 registrations: {customer_company_registrations}\n" + f":Customer address: {self.customer_address}\n" + f":Line Items: {line_items}" + f":Taxes: {self.taxes}\n" + f":Total tax: {self.total_tax}\n" + f":Total net: {self.total_net}\n" + f":Total amount: {self.total_amount}" ) def _reconstruct(self) -> None: diff --git a/mindee/documents/receipt/line_item_v5.py b/mindee/documents/receipt/line_item_v5.py index 365cb8c1..35319297 100644 --- a/mindee/documents/receipt/line_item_v5.py +++ b/mindee/documents/receipt/line_item_v5.py @@ -50,9 +50,9 @@ def __str__(self) -> str: if len(description) > 32: description = description[:32] + "..." row = [ + description, float_to_string(self.quantity), - float_to_string(self.unit_price), float_to_string(self.total_amount), - description, + float_to_string(self.unit_price), ] - return "| {:<8} | {:<8} | {:<9} | {:<34} |".format(*row) + return "| {:<36} | {:<8} | {:<12} | {:<10} |".format(*row) diff --git a/mindee/documents/receipt/receipt_v3.py b/mindee/documents/receipt/receipt_v3.py index 2cc5fe65..5dff5751 100644 --- a/mindee/documents/receipt/receipt_v3.py +++ b/mindee/documents/receipt/receipt_v3.py @@ -1,4 +1,4 @@ -from typing import List, Optional, TypeVar +from typing import Optional, TypeVar from mindee.documents.base import Document, TypeApiPrediction, clean_out_string from mindee.fields.amount import AmountField @@ -6,7 +6,7 @@ from mindee.fields.classification import ClassificationField from mindee.fields.date import DateField from mindee.fields.locale import LocaleField -from mindee.fields.tax import TaxField +from mindee.fields.tax import Taxes from mindee.fields.text import TextField @@ -23,7 +23,7 @@ class ReceiptV3(Document): """Service category""" merchant_name: TextField """Merchant's name""" - taxes: List[TaxField] + taxes: Taxes """List of all taxes""" total_tax: AmountField """Sum total of all taxes""" @@ -54,20 +54,19 @@ def __init__( self._reconstruct() def __str__(self) -> str: - taxes = "\n ".join(f"{t}" for t in self.taxes) return clean_out_string( - "-----Receipt data-----\n" - f"Filename: {self.filename or ''}\n" - f"Total amount including taxes: {self.total_incl}\n" - f"Total amount excluding taxes: {self.total_excl}\n" - f"Date: {self.date}\n" - f"Category: {self.category}\n" - f"Time: {self.time}\n" - f"Merchant name: {self.merchant_name}\n" - f"Taxes: {taxes}\n" - f"Total taxes: {self.total_tax}\n" - f"Locale: {self.locale}\n" - "----------------------" + "Receipt V3 Prediction\n" + "=====================\n" + f":Filename: {self.filename or ''}\n" + f":Total amount: {self.total_incl}\n" + f":Total net: {self.total_excl}\n" + f":Date: {self.date}\n" + f":Category: {self.category}\n" + f":Time: {self.time}\n" + f":Merchant name: {self.merchant_name}\n" + f":Taxes: {self.taxes}\n" + f":Total tax: {self.total_tax}\n" + f":Locale: {self.locale}" ) def _build_from_api_prediction( @@ -87,16 +86,7 @@ def _build_from_api_prediction( api_prediction["supplier"], value_key="value", page_n=page_n ) 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.taxes = Taxes(api_prediction["taxes"], page_id=page_n) self.total_tax = AmountField({"value": None, "confidence": 0.0}, page_n=page_n) self.total_excl = AmountField({"value": None, "confidence": 0.0}, page_n=page_n) diff --git a/mindee/documents/receipt/receipt_v4.py b/mindee/documents/receipt/receipt_v4.py index 04d92943..0f66e109 100644 --- a/mindee/documents/receipt/receipt_v4.py +++ b/mindee/documents/receipt/receipt_v4.py @@ -1,11 +1,11 @@ -from typing import List, Optional, TypeVar +from typing import Optional, TypeVar from mindee.documents.base import Document, TypeApiPrediction, clean_out_string from mindee.fields.amount import AmountField from mindee.fields.classification import ClassificationField from mindee.fields.date import DateField from mindee.fields.locale import LocaleField -from mindee.fields.tax import TaxField +from mindee.fields.tax import Taxes from mindee.fields.text import TextField @@ -26,7 +26,7 @@ class ReceiptV4(Document): """Whether the document is an expense receipt or a credit card receipt.""" supplier: TextField """The merchant, or supplier, as found on the receipt.""" - taxes: List[TaxField] + taxes: Taxes """List of all taxes.""" total_tax: AmountField """Total tax amount of the purchase.""" @@ -82,35 +82,25 @@ def _build_from_api_prediction( api_prediction["supplier"], value_key="value", page_n=page_n ) 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.taxes = Taxes(api_prediction["taxes"], page_id=page_n) def __str__(self) -> str: - taxes = "\n ".join(f"{t}" for t in self.taxes) return clean_out_string( - "----- Receipt V4 -----\n" - f"Filename: {self.filename or ''}\n" - f"Total amount: {self.total_amount}\n" - f"Total net: {self.total_net}\n" - f"Tip: {self.tip}\n" - f"Date: {self.date}\n" - f"Category: {self.category}\n" - f"Subcategory: {self.subcategory}\n" - f"Document type: {self.document_type}\n" - f"Time: {self.time}\n" - f"Supplier name: {self.supplier}\n" - f"Taxes: {taxes}\n" - f"Total taxes: {self.total_tax}\n" - f"Locale: {self.locale}\n" - "----------------------" + "Receipt V4 Prediction\n" + "=====================\n" + f":Filename: {self.filename or ''}\n" + f":Total amount: {self.total_amount}\n" + f":Total net: {self.total_net}\n" + f":Tip: {self.tip}\n" + f":Date: {self.date}\n" + f":Category: {self.category}\n" + f":Subcategory: {self.subcategory}\n" + f":Document type: {self.document_type}\n" + f":Time: {self.time}\n" + f":Supplier name: {self.supplier}\n" + f":Taxes: {self.taxes}\n" + f":Total tax: {self.total_tax}\n" + f":Locale: {self.locale}" ) def _checklist(self) -> None: diff --git a/mindee/documents/receipt/receipt_v5.py b/mindee/documents/receipt/receipt_v5.py index 5a56900d..84bf77ad 100644 --- a/mindee/documents/receipt/receipt_v5.py +++ b/mindee/documents/receipt/receipt_v5.py @@ -7,7 +7,7 @@ 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.tax import Taxes from mindee.fields.text import TextField @@ -34,7 +34,7 @@ class ReceiptV5(Document): """The address of the supplier or merchant.""" supplier_company_registrations: List[CompanyRegistrationField] """List of supplier company registrations or identifiers.""" - taxes: List[TaxField] + taxes: Taxes """List of tax lines information including: Amount, tax rate, tax base amount and tax code.""" total_tax: AmountField """The total amount of taxes.""" @@ -102,58 +102,55 @@ def _build_from_api_prediction( 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.taxes = Taxes(api_prediction["taxes"], page_id=page_n) self.line_items = [ ReceiptV5LineItem(prediction=line_item, page_n=page_n) for line_item in api_prediction["line_items"] ] + @staticmethod + def _line_items_separator(char: str): + out_str = " " + out_str += f"+{char * 38}" + out_str += f"+{char * 10}" + out_str += f"+{char * 14}" + out_str += f"+{char * 12}" + return out_str + "+" + 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 +==========+==========+===========+====================================+" + f"\n{self._line_items_separator('-')}" + "\n | Description | Quantity | Total Amount | Unit Price |" + f"\n{self._line_items_separator('=')}" ) for item in self.line_items: - line_items += ( - f"\n {item}" - "\n +----------+----------+-----------+------------------------------------+" - ) + line_items += f"\n {item}\n{self._line_items_separator('-')}" return clean_out_string( - "Receipt V5 Prediction\n=====================\n" + "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":Purchase Date: {self.date}\n" + f":Purchase Time: {self.time}\n" + f":Total Amount: {self.total_amount}\n" + f":Total Excluding Taxes: {self.total_net}\n" + f":Total Tax: {self.total_tax}\n" + f":Tip and Gratuity: {self.tip}\n" + f":Taxes: {self.taxes}\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":Supplier Address: {self.supplier_address}\n" + f":Supplier Phone Number: {self.supplier_phone_number}\n" f":Line Items: {line_items}\n" - f":Taxes: {taxes}\n" - f":Total Taxes: {self.total_tax}\n" ) def _checklist(self) -> None: diff --git a/mindee/fields/tax.py b/mindee/fields/tax.py index dd8b8155..510f23fe 100644 --- a/mindee/fields/tax.py +++ b/mindee/fields/tax.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Dict, List, Optional from mindee.fields.base import ( BaseField, @@ -12,18 +12,16 @@ class TaxField(FieldPositionMixin, BaseField): value: Optional[float] """The amount of the tax line.""" rate: Optional[float] - """The tax rate, represented as a float between 0 and 1.""" + """The tax rate.""" code: Optional[str] - "The tax code." + "The tax code (HST, GST... for Canadian; City Tax, State tax for US, etc..)." basis: Optional[float] - "The amount used to calculate the tax." + "The tax base." def __init__( self, prediction: TypePrediction, value_key: str = "value", - rate_key: str = "rate", - code_key: str = "code", reconstructed: bool = False, page_n: Optional[int] = None, ): @@ -32,8 +30,6 @@ def __init__( :param prediction: Tax prediction object from HTTP response :param value_key: Key to use in the tax_prediction dict - :param rate_key: Key to use for getting the Tax rate in the tax_prediction dict - :param code_key: Key to use for getting the Tax code in the tax_prediction dict :param reconstructed: Bool for reconstructed object (not extracted in the API) :param page_n: Page number for multi pages document """ @@ -47,12 +43,12 @@ def __init__( self._set_position(prediction) try: - self.rate = float(prediction[rate_key]) + self.rate = float(prediction["rate"]) except (ValueError, TypeError, KeyError): self.rate = None try: - self.code = str(prediction[code_key]) + self.code = str(prediction["code"]) except (TypeError, KeyError): self.code = None if self.code in ("N/A", "None"): @@ -64,15 +60,62 @@ def __init__( self.basis = None try: - self.value = float(prediction[value_key]) + self.value = float(prediction["value"]) except (ValueError, TypeError, KeyError): self.value = None self.confidence = 0.0 + def _printable_values(self) -> Dict[str, str]: + return { + "code": self.code if self.code is not None else "", + "basis": float_to_string(self.basis) if self.basis is not None else "", + "rate": float_to_string(self.rate) if self.rate is not None else "", + "value": float_to_string(self.value) if self.value is not None else "", + } + + def to_table_line(self) -> str: + """Output in a format suitable for inclusion in an rST table.""" + printable = self._printable_values() + return ( + f"| {printable['basis']:<13}" + f" | {printable['code']:<6}" + f" | {printable['rate']:<8}" + f" | {printable['value']:<13}" + " |" + ) + def __str__(self) -> str: - out_str = float_to_string(self.value) - if self.rate is not None: - out_str += f" {float_to_string(self.rate)}%" - if self.code is not None: - out_str += f" {self.code}" - return out_str.strip() + """Default string representation.""" + printable = self._printable_values() + return ( + f"Base: {printable['basis']}, " + f"Code: {printable['code']}, " + f"Rate (%): {printable['rate']}, " + f"Amount: {printable['value']}" + ).strip() + + +class Taxes(List[TaxField]): + @staticmethod + def _line_separator(char: str): + out_str = " " + out_str += f"+{char * 15}" + out_str += f"+{char * 8}" + out_str += f"+{char * 10}" + out_str += f"+{char * 15}" + return out_str + "+" + + def __init__(self, api_prediction: List[TypePrediction], page_id: Optional[int]): + super().__init__() + for entry in api_prediction: + tax = TaxField(entry, page_n=page_id) + self.append(tax) + + def __str__(self) -> str: + out_str = f"\n{self._line_separator('-')}\n" + out_str += " | Base | Code | Rate (%) | Amount |\n" + out_str += f"{self._line_separator('=')}" + out_str += "\n".join( + f"\n {t.to_table_line()}\n{self._line_separator('-')}" for t in self + ) + return out_str diff --git a/tests/data b/tests/data index eb57e829..f38ddf1a 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit eb57e8297078fc3dd34739fc7c38a33148827cbd +Subproject commit f38ddf1a7ee7c5fe3508400add0648eeec075e84 diff --git a/tests/documents/test_financial_document_v1.py b/tests/documents/test_financial_document_v1.py index 47acdc5b..70ddf4f6 100644 --- a/tests/documents/test_financial_document_v1.py +++ b/tests/documents/test_financial_document_v1.py @@ -44,22 +44,14 @@ def test_doc_constructor_invoice(financial_doc_from_invoice_object): financial_doc_from_invoice_object.supplier_address.value == "4490 Oak Drive Albany, NY 12210" ) - doc_str = ( - open(f"{FINANCIAL_DOC_DATA_DIR}/response_v1/invoice_to_string.txt") - .read() - .strip() - ) + doc_str = open(f"{FINANCIAL_DOC_DATA_DIR}/response_v1/invoice_to_string.rst").read() assert str(financial_doc_from_invoice_object) == doc_str 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() - ) + doc_str = open(f"{FINANCIAL_DOC_DATA_DIR}/response_v1/receipt_to_string.rst").read() assert str(financial_doc_from_receipt_object) == doc_str diff --git a/tests/documents/test_invoice_v3.py b/tests/documents/test_invoice_v3.py index f8face63..5bb3ca9e 100644 --- a/tests/documents/test_invoice_v3.py +++ b/tests/documents/test_invoice_v3.py @@ -47,12 +47,12 @@ def test_doc_constructor(invoice_v3_doc_object): assert invoice_v3_doc_object.invoice_date.confidence == 0.99 assert invoice_v3_doc_object.invoice_number.value == "0042004801351" assert invoice_v3_doc_object.invoice_number.confidence == 0.95 - doc_str = open(f"{INVOICE_DATA_DIR}/response_v3/doc_to_string.txt").read().strip() + doc_str = open(f"{INVOICE_DATA_DIR}/response_v3/doc_to_string.rst").read().strip() assert str(invoice_v3_doc_object) == doc_str def test_page_constructor(invoice_v3_page_object): - doc_str = open(f"{INVOICE_DATA_DIR}/response_v3/page0_to_string.txt").read().strip() + doc_str = open(f"{INVOICE_DATA_DIR}/response_v3/page0_to_string.rst").read().strip() assert invoice_v3_page_object.orientation.value == 0 assert invoice_v3_page_object.invoice_number.page_n == 0 assert str(invoice_v3_page_object) == doc_str diff --git a/tests/documents/test_invoice_v4.py b/tests/documents/test_invoice_v4.py index fca05935..3e39a9af 100644 --- a/tests/documents/test_invoice_v4.py +++ b/tests/documents/test_invoice_v4.py @@ -52,12 +52,12 @@ def test_doc_constructor(invoice_v4_doc_object): for line_item in invoice_v4_doc_object.line_items: assert line_item.page_n == 0 or line_item.page_n == 1 assert len(line_item.polygon) == 4 - doc_str = open(f"{INVOICE_DATA_DIR}/response_v4/doc_to_string.txt").read().strip() + doc_str = open(f"{INVOICE_DATA_DIR}/response_v4/doc_to_string.rst").read().strip() assert str(invoice_v4_doc_object) == doc_str def test_page_constructor(invoice_v4_page_object): - doc_str = open(f"{INVOICE_DATA_DIR}/response_v4/page0_to_string.txt").read().strip() + doc_str = open(f"{INVOICE_DATA_DIR}/response_v4/page0_to_string.rst").read().strip() assert invoice_v4_page_object.orientation.value == 0 assert invoice_v4_page_object.invoice_number.page_n == 0 assert str(invoice_v4_page_object) == doc_str diff --git a/tests/documents/test_receipt_v3.py b/tests/documents/test_receipt_v3.py index ccc325d6..f6f14ea4 100644 --- a/tests/documents/test_receipt_v3.py +++ b/tests/documents/test_receipt_v3.py @@ -31,7 +31,7 @@ def test_doc_constructor(receipt_v3_doc_object): assert receipt_v3_doc_object.date.value == "2016-02-26" assert receipt_v3_doc_object.total_tax.value == 1.7 assert receipt_v3_doc_object.checklist["taxes_match_total_incl"] is True - doc_str = open(f"{RECEIPT_DATA_DIR}/response_v3/doc_to_string.txt").read().strip() + doc_str = open(f"{RECEIPT_DATA_DIR}/response_v3/doc_to_string.rst").read().strip() assert receipt_v3_doc_object.date.page_n == 0 assert str(receipt_v3_doc_object) == doc_str diff --git a/tests/documents/test_receipt_v4.py b/tests/documents/test_receipt_v4.py index 25531c45..a4f24c1d 100644 --- a/tests/documents/test_receipt_v4.py +++ b/tests/documents/test_receipt_v4.py @@ -32,7 +32,7 @@ def receipt_v4_page_object(): def test_doc_constructor(receipt_v4_doc_object): assert receipt_v4_doc_object.date.value == "2014-07-07" assert receipt_v4_doc_object.total_tax.value == 3.34 - doc_str = open(f"{RECEIPT_DATA_DIR}/response_v4/doc_to_string.txt").read().strip() + doc_str = open(f"{RECEIPT_DATA_DIR}/response_v4/doc_to_string.rst").read().strip() assert receipt_v4_doc_object.orientation is None assert receipt_v4_doc_object.date.page_n == 0 assert str(receipt_v4_doc_object) == doc_str @@ -41,7 +41,7 @@ def test_doc_constructor(receipt_v4_doc_object): def test_page_constructor(receipt_v4_page_object): assert receipt_v4_page_object.date.value == "2014-07-07" assert receipt_v4_page_object.total_tax.value == 3.34 - doc_str = open(f"{RECEIPT_DATA_DIR}/response_v4/page0_to_string.txt").read().strip() + doc_str = open(f"{RECEIPT_DATA_DIR}/response_v4/page0_to_string.rst").read().strip() assert receipt_v4_page_object.orientation.value == 0 assert receipt_v4_page_object.date.page_n == 0 assert str(receipt_v4_page_object) == doc_str diff --git a/tests/fields/test_tax.py b/tests/fields/test_tax.py index 7d40825b..4a134cad 100644 --- a/tests/fields/test_tax.py +++ b/tests/fields/test_tax.py @@ -14,7 +14,7 @@ def test_constructor(): assert tax.confidence == 0.1 assert tax.rate == 0.2 assert len(tax.bounding_box) > 0 - assert str(tax) == "2.00 0.20% QST" + assert str(tax) == "Base: , Code: QST, Rate (%): 0.20, Amount: 2.00" def test_constructor_no_rate(): @@ -22,14 +22,14 @@ def test_constructor_no_rate(): tax = TaxField(field_dict) assert tax.rate is None assert tax.bounding_box is None - assert str(tax) == "2.00" + assert str(tax) == "Base: , Code: , Rate (%): , Amount: 2.00" def test_constructor_no_amount(): field_dict = {"value": "NA", "rate": "AA", "code": "N/A", "confidence": 0.1} tax = TaxField(field_dict) assert tax.value is None - assert str(tax) == "" + assert str(tax) == "Base: , Code: , Rate (%): , Amount:" def test_constructor_only_code(): @@ -41,4 +41,4 @@ def test_constructor_only_code(): } tax = TaxField(field_dict) assert tax.value is None - assert str(tax) == "TAXES AND FEES" + assert str(tax) == "Base: , Code: TAXES AND FEES, Rate (%): , Amount:"