def check_sal_struct(self, joining_date, relieving_date): cond = '' payroll_frequency = "Monthly" date_details = get_start_end_dates(payroll_frequency, self.relieving_date) start_date = date_details.start_date end_date = date_details.end_date if payroll_frequency: cond = """and payroll_frequency = '%(payroll_frequency)s'""" % { "payroll_frequency": payroll_frequency } st_name = frappe.db.sql( """select parent from `tabSalary Structure Employee` where employee=%s and (from_date <= %s or from_date <= %s) and (to_date is null or to_date >= %s or to_date >= %s) and parent in (select name from `tabSalary Structure` where is_active = 'Yes'%s) """ % ('%s', '%s', '%s', '%s', '%s', cond), (self.employee, start_date, joining_date, end_date, relieving_date)) if st_name: if len(st_name) > 1: frappe.msgprint(_( "Multiple active Salary Structures found for employee {0} for the given dates" ).format(self.employee), title=_('Warning')) return st_name and st_name[0][0] or '' else: frappe.msgprint(_( "No active or default Salary Structure found for employee {0} for the given dates" ).format(self.employee), title=_('Salary Structure Missing'))
def get_month_dates(doc): date_details = get_start_end_dates(doc.payroll_frequency, doc.start_date or doc.posting_date) doc.end_date = date_details.end_date med = date_details.end_date doc.start_date = date_details.start_date msd = date_details.start_date return msd, med
def check_loan_deductions(self): payroll_frequency = "Monthly" date_details = get_start_end_dates(payroll_frequency, self.relieving_date) it = date_details.start_date dt = date_details.end_date loandata = frappe.db.sql(""" select t1.transaction_amount,t1.transaction_date from `tabLoan Transaction` t1,`tabMRP Loan Type` t2 where t1.parent = %s and t1.transaction_date >= %s and t1.transaction_date <= %s and (t2.name = t1.transaction_type and t2.type = 'Deduction' and t2.affect_doctype = 'Gratuity') """, (self.employee, it, dt), as_dict=True) company_currency = get_company_currency(self.company) loan_deduction = 0 loan_deduction_summary = "" if loandata: # loan_deduction_summary = "<b>Loan Deducions</b><br>" for d in loandata: # loan_deduction_summary += str(formatdate(d.transaction_date)) + " - " + str(fmt_money(d.transaction_amount, currency=company_currency)) + "<br>" loan_deduction += flt(d.transaction_amount) loan_deduction_summary = "<b>Total Loan Deduction:</b> " + str( fmt_money(loan_deduction, currency=company_currency)) return loan_deduction, loan_deduction_summary
def get_month_dates(doc): date_details = get_start_end_dates(doc.payroll_frequency, doc.start_date or doc.posting_date) doc.end_date = date_details.end_date med = date_details.end_date doc.start_date = date_details.start_date msd = date_details.start_date return msd, med
def test_loan(self): branch = "Test Employee Branch" applicant = make_employee("*****@*****.**", company="_Test Company") company = "_Test Company" holiday_list = make_holiday("test holiday for loan") company_doc = frappe.get_doc('Company', company) if not company_doc.default_payroll_payable_account: company_doc.default_payroll_payable_account = frappe.db.get_value('Account', {'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name') company_doc.save() if not frappe.db.exists('Branch', branch): frappe.get_doc({ 'doctype': 'Branch', 'branch': branch }).insert() employee_doc = frappe.get_doc('Employee', applicant) employee_doc.branch = branch employee_doc.holiday_list = holiday_list employee_doc.save() salary_structure = "Test Salary Structure for Loan" make_salary_structure(salary_structure, "Monthly", employee=employee_doc.name, company="_Test Company") loan = create_loan(applicant, "Car Loan", 280000, "Repay Over Number of Periods", 20, posting_date=add_months(nowdate(), -1)) loan.repay_from_salary = 1 loan.submit() make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1)) process_loan_interest_accrual_for_term_loans(posting_date=nowdate()) dates = get_start_end_dates('Monthly', nowdate()) make_payroll_entry(company="_Test Company", start_date=dates.start_date, end_date=dates.end_date, branch=branch, cost_center="Main - _TC", payment_account="Cash - _TC") name = frappe.db.get_value('Salary Slip', {'posting_date': nowdate(), 'employee': applicant}, 'name') salary_slip = frappe.get_doc('Salary Slip', name) for row in salary_slip.loans: if row.loan == loan.name: interest_amount = (280000 * 8.4)/(12*100) principal_amount = loan.monthly_repayment_amount - interest_amount self.assertEqual(row.interest_amount, interest_amount) self.assertEqual(row.principal_amount, principal_amount) self.assertEqual(row.total_payment, interest_amount + principal_amount) if salary_slip.docstatus == 0: frappe.delete_doc('Salary Slip', name)
def test_payroll_entry(self): # pylint: disable=no-self-use company = erpnext.get_default_company() for data in frappe.get_all('Salary Component', fields = ["name"]): if not frappe.db.get_value('Salary Component Account', {'parent': data.name, 'company': company}, 'name'): get_salary_component_account(data.name) employee = frappe.db.get_value("Employee", {'company': company}) make_salary_structure("_Test Salary Structure", "Monthly", employee) dates = get_start_end_dates('Monthly', nowdate()) if not frappe.db.get_value("Salary Slip", {"start_date": dates.start_date, "end_date": dates.end_date}): make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date)
def validate(doc, method): #Validate From Date should be first date of month if doc.from_date > doc.to_date: frappe.throw("From Date cannot be after To Date") date_details = get_start_end_dates("Monthly", doc.from_date) doj = frappe.db.get_value("Employee", doc.employee, "date_of_joining") if doj < date_details.end_date and doj >= date_details.start_date: doc.from_date = doj else: doc.from_date = date_details.start_date
def test_loan(self): branch = "Test Employee Branch" applicant = make_employee("*****@*****.**") company = erpnext.get_default_company() holiday_list = make_holiday("test holiday for loan") company_doc = frappe.get_doc('Company', company) if not company_doc.default_payroll_payable_account: company_doc.default_payroll_payable_account = frappe.db.get_value('Account', {'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name') company_doc.save() if not frappe.db.exists('Branch', branch): frappe.get_doc({ 'doctype': 'Branch', 'branch': branch }).insert() employee_doc = frappe.get_doc('Employee', applicant) employee_doc.branch = branch employee_doc.holiday_list = holiday_list employee_doc.save() loan = create_loan(applicant, "Personal Loan", 280000, "Repay Over Number of Periods", 20) loan.repay_from_salary = 1 loan.submit() salary_structure = "Test Salary Structure for Loan" make_salary_structure(salary_structure, "Monthly", employee_doc.name) dates = get_start_end_dates('Monthly', nowdate()) make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, branch=branch) name = frappe.db.get_value('Salary Slip', {'posting_date': nowdate(), 'employee': applicant}, 'name') salary_slip = frappe.get_doc('Salary Slip', name) for row in salary_slip.loans: if row.loan == loan.name: interest_amount = (280000 * 8.4)/(12*100) principal_amount = loan.monthly_repayment_amount - interest_amount self.assertEqual(row.interest_amount, interest_amount) self.assertEqual(row.principal_amount, principal_amount) self.assertEqual(row.total_payment, interest_amount + principal_amount) if salary_slip.docstatus == 0: frappe.delete_doc('Salary Slip', name)
def test_payroll_entry_with_employee_cost_center(self): # pylint: disable=no-self-use for data in frappe.get_all('Salary Component', fields = ["name"]): if not frappe.db.get_value('Salary Component Account', {'parent': data.name, 'company': "_Test Company"}, 'name'): get_salary_component_account(data.name) if not frappe.db.exists('Department', "cc - _TC"): frappe.get_doc({ 'doctype': 'Department', 'department_name': "cc", "company": "_Test Company" }).insert() employee1 = make_employee("*****@*****.**", payroll_cost_center="_Test Cost Center - _TC", department="cc - _TC", company="_Test Company") employee2 = make_employee("*****@*****.**", payroll_cost_center="_Test Cost Center 2 - _TC", department="cc - _TC", company="_Test Company") make_salary_structure("_Test Salary Structure 1", "Monthly", employee1, company="_Test Company") make_salary_structure("_Test Salary Structure 2", "Monthly", employee2, company="_Test Company") if not frappe.db.exists("Account", "_Test Payroll Payable - _TC"): create_account(account_name="_Test Payroll Payable", company="_Test Company", parent_account="Current Liabilities - _TC") frappe.db.set_value("Company", "_Test Company", "default_payroll_payable_account", "_Test Payroll Payable - _TC") dates = get_start_end_dates('Monthly', nowdate()) if not frappe.db.get_value("Salary Slip", {"start_date": dates.start_date, "end_date": dates.end_date}): pe = make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, department="cc - _TC", company="_Test Company", payment_account="Cash - _TC", cost_center="Main - _TC") je = frappe.db.get_value("Salary Slip", {"payroll_entry": pe.name}, "journal_entry") je_entries = frappe.db.sql(""" select account, cost_center, debit, credit from `tabJournal Entry Account` where parent=%s order by account, cost_center """, je) expected_je = ( ('_Test Payroll Payable - _TC', 'Main - _TC', 0.0, 155600.0), ('Salary - _TC', '_Test Cost Center - _TC', 78000.0, 0.0), ('Salary - _TC', '_Test Cost Center 2 - _TC', 78000.0, 0.0), ('Salary Deductions - _TC', '_Test Cost Center - _TC', 0.0, 200.0), ('Salary Deductions - _TC', '_Test Cost Center 2 - _TC', 0.0, 200.0) ) self.assertEqual(je_entries, expected_je)
def validate(doc,method): #Validate From Date should be first date of month if doc.from_date > doc.to_date: frappe.throw("From Date cannot be after To Date") date_details = get_start_end_dates("Monthly", doc.from_date) doj = frappe.db.get_value("Employee", doc.employee, "date_of_joining") if doj < date_details.end_date and doj >= date_details.start_date: doc.from_date = doj else: doc.from_date = date_details.start_date if doc.minimum_applicable > 0: if doc.basic_percent > 0: if ((doc.base + doc.variable) * doc.basic_percent)/100 < doc.minimum_applicable: frappe.throw("Basic Salary Cannot be Less than Minimum Applicable")
def get_date_details(self): if not self.end_date: date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date) self.start_date = date_details.start_date self.end_date = date_details.end_date
def test_employee_loan(self): from erpnext.hr.doctype.salary_structure.test_salary_structure import ( make_employee, make_salary_structure) from erpnext.hr.doctype.employee_loan.test_employee_loan import create_employee_loan branch = "Test Employee Branch" employee = make_employee("*****@*****.**") company = erpnext.get_default_company() holiday_list = make_holiday("test holiday for loan") if not frappe.db.exists('Salary Component', 'Basic Salary'): frappe.get_doc({ 'doctype': 'Salary Component', 'salary_component': 'Basic Salary', 'salary_component_abbr': 'BS', 'type': 'Earning', 'accounts': [{ 'company': company, 'default_account': frappe.db.get_value( 'Account', { 'company': company, 'root_type': 'Expense', 'account_type': '' }, 'name') }] }).insert() if not frappe.db.get_value('Salary Component Account', { 'parent': 'Basic Salary', 'company': company }): salary_component = frappe.get_doc('Salary Component', 'Basic Salary') salary_component.append('accounts', { 'company': company, 'default_account': 'Salary - WP' }) company_doc = frappe.get_doc('Company', company) if not company_doc.default_payroll_payable_account: company_doc.default_payroll_payable_account = frappe.db.get_value( 'Account', { 'company': company, 'root_type': 'Liability', 'account_type': '' }, 'name') company_doc.save() if not frappe.db.exists('Branch', branch): frappe.get_doc({'doctype': 'Branch', 'branch': branch}).insert() employee_doc = frappe.get_doc('Employee', employee) employee_doc.branch = branch employee_doc.holiday_list = holiday_list employee_doc.save() employee_loan = create_employee_loan(employee, "Personal Loan", 280000, "Repay Over Number of Periods", 20) employee_loan.repay_from_salary = 1 employee_loan.submit() salary_strcture = "Test Salary Structure for Loan" if not frappe.db.exists('Salary Structure', salary_strcture): salary_strcture = make_salary_structure( salary_strcture, [{ 'employee': employee, 'from_date': '2017-01-01', 'base': 30000 }]) salary_strcture = frappe.get_doc('Salary Structure', salary_strcture) salary_strcture.set('earnings', [{ 'salary_component': 'Basic Salary', 'abbr': 'BS', 'amount_based_on_formula': 1, 'formula': 'base*.5' }]) salary_strcture.save() dates = get_start_end_dates('Monthly', nowdate()) make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, branch=branch) name = frappe.db.get_value('Salary Slip', { 'posting_date': nowdate(), 'employee': employee }, 'name') salary_slip = frappe.get_doc('Salary Slip', name) for row in salary_slip.loans: if row.employee_loan == employee_loan.name: interest_amount = (280000 * 8.4) / (12 * 100) principal_amount = employee_loan.monthly_repayment_amount - interest_amount self.assertEqual(row.interest_amount, interest_amount) self.assertEqual(row.principal_amount, principal_amount) self.assertEqual(row.total_payment, interest_amount + principal_amount) if salary_slip.docstatus == 0: frappe.delete_doc('Salary Slip', name) employee_loan.cancel() frappe.delete_doc('Employee Loan', employee_loan.name)
def get_date_details(self): if not self.end_date: date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date) self.start_date = date_details.start_date self.end_date = date_details.end_date
def test_employee_loan(self): from erpnext.hr.doctype.salary_structure.test_salary_structure import (make_employee, make_salary_structure) from erpnext.hr.doctype.employee_loan.test_employee_loan import create_employee_loan branch = "Test Employee Branch" employee = make_employee("*****@*****.**") company = erpnext.get_default_company() holiday_list = make_holiday("test holiday for loan") if not frappe.db.exists('Salary Component', 'Basic Salary'): frappe.get_doc({ 'doctype': 'Salary Component', 'salary_component': 'Basic Salary', 'salary_component_abbr': 'BS', 'type': 'Earning', 'accounts': [{ 'company': company, 'default_account': frappe.db.get_value('Account', {'company': company, 'root_type': 'Expense', 'account_type': ''}, 'name') }] }).insert() if not frappe.db.get_value('Salary Component Account', {'parent': 'Basic Salary', 'company': company}): salary_component = frappe.get_doc('Salary Component', 'Basic Salary') salary_component.append('accounts', { 'company': company, 'default_account': 'Salary - WP' }) company_doc = frappe.get_doc('Company', company) if not company_doc.default_payroll_payable_account: company_doc.default_payroll_payable_account = frappe.db.get_value('Account', {'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name') company_doc.save() if not frappe.db.exists('Branch', branch): frappe.get_doc({ 'doctype': 'Branch', 'branch': branch }).insert() employee_doc = frappe.get_doc('Employee', employee) employee_doc.branch = branch employee_doc.holiday_list = holiday_list employee_doc.save() employee_loan = create_employee_loan(employee, "Personal Loan", 280000, "Repay Over Number of Periods", 20) employee_loan.repay_from_salary = 1 employee_loan.submit() salary_strcture = "Test Salary Structure for Loan" if not frappe.db.exists('Salary Structure', salary_strcture): salary_strcture = make_salary_structure(salary_strcture, [{ 'employee': employee, 'from_date': '2017-01-01', 'base': 30000 }]) salary_strcture = frappe.get_doc('Salary Structure', salary_strcture) salary_strcture.set('earnings', [{ 'salary_component': 'Basic Salary', 'abbr': 'BS', 'amount_based_on_formula':1, 'formula': 'base*.5' }]) salary_strcture.save() dates = get_start_end_dates('Monthly', nowdate()) make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, branch=branch) name = frappe.db.get_value('Salary Slip', {'posting_date': nowdate(), 'employee': employee}, 'name') salary_slip = frappe.get_doc('Salary Slip', name) for row in salary_slip.loans: if row.employee_loan == employee_loan.name: interest_amount = (280000 * 8.4)/(12*100) principal_amount = employee_loan.monthly_repayment_amount - interest_amount self.assertEqual(row.interest_amount, interest_amount) self.assertEqual(row.principal_amount, principal_amount) self.assertEqual(row.total_payment, interest_amount + principal_amount) if salary_slip.docstatus == 0: frappe.delete_doc('Salary Slip', name) employee_loan.cancel() frappe.delete_doc('Employee Loan', employee_loan.name)