Payroll Entry - Validate Attendance (#14738)
This commit is contained in:
parent
7324815fdb
commit
a10f118ddd
@ -185,6 +185,23 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
validate_attendance: function(frm){
|
||||
if(frm.doc.validate_attendance && frm.doc.employees){
|
||||
frappe.call({
|
||||
method: 'validate_employee_attendance',
|
||||
args: {},
|
||||
callback: function(r) {
|
||||
render_employee_attendance(frm, r.message);
|
||||
},
|
||||
doc: frm.doc,
|
||||
freeze: true,
|
||||
freeze_message: 'Validating Employee Attendance...'
|
||||
});
|
||||
}else{
|
||||
frm.fields_dict.attendance_detail_html.html("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Submit salary slips
|
||||
@ -214,6 +231,9 @@ cur_frm.cscript.get_employee_details = function (doc) {
|
||||
var callback = function (r) {
|
||||
if (r.docs[0].employees){
|
||||
cur_frm.refresh_field('employees');
|
||||
if(r.docs[0].validate_attendance){
|
||||
render_employee_attendance(cur_frm, r.message);
|
||||
}
|
||||
}
|
||||
};
|
||||
return $c('runserverobj', { 'method': 'fill_employee_details', 'docs': doc }, callback);
|
||||
@ -237,3 +257,12 @@ let make_bank_entry = function (frm) {
|
||||
frappe.msgprint(__("Company, Payment Account, From Date and To Date is mandatory"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let render_employee_attendance = function(frm, data) {
|
||||
frm.fields_dict.attendance_detail_html.html(
|
||||
frappe.render_template('employees_to_mark_attendance', {
|
||||
data: data
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -46,6 +47,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -77,6 +79,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -110,6 +113,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -142,6 +146,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -176,6 +181,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -207,6 +213,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -239,6 +246,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -271,6 +279,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -303,6 +312,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -333,6 +343,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -364,6 +375,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -396,6 +408,101 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_13",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "validate_attendance",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Validate Attendance",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "attendance_detail_html",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -426,6 +533,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -459,6 +567,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -490,6 +599,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -522,6 +632,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -554,6 +665,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -584,6 +696,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -615,6 +728,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -646,6 +760,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -677,6 +792,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -709,6 +825,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -739,6 +856,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -771,6 +889,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -802,6 +921,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -833,6 +953,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -866,6 +987,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -896,6 +1018,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -927,6 +1050,7 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -968,7 +1092,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-04-27 12:42:45.054509",
|
||||
"modified": "2018-06-28 13:55:48.295327",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Payroll Entry",
|
||||
|
@ -6,16 +6,21 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from frappe.utils import cint, flt, nowdate, add_days, getdate, fmt_money, add_to_date, DATE_FORMAT
|
||||
from frappe.utils import cint, flt, nowdate, add_days, getdate, fmt_money, add_to_date, DATE_FORMAT, date_diff
|
||||
from frappe import _
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
|
||||
from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
|
||||
|
||||
class PayrollEntry(Document):
|
||||
|
||||
def on_submit(self):
|
||||
self.create_salary_slips()
|
||||
|
||||
def before_submit(self):
|
||||
if self.validate_attendance:
|
||||
if self.validate_employee_attendance():
|
||||
frappe.throw(_("Cannot Submit, Employees left to mark attendance"))
|
||||
|
||||
def get_emp_list(self):
|
||||
"""
|
||||
Returns list of active employees based on selected criteria
|
||||
@ -61,6 +66,9 @@ class PayrollEntry(Document):
|
||||
for d in employees:
|
||||
self.append('employees', d)
|
||||
|
||||
if self.validate_attendance:
|
||||
return self.validate_employee_attendance()
|
||||
|
||||
def get_filter_condition(self):
|
||||
self.check_mandatory()
|
||||
|
||||
@ -381,6 +389,39 @@ class PayrollEntry(Document):
|
||||
self.update(get_start_end_dates(self.payroll_frequency,
|
||||
self.start_date or self.posting_date, self.company))
|
||||
|
||||
def validate_employee_attendance(self):
|
||||
employees_to_mark_attendance = []
|
||||
days_in_payroll, days_holiday, days_attendance_marked = 0, 0, 0
|
||||
for employee_detail in self.employees:
|
||||
days_holiday = self.get_count_holidays_of_employee(employee_detail.employee)
|
||||
days_attendance_marked = self.get_count_employee_attendance(employee_detail.employee)
|
||||
days_in_payroll = date_diff(self.end_date, self.start_date) + 1
|
||||
if days_in_payroll > days_holiday + days_attendance_marked:
|
||||
employees_to_mark_attendance.append({
|
||||
"employee": employee_detail.employee,
|
||||
"employee_name": employee_detail.employee_name
|
||||
})
|
||||
return employees_to_mark_attendance
|
||||
|
||||
def get_count_holidays_of_employee(self, employee):
|
||||
holiday_list = get_holiday_list_for_employee(employee)
|
||||
holidays = 0
|
||||
if holiday_list:
|
||||
days = frappe.db.sql("""select count(*) from tabHoliday where
|
||||
parent=%s and holiday_date between %s and %s""", (holiday_list,
|
||||
self.start_date, self.end_date))
|
||||
if days and days[0][0]:
|
||||
holidays = days[0][0]
|
||||
return holidays
|
||||
|
||||
def get_count_employee_attendance(self, employee):
|
||||
marked_days = 0
|
||||
attendances = frappe.db.sql("""select count(*) from tabAttendance where
|
||||
employee=%s and docstatus=1 and attendance_date between %s and %s""",
|
||||
(employee, self.start_date, self.end_date))
|
||||
if attendances and attendances[0][0]:
|
||||
marked_days = attendances[0][0]
|
||||
return marked_days
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_start_end_dates(payroll_frequency, start_date=None, company=None):
|
||||
|
@ -30,6 +30,7 @@
|
||||
"public/js/payment/pos_payment.html",
|
||||
"public/js/payment/payment_details.html",
|
||||
"public/js/templates/item_selector.html",
|
||||
"public/js/templates/employees_to_mark_attendance.html",
|
||||
"public/js/utils/item_selector.js",
|
||||
"public/js/help_links.js",
|
||||
"public/js/agriculture/ternary_plot.js",
|
||||
|
@ -0,0 +1,14 @@
|
||||
{% if data %}
|
||||
<div class="col-md-12 col-xs-12" align="center">
|
||||
<div class="col-md-12 col-xs-12" style="padding-bottom:15px;">
|
||||
<b>Employees to mark attendance</b>
|
||||
</div>
|
||||
{% for item in data %}
|
||||
<div class="col-md-4 col-xs-6" style="padding-bottom:10px;">
|
||||
{{ item.employee }} {{ item.employee_name }}
|
||||
</div>
|
||||
{% } %}
|
||||
</div>
|
||||
{% } else { %}
|
||||
<div></div>
|
||||
{% } %}
|
Loading…
x
Reference in New Issue
Block a user