diff --git a/smash/web/forms/appointment_form.py b/smash/web/forms/appointment_form.py index a07294741c65d29d1482b27e4f1cce1d4f2a72e9..d5ace225b009eee19ba16c3f1f029e8ffc26e10a 100644 --- a/smash/web/forms/appointment_form.py +++ b/smash/web/forms/appointment_form.py @@ -6,8 +6,9 @@ from django.forms import ModelForm from web.models.worker_study_role import WORKER_STAFF from web.forms.forms import DATETIMEPICKER_DATE_ATTRS, APPOINTMENT_TYPES_FIELD_POSITION -from web.models import Appointment, Worker, AppointmentTypeLink, AppointmentType +from web.models import Appointment, Worker, AppointmentTypeLink, AppointmentType, Provenance from web.views.notifications import get_filter_locations +from django.db.models.query import QuerySet logger = logging.getLogger(__name__) @@ -22,6 +23,46 @@ class AppointmentForm(ModelForm): self.fields['worker_assigned'].queryset = Worker.get_workers_by_worker_type(WORKER_STAFF).filter( locations__in=get_filter_locations(self.user)).distinct().order_by('first_name', 'last_name') + def save_changes(self): + for change in self.changes: + if change.modified_table_id is None: + change.modified_table_id = self.instance.id + change.save() + + def register_changes(self): + self.changes = [] + for field in self.changed_data: + new_value = self.cleaned_data[field] + if isinstance(new_value, QuerySet): + new_human_values = '; '.join([str(element) for element in new_value]) + new_value = ','.join([str(element.id) for element in new_value]) #overwrite variable + #old value + if self.instance.id: #update instance + previous_value = getattr(self.instance, field).all() + old_human_values = '; '.join([str(element) for element in previous_value]) + previous_value = ','.join([str(element.id) for element in previous_value]) #overwrite variable + else: #new instance + old_human_values = '' + previous_value = '' + #description + description = '{} changed from "{}" to "{}"'.format(field, old_human_values, new_human_values) + else: + if self.instance.id: #update instance + previous_value = str(getattr(self.instance, field)) + else: + previous_value = '' + new_value = str(self.cleaned_data[field]) + description = '{} changed from "{}" to "{}"'.format(field, previous_value, new_value) + + p = Provenance(modified_table = Appointment._meta.db_table, + modified_table_id = self.instance.id, + modification_author=self.user, + previous_value = previous_value, + new_value = new_value, + modification_description = description, + modified_field = field, + ) + self.changes.append(p) class AppointmentDetailForm(AppointmentForm): class Meta: @@ -67,7 +108,11 @@ class AppointmentEditForm(AppointmentForm): else: return location + def clean(self): + self.register_changes() #right before instance is changed + def save(self, commit=True): + appointment = super(AppointmentEditForm, self).save(commit) # if appointment date change, remove appointment_type links if 'datetime_when' in self.changed_data: @@ -89,6 +134,8 @@ class AppointmentEditForm(AppointmentForm): appointment_type_link = AppointmentTypeLink(appointment=appointment, appointment_type=appointment_type) appointment_type_link.save() + + self.save_changes() return appointment @@ -123,6 +170,9 @@ class AppointmentAddForm(AppointmentForm): self.fields = fields self.fields['location'].queryset = get_filter_locations(self.user) + def clean(self): + self.register_changes() #right before instance is changed + def clean_location(self): location = self.cleaned_data['location'] if self.user.locations.filter(id=location.id).count() == 0: @@ -136,4 +186,5 @@ class AppointmentAddForm(AppointmentForm): for appointment_type in appointment_types: appointment_type_link = AppointmentTypeLink(appointment=appointment, appointment_type=appointment_type) appointment_type_link.save() + self.save_changes() return appointment diff --git a/smash/web/views/appointment.py b/smash/web/views/appointment.py index d2d1f0ff92fa75353f7e8a08845270c45c67908e..84b12b2493f97f22c0e1073588c785815f2b515d 100644 --- a/smash/web/views/appointment.py +++ b/smash/web/views/appointment.py @@ -12,7 +12,7 @@ from web.models.appointment_list import APPOINTMENT_LIST_APPROACHING, APPOINTMEN from . import wrap_response from web.forms import AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, SubjectEditForm, \ StudySubjectEditForm -from ..models import Appointment, StudySubject, MailTemplate, Visit, Study +from ..models import Appointment, StudySubject, MailTemplate, Visit, Study, Provenance, Worker from django.views.generic import DeleteView from . import WrappedView from django.urls import reverse_lazy @@ -184,6 +184,16 @@ class AppointmentDeleteView(DeleteView, WrappedView): return redirect('web.views.appointment_edit', id=appointment.id) else: messages.success(request, "Appointment deleted") + worker = Worker.get_by_user(request.user) + p = Provenance(modified_table = Appointment._meta.db_table, + modified_table_id = appointment.id, + modification_author = worker, + previous_value = '', + new_value = '', + modification_description = 'Appointment deleted', + modified_field = '', + ) + p.save() return super(AppointmentDeleteView, self).delete(request, *args, **kwargs) @PermissionDecorator('delete_appointment', 'configuration')