Merge pull request #25797 from marination/item-variants-report

fix: Item Variant Details Report
This commit is contained in:
Marica 2021-05-22 19:05:54 +05:30 committed by GitHub
commit eaf0465c44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,47 +14,58 @@ def get_data(item):
if not item: if not item:
return [] return []
item_dicts = [] item_dicts = []
variants = None
variant_results = frappe.db.sql("""select name from `tabItem` variant_results = frappe.db.get_all(
where variant_of = %s""", item, as_dict=1) "Item",
fields=["name"],
filters={
"variant_of": ["=", item],
"disabled": 0
}
)
if not variant_results: if not variant_results:
frappe.msgprint(_("There isn't any item variant for the selected item")) frappe.msgprint(_("There aren't any item variants for the selected item"))
return [] return []
else: else:
variants = ", ".join([frappe.db.escape(variant['name']) for variant in variant_results]) variant_list = [variant['name'] for variant in variant_results]
order_count_map = get_open_sales_orders_map(variants) order_count_map = get_open_sales_orders_count(variant_list)
stock_details_map = get_stock_details_map(variants) stock_details_map = get_stock_details_map(variant_list)
buying_price_map = get_buying_price_map(variants) buying_price_map = get_buying_price_map(variant_list)
selling_price_map = get_selling_price_map(variants) selling_price_map = get_selling_price_map(variant_list)
attr_val_map = get_attribute_values_map(variants) attr_val_map = get_attribute_values_map(variant_list)
attribute_list = [d[0] for d in frappe.db.sql("""select attribute attributes = frappe.db.get_all(
from `tabItem Variant Attribute` "Item Variant Attribute",
where parent in ({variants}) group by attribute""".format(variants=variants))] fields=["attribute"],
filters={
"parent": ["in", variant_list]
},
group_by="attribute"
)
attribute_list = [row.get("attribute") for row in attributes]
# Prepare dicts # Prepare dicts
variant_dicts = [{"variant_name": d['name']} for d in variant_results] variant_dicts = [{"variant_name": d['name']} for d in variant_results]
for item_dict in variant_dicts: for item_dict in variant_dicts:
name = item_dict["variant_name"] name = item_dict.get("variant_name")
for d in attribute_list: for attribute in attribute_list:
attr_dict = attr_val_map[name] attr_dict = attr_val_map.get(name)
if attr_dict and attr_dict.get(d): if attr_dict and attr_dict.get(attribute):
item_dict[d] = attr_val_map[name][d] item_dict[frappe.scrub(attribute)] = attr_val_map.get(name).get(attribute)
item_dict["Open Orders"] = order_count_map.get(name) or 0 item_dict["open_orders"] = order_count_map.get(name) or 0
if stock_details_map.get(name): if stock_details_map.get(name):
item_dict["Inventory"] = stock_details_map.get(name)["Inventory"] or 0 item_dict["current_stock"] = stock_details_map.get(name)["Inventory"] or 0
item_dict["In Production"] = stock_details_map.get(name)["In Production"] or 0 item_dict["in_production"] = stock_details_map.get(name)["In Production"] or 0
item_dict["Available Selling"] = stock_details_map.get(name)["Available Selling"] or 0
else: else:
item_dict["Inventory"] = item_dict["In Production"] = item_dict["Available Selling"] = 0 item_dict["current_stock"] = item_dict["in_production"] = 0
item_dict["Avg. Buying Price List Rate"] = buying_price_map.get(name) or 0 item_dict["avg_buying_price_list_rate"] = buying_price_map.get(name) or 0
item_dict["Avg. Selling Price List Rate"] = selling_price_map.get(name) or 0 item_dict["avg_selling_price_list_rate"] = selling_price_map.get(name) or 0
item_dicts.append(item_dict) item_dicts.append(item_dict)
@ -71,117 +82,158 @@ def get_columns(item):
item_doc = frappe.get_doc("Item", item) item_doc = frappe.get_doc("Item", item)
for d in item_doc.attributes: for entry in item_doc.attributes:
columns.append(d.attribute + ":Data:100") columns.append({
"fieldname": frappe.scrub(entry.attribute),
"label": entry.attribute,
"fieldtype": "Data",
"width": 100
})
columns += [_("Avg. Buying Price List Rate") + ":Currency:110", _("Avg. Selling Price List Rate") + ":Currency:110", additional_columns = [
_("Inventory") + ":Float:100", _("In Production") + ":Float:100", {
_("Open Orders") + ":Float:100", _("Available Selling") + ":Float:100" "fieldname": "avg_buying_price_list_rate",
"label": _("Avg. Buying Price List Rate"),
"fieldtype": "Currency",
"width": 150
},
{
"fieldname": "avg_selling_price_list_rate",
"label": _("Avg. Selling Price List Rate"),
"fieldtype": "Currency",
"width": 150
},
{
"fieldname": "current_stock",
"label": _("Current Stock"),
"fieldtype": "Float",
"width": 120
},
{
"fieldname": "in_production",
"label": _("In Production"),
"fieldtype": "Float",
"width": 150
},
{
"fieldname": "open_orders",
"label": _("Open Sales Orders"),
"fieldtype": "Float",
"width": 150
}
] ]
columns.extend(additional_columns)
return columns return columns
def get_open_sales_orders_map(variants): def get_open_sales_orders_count(variants_list):
open_sales_orders = frappe.db.sql(""" open_sales_orders = frappe.db.get_list(
select "Sales Order",
count(*) as count, fields=[
item_code "name",
from "`tabSales Order Item`.item_code"
`tabSales Order Item` ],
where filters=[
docstatus = 1 and ["Sales Order", "docstatus", "=", 1],
qty > ifnull(delivered_qty, 0) and ["Sales Order Item", "item_code", "in", variants_list]
item_code in ({variants}) ],
group by distinct=1
item_code )
""".format(variants=variants), as_dict=1)
order_count_map = {} order_count_map = {}
for d in open_sales_orders: for row in open_sales_orders:
order_count_map[d["item_code"]] = d["count"] item_code = row.get("item_code")
if order_count_map.get(item_code) is None:
order_count_map[item_code] = 1
else:
order_count_map[item_code] += 1
return order_count_map return order_count_map
def get_stock_details_map(variants): def get_stock_details_map(variant_list):
stock_details = frappe.db.sql(""" stock_details = frappe.db.get_all(
select "Bin",
sum(planned_qty) as planned_qty, fields=[
sum(actual_qty) as actual_qty, "sum(planned_qty) as planned_qty",
sum(projected_qty) as projected_qty, "sum(actual_qty) as actual_qty",
item_code "sum(projected_qty) as projected_qty",
from "item_code",
`tabBin` ],
where filters={
item_code in ({variants}) "item_code": ["in", variant_list]
group by },
item_code group_by="item_code"
""".format(variants=variants), as_dict=1) )
stock_details_map = {} stock_details_map = {}
for d in stock_details: for row in stock_details:
name = d["item_code"] name = row.get("item_code")
stock_details_map[name] = { stock_details_map[name] = {
"Inventory" :d["actual_qty"], "Inventory": row.get("actual_qty"),
"In Production" :d["planned_qty"], "In Production": row.get("planned_qty")
"Available Selling" :d["projected_qty"]
} }
return stock_details_map return stock_details_map
def get_buying_price_map(variants): def get_buying_price_map(variant_list):
buying = frappe.db.sql(""" buying = frappe.db.get_all(
select "Item Price",
avg(price_list_rate) as avg_rate, fields=[
item_code "avg(price_list_rate) as avg_rate",
from "item_code",
`tabItem Price` ],
where filters={
item_code in ({variants}) and buying=1 "item_code": ["in", variant_list],
group by "buying": 1
item_code },
""".format(variants=variants), as_dict=1) group_by="item_code"
)
buying_price_map = {} buying_price_map = {}
for d in buying: for row in buying:
buying_price_map[d["item_code"]] = d["avg_rate"] buying_price_map[row.get("item_code")] = row.get("avg_rate")
return buying_price_map return buying_price_map
def get_selling_price_map(variants): def get_selling_price_map(variant_list):
selling = frappe.db.sql(""" selling = frappe.db.get_all(
select "Item Price",
avg(price_list_rate) as avg_rate, fields=[
item_code "avg(price_list_rate) as avg_rate",
from "item_code",
`tabItem Price` ],
where filters={
item_code in ({variants}) and selling=1 "item_code": ["in", variant_list],
group by "selling": 1
item_code },
""".format(variants=variants), as_dict=1) group_by="item_code"
)
selling_price_map = {} selling_price_map = {}
for d in selling: for row in selling:
selling_price_map[d["item_code"]] = d["avg_rate"] selling_price_map[row.get("item_code")] = row.get("avg_rate")
return selling_price_map return selling_price_map
def get_attribute_values_map(variants): def get_attribute_values_map(variant_list):
list_attr = frappe.db.sql(""" attribute_list = frappe.db.get_all(
select "Item Variant Attribute",
attribute, attribute_value, parent fields=[
from "attribute",
`tabItem Variant Attribute` "attribute_value",
where "parent"
parent in ({variants}) ],
""".format(variants=variants), as_dict=1) filters={
"parent": ["in", variant_list]
}
)
attr_val_map = {} attr_val_map = {}
for d in list_attr: for row in attribute_list:
name = d["parent"] name = row.get("parent")
if not attr_val_map.get(name): if not attr_val_map.get(name):
attr_val_map[name] = {} attr_val_map[name] = {}
attr_val_map[name][d["attribute"]] = d["attribute_value"] attr_val_map[name][row.get("attribute")] = row.get("attribute_value")
return attr_val_map return attr_val_map