mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-12 03:15:07 +00:00
feat(employee): Create User button and form.
(cherry picked from commit 3b521b74ea)
This commit is contained in:
committed by
Mergify
parent
cd1dfeeab3
commit
cd0a25ca17
@@ -45,6 +45,54 @@ frappe.ui.form.on("Employee", {
|
|||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
frm.fields_dict.date_of_birth.datepicker.update({ maxDate: new Date() });
|
frm.fields_dict.date_of_birth.datepicker.update({ maxDate: new Date() });
|
||||||
|
|
||||||
|
if (!frm.is_new() && !frm.doc.user_id) {
|
||||||
|
frm.add_custom_button(__("Create User"), () => {
|
||||||
|
const dialog = new frappe.ui.Dialog({
|
||||||
|
title: __("Create User"),
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldtype: "Data",
|
||||||
|
fieldname: "email",
|
||||||
|
label: __("Email"),
|
||||||
|
reqd: 1,
|
||||||
|
default: frm.doc.company_email || frm.doc.personal_email || frm.doc.user_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Check",
|
||||||
|
fieldname: "create_user_permission",
|
||||||
|
label: __("Create User Permission"),
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
primary_action_label: __("Create"),
|
||||||
|
primary_action: (values) => {
|
||||||
|
if (!values.email) {
|
||||||
|
frappe.msgprint(__("Email is required to create a user."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe
|
||||||
|
.call({
|
||||||
|
method: "erpnext.setup.doctype.employee.employee.create_user",
|
||||||
|
args: {
|
||||||
|
employee: frm.doc.name,
|
||||||
|
email: values.email,
|
||||||
|
create_user_permission: values.create_user_permission ? 1 : 0,
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
freeze_message: __("Creating User..."),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
dialog.hide();
|
||||||
|
frm.reload_doc();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
prefered_contact_email: function (frm) {
|
prefered_contact_email: function (frm) {
|
||||||
@@ -77,24 +125,6 @@ frappe.ui.form.on("Employee", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
create_user: function (frm) {
|
|
||||||
if (!frm.doc.prefered_email) {
|
|
||||||
frappe.throw(__("Please enter Preferred Contact Email"));
|
|
||||||
}
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.setup.doctype.employee.employee.create_user",
|
|
||||||
args: {
|
|
||||||
employee: frm.doc.name,
|
|
||||||
email: frm.doc.prefered_email,
|
|
||||||
},
|
|
||||||
freeze: true,
|
|
||||||
freeze_message: __("Creating User..."),
|
|
||||||
callback: function (r) {
|
|
||||||
frm.reload_doc();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cur_frm.cscript = new erpnext.setup.EmployeeController({
|
cur_frm.cscript = new erpnext.setup.EmployeeController({
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
"status",
|
"status",
|
||||||
"erpnext_user",
|
"erpnext_user",
|
||||||
"user_id",
|
"user_id",
|
||||||
"create_user",
|
|
||||||
"create_user_permission",
|
"create_user_permission",
|
||||||
"company_details_section",
|
"company_details_section",
|
||||||
"company",
|
"company",
|
||||||
@@ -285,12 +284,6 @@
|
|||||||
"label": "User ID",
|
"label": "User ID",
|
||||||
"options": "User"
|
"options": "User"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:(!doc.user_id)",
|
|
||||||
"fieldname": "create_user",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"label": "Create User"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"depends_on": "user_id",
|
"depends_on": "user_id",
|
||||||
@@ -823,7 +816,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-08-29 11:52:12.819878",
|
"modified": "2026-02-16 13:06:01.752904",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Employee",
|
"name": "Employee",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from frappe.permissions import (
|
|||||||
get_doc_permissions,
|
get_doc_permissions,
|
||||||
remove_user_permission,
|
remove_user_permission,
|
||||||
)
|
)
|
||||||
from frappe.utils import cstr, getdate, today, validate_email_address
|
from frappe.utils import cint, cstr, getdate, today, validate_email_address
|
||||||
from frappe.utils.nestedset import NestedSet
|
from frappe.utils.nestedset import NestedSet
|
||||||
|
|
||||||
from erpnext.utilities.transaction_base import delete_events
|
from erpnext.utilities.transaction_base import delete_events
|
||||||
@@ -23,6 +23,93 @@ class InactiveEmployeeStatusError(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class Employee(NestedSet):
|
class Employee(NestedSet):
|
||||||
|
# begin: auto-generated types
|
||||||
|
# This code is auto-generated. Do not modify anything in this block.
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from frappe.types import DF
|
||||||
|
|
||||||
|
from erpnext.setup.doctype.employee_education.employee_education import EmployeeEducation
|
||||||
|
from erpnext.setup.doctype.employee_external_work_history.employee_external_work_history import (
|
||||||
|
EmployeeExternalWorkHistory,
|
||||||
|
)
|
||||||
|
from erpnext.setup.doctype.employee_internal_work_history.employee_internal_work_history import (
|
||||||
|
EmployeeInternalWorkHistory,
|
||||||
|
)
|
||||||
|
|
||||||
|
attendance_device_id: DF.Data | None
|
||||||
|
bank_ac_no: DF.Data | None
|
||||||
|
bank_name: DF.Data | None
|
||||||
|
bio: DF.TextEditor | None
|
||||||
|
blood_group: DF.Literal["", "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]
|
||||||
|
branch: DF.Link | None
|
||||||
|
cell_number: DF.Data | None
|
||||||
|
company: DF.Link
|
||||||
|
company_email: DF.Data | None
|
||||||
|
contract_end_date: DF.Date | None
|
||||||
|
create_user_permission: DF.Check
|
||||||
|
ctc: DF.Currency
|
||||||
|
current_accommodation_type: DF.Literal["", "Rented", "Owned"]
|
||||||
|
current_address: DF.SmallText | None
|
||||||
|
date_of_birth: DF.Date
|
||||||
|
date_of_issue: DF.Date | None
|
||||||
|
date_of_joining: DF.Date
|
||||||
|
date_of_retirement: DF.Date | None
|
||||||
|
department: DF.Link | None
|
||||||
|
designation: DF.Link | None
|
||||||
|
education: DF.Table[EmployeeEducation]
|
||||||
|
emergency_phone_number: DF.Data | None
|
||||||
|
employee: DF.Data | None
|
||||||
|
employee_name: DF.Data | None
|
||||||
|
employee_number: DF.Data | None
|
||||||
|
encashment_date: DF.Date | None
|
||||||
|
external_work_history: DF.Table[EmployeeExternalWorkHistory]
|
||||||
|
family_background: DF.SmallText | None
|
||||||
|
feedback: DF.SmallText | None
|
||||||
|
final_confirmation_date: DF.Date | None
|
||||||
|
first_name: DF.Data
|
||||||
|
gender: DF.Link
|
||||||
|
health_details: DF.SmallText | None
|
||||||
|
held_on: DF.Date | None
|
||||||
|
holiday_list: DF.Link | None
|
||||||
|
iban: DF.Data | None
|
||||||
|
image: DF.AttachImage | None
|
||||||
|
internal_work_history: DF.Table[EmployeeInternalWorkHistory]
|
||||||
|
last_name: DF.Data | None
|
||||||
|
leave_encashed: DF.Literal["", "Yes", "No"]
|
||||||
|
lft: DF.Int
|
||||||
|
marital_status: DF.Literal["", "Single", "Married", "Divorced", "Widowed"]
|
||||||
|
middle_name: DF.Data | None
|
||||||
|
naming_series: DF.Literal["HR-EMP-"]
|
||||||
|
new_workplace: DF.Data | None
|
||||||
|
notice_number_of_days: DF.Int
|
||||||
|
old_parent: DF.Data | None
|
||||||
|
passport_number: DF.Data | None
|
||||||
|
permanent_accommodation_type: DF.Literal["", "Rented", "Owned"]
|
||||||
|
permanent_address: DF.SmallText | None
|
||||||
|
person_to_be_contacted: DF.Data | None
|
||||||
|
personal_email: DF.Data | None
|
||||||
|
place_of_issue: DF.Data | None
|
||||||
|
prefered_contact_email: DF.Literal["", "Company Email", "Personal Email", "User ID"]
|
||||||
|
prefered_email: DF.Data | None
|
||||||
|
reason_for_leaving: DF.SmallText | None
|
||||||
|
relation: DF.Data | None
|
||||||
|
relieving_date: DF.Date | None
|
||||||
|
reports_to: DF.Link | None
|
||||||
|
resignation_letter_date: DF.Date | None
|
||||||
|
rgt: DF.Int
|
||||||
|
salary_currency: DF.Link | None
|
||||||
|
salary_mode: DF.Literal["", "Bank", "Cash", "Cheque"]
|
||||||
|
salutation: DF.Link | None
|
||||||
|
scheduled_confirmation_date: DF.Date | None
|
||||||
|
status: DF.Literal["Active", "Inactive", "Suspended", "Left"]
|
||||||
|
unsubscribed: DF.Check
|
||||||
|
user_id: DF.Link | None
|
||||||
|
valid_upto: DF.Date | None
|
||||||
|
# end: auto-generated types
|
||||||
|
|
||||||
nsm_parent_field = "reports_to"
|
nsm_parent_field = "reports_to"
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
@@ -310,9 +397,28 @@ def deactivate_sales_person(status=None, employee=None):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_user(employee, user=None, email=None):
|
def create_user(employee, user=None, email=None, create_user_permission=0):
|
||||||
|
if not employee:
|
||||||
|
frappe.throw(_("Employee is required"))
|
||||||
|
|
||||||
emp = frappe.get_doc("Employee", employee)
|
emp = frappe.get_doc("Employee", employee)
|
||||||
|
|
||||||
|
if email:
|
||||||
|
email = cstr(email).strip().lower()
|
||||||
|
else:
|
||||||
|
email = emp.prefered_email
|
||||||
|
|
||||||
|
if not email:
|
||||||
|
frappe.throw(_("Email is required to create a user"))
|
||||||
|
|
||||||
|
validate_email_address(email, True)
|
||||||
|
|
||||||
|
if emp.user_id:
|
||||||
|
frappe.throw(_("Employee {0} already has a linked user").format(emp.name))
|
||||||
|
|
||||||
|
if frappe.db.exists("User", email):
|
||||||
|
frappe.throw(_("User {0} already exists").format(email))
|
||||||
|
|
||||||
employee_name = emp.employee_name.split(" ")
|
employee_name = emp.employee_name.split(" ")
|
||||||
middle_name = last_name = ""
|
middle_name = last_name = ""
|
||||||
|
|
||||||
@@ -324,14 +430,14 @@ def create_user(employee, user=None, email=None):
|
|||||||
|
|
||||||
first_name = employee_name[0]
|
first_name = employee_name[0]
|
||||||
|
|
||||||
if email:
|
frappe.db.set_value("Employee", emp.name, "user_id", email, update_modified=False)
|
||||||
emp.prefered_email = email
|
frappe.db.commit()
|
||||||
|
|
||||||
user = frappe.new_doc("User")
|
user = frappe.new_doc("User")
|
||||||
user.update(
|
user.update(
|
||||||
{
|
{
|
||||||
"name": emp.employee_name,
|
"name": emp.employee_name,
|
||||||
"email": emp.prefered_email,
|
"email": email,
|
||||||
"enabled": 1,
|
"enabled": 1,
|
||||||
"first_name": first_name,
|
"first_name": first_name,
|
||||||
"middle_name": middle_name,
|
"middle_name": middle_name,
|
||||||
@@ -340,11 +446,31 @@ def create_user(employee, user=None, email=None):
|
|||||||
"birth_date": emp.date_of_birth,
|
"birth_date": emp.date_of_birth,
|
||||||
"phone": emp.cell_number,
|
"phone": emp.cell_number,
|
||||||
"bio": emp.bio,
|
"bio": emp.bio,
|
||||||
|
"send_welcome_email": 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
user.insert()
|
user.append_roles("Employee")
|
||||||
emp.user_id = user.name
|
user.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
emp.reload()
|
||||||
|
emp.company_email = email
|
||||||
|
if not emp.prefered_contact_email:
|
||||||
|
emp.prefered_contact_email = "Company Email"
|
||||||
emp.save()
|
emp.save()
|
||||||
|
|
||||||
|
if cint(create_user_permission):
|
||||||
|
if not frappe.db.exists(
|
||||||
|
"User Permission",
|
||||||
|
{"allow": "Employee", "for_value": emp.name, "user": user.name},
|
||||||
|
):
|
||||||
|
add_user_permission("Employee", emp.name, user.name)
|
||||||
|
|
||||||
|
if not frappe.db.exists(
|
||||||
|
"User Permission",
|
||||||
|
{"allow": "Company", "for_value": emp.company, "user": user.name},
|
||||||
|
):
|
||||||
|
add_user_permission("Company", emp.company, user.name)
|
||||||
|
|
||||||
return user.name
|
return user.name
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user