Refactor abacus XML code

This commit is contained in:
Daniel Egger 2024-05-30 11:20:32 +02:00
parent 590b6a17bc
commit 8ce7f9935e
3 changed files with 248 additions and 126 deletions

View File

@ -1,5 +1,4 @@
import datetime import datetime
from typing import List
from uuid import uuid4 from uuid import uuid4
from xml.dom import minidom from xml.dom import minidom
from xml.etree.ElementTree import Element, SubElement, tostring from xml.etree.ElementTree import Element, SubElement, tostring
@ -44,17 +43,62 @@ class AbacusInvoiceCreator(InvoiceCreator):
self.repository.upload_invoice(invoice, filename) self.repository.upload_invoice(invoice, filename)
def create_invoice_xml(self, checkout_information: CheckoutInformation):
pass
@staticmethod def create_invoice_xml(checkout_information: CheckoutInformation):
def render_invoice_xml( # set fill abacus numbers
checkout_information = checkout_information.set_increment_abacus_order_id()
customer = checkout_information.user.set_increment_abacus_debitor_number()
invoice_xml_content = render_invoice_xml(
abacus_debitor_number=customer.abacus_debitor_number,
abacus_order_id=checkout_information.abacus_order_id,
datatrans_transaction_id=checkout_information.transaction_id,
order_date=checkout_information.created_at.date(),
# TODO was ist der korrekte text für die item_description?
item_description=f"{checkout_information.product_name} - {checkout_information.created_at.date().isoformat()} - {checkout_information.user.last_name} {checkout_information.user.first_name}",
)
# YYYYMMDDhhmmss
filename_datetime = checkout_information.created_at.strftime("%Y%m%d%H%M%S")
invoice_xml_filename = f"myVBV_orde_{customer.abacus_debitor_number}_{filename_datetime}_{checkout_information.abacus_order_id}.xml"
return invoice_xml_filename, invoice_xml_content
def create_customer_xml(checkout_information: CheckoutInformation):
customer = checkout_information.user.set_increment_abacus_debitor_number()
customer_xml_content = render_customer_xml(
abacus_debitor_number=customer.abacus_debitor_number,
last_name=checkout_information.last_name,
first_name=checkout_information.first_name,
company_name=checkout_information.company_name,
street=(checkout_information.company_street or checkout_information.street),
house_number=(
checkout_information.company_street_number
or checkout_information.street_number
),
zip_code=(
checkout_information.company_postal_code or checkout_information.postal_code
),
city=(checkout_information.company_city or checkout_information.city),
country=(checkout_information.company_country or checkout_information.country),
language=customer.language,
email=customer.email,
)
customer_xml_filename = f"myVBV_debi_{customer.abacus_debitor_number}.xml"
return customer_xml_filename, customer_xml_content
def render_invoice_xml(
abacus_debitor_number: int, abacus_debitor_number: int,
abacus_order_id: int, abacus_order_id: int,
datatrans_transaction_id: str, datatrans_transaction_id: str,
order_date: datetime.date, order_date: datetime.date,
item_description: str, item_description: str,
) -> str: ) -> str:
container = Element("AbaConnectContainer") container = Element("AbaConnectContainer")
task = SubElement(container, "Task") task = SubElement(container, "Task")
parameter = SubElement(task, "Parameter") parameter = SubElement(task, "Parameter")
@ -106,10 +150,10 @@ class AbacusInvoiceCreator(InvoiceCreator):
item_text_fields = SubElement(item_text, "ItemTextFields", mode="SAVE") item_text_fields = SubElement(item_text, "ItemTextFields", mode="SAVE")
SubElement(item_text_fields, "Text").text = item_description SubElement(item_text_fields, "Text").text = item_description
return AbacusInvoiceCreator.create_xml_string(container) return create_xml_string(container)
@staticmethod
def render_customer_xml( def render_customer_xml(
abacus_debitor_number: int, abacus_debitor_number: int,
last_name: str, last_name: str,
first_name: str, first_name: str,
@ -121,7 +165,7 @@ class AbacusInvoiceCreator(InvoiceCreator):
country: str, country: str,
language: str, language: str,
email: str, email: str,
): ):
container = Element("AbaConnectContainer") container = Element("AbaConnectContainer")
task = SubElement(container, "Task") task = SubElement(container, "Task")
@ -152,10 +196,10 @@ class AbacusInvoiceCreator(InvoiceCreator):
SubElement(address_data, "Language").text = language SubElement(address_data, "Language").text = language
SubElement(address_data, "Email").text = email SubElement(address_data, "Email").text = email
return AbacusInvoiceCreator.create_xml_string(container) return 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_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

