diff --git a/compose.yaml b/compose.yaml
index f1b75256b..99f065140 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -31,7 +31,7 @@ services:
sh -c "
python manage.py makemigrations &&
python manage.py migrate &&
- python manage.py loaddata dev_data.yaml org_permissions.yaml &&
+ python manage.py loaddata core_dev.yaml rcrasite_dev.yaml org_dev.yaml profile_dev.yaml &&
python manage.py runserver 0.0.0.0:8000"
healthcheck:
test:
diff --git a/server/.dockerignore b/server/.dockerignore
index 111a454c5..d70243a40 100644
--- a/server/.dockerignore
+++ b/server/.dockerignore
@@ -2,7 +2,7 @@
**/tests
Dockerfile
.dockerignore
-db.sqlite3
+**/*.sqlite3
**/.git
**/.gitignore
**/.vscode
diff --git a/server/core/fixtures/core_dev.yaml b/server/core/fixtures/core_dev.yaml
new file mode 100644
index 000000000..499c340ae
--- /dev/null
+++ b/server/core/fixtures/core_dev.yaml
@@ -0,0 +1,45 @@
+- model: core.trakuser
+ pk: 8062d496-15f1-485d-961c-a8e5fa118dde
+ fields:
+ password: pbkdf2_sha256$390000$iVFyQyb6N3g06Wan8YLnTv$MgFhKBvwPSwctgxWSviA/OXClEKtDXg87iPU+g9+Zjs=
+ last_login: 2023-03-19 00:29:46.249589+00:00
+ is_superuser: false
+ username: orgadmin
+ first_name: "org"
+ last_name: "admin"
+ email: foo@generator.com
+ is_staff: true
+ is_active: true
+ date_joined: 2022-12-17 19:14:17.239000+00:00
+ groups: [1, 2]
+ user_permissions: []
+- model: core.trakuser
+ pk: a0ba4966-aa53-44c8-be1a-0a0d2d6b6acd
+ fields:
+ password: pbkdf2_sha256$390000$iVFyQyb6N3g06Wan8YLnTv$MgFhKBvwPSwctgxWSviA/OXClEKtDXg87iPU+g9+Zjs=
+ last_login: 2023-03-19 00:29:46.249589+00:00
+ is_superuser: true
+ username: admin
+ first_name: ""
+ last_name: ""
+ email: balh@blah.com
+ is_staff: true
+ is_active: true
+ date_joined: 2022-12-17 19:14:17.239000+00:00
+ groups: []
+ user_permissions: []
+- model: core.trakuser
+ pk: 4ac96f68-42cf-47ea-bffb-f24d423dbc35
+ fields:
+ password: pbkdf2_sha256$390000$SB7EHpYC88CjsX5tcbxa8E$yh1TWONkGI2z/bjblkPSTyjpd1UdhnivPW5nzA9NGOk=
+ last_login: null
+ is_superuser: false
+ username: testuser1
+ first_name: "David"
+ last_name: "Graham"
+ email: "myemail@proton.me"
+ is_staff: false
+ is_active: true
+ date_joined: 2022-12-17 19:17:58.260000+00:00
+ groups: [2]
+ user_permissions: []
diff --git a/server/core/tests/test_rcrainfo_service.py b/server/core/tests/test_rcrainfo_service.py
index c06cbfdd2..2c9064d95 100644
--- a/server/core/tests/test_rcrainfo_service.py
+++ b/server/core/tests/test_rcrainfo_service.py
@@ -1,12 +1,12 @@
from datetime import UTC, datetime
import emanifest
+from manifest.models import QuickerSign
+from manifest.serializers import QuickerSignSerializer
from responses import matchers
from rest_framework import status
from core.services import RcraClient, get_rcra_client
-from handler.models import QuickerSign
-from handler.serializers import QuickerSignSerializer
class TestRcrainfoService:
diff --git a/server/fixtures/dev_data.yaml b/server/fixtures/dev_data.yaml
deleted file mode 100644
index 9cdb6594d..000000000
--- a/server/fixtures/dev_data.yaml
+++ /dev/null
@@ -1,210 +0,0 @@
-- model: core.trakuser
- pk: 8062d496-15f1-485d-961c-a8e5fa118dde
- fields:
- password: pbkdf2_sha256$390000$iVFyQyb6N3g06Wan8YLnTv$MgFhKBvwPSwctgxWSviA/OXClEKtDXg87iPU+g9+Zjs=
- last_login: 2023-03-19 00:29:46.249589+00:00
- is_superuser: false
- username: orgadmin
- first_name: "org"
- last_name: "admin"
- email: foo@generator.com
- is_staff: true
- is_active: true
- date_joined: 2022-12-17 19:14:17.239000+00:00
- groups: [1, 2]
- user_permissions: []
-- model: core.trakuser
- pk: a0ba4966-aa53-44c8-be1a-0a0d2d6b6acd
- fields:
- password: pbkdf2_sha256$390000$iVFyQyb6N3g06Wan8YLnTv$MgFhKBvwPSwctgxWSviA/OXClEKtDXg87iPU+g9+Zjs=
- last_login: 2023-03-19 00:29:46.249589+00:00
- is_superuser: true
- username: admin
- first_name: ""
- last_name: ""
- email: balh@blah.com
- is_staff: true
- is_active: true
- date_joined: 2022-12-17 19:14:17.239000+00:00
- groups: []
- user_permissions: []
-- model: core.trakuser
- pk: 4ac96f68-42cf-47ea-bffb-f24d423dbc35
- fields:
- password: pbkdf2_sha256$390000$SB7EHpYC88CjsX5tcbxa8E$yh1TWONkGI2z/bjblkPSTyjpd1UdhnivPW5nzA9NGOk=
- last_login: null
- is_superuser: false
- username: testuser1
- first_name: "David"
- last_name: "Graham"
- email: "myemail@proton.me"
- is_staff: false
- is_active: true
- date_joined: 2022-12-17 19:17:58.260000+00:00
- groups: [2]
- user_permissions: []
-- model: authtoken.token
- pk: d9609d7764af771ee0def1db08dc7f90dd5e2d6d
- fields:
- user: 4ac96f68-42cf-47ea-bffb-f24d423dbc35
- created: 2022-12-18 13:10:40.552000+00:00
-- model: rcrasite.address
- pk: 1
- fields:
- street_number: null
- address1: 123 VA TEST GEN 2021 WAY
- address2: null
- city: ARLINGTON
- state: VA
- country: US
- zip: "22202"
-- model: handler.manifestphone
- pk: 1
- fields:
- number: 321-321-3214
- extension: null
-- model: rcrasite.rcraphone
- pk: 1
- fields:
- number: 321-321-3214
- extension: null
-- model: rcrasite.contact
- pk: 1
- fields:
- first_name: David
- middle_initial: P
- last_name: Graham
- phone: 1
- email: testuser1@haztrak.net
- company_name: haztrak
-- model: rcrasite.rcrasite
- pk: 1
- fields:
- site_type: Generator
- epa_id: VATESTGEN001
- name: VA TEST GEN 2021
- site_address: 1
- mail_address: 1
- modified: false
- registered: false
- contact: 1
- emergency_phone: null
- gis_primary: false
- can_esign: true
- limited_esign: true
- registered_emanifest_user: true
-- model: rcrasite.rcrasite
- pk: 2
- fields:
- site_type: Transporter
- epa_id: MOCKTRANS001
- name: Mock Transporter 01
- site_address: 1
- mail_address: 1
- modified: false
- registered: false
- contact: 1
- emergency_phone: null
- gis_primary: false
- can_esign: true
- limited_esign: true
- registered_emanifest_user: true
-- model: rcrasite.rcrasite
- pk: 3
- fields:
- site_type: Transporter
- epa_id: MOCKTRANS002
- name: Mock Transporter 02
- site_address: 1
- mail_address: 1
- modified: false
- registered: false
- contact: 1
- emergency_phone: null
- gis_primary: false
- can_esign: true
- limited_esign: true
- registered_emanifest_user: true
-- model: rcrasite.rcrasite
- pk: 4
- fields:
- site_type: Tsdf
- epa_id: MOCKTSDFS001
- name: Mock haztrak TSDF 01
- site_address: 1
- mail_address: 1
- modified: false
- registered: false
- contact: 1
- emergency_phone: null
- gis_primary: false
- can_esign: true
- limited_esign: true
- registered_emanifest_user: true
-- model: profile.rcrainfoprofile
- pk: d74f904a-7843-4a60-862c-3b94b6051359
- fields:
- rcra_username: dpgraham4401
- phone_number: null
- email: orgadmin@generator.com
-- model: profile.rcrainfoprofile
- pk: 1fd27bec-8743-4eb3-a44c-fd063ea62021
- fields:
- rcra_username: ""
- phone_number: null
- email: superadmin@gmail.com
-- model: profile.rcrainfoprofile
- pk: 192c73f4-24f1-4f21-8239-dee2da43c547
- fields:
- rcra_username: emanifestpyuser1
- phone_number: null
- email: testuser1@haztrak.net
-- model: org.org
- pk: efb9e104-7f61-4365-a9af-9d7b55c854c4
- fields:
- name: Generators Org LLC
- admin: 8062d496-15f1-485d-961c-a8e5fa118dde
- slug: generators-org-llc
-- model: profile.profile
- pk: c65dbee9-b6bf-400e-93e0-90a749cc2939
- fields:
- user: 8062d496-15f1-485d-961c-a8e5fa118dde
- rcrainfo_profile: d74f904a-7843-4a60-862c-3b94b6051359
-- model: profile.profile
- pk: 186642a9-7b5f-4bcb-b328-0fdf8b43f191
- fields:
- user: a0ba4966-aa53-44c8-be1a-0a0d2d6b6acd
- rcrainfo_profile: 1fd27bec-8743-4eb3-a44c-fd063ea62021
-- model: profile.profile
- pk: 87e355dd-1898-4a0a-81c3-1e9ac8473143
- fields:
- user: 4ac96f68-42cf-47ea-bffb-f24d423dbc35
- rcrainfo_profile: 192c73f4-24f1-4f21-8239-dee2da43c547
-- model: org.site
- pk: 1
- fields:
- name: VA TEST GEN 2021
- rcra_site: 1
- last_rcrainfo_manifest_sync: null
- org: efb9e104-7f61-4365-a9af-9d7b55c854c4
-- model: profile.rcrainfositeaccess
- pk: 1
- fields:
- site: 1
- profile: 192c73f4-24f1-4f21-8239-dee2da43c547
- site_manager: true
- annual_report: Certifier
- biennial_report: Certifier
- e_manifest: Certifier
- my_rcra_id: Certifier
- wiets: Certifier
-- model: org.siteuserobjectpermission
- pk: 1
- fields:
- permission:
- - view_site
- - org
- - site
- user:
- - testuser1
- content_object: 1
diff --git a/server/handler/admin.py b/server/handler/admin.py
deleted file mode 100644
index bba589bc2..000000000
--- a/server/handler/admin.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from django.contrib import admin
-from django.db.models import Q, QuerySet
-from django.urls import reverse
-from django.utils.html import format_html, urlencode
-
-from core.admin import HiddenListView
-
-from .models import (
- ESignature,
- Handler,
- Signer,
- Transporter,
-)
-from .models.contact import ManifestPhone
-
-
-class IsApiUser(admin.SimpleListFilter):
- title = "API User"
- parameter_name = "has_rcrainfo_api_id_key"
-
- def lookups(self, request, model_admin):
- return ("True", True), ("False", False)
-
- def queryset(self, request, queryset: QuerySet):
- if self.value() == "True":
- return queryset.filter(mtn__iendswith="DFT")
- elif self.value() == "False":
- return queryset.filter(~Q(mtn__iendswith="DFT"))
- else:
- return queryset
-
-
-@admin.register(Transporter)
-class TransporterAdmin(admin.ModelAdmin):
- list_display = ["__str__", "related_manifest", "order"]
- search_fields = ["handler__epa_id", "manifest__mtn"]
-
- def related_manifest(self, obj):
- url = (
- reverse("admin:trak_manifest_changelist")
- + "?"
- + urlencode({"mtn": str(obj.manifest.mtn)})
- )
- return format_html("{}", url, obj.manifest.mtn)
-
- related_manifest.short_description = "Manifest"
-
-
-@admin.register(Handler)
-class HandlerAdmin(admin.ModelAdmin):
- list_display = ["__str__", "related_manifest"]
- search_fields = ["handler__epa_id"]
-
- def related_manifest(self, obj: Handler):
- if obj.generator:
- return obj.generator.get()
- if obj.designated_facility:
- return obj.designated_facility.get()
-
- related_manifest.short_description = "Manifest"
-
-
-# Register models That should only be edited within the context of another form here.
-admin.site.register(ManifestPhone, HiddenListView)
-admin.site.register(ESignature, HiddenListView)
-admin.site.register(Signer, HiddenListView)
diff --git a/server/handler/apps.py b/server/handler/apps.py
deleted file mode 100644
index f4db87f6e..000000000
--- a/server/handler/apps.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class TrakConfig(AppConfig):
- default_auto_field = "django.db.models.BigAutoField"
- name = "handler"
diff --git a/server/handler/migrations/0001_initial.py b/server/handler/migrations/0001_initial.py
deleted file mode 100644
index fc03a627c..000000000
--- a/server/handler/migrations/0001_initial.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# Generated by Django 4.2.10 on 2024-02-21 22:17
-
-import django.db.models.deletion
-import handler.models.contact
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- initial = True
-
- dependencies = [
- ("rcrasite", "0001_initial"),
- ]
-
- operations = [
- migrations.CreateModel(
- name="Handler",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
- ),
- ),
- ],
- options={
- "ordering": ["rcra_site"],
- },
- ),
- migrations.CreateModel(
- name="ManifestPhone",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
- ),
- ),
- ("number", handler.models.contact.ManifestPhoneNumber(max_length=12)),
- ("extension", models.CharField(blank=True, max_length=6, null=True)),
- ],
- options={
- "ordering": ["number"],
- },
- ),
- migrations.CreateModel(
- name="PaperSignature",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
- ),
- ),
- ("printed_name", models.CharField(max_length=255)),
- ("sign_date", models.DateTimeField()),
- ],
- options={
- "ordering": ["pk"],
- "abstract": False,
- },
- ),
- migrations.CreateModel(
- name="Transporter",
- fields=[
- (
- "handler_ptr",
- models.OneToOneField(
- auto_created=True,
- on_delete=django.db.models.deletion.CASCADE,
- parent_link=True,
- primary_key=True,
- serialize=False,
- to="handler.handler",
- ),
- ),
- ("order", models.PositiveIntegerField()),
- ],
- options={
- "ordering": ["manifest__mtn"],
- },
- bases=("handler.handler",),
- ),
- migrations.CreateModel(
- name="Signer",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
- ),
- ),
- ("rcra_user_id", models.CharField(blank=True, max_length=100, null=True)),
- ("first_name", models.CharField(blank=True, max_length=38, null=True)),
- ("middle_initial", models.CharField(blank=True, max_length=1, null=True)),
- ("last_name", models.CharField(blank=True, max_length=38, null=True)),
- ("email", models.CharField(blank=True, max_length=38, null=True)),
- ("company_name", models.CharField(blank=True, max_length=80, null=True)),
- (
- "contact_type",
- models.CharField(
- blank=True,
- choices=[("email", "Email"), ("voice", "Voice"), ("text", "Text")],
- max_length=5,
- null=True,
- ),
- ),
- (
- "signer_role",
- models.CharField(
- choices=[
- ("Industry", "Industry"),
- ("PPC", "Ppc"),
- ("EPA", "Epa"),
- ("State", "State"),
- ],
- max_length=10,
- null=True,
- ),
- ),
- (
- "phone",
- models.ForeignKey(
- null=True,
- on_delete=django.db.models.deletion.CASCADE,
- to="handler.manifestphone",
- ),
- ),
- ],
- options={
- "ordering": ["first_name"],
- },
- ),
- migrations.AddField(
- model_name="handler",
- name="emergency_phone",
- field=models.ForeignKey(
- blank=True,
- help_text="Emergency phone number for the hazardous waste rcra_site",
- null=True,
- on_delete=django.db.models.deletion.PROTECT,
- to="handler.manifestphone",
- ),
- ),
- migrations.AddField(
- model_name="handler",
- name="paper_signature",
- field=models.OneToOneField(
- blank=True,
- help_text="The signature associated with hazardous waste custody exchange",
- null=True,
- on_delete=django.db.models.deletion.CASCADE,
- to="handler.papersignature",
- ),
- ),
- migrations.AddField(
- model_name="handler",
- name="rcra_site",
- field=models.ForeignKey(
- help_text="Hazardous waste rcra_site associated with the manifest",
- on_delete=django.db.models.deletion.CASCADE,
- to="rcrasite.rcrasite",
- ),
- ),
- migrations.CreateModel(
- name="ESignature",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
- ),
- ),
- ("sign_date", models.DateTimeField(blank=True, null=True)),
- ("cromerr_activity_id", models.CharField(blank=True, max_length=100, null=True)),
- ("cromerr_document_id", models.CharField(blank=True, max_length=100, null=True)),
- ("on_behalf", models.BooleanField(blank=True, default=False, null=True)),
- (
- "manifest_handler",
- models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE,
- related_name="e_signatures",
- to="handler.handler",
- ),
- ),
- (
- "signer",
- models.OneToOneField(
- blank=True,
- null=True,
- on_delete=django.db.models.deletion.CASCADE,
- to="handler.signer",
- ),
- ),
- ],
- options={
- "verbose_name": "e-Signature",
- "ordering": ["sign_date"],
- },
- ),
- ]
diff --git a/server/handler/migrations/0002_initial.py b/server/handler/migrations/0002_initial.py
deleted file mode 100644
index 28a65cfbd..000000000
--- a/server/handler/migrations/0002_initial.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Generated by Django 4.2.10 on 2024-02-21 22:17
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- ('manifest', '0001_initial'),
- ('handler', '0001_initial'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='transporter',
- name='manifest',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transporters', to='manifest.manifest'),
- ),
- ]
diff --git a/server/handler/migrations/0003_alter_papersignature_options.py b/server/handler/migrations/0003_alter_papersignature_options.py
deleted file mode 100644
index a630ebc0b..000000000
--- a/server/handler/migrations/0003_alter_papersignature_options.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 5.0.4 on 2024-06-03 02:04
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('handler', '0002_initial'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='papersignature',
- options={},
- ),
- ]
diff --git a/server/handler/serializers/base_serializer.py b/server/handler/serializers/base_serializer.py
deleted file mode 100644
index f43b6940d..000000000
--- a/server/handler/serializers/base_serializer.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from rest_framework import serializers
-
-
-class HandlerBaseSerializer(serializers.ModelSerializer):
- """
- The Django Trak app base serializers class used to share functionality
- across trak app serializers universally.
- """
-
- def __str__(self):
- return f"{self.__class__.__name__}"
-
- def __repr__(self):
- return f"<{self.__class__.__name__}({self.data})>"
-
- def to_representation(self, instance):
- """
- Remove empty fields when serializing
- """
- data = super().to_representation(instance)
- for field in self.fields:
- try:
- if data[field] is None:
- data.pop(field)
- except KeyError:
- pass
- return data
diff --git a/server/handler/tests/conftest.py b/server/handler/tests/conftest.py
deleted file mode 100644
index 94865b1e4..000000000
--- a/server/handler/tests/conftest.py
+++ /dev/null
@@ -1,111 +0,0 @@
-from datetime import UTC, datetime
-from typing import Optional
-
-import pytest
-from faker import Faker
-
-from handler.models import (
- ESignature,
- Handler,
- PaperSignature,
- Signer,
- Transporter,
-)
-from manifest.models import Manifest
-from rcrasite.models import RcraSite
-
-
-@pytest.fixture
-def manifest_handler_factory(db, rcra_site_factory, paper_signature_factory):
- """Abstract factory for Haztrak Handler model"""
-
- def create_manifest_handler(
- rcra_site: Optional[RcraSite] = None,
- paper_signature: Optional[PaperSignature] = None,
- ) -> Handler:
- return Handler.objects.create(
- rcra_site=rcra_site or rcra_site_factory(),
- paper_signature=paper_signature or paper_signature_factory(),
- )
-
- return create_manifest_handler
-
-
-@pytest.fixture
-def manifest_transporter_factory(db, rcra_site_factory, paper_signature_factory):
- """Abstract factory for Haztrak Handler model"""
-
- def create_manifest_handler(
- rcra_site: Optional[RcraSite] = None,
- paper_signature: Optional[PaperSignature] = None,
- manifest: Manifest = None,
- order: Optional[int] = 1,
- ) -> Transporter:
- return Transporter.objects.create(
- manifest=manifest,
- order=order,
- rcra_site=rcra_site or rcra_site_factory(),
- paper_signature=paper_signature or paper_signature_factory(),
- )
-
- return create_manifest_handler
-
-
-@pytest.fixture
-def paper_signature_factory(db, faker: Faker):
- """Abstract factory for Paper Signature"""
-
- def create_signature(
- printed_name: Optional[str] = None,
- sign_date: Optional[datetime] = None,
- ) -> PaperSignature:
- return PaperSignature.objects.create(
- printed_name=printed_name or faker.name(),
- sign_date=sign_date or datetime.now(UTC),
- )
-
- return create_signature
-
-
-@pytest.fixture
-def e_signature_factory(db, signer_factory, manifest_handler_factory, faker: Faker):
- """Abstract factory for Haztrak Handler model"""
-
- def create_e_signature(
- signer: Optional[Signer] = None,
- manifest_handler: Optional[Handler] = None,
- ) -> ESignature:
- return ESignature.objects.create(
- signer=signer or signer_factory(),
- manifest_handler=manifest_handler or manifest_handler_factory(),
- sign_date=datetime.now(UTC),
- cromerr_activity_id=faker.pystr(max_chars=10),
- cromerr_document_id=faker.pystr(max_chars=10),
- on_behalf=False,
- )
-
- return create_e_signature
-
-
-@pytest.fixture
-def signer_factory(db, faker: Faker):
- """Abstract factory for Haztrak Signer model"""
-
- def creat_signer(
- first_name: Optional[str] = None,
- middle_initial: Optional[str] = None,
- last_name: Optional[str] = None,
- signer_role: Optional[str] = "EP",
- company_name: Optional[str] = None,
- rcra_user_id: Optional[str] = None,
- ) -> Signer:
- return Signer.objects.create(
- first_name=first_name or faker.first_name(),
- middle_initial=middle_initial or faker.pystr(max_chars=1),
- last_name=last_name or faker.last_name(),
- signer_role=signer_role,
- company_name=company_name or faker.company(),
- rcra_user_id=rcra_user_id or faker.user_name(),
- )
-
- return creat_signer
diff --git a/server/haztrak/settings/base.py b/server/haztrak/settings/base.py
index 9ee69655b..7a3ce5c74 100644
--- a/server/haztrak/settings/base.py
+++ b/server/haztrak/settings/base.py
@@ -56,7 +56,6 @@
"django_celery_results",
"django_celery_beat",
"drf_spectacular",
- "handler",
"rcrasite",
"core",
"manifest",
@@ -263,4 +262,3 @@
TRAK_MANIFEST_MODEL = "manifest.Manifest"
TRAK_SITE_MODEL = "org.Site"
TRAK_WASTELINE_MODEL = "wasteline.Wasteline"
-TRAK_HANDLER_MODEL = "handler.Handler"
diff --git a/server/manage.py b/server/manage.py
index 014ac6f33..510907acb 100755
--- a/server/manage.py
+++ b/server/manage.py
@@ -1,12 +1,13 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
+
import os
import sys
def main():
"""Run administrative tasks."""
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "haztrak.settings")
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "haztrak.settings.dev")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
diff --git a/server/manifest/admin.py b/server/manifest/admin.py
index d084487e4..a2efbf72b 100644
--- a/server/manifest/admin.py
+++ b/server/manifest/admin.py
@@ -1,9 +1,19 @@
+from core.admin import HiddenListView
from django.contrib import admin
from django.db.models import Q, QuerySet
+from django.urls import reverse
+from django.utils.html import format_html, urlencode
+from wasteline.admin import WasteLineInline
-from handler.models import Transporter
from manifest.models import Manifest
-from wasteline.admin import WasteLineInline
+
+from .models import (
+ ESignature,
+ Handler,
+ ManifestPhone,
+ Signer,
+ Transporter,
+)
class IsDraftMtn(admin.SimpleListFilter):
@@ -33,3 +43,55 @@ class ManifestAdmin(admin.ModelAdmin):
def transporter_count(self, manifest):
# ToDo: this will result in additional DB hit for every Manifest in the list rendered.
return Transporter.objects.filter(manifest=manifest).count()
+
+
+class IsApiUser(admin.SimpleListFilter):
+ title = "API User"
+ parameter_name = "has_rcrainfo_api_id_key"
+
+ def lookups(self, request, model_admin):
+ return ("True", True), ("False", False)
+
+ def queryset(self, request, queryset: QuerySet):
+ if self.value() == "True":
+ return queryset.filter(mtn__iendswith="DFT")
+ elif self.value() == "False":
+ return queryset.filter(~Q(mtn__iendswith="DFT"))
+ else:
+ return queryset
+
+
+@admin.register(Transporter)
+class TransporterAdmin(admin.ModelAdmin):
+ list_display = ["__str__", "related_manifest", "order"]
+ search_fields = ["handler__epa_id", "manifest__mtn"]
+
+ def related_manifest(self, obj):
+ url = (
+ reverse("admin:trak_manifest_changelist")
+ + "?"
+ + urlencode({"mtn": str(obj.manifest.mtn)})
+ )
+ return format_html("{}", url, obj.manifest.mtn)
+
+ related_manifest.short_description = "Manifest"
+
+
+@admin.register(Handler)
+class HandlerAdmin(admin.ModelAdmin):
+ list_display = ["__str__", "related_manifest"]
+ search_fields = ["handler__epa_id"]
+
+ def related_manifest(self, obj: Handler):
+ if obj.generator:
+ return obj.generator.get()
+ if obj.designated_facility:
+ return obj.designated_facility.get()
+
+ related_manifest.short_description = "Manifest"
+
+
+# Register models That should only be edited within the context of another form here.
+admin.site.register(ManifestPhone, HiddenListView)
+admin.site.register(ESignature, HiddenListView)
+admin.site.register(Signer, HiddenListView)
diff --git a/server/manifest/migrations/0001_initial.py b/server/manifest/migrations/0001_initial.py
index 33da08327..bd7ae4490 100644
--- a/server/manifest/migrations/0001_initial.py
+++ b/server/manifest/migrations/0001_initial.py
@@ -1,7 +1,8 @@
-# Generated by Django 4.2.10 on 2024-02-21 22:17
+# Generated by Django 5.0.8 on 2024-08-22 16:38
import django.db.models.deletion
-import manifest.models
+import manifest.models.contact
+import manifest.models.manifest
from django.db import migrations, models
@@ -9,7 +10,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
- ("handler", "0001_initial"),
+ ("rcrasite", "0001_initial"),
]
operations = [
@@ -28,7 +29,7 @@ class Migration(migrations.Migration):
blank=True,
help_text="Original manifest tracking number of rejected manifestRegex expression validation: [0-9]{9}[A-Z]{3}",
null=True,
- validators=[manifest.models.validate_mtn],
+ validators=[manifest.models.manifest.validate_mtn],
),
),
(
@@ -58,6 +59,57 @@ class Migration(migrations.Migration):
"verbose_name_plural": "Additional Info",
},
),
+ migrations.CreateModel(
+ name="Handler",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ (
+ "rcra_site",
+ models.ForeignKey(
+ help_text="Hazardous waste rcra_site associated with the manifest",
+ on_delete=django.db.models.deletion.CASCADE,
+ to="rcrasite.rcrasite",
+ ),
+ ),
+ ],
+ options={
+ "ordering": ["rcra_site"],
+ },
+ ),
+ migrations.CreateModel(
+ name="ManifestPhone",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("number", manifest.models.contact.ManifestPhoneNumber(max_length=12)),
+ ("extension", models.CharField(blank=True, max_length=6, null=True)),
+ ],
+ options={
+ "ordering": ["number"],
+ },
+ ),
+ migrations.CreateModel(
+ name="PaperSignature",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("printed_name", models.CharField(max_length=255)),
+ ("sign_date", models.DateTimeField()),
+ ],
+ ),
migrations.CreateModel(
name="PortOfEntry",
fields=[
@@ -163,10 +215,10 @@ class Migration(migrations.Migration):
(
"mtn",
models.CharField(
- default=manifest.models.draft_mtn,
+ default=manifest.models.manifest.draft_mtn,
max_length=30,
unique=True,
- validators=[manifest.models.validate_mtn],
+ validators=[manifest.models.manifest.validate_mtn],
verbose_name="manifest Tracking Number",
),
),
@@ -302,7 +354,7 @@ class Migration(migrations.Migration):
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="generator",
- to="handler.handler",
+ to="manifest.handler",
),
),
(
@@ -310,7 +362,7 @@ class Migration(migrations.Migration):
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="designated_facility",
- to="handler.handler",
+ to="manifest.handler",
verbose_name="designated facility",
),
),
@@ -319,4 +371,141 @@ class Migration(migrations.Migration):
"ordering": ["update_date", "mtn"],
},
),
+ migrations.AddField(
+ model_name="handler",
+ name="emergency_phone",
+ field=models.ForeignKey(
+ blank=True,
+ help_text="Emergency phone number for the hazardous waste rcra_site",
+ null=True,
+ on_delete=django.db.models.deletion.PROTECT,
+ to="manifest.manifestphone",
+ ),
+ ),
+ migrations.AddField(
+ model_name="handler",
+ name="paper_signature",
+ field=models.OneToOneField(
+ blank=True,
+ help_text="The signature associated with hazardous waste custody exchange",
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ to="manifest.papersignature",
+ ),
+ ),
+ migrations.CreateModel(
+ name="Signer",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("rcra_user_id", models.CharField(blank=True, max_length=100, null=True)),
+ ("first_name", models.CharField(blank=True, max_length=38, null=True)),
+ ("middle_initial", models.CharField(blank=True, max_length=1, null=True)),
+ ("last_name", models.CharField(blank=True, max_length=38, null=True)),
+ ("email", models.CharField(blank=True, max_length=38, null=True)),
+ ("company_name", models.CharField(blank=True, max_length=80, null=True)),
+ (
+ "contact_type",
+ models.CharField(
+ blank=True,
+ choices=[("email", "Email"), ("voice", "Voice"), ("text", "Text")],
+ max_length=5,
+ null=True,
+ ),
+ ),
+ (
+ "signer_role",
+ models.CharField(
+ choices=[
+ ("Industry", "Industry"),
+ ("PPC", "Ppc"),
+ ("EPA", "Epa"),
+ ("State", "State"),
+ ],
+ max_length=10,
+ null=True,
+ ),
+ ),
+ (
+ "phone",
+ models.ForeignKey(
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ to="manifest.manifestphone",
+ ),
+ ),
+ ],
+ options={
+ "ordering": ["first_name"],
+ },
+ ),
+ migrations.CreateModel(
+ name="ESignature",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("sign_date", models.DateTimeField(blank=True, null=True)),
+ ("cromerr_activity_id", models.CharField(blank=True, max_length=100, null=True)),
+ ("cromerr_document_id", models.CharField(blank=True, max_length=100, null=True)),
+ ("on_behalf", models.BooleanField(blank=True, default=False, null=True)),
+ (
+ "manifest_handler",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="e_signatures",
+ to="manifest.handler",
+ ),
+ ),
+ (
+ "signer",
+ models.OneToOneField(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ to="manifest.signer",
+ ),
+ ),
+ ],
+ options={
+ "verbose_name": "e-Signature",
+ "ordering": ["sign_date"],
+ },
+ ),
+ migrations.CreateModel(
+ name="Transporter",
+ fields=[
+ (
+ "handler_ptr",
+ models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ serialize=False,
+ to="manifest.handler",
+ ),
+ ),
+ ("order", models.PositiveIntegerField()),
+ (
+ "manifest",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="transporters",
+ to="manifest.manifest",
+ ),
+ ),
+ ],
+ options={
+ "ordering": ["manifest__mtn"],
+ },
+ bases=("manifest.handler",),
+ ),
]
diff --git a/server/handler/models/__init__.py b/server/manifest/models/__init__.py
similarity index 52%
rename from server/handler/models/__init__.py
rename to server/manifest/models/__init__.py
index bbe8277ea..0c45b8437 100644
--- a/server/handler/models/__init__.py
+++ b/server/manifest/models/__init__.py
@@ -1,7 +1,11 @@
-"""
-Model definitions for the trak domain
-"""
-
from .contact import ManifestPhone
from .handler import Handler, Transporter
+from .manifest import (
+ AdditionalInfo,
+ Manifest,
+ PortOfEntry,
+ draft_mtn,
+ manifest_factory,
+ validate_mtn,
+)
from .signature import ESignature, PaperSignature, QuickerSign, Signer
diff --git a/server/handler/models/contact.py b/server/manifest/models/contact.py
similarity index 100%
rename from server/handler/models/contact.py
rename to server/manifest/models/contact.py
diff --git a/server/handler/models/handler.py b/server/manifest/models/handler.py
similarity index 99%
rename from server/handler/models/handler.py
rename to server/manifest/models/handler.py
index c935af8d8..6df9ab1e4 100644
--- a/server/handler/models/handler.py
+++ b/server/manifest/models/handler.py
@@ -4,7 +4,6 @@
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
-
from rcrasite.models import RcraSite
from .contact import ManifestPhone
diff --git a/server/manifest/models.py b/server/manifest/models/manifest.py
similarity index 98%
rename from server/manifest/models.py
rename to server/manifest/models/manifest.py
index 6aa66b3db..d980ec2da 100644
--- a/server/manifest/models.py
+++ b/server/manifest/models/manifest.py
@@ -3,16 +3,15 @@
from abc import ABC, abstractmethod
from typing import List, Literal, Optional
-from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q, QuerySet
from django.utils.translation import gettext_lazy as _
-
-from handler.models import Handler, Transporter
from rcrasite.models import RcraSiteType, RcraStates
from wasteline.models import WasteLine
+from .handler import Handler, Transporter
+
logger = logging.getLogger(__name__)
@@ -247,13 +246,13 @@ class Status(models.TextChoices):
blank=True,
)
generator = models.ForeignKey(
- settings.TRAK_HANDLER_MODEL,
+ "Handler",
on_delete=models.PROTECT,
related_name="generator",
)
# transporters - one-to-many relationship, a manifest can have many transporters
tsdf = models.ForeignKey(
- settings.TRAK_HANDLER_MODEL,
+ "Handler",
verbose_name="designated facility",
on_delete=models.PROTECT,
related_name="designated_facility",
diff --git a/server/handler/models/signature.py b/server/manifest/models/signature.py
similarity index 98%
rename from server/handler/models/signature.py
rename to server/manifest/models/signature.py
index f8372655b..15bc94ffe 100644
--- a/server/handler/models/signature.py
+++ b/server/manifest/models/signature.py
@@ -2,7 +2,6 @@
from datetime import datetime, timezone
from typing import List, Literal, Optional
-from django.conf import settings
from django.db import models
logger = logging.getLogger(__name__)
@@ -103,7 +102,7 @@ class Meta:
objects = ESignatureManager()
manifest_handler = models.ForeignKey(
- settings.TRAK_HANDLER_MODEL,
+ "Handler",
related_name="e_signatures",
on_delete=models.CASCADE,
)
diff --git a/server/handler/serializers/__init__.py b/server/manifest/serializers/__init__.py
similarity index 74%
rename from server/handler/serializers/__init__.py
rename to server/manifest/serializers/__init__.py
index 85b78d627..ec0da33b2 100644
--- a/server/handler/serializers/__init__.py
+++ b/server/manifest/serializers/__init__.py
@@ -1,2 +1,3 @@
from .handler_serializer import HandlerSerializer, TransporterSerializer
+from .manifest import ManifestSerializer, MtnSerializer
from .signatures import ESignatureSerializer, PaperSignatureSerializer, QuickerSignSerializer
diff --git a/server/handler/serializers/handler_serializer.py b/server/manifest/serializers/handler_serializer.py
similarity index 97%
rename from server/handler/serializers/handler_serializer.py
rename to server/manifest/serializers/handler_serializer.py
index 3ccd3991b..03efbf483 100644
--- a/server/handler/serializers/handler_serializer.py
+++ b/server/manifest/serializers/handler_serializer.py
@@ -1,10 +1,10 @@
from typing import Dict
+from rcrasite.serializers import RcraSiteSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
-from handler.models import Handler, ManifestPhone, Transporter
-from rcrasite.serializers import RcraSiteSerializer
+from manifest.models import Handler, ManifestPhone, Transporter
from .signatures import ESignatureSerializer, PaperSignatureSerializer
diff --git a/server/manifest/serializers.py b/server/manifest/serializers/manifest.py
similarity index 99%
rename from server/manifest/serializers.py
rename to server/manifest/serializers/manifest.py
index d11bb90d3..f73ad771a 100644
--- a/server/manifest/serializers.py
+++ b/server/manifest/serializers/manifest.py
@@ -1,21 +1,21 @@
import logging
from typing import Dict, override
+from rcrasite.models import RcraStates
from rest_framework import serializers
-
-from handler.serializers import (
- HandlerSerializer,
- TransporterSerializer,
+from wasteline.serializers import (
+ WasteLineSerializer,
)
+
from manifest.models import (
AdditionalInfo,
Manifest,
PortOfEntry,
draft_mtn,
)
-from rcrasite.models import RcraStates
-from wasteline.serializers import (
- WasteLineSerializer,
+from manifest.serializers import (
+ HandlerSerializer,
+ TransporterSerializer,
)
logger = logging.getLogger(__name__)
diff --git a/server/handler/serializers/signatures.py b/server/manifest/serializers/signatures.py
similarity index 88%
rename from server/handler/serializers/signatures.py
rename to server/manifest/serializers/signatures.py
index e9d8fba16..2cb3cc243 100644
--- a/server/handler/serializers/signatures.py
+++ b/server/manifest/serializers/signatures.py
@@ -2,12 +2,33 @@
from datetime import timezone
from typing import Dict
+from rcrasite.serializers import RcraPhoneSerializer
from rest_framework import serializers
-from handler.models import ESignature, PaperSignature, QuickerSign, Signer
-from rcrasite.serializers import RcraPhoneSerializer
+from manifest.models import ESignature, PaperSignature, QuickerSign, Signer
+
+
+class HandlerBaseSerializer(serializers.ModelSerializer):
+ # ToDo: remove
-from .base_serializer import HandlerBaseSerializer
+ def __str__(self):
+ return f"{self.__class__.__name__}"
+
+ def __repr__(self):
+ return f"<{self.__class__.__name__}({self.data})>"
+
+ def to_representation(self, instance):
+ """
+ Remove empty fields when serializing
+ """
+ data = super().to_representation(instance)
+ for field in self.fields:
+ try:
+ if data[field] is None:
+ data.pop(field)
+ except KeyError:
+ pass
+ return data
class QuickerSignSerializer(serializers.Serializer):
diff --git a/server/manifest/services/emanifest.py b/server/manifest/services/emanifest.py
index e10c0ef0a..0533cab42 100644
--- a/server/manifest/services/emanifest.py
+++ b/server/manifest/services/emanifest.py
@@ -2,16 +2,14 @@
from datetime import datetime
from typing import List, Literal, NotRequired, Optional, TypedDict
+from core.services import RcraClient, get_rcra_client
from django.db import transaction
from django.db.models import QuerySet
from emanifest import RcrainfoResponse
from requests import RequestException
-from core.services import RcraClient, get_rcra_client
-from handler.models import QuickerSign
-from handler.serializers import QuickerSignSerializer
-from manifest.models import Manifest
-from manifest.serializers import ManifestSerializer
+from manifest.models import Manifest, QuickerSign
+from manifest.serializers import ManifestSerializer, QuickerSignSerializer
from manifest.services.emanifest_search import EmanifestSearch
from manifest.tasks import pull_manifest, sign_manifest
diff --git a/server/manifest/tests/conftest.py b/server/manifest/tests/conftest.py
index b580f8c25..d5426f71a 100644
--- a/server/manifest/tests/conftest.py
+++ b/server/manifest/tests/conftest.py
@@ -7,11 +7,113 @@
from django.db import IntegrityError
from faker import Faker
from faker.providers import BaseProvider
-
-from handler.models import Handler, PaperSignature, Transporter
-from manifest.models import Manifest
from rcrasite.models import RcraSite, RcraSiteType
+from manifest.models import (
+ ESignature,
+ Handler,
+ Manifest,
+ PaperSignature,
+ Signer,
+ Transporter,
+)
+
+
+@pytest.fixture
+def manifest_handler_factory(db, rcra_site_factory, paper_signature_factory):
+ """Abstract factory for Haztrak Handler model"""
+
+ def create_manifest_handler(
+ rcra_site: Optional[RcraSite] = None,
+ paper_signature: Optional[PaperSignature] = None,
+ ) -> Handler:
+ return Handler.objects.create(
+ rcra_site=rcra_site or rcra_site_factory(),
+ paper_signature=paper_signature or paper_signature_factory(),
+ )
+
+ return create_manifest_handler
+
+
+@pytest.fixture
+def manifest_transporter_factory(db, rcra_site_factory, paper_signature_factory):
+ """Abstract factory for Haztrak Handler model"""
+
+ def create_manifest_handler(
+ rcra_site: Optional[RcraSite] = None,
+ paper_signature: Optional[PaperSignature] = None,
+ manifest: Manifest = None,
+ order: Optional[int] = 1,
+ ) -> Transporter:
+ return Transporter.objects.create(
+ manifest=manifest,
+ order=order,
+ rcra_site=rcra_site or rcra_site_factory(),
+ paper_signature=paper_signature or paper_signature_factory(),
+ )
+
+ return create_manifest_handler
+
+
+@pytest.fixture
+def paper_signature_factory(db, faker: Faker):
+ """Abstract factory for Paper Signature"""
+
+ def create_signature(
+ printed_name: Optional[str] = None,
+ sign_date: Optional[datetime] = None,
+ ) -> PaperSignature:
+ return PaperSignature.objects.create(
+ printed_name=printed_name or faker.name(),
+ sign_date=sign_date or datetime.now(UTC),
+ )
+
+ return create_signature
+
+
+@pytest.fixture
+def e_signature_factory(db, signer_factory, manifest_handler_factory, faker: Faker):
+ """Abstract factory for Haztrak Handler model"""
+
+ def create_e_signature(
+ signer: Optional[Signer] = None,
+ manifest_handler: Optional[Handler] = None,
+ ) -> ESignature:
+ return ESignature.objects.create(
+ signer=signer or signer_factory(),
+ manifest_handler=manifest_handler or manifest_handler_factory(),
+ sign_date=datetime.now(UTC),
+ cromerr_activity_id=faker.pystr(max_chars=10),
+ cromerr_document_id=faker.pystr(max_chars=10),
+ on_behalf=False,
+ )
+
+ return create_e_signature
+
+
+@pytest.fixture
+def signer_factory(db, faker: Faker):
+ """Abstract factory for Haztrak Signer model"""
+
+ def creat_signer(
+ first_name: Optional[str] = None,
+ middle_initial: Optional[str] = None,
+ last_name: Optional[str] = None,
+ signer_role: Optional[str] = "EP",
+ company_name: Optional[str] = None,
+ rcra_user_id: Optional[str] = None,
+ ) -> Signer:
+ return Signer.objects.create(
+ first_name=first_name or faker.first_name(),
+ middle_initial=middle_initial or faker.pystr(max_chars=1),
+ last_name=last_name or faker.last_name(),
+ signer_role=signer_role,
+ company_name=company_name or faker.company(),
+ rcra_user_id=rcra_user_id or faker.user_name(),
+ )
+
+ return creat_signer
+
class MtnProvider(BaseProvider):
SUFFIXES = ["ELC", "JJK", "FLE"]
@@ -70,55 +172,3 @@ def create_manifest(
)
return create_manifest
-
-
-@pytest.fixture
-def manifest_handler_factory(db, rcra_site_factory, paper_signature_factory):
- """Abstract factory for manifest Handler model"""
-
- def create_manifest_handler(
- rcra_site: Optional[RcraSite] = None,
- paper_signature: Optional[PaperSignature] = None,
- ) -> Handler:
- return Handler.objects.create(
- rcra_site=rcra_site or rcra_site_factory(),
- paper_signature=paper_signature or paper_signature_factory(),
- )
-
- return create_manifest_handler
-
-
-@pytest.fixture
-def manifest_transporter_factory(db, rcra_site_factory, paper_signature_factory):
- """Abstract factory for the manifest transporter model"""
-
- def create_manifest_handler(
- rcra_site: Optional[RcraSite] = None,
- paper_signature: Optional[PaperSignature] = None,
- manifest: Manifest = None,
- order: Optional[int] = 1,
- ) -> Transporter:
- return Transporter.objects.create(
- manifest=manifest,
- order=order,
- rcra_site=rcra_site or rcra_site_factory(),
- paper_signature=paper_signature or paper_signature_factory(),
- )
-
- return create_manifest_handler
-
-
-@pytest.fixture
-def paper_signature_factory(db, faker: Faker):
- """Abstract factory for Paper Signature"""
-
- def create_signature(
- printed_name: Optional[str] = None,
- sign_date: Optional[datetime] = None,
- ) -> PaperSignature:
- return PaperSignature.objects.create(
- printed_name=printed_name or faker.name(),
- sign_date=sign_date or datetime.now(UTC),
- )
-
- return create_signature
diff --git a/server/handler/__init__.py b/server/manifest/tests/models/__init__.py
similarity index 100%
rename from server/handler/__init__.py
rename to server/manifest/tests/models/__init__.py
diff --git a/server/handler/tests/test_handler_models.py b/server/manifest/tests/models/test_handler_models.py
similarity index 98%
rename from server/handler/tests/test_handler_models.py
rename to server/manifest/tests/models/test_handler_models.py
index bd5091b4b..8da2d8900 100644
--- a/server/handler/tests/test_handler_models.py
+++ b/server/manifest/tests/models/test_handler_models.py
@@ -1,6 +1,6 @@
import pytest
-from handler.models import Handler
+from manifest.models import Handler
@pytest.mark.django_db
diff --git a/server/manifest/tests/test_models.py b/server/manifest/tests/models/test_manifest_models.py
similarity index 99%
rename from server/manifest/tests/test_models.py
rename to server/manifest/tests/models/test_manifest_models.py
index 8f5f847c0..44dd5d7d9 100644
--- a/server/manifest/tests/test_models.py
+++ b/server/manifest/tests/models/test_manifest_models.py
@@ -3,10 +3,10 @@
import pytest
from django.core.exceptions import ValidationError
+from rcrasite.models import RcraSiteType
-from handler.serializers import HandlerSerializer
from manifest.models import Manifest, draft_mtn, manifest_factory, validate_mtn
-from rcrasite.models import RcraSiteType
+from manifest.serializers import HandlerSerializer
@pytest.mark.django_db
diff --git a/server/handler/tests/test_signature_models.py b/server/manifest/tests/models/test_signature_models.py
similarity index 94%
rename from server/handler/tests/test_signature_models.py
rename to server/manifest/tests/models/test_signature_models.py
index b8a6859f8..9a293df40 100644
--- a/server/handler/tests/test_signature_models.py
+++ b/server/manifest/tests/models/test_signature_models.py
@@ -3,7 +3,7 @@
import pytest
from django.db import IntegrityError
-from handler.models import PaperSignature
+from manifest.models import PaperSignature
@pytest.mark.django_db
diff --git a/server/handler/migrations/__init__.py b/server/manifest/tests/serializers/__init__.py
similarity index 100%
rename from server/handler/migrations/__init__.py
rename to server/manifest/tests/serializers/__init__.py
diff --git a/server/handler/tests/test_handler_serializer.py b/server/manifest/tests/serializers/test_handler.py
similarity index 94%
rename from server/handler/tests/test_handler_serializer.py
rename to server/manifest/tests/serializers/test_handler.py
index ac388c4e9..ff50af2d5 100644
--- a/server/handler/tests/test_handler_serializer.py
+++ b/server/manifest/tests/serializers/test_handler.py
@@ -1,7 +1,7 @@
import pytest
-from handler.models import Handler, PaperSignature
-from handler.serializers import HandlerSerializer
+from manifest.models import Handler, PaperSignature
+from manifest.serializers import HandlerSerializer
@pytest.mark.django_db
diff --git a/server/manifest/tests/test_serializers.py b/server/manifest/tests/serializers/test_manifest.py
similarity index 100%
rename from server/manifest/tests/test_serializers.py
rename to server/manifest/tests/serializers/test_manifest.py
index 267c93d81..a6149f22c 100644
--- a/server/manifest/tests/test_serializers.py
+++ b/server/manifest/tests/serializers/test_manifest.py
@@ -1,8 +1,8 @@
import pytest
+from wasteline.models import WasteLine
from manifest.models import AdditionalInfo, Manifest
from manifest.serializers import ManifestSerializer
-from wasteline.models import WasteLine
@pytest.fixture
diff --git a/server/handler/tests/test_signature_serializer.py b/server/manifest/tests/serializers/test_signature.py
similarity index 92%
rename from server/handler/tests/test_signature_serializer.py
rename to server/manifest/tests/serializers/test_signature.py
index 3813c0c32..2e6c83b81 100644
--- a/server/handler/tests/test_signature_serializer.py
+++ b/server/manifest/tests/serializers/test_signature.py
@@ -1,7 +1,7 @@
import pytest
-from handler.models import Signer
-from handler.serializers import ESignatureSerializer
+from manifest.models import Signer
+from manifest.serializers import ESignatureSerializer
@pytest.fixture
diff --git a/server/handler/tests/__init__.py b/server/manifest/tests/services/__init__.py
similarity index 100%
rename from server/handler/tests/__init__.py
rename to server/manifest/tests/services/__init__.py
diff --git a/server/manifest/tests/test_emanifest_service.py b/server/manifest/tests/services/test_emanifest.py
similarity index 100%
rename from server/manifest/tests/test_emanifest_service.py
rename to server/manifest/tests/services/test_emanifest.py
index e22bc99a0..b9670d943 100644
--- a/server/manifest/tests/test_emanifest_service.py
+++ b/server/manifest/tests/services/test_emanifest.py
@@ -1,8 +1,8 @@
import pytest
import pytest_mock
+from core.services import RcraClient, get_rcra_client
from rest_framework import status
-from core.services import RcraClient, get_rcra_client
from manifest.services import EManifest
diff --git a/server/handler/tests/test_handler_services.py b/server/manifest/tests/services/test_handler.py
similarity index 99%
rename from server/handler/tests/test_handler_services.py
rename to server/manifest/tests/services/test_handler.py
index 7efa3a56a..e136008b4 100644
--- a/server/handler/tests/test_handler_services.py
+++ b/server/manifest/tests/services/test_handler.py
@@ -1,5 +1,4 @@
import pytest
-
from core.services import RcraClient
from rcrasite.models import RcraSite
from rcrasite.services import RcraSiteService
diff --git a/server/manifest/tests/test_manifest_services.py b/server/manifest/tests/services/test_manifest.py
similarity index 99%
rename from server/manifest/tests/test_manifest_services.py
rename to server/manifest/tests/services/test_manifest.py
index 8438451bc..68f9370d6 100644
--- a/server/manifest/tests/test_manifest_services.py
+++ b/server/manifest/tests/services/test_manifest.py
@@ -4,6 +4,7 @@
class TestGetManifestService:
+ # ToDo: fix transaction related to this test
def test_returns_manifests_from_all_user_sites_by_default(
self,
manifest_factory,
diff --git a/server/manifest/tests/test_search_emanifest.py b/server/manifest/tests/services/test_search_emanifest.py
similarity index 100%
rename from server/manifest/tests/test_search_emanifest.py
rename to server/manifest/tests/services/test_search_emanifest.py
index b13f97bb3..59fb9c914 100644
--- a/server/manifest/tests/test_search_emanifest.py
+++ b/server/manifest/tests/services/test_search_emanifest.py
@@ -2,8 +2,8 @@
from datetime import UTC, datetime
import pytest
-
from core.services import RcraClient
+
from manifest.services.emanifest_search import EmanifestSearch
diff --git a/server/manifest/views.py b/server/manifest/views.py
index 423c6fdeb..c3df83519 100644
--- a/server/manifest/views.py
+++ b/server/manifest/views.py
@@ -1,15 +1,15 @@
import logging
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
+from org.services import sync_site_manifest_with_rcrainfo
from rest_framework import mixins, serializers, status, viewsets
from rest_framework.generics import GenericAPIView, ListAPIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
-from handler.serializers import QuickerSignSerializer
from manifest.models import Manifest
-from manifest.serializers import ManifestSerializer, MtnSerializer
+from manifest.serializers import ManifestSerializer, MtnSerializer, QuickerSignSerializer
from manifest.services import (
EManifest,
TaskResponse,
@@ -18,7 +18,6 @@
save_emanifest,
update_manifest,
)
-from org.services import sync_site_manifest_with_rcrainfo
logger = logging.getLogger(__name__)
diff --git a/server/org/fixtures/org_permissions.yaml b/server/org/fixtures/org_dev.yaml
similarity index 67%
rename from server/org/fixtures/org_permissions.yaml
rename to server/org/fixtures/org_dev.yaml
index 822e77a7c..2ab89481f 100644
--- a/server/org/fixtures/org_permissions.yaml
+++ b/server/org/fixtures/org_dev.yaml
@@ -1,3 +1,26 @@
+- model: org.org
+ pk: efb9e104-7f61-4365-a9af-9d7b55c854c4
+ fields:
+ name: Generators Org LLC
+ admin: 8062d496-15f1-485d-961c-a8e5fa118dde
+ slug: generators-org-llc
+- model: org.site
+ pk: 1
+ fields:
+ name: VA TEST GEN 2021
+ rcra_site: 1
+ last_rcrainfo_manifest_sync: null
+ org: efb9e104-7f61-4365-a9af-9d7b55c854c4
+- model: org.siteuserobjectpermission
+ pk: 1
+ fields:
+ permission:
+ - view_site
+ - org
+ - site
+ user:
+ - testuser1
+ content_object: 1
- model: auth.group
fields:
name: Org admin
diff --git a/server/profile/fixtures/profile_dev.yaml b/server/profile/fixtures/profile_dev.yaml
new file mode 100644
index 000000000..8dd01c7d0
--- /dev/null
+++ b/server/profile/fixtures/profile_dev.yaml
@@ -0,0 +1,44 @@
+- model: profile.rcrainfoprofile
+ pk: d74f904a-7843-4a60-862c-3b94b6051359
+ fields:
+ rcra_username: dpgraham4401
+ phone_number: null
+ email: orgadmin@generator.com
+- model: profile.rcrainfoprofile
+ pk: 1fd27bec-8743-4eb3-a44c-fd063ea62021
+ fields:
+ rcra_username: ""
+ phone_number: null
+ email: superadmin@gmail.com
+- model: profile.rcrainfoprofile
+ pk: 192c73f4-24f1-4f21-8239-dee2da43c547
+ fields:
+ rcra_username: emanifestpyuser1
+ phone_number: null
+ email: testuser1@haztrak.net
+- model: profile.profile
+ pk: c65dbee9-b6bf-400e-93e0-90a749cc2939
+ fields:
+ user: 8062d496-15f1-485d-961c-a8e5fa118dde
+ rcrainfo_profile: d74f904a-7843-4a60-862c-3b94b6051359
+- model: profile.profile
+ pk: 186642a9-7b5f-4bcb-b328-0fdf8b43f191
+ fields:
+ user: a0ba4966-aa53-44c8-be1a-0a0d2d6b6acd
+ rcrainfo_profile: 1fd27bec-8743-4eb3-a44c-fd063ea62021
+- model: profile.profile
+ pk: 87e355dd-1898-4a0a-81c3-1e9ac8473143
+ fields:
+ user: 4ac96f68-42cf-47ea-bffb-f24d423dbc35
+ rcrainfo_profile: 192c73f4-24f1-4f21-8239-dee2da43c547
+- model: profile.rcrainfositeaccess
+ pk: 1
+ fields:
+ site: 1
+ profile: 192c73f4-24f1-4f21-8239-dee2da43c547
+ site_manager: true
+ annual_report: Certifier
+ biennial_report: Certifier
+ e_manifest: Certifier
+ my_rcra_id: Certifier
+ wiets: Certifier
diff --git a/server/rcrasite/fixtures/rcrasite_dev.yaml b/server/rcrasite/fixtures/rcrasite_dev.yaml
new file mode 100644
index 000000000..88b0b323b
--- /dev/null
+++ b/server/rcrasite/fixtures/rcrasite_dev.yaml
@@ -0,0 +1,93 @@
+- model: rcrasite.address
+ pk: 1
+ fields:
+ street_number: null
+ address1: 123 VA TEST GEN 2021 WAY
+ address2: null
+ city: ARLINGTON
+ state: VA
+ country: US
+ zip: "22202"
+- model: manifest.manifestphone
+ pk: 1
+ fields:
+ number: 321-321-3214
+ extension: null
+- model: rcrasite.rcraphone
+ pk: 1
+ fields:
+ number: 321-321-3214
+ extension: null
+- model: rcrasite.contact
+ pk: 1
+ fields:
+ first_name: David
+ middle_initial: P
+ last_name: Graham
+ phone: 1
+ email: testuser1@haztrak.net
+ company_name: haztrak
+- model: rcrasite.rcrasite
+ pk: 1
+ fields:
+ site_type: Generator
+ epa_id: VATESTGEN001
+ name: VA TEST GEN 2021
+ site_address: 1
+ mail_address: 1
+ modified: false
+ registered: false
+ contact: 1
+ emergency_phone: null
+ gis_primary: false
+ can_esign: true
+ limited_esign: true
+ registered_emanifest_user: true
+- model: rcrasite.rcrasite
+ pk: 2
+ fields:
+ site_type: Transporter
+ epa_id: MOCKTRANS001
+ name: Mock Transporter 01
+ site_address: 1
+ mail_address: 1
+ modified: false
+ registered: false
+ contact: 1
+ emergency_phone: null
+ gis_primary: false
+ can_esign: true
+ limited_esign: true
+ registered_emanifest_user: true
+- model: rcrasite.rcrasite
+ pk: 3
+ fields:
+ site_type: Transporter
+ epa_id: MOCKTRANS002
+ name: Mock Transporter 02
+ site_address: 1
+ mail_address: 1
+ modified: false
+ registered: false
+ contact: 1
+ emergency_phone: null
+ gis_primary: false
+ can_esign: true
+ limited_esign: true
+ registered_emanifest_user: true
+- model: rcrasite.rcrasite
+ pk: 4
+ fields:
+ site_type: Tsdf
+ epa_id: MOCKTSDFS001
+ name: Mock haztrak TSDF 01
+ site_address: 1
+ mail_address: 1
+ modified: false
+ registered: false
+ contact: 1
+ emergency_phone: null
+ gis_primary: false
+ can_esign: true
+ limited_esign: true
+ registered_emanifest_user: true
diff --git a/server/wasteline/migrations/0001_initial.py b/server/wasteline/migrations/0001_initial.py
index 182020625..1f77d1c39 100644
--- a/server/wasteline/migrations/0001_initial.py
+++ b/server/wasteline/migrations/0001_initial.py
@@ -1,66 +1,182 @@
-# Generated by Django 4.2.10 on 2024-02-21 22:17
+# Generated by Django 5.0.8 on 2024-08-22 16:38
-from django.db import migrations, models
import django.db.models.deletion
+from django.db import migrations, models
class Migration(migrations.Migration):
-
initial = True
dependencies = [
- ('manifest', '0001_initial'),
+ ("manifest", "0001_initial"),
]
operations = [
migrations.CreateModel(
- name='DotLookup',
+ name="DotLookup",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('value', models.CharField(max_length=255)),
- ('value_type', models.CharField(choices=[('ID', 'Id'), ('GROUP', 'Group'), ('NAME', 'Name'), ('CLASS', 'Class')], max_length=5)),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("value", models.CharField(max_length=255)),
+ (
+ "value_type",
+ models.CharField(
+ choices=[
+ ("ID", "Id"),
+ ("GROUP", "Group"),
+ ("NAME", "Name"),
+ ("CLASS", "Class"),
+ ],
+ max_length=5,
+ ),
+ ),
],
options={
- 'verbose_name': 'DOT lookup',
- 'verbose_name_plural': 'DOT lookups',
- 'ordering': ['value_type', 'value'],
+ "verbose_name": "DOT lookup",
+ "verbose_name_plural": "DOT lookups",
+ "ordering": ["value_type", "value"],
},
),
migrations.CreateModel(
- name='WasteCode',
+ name="WasteCode",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('code', models.CharField(max_length=6, unique=True)),
- ('description', models.TextField(blank=True, null=True)),
- ('code_type', models.CharField(choices=[('ST', 'State'), ('FD', 'Federal')], max_length=2)),
- ('state_id', models.CharField(blank=True, choices=[('AK', 'Alaska'), ('AL', 'Alabama'), ('AP', 'Armed Forces Pacific'), ('AR', 'Arkansas'), ('AZ', 'Arizona'), ('CA', 'California'), ('CO', 'Colorado'), ('CT', 'Connecticut'), ('DC', 'District of Columbia'), ('DE', 'Delaware'), ('FL', 'Florida'), ('GA', 'Georgia'), ('GU', 'Guam'), ('HI', 'Hawaii'), ('IA', 'Iowa'), ('ID', 'Idaho'), ('IL', 'Illinois'), ('IN', 'Indiana'), ('KS', 'Kansas'), ('KY', 'Kentucky'), ('LA', 'Louisiana'), ('MA', 'Massachusetts'), ('MD', 'Maryland'), ('ME', 'Maine'), ('MI', 'Michigan'), ('MN', 'Minnesota'), ('MO', 'Missouri'), ('MS', 'Mississippi'), ('MT', 'Montana'), ('NC', 'North Carolina'), ('ND', 'North Dakota'), ('NE', 'Nebraska'), ('NH', 'New Hampshire'), ('NJ', 'New Jersey'), ('NM', 'New Mexico'), ('NV', 'Nevada'), ('NY', 'New York'), ('OH', 'Ohio'), ('OK', 'Oklahoma'), ('OR', 'Oregon'), ('PA', 'Pennsylvania'), ('PR', 'Puerto Rico'), ('RI', 'Rhode Island'), ('SC', 'South Carolina'), ('SD', 'South Dakota'), ('TN', 'Tennessee'), ('TX', 'Texas'), ('UT', 'Utah'), ('VA', 'Virginia'), ('VI', 'Virgin Islands'), ('VT', 'Vermont'), ('WA', 'Washington'), ('WI', 'Wisconsin'), ('WV', 'West Virginia'), ('WY', 'Wyoming')], max_length=3, null=True)),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("code", models.CharField(max_length=6, unique=True)),
+ ("description", models.TextField(blank=True, null=True)),
+ (
+ "code_type",
+ models.CharField(choices=[("ST", "State"), ("FD", "Federal")], max_length=2),
+ ),
+ (
+ "state_id",
+ models.CharField(
+ blank=True,
+ choices=[
+ ("AK", "Alaska"),
+ ("AL", "Alabama"),
+ ("AP", "Armed Forces Pacific"),
+ ("AR", "Arkansas"),
+ ("AZ", "Arizona"),
+ ("CA", "California"),
+ ("CO", "Colorado"),
+ ("CT", "Connecticut"),
+ ("DC", "District of Columbia"),
+ ("DE", "Delaware"),
+ ("FL", "Florida"),
+ ("GA", "Georgia"),
+ ("GU", "Guam"),
+ ("HI", "Hawaii"),
+ ("IA", "Iowa"),
+ ("ID", "Idaho"),
+ ("IL", "Illinois"),
+ ("IN", "Indiana"),
+ ("KS", "Kansas"),
+ ("KY", "Kentucky"),
+ ("LA", "Louisiana"),
+ ("MA", "Massachusetts"),
+ ("MD", "Maryland"),
+ ("ME", "Maine"),
+ ("MI", "Michigan"),
+ ("MN", "Minnesota"),
+ ("MO", "Missouri"),
+ ("MS", "Mississippi"),
+ ("MT", "Montana"),
+ ("NC", "North Carolina"),
+ ("ND", "North Dakota"),
+ ("NE", "Nebraska"),
+ ("NH", "New Hampshire"),
+ ("NJ", "New Jersey"),
+ ("NM", "New Mexico"),
+ ("NV", "Nevada"),
+ ("NY", "New York"),
+ ("OH", "Ohio"),
+ ("OK", "Oklahoma"),
+ ("OR", "Oregon"),
+ ("PA", "Pennsylvania"),
+ ("PR", "Puerto Rico"),
+ ("RI", "Rhode Island"),
+ ("SC", "South Carolina"),
+ ("SD", "South Dakota"),
+ ("TN", "Tennessee"),
+ ("TX", "Texas"),
+ ("UT", "Utah"),
+ ("VA", "Virginia"),
+ ("VI", "Virgin Islands"),
+ ("VT", "Vermont"),
+ ("WA", "Washington"),
+ ("WI", "Wisconsin"),
+ ("WV", "West Virginia"),
+ ("WY", "Wyoming"),
+ ],
+ max_length=3,
+ null=True,
+ ),
+ ),
],
options={
- 'ordering': ['code'],
+ "ordering": ["code"],
},
),
migrations.CreateModel(
- name='WasteLine',
+ name="WasteLine",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('line_number', models.PositiveIntegerField(verbose_name='waste line number')),
- ('dot_hazardous', models.BooleanField(verbose_name='DOT hazardous')),
- ('dot_info', models.JSONField(blank=True, null=True, verbose_name='DOT information')),
- ('quantity', models.JSONField(blank=True, null=True)),
- ('hazardous_waste', models.JSONField(blank=True, null=True)),
- ('br', models.BooleanField(verbose_name='BR info provided')),
- ('br_info', models.JSONField(blank=True, null=True, verbose_name='BR information')),
- ('management_method', models.JSONField(blank=True, null=True, verbose_name='management method code')),
- ('pcb', models.BooleanField(verbose_name='contains PCBs')),
- ('pcb_infos', models.JSONField(blank=True, null=True, verbose_name='PCB information')),
- ('discrepancy_info', models.JSONField(blank=True, null=True, verbose_name='discrepancy-residue information')),
- ('epa_waste', models.BooleanField(verbose_name='EPA waste')),
- ('additional_info', models.JSONField(blank=True, null=True)),
- ('manifest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wastes', to='manifest.manifest')),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("line_number", models.PositiveIntegerField(verbose_name="waste line number")),
+ ("dot_hazardous", models.BooleanField(verbose_name="DOT hazardous")),
+ (
+ "dot_info",
+ models.JSONField(blank=True, null=True, verbose_name="DOT information"),
+ ),
+ ("quantity", models.JSONField(blank=True, null=True)),
+ ("hazardous_waste", models.JSONField(blank=True, null=True)),
+ ("br", models.BooleanField(verbose_name="BR info provided")),
+ (
+ "br_info",
+ models.JSONField(blank=True, null=True, verbose_name="BR information"),
+ ),
+ (
+ "management_method",
+ models.JSONField(blank=True, null=True, verbose_name="management method code"),
+ ),
+ ("pcb", models.BooleanField(verbose_name="contains PCBs")),
+ (
+ "pcb_infos",
+ models.JSONField(blank=True, null=True, verbose_name="PCB information"),
+ ),
+ (
+ "discrepancy_info",
+ models.JSONField(
+ blank=True, null=True, verbose_name="discrepancy-residue information"
+ ),
+ ),
+ ("epa_waste", models.BooleanField(verbose_name="EPA waste")),
+ ("additional_info", models.JSONField(blank=True, null=True)),
+ (
+ "manifest",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="wastes",
+ to="manifest.manifest",
+ ),
+ ),
],
options={
- 'ordering': ['manifest__mtn', 'line_number'],
- 'unique_together': {('manifest', 'line_number')},
+ "ordering": ["manifest__mtn", "line_number"],
+ "unique_together": {("manifest", "line_number")},
},
),
]