mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-03 20:29:09 +00:00
Fixed merge conflict
This commit is contained in:
@@ -1,6 +1,62 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Process Payroll", {
|
||||
refresh: function(frm) {
|
||||
frm.disable_save();
|
||||
frm.trigger("toggle_fields");
|
||||
frm.trigger("set_month_dates");
|
||||
},
|
||||
|
||||
month: function(frm) {
|
||||
frm.trigger("set_month_dates");
|
||||
},
|
||||
|
||||
fiscal_year: function(frm) {
|
||||
frm.trigger("set_month_dates");
|
||||
},
|
||||
|
||||
salary_slip_based_on_timesheet: function(frm) {
|
||||
frm.trigger("toggle_fields")
|
||||
},
|
||||
|
||||
toggle_fields: function(frm) {
|
||||
frm.toggle_display(['from_date','to_date'],
|
||||
cint(frm.doc.salary_slip_based_on_timesheet)==1);
|
||||
frm.toggle_display(['fiscal_year', 'month'],
|
||||
cint(frm.doc.salary_slip_based_on_timesheet)==0);
|
||||
},
|
||||
|
||||
set_month_dates: function(frm) {
|
||||
if (!frm.doc.salary_slip_based_on_timesheet){
|
||||
frappe.call({
|
||||
method:'erpnext.hr.doctype.process_payroll.process_payroll.get_month_details',
|
||||
args:{
|
||||
year: frm.doc.fiscal_year,
|
||||
month: frm.doc.month
|
||||
},
|
||||
callback: function(r){
|
||||
if (r.message){
|
||||
frm.set_value('from_date', r.message.month_start_date);
|
||||
frm.set_value('to_date', r.message.month_end_date);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
cur_frm.cscript.onload = function(doc,cdt,cdn){
|
||||
if(!doc.month) {
|
||||
var today=new Date();
|
||||
month = (today.getMonth()+01).toString();
|
||||
if(month.length>1) doc.month = month;
|
||||
else doc.month = '0'+month;
|
||||
}
|
||||
if(!doc.fiscal_year) doc.fiscal_year = sys_defaults['fiscal_year'];
|
||||
refresh_many(['month', 'fiscal_year']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.display_activity_log = function(msg) {
|
||||
if(!cur_frm.ss_html)
|
||||
cur_frm.ss_html = $a(cur_frm.fields_dict['activity_log'].wrapper,'div');
|
||||
@@ -26,7 +82,7 @@ cur_frm.cscript.create_salary_slip = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.display_activity_log("");
|
||||
|
||||
frappe.confirm(__("Do you really want to Submit all Salary Slip for month {0} and year {1}", [doc.month, doc.fiscal_year]), function() {
|
||||
frappe.confirm(__("Do you really want to Submit all Salary Slip for Account {0} from {1} to {2}", [doc.payment_account, doc.from_date, doc.to_date]), function() {
|
||||
// clear all in locals
|
||||
if(locals["Salary Slip"]) {
|
||||
$.each(locals["Salary Slip"], function(name, d) {
|
||||
@@ -44,22 +100,45 @@ cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_bank_entry = function(doc,cdt,cdn){
|
||||
if(doc.company && doc.month && doc.fiscal_year){
|
||||
cur_frm.cscript.make_jv(doc, cdt, cdn);
|
||||
if(doc.company && doc.from_date && doc.to_date){
|
||||
return cur_frm.cscript.reference_entry(doc,cdt,cdn);
|
||||
} else {
|
||||
msgprint(__("Company, Month and Fiscal Year is mandatory"));
|
||||
msgprint(__("Company, From Date and To Date is mandatory"));
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_jv = function(doc, dt, dn) {
|
||||
return $c_obj(doc, 'make_journal_entry', '', function(r) {
|
||||
var doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
cur_frm.cscript.reference_entry = function(doc,cdt,cdn){
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: __("Bank Transaction Reference"),
|
||||
fields: [
|
||||
{
|
||||
"label": __("Reference Number"),
|
||||
"fieldname": "reference_number",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"label": __("Reference Date"),
|
||||
"fieldname": "reference_date",
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
"default": get_today()
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
frappe.ui.form.on("Process Payroll", {
|
||||
refresh: function(frm) {
|
||||
frm.disable_save();
|
||||
}
|
||||
})
|
||||
dialog.set_primary_action(__("Make"), function() {
|
||||
args = dialog.get_values();
|
||||
if(!args) return;
|
||||
dialog.hide();
|
||||
return frappe.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "make_journal_entry",
|
||||
args: {"reference_number": args.reference_number, "reference_date":args.reference_date},
|
||||
callback: function(r) {
|
||||
if (r.message)
|
||||
cur_frm.cscript.display_activity_log(r.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
@@ -8,11 +8,13 @@
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break0",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -37,6 +39,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@@ -61,6 +64,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -86,6 +90,59 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Today",
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Posting Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "branch",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -111,30 +168,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "department",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -160,6 +194,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "designation",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -185,6 +220,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -209,9 +245,10 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "salary_slip_based_on_timesheet",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -234,14 +271,15 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "select_payroll_year_and_month",
|
||||
"columns": 0,
|
||||
"fieldname": "select_payroll_period",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Select Payroll Year and Month",
|
||||
"label": "Select Payroll Period",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -259,6 +297,33 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "From",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -284,6 +349,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@@ -308,6 +374,33 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "To",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "month",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@@ -333,32 +426,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"default": "Today",
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Posting Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "process_payroll",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -384,6 +452,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@@ -408,6 +477,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Creates salary slip for above mentioned criteria.",
|
||||
"fieldname": "create_salary_slip",
|
||||
"fieldtype": "Button",
|
||||
@@ -433,6 +503,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@@ -457,6 +528,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Submit all salary slips for the above selected criteria",
|
||||
"fieldname": "submit_salary_slip",
|
||||
"fieldtype": "Button",
|
||||
@@ -482,16 +554,19 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "column_break4",
|
||||
"fieldtype": "Column Break",
|
||||
"columns": 0,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
@@ -499,13 +574,42 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"width": "25%"
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select Payment Account to make Bank Entry",
|
||||
"fieldname": "payment_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Payment Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "payment_account",
|
||||
"description": "Create Bank Entry for the total salary paid for the above selected criteria",
|
||||
"fieldname": "make_bank_entry",
|
||||
"fieldtype": "Button",
|
||||
@@ -531,6 +635,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break2",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -554,6 +659,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "activity_log",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
@@ -586,7 +692,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-09-19 15:12:54.090381",
|
||||
"modified": "2016-09-28 05:43:26.472928",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Process Payroll",
|
||||
|
||||
@@ -5,12 +5,13 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import cint, flt, nowdate
|
||||
from frappe import _
|
||||
import collections
|
||||
from collections import defaultdict
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ProcessPayroll(Document):
|
||||
|
||||
|
||||
def get_emp_list(self):
|
||||
"""
|
||||
Returns list of active employees based on selected criteria
|
||||
@@ -21,19 +22,20 @@ class ProcessPayroll(Document):
|
||||
|
||||
sal_struct = frappe.db.sql("""
|
||||
select name from `tabSalary Structure`
|
||||
where docstatus != 2 and
|
||||
ifnull(salary_slip_based_on_timesheet,0) = 0""")
|
||||
|
||||
where docstatus != 2 and payment_account = '%(payment_account)s' and
|
||||
ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s"""%
|
||||
{"payment_account": self.payment_account, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
|
||||
|
||||
if sal_struct:
|
||||
cond += "and t2.parent IN %(sal_struct)s "
|
||||
|
||||
emp_list = frappe.db.sql("""
|
||||
select t1.name
|
||||
from `tabEmployee` t1, `tabSalary Structure Employee` t2
|
||||
where t1.docstatus!=2 and t1.name = t2.employee
|
||||
%s """% cond, {"sal_struct": sal_struct})
|
||||
emp_list = frappe.db.sql("""
|
||||
select t1.name
|
||||
from `tabEmployee` t1, `tabSalary Structure Employee` t2
|
||||
where t1.docstatus!=2 and t1.name = t2.employee
|
||||
%s """% cond, {"sal_struct": sal_struct})
|
||||
|
||||
return emp_list
|
||||
return emp_list
|
||||
|
||||
|
||||
def get_filter_condition(self):
|
||||
@@ -48,16 +50,15 @@ class ProcessPayroll(Document):
|
||||
|
||||
|
||||
def get_joining_releiving_condition(self):
|
||||
m = get_month_details(self.fiscal_year, self.month)
|
||||
cond = """
|
||||
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(month_end_date)s'
|
||||
and ifnull(t1.relieving_date, '2199-12-31') >= '%(month_start_date)s'
|
||||
""" % m
|
||||
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(from_date)s'
|
||||
and ifnull(t1.relieving_date, '2199-12-31') >= '%(to_date)s'
|
||||
""" % {"from_date": self.from_date, "to_date": self.to_date}
|
||||
return cond
|
||||
|
||||
|
||||
def check_mandatory(self):
|
||||
for f in ['company', 'month', 'fiscal_year']:
|
||||
for f in ['company', 'from_date', 'to_date']:
|
||||
if not self.get(f):
|
||||
frappe.throw(_("Please set {0}").format(f))
|
||||
|
||||
@@ -65,27 +66,37 @@ class ProcessPayroll(Document):
|
||||
"""
|
||||
Creates salary slip for selected employees if already not created
|
||||
"""
|
||||
|
||||
self.check_permission('write')
|
||||
|
||||
emp_list = self.get_emp_list()
|
||||
ss_list = []
|
||||
for emp in emp_list:
|
||||
if not frappe.db.sql("""select name from `tabSalary Slip`
|
||||
where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s
|
||||
""", (emp[0], self.month, self.fiscal_year, self.company)):
|
||||
ss = frappe.get_doc({
|
||||
"doctype": "Salary Slip",
|
||||
"salary_slip_based_on_timesheet": 0,
|
||||
"fiscal_year": self.fiscal_year,
|
||||
"employee": emp[0],
|
||||
"month": self.month,
|
||||
"company": self.company,
|
||||
"posting_date": self.posting_date,
|
||||
})
|
||||
ss.insert()
|
||||
ss_list.append(ss.name)
|
||||
|
||||
if emp_list:
|
||||
for emp in emp_list:
|
||||
if not frappe.db.sql("""select name from `tabSalary Slip`
|
||||
where docstatus!= 2 and employee = %s and start_date >= %s and end_date <= %s and company = %s
|
||||
""", (emp[0], self.from_date, self.to_date, self.company)):
|
||||
if self.salary_slip_based_on_timesheet:
|
||||
ss = frappe.get_doc({
|
||||
"doctype": "Salary Slip",
|
||||
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
|
||||
"start_date": self.from_date,
|
||||
"end_date": self.to_date,
|
||||
"employee": emp[0],
|
||||
"company": self.company,
|
||||
"posting_date": self.posting_date
|
||||
})
|
||||
else:
|
||||
ss = frappe.get_doc({
|
||||
"doctype": "Salary Slip",
|
||||
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
|
||||
"fiscal_year": self.fiscal_year,
|
||||
"month": self.month,
|
||||
"employee": emp[0],
|
||||
"company": self.company,
|
||||
"posting_date": self.posting_date
|
||||
})
|
||||
ss.insert()
|
||||
ss_list.append(ss.name)
|
||||
return self.create_log(ss_list)
|
||||
|
||||
|
||||
@@ -97,16 +108,17 @@ class ProcessPayroll(Document):
|
||||
return log
|
||||
|
||||
|
||||
def get_sal_slip_list(self):
|
||||
def get_sal_slip_list(self, ss_status, as_dict=False):
|
||||
"""
|
||||
Returns list of salary slips based on selected criteria
|
||||
which are not submitted
|
||||
"""
|
||||
cond = self.get_filter_condition()
|
||||
|
||||
ss_list = frappe.db.sql("""
|
||||
select t1.name from `tabSalary Slip` t1
|
||||
where t1.docstatus = 0 and month = %s and fiscal_year = %s %s
|
||||
""" % ('%s', '%s', cond), (self.month, self.fiscal_year))
|
||||
select t1.name, t1.salary_structure from `tabSalary Slip` t1
|
||||
where t1.docstatus = %s and t1.start_date >= %s and t1.end_date <= %s
|
||||
and (t1.journal_entry is null or t1.journal_entry = "") and ifnull(salary_slip_based_on_timesheet,0) = %s %s
|
||||
""" % ('%s', '%s', '%s','%s', cond), (ss_status, self.from_date, self.to_date, self.salary_slip_based_on_timesheet), as_dict=as_dict)
|
||||
return ss_list
|
||||
|
||||
|
||||
@@ -116,16 +128,17 @@ class ProcessPayroll(Document):
|
||||
"""
|
||||
self.check_permission('write')
|
||||
|
||||
ss_list = self.get_sal_slip_list()
|
||||
ss_list = self.get_sal_slip_list(ss_status=0)
|
||||
not_submitted_ss = []
|
||||
for ss in ss_list:
|
||||
ss_obj = frappe.get_doc("Salary Slip",ss[0])
|
||||
try:
|
||||
ss_obj.submit()
|
||||
except Exception,e:
|
||||
if ss_obj.net_pay<0:
|
||||
not_submitted_ss.append(ss[0])
|
||||
frappe.msgprint(e)
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
ss_obj.submit()
|
||||
except Exception,e:
|
||||
not_submitted_ss.append(ss[0])
|
||||
|
||||
return self.create_submit_log(ss_list, not_submitted_ss)
|
||||
|
||||
@@ -148,6 +161,7 @@ class ProcessPayroll(Document):
|
||||
<b>Not Submitted Salary Slips: </b>\
|
||||
<br><br> %s <br><br> \
|
||||
Reason: <br>\
|
||||
May be net pay is less than 0 <br>
|
||||
May be company email id specified in employee master is not valid. <br> \
|
||||
Please mention correct email id in employee master or if you don't want to \
|
||||
send mail, uncheck 'Send Email' checkbox. <br>\
|
||||
@@ -166,38 +180,105 @@ class ProcessPayroll(Document):
|
||||
cond = self.get_filter_condition()
|
||||
tot = frappe.db.sql("""
|
||||
select sum(rounded_total) from `tabSalary Slip` t1
|
||||
where t1.docstatus = 1 and month = %s and fiscal_year = %s %s
|
||||
""" % ('%s', '%s', cond), (self.month, self.fiscal_year))
|
||||
where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
|
||||
""" % ('%s', '%s', cond), (self.from_date, self.to_date))
|
||||
|
||||
return flt(tot[0][0])
|
||||
|
||||
|
||||
def make_journal_entry(self, salary_account = None):
|
||||
|
||||
def get_salary_component_account(self, salary_component):
|
||||
account = frappe.db.get_value("Salary Component Account",
|
||||
{"parent": salary_component, "company": self.company}, "default_account")
|
||||
|
||||
if not account:
|
||||
frappe.throw(_("Please set default account in Salary Component {0}")
|
||||
.format(salary_component))
|
||||
|
||||
return account
|
||||
|
||||
def get_salary_components(self, component_type):
|
||||
salary_slips = self.get_sal_slip_list(ss_status = 1, as_dict = True)
|
||||
if salary_slips:
|
||||
salary_components = frappe.db.sql("""select salary_component, amount, parentfield
|
||||
from `tabSalary Detail` where parentfield = '%s' and parent in (%s)""" %
|
||||
(component_type, ', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=True)
|
||||
return salary_components
|
||||
|
||||
def get_salary_component_total(self, component_type = None):
|
||||
salary_components = self.get_salary_components(component_type)
|
||||
if salary_components:
|
||||
component_dict = {}
|
||||
for item in salary_components:
|
||||
component_dict[item['salary_component']] = component_dict.get(item['salary_component'], 0) + item['amount']
|
||||
account_details = self.get_account(component_dict = component_dict)
|
||||
return account_details
|
||||
|
||||
def get_account(self, component_dict = None):
|
||||
account_dict = {}
|
||||
for s, a in component_dict.items():
|
||||
account = self.get_salary_component_account(s)
|
||||
account_dict[account] = account_dict.get(account, 0) + a
|
||||
return account_dict
|
||||
|
||||
|
||||
def make_journal_entry(self, reference_number = None, reference_date = None):
|
||||
self.check_permission('write')
|
||||
earnings = self.get_salary_component_total(component_type = "earnings")
|
||||
deductions = self.get_salary_component_total(component_type = "deductions")
|
||||
jv_name = ""
|
||||
|
||||
amount = self.get_total_salary()
|
||||
default_bank_account = frappe.db.get_value("Company", self.company,
|
||||
"default_bank_account")
|
||||
if earnings or deductions:
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Payment of salary from {0} to {1}').format(self.from_date,
|
||||
self.to_date)
|
||||
journal_entry.company = self.company
|
||||
journal_entry.posting_date = nowdate()
|
||||
|
||||
account_amt_list = []
|
||||
adjustment_amt = 0
|
||||
for acc, amt in earnings.items():
|
||||
adjustment_amt = adjustment_amt+amt
|
||||
account_amt_list.append({
|
||||
"account": acc,
|
||||
"debit_in_account_currency": amt
|
||||
})
|
||||
for acc, amt in deductions.items():
|
||||
adjustment_amt = adjustment_amt-amt
|
||||
account_amt_list.append({
|
||||
"account": acc,
|
||||
"credit_in_account_currency": amt
|
||||
})
|
||||
account_amt_list.append({
|
||||
"account": self.payment_account,
|
||||
"credit_in_account_currency": adjustment_amt
|
||||
})
|
||||
journal_entry.set("accounts", account_amt_list)
|
||||
journal_entry.cheque_no = reference_number
|
||||
journal_entry.cheque_date = reference_date
|
||||
journal_entry.save()
|
||||
try:
|
||||
journal_entry.submit()
|
||||
jv_name = journal_entry.name
|
||||
self.update_salary_slip_status(jv_name = jv_name)
|
||||
except Exception, e:
|
||||
frappe.msgprint(e)
|
||||
return self.create_jv_log(jv_name)
|
||||
|
||||
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Payment of salary for the month {0} and year {1}').format(self.month,
|
||||
self.fiscal_year)
|
||||
journal_entry.fiscal_year = self.fiscal_year
|
||||
journal_entry.company = self.company
|
||||
journal_entry.posting_date = nowdate()
|
||||
journal_entry.set("accounts", [
|
||||
{
|
||||
"account": salary_account,
|
||||
"debit_in_account_currency": amount
|
||||
},
|
||||
{
|
||||
"account": default_bank_account,
|
||||
"credit_in_account_currency": amount
|
||||
},
|
||||
])
|
||||
def create_jv_log(self, jv_name):
|
||||
log = "<p>" + _("No submitted Salary Slip found") + "</p>"
|
||||
if jv_name:
|
||||
log = "<b>" + _("Journal Entry Submitted") + "</b>\
|
||||
%s" % '<br>''<a href="#Form/Journal Entry/{0}">{0}</a>'.format(jv_name)
|
||||
return log
|
||||
|
||||
def update_salary_slip_status(self, jv_name = None):
|
||||
ss_list = self.get_sal_slip_list(ss_status=1)
|
||||
for ss in ss_list:
|
||||
ss_obj = frappe.get_doc("Salary Slip",ss[0])
|
||||
frappe.db.set_value("Salary Slip", ss_obj.name, "status", "Paid")
|
||||
frappe.db.set_value("Salary Slip", ss_obj.name, "journal_entry", jv_name)
|
||||
|
||||
return journal_entry.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_month_details(year, month):
|
||||
|
||||
27
erpnext/hr/doctype/process_payroll/test_process_payroll.py
Normal file
27
erpnext/hr/doctype/process_payroll/test_process_payroll.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
import frappe
|
||||
import erpnext
|
||||
from frappe.utils import flt, add_months, cint, nowdate, getdate, add_days, random_string
|
||||
from frappe.utils.make_random import get_random
|
||||
|
||||
class TestProcessPayroll(unittest.TestCase):
|
||||
def test_process_payroll(self):
|
||||
month = "11"
|
||||
fiscal_year = "_Test Fiscal Year 2016"
|
||||
payment_account = frappe.get_all("Account")[0].name
|
||||
if not frappe.db.get_value("Salary Slip", {"fiscal_year": fiscal_year, "month": month}):
|
||||
process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
|
||||
process_payroll.company = erpnext.get_default_company()
|
||||
process_payroll.month = month
|
||||
process_payroll.fiscal_year = fiscal_year
|
||||
process_payroll.from_date = "2016-11-01"
|
||||
process_payroll.to_date = "2016-11-30"
|
||||
process_payroll.payment_account = payment_account
|
||||
process_payroll.create_sal_slip()
|
||||
process_payroll.submit_salary_slip()
|
||||
if process_payroll.get_sal_slip_list(ss_status = 1):
|
||||
r = process_payroll.make_journal_entry(reference_number=random_string(10),reference_date=nowdate())
|
||||
@@ -65,6 +65,33 @@
|
||||
"unique": 0,
|
||||
"width": "120px"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Earning\nDeduction",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -91,6 +118,31 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -117,33 +169,6 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Earning\nDeduction",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
@@ -157,7 +182,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-08-29 05:33:22.495594",
|
||||
"modified": "2016-08-31 08:08:47.359578",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Component",
|
||||
|
||||
@@ -229,6 +229,59 @@
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Draft\nSubmitted\nPaid\nCancelled",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "journal_entry",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Journal Entry",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -1244,7 +1297,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-09-24 05:16:54.102341",
|
||||
"modified": "2016-09-25 04:29:14.432800",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Slip",
|
||||
|
||||
@@ -20,6 +20,7 @@ class SalarySlip(TransactionBase):
|
||||
self.name = make_autoname('Sal Slip/' +self.employee + '/.#####')
|
||||
|
||||
def validate(self):
|
||||
self.status = self.get_status()
|
||||
self.validate_dates()
|
||||
self.check_existing()
|
||||
self.set_month_dates()
|
||||
@@ -340,11 +341,16 @@ class SalarySlip(TransactionBase):
|
||||
self.precision("net_pay") if disable_rounded_total else 0)
|
||||
|
||||
def on_submit(self):
|
||||
self.update_status(self.name)
|
||||
if(frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee")):
|
||||
self.email_salary_slip()
|
||||
if self.net_pay < 0:
|
||||
frappe.throw(_("Net Pay cannot be less than 0"))
|
||||
else:
|
||||
self.set_status()
|
||||
self.update_status(self.name)
|
||||
if(frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee")):
|
||||
self.email_salary_slip()
|
||||
|
||||
def on_cancel(self):
|
||||
self.set_status()
|
||||
self.update_status()
|
||||
|
||||
def email_salary_slip(self):
|
||||
@@ -365,3 +371,29 @@ class SalarySlip(TransactionBase):
|
||||
timesheet.flags.ignore_validate_update_after_submit = True
|
||||
timesheet.set_status()
|
||||
timesheet.save()
|
||||
|
||||
def set_status(self, status=None):
|
||||
'''Get and update status'''
|
||||
if not status:
|
||||
status = self.get_status()
|
||||
self.db_set("status", status)
|
||||
|
||||
def get_status(self):
|
||||
if self.docstatus == 0:
|
||||
status = "Draft"
|
||||
elif self.docstatus == 1:
|
||||
status = "Submitted"
|
||||
if self.journal_entry:
|
||||
status = "Paid"
|
||||
elif self.docstatus == 2:
|
||||
status = "Cancelled"
|
||||
return status
|
||||
|
||||
def unlink_ref_doc_from_salary_slip(ref_no):
|
||||
linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
|
||||
where journal_entry=%s and docstatus < 2""", (ref_no))
|
||||
if linked_ss:
|
||||
for ss in linked_ss:
|
||||
ss_doc = frappe.get_doc("Salary Slip", ss)
|
||||
frappe.db.set_value("Salary Slip", ss_doc.name, "status", "Submitted")
|
||||
frappe.db.set_value("Salary Slip", ss_doc.name, "journal_entry", "")
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
import erpnext
|
||||
from frappe.utils.make_random import get_random
|
||||
from frappe.utils import today, now_datetime, getdate, cstr, add_years, nowdate
|
||||
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
||||
from erpnext.hr.doctype.leave_application.test_leave_application import make_allocation_record
|
||||
@@ -203,7 +204,8 @@ def make_salary_structure(sal_struct):
|
||||
"from_date": nowdate(),
|
||||
"employees": get_employee_details(),
|
||||
"earnings": get_earnings_component(),
|
||||
"deductions": get_deductions_component()
|
||||
"deductions": get_deductions_component(),
|
||||
"payment_account": get_random("Account")
|
||||
}).insert()
|
||||
return sal_struct
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
{% include "erpnext/public/js/controllers/accounts.js" %}
|
||||
|
||||
cur_frm.add_fetch('employee', 'company', 'company');
|
||||
cur_frm.add_fetch('company', 'default_letter_head', 'letter_head');
|
||||
|
||||
@@ -687,6 +687,111 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Mode of Payment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Mode of Payment",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_28",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payment_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Payment Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
@@ -700,7 +805,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-08-23 12:49:41.258649",
|
||||
"modified": "2016-09-06 05:40:18.311581",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Structure",
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
import unittest
|
||||
import erpnext
|
||||
from frappe.utils.make_random import get_random
|
||||
from frappe.utils import nowdate, add_days, add_years
|
||||
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
||||
# test_records = frappe.get_test_records('Salary Structure')
|
||||
@@ -85,11 +86,11 @@ class TestSalaryStructure(unittest.TestCase):
|
||||
if not sal_slip:
|
||||
sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
|
||||
self.assertEquals(sal_slip.get("salary_structure"), 'Salary Structure Sample')
|
||||
self.assertEquals(sal_slip.get("earnings")[0].amount, 0)
|
||||
self.assertEquals(sal_slip.get("deductions")[0].amount, 0)
|
||||
self.assertEquals(sal_slip.get("deductions")[1].amount, 0)
|
||||
self.assertEquals(sal_slip.get("total_deduction"), 0)
|
||||
self.assertEquals(sal_slip.get("net_pay"), 0)
|
||||
self.assertEquals(sal_slip.get("earnings")[0].amount, 5000)
|
||||
self.assertEquals(sal_slip.get("deductions")[0].amount, 5000)
|
||||
self.assertEquals(sal_slip.get("deductions")[1].amount, 2500)
|
||||
self.assertEquals(sal_slip.get("total_deduction"), 7500)
|
||||
self.assertEquals(sal_slip.get("net_pay"), 7500)
|
||||
|
||||
|
||||
def make_salary_slip_from_salary_structure(employee):
|
||||
@@ -112,7 +113,8 @@ def make_salary_structure(sal_struct):
|
||||
"from_date": nowdate(),
|
||||
"employees": get_employee_details(),
|
||||
"earnings": get_earnings_component(),
|
||||
"deductions": get_deductions_component()
|
||||
"deductions": get_deductions_component(),
|
||||
"payment_account": frappe.get_all("Account")[0].name
|
||||
}).insert()
|
||||
return sal_struct
|
||||
|
||||
@@ -124,7 +126,7 @@ def get_employee_details():
|
||||
"idx": 1
|
||||
},
|
||||
{"employee": frappe.get_value("Employee", {"employee_name":"test_employee_2@salary.com"}, "name"),
|
||||
"base": 2100,
|
||||
"base": 15000,
|
||||
"variable": 100,
|
||||
"idx": 2
|
||||
}
|
||||
@@ -149,7 +151,7 @@ def get_earnings_component():
|
||||
{
|
||||
"salary_component": 'HRA',
|
||||
"abbr":'H',
|
||||
"amount": 3000,
|
||||
"amount": 10000,
|
||||
"idx": 3
|
||||
},
|
||||
{
|
||||
@@ -173,6 +175,7 @@ def get_deductions_component():
|
||||
{
|
||||
"salary_component": 'TDS',
|
||||
"abbr":'T',
|
||||
"condition": 'employment_type!="Intern"',
|
||||
"formula": 'base*.5',
|
||||
"idx": 2
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user