diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index a078ef2033b..bb90be4f85e 100755 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -289,3 +289,13 @@ def create_user(employee, user = None): }) user.insert() return user.name + +def get_employee_emails(employee_list): + '''Returns list of employee emails either based on user_id or company_email''' + employee_emails = [] + for employee in employee_list: + user, email = frappe.db.get_value('Employee', employee, ['user_id', 'company_email']) + if user or email: + employee_emails.append(user or email) + + return employee_emails \ No newline at end of file diff --git a/erpnext/hr/doctype/training_event/training_event.js b/erpnext/hr/doctype/training_event/training_event.js index c3bb5b19c48..6a6e8fe0a6a 100644 --- a/erpnext/hr/doctype/training_event/training_event.js +++ b/erpnext/hr/doctype/training_event/training_event.js @@ -17,36 +17,5 @@ frappe.ui.form.on('Training Event', { frappe.set_route("List", "Training Feedback"); }); } - }, - onload: function(frm) { - var params = get_search_parameters(); - 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(__('{0}: Status for {1} is updated to {2}', [frm.doc.name, newTemp[0].employee_name, newTemp[0].status])); - frappe.route_options = {}; - frappe.set_route("List", "Training Event"); - } - } } -}); - -function get_search_parameters() { - 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; -} - +}); \ No newline at end of file diff --git a/erpnext/hr/doctype/training_event/training_event.json b/erpnext/hr/doctype/training_event/training_event.json index 0b13bc27b57..7be9d974fe6 100644 --- a/erpnext/hr/doctype/training_event/training_event.json +++ b/erpnext/hr/doctype/training_event/training_event.json @@ -581,68 +581,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Will send an email about the event to employees with status 'Open'", - "fieldname": "send_email", - "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": "Send Email", - "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": 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, @@ -703,6 +641,37 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "employee_emails", + "fieldtype": "Small Text", + "hidden": 1, + "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 Emails", + "length": 0, + "no_copy": 0, + "options": "Email", + "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, @@ -715,7 +684,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-07-25 01:43:53.189382", + "modified": "2017-08-11 03:11:25.768563", "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 4323f3ab274..cc568414a03 100644 --- a/erpnext/hr/doctype/training_event/training_event.py +++ b/erpnext/hr/doctype/training_event/training_event.py @@ -3,82 +3,10 @@ # For license information, please see license.txt 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") +from erpnext.hr.doctype.employee.employee import get_employee_emails class TrainingEvent(Document): - def on_update(self): - 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}."""\ - .format(self.type, self.event_name, self.start_time, self.end_time, self.location)) - - for emp in self.employees: - if emp.status== "Open": - 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) - 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 + def validate(self): + self.employee_emails = ', '.join(get_employee_emails([d.employee + for d in self.employees])) 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 b2f51f73ed0..a8a72b1a701 100644 --- a/erpnext/hr/doctype/training_event_employee/training_event_employee.json +++ b/erpnext/hr/doctype/training_event_employee/training_event_employee.json @@ -121,7 +121,7 @@ "label": "Status", "length": 0, "no_copy": 1, - "options": "Open\nInvited\nConfirmed\nAttended\nWithdrawn", + "options": "Open\nInvited\nCompleted\nFeedback Submitted", "permlevel": 0, "precision": "", "print_hide": 0, @@ -176,7 +176,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-07-25 01:41:28.915089", + "modified": "2017-08-11 03:36:22.738253", "modified_by": "Administrator", "module": "HR", "name": "Training Event Employee", diff --git a/erpnext/hr/doctype/training_feedback/training_feedback.py b/erpnext/hr/doctype/training_feedback/training_feedback.py index 2a0403bd53a..20a3bc5652e 100644 --- a/erpnext/hr/doctype/training_feedback/training_feedback.py +++ b/erpnext/hr/doctype/training_feedback/training_feedback.py @@ -5,6 +5,19 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document +from frappe import _ class TrainingFeedback(Document): - pass + def validate(self): + training_event = frappe.get_doc("Training Event", self.training_event) + if training_event.docstatus != 1: + frappe.throw(_('{0} must be submitted').format(_('Training Event'))) + + def on_submit(self): + training_event = frappe.get_doc("Training Event", self.training_event) + for e in training_event.employees: + if e.employee == self.employee: + training_event.status = 'Feedback Submitted' + break + + training_event.update_after_submit() diff --git a/erpnext/hr/doctype/training_result/test_training_result.js b/erpnext/hr/doctype/training_result/test_training_result.js new file mode 100644 index 00000000000..cb1d7fb27a3 --- /dev/null +++ b/erpnext/hr/doctype/training_result/test_training_result.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Training Result", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Training Result + () => frappe.tests.make('Training Result', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/hr/doctype/training_result/training_result.json b/erpnext/hr/doctype/training_result/training_result.json index e5fbb5fd426..41142b59e69 100644 --- a/erpnext/hr/doctype/training_result/training_result.json +++ b/erpnext/hr/doctype/training_result/training_result.json @@ -26,7 +26,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": "Training Event", "length": 0, @@ -133,6 +133,37 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "employee_emails", + "fieldtype": "Small Text", + "hidden": 1, + "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 Emails", + "length": 0, + "no_copy": 0, + "options": "Email", + "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, @@ -145,7 +176,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-06-15 08:16:01.566531", + "modified": "2017-08-11 03:53:21.283968", "modified_by": "Administrator", "module": "HR", "name": "Training Result", diff --git a/erpnext/hr/doctype/training_result/training_result.py b/erpnext/hr/doctype/training_result/training_result.py index 36c3cb93bc1..7cdc51f8010 100644 --- a/erpnext/hr/doctype/training_result/training_result.py +++ b/erpnext/hr/doctype/training_result/training_result.py @@ -6,19 +6,27 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document +from erpnext.hr.doctype.employee.employee import get_employee_emails class TrainingResult(Document): + def validate(self): + training_event = frappe.get_doc("Training Event", self.training_event) + if training_event.docstatus != 1: + frappe.throw(_('{0} must be submitted').format(_('Training Event'))) + + self.employee_emails = ', '.join(get_employee_emails([d.employee + for d in self.employees])) + def on_submit(self): - self.send_result() - - def send_result(self): - for emp in self.employees: - message = "Thank You for attending {0}.".format(self.training_event) - if emp.grade: - message = message + "Your grade: {0}".format(emp.grade) - frappe.sendmail(frappe.db.get_value("Employee", emp.employee, "company_email"), \ - subject=_("{0} Results".format(self.training_event)), \ - content=message) + training_event = frappe.get_doc("Training Event", self.training_event) + training_event.status = 'Completed' + for e in self.employees: + for e1 in training_event.employees: + if e1.employee == e.employee: + e1.status = 'Completed' + break + + training_event.save() @frappe.whitelist() def get_employees(training_event): diff --git a/erpnext/hr/email_alert/__init__.py b/erpnext/hr/email_alert/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/hr/email_alert/training_feedback/__init__.py b/erpnext/hr/email_alert/training_feedback/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/hr/email_alert/training_feedback/training_feedback.html b/erpnext/hr/email_alert/training_feedback/training_feedback.html new file mode 100644 index 00000000000..fd8fef9e82c --- /dev/null +++ b/erpnext/hr/email_alert/training_feedback/training_feedback.html @@ -0,0 +1,6 @@ +
{{ _("Hello") }},
+ +You attended training {{ frappe.utils.get_link_to_form( + "Training Event", doc.training_event) }}
+ +{{ _("Please share your feedback to the training by clicking on 'Training Feedback' and then 'New'") }}
\ No newline at end of file diff --git a/erpnext/hr/email_alert/training_feedback/training_feedback.json b/erpnext/hr/email_alert/training_feedback/training_feedback.json new file mode 100644 index 00000000000..aabf9c0eb60 --- /dev/null +++ b/erpnext/hr/email_alert/training_feedback/training_feedback.json @@ -0,0 +1,24 @@ +{ + "attach_print": 0, + "creation": "2017-08-11 03:17:11.769210", + "days_in_advance": 0, + "docstatus": 0, + "doctype": "Email Alert", + "document_type": "Training Result", + "enabled": 1, + "event": "Submit", + "idx": 0, + "is_standard": 1, + "message": "{{ message }}
\n\n{{ message }}
+ +{{ doc.introduction }}
+ +{{ message }}
\n\n{{ message }}
+ +{{ message }}
- -{{_("Please update your status for this training event")}}:
- - -{% else %} -{{_("Please confirm once you have completed your training")}}:
- -{% endif %} -{{_("Thank you")}},
-{{ user_fullname }}