fix: cost of poor quality report time filters not working (#28958)
* fix: cost of poor quality report time filters not working * chore:update cost of poor quality report to use query builder * fix: linter warnings * chore: updated report query * chore: added test filters * fix : cleared linter warnings * chore: formatting * refactor: query generation - optionally apply date filters - join instead of expensive sub-query - return as dictionary * test: simplify test Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
parent
b818b93568
commit
0f7c2a19de
@ -17,14 +17,12 @@ frappe.query_reports["Cost of Poor Quality Report"] = {
|
|||||||
fieldname:"from_date",
|
fieldname:"from_date",
|
||||||
fieldtype: "Datetime",
|
fieldtype: "Datetime",
|
||||||
default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
|
default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
|
||||||
reqd: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __("To Date"),
|
label: __("To Date"),
|
||||||
fieldname:"to_date",
|
fieldname:"to_date",
|
||||||
fieldtype: "Datetime",
|
fieldtype: "Datetime",
|
||||||
default: frappe.datetime.now_datetime(),
|
default: frappe.datetime.now_datetime(),
|
||||||
reqd: 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __("Job Card"),
|
label: __("Job Card"),
|
||||||
|
@ -3,46 +3,65 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt
|
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns, data = [], []
|
return get_columns(filters), get_data(filters)
|
||||||
|
|
||||||
columns = get_columns(filters)
|
|
||||||
data = get_data(filters)
|
|
||||||
|
|
||||||
return columns, data
|
|
||||||
|
|
||||||
def get_data(report_filters):
|
def get_data(report_filters):
|
||||||
data = []
|
data = []
|
||||||
operations = frappe.get_all("Operation", filters = {"is_corrective_operation": 1})
|
operations = frappe.get_all("Operation", filters = {"is_corrective_operation": 1})
|
||||||
if operations:
|
if operations:
|
||||||
operations = [d.name for d in operations]
|
if report_filters.get('operation'):
|
||||||
fields = ["production_item as item_code", "item_name", "work_order", "operation",
|
operations = [report_filters.get('operation')]
|
||||||
"workstation", "total_time_in_mins", "name", "hour_rate", "serial_no", "batch_no"]
|
else:
|
||||||
|
operations = [d.name for d in operations]
|
||||||
|
|
||||||
filters = get_filters(report_filters, operations)
|
job_card = frappe.qb.DocType("Job Card")
|
||||||
|
|
||||||
job_cards = frappe.get_all("Job Card", fields = fields,
|
operating_cost = ((job_card.hour_rate) * (job_card.total_time_in_mins) / 60.0).as_('operating_cost')
|
||||||
filters = filters)
|
item_code = (job_card.production_item).as_('item_code')
|
||||||
|
|
||||||
for row in job_cards:
|
query = (frappe.qb
|
||||||
row.operating_cost = flt(row.hour_rate) * (flt(row.total_time_in_mins) / 60.0)
|
.from_(job_card)
|
||||||
data.append(row)
|
.select(job_card.name, job_card.work_order, item_code, job_card.item_name,
|
||||||
|
job_card.operation, job_card.serial_no, job_card.batch_no,
|
||||||
|
job_card.workstation, job_card.total_time_in_mins, job_card.hour_rate,
|
||||||
|
operating_cost)
|
||||||
|
.where(
|
||||||
|
(job_card.docstatus == 1)
|
||||||
|
& (job_card.is_corrective_job_card == 1))
|
||||||
|
.groupby(job_card.name)
|
||||||
|
)
|
||||||
|
|
||||||
|
query = append_filters(query, report_filters, operations, job_card)
|
||||||
|
data = query.run(as_dict=True)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_filters(report_filters, operations):
|
def append_filters(query, report_filters, operations, job_card):
|
||||||
filters = {"docstatus": 1, "operation": ("in", operations), "is_corrective_job_card": 1}
|
"""Append optional filters to query builder. """
|
||||||
for field in ["name", "work_order", "operation", "workstation", "company", "serial_no", "batch_no", "production_item"]:
|
|
||||||
if report_filters.get(field):
|
|
||||||
if field != 'serial_no':
|
|
||||||
filters[field] = report_filters.get(field)
|
|
||||||
else:
|
|
||||||
filters[field] = ('like', '% {} %'.format(report_filters.get(field)))
|
|
||||||
|
|
||||||
return filters
|
for field in ("name", "work_order", "operation", "workstation",
|
||||||
|
"company", "serial_no", "batch_no", "production_item"):
|
||||||
|
if report_filters.get(field):
|
||||||
|
if field == 'serial_no':
|
||||||
|
query = query.where(job_card[field].like('%{}%'.format(report_filters.get(field))))
|
||||||
|
elif field == 'operation':
|
||||||
|
query = query.where(job_card[field].isin(operations))
|
||||||
|
else:
|
||||||
|
query = query.where(job_card[field] == report_filters.get(field))
|
||||||
|
|
||||||
|
if report_filters.get('from_date') or report_filters.get('to_date'):
|
||||||
|
job_card_time_log = frappe.qb.DocType("Job Card Time Log")
|
||||||
|
|
||||||
|
query = query.join(job_card_time_log).on(job_card.name == job_card_time_log.parent)
|
||||||
|
if report_filters.get('from_date'):
|
||||||
|
query = query.where(job_card_time_log.from_time >= report_filters.get('from_date'))
|
||||||
|
if report_filters.get('to_date'):
|
||||||
|
query = query.where(job_card_time_log.to_time <= report_filters.get('to_date'))
|
||||||
|
|
||||||
|
return query
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
return [
|
return [
|
||||||
|
@ -18,7 +18,7 @@ REPORT_FILTER_TEST_CASES: List[Tuple[ReportName, ReportFilters]] = [
|
|||||||
("BOM Operations Time", {}),
|
("BOM Operations Time", {}),
|
||||||
("BOM Stock Calculated", {"bom": frappe.get_last_doc("BOM").name, "qty_to_make": 2}),
|
("BOM Stock Calculated", {"bom": frappe.get_last_doc("BOM").name, "qty_to_make": 2}),
|
||||||
("BOM Stock Report", {"bom": frappe.get_last_doc("BOM").name, "qty_to_produce": 2}),
|
("BOM Stock Report", {"bom": frappe.get_last_doc("BOM").name, "qty_to_produce": 2}),
|
||||||
("Cost of Poor Quality Report", {}),
|
("Cost of Poor Quality Report", {"item": "_Test Item", "serial_no": "00"}),
|
||||||
("Downtime Analysis", {}),
|
("Downtime Analysis", {}),
|
||||||
(
|
(
|
||||||
"Exponential Smoothing Forecasting",
|
"Exponential Smoothing Forecasting",
|
||||||
|
Loading…
Reference in New Issue
Block a user