From 5661931412a296e78c03000664ac4b4d64e3c849 Mon Sep 17 00:00:00 2001
From: David Paul Graham <43794491+dpgraham4401@users.noreply.github.com>
Date: Mon, 13 Mar 2023 18:32:01 -0400
Subject: [PATCH] 372 manager class refactor (#400)
* replace create_x Manager methods with 'save(**kwargs)' interface method
add e_signature_factory fixture
* move Serializer create method logic to ModelManagers
* misc fixes, fixture datetime naive warnings, rename module for consistency
---
.idea/scopes/server.xml | 4 +-
server/apps/trak/models/__init__.py | 2 +-
server/apps/trak/models/address_model.py | 146 +++++++++---------
server/apps/trak/models/base_model.py | 14 ++
server/apps/trak/models/contact_model.py | 12 +-
server/apps/trak/models/handler_model.py | 36 ++---
server/apps/trak/models/manifest_model.py | 39 +++--
server/apps/trak/models/signature_model.py | 24 +--
server/apps/trak/models/transporter_model.py | 15 +-
server/apps/trak/models/waste_model.py | 13 ++
server/apps/trak/serializers/address_ser.py | 9 +-
.../serializers/{trak_ser.py => base_ser.py} | 0
server/apps/trak/serializers/contact_ser.py | 3 +-
server/apps/trak/serializers/handler_ser.py | 21 +--
server/apps/trak/serializers/manifest_ser.py | 21 +--
.../apps/trak/serializers/rcra_profile_ser.py | 3 +-
server/apps/trak/serializers/signature_ser.py | 19 +--
server/apps/trak/serializers/sites_ser.py | 3 +-
.../apps/trak/serializers/transporter_ser.py | 3 +-
.../apps/trak/serializers/waste_line_ser.py | 3 +-
server/apps/trak/services/handler_service.py | 2 +-
server/apps/trak/tests/conftest.py | 55 +++++--
server/apps/trak/tests/models/test_handler.py | 2 +-
.../serializers/test_handler_serializer.py | 3 -
24 files changed, 249 insertions(+), 203 deletions(-)
create mode 100644 server/apps/trak/models/base_model.py
rename server/apps/trak/serializers/{trak_ser.py => base_ser.py} (100%)
diff --git a/.idea/scopes/server.xml b/.idea/scopes/server.xml
index e72ff9237..4d8f26535 100644
--- a/.idea/scopes/server.xml
+++ b/.idea/scopes/server.xml
@@ -1,3 +1,3 @@
-
-
+
+
\ No newline at end of file
diff --git a/server/apps/trak/models/__init__.py b/server/apps/trak/models/__init__.py
index d3cdb9833..014ec125b 100644
--- a/server/apps/trak/models/__init__.py
+++ b/server/apps/trak/models/__init__.py
@@ -1,7 +1,7 @@
"""
Model definitions for the trak domain
"""
-from .address_model import Address, EpaCountries, EpaStates
+from .address_model import Address
from .contact_model import Contact, EpaPhone
from .handler_model import Handler, ManifestHandler
from .manifest_model import Manifest
diff --git a/server/apps/trak/models/address_model.py b/server/apps/trak/models/address_model.py
index 24e57eec4..da1f05cfa 100644
--- a/server/apps/trak/models/address_model.py
+++ b/server/apps/trak/models/address_model.py
@@ -2,85 +2,83 @@
from django.utils.translation import gettext_lazy as _
-class EpaCountries(models.TextChoices):
- US = "US", _("United States")
- MX = "MX", _("Mexico")
- CA = "CA", _("Canada")
-
-
-class EpaStates(models.TextChoices):
- AK = "AK", _("Alaska")
- AL = "AL", _("Alabama")
- AP = "AP", _("Armed Forces Pacific")
- AR = "AR", _("Arkansas")
- AZ = "AZ", _("Arizona")
- CA = "CA", _("California")
- CO = "CO", _("Colorado")
- CT = "CT", _("Connecticut")
- DC = "DC", _("Washington DC")
- DE = "DE", _("Delaware")
- FL = "FL", _("Florida")
- GA = "GA", _("Georgia")
- GU = "GU", _("Guam")
- HI = "HI", _("Hawaii")
- IA = "IA", _("Iowa")
- ID = "ID", _("Idaho")
- IL = "IL", _("Illinois")
- IN = "IN", _("Indiana")
- KS = "KS", _("Kansas")
- KY = "KY", _("Kentucky")
- LA = "LA", _("Louisiana")
- MA = "MA", _("Massachusetts")
- MD = "MD", _("Maryland")
- ME = "ME", _("Maine")
- MI = "MI", _("Michigan")
- MN = "MN", _("Minnesota")
- MO = "MO", _("Missouri")
- MS = "MS", _("Mississippi")
- MT = "MT", _("Montana")
- NC = "NC", _("North Carolina")
- ND = "ND", _("North Dakota")
- NE = "NE", _("Nebraska")
- NH = "NH", _("New Hampshire")
- NJ = "NJ", _("New Jersey")
- NM = "NM", _("New Mexico")
- NV = "NV", _("Nevada")
- NY = "NY", _("New York")
- OH = "OH", _("Ohio")
- OK = "OK", _("Oklahoma")
- OR = "OR", _("Oregon")
- PA = "PA", _("Pennsylvania")
- PR = "PR", _("Puerto Rico")
- RI = "RI", _("Rhode Island")
- SC = "SC", _("South Carolina")
- SD = "SD", _("South Dakota")
- TN = "TN", _("Tennessee")
- TX = "TX", _("Texas")
- UT = "UT", _("Utah")
- VA = "VA", _("Virginia")
- VI = "VI", _("Virgin Islands")
- VT = "VT", _("Vermont")
- WA = "WA", _("Washington")
- WI = "WI", _("Wisconsin")
- WV = "WV", _("West Virginia")
- WY = "WY", _("Wyoming")
- XA = "XA", _("REGION 01 PURVIEW")
- XB = "XB", _("REGION 02 PURVIEW")
- XC = "XC", _("REGION 03 PURVIEW")
- XD = "XD", _("REGION 04 PURVIEW")
- XE = "XE", _("REGION 05 PURVIEW")
- XF = "XF", _("REGION 06 PURVIEW")
- XG = "XG", _("REGION 07 PURVIEW")
- XH = "XH", _("REGION 08 PURVIEW")
- XI = "XI", _("REGION 09 PURVIEW")
- XJ = "XJ", _("REGION 10 PURVIEW")
-
-
class Address(models.Model):
"""
Used to capture RCRAInfo address instances (mail, site).
"""
+ class EpaCountries(models.TextChoices):
+ US = "US", _("United States")
+ MX = "MX", _("Mexico")
+ CA = "CA", _("Canada")
+
+ class EpaStates(models.TextChoices):
+ AK = "AK", _("Alaska")
+ AL = "AL", _("Alabama")
+ AP = "AP", _("Armed Forces Pacific")
+ AR = "AR", _("Arkansas")
+ AZ = "AZ", _("Arizona")
+ CA = "CA", _("California")
+ CO = "CO", _("Colorado")
+ CT = "CT", _("Connecticut")
+ DC = "DC", _("Washington DC")
+ DE = "DE", _("Delaware")
+ FL = "FL", _("Florida")
+ GA = "GA", _("Georgia")
+ GU = "GU", _("Guam")
+ HI = "HI", _("Hawaii")
+ IA = "IA", _("Iowa")
+ ID = "ID", _("Idaho")
+ IL = "IL", _("Illinois")
+ IN = "IN", _("Indiana")
+ KS = "KS", _("Kansas")
+ KY = "KY", _("Kentucky")
+ LA = "LA", _("Louisiana")
+ MA = "MA", _("Massachusetts")
+ MD = "MD", _("Maryland")
+ ME = "ME", _("Maine")
+ MI = "MI", _("Michigan")
+ MN = "MN", _("Minnesota")
+ MO = "MO", _("Missouri")
+ MS = "MS", _("Mississippi")
+ MT = "MT", _("Montana")
+ NC = "NC", _("North Carolina")
+ ND = "ND", _("North Dakota")
+ NE = "NE", _("Nebraska")
+ NH = "NH", _("New Hampshire")
+ NJ = "NJ", _("New Jersey")
+ NM = "NM", _("New Mexico")
+ NV = "NV", _("Nevada")
+ NY = "NY", _("New York")
+ OH = "OH", _("Ohio")
+ OK = "OK", _("Oklahoma")
+ OR = "OR", _("Oregon")
+ PA = "PA", _("Pennsylvania")
+ PR = "PR", _("Puerto Rico")
+ RI = "RI", _("Rhode Island")
+ SC = "SC", _("South Carolina")
+ SD = "SD", _("South Dakota")
+ TN = "TN", _("Tennessee")
+ TX = "TX", _("Texas")
+ UT = "UT", _("Utah")
+ VA = "VA", _("Virginia")
+ VI = "VI", _("Virgin Islands")
+ VT = "VT", _("Vermont")
+ WA = "WA", _("Washington")
+ WI = "WI", _("Wisconsin")
+ WV = "WV", _("West Virginia")
+ WY = "WY", _("Wyoming")
+ XA = "XA", _("REGION 01 PURVIEW")
+ XB = "XB", _("REGION 02 PURVIEW")
+ XC = "XC", _("REGION 03 PURVIEW")
+ XD = "XD", _("REGION 04 PURVIEW")
+ XE = "XE", _("REGION 05 PURVIEW")
+ XF = "XF", _("REGION 06 PURVIEW")
+ XG = "XG", _("REGION 07 PURVIEW")
+ XH = "XH", _("REGION 08 PURVIEW")
+ XI = "XI", _("REGION 09 PURVIEW")
+ XJ = "XJ", _("REGION 10 PURVIEW")
+
street_number = models.CharField(
max_length=12,
null=True,
diff --git a/server/apps/trak/models/base_model.py b/server/apps/trak/models/base_model.py
new file mode 100644
index 000000000..b63e126f5
--- /dev/null
+++ b/server/apps/trak/models/base_model.py
@@ -0,0 +1,14 @@
+from abc import ABCMeta, abstractmethod
+
+from django.db import models
+
+
+class TrakManager(models.Manager, metaclass=ABCMeta):
+ """
+ Abstract class that defines an interface for our model managers
+ """
+
+ @abstractmethod
+ def save(self, **kwargs) -> models.QuerySet:
+ """Save instance and its related models to the database"""
+ return self.create(**kwargs)
diff --git a/server/apps/trak/models/contact_model.py b/server/apps/trak/models/contact_model.py
index 617b8fe1b..9c80bc868 100644
--- a/server/apps/trak/models/contact_model.py
+++ b/server/apps/trak/models/contact_model.py
@@ -4,6 +4,8 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
+from apps.trak.models.base_model import TrakManager
+
class EpaPhoneNumber(models.CharField):
"""
@@ -39,26 +41,24 @@ def __str__(self):
return f"{self.number}"
-class ContactManager(models.Manager):
+class ContactManager(TrakManager):
"""
Inter-model related functionality for Contact Model
"""
- def create(self, contact=None, **contact_data):
+ def save(self, **contact_data) -> models.QuerySet:
"""
Create Contact instance in database, create related phone instance if applicable,
and return the new instance.
"""
- if isinstance(contact, Contact):
- return contact
if "phone" in contact_data:
phone_data = contact_data.pop("phone")
if isinstance(phone_data, EpaPhone):
phone = phone_data
else:
phone = EpaPhone.objects.create(**phone_data)
- return super().create(**contact_data, phone=phone)
- return super().create(**contact_data)
+ return self.create(**contact_data, phone=phone)
+ return super().save(**contact_data)
class Contact(models.Model):
diff --git a/server/apps/trak/models/handler_model.py b/server/apps/trak/models/handler_model.py
index 40cd48438..68b1824ac 100644
--- a/server/apps/trak/models/handler_model.py
+++ b/server/apps/trak/models/handler_model.py
@@ -5,13 +5,14 @@
from django.db import models
from .address_model import Address
+from .base_model import TrakManager
from .contact_model import Contact, EpaPhone
from .signature_model import ESignature, PaperSignature
logger = logging.getLogger(__name__)
-class HandlerManager(models.Manager):
+class HandlerManager(TrakManager):
"""
Inter-model related functionality for Handler Model
"""
@@ -20,7 +21,7 @@ def __init__(self):
self.handler_data = None
super().__init__()
- def create_handler(self, **handler_data):
+ def save(self, **handler_data):
"""
Create a handler and its related fields
@@ -32,14 +33,14 @@ def create_handler(self, **handler_data):
"""
try:
epa_id = handler_data.get("epa_id")
- if Handler.objects.filter(epa_id=epa_id).exists():
+ if self.model.objects.filter(epa_id=epa_id).exists():
return Handler.objects.get(epa_id=epa_id)
self.handler_data = handler_data
- new_contact = Contact.objects.create(self.handler_data.pop("contact"))
+ new_contact = Contact.objects.save(**self.handler_data.pop("contact"))
emergency_phone = self.get_emergency_phone()
site_address = self.get_address("site_address")
mail_address = self.get_address("mail_address")
- return super().create(
+ return super().save(
site_address=site_address,
mail_address=mail_address,
emergency_phone=emergency_phone,
@@ -166,23 +167,12 @@ def __repr__(self):
return f"<{self.__class__.__name__}({field_values})>"
-class ManifestHandlerManager(models.Manager):
+class ManifestHandlerManager(TrakManager):
"""
Inter-model related functionality for ManifestHandler Model
"""
- def __init__(self):
- self.manifest_handler_data = None
- super().__init__()
-
- @staticmethod
- def create_manifest_handler(**handler_data):
- """
- Create a Manifest handler and its related fields
-
- Keyword Args:
- handler (dict): handler data in (ordered)dict format
- """
+ def save(self, **handler_data) -> models.QuerySet:
e_signatures = []
paper_signature = None
if "e_signatures" in handler_data:
@@ -195,14 +185,14 @@ def create_manifest_handler(**handler_data):
handler = Handler.objects.get(epa_id=handler_data["handler"]["epa_id"])
logger.debug(f"using existing Handler {handler}")
else:
- handler = Handler.objects.create_handler(**handler_data["handler"])
+ handler = Handler.objects.save(**handler_data["handler"])
logger.debug(f"Handler created {handler}")
manifest_handler = ManifestHandler.objects.create(
handler=handler, paper_signature=paper_signature
)
logger.debug(f"ManifestHandler created {manifest_handler}")
for e_signature_data in e_signatures:
- e_sig = ESignature.objects.create_e_signature(
+ e_sig = ESignature.objects.save(
manifest_handler=manifest_handler, **e_signature_data
)
logger.debug(f"ESignature created {e_sig}")
@@ -237,3 +227,9 @@ class ManifestHandler(models.Model):
def __str__(self):
return f"ManifestHandler: {self.handler.epa_id}"
+
+ def __repr__(self):
+ field_values = ", ".join(
+ f"{field.name}={getattr(self, field.name)!r}" for field in self._meta.fields
+ )
+ return f"<{self.__class__.__name__}({field_values})>"
diff --git a/server/apps/trak/models/manifest_model.py b/server/apps/trak/models/manifest_model.py
index 4864f6fe2..f378418ba 100644
--- a/server/apps/trak/models/manifest_model.py
+++ b/server/apps/trak/models/manifest_model.py
@@ -1,5 +1,6 @@
import logging
import re
+from typing import Dict
from django.core.exceptions import ValidationError
from django.db import models
@@ -7,6 +8,10 @@
from django.utils.translation import gettext_lazy as _
from apps.trak.models import ManifestHandler
+from apps.trak.models.base_model import TrakManager
+
+from .transporter_model import Transporter
+from .waste_model import WasteLine
logger = logging.getLogger(__name__)
@@ -32,29 +37,43 @@ def validate_mtn(value):
)
-class ManifestManager(models.Manager):
+class ManifestManager(TrakManager):
"""
Inter-model related functionality for Manifest Model
"""
- @staticmethod
- def create_manifest(manifest_data):
+ def save(self, **manifest_data: Dict):
"""Create a manifest with its related models instances"""
+ waste_data = []
+ trans_data = []
additional_info = None
+ manifest_generator = None
+ manifest_tsd = None
+ if "wastes" in manifest_data:
+ waste_data = manifest_data.pop("wastes")
+ if "transporters" in manifest_data:
+ trans_data = manifest_data.pop("transporters")
# Create manifest handlers (generator and TSD) and all related models
- tsd_data = manifest_data.pop("tsd")
- gen_data = manifest_data.pop("generator")
- manifest_generator = ManifestHandler.objects.create_manifest_handler(**gen_data)
- manifest_tsd = ManifestHandler.objects.create_manifest_handler(**tsd_data)
+ if "generator" in manifest_data:
+ manifest_generator = ManifestHandler.objects.save(**manifest_data.pop("generator"))
+ if "tsd" in manifest_data:
+ manifest_tsd = ManifestHandler.objects.save(**manifest_data.pop("tsd"))
if "additional_info" in manifest_data:
additional_info = AdditionalInfo.objects.create(**manifest_data.pop("additional_info"))
# Create model instances
- return Manifest.objects.create(
+ manifest = super().save(
generator=manifest_generator,
tsd=manifest_tsd,
additional_info=additional_info,
**manifest_data,
)
+ for waste_line in waste_data:
+ saved_waste_line = WasteLine.objects.save(manifest=manifest, **waste_line)
+ logger.debug(f"WasteLine saved {saved_waste_line.pk}")
+ for transporter in trans_data:
+ saved_transporter = Transporter.objects.save(manifest=manifest, **transporter)
+ logger.debug(f"WasteLine saved {saved_transporter.pk}")
+ return manifest
class Manifest(models.Model):
@@ -62,6 +81,8 @@ class Manifest(models.Model):
Model definition the e-Manifest Uniform Hazardous Waste Manifest
"""
+ objects = ManifestManager()
+
class LockReason(models.TextChoices):
ASYNC_SIGN = "ACS", _("AsyncSign")
CHANGE_BILLER = "ECB", _("EpaChangeBiller")
@@ -89,8 +110,6 @@ class Status(models.TextChoices):
UNDER_CORRECTION = "UnderCorrection", _("Under Correction")
VALIDATION_FAILED = "MtnValidationFailed", _("MTN Validation Failed")
- objects = ManifestManager()
-
created_date = models.DateTimeField(
null=True,
auto_now=True,
diff --git a/server/apps/trak/models/signature_model.py b/server/apps/trak/models/signature_model.py
index 64397bbe6..bba44585d 100644
--- a/server/apps/trak/models/signature_model.py
+++ b/server/apps/trak/models/signature_model.py
@@ -1,9 +1,10 @@
import logging
-from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _
+from apps.trak.models.base_model import TrakManager
+
logger = logging.getLogger(__name__)
@@ -76,24 +77,19 @@ def __str__(self):
)
-class ESignatureManager(models.Manager):
+class ESignatureManager(TrakManager):
"""
Inter-model related functionality for ESignature Model
"""
- def create_e_signature(self, **e_signature_data):
+ def save(self, **e_signature_data):
"""
Create Contact instance in database, create related phone instance if applicable,
and return the new instance.
"""
- try:
- if "signer" in e_signature_data:
- signer_data = e_signature_data.pop("signer")
- e_signature_data["signer"] = Signer.objects.create(**signer_data)
- return super().create(**e_signature_data)
- except ValidationError as exc:
- logger.error(exc)
- raise exc
+ if "signer" in e_signature_data:
+ e_signature_data["signer"] = Signer.objects.create(**e_signature_data.pop("signer"))
+ return super().save(**e_signature_data)
class ESignature(models.Model):
@@ -142,6 +138,12 @@ def __str__(self):
)
return f"e-signature on {self.sign_date}"
+ def __repr__(self):
+ field_values = ", ".join(
+ f"{field.name}={getattr(self, field.name)!r}" for field in self._meta.fields
+ )
+ return f"<{self.__class__.__name__}({field_values})>"
+
class Meta:
verbose_name = "e-Signature"
diff --git a/server/apps/trak/models/transporter_model.py b/server/apps/trak/models/transporter_model.py
index 3009308ab..3af746bc8 100644
--- a/server/apps/trak/models/transporter_model.py
+++ b/server/apps/trak/models/transporter_model.py
@@ -3,7 +3,6 @@
from django.db import models
from .handler_model import Handler, ManifestHandler, ManifestHandlerManager
-from .manifest_model import Manifest
class TransporterManager(ManifestHandlerManager):
@@ -11,18 +10,14 @@ class TransporterManager(ManifestHandlerManager):
Inter-model related functionality for Transporter Model
"""
- @staticmethod
- def create_transporter(manifest: Manifest, **data: Dict):
+ def save(self, **transporter_data: Dict):
"""
Create a Transporter from a manifest instance and handler dict
-
- ToDo: See ManifestHandlerManager method, there's overlap that can be refactored
- as a bigger item, look at our custom model managers, see where we can apply a better
- design to take advantage of polymorphism and inheritance
+ ToDo: fix this implementation
"""
- handler_data = data.pop("handler")
- new_handler = Handler.objects.create_handler(**handler_data)
- return Transporter.objects.create(handler=new_handler, manifest=manifest, **data)
+ handler_data = transporter_data.pop("handler")
+ handler = Handler.objects.save(**handler_data)
+ return self.create(handler=handler, **transporter_data)
class Transporter(ManifestHandler):
diff --git a/server/apps/trak/models/waste_model.py b/server/apps/trak/models/waste_model.py
index 2422f45a9..d63fb98ba 100644
--- a/server/apps/trak/models/waste_model.py
+++ b/server/apps/trak/models/waste_model.py
@@ -1,5 +1,16 @@
from django.db import models
+from apps.trak.models.base_model import TrakManager
+
+
+class WasteLineManager(TrakManager):
+ """
+ Inter-model related functionality for Contact Model
+ """
+
+ def save(self, **waste_data) -> models.QuerySet:
+ return super().save(**waste_data)
+
class WasteLine(models.Model):
"""
@@ -7,6 +18,8 @@ class WasteLine(models.Model):
Model definition for hazardous waste listed on a uniform hazardous waste manifest.
"""
+ objects = WasteLineManager()
+
manifest = models.ForeignKey(
"Manifest",
related_name="wastes",
diff --git a/server/apps/trak/serializers/address_ser.py b/server/apps/trak/serializers/address_ser.py
index 067a5ca1d..471e172ba 100644
--- a/server/apps/trak/serializers/address_ser.py
+++ b/server/apps/trak/serializers/address_ser.py
@@ -3,10 +3,9 @@
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
-# ToDo (convert to enums and remove this import)
-from apps.trak.models import Address, EpaCountries, EpaStates
+from apps.trak.models import Address
-from .trak_ser import TrakBaseSerializer
+from .base_ser import TrakBaseSerializer
@extend_schema_field(OpenApiTypes.OBJECT)
@@ -39,11 +38,11 @@ class AddressSerializer(TrakBaseSerializer):
required=False,
)
state = LocalityField(
- choices=EpaStates.choices,
+ choices=Address.EpaStates.choices,
required=False,
)
country = LocalityField(
- choices=EpaCountries.choices,
+ choices=Address.EpaCountries.choices,
required=False,
)
diff --git a/server/apps/trak/serializers/trak_ser.py b/server/apps/trak/serializers/base_ser.py
similarity index 100%
rename from server/apps/trak/serializers/trak_ser.py
rename to server/apps/trak/serializers/base_ser.py
diff --git a/server/apps/trak/serializers/contact_ser.py b/server/apps/trak/serializers/contact_ser.py
index 49280e964..6e7382b7f 100644
--- a/server/apps/trak/serializers/contact_ser.py
+++ b/server/apps/trak/serializers/contact_ser.py
@@ -1,7 +1,8 @@
from rest_framework import serializers
from apps.trak.models import Contact
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
+
+from .base_ser import TrakBaseSerializer
class EpaPhoneSerializer(TrakBaseSerializer):
diff --git a/server/apps/trak/serializers/handler_ser.py b/server/apps/trak/serializers/handler_ser.py
index 9447483ea..63dd339cc 100644
--- a/server/apps/trak/serializers/handler_ser.py
+++ b/server/apps/trak/serializers/handler_ser.py
@@ -1,13 +1,13 @@
-from typing import Dict, List
+from typing import Dict
from rest_framework import serializers
-from apps.trak.models import ESignature, Handler, ManifestHandler
+from apps.trak.models import Handler, ManifestHandler
from apps.trak.serializers import AddressSerializer
+from .base_ser import TrakBaseSerializer
from .contact_ser import ContactSerializer, EpaPhoneSerializer
from .signature_ser import ESignatureSerializer, PaperSignatureSerializer
-from .trak_ser import TrakBaseSerializer
class HandlerSerializer(TrakBaseSerializer):
@@ -67,7 +67,7 @@ class HandlerSerializer(TrakBaseSerializer):
)
def create(self, validated_data):
- return Handler.objects.create_handler(**validated_data)
+ return self.Meta.model.objects.save(**validated_data)
class Meta:
model = Handler
@@ -102,16 +102,11 @@ class ManifestHandlerSerializer(HandlerSerializer):
required=False,
)
+ def update(self, instance, validated_data: Dict):
+ return self.Meta.model.objects.update(instance, **validated_data)
+
def create(self, validated_data: Dict):
- e_signatures_data = []
- if "e_signatures" in validated_data:
- e_signatures_data: List = validated_data.pop("e_signatures")
- manifest_handler = ManifestHandler.objects.create_manifest_handler(**validated_data)
- for e_signature_data in e_signatures_data:
- ESignature.objects.create_e_signature(
- manifest_handler=manifest_handler, **e_signature_data
- )
- return manifest_handler
+ return self.Meta.model.objects.save(**validated_data)
def to_representation(self, instance):
representation = super().to_representation(instance)
diff --git a/server/apps/trak/serializers/manifest_ser.py b/server/apps/trak/serializers/manifest_ser.py
index bfa70b1ba..b2167d848 100644
--- a/server/apps/trak/serializers/manifest_ser.py
+++ b/server/apps/trak/serializers/manifest_ser.py
@@ -1,12 +1,13 @@
import logging
+from typing import Dict
from rest_framework import serializers
-from apps.trak.models import Manifest, Transporter, WasteLine
+from apps.trak.models import Manifest
from apps.trak.serializers.handler_ser import ManifestHandlerSerializer
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
from ..models.manifest_model import AdditionalInfo
+from .base_ser import TrakBaseSerializer
from .transporter_ser import TransporterSerializer
from .waste_line_ser import WasteLineSerializer
@@ -204,17 +205,11 @@ class ManifestSerializer(TrakBaseSerializer):
allow_null=True,
)
- def create(self, validated_data) -> Manifest:
- waste_data = validated_data.pop("wastes")
- trans_data = validated_data.pop("transporters")
- manifest = Manifest.objects.create_manifest(validated_data)
- logger.debug(f"ManifestSerializer created manifest {manifest}")
- for waste_line in waste_data:
- WasteLine.objects.create(manifest=manifest, **waste_line)
- for transporter in trans_data:
- transporter["manifest"] = manifest
- Transporter.objects.create_transporter(**transporter)
- return manifest
+ def update(self, instance, validated_data: Dict) -> Manifest:
+ return self.Meta.model.objects.save(**validated_data)
+
+ def create(self, validated_data: Dict) -> Manifest:
+ return self.Meta.model.objects.save(**validated_data)
# https://www.django-rest-framework.org/api-guide/serializers/#overriding-serialization-and-deserialization-behavior
def to_representation(self, instance) -> str:
diff --git a/server/apps/trak/serializers/rcra_profile_ser.py b/server/apps/trak/serializers/rcra_profile_ser.py
index 4012d4a64..a77ac84b0 100644
--- a/server/apps/trak/serializers/rcra_profile_ser.py
+++ b/server/apps/trak/serializers/rcra_profile_ser.py
@@ -3,7 +3,8 @@
from rest_framework.serializers import ModelSerializer
from apps.trak.models import RcraProfile, SitePermission
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
+
+from .base_ser import TrakBaseSerializer
class SitePermissionSerializer(TrakBaseSerializer):
diff --git a/server/apps/trak/serializers/signature_ser.py b/server/apps/trak/serializers/signature_ser.py
index eb987d2d6..d27687c41 100644
--- a/server/apps/trak/serializers/signature_ser.py
+++ b/server/apps/trak/serializers/signature_ser.py
@@ -4,7 +4,8 @@
from apps.trak.models import ESignature, PaperSignature, Signer
from apps.trak.serializers.contact_ser import EpaPhoneSerializer
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
+
+from .base_ser import TrakBaseSerializer
class SignerSerializer(TrakBaseSerializer):
@@ -88,16 +89,10 @@ class ESignatureSerializer(TrakBaseSerializer):
)
def update(self, instance, validated_data):
- super().update(instance, validated_data)
+ return super().update(instance, validated_data)
def create(self, validated_data: Dict):
- signer = None
- try:
- signer_data = validated_data.pop("signer")
- signer = Signer.objects.create(**signer_data)
- except KeyError:
- pass
- return ESignature.objects.create(**validated_data, signer=signer)
+ return self.Meta.model.objects.save(**validated_data)
class Meta:
model = ESignature
@@ -126,11 +121,11 @@ class PaperSignatureSerializer(TrakBaseSerializer):
required=False,
)
- def update(self, instance, validated_data):
- return super().update(instance, validated_data)
+ def update(self, instance, validated_data: Dict):
+ return super().update(instance, **validated_data)
def create(self, validated_data: Dict):
- return super().create(validated_data)
+ return super().create(**validated_data)
class Meta:
model = PaperSignature
diff --git a/server/apps/trak/serializers/sites_ser.py b/server/apps/trak/serializers/sites_ser.py
index 3bfca8faf..78e48aff4 100644
--- a/server/apps/trak/serializers/sites_ser.py
+++ b/server/apps/trak/serializers/sites_ser.py
@@ -2,7 +2,8 @@
from apps.trak.models import Site
from apps.trak.serializers import HandlerSerializer
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
+
+from .base_ser import TrakBaseSerializer
class SiteSerializer(TrakBaseSerializer):
diff --git a/server/apps/trak/serializers/transporter_ser.py b/server/apps/trak/serializers/transporter_ser.py
index d0361f4ad..7a6ef9ea6 100644
--- a/server/apps/trak/serializers/transporter_ser.py
+++ b/server/apps/trak/serializers/transporter_ser.py
@@ -1,6 +1,7 @@
from apps.trak.models import Transporter
from apps.trak.serializers.handler_ser import HandlerSerializer
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
+
+from .base_ser import TrakBaseSerializer
class TransporterSerializer(TrakBaseSerializer):
diff --git a/server/apps/trak/serializers/waste_line_ser.py b/server/apps/trak/serializers/waste_line_ser.py
index b5b914b0b..87201c397 100644
--- a/server/apps/trak/serializers/waste_line_ser.py
+++ b/server/apps/trak/serializers/waste_line_ser.py
@@ -1,7 +1,8 @@
from rest_framework import serializers
from apps.trak.models import WasteLine
-from apps.trak.serializers.trak_ser import TrakBaseSerializer
+
+from .base_ser import TrakBaseSerializer
class WasteLineSerializer(TrakBaseSerializer):
diff --git a/server/apps/trak/services/handler_service.py b/server/apps/trak/services/handler_service.py
index e0fdfd1d1..e84eaf831 100644
--- a/server/apps/trak/services/handler_service.py
+++ b/server/apps/trak/services/handler_service.py
@@ -74,5 +74,5 @@ def _create_or_update_handler(self, *, handler_data: dict) -> Handler:
if Handler.objects.filter(epa_id=epa_id).exists():
handler = Handler.objects.get(epa_id=epa_id)
return handler
- handler = Handler.objects.create_handler(**handler_data)
+ handler = Handler.objects.save(**handler_data)
return handler
diff --git a/server/apps/trak/tests/conftest.py b/server/apps/trak/tests/conftest.py
index 070906782..54c3b2c20 100644
--- a/server/apps/trak/tests/conftest.py
+++ b/server/apps/trak/tests/conftest.py
@@ -1,6 +1,8 @@
import json
import os
-from datetime import date, datetime
+import random
+import string
+from datetime import date, datetime, timezone
from enum import Enum
from http import HTTPStatus
from typing import Dict, Optional
@@ -14,6 +16,7 @@
Address,
Contact,
EpaPhone,
+ ESignature,
Handler,
Manifest,
ManifestHandler,
@@ -148,7 +151,7 @@ def create_signature(
) -> PaperSignature:
return PaperSignature.objects.create(
printed_name=printed_name,
- sign_date=sign_date or datetime.utcnow(),
+ sign_date=sign_date or datetime.utcnow().replace(tzinfo=timezone.utc),
)
return create_signature
@@ -200,6 +203,38 @@ def create_handler(
return create_handler
+@pytest.fixture
+def e_signature_factory(db, signer_factory, manifest_handler_factory):
+ """Abstract factory for Haztrak ManifestHandler model"""
+
+ def create_e_signature(
+ signer: Optional[Signer] = None,
+ manifest_handler: Optional[ManifestHandler] = None,
+ ) -> ESignature:
+ return ESignature.objects.create(
+ signer=signer or signer_factory(),
+ manifest_handler=manifest_handler or manifest_handler_factory(),
+ sign_date=datetime.utcnow().replace(tzinfo=timezone.utc),
+ cromerr_activity_id="".join(random.choices(string.ascii_letters, k=10)),
+ cromerr_document_id="".join(random.choices(string.ascii_letters, k=10)),
+ on_behalf=False,
+ )
+
+ return create_e_signature
+
+
+@pytest.fixture
+def manifest_handler_factory(db, handler_factory):
+ """Abstract factory for Haztrak ManifestHandler model"""
+
+ def create_manifest_handler(handler: Optional[Handler] = None) -> ManifestHandler:
+ return ManifestHandler.objects.create(
+ handler=handler or handler_factory(),
+ )
+
+ return create_manifest_handler
+
+
@pytest.fixture
def site_factory(db, handler_factory):
"""Abstract factory for Haztrak Site model"""
@@ -269,18 +304,6 @@ def create_permission(
return create_permission
-@pytest.fixture
-def manifest_handler_factory(db, handler_factory):
- """Abstract factory for Haztrak ManifestHandler model"""
-
- def create_manifest_handler(handler: Optional[Handler] = None) -> ManifestHandler:
- return ManifestHandler.objects.create(
- handler=handler or handler_factory(),
- )
-
- return create_manifest_handler
-
-
@pytest.fixture
def manifest_factory(db, manifest_handler_factory, handler_factory):
"""Abstract factory for Haztrak Manifest model"""
@@ -296,8 +319,8 @@ def create_manifest(
tsd = manifest_handler_factory(handler=handler)
return Manifest.objects.create(
mtn=mtn,
- created_date=datetime.now(),
- potential_ship_date=date.today(),
+ created_date=datetime.now().replace(tzinfo=timezone.utc),
+ potential_ship_date=datetime.now().replace(tzinfo=timezone.utc),
generator=generator or manifest_handler_factory(),
tsd=tsd or manifest_handler_factory(handler=handler_factory(epa_id="tsd001")),
)
diff --git a/server/apps/trak/tests/models/test_handler.py b/server/apps/trak/tests/models/test_handler.py
index 0d521d7e6..1dd624496 100644
--- a/server/apps/trak/tests/models/test_handler.py
+++ b/server/apps/trak/tests/models/test_handler.py
@@ -9,6 +9,6 @@ def test_handler_created(self, db, manifest_handler_factory) -> None:
def test_manager_creates_new_handler(self, handler_serializer) -> None:
handler_serializer.is_valid()
- ManifestHandler.objects.create_manifest_handler(handler=handler_serializer.validated_data)
+ ManifestHandler.objects.save(handler=handler_serializer.validated_data)
new_handler = Handler.objects.get(epa_id=handler_serializer.validated_data["epa_id"])
assert isinstance(new_handler, Handler)
diff --git a/server/apps/trak/tests/serializers/test_handler_serializer.py b/server/apps/trak/tests/serializers/test_handler_serializer.py
index e70dbaab2..2b4343178 100644
--- a/server/apps/trak/tests/serializers/test_handler_serializer.py
+++ b/server/apps/trak/tests/serializers/test_handler_serializer.py
@@ -3,9 +3,6 @@
class TestManifestHandlerSerializer:
- def test_new_fixture(self, haztrak_json):
- print(haztrak_json.MANIFEST.value)
-
def test_m_handler_serializes(self, haztrak_json) -> None:
manifest_handler_serializer = ManifestHandlerSerializer(data=haztrak_json.HANDLER.value)
assert manifest_handler_serializer.is_valid()