Refactor Abacus invoice xml code
This commit is contained in:
parent
059a4cad5c
commit
677467d4c3
|
|
@ -31,7 +31,7 @@ class AbacusInvoiceCreator(InvoiceCreator):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
invoice = self.invoice_xml(
|
invoice = self.render_invoice_xml(
|
||||||
customer_number,
|
customer_number,
|
||||||
order_date,
|
order_date,
|
||||||
reference_purchase_order,
|
reference_purchase_order,
|
||||||
|
|
@ -45,12 +45,12 @@ class AbacusInvoiceCreator(InvoiceCreator):
|
||||||
self.repository.upload_invoice(invoice, filename)
|
self.repository.upload_invoice(invoice, filename)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def invoice_xml(
|
def render_invoice_xml(
|
||||||
customer_number: str,
|
abacus_debitor_number: int,
|
||||||
|
abacus_order_id: int,
|
||||||
|
datatrans_transaction_id: str,
|
||||||
order_date: datetime.date,
|
order_date: datetime.date,
|
||||||
reference_purchase_order: str,
|
item_description: str,
|
||||||
unic_id: str,
|
|
||||||
items: List[Item],
|
|
||||||
) -> str:
|
) -> str:
|
||||||
container = Element("AbaConnectContainer")
|
container = Element("AbaConnectContainer")
|
||||||
task = SubElement(container, "Task")
|
task = SubElement(container, "Task")
|
||||||
|
|
@ -66,37 +66,51 @@ class AbacusInvoiceCreator(InvoiceCreator):
|
||||||
sales_order_header, "SalesOrderHeaderFields", mode="SAVE"
|
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(
|
SubElement(
|
||||||
sales_order_header_fields, "PurchaseOrderDate"
|
sales_order_header_fields, "PurchaseOrderDate"
|
||||||
).text = order_date.isoformat()
|
).text = order_date.isoformat()
|
||||||
SubElement(
|
|
||||||
sales_order_header_fields, "DeliveryDate"
|
# Skender: ePayment: TRANSACTION-ID von Datatrans in Bestellreferenz
|
||||||
).text = order_date.isoformat()
|
|
||||||
SubElement(
|
SubElement(
|
||||||
sales_order_header_fields, "ReferencePurchaseOrder"
|
sales_order_header_fields, "ReferencePurchaseOrder"
|
||||||
).text = reference_purchase_order
|
).text = datatrans_transaction_id
|
||||||
SubElement(sales_order_header_fields, "UnicId").text = unic_id
|
|
||||||
|
|
||||||
for index, item in enumerate(items, start=1):
|
# Skender: ePayment: OrderID. max 10 Ziffern, erste Ziffer abhängig von der Plattform (4 = LMS, 6 = myVBV, 7 = EduManager)
|
||||||
item_element = SubElement(sales_order_header, "Item", mode="SAVE")
|
SubElement(sales_order_header_fields, "GroupingNumberAscii1").text = str(
|
||||||
item_fields = SubElement(item_element, "ItemFields", mode="SAVE")
|
abacus_order_id
|
||||||
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_element = SubElement(sales_order_header, "Item", mode="SAVE")
|
||||||
item_text_fields = SubElement(item_text, "ItemTextFields", mode="SAVE")
|
item_fields = SubElement(item_element, "ItemFields", mode="SAVE")
|
||||||
SubElement(item_text_fields, "Text").text = item.description
|
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)
|
return AbacusInvoiceCreator.create_xml_string(container)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def customer_xml(
|
def render_customer_xml(
|
||||||
customer_number: str,
|
abacus_debitor_number: int,
|
||||||
name: str,
|
last_name: str,
|
||||||
first_name: str,
|
first_name: str,
|
||||||
address_text: str,
|
company_name: str,
|
||||||
street: str,
|
street: str,
|
||||||
house_number: str,
|
house_number: str,
|
||||||
zip_code: str,
|
zip_code: str,
|
||||||
|
|
@ -117,16 +131,16 @@ class AbacusInvoiceCreator(InvoiceCreator):
|
||||||
transaction = SubElement(task, "Transaction")
|
transaction = SubElement(task, "Transaction")
|
||||||
customer_element = SubElement(transaction, "Customer", mode="SAVE")
|
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, "DefaultCurrency").text = "CHF"
|
||||||
SubElement(customer_element, "PaymentTermNumber").text = "1"
|
SubElement(customer_element, "PaymentTermNumber").text = "1"
|
||||||
SubElement(customer_element, "ReminderProcedure").text = "NORM"
|
SubElement(customer_element, "ReminderProcedure").text = "NORM"
|
||||||
|
|
||||||
address_data = SubElement(customer_element, "AddressData", mode="SAVE")
|
address_data = SubElement(customer_element, "AddressData", mode="SAVE")
|
||||||
SubElement(address_data, "AddressNumber").text = customer_number
|
SubElement(address_data, "AddressNumber").text = str(abacus_debitor_number)
|
||||||
SubElement(address_data, "Name").text = name
|
SubElement(address_data, "Name").text = last_name
|
||||||
SubElement(address_data, "FirstName").text = first_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, "Street").text = street
|
||||||
SubElement(address_data, "HouseNumber").text = house_number
|
SubElement(address_data, "HouseNumber").text = house_number
|
||||||
SubElement(address_data, "ZIP").text = zip_code
|
SubElement(address_data, "ZIP").text = zip_code
|
||||||
|
|
@ -138,7 +152,7 @@ class AbacusInvoiceCreator(InvoiceCreator):
|
||||||
return AbacusInvoiceCreator.create_xml_string(container)
|
return AbacusInvoiceCreator.create_xml_string(container)
|
||||||
|
|
||||||
@staticmethod
|
@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_bytes = tostring(container, encoding)
|
||||||
xml_pretty_str = minidom.parseString(xml_bytes).toprettyxml(
|
xml_pretty_str = minidom.parseString(xml_bytes).toprettyxml(
|
||||||
indent=" ", encoding=encoding
|
indent=" ", encoding=encoding
|
||||||
|
|
|
||||||
|
|
@ -23,30 +23,122 @@ class InvoiceTestCase(TestCase):
|
||||||
is_active=True,
|
is_active=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_render_invoice(self):
|
def test_render_invoice_xml(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
creator = AbacusInvoiceCreator(repository=create_autospec(InvoiceRepository))
|
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
|
# WHEN
|
||||||
invoice_xml = creator.invoice_xml(
|
invoice_xml = creator.render_invoice_xml(
|
||||||
customer_number,
|
abacus_debitor_number=60000012,
|
||||||
order_date,
|
abacus_order_id=6000000001,
|
||||||
reference_purchase_order,
|
order_date=date(2024, 2, 15),
|
||||||
unic_id,
|
datatrans_transaction_id="24021508331287484",
|
||||||
items,
|
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
|
# THEN
|
||||||
assert "<CustomerNumber>12345</CustomerNumber>" in invoice_xml
|
self.maxDiff = None
|
||||||
assert "<ItemNumber>1</ItemNumber>" in invoice_xml
|
self.assertXMLEqual(expected_xml, invoice_xml)
|
||||||
assert "<ProductNumber>001</ProductNumber>" in invoice_xml
|
|
||||||
assert "<QuantityOrdered>1</QuantityOrdered>" in invoice_xml
|
def test_render_customer_xml(self):
|
||||||
assert "<Text>Test Item</Text>" in invoice_xml
|
# 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):
|
def test_create_invoice_calls_upload(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue