From 9ea19b8fe12a968593a81ca5e78571dea2be58de Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 31 Jan 2019 15:53:25 +0530 Subject: [PATCH 01/18] fix: Fixed error on stock balance report --- .../report/stock_balance/stock_balance.py | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index e72e94b12d..0ece78f256 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -173,15 +173,15 @@ def get_item_warehouse_map(filters, sle): qty_dict.val_rate = d.valuation_rate qty_dict.bal_qty += qty_diff qty_dict.bal_val += value_diff - + iwb_map = filter_items_with_no_transactions(iwb_map) return iwb_map - + def filter_items_with_no_transactions(iwb_map): for (company, item, warehouse) in sorted(iwb_map): qty_dict = iwb_map[(company, item, warehouse)] - + no_transactions = True float_precision = cint(frappe.db.get_default("float_precision")) or 3 for key, val in iteritems(qty_dict): @@ -189,7 +189,7 @@ def filter_items_with_no_transactions(iwb_map): qty_dict[key] = val if key != "val_rate" and val: no_transactions = False - + if no_transactions: iwb_map.pop((company, item, warehouse)) @@ -216,20 +216,28 @@ def get_item_details(items, sle, filters): if not items: items = list(set([d.item_code for d in sle])) - if items: - cf_field = cf_join = "" - if filters.get("include_uom"): - cf_field = ", ucd.conversion_factor" - cf_join = "left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom=%(include_uom)s" + if not items: + return item_details - for item in frappe.db.sql(""" - select item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom{cf_field} - from `tabItem` item + cf_field = cf_join = "" + if filters.get("include_uom"): + cf_field = ", ucd.conversion_factor" + cf_join = "left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom='%s'" \ + % frappe.db.escape(filters.get("include_uom")) + + item_codes = ', '.join(['"' + frappe.db.escape(i, percent=False) + '"' for i in items]) + res = frappe.db.sql(""" + select + item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom {cf_field} + from + `tabItem` item {cf_join} - where item.name in ({names}) and ifnull(item.disabled, 0) = 0 - """.format(cf_field=cf_field, cf_join=cf_join, names=', '.join(['"' + frappe.db.escape(i, percent=False) + '"' for i in items])), - {"include_uom": filters.get("include_uom")}, as_dict=1): - item_details.setdefault(item.name, item) + where + item.name in ({item_codes}) and ifnull(item.disabled, 0) = 0 + """.format(cf_field=cf_field, cf_join=cf_join, item_codes=item_codes), as_dict=1) + + for item in res: + item_details.setdefault(item.name, item) if filters.get('show_variant_attributes', 0) == 1: variant_values = get_variant_values_for(list(item_details)) From 088886e082211a3f6f2275dd5b90c70ebc2b2d70 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Thu, 7 Feb 2019 07:09:20 +0530 Subject: [PATCH 02/18] Remove illegal character after break (#16589) --- .../doctype/woocommerce_settings/woocommerce_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py index bb4f62a099..1edc102956 100644 --- a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py +++ b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py @@ -28,7 +28,7 @@ class WoocommerceSettings(Document): if not frappe.get_value("Custom Field",{"name":i[0]}) or not frappe.get_value("Custom Field",{"name":i[1]}): create_custom_field_id_and_check_status = True - break; + break if create_custom_field_id_and_check_status: From 8ae5dbcac81868ac152150d07ae4c7467a4e5643 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 7 Feb 2019 07:09:49 +0530 Subject: [PATCH 03/18] fix: Set barcode in Item row after scanning barcode (#16591) --- erpnext/public/js/controllers/transaction.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 20e1098806..3751d7b9f3 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -314,8 +314,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ show_description(child.idx, r.message.item_code, child.item_code); frappe.model.set_value(child.doctype, child.name, { - "item_code": r.message.item_code, - "qty": (child.qty || 0) + 1 + item_code: r.message.item_code, + qty: (child.qty || 0) + 1, + barcode: r.message.barcode }); } else{ From 504f317434c949141f4caac6d6bfb15024b29691 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 7 Feb 2019 07:15:38 +0530 Subject: [PATCH 04/18] fix: BOM Stock Calculated Report (#16585) - Cast null values to 0 to avoid mathematic errors --- .../bom_stock_calculated.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py index 2d3d078179..612f415beb 100644 --- a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py +++ b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py @@ -13,16 +13,16 @@ def execute(filters=None): data = get_bom_stock(filters) qty_to_make = filters.get("qty_to_make") - for rows in data: - item_map = get_item_details(rows[0]) - reqd_qty = qty_to_make * rows[3] - last_pur_price = frappe.db.get_value("Item", rows[0], "last_purchase_rate") - if rows[4] > 0: - diff_qty = rows[4] - reqd_qty - summ_data.append([rows[0], rows[1], item_map[rows[0]]["manufacturer"], item_map[rows[0]]["manufacturer_part_no"], rows[3], rows[4], reqd_qty, diff_qty, last_pur_price]) + for row in data: + item_map = get_item_details(row.item_code) + reqd_qty = qty_to_make * row.actual_qty + last_pur_price = frappe.db.get_value("Item", row.item_code, "last_purchase_rate") + if row.to_build > 0: + diff_qty = row.to_build - reqd_qty + summ_data.append([row.item_code, row.description, item_map[row.item_code]["manufacturer"], item_map[row.item_code]["manufacturer_part_no"], row.actual_qty, row.to_build, reqd_qty, diff_qty, last_pur_price]) else: diff_qty = 0 - reqd_qty - summ_data.append([rows[0], rows[1], item_map[rows[0]]["manufacturer"], item_map[rows[0]]["manufacturer_part_no"], rows[3], "0.000", reqd_qty, diff_qty, last_pur_price]) + summ_data.append([row.item_code, row.description, item_map[row.item_code]["manufacturer"], item_map[row.item_code]["manufacturer_part_no"], row.actual_qty, "0.000", reqd_qty, diff_qty, last_pur_price]) return columns, summ_data @@ -72,8 +72,8 @@ def get_bom_stock(filters): bom_item.item_code, bom_item.description, bom_item.{qty_field}, - sum(ledger.actual_qty) as actual_qty, - sum(FLOOR(ledger.actual_qty / bom_item.{qty_field}))as to_build + ifnull(sum(ledger.actual_qty), 0) as actual_qty, + ifnull(sum(FLOOR(ledger.actual_qty / bom_item.{qty_field})), 0) as to_build FROM {table} AS bom_item LEFT JOIN `tabBin` AS ledger @@ -83,7 +83,7 @@ def get_bom_stock(filters): WHERE bom_item.parent = '{bom}' and bom_item.parenttype='BOM' - GROUP BY bom_item.item_code""".format(qty_field=qty_field, table=table, conditions=conditions, bom=bom)) + GROUP BY bom_item.item_code""".format(qty_field=qty_field, table=table, conditions=conditions, bom=bom), as_dict=1) def get_item_details(item_code): items = frappe.db.sql("""select it.item_group, it.item_name, it.stock_uom, it.name, it.brand, it.description, it.manufacturer_part_no, it.manufacturer from tabItem it where it.item_code = %s""", item_code, as_dict=1) From 27af6b377fb77bcf869714dac50d81677998d54c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 8 Feb 2019 16:52:13 +0530 Subject: [PATCH 05/18] fix: defered accounting fixes --- erpnext/accounts/deferred_revenue.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py index 9ff8b04281..13c57fe326 100644 --- a/erpnext/accounts/deferred_revenue.py +++ b/erpnext/accounts/deferred_revenue.py @@ -128,9 +128,13 @@ def book_deferred_income_or_expense(doc, start_date=None, end_date=None): # book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM # start_date: 1st of the last month or the start date # end_date: end_date or today-1 + enable_check = "enable_deferred_revenue" \ + if doc.doctype=="Sales Invoice" else "enable_deferred_expense" gl_entries = [] for item in doc.get('items'): + if not item.get(enable_check): continue + skip = False last_gl_entry, booking_start_date, booking_end_date, skip = \ get_booking_dates(doc, item, start_date, end_date) From e3b0f4f9f639579fd58f928cc8d2d280a77c0bfd Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 8 Feb 2019 16:53:02 +0530 Subject: [PATCH 06/18] fix: removed account type filter on employee advance account --- erpnext/accounts/doctype/payment_entry/payment_entry.py | 4 ++-- erpnext/hr/doctype/employee_advance/employee_advance.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 7f1f55005c..f303301a33 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -171,7 +171,7 @@ class PaymentEntry(AccountsController): if not frappe.db.exists(self.party_type, self.party): frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party)) - if self.party_account: + if self.party_account and self.party_type in ("Customer", "Supplier"): self.validate_account_type(self.party_account, [erpnext.get_party_account_type(self.party_type)]) @@ -689,7 +689,7 @@ def get_party_details(company, party_type, party, date, cost_center=None): account_currency = get_account_currency(party_account) account_balance = get_balance_on(party_account, date, cost_center=cost_center) - _party_name = "title" if party_type == "Student" else party_type.lower() + "_name" + _party_name = "title" if party_type in ("Student", "Shareholder") else party_type.lower() + "_name" party_name = frappe.db.get_value(party_type, party, _party_name) party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center) if party_type in ["Customer", "Supplier"]: diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.js b/erpnext/hr/doctype/employee_advance/employee_advance.js index c73df624e2..f4285a2ca2 100644 --- a/erpnext/hr/doctype/employee_advance/employee_advance.js +++ b/erpnext/hr/doctype/employee_advance/employee_advance.js @@ -19,7 +19,6 @@ frappe.ui.form.on('Employee Advance', { filters: { "root_type": "Asset", "is_group": 0, - "account_type": "Payable", "company": frm.doc.company } }; From 450fe309d681d8d30c34359e2bfdc1e92de57816 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 8 Feb 2019 16:54:56 +0530 Subject: [PATCH 07/18] fix: allow updating title of material request --- erpnext/stock/doctype/material_request/material_request.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index f3e3abfde2..47d61f847f 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -81,9 +81,9 @@ class MaterialRequest(BuyingController): def set_title(self): '''Set title as comma separated list of items''' - items = ', '.join([d.item_name for d in self.items][:4]) - - self.title = _('{0} for {1}'.format(self.material_request_type, items))[:100] + if not self.title: + items = ', '.join([d.item_name for d in self.items][:3]) + self.title = _('{0} Request for {1}').format(self.material_request_type, items)[:100] def on_submit(self): # frappe.db.set(self, 'status', 'Submitted') From 8d4bb3e327b6bb0d0dbde62c2c191ed05199c33c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 8 Feb 2019 16:55:46 +0530 Subject: [PATCH 08/18] fix: backflush only if transferred item is present in work order --- erpnext/stock/doctype/stock_entry/stock_entry.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 5d3c6c4adc..358d4e93be 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -914,6 +914,11 @@ class StockEntry(StockController): filters={'parent': self.work_order, 'item_code': item_code}, fields=["required_qty", "consumed_qty"] ) + if not req_items: + frappe.msgprint(_("Did not found transfered item {0} in Work Order {1}, the item not added in Stock Entry") + .format(item_code, self.work_order)) + continue + req_qty = flt(req_items[0].required_qty) req_qty_each = flt(req_qty / manufacturing_qty) consumed_qty = flt(req_items[0].consumed_qty) From 17e0513270b7fe04bc4d2d47860ec1721e1b2b7d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 8 Feb 2019 16:56:11 +0530 Subject: [PATCH 09/18] fix: message if stock reco is enqueued --- .../stock/doctype/stock_reconciliation/stock_reconciliation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index eb60ce56e9..a00d279f97 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -259,6 +259,7 @@ class StockReconciliation(StockController): def submit(self): if len(self.items) > 100: + msgprint(_("The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Draft stage")) self.queue_action('submit') else: self._submit() From 453964728d2e9ac1f665d1888fa70af5b58bbc38 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 9 Feb 2019 20:27:42 +0530 Subject: [PATCH 10/18] fix: Set company_currency for Warehouse Tree --- erpnext/stock/doctype/warehouse/warehouse.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index ef63740650..da97bc61a9 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -157,6 +157,8 @@ def get_children(doctype, parent=None, company=None, is_root=False): # return warehouses for wh in warehouses: wh["balance"] = get_stock_value_from_bin(warehouse=wh.value) + if company: + wh["company_currency"] = frappe.db.get_value('Company', company, 'default_currency') return warehouses @frappe.whitelist() From a206f06af90876a32f97a4f968a8c3a228c7e8a8 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 11 Feb 2019 12:01:01 +0530 Subject: [PATCH 11/18] delete notification control's docctype entry --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 29c86196da..b8e2e358b1 100755 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -585,3 +585,4 @@ erpnext.patches.v11_0.rename_additional_salary_component_additional_salary erpnext.patches.v11_0.renamed_from_to_fields_in_project erpnext.patches.v11_0.add_permissions_in_gst_settings erpnext.patches.v11_1.setup_guardian_role +execute:frappe.delete_doc('DocType', 'Notification Control') From 1a7e438fb250754fa8e6110ec7b0e3e6532e05c4 Mon Sep 17 00:00:00 2001 From: sahil28297 <37302950+sahil28297@users.noreply.github.com> Date: Mon, 11 Feb 2019 15:53:04 +0530 Subject: [PATCH 12/18] fix(pstch): allow duplicate entries (#16632) --- .../v11_0/create_department_records_for_each_company.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v11_0/create_department_records_for_each_company.py b/erpnext/patches/v11_0/create_department_records_for_each_company.py index 1257f1918b..b5a7bd91bd 100644 --- a/erpnext/patches/v11_0/create_department_records_for_each_company.py +++ b/erpnext/patches/v11_0/create_department_records_for_each_company.py @@ -27,8 +27,10 @@ def execute(): for company in companies: copy_doc = frappe.copy_doc(department_doc) copy_doc.update({"company": company.name}) - copy_doc.insert() - + try: + copy_doc.insert() + except frappe.DuplicateEntryError: + pass # append list of new department for each company comp_dict[company.name][department.name] = copy_doc.name From ab50211e18bdac06fd5a719b8dcb73e997de0d6f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 11 Feb 2019 18:22:36 +0530 Subject: [PATCH 13/18] fix: show project even if PI is directly created --- erpnext/accounts/report/purchase_register/purchase_register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py index 5d2409651e..e33b90d019 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.py +++ b/erpnext/accounts/report/purchase_register/purchase_register.py @@ -193,7 +193,7 @@ def get_invoice_po_pr_map(invoice_list): pi_items = frappe.db.sql(""" select parent, purchase_order, purchase_receipt, po_detail, project from `tabPurchase Invoice Item` - where parent in (%s) and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '') + where parent in (%s) """ % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1) invoice_po_pr_map = {} From fd3998cfc913707a699c17be2f0322d0b91bf227 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 12 Feb 2019 11:27:23 +0530 Subject: [PATCH 14/18] fix: make branch as link field --- erpnext/hr/doctype/salary_slip/salary_slip.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json index 83afa8c6b5..76e43d6ea7 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.json +++ b/erpnext/hr/doctype/salary_slip/salary_slip.json @@ -195,7 +195,7 @@ "columns": 0, "fetch_from": "employee.branch", "fieldname": "branch", - "fieldtype": "Read Only", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -208,11 +208,11 @@ "no_copy": 0, "oldfieldname": "branch", "oldfieldtype": "Link", - "options": "", + "options": "Branch", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -1906,7 +1906,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-01-30 11:28:11.774739", + "modified": "2019-02-12 11:24:20.848207", "modified_by": "Administrator", "module": "HR", "name": "Salary Slip", From b614fb1d4523287931e96130f30a64943192637a Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 12 Feb 2019 11:30:58 +0530 Subject: [PATCH 15/18] fix: make finance book field as link field and rectify fetch_from --- erpnext/assets/doctype/asset/asset.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 6b3c3cc73d..bbe92f636a 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -1812,8 +1812,9 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_from": "company.default_finance_book", "fieldname": "default_finance_book", - "fieldtype": "Read Only", + "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -1824,12 +1825,12 @@ "label": "Default Finance Book", "length": 0, "no_copy": 0, - "options": "company.default_finance_book", + "options": "Finance Book", "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -1882,7 +1883,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-01-15 16:12:48.314196", + "modified": "2019-02-12 11:29:01.747819", "modified_by": "Administrator", "module": "Assets", "name": "Asset", From fc88029d7d753cc73670f44a3833b6cb3945e86c Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 12 Feb 2019 11:38:27 +0530 Subject: [PATCH 16/18] fix: fix item field for clinical procedure template --- .../clinical_procedure_template.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json index df56918b9c..26564a34ce 100644 --- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json +++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, @@ -55,7 +56,7 @@ "collapsible": 0, "columns": 0, "fieldname": "item_code", - "fieldtype": "Read Only", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -71,7 +72,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -707,7 +708,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-08-08 13:00:06.260997", + "modified": "2019-02-12 11:37:18.713344", "modified_by": "Administrator", "module": "Healthcare", "name": "Clinical Procedure Template", From da7c20e47423461ca28439b347224b033dbfb77d Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Tue, 12 Feb 2019 12:55:50 +0530 Subject: [PATCH 17/18] fix: Validate task dates in project (#16586) * fix: Validate task dates in project * fix: Test case fix and validation only if date exists * fix: Added dates in error messages --- erpnext/projects/doctype/project/project.py | 20 +++++++++++++++++++- erpnext/projects/doctype/task/task.py | 6 ------ erpnext/projects/doctype/task/test_task.py | 11 +---------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 3b42f6a69d..e3fd1a8622 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -66,11 +66,11 @@ class Project(Document): def validate(self): self.validate_project_name() - self.validate_dates() self.validate_weights() self.sync_tasks() self.tasks = [] self.load_tasks() + self.validate_dates() self.send_welcome_email() self.update_percent_complete() @@ -79,6 +79,24 @@ class Project(Document): frappe.throw(_("Project {0} already exists").format(frappe.safe_decode(self.project_name))) def validate_dates(self): + if self.tasks: + for d in self.tasks: + if self.expected_start_date: + if d.start_date and getdate(d.start_date) < getdate(self.expected_start_date): + frappe.throw(_("Start date of task {0} cannot be less than {1} expected start date {2}") + .format(d.title, self.name, self.expected_start_date)) + if d.end_date and getdate(d.end_date) < getdate(self.expected_start_date): + frappe.throw(_("End date of task {0} cannot be less than {1} expected start date {2}") + .format(d.title, self.name, self.expected_start_date)) + + if self.expected_end_date: + if d.start_date and getdate(d.start_date) > getdate(self.expected_end_date): + frappe.throw(_("Start date of task {0} cannot be greater than {1} expected end date {2}") + .format(d.title, self.name, self.expected_end_date)) + if d.end_date and getdate(d.end_date) > getdate(self.expected_end_date): + frappe.throw(_("End date of task {0} cannot be greater than {1} expected end date {2}") + .format(d.title, self.name, self.expected_end_date)) + if self.expected_start_date and self.expected_end_date: if getdate(self.expected_end_date) < getdate(self.expected_start_date): frappe.throw(_("Expected End Date can not be less than Expected Start Date")) diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index 371fc5c79b..fffa9c1657 100755 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -44,12 +44,6 @@ class Task(NestedSet): if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date): frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'")) - if(self.project): - if frappe.db.exists("Project", self.project): - expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date") - if self.exp_end_date and expected_end_date and getdate(self.exp_end_date) > getdate(expected_end_date) : - frappe.throw(_("Expected end date cannot be after Project: '{0}' Expected end date").format(self.project), EndDateCannotBeGreaterThanProjectEndDateError) - def validate_status(self): if self.status!=self.get_db_value("status") and self.status == "Closed": for d in self.depends_on: diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py index 6fb5412473..9971946cb4 100644 --- a/erpnext/projects/doctype/task/test_task.py +++ b/erpnext/projects/doctype/task/test_task.py @@ -5,7 +5,7 @@ import frappe import unittest from frappe.utils import getdate, nowdate, add_days -from erpnext.projects.doctype.task.task import CircularReferenceError, EndDateCannotBeGreaterThanProjectEndDateError +from erpnext.projects.doctype.task.task import CircularReferenceError class TestTask(unittest.TestCase): def test_circular_reference(self): @@ -97,15 +97,6 @@ class TestTask(unittest.TestCase): self.assertEqual(frappe.db.get_value("Task", task.name, "status"), "Overdue") - def test_end_date_validation(self): - task_end = create_task("Testing_Enddate_validation", add_days(nowdate(), 35), add_days(nowdate(), 45), save=False) - pro = frappe.get_doc("Project", task_end.project) - pro.expected_end_date = add_days(nowdate(), 40) - pro.save() - self.assertRaises(EndDateCannotBeGreaterThanProjectEndDateError, task_end.save) - - - def create_task(subject, start=None, end=None, depends_on=None, project=None, save=True): if not frappe.db.exists("Task", subject): task = frappe.new_doc('Task') From 6837ae3377917742ef56d8b15b9019db5a83510f Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Tue, 12 Feb 2019 16:54:29 +0550 Subject: [PATCH 18/18] bumped to version 11.1.5 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 89ac6d9b18..40e094d1ba 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '11.1.4' +__version__ = '11.1.5' def get_default_company(user=None): '''Get default company for user'''