mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 00:44:45 +00:00
[merge] merge with master
This commit is contained in:
@@ -18,7 +18,6 @@ from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import getdate, nowdate
|
||||
from webnotes.model.doc import make_autoname
|
||||
from webnotes import msgprint, _
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
@@ -28,9 +27,6 @@ class DocType:
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
def get_emp_name(self):
|
||||
return {
|
||||
"employee_name": webnotes.conn.get_value("Employee",
|
||||
|
||||
@@ -36,7 +36,7 @@ class DocType:
|
||||
if ret[0][0]=='Naming Series':
|
||||
self.doc.name = make_autoname(self.doc.naming_series + '.####')
|
||||
elif ret[0][0]=='Employee Number':
|
||||
self.doc.name = make_autoname(self.doc.employee_number)
|
||||
self.doc.name = self.doc.employee_number
|
||||
|
||||
self.doc.employee = self.doc.name
|
||||
|
||||
@@ -80,7 +80,7 @@ class DocType:
|
||||
if not "Employee" in webnotes.conn.sql_list("""select role from tabUserRole
|
||||
where parent=%s""", self.doc.user_id):
|
||||
from webnotes.profile import add_role
|
||||
add_role(self.doc.user_id, "HR User")
|
||||
add_role(self.doc.user_id, "Employee")
|
||||
|
||||
profile_wrapper = webnotes.bean("Profile", self.doc.user_id)
|
||||
|
||||
|
||||
@@ -335,15 +335,22 @@ def add_holidays(events, start, end, employee, company):
|
||||
def query_for_permitted_employees(doctype, txt, searchfield, start, page_len, filters):
|
||||
txt = "%" + cstr(txt) + "%"
|
||||
|
||||
return webnotes.conn.sql("""select name, employee_name from `tabEmployee` emp
|
||||
if "Leave Approver" in webnotes.user.get_roles():
|
||||
condition = """and (exists(select ela.name from `tabEmployee Leave Approver` ela
|
||||
where ela.parent=`tabEmployee`.name and ela.leave_approver= "%s") or
|
||||
not exists(select ela.name from `tabEmployee Leave Approver` ela
|
||||
where ela.parent=`tabEmployee`.name)
|
||||
or user_id = "%s")""" % (webnotes.session.user, webnotes.session.user)
|
||||
else:
|
||||
from webnotes.widgets.reportview import build_match_conditions
|
||||
condition = build_match_conditions("Employee")
|
||||
condition = ("and " + condition) if condition else ""
|
||||
|
||||
return webnotes.conn.sql("""select name, employee_name from `tabEmployee`
|
||||
where status = 'Active' and docstatus < 2 and
|
||||
(`%s` like %s or employee_name like %s) and
|
||||
(exists(select ela.name from `tabEmployee Leave Approver` ela
|
||||
where ela.parent=emp.name and ela.leave_approver=%s) or
|
||||
not exists(select ela.name from `tabEmployee Leave Approver` ela where ela.parent=emp.name)
|
||||
or user_id = %s)
|
||||
(`%s` like %s or employee_name like %s) %s
|
||||
order by
|
||||
case when name like %s then 0 else 1 end,
|
||||
case when employee_name like %s then 0 else 1 end,
|
||||
name limit %s, %s""" % tuple([searchfield] + ["%s"]*8),
|
||||
(txt, txt, webnotes.session.user, webnotes.session.user, txt, txt, start, page_len))
|
||||
name limit %s, %s""" % tuple([searchfield] + ["%s"]*2 + [condition] + ["%s"]*4),
|
||||
(txt, txt, txt, txt, start, page_len))
|
||||
|
||||
@@ -75,7 +75,6 @@ erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({
|
||||
r.messages = ["<h4 style='color:green'>Import Successful!</h4>"].
|
||||
concat(r.messages)
|
||||
}
|
||||
console.log(r.messages);
|
||||
|
||||
$.each(r.messages, function(i, v) {
|
||||
var $p = $('<p>').html(v).appendTo($log_wrapper);
|
||||
|
||||
@@ -100,7 +100,6 @@ def get_naming_series():
|
||||
def upload():
|
||||
from webnotes.utils.datautils import read_csv_content_from_uploaded_file
|
||||
from webnotes.modules import scrub
|
||||
from core.page.data_import_tool.data_import_tool import check_record, import_doc
|
||||
|
||||
rows = read_csv_content_from_uploaded_file()
|
||||
if not rows:
|
||||
@@ -112,6 +111,9 @@ def upload():
|
||||
ret = []
|
||||
error = False
|
||||
|
||||
from webnotes.utils.datautils import check_record, import_doc
|
||||
doctype_dl = webnotes.get_doctype("Attendance")
|
||||
|
||||
for i, row in enumerate(rows[5:]):
|
||||
if not row: continue
|
||||
row_idx = i + 5
|
||||
@@ -121,7 +123,7 @@ def upload():
|
||||
d["docstatus"] = webnotes.conn.get_value("Attendance", d.name, "docstatus")
|
||||
|
||||
try:
|
||||
check_record(d)
|
||||
check_record(d, doctype_dl=doctype_dl)
|
||||
ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True))
|
||||
except Exception, e:
|
||||
error = True
|
||||
|
||||
@@ -177,6 +177,14 @@ wn.module_page["HR"] = [
|
||||
"label":wn._("Employee Information"),
|
||||
route: "Report2/Employee/Employee Information"
|
||||
},
|
||||
{
|
||||
"label":wn._("Monthly Salary Register"),
|
||||
route: "query-report/Monthly Salary Register"
|
||||
},
|
||||
{
|
||||
"label":wn._("Monthly Attendance Sheet"),
|
||||
route: "query-report/Monthly Attendance Sheet"
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
0
hr/report/monthly_attendance_sheet/__init__.py
Normal file
0
hr/report/monthly_attendance_sheet/__init__.py
Normal file
@@ -0,0 +1,32 @@
|
||||
wn.query_reports["Monthly Attendance Sheet"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"month",
|
||||
"label": "Month",
|
||||
"fieldtype": "Select",
|
||||
"options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
|
||||
"default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||
"Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()],
|
||||
},
|
||||
{
|
||||
"fieldname":"fiscal_year",
|
||||
"label": "Fiscal Year",
|
||||
"fieldtype": "Link",
|
||||
"options": "Fiscal Year",
|
||||
"default": sys_defaults.fiscal_year,
|
||||
},
|
||||
{
|
||||
"fieldname":"employee",
|
||||
"label": "Employee",
|
||||
"fieldtype": "Link",
|
||||
"options": "Employee"
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": "Company",
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": sys_defaults.company
|
||||
}
|
||||
]
|
||||
}
|
||||
107
hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
Normal file
107
hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
Normal file
@@ -0,0 +1,107 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import cstr, cint
|
||||
from webnotes import msgprint, _
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
conditions, filters = get_conditions(filters)
|
||||
columns = get_columns(filters)
|
||||
att_map = get_attendance_list(conditions, filters)
|
||||
emp_map = get_employee_details()
|
||||
|
||||
data = []
|
||||
for emp in sorted(att_map):
|
||||
emp_det = emp_map.get(emp)
|
||||
row = [emp, emp_det.employee_name, emp_det.branch, emp_det.department, emp_det.designation,
|
||||
emp_det.company]
|
||||
|
||||
total_p = total_a = 0.0
|
||||
for day in range(filters["total_days_in_month"]):
|
||||
status = att_map.get(emp).get(day + 1, "Absent")
|
||||
status_map = {"Present": "P", "Absent": "A", "Half Day": "HD"}
|
||||
row.append(status_map[status])
|
||||
|
||||
if status == "Present":
|
||||
total_p += 1
|
||||
elif status == "Absent":
|
||||
total_a += 1
|
||||
elif status == "Half Day":
|
||||
total_p += 0.5
|
||||
total_a += 0.5
|
||||
|
||||
row += [total_p, total_a]
|
||||
|
||||
data.append(row)
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns(filters):
|
||||
columns = [
|
||||
"Employee:Link/Employee:120", "Employee Name::140", "Branch:Link/Branch:120",
|
||||
"Department:Link/Department:120", "Designation:Link/Designation:120",
|
||||
"Company:Link/Company:120"
|
||||
]
|
||||
|
||||
for day in range(filters["total_days_in_month"]):
|
||||
columns.append(cstr(day+1) +"::20")
|
||||
|
||||
columns += ["Total Present:Float:80", "Total Absent:Float:80"]
|
||||
return columns
|
||||
|
||||
def get_attendance_list(conditions, filters):
|
||||
attendance_list = webnotes.conn.sql("""select employee, day(att_date) as day_of_month,
|
||||
status from tabAttendance where docstatus = 1 %s order by employee, att_date""" %
|
||||
conditions, filters, as_dict=1)
|
||||
|
||||
att_map = {}
|
||||
for d in attendance_list:
|
||||
att_map.setdefault(d.employee, webnotes._dict()).setdefault(d.day_of_month, "")
|
||||
att_map[d.employee][d.day_of_month] = d.status
|
||||
|
||||
return att_map
|
||||
|
||||
def get_conditions(filters):
|
||||
if not (filters.get("month") and filters.get("fiscal_year")):
|
||||
msgprint(_("Please select month and year"), raise_exception=1)
|
||||
|
||||
filters["month"] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||
"Dec"].index(filters["month"]) + 1
|
||||
|
||||
from calendar import monthrange
|
||||
filters["total_days_in_month"] = monthrange(cint(filters["fiscal_year"].split("-")[-1]),
|
||||
filters["month"])[1]
|
||||
|
||||
conditions = " and month(att_date) = %(month)s and fiscal_year = %(fiscal_year)s"
|
||||
|
||||
if filters.get("company"): conditions += " and company = %(company)s"
|
||||
if filters.get("employee"): conditions += " and employee = %(employee)s"
|
||||
|
||||
return conditions, filters
|
||||
|
||||
def get_employee_details():
|
||||
employee = webnotes.conn.sql("""select name, employee_name, designation, department,
|
||||
branch, company from tabEmployee where docstatus < 2 and status = 'Active'""", as_dict=1)
|
||||
|
||||
emp_map = {}
|
||||
for emp in employee:
|
||||
emp_map[emp.name] = emp
|
||||
|
||||
return emp_map
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-05-13 14:04:03",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-13 14:32:42",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Attendance",
|
||||
"report_name": "Monthly Attendance Sheet",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Monthly Attendance Sheet"
|
||||
}
|
||||
]
|
||||
0
hr/report/monthly_salary_register/__init__.py
Normal file
0
hr/report/monthly_salary_register/__init__.py
Normal file
32
hr/report/monthly_salary_register/monthly_salary_register.js
Normal file
32
hr/report/monthly_salary_register/monthly_salary_register.js
Normal file
@@ -0,0 +1,32 @@
|
||||
wn.query_reports["Monthly Salary Register"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"month",
|
||||
"label": "Month",
|
||||
"fieldtype": "Select",
|
||||
"options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
|
||||
"default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||
"Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()],
|
||||
},
|
||||
{
|
||||
"fieldname":"fiscal_year",
|
||||
"label": "Fiscal Year",
|
||||
"fieldtype": "Link",
|
||||
"options": "Fiscal Year",
|
||||
"default": sys_defaults.fiscal_year,
|
||||
},
|
||||
{
|
||||
"fieldname":"employee",
|
||||
"label": "Employee",
|
||||
"fieldtype": "Link",
|
||||
"options": "Employee"
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": "Company",
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": sys_defaults.company
|
||||
}
|
||||
]
|
||||
}
|
||||
119
hr/report/monthly_salary_register/monthly_salary_register.py
Normal file
119
hr/report/monthly_salary_register/monthly_salary_register.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import flt, cstr
|
||||
from webnotes import msgprint, _
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
salary_slips = get_salary_slips(filters)
|
||||
columns, earning_types, ded_types = get_columns(salary_slips)
|
||||
ss_earning_map = get_ss_earning_map(salary_slips)
|
||||
ss_ded_map = get_ss_ded_map(salary_slips)
|
||||
|
||||
data = []
|
||||
for ss in salary_slips:
|
||||
row = [ss.employee, ss.employee_name, ss.branch, ss.department, ss.designation,
|
||||
ss.company, ss.month, ss.leave_withut_pay, ss.payment_days]
|
||||
|
||||
for e in earning_types:
|
||||
row.append(ss_earning_map.get(ss.name, {}).get(e))
|
||||
|
||||
row += [ss.arrear_amount, ss.leave_encashment_amount, ss.gross_pay]
|
||||
|
||||
for d in ded_types:
|
||||
row.append(ss_ded_map.get(ss.name, {}).get(d))
|
||||
|
||||
row += [ss.total_deduction, ss.net_pay]
|
||||
|
||||
data.append(row)
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns(salary_slips):
|
||||
columns = [
|
||||
"Employee:Link/Employee:120", "Employee Name::140", "Branch:Link/Branch:120",
|
||||
"Department:Link/Department:120", "Designation:Link/Designation:120",
|
||||
"Company:Link/Company:120", "Month::80", "Leave Without pay:Float:130",
|
||||
"Payment Days:Float:120"
|
||||
]
|
||||
|
||||
earning_types = webnotes.conn.sql_list("""select distinct e_type from `tabSalary Slip Earning`
|
||||
where ifnull(e_modified_amount, 0) != 0 and parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
||||
|
||||
ded_types = webnotes.conn.sql_list("""select distinct d_type from `tabSalary Slip Deduction`
|
||||
where ifnull(d_modified_amount, 0) != 0 and parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
||||
|
||||
columns = columns + [(e + ":Link/Earning Type:120") for e in earning_types] + \
|
||||
["Arrear Amount:Currency:120", "Leave Encashment Amount:Currency:150",
|
||||
"Gross Pay:Currency:120"] + [(d + ":Link/Deduction Type:120") for d in ded_types] + \
|
||||
["Total Deduction:Currency:120", "Net Pay:Currency:120"]
|
||||
|
||||
return columns, earning_types, ded_types
|
||||
|
||||
def get_salary_slips(filters):
|
||||
conditions, filters = get_conditions(filters)
|
||||
salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s""" %
|
||||
conditions, filters, as_dict=1)
|
||||
|
||||
if not salary_slips:
|
||||
msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) +
|
||||
_(" and year: ") + cstr(filters.get("fiscal_year")), raise_exception=1)
|
||||
|
||||
return salary_slips
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if filters.get("month"):
|
||||
month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||
"Dec"].index(filters["month"]) + 1
|
||||
filters["month"] = month
|
||||
conditions += " and month = %(month)s"
|
||||
|
||||
if filters.get("fiscal_year"): conditions += " and fiscal_year = %(fiscal_year)s"
|
||||
if filters.get("company"): conditions += " and company = %(company)s"
|
||||
if filters.get("employee"): conditions += " and employee = %(employee)s"
|
||||
|
||||
return conditions, filters
|
||||
|
||||
def get_ss_earning_map(salary_slips):
|
||||
ss_earnings = webnotes.conn.sql("""select parent, e_type, e_modified_amount
|
||||
from `tabSalary Slip Earning` where parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||
|
||||
ss_earning_map = {}
|
||||
for d in ss_earnings:
|
||||
ss_earning_map.setdefault(d.parent, webnotes._dict()).setdefault(d.e_type, [])
|
||||
ss_earning_map[d.parent][d.e_type] = flt(d.e_modified_amount)
|
||||
|
||||
return ss_earning_map
|
||||
|
||||
def get_ss_ded_map(salary_slips):
|
||||
ss_deductions = webnotes.conn.sql("""select parent, d_type, d_modified_amount
|
||||
from `tabSalary Slip Deduction` where parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||
|
||||
ss_ded_map = {}
|
||||
for d in ss_deductions:
|
||||
ss_ded_map.setdefault(d.parent, webnotes._dict()).setdefault(d.d_type, [])
|
||||
ss_ded_map[d.parent][d.e_type] = flt(d.d_modified_amount)
|
||||
|
||||
return ss_ded_map
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-05-07 18:09:42",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-07 18:09:42",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Salary Slip",
|
||||
"report_name": "Monthly Salary Register",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Monthly Salary Register"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user