diff --git a/frontend/src/hotline/ServiceRequestDetails.js b/frontend/src/hotline/ServiceRequestDetails.js
index b1e5d2d1..1692edec 100644
--- a/frontend/src/hotline/ServiceRequestDetails.js
+++ b/frontend/src/hotline/ServiceRequestDetails.js
@@ -9,7 +9,7 @@ import {
faClipboardCheck, faClipboardList, faComment, faEdit, faHouseDamage,
faKey, faMapMarkedAlt, faMinusSquare, faPlusSquare, faTimes, faTrailer, faUsers
} from '@fortawesome/free-solid-svg-icons';
-import { faCalendarEdit, faHomeAlt } from '@fortawesome/pro-solid-svg-icons';
+import { faCalendarEdit, faHomeAlt, faHomeHeart } from '@fortawesome/pro-solid-svg-icons';
import Header from '../components/Header';
import History from '../components/History';
import noImageFound from '../static/images/image-not-found.png';
@@ -64,10 +64,25 @@ function ServiceRequestDetails({id}) {
visit_notes: [],
});
+ const [show, setShow] = useState(false);
+ const handleClose = () => setShow(false);
const [animalToDelete, setAnimalToDelete] = useState({id:0, name:''});
const [showAnimalConfirm, setShowAnimalConfirm] = useState(false);
const handleAnimalClose = () => setShowAnimalConfirm(false);
+ // Handle animal reunification submit.
+ const handleSubmit = async () => {
+ await axios.patch('/hotline/api/servicerequests/' + id + '/', {reunite_animals:true})
+ .then(response => {
+ setData(prevState => ({ ...prevState, "status":"Closed", "animals":prevState['animals'].map(animal => ({...animal, status:animal.status !== 'DECEASED' ? 'REUNITED' : 'DECEASED'})) }));
+ handleClose()
+ })
+ .catch(error => {
+ console.log(error.response);
+ });
+ }
+
+ // Handle animal removal submit.
const handleAnimalSubmit = async () => {
await axios.patch('/hotline/api/servicerequests/' + id + '/', {remove_animal:animalToDelete.id})
.then(response => {
@@ -300,6 +315,19 @@ function ServiceRequestDetails({id}) {
>
+ {data.status.toLowerCase() !== 'closed' ?
+
+ Reunite all service request animals
+
+ }
+ >
+ setShow(true)} style={{cursor:'pointer'}} className="ml-1 fa-move-up" inverse />
+
+ : ""}
@@ -517,6 +545,20 @@ function ServiceRequestDetails({id}) {
+
+
+ Confirm Animal Reunification
+
+
+
+ Have all of the animals in this service request been reunited with their owner?
+
+
+
+
+
+
+
>
);
};
diff --git a/frontend/src/people/PersonDetails.js b/frontend/src/people/PersonDetails.js
index 5e8003d0..2ceb012c 100644
--- a/frontend/src/people/PersonDetails.js
+++ b/frontend/src/people/PersonDetails.js
@@ -1,11 +1,12 @@
import React, {useEffect, useState} from 'react';
import axios from "axios";
import { Link } from 'raviger';
-import { Card, ListGroup, OverlayTrigger, Tooltip } from 'react-bootstrap';
+import { Button, Card, ListGroup, Modal, OverlayTrigger, Tooltip } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faClipboardList, faEdit, faPhone, faPlusSquare
} from '@fortawesome/free-solid-svg-icons';
+import { faHomeHeart } from '@fortawesome/pro-solid-svg-icons';
import Moment from 'react-moment';
import Header from '../components/Header';
import History from '../components/History';
@@ -16,6 +17,21 @@ function PersonDetails({id}) {
// Determine if this is an owner or reporter when creating a Person.
var is_owner = window.location.pathname.includes("owner")
+ const [show, setShow] = useState(false);
+ const handleClose = () => setShow(false);
+
+ // Handle animal reunification submit.
+ const handleSubmit = async () => {
+ await axios.patch('/people/api/person/' + id + '/', {reunite_animals:true})
+ .then(response => {
+ setData(prevState => ({ ...prevState, "animals":prevState['animals'].map(animal => ({...animal, status:animal.status !== 'DECEASED' ? 'REUNITED' : 'DECEASED'})) }));
+ handleClose()
+ })
+ .catch(error => {
+ console.log(error.response);
+ });
+ }
+
const [data, setData] = useState({
first_name: '',
last_name: '',
@@ -73,7 +89,7 @@ function PersonDetails({id}) {
placement="bottom"
overlay={
- Add another owner
+ Add another owner for all of these animals
}
>
@@ -166,6 +182,19 @@ function PersonDetails({id}) {
>
+ {is_owner && data.animals.filter(animal => (!['REUNITED', 'DECEASED'].includes(animal.status))).length > 0 ?
+
+ Reunite all owner animals
+
+ }
+ >
+ setShow(true)} style={{cursor:'pointer'}} className="ml-1 fa-move-up" inverse />
+
+ : ""}
@@ -176,6 +205,20 @@ function PersonDetails({id}) {
+
+
+ Confirm Animal Reunification
+
+
+
+ Have all of the animals been reunited with this owner?
+
+
+
+
+
+
+
>
);
};
diff --git a/hotline/models.py b/hotline/models.py
index 31ab35cf..62cbd221 100644
--- a/hotline/models.py
+++ b/hotline/models.py
@@ -13,7 +13,7 @@
class ServiceRequest(Location):
#keys
- owners = models.ManyToManyField(Person, blank=True)
+ owners = models.ManyToManyField(Person, blank=True, related_name='request')
reporter = models.ForeignKey(Person, on_delete=models.SET_NULL, blank=True, null=True, related_name='reporter_service_request')
status = models.CharField(max_length=10, choices=STATUS_CHOICES, blank=False, default='open')
diff --git a/hotline/views.py b/hotline/views.py
index 70df501b..1e6429f3 100644
--- a/hotline/views.py
+++ b/hotline/views.py
@@ -41,7 +41,16 @@ def perform_update(self, serializer):
if service_request.status == 'canceled':
service_request.animal_set.update(status='CANCELED')
- action.send(self.request.user, verb='updated service request', target=service_request)
+
+ if self.request.data.get('reunite_animals'):
+ service_request.animal_set.exclude(status='DECEASED').update(status='REUNITED', shelter=None, room=None)
+ for animal in service_request.animal_set.exclude(status='DECEASED'):
+ action.send(self.request.user, verb=f'changed animal status to reunited', target=animal)
+ service_request.status = 'closed'
+ service_request.save()
+ action.send(self.request.user, verb='closed service request', target=service_request)
+ else:
+ action.send(self.request.user, verb='updated service request', target=service_request)
def get_queryset(self):
queryset = (
diff --git a/people/views.py b/people/views.py
index eaa587bf..c8f1db18 100644
--- a/people/views.py
+++ b/people/views.py
@@ -77,8 +77,18 @@ def perform_update(self, serializer):
if change_dict:
PersonChange.objects.create(user=self.request.user, person=person, changes=change_dict, reason=self.request.data.get('change_reason', ''))
- # Record update action.
- action.send(self.request.user, verb='updated person', target=person)
+ if self.request.data.get('reunite_animals'):
+ person.animal_set.exclude(status='DECEASED').update(status='REUNITED', shelter=None, room=None)
+ for animal in person.animal_set.exclude(status='DECEASED'):
+ action.send(self.request.user, verb=f'changed animal status to reunited', target=animal)
+ if person.request.exists():
+ service_request = person.request.first()
+ service_request.status = 'closed'
+ service_request.save()
+ action.send(self.request.user, verb='closed service request', target=service_request)
+ else:
+ # Record update action.
+ action.send(self.request.user, verb='updated person', target=person)
class OwnerContactViewSet(viewsets.ModelViewSet):