Skip to content

Commit

Permalink
377 manifest handler signed indicator (#402)
Browse files Browse the repository at this point in the history
* `PaperSignature` TypeScript definition

* `TransporterSerializer` subclass `ManifestHandlerSerializer`

* "signed" icon to Transporter table

* new `TrakBaseModel` abstract base class for all `apps.trak.models` classes

* `signed` property to ManifestHandler model

* `ManifestHandler.signed` property to serializers and front end indicators in the manifest view (Generators, transports, and TSDF)
  • Loading branch information
dpgraham4401 authored Mar 15, 2023
1 parent 5661931 commit 52e2ca1
Show file tree
Hide file tree
Showing 25 changed files with 175 additions and 161 deletions.
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "haztrak",
"version": "0.1.0",
"version": "0.3.0",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.2.1",
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/HandlerDetails/HandlerDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function HandlerDetails({ handler }: HandlerDetailsProps) {
<h4>{handler.name}</h4>
</Col>
<Col className="d-flex justify-content-end">
{handler.electronicSignaturesInfo && (
{handler.signed && (
<p className="text-right">
signed <FontAwesomeIcon icon={faSignature} className="text-success" size="xl" />
</p>
Expand Down
33 changes: 20 additions & 13 deletions client/src/components/ManifestForm/ManifestForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { WasteLineTable } from 'components/ManifestForm/WasteLine/WasteLineTable
import React, { useEffect, useState } from 'react';
import { Button, Col, Row } from 'react-bootstrap';
import { FormProvider, SubmitHandler, useFieldArray, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';
import htApi from 'services';
import { addMsg, useAppDispatch } from 'store';
import { Manifest } from 'types/Manifest';
Expand All @@ -21,19 +22,22 @@ import AddWasteLine from './WasteLine';
interface ManifestFormProps {
readOnly?: boolean;
manifestData?: Manifest;
siteId?: string;
mtn?: string;
}

/**
* Returns form for the uniform hazardous waste manifest. It also acts
* as the current method of viewing manifest when the form is read only.
* @constructor
*/
function ManifestForm({ readOnly, manifestData }: ManifestFormProps) {
function ManifestForm({ readOnly, manifestData, siteId, mtn }: ManifestFormProps) {
// Top level ManifestForm methods and objects
const manifestMethods = useForm<Manifest>({ values: manifestData });
// On load, focus the generator EPA ID.
useEffect(() => manifestMethods.setFocus('generator.epaSiteId'), []);
const dispatch = useAppDispatch();
const navigate = useNavigate();
const onSubmit: SubmitHandler<Manifest> = (data: Manifest) => {
// ToDo: on submit, validate the user input
htApi
Expand Down Expand Up @@ -63,10 +67,8 @@ function ManifestForm({ readOnly, manifestData }: ManifestFormProps) {
);
});
};

// Generator controls
const generator: ManifestHandler = manifestMethods.getValues('generator');
console.log(generator);

// Transporter controls
const [transFormShow, setTransFormShow] = useState<boolean>(false);
Expand Down Expand Up @@ -95,9 +97,11 @@ function ManifestForm({ readOnly, manifestData }: ManifestFormProps) {
<>
<FormProvider {...manifestMethods}>
<HtForm onSubmit={manifestMethods.handleSubmit(onSubmit)}>
<h2 className="fw-bold">{`${
manifestData?.manifestTrackingNumber || 'Draft'
} Manifest`}</h2>
<div className="d-flex justify-content-between">
<h2 className="fw-bold">{`${
manifestData?.manifestTrackingNumber || 'Draft'
} Manifest`}</h2>
</div>
<HtCard id="general-form-card">
<HtCard.Header title="General info" />
<HtCard.Body>
Expand Down Expand Up @@ -293,13 +297,16 @@ function ManifestForm({ readOnly, manifestData }: ManifestFormProps) {
</HtCard.Body>
</HtCard>
<div className="mx-1 d-flex flex-row-reverse">
{readOnly ? (
<></>
) : (
<Button variant="success" type="submit">
Save Manifest
</Button>
)}
<Button className="mx-2" variant="success" type="submit" disabled={readOnly}>
Save Manifest
</Button>
<Button
variant="primary"
disabled={!readOnly}
onClick={() => navigate(`/site/${siteId}/manifest/${mtn}/edit`)}
>
Edit Manifest
</Button>
</div>
</HtForm>
<AddTransporter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { faCircleCheck, faCircleXmark } from '@fortawesome/free-solid-svg-icons';
import React from 'react';
import { Table } from 'react-bootstrap';
import { Manifest } from 'types/Manifest';
import { Transporter } from 'types/Handler';
import { TransporterRowActions } from './TransporterRowActions';
import { UseFieldArrayReturn } from 'react-hook-form';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

interface TransporterTableProps {
transporters?: Array<Transporter>;
Expand All @@ -28,8 +30,8 @@ function TransporterTable({ transporters, arrayFieldMethods, readOnly }: Transpo
<th>#</th>
<th>EPA ID</th>
<th>Name</th>
<th>e-Signer?</th>
<th>Edit</th>
<th className="text-center">Signed</th>
{readOnly ? <></> : <th className="text-center">Edit</th>}
</tr>
</thead>
<tbody>
Expand All @@ -39,7 +41,13 @@ function TransporterTable({ transporters, arrayFieldMethods, readOnly }: Transpo
<td>{transporter.order}</td>
<td>{transporter.epaSiteId}</td>
<td>{transporter.name}</td>
<td>{transporter.canEsign ? 'yes' : 'no'}</td>
<td className="text-center">
{transporter.signed ? (
<FontAwesomeIcon icon={faCircleCheck} size="lg" className="text-success" />
) : (
<FontAwesomeIcon icon={faCircleXmark} size="lg" className="text-danger" />
)}
</td>
<td>
{readOnly ? (
<></>
Expand Down
4 changes: 2 additions & 2 deletions client/src/features/manifest/ManifestDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useParams } from 'react-router-dom';
import { Manifest } from 'types/Manifest';

function ManifestDetails() {
const { mtn, action } = useParams();
const { mtn, action, siteId } = useParams();
useTitle(`${mtn}`);
const [manifestData, loading, error] = useHtAPI<Manifest>(`trak/manifest/${mtn}`);

Expand All @@ -21,7 +21,7 @@ function ManifestDetails() {
return loading ? (
<HtSpinner />
) : manifestData ? (
<ManifestForm manifestData={manifestData} readOnly={readOnly} />
<ManifestForm manifestData={manifestData} readOnly={readOnly} siteId={siteId} mtn={mtn} />
) : (
<></>
);
Expand Down
14 changes: 13 additions & 1 deletion client/src/types/Handler/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,25 @@ export interface Handler {
gisPrimary?: boolean;
}

/**
* The Signature that appears on paper versions of the manifest
*/
export interface PaperSignature {
printedName: string;
signatureDate: string;
}

/**
* The ManifestHandler extends to Handler schema and adds manifest specific data
*/
export interface ManifestHandler extends Handler {
// paperSignatureInfo: PaperSignature
paperSignatureInfo?: PaperSignature;
electronicSignaturesInfo?: Array<ElectronicSignature>;
siteType?: 'Generator' | 'Broken' | 'Transporter' | 'Tsdf';
/**
* Property on by back end to signify whether the handler has signed
*/
signed?: boolean;
}

/**
Expand Down
10 changes: 3 additions & 7 deletions server/apps/trak/models/address_model.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from django.db import models
from django.utils.translation import gettext_lazy as _

from apps.trak.models.base_model import TrakBaseModel

class Address(models.Model):

class Address(TrakBaseModel):
"""
Used to capture RCRAInfo address instances (mail, site).
"""
Expand Down Expand Up @@ -122,9 +124,3 @@ def __str__(self):
if self.street_number:
return f"{self.street_number} {self.address1}"
return f" {self.address1}"

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})>"
24 changes: 23 additions & 1 deletion server/apps/trak/models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,34 @@
from django.db import models


class TrakManager(models.Manager, metaclass=ABCMeta):
class TrakBaseManager(models.Manager, metaclass=ABCMeta):
"""
Abstract class that defines an interface for our model managers
"""

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})>"

@abstractmethod
def save(self, **kwargs) -> models.QuerySet:
"""Save instance and its related models to the database"""
return self.create(**kwargs)


class TrakBaseModel(models.Model):
"""Base class for all apps.trak models"""

def __str__(self):
return f"{self.__class__.__name__}"

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:
abstract = True
12 changes: 3 additions & 9 deletions server/apps/trak/models/contact_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _

from apps.trak.models.base_model import TrakManager
from apps.trak.models.base_model import TrakBaseManager, TrakBaseModel


class EpaPhoneNumber(models.CharField):
Expand Down Expand Up @@ -41,7 +41,7 @@ def __str__(self):
return f"{self.number}"


class ContactManager(TrakManager):
class ContactManager(TrakBaseManager):
"""
Inter-model related functionality for Contact Model
"""
Expand All @@ -61,7 +61,7 @@ def save(self, **contact_data) -> models.QuerySet:
return super().save(**contact_data)


class Contact(models.Model):
class Contact(TrakBaseModel):
"""
RCRAInfo contact including personnel information such as name, email, company,
includes a phone related field.
Expand Down Expand Up @@ -108,9 +108,3 @@ def __str__(self):
return f"{first.capitalize()} {middle.capitalize()} {last.capitalize()}"
except AttributeError:
return f"contact {self.pk}: {self.first_name} {self.middle_initial} {self.last_name}"

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})>"
Loading

0 comments on commit 52e2ca1

Please sign in to comment.