From 363ed9ccba3f848908113e6d728735a1c894aec8 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Sat, 5 Feb 2022 14:06:18 +0100 Subject: [PATCH 01/15] =?UTF-8?q?revert:=20BU=20Schl=C3=BCssel=20(a21f76f)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- erpnext/regional/report/datev/datev.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py index beac7ed65c..92a10c288f 100644 --- a/erpnext/regional/report/datev/datev.py +++ b/erpnext/regional/report/datev/datev.py @@ -343,8 +343,7 @@ def run_query(filters, extra_fields, extra_joins, extra_filters, as_dict=1): /* against number or, if empty, party against number */ %(temporary_against_account_number)s as 'Gegenkonto (ohne BU-Schlüssel)', - /* disable automatic VAT deduction */ - '40' as 'BU-Schlüssel', + '' as 'BU-Schlüssel', gl.posting_date as 'Belegdatum', gl.voucher_no as 'Belegfeld 1', From b2755f6fdddd3e1b0a305b57c18651c98fee8f7e Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 7 Mar 2022 13:02:08 +0530 Subject: [PATCH 02/15] feat: Include child item group products in Item Group Page & cleanup - Added 'Include descendants' checkbox, which will pull child item group products too - Build item group filters in query engine file - Include logic in filter engine - Clean up Website section of Item Group page (UX) - Add util to fetch child item groups including self --- erpnext/e_commerce/api.py | 1 - .../e_commerce/product_data_engine/filters.py | 22 ++++++--- .../e_commerce/product_data_engine/query.py | 48 ++++++++----------- .../setup/doctype/item_group/item_group.json | 31 +++++++++--- .../setup/doctype/item_group/item_group.py | 8 +++- 5 files changed, 69 insertions(+), 41 deletions(-) diff --git a/erpnext/e_commerce/api.py b/erpnext/e_commerce/api.py index 43cb36ca2e..84554ae7d0 100644 --- a/erpnext/e_commerce/api.py +++ b/erpnext/e_commerce/api.py @@ -48,7 +48,6 @@ def get_product_filter_data(query_args=None): sub_categories = [] if item_group: - field_filters['item_group'] = item_group sub_categories = get_child_groups_for_website(item_group, immediate=True) engine = ProductQuery() diff --git a/erpnext/e_commerce/product_data_engine/filters.py b/erpnext/e_commerce/product_data_engine/filters.py index c4a3cb9fbe..89d4ffdff4 100644 --- a/erpnext/e_commerce/product_data_engine/filters.py +++ b/erpnext/e_commerce/product_data_engine/filters.py @@ -14,6 +14,8 @@ class ProductFiltersBuilder: self.item_group = item_group def get_field_filters(self): + from erpnext.setup.doctype.item_group.item_group import get_child_groups_for_website + if not self.item_group and not self.doc.enable_field_filters: return @@ -25,18 +27,26 @@ class ProductFiltersBuilder: fields = [item_meta.get_field(field) for field in filter_fields if item_meta.has_field(field)] for df in fields: - item_filters, item_or_filters = {}, [] + item_filters, item_or_filters = {"published_in_website": 1}, [] link_doctype_values = self.get_filtered_link_doctype_records(df) if df.fieldtype == "Link": if self.item_group: - item_or_filters.extend([ - ["item_group", "=", self.item_group], - ["Website Item Group", "item_group", "=", self.item_group] # consider website item groups - ]) + include_child = frappe.db.get_value("Item Group", self.item_group, "include_descendants") + if include_child: + include_groups = get_child_groups_for_website(self.item_group, include_self=True) + include_groups = [x.name for x in include_groups] + item_or_filters.extend([ + ["item_group", "in", include_groups], + ["Website Item Group", "item_group", "=", self.item_group] # consider website item groups + ]) + else: + item_or_filters.extend([ + ["item_group", "=", self.item_group], + ["Website Item Group", "item_group", "=", self.item_group] # consider website item groups + ]) # Get link field values attached to published items - item_filters['published_in_website'] = 1 item_values = frappe.get_all( "Item", fields=[df.fieldname], diff --git a/erpnext/e_commerce/product_data_engine/query.py b/erpnext/e_commerce/product_data_engine/query.py index cfc3c7b357..5c92e3d98a 100644 --- a/erpnext/e_commerce/product_data_engine/query.py +++ b/erpnext/e_commerce/product_data_engine/query.py @@ -46,10 +46,10 @@ class ProductQuery: self.filter_with_discount = bool(fields.get("discount")) result, discount_list, website_item_groups, cart_items, count = [], [], [], [], 0 - website_item_groups = self.get_website_item_group_results(item_group, website_item_groups) - if fields: self.build_fields_filters(fields) + if item_group: + self.build_item_group_filters(item_group) if search_term: self.build_search_filters(search_term) if self.settings.hide_variants: @@ -61,8 +61,6 @@ class ProductQuery: else: result, count = self.query_items(start=start) - result = self.combine_web_item_group_results(item_group, result, website_item_groups) - # sort combined results by ranking result = sorted(result, key=lambda x: x.get("ranking"), reverse=True) @@ -167,6 +165,25 @@ class ProductQuery: # `=` will be faster than `IN` for most cases self.filters.append([field, "=", values]) + def build_item_group_filters(self, item_group): + "Add filters for Item group page and include Website Item Groups." + from erpnext.setup.doctype.item_group.item_group import get_child_groups_for_website + item_group_filters = [] + + item_group_filters.append(["Website Item", "item_group", "=", item_group]) + # Consider Website Item Groups + item_group_filters.append(["Website Item Group", "item_group", "=", item_group]) + + if frappe.db.get_value("Item Group", item_group, "include_descendants"): + # include child item group's items as well + # eg. Group Node A, will show items of child 1 and child 2 as well + # on it's web page + include_groups = get_child_groups_for_website(item_group, include_self=True) + include_groups = [x.name for x in include_groups] + item_group_filters.append(["Website Item", "item_group", "in", include_groups]) + + self.or_filters.extend(item_group_filters) + def build_search_filters(self, search_term): """Query search term in specified fields @@ -190,19 +207,6 @@ class ProductQuery: for field in search_fields: self.or_filters.append([field, "like", search]) - def get_website_item_group_results(self, item_group, website_item_groups): - """Get Web Items for Item Group Page via Website Item Groups.""" - if item_group: - website_item_groups = frappe.db.get_all( - "Website Item", - fields=self.fields + ["`tabWebsite Item Group`.parent as wig_parent"], - filters=[ - ["Website Item Group", "item_group", "=", item_group], - ["published", "=", 1] - ] - ) - return website_item_groups - def add_display_details(self, result, discount_list, cart_items): """Add price and availability details in result.""" for item in result: @@ -278,16 +282,6 @@ class ProductQuery: return [] - def combine_web_item_group_results(self, item_group, result, website_item_groups): - """Combine results with context of website item groups into item results.""" - if item_group and website_item_groups: - items_list = {row.name for row in result} - for row in website_item_groups: - if row.wig_parent not in items_list: - result.append(row) - - return result - def filter_results_by_discount(self, fields, result): if fields and fields.get("discount"): discount_percent = frappe.utils.flt(fields["discount"][0]) diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json index 3e0680f4f5..a090c8d76c 100644 --- a/erpnext/setup/doctype/item_group/item_group.json +++ b/erpnext/setup/doctype/item_group/item_group.json @@ -20,12 +20,14 @@ "sec_break_taxes", "taxes", "sb9", - "show_in_website", "route", - "weightage", - "slideshow", "website_title", "description", + "show_in_website", + "include_descendants", + "column_break_16", + "weightage", + "slideshow", "website_specifications", "website_filters_section", "filter_fields", @@ -111,7 +113,7 @@ }, { "default": "0", - "description": "Check this if you want to show in website", + "description": "Make Item Group visible in website", "fieldname": "show_in_website", "fieldtype": "Check", "label": "Show in Website" @@ -124,6 +126,7 @@ "unique": 1 }, { + "depends_on": "show_in_website", "fieldname": "weightage", "fieldtype": "Int", "label": "Weightage" @@ -186,6 +189,8 @@ "report_hide": 1 }, { + "collapsible": 1, + "depends_on": "show_in_website", "fieldname": "website_filters_section", "fieldtype": "Section Break", "label": "Website Filters" @@ -203,9 +208,21 @@ "options": "Website Attribute" }, { + "depends_on": "show_in_website", "fieldname": "website_title", "fieldtype": "Data", "label": "Title" + }, + { + "fieldname": "column_break_16", + "fieldtype": "Column Break" + }, + { + "default": "0", + "description": "Include Website Items belonging to child Item Groups", + "fieldname": "include_descendants", + "fieldtype": "Check", + "label": "Include Descendants" } ], "icon": "fa fa-sitemap", @@ -214,11 +231,12 @@ "is_tree": 1, "links": [], "max_attachments": 3, - "modified": "2021-02-18 13:40:30.049650", + "modified": "2022-03-07 09:44:47.561532", "modified_by": "Administrator", "module": "Setup", "name": "Item Group", "name_case": "Title Case", + "naming_rule": "By fieldname", "nsm_parent_field": "parent_item_group", "owner": "Administrator", "permissions": [ @@ -285,5 +303,6 @@ "search_fields": "parent_item_group", "show_name_in_global_search": 1, "sort_field": "modified", - "sort_order": "DESC" + "sort_order": "DESC", + "states": [] } \ No newline at end of file diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index 4f92240c84..5c7194baf6 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -111,7 +111,7 @@ class ItemGroup(NestedSet, WebsiteGenerator): from erpnext.stock.doctype.item.item import validate_item_default_company_links validate_item_default_company_links(self.item_group_defaults) -def get_child_groups_for_website(item_group_name, immediate=False): +def get_child_groups_for_website(item_group_name, immediate=False, include_self=False): """Returns child item groups *excluding* passed group.""" item_group = frappe.get_cached_value("Item Group", item_group_name, ["lft", "rgt"], as_dict=1) filters = { @@ -123,6 +123,12 @@ def get_child_groups_for_website(item_group_name, immediate=False): if immediate: filters["parent_item_group"] = item_group_name + if include_self: + filters.update({ + "lft": [">=", item_group.lft], + "rgt": ["<=", item_group.rgt] + }) + return frappe.get_all( "Item Group", filters=filters, From f3a95d3c27a5430c4a9176b685da20489a7e2429 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 7 Mar 2022 16:10:26 +0530 Subject: [PATCH 03/15] fix(ux): Improve label for better understanding --- .../doctype/sales_invoice/sales_invoice.json | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 5062c1c807..973c8371ea 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -2,13 +2,14 @@ "actions": [], "allow_import": 1, "autoname": "naming_series:", - "creation": "2013-05-24 19:29:05", + "creation": "2022-01-25 10:29:57.771398", "doctype": "DocType", "engine": "InnoDB", "field_order": [ "customer_section", "title", "naming_series", + "tax_invoice_number", "customer", "customer_name", "tax_id", @@ -651,7 +652,6 @@ "hide_seconds": 1, "label": "Ignore Pricing Rule", "no_copy": 1, - "permlevel": 0, "print_hide": 1 }, { @@ -1974,9 +1974,10 @@ }, { "default": "0", + "description": "Issue a debit note with 0 qty against an existing Sales Invoice", "fieldname": "is_debit_note", "fieldtype": "Check", - "label": "Is Debit Note" + "label": "Is Rate Adjustment Entry (Debit Note)" }, { "default": "0", @@ -2026,6 +2027,12 @@ "fieldtype": "Currency", "label": "Amount Eligible for Commission", "read_only": 1 + }, + { + "fieldname": "tax_invoice_number", + "fieldtype": "Data", + "label": "Tax Invoice Number", + "read_only": 1 } ], "icon": "fa fa-file-text", @@ -2038,7 +2045,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2021-12-23 20:19:38.667508", + "modified": "2022-03-07 16:08:53.517903", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", @@ -2089,8 +2096,9 @@ "show_name_in_global_search": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "timeline_field": "customer", "title_field": "title", "track_changes": 1, "track_seen": 1 -} +} \ No newline at end of file From 66f20209f657ae1825bc9971dbd19f186e454d50 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 8 Mar 2022 15:57:54 +0530 Subject: [PATCH 04/15] perf(asset): fetch only distinct depreciable assets --- erpnext/assets/doctype/asset/depreciation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 874fb630f8..6e04242210 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -23,7 +23,7 @@ def post_depreciation_entries(date=None): frappe.db.commit() def get_depreciable_assets(date): - return frappe.db.sql_list("""select a.name + return frappe.db.sql_list("""select distinct a.name from tabAsset a, `tabDepreciation Schedule` ds where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s and a.calculate_depreciation = 1 and a.status in ('Submitted', 'Partially Depreciated') From 3507cf59852c6d6814f6650b4b1a6e6584e69aa6 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 9 Mar 2022 12:24:57 +0530 Subject: [PATCH 05/15] test: Test include_descendants in Item Group Product Listing - Also made include_descendants field's visibility dependant on show_in_website --- .../test_item_group_product_data_engine.py | 53 ++++++++++++++++--- .../setup/doctype/item_group/item_group.json | 3 +- .../templates/pages/non_profit/__init__.py | 0 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 erpnext/templates/pages/non_profit/__init__.py diff --git a/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py b/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py index f0f7918d00..6549ba692a 100644 --- a/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py +++ b/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py @@ -13,8 +13,7 @@ test_dependencies = ["Item", "Item Group"] class TestItemGroupProductDataEngine(unittest.TestCase): "Test Products & Sub-Category Querying for Product Listing on Item Group Page." - @classmethod - def setUpClass(cls): + def setUp(self): item_codes = [ ("Test Mobile A", "_Test Item Group B"), ("Test Mobile B", "_Test Item Group B"), @@ -28,8 +27,10 @@ class TestItemGroupProductDataEngine(unittest.TestCase): if not frappe.db.exists("Website Item", {"item_code": item_code}): create_regular_web_item(item_code, item_args=item_args) - @classmethod - def tearDownClass(cls): + frappe.db.set_value("Item Group", "_Test Item Group B - 1", "show_in_website", 1) + frappe.db.set_value("Item Group", "_Test Item Group B - 2", "show_in_website", 1) + + def tearDown(self): frappe.db.rollback() def test_product_listing_in_item_group(self): @@ -87,7 +88,6 @@ class TestItemGroupProductDataEngine(unittest.TestCase): def test_item_group_with_sub_groups(self): "Test Valid Sub Item Groups in Item Group Page." - frappe.db.set_value("Item Group", "_Test Item Group B - 1", "show_in_website", 1) frappe.db.set_value("Item Group", "_Test Item Group B - 2", "show_in_website", 0) result = get_product_filter_data(query_args={ @@ -114,4 +114,45 @@ class TestItemGroupProductDataEngine(unittest.TestCase): # check if child group is fetched if shown in website self.assertIn("_Test Item Group B - 1", child_groups) - self.assertIn("_Test Item Group B - 2", child_groups) \ No newline at end of file + self.assertIn("_Test Item Group B - 2", child_groups) + + def test_item_group_page_with_descendants_included(self): + """ + Test if 'include_descendants' pulls Items belonging to descendant Item Groups (Level 2 & 3). + > _Test Item Group B [Level 1] + > _Test Item Group B - 1 [Level 2] + > _Test Item Group B - 1 - 1 [Level 3] + """ + frappe.get_doc({ # create Level 3 nested child group + "doctype": "Item Group", + "is_group": 1, + "item_group_name": "_Test Item Group B - 1 - 1", + "parent_item_group": "_Test Item Group B - 1" + }).insert() + + create_regular_web_item( # create an item belonging to level 3 item group + "Test Mobile F", + item_args={"item_group": "_Test Item Group B - 1 - 1"} + ) + + frappe.db.set_value("Item Group", "_Test Item Group B - 1 - 1", "show_in_website", 1) + + # enable 'include descendants' in Level 1 + frappe.db.set_value("Item Group", "_Test Item Group B", "include_descendants", 1) + + result = get_product_filter_data(query_args={ + "field_filters": {}, + "attribute_filters": {}, + "start": 0, + "item_group": "_Test Item Group B" + }) + + items = result.get("items") + item_codes = [item.get("item_code") for item in items] + + # check if all sub groups' items are pulled + self.assertEqual(len(items), 6) + self.assertIn("Test Mobile A", item_codes) + self.assertIn("Test Mobile C", item_codes) + self.assertIn("Test Mobile E", item_codes) + self.assertIn("Test Mobile F", item_codes) \ No newline at end of file diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json index a090c8d76c..50f923d87e 100644 --- a/erpnext/setup/doctype/item_group/item_group.json +++ b/erpnext/setup/doctype/item_group/item_group.json @@ -219,6 +219,7 @@ }, { "default": "0", + "depends_on": "show_in_website", "description": "Include Website Items belonging to child Item Groups", "fieldname": "include_descendants", "fieldtype": "Check", @@ -231,7 +232,7 @@ "is_tree": 1, "links": [], "max_attachments": 3, - "modified": "2022-03-07 09:44:47.561532", + "modified": "2022-03-09 12:27:11.055782", "modified_by": "Administrator", "module": "Setup", "name": "Item Group", diff --git a/erpnext/templates/pages/non_profit/__init__.py b/erpnext/templates/pages/non_profit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 64905188c46b90452e30927323f892d8b210f14a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 9 Mar 2022 15:37:14 +0530 Subject: [PATCH 06/15] fix: dont fetch entire barcode table in get_item_details (#30131) --- erpnext/stock/get_item_details.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 9bec5f7494..9bb41b9dbb 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -367,7 +367,7 @@ def get_basic_details(args, item, overwrite_warehouse=True): if not out[d[1]]: out[d[1]] = frappe.get_cached_value('Company', args.company, d[2]) if d[2] else None - for fieldname in ("item_name", "item_group", "barcodes", "brand", "stock_uom"): + for fieldname in ("item_name", "item_group", "brand", "stock_uom"): out[fieldname] = item.get(fieldname) if args.get("manufacturer"): From 8a2fe7a2e39c28ccb52238651b439eba17d153ab Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 9 Mar 2022 15:42:06 +0530 Subject: [PATCH 07/15] fix: Remove tax invoice no field --- erpnext/accounts/doctype/sales_invoice/sales_invoice.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 973c8371ea..82854ba2a6 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -9,7 +9,6 @@ "customer_section", "title", "naming_series", - "tax_invoice_number", "customer", "customer_name", "tax_id", @@ -2027,12 +2026,6 @@ "fieldtype": "Currency", "label": "Amount Eligible for Commission", "read_only": 1 - }, - { - "fieldname": "tax_invoice_number", - "fieldtype": "Data", - "label": "Tax Invoice Number", - "read_only": 1 } ], "icon": "fa fa-file-text", From 9b8258479c6e71a06303d4774df5ab3a749d9de9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 9 Mar 2022 15:43:26 +0530 Subject: [PATCH 08/15] fix: Update timestamp --- erpnext/accounts/doctype/sales_invoice/sales_invoice.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 82854ba2a6..80b95db886 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -2038,7 +2038,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2022-03-07 16:08:53.517903", + "modified": "2022-03-08 16:08:53.517903", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", From 7b37a74023b088b8dcc5114b954c716ebf7f6eae Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 9 Mar 2022 16:04:12 +0530 Subject: [PATCH 09/15] fix: Linter --- erpnext/assets/doctype/asset/asset_dashboard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/assets/doctype/asset/asset_dashboard.py b/erpnext/assets/doctype/asset/asset_dashboard.py index 1833b0e716..c81b611a41 100644 --- a/erpnext/assets/doctype/asset/asset_dashboard.py +++ b/erpnext/assets/doctype/asset/asset_dashboard.py @@ -1,5 +1,6 @@ from frappe import _ + def get_data(): return { 'non_standard_fieldnames': { From 4d8798b0ead57eb3ae3a0b27755aad60a84989b9 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 9 Mar 2022 16:41:54 +0530 Subject: [PATCH 10/15] fix: ignore non-unique swift numbers while migrating (#30132) --- .../v12_0/move_bank_account_swift_number_to_bank.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py b/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py index b3ee340464..7ae4c42cec 100644 --- a/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py +++ b/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py @@ -5,10 +5,13 @@ def execute(): frappe.reload_doc('accounts', 'doctype', 'bank', force=1) if frappe.db.table_exists('Bank') and frappe.db.table_exists('Bank Account') and frappe.db.has_column('Bank Account', 'swift_number'): - frappe.db.sql(""" - UPDATE `tabBank` b, `tabBank Account` ba - SET b.swift_number = ba.swift_number WHERE b.name = ba.bank - """) + try: + frappe.db.sql(""" + UPDATE `tabBank` b, `tabBank Account` ba + SET b.swift_number = ba.swift_number WHERE b.name = ba.bank + """) + except Exception as e: + frappe.log_error(e, title="Patch Migration Failed") frappe.reload_doc('accounts', 'doctype', 'bank_account') frappe.reload_doc('accounts', 'doctype', 'payment_request') From b1c8a4543d226a1b6422a6778182cc20eacfaa56 Mon Sep 17 00:00:00 2001 From: Chillar Anand Date: Wed, 9 Mar 2022 17:05:00 +0530 Subject: [PATCH 11/15] test: Added test for monthly attendance report (#29989) Co-authored-by: Rucha Mahabal --- .../test_monthly_attendance_sheet.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py diff --git a/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py b/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py new file mode 100644 index 0000000000..b196fb5b98 --- /dev/null +++ b/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py @@ -0,0 +1,45 @@ +import frappe +from dateutil.relativedelta import relativedelta + +from frappe.tests.utils import FrappeTestCase +from frappe.utils import now_datetime + +from erpnext.hr.doctype.attendance.attendance import mark_attendance +from erpnext.hr.doctype.employee.test_employee import make_employee +from erpnext.hr.report.monthly_attendance_sheet.monthly_attendance_sheet import execute + + +class TestMonthlyAttendanceSheet(FrappeTestCase): + def setUp(self): + self.employee = make_employee("test_employee@example.com") + frappe.db.delete('Attendance', {'employee': self.employee}) + + def test_monthly_attendance_sheet_report(self): + now = now_datetime() + previous_month = now.month - 1 + previous_month_first = now.replace(day=1).replace(month=previous_month).date() + + company = frappe.db.get_value('Employee', self.employee, 'company') + + # mark different attendance status on first 3 days of previous month + mark_attendance(self.employee, previous_month_first, 'Absent') + mark_attendance(self.employee, previous_month_first + relativedelta(days=1), 'Present') + mark_attendance(self.employee, previous_month_first + relativedelta(days=2), 'On Leave') + + filters = frappe._dict({ + 'month': previous_month, + 'year': now.year, + 'company': company, + }) + report = execute(filters=filters) + employees = report[1][0] + datasets = report[3]['data']['datasets'] + absent = datasets[0]['values'] + present = datasets[1]['values'] + leaves = datasets[2]['values'] + + # ensure correct attendance is reflect on the report + self.assertIn(self.employee, employees) + self.assertEqual(absent[0], 1) + self.assertEqual(present[1], 1) + self.assertEqual(leaves[2], 1) From fe4b6771b5fd935ed278cf553c864a18e3356a33 Mon Sep 17 00:00:00 2001 From: Chillar Anand Date: Wed, 9 Mar 2022 17:16:05 +0530 Subject: [PATCH 12/15] refactor: Remove dead code (#30140) --- erpnext/hr/doctype/leave_application/leave_application.py | 1 - .../report/project_profitability/project_profitability.py | 2 -- erpnext/regional/report/irs_1099/irs_1099.py | 1 - erpnext/regional/report/uae_vat_201/test_uae_vat_201.py | 3 +-- erpnext/stock/report/stock_balance/stock_balance.py | 1 - 5 files changed, 1 insertion(+), 7 deletions(-) diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index ef5f4bcb0f..345d8dc370 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -495,7 +495,6 @@ def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day number_of_days = date_diff(to_date, from_date) + .5 else: number_of_days = date_diff(to_date, from_date) + 1 - else: number_of_days = date_diff(to_date, from_date) + 1 diff --git a/erpnext/projects/report/project_profitability/project_profitability.py b/erpnext/projects/report/project_profitability/project_profitability.py index 9520cd17be..23c3b82c6d 100644 --- a/erpnext/projects/report/project_profitability/project_profitability.py +++ b/erpnext/projects/report/project_profitability/project_profitability.py @@ -1,14 +1,12 @@ # Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt - import frappe from frappe import _ from frappe.utils import flt def execute(filters=None): - columns, data = [], [] data = get_data(filters) columns = get_columns() charts = get_chart_data(data) diff --git a/erpnext/regional/report/irs_1099/irs_1099.py b/erpnext/regional/report/irs_1099/irs_1099.py index b1a5d10962..147a59fb01 100644 --- a/erpnext/regional/report/irs_1099/irs_1099.py +++ b/erpnext/regional/report/irs_1099/irs_1099.py @@ -30,7 +30,6 @@ def execute(filters=None): if region != 'United States': return [], [] - data = [] columns = get_columns() conditions = "" if filters.supplier_group: diff --git a/erpnext/regional/report/uae_vat_201/test_uae_vat_201.py b/erpnext/regional/report/uae_vat_201/test_uae_vat_201.py index 41336873ac..464939f39e 100644 --- a/erpnext/regional/report/uae_vat_201/test_uae_vat_201.py +++ b/erpnext/regional/report/uae_vat_201/test_uae_vat_201.py @@ -118,8 +118,7 @@ def make_customer(): "customer_type": "Company", }) customer.insert() - else: - customer = frappe.get_doc("Customer", "_Test UAE Customer") + def make_supplier(): if not frappe.db.exists("Supplier", "_Test UAE Supplier"): diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index b4f43a7fef..24f47c1946 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -18,7 +18,6 @@ def execute(filters=None): is_reposting_item_valuation_in_progress() if not filters: filters = {} - from_date = filters.get('from_date') to_date = filters.get('to_date') if filters.get("company"): From fc42041f8fff7bd9f3b374992565bf3eccfaf43d Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 9 Mar 2022 18:01:10 +0530 Subject: [PATCH 13/15] fix(psoa): add company filter to account --- .../process_statement_of_accounts.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js index 088c190f45..29f2e98e77 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js @@ -51,6 +51,13 @@ frappe.ui.form.on('Process Statement Of Accounts', { } } }); + frm.set_query("account", function() { + return { + filters: { + 'company': frm.doc.company + } + }; + }); if(frm.doc.__islocal){ frm.set_value('from_date', frappe.datetime.add_months(frappe.datetime.get_today(), -1)); frm.set_value('to_date', frappe.datetime.get_today()); From f0664279130edea2b9ba1233f5fcbd0a8a001649 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 10 Mar 2022 10:06:07 +0530 Subject: [PATCH 14/15] fix: program enrollment button labels (#30148) --- erpnext/www/lms/macros/hero.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/erpnext/www/lms/macros/hero.html b/erpnext/www/lms/macros/hero.html index 95ba8f7df2..dd3c23a014 100644 --- a/erpnext/www/lms/macros/hero.html +++ b/erpnext/www/lms/macros/hero.html @@ -39,16 +39,13 @@ frappe.call(opts).then(res => { let success_dialog = new frappe.ui.Dialog({ title: __('Success'), - primary_action_label: __('View Program Content'), + primary_action_label: __('OK'), primary_action: function() { window.location.reload(); - }, - secondary_action: function() { - window.location.reload(); } }) success_dialog.show(); - success_dialog.set_message(__('You have successfully enrolled for the program ')); + success_dialog.set_message(__('You have successfully enrolled for the program.')); }) } From 84568ac3410f53976c76aa3e583b739df5f2a7a6 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 10 Mar 2022 11:20:23 +0530 Subject: [PATCH 15/15] chore: imports --- .../monthly_attendance_sheet/test_monthly_attendance_sheet.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py b/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py index b196fb5b98..952af8117e 100644 --- a/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py +++ b/erpnext/hr/report/monthly_attendance_sheet/test_monthly_attendance_sheet.py @@ -1,6 +1,5 @@ import frappe from dateutil.relativedelta import relativedelta - from frappe.tests.utils import FrappeTestCase from frappe.utils import now_datetime