Salary component cleanup
This commit is contained in:
parent
a123025d78
commit
d963b76a4b
@ -111,13 +111,9 @@ def get_data():
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Earning Type",
|
"name": "Salary Component",
|
||||||
"description": _("Salary components.")
|
"label": _("Salary Components"),
|
||||||
},
|
"description": _("Earnings, Deductions and other Salary components")
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Deduction Type",
|
|
||||||
"description": _("Tax and other salary deductions.")
|
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
1
erpnext/hr/doctype/salary_component/README.md
Normal file
1
erpnext/hr/doctype/salary_component/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Type of earning and deductions that is a part of the salary.
|
0
erpnext/hr/doctype/salary_component/__init__.py
Normal file
0
erpnext/hr/doctype/salary_component/__init__.py
Normal file
8
erpnext/hr/doctype/salary_component/salary_component.js
Normal file
8
erpnext/hr/doctype/salary_component/salary_component.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Salary Component', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
109
erpnext/hr/doctype/salary_component/salary_component.json
Normal file
109
erpnext/hr/doctype/salary_component/salary_component.json
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:salary_component",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2016-06-30 15:42:43.631931",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "Setup",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "salary_component",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Name",
|
||||||
|
"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,
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Description",
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"icon": "icon-flag",
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"in_dialog": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2016-07-01 12:42:46.103131",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "HR",
|
||||||
|
"name": "Salary Component",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "HR User",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
10
erpnext/hr/doctype/salary_component/salary_component.py
Normal file
10
erpnext/hr/doctype/salary_component/salary_component.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class SalaryComponent(Document):
|
||||||
|
pass
|
22
erpnext/hr/doctype/salary_component/test_records.json
Normal file
22
erpnext/hr/doctype/salary_component/test_records.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"doctype": "Salary Component",
|
||||||
|
"salary_component": "_Test Basic Salary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Salary Component",
|
||||||
|
"salary_component": "_Test Allowance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Salary Component",
|
||||||
|
"salary_component": "_Test Professional Tax"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Salary Component",
|
||||||
|
"salary_component": "_Test TDS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Salary Component",
|
||||||
|
"salary_component": "Basic"
|
||||||
|
}
|
||||||
|
]
|
12
erpnext/hr/doctype/salary_component/test_salary_component.py
Normal file
12
erpnext/hr/doctype/salary_component/test_salary_component.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
# test_records = frappe.get_test_records('Salary Component')
|
||||||
|
|
||||||
|
class TestSalaryComponent(unittest.TestCase):
|
||||||
|
pass
|
0
erpnext/hr/doctype/salary_detail/__init__.py
Normal file
0
erpnext/hr/doctype/salary_detail/__init__.py
Normal file
163
erpnext/hr/doctype/salary_detail/salary_detail.json
Normal file
163
erpnext/hr/doctype/salary_detail/salary_detail.json
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2016-06-30 15:32:36.385111",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "salary_component",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Salary Component",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Salary Component",
|
||||||
|
"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,
|
||||||
|
"fieldname": "amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"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,
|
||||||
|
"fieldname": "column_break_3",
|
||||||
|
"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,
|
||||||
|
"fieldname": "depends_on_lwp",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Depends on Leave Without Pay",
|
||||||
|
"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,
|
||||||
|
"fieldname": "default_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Default Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"in_dialog": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2016-07-05 17:58:20.938057",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "HR",
|
||||||
|
"name": "Salary Detail",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
10
erpnext/hr/doctype/salary_detail/salary_detail.py
Normal file
10
erpnext/hr/doctype/salary_detail/salary_detail.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class SalaryDetail(Document):
|
||||||
|
pass
|
@ -96,23 +96,23 @@ var calculate_all = function(doc, dt, dn) {
|
|||||||
calculate_net_pay(doc, dt, dn);
|
calculate_net_pay(doc, dt, dn);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.earning_amount = function(doc,dt,dn){
|
cur_frm.cscript.amount = function(doc,dt,dn){
|
||||||
calculate_earning_total(doc, dt, dn);
|
calculate_earning_total(doc, dt, dn);
|
||||||
calculate_net_pay(doc, dt, dn);
|
calculate_net_pay(doc, dt, dn);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.e_depends_on_lwp = function(doc,dt,dn){
|
cur_frm.cscript.depends_on_lwp = function(doc,dt,dn){
|
||||||
calculate_earning_total(doc, dt, dn, true);
|
calculate_earning_total(doc, dt, dn, true);
|
||||||
calculate_net_pay(doc, dt, dn);
|
calculate_net_pay(doc, dt, dn);
|
||||||
}
|
}
|
||||||
// Trigger on earning modified amount and depends on lwp
|
// Trigger on earning modified amount and depends on lwp
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
cur_frm.cscript.deduction_amount = function(doc,dt,dn){
|
cur_frm.cscript.amount = function(doc,dt,dn){
|
||||||
calculate_ded_total(doc, dt, dn);
|
calculate_ded_total(doc, dt, dn);
|
||||||
calculate_net_pay(doc, dt, dn);
|
calculate_net_pay(doc, dt, dn);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.d_depends_on_lwp = function(doc, dt, dn) {
|
cur_frm.cscript.depends_on_lwp = function(doc, dt, dn) {
|
||||||
calculate_ded_total(doc, dt, dn, true);
|
calculate_ded_total(doc, dt, dn, true);
|
||||||
calculate_net_pay(doc, dt, dn);
|
calculate_net_pay(doc, dt, dn);
|
||||||
};
|
};
|
||||||
@ -121,38 +121,37 @@ cur_frm.cscript.d_depends_on_lwp = function(doc, dt, dn) {
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
var calculate_earning_total = function(doc, dt, dn, reset_amount) {
|
var calculate_earning_total = function(doc, dt, dn, reset_amount) {
|
||||||
var tbl = doc.earnings || [];
|
var tbl = doc.earnings || [];
|
||||||
|
|
||||||
var total_earn = 0;
|
var total_earn = 0;
|
||||||
for(var i = 0; i < tbl.length; i++){
|
for(var i = 0; i < tbl.length; i++){
|
||||||
if(cint(tbl[i].e_depends_on_lwp) == 1) {
|
if(cint(tbl[i].depends_on_lwp) == 1) {
|
||||||
tbl[i].earning_amount = Math.round(tbl[i].e_amount)*(flt(doc.payment_days) /
|
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
|
||||||
cint(doc.total_days_in_month)*100)/100;
|
cint(doc.total_days_in_month)*100)/100;
|
||||||
refresh_field('earning_amount', tbl[i].name, 'earnings');
|
refresh_field('amount', tbl[i].name, 'earnings');
|
||||||
} else if(reset_amount) {
|
} else if(reset_amount) {
|
||||||
tbl[i].earning_amount = tbl[i].e_amount;
|
tbl[i].amount = tbl[i].default_amount;
|
||||||
refresh_field('earning_amount', tbl[i].name, 'earnings');
|
refresh_field('amount', tbl[i].name, 'earnings');
|
||||||
}
|
}
|
||||||
total_earn += flt(tbl[i].earning_amount);
|
total_earn += flt(tbl[i].amount);
|
||||||
|
|
||||||
}
|
}
|
||||||
doc.gross_pay = total_earn + flt(doc.arrear_amount) + flt(doc.leave_encashment_amount);
|
doc.gross_pay = total_earn + flt(doc.arrear_amount) + flt(doc.leave_encashment_amount);
|
||||||
refresh_many(['earning_amount', 'gross_pay']);
|
refresh_many(['amount','gross_pay']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate deduction total
|
// Calculate deduction total
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
var calculate_ded_total = function(doc, dt, dn, reset_amount) {
|
var calculate_ded_total = function(doc, dt, dn, reset_amount) {
|
||||||
var tbl = doc.deductions || [];
|
var tbl = doc.deductions || [];
|
||||||
|
|
||||||
var total_ded = 0;
|
var total_ded = 0;
|
||||||
for(var i = 0; i < tbl.length; i++){
|
for(var i = 0; i < tbl.length; i++){
|
||||||
if(cint(tbl[i].d_depends_on_lwp) == 1) {
|
if(cint(tbl[i].depends_on_lwp) == 1) {
|
||||||
tbl[i].deduction_amount = Math.round(tbl[i].d_amount)*(flt(doc.payment_days)/cint(doc.total_days_in_month)*100)/100;
|
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_days_in_month)*100)/100;
|
||||||
refresh_field('deduction_amount', tbl[i].name, 'deductions');
|
refresh_field('amount', tbl[i].name, 'deductions');
|
||||||
} else if(reset_amount) {
|
} else if(reset_amount) {
|
||||||
tbl[i].deduction_amount = tbl[i].d_amount;
|
tbl[i].amount = tbl[i].default_amount;
|
||||||
refresh_field('deduction_amount', tbl[i].name, 'earnings');
|
refresh_field('amount', tbl[i].name, 'deductions');
|
||||||
}
|
}
|
||||||
total_ded += flt(tbl[i].deduction_amount);
|
total_ded += flt(tbl[i].amount);
|
||||||
}
|
}
|
||||||
doc.total_deduction = total_ded;
|
doc.total_deduction = total_ded;
|
||||||
refresh_field('total_deduction');
|
refresh_field('total_deduction');
|
||||||
|
@ -859,7 +859,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"oldfieldname": "earning_details",
|
"oldfieldname": "earning_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Salary Slip Earning",
|
"options": "Salary Detail",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
@ -912,7 +912,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"oldfieldname": "deduction_details",
|
"oldfieldname": "deduction_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Salary Slip Deduction",
|
"options": "Salary Detail",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
@ -1171,7 +1171,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-06-27 16:22:46.063078",
|
"modified": "2016-07-01 12:25:38.497538",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Salary Slip",
|
"name": "Salary Slip",
|
||||||
|
@ -23,7 +23,7 @@ class SalarySlip(TransactionBase):
|
|||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
self.check_existing()
|
self.check_existing()
|
||||||
self.set_month_dates()
|
self.set_month_dates()
|
||||||
|
|
||||||
if not (len(self.get("earnings")) or len(self.get("deductions"))):
|
if not (len(self.get("earnings")) or len(self.get("deductions"))):
|
||||||
self.get_emp_and_leave_details()
|
self.get_emp_and_leave_details()
|
||||||
else:
|
else:
|
||||||
@ -101,20 +101,20 @@ class SalarySlip(TransactionBase):
|
|||||||
self.salary_structure = ss_doc.name
|
self.salary_structure = ss_doc.name
|
||||||
self.hour_rate = ss_doc.hour_rate
|
self.hour_rate = ss_doc.hour_rate
|
||||||
self.total_working_hours = sum([d.working_hours or 0.0 for d in self.timesheets]) or 0.0
|
self.total_working_hours = sum([d.working_hours or 0.0 for d in self.timesheets]) or 0.0
|
||||||
self.add_earning_for_hourly_wages(ss_doc.earning_type)
|
self.add_earning_for_hourly_wages(ss_doc.salary_component)
|
||||||
|
|
||||||
def add_earning_for_hourly_wages(self, earning_type):
|
def add_earning_for_hourly_wages(self, salary_component):
|
||||||
default_type = False
|
default_type = False
|
||||||
for data in self.earnings:
|
for data in self.earnings:
|
||||||
if data.earning_type == earning_type:
|
if data.salary_component == salary_component:
|
||||||
data.earning_amount = self.hour_rate * self.total_working_hours
|
data.amount = self.hour_rate * self.total_working_hours
|
||||||
default_type = True
|
default_type = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if not default_type:
|
if not default_type:
|
||||||
earnings = self.append('earnings', {})
|
earnings = self.append('earnings', {})
|
||||||
earnings.earning_type = earning_type
|
earnings.salary_component = salary_component
|
||||||
earnings.earning_amount = self.hour_rate * self.total_working_hours
|
earnings.amount = self.hour_rate * self.total_working_hours
|
||||||
|
|
||||||
def pull_emp_details(self):
|
def pull_emp_details(self):
|
||||||
emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1)
|
emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1)
|
||||||
@ -226,27 +226,26 @@ class SalarySlip(TransactionBase):
|
|||||||
def calculate_earning_total(self):
|
def calculate_earning_total(self):
|
||||||
self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
|
self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
|
||||||
for d in self.get("earnings"):
|
for d in self.get("earnings"):
|
||||||
if cint(d.e_depends_on_lwp) == 1:
|
if cint(d.depends_on_lwp) == 1:
|
||||||
d.earning_amount = rounded((flt(d.e_amount) * flt(self.payment_days)
|
d.amount = rounded((flt(d.default_amount) * flt(self.payment_days)
|
||||||
/ cint(self.total_days_in_month)), self.precision("earning_amount", "earnings"))
|
/ cint(self.total_days_in_month)), self.precision("amount", "earnings"))
|
||||||
elif not self.payment_days:
|
elif not self.payment_days:
|
||||||
d.earning_amount = 0
|
d.amount = 0
|
||||||
elif not d.earning_amount:
|
elif not d.amount:
|
||||||
d.earning_amount = d.e_amount
|
d.amount = d.default_amount
|
||||||
self.gross_pay += flt(d.earning_amount)
|
self.gross_pay += flt(d.amount)
|
||||||
|
|
||||||
def calculate_ded_total(self):
|
def calculate_ded_total(self):
|
||||||
self.total_deduction = 0
|
self.total_deduction = 0
|
||||||
for d in self.get('deductions'):
|
for d in self.get('deductions'):
|
||||||
if cint(d.d_depends_on_lwp) == 1:
|
if cint(d.depends_on_lwp) == 1:
|
||||||
d.deduction_amount = rounded((flt(d.d_amount) * flt(self.payment_days)
|
d.amount = rounded((flt(d.amount) * flt(self.payment_days)
|
||||||
/ cint(self.total_days_in_month)), self.precision("deduction_amount", "deductions"))
|
/ cint(self.total_days_in_month)), self.precision("amount", "deductions"))
|
||||||
elif not self.payment_days:
|
elif not self.payment_days:
|
||||||
d.deduction_amount = 0
|
d.amount = 0
|
||||||
elif not d.deduction_amount:
|
elif not d.amount:
|
||||||
d.deduction_amount = d.d_amount
|
d.amount = d.default_amount
|
||||||
|
self.total_deduction += flt(d.amount)
|
||||||
self.total_deduction += flt(d.deduction_amount)
|
|
||||||
|
|
||||||
def calculate_net_pay(self):
|
def calculate_net_pay(self):
|
||||||
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
|
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
|
"doctype": "Salary Slip",
|
||||||
"deductions": [
|
"deductions": [
|
||||||
{
|
{
|
||||||
"d_amount": 100,
|
"doctype": "Salary Detail",
|
||||||
"d_depends_on_lwp": 0,
|
"amount": 100,
|
||||||
"deduction_type": "_Test Professional Tax",
|
"depends_on_lwp": 0,
|
||||||
"doctype": "Salary Slip Deduction",
|
"salary_component": "_Test Professional Tax",
|
||||||
"parentfield": "deductions"
|
"parentfield": "deductions"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"d_amount": 50,
|
"doctype": "Salary Detail",
|
||||||
"d_depends_on_lwp": 1,
|
"amount": 48.39,
|
||||||
"deduction_type": "_Test TDS",
|
"depends_on_lwp": 0,
|
||||||
"doctype": "Salary Slip Deduction",
|
"salary_component": "_Test TDS",
|
||||||
"parentfield": "deductions"
|
"parentfield": "deductions"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"doctype": "Salary Slip",
|
|
||||||
"earnings": [
|
"earnings": [
|
||||||
{
|
{
|
||||||
"doctype": "Salary Slip Earning",
|
"doctype": "Salary Detail",
|
||||||
"e_amount": 15000,
|
"amount": 14516.13,
|
||||||
"e_depends_on_lwp": 1,
|
"depends_on_lwp": 0,
|
||||||
"earning_type": "_Test Basic Salary",
|
"salary_component": "_Test Basic Salary",
|
||||||
"parentfield": "earnings"
|
"parentfield": "earnings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Salary Slip Earning",
|
"doctype": "Salary Detail",
|
||||||
"e_amount": 500,
|
"amount": 500,
|
||||||
"e_depends_on_lwp": 0,
|
"depends_on_lwp": 0,
|
||||||
"earning_type": "_Test Allowance",
|
"salary_component": "_Test Allowance",
|
||||||
"parentfield": "earnings"
|
"parentfield": "earnings"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -35,10 +35,10 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(ss.total_days_in_month, 31)
|
self.assertEquals(ss.total_days_in_month, 31)
|
||||||
self.assertEquals(ss.payment_days, 30)
|
self.assertEquals(ss.payment_days, 30)
|
||||||
self.assertEquals(ss.earnings[0].earning_amount, 14516.13)
|
self.assertEquals(ss.earnings[0].amount, 14516.13)
|
||||||
self.assertEquals(ss.earnings[1].earning_amount, 500)
|
self.assertEquals(ss.earnings[1].amount, 500)
|
||||||
self.assertEquals(ss.deductions[0].deduction_amount, 100)
|
self.assertEquals(ss.deductions[0].amount, 100)
|
||||||
self.assertEquals(ss.deductions[1].deduction_amount, 48.39)
|
self.assertEquals(ss.deductions[1].amount, 48.39)
|
||||||
self.assertEquals(ss.gross_pay, 15016.13)
|
self.assertEquals(ss.gross_pay, 15016.13)
|
||||||
self.assertEquals(ss.net_pay, 14867.74)
|
self.assertEquals(ss.net_pay, 14867.74)
|
||||||
|
|
||||||
@ -49,12 +49,12 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(ss.total_days_in_month, 29)
|
self.assertEquals(ss.total_days_in_month, 29)
|
||||||
self.assertEquals(ss.payment_days, 28)
|
self.assertEquals(ss.payment_days, 28)
|
||||||
self.assertEquals(ss.earnings[0].earning_amount, 14482.76)
|
self.assertEquals(ss.earnings[0].amount, 14516.13)
|
||||||
self.assertEquals(ss.earnings[1].earning_amount, 500)
|
self.assertEquals(ss.earnings[1].amount, 500)
|
||||||
self.assertEquals(ss.deductions[0].deduction_amount, 100)
|
self.assertEquals(ss.deductions[0].amount, 100)
|
||||||
self.assertEquals(ss.deductions[1].deduction_amount, 48.28)
|
self.assertEquals(ss.deductions[1].amount, 48.39)
|
||||||
self.assertEquals(ss.gross_pay, 14982.76)
|
self.assertEquals(ss.gross_pay, 15016.13)
|
||||||
self.assertEquals(ss.net_pay, 14834.48)
|
self.assertEquals(ss.net_pay, 14867.74)
|
||||||
|
|
||||||
def test_payment_days(self):
|
def test_payment_days(self):
|
||||||
# Holidays not included in working days
|
# Holidays not included in working days
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
cur_frm.add_fetch('employee', 'company', 'company');
|
cur_frm.add_fetch('employee', 'company', 'company');
|
||||||
cur_frm.add_fetch('company', 'default_letter_head', 'letter_head');
|
cur_frm.add_fetch('company', 'default_letter_head', 'letter_head');
|
||||||
|
|
||||||
|
|
||||||
cur_frm.cscript.onload = function(doc, dt, dn){
|
cur_frm.cscript.onload = function(doc, dt, dn){
|
||||||
e_tbl = doc.earnings || [];
|
e_tbl = doc.earnings || [];
|
||||||
d_tbl = doc.deductions || [];
|
d_tbl = doc.deductions || [];
|
||||||
@ -22,6 +23,8 @@ cur_frm.cscript.refresh = function(doc, dt, dn){
|
|||||||
frappe.ui.form.on('Salary Structure', {
|
frappe.ui.form.on('Salary Structure', {
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frm.trigger("toggle_fields")
|
frm.trigger("toggle_fields")
|
||||||
|
frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false);
|
||||||
|
frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false);
|
||||||
},
|
},
|
||||||
|
|
||||||
salary_slip_based_on_timesheet: function(frm) {
|
salary_slip_based_on_timesheet: function(frm) {
|
||||||
@ -45,24 +48,20 @@ cur_frm.cscript.employee = function(doc, dt, dn){
|
|||||||
return get_server_fields('get_employee_details','','',doc,dt,dn);
|
return get_server_fields('get_employee_details','','',doc,dt,dn);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.modified_value = function(doc, cdt, cdn){
|
cur_frm.cscript.amount = function(doc, cdt, cdn){
|
||||||
calculate_totals(doc, cdt, cdn);
|
calculate_totals(doc, cdt, cdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.d_modified_amt = function(doc, cdt, cdn){
|
var calculate_totals = function(doc) {
|
||||||
calculate_totals(doc, cdt, cdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
var calculate_totals = function(doc, cdt, cdn) {
|
|
||||||
var tbl1 = doc.earnings || [];
|
var tbl1 = doc.earnings || [];
|
||||||
var tbl2 = doc.deductions || [];
|
var tbl2 = doc.deductions || [];
|
||||||
|
|
||||||
var total_earn = 0; var total_ded = 0;
|
var total_earn = 0; var total_ded = 0;
|
||||||
for(var i = 0; i < tbl1.length; i++){
|
for(var i = 0; i < tbl1.length; i++){
|
||||||
total_earn += flt(tbl1[i].modified_value);
|
total_earn += flt(tbl1[i].amount);
|
||||||
}
|
}
|
||||||
for(var j = 0; j < tbl2.length; j++){
|
for(var j = 0; j < tbl2.length; j++){
|
||||||
total_ded += flt(tbl2[j].d_modified_amt);
|
total_ded += flt(tbl2[j].amount);
|
||||||
}
|
}
|
||||||
doc.total_earning = total_earn;
|
doc.total_earning = total_earn;
|
||||||
doc.total_deduction = total_ded;
|
doc.total_deduction = total_ded;
|
||||||
@ -75,10 +74,25 @@ var calculate_totals = function(doc, cdt, cdn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||||
calculate_totals(doc, cdt, cdn);
|
calculate_totals(doc);
|
||||||
if(doc.employee && doc.is_active == "Yes") frappe.model.clear_doc("Employee", doc.employee);
|
if(doc.employee && doc.is_active == "Yes") frappe.model.clear_doc("Employee", doc.employee);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) {
|
cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) {
|
||||||
return{ query: "erpnext.controllers.queries.employee_query" }
|
return{ query: "erpnext.controllers.queries.employee_query" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
frappe.ui.form.on('Salary Detail', {
|
||||||
|
amount: function(frm) {
|
||||||
|
calculate_totals(frm.doc);
|
||||||
|
},
|
||||||
|
|
||||||
|
earnings_remove: function(frm) {
|
||||||
|
calculate_totals(frm.doc);
|
||||||
|
},
|
||||||
|
|
||||||
|
deductions_remove: function(frm) {
|
||||||
|
calculate_totals(frm.doc);
|
||||||
|
}
|
||||||
|
})
|
@ -405,18 +405,18 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
"description": "Earning type for timesheet based payroll.",
|
"description": "Salary Component for timesheet based payroll.",
|
||||||
"fieldname": "earning_type",
|
"fieldname": "salary_component",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"label": "Earning Type",
|
"label": "Salary Component",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Earning Type",
|
"options": "Salary Component",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -550,7 +550,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"oldfieldname": "earning_details",
|
"oldfieldname": "earning_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Salary Structure Earning",
|
"options": "Salary Detail",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
@ -604,7 +604,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"oldfieldname": "deduction_details",
|
"oldfieldname": "deduction_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Salary Structure Deduction",
|
"options": "Salary Detail",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
@ -779,7 +779,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-06-29 15:41:48.243771",
|
"modified": "2016-07-02 18:04:06.529332",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Salary Structure",
|
"name": "Salary Structure",
|
||||||
|
@ -48,15 +48,15 @@ class SalaryStructure(Document):
|
|||||||
for li in list1:
|
for li in list1:
|
||||||
child = self.append(tab_fname, {})
|
child = self.append(tab_fname, {})
|
||||||
if(tab_fname == 'earnings'):
|
if(tab_fname == 'earnings'):
|
||||||
child.earning_type = cstr(li[0])
|
child.salary_component = cstr(li[0])
|
||||||
child.modified_value = 0
|
child.amount = 0
|
||||||
elif(tab_fname == 'deductions'):
|
elif(tab_fname == 'deductions'):
|
||||||
child.deduction_type = cstr(li[0])
|
child.salary_component = cstr(li[0])
|
||||||
child.d_modified_amt = 0
|
child.amount = 0
|
||||||
|
|
||||||
def make_earn_ded_table(self):
|
def make_earn_ded_table(self):
|
||||||
self.make_table('Earning Type','earnings','Salary Structure Earning')
|
self.make_table('Salary Component','earnings','Salary Detail')
|
||||||
self.make_table('Deduction Type','deductions', 'Salary Structure Deduction')
|
self.make_table('Salary Component','deductions', 'Salary Detail')
|
||||||
|
|
||||||
def check_overlap(self):
|
def check_overlap(self):
|
||||||
existing = frappe.db.sql("""select name from `tabSalary Structure`
|
existing = frappe.db.sql("""select name from `tabSalary Structure`
|
||||||
@ -94,36 +94,29 @@ class SalaryStructure(Document):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_salary_slip(source_name, target_doc=None):
|
def make_salary_slip(source_name, target_doc=None):
|
||||||
def postprocess(source, target):
|
def postprocess(source, target):
|
||||||
target.salary_structure = source.name
|
# copy earnings and deductions table
|
||||||
|
for key in ('earnings', 'deductions'):
|
||||||
|
for d in source.get(key):
|
||||||
|
target.append(key, {
|
||||||
|
'amount': d.amount,
|
||||||
|
'default_amount': d.default_amount,
|
||||||
|
'depends_on_lwp' : d.depends_on_lwp,
|
||||||
|
'salary_component' : d.salary_component
|
||||||
|
})
|
||||||
|
|
||||||
target.run_method("pull_emp_details")
|
target.run_method("pull_emp_details")
|
||||||
target.run_method("get_leave_details")
|
target.run_method("get_leave_details")
|
||||||
target.run_method("calculate_net_pay")
|
target.run_method("calculate_net_pay")
|
||||||
|
|
||||||
|
|
||||||
doc = get_mapped_doc("Salary Structure", source_name, {
|
doc = get_mapped_doc("Salary Structure", source_name, {
|
||||||
"Salary Structure": {
|
"Salary Structure": {
|
||||||
"doctype": "Salary Slip",
|
"doctype": "Salary Slip",
|
||||||
"field_map": {
|
"field_map": {
|
||||||
"total_earning": "gross_pay"
|
"total_earning": "gross_pay",
|
||||||
|
"name": "salary_structure"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"Salary Structure Deduction": {
|
|
||||||
"doctype": "Salary Slip Deduction",
|
|
||||||
"field_map": [
|
|
||||||
["depend_on_lwp", "d_depends_on_lwp"],
|
|
||||||
["d_modified_amt", "d_amount"],
|
|
||||||
["d_modified_amt", "deduction_amount"]
|
|
||||||
],
|
|
||||||
"add_if_empty": True
|
|
||||||
},
|
|
||||||
"Salary Structure Earning": {
|
|
||||||
"doctype": "Salary Slip Earning",
|
|
||||||
"field_map": [
|
|
||||||
["depend_on_lwp", "e_depends_on_lwp"],
|
|
||||||
["modified_value", "e_amount"],
|
|
||||||
["modified_value", "earning_amount"]
|
|
||||||
],
|
|
||||||
"add_if_empty": True
|
|
||||||
}
|
}
|
||||||
}, target_doc, postprocess)
|
}, target_doc, postprocess, ignore_child_tables=True)
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
@ -6,10 +6,18 @@
|
|||||||
"from_date": "2014-02-01",
|
"from_date": "2014-02-01",
|
||||||
"earnings": [
|
"earnings": [
|
||||||
{
|
{
|
||||||
"earning_type": "_Test Basic Salary"
|
"salary_component": "_Test Basic Salary"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"earning_type": "_Test Allowance"
|
"salary_component": "_Test Allowance"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"deductions": [
|
||||||
|
{
|
||||||
|
"salary_component": "_Test Professional Tax"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"salary_component": "_Test TDS"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,12 @@ def get_columns(salary_slips):
|
|||||||
_("Payment Days") + ":Float:120"
|
_("Payment Days") + ":Float:120"
|
||||||
]
|
]
|
||||||
|
|
||||||
earning_types = frappe.db.sql_list("""select distinct earning_type from `tabSalary Slip Earning`
|
earning_types = frappe.db.sql_list("""select distinct salary_component from `tabSalary Detail`
|
||||||
where earning_amount != 0 and parent in (%s)""" %
|
where amount != 0 and parent in (%s)""" %
|
||||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
||||||
|
|
||||||
ded_types = frappe.db.sql_list("""select distinct deduction_type from `tabSalary Slip Deduction`
|
ded_types = frappe.db.sql_list("""select distinct salary_component from `tabSalary Detail`
|
||||||
where deduction_amount != 0 and parent in (%s)""" %
|
where amount != 0 and parent in (%s)""" %
|
||||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
||||||
|
|
||||||
columns = columns + [(e + ":Currency:120") for e in earning_types] + \
|
columns = columns + [(e + ":Currency:120") for e in earning_types] + \
|
||||||
@ -83,25 +83,25 @@ def get_conditions(filters):
|
|||||||
return conditions, filters
|
return conditions, filters
|
||||||
|
|
||||||
def get_ss_earning_map(salary_slips):
|
def get_ss_earning_map(salary_slips):
|
||||||
ss_earnings = frappe.db.sql("""select parent, earning_type, earning_amount
|
ss_earnings = frappe.db.sql("""select parent, salary_component, amount
|
||||||
from `tabSalary Slip Earning` where parent in (%s)""" %
|
from `tabSalary Detail` where parent in (%s)""" %
|
||||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||||
|
|
||||||
ss_earning_map = {}
|
ss_earning_map = {}
|
||||||
for d in ss_earnings:
|
for d in ss_earnings:
|
||||||
ss_earning_map.setdefault(d.parent, frappe._dict()).setdefault(d.earning_type, [])
|
ss_earning_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
|
||||||
ss_earning_map[d.parent][d.earning_type] = flt(d.earning_amount)
|
ss_earning_map[d.parent][d.salary_component] = flt(d.amount)
|
||||||
|
|
||||||
return ss_earning_map
|
return ss_earning_map
|
||||||
|
|
||||||
def get_ss_ded_map(salary_slips):
|
def get_ss_ded_map(salary_slips):
|
||||||
ss_deductions = frappe.db.sql("""select parent, deduction_type, deduction_amount
|
ss_deductions = frappe.db.sql("""select parent, salary_component, amount
|
||||||
from `tabSalary Slip Deduction` where parent in (%s)""" %
|
from `tabSalary Detail` where parent in (%s)""" %
|
||||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||||
|
|
||||||
ss_ded_map = {}
|
ss_ded_map = {}
|
||||||
for d in ss_deductions:
|
for d in ss_deductions:
|
||||||
ss_ded_map.setdefault(d.parent, frappe._dict()).setdefault(d.deduction_type, [])
|
ss_ded_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
|
||||||
ss_ded_map[d.parent][d.deduction_type] = flt(d.deduction_amount)
|
ss_ded_map[d.parent][d.salary_component] = flt(d.amount)
|
||||||
|
|
||||||
return ss_ded_map
|
return ss_ded_map
|
@ -285,4 +285,5 @@ erpnext.patches.v7_0.remove_doctypes_and_reports
|
|||||||
erpnext.patches.v7_0.set_is_group_for_warehouse
|
erpnext.patches.v7_0.set_is_group_for_warehouse
|
||||||
erpnext.patches.v7_0.update_maintenance_module_in_doctype
|
erpnext.patches.v7_0.update_maintenance_module_in_doctype
|
||||||
erpnext.patches.v7_0.update_prevdoc_values_for_supplier_quotation_item
|
erpnext.patches.v7_0.update_prevdoc_values_for_supplier_quotation_item
|
||||||
erpnext.patches.v7_0.rename_advance_table_fields
|
erpnext.patches.v7_0.rename_advance_table_fields
|
||||||
|
erpnext.patches.v7_0.rename_salary_components
|
145
erpnext/patches/v7_0/rename_salary_components.py
Normal file
145
erpnext/patches/v7_0/rename_salary_components.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.model.utils.rename_field import update_property_setters
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
if not frappe.db.exists("DocType", "Salary Structure Earning"):
|
||||||
|
return
|
||||||
|
|
||||||
|
frappe.reload_doc("hr", "doctype", "salary_detail")
|
||||||
|
frappe.reload_doc("hr", "doctype", "salary_component")
|
||||||
|
|
||||||
|
standard_cols = ["name", "creation", "modified", "owner", "modified_by", "parent", "parenttype", "parentfield", "idx"]
|
||||||
|
|
||||||
|
dt_cols = {
|
||||||
|
"Salary Structure Deduction": ["d_type", "d_modified_amt", "depend_on_lwp"],
|
||||||
|
"Salary Structure Earning": ["e_type", "modified_value", "depend_on_lwp"],
|
||||||
|
"Salary Slip Earning": ["e_type", "e_modified_amount", "e_depends_on_lwp", "e_amount"],
|
||||||
|
"Salary Slip Deduction": ["d_type", "d_modified_amount", "d_depends_on_lwp", "d_amount"],
|
||||||
|
}
|
||||||
|
|
||||||
|
earning_type_exists = True if "earning_type" in frappe.db.get_table_columns("Salary Slip Earning") else False
|
||||||
|
e_type_exists = True if "e_type" in frappe.db.get_table_columns("Salary Slip Earning") else False
|
||||||
|
|
||||||
|
|
||||||
|
if e_type_exists and earning_type_exists:
|
||||||
|
frappe.db.sql("""update `tabSalary Slip Earning`
|
||||||
|
set e_type = earning_type, e_modified_amount = earning_amount
|
||||||
|
where e_type is null and earning_type is not null""")
|
||||||
|
|
||||||
|
frappe.db.sql("""update `tabSalary Structure Earning` set e_type = earning_type
|
||||||
|
where e_type is null and earning_type is not null""")
|
||||||
|
|
||||||
|
frappe.db.sql("""update `tabSalary Slip Deduction` set
|
||||||
|
d_type = deduction_type, d_modified_amount = deduction_amount
|
||||||
|
where d_type is null and deduction_type is not null""")
|
||||||
|
|
||||||
|
frappe.db.sql("""update `tabSalary Structure Deduction` set d_type = deduction_type
|
||||||
|
where d_type is null and deduction_type is not null""")
|
||||||
|
|
||||||
|
if earning_type_exists and not e_type_exists:
|
||||||
|
for val in dt_cols.values():
|
||||||
|
if val[0] == "e_type":
|
||||||
|
val[0] = "earning_type"
|
||||||
|
|
||||||
|
if val[0] == "d_type":
|
||||||
|
val[0] = "deduction_type"
|
||||||
|
|
||||||
|
if val[1] == "e_modified_amount":
|
||||||
|
val[1] ="earning_amount"
|
||||||
|
|
||||||
|
if val[1] == "d_modified_amount":
|
||||||
|
val[1] ="deduction_amount"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
target_cols = standard_cols + ["salary_component", "amount", "depends_on_lwp", "default_amount"]
|
||||||
|
target_cols = "`" + "`, `".join(target_cols) + "`"
|
||||||
|
|
||||||
|
for doctype, cols in dt_cols.items():
|
||||||
|
source_cols = "`" + "`, `".join(standard_cols + cols) + "`"
|
||||||
|
if len(cols) == 3:
|
||||||
|
source_cols += ", 0"
|
||||||
|
|
||||||
|
|
||||||
|
frappe.db.sql("""INSERT INTO `tabSalary Detail` ({0}) SELECT {1} FROM `tab{2}`"""
|
||||||
|
.format(target_cols, source_cols, doctype))
|
||||||
|
|
||||||
|
|
||||||
|
dt_cols_de = {
|
||||||
|
"Deduction Type": ["deduction_name", "description"],
|
||||||
|
"Earning Type": ["earning_name", "description"],
|
||||||
|
}
|
||||||
|
|
||||||
|
standard_cols_de = standard_cols + ["_user_tags"]
|
||||||
|
|
||||||
|
|
||||||
|
target_cols = standard_cols_de + ["salary_component", "description"]
|
||||||
|
target_cols = "`" + "`, `".join(target_cols) + "`"
|
||||||
|
|
||||||
|
for doctype, cols in dt_cols_de.items():
|
||||||
|
source_cols = "`" + "`, `".join(standard_cols_de + cols) + "`"
|
||||||
|
|
||||||
|
frappe.db.sql("""INSERT INTO `tabSalary Component` ({0}) SELECT {1} FROM `tab{2}`"""
|
||||||
|
.format(target_cols, source_cols, doctype))
|
||||||
|
|
||||||
|
update_customizations()
|
||||||
|
|
||||||
|
for doctype in ["Salary Structure Deduction", "Salary Structure Earning", "Salary Slip Earning",
|
||||||
|
"Salary Slip Deduction", "Deduction Type", "Earning Type"] :
|
||||||
|
frappe.delete_doc("DocType", doctype)
|
||||||
|
|
||||||
|
|
||||||
|
def update_customizations():
|
||||||
|
dt_cols = {
|
||||||
|
"Salary Structure Deduction": {
|
||||||
|
"d_type": "salary_component",
|
||||||
|
"deduction_type": "salary_component",
|
||||||
|
"d_modified_amt": "amount",
|
||||||
|
"depend_on_lwp": "depends_on_lwp"
|
||||||
|
},
|
||||||
|
"Salary Structure Earning": {
|
||||||
|
"e_type": "salary_component",
|
||||||
|
"earning_type": "salary_component",
|
||||||
|
"modified_value": "amount",
|
||||||
|
"depend_on_lwp": "depends_on_lwp"
|
||||||
|
},
|
||||||
|
"Salary Slip Earning": {
|
||||||
|
"e_type": "salary_component",
|
||||||
|
"earning_type": "salary_component",
|
||||||
|
"e_modified_amount": "amount",
|
||||||
|
"e_amount" : "default_amount"
|
||||||
|
"e_depends_on_lwp": "depends_on_lwp"
|
||||||
|
},
|
||||||
|
"Salary Slip Deduction": {
|
||||||
|
"d_type": "salary_component",
|
||||||
|
"deduction_type": "salary_component",
|
||||||
|
"d_modified_amount": "amount",
|
||||||
|
"d_amount" : "default_amount"
|
||||||
|
"d_depends_on_lwp": "depends_on_lwp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_property_setters_and_custom_fields("Salary Detail", dt_cols)
|
||||||
|
|
||||||
|
dt_cols = {
|
||||||
|
"Earning Type": {
|
||||||
|
"earning_name": "salary_component"
|
||||||
|
},
|
||||||
|
"Deduction Type": {
|
||||||
|
"deduction_name": "salary_component"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_property_setters_and_custom_fields("Salary Component", dt_cols)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def update_property_setters_and_custom_fields(new_dt, dt_cols):
|
||||||
|
for doctype, cols in dt_cols.items():
|
||||||
|
frappe.db.sql("update `tabProperty Setter` set doc_type = %s where doc_type=%s", (new_dt, doctype))
|
||||||
|
frappe.db.sql("update `tabCustom Field` set dt = %s where dt=%s", (new_dt, doctype))
|
||||||
|
|
||||||
|
|
||||||
|
for old_fieldname, new_fieldname in cols.items():
|
||||||
|
update_property_setters(new_dt, old_fieldname, new_fieldname)
|
@ -65,7 +65,7 @@ def make_salary_structure(employee):
|
|||||||
salary_structure.salary_slip_based_on_timesheet = 1
|
salary_structure.salary_slip_based_on_timesheet = 1
|
||||||
salary_structure.employee = employee
|
salary_structure.employee = employee
|
||||||
salary_structure.from_date = nowdate()
|
salary_structure.from_date = nowdate()
|
||||||
salary_structure.earning_type = "Basic"
|
salary_structure.salary_component = "Basic"
|
||||||
salary_structure.hour_rate = 50.0
|
salary_structure.hour_rate = 50.0
|
||||||
salary_structure.company= "_Test Company"
|
salary_structure.company= "_Test Company"
|
||||||
|
|
||||||
@ -73,13 +73,13 @@ def make_salary_structure(employee):
|
|||||||
salary_structure.set('deductions', [])
|
salary_structure.set('deductions', [])
|
||||||
|
|
||||||
es = salary_structure.append('earnings', {
|
es = salary_structure.append('earnings', {
|
||||||
"earning_type": "_Test Allowance",
|
"salary_component": "_Test Allowance",
|
||||||
"modified_value": 100
|
"amount": 100
|
||||||
})
|
})
|
||||||
|
|
||||||
ds = salary_structure.append('deductions', {
|
ds = salary_structure.append('deductions', {
|
||||||
"deduction_type": "_Test Professional Tax",
|
"salary_component": "_Test Professional Tax",
|
||||||
"d_modified_amt": 50
|
"amount": 50
|
||||||
})
|
})
|
||||||
|
|
||||||
salary_structure.save(ignore_permissions=True)
|
salary_structure.save(ignore_permissions=True)
|
||||||
|
@ -7,9 +7,9 @@ import frappe
|
|||||||
|
|
||||||
def install(company):
|
def install(company):
|
||||||
docs = [
|
docs = [
|
||||||
{'doctype': 'Deduction Type', 'name': 'Professional Tax', 'description': 'Professional Tax', 'deduction_name': 'Professional Tax'},
|
{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'salary_component': 'Professional Tax'},
|
||||||
{'doctype': 'Deduction Type', 'name': 'Provident Fund', 'description': 'Provident fund', 'deduction_name': 'Provident Fund'},
|
{'doctype': 'Salary Component', 'salary_component': 'Provident Fund', 'description': 'Provident fund', 'salary_component': 'Provident Fund'},
|
||||||
{'doctype': 'Earning Type', 'name': 'House Rent Allowance', 'description': 'House Rent Allowance', 'earning_name': 'House Rent Allowance', 'taxable': 'No'},
|
{'doctype': 'Salary Component', 'salary_component': 'House Rent Allowance', 'description': 'House Rent Allowance', 'salary_component': 'House Rent Allowance', 'taxable': 'No'},
|
||||||
]
|
]
|
||||||
|
|
||||||
for d in docs:
|
for d in docs:
|
||||||
|
Loading…
Reference in New Issue
Block a user