mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-12 17:23:38 +00:00
fix(manufacturing): handle None value for actual_end_date
(cherry picked from commit 16f09141da)
This commit is contained in:
@@ -8,6 +8,8 @@ from frappe.utils import getdate, today
|
|||||||
|
|
||||||
from erpnext.stock.report.stock_analytics.stock_analytics import get_period, get_period_date_ranges
|
from erpnext.stock.report.stock_analytics.stock_analytics import get_period, get_period_date_ranges
|
||||||
|
|
||||||
|
WORK_ORDER_STATUS_LIST = ["Not Started", "Overdue", "Pending", "Completed", "Closed", "Stopped"]
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
@@ -16,119 +18,97 @@ def execute(filters=None):
|
|||||||
|
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [{"label": _("Status"), "fieldname": "Status", "fieldtype": "Data", "width": 140}]
|
columns = [{"label": _("Status"), "fieldname": "status", "fieldtype": "Data", "width": 140}]
|
||||||
|
|
||||||
ranges = get_period_date_ranges(filters)
|
ranges = get_period_date_ranges(filters)
|
||||||
|
|
||||||
for _dummy, end_date in ranges:
|
for _dummy, end_date in ranges:
|
||||||
period = get_period(end_date, filters)
|
period = get_period(end_date, filters)
|
||||||
|
|
||||||
columns.append({"label": _(period), "fieldname": scrub(period), "fieldtype": "Float", "width": 120})
|
columns.append({"label": _(period), "fieldname": scrub(period), "fieldtype": "Float", "width": 120})
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
|
|
||||||
def get_periodic_data(filters, entry):
|
def get_work_orders(filters):
|
||||||
periodic_data = {
|
from_date = filters.get("from_date")
|
||||||
"Not Started": {},
|
to_date = filters.get("to_date")
|
||||||
"Overdue": {},
|
|
||||||
"Pending": {},
|
|
||||||
"Completed": {},
|
|
||||||
"Closed": {},
|
|
||||||
"Stopped": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
ranges = get_period_date_ranges(filters)
|
WorkOrder = frappe.qb.DocType("Work Order")
|
||||||
|
|
||||||
for from_date, end_date in ranges:
|
return (
|
||||||
period = get_period(end_date, filters)
|
frappe.qb.from_(WorkOrder)
|
||||||
for d in entry:
|
.select(WorkOrder.creation, WorkOrder.actual_end_date, WorkOrder.planned_end_date, WorkOrder.status)
|
||||||
if getdate(from_date) <= getdate(d.creation) <= getdate(end_date) and d.status not in [
|
.where(
|
||||||
"Draft",
|
(WorkOrder.docstatus == 1)
|
||||||
"Submitted",
|
& (WorkOrder.company == filters.get("company"))
|
||||||
"Completed",
|
& (
|
||||||
"Cancelled",
|
(WorkOrder.creation.between(from_date, to_date))
|
||||||
]:
|
| (WorkOrder.actual_end_date.between(from_date, to_date))
|
||||||
if d.status in ["Not Started", "Closed", "Stopped"]:
|
)
|
||||||
periodic_data = update_periodic_data(periodic_data, d.status, period)
|
)
|
||||||
elif getdate(today()) > getdate(d.planned_end_date):
|
.run(as_dict=True)
|
||||||
periodic_data = update_periodic_data(periodic_data, "Overdue", period)
|
)
|
||||||
elif getdate(today()) < getdate(d.planned_end_date):
|
|
||||||
periodic_data = update_periodic_data(periodic_data, "Pending", period)
|
|
||||||
|
|
||||||
if (
|
|
||||||
getdate(from_date) <= getdate(d.actual_end_date) <= getdate(end_date)
|
|
||||||
and d.status == "Completed"
|
|
||||||
):
|
|
||||||
periodic_data = update_periodic_data(periodic_data, "Completed", period)
|
|
||||||
|
|
||||||
return periodic_data
|
|
||||||
|
|
||||||
|
|
||||||
def update_periodic_data(periodic_data, status, period):
|
|
||||||
if periodic_data.get(status).get(period):
|
|
||||||
periodic_data[status][period] += 1
|
|
||||||
else:
|
|
||||||
periodic_data[status][period] = 1
|
|
||||||
|
|
||||||
return periodic_data
|
|
||||||
|
|
||||||
|
|
||||||
def get_data(filters, columns):
|
def get_data(filters, columns):
|
||||||
data = []
|
ranges = build_ranges(filters)
|
||||||
entry = frappe.get_all(
|
period_labels = [pd for _fd, _td, pd in ranges]
|
||||||
"Work Order",
|
periodic_data = {status: {pd: 0 for pd in period_labels} for status in WORK_ORDER_STATUS_LIST}
|
||||||
fields=[
|
entries = get_work_orders(filters)
|
||||||
"creation",
|
|
||||||
"actual_end_date",
|
|
||||||
"planned_end_date",
|
|
||||||
"status",
|
|
||||||
],
|
|
||||||
filters={"docstatus": 1, "company": filters["company"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
periodic_data = get_periodic_data(filters, entry)
|
for d in entries:
|
||||||
|
if d.status == "Completed":
|
||||||
|
if not d.actual_end_date:
|
||||||
|
continue
|
||||||
|
|
||||||
labels = ["Not Started", "Overdue", "Pending", "Completed", "Closed", "Stopped"]
|
if period := get_period_for_date(getdate(d.actual_end_date), ranges):
|
||||||
chart_data = get_chart_data(periodic_data, columns)
|
periodic_data["Completed"][period] += 1
|
||||||
ranges = get_period_date_ranges(filters)
|
continue
|
||||||
|
|
||||||
for label in labels:
|
creation_date = getdate(d.creation)
|
||||||
work = {}
|
period = get_period_for_date(creation_date, ranges)
|
||||||
work["Status"] = _(label)
|
if not period:
|
||||||
for _dummy, end_date in ranges:
|
continue
|
||||||
period = get_period(end_date, filters)
|
|
||||||
if periodic_data.get(label).get(period):
|
if d.status in ("Not Started", "Closed", "Stopped"):
|
||||||
work[scrub(period)] = periodic_data.get(label).get(period)
|
periodic_data[d.status][period] += 1
|
||||||
|
else:
|
||||||
|
if d.planned_end_date and getdate(today()) > getdate(d.planned_end_date):
|
||||||
|
periodic_data["Overdue"][period] += 1
|
||||||
else:
|
else:
|
||||||
work[scrub(period)] = 0.0
|
periodic_data["Pending"][period] += 1
|
||||||
data.append(work)
|
|
||||||
|
|
||||||
return data, chart_data
|
data = []
|
||||||
|
for status in WORK_ORDER_STATUS_LIST:
|
||||||
|
row = {"status": _(status)}
|
||||||
|
for _fd, _td, pd in ranges:
|
||||||
|
row[scrub(pd)] = periodic_data[status].get(pd, 0)
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
chart = get_chart_data(periodic_data, columns)
|
||||||
|
return data, chart
|
||||||
|
|
||||||
|
|
||||||
|
def get_period_for_date(date, ranges):
|
||||||
|
for from_date, to_date, period in ranges:
|
||||||
|
if from_date <= date <= to_date:
|
||||||
|
return period
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def build_ranges(filters):
|
||||||
|
ranges = []
|
||||||
|
for from_date, end_date in get_period_date_ranges(filters):
|
||||||
|
period = get_period(end_date, filters)
|
||||||
|
ranges.append((getdate(from_date), getdate(end_date), period))
|
||||||
|
return ranges
|
||||||
|
|
||||||
|
|
||||||
def get_chart_data(periodic_data, columns):
|
def get_chart_data(periodic_data, columns):
|
||||||
labels = [d.get("label") for d in columns[1:]]
|
labels = [d.get("label") for d in columns[1:]]
|
||||||
|
|
||||||
not_start, overdue, pending, completed, closed, stopped = [], [], [], [], [], []
|
|
||||||
datasets = []
|
datasets = []
|
||||||
|
for status in WORK_ORDER_STATUS_LIST:
|
||||||
|
values = [periodic_data.get(status, {}).get(label, 0) for label in labels]
|
||||||
|
datasets.append({"name": _(status), "values": values})
|
||||||
|
|
||||||
for d in labels:
|
return {"data": {"labels": labels, "datasets": datasets}, "type": "line"}
|
||||||
not_start.append(periodic_data.get("Not Started").get(d))
|
|
||||||
overdue.append(periodic_data.get("Overdue").get(d))
|
|
||||||
pending.append(periodic_data.get("Pending").get(d))
|
|
||||||
completed.append(periodic_data.get("Completed").get(d))
|
|
||||||
closed.append(periodic_data.get("Closed").get(d))
|
|
||||||
stopped.append(periodic_data.get("Stopped").get(d))
|
|
||||||
|
|
||||||
datasets.append({"name": _("Not Started"), "values": not_start})
|
|
||||||
datasets.append({"name": _("Overdue"), "values": overdue})
|
|
||||||
datasets.append({"name": _("Pending"), "values": pending})
|
|
||||||
datasets.append({"name": _("Completed"), "values": completed})
|
|
||||||
datasets.append({"name": _("Closed"), "values": closed})
|
|
||||||
datasets.append({"name": _("Stopped"), "values": stopped})
|
|
||||||
|
|
||||||
chart = {"data": {"labels": labels, "datasets": datasets}}
|
|
||||||
chart["type"] = "line"
|
|
||||||
|
|
||||||
return chart
|
|
||||||
|
|||||||
Reference in New Issue
Block a user