From 4babfdb987bcba43f7d0ea9bf8820497b2a7414c Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 15 Apr 2019 15:34:38 +0530 Subject: [PATCH 1/5] fix(delivery): Add more context for dispatch notification email + formatting fixes --- .../doctype/delivery_trip/delivery_trip.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 01b4734bf5..bc8c7493d5 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -20,8 +20,7 @@ class DeliveryTrip(Document): # Google Maps returns distances in meters by default self.default_distance_uom = frappe.db.get_single_value("Global Defaults", "default_distance_unit") or "Meter" self.uom_conversion_factor = frappe.db.get_value("UOM Conversion Factor", - {"from_uom": "Meter", "to_uom": self.default_distance_uom}, - "value") + {"from_uom": "Meter", "to_uom": self.default_distance_uom}, "value") def validate(self): self.validate_stop_addresses() @@ -139,7 +138,7 @@ class DeliveryTrip(Document): # Include last leg in the final distance calculation self.uom = self.default_distance_uom total_distance = sum([leg.get("distance", {}).get("value", 0.0) - for leg in directions.get("legs")]) # in meters + for leg in directions.get("legs")]) # in meters self.total_distance = total_distance * self.uom_conversion_factor else: idx += len(route) - 1 @@ -358,8 +357,12 @@ def notify_customers(delivery_trip): email_recipients = [] for stop in delivery_trip.delivery_stops: - contact_info = frappe.db.get_value("Contact", stop.contact, - ["first_name", "last_name", "email_id", "gender"], as_dict=1) + contact_info = frappe.db.get_value("Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1) + + context.update({"items": []}) + if stop.delivery_note: + items = frappe.get_all("Delivery Note Item", filters={"parent": stop.delivery_note, "docstatus": 1}, fields=["*"]) + context.update({"items": items}) if contact_info and contact_info.email_id: context.update(stop.as_dict()) @@ -369,9 +372,9 @@ def notify_customers(delivery_trip): dispatch_template = frappe.get_doc("Email Template", dispatch_template_name) frappe.sendmail(recipients=contact_info.email_id, - subject=dispatch_template.subject, - message=frappe.render_template(dispatch_template.response, context), - attachments=get_attachments(stop)) + subject=dispatch_template.subject, + message=frappe.render_template(dispatch_template.response, context), + attachments=get_attachments(stop)) stop.db_set("email_sent_to", contact_info.email_id) email_recipients.append(contact_info.email_id) @@ -388,9 +391,7 @@ def get_attachments(delivery_stop): return [] dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment") - attachments = frappe.attach_print("Delivery Note", - delivery_stop.delivery_note, - file_name="Delivery Note", - print_format=dispatch_attachment) + attachments = frappe.attach_print("Delivery Note", delivery_stop.delivery_note, + file_name="Delivery Note", print_format=dispatch_attachment) return [attachments] From 9ee5c8a4c68817622eabd7fb4b57f66a8c8070f6 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 17 Jun 2019 18:05:41 +0530 Subject: [PATCH 2/5] fix(employee-benefit-application): remove query from setup --- .../employee_benefit_application.js | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js index e71ce1276b..c55c46db99 100644 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js +++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js @@ -2,20 +2,8 @@ // For license information, please see license.txt frappe.ui.form.on('Employee Benefit Application', { - setup: function(frm) { - if(!frm.doc.employee || !frm.doc.date) { - frappe.throw(__("Please select Employee and Date first")); - } else { - frm.set_query("earning_component", "employee_benefits", function() { - return { - query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", - filters: {date: frm.doc.date, employee: frm.doc.employee} - }; - }); - } - }, - employee: function(frm) { + frm.trigger('set_earning_component'); var method, args; if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){ method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining"; @@ -35,6 +23,21 @@ frappe.ui.form.on('Employee Benefit Application', { get_max_benefits(frm, method, args); } }, + + date: function(frm) { + frm.trigger('set_earning_component'); + }, + + set_earning_component: function(frm) { + if(!frm.doc.employee && !frm.doc.date) return; + frm.set_query("earning_component", "employee_benefits", function() { + return { + query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", + filters: {date: frm.doc.date, employee: frm.doc.employee} + } + }); + }, + payroll_period: function(frm) { var method, args; if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){ From 7293a98a10b0a7fedf09f519af740fa98061b3d8 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 17 Jun 2019 19:03:46 +0530 Subject: [PATCH 3/5] fix: change formatting --- .../employee_benefit_application.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js index c55c46db99..b73dcf8ac3 100644 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js +++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js @@ -34,7 +34,7 @@ frappe.ui.form.on('Employee Benefit Application', { return { query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", filters: {date: frm.doc.date, employee: frm.doc.employee} - } + }; }); }, From 48585c94ffc99dd5e1daceca98e78eae63a81ec8 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Tue, 18 Jun 2019 19:11:17 +0530 Subject: [PATCH 4/5] fix: Consider discount_amount only when provided to calculate rate After selecting item_code in items table and not entering rate, Clicking elsewhere will set rate to NaN. All DocTypes on buying side have this bug. --- erpnext/public/js/controllers/buying.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 7e61f03af9..97c823d053 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -144,7 +144,9 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ item.discount_amount = flt(item_rate) * flt(item.discount_percentage) / 100; } - item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item)); + if (item.discount_amount) { + item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item)); + } this.calculate_taxes_and_totals(); }, From 2632107129bc8726a7dcd6d70c1d6df7d4bd8eab Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 19 Jun 2019 12:15:37 +0530 Subject: [PATCH 5/5] fix: User MultiSelectList control for Party filter (#17943) * fix: User MultiSelectList control for Party filter The comma based filter wouldn't work for values that had comma in them * fix: Replace with MultiSelectList in reports * fix: Parse json instead of string split --- .../accounts/report/financial_statements.py | 4 +- .../report/general_ledger/general_ledger.js | 92 +++---------------- .../report/general_ledger/general_ledger.py | 9 +- .../gross_and_net_profit_report.js | 30 +----- .../profit_and_loss_statement.js | 30 +----- erpnext/public/js/financial_statements.js | 31 +------ 6 files changed, 31 insertions(+), 165 deletions(-) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 41205ae2b0..c06856aa75 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -390,8 +390,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): if filters: if filters.get("project"): if not isinstance(filters.get("project"), list): - projects = frappe.safe_encode(filters.get("project")) - filters.project = [d.strip() for d in projects.strip().split(',') if d] + filters.project = frappe.parse_json(filters.get("project")) + additional_conditions.append("project in %(project)s") if filters.get("cost_center"): diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index 4235b7f60d..5c98b249db 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -72,46 +72,25 @@ frappe.query_reports["General Ledger"] = { { "fieldname":"party", "label": __("Party"), - "fieldtype": "MultiSelect", - get_data: function() { + "fieldtype": "MultiSelectList", + get_data: function(txt) { if (!frappe.query_report.filters) return; - var party_type = frappe.query_report.get_filter_value('party_type'); - var parties = frappe.query_report.get_filter_value('party'); - if(!party_type) return; - const values = parties.split(/\s*,\s*/).filter(d => d); - const txt = parties.match(/[^,\s*]*$/)[0] || ''; - let data = []; + let party_type = frappe.query_report.get_filter_value('party_type'); + if (!party_type) return; - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: frappe.query_report.get_filter_value('party_type'), - txt: txt, - filters: { - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + return frappe.db.get_link_options(party_type, txt); }, on_change: function() { var party_type = frappe.query_report.get_filter_value('party_type'); var parties = frappe.query_report.get_filter_value('party'); - const values = parties.split(/\s*,\s*/).filter(d => d); - if(!party_type || !parties || values.length>1) { + if(!party_type || parties.length === 0 || parties.length > 1) { frappe.query_report.set_filter_value('party_name', ""); frappe.query_report.set_filter_value('tax_id', ""); return; } else { - var party = values[0]; + var party = parties[0]; var fieldname = erpnext.utils.get_party_name(party_type) || "name"; frappe.db.get_value(party_type, party, fieldname, function(value) { frappe.query_report.set_filter_value('party_name', value[fieldname]); @@ -154,62 +133,17 @@ frappe.query_reports["General Ledger"] = { { "fieldname":"cost_center", "label": __("Cost Center"), - "fieldtype": "MultiSelect", - get_data: function() { - var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; - - const values = cost_centers.split(/\s*,\s*/).filter(d => d); - const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Cost Center", - txt: txt, - filters: { - "company": frappe.query_report.get_filter_value("company"), - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Cost Center', txt); } }, { "fieldname":"project", "label": __("Project"), - "fieldtype": "MultiSelect", - get_data: function() { - var projects = frappe.query_report.get_filter_value("project") || ""; - - const values = projects.split(/\s*,\s*/).filter(d => d); - const txt = projects.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Project", - txt: txt, - filters: { - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Project', txt); } }, { diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index d9f395b895..1c5e089534 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -26,8 +26,7 @@ def execute(filters=None): account_details.setdefault(acc.name, acc) if filters.get('party'): - parties = cstr(filters.get("party")).strip() - filters.party = [d.strip() for d in parties.split(',') if d] + filters.party = frappe.parse_json(filters.get("party")) validate_filters(filters, account_details) @@ -61,12 +60,10 @@ def validate_filters(filters, account_details): frappe.throw(_("From Date must be before To Date")) if filters.get('project'): - projects = cstr(filters.get("project")).strip() - filters.project = [d.strip() for d in projects.split(',') if d] + filters.project = frappe.parse_json(filters.get('project')) if filters.get('cost_center'): - cost_centers = cstr(filters.get("cost_center")).strip() - filters.cost_center = [d.strip() for d in cost_centers.split(',') if d] + filters.cost_center = frappe.parse_json(filters.get('cost_center')) def validate_party(filters): diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js index 63ac281cdb..8dc5ab36dd 100644 --- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js +++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js @@ -13,33 +13,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { frappe.query_reports["Gross and Net Profit Report"]["filters"].push( { - "fieldname":"project", + "fieldname": "project", "label": __("Project"), - "fieldtype": "MultiSelect", - get_data: function() { - var projects = frappe.query_report.get_filter_value("project") || ""; - - const values = projects.split(/\s*,\s*/).filter(d => d); - const txt = projects.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Project", - txt: txt, - filters: { - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Project', txt); } }, { diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js index 250e516d7d..df5c982258 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js @@ -8,33 +8,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { frappe.query_reports["Profit and Loss Statement"]["filters"].push( { - "fieldname":"project", + "fieldname": "project", "label": __("Project"), - "fieldtype": "MultiSelect", - get_data: function() { - var projects = frappe.query_report.get_filter_value("project") || ""; - - const values = projects.split(/\s*,\s*/).filter(d => d); - const txt = projects.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Project", - txt: txt, - filters: { - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Project', txt); } }, { diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js index 73e04c0ff0..d1113a4ca4 100644 --- a/erpnext/public/js/financial_statements.js +++ b/erpnext/public/js/financial_statements.js @@ -118,34 +118,13 @@ function get_filters(){ "options": erpnext.get_presentation_currency_list() }, { - "fieldname":"cost_center", + "fieldname": "cost_center", "label": __("Cost Center"), - "fieldtype": "MultiSelect", - get_data: function() { - var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; - - const values = cost_centers.split(/\s*,\s*/).filter(d => d); - const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Cost Center", - txt: txt, - filters: { - "company": frappe.query_report.get_filter_value("company"), - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Cost Center', txt, { + company: frappe.query_report.get_filter_value("company") }); - return data; } } ]