From 5ce31174be068fee0e8c544e2d3877b6b3d8e3e9 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 28 Apr 2015 12:36:09 +0530 Subject: [PATCH 1/6] precision fixed in batch-wise balance report --- .../batch_wise_balance_history.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py index 3679457136..aa5c19422c 100644 --- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py +++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py @@ -9,19 +9,20 @@ from frappe.utils import flt, cint def execute(filters=None): if not filters: filters = {} + float_precision = cint(frappe.db.get_default("float_precision")) or 3 + columns = get_columns(filters) item_map = get_item_details(filters) - iwb_map = get_item_warehouse_batch_map(filters) + iwb_map = get_item_warehouse_batch_map(filters, float_precision) data = [] for item in sorted(iwb_map): for wh in sorted(iwb_map[item]): for batch in sorted(iwb_map[item][wh]): qty_dict = iwb_map[item][wh][batch] - data.append([item, item_map[item]["item_name"], - item_map[item]["description"], wh, batch, - qty_dict.opening_qty, qty_dict.in_qty, - qty_dict.out_qty, qty_dict.bal_qty + data.append([item, item_map[item]["item_name"], item_map[item]["description"], wh, batch, + flt(qty_dict.opening_qty, float_precision), flt(qty_dict.in_qty, float_precision), + flt(qty_dict.out_qty, float_precision), flt(qty_dict.bal_qty, float_precision) ]) return columns, data @@ -56,8 +57,7 @@ def get_stock_ledger_entries(filters): where docstatus < 2 %s order by item_code, warehouse""" % conditions, as_dict=1) -def get_item_warehouse_batch_map(filters): - float_precision = cint(frappe.db.get_default("float_precision")) or 3 +def get_item_warehouse_batch_map(filters, float_precision): sle = get_stock_ledger_entries(filters) iwb_map = {} From 59ab65ded689130e06f4e43549a69a53b0c0b01f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 29 Apr 2015 13:07:06 +0530 Subject: [PATCH 2/6] fixed trial balance related to showing zero balance --- .../accounts/report/trial_balance/trial_balance.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index dedbef9398..0f72536f02 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -123,7 +123,8 @@ def accumulate_values_into_parents(accounts, accounts_by_name): def prepare_data(accounts, filters, total_row): show_zero_values = cint(filters.show_zero_values) data = [] - for i, d in enumerate(accounts): + accounts_with_zero_value = [] + for d in accounts: has_value = False row = { "account_name": d.account_name, @@ -140,9 +141,14 @@ def prepare_data(accounts, filters, total_row): row[key] = d.get(key, 0.0) if row[key]: has_value = True - - if has_value or show_zero_values: + + if show_zero_values: data.append(row) + else: + if not has_value: + accounts_with_zero_value.append(d.name) + elif d.parent_account not in accounts_with_zero_value: + data.append(row) data.extend([{},total_row]) From 6e59aca394b40a71c3ae3bbc988acb1501522d00 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 29 Apr 2015 13:07:36 +0530 Subject: [PATCH 3/6] [enhancement] sort root accounts as assets, liability, equity, income, expense --- .../page/accounts_browser/accounts_browser.py | 6 +++++- .../accounts/report/financial_statements.py | 21 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.py b/erpnext/accounts/page/accounts_browser/accounts_browser.py index 15cfdd2acc..2318588efe 100644 --- a/erpnext/accounts/page/accounts_browser/accounts_browser.py +++ b/erpnext/accounts/page/accounts_browser/accounts_browser.py @@ -6,6 +6,7 @@ import frappe import frappe.defaults from frappe.utils import flt from erpnext.accounts.utils import get_balance_on +from erpnext.accounts.report.financial_statements import sort_root_accounts @frappe.whitelist() def get_companies(): @@ -21,12 +22,15 @@ def get_children(): # root if args['parent'] in ("Accounts", "Cost Centers"): acc = frappe.db.sql(""" select - name as value, if(group_or_ledger='Group', 1, 0) as expandable + name as value, if(group_or_ledger='Group', 1, 0) as expandable, root_type, report_type from `tab%s` where ifnull(parent_%s,'') = '' and `company` = %s and docstatus<2 order by name""" % (ctype, ctype.lower().replace(' ','_'), '%s'), company, as_dict=1) + + if args["parent"]=="Accounts": + sort_root_accounts(acc) else: # other acc = frappe.db.sql("""select diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 4ae61ca513..fc4ebec232 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -186,7 +186,10 @@ def filter_accounts(accounts, depth=10): filtered_accounts = [] def add_to_list(parent, level): if level < depth: - for child in (parent_children_map.get(parent) or []): + children = parent_children_map.get(parent) or [] + if parent == None: + sort_root_accounts(children) + for child in children: child.indent = level filtered_accounts.append(child) add_to_list(child.name, level + 1) @@ -202,6 +205,22 @@ def filter_accounts(accounts, depth=10): add_to_list(None, 0) return filtered_accounts, accounts_by_name + +def sort_root_accounts(roots): + """Sort root types as Asset, Liability, Equity, Income, Expense""" + + def compare_roots(a, b): + if a.report_type != b.report_type and a.report_type == "Balance Sheet": + return -1 + if a.root_type != b.root_type and a.root_type == "Asset": + return -1 + if a.root_type == "Liability" and b.root_type == "Equity": + return -1 + if a.root_type == "Income" and b.root_type == "Expense": + return -1 + return 1 + + roots.sort(compare_roots) def get_gl_entries(company, from_date, to_date, root_lft, root_rgt, ignore_closing_entries=False): """Returns a dict like { "account": [gl entries], ... }""" From acfdce6aded91b830b773ce84b08da47d44be790 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Apr 2015 11:50:27 +0530 Subject: [PATCH 4/6] Removed duplicate item validation --- .../purchase_common/purchase_common.py | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index 2cf8673dc5..25f429a1c5 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import flt +from frappe.utils import flt, cstr from frappe import _ from erpnext.stock.doctype.item.item import get_last_purchase_details @@ -64,7 +64,7 @@ class PurchaseCommon(BuyingController): = d.rate = item_last_purchase_rate def validate_for_items(self, obj): - check_list, chk_dupl_itm=[],[] + items = [] for d in obj.get(obj.fname): # validation for valid qty if flt(d.qty) < 0 or (d.parenttype != 'Purchase Receipt' and not flt(d.qty)): @@ -96,30 +96,10 @@ class PurchaseCommon(BuyingController): if item[0][1] != 'Yes' and item[0][2] != 'Yes': frappe.throw(_("{0} must be a Purchased or Sub-Contracted Item in row {1}").format(d.item_code, d.idx)) - # list criteria that should not repeat if item is stock item - e = [getattr(d, "schedule_date", None), d.item_code, d.description, d.warehouse, d.uom, - d.meta.get_field('prevdoc_docname') and d.prevdoc_docname or d.meta.get_field('sales_order_no') and d.sales_order_no or '', - d.meta.get_field('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', - d.meta.get_field('batch_no') and d.batch_no or ''] - - # if is not stock item - f = [getattr(d, "schedule_date", None), d.item_code, d.description] - - ch = frappe.db.sql("""select is_stock_item from `tabItem` where name = %s""", d.item_code) - - if ch and ch[0][0] == 'Yes': - # check for same items - if e in check_list: - frappe.throw(_("Item {0} has been entered multiple times with same description or date or warehouse").format(d.item_code)) - else: - check_list.append(e) - - elif ch and ch[0][0] == 'No': - # check for same items - if f in chk_dupl_itm: - frappe.throw(_("Item {0} has been entered multiple times with same description or date").format(d.item_code)) - else: - chk_dupl_itm.append(f) + items.append(cstr(d.item_code)) + if items and len(items) != len(set(items)): + frappe.msgprint(_("Warning: Same item has been entered multiple times.")) + def check_for_stopped_status(self, doctype, docname): stopped = frappe.db.sql("""select name from `tab%s` where name = %s and From 6e659a4f2787dfce923adb9294481ca13e0a83f7 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Apr 2015 11:51:09 +0530 Subject: [PATCH 5/6] Service items should not be considered as raw material in production planning tool --- .../production_planning_tool/production_planning_tool.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py index f0bb9377c4..efc439961a 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -254,8 +254,10 @@ class ProductionPlanningTool(Document): ifnull(sum(ifnull(fb.qty, 0)/ifnull(bom.quantity, 1)), 0) as qty, fb.description, fb.stock_uom, it.min_order_qty from `tabBOM Explosion Item` fb, `tabBOM` bom, `tabItem` it - where bom.name = fb.parent and it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No' + where bom.name = fb.parent and it.name = fb.item_code + and ifnull(it.is_pro_applicable, 'No') = 'No' and ifnull(it.is_sub_contracted_item, 'No') = 'No' + and ifnull(it.is_stock_item, 'No') = 'Yes' and fb.docstatus<2 and bom.name=%s group by item_code, stock_uom""", bom, as_dict=1): bom_wise_item_details.setdefault(d.item_code, d) @@ -268,6 +270,7 @@ class ProductionPlanningTool(Document): from `tabBOM Item` bom_item, `tabBOM` bom, tabItem item where bom.name = bom_item.parent and bom.name = %s and bom_item.docstatus < 2 and bom_item.item_code = item.name + and ifnull(item.is_stock_item, 'No') = 'Yes' group by item_code""", bom, as_dict=1): bom_wise_item_details.setdefault(d.item_code, d) From 7358e6a100316eb82bdf9ce7fdc52af78107b4c7 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 30 Apr 2015 17:01:02 +0600 Subject: [PATCH 6/6] bumped to version 4.25.3 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index 61e02d0885..2971b7f17d 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1,2 +1,2 @@ from __future__ import unicode_literals -__version__ = '4.25.2' +__version__ = '4.25.3' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 57916db98e..d1ac22171e 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -5,7 +5,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "4.25.2" +app_version = "4.25.3" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index f6286626d9..a103bed1c3 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.25.2" +version = "4.25.3" with open("requirements.txt", "r") as f: install_requires = f.readlines()