blob: 17d5829f9080f2b3a62c815003ff9c6157b45cc1 [file] [log] [blame]
Rushabh Mehtadc8067e2016-06-29 18:38:32 +05301from __future__ import unicode_literals
Chillar Anand915b3432021-09-02 16:44:59 +05302
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +05303import datetime
Chillar Anand915b3432021-09-02 16:44:59 +05304import random
5
6import frappe
7from frappe.utils import add_days, get_last_day, getdate, random_string
8from frappe.utils.make_random import get_random
9
10import erpnext
11from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry
12from erpnext.hr.doctype.expense_claim.test_expense_claim import get_payable_account
13from erpnext.hr.doctype.leave_application.leave_application import (
14 AttendanceAlreadyMarkedError,
15 OverlapError,
16 get_leave_balance_on,
17)
Rohit Waghchaure8002d472016-07-13 16:03:05 +053018from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet
19from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
Chillar Anand915b3432021-09-02 16:44:59 +053020
Rushabh Mehtadc8067e2016-06-29 18:38:32 +053021
22def work():
23 frappe.set_user(frappe.db.get_global('demo_hr_user'))
Rushabh Mehtadc8067e2016-06-29 18:38:32 +053024 year, month = frappe.flags.current_date.strftime("%Y-%m").split("-")
Zlash65c24d2fd2018-09-27 18:49:00 +053025 setup_department_approvers()
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +053026 mark_attendance()
27 make_leave_application()
Rushabh Mehtadc8067e2016-06-29 18:38:32 +053028
Shreyaf8e7bc72017-12-01 10:42:12 +053029 # payroll entry
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +053030 if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'):
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +053031 # based on frequency
Zlash65796bffb2018-09-26 12:27:09 +053032 payroll_entry = get_payroll_entry()
Shreyaf8e7bc72017-12-01 10:42:12 +053033 payroll_entry.salary_slip_based_on_timesheet = 0
Zlash65796bffb2018-09-26 12:27:09 +053034 payroll_entry.save()
Shreyaf8e7bc72017-12-01 10:42:12 +053035 payroll_entry.create_salary_slips()
36 payroll_entry.submit_salary_slips()
Shreya9240eaa2018-03-30 12:19:11 +053037 payroll_entry.make_accrual_jv_entry()
Zlash65796bffb2018-09-26 12:27:09 +053038 payroll_entry.submit()
Shreyaf8e7bc72017-12-01 10:42:12 +053039 # payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
Rushabh Mehtacc8b2b22017-03-31 12:44:29 +053040 # reference_number=random_string(10))
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +053041
Zlash65796bffb2018-09-26 12:27:09 +053042 # based on timesheet
43 payroll_entry = get_payroll_entry()
Shreyaf8e7bc72017-12-01 10:42:12 +053044 payroll_entry.salary_slip_based_on_timesheet = 1
Zlash65796bffb2018-09-26 12:27:09 +053045 payroll_entry.save()
Shreyaf8e7bc72017-12-01 10:42:12 +053046 payroll_entry.create_salary_slips()
47 payroll_entry.submit_salary_slips()
Shreya9240eaa2018-03-30 12:19:11 +053048 payroll_entry.make_accrual_jv_entry()
Zlash65796bffb2018-09-26 12:27:09 +053049 payroll_entry.submit()
Shreyaf8e7bc72017-12-01 10:42:12 +053050 # payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
Rushabh Mehtacc8b2b22017-03-31 12:44:29 +053051 # reference_number=random_string(10))
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +053052
Rohit Waghchaure8002d472016-07-13 16:03:05 +053053 if frappe.db.get_global('demo_hr_user'):
54 make_timesheet_records()
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +053055
Saurabhf589c822016-07-15 18:28:05 +053056 #expense claim
57 expense_claim = frappe.new_doc("Expense Claim")
58 expense_claim.extend('expenses', get_expenses())
59 expense_claim.employee = get_random("Employee")
60 expense_claim.company = frappe.flags.company
rohitwaghchaureea092a72017-02-01 12:02:08 +053061 expense_claim.payable_account = get_payable_account(expense_claim.company)
Saurabhf589c822016-07-15 18:28:05 +053062 expense_claim.posting_date = frappe.flags.current_date
Zlash65c24d2fd2018-09-27 18:49:00 +053063 expense_claim.expense_approver = frappe.db.get_global('demo_hr_user')
64 expense_claim.save()
Saurabhf589c822016-07-15 18:28:05 +053065
66 rand = random.random()
67
Saurabh9cba6e12016-07-18 16:22:51 +053068 if rand < 0.4:
Saurabhf589c822016-07-15 18:28:05 +053069 update_sanctioned_amount(expense_claim)
Zlash65c24d2fd2018-09-27 18:49:00 +053070 expense_claim.approval_status = 'Approved'
Saurabhf589c822016-07-15 18:28:05 +053071 expense_claim.submit()
72
73 if random.randint(0, 1):
74 #make journal entry against expense claim
Nabin Hait9641d5b2017-08-01 17:33:08 +053075 je = frappe.get_doc(make_bank_entry("Expense Claim", expense_claim.name))
Saurabhf589c822016-07-15 18:28:05 +053076 je.posting_date = frappe.flags.current_date
77 je.cheque_no = random_string(10)
78 je.cheque_date = frappe.flags.current_date
79 je.flags.ignore_permissions = 1
80 je.submit()
81
Zlash65796bffb2018-09-26 12:27:09 +053082def get_payroll_entry():
83 # process payroll for previous month
84 payroll_entry = frappe.new_doc("Payroll Entry")
85 payroll_entry.company = frappe.flags.company
86 payroll_entry.payroll_frequency = 'Monthly'
87
88 # select a posting date from the previous month
89 payroll_entry.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10))
90 payroll_entry.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
91
92 payroll_entry.set_start_end_dates()
93 return payroll_entry
94
Saurabhf589c822016-07-15 18:28:05 +053095def get_expenses():
96 expenses = []
Saurabh718d8352016-07-18 15:20:47 +053097 expese_types = frappe.db.sql("""select ect.name, eca.default_account from `tabExpense Claim Type` ect,
98 `tabExpense Claim Account` eca where eca.parent=ect.name
99 and eca.company=%s """, frappe.flags.company,as_dict=1)
Saurabhf589c822016-07-15 18:28:05 +0530100
101 for expense_type in expese_types[:random.randint(1,4)]:
102 claim_amount = random.randint(1,20)*10
103
104 expenses.append({
105 "expense_date": frappe.flags.current_date,
106 "expense_type": expense_type.name,
107 "default_account": expense_type.default_account or "Miscellaneous Expenses - WPL",
Mangesh-Khairnar444313b2019-06-12 12:52:02 +0530108 "amount": claim_amount,
Saurabhf589c822016-07-15 18:28:05 +0530109 "sanctioned_amount": claim_amount
110 })
111
112 return expenses
113
114def update_sanctioned_amount(expense_claim):
115 for expense in expense_claim.expenses:
116 sanctioned_amount = random.randint(1,20)*10
117
Mangesh-Khairnar444313b2019-06-12 12:52:02 +0530118 if sanctioned_amount < expense.amount:
Saurabhf589c822016-07-15 18:28:05 +0530119 expense.sanctioned_amount = sanctioned_amount
Rohit Waghchaure8002d472016-07-13 16:03:05 +0530120
121def get_timesheet_based_salary_slip_employee():
Kanchan Chauhandb197d52016-08-20 00:30:59 +0530122 sal_struct = frappe.db.sql("""
123 select name from `tabSalary Structure`
124 where salary_slip_based_on_timesheet = 1
125 and docstatus != 2""")
126 if sal_struct:
127 employees = frappe.db.sql("""
Nabin Hait2f82bce2018-04-26 16:32:17 +0530128 select employee from `tabSalary Structure Assignment`
129 where salary_structure IN %(sal_struct)s""", {"sal_struct": sal_struct}, as_dict=True)
Kanchan Chauhandb197d52016-08-20 00:30:59 +0530130 return employees
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530131 else:
132 return []
133
Rohit Waghchaure8002d472016-07-13 16:03:05 +0530134def make_timesheet_records():
135 employees = get_timesheet_based_salary_slip_employee()
Kanchan Chauhandb197d52016-08-20 00:30:59 +0530136 for e in employees:
Zlash65796bffb2018-09-26 12:27:09 +0530137 ts = make_timesheet(e.employee, simulate = True, billable = 1, activity_type=get_random("Activity Type"), company=frappe.flags.company)
Rushabh Mehta397e5082017-01-21 16:57:24 +0530138 frappe.db.commit()
Rohit Waghchaure8002d472016-07-13 16:03:05 +0530139
140 rand = random.random()
141 if rand >= 0.3:
142 make_salary_slip_for_timesheet(ts.name)
143
144 rand = random.random()
145 if rand >= 0.2:
146 make_sales_invoice_for_timesheet(ts.name)
147
148def make_salary_slip_for_timesheet(name):
149 salary_slip = make_salary_slip(name)
150 salary_slip.insert()
151 salary_slip.submit()
Rohit Waghchaure7d439ec2016-07-21 14:50:59 +0530152 frappe.db.commit()
Rohit Waghchaure8002d472016-07-13 16:03:05 +0530153
154def make_sales_invoice_for_timesheet(name):
155 sales_invoice = make_sales_invoice(name)
156 sales_invoice.customer = get_random("Customer")
157 sales_invoice.append('items', {
Rushabh Mehta397e5082017-01-21 16:57:24 +0530158 'item_code': get_random("Item", {"has_variants": 0, "is_stock_item": 0,
159 "is_fixed_asset": 0}),
Rohit Waghchaure8002d472016-07-13 16:03:05 +0530160 'qty': 1,
161 'rate': 1000
162 })
Rohit Waghchaure7d439ec2016-07-21 14:50:59 +0530163 sales_invoice.flags.ignore_permissions = 1
Rohit Waghchaure8002d472016-07-13 16:03:05 +0530164 sales_invoice.set_missing_values()
165 sales_invoice.calculate_taxes_and_totals()
166 sales_invoice.insert()
Rohit Waghchaure7d439ec2016-07-21 14:50:59 +0530167 sales_invoice.submit()
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530168 frappe.db.commit()
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530169
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530170def make_leave_application():
171 allocated_leaves = frappe.get_all("Leave Allocation", fields=['employee', 'leave_type'])
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530172
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530173 for allocated_leave in allocated_leaves:
174 leave_balance = get_leave_balance_on(allocated_leave.employee, allocated_leave.leave_type, frappe.flags.current_date,
175 consider_all_leaves_in_the_allocation_period=True)
176 if leave_balance != 0:
177 if leave_balance == 1:
178 to_date = frappe.flags.current_date
179 else:
180 to_date = add_days(frappe.flags.current_date, random.randint(0, leave_balance-1))
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530181
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530182 leave_application = frappe.get_doc({
183 "doctype": "Leave Application",
184 "employee": allocated_leave.employee,
185 "from_date": frappe.flags.current_date,
186 "to_date": to_date,
187 "leave_type": allocated_leave.leave_type,
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530188 })
189 try:
190 leave_application.insert()
191 leave_application.submit()
192 frappe.db.commit()
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530193 except (OverlapError, AttendanceAlreadyMarkedError):
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530194 frappe.db.rollback()
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530195
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530196def mark_attendance():
Kanchan Chauhan7933eb62017-01-12 17:24:53 +0530197 attendance_date = frappe.flags.current_date
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530198 for employee in frappe.get_all('Employee', fields=['name'], filters = {'status': 'Active'}):
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530199
Kanchan Chauhan7933eb62017-01-12 17:24:53 +0530200 if not frappe.db.get_value("Attendance", {"employee": employee.name, "attendance_date": attendance_date}):
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530201 attendance = frappe.get_doc({
202 "doctype": "Attendance",
203 "employee": employee.name,
Kanchan Chauhan7933eb62017-01-12 17:24:53 +0530204 "attendance_date": attendance_date
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530205 })
Shreya Shahd9a585b2018-02-12 16:02:57 +0530206
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530207 leave = frappe.db.sql("""select name from `tabLeave Application`
Shreya Shahd9a585b2018-02-12 16:02:57 +0530208 where employee = %s and %s between from_date and to_date
Kanchan Chauhan7933eb62017-01-12 17:24:53 +0530209 and docstatus = 1""", (employee.name, attendance_date))
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530210
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530211 if leave:
212 attendance.status = "Absent"
213 else:
Neil Trini Lasrado06724592016-08-22 12:57:09 +0530214 attendance.status = "Present"
Kanchan Chauhandb0e57c2016-07-29 15:59:39 +0530215 attendance.save()
Rushabh Mehtae9d9b8e2016-12-15 11:27:35 +0530216 attendance.submit()
Neil Trini Lasrado06724592016-08-22 12:57:09 +0530217 frappe.db.commit()
Zlash65c24d2fd2018-09-27 18:49:00 +0530218
219def setup_department_approvers():
220 for d in frappe.get_all('Department', filters={'department_name': ['!=', 'All Departments']}):
221 doc = frappe.get_doc('Department', d.name)
222 doc.append("leave_approvers", {'approver': frappe.session.user})
223 doc.append("expense_approvers", {'approver': frappe.session.user})
224 doc.flags.ignore_mandatory = True
225 doc.save()