feat: Supplier Quotation Comparison - v3

This commit is contained in:
marination 2020-09-14 17:34:21 +05:30
parent 59d20c7d2c
commit 59239172a1
6 changed files with 106 additions and 53 deletions

View File

@ -1,32 +0,0 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2016-07-21 08:31:05.890362",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 2,
"is_standard": "Yes",
"modified": "2017-02-24 20:04:58.784351",
"modified_by": "Administrator",
"module": "Buying",
"name": "Quoted Item Comparison",
"owner": "Administrator",
"ref_doctype": "Supplier Quotation",
"report_name": "Quoted Item Comparison",
"report_type": "Script Report",
"roles": [
{
"role": "Manufacturing Manager"
},
{
"role": "Purchase Manager"
},
{
"role": "Purchase User"
},
{
"role": "Stock User"
}
]
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt // For license information, please see license.txt
frappe.query_reports["Quoted Item Comparison"] = { frappe.query_reports["Supplier Quotation Comparison"] = {
filters: [ filters: [
{ {
fieldtype: "Link", fieldtype: "Link",
@ -78,6 +78,13 @@ frappe.query_reports["Quoted Item Comparison"] = {
return { filters: { "docstatus": ["<", 2] } } return { filters: { "docstatus": ["<", 2] } }
} }
}, },
{
"fieldname":"group_by",
"label": __("Group by"),
"fieldtype": "Select",
"options": [__("Group by Supplier"), __("Group by Item")],
"default": __("Group by Supplier")
},
{ {
fieldtype: "Check", fieldtype: "Check",
label: __("Include Expired"), label: __("Include Expired"),
@ -98,6 +105,9 @@ frappe.query_reports["Quoted Item Comparison"] = {
} }
} }
if(column.fieldname === "price_per_unit" && data.price_per_unit && data.min && data.min === 1){
value = `<div style="color:green">${value}</div>`;
}
return value; return value;
}, },

View File

@ -0,0 +1,32 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2016-07-21 08:31:05.890362",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 2,
"is_standard": "Yes",
"modified": "2017-02-24 20:04:58.784351",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation Comparison",
"owner": "Administrator",
"ref_doctype": "Supplier Quotation",
"report_name": "Supplier Quotation Comparison",
"report_type": "Script Report",
"roles": [
{
"role": "Manufacturing Manager"
},
{
"role": "Purchase Manager"
},
{
"role": "Purchase User"
},
{
"role": "Stock User"
}
]
}

View File

