Refactor abacus XML code
This commit is contained in:
parent
590b6a17bc
commit
8ce7f9935e
|
|
@ -1,5 +1,4 @@
|
|||
import datetime
|
||||
from typing import List
|
||||
from uuid import uuid4
|
||||
from xml.dom import minidom
|
||||
from xml.etree.ElementTree import Element, SubElement, tostring
|
||||
|
|
@ -44,120 +43,165 @@ class AbacusInvoiceCreator(InvoiceCreator):
|
|||
|
||||
self.repository.upload_invoice(invoice, filename)
|
||||
|
||||
def create_invoice_xml(self, checkout_information: CheckoutInformation):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def render_invoice_xml(
|
||||
abacus_debitor_number: int,
|
||||
abacus_order_id: int,
|
||||
datatrans_transaction_id: str,
|
||||
order_date: datetime.date,
|
||||
item_description: str,
|
||||
) -> 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"
|
||||
def create_invoice_xml(checkout_information: CheckoutInformation):
|
||||
# set fill abacus numbers
|
||||
checkout_information = checkout_information.set_increment_abacus_order_id()
|
||||
customer = checkout_information.user.set_increment_abacus_debitor_number()
|
||||
|
||||
transaction = SubElement(task, "Transaction")
|
||||
sales_order_header = SubElement(transaction, "SalesOrderHeader", mode="SAVE")
|
||||
sales_order_header_fields = SubElement(
|
||||
sales_order_header, "SalesOrderHeaderFields", mode="SAVE"
|
||||
)
|
||||
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}",
|
||||
)
|
||||
|
||||
# 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
|
||||
)
|
||||
# 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"
|
||||
|
||||
# Skender: ePayment: Ablaufnr. für ePayment Rechnung in Abacus
|
||||
SubElement(sales_order_header_fields, "ProcessFlowNumber").text = "30"
|
||||
return invoice_xml_filename, invoice_xml_content
|
||||
|
||||
# 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()
|
||||
def create_customer_xml(checkout_information: CheckoutInformation):
|
||||
customer = checkout_information.user.set_increment_abacus_debitor_number()
|
||||
|
||||
# Skender: ePayment: TRANSACTION-ID von Datatrans in Bestellreferenz
|
||||
SubElement(
|
||||
sales_order_header_fields, "ReferencePurchaseOrder"
|
||||
).text = datatrans_transaction_id
|
||||
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,
|
||||
)
|
||||
|
||||
# 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
|
||||
)
|
||||
customer_xml_filename = f"myVBV_debi_{customer.abacus_debitor_number}.xml"
|
||||
|
||||
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"
|
||||
return customer_xml_filename, customer_xml_content
|
||||
|
||||
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)
|
||||
def render_invoice_xml(
|
||||
abacus_debitor_number: int,
|
||||
abacus_order_id: int,
|
||||
datatrans_transaction_id: str,
|
||||
order_date: datetime.date,
|
||||
item_description: str,
|
||||
) -> 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"
|
||||
|
||||
@staticmethod
|
||||
def render_customer_xml(
|
||||
abacus_debitor_number: int,
|
||||
last_name: str,
|
||||
first_name: str,
|
||||
company_name: str,
|
||||
street: str,
|
||||
house_number: str,
|
||||
zip_code: str,
|
||||
city: str,
|
||||
country: str,
|
||||
language: str,
|
||||
email: str,
|
||||
):
|
||||
container = Element("AbaConnectContainer")
|
||||
task = SubElement(container, "Task")
|
||||
transaction = SubElement(task, "Transaction")
|
||||
sales_order_header = SubElement(transaction, "SalesOrderHeader", mode="SAVE")
|
||||
sales_order_header_fields = SubElement(
|
||||
sales_order_header, "SalesOrderHeaderFields", mode="SAVE"
|
||||
)
|
||||
|
||||
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"
|
||||
# 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
|
||||
)
|
||||
|
||||
transaction = SubElement(task, "Transaction")
|
||||
customer_element = SubElement(transaction, "Customer", mode="SAVE")
|
||||
# Skender: ePayment: Ablaufnr. für ePayment Rechnung in Abacus
|
||||
SubElement(sales_order_header_fields, "ProcessFlowNumber").text = "30"
|
||||
|
||||
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"
|
||||
# Skender: ePayment: Zahlungskondition für ePaymente in Abacus 9999 Tage Mahnungsfrist, da schon bezahlt
|
||||
SubElement(sales_order_header_fields, "PaymentCode").text = "9999"
|
||||
|
||||
address_data = SubElement(customer_element, "AddressData", mode="SAVE")
|
||||
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 = company_name
|
||||
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
|
||||
# Skender: Bestellzeitpunkt
|
||||
SubElement(
|
||||
sales_order_header_fields, "PurchaseOrderDate"
|
||||
).text = order_date.isoformat()
|
||||
|
||||
return AbacusInvoiceCreator.create_xml_string(container)
|
||||
# Skender: ePayment: TRANSACTION-ID von Datatrans in Bestellreferenz
|
||||
SubElement(
|
||||
sales_order_header_fields, "ReferencePurchaseOrder"
|
||||
).text = datatrans_transaction_id
|
||||
|
||||
@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)
|
||||
# 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_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 create_xml_string(container)
|
||||
|
||||
|
||||
def render_customer_xml(
|
||||
abacus_debitor_number: int,
|
||||
last_name: str,
|
||||
first_name: str,
|
||||
company_name: 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 = 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 = str(abacus_debitor_number)
|
||||
SubElement(address_data, "Name").text = last_name
|
||||
SubElement(address_data, "FirstName").text = first_name
|
||||
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
|
||||
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 create_xml_string(container)
|
||||
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -11,3 +11,5 @@ class CheckoutInformationFactory(DjangoModelFactory):
|
|||
product_sku = VV_DE_PRODUCT_SKU
|
||||
product_price = 324_30
|
||||
state = CheckoutState.PAID
|
||||
product_name = "Versicherungsvermittler/-in VBV"
|
||||
product_description = "Versicherungsvermittler/-in VBV DE"
|
||||
|
|
|
|||
|
|
@ -1,34 +1,74 @@
|
|||
from datetime import date
|
||||
from datetime import date, datetime
|
||||
from unittest.mock import create_autospec
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from vbv_lernwelt.core.admin import User
|
||||
from vbv_lernwelt.shop.invoice.abacus import AbacusInvoiceCreator
|
||||
from vbv_lernwelt.shop.invoice.creator import Item
|
||||
from vbv_lernwelt.core.create_default_users import create_default_users
|
||||
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.models import CheckoutInformation
|
||||
from vbv_lernwelt.shop.tests.factories import CheckoutInformationFactory
|
||||
|
||||
USER_USERNAME = "testuser"
|
||||
USER_EMAIL = "test@example.com"
|
||||
USER_PASSWORD = "testpassword"
|
||||
|
||||
|
||||
class InvoiceTestCase(TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_user(
|
||||
username=USER_USERNAME,
|
||||
email=USER_EMAIL,
|
||||
password=USER_PASSWORD,
|
||||
is_active=True,
|
||||
class AbacusInvoiceTestCase(TestCase):
|
||||
def setUp(self):
|
||||
create_default_users()
|
||||
|
||||
def test_create_invoice_xml(self):
|
||||
# set abacus_number before
|
||||
_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):
|
||||
# GIVEN
|
||||
creator = AbacusInvoiceCreator(repository=create_autospec(InvoiceRepository))
|
||||
|
||||
# WHEN
|
||||
invoice_xml = creator.render_invoice_xml(
|
||||
invoice_xml = render_invoice_xml(
|
||||
abacus_debitor_number=60000012,
|
||||
abacus_order_id=6000000001,
|
||||
order_date=date(2024, 2, 15),
|
||||
|
|
@ -75,17 +115,56 @@ class InvoiceTestCase(TestCase):
|
|||
</AbaConnectContainer>
|
||||
"""
|
||||
|
||||
# THEN
|
||||
self.maxDiff = None
|
||||
self.assertXMLEqual(expected_xml, invoice_xml)
|
||||
|
||||
def test_render_customer_xml(self):
|
||||
# GIVEN
|
||||
creator = AbacusInvoiceCreator(
|
||||
repository=create_autospec(InvoiceRepository))
|
||||
def test_create_customer_xml_with_company_address(self):
|
||||
_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
|
||||
)
|
||||
|
||||
# WHEN
|
||||
customer_xml = creator.render_customer_xml(
|
||||
feuz = User.objects.get(username="andreas.feuz@eiger-versicherungen.ch")
|
||||
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,
|
||||
last_name="Gebhart-Krasniqi",
|
||||
first_name="Skender",
|
||||
|
|
@ -96,11 +175,9 @@ class InvoiceTestCase(TestCase):
|
|||
city="Bern",
|
||||
country="CH",
|
||||
language="de",
|
||||
email="skender.krasniqi@vbv-afa.ch"
|
||||
email="skender.krasniqi@vbv-afa.ch",
|
||||
)
|
||||
|
||||
print(customer_xml)
|
||||
|
||||
# example from Skender
|
||||
expected_xml = """<?xml version="1.0" encoding="utf-8"?>
|
||||
<AbaConnectContainer>
|
||||
|
|
@ -136,7 +213,6 @@ class InvoiceTestCase(TestCase):
|
|||
</AbaConnectContainer>
|
||||
"""
|
||||
|
||||
# THEN
|
||||
self.maxDiff = None
|
||||
self.assertXMLEqual(expected_xml, customer_xml)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue