Skip to content

Commit

Permalink
send email about reports
Browse files Browse the repository at this point in the history
  • Loading branch information
Ederporto committed Feb 20, 2024
1 parent 158d57b commit 3e5a46d
Show file tree
Hide file tree
Showing 14 changed files with 416 additions and 6 deletions.
20 changes: 20 additions & 0 deletions agenda/migrations/0003_event_activity_associated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.1.7 on 2024-02-19 03:03

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('metrics', '0013_activity_is_main_activity'),
('agenda', '0002_event_metric_associated'),
]

operations = [
migrations.AddField(
model_name='event',
name='activity_associated',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='event_activity', to='metrics.activity'),
),
]
17 changes: 17 additions & 0 deletions agenda/migrations/0004_remove_event_activity_associated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.1.7 on 2024-02-19 13:56

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('agenda', '0003_event_activity_associated'),
]

operations = [
migrations.RemoveField(
model_name='event',
name='activity_associated',
),
]
20 changes: 20 additions & 0 deletions agenda/migrations/0005_event_activity_associated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.1.7 on 2024-02-19 14:08

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('metrics', '0014_activity_area_responsible'),
('agenda', '0004_remove_event_activity_associated'),
]

operations = [
migrations.AddField(
model_name='event',
name='activity_associated',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='event_activity', to='metrics.activity'),
),
]
3 changes: 2 additions & 1 deletion agenda/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
from users.models import TeamArea
from metrics.models import Metric
from metrics.models import Metric, Activity


# CALENDAR OF EVENTS
Expand Down Expand Up @@ -31,6 +31,7 @@ class Event(models.Model):
area_responsible = models.ForeignKey(TeamArea, on_delete=models.RESTRICT, related_name="area_responsible")
area_involved = models.ManyToManyField(TeamArea, related_name="area_involved", blank=True)
metric_associated = models.ManyToManyField(Metric, related_name="event_metrics", blank=True)
activity_associated = models.ForeignKey(Activity, on_delete=models.RESTRICT, related_name="event_activity", null=True, blank=True)

class Meta:
verbose_name = _("Event")
Expand Down
57 changes: 57 additions & 0 deletions agenda/templates/agenda/email_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{% load i18n %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ manager }}</title>
</head>
<body style="margin: 0; padding: 0;">
<!-- Wrapper -->
<table style="width: 100%; font:medium/1.5 Montserrat, sans-serif">
<tr>
<td style="text-align: center; padding: 1em; background-color: #3267FF; border-radius: 2em;">
<h1 style="color: #f8f8f8;">S.A.R.A.</h1>
<h2 style="color: #f8f8f8;">{{ area }}</h2>
</td>
</tr>
<tr>
<td style="padding: 2em; background-color: #f8f8f8; border-radius: 2em; ">
{% blocktrans with manager=manager %}Dear {{ manager }},<br><br>This is a reminder of the reports and activities under your responsibility that must be reported into SARA.<br><br>Please, look into the following activities:{% endblocktrans %}
<table style="width: 100%;">
{% if late_reports %}
<tr>
<td>
<h2 style="color: #FF3333; text-decoration: underline; ">{% trans "◂ Late reports" %}</h2>
{% autoescape off %}{{ late_reports }}{% endautoescape %}
</td>
</tr>
{% endif %}
{% if upcoming_reports %}
<tr>
<td>
<h2 style="color: #E07800; text-decoration: underline; ">{% trans "◂ Upcoming reports" %}</h2>
{% autoescape off %}{{ upcoming_reports }}{% endautoescape %}
</td>
</tr>
{% endif %}
{% if about_to_kickoff %}
<tr>
<td>
<h2 style="color: #3267FF; text-decoration: underline; ">{% trans "◂ About to kickoff" %}</h2>
{% autoescape off %}{{ about_to_kickoff }}{% endautoescape %}
</td>
</tr>
{% endif %}
</table>
</td>
</tr>
<tr>
<td style="text-align: center; padding: 1em; background-color: #3267FF; color: #f8f8f8; font-size: 85%; border-radius: 1em">
{% trans "For any inquiries or assistance, please don't hesitate to reach out to our Products and Technology team." %}
</td>
</tr>
</table>
</body>
</html>
134 changes: 132 additions & 2 deletions agenda/tests.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import datetime
from django.test import TestCase
from django.urls import reverse
from django.conf import settings
from django.core.exceptions import ValidationError

from django.contrib.auth.models import Group
from metrics.models import Metric, Activity
from agenda.models import Event
from users.models import User, UserProfile, TeamArea
from users.models import User, UserProfile, TeamArea, Position
from agenda.views import get_activities_soon_to_be_finished, get_activities_already_finished,\
get_activities_about_to_kickoff


class EventModelTests(TestCase):
Expand Down Expand Up @@ -209,3 +213,129 @@ def test_update_event_post_with_invalid_parameters(self):
self.assertEqual(response.status_code, 302)
self.assertFalse(Event.objects.filter(name="").exists())
self.assertTrue(Event.objects.filter(name=self.name).exists())


