Improve email format for training event, add ui test

This commit is contained in:
Ben Cornwell-Mott 2017-07-25 04:49:14 -07:00 committed by Rushabh Mehta
parent a5cb9ae8bd
commit e9dbafcc10
7 changed files with 237 additions and 15 deletions

View File

@ -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()
]);
});

View File

@ -17,5 +17,37 @@ frappe.ui.form.on('Training Event', {
frappe.set_route("List", "Training Feedback"); 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;
}

View File

@ -25,7 +25,7 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 1,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Event Name", "label": "Event Name",
"length": 0, "length": 0,
@ -55,7 +55,7 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Event Status", "label": "Event Status",
"length": 0, "length": 0,
@ -115,12 +115,12 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Type", "label": "Type",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Seminar\nTheory\nWorkshop\nConference\nExam\nInternet", "options": "Seminar\nTheory\nWorkshop\nConference\nExam\nInternet\nSelf-Study",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -386,7 +386,7 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Location", "label": "Location",
"length": 0, "length": 0,
@ -612,6 +612,37 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 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_bulk_edit": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
@ -684,7 +715,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-05-29 06:13:38.411039", "modified": "2017-07-25 01:43:53.189382",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Training Event", "name": "Training Event",

View File

@ -6,14 +6,21 @@ from __future__ import unicode_literals
import frappe import frappe
from frappe import _ from frappe import _
from frappe.model.document import Document 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): class TrainingEvent(Document):
def on_update(self): def on_update(self):
self.invite_employee() if self.docstatus == 1:
self.invite_employee()
def on_update_after_submit(self): def on_update_after_submit(self):
self.invite_employee() self.invite_employee()
def invite_employee(self): def invite_employee(self):
if self.event_status == "Scheduled" and self.send_email: 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}."""\ 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: for emp in self.employees:
if emp.status== "Open": if emp.status== "Open":
frappe.sendmail(frappe.db.get_value("Employee", emp.employee, "company_email"), \ self.send_training_mail(emp)
subject=subject, content= self.introduction) emp.status= "Invited"
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")

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
"beta": 0, "beta": 0,
@ -11,6 +12,7 @@
"editable_grid": 1, "editable_grid": 1,
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -21,6 +23,7 @@
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Employee", "label": "Employee",
@ -40,6 +43,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -50,6 +54,7 @@
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Employee Name", "label": "Employee Name",
@ -69,6 +74,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -79,6 +85,7 @@
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"length": 0, "length": 0,
@ -96,6 +103,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -107,6 +115,7 @@
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Status", "label": "Status",
@ -124,19 +133,50 @@
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"unique": 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_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 0, "idx": 0,
"image_view": 0, "image_view": 0,
"in_create": 0, "in_create": 0,
"in_dialog": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-12-14 11:43:40.996578", "modified": "2017-07-25 01:41:28.915089",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Training Event Employee", "name": "Training Event Employee",
@ -146,7 +186,9 @@
"quick_entry": 1, "quick_entry": 1,
"read_only": 0, "read_only": 0,
"read_only_onload": 0, "read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 0,
"track_seen": 0 "track_seen": 0
} }

View File

@ -0,0 +1,20 @@
<h3>{{_("Training Event")}}</h3>
<p>{{ message }}</p>
<h4>{{_("Details")}}</h4>
{{_("Event Name")}}: <a href="{{ event_link }}">{{ name }}</a>
<br>{{_("Event Location")}}: {{ location }}
<br>{{_("Start Time")}}: {{ start_time }}
<br>{{_("End Time")}}: {{ end_time }}
<br>{{_("Attendance")}}: {{ attendance }}
<h4>{{_("Update Response")}}</h4>
<p>{{_("Please update your status for this training event")}}:</p>
{% if not self_study %}
<form action="{{ confirm_link }}"><input style="display:inline-block" type="submit" value="Confirm Attendance" /></form>
<form action="{{ reject_link }}"><input style="display:inline-block" type="submit" value="Reject Invitation" /></form>
{% else %}
<form action="{{ complete_link }}"><input style="display:inline-block" type="submit" value="Completed Training" /></form>
{% endif %}
<p>{{_("Thank you")}},<br>
{{ user_fullname }}</p>

View File

@ -29,6 +29,7 @@ erpnext/manufacturing/doctype/bom/test_bom.js
erpnext/projects/doctype/project/project_timesheet.js erpnext/projects/doctype/project/project_timesheet.js
erpnext/hr/doctype/holiday_list/test_holiday_list.js erpnext/hr/doctype/holiday_list/test_holiday_list.js
erpnext/hr/doctype/branch/test_branch.js erpnext/hr/doctype/branch/test_branch.js
<<<<<<< a5cb9ae8bdd7c810bf3241ea7525d378b91b05a4
erpnext/hr/doctype/leave_block_list/test_leave_block_list.js erpnext/hr/doctype/leave_block_list/test_leave_block_list.js
erpnext/hr/doctype/department/test_department.js erpnext/hr/doctype/department/test_department.js
erpnext/hr/doctype/designation/test_designation.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/supplier/test_supplier.js
erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.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.js
erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_taxes_and_charges.js 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