@ -12,9 +12,9 @@ def execute(filters=None):
if not filters: if not filters:
return [], [] return [], []
columns = get_columns(filters)
conditions = get_conditions(filters) conditions = get_conditions(filters)
supplier_quotation_data = get_data(filters, conditions) supplier_quotation_data = get_data(filters, conditions)
columns = get_columns()
data, chart_data = prepare_data(supplier_quotation_data, filters) data, chart_data = prepare_data(supplier_quotation_data, filters)
message = get_message() message = get_message()
@ -41,9 +41,13 @@ def get_conditions(filters):
return conditions return conditions
def get_data(filters, conditions): def get_data(filters, conditions):
supplier_quotation_data = frappe.db.sql("""SELECT supplier_quotation_data = frappe.db.sql("""
sqi.parent, sqi.item_code, sqi.qty, sqi.rate, sqi.uom, sqi.request_for_quotation, SELECT
sqi.lead_time_days, sq.supplier, sq.valid_till sqi.parent, sqi.item_code,
sqi.qty, sqi.stock_qty, sqi.rate,
sqi.uom, sqi.stock_uom,
sqi.request_for_quotation,
sqi.lead_time_days, sq.supplier as supplier_name, sq.valid_till
FROM FROM
`tabSupplier Quotation Item` sqi, `tabSupplier Quotation Item` sqi,
`tabSupplier Quotation` sq `tabSupplier Quotation` sq
@ -58,16 +62,18 @@ def get_data(filters, conditions):
return supplier_quotation_data return supplier_quotation_data
def prepare_data(supplier_quotation_data, filters): def prepare_data(supplier_quotation_data, filters):
out, suppliers, qty_list, chart_data = [], [], [], [] out, groups, qty_list, suppliers, chart_data = [], [], [], [], []
supplier_wise_map = defaultdict(list) group_wise_map = defaultdict(list)
supplier_qty_price_map = {} supplier_qty_price_map = {}
group_by_field = "supplier_name" if filters.get("group_by") == "Group by Supplier" else "item_code"
company_currency = frappe.db.get_default("currency") company_currency = frappe.db.get_default("currency")
float_precision = cint(frappe.db.get_default("float_precision")) or 2 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") group = data.get(group_by_field) # get item or supplier value for this row
supplier_currency = frappe.db.get_value("Supplier", data.get("supplier"), "default_currency")
supplier_currency = frappe.db.get_value("Supplier", data.get("supplier_name"), "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)
@ -75,38 +81,55 @@ def prepare_data(supplier_quotation_data, filters):
exchange_rate = 1 exchange_rate = 1
row = { row = {
"item_code": data.get('item_code'), "item_code": "" if group_by_field=="item_code" else data.get("item_code"), # leave blank if group by field
"supplier_name": "" if group_by_field=="supplier_name" else data.get("supplier_name"),
"quotation": data.get("parent"), "quotation": data.get("parent"),
"qty": data.get("qty"), "qty": data.get("qty"),
"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"),
"stock_uom": data.get('stock_uom'),
"request_for_quotation": data.get("request_for_quotation"), "request_for_quotation": data.get("request_for_quotation"),
"valid_till": data.get('valid_till'), "valid_till": data.get('valid_till'),
"lead_time_days": data.get('lead_time_days') "lead_time_days": data.get('lead_time_days')
} }
row["price_per_unit"] = flt(row["price"]) / (flt(data.get("stock_qty")) or 1)
# map for report view of form {'supplier1':[{},{},...]} # map for report view of form {'supplier1'/'item1':[{},{},...]}
supplier_wise_map[supplier].append(row) group_wise_map[group].append(row)
# map for chart preparation of the form {'supplier1': {'qty': 'price'}} # map for chart preparation of the form {'supplier1': {'qty': 'price'}}
supplier = data.get("supplier_name")
if filters.get("item_code"): if filters.get("item_code"):
if not supplier in supplier_qty_price_map: if not supplier in supplier_qty_price_map:
supplier_qty_price_map[supplier] = {} supplier_qty_price_map[supplier] = {}
supplier_qty_price_map[supplier][row["qty"]] = row["price"] supplier_qty_price_map[supplier][row["qty"]] = row["price"]
groups.append(group)
suppliers.append(supplier) suppliers.append(supplier)
qty_list.append(data.get("qty")) qty_list.append(data.get("qty"))
groups = list(set(groups))
suppliers = list(set(suppliers)) suppliers = list(set(suppliers))
qty_list = list(set(qty_list)) qty_list = list(set(qty_list))
highlight_min_price = group_by_field == "item_code"
# final data format for report view # final data format for report view
for supplier in suppliers: for group in groups:
supplier_wise_map[supplier][0].update({"supplier_name": supplier}) group_entries = group_wise_map[group] # all entries pertaining to item/supplier
for entry in supplier_wise_map[supplier]: group_entries[0].update({group_by_field : group})
if highlight_min_price:
prices = [group_entry["price_per_unit"] for group_entry in group_entries]
min_price = min(prices)
for entry in group_entries:
if highlight_min_price and entry["price_per_unit"] == min_price:
entry["min"] = 1
out.append(entry) out.append(entry)
if filters.get("item_code"): if filters.get("item_code"):
# render chart only for one item comparison
chart_data = prepare_chart_data(suppliers, qty_list, supplier_qty_price_map) chart_data = prepare_chart_data(suppliers, qty_list, supplier_qty_price_map)
return out, chart_data return out, chart_data
@ -145,8 +168,9 @@ def prepare_chart_data(suppliers, qty_list, supplier_qty_price_map):
return chart_data return chart_data
def get_columns(): def get_columns(filters):
columns = [{ group_by_columns = [
{
"fieldname": "supplier_name", "fieldname": "supplier_name",
"label": _("Supplier"), "label": _("Supplier"),
"fieldtype": "Link", "fieldtype": "Link",
@ -158,8 +182,10 @@ def get_columns():
"label": _("Item"), "label": _("Item"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Item", "options": "Item",
"width": 200 "width": 150
}, }]
columns = [
{ {
"fieldname": "uom", "fieldname": "uom",
"label": _("UOM"), "label": _("UOM"),
@ -180,6 +206,20 @@ def get_columns():
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"width": 110 "width": 110
}, },
{
"fieldname": "stock_uom",
"label": _("Stock UOM"),
"fieldtype": "Link",
"options": "UOM",
"width": 90
},
{
"fieldname": "price_per_unit",
"label": _("Price per Unit (Stock UOM)"),
"fieldtype": "Currency",
"options": "Company:company:default_currency",
"width": 120
},
{ {
"fieldname": "quotation", "fieldname": "quotation",
"label": _("Supplier Quotation"), "label": _("Supplier Quotation"),
@ -205,9 +245,12 @@ def get_columns():
"fieldtype": "Link", "fieldtype": "Link",
"options": "Request for Quotation", "options": "Request for Quotation",
"width": 150 "width": 150
} }]
]
if filters.get("group_by") == "Group by Item":
group_by_columns.reverse()
columns[0:0] = group_by_columns # add positioned group by columns to the report
return columns return columns
def get_message(): def get_message():