Skip to content

Commit

Permalink
update Manifest model manager save method to update/create/remove one…
Browse files Browse the repository at this point in the history
…-to-many models (instead of just create) such as waste lines and transporters
  • Loading branch information
dpgraham4401 committed Dec 15, 2023
1 parent c95c9a9 commit 17d9150
Show file tree
Hide file tree
Showing 26 changed files with 236 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { Cell, Legend, Pie, PieChart, ResponsiveContainer } from 'recharts';
import { useNavigate } from 'react-router-dom';

const data = [
{ name: 'Pending', value: 40, searchParam: 'pending' },
{ name: 'Scheduled', value: 39, searchParam: 'scheduled' },
{ name: 'In Transit', value: 33, searchParam: 'intransit' },
{ name: 'Ready for TSDF Signature', value: 21, searchParam: 'readyforsignature' },
];

const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];

export function ManifestStatusPieChart() {
const navigate = useNavigate();
return (
<ResponsiveContainer minWidth={100} minHeight={300} height={'10%'}>
<PieChart width={400} height={400}>
<Legend verticalAlign="bottom" height={36} />
<Pie
data={data}
cx="50%"
cy="50%"
label={true}
labelLine={true}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{data.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={COLORS[index % COLORS.length]}
onClick={() => {
navigate({ pathname: './manifest', search: `?status=${entry.searchParam}` });
}}
/>
);
})}
</Pie>
</PieChart>
</ResponsiveContainer>
);
}
File renamed without changes.

This file was deleted.