View File

@ -11,3 +11,5 @@ class CheckoutInformationFactory(DjangoModelFactory):
product_sku = VV_DE_PRODUCT_SKU product_sku = VV_DE_PRODUCT_SKU
product_price = 324_30 product_price = 324_30
state = CheckoutState.PAID state = CheckoutState.PAID
product_name = "Versicherungsvermittler/-in VBV"
product_description = "Versicherungsvermittler/-in VBV DE"

View File

@ -1,34 +1,74 @@
from datetime import date from datetime import date, datetime
from unittest.mock import create_autospec from unittest.mock import create_autospec
from django.test import TestCase from django.test import TestCase
from vbv_lernwelt.core.admin import User from vbv_lernwelt.core.admin import User
from vbv_lernwelt.shop.invoice.abacus import AbacusInvoiceCreator from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.shop.invoice.creator import Item from vbv_lernwelt.shop.invoice.abacus import (
AbacusInvoiceCreator,
render_invoice_xml,
render_customer_xml,
create_invoice_xml,
create_customer_xml,
)
from vbv_lernwelt.shop.invoice.repositories import InvoiceRepository from vbv_lernwelt.shop.invoice.repositories import InvoiceRepository
from vbv_lernwelt.shop.models import CheckoutInformation from vbv_lernwelt.shop.models import CheckoutInformation
from vbv_lernwelt.shop.tests.factories import CheckoutInformationFactory
USER_USERNAME = "testuser" USER_USERNAME = "testuser"
USER_EMAIL = "test@example.com" USER_EMAIL = "test@example.com"
USER_PASSWORD = "testpassword" USER_PASSWORD = "testpassword"
class InvoiceTestCase(TestCase): class AbacusInvoiceTestCase(TestCase):
def setUp(self) -> None: def setUp(self):
self.user = User.objects.create_user( create_default_users()
username=USER_USERNAME,
email=USER_EMAIL, def test_create_invoice_xml(self):
password=USER_PASSWORD, # set abacus_number before
is_active=True, _pat = User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch")
_pat.abacus_debitor_number = 60000011
_pat.save()
_ignore_checkout_information = CheckoutInformationFactory(
user=_pat, abacus_order_id=6_000_000_123
)
feuz = User.objects.get(username="andreas.feuz@eiger-versicherungen.ch")
feuz_checkout_info = CheckoutInformationFactory(
user=feuz,
transaction_id="24021508331287484",
)
feuz_checkout_info.created_at = datetime(2024, 2, 15, 8, 33, 12, 0)
invoice_xml_filename, invoice_xml_content = create_invoice_xml(
feuz_checkout_info
)
self.assertEqual(
invoice_xml_filename, "myVBV_orde_60000012_20240215083312_6000000124.xml"
)
# print(invoice_xml_content)
assert "<CustomerNumber>60000012</CustomerNumber>" in invoice_xml_content
assert (
"<PurchaseOrderDate>2024-02-15</PurchaseOrderDate>" in invoice_xml_content
)
assert (
"<GroupingNumberAscii1>6000000124</GroupingNumberAscii1>"
in invoice_xml_content
)
assert (
"<ReferencePurchaseOrder>24021508331287484</ReferencePurchaseOrder>"
in invoice_xml_content
)
assert "<DeliveryDate>2024-02-15</DeliveryDate>" in invoice_xml_content
assert (
"<Text>Versicherungsvermittler/-in VBV - 2024-02-15 - Feuz Andreas</Text>"
in invoice_xml_content
) )
def test_render_invoice_xml(self): def test_render_invoice_xml(self):
# GIVEN invoice_xml = render_invoice_xml(
creator = AbacusInvoiceCreator(repository=create_autospec(InvoiceRepository))
# WHEN
invoice_xml = creator.render_invoice_xml(
abacus_debitor_number=60000012, abacus_debitor_number=60000012,
abacus_order_id=6000000001, abacus_order_id=6000000001,
order_date=date(2024, 2, 15), order_date=date(2024, 2, 15),
@ -75,17 +115,56 @@ class InvoiceTestCase(TestCase):
</AbaConnectContainer> </AbaConnectContainer>
""" """
# THEN
self.maxDiff = None self.maxDiff = None
self.assertXMLEqual(expected_xml, invoice_xml) self.assertXMLEqual(expected_xml, invoice_xml)
def test_render_customer_xml(self): def test_create_customer_xml_with_company_address(self):
# GIVEN _pat = User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch")
creator = AbacusInvoiceCreator( _pat.abacus_debitor_number = 60000011
repository=create_autospec(InvoiceRepository)) _pat.save()
_ignore_checkout_information = CheckoutInformationFactory(
user=_pat, abacus_order_id=6_000_000_123
)
# WHEN feuz = User.objects.get(username="andreas.feuz@eiger-versicherungen.ch")
customer_xml = creator.render_customer_xml( feuz_checkout_info = CheckoutInformationFactory(
user=feuz,
transaction_id="24021508331287484",
first_name="Andreas",
last_name="Feuz",
street="Eggersmatt",
street_number="32",
postal_code="1719",
city="Zumholz",
country="209",
company_name="VBV",
company_street="Laupenstrasse",
company_street_number="10",
company_postal_code="3000",
company_city="Bern",
company_country="209",
)
feuz_checkout_info.created_at = datetime(2024, 2, 15, 8, 33, 12, 0)
customer_xml_filename, customer_xml_content = create_customer_xml(
checkout_information=feuz_checkout_info
)
print(customer_xml_content)
print(customer_xml_filename)
self.assertEqual("myVBV_debi_60000012.xml", customer_xml_filename)
assert "<CustomerNumber>60000012</CustomerNumber>" in customer_xml_content
assert (
"<Email>andreas.feuz@eiger-versicherungen.ch</Email>"
in customer_xml_content
)
assert "<Text>VBV</Text>" in customer_xml_content
# FIXME refactor country
assert "<Country>209</Country>" in customer_xml_content
def test_render_customer_xml(self):
customer_xml = render_customer_xml(
abacus_debitor_number=60000012, abacus_debitor_number=60000012,
last_name="Gebhart-Krasniqi", last_name="Gebhart-Krasniqi",
first_name="Skender", first_name="Skender",
@ -96,11 +175,9 @@ class InvoiceTestCase(TestCase):
city="Bern", city="Bern",
country="CH", country="CH",
language="de", language="de",
email="skender.krasniqi@vbv-afa.ch" email="skender.krasniqi@vbv-afa.ch",
) )
print(customer_xml)
# example from Skender # example from Skender
expected_xml = """<?xml version="1.0" encoding="utf-8"?> expected_xml = """<?xml version="1.0" encoding="utf-8"?>
<AbaConnectContainer> <AbaConnectContainer>
@ -136,7 +213,6 @@ class InvoiceTestCase(TestCase):
</AbaConnectContainer> </AbaConnectContainer>
""" """
# THEN
self.maxDiff = None self.maxDiff = None
self.assertXMLEqual(expected_xml, customer_xml) self.assertXMLEqual(expected_xml, customer_xml)