From fd7f6e302b763bce71fc354c01a956be87135d6f Mon Sep 17 00:00:00 2001
From: Carlos Vega <carlos.vega@uni.lu>
Date: Mon, 16 Nov 2020 17:26:45 +0100
Subject: [PATCH] WIP: first draft of privacy notice, go to /privacy_notices to
 list them and add them, please, create the folder privacy_notices/ before
 running

---
 smash/web/forms/privacy_notice.py             | 15 ++++
 .../web/migrations/0177_auto_20201116_1508.py | 29 +++++++
 .../web/migrations/0178_auto_20201116_1513.py | 21 +++++
 .../web/migrations/0179_auto_20201116_1528.py | 21 +++++
 smash/web/models/__init__.py                  |  1 +
 smash/web/models/study.py                     |  7 ++
 smash/web/templates/privacy_notice/add.html   |  8 ++
 .../templates/privacy_notice/add_edit.html    | 83 ++++++++++++++++++
 .../templates/privacy_notice/breadcrumb.html  |  2 +
 .../privacy_notice/confirm_delete.html        | 62 ++++++++++++++
 smash/web/templates/privacy_notice/edit.html  |  9 ++
 smash/web/templates/privacy_notice/list.html  | 84 +++++++++++++++++++
 smash/web/templates/study/edit.html           |  6 ++
 smash/web/templatetags/filters.py             |  8 +-
 smash/web/urls.py                             | 11 +++
 smash/web/views/__init__.py                   |  3 +-
 16 files changed, 367 insertions(+), 3 deletions(-)
 create mode 100644 smash/web/forms/privacy_notice.py
 create mode 100644 smash/web/migrations/0177_auto_20201116_1508.py
 create mode 100644 smash/web/migrations/0178_auto_20201116_1513.py
 create mode 100644 smash/web/migrations/0179_auto_20201116_1528.py
 create mode 100644 smash/web/templates/privacy_notice/add.html
 create mode 100644 smash/web/templates/privacy_notice/add_edit.html
 create mode 100644 smash/web/templates/privacy_notice/breadcrumb.html
 create mode 100644 smash/web/templates/privacy_notice/confirm_delete.html
 create mode 100644 smash/web/templates/privacy_notice/edit.html
 create mode 100644 smash/web/templates/privacy_notice/list.html

diff --git a/smash/web/forms/privacy_notice.py b/smash/web/forms/privacy_notice.py
new file mode 100644
index 00000000..5c015dd2
--- /dev/null
+++ b/smash/web/forms/privacy_notice.py
@@ -0,0 +1,15 @@
+from django import forms
+from django.forms import ModelForm
+from web.models import PrivacyNotice
+
+import logging
+logger = logging.getLogger(__name__)
+
+class PrivacyNoticeForm(ModelForm):
+    class Meta:
+        model = PrivacyNotice
+        fields = '__all__'
+        
+    def clean(self):
+        cleaned_data = super(PrivacyNoticeForm, self).clean()
+        return cleaned_data
\ No newline at end of file
diff --git a/smash/web/migrations/0177_auto_20201116_1508.py b/smash/web/migrations/0177_auto_20201116_1508.py
new file mode 100644
index 00000000..969d1db8
--- /dev/null
+++ b/smash/web/migrations/0177_auto_20201116_1508.py
@@ -0,0 +1,29 @@
+# Generated by Django 2.0.13 on 2020-11-16 15:08
+
+import django.core.files.storage
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0176_configurationitem_local_setting_clean'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='PrivacyNotice',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+                ('document', models.FileField(editable=False, upload_to='privacy_notices/', verbose_name='Study Privacy Notice file')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='study',
+            name='study_privacy_notice',
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='studies', to='web.PrivacyNotice', verbose_name='Study Privacy Note'),
+        )
+    ]
diff --git a/smash/web/migrations/0178_auto_20201116_1513.py b/smash/web/migrations/0178_auto_20201116_1513.py
new file mode 100644
index 00000000..c3c4c4cc
--- /dev/null
+++ b/smash/web/migrations/0178_auto_20201116_1513.py
@@ -0,0 +1,21 @@
+# Generated by Django 2.0.13 on 2020-11-16 15:13
+
+import django.core.files.storage
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0177_auto_20201116_1508'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='privacynotice',
+            name='study',
+            field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Study', verbose_name='Study'),
+        )
+    ]
diff --git a/smash/web/migrations/0179_auto_20201116_1528.py b/smash/web/migrations/0179_auto_20201116_1528.py
new file mode 100644
index 00000000..da1ab045
--- /dev/null
+++ b/smash/web/migrations/0179_auto_20201116_1528.py
@@ -0,0 +1,21 @@
+# Generated by Django 2.0.13 on 2020-11-16 15:28
+
+import django.core.files.storage
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0178_auto_20201116_1513'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='privacynotice',
+            name='updated_at',
+            field=models.DateTimeField(auto_now=True),
+        )
+    ]
diff --git a/smash/web/models/__init__.py b/smash/web/models/__init__.py
index 9c193eaa..46f20636 100644
--- a/smash/web/models/__init__.py
+++ b/smash/web/models/__init__.py
@@ -38,6 +38,7 @@ from .contact_attempt import ContactAttempt
 from .mail_template import MailTemplate
 from .missing_subject import MissingSubject
 from .inconsistent_subject import InconsistentSubject, InconsistentField
