Merge branch 'version-13-hotfix' into backport/v13-h/32304

This commit is contained in:
Sagar Sharma
2022-09-22 01:32:20 +05:30
committed by GitHub
2 changed files with 97 additions and 107 deletions

View File

@@ -5,6 +5,7 @@ from typing import Dict, List, Tuple
import frappe import frappe
from frappe import _ from frappe import _
from frappe.query_builder.functions import Sum
Filters = frappe._dict Filters = frappe._dict
Row = frappe._dict Row = frappe._dict
@@ -14,15 +15,50 @@ QueryArgs = Dict[str, str]
def execute(filters: Filters) -> Tuple[Columns, Data]: def execute(filters: Filters) -> Tuple[Columns, Data]:
filters = frappe._dict(filters or {})
columns = get_columns() columns = get_columns()
data = get_data(filters) data = get_data(filters)
return columns, data return columns, data
def get_data(filters: Filters) -> Data: def get_data(filters: Filters) -> Data:
query_args = get_query_args(filters) wo = frappe.qb.DocType("Work Order")
data = run_query(query_args) se = frappe.qb.DocType("Stock Entry")
query = (
frappe.qb.from_(wo)
.inner_join(se)
.on(wo.name == se.work_order)
.select(
wo.name,
wo.status,
wo.production_item,
wo.qty,
wo.produced_qty,
wo.process_loss_qty,
(wo.produced_qty - wo.process_loss_qty).as_("actual_produced_qty"),
Sum(se.total_incoming_value).as_("total_fg_value"),
Sum(se.total_outgoing_value).as_("total_rm_value"),
)
.where(
(wo.process_loss_qty > 0)
& (wo.company == filters.company)
& (se.docstatus == 1)
& (se.posting_date.between(filters.from_date, filters.to_date))
)
.groupby(se.work_order)
)
if "item" in filters:
query.where(wo.production_item == filters.item)
if "work_order" in filters:
query.where(wo.name == filters.work_order)
data = query.run(as_dict=True)
update_data_with_total_pl_value(data) update_data_with_total_pl_value(data)
return data return data
@@ -67,54 +103,7 @@ def get_columns() -> Columns:
] ]
def get_query_args(filters: Filters) -> QueryArgs:
query_args = {}
query_args.update(filters)
query_args.update(get_filter_conditions(filters))
return query_args
def run_query(query_args: QueryArgs) -> Data:
return frappe.db.sql(
"""
SELECT
wo.name, wo.status, wo.production_item, wo.qty,
wo.produced_qty, wo.process_loss_qty,
(wo.produced_qty - wo.process_loss_qty) as actual_produced_qty,
sum(se.total_incoming_value) as total_fg_value,
sum(se.total_outgoing_value) as total_rm_value
FROM
`tabWork Order` wo INNER JOIN `tabStock Entry` se
ON wo.name=se.work_order
WHERE
process_loss_qty > 0
AND wo.company = %(company)s
AND se.docstatus = 1
AND se.posting_date BETWEEN %(from_date)s AND %(to_date)s
{item_filter}
{work_order_filter}
GROUP BY
se.work_order
""".format(
**query_args
),
query_args,
as_dict=1,
)
def update_data_with_total_pl_value(data: Data) -> None: def update_data_with_total_pl_value(data: Data) -> None:
for row in data: for row in data:
value_per_unit_fg = row["total_fg_value"] / row["actual_produced_qty"] value_per_unit_fg = row["total_fg_value"] / row["actual_produced_qty"]
row["total_pl_value"] = row["process_loss_qty"] * value_per_unit_fg row["total_pl_value"] = row["process_loss_qty"] * value_per_unit_fg
def get_filter_conditions(filters: Filters) -> QueryArgs:
filter_conditions = dict(item_filter="", work_order_filter="")
if "item" in filters:
production_item = filters.get("item")
filter_conditions.update({"item_filter": f"AND wo.production_item='{production_item}'"})
if "work_order" in filters:
work_order_name = filters.get("work_order")
filter_conditions.update({"work_order_filter": f"AND wo.name='{work_order_name}'"})
return filter_conditions

View File

@@ -3,6 +3,7 @@
import frappe import frappe
from frappe.query_builder.functions import IfNull
from frappe.utils import cint from frappe.utils import cint
@@ -16,6 +17,11 @@ def execute(filters=None):
def get_item_list(wo_list, filters): def get_item_list(wo_list, filters):
out = [] out = []
if wo_list:
bin = frappe.qb.DocType("Bin")
bom = frappe.qb.DocType("BOM")
bom_item = frappe.qb.DocType("BOM Item")
# Add a row for each item/qty # Add a row for each item/qty
for wo_details in wo_list: for wo_details in wo_list:
desc = frappe.db.get_value("BOM", wo_details.bom_no, "description") desc = frappe.db.get_value("BOM", wo_details.bom_no, "description")
@@ -23,30 +29,25 @@ def get_item_list(wo_list, filters):
for wo_item_details in frappe.db.get_values( for wo_item_details in frappe.db.get_values(
"Work Order Item", {"parent": wo_details.name}, ["item_code", "source_warehouse"], as_dict=1 "Work Order Item", {"parent": wo_details.name}, ["item_code", "source_warehouse"], as_dict=1
): ):
item_list = (
item_list = frappe.db.sql( frappe.qb.from_(bom)
"""SELECT .from_(bom_item)
bom_item.item_code as item_code, .left_join(bin)
ifnull(ledger.actual_qty*bom.quantity/bom_item.stock_qty,0) as build_qty .on(
FROM (bom_item.item_code == bin.item_code)
`tabBOM` as bom, `tabBOM Item` AS bom_item & (bin.warehouse == IfNull(wo_item_details.source_warehouse, filters.warehouse))
LEFT JOIN `tabBin` AS ledger
ON bom_item.item_code = ledger.item_code
AND ledger.warehouse = ifnull(%(warehouse)s,%(filterhouse)s)
WHERE
bom.name = bom_item.parent
and bom_item.item_code = %(item_code)s
and bom.name = %(bom)s
GROUP BY
bom_item.item_code""",
{
"bom": wo_details.bom_no,
"warehouse": wo_item_details.source_warehouse,
"filterhouse": filters.warehouse,
"item_code": wo_item_details.item_code,
},
as_dict=1,
) )
.select(
bom_item.item_code.as_("item_code"),
IfNull(bin.actual_qty * bom.quantity / bom_item.stock_qty, 0).as_("build_qty"),
)
.where(
(bom.name == bom_item.parent)
& (bom_item.item_code == wo_item_details.item_code)
& (bom.name == wo_details.bom_no)
)
.groupby(bom_item.item_code)
).run(as_dict=1)
stock_qty = 0 stock_qty = 0
count = 0 count = 0