From e9dbafcc106f352742cce686cc315bb27f1b1ae7 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Tue, 25 Jul 2017 04:49:14 -0700 Subject: [PATCH] Improve email format for training event, add ui test --- .../training_event/test_training_event.js | 36 ++++++++++ .../doctype/training_event/training_event.js | 32 +++++++++ .../training_event/training_event.json | 43 ++++++++++-- .../doctype/training_event/training_event.py | 70 +++++++++++++++++-- .../training_event_employee.json | 46 +++++++++++- erpnext/templates/emails/training_event.html | 20 ++++++ erpnext/tests/ui/tests.txt | 5 +- 7 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 erpnext/hr/doctype/training_event/test_training_event.js create mode 100644 erpnext/templates/emails/training_event.html diff --git a/erpnext/hr/doctype/training_event/test_training_event.js b/erpnext/hr/doctype/training_event/test_training_event.js new file mode 100644 index 00000000000..c8310947c16 --- /dev/null +++ b/erpnext/hr/doctype/training_event/test_training_event.js @@ -0,0 +1,36 @@ +QUnit.module('hr'); + +QUnit.test("test: Training Event", function (assert) { + // number of asserts + assert.expect(1); + let done = assert.async(); + + frappe.run_serially([ + // insert a new Training Event + () => frappe.set_route("List", "Training Event", "List"), + () => frappe.new_doc("Training Event"), + () => frappe.timeout(1), + () => frappe.click_link('Edit in full page'), + () => cur_frm.set_value("event_name", "Test Event"), + () => cur_frm.set_value("start_time", "2017-07-26, 2:00 pm PDT"), + () => cur_frm.set_value("end_time", "2017-07-26, 2:30 pm PDT"), + () => cur_frm.set_value("introduction", "This is a test report"), + () => cur_frm.set_value("location", "Fake office"), + () => cur_frm.set_value("send_email", 0), + () => frappe.click_button('Add Row'), + () => { + cur_frm.fields_dict.employees.grid.grid_rows[0].doc.attendance = "Optional"; + }, + () => frappe.click_button('Save'), + () => frappe.timeout(1), + () => frappe.click_button('Submit'), + () => frappe.timeout(1), + () => frappe.click_button('Yes'), + () => frappe.timeout(1), + () => { + assert.equal(cur_frm.doc.docstatus, 1); + }, + () => done() + ]); + +}); diff --git a/erpnext/hr/doctype/training_event/training_event.js b/erpnext/hr/doctype/training_event/training_event.js index ebe0c7907ce..86a4eaf0ae2 100644 --- a/erpnext/hr/doctype/training_event/training_event.js +++ b/erpnext/hr/doctype/training_event/training_event.js @@ -17,5 +17,37 @@ frappe.ui.form.on('Training Event', { frappe.set_route("List", "Training Feedback"); }); } + }, + onload: function(frm) { + var params = getSearchParameters(); + if (params.hasOwnProperty('employee') && params.hasOwnProperty('status')) { + var newTemp = frm.doc.employees.filter(function(obj) { + return obj.name == params.employee + }); + if (newTemp) { + newTemp[0].status = params.status; + frm.refresh_field("employees"); + frappe.msgprint(__(frm.doc.name + ": Status for " + newTemp[0].employee_name + + " is updated to " + newTemp[0].status)); + frappe.route_options = {}; + frappe.set_route("List", "Training Event"); + } + } } }); + +function getSearchParameters() { + var prmstr = window.location.href.split('?')[2]; + return prmstr != null && prmstr != "" ? transformToAssocArray(prmstr) : {}; +} + +function transformToAssocArray( prmstr ) { + var params = {}; + var prmarr = prmstr.split("&"); + for ( var i = 0; i < prmarr.length; i++) { + var tmparr = prmarr[i].split("="); + params[tmparr[0]] = tmparr[1]; + } + return params; +} + diff --git a/erpnext/hr/doctype/training_event/training_event.json b/erpnext/hr/doctype/training_event/training_event.json index 03b58b48021..0b13bc27b57 100644 --- a/erpnext/hr/doctype/training_event/training_event.json +++ b/erpnext/hr/doctype/training_event/training_event.json @@ -25,7 +25,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Event Name", "length": 0, @@ -55,7 +55,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 1, "label": "Event Status", "length": 0, @@ -115,12 +115,12 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 1, "label": "Type", "length": 0, "no_copy": 0, - "options": "Seminar\nTheory\nWorkshop\nConference\nExam\nInternet", + "options": "Seminar\nTheory\nWorkshop\nConference\nExam\nInternet\nSelf-Study", "permlevel": 0, "precision": "", "print_hide": 0, @@ -386,7 +386,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 1, "label": "Location", "length": 0, @@ -612,6 +612,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.send_email", + "fieldname": "include_attachments", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Include Attachments", + "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 + }, { "allow_bulk_edit": 0, "allow_on_submit": 1, @@ -684,7 +715,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-05-29 06:13:38.411039", + "modified": "2017-07-25 01:43:53.189382", "modified_by": "Administrator", "module": "HR", "name": "Training Event", diff --git a/erpnext/hr/doctype/training_event/training_event.py b/erpnext/hr/doctype/training_event/training_event.py index 27ae8cf5491..f2860c78cae 100644 --- a/erpnext/hr/doctype/training_event/training_event.py +++ b/erpnext/hr/doctype/training_event/training_event.py @@ -6,14 +6,21 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document +from frappe.desk.form.load import get_attachments +from frappe.core.doctype.communication.email import make +from frappe.utils.user import get_user_fullname +from frappe.utils import get_url_to_form + +STANDARD_USERS = ("Guest", "Administrator") class TrainingEvent(Document): def on_update(self): - self.invite_employee() - + if self.docstatus == 1: + self.invite_employee() + def on_update_after_submit(self): self.invite_employee() - + def invite_employee(self): if self.event_status == "Scheduled" and self.send_email: subject = _("""You are invited for to attend {0} - {1} scheduled from {2} to {3} at {4}."""\ @@ -21,6 +28,57 @@ class TrainingEvent(Document): for emp in self.employees: if emp.status== "Open": - frappe.sendmail(frappe.db.get_value("Employee", emp.employee, "company_email"), \ - subject=subject, content= self.introduction) - emp.status= "Invited" \ No newline at end of file + self.send_training_mail(emp) + emp.status= "Invited" + + def get_link(self, employee, status): + return get_url_to_form("Training Event",self.name) + "?employee=" + employee + "&status=" + status + + def send_training_mail(self, data): + full_name = get_user_fullname(frappe.session['user']) + if full_name == "Guest": + full_name = "Administrator" + + args = { + 'message': frappe.render_template(self.introduction, data.as_dict()), + 'confirm_link': self.get_link(data.name, "Confirmed"), + 'reject_link': self.get_link(data.name, "Withdrawn"), + 'complete_link': self.get_link(data.name, "Attended"), + 'event_link': get_url_to_form("Training Event",self.name), + 'self_study': 1 if self.type == "Self-Study" else 0, + 'attendance': data.attendance, + 'user_fullname': full_name + } + + args.update(self.as_dict()) + subject = _("Training Event") + template = "templates/emails/training_event.html" + sender = frappe.session.user not in STANDARD_USERS and frappe.session.user or None + message = frappe.get_template(template).render(args) + attachments = self.get_attachments() + + self.send_invitation_email(data, sender, subject, message, attachments) + + def send_invitation_email(self, data, sender, subject, message, attachments): + email = frappe.db.get_value("Employee", data.employee, "company_email") + if email: + make(subject = subject, content=message,recipients=email, + sender=sender,attachments = attachments, send_email=True, + doctype=self.doctype, name=self.name)["name"] + frappe.msgprint(_("Email sent to {0}").format(data.employee_name)) + + def get_attachments(self): + if self.include_attachments: + attachments = [d.name for d in get_attachments(self.doctype, self.name)] + else: + attachments = [] + return attachments + +@frappe.whitelist(allow_guest=True) +def set_response(event, response): + doc = frappe.get_doc('Training Event Employee', event) + + if doc: + doc.status = response + doc.save() + frappe.msgprint("Status for this training event as been updated") \ No newline at end of file diff --git a/erpnext/hr/doctype/training_event_employee/training_event_employee.json b/erpnext/hr/doctype/training_event_employee/training_event_employee.json index 575d0e75822..b2f51f73ed0 100644 --- a/erpnext/hr/doctype/training_event_employee/training_event_employee.json +++ b/erpnext/hr/doctype/training_event_employee/training_event_employee.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -11,6 +12,7 @@ "editable_grid": 1, "fields": [ { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -21,6 +23,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, "label": "Employee", @@ -40,6 +43,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -50,6 +54,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Employee Name", @@ -69,6 +74,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -79,6 +85,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "length": 0, @@ -96,6 +103,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, @@ -107,6 +115,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, "label": "Status", @@ -124,19 +133,50 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "attendance", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Attendance", + "length": 0, + "no_copy": 0, + "options": "Mandatory\nOptional", + "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 } ], + "has_web_view": 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-12-14 11:43:40.996578", + "modified": "2017-07-25 01:41:28.915089", "modified_by": "Administrator", "module": "HR", "name": "Training Event Employee", @@ -146,7 +186,9 @@ "quick_entry": 1, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", + "track_changes": 0, "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/templates/emails/training_event.html b/erpnext/templates/emails/training_event.html new file mode 100644 index 00000000000..6e733fb60d0 --- /dev/null +++ b/erpnext/templates/emails/training_event.html @@ -0,0 +1,20 @@ +

{{_("Training Event")}}

+

{{ message }}

+ +

{{_("Details")}}

+{{_("Event Name")}}: {{ name }} +
{{_("Event Location")}}: {{ location }} +
{{_("Start Time")}}: {{ start_time }} +
{{_("End Time")}}: {{ end_time }} +
{{_("Attendance")}}: {{ attendance }} + +

{{_("Update Response")}}

+

{{_("Please update your status for this training event")}}:

+{% if not self_study %} +
+
+{% else %} +
+{% endif %} +

{{_("Thank you")}},
+{{ user_fullname }}

diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt index 0bc61fa88d7..38074d0d9ee 100644 --- a/erpnext/tests/ui/tests.txt +++ b/erpnext/tests/ui/tests.txt @@ -29,6 +29,7 @@ erpnext/manufacturing/doctype/bom/test_bom.js erpnext/projects/doctype/project/project_timesheet.js erpnext/hr/doctype/holiday_list/test_holiday_list.js erpnext/hr/doctype/branch/test_branch.js +<<<<<<< a5cb9ae8bdd7c810bf3241ea7525d378b91b05a4 erpnext/hr/doctype/leave_block_list/test_leave_block_list.js erpnext/hr/doctype/department/test_department.js erpnext/hr/doctype/designation/test_designation.js @@ -82,4 +83,6 @@ erpnext/schools/doctype/assessment_result_tool/test_assessment_result_tool.js erpnext/buying/doctype/supplier/test_supplier.js erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.js erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js -erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_taxes_and_charges.js \ No newline at end of file +erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_taxes_and_charges.js +erpnext/manufacturing/doctype/bom/test_bom.js +erpnext/hr/doctype/training_event/test_training_event.js