diff --git a/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py b/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py new file mode 100644 index 00000000..c944304a --- /dev/null +++ b/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.20 on 2024-05-29 13:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0007_auto_20240220_1058'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='abacus_debitor_number', + field=models.BigIntegerField(blank=True, null=True, unique=True), + ), + ] diff --git a/server/vbv_lernwelt/core/models.py b/server/vbv_lernwelt/core/models.py index 75e18afb..f75b5d5c 100644 --- a/server/vbv_lernwelt/core/models.py +++ b/server/vbv_lernwelt/core/models.py @@ -3,7 +3,7 @@ import uuid import structlog from django.contrib.auth.models import AbstractUser from django.db import models -from django.db.models import JSONField +from django.db.models import JSONField, Max from django.urls import reverse logger = structlog.get_logger(__name__) @@ -110,6 +110,24 @@ class User(AbstractUser): blank=True, ) + # is only set by abacus invoice export code + abacus_debitor_number = models.BigIntegerField(unique=True, null=True, blank=True) + + def set_increment_abacus_debitor_number(self): + if self.abacus_debitor_number: + return self + + # Get the current maximum debitor_number and increment it by 1 + current_max = User.objects.aggregate(max_number=Max("abacus_debitor_number"))[ + "max_number" + ] + new_debitor_number = ( + current_max if current_max is not None else 60_000_000 + ) + 1 + self.abacus_debitor_number = new_debitor_number + self.save() + return self + def create_avatar_url(self, size=400): try: if self.avatar: diff --git a/server/vbv_lernwelt/core/tests/test_abacus_debitor_number.py b/server/vbv_lernwelt/core/tests/test_abacus_debitor_number.py new file mode 100644 index 00000000..c58f9f78 --- /dev/null +++ b/server/vbv_lernwelt/core/tests/test_abacus_debitor_number.py @@ -0,0 +1,30 @@ +from django.test import TestCase + +from vbv_lernwelt.core.create_default_users import create_default_users +from vbv_lernwelt.core.models import User + + +class UserAbacusDebitorNumberTestCase(TestCase): + def setUp(self): + create_default_users() + + def test_set_debitor_number(self): + pat = User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch") + + self.assertIsNone(pat.abacus_debitor_number) + + pat.set_increment_abacus_debitor_number() + self.assertEqual(pat.abacus_debitor_number, 60000001) + pat = pat.set_increment_abacus_debitor_number() + self.assertEqual(pat.abacus_debitor_number, 60000001) + + pat = User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch") + self.assertEqual(pat.abacus_debitor_number, 60000001) + + feuz = User.objects.get(username="andreas.feuz@eiger-versicherungen.ch") + self.assertIsNone(feuz.abacus_debitor_number) + feuz = feuz.set_increment_abacus_debitor_number() + self.assertEqual(feuz.abacus_debitor_number, 60000002) + + feuz = User.objects.get(username="andreas.feuz@eiger-versicherungen.ch") + self.assertEqual(feuz.abacus_debitor_number, 60000002) diff --git a/server/vbv_lernwelt/shop/invoice/abacus.py b/server/vbv_lernwelt/shop/invoice/abacus.py index 946d5750..697f5b15 100644 --- a/server/vbv_lernwelt/shop/invoice/abacus.py +++ b/server/vbv_lernwelt/shop/invoice/abacus.py @@ -44,6 +44,9 @@ 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, diff --git a/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py b/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py new file mode 100644 index 00000000..b133a813 --- /dev/null +++ b/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.20 on 2024-05-29 13:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('shop', '0012_delete_country'), + ] + + operations = [ + migrations.AddField( + model_name='checkoutinformation', + name='abacus_order_id', + field=models.BigIntegerField(blank=True, null=True, unique=True), + ), + ] diff --git a/server/vbv_lernwelt/shop/models.py b/server/vbv_lernwelt/shop/models.py index 0c3e75f5..25a61cbe 100644 --- a/server/vbv_lernwelt/shop/models.py +++ b/server/vbv_lernwelt/shop/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.db.models import Max class BillingAddress(models.Model): @@ -100,3 +101,21 @@ class CheckoutInformation(models.Model): # webhook metadata webhook_history = models.JSONField(default=list) + + # is only set by abacus invoice export code + abacus_order_id = models.BigIntegerField(unique=True, null=True, blank=True) + + def set_increment_abacus_order_id(self): + if self.abacus_order_id: + return self + + # Get the current maximum abacus_order_id and increment it by 1 + current_max = CheckoutInformation.objects.aggregate( + max_number=Max("abacus_order_id") + )["max_number"] + new_abacus_order_id = ( + current_max if current_max is not None else 6_000_000_000 + ) + 1 + self.abacus_order_id = new_abacus_order_id + self.save() + return self diff --git a/server/vbv_lernwelt/shop/tests/factories.py b/server/vbv_lernwelt/shop/tests/factories.py new file mode 100644 index 00000000..f8396de9 --- /dev/null +++ b/server/vbv_lernwelt/shop/tests/factories.py @@ -0,0 +1,13 @@ +from factory.django import DjangoModelFactory + +from vbv_lernwelt.shop.const import VV_DE_PRODUCT_SKU +from vbv_lernwelt.shop.models import CheckoutInformation, CheckoutState + + +class CheckoutInformationFactory(DjangoModelFactory): + class Meta: + model = CheckoutInformation + + product_sku = VV_DE_PRODUCT_SKU + product_price = 324_30 + state = CheckoutState.PAID diff --git a/server/vbv_lernwelt/shop/tests/test_abacus_order_id.py b/server/vbv_lernwelt/shop/tests/test_abacus_order_id.py new file mode 100644 index 00000000..0dd49eb0 --- /dev/null +++ b/server/vbv_lernwelt/shop/tests/test_abacus_order_id.py @@ -0,0 +1,31 @@ +from django.test import TestCase + +from vbv_lernwelt.core.create_default_users import create_default_users +from vbv_lernwelt.core.models import User +from vbv_lernwelt.shop.models import CheckoutInformation +from vbv_lernwelt.shop.tests.factories import CheckoutInformationFactory + + +class AbacusOrderIdTestCase(TestCase): + def setUp(self): + create_default_users() + self.pat = User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch") + self.feuz = User.objects.get(username="andreas.feuz@eiger-versicherungen.ch") + + def test_set_increment_abacus_order_id(self): + checkout_info = CheckoutInformationFactory(user=self.pat) + + self.assertIsNone(checkout_info.abacus_order_id) + checkout_info.set_increment_abacus_order_id() + + self.assertEqual(checkout_info.abacus_order_id, 6_000_000_001) + checkout_info = CheckoutInformation.objects.get(id=checkout_info.id) + self.assertEqual(checkout_info.abacus_order_id, 6_000_000_001) + checkout_info = checkout_info.set_increment_abacus_order_id() + self.assertEqual(checkout_info.abacus_order_id, 6_000_000_001) + + checkout_info2 = CheckoutInformationFactory(user=self.feuz) + checkout_info2 = checkout_info2.set_increment_abacus_order_id() + self.assertEqual(checkout_info2.abacus_order_id, 6_000_000_002) + checkout_info2 = CheckoutInformation.objects.get(id=checkout_info2.id) + self.assertEqual(checkout_info2.abacus_order_id, 6_000_000_002)