diff --git a/aidants_connect/settings.py b/aidants_connect/settings.py index a94fbe151..284425aaa 100644 --- a/aidants_connect/settings.py +++ b/aidants_connect/settings.py @@ -493,6 +493,7 @@ def getenv_bool(key: str, default: Optional[bool] = None) -> bool: DATAPASS_KEY = os.getenv("DATAPASS_KEY", None) DATAPASS_FROM_EMAIL = os.getenv("DATAPASS_FROM_EMAIL", None) DATAPASS_TO_EMAIL = os.getenv("DATAPASS_TO_EMAIL", None) +DATAPASS_CODE_FOR_ID_GENERATOR = "datapassid" AC_HABILITATION_FORM_ENABLED = getenv_bool("AC_HABILITATION_FORM_ENABLED", False) AC_IMPORT_HABILITATION_REQUESTS = getenv_bool("AC_IMPORT_HABILITATION_REQUESTS", False) diff --git a/aidants_connect_web/migrations/0084_idgenerator.py b/aidants_connect_web/migrations/0084_idgenerator.py new file mode 100644 index 000000000..186419761 --- /dev/null +++ b/aidants_connect_web/migrations/0084_idgenerator.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.12 on 2022-03-28 21:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('aidants_connect_web', '0083_alter_organisation_data_pass_id'), + ] + + operations = [ + migrations.CreateModel( + name='IdGenerator', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=100, unique=True)), + ('last_id', models.PositiveIntegerField()), + ], + ), + ] diff --git a/aidants_connect_web/migrations/0085_auto_20220329_0005.py b/aidants_connect_web/migrations/0085_auto_20220329_0005.py new file mode 100644 index 000000000..28c935a0f --- /dev/null +++ b/aidants_connect_web/migrations/0085_auto_20220329_0005.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.12 on 2022-03-28 22:05 + +from django.conf import settings +from django.db import migrations + + +def populate_datapass_generator(apps, _): + IdGenerator = apps.get_model("aidants_connect_web", "IdGenerator") + IdGenerator.objects.get_or_create(code=settings.DATAPASS_CODE_FOR_ID_GENERATOR, + defaults={"last_id": 10000}) + + +class Migration(migrations.Migration): + + dependencies = [ + ('aidants_connect_web', '0084_idgenerator'), + ] + + operations = [ + migrations.RunPython(populate_datapass_generator), + ] diff --git a/aidants_connect_web/models.py b/aidants_connect_web/models.py index 4cce78b5f..6664cafa5 100644 --- a/aidants_connect_web/models.py +++ b/aidants_connect_web/models.py @@ -1440,6 +1440,11 @@ def createTOTPDevice(self, confirmed=False, tolerance=30): ) +class IdGenerator(models.Model): + code = models.CharField(max_length=100, unique=True) + last_id = models.PositiveIntegerField() + + # The Dataviz* models represent metadata that are used for data display in Metabase. # Do not remove even if they are not used directly in the code. class DatavizDepartment(models.Model): diff --git a/aidants_connect_web/tests/test_utilities.py b/aidants_connect_web/tests/test_utilities.py index d70f4c309..55ff301b1 100644 --- a/aidants_connect_web/tests/test_utilities.py +++ b/aidants_connect_web/tests/test_utilities.py @@ -1,6 +1,6 @@ -from django.test import TestCase, tag +from django.test import TestCase, TransactionTestCase, tag -from aidants_connect_web.utilities import generate_sha256_hash +from aidants_connect_web.utilities import generate_new_datapass_id, generate_sha256_hash @tag("utilities") @@ -18,3 +18,11 @@ def test_generate_sha256_hash(self): ) self.assertEqual(generate_sha256_hash("123salt".encode()), hash_123salt) self.assertEqual(len(generate_sha256_hash("123salt".encode())), 64) + + +@tag("utilities") +class GenerateDatapassIdTests(TransactionTestCase): + + def test_generate_new_datapass_id(self): + self.assertEqual(generate_new_datapass_id(), 10001) + self.assertEqual(generate_new_datapass_id(), 10002) diff --git a/aidants_connect_web/utilities.py b/aidants_connect_web/utilities.py index c957edace..4539114c7 100644 --- a/aidants_connect_web/utilities.py +++ b/aidants_connect_web/utilities.py @@ -6,6 +6,8 @@ from urllib.parse import quote, urlencode from django.conf import settings +from django.db import transaction +from django.db.models import F import qrcode @@ -13,6 +15,18 @@ from aidants_connect_web.models import Aidant, Usager +@transaction.atomic +def generate_new_datapass_id() -> int: + from .models import IdGenerator + id_datapass = IdGenerator.objects.select_for_update().get( + code=settings.DATAPASS_CODE_FOR_ID_GENERATOR) + + id_datapass.last_id = F('last_id') + 1 + id_datapass.save() + id_datapass.refresh_from_db() + return id_datapass.last_id + + def generate_sha256_hash(value: bytes): """ Generate a SHA-256 hash