25 changes: 23 additions & 2 deletions client/src/components/Manifest/ManifestForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
useAppSelector,
useCreateManifestMutation,
useSaveEManifestMutation,
useUpdateManifestMutation,
} from 'store';
import { ContactForm, PhoneForm } from './Contact';
import { AddHandler, GeneratorForm, Handler } from './Handler';
Expand Down Expand Up @@ -107,16 +108,21 @@ export function ManifestForm({
saveEmanifest,
{ data: eManifestResult, error: eManifestError, isLoading: eManifestIsLoading },
] = useSaveEManifestMutation();
const [updateManifest, { data: updateResults, error: updateError, isLoading: updateIsLoading }] =
useUpdateManifestMutation();

// React-Hook-Form component state and methods
const manifestForm = useForm<Manifest>({
values: values,
resolver: zodResolver(manifestSchema),
});
const {
watch,
formState: { errors },
} = manifestForm;

console.log(watch('designatedFacility'));

useEffect(() => {
if (createData) {
if ('manifestTrackingNumber' in createData) {
Expand All @@ -132,6 +138,22 @@ export function ManifestForm({
}
}, [createData, createIsLoading, createError]);

useEffect(() => {
if (updateResults) {
if ('manifestTrackingNumber' in updateResults) {
navigate(`/manifest/${updateResults.manifestTrackingNumber}/view`);
}
}
if (updateIsLoading) {
setShowSpinner(true);
}
if (updateError) {
console.error(updateError);
toast.error('Error Updating manifest');
setShowSpinner(false);
}
}, [updateResults, updateError, updateIsLoading]);

useEffect(() => {
if (eManifestResult) {
setTaskId(eManifestResult.taskId);
Expand All @@ -142,7 +164,7 @@ export function ManifestForm({
const onSubmit: SubmitHandler<Manifest> = (data: Manifest) => {
if (data.status === 'NotAssigned') {
if (data.manifestTrackingNumber?.endsWith('DFT')) {
console.log('updating draft manifest');
updateManifest({ mtn: data.manifestTrackingNumber, manifest: data });
} else {
createManifest(data);
}
Expand Down Expand Up @@ -572,7 +594,6 @@ export function ManifestForm({
{tsdf ? (
<>
<RcraSiteDetails handler={tsdf} />
<PhoneForm handlerType={'designatedFacility'} />
<div className="d-flex justify-content-between">
{/* Button to bring up the Quicker Sign modal*/}
<Col className="text-end">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function SyncManifestBtn({

return (
<RcraApiUserBtn
variant="primary"
variant="secondary"
disabled={disabled || !siteId || inProgress}
onClick={() => {
if (siteId) syncSiteManifest(siteId);
Expand Down
2 changes: 1 addition & 1 deletion client/src/features/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
GeneratorStatusAreaChart,
ManifestCountBarChart,
ManifestStatusPieChart,
} from 'components/Dash';
} from 'components/Charts';

/** Dashboard page for logged-in user*/
export function Dashboard(): ReactElement {
Expand Down
10 changes: 5 additions & 5 deletions client/src/store/haztrakApiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ export const haztrakApi = createApi({
data,
}),
}),
updateManifest: build.mutation<Manifest, Manifest>({
query: (data) => ({
url: 'rcra/manifest',
method: 'PATCH',
data,
updateManifest: build.mutation<Manifest, { mtn: string; manifest: Manifest }>({
query: ({ mtn, manifest }) => ({
url: `rcra/manifest/${mtn}`,
method: 'PUT',
data: manifest,
}),
}),
saveEManifest: build.mutation<TaskResponse, Manifest>({
Expand Down
1 change: 1 addition & 0 deletions client/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const {
useSaveEManifestMutation,
useSyncEManifestMutation,
useSignEManifestMutation,
useUpdateManifestMutation,
} = haztrakApi;

// Authentication Slice
Expand Down
10 changes: 6 additions & 4 deletions server/apps/sites/models/site_models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import uuid
from typing import Union
from typing import Optional, Union

from django.core.exceptions import ValidationError
from django.core.validators import MinLengthValidator
Expand Down Expand Up @@ -78,7 +78,7 @@ def __init__(self):
self.handler_data = None
super().__init__()

def save(self, **handler_data):
def save(self, instance: Optional["RcraSite"], **handler_data) -> "RcraSite":
"""
Create an RcraSite and its related fields
Expand All @@ -97,13 +97,15 @@ def save(self, **handler_data):
emergency_phone = self.get_emergency_phone()
site_address = self.get_address("site_address")
mail_address = self.get_address("mail_address")
return super().save(
rcra_site, created = self.model.objects.update_or_create(
epa_id=self.handler_data.pop("epa_id"),
site_address=site_address,
mail_address=mail_address,
emergency_phone=emergency_phone,
contact=new_contact,
**self.handler_data,
defaults=self.handler_data,
)
return rcra_site
except KeyError as exc:
logger.warning(f"error while creating {self.model.__class__.__name__}{exc}")

Expand Down
4 changes: 2 additions & 2 deletions server/apps/sites/serializers/site_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ class RcraSiteSerializer(SitesBaseSerializer):
)

def update(self, instance, validated_data):
return self.Meta.model.objects.save(**validated_data)
return self.Meta.model.objects.save(instance, **validated_data)

def create(self, validated_data):
return self.Meta.model.objects.save(**validated_data)
return self.Meta.model.objects.save(None, **validated_data)

class Meta:
model = RcraSite
Expand Down
2 changes: 2 additions & 0 deletions server/apps/sites/services/rcra_site_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class HandlerSearchResults(TypedDict):
def query_rcra_sites(
*, epa_id: Optional[str] = None, name: Optional[str] = None, site_type: Optional[str] = None
) -> QuerySet[RcraSite]:
if site_type == "designatedFacility":
site_type = "Tsdf"
"""Query RcraSites from our Database"""
queryset: QuerySet[RcraSite] = RcraSite.objects.all()
if epa_id is not None:
Expand Down
5 changes: 2 additions & 3 deletions server/apps/sites/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ def get(self, request, *args, **kwargs):
),
)
class SearchRcraSiteView(APIView):
"""
Search for locally saved hazardous waste sites ("Generators", "Transporters", "Tsdf's")
"""
"""Search for locally saved hazardous waste sites ("Generators", "Transporters", "Tsdf's")"""

queryset = RcraSite.objects.all()
serializer_class = RcraSiteSerializer
Expand All @@ -110,6 +108,7 @@ class RcraSiteSearchSerializer(serializers.Serializer):
"Transporter",
"Tsdf",
"tsdf",
"designatedFacility",
"Generator",
"generator",
],
Expand Down
19 changes: 19 additions & 0 deletions server/apps/trak/migrations/0008_handler_emergency_phone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.7 on 2023-12-13 20:56

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('trak', '0007_alter_wasteline_unique_together'),
]

operations = [
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='trak.manifestphone'),
),
]
50 changes: 44 additions & 6 deletions server/apps/trak/models/handler_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from apps.sites.models import RcraSite

from . import ManifestPhone
from .base_models import TrakBaseManager, TrakBaseModel
from .signature_models import ESignature, PaperSignature

Expand All @@ -18,14 +19,19 @@ class HandlerManager(TrakBaseManager):
def save(self, instance: Optional["Handler"], **handler_data) -> "Handler":
paper_signature = handler_data.pop("paper_signature", None)
e_signatures = handler_data.pop("e_signatures", [])
if paper_signature:
print("handler data", handler_data)
if paper_signature is not None:
paper_signature = PaperSignature.objects.create(**paper_signature)
if handler_data.get("emergency_phone", None) is not None:
handler_data["emergency_phone"] = ManifestPhone.objects.create(
**handler_data.pop("emergency_phone")
)
try:
if RcraSite.objects.filter(epa_id=handler_data["rcra_site"]["epa_id"]).exists():
rcra_site = RcraSite.objects.get(epa_id=handler_data["rcra_site"]["epa_id"])
handler_data.pop("rcra_site")
else:
rcra_site = RcraSite.objects.save(**handler_data.pop("rcra_site"))
rcra_site = RcraSite.objects.save(None, **handler_data.pop("rcra_site"))
manifest_handler = self.model.objects.create(
rcra_site=rcra_site,
paper_signature=paper_signature,
Expand All @@ -39,9 +45,9 @@ def save(self, instance: Optional["Handler"], **handler_data) -> "Handler":
logger.debug(f"ESignature created {e_sig}")
return manifest_handler
except KeyError as exc:
logger.warning(f"KeyError while creating Manifest rcra_site {exc}")
raise ValidationError(f"KeyError while creating rcra_site {exc}")
except ValidationError as exc:
logger.warning(f"ValidationError while creating Manifest rcra_site {exc}")
logger.warning(f"ValidationError while creating rcra_site {exc}")
raise exc


Expand All @@ -58,6 +64,13 @@ class Meta:
on_delete=models.CASCADE,
help_text="Hazardous waste rcra_site associated with the manifest",
)
emergency_phone = models.ForeignKey(
"trak.ManifestPhone",
on_delete=models.PROTECT,
null=True,
blank=True,
help_text="Emergency phone number for the hazardous waste rcra_site",
)
paper_signature = models.OneToOneField(
"PaperSignature",
on_delete=models.CASCADE,
Expand All @@ -82,9 +95,34 @@ def __str__(self):
class TransporterManager(HandlerManager):
"""Inter-model related functionality for Transporter Model"""

def save(self, **transporter_data: Dict) -> "Transporter":
def save(self, instance: Optional["Transporter"], **data: Dict) -> "Transporter":
"""Create a Transporter from a manifest instance and rcra_site dict"""
return super().save(None, **transporter_data)
e_signatures = data.pop("e_signatures", [])
if data.get("paper_signature", None) is not None:
data["paper_signature"] = PaperSignature.objects.create(**data.pop("paper_signature"))
try:
if RcraSite.objects.filter(epa_id=data["rcra_site"]["epa_id"]).exists():
rcra_site = RcraSite.objects.get(epa_id=data["rcra_site"]["epa_id"])
data.pop("rcra_site")
else:
rcra_site = RcraSite.objects.save(None, **data.pop("rcra_site"))
transporter, created = self.model.objects.update_or_create(
manifest=data.pop("manifest"),
order=data.pop("order"),
rcra_site__epa_id=rcra_site.epa_id,
rcra_site=rcra_site,
defaults=data,
)
logger.debug(f"Handler created {transporter}")
for e_signature_data in e_signatures:
e_sig = ESignature.objects.save(manifest_handler=transporter, **e_signature_data)
logger.debug(f"ESignature created {e_sig}")
return transporter
except KeyError as exc:
logger.warning(f"KeyError while creating rcra_site {exc}")
except ValidationError as exc:
logger.warning(f"ValidationError while creating rcra_site {exc}")
raise exc


class Transporter(Handler):
Expand Down
Loading

0 comments on commit 17d9150

Please sign in to comment.