Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Formula-based Final Score calculation in Appraisals #1670

Merged
merged 12 commits into from
May 29, 2024

Conversation

vinyselopal
Copy link
Contributor

@vinyselopal vinyselopal commented Apr 16, 2024

Description: Added field in Appraisal Cycle to calculate final score for an employee appraisal using custom formula. Checking the field makes "Final Score Formula" field visible wherein you can add a Python Expression using autocompletion suggestions for various Employee master, Appraisal and Appraisal Cycle fields. This will automatically calculate the final score when creating new Appraisal

image

appraisal

Closes #690

docs: https://frappehr.com/docs/v14/en/appraisal-cycle

@ruchamahabal ruchamahabal changed the title Appraisal enhancement feat: Formula-based Final Score calculation in Appraisals Apr 17, 2024

if based_on_formula == 1:
final_score = eval(sanitized_formula, vars)
else:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Push this up before doing anything related to the formula. Non-formula eval is lighter so makes sense to check and execute that first.

@@ -178,9 +179,35 @@ def calculate_avg_feedback_score(self, update=False):
self.db_update()

def calculate_final_score(self):
final_score = (flt(self.total_score) + flt(self.avg_feedback_score) + flt(self.self_score)) / 3
if self.appraisal_cycle:
apraisal_cycle_doc = frappe.get_doc("Appraisal Cycle", self.appraisal_cycle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
apraisal_cycle_doc = frappe.get_doc("Appraisal Cycle", self.appraisal_cycle)
appraisal_cycle_doc = frappe.get_doc("Appraisal Cycle", self.appraisal_cycle)

fix typo everywhere

Comment on lines 189 to 203
appraisal_cycle_fields = apraisal_cycle_doc.as_dict()
employee_fields = employee_doc.as_dict()

sanitized_formula = sanitize_expression(formula)

vars = {
"goal_score": flt(self.total_score),
"average_feedback_score": flt(self.avg_feedback_score),
"self_appraisal_score": flt(self.self_score),
}

vars.update(appraisal_cycle_fields)
vars.update(employee_fields)

vars = {key: flt(value) for (key, value) in vars.items()}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
appraisal_cycle_fields = apraisal_cycle_doc.as_dict()
employee_fields = employee_doc.as_dict()
sanitized_formula = sanitize_expression(formula)
vars = {
"goal_score": flt(self.total_score),
"average_feedback_score": flt(self.avg_feedback_score),
"self_appraisal_score": flt(self.self_score),
}
vars.update(appraisal_cycle_fields)
vars.update(employee_fields)
vars = {key: flt(value) for (key, value) in vars.items()}
sanitized_formula = sanitize_expression(formula)
data = frappe._dict({
"goal_score": flt(self.total_score),
"average_feedback_score": flt(self.avg_feedback_score),
"self_appraisal_score": flt(self.self_score),
})
data.update(appraisal_cycle_doc.as_dict())
data.update(self.as_dict())
data.update(employee_doc.as_dict())
  • updating as_dict() directly here saving some extra variables
  • lets call vars -> data?
  • Appraisal fields should also be available for eval -> added self.as_dict()
  • Do we really need the flt() casting on line number 203. Not all fields in vars are float right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added flt because, adding some field that wasnt a float in expression was throwing incompatible data types error. e.g. employee.employee_name

hrms/hr/doctype/appraisal_cycle/appraisal_cycle.js Outdated Show resolved Hide resolved
@ruchamahabal ruchamahabal marked this pull request as ready for review April 17, 2024 07:15
@vinyselopal vinyselopal reopened this Apr 18, 2024
@vinyselopal vinyselopal force-pushed the appraisal-enhancement branch 2 times, most recently from 9516507 to 51a688b Compare April 18, 2024 12:15
Comment on lines 185 to 188
appraisal_cycle_doc = frappe.get_doc("Appraisal Cycle", self.appraisal_cycle)
employee_doc = frappe.get_doc("Employee", self.employee)

formula = appraisal_cycle_doc.final_score_formula
based_on_formula = appraisal_cycle_doc.calculate_final_score_based_on_formula
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this inside the else block. We don't need this at all if its not based on formula. For the formula checkbox you can do a db call directly instead of get_doc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved the statements not required to calculate the condition inside else block

hrms/hr/doctype/appraisal/appraisal.py Outdated Show resolved Hide resolved
hrms/hr/doctype/appraisal_cycle/appraisal_cycle.js Outdated Show resolved Hide resolved
hrms/public/js/hrms.bundle.js Outdated Show resolved Hide resolved
@vinyselopal vinyselopal force-pushed the appraisal-enhancement branch 2 times, most recently from 012e060 to cc42051 Compare April 23, 2024 06:43
@ruchamahabal ruchamahabal merged commit adb4c57 into frappe:develop May 29, 2024
9 checks passed
ruchamahabal added a commit that referenced this pull request May 29, 2024
…1670

feat: Formula-based Final Score calculation in Appraisals (backport #1670)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Important Appraisal Enhancement: Formula based appraisals
2 participants