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/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'] 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")) diff --git a/erpnext/education/doctype/student_group/student_group.js b/erpnext/education/doctype/student_group/student_group.js index 4165ce0f2e7..13724409bab 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); } }, 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 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", 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")) 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"