Dhia Shalabi
Dhia Shalabi

Reputation: 1540

Frappe save objects in another doctype based on the base doctype?

I am tring to trigger an event to save doctype data based on another doctype.

This is how my doctype are:

  1. Employee has a Job Role.
  2. Job Role has tow doctypes as Table 'Job Role Course Item' and 'Job Role Skill Item'.
  3. 'Job Role Course Item' is a Table type linked with 'Course Template'.
  4. 'Job Role Skill Item' ia a Table type linked with 'Skill'.

What I want to achiave is this:

  1. When use saves data into db usign Frappe in the Employee DocType I want to save the data also into another two DocTypes 'Course Assignment' and 'Employee Skill'.
  2. This will achive by using the Job Role that is linked with the Employee DocType as Table field.
  3. Also I have another issue is that when I save the DocType for the first time it tells me that DocType doesn't exsists.

Please Note:

My code is working and what I need is to replace the inner for to search just for the Courses or Skills in the 'Job Role', 'Course Assignmant' or 'Employee Skill' that is not prsented in the 'Course Assignmant' and 'Employee Skill' based on name and employee.

This is my whole code for the Employee DocType.

import frappe
from frappe import _
from frappe.model.document import Document


class Employee(Document):
    def before_save(self):
        if not self.full_name:
            self.full_name = ((self.first_name + ' ' if self.first_name else '') + (self.middle_name + ' ' if self.middle_name else '') + (self.last_name if self.last_name else '')).strip()
        if self._doc_before_save:
            if self._doc_before_save.job_roles != self.job_roles: self.trigger_job_roles()
        # DocType dosn't exsists if the DocType of saved as first time.
        else: self.trigger_job_roles()

    def validate(self):
        if (self.work_start_date and self.work_end_date):
            if (self.work_start_date >= self.work_end_date):
                frappe.throw(_('The Work End Date should be greater than the Work Start Date'))

    def trigger_job_roles(self):
        frappe.enqueue(
            "medad_tms.trainee_management.doctype.employee.employee.assign_employee",
            doc=self,
        )


def assign_employee(doc):
    try:
        for job_role in doc.job_roles:
            for course in frappe.get_doc("Job Role", job_role.job_role).required_courses: # I want to replace this to enhance the code performace.
                if not frappe.db.exists("Course Assignment", f"{course.course}-{doc.related_user}"):
                    course_doc = frappe.new_doc("Course Assignment")
                    course_doc.trainee = doc.related_user
                    course_doc.course = course.course
                    course_doc.source = "Job Role"
                    course_doc.due_date = frappe.get_doc("Course Template", course.course).start_date
                    course_doc.insert()
            for skill in frappe.get_doc("Job Role", job_role.job_role).required_skills: # I want to replace this to enhance the code performace.
                if not frappe.db.exists("Employee Skill", f"{doc.name}-{skill.skill}"):
                    skill_doc = frappe.new_doc("Employee Skill")
                    skill_doc.employee = doc.name
                    skill_doc.skill = skill.skill
                    skill_doc.skill_type = "Training Programs"
                    skill_doc.proficiency_scale_level = 1
                    skill_doc.required_scale_level = 5
                    skill_doc.insert()
        frappe.db.commit()
        frappe.publish_realtime(
            "assign_employee",
            {"progress": 1, "total": 3,
                "message": "Assigning Courses and Skills to Employee"},
            user=frappe.session.user,
            after_commit=True,
        )
    except Exception:
        frappe.db.rollback()
        frappe.log_error(frappe.get_traceback(), "Employee")
        frappe.throw(_("Error in Assigning Courses and Skills to Employee"))

Upvotes: 0

Views: 1346

Answers (1)

Yosef Ali
Yosef Ali

Reputation: 1

To optimize the code, you mentioned that you want to replace the inner loop that retrieves courses and skills from the 'Job Role' doctype. Assuming that you want to retrieve only the courses and skills that are not already present in the 'Course Assignment' and 'Employee Skill' doctypes

def assign_employee(doc):
try:
    for job_role in doc.job_roles:
        job_role_doc = frappe.get_doc("Job Role", job_role.job_role)
        course_assignment_names = [ca.course for ca in frappe.get_all("Course Assignment", filters={"trainee": doc.related_user}, pluck="course")]
        employee_skill_names = [es.skill for es in frappe.get_all("Employee Skill", filters={"employee": doc.name}, pluck="skill")]

        for course_item in job_role_doc.required_courses:
            course = course_item.course
            if course not in course_assignment_names:
                course_doc = frappe.new_doc("Course Assignment")
                course_doc.trainee = doc.related_user
                course_doc.course = course
                course_doc.source = "Job Role"
                course_doc.due_date = frappe.get_value("Course Template", course, "start_date")
                course_doc.insert()

        for skill_item in job_role_doc.required_skills:
            skill = skill_item.skill
            if skill not in employee_skill_names:
                skill_doc = frappe.new_doc("Employee Skill")
                skill_doc.employee = doc.name
                skill_doc.skill = skill
                skill_doc.skill_type = "Training Programs"
                skill_doc.proficiency_scale_level = 1
                skill_doc.required_scale_level = 5
                skill_doc.insert()

    frappe.db.commit()
    frappe.publish_realtime(
        "assign_employee",
        {"progress": 1, "total": 3, "message": "Assigning Courses and Skills to Employee"},
        user=frappe.session.user,
        after_commit=True,
    )
except Exception:
    frappe.db.rollback()
    frappe.log_error(frappe.get_traceback(), "Employee")
    frappe.throw(_("Error in Assigning Courses and Skills to Employee"))

Upvotes: 0

Related Questions