From eccd567da647f219bf1ecb02568b31ed28b159f8 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Wed, 17 May 2017 16:15:39 +0200
Subject: [PATCH] Improve production page

---
 journals/forms.py                             |  5 +++
 .../migrations/0021_auto_20170517_1452.py     | 31 ++++++++++++++++
 .../migrations/0022_auto_20170517_1608.py     | 26 +++++++++++++
 journals/models.py                            | 20 +++++++---
 .../journals/_production_event_li.html        | 12 ++++++
 .../journals/_production_stream_card.html     | 37 ++++++++++++-------
 scipost/templatetags/scipost_extras.py        |  7 ++++
 7 files changed, 120 insertions(+), 18 deletions(-)
 create mode 100644 journals/migrations/0021_auto_20170517_1452.py
 create mode 100644 journals/migrations/0022_auto_20170517_1608.py
 create mode 100644 journals/templates/journals/_production_event_li.html

diff --git a/journals/forms.py b/journals/forms.py
index 6d14eaba4..910bbd5b4 100644
--- a/journals/forms.py
+++ b/journals/forms.py
@@ -12,6 +12,11 @@ class ProductionEventForm(forms.ModelForm):
         model = ProductionEvent
         exclude = ['stream', 'noted_on', 'noted_by']
 
+    def __init__(self, *args, **kwargs):
+        super(ProductionEventForm, self).__init__(*args, **kwargs)
+        self.fields['duration'].widget.attrs.update(
+            {'placeholder': 'HH:MM:SS'})
+
 
 class InitiatePublicationForm(forms.Form):
     accepted_submission = forms.ModelChoiceField(
diff --git a/journals/migrations/0021_auto_20170517_1452.py b/journals/migrations/0021_auto_20170517_1452.py
new file mode 100644
index 000000000..e512a45e0
--- /dev/null
+++ b/journals/migrations/0021_auto_20170517_1452.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-05-17 12:52
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0020_auto_20170515_1829'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='productionevent',
+            name='noted_by',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='productionevent',
+            name='stream',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.ProductionStream'),
+        ),
+        migrations.AlterField(
+            model_name='productionstream',
+            name='submission',
+            field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='submissions.Submission'),
+        ),
+    ]
diff --git a/journals/migrations/0022_auto_20170517_1608.py b/journals/migrations/0022_auto_20170517_1608.py
new file mode 100644
index 000000000..0f0c51220
--- /dev/null
+++ b/journals/migrations/0022_auto_20170517_1608.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-05-17 14:08
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0021_auto_20170517_1452'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='productionevent',
+            name='comments',
+            field=models.TextField(blank=True, null=True),
+        ),
+        migrations.AlterField(
+            model_name='productionevent',
+            name='noted_on',
+            field=models.DateTimeField(default=django.utils.timezone.now),
+        ),
+    ]
diff --git a/journals/models.py b/journals/models.py
index ca45e5000..df59b73d6 100644
--- a/journals/models.py
+++ b/journals/models.py
@@ -22,17 +22,27 @@ from scipost.models import Contributor
 ##############
 
 class ProductionStream(models.Model):
-    submission = models.OneToOneField('submissions.Submission', related_name='stream')
+    submission = models.OneToOneField('submissions.Submission', on_delete=models.CASCADE)
     opened = models.DateTimeField()
 
+    def __str__(self):
+        return str(self.submission)
+
+    def total_duration(self):
+        totdur = self.productionevent_set.all().aggregate(models.Sum('duration'))
+        return totdur['duration__sum']
+
+
 class ProductionEvent(models.Model):
-    stream = models.ForeignKey(ProductionStream, related_name='events')
+    stream = models.ForeignKey(ProductionStream, on_delete=models.CASCADE)
     event = models.CharField(max_length=64, choices=PRODUCTION_EVENTS)
-    comments = models.TextField()
-    noted_on = models.DateTimeField()
-    noted_by = models.ForeignKey(Contributor, related_name='event')
+    comments = models.TextField(blank=True, null=True)
+    noted_on = models.DateTimeField(default=timezone.now)
+    noted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE)
     duration = models.DurationField(blank=True, null=True)
 
+    def __str__(self):
+        return '%s: %s' % (str(self.stream.submission), self.get_event_display())
 
 
 ################
diff --git a/journals/templates/journals/_production_event_li.html b/journals/templates/journals/_production_event_li.html
new file mode 100644
index 000000000..117a80234
--- /dev/null
+++ b/journals/templates/journals/_production_event_li.html
@@ -0,0 +1,12 @@
+{% load scipost_extras %}
+
+<li id="{{ event.id }}">
+  <div class="font-weight-bold">{{ event.get_event_display }} <small class="text-muted">noted {{ event.noted_on }} by {{ event.noted_by }}</small>
+  </div>
+  {% if event.duration %}
+  <div><small>Duration: {{ event.duration|duration }}</small></div>
+  {% endif %}
+  {% if event.comments %}
+  <div>{{ event.comments|linebreaks }}</div>
+  {% endif %}
+</li>
diff --git a/journals/templates/journals/_production_stream_card.html b/journals/templates/journals/_production_stream_card.html
index 007f14a83..f2a78b13f 100644
--- a/journals/templates/journals/_production_stream_card.html
+++ b/journals/templates/journals/_production_stream_card.html
@@ -1,18 +1,29 @@
 {% load bootstrap %}
+{% load scipost_extras %}
 
 <div class="card-block">
   {% include 'submissions/_submission_card_content_sparse.html' with submission=stream.submission %}
-  <h3>Events</h3>
-  <ul>
-    {% for event in stream.events_set.all %}
-    <li>{{ event.get_event_display }}</li>
-    {% empty %}
-    <li>No events were found.</li>
-    {% endfor %}
-  </ul>
-  <form action="{% url 'journals:add_production_event' stream_id=stream.id %}" method="post">
-    {% csrf_token %}
-    {{ form|bootstrap }}
-    <input type="submit" name="submit" value="Submit">
-  </form>
+  <div class="row">
+    <div class="col-7">
+      <h3>Events</h3>
+      <ul>
+	{% for event in stream.productionevent_set.all %}
+	{% include 'journals/_production_event_li.html' with event=event %}
+	{% empty %}
+	<li>No events were found.</li>
+	{% endfor %}
+      </ul>
+      <br/>
+      {% if stream.total_duration %}
+      <h3>Total duration for this stream: {{ stream.total_duration|duration }}</h3>
+      {% endif %}
+    </div>
+    <div class="col-5">
+      <h3>Add an event to this production stream:</h3>
+      <form action="{% url 'journals:add_production_event' stream_id=stream.id %}" method="post">
+	{% csrf_token %}
+	{{ form|bootstrap }}
+	<input type="submit" name="submit" value="Submit">
+      </form>
+    </div>
 </div>
diff --git a/scipost/templatetags/scipost_extras.py b/scipost/templatetags/scipost_extras.py
index 0a365cf28..9d9861514 100644
--- a/scipost/templatetags/scipost_extras.py
+++ b/scipost/templatetags/scipost_extras.py
@@ -15,6 +15,13 @@ register = template.Library()
 def sort_by(queryset, order):
     return queryset.order_by(order)
 
+@register.filter(name='duration')
+def duration(dur):
+    total_seconds = int(dur.total_seconds())
+    hours = total_seconds // 3600
+    minutes = (total_seconds % 3600) // 60
+    return '{}h {}m'.format(hours, minutes)
+
 
 #######################
 # For scipost objects #
-- 
GitLab