fix: Query enhancement, cleanup, added extra filter

- Query changes as requested
- Moved chart generation from js to py
- Added Supplier Multiselect filter
This commit is contained in:
marination 2020-05-07 17:38:00 +05:30
parent 8890b6044d
commit 31a747b98a
2 changed files with 88 additions and 77 deletions

View File

@ -16,7 +16,7 @@ frappe.query_reports["Quoted Item Comparison"] = {
default: "", default: "",
options: "Item", options: "Item",
label: __("Item"), label: __("Item"),
fieldname: "item", fieldname: "item_code",
fieldtype: "Link", fieldtype: "Link",
get_query: () => { get_query: () => {
let quote = frappe.query_report.get_filter_value('supplier_quotation'); let quote = frappe.query_report.get_filter_value('supplier_quotation');
@ -36,6 +36,14 @@ frappe.query_reports["Quoted Item Comparison"] = {
} }
} }
}, },
{
fieldname: "supplier",
label: __("Supplier"),
fieldtype: "MultiSelectList",
get_data: function(txt) {
return frappe.db.get_link_options('Supplier', txt);
}
},
{ {
fieldtype: "Link", fieldtype: "Link",
label: __("Supplier Quotation"), label: __("Supplier Quotation"),
@ -58,60 +66,6 @@ frappe.query_reports["Quoted Item Comparison"] = {
} }
], ],
prepare_chart_data: (result) => {
let supplier_wise_map = {}, data_points_map = {};
let qty_list = result.map(res => res.qty);
qty_list.sort();
qty_list = new Set(qty_list);
// create supplier wise map like in Report
for (let res of result) {
if (!(res.supplier in supplier_wise_map)) {
supplier_wise_map[res.supplier] = {};
}
supplier_wise_map[res.supplier][res.qty] = res.price;
}
// create datapoints for each qty
for (let supplier of Object.keys(supplier_wise_map)) {
let row = supplier_wise_map[supplier];
for (let qty of qty_list) {
if (!data_points_map[qty]) {
data_points_map[qty] = [];
}
if (row[qty]) {
data_points_map[qty].push(row[qty]);
}
else {
data_points_map[qty].push(null);
}
}
}
let dataset = [];
qty_list.forEach((qty) => {
let datapoints = {
'name': __('Price for Qty ') + qty,
'values': data_points_map[qty]
}
dataset.push(datapoints);
});
return dataset;
},
get_chart_data: function (columns, result) {
let suppliers = result.filter(d => d.supplier_name).map(res => res.supplier_name);
let dataset = frappe.query_reports["Quoted Item Comparison"].prepare_chart_data(result);
return {
data: {
labels: suppliers,
datasets: dataset
},
type: 'bar'
}
},
onload: (report) => { onload: (report) => {
// Create a button for setting the default supplier // Create a button for setting the default supplier
report.page.add_inner_button(__("Select Default Supplier"), () => { report.page.add_inner_button(__("Select Default Supplier"), () => {

View File

@ -9,21 +9,33 @@ from collections import defaultdict
from erpnext.setup.utils import get_exchange_rate from erpnext.setup.utils import get_exchange_rate
def execute(filters=None): def execute(filters=None):
if not filters:
return [], []
conditions = get_conditions(filters) conditions = get_conditions(filters)
data = get_data(filters, conditions) supplier_quotation_data = get_data(filters, conditions)
columns = get_columns() columns = get_columns()
return columns, data
data, chart_data = prepare_data(supplier_quotation_data)
return columns, data, None, chart_data
def get_conditions(filters):
conditions = ""
if filters.get("supplier_quotation"):
conditions += " AND sqi.parent = %(supplier_quotation)s"
if filters.get("request_for_quotation"):
conditions += " AND sqi.request_for_quotation = %(request_for_quotation)s"
if filters.get("supplier"):
conditions += " AND sq.supplier in %(supplier)s"
return conditions
def get_data(filters, conditions): def get_data(filters, conditions):
out, suppliers = [], [] if not filters.get("item_code"):
item = filters.get("item")
if not item:
return [] return []
company_currency = frappe.db.get_default("currency")
float_precision = cint(frappe.db.get_default("float_precision")) or 2
supplier_quotation_data = frappe.db.sql("""SELECT supplier_quotation_data = frappe.db.sql("""SELECT
sqi.parent, sqi.qty, sqi.rate, sqi.uom, sqi.request_for_quotation, sqi.parent, sqi.qty, sqi.rate, sqi.uom, sqi.request_for_quotation,
sq.supplier sq.supplier
@ -31,17 +43,27 @@ def get_data(filters, conditions):
`tabSupplier Quotation Item` sqi, `tabSupplier Quotation Item` sqi,
`tabSupplier Quotation` sq `tabSupplier Quotation` sq
WHERE WHERE
sqi.item_code = '{0}' sqi.item_code = %(item_code)s
AND sqi.parent = sq.name AND sqi.parent = sq.name
AND sqi.docstatus < 2 AND sqi.docstatus < 2
AND sq.company = '{1}' AND sq.company = %(company)s
AND sq.status != 'Expired' AND sq.status != 'Expired'
{2}""".format(item, filters.get("company"), conditions), as_dict=1) {0}""".format(conditions), filters, as_dict=1)
return supplier_quotation_data
def prepare_data(supplier_quotation_data):
out, suppliers, qty_list = [], [], []
supplier_wise_map = defaultdict(list) supplier_wise_map = defaultdict(list)
supplier_qty_price_map = {}
company_currency = frappe.db.get_default("currency")
float_precision = cint(frappe.db.get_default("float_precision")) or 2
for data in supplier_quotation_data: for data in supplier_quotation_data:
supplier = data.get("supplier")
supplier_currency = frappe.db.get_value("Supplier", data.get("supplier"), "default_currency") supplier_currency = frappe.db.get_value("Supplier", data.get("supplier"), "default_currency")
if supplier_currency: if supplier_currency:
exchange_rate = get_exchange_rate(supplier_currency, company_currency) exchange_rate = get_exchange_rate(supplier_currency, company_currency)
else: else:
@ -53,29 +75,64 @@ def get_data(filters, conditions):
"price": flt(data.get("rate") * exchange_rate, float_precision), "price": flt(data.get("rate") * exchange_rate, float_precision),
"uom": data.get("uom"), "uom": data.get("uom"),
"request_for_quotation": data.get("request_for_quotation"), "request_for_quotation": data.get("request_for_quotation"),
"supplier": data.get("supplier") # used for chart generation
} }
supplier_wise_map[data.supplier].append(row) # map for report view of form {'supplier1':[{},{},...]}
suppliers.append(data.supplier) supplier_wise_map[supplier].append(row)
suppliers = set(suppliers) # map for chart preparation of the form {'supplier1': {'qty': 'price'}}
if not supplier in supplier_qty_price_map:
supplier_qty_price_map[supplier] = {}
supplier_qty_price_map[supplier][row["qty"]] = row["price"]
suppliers.append(supplier)
qty_list.append(data.get("qty"))
suppliers = list(set(suppliers))
qty_list = list(set(qty_list))
# final data format for report view
for supplier in suppliers: for supplier in suppliers:
supplier_wise_map[supplier][0].update({"supplier_name": supplier}) supplier_wise_map[supplier][0].update({"supplier_name": supplier})
for entry in supplier_wise_map[supplier]: for entry in supplier_wise_map[supplier]:
out.append(entry) out.append(entry)
return out chart_data = prepare_chart_data(suppliers, qty_list, supplier_qty_price_map)
def get_conditions(filters): return out, chart_data
conditions = ""
if filters.get("request_for_quotation"): def prepare_chart_data(suppliers, qty_list, supplier_qty_price_map):
conditions += " AND sqi.request_for_quotation = '{0}' ".format(filters.get("request_for_quotation")) data_points_map = {}
qty_list.sort()
return conditions # create qty wise values map of the form {'qty1':[value1, value2]}
for supplier in suppliers:
entry = supplier_qty_price_map[supplier]
for qty in qty_list:
if not qty in data_points_map:
data_points_map[qty] = []
if qty in entry:
data_points_map[qty].append(entry[qty])
else:
data_points_map[qty].append(None)
dataset = []
for qty in qty_list:
datapoints = {
"name": _("Price for Qty ") + str(qty),
"values": data_points_map[qty]
}
dataset.append(datapoints)
chart_data = {
"data": {
"labels": suppliers,
"datasets": dataset
},
"type": "bar"
}
return chart_data
def get_columns(): def get_columns():
columns = [{ columns = [{