Refactor Abacus invoice xml code

This commit is contained in:
Daniel Egger 2024-05-29 14:22:35 +02:00
parent 059a4cad5c
commit 677467d4c3
2 changed files with 153 additions and 47 deletions

View File

@ -31,7 +31,7 @@ class AbacusInvoiceCreator(InvoiceCreator):
)
]
invoice = self.invoice_xml(
invoice = self.render_invoice_xml(
customer_number,
order_date,
reference_purchase_order,
@ -45,12 +45,12 @@ class AbacusInvoiceCreator(InvoiceCreator):
self.repository.upload_invoice(invoice, filename)
@staticmethod
def invoice_xml(
customer_number: str,
def render_invoice_xml(
abacus_debitor_number: int,
abacus_order_id: int,
datatrans_transaction_id: str,
order_date: datetime.date,
reference_purchase_order: str,
unic_id: str,
items: List[Item],
item_description: str,
) -> str:
container = Element("AbaConnectContainer")
task = SubElement(container, "Task")
@ -66,37 +66,51 @@ class AbacusInvoiceCreator(InvoiceCreator):
sales_order_header, "SalesOrderHeaderFields", mode="SAVE"
)
SubElement(sales_order_header_fields, "CustomerNumber").text = customer_number
# Skender: Kundennummer, erste Ziffer abhängig von der Plattform (4 = LMS, 6 = myVBV, 7 = EduManager), Plattform führt ein eigenständiges hochzählendes Mapping.
SubElement(sales_order_header_fields, "CustomerNumber").text = str(
abacus_debitor_number
)
# Skender: ePayment: Ablaufnr. für ePayment Rechnung in Abacus
SubElement(sales_order_header_fields, "ProcessFlowNumber").text = "30"
# Skender: ePayment: Zahlungskondition für ePaymente in Abacus 9999 Tage Mahnungsfrist, da schon bezahlt
SubElement(sales_order_header_fields, "PaymentCode").text = "9999"
# Skender: Bestellzeitpunkt
SubElement(
sales_order_header_fields, "PurchaseOrderDate"
).text = order_date.isoformat()
SubElement(
sales_order_header_fields, "DeliveryDate"
).text = order_date.isoformat()
# Skender: ePayment: TRANSACTION-ID von Datatrans in Bestellreferenz
SubElement(
sales_order_header_fields, "ReferencePurchaseOrder"
).text = reference_purchase_order
SubElement(sales_order_header_fields, "UnicId").text = unic_id
).text = datatrans_transaction_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)
# Skender: ePayment: OrderID. max 10 Ziffern, erste Ziffer abhängig von der Plattform (4 = LMS, 6 = myVBV, 7 = EduManager)
SubElement(sales_order_header_fields, "GroupingNumberAscii1").text = str(
abacus_order_id
)
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
item_element = SubElement(sales_order_header, "Item", mode="SAVE")
item_fields = SubElement(item_element, "ItemFields", mode="SAVE")
SubElement(item_fields, "DeliveryDate").text = order_date.isoformat()
SubElement(item_fields, "ItemNumber").text = "1"
SubElement(item_fields, "ProductNumber").text = "30202"
SubElement(item_fields, "QuantityOrdered").text = "1"
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,
def render_customer_xml(
abacus_debitor_number: int,
last_name: str,
first_name: str,
address_text: str,
company_name: str,
street: str,
house_number: str,
zip_code: str,
@ -117,16 +131,16 @@ class AbacusInvoiceCreator(InvoiceCreator):
transaction = SubElement(task, "Transaction")
customer_element = SubElement(transaction, "Customer", mode="SAVE")
SubElement(customer_element, "CustomerNumber").text = customer_number
SubElement(customer_element, "CustomerNumber").text = str(abacus_debitor_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, "AddressNumber").text = str(abacus_debitor_number)
SubElement(address_data, "Name").text = last_name
SubElement(address_data, "FirstName").text = first_name
SubElement(address_data, "Text").text = address_text
SubElement(address_data, "Text").text = company_name
SubElement(address_data, "Street").text = street
SubElement(address_data, "HouseNumber").text = house_number
SubElement(address_data, "ZIP").text = zip_code
@ -138,7 +152,7 @@ class AbacusInvoiceCreator(InvoiceCreator):
return AbacusInvoiceCreator.create_xml_string(container)
@staticmethod
def create_xml_string(container: Element, encoding: str = "UTF-8") -> str:
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

View File

@ -23,30 +23,122 @@ class InvoiceTestCase(TestCase):
is_active=True,
)
def test_render_invoice(self):
def test_render_invoice_xml(self):
# GIVEN
creator = AbacusInvoiceCreator(repository=create_autospec(InvoiceRepository))
items = [Item(product_number="001", quantity=1, description="Test Item")]
customer_number = "12345"
order_date = date(2023, 1, 1)
reference_purchase_order = "PO12345678"
unic_id = "UNIC001"
# WHEN
invoice_xml = creator.invoice_xml(
customer_number,
order_date,
reference_purchase_order,
unic_id,
items,
invoice_xml = creator.render_invoice_xml(
abacus_debitor_number=60000012,
abacus_order_id=6000000001,
order_date=date(2024, 2, 15),
datatrans_transaction_id="24021508331287484",
item_description="myVBV Versicherungsvermittler - Lernpfad, 2024-02-15, Skender, Gebhart-Krasniqi",
)
# example from Skender
expected_xml = """<?xml version="1.0" encoding="utf-8"?>
<AbaConnectContainer>
<Task>
<Parameter>
<Application>ORDE</Application>
<Id>Verkaufsauftrag</Id>
<MapId>AbaDefault</MapId>
<Version>2022.00</Version>
</Parameter>
<Transaction>
<SalesOrderHeader mode="SAVE">
<SalesOrderHeaderFields mode="SAVE">
<CustomerNumber>60000012</CustomerNumber>
<ProcessFlowNumber>30</ProcessFlowNumber>
<PaymentCode>9999</PaymentCode>
<PurchaseOrderDate>2024-02-15</PurchaseOrderDate>
<ReferencePurchaseOrder>24021508331287484</ReferencePurchaseOrder>
<GroupingNumberAscii1>6000000001</GroupingNumberAscii1>
</SalesOrderHeaderFields>
<Item mode="SAVE">
<ItemFields mode="SAVE">
<DeliveryDate>2024-02-15</DeliveryDate>
<ItemNumber>1</ItemNumber>
<ProductNumber>30202</ProductNumber>
<QuantityOrdered>1</QuantityOrdered>
</ItemFields>
<ItemText mode="SAVE">
<ItemTextFields mode="SAVE">
<Text>myVBV Versicherungsvermittler - Lernpfad, 2024-02-15, Skender, Gebhart-Krasniqi</Text>
</ItemTextFields>
</ItemText>
</Item>
</SalesOrderHeader>
</Transaction>
</Task>
</AbaConnectContainer>
"""
# THEN
assert "<CustomerNumber>12345</CustomerNumber>" in invoice_xml
assert "<ItemNumber>1</ItemNumber>" in invoice_xml
assert "<ProductNumber>001</ProductNumber>" in invoice_xml
assert "<QuantityOrdered>1</QuantityOrdered>" in invoice_xml
assert "<Text>Test Item</Text>" in invoice_xml
self.maxDiff = None
self.assertXMLEqual(expected_xml, invoice_xml)
def test_render_customer_xml(self):
# GIVEN
creator = AbacusInvoiceCreator(
repository=create_autospec(InvoiceRepository))
# WHEN
customer_xml = creator.render_customer_xml(
abacus_debitor_number=60000012,
last_name="Gebhart-Krasniqi",
first_name="Skender",
company_name="VBV",
street="Laupenstrasse",
house_number="10",
zip_code="3000",
city="Bern",
country="CH",
language="de",
email="skender.krasniqi@vbv-afa.ch"
)
print(customer_xml)
# example from Skender
expected_xml = """<?xml version="1.0" encoding="utf-8"?>
<AbaConnectContainer>
<Task>
<Parameter>
<Application>DEBI</Application>
<ID>Kunden</ID>
<MapID>AbaDefault</MapID>
<Version>2022.00</Version>
</Parameter>
<Transaction>
<Customer mode="SAVE">
<CustomerNumber>60000012</CustomerNumber>
<DefaultCurrency>CHF</DefaultCurrency>
<PaymentTermNumber>1</PaymentTermNumber>
<ReminderProcedure>NORM</ReminderProcedure>
<AddressData mode="SAVE">
<AddressNumber>60000012</AddressNumber>
<Name>Gebhart-Krasniqi</Name>
<FirstName>Skender</FirstName>
<Text>VBV</Text>
<Street>Laupenstrasse</Street>
<HouseNumber>10</HouseNumber>
<ZIP>3000</ZIP>
<City>Bern</City>
<Country>CH</Country>
<Language>de</Language>
<Email>skender.krasniqi@vbv-afa.ch</Email>
</AddressData>
</Customer>
</Transaction>
</Task>
</AbaConnectContainer>
"""
# THEN
self.maxDiff = None
self.assertXMLEqual(expected_xml, customer_xml)
def test_create_invoice_calls_upload(self):
# GIVEN