import datetime from typing import List from uuid import uuid4 from xml.dom import minidom from xml.etree.ElementTree import Element, SubElement, tostring from vbv_lernwelt.shop.invoice.creator import InvoiceCreator, Item from vbv_lernwelt.shop.invoice.repositories import InvoiceRepository from vbv_lernwelt.shop.models import CheckoutInformation class AbacusInvoiceCreator(InvoiceCreator): def __init__(self, repository: InvoiceRepository): self.repository = repository def create_invoice( self, checkout_information: CheckoutInformation, filename: str = None, ): customer_number = checkout_information.transaction_id order_date = checkout_information.created_at.date() reference_purchase_order = str(checkout_information.id) unic_id = checkout_information.transaction_id items = [ Item( product_number=checkout_information.product_sku, quantity=1, description=checkout_information.product_description, ) ] invoice = self.invoice_xml( customer_number, order_date, reference_purchase_order, unic_id, items, ) if filename is None: filename = f"vbv-vv-{uuid4().hex}.xml" self.repository.upload_invoice(invoice, filename) @staticmethod def invoice_xml( customer_number: str, order_date: datetime.date, reference_purchase_order: str, unic_id: str, items: List[Item], ) -> str: container = Element("AbaConnectContainer") task = SubElement(container, "Task") parameter = SubElement(task, "Parameter") SubElement(parameter, "Application").text = "ORDE" SubElement(parameter, "Id").text = "Verkaufsauftrag" SubElement(parameter, "MapId").text = "AbaDefault" SubElement(parameter, "Version").text = "2022.00" transaction = SubElement(task, "Transaction") sales_order_header = SubElement(transaction, "SalesOrderHeader", mode="SAVE") sales_order_header_fields = SubElement( sales_order_header, "SalesOrderHeaderFields", mode="SAVE" ) SubElement(sales_order_header_fields, "CustomerNumber").text = customer_number SubElement( sales_order_header_fields, "PurchaseOrderDate" ).text = order_date.isoformat() SubElement( sales_order_header_fields, "DeliveryDate" ).text = order_date.isoformat() SubElement( sales_order_header_fields, "ReferencePurchaseOrder" ).text = reference_purchase_order SubElement(sales_order_header_fields, "UnicId").text = unic_id for index, item in enumerate(items, start=1): item_element = SubElement(sales_order_header, "Item", mode="SAVE") item_fields = SubElement(item_element, "ItemFields", mode="SAVE") SubElement(item_fields, "ItemNumber").text = str(index) SubElement(item_fields, "ProductNumber").text = item.product_number SubElement(item_fields, "QuantityOrdered").text = str(item.quantity) item_text = SubElement(item_element, "ItemText", mode="SAVE") item_text_fields = SubElement(item_text, "ItemTextFields", mode="SAVE") SubElement(item_text_fields, "Text").text = item.description return AbacusInvoiceCreator.create_xml_string(container) @staticmethod def customer_xml( customer_number: str, name: str, first_name: str, address_text: str, street: str, house_number: str, zip_code: str, city: str, country: str, language: str, email: str, ): container = Element("AbaConnectContainer") task = SubElement(container, "Task") parameter = SubElement(task, "Parameter") SubElement(parameter, "Application").text = "DEBI" SubElement(parameter, "ID").text = "Kunden" SubElement(parameter, "MapID").text = "AbaDefault" SubElement(parameter, "Version").text = "2022.00" transaction = SubElement(task, "Transaction") customer_element = SubElement(transaction, "Customer", mode="SAVE") SubElement(customer_element, "CustomerNumber").text = customer_number SubElement(customer_element, "DefaultCurrency").text = "CHF" SubElement(customer_element, "PaymentTermNumber").text = "1" SubElement(customer_element, "ReminderProcedure").text = "NORM" address_data = SubElement(customer_element, "AddressData", mode="SAVE") SubElement(address_data, "AddressNumber").text = customer_number SubElement(address_data, "Name").text = name SubElement(address_data, "FirstName").text = first_name SubElement(address_data, "Text").text = address_text SubElement(address_data, "Street").text = street SubElement(address_data, "HouseNumber").text = house_number SubElement(address_data, "ZIP").text = zip_code SubElement(address_data, "City").text = city SubElement(address_data, "Country").text = country SubElement(address_data, "Language").text = language SubElement(address_data, "Email").text = email return AbacusInvoiceCreator.create_xml_string(container) @staticmethod def create_xml_string(container: Element, encoding: str = "UTF-8") -> str: xml_bytes = tostring(container, encoding) xml_pretty_str = minidom.parseString(xml_bytes).toprettyxml( indent=" ", encoding=encoding ) return xml_pretty_str.decode(encoding)