From bddc80bc66cd7e10803bfec9ad9b89e3342f407d Mon Sep 17 00:00:00 2001 From: Valmik Jangla Date: Tue, 9 Feb 2016 02:05:22 -0800 Subject: [PATCH 1/4] Make Employee from Offer Letter --- erpnext/hr/doctype/employee/employee.js | 1 - erpnext/hr/doctype/employee/employee.py | 41 ++++++++++++++----- .../doctype/job_applicant/job_applicant.json | 9 ++-- .../hr/doctype/offer_letter/offer_letter.js | 15 +++++++ .../hr/doctype/offer_letter/offer_letter.json | 18 +++++++- .../salary_structure/salary_structure.js | 0 6 files changed, 67 insertions(+), 17 deletions(-) mode change 100644 => 100755 erpnext/hr/doctype/employee/employee.py mode change 100644 => 100755 erpnext/hr/doctype/offer_letter/offer_letter.js mode change 100644 => 100755 erpnext/hr/doctype/salary_structure/salary_structure.js diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js index 8a20a09cdd..55bc7aa16c 100644 --- a/erpnext/hr/doctype/employee/employee.js +++ b/erpnext/hr/doctype/employee/employee.js @@ -11,7 +11,6 @@ erpnext.hr.EmployeeController = frappe.ui.form.Controller.extend({ }, onload: function() { - if(this.frm.doc.__islocal) this.frm.set_value("employee_name", ""); this.frm.set_query("leave_approver", "leave_approvers", function() { return { filters: [["UserRole", "role", "=", "Leave Approver"]] diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py old mode 100644 new mode 100755 index e781532e10..5cdf35344d --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -12,21 +12,24 @@ from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc from erpnext.utilities.transaction_base import delete_events -class EmployeeUserDisabledError(frappe.ValidationError): pass + +class EmployeeUserDisabledError(frappe.ValidationError): + pass + class Employee(Document): def onload(self): self.get("__onload").salary_structure_exists = frappe.db.get_value("Salary Structure", - {"employee": self.name, "is_active": "Yes", "docstatus": ["!=", 2]}) + {"employee": self.name, "is_active": "Yes", "docstatus": ["!=", 2]}) def autoname(self): naming_method = frappe.db.get_value("HR Settings", None, "emp_created_by") if not naming_method: throw(_("Please setup Employee Naming System in Human Resource > HR Settings")) else: - if naming_method=='Naming Series': + if naming_method == 'Naming Series': self.name = make_autoname(self.naming_series + '.####') - elif naming_method=='Employee Number': + elif naming_method == 'Employee Number': self.name = self.employee_number self.employee = self.name @@ -48,7 +51,8 @@ class Employee(Document): else: existing_user_id = frappe.db.get_value("Employee", self.name, "user_id") if existing_user_id: - frappe.permissions.remove_user_permission("Employee", self.name, existing_user_id) + frappe.permissions.remove_user_permission( + "Employee", self.name, existing_user_id) def on_update(self): if self.user_id: @@ -113,7 +117,7 @@ class Employee(Document): elif self.relieving_date and self.date_of_joining and (getdate(self.relieving_date) <= getdate(self.date_of_joining)): throw(_("Relieving Date must be greater than Date of Joining")) - elif self.contract_end_date and self.date_of_joining and (getdate(self.contract_end_date)<=getdate(self.date_of_joining)): + elif self.contract_end_date and self.date_of_joining and (getdate(self.contract_end_date) <= getdate(self.date_of_joining)): throw(_("Contract End Date must be greater than Date of Joining")) def validate_email(self): @@ -132,20 +136,21 @@ class Employee(Document): enabled = frappe.db.sql("""select name from `tabUser` where name=%s and enabled=1""", self.user_id) if not enabled: - throw(_("User {0} is disabled").format(self.user_id), EmployeeUserDisabledError) + throw(_("User {0} is disabled").format( + self.user_id), EmployeeUserDisabledError) def validate_duplicate_user_id(self): employee = frappe.db.sql_list("""select name from `tabEmployee` where user_id=%s and status='Active' and name!=%s""", (self.user_id, self.name)) if employee: - throw(_("User {0} is already assigned to Employee {1}").format(self.user_id, employee[0]), frappe.DuplicateEntryError) + throw(_("User {0} is already assigned to Employee {1}").format( + self.user_id, employee[0]), frappe.DuplicateEntryError) def validate_employee_leave_approver(self): for l in self.get("leave_approvers")[:]: if "Leave Approver" not in frappe.get_roles(l.leave_approver): frappe.get_doc("User", l.leave_approver).add_roles("Leave Approver") - def validate_reports_to(self): if self.reports_to == self.name: throw(_("Employee cannot report to himself.")) @@ -153,6 +158,7 @@ class Employee(Document): def on_trash(self): delete_events(self.doctype, self.name) + @frappe.whitelist() def get_retirement_date(date_of_birth=None): import datetime @@ -167,19 +173,34 @@ def get_retirement_date(date_of_birth=None): return ret + @frappe.whitelist() def make_salary_structure(source_name, target=None): target = get_mapped_doc("Employee", source_name, { "Employee": { "doctype": "Salary Structure", "field_map": { - "name": "employee" + "name": "employee", } } }) target.make_earn_ded_table() return target + +@frappe.whitelist() +def make_employee(source_name, target_doc=None): + def set_missing_values(source, target): + target.personal_email = frappe.db.get_value("Job Applicant", source.job_applicant, "email_id") + doclist = get_mapped_doc("Offer Letter", source_name, { + "Offer Letter": { + "doctype": "Employee", + "field_map": { + "applicant_name": "employee_name", + }} + }, target_doc, set_missing_values) + return doclist + def validate_employee_role(doc, method): # called via User hook if "Employee" in [d.role for d in doc.get("user_roles")]: diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.json b/erpnext/hr/doctype/job_applicant/job_applicant.json index b9660e2848..423ab7e130 100644 --- a/erpnext/hr/doctype/job_applicant/job_applicant.json +++ b/erpnext/hr/doctype/job_applicant/job_applicant.json @@ -28,7 +28,7 @@ "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -52,7 +52,7 @@ "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -76,7 +76,7 @@ "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -184,7 +184,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-06 02:36:13.556143", + "modified": "2016-02-12 00:38:31.773297", "modified_by": "Administrator", "module": "HR", "name": "Job Applicant", @@ -214,5 +214,6 @@ "read_only": 0, "read_only_onload": 0, "search_fields": "applicant_name", + "sort_order": "ASC", "title_field": "applicant_name" } \ No newline at end of file diff --git a/erpnext/hr/doctype/offer_letter/offer_letter.js b/erpnext/hr/doctype/offer_letter/offer_letter.js old mode 100644 new mode 100755 index 62cfc83bc4..552a9f0313 --- a/erpnext/hr/doctype/offer_letter/offer_letter.js +++ b/erpnext/hr/doctype/offer_letter/offer_letter.js @@ -6,5 +6,20 @@ frappe.ui.form.on("Offer Letter", { frappe.model.get_value("Terms and Conditions", frm.doc.select_terms, "terms", function(value) { frm.set_value("terms", value.terms); }); + }, + + refresh:function(frm){ + if((!frm.doc.__islocal) && (frm.doc.status=='Accepted') && (frm.doc.docstatus===1)){ + frm.add_custom_button(__('Make Employee'), + frm.cscript['Make Employee']); } +} }); + + +cur_frm.cscript['Make Employee'] = function() { +frappe.model.open_mapped_doc({ + method: "erpnext.hr.doctype.employee.employee.make_employee", + frm : cur_frm +}); +} \ No newline at end of file diff --git a/erpnext/hr/doctype/offer_letter/offer_letter.json b/erpnext/hr/doctype/offer_letter/offer_letter.json index f0000a45de..182ba5ddb5 100644 --- a/erpnext/hr/doctype/offer_letter/offer_letter.json +++ b/erpnext/hr/doctype/offer_letter/offer_letter.json @@ -27,6 +27,7 @@ "permlevel": 0, "precision": "", "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -51,6 +52,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 1, @@ -73,6 +75,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -92,11 +95,12 @@ "in_list_view": 0, "label": "Status", "length": 0, - "no_copy": 0, + "no_copy": 1, "options": "Awaiting Response\nAccepted\nRejected", "permlevel": 0, "precision": "", "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -121,6 +125,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -145,6 +150,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -169,6 +175,7 @@ "permlevel": 0, "precision": "", "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -191,6 +198,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -215,6 +223,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -237,6 +246,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -261,6 +271,7 @@ "permlevel": 0, "precision": "", "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -285,6 +296,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -308,6 +320,7 @@ "options": "Offer Letter", "permlevel": 0, "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 0, @@ -318,13 +331,14 @@ ], "hide_heading": 0, "hide_toolbar": 0, + "idx": 0, "in_create": 0, "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-11-16 06:29:50.746594", + "modified": "2016-02-12 00:33:04.068380", "modified_by": "Administrator", "module": "HR", "name": "Offer Letter", diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js old mode 100644 new mode 100755 From 93b1072cbad3577a7b5d7023e5b06ced01b74da4 Mon Sep 17 00:00:00 2001 From: Valmik Jangla Date: Tue, 16 Feb 2016 14:47:05 +0530 Subject: [PATCH 2/4] Improved code --- .../hr/doctype/offer_letter/offer_letter.js | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/erpnext/hr/doctype/offer_letter/offer_letter.js b/erpnext/hr/doctype/offer_letter/offer_letter.js index 552a9f0313..526833a4ce 100755 --- a/erpnext/hr/doctype/offer_letter/offer_letter.js +++ b/erpnext/hr/doctype/offer_letter/offer_letter.js @@ -1,6 +1,8 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt +frappe.provide("erpnext.offer_letter"); + frappe.ui.form.on("Offer Letter", { select_terms: function(frm) { frappe.model.get_value("Terms and Conditions", frm.doc.select_terms, "terms", function(value) { @@ -10,16 +12,20 @@ frappe.ui.form.on("Offer Letter", { refresh:function(frm){ if((!frm.doc.__islocal) && (frm.doc.status=='Accepted') && (frm.doc.docstatus===1)){ - frm.add_custom_button(__('Make Employee'), - frm.cscript['Make Employee']); - } -} + frm.add_custom_button(__('Make Employee'), + function() { + erpnext.offer_letter.make_employee(frm) + } + ); + } + } + }); -cur_frm.cscript['Make Employee'] = function() { -frappe.model.open_mapped_doc({ - method: "erpnext.hr.doctype.employee.employee.make_employee", - frm : cur_frm -}); +erpnext.offer_letter.make_employee = function(frm) { + frappe.model.open_mapped_doc({ + method: "erpnext.hr.doctype.employee.employee.make_employee", + frm : frm + }); } \ No newline at end of file From 5e771c5678c2e156b9db901b9a07d747b9e3a201 Mon Sep 17 00:00:00 2001 From: Valmik Jangla Date: Tue, 16 Feb 2016 14:52:16 +0530 Subject: [PATCH 3/4] Changed doclist to doc --- erpnext/hr/doctype/employee/employee.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index 5cdf35344d..a8b7d8f6ad 100755 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -192,14 +192,14 @@ def make_salary_structure(source_name, target=None): def make_employee(source_name, target_doc=None): def set_missing_values(source, target): target.personal_email = frappe.db.get_value("Job Applicant", source.job_applicant, "email_id") - doclist = get_mapped_doc("Offer Letter", source_name, { + doc = get_mapped_doc("Offer Letter", source_name, { "Offer Letter": { "doctype": "Employee", "field_map": { "applicant_name": "employee_name", }} }, target_doc, set_missing_values) - return doclist + return doc def validate_employee_role(doc, method): # called via User hook From 870d0441a88ca3020bf9d796f2d6ec027dbb3ff2 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 16 Feb 2016 15:53:09 +0530 Subject: [PATCH 4/4] [minor] moved make_employee from Employee to Offer Letter --- erpnext/hr/doctype/employee/employee.py | 14 -------------- erpnext/hr/doctype/offer_letter/offer_letter.js | 11 +++++------ erpnext/hr/doctype/offer_letter/offer_letter.py | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index a8b7d8f6ad..a2b56fcb82 100755 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -187,20 +187,6 @@ def make_salary_structure(source_name, target=None): target.make_earn_ded_table() return target - -@frappe.whitelist() -def make_employee(source_name, target_doc=None): - def set_missing_values(source, target): - target.personal_email = frappe.db.get_value("Job Applicant", source.job_applicant, "email_id") - doc = get_mapped_doc("Offer Letter", source_name, { - "Offer Letter": { - "doctype": "Employee", - "field_map": { - "applicant_name": "employee_name", - }} - }, target_doc, set_missing_values) - return doc - def validate_employee_role(doc, method): # called via User hook if "Employee" in [d.role for d in doc.get("user_roles")]: diff --git a/erpnext/hr/doctype/offer_letter/offer_letter.js b/erpnext/hr/doctype/offer_letter/offer_letter.js index 526833a4ce..643eaa88e7 100755 --- a/erpnext/hr/doctype/offer_letter/offer_letter.js +++ b/erpnext/hr/doctype/offer_letter/offer_letter.js @@ -18,14 +18,13 @@ frappe.ui.form.on("Offer Letter", { } ); } - } + } }); - -erpnext.offer_letter.make_employee = function(frm) { +erpnext.offer_letter.make_employee = function(frm) { frappe.model.open_mapped_doc({ - method: "erpnext.hr.doctype.employee.employee.make_employee", - frm : frm + method: "erpnext.hr.doctype.offer_letter.offer_letter.make_employee", + frm: frm }); -} \ No newline at end of file +}; diff --git a/erpnext/hr/doctype/offer_letter/offer_letter.py b/erpnext/hr/doctype/offer_letter/offer_letter.py index b3eb865f14..f3479287f9 100644 --- a/erpnext/hr/doctype/offer_letter/offer_letter.py +++ b/erpnext/hr/doctype/offer_letter/offer_letter.py @@ -4,6 +4,21 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document +from frappe.model.mapper import get_mapped_doc class OfferLetter(Document): pass + +@frappe.whitelist() +def make_employee(source_name, target_doc=None): + def set_missing_values(source, target): + target.personal_email = frappe.db.get_value("Job Applicant", source.job_applicant, "email_id") + doc = get_mapped_doc("Offer Letter", source_name, { + "Offer Letter": { + "doctype": "Employee", + "field_map": { + "applicant_name": "employee_name", + }} + }, target_doc, set_missing_values) + return doc +