employee_payout_process.js
=====================
frappe.ui.form.on('Employee Payout Process', {
onload: function (frm) {
frm.doc.bank_name = '';
frm.doc.start_date = '';
frm.doc.end_date = '';
},
refresh: function(frm) {
frm.doc.bank_name = '';
frm.doc.start_date = '';
frm.doc.end_date = '';
frm.disable_save();
},
setup: function(frm) {
},
payment_account: function (frm) {
frm.toggle_display(['make_bank_entry'], (frm.doc.payment_account != "" && frm.doc.payment_account != "undefined" && frm.doc.empdata != ""));
},
start_date: function(frm) {
frm.set_value("bank_name",'');
},
end_date: function(frm) {
frm.set_value("bank_name",'');
},
bank_name: function(frm) {
frm.set_value("payment_account",'');
frm.events.get_salary_slip_data(frm);
},
get_salary_slip_data: function(frm) {
if(frm.doc.start_date != null && frm.doc.start_date != null && frm.doc.start_date < frm.doc.end_date){
frappe.call({
method: "erpnext.hr.doctype.employee_payout_process.employee_payout_process.salary_slip_data",
args: {
"bank_name": frm.doc.bank_name,
"start_date": frm.doc.start_date,
"end_date": frm.doc.end_date
},
callback: function(r,rt)
{
frappe.model.clear_table(frm.doc, "empdata");
if(r.message) {
$.each(r.message, function(i, d) {
var row = frappe.model.add_child(frm.doc, "Salary Slip Data", "empdata");
row.employee = d.employee;
row.ifsc_code = d.ifsc_code;
row.bank_ac_no = d.bank_ac_no;
row.bank_name = d.bank_name;
row.net_pay = d.net_pay;
});
frm.refresh_field("empdata");
}else {
empdata_flag = false
frappe.msgprint("No data found");
}
frm.refresh_field("empdata");
}
});
}else{
frappe.msgprint("Select valid Start date and End date");
}
}
});
cur_frm.cscript.make_bank_entry = function (doc, cdt, cdn) {
if (doc.company && doc.start_date && doc.end_date) {
return frappe.call({
method: 'make_bank_payment_entry',
doc: cur_frm.doc,
callback: function (r) {
if (r.message)
var doc = frappe.model.sync(r.message)[0];
frappe.set_route("Form", doc.doctype, doc.name);
}
});
} else {
frappe.msgprint(__("Company, From Date and To Date is mandatory"));
}
}
-------------------------------------------------------------
employee_payout_process.py
=====================
from __future__ import unicode_literals
import frappe
from frappe.utils import getdate
from frappe import _
from erpnext.accounts.utils import get_fiscal_year
from frappe.model.document import Document
class EmployeePayoutProcess(Document):
def get_sal_slip_list(self, ss_status, as_dict=False):
"""
Returns list of salary slips based on selected criteria
"""
ss_list = frappe.db.sql("""
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 = "") %s
""" % (ss_status, self.start_date, self.end_date), as_dict=as_dict)
print "@@@@@ salary slip list based on selected criteria ss_list"+ss_list
return ss_list
def get_total_salary_and_loan_amounts(self):
"""
Get total loan principal, loan interest and salary amount from submitted salary slip based on selected criteria
"""
totals = frappe.db.sql("""
select sum(principal_amount) as total_principal_amount, sum(interest_amount) as total_interest_amount,
sum(total_loan_repayment) as total_loan_repayment, sum(rounded_total) as rounded_total from `tabSalary Slip` t1
where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
""" % (self.start_date, self.end_date), as_dict=True)
return totals[0]
def get_default_payroll_payable_account(self):
payroll_payable_account = frappe.db.get_value("Company",
{"company_name": self.company}, "default_payroll_payable_account")
if not payroll_payable_account:
frappe.throw(_("Please set Default Payroll Payable Account in Company {0}")
.format(self.company))
return payroll_payable_account
def make_bank_payment_entry(self):
self.check_permission('write')
total_salary_amount = self.get_total_salary_and_loan_amounts()
default_payroll_payable_account = self.get_default_payroll_payable_account()
if total_salary_amount.rounded_total:
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.start_date,
self.end_date)
journal_entry.company = self.company
journal_entry.posting_date = nowdate()
account_amt_list = []
account_amt_list.append({
"account": self.payment_account,
"credit_in_account_currency": total_salary_amount.rounded_total
})
account_amt_list.append({
"account": default_payroll_payable_account,
"debit_in_account_currency": total_salary_amount.rounded_total
})
journal_entry.set("accounts", account_amt_list)
return journal_entry.as_dict()
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)
def set_start_end_dates(self):
self.update(get_start_end_dates(self.payroll_frequency,
self.start_date or self.posting_date, self.company))
@frappe.whitelist()
def salary_slip_data(bank_name,start_date,end_date):
emp_salary_data = []
emp_data = frappe.get_all('Employee', fields=['employee','bank_name','bank_ac_no','ifsc_code'],filters={"bank_name": bank_name})
for emp_details in emp_data:
salary_data = frappe.get_all('Salary Slip', fields=['net_pay','start_date','end_date'],filters={
"employee": emp_details.employee,
"start_date":[">=", getdate(start_date)],
"end_date":["<=", getdate(end_date)]
})
for sal_filter in salary_data:
aaaaa = {
"employee" : emp_details.employee,
"bank_name" : emp_details.bank_name,
"bank_ac_no" : emp_details.bank_ac_no,
"ifsc_code" : emp_details.ifsc_code,
"net_pay" : sal_filter.net_pay
}
print "@@@@@ aaaaa[] :::::::"+str(aaaaa)
emp_salary_data.append(aaaaa)
return emp_salary_data