vbv/server/vbv_lernwelt/shop/invoice/abacus.py

147 lines
5.6 KiB
Python

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)