class EventEmailTests(TestCase):
def setUp(self):
self.name = "Event"
self.initial_date = datetime.date.today()
self.end_date = self.initial_date + datetime.timedelta(7)
self.area_responsible = TeamArea.objects.create(text="Area responsible", code="Ar code", color_code="AR")
self.area_involved = TeamArea.objects.create(text="Area involved", code="Ai code", color_code="AI")
self.activity_associated = Activity.objects.create(text="Activity", area_responsible=self.area_responsible)
self.metric_associated = Metric.objects.create(text="Metric", activity=self.activity_associated)
self.event = Event.objects.create(
name=self.name,
initial_date=self.initial_date,
end_date=self.end_date,
area_responsible=self.area_responsible,
activity_associated=self.activity_associated)

self.event.metric_associated.add(self.metric_associated)
self.event.save()

def test_get_activities_soon_to_be_finished_returns_events_near_the_end(self):
events = get_activities_soon_to_be_finished(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.filter(pk=self.event.pk))

def test_if_events_are_too_far_away_get_activities_soon_to_be_finished_returns_empty_queryset(self):
self.event.end_date += datetime.timedelta(16)
self.event.save()
events = get_activities_soon_to_be_finished(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.none())

def test_if_get_activities_soon_to_be_finished_returns_empty_queryset_if_events_already_finished(self):
self.event.end_date = datetime.date.today() - datetime.timedelta(1)
self.event.save()
events = get_activities_soon_to_be_finished(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.none())

def test_get_activities_already_finished_returns_events_already_finished(self):
self.event.initial_date = datetime.date.today() - datetime.timedelta(3)
self.event.end_date = datetime.date.today() - datetime.timedelta(2)
self.event.save()
events = get_activities_already_finished(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.filter(pk=self.event.pk))

def test_if_events_are_too_far_away_get_activities_already_finished_returns_empty_queryset(self):
self.event.initial_date -= datetime.timedelta(60)
self.event.end_date -= datetime.timedelta(60)
self.event.save()
events = get_activities_already_finished(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.none())

def test_get_activities_already_finished_returns_empty_queryset_if_events_are_not_finished(self):
self.event.end_date = datetime.date.today()
self.event.save()
events = get_activities_already_finished(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.none())


def test_get_activities_about_to_kickoff_returns_events_with_start_in_near_future(self):
self.event.initial_date = datetime.date.today() + datetime.timedelta(1)
self.event.save()
events = get_activities_about_to_kickoff(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.filter(pk=self.event.pk))

def test_if_events_are_too_far_away_get_activities_about_to_kickoff_returns_empty_queryset(self):
self.event.initial_date += datetime.timedelta(60)
self.event.save()
events = get_activities_about_to_kickoff(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.none())

def test_get_activities_about_to_kickoff_returns_empty_queryset_if_events_started_before_today(self):
self.event.initial_date = datetime.date.today() - datetime.timedelta(1)
self.event.save()
events = get_activities_about_to_kickoff(self.area_responsible)
self.assertQuerysetEqual(events, Event.objects.none())

def test_trying_to_send_email_for_manager_without_email_doesnt_sends_the_email(self):
group = Group.objects.create(name="Group_name")
position = Position.objects.create(text="Position", type=group, area_associated=self.area_responsible)
user = User.objects.create_user(username="Username", password="Password")
user.userprofile.position = position
user.userprofile.save()

response = self.client.get(reverse('agenda:send_email'))
self.assertEqual(response.status_code, 302)

def test_trying_to_send_email_for_manager_with_email_sends_the_email(self):
group = Group.objects.create(name="Group_name")
position = Position.objects.create(text="Position", type=group, area_associated=self.area_responsible)
user = User.objects.create_user(username="Username", password="Password")
user.userprofile.position = position
user.userprofile.save()
user.email = "[email protected]"
user.save()

response = self.client.get(reverse('agenda:send_email'))
self.assertEqual(response.status_code, 302)

def test_trying_to_send_email_with_no_activities_doesnt_sends_the_email(self):
group = Group.objects.create(name="Group_name")
position = Position.objects.create(text="Position", type=group, area_associated=self.area_responsible)
user = User.objects.create_user(username="Username", password="Password")
user.userprofile.position = position
user.userprofile.save()
user.email = "[email protected]"
user.save()

self.event.delete()

response = self.client.get(reverse('agenda:send_email'))
self.assertEqual(response.status_code, 302)

def test_trying_to_send_email_with_activities_of_one_day_sends_the_email_with_proper_representation(self):
group = Group.objects.create(name="Group_name")
position = Position.objects.create(text="Position", type=group, area_associated=self.area_responsible)
user = User.objects.create_user(username="Username", password="Password")
user.userprofile.position = position
user.userprofile.save()
user.email = "[email protected]"
user.save()

self.event.initial_date=self.event.end_date
self.event.save()

response = self.client.get(reverse('agenda:send_email'))
self.assertEqual(response.status_code, 302)
1 change: 1 addition & 0 deletions agenda/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
path('list', views.list_events, name="list_events"),
path('activity/<int:event_id>/delete', views.delete_event, name="delete_event"),
path('activity/<int:event_id>/edit', views.update_event, name="edit_event"),
path('send_email', views.send_email, name="send_email"),
re_path(r'^(?P<year>20\d{2})/(?P<month>(0?[1-9]|1[012]))$',views.show_specific_calendar, name='show_specific_calendar'),
re_path(r'^(?P<year>20\d{2})/(?P<month>(0?[1-9]|1[012]))/(?P<day>(3[01]|[12][0-9]|0?[1-9]))$',views.show_specific_calendar_day, name='show_specific_calendar_day')
]
Loading

0 comments on commit 3e5a46d

Please sign in to comment.