how to credit leave automaticalled

my leave is not crediting automatically

so i want to write script for that can any one tell me how to implement this script

will it work or can you suggest any other option for that

import frappe
from frappe.utils import add_months, nowdate

def allocate_monthly_leaves():
employees = frappe.get_all(“Employee”, filters={“status”: “Active”})
for employee in employees:
leave_type = “Annual Leave”
leaves_per_month = 1
start_date = nowdate()
end_date = add_months(start_date, 1)

    leave_allocation = frappe.get_doc({
        "doctype": "Leave Allocation",
        "employee": employee.name,
        "leave_type": leave_type,
        "from_date": start_date,
        "to_date": end_date,
        "new_leaves_allocated": leaves_per_month
    })
    leave_allocation.save()
    frappe.db.commit()

Schedule this function to run monthly

scheduler_events = {
“monthly”: [
“path.to.your.script.allocate_monthly_leaves”
]
}

Hi @Prashanth_Kolhetkar,

Your script is perfect, there is not issue.

I tested the code:

employees = frappe.get_all("Employee", filters={"status": "Active"})

leave_type = "Casual Leave"
leaves_per_month = 1

for employee in employees:
    start_date = frappe.utils.nowdate()
    end_date = frappe.utils.add_months(start_date, 1)

    leave_allocation = frappe.get_doc({
        "doctype": "Leave Allocation",
        "employee": employee.name,
        "leave_type": leave_type,
        "from_date": start_date,
        "to_date": end_date,
        "new_leaves_allocated": leaves_per_month
    })

    leave_allocation.insert(ignore_permissions=True)
    frappe.db.commit()

It’s worked properly.

If you want to test the code then check it in the bench console, otherwise if you want to test in realtime then create a server script and set the my code.

If an error comes then go to the Scheduled Job Log

Output:

Now, set your according to the scenario.

I hope this helps.

@NCP i wrote server script waiting for one hours to execute

Click on execute, it will run in a few seconds.

error came