+from .privacy_notice import PrivacyNotice
 
 __all__ = [Study, FlyingTeam, Appointment, AppointmentType, Availability, Holiday, Item, Language, Location, Room,
            Subject, StudySubject, StudySubjectList, SubjectColumns, StudyNotificationParameters,
diff --git a/smash/web/models/study.py b/smash/web/models/study.py
index 2ff035ab..f672a5e1 100644
--- a/smash/web/models/study.py
+++ b/smash/web/models/study.py
@@ -94,6 +94,13 @@ class Study(models.Model):
         blank=False
     )
 
+    study_privacy_notice = models.ForeignKey("web.PrivacyNotice",
+                              verbose_name='Study Privacy Note',
+                              editable=True,
+                              null=True, on_delete=models.CASCADE, #check cascade ondelete
+                              related_name='studies'
+                              )
+
     def check_nd_number(self, nd_number):
         regex = re.compile(self.nd_number_study_subject_regex)
         return regex.match(nd_number) is not None
diff --git a/smash/web/templates/privacy_notice/add.html b/smash/web/templates/privacy_notice/add.html
new file mode 100644
index 00000000..6d4f87bf
--- /dev/null
+++ b/smash/web/templates/privacy_notice/add.html
@@ -0,0 +1,8 @@
+{% extends "privacy_notice/add_edit.html" %}
+
+{% block page_header %}New privacy notice{% endblock page_header %}
+
+{% block title %}{{ block.super }} - Add new privacy notice{% endblock %}
+
+{% block form-title %}Enter privacy notice details{% endblock %}
+{% block save-button %}Add{% endblock %}
\ No newline at end of file
diff --git a/smash/web/templates/privacy_notice/add_edit.html b/smash/web/templates/privacy_notice/add_edit.html
new file mode 100644
index 00000000..17ad93d6
--- /dev/null
+++ b/smash/web/templates/privacy_notice/add_edit.html
@@ -0,0 +1,83 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+    <style type="text/css">
+        .help_text{
+            margin-left: 5px;
+        }
+    </style>
+{% endblock styles %}
+
+{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "privacy_notice/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    {% block content %}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">{% block form-title %}Enter privacy notice details{% endblock %}</h3>
+                    </div>
+
+
+                    <form method="post" action="" class="form-horizontal" enctype="multipart/form-data">
+                        {% csrf_token %}
+
+                        <div class="box-body">
+                            {% for field in form %}
+                                <div class="form-group {% if field.errors %}has-error{% endif %}">
+                                    <label class="col-sm-4  col-lg-offset-1 col-lg-2 control-label">
+                                        {{ field.label }}
+                                        {% if field.help_text %}
+                                           <i class="fa fa-info-circle help_text" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="{{field.help_text}}"></i>
+                                        {% endif %}
+                                    </label>
+
+                                    <div class="col-sm-8 col-lg-4">
+                                        {{ field|add_class:'form-control' }}
+                                        {% if field.errors %}
+                                            <span class="help-block">{{ field.errors }}</span>
+                                        {% endif %}
+                                    </div>
+
+
+                                </div>
+                            {% endfor %}
+                        </div><!-- /.box-body -->
+                        <div class="box-footer">
+                            <div class="col-sm-6">
+                                <button type="submit" class="btn btn-block btn-success">{% block save-button %}
+                                    Add{% endblock %}</button>
+                            </div>
+                            <div class="col-sm-6">
+                                <a href="{% url 'web.views.privacy_notices' %}"
+                                   class="btn btn-block btn-default">Cancel</a>
+                            </div>
+                        </div><!-- /.box-footer -->
+                    </form>
+                </div>
+
+            </div>
+        </div>
+
+    {% endblock %}
+
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
+    
+{% endblock scripts %}
\ No newline at end of file
diff --git a/smash/web/templates/privacy_notice/breadcrumb.html b/smash/web/templates/privacy_notice/breadcrumb.html
new file mode 100644
index 00000000..3a3bdd23
--- /dev/null
+++ b/smash/web/templates/privacy_notice/breadcrumb.html
@@ -0,0 +1,2 @@
+<li><a href="{% url 'web.views.appointments' %}"><i class="fa fa-dashboard"></i> Dashboard</a></li>
+<li class="active"><a href="{% url 'web.views.privacy_notices' %}">Privacy Notices</a></li>
\ No newline at end of file
diff --git a/smash/web/templates/privacy_notice/confirm_delete.html b/smash/web/templates/privacy_notice/confirm_delete.html
new file mode 100644
index 00000000..8e618e11
--- /dev/null
+++ b/smash/web/templates/privacy_notice/confirm_delete.html
@@ -0,0 +1,62 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+
+{% endblock styles %}
+
+{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
+{% block page_header %}Delete privacy notice{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block title %}{{ block.super }} - Delete privacy notice{% endblock %}
+
+{% block breadcrumb %}
+    {% include "privacy_notice/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    {% block content %}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">Confirm deletion</h3>
+                    </div>
+
+                    <form action="" method="post" class="form-horizontal">{% csrf_token %}
+                        <div class="box-body">
+                            <p>Are you sure you want to delete privacy notice "{{ object.document.url | basename }}" from Study "{{object.study}}"?</p>
+                        </div><!-- /.box-body -->
+                        <div class="box-footer">
+                            <div class="col-sm-6">
+                                <button type="submit" class="btn btn-block btn-danger">Delete</button>
+                            </div>
+                            <div class="col-sm-6">
+                                <a href="{% url 'web.views.privacy_notices' %}"
+                                   class="btn btn-block btn-default">Cancel</a>
+                            </div>
+                        </div><!-- /.box-footer -->
+                    </form>
+                </div>
+
+            </div>
+        </div>
+
+    {% endblock %}
+
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
+
+{% endblock scripts %}
+
+
diff --git a/smash/web/templates/privacy_notice/edit.html b/smash/web/templates/privacy_notice/edit.html
new file mode 100644
index 00000000..f1f0d651
--- /dev/null
+++ b/smash/web/templates/privacy_notice/edit.html
@@ -0,0 +1,9 @@
+{% extends "privacy_notice/add_edit.html" %}
+
+{% block page_header %}Edit privacy notice "{{ privacy_notice.name }}"{% endblock page_header %}
+
+{% block title %}{{ block.super }} - Edit privacy notice "{{ privacy_notice.name }}"{% endblock %}
+
+{% block form-title %}Enter privacy notice details{% endblock %}
+
+{% block save-button %}Save{% endblock %}
diff --git a/smash/web/templates/privacy_notice/list.html b/smash/web/templates/privacy_notice/list.html
new file mode 100644
index 00000000..f42a803c
--- /dev/null
+++ b/smash/web/templates/privacy_notice/list.html
@@ -0,0 +1,84 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <!-- DataTables -->
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}">
+{% endblock styles %}
+
+{% block ui_active_tab %}'privacy_notices'{% endblock ui_active_tab %}
+{% block page_header %}Privacy Notices{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "privacy_notice/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+
+    <div class="box box-success">
+        <div class="box-header with-border">
+            <h3 class="box-title">Privacy Notices</h3>
+        </div>
+        <div class="box-body">
+
+            <div>
+                <a class="btn btn-app" href="{% url 'web.views.privacy_notice_add' %}">
+                    <i class="fa fa-plus"></i> Add new privacy notice
+                </a>
+            </div>
+            <table id="table" class="table table-bordered table-striped">
+                <thead>
+                <tr>
+                    <th>No.</th>
+                    <th>Creation Date</th>
+                    <th>Last Updated</th>
+                    <th>Study</th>
+                    <th>Download</th>
+                    <th>Edit</th>
+                    <th>Delete</th>
+                </tr>
+                </thead>
+                <tbody>
+                {% for privacy_notice in privacy_notices %}
+                    <tr>
+                        <td>{{ forloop.counter }}</td>
+                        <td>{{ privacy_notice.created_at }}</td>
+                        <td>{{ privacy_notice.updated_at }}</td>
+                        <td>{{ privacy_notice.study }}</td>
+                        <td><a href="{{ privacy_notice.document.url }}"><i class="fa fa-download"></i></a>&nbsp; &nbsp;{{privacy_notice.document.url | basename}}</td>
+                        <td><a href="{% url 'web.views.privacy_notice_edit' privacy_notice.id %}"><i
+                                class="fa fa-edit"></i></a></td>
+                        <td><a href="{% url 'web.views.privacy_notice_delete' privacy_notice.id %}"><i
+                                class="fa fa-trash text-danger"></i></a></td>
+                    </tr>
+                {% endfor %}
+                </tbody>
+            </table>
+        </div>
+    </div>
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script>
+    <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
+
+    <script>
+        $(function () {
+            $('#table').DataTable({
+                "paging": true,
+                "lengthChange": false,
+                "searching": true,
+                "ordering": true,
+                "info": true,
+                "autoWidth": false
+            });
+        });
+    </script>
+{% endblock scripts %}
diff --git a/smash/web/templates/study/edit.html b/smash/web/templates/study/edit.html
index 2fc025e0..57ae2071 100644
--- a/smash/web/templates/study/edit.html
+++ b/smash/web/templates/study/edit.html
@@ -66,6 +66,12 @@
                                 {% endfor %}
 
                             </div>
+
+                            <div>
+                                <a class="btn btn-app" href="{% url 'web.views.mail_template_add' %}">
+                                    <i class="fa fa-plus"></i> Add new privacy notice
+                                </a>
+                            </div>
                         </div><!-- /.box-body -->
 
                         <div class="box-header with-border">
diff --git a/smash/web/templatetags/filters.py b/smash/web/templatetags/filters.py
index a7a63383..6e2e122e 100644
--- a/smash/web/templatetags/filters.py
+++ b/smash/web/templatetags/filters.py
@@ -2,7 +2,7 @@
 from django import template
 from django.forms import CheckboxSelectMultiple, CheckboxInput
 from django.utils.safestring import mark_safe
-import datetime
+import datetime, os
 from web.models import ConfigurationItem
 from web.models.constants import VISIT_SHOW_VISIT_NUMBER_FROM_ZERO
 from distutils.util import strtobool
@@ -59,4 +59,8 @@ def display_visit_number(visit_number):
     if strtobool(visit_from_zero):
         return (visit_number - 1)
     else:
-        return visit_number
\ No newline at end of file
+        return visit_number
+
+@register.filter(name='basename')
+def basename(path):
+    return os.path.basename(path)
\ No newline at end of file
diff --git a/smash/web/urls.py b/smash/web/urls.py
index 651e74f0..05889ef1 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -161,6 +161,17 @@ urlpatterns = [
     url(r'^equipment_and_rooms/rooms/delete/(?P<room_id>\d+)$', views.rooms.rooms_delete,
         name='web.views.equipment_and_rooms.rooms_delete'),
 
+    ####################
+    #  PRIVACY NOTICE  #
+    ####################
+
+    url(r'^privacy_notices$', views.privacy_notice.PrivacyNoticeListView.as_view(), name='web.views.privacy_notices'),
+
+    url(r'^privacy_notices/add$', views.privacy_notice.privacy_notice_add, name='web.views.privacy_notice_add'),
+    url(r'^privacy_notices/(?P<pk>\d+)/edit$', views.privacy_notice.privacy_notice_edit, name='web.views.privacy_notice_edit'),
+
+    url(r'^privacy_notices/(?P<pk>\d+)/delete$', views.privacy_notice.PrivacyNoticeDeleteView.as_view(), name='web.views.privacy_notice_delete'),
+   
     ####################
     #       MAIL       #
     ####################
diff --git a/smash/web/views/__init__.py b/smash/web/views/__init__.py
index 90f25422..a7dcf170 100644
--- a/smash/web/views/__init__.py
+++ b/smash/web/views/__init__.py
@@ -105,4 +105,5 @@ from . import uploaded_files
 from . import study
 from . import password
 from . import appointment_type
-from . import provenance
\ No newline at end of file
+from . import provenance
+from . import privacy_notice
\ No newline at end of file
-- 
GitLab