From 94e14257fba5d759106999cd32895540e6d98ab9 Mon Sep 17 00:00:00 2001 From: Er-Naren719 <49683121+Er-Naren719@users.noreply.github.com> Date: Mon, 10 Feb 2020 13:46:47 +0530 Subject: [PATCH 1/8] feat: column width increased for view attachments field (#314) --- erpnext/projects/doctype/project_user/project_user.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/projects/doctype/project_user/project_user.json b/erpnext/projects/doctype/project_user/project_user.json index f0a70dd1df9..2f452cc2d75 100644 --- a/erpnext/projects/doctype/project_user/project_user.json +++ b/erpnext/projects/doctype/project_user/project_user.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2016-03-25 02:52:19.283003", "doctype": "DocType", "editable_grid": 1, @@ -46,6 +47,7 @@ "fetch_from": "user.full_name", "fieldname": "full_name", "fieldtype": "Read Only", + "in_list_view": 1, "label": "Full Name" }, { @@ -55,7 +57,7 @@ "label": "Welcome email sent" }, { - "columns": 1, + "columns": 2, "default": "0", "fieldname": "view_attachments", "fieldtype": "Check", @@ -74,7 +76,8 @@ } ], "istable": 1, - "modified": "2019-07-15 19:37:26.942294", + "links": [], + "modified": "2020-02-09 23:26:50.321417", "modified_by": "Administrator", "module": "Projects", "name": "Project User", From 21d662f96ddb382f4582e34aa90f8da7b012f09b Mon Sep 17 00:00:00 2001 From: Anuradha Kalaskar Date: Sat, 15 Feb 2020 13:17:57 +0530 Subject: [PATCH 2/8] fix: to date cannot be less than from date validation on student leave application --- .../student_leave_application.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/erpnext/education/doctype/student_leave_application/student_leave_application.py b/erpnext/education/doctype/student_leave_application/student_leave_application.py index b3e71a2b086..410f0cca3f4 100644 --- a/erpnext/education/doctype/student_leave_application/student_leave_application.py +++ b/erpnext/education/doctype/student_leave_application/student_leave_application.py @@ -7,9 +7,11 @@ import frappe from frappe import _ from frappe.utils import get_link_to_form from frappe.model.document import Document +from frappe import throw, _ class StudentLeaveApplication(Document): def validate(self): + self.validate_dates() self.validate_duplicate() def validate_duplicate(self): @@ -29,4 +31,8 @@ class StudentLeaveApplication(Document): if data: link = get_link_to_form("Student Leave Application", data[0].name) frappe.throw(_("Leave application {0} already exists against the student {1}") - .format(link, self.student)) \ No newline at end of file + .format(link, self.student)) + + def validate_dates(self): + if self.to_date < self.from_date : + throw(_("To Date cannot be less than From Date")) \ No newline at end of file From 3a6ca13b4479e313f5c473444eb34308c9236e01 Mon Sep 17 00:00:00 2001 From: jsukrut Date: Sat, 15 Feb 2020 16:18:17 +0530 Subject: [PATCH 3/8] fix:Mandatory field property failed to work based on the selection of field 'Group Based on' on 'Student Group' Page #20605 --- .../education/doctype/student_group/student_group.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/erpnext/education/doctype/student_group/student_group.js b/erpnext/education/doctype/student_group/student_group.js index 4165ce0f2e7..d7822487ecc 100644 --- a/erpnext/education/doctype/student_group/student_group.js +++ b/erpnext/education/doctype/student_group/student_group.js @@ -70,6 +70,16 @@ frappe.ui.form.on("Student Group", { group_based_on: function(frm) { if (frm.doc.group_based_on == "Batch") { frm.doc.course = null; + frm.set_df_property('program', 'reqd', 1); + frm.set_df_property('course', 'reqd', 0); + } + else if (frm.doc.group_based_on == "Course") { + frm.set_df_property('program', 'reqd', 0); + frm.set_df_property('course', 'reqd', 1); + } + else if (frm.doc.group_based_on == "Activity") { + frm.set_df_property('program', 'reqd', 0); + frm.set_df_property('course', 'reqd', 0); } }, From c0fd30a7ec63cba49efd5fb282f991a78c8b82ec Mon Sep 17 00:00:00 2001 From: jsukrut Date: Sat, 15 Feb 2020 17:33:52 +0530 Subject: [PATCH 4/8] fix: Indentation --- erpnext/education/doctype/student_group/student_group.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/education/doctype/student_group/student_group.js b/erpnext/education/doctype/student_group/student_group.js index d7822487ecc..13724409bab 100644 --- a/erpnext/education/doctype/student_group/student_group.js +++ b/erpnext/education/doctype/student_group/student_group.js @@ -74,8 +74,8 @@ frappe.ui.form.on("Student Group", { frm.set_df_property('course', 'reqd', 0); } else if (frm.doc.group_based_on == "Course") { - frm.set_df_property('program', 'reqd', 0); - frm.set_df_property('course', 'reqd', 1); + frm.set_df_property('program', 'reqd', 0); + frm.set_df_property('course', 'reqd', 1); } else if (frm.doc.group_based_on == "Activity") { frm.set_df_property('program', 'reqd', 0); From e329d417d66d6b1698d71ff9e3b58a435e6d24ba Mon Sep 17 00:00:00 2001 From: shrikant dixit Date: Sat, 15 Feb 2020 18:20:05 +0530 Subject: [PATCH 5/8] fix: Added validation for student DOB can not be greater than Joining Date --- erpnext/education/doctype/student/student.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py index 99c4c0e9089..ae8f3a2e54b 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -25,6 +25,9 @@ class Student(Document): if self.date_of_birth and getdate(self.date_of_birth) >= getdate(today()): frappe.throw(_("Date of Birth cannot be greater than today.")) + if self.date_of_birth and getdate(self.date_of_birth) >= getdate(self.joining_date): + frappe.throw(_("Date of Birth cannot be greater than Joining Date.")) + if self.joining_date and self.date_of_leaving and getdate(self.joining_date) > getdate(self.date_of_leaving): frappe.throw(_("Joining Date can not be greater than Leaving Date")) From b3712158aef85ae298e3af5e0c54f50f02190ca5 Mon Sep 17 00:00:00 2001 From: P-Froggy <60393001+P-Froggy@users.noreply.github.com> Date: Sun, 16 Feb 2020 19:10:53 +0100 Subject: [PATCH 6/8] Bank accounts reference in supplier dashboard Adds a reference to linked bank accounts in supplier dashboard, which was previously missing. --- erpnext/buying/doctype/supplier/supplier_dashboard.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/supplier/supplier_dashboard.py b/erpnext/buying/doctype/supplier/supplier_dashboard.py index 887a0937369..b3b294d5701 100644 --- a/erpnext/buying/doctype/supplier/supplier_dashboard.py +++ b/erpnext/buying/doctype/supplier/supplier_dashboard.py @@ -9,7 +9,8 @@ def get_data(): 'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'), 'fieldname': 'supplier', 'non_standard_fieldnames': { - 'Payment Entry': 'party_name' + 'Payment Entry': 'party_name', + 'Bank Account': 'party' }, 'transactions': [ { @@ -24,6 +25,10 @@ def get_data(): 'label': _('Payments'), 'items': ['Payment Entry'] }, + { + 'label': _('Bank'), + 'items': ['Bank Account'] + }, { 'label': _('Pricing'), 'items': ['Pricing Rule'] From 7a46aae57a613e65cba3d7ba8a6dc5ce65cfd9f0 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 17 Feb 2020 12:20:25 +0530 Subject: [PATCH 7/8] fix: updated package.json * fixed devDependencies typo which possibly caused https://discuss.erpnext.com/t/bin-sh-1-snyk-not-found-when-bench-update/58035 which was introduced in https://github.com/frappe/erpnext/pull/20563 * Added missing fields for package meta data --- package.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 13fcc0f98d2..1b2dc9efcf5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,21 @@ { - "devdependencies": { + "name": "erpnext", + "description": "Open Source ERP System powered by the Frappe Framework", + "repository": { + "type": "git", + "url": "git+https://github.com/frappe/erpnext.git" + }, + "homepage": "https://erpnext.com", + "author": "Frappe Technologies Pvt. Ltd.", + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/frappe/erpnext/issues" + }, + "devDependencies": { "snyk": "^1.290.1" }, + "dependencies": { + }, "scripts": { "snyk-protect": "snyk protect", "prepare": "yarn run snyk-protect" From db002708958dc88b09b05c1d7deea16687a1b345 Mon Sep 17 00:00:00 2001 From: Marica Date: Mon, 17 Feb 2020 15:58:08 +0530 Subject: [PATCH 8/8] feat: Added popup to 'Get Items from Open Material Requests' in Purchase Order (#20371) * feat: Added popup to 'Get Items from Open Material Requests' in Purchase Order * fix: Query with filters, UX enhancements and cleanup --- .../doctype/purchase_order/purchase_order.js | 12 ++- .../purchase_order/purchase_order.json | 3 +- erpnext/public/js/utils.js | 17 +++- .../material_request/material_request.py | 81 +++++++++++-------- 4 files changed, 75 insertions(+), 38 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 7b1f1354d79..a3264a4c0f8 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -180,10 +180,20 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( get_items_from_open_material_requests: function() { erpnext.utils.map_current_doc({ method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier", + args: { + supplier: this.frm.doc.supplier + }, + source_doctype: "Material Request", source_name: this.frm.doc.supplier, + target: this.frm, + setters: { + company: me.frm.doc.company + }, get_query_filters: { docstatus: ["!=", 2], - } + supplier: this.frm.doc.supplier + }, + get_query_method: "erpnext.stock.doctype.material_request.material_request.get_material_requests_based_on_supplier" }); }, diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index d82e128735e..4d836903911 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -12,8 +12,8 @@ "supplier", "get_items_from_open_material_requests", "supplier_name", - "company", "column_break1", + "company", "transaction_date", "schedule_date", "order_confirmation_no", @@ -170,6 +170,7 @@ "search_index": 1 }, { + "description": "Fetch items based on Default Supplier.", "depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))", "fieldname": "get_items_from_open_material_requests", "fieldtype": "Button", diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 3f444f83879..35dc8427aa9 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -514,9 +514,18 @@ erpnext.utils.update_child_items = function(opts) { } erpnext.utils.map_current_doc = function(opts) { - if(opts.get_query_filters) { - opts.get_query = function() { - return {filters: opts.get_query_filters}; + let query_args = {}; + if (opts.get_query_filters) { + query_args.filters = opts.get_query_filters; + } + + if (opts.get_query_method) { + query_args.query = opts.get_query_method; + } + + if (query_args.filters || query_args.query) { + opts.get_query = () => { + return query_args; } } var _map = function() { @@ -582,7 +591,7 @@ erpnext.utils.map_current_doc = function(opts) { "method": opts.method, "source_names": opts.source_name, "target_doc": cur_frm.doc, - 'args': opts.args + "args": opts.args }, callback: function(r) { if(!r.exc) { diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 941f9041023..45428470167 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import frappe +import json from frappe.utils import cstr, flt, getdate, new_line_sep, nowdate, add_days from frappe import msgprint, _ @@ -329,17 +330,13 @@ def make_request_for_quotation(source_name, target_doc=None): return doclist @frappe.whitelist() -def make_purchase_order_based_on_supplier(source_name, target_doc=None): - if target_doc: - if isinstance(target_doc, string_types): - import json - target_doc = frappe.get_doc(json.loads(target_doc)) - target_doc.set("items", []) +def make_purchase_order_based_on_supplier(source_name, target_doc=None, args=None): + mr = source_name - material_requests, supplier_items = get_material_requests_based_on_supplier(source_name) + supplier_items = get_items_based_on_default_supplier(args.get("supplier")) def postprocess(source, target_doc): - target_doc.supplier = source_name + target_doc.supplier = args.get("supplier") if getdate(target_doc.schedule_date) < getdate(nowdate()): target_doc.schedule_date = None target_doc.set("items", [d for d in target_doc.get("items") @@ -347,44 +344,64 @@ def make_purchase_order_based_on_supplier(source_name, target_doc=None): set_missing_values(source, target_doc) - for mr in material_requests: - target_doc = get_mapped_doc("Material Request", mr, { - "Material Request": { - "doctype": "Purchase Order", - }, - "Material Request Item": { - "doctype": "Purchase Order Item", - "field_map": [ - ["name", "material_request_item"], - ["parent", "material_request"], - ["uom", "stock_uom"], - ["uom", "uom"] - ], - "postprocess": update_item, - "condition": lambda doc: doc.ordered_qty < doc.qty - } - }, target_doc, postprocess) + target_doc = get_mapped_doc("Material Request", mr, { + "Material Request": { + "doctype": "Purchase Order", + }, + "Material Request Item": { + "doctype": "Purchase Order Item", + "field_map": [ + ["name", "material_request_item"], + ["parent", "material_request"], + ["uom", "stock_uom"], + ["uom", "uom"] + ], + "postprocess": update_item, + "condition": lambda doc: doc.ordered_qty < doc.qty + } + }, target_doc, postprocess) return target_doc -def get_material_requests_based_on_supplier(supplier): +@frappe.whitelist() +def get_items_based_on_default_supplier(supplier): supplier_items = [d.parent for d in frappe.db.get_all("Item Default", - {"default_supplier": supplier}, 'parent')] + {"default_supplier": supplier, "parenttype": "Item"}, 'parent')] + + return supplier_items + +@frappe.whitelist() +def get_material_requests_based_on_supplier(doctype, txt, searchfield, start, page_len, filters): + conditions = "" + if txt: + conditions += "and mr.name like '%%"+txt+"%%' " + + if filters.get("transaction_date"): + date = filters.get("transaction_date")[1] + conditions += "and mr.transaction_date between '{0}' and '{1}' ".format(date[0], date[1]) + + supplier = filters.get("supplier") + supplier_items = get_items_based_on_default_supplier(supplier) + if not supplier_items: frappe.throw(_("{0} is not the default supplier for any items.").format(supplier)) - material_requests = frappe.db.sql_list("""select distinct mr.name + material_requests = frappe.db.sql("""select distinct mr.name, transaction_date,company from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item where mr.name = mr_item.parent - and mr_item.item_code in (%s) + and mr_item.item_code in ({0}) and mr.material_request_type = 'Purchase' and mr.per_ordered < 99.99 and mr.docstatus = 1 and mr.status != 'Stopped' - order by mr_item.item_code ASC""" % ', '.join(['%s']*len(supplier_items)), - tuple(supplier_items)) + and mr.company = '{1}' + {2} + order by mr_item.item_code ASC + limit {3} offset {4} """ \ + .format(', '.join(['%s']*len(supplier_items)), filters.get("company"), conditions, page_len, start), + tuple(supplier_items), as_dict=1) - return material_requests, supplier_items + return material_requests def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters): doc = frappe.get_doc("Material Request", filters.get("doc"))