Traceback with variables (most recent call last):
File “apps/frappe/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py”, line 141, in execute
frappe.get_doc(“Server Script”, script_name).execute_scheduled_method()
self = <ScheduledJobType: leave_assign_by_hours_hourly>
script_name = ‘leave assign by hours’
File “apps/frappe/frappe/core/doctype/server_script/server_script.py”, line 185, in execute_scheduled_method
safe_exec(self.script, script_filename=self.name)
self = <ServerScript: leave assign by hours>
File “apps/frappe/frappe/utils/safe_exec.py”, line 111, in safe_exec
exec(
script = ‘employees = frappe.get_all(“Employee”, filters={“status”: “Active”})\n\nleave_type = “Casual Leave”\nleaves_per_month = 1\n\nfor employee in employees:\n start_date = frappe.utils.nowdate()\n end_date = frappe.utils.add_months(start_date, 1)\n\n leave_allocation = frappe.get_doc({\n “doctype”: “Leave Allocation”,\n “employee”: employee.name,\n “leave_type”: leave_type,\n “from_date”: start_date,\n “to_date”: end_date,\n “new_leaves_allocated”: leaves_per_month\n })\n\n leave_allocation.insert(ignore_permissions=True)\n frappe.db.commit()’
_globals = None
_locals = None
restrict_commit_rollback = False
script_filename = ‘leave assign by hours’
exec_globals = {‘json’: {‘loads’: <function loads at 0x7486924ec040>, ‘dumps’: <function dumps at 0x7486926d3240>}, ‘as_json’: <function as_json at 0x7486915be7a0>, ‘dict’: <class ‘dict’>, ‘log’: <function log at 0x74869170c540>, ‘_dict’: <class ‘frappe._dict’>, ‘args’: {}, ‘frappe’: {‘call’: <function call_whitelisted_function at 0x74868e11b2e0>, ‘flags’: {}, ‘format’: <function format_value at 0x7486915be980>, ‘format_value’: <function format_value at 0x7486915be980>, ‘date_format’: ‘dd-mm-yyyy’, ‘time_format’: ‘HH:mm:ss’, ‘format_date’: <function global_date_format at 0x7486916d13a0>, ‘form_dict’: {}, ‘bold’: <function bold at 0x7486915bf1a0>, ‘copy_doc’: <function copy_doc at 0x7486915be2a0>, ‘errprint’: <function errprint at 0x74869170c400>, ‘qb’: <class ‘frappe.query_builder.builder.MariaDB’>, ‘get_meta’: <function get_meta at 0x74869170e0c0>, ‘new_doc’: <function new_doc at 0x74869170d620>, ‘get_doc’: <function get_doc at 0x74869170dee0>, ‘get_mapped_doc’: <function get_mapped_doc at 0x74868e0…
filename = ‘: leave_assign_by_hours’
File “: leave_assign_by_hours”, line 19, in
json = {‘loads’: <function loads at 0x7486924ec040>, ‘dumps’: <function dumps at 0x7486926d3240>}
as_json = <function as_json at 0x7486915be7a0>
dict = <class ‘dict’>
log = <function log at 0x74869170c540>
_dict = <class ‘frappe._dict’>
args = {}
frappe = {‘call’: <function call_whitelisted_function at 0x74868e11b2e0>, ‘flags’: {}, ‘format’: <function format_value at 0x7486915be980>, ‘format_value’: <function format_value at 0x7486915be980>, ‘date_format’: ‘dd-mm-yyyy’, ‘time_format’: ‘HH:mm:ss’, ‘format_date’: <function global_date_format at 0x7486916d13a0>, ‘form_dict’: {}, ‘bold’: <function bold at 0x7486915bf1a0>, ‘copy_doc’: <function copy_doc at 0x7486915be2a0>, ‘errprint’: <function errprint at 0x74869170c400>, ‘qb’: <class ‘frappe.query_builder.builder.MariaDB’>, ‘get_meta’: <function get_meta at 0x74869170e0c0>, ‘new_doc’: <function new_doc at 0x74869170d620>, ‘get_doc’: <function get_doc at 0x74869170dee0>, ‘get_mapped_doc’: <function get_mapped_doc at 0x74868e0feb60>, ‘get_last_doc’: <function get_last_doc at 0x74869170df80>, ‘get_cached_doc’: <function get_cached_doc at 0x74869170d760>, ‘get_list’: <function get_list at 0x7486915be5c0>, ‘get_all’: <function get_all at 0x7486915be660>, ‘get_system_settings’: <function get_sys…
FrappeClient = <class ‘frappe.frappeclient.FrappeClient’>
style = {‘border_color’: ‘#d1d8dd’}
get_toc = <function get_toc at 0x74868eaf4ae0>
get_next_link = <function get_next_link at 0x74868eaf4b80>
_ = <function _ at 0x748692741e40>
scrub = <function scrub at 0x7486915bd300>
guess_mimetype = <function guess_type at 0x7486923936a0>
html2text = <function html2text at 0x74868ebe7740>
dev_server = 0
run_script = <function run_script at 0x74868e11b380>
is_job_queued = <function is_job_queued at 0x74868e11b1a0>
get_visible_columns = <function get_visible_columns at 0x74868e11a8e0>
builtins = {‘build_class’: , ‘None’: None, ‘False’: False, ‘True’: True, ‘abs’: , ‘bool’: <class ‘bool’>, ‘bytes’: <class ‘bytes’>, ‘callable’: , ‘chr’: , ‘complex’: <class ‘complex’>, ‘divmod’: , ‘float’: <class ‘float’>, ‘hash’: , ‘hex’: , ‘id’: , ‘int’: <class ‘int’>, ‘isinstance’: , ‘issubclass’: , ‘len’: , ‘oct’: , ‘ord’: , ‘pow’: , ‘range’: <class ‘range’>, ‘repr’: , ‘round’: , ‘slice’: <class ‘slice’>, ‘sorted’: , ‘str’: <class ‘str’>, ‘tuple’: <class ‘tuple’>, ‘zip’: <class ‘zip’>, ‘ArithmeticError’: <class ‘ArithmeticError’>, ‘AssertionError’: <class 'Assertion…
write = <function _write at 0x74868e11bc40>
getitem = <function _getitem at 0x74868e11b9c0>
getattr = <function _getattr_for_safe_exec at 0x74868e11ba60>
print = <class ‘frappe.utils.safe_exec.FrappePrintCollector’>
getiter =
iter_unpack_sequence = <function guarded_iter_unpack_sequence at 0x74868e1eccc0>
abs =
all =
any =
bool = <class ‘bool’>
enumerate = <class ‘enumerate’>
isinstance =
issubclass =
list = <class ‘list’>
max =
min =
range = <class ‘range’>
set = <class ‘set’>
sorted =
sum =
tuple = <class ‘tuple’>
employees = [{‘name’: ‘HR-EMP-00084’}, {‘name’: ‘HR-EMP-00006’}, {‘name’: ‘Razia Sulthana Syed’}, {‘name’: ‘HR-EMP-00002’}, {‘name’: ‘HR-EMP-00003’}, {‘name’: ‘HR-EMP-00010’}, {‘name’: ‘HR-EMP-00008’}, {‘name’: ‘HR-EMP-00075’}, {‘name’: ‘HR-EMP-00009’}, {‘name’: ‘HR-EMP-00053’}, {‘name’: ‘HR-EMP-00074’}, {‘name’: ‘HR-EMP-00083’}, {‘name’: ‘HR-EMP-00026’}, {‘name’: ‘HR-EMP-00012’}, {‘name’: ‘HR-EMP-00077’}, {‘name’: ‘HR-EMP-00061’}, {‘name’: ‘HR-EMP-00011’}, {‘name’: ‘HR-EMP-00051’}, {‘name’: ‘HR-EMP-00071’}, {‘name’: ‘HR-EMP-00044’}, {‘name’: ‘HR-EMP-00017’}, {‘name’: ‘HR-EMP-00030’}, {‘name’: ‘HR-EMP-00019’}, {‘name’: ‘HR-EMP-00029’}, {‘name’: ‘HR-EMP-00055’}, {‘name’: ‘HR-EMP-00025’}, {‘name’: ‘HR-EMP-00067’}, {‘name’: ‘HR-EMP-00013’}, {‘name’: ‘HR-EMP-00052’}, {‘name’: ‘HR-EMP-00070’}, {‘name’: ‘HR-EMP-00066’}, {‘name’: ‘HR-EMP-00068’}, {‘name’: ‘HR-EMP-00020’}, {‘name’: ‘HR-EMP-00022’}, {‘name’: ‘HR-EMP-00016’}, {‘name’: ‘HR-EMP-00048’}, {‘name’: ‘HR-EMP-00054’}, {‘name’: ‘HR-EMP-00035’}, {‘na…
leave_type = ‘Casual Leave’
leaves_per_month = 1
employee = {‘name’: ‘HR-EMP-00084’}
start_date = ‘2024-08-06’
end_date = ‘2024-09-06’
leave_allocation = <LeaveAllocation: HR-LAL-2024-00791>
File “apps/frappe/frappe/model/document.py”, line 291, in insert
self.run_before_save_methods()
self = <LeaveAllocation: HR-LAL-2024-00791>
ignore_permissions = True
ignore_links = None
ignore_if_duplicate = False
ignore_mandatory = None
set_name = None
set_child_names = True
File “apps/frappe/frappe/model/document.py”, line 1091, in run_before_save_methods
self.run_method(“validate”)
self = <LeaveAllocation: HR-LAL-2024-00791>
File “apps/frappe/frappe/model/document.py”, line 962, in run_method
out = Document.hook(fn)(self, *args, **kwargs)
self = <LeaveAllocation: HR-LAL-2024-00791>
method = ‘validate’
args = ()
kwargs = {}
fn = <function Document.run_method..fn at 0x74868deb0a40>
File “apps/frappe/frappe/model/document.py”, line 1322, in composer
return composed(self, method, args, **kwargs)
self = <LeaveAllocation: HR-LAL-2024-00791>
args = ()
kwargs = {}
hooks = [<function apply at 0x74868dfc5bc0>, <function check_for_running_deletion_job at 0x74868dfc7880>]
method = ‘validate’
doc_events = {'
’: {‘on_update’: [‘frappe.desk.notifications.clear_doctype_notifications’, ‘frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions’, ‘frappe.core.doctype.file.utils.attach_files_to_document’, ‘frappe.automation.doctype.assignment_rule.assignment_rule.apply’, ‘frappe.automation.doctype.assignment_rule.assignment_rule.update_due_date’, ‘frappe.core.doctype.user_type.user_type.apply_permissions_for_non_standard_user_type’], ‘after_rename’: [‘frappe.desk.notifications.clear_doctype_notifications’], ‘on_cancel’: [‘frappe.desk.notifications.clear_doctype_notifications’, ‘frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions’, ‘frappe.automation.doctype.assignment_rule.assignment_rule.apply’], ‘on_trash’: [‘frappe.desk.notifications.clear_doctype_notifications’, ‘frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions’], ‘on_update_after_submit’: ['frappe.workflow.doctype.workflow_action.workflow_action.process_w…
handler = ‘erpnext.setup.doctype.transaction_deletion_record.transaction_deletion_record.check_for_running_deletion_job’
composed = <function Document.hook..compose..runner at 0x74868dd700e0>
compose = <function Document.hook..compose at 0x74868dd70040>
f = <function Document.run_method..fn at 0x74868deb0a40>
File “apps/frappe/frappe/model/document.py”, line 1304, in runner
add_to_return_value(self, fn(self, *args, **kwargs))
self = <LeaveAllocation: HR-LAL-2024-00791>
method = ‘validate’
args = ()
kwargs = {}
add_to_return_value = <function Document.hook..add_to_return_value at 0x74868deb0b80>
fn = <function Document.run_method..fn at 0x74868deb0a40>
hooks = (<function apply at 0x74868dfc5bc0>, <function check_for_running_deletion_job at 0x74868dfc7880>)
File “apps/frappe/frappe/model/document.py”, line 959, in fn
return method_object(*args, **kwargs)
self = <LeaveAllocation: HR-LAL-2024-00791>
args = ()
kwargs = {}
method_object = <bound method LeaveAllocation.validate of <LeaveAllocation: HR-LAL-2024-00791>>
method = ‘validate’
File “apps/hrms/hrms/hr/doctype/leave_allocation/leave_allocation.py”, line 41, in validate
self.validate_allocation_overlap()
self = <LeaveAllocation: HR-LAL-2024-00791>
File “apps/hrms/hrms/hr/doctype/leave_allocation/leave_allocation.py”, line 206, in validate_allocation_overlap
frappe.throw(
self = <LeaveAllocation: HR-LAL-2024-00791>
leave_allocation = ((‘HR-LAL-2024-00783’,),)
File “apps/frappe/frappe/init.py”, line 645, in throw
msgprint(
msg = ‘Reference: HR-LAL-2024-00783
exc = <class ‘hrms.hr.doctype.leave_allocation.leave_allocation.OverlapError’>
title = None
is_minimizable = False
wide = False
as_list = False
primary_action = None
File “apps/frappe/frappe/init.py”, line 610, in msgprint
_raise_exception()
msg = ‘Reference: HR-LAL-2024-00783
title = None
raise_exception = <class ‘hrms.hr.doctype.leave_allocation.leave_allocation.OverlapError’>
as_table = False
as_list = False
indicator = ‘red’
alert = False
primary_action = None
is_minimizable = False
wide = False
realtime = False
sys = <module ‘sys’ (built-in)>
_raise_exception = <function msgprint.._raise_exception at 0x74868ddc6e80>
inspect = <module ‘inspect’ from ‘/usr/lib/python3.12/inspect.py’>
out = {‘message’: ‘Reference: HR-LAL-2024-00783’, ‘title’: ‘Message’, ‘indicator’: ‘red’, ‘raise_exception’: 1, ‘__frappe_exc_id’: ‘0f0e6ae742533a8f6e4fc88843f35faccf6e2cecec9aa77b83eae925’}
File “apps/frappe/frappe/init.py”, line 561, in _raise_exception
raise exc
exc = OverlapError(‘Reference: HR-LAL-2024-00783’)
inspect = <module ‘inspect’ from ‘/usr/lib/python3.12/inspect.py’>
msg = ‘Reference: HR-LAL-2024-00783
out = {‘message’: ‘Reference: HR-LAL-2024-00783’, ‘title’: ‘Message’, ‘indicator’: ‘red’, ‘raise_exception’: 1, ‘__frappe_exc_id’: ‘0f0e6ae742533a8f6e4fc88843f35faccf6e2cecec9aa77b83eae925’}
raise_exception = <class ‘hrms.hr.doctype.leave_allocation.leave_allocation.OverlapError’>
hrms.hr.doctype.leave_allocation.leave_allocation.OverlapError: Reference: HR-LAL-2024-00783

Test what I have applied first, don’t add any code to it. and don’t use the import in server script doctype. so again check my code and follow the steps that I provide.