From c10d2a00254f403d2ed33aa24ec3aa1c1f27e548 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 14 Nov 2016 10:52:01 +0530 Subject: [PATCH] [wip] daily work summary --- .../daily_work_summary.json | 19 ++-- .../daily_work_summary/daily_work_summary.py | 65 +++++++++---- .../test_daily_work_summary.py | 3 + .../daily_work_summary_response/__init__.py | 0 .../daily_work_summary_response.json | 95 ------------------- .../daily_work_summary_response.py | 10 -- .../daily_work_summary_settings.js | 5 +- .../daily_work_summary_settings.py | 15 ++- erpnext/hr/doctype/employee/employee.py | 15 ++- 9 files changed, 88 insertions(+), 139 deletions(-) delete mode 100644 erpnext/hr/doctype/daily_work_summary_response/__init__.py delete mode 100644 erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.json delete mode 100644 erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.py diff --git a/erpnext/hr/doctype/daily_work_summary/daily_work_summary.json b/erpnext/hr/doctype/daily_work_summary/daily_work_summary.json index 281a6abd16..d4de3b2e7c 100644 --- a/erpnext/hr/doctype/daily_work_summary/daily_work_summary.json +++ b/erpnext/hr/doctype/daily_work_summary/daily_work_summary.json @@ -22,7 +22,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Company", "length": 0, @@ -32,7 +32,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -45,23 +45,24 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "responses", - "fieldtype": "Table", + "default": "Open", + "fieldname": "status", + "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, - "label": "Responses", + "label": "Status", "length": 0, "no_copy": 0, - "options": "Daily Work Summary Response", + "options": "Open\nSummary Sent", "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -80,7 +81,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-11-08 06:03:21.121442", + "modified": "2016-11-10 16:09:11.619822", "modified_by": "Administrator", "module": "HR", "name": "Daily Work Summary", diff --git a/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py b/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py index d3e92e9a74..45b0c9a2fe 100644 --- a/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py +++ b/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py @@ -6,40 +6,69 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document from frappe import _ +from email_reply_parser import EmailReplyParser +from erpnext.hr.doctype.employee.employee import is_holiday class DailyWorkSummary(Document): - def send_mails(self, settings): + def send_mails(self, settings, emails): '''Send emails to get daily work summary to all employees''' - frappe.sendmail(recipients = self.get_employee_emails(), message = settings.message, - subject = settings.subject, reference_doctype=self.doctype, reference_name=self.name) + incoming_email_account = frappe.db.get_value('Email Account', + dict(enable_incoming=1, default_incoming=1), 'email_id') + frappe.sendmail(recipients = emails, message = settings.message, + subject = settings.subject, reference_doctype=self.doctype, + reference_name=self.name, reply_to = incoming_email_account) def send_summary(self): '''Send summary of all replies''' - settings = frappe.get_doc('Daily Work Summary Settings') + message = self.get_summary_message() - replies = frappe.get_doc('Communication', fields=['content', 'sender'], - filters=dict(reference_doctype=self.doctype, reference_name=self.name, - communication_type='Email', sent_or_received='Received')) - - message = frappe.render_template(template, dict(replies=replies, - original_message=settings.message)) - - frappe.sendmail(recipients = self.get_employee_emails(), message = message, + frappe.sendmail(recipients = get_employee_emails(self.company, False), message = message, subject = _('Daily Work Summary for {0}').format(self.company), reference_doctype=self.doctype, reference_name=self.name) - def get_employee_emails(self): - return filter(None, [d.user_id for d in - frappe.get_all('Employee', fields=['user_id'], - filters={'status': 'Active', 'company': self.company})]) + def get_summary_message(self): + '''Return summary of replies as HTML''' + settings = frappe.get_doc('Daily Work Summary Settings') + + replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'], + filters=dict(reference_doctype=self.doctype, reference_name=self.name, + communication_type='Communication', sent_or_received='Received')) + + if not replies: + return None + + for d in replies: + if d.text_content: + d.content = EmailReplyParser.parse_reply(d.text_content) + + return frappe.render_template(template, dict(replies=replies, + original_message=settings.message)) + +def get_employee_emails(company, only_working=True): + '''Returns list of Employee user ids for the given company who are working today + + :param company: Company `name`''' + employee_list = frappe.get_all('Employee', fields=['name', 'user_id'], + filters={'status': 'Active', 'company': company}) + + out = [] + for e in employee_list: + if e.user_id: + if only_working and is_holiday(e.name): + # don't add if holiday + pass + out.append(e.user_id) + + return out + template = '''

Summary of replies:

{% for reply in replies %} -
{{ frappe.db.get_value("Employee", reply.sender, "full_name") }}
+
{{ frappe.db.get_value("Employee", {"user_id": reply.sender}, "employee_name") or reply.sender }}
- {{ reply.content.split(original_message)[0].strip() }} + {{ reply.content }}
{% endfor %} ''' \ No newline at end of file diff --git a/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.py b/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.py index 7cc2bc2cfc..12b3e2f072 100644 --- a/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.py +++ b/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.py @@ -30,6 +30,9 @@ class TestDailyWorkSummary(unittest.TestCase): self.assertFalse(d.user_id in [d.recipient for d in emails if settings.subject in d.message]) + def test_summary(self): + pass + def setup_and_prepare_test(self, hour): frappe.db.sql('delete from `tabEmail Queue`') diff --git a/erpnext/hr/doctype/daily_work_summary_response/__init__.py b/erpnext/hr/doctype/daily_work_summary_response/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.json b/erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.json deleted file mode 100644 index b4295d4a49..0000000000 --- a/erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "allow_copy": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-11-08 04:56:39.588230", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "response", - "fieldtype": "Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Response", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "in_dialog": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2016-11-08 04:56:39.588230", - "modified_by": "Administrator", - "module": "HR", - "name": "Daily Work Summary Response", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.py b/erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.py deleted file mode 100644 index 739eaa771a..0000000000 --- a/erpnext/hr/doctype/daily_work_summary_response/daily_work_summary_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe.model.document import Document - -class DailyWorkSummaryResponse(Document): - pass diff --git a/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.js b/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.js index cb0b6086ac..f5c0a5cb16 100644 --- a/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.js +++ b/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.js @@ -2,6 +2,9 @@ // For license information, please see license.txt frappe.ui.form.on('Daily Work Summary Settings', { - onload: function(frm) { + refresh: function(frm) { + frm.add_custom_button(__('Daily Work Summary'), function() { + frappe.set_route('List', 'Daily Work Summary'); + }); } }); diff --git a/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.py b/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.py index d36f348e9f..259b976bb5 100644 --- a/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.py +++ b/erpnext/hr/doctype/daily_work_summary_settings/daily_work_summary_settings.py @@ -6,15 +6,22 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document import frappe.utils +from frappe import _ +from erpnext.hr.doctype.daily_work_summary.daily_work_summary import get_employee_emails class DailyWorkSummarySettings(Document): - pass + def validate(self): + if self.companies: + if not frappe.db.get_value('Email Account', dict(enable_incoming=1, default_incoming=1)): + frappe.throw(_('There must be a default incoming Email Account enabled for this to work. Please setup a default incoming Email Account (POP/IMAP) and try again.')) def trigger_emails(): settings = frappe.get_doc('Daily Work Summary Settings') for d in settings.companies: # if current hour if frappe.utils.nowtime().split(':')[0] == d.send_emails_at.split(':')[0]: - work_summary = frappe.get_doc(dict(doctype='Daily Work Summary', - company=d.company)).insert() - work_summary.send_mails(settings) \ No newline at end of file + emails = get_employee_emails(d.company) + if emails: + work_summary = frappe.get_doc(dict(doctype='Daily Work Summary', + company=d.company)).insert() + work_summary.send_mails(settings, emails) \ No newline at end of file diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index 2e5fb26093..e2e541bdb0 100755 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -9,7 +9,6 @@ from frappe.model.naming import make_autoname from frappe import throw, _ import frappe.permissions from frappe.model.document import Document -from frappe.model.mapper import get_mapped_doc from erpnext.utilities.transaction_base import delete_events @@ -164,7 +163,6 @@ def get_timeline_data(doctype, name): @frappe.whitelist() def get_retirement_date(date_of_birth=None): - import datetime ret = {} if date_of_birth: try: @@ -233,3 +231,16 @@ def get_holiday_list_for_employee(employee, raise_exception=True): return holiday_list +def is_holiday(employee, date=None): + '''Returns True if given Employee has an holiday on the given date + + :param employee: Employee `name` + :param date: Date to check. Will check for today if None''' + + holiday_list = get_holiday_list_for_employee(employee) + if not date: + date = today() + + if holiday_list: + return frappe.get_all('Holiday List', dict(name=holiday_list, holiday_date=date)) and True or False +