From ab8df98cab91a0945abb6ed4bb795a8f8b6d03fc Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 10 Jun 2022 18:22:07 +0530 Subject: [PATCH] chore: Remove regional code for India HR, moved to HRMS --- erpnext/hooks.py | 10 -- erpnext/regional/india/utils.py | 209 +------------------------------- 2 files changed, 1 insertion(+), 218 deletions(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 5fca061f6bd..ac529969e83 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -399,17 +399,14 @@ scheduler_events = { }, "all": [ "erpnext.projects.doctype.project.project.project_status_update_reminder", - "erpnext.hr.doctype.interview.interview.send_interview_reminder", "erpnext.crm.doctype.social_media_post.social_media_post.process_scheduled_social_media_posts", ], "hourly": [ - "erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails", "erpnext.accounts.doctype.subscription.subscription.process_all", "erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs", "erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.automatic_synchronization", "erpnext.projects.doctype.project.project.hourly_reminder", "erpnext.projects.doctype.project.project.collect_project_status", - "erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts", ], "hourly_long": [ "erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.repost_entries", @@ -423,7 +420,6 @@ scheduler_events = { "erpnext.accounts.doctype.fiscal_year.fiscal_year.auto_create_fiscal_year", "erpnext.projects.doctype.task.task.set_tasks_as_overdue", "erpnext.assets.doctype.asset.depreciation.post_depreciation_entries", - "erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.send_summary", "erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status", "erpnext.buying.doctype.supplier_scorecard.supplier_scorecard.refresh_scorecards", "erpnext.setup.doctype.company.company.cache_companies_monthly_sales_history", @@ -439,14 +435,10 @@ scheduler_events = { "erpnext.selling.doctype.quotation.quotation.set_expired_status", "erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status", "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email", - "erpnext.hr.doctype.interview.interview.send_daily_feedback_reminder", ], "daily_long": [ "erpnext.setup.doctype.email_digest.email_digest.send", "erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.auto_update_latest_price_in_all_boms", - "erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation", - "erpnext.hr.utils.generate_leave_encashment", - "erpnext.hr.utils.allocate_earned_leaves", "erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall.create_process_loan_security_shortfall", "erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual.process_loan_interest_accrual_for_term_loans", "erpnext.crm.doctype.lead.lead.daily_open_lead", @@ -535,8 +527,6 @@ regional_overrides = { "erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_data": "erpnext.regional.india.utils.get_itemised_tax_breakup_data", "erpnext.accounts.party.get_regional_address_details": "erpnext.regional.india.utils.get_regional_address_details", "erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts": "erpnext.regional.india.utils.get_regional_round_off_accounts", - "erpnext.hr.utils.calculate_annual_eligible_hra_exemption": "erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption", - "erpnext.hr.utils.calculate_hra_exemption_for_period": "erpnext.regional.india.utils.calculate_hra_exemption_for_period", "erpnext.controllers.accounts_controller.validate_einvoice_fields": "erpnext.regional.india.e_invoice.utils.validate_einvoice_fields", "erpnext.assets.doctype.asset.asset.get_depreciation_amount": "erpnext.regional.india.utils.get_depreciation_amount", "erpnext.stock.doctype.item.item.set_item_tax_from_hsn_code": "erpnext.regional.india.utils.set_item_tax_from_hsn_code", diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index ee48ccb24a4..049486e9c99 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -1,25 +1,13 @@ import json -import math import re import frappe from frappe import _ from frappe.model.utils import get_fetch_values -from frappe.utils import ( - add_days, - cint, - cstr, - date_diff, - flt, - get_link_to_form, - getdate, - month_diff, -) +from frappe.utils import cint, cstr, date_diff, flt, getdate from erpnext.controllers.accounts_controller import get_taxes_and_charges from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount -from erpnext.hr.utils import get_salary_assignments -from erpnext.payroll.doctype.salary_structure.salary_structure import make_salary_slip from erpnext.regional.india import number_state_mapping, state_numbers, states GST_INVOICE_NUMBER_FORMAT = re.compile(r"^[a-zA-Z0-9\-/]+$") # alphanumeric and - / @@ -365,201 +353,6 @@ def get_tax_template(master_doctype, company, is_inter_state, state_code): return default_tax -def calculate_annual_eligible_hra_exemption(doc): - basic_component, hra_component = frappe.db.get_value( - "Company", doc.company, ["basic_component", "hra_component"] - ) - - if not (basic_component and hra_component): - frappe.throw( - _("Please set Basic and HRA component in Company {0}").format( - get_link_to_form("Company", doc.company) - ) - ) - - annual_exemption = monthly_exemption = hra_amount = basic_amount = 0 - - if hra_component and basic_component: - assignments = get_salary_assignments(doc.employee, doc.payroll_period) - - if not assignments and doc.docstatus == 1: - frappe.throw( - _("Salary Structure must be submitted before submission of {0}").format(doc.doctype) - ) - - assignment_dates = [assignment.from_date for assignment in assignments] - - for idx, assignment in enumerate(assignments): - if has_hra_component(assignment.salary_structure, hra_component): - basic_salary_amt, hra_salary_amt = get_component_amt_from_salary_slip( - doc.employee, - assignment.salary_structure, - basic_component, - hra_component, - assignment.from_date, - ) - to_date = get_end_date_for_assignment(assignment_dates, idx, doc.payroll_period) - - frequency = frappe.get_value( - "Salary Structure", assignment.salary_structure, "payroll_frequency" - ) - basic_amount += get_component_pay(frequency, basic_salary_amt, assignment.from_date, to_date) - hra_amount += get_component_pay(frequency, hra_salary_amt, assignment.from_date, to_date) - - if hra_amount: - if doc.monthly_house_rent: - annual_exemption = calculate_hra_exemption( - assignment.salary_structure, - basic_amount, - hra_amount, - doc.monthly_house_rent, - doc.rented_in_metro_city, - ) - if annual_exemption > 0: - monthly_exemption = annual_exemption / 12 - else: - annual_exemption = 0 - - return frappe._dict( - { - "hra_amount": hra_amount, - "annual_exemption": annual_exemption, - "monthly_exemption": monthly_exemption, - } - ) - - -def has_hra_component(salary_structure, hra_component): - return frappe.db.exists( - "Salary Detail", - { - "parent": salary_structure, - "salary_component": hra_component, - "parentfield": "earnings", - "parenttype": "Salary Structure", - }, - ) - - -def get_end_date_for_assignment(assignment_dates, idx, payroll_period): - end_date = None - - try: - end_date = assignment_dates[idx + 1] - end_date = add_days(end_date, -1) - except IndexError: - pass - - if not end_date: - end_date = frappe.db.get_value("Payroll Period", payroll_period, "end_date") - - return end_date - - -def get_component_amt_from_salary_slip( - employee, salary_structure, basic_component, hra_component, from_date -): - salary_slip = make_salary_slip( - salary_structure, - employee=employee, - for_preview=1, - ignore_permissions=True, - posting_date=from_date, - ) - - basic_amt, hra_amt = 0, 0 - for earning in salary_slip.earnings: - if earning.salary_component == basic_component: - basic_amt = earning.amount - elif earning.salary_component == hra_component: - hra_amt = earning.amount - if basic_amt and hra_amt: - return basic_amt, hra_amt - return basic_amt, hra_amt - - -def calculate_hra_exemption( - salary_structure, annual_basic, annual_hra, monthly_house_rent, rented_in_metro_city -): - # TODO make this configurable - exemptions = [] - # case 1: The actual amount allotted by the employer as the HRA. - exemptions.append(annual_hra) - - # case 2: Actual rent paid less 10% of the basic salary. - actual_annual_rent = monthly_house_rent * 12 - exemptions.append(flt(actual_annual_rent) - flt(annual_basic * 0.1)) - - # case 3: 50% of the basic salary, if the employee is staying in a metro city (40% for a non-metro city). - exemptions.append(annual_basic * 0.5 if rented_in_metro_city else annual_basic * 0.4) - - # return minimum of 3 cases - return min(exemptions) - - -def get_component_pay(frequency, amount, from_date, to_date): - days = date_diff(to_date, from_date) + 1 - - if frequency == "Daily": - return amount * days - elif frequency == "Weekly": - return amount * math.floor(days / 7) - elif frequency == "Fortnightly": - return amount * math.floor(days / 14) - elif frequency == "Monthly": - return amount * month_diff(to_date, from_date) - elif frequency == "Bimonthly": - return amount * (month_diff(to_date, from_date) / 2) - - -def validate_house_rent_dates(doc): - if not doc.rented_to_date or not doc.rented_from_date: - frappe.throw(_("House rented dates required for exemption calculation")) - - if date_diff(doc.rented_to_date, doc.rented_from_date) < 14: - frappe.throw(_("House rented dates should be atleast 15 days apart")) - - proofs = frappe.db.sql( - """ - select name - from `tabEmployee Tax Exemption Proof Submission` - where - docstatus=1 and employee=%(employee)s and payroll_period=%(payroll_period)s - and (rented_from_date between %(from_date)s and %(to_date)s or rented_to_date between %(from_date)s and %(to_date)s) - """, - { - "employee": doc.employee, - "payroll_period": doc.payroll_period, - "from_date": doc.rented_from_date, - "to_date": doc.rented_to_date, - }, - ) - - if proofs: - frappe.throw(_("House rent paid days overlapping with {0}").format(proofs[0][0])) - - -def calculate_hra_exemption_for_period(doc): - monthly_rent, eligible_hra = 0, 0 - if doc.house_rent_payment_amount: - validate_house_rent_dates(doc) - # TODO receive rented months or validate dates are start and end of months? - # Calc monthly rent, round to nearest .5 - factor = flt(date_diff(doc.rented_to_date, doc.rented_from_date) + 1) / 30 - factor = round(factor * 2) / 2 - monthly_rent = doc.house_rent_payment_amount / factor - # update field used by calculate_annual_eligible_hra_exemption - doc.monthly_house_rent = monthly_rent - exemptions = calculate_annual_eligible_hra_exemption(doc) - - if exemptions["monthly_exemption"]: - # calc total exemption amount - eligible_hra = exemptions["monthly_exemption"] * factor - exemptions["monthly_house_rent"] = monthly_rent - exemptions["total_eligible_hra_exemption"] = eligible_hra - return exemptions - - def get_ewb_data(dt, dn): ewaybills = []