From 1e7c32b909cf99d7e46abb17624971979ee5ca23 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 26 Sep 2018 18:01:00 +0530 Subject: [PATCH] Payroll fixes and more (#15475) * fix(payroll): multiple minor fixes related to salary structure * Added GSTR-1 and GSTR-2 report in Accounts module page * delete asset movement records on cancellation of Purchase Receipt * Update consolidated_financial_statement.py * minor fix * minor fix * add filters on item prices report (#15495) --- .../consolidated_financial_statement.py | 3 +- erpnext/config/accounts.py | 10 ++++++ erpnext/controllers/buying_controller.py | 2 +- .../leave_application/leave_application.json | 35 ++++++++++++++++++- .../salary_component/salary_component.json | 9 ++--- .../doctype/salary_detail/salary_detail.json | 7 ++-- erpnext/hr/doctype/salary_slip/salary_slip.py | 4 +-- .../doctype/salary_slip/test_salary_slip.py | 29 +++++++++------ .../salary_structure/salary_structure.py | 15 +++++--- .../stock/report/item_prices/item_prices.js | 11 +++++- .../stock/report/item_prices/item_prices.py | 21 ++++++++--- 11 files changed, 113 insertions(+), 33 deletions(-) diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py index d517a56047..b6d4875e97 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py @@ -268,8 +268,7 @@ def get_companies(filters): return all_companies, companies def get_subsidiary_companies(company): - lft, rgt = frappe.get_cached_value('Company', - company, ["lft", "rgt"]) + lft, rgt = frappe.db.get_value('Company', company, ["lft", "rgt"]) return frappe.db.sql_list("""select name from `tabCompany` where lft >= {0} and rgt <= {1} order by lft, rgt""".format(lft, rgt)) diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py index 660f78cc91..d9ffced547 100644 --- a/erpnext/config/accounts.py +++ b/erpnext/config/accounts.py @@ -235,6 +235,16 @@ def get_data(): "type": "doctype", "name": "GST HSN Code", }, + { + "type": "report", + "name": "GSTR-1", + "is_query_report": True + }, + { + "type": "report", + "name": "GSTR-2", + "is_query_report": True + }, { "type": "report", "name": "GST Sales Register", diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 3671481682..86fecdce45 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -661,7 +661,7 @@ class BuyingController(StockController): if self.doctype == 'Purchase Invoice' and not self.get('update_stock'): return - frappe.db.sql("delete from `tabAsset Movement` where reference_name=%s and docstatus = 0", self.name) + frappe.db.sql("delete from `tabAsset Movement` where reference_name=%s", self.name) frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name) def validate_schedule_date(self): diff --git a/erpnext/hr/doctype/leave_application/leave_application.json b/erpnext/hr/doctype/leave_application/leave_application.json index 914dda21cb..f9d83a4244 100644 --- a/erpnext/hr/doctype/leave_application/leave_application.json +++ b/erpnext/hr/doctype/leave_application/leave_application.json @@ -651,6 +651,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "salary_slip", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Salary Slip", + "length": 0, + "no_copy": 0, + "options": "Salary Slip", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -916,7 +949,7 @@ "issingle": 0, "istable": 0, "max_attachments": 3, - "modified": "2018-08-21 14:44:42.766422", + "modified": "2018-09-21 15:53:11.935416", "modified_by": "Administrator", "module": "HR", "name": "Leave Application", diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json index 4221916469..f7ce08c737 100644 --- a/erpnext/hr/doctype/salary_component/salary_component.json +++ b/erpnext/hr/doctype/salary_component/salary_component.json @@ -770,7 +770,7 @@ "collapsible": 1, "collapsible_depends_on": "", "columns": 0, - "depends_on": "eval:doc.is_flexible_benefit != 1 && doc.variable_based_on_taxable_salary != 1 && doc.is_additional_component != 1", + "depends_on": "eval:doc.is_flexible_benefit != 1 && doc.variable_based_on_taxable_salary != 1", "fieldname": "condition_and_formula", "fieldtype": "Section Break", "hidden": 0, @@ -835,7 +835,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "default": "1", + "default": "", "fieldname": "amount_based_on_formula", "fieldtype": "Check", "hidden": 0, @@ -1003,7 +1003,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-07-02 16:55:44.467519", + "modified": "2018-09-20 16:44:58.876044", "modified_by": "Administrator", "module": "HR", "name": "Salary Component", @@ -1056,5 +1056,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json index ebec32b6f8..bc9812c34f 100644 --- a/erpnext/hr/doctype/salary_detail/salary_detail.json +++ b/erpnext/hr/doctype/salary_detail/salary_detail.json @@ -385,7 +385,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "default": "1", + "default": "0", "depends_on": "eval:doc.parenttype=='Salary Structure'", "fetch_from": "", "fieldname": "amount_based_on_formula", @@ -692,7 +692,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-07-04 16:28:32.314907", + "modified": "2018-09-20 16:59:33.622652", "modified_by": "Administrator", "module": "HR", "name": "Salary Detail", @@ -706,5 +706,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index 2c2e4d4a02..85e372d184 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -384,8 +384,8 @@ class SalarySlip(TransactionBase): and t2.is_lwp = 1 and t1.docstatus = 1 and t1.employee = %(employee)s - and CASE WHEN t2.include_holiday != 1 THEN %(dt)s not in ('{0}') and %(dt)s between from_date and to_date - WHEN t2.include_holiday THEN %(dt)s between from_date and to_date + and CASE WHEN t2.include_holiday != 1 THEN %(dt)s not in ('{0}') and %(dt)s between from_date and to_date and ifnull(t1.salary_slip, '') = '' + WHEN t2.include_holiday THEN %(dt)s between from_date and to_date and ifnull(t1.salary_slip, '') = '' END """.format(holidays), {"employee": self.employee, "dt": dt}) if leave: diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py index 144022b08e..73ab67dd6f 100644 --- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py @@ -323,11 +323,12 @@ def make_salary_component(salary_components, test_tax): def get_salary_component_account(sal_comp): company = erpnext.get_default_company() sal_comp = frappe.get_doc("Salary Component", sal_comp) - sal_comp.append("accounts", { - "company": company, - "default_account": create_account(company) - }) - sal_comp.save() + if not sal_comp.get("accounts"): + sal_comp.append("accounts", { + "company": company, + "default_account": create_account(company) + }) + sal_comp.save() def create_account(company): salary_account = frappe.db.get_value("Account", "Salary - " + frappe.get_cached_value('Company', company, 'abbr')) @@ -347,7 +348,8 @@ def make_earning_salary_component(setup=False, test_tax=False): "abbr":'BS', "condition": 'base > 10000', "formula": 'base*.5', - "type": "Earning" + "type": "Earning", + "amount_based_on_formula": 1 }, { "salary_component": 'HRA', @@ -360,7 +362,8 @@ def make_earning_salary_component(setup=False, test_tax=False): "abbr":'SA', "condition": 'H < 10000', "formula": 'BS*.5', - "type": "Earning" + "type": "Earning", + "amount_based_on_formula": 1 }, { "salary_component": "Leave Encashment", @@ -401,7 +404,8 @@ def make_earning_salary_component(setup=False, test_tax=False): "abbr":'BS', "condition": 'base < 10000', "formula": 'base*.2', - "type": "Earning" + "type": "Earning", + "amount_based_on_formula": 1 }) return data @@ -412,13 +416,15 @@ def make_deduction_salary_component(setup=False, test_tax=False): "abbr":'PT', "condition": 'base > 10000', "formula": 'base*.1', - "type": "Deduction" + "type": "Deduction", + "amount_based_on_formula": 1 }, { "salary_component": 'TDS', "abbr":'T', "formula": 'base*.1', - "type": "Deduction" + "type": "Deduction", + "amount_based_on_formula": 1 } ] if not test_tax: @@ -427,7 +433,8 @@ def make_deduction_salary_component(setup=False, test_tax=False): "abbr":'T', "condition": 'employment_type=="Intern"', "formula": 'base*.1', - "type": "Deduction" + "type": "Deduction", + "amount_based_on_formula": 1 }) if setup or test_tax: make_salary_component(data, test_tax) diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py index 6b190db01f..a36d820f2c 100644 --- a/erpnext/hr/doctype/salary_structure/salary_structure.py +++ b/erpnext/hr/doctype/salary_structure/salary_structure.py @@ -18,14 +18,21 @@ class SalaryStructure(Document): self.validate_max_benefits_with_flexi() def set_missing_values(self): - fields = ["depends_on_lwp", "variable_based_on_taxable_salary", "is_tax_applicable", "is_flexible_benefit"] + overwritten_fields = ["depends_on_lwp", "variable_based_on_taxable_salary", "is_tax_applicable", "is_flexible_benefit"] + overwritten_fields_if_missing = ["amount_based_on_formula", "formula", "amount"] for table in ["earnings", "deductions"]: for d in self.get(table): - component_default_value = frappe.db.get_value("Salary Component", str(d.salary_component), fields, as_dict=1) + component_default_value = frappe.db.get_value("Salary Component", str(d.salary_component), + overwritten_fields + overwritten_fields_if_missing, as_dict=1) if component_default_value: - for fieldname, value in iteritems(component_default_value): + for fieldname in overwritten_fields: + value = component_default_value.get(fieldname) if d.get(fieldname) != value: - d[fieldname] = value + d.set(fieldname, value) + + if not (d.get("amount") or d.get("formula")): + for fieldname in overwritten_fields_if_missing: + d.set(fieldname, component_default_value.get(fieldname)) def validate_amount(self): if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet: diff --git a/erpnext/stock/report/item_prices/item_prices.js b/erpnext/stock/report/item_prices/item_prices.js index 272f83e228..77bca4466d 100644 --- a/erpnext/stock/report/item_prices/item_prices.js +++ b/erpnext/stock/report/item_prices/item_prices.js @@ -3,6 +3,15 @@ frappe.query_reports["Item Prices"] = { "filters": [ - + { + "fieldname": "items", + "label": __("Items Filter"), + "fieldtype": "Select", + "options": "Enabled Items only\nDisabled Items only\nAll Items", + "default": "Enabled Items only", + "on_change": function(query_report) { + query_report.trigger_refresh(); + } + } ] } diff --git a/erpnext/stock/report/item_prices/item_prices.py b/erpnext/stock/report/item_prices/item_prices.py index 0375d8fabb..aa3ed92079 100644 --- a/erpnext/stock/report/item_prices/item_prices.py +++ b/erpnext/stock/report/item_prices/item_prices.py @@ -10,7 +10,8 @@ def execute(filters=None): if not filters: filters = {} columns = get_columns(filters) - item_map = get_item_details() + conditions = get_condition(filters) + item_map = get_item_details(conditions) pl = get_price_list() last_purchase_rate = get_last_purchase_rate() bom_rate = get_item_bom_rate() @@ -41,14 +42,14 @@ def get_columns(filters): return columns -def get_item_details(): +def get_item_details(conditions): """returns all items details""" item_map = {} for i in frappe.db.sql("""select name, item_group, item_name, description, - brand, stock_uom from tabItem - order by item_code, item_group""", as_dict=1): + brand, stock_uom from tabItem %s + order by item_code, item_group""" % (conditions), as_dict=1): item_map.setdefault(i.name, i) return item_map @@ -133,3 +134,15 @@ def get_valuation_rate(): item_val_rate_map.setdefault(d.item_code, d.val_rate) return item_val_rate_map + +def get_condition(filters): + """Get Filter Items""" + + if filters.get("items") == "Enabled Items only": + conditions = " where disabled=0 " + elif filters.get("items") == "Disabled Items only": + conditions = " where disabled=1 " + else: + conditions = "" + + return conditions