diff options
author | Markus Krogh <markus@nordu.net> | 2016-03-15 12:37:16 +0000 |
---|---|---|
committer | Markus Krogh <markus@nordu.net> | 2016-03-15 12:37:16 +0000 |
commit | 2d953d27d0d1aad7491485c739a9507127354af9 (patch) | |
tree | a5a47c5d0ed8e3295e3babcb2f25267ff2892dc1 | |
parent | c9d7afac4f1396b6e632277b39fea816b974131e (diff) |
Update manager mails and ceo mail
-rw-r--r-- | maconomy/models.py | 9 | ||||
-rw-r--r-- | maconomy/templates.py | 54 | ||||
-rw-r--r-- | maconomy/utils.py | 15 | ||||
-rw-r--r-- | maconomy_hours.py | 14 | ||||
-rw-r--r-- | templates/ceo.html | 2 | ||||
-rw-r--r-- | test/templates/test_ceo_template.py | 10 | ||||
-rw-r--r-- | test/templates/test_employee_status_template.py | 26 | ||||
-rw-r--r-- | test/templates/test_manager_template.py | 15 |
8 files changed, 83 insertions, 62 deletions
diff --git a/maconomy/models.py b/maconomy/models.py index f878172..7f4fcd4 100644 --- a/maconomy/models.py +++ b/maconomy/models.py @@ -38,5 +38,14 @@ class Timesheet: return self.approved == 1 def __str__(self): return self.__unicode__() + def status_summary(self): + status = u"[OK]" + if self.is_missing(): + status = u"[Missing]" + elif not self.is_submitted(): + status = u"[Unsubmitted]" + elif not self.is_approved(): + status = u"[Not approved]" + return u"{} {}".format(status, self.employee) def __unicode__(self): u"{} ({})".format(self.week, self.status) diff --git a/maconomy/templates.py b/maconomy/templates.py index 05c3319..80cafbb 100644 --- a/maconomy/templates.py +++ b/maconomy/templates.py @@ -1,4 +1,5 @@ from string import Template +from maconomy import utils class BaseTemplate(object): def __init__(self, template_file): @@ -12,6 +13,9 @@ class BaseTemplate(object): template_base = f.read() self.template = Template(template_base) + def tag(self, tag, content): + return u"<{tag}>{content}</{tag}>".format(tag=tag, content=content) + class UnsubmittedEmailTemplate(BaseTemplate): def __init__(self): @@ -30,38 +34,46 @@ class MissingEmailTemplate(BaseTemplate): class ManagerEmailTemplate(BaseTemplate): def __init__(self): self.set_template("templates/manager.html") - self.status_template = EmployeeStatusTemplate() + self.status_template = EmployeeStatusListTemplate() def build(self, timesheets, maconomyurl): statuslist = self.build_statuslist(timesheets) return self.template.substitute(statuslist=statuslist,maconomyurl=maconomyurl, amount=len(timesheets)) def build_statuslist(self, timesheets): - statuslist = [self.status_template.build(timesheet) for timesheet in timesheets] - return "\n".join(statuslist) - -class EmployeeStatusTemplate(BaseTemplate): - def __init__(self, include_approver=False): - self.set_template("templates/_employee_status.html") - self.include_approver = include_approver + result = u"" + unfinished = [timesheet for timesheet in timesheets if not timesheet.is_submitted()] + #Sort to get unsubmitted last + unfinished.sort(key=lambda t: t.status_summary()) + if unfinished: + result += self.tag("h4","Unfinished:")+u"\n{}".format(self.status_template.build(unfinished)) + + notapproved = set(timesheets) - set(unfinished) + if notapproved: + result += self.tag("h4", "For approval:") + u"\n{}".format(self.status_template.build(notapproved)) + return result + +class EmployeeStatusListTemplate(BaseTemplate): + def __init__(self): + pass + def build(self, timesheets): + statuslist = u"\n".join([self.status_summary(t) for t in timesheets]) + return self.tag("ul", statuslist) if statuslist else "" - def build(self, timesheet): - employee = timesheet.employee - submitted = '' if timesheet.is_submitted() else 'not' - approver = timesheet.approver if self.include_approver else 'you' - approved = '' if timesheet.is_approved() else 'not' - return self.template.substitute(employee=employee.__unicode__(), submitted=submitted, approved=approved, approver=approver) + def status_summary(self, timesheet): + content = u"{}".format(timesheet.status_summary()) + return self.tag("li", content) class CEOEmailTemplate(BaseTemplate): def __init__(self): self.set_template("templates/ceo.html") - self.status_template = EmployeeStatusTemplate(include_approver=True) + self.status_template = EmployeeStatusListTemplate() def build(self, timesheets): - statuslist = self.build_statuslist(timesheets) + per_manager = utils.per_manager(timesheets) + statuslist = u"" + for manager_id, relevant_timesheets in per_manager.items(): + relevant_timesheets.sort(key=lambda t: t.status_summary()) + statuslist += self.tag("h4", u"Status for {} employees:".format(manager_id)) + statuslist += self.status_template.build(relevant_timesheets) return self.template.substitute(statuslist=statuslist) - - def build_statuslist(self, timesheets): - statuslist = [self.status_template.build(timesheet) for timesheet in timesheets] - return "\n".join(statuslist) - diff --git a/maconomy/utils.py b/maconomy/utils.py new file mode 100644 index 0000000..e22239b --- /dev/null +++ b/maconomy/utils.py @@ -0,0 +1,15 @@ +from collections import defaultdict + +def per_manager(timesheets): + per_manager = defaultdict(list) + # filter timesheets per manager + for timesheet in [t for t in timesheets if need_manager_mail(t)]: + manager_id = timesheet.approver + per_manager[manager_id].append(timesheet) + return per_manager + +def need_manager_mail(timesheet): + return not timesheet.is_submitted() or not timesheet.is_approved() + +def employees(timesheets): + return dict([(t.employee.id, t.employee) for t in timesheets]) diff --git a/maconomy_hours.py b/maconomy_hours.py index 1efcc7c..b41cd06 100644 --- a/maconomy_hours.py +++ b/maconomy_hours.py @@ -1,7 +1,9 @@ from maconomy import cli, create_db, TimeRegistrationRepository, Mailer from maconomy.views import EmployeeEmailView, ManagerEmailView, CEOEmailView +from maconomy import utils from collections import defaultdict + def main(config, options): db = create_db(config) timereg_repo = TimeRegistrationRepository(db) @@ -43,12 +45,8 @@ def normal(timesheets, config, mailer): def manager(timesheets, config, mailer): view = ManagerEmailView(config) # extract employees for manager email lookup - employees = dict([(t.employee.id, t.employee) for t in timesheets]) - per_manager = defaultdict(list) - # filter timesheets per manager - for timesheet in [t for t in timesheets if need_manager_mail(t)]: - manager_id = timesheet.approver - per_manager[manager_id].append(timesheet) + employees = utils.employees(timesheets) + per_manager = utils.per_manager(timesheets) # send mails to managers for manager_id, relevant_timesheets in per_manager.items(): mail = view.render(relevant_timesheets) @@ -66,7 +64,7 @@ def manager(timesheets, config, mailer): def ceo(timesheets, config, mailer): to = config.get("mail", "ceo") # Filter only "bad" entries - relevant = [t for t in timesheets if need_manager_mail(t)] + relevant = [t for t in timesheets if utils.need_manager_mail(t)] view = CEOEmailView() mail = view.render(relevant) subject = "Warning: Timesheet overdue for {} employees".format(len(relevant)) @@ -75,8 +73,6 @@ def ceo(timesheets, config, mailer): else: print mail -def need_manager_mail(timesheet): - return not timesheet.is_submitted() or not timesheet.is_approved() def summary(timesheets): for timesheet in timesheets: diff --git a/templates/ceo.html b/templates/ceo.html index 8485009..fbdc56c 100644 --- a/templates/ceo.html +++ b/templates/ceo.html @@ -1,3 +1,3 @@ <p>Time registration status mail.</p> -$statuslist: +$statuslist diff --git a/test/templates/test_ceo_template.py b/test/templates/test_ceo_template.py index 6962a20..4bf37d0 100644 --- a/test/templates/test_ceo_template.py +++ b/test/templates/test_ceo_template.py @@ -10,10 +10,8 @@ class CEOEmailTemplateTest(unittest.TestCase): def test_ceo_email(self): result = self.template.build(timesheets=[self.not_approved, self.not_submitted]) - self.assertIn("Markus Krogh (MKR)", result) - self.assertIn("Markus Krogh (MK)", result) - self.assertIn("has not been approved by JK", result) - self.assertIn("has not been approved by JKL", result) - self.assertIn("has been submitted", result) - self.assertIn("has not been submitted", result) + self.assertIn("[Not approved] Markus Krogh (MK)", result) + self.assertIn("JK", result) + self.assertIn("[Unsubmitted] Markus Krogh (MKR)", result) + self.assertIn("JKL", result) diff --git a/test/templates/test_employee_status_template.py b/test/templates/test_employee_status_template.py index 0d37d3e..9869b81 100644 --- a/test/templates/test_employee_status_template.py +++ b/test/templates/test_employee_status_template.py @@ -1,25 +1,23 @@ -from maconomy import EmployeeStatusTemplate, Employee, Timesheet +from maconomy import EmployeeStatusListTemplate, Employee, Timesheet import unittest -class EmployeeStatusTemplateTest(unittest.TestCase): +class EmployeeStatusListTemplateTest(unittest.TestCase): def setUp(self): - self.template = EmployeeStatusTemplate() + self.template = EmployeeStatusListTemplate() self.employee = Employee.from_result(("MK", "Markus Krogh", "markus@nordu.net")) def test_substitute(self): - timesheet = Timesheet("11", 0, 0, self.employee, "JK") - result = self.template.build(timesheet) - self.assertIn("Markus Krogh (MK)", result) - self.assertIn("not been submitted", result) - self.assertIn("not been approved", result) + timesheets = [Timesheet("11", 0, 0, self.employee, "JK")] + result = self.template.build(timesheets) + self.assertIn("[Unsubmitted] Markus Krogh (MK)", result) def test_submitted(self): - timesheet = Timesheet("11", submitted=1, approved=0, employee=self.employee, approver="JK") - result = self.template.build(timesheet) - self.assertIn("has been submitted", result) + timesheets = [Timesheet("11", submitted=1, approved=0, employee=self.employee, approver="JK")] + result = self.template.build(timesheets) + self.assertIn("[Not approved] Markus Krogh (MK)", result) def test_approved(self): - timesheet = Timesheet("11", submitted=1, approved=1, employee=self.employee, approver="JK") - result = self.template.build(timesheet) - self.assertIn("has been approved", result) + timesheets = [Timesheet("11", submitted=1, approved=1, employee=self.employee, approver="JK")] + result = self.template.build(timesheets) + self.assertIn("[OK] Markus Krogh (MK)", result) diff --git a/test/templates/test_manager_template.py b/test/templates/test_manager_template.py index bdc7387..d650eb9 100644 --- a/test/templates/test_manager_template.py +++ b/test/templates/test_manager_template.py @@ -11,18 +11,14 @@ class ManagerEmailTemplateTest(unittest.TestCase): result = self.template.build( timesheets=[self.not_approved], maconomyurl="http://localhost/") - self.assertIn("Markus Krogh (MK)", result) - self.assertIn("has not been approved", result) - self.assertIn("has been submitted", result) + self.assertIn("[Not approved] Markus Krogh (MK)", result) self.assertIn("href=\"http://localhost/\"", result) def test_not_submitted(self): result = self.template.build( timesheets=[self.not_submitted], maconomyurl="http://localhost/") - self.assertIn("Markus Krogh (MKR)", result) - self.assertIn("has not been approved", result) - self.assertIn("has not been submitted", result) + self.assertIn("[Unsubmitted] Markus Krogh (MKR)", result) self.assertIn("href=\"http://localhost/\"", result) def test_multiple_timesheets(self): @@ -30,10 +26,7 @@ class ManagerEmailTemplateTest(unittest.TestCase): timesheets=[self.not_submitted, self.not_approved], maconomyurl="http://localhost/") - self.assertIn("Markus Krogh (MKR)", result) - self.assertIn("Markus Krogh (MK)", result) - self.assertIn("has not been approved", result) - self.assertIn("has been submitted", result) - self.assertIn("has not been submitted", result) + self.assertIn("[Unsubmitted] Markus Krogh (MKR)", result) + self.assertIn("[Not approved] Markus Krogh (MK)", result) self.assertIn("href=\"http://localhost/\"", result) |