diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 357a299..fa12a1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,6 +103,21 @@ jobs: npm ci npm install -g mjml + - name: Purge postgres + run: | + sudo apt-get --purge remove postgresql postgresql-* + + - name: Upgrade packages + run: | + sudo apt-get update && sudo apt-get upgrade + - name: Install Postgresql/PostGIS 12 + run: | + sudo apt-get install postgresql-12 postgresql-12-postgis-3 + - name: Setup and start postgres service + run: | + sudo pg_ctlcluster 12 main start + sudo -u ${POSTGRES_USER} psql -p ${POSTGRES_PORT} -c "ALTER USER ${POSTGRES_USER} WITH PASSWORD '${POSTGRES_PASSWORD}';" + - name: Set up Django run: | python manage.py migrate diff --git a/mycarehub/clients/models.py b/mycarehub/clients/models.py index 86a5f36..1dcc5bb 100644 --- a/mycarehub/clients/models.py +++ b/mycarehub/clients/models.py @@ -1,5 +1,6 @@ from django.contrib.auth import get_user_model from django.contrib.postgres.fields import ArrayField +from django.core.exceptions import ValidationError from django.db import models from django.db.models.enums import TextChoices from django.utils import timezone @@ -98,6 +99,8 @@ class IdentifierUse(models.TextChoices): valid_to = models.DateTimeField(null=True, blank=True) is_primary_identifier = models.BooleanField(default=False) + model_validators = ["validate_if_identifier_value_exists"] + def __str__(self): return f"{self.identifier_value} ({self.identifier_type}, {self.identifier_use})" @@ -107,6 +110,22 @@ class Meta(AbstractBase.Meta): "identifier_value", ) + def validate_if_identifier_value_exists(self): + if Identifier.objects.filter( + identifier_value=self.identifier_value, + identifier_type=self.identifier_type, + ).exists(): + raise ValidationError( + _( + "Identifier value %(identifier_value)s of " + "type %(identifier_type)s already exists" + ), + params={ + "identifier_value": self.identifier_value, + "identifier_type": self.identifier_type, + }, + ) + @register_snippet class SecurityQuestion(AbstractBase): diff --git a/mycarehub/clients/tests/test_models.py b/mycarehub/clients/tests/test_models.py index 5de925f..1e961b0 100644 --- a/mycarehub/clients/tests/test_models.py +++ b/mycarehub/clients/tests/test_models.py @@ -25,6 +25,27 @@ def test_identifier_str(): assert str(identifier) == "222 (NATIONAL_ID, OFFICIAL)" +def test_validate_if_identifier_value_exists(): + identifier_value = "111" + identifier_type = "NATIONAL_ID" + identifier_use = "OFFICIAL" + baker.make( + Identifier, + identifier_value=identifier_value, + identifier_type=identifier_type, + identifier_use=identifier_use, + ) + + duplicate_identifier = baker.prepare( + Identifier, + identifier_value=identifier_value, + identifier_type=identifier_type, + identifier_use=identifier_use, + ) + with pytest.raises(Exception): + duplicate_identifier.save() + + def test_related_person_str(): related_person = baker.make( RelatedPerson, diff --git a/mycarehub/clients/views.py b/mycarehub/clients/views.py index ddb4b4c..da108f8 100644 --- a/mycarehub/clients/views.py +++ b/mycarehub/clients/views.py @@ -113,18 +113,17 @@ def post(self, request, format=None): ) # create an identifier (CCC) - identifier, _ = Identifier.objects.get_or_create( - identifier_value=data["ccc_number"], - identifier_type="CCC", - defaults={ - "identifier_use": "OFFICIAL", - "description": "CCC Number, Primary Identifier", - "is_primary_identifier": True, - "organisation": org, - "created_by": request_user.pk, - "updated_by": request_user.pk, - }, - ) + identifier_data = { + "identifier_type": "CCC", + "identifier_value": data["ccc_number"], + "identifier_use": "OFFICIAL", + "description": "CCC Number, Primary Identifier", + "is_primary_identifier": True, + "organisation": org, + "created_by": request_user.pk, + "updated_by": request_user.pk, + } + identifier = Identifier.objects.create(**identifier_data) # retrieve the facility by the unique name facility_name = data["facility"]