///|
pub struct QualityWorkOrder {
order_id : String
lot_id : String
title : String
owner : String
priority : Int
due_day : Int
status : String
estimated_hours : Double
actual_hours : Double
evidence_count : Int
} derive(Debug, ToJson)
///|
pub fn quality_work_order(
order_id~ : String,
lot_id~ : String,
title~ : String,
owner~ : String,
priority~ : Int,
due_day~ : Int,
estimated_hours~ : Double,
) -> QualityWorkOrder {
{
order_id,
lot_id,
title,
owner,
priority: priority.max(1).min(5),
due_day,
status: "open",
estimated_hours,
actual_hours: 0.0,
evidence_count: 0,
}
}
///|
pub fn start_work_order(order : QualityWorkOrder) -> QualityWorkOrder {
{ ..order, status: "in_progress" }
}
///|
pub fn complete_work_order(
order : QualityWorkOrder,
actual_hours : Double,
evidence_count : Int,
) -> QualityWorkOrder {
{ ..order, status: "completed", actual_hours, evidence_count }
}
///|
pub fn block_work_order(order : QualityWorkOrder) -> QualityWorkOrder {
{ ..order, status: "blocked" }
}
///|
pub fn work_order_is_overdue(
order : QualityWorkOrder,
current_day : Int,
) -> Bool {
order.status != "completed" && current_day > order.due_day
}
///|
pub fn work_order_efficiency(order : QualityWorkOrder) -> Double {
if order.actual_hours <= 0.0 {
0.0
} else {
order.estimated_hours / order.actual_hours
}
}
///|
pub fn work_order_score(order : QualityWorkOrder, current_day : Int) -> Double {
let urgency = if order.due_day - current_day <= 0 {
2.0
} else {
1.0 / (order.due_day - current_day).to_double()
}
order.priority.to_double() * urgency
}
///|
pub fn sort_work_orders(
orders : Array[QualityWorkOrder],
current_day : Int,
) -> Array[QualityWorkOrder] {
let result = orders.copy()
result.sort_by(fn(a, b) {
if work_order_score(a, current_day) > work_order_score(b, current_day) {
-1
} else {
1
}
})
result
}
///|
pub fn open_work_order_count(orders : Array[QualityWorkOrder]) -> Int {
let mut count = 0
for order in orders {
if order.status != "completed" {
count += 1
}
}
count
}
///|
pub fn overdue_work_order_count(
orders : Array[QualityWorkOrder],
current_day : Int,
) -> Int {
let mut count = 0
for order in orders {
if work_order_is_overdue(order, current_day) {
count += 1
}
}
count
}
///|
pub fn completion_rate(orders : Array[QualityWorkOrder]) -> Double {
if orders.length() == 0 {
0.0
} else {
(orders.length() - open_work_order_count(orders)).to_double() /
orders.length().to_double()
}
}
///|
pub fn work_orders_for_lot(
orders : Array[QualityWorkOrder],
lot_id : String,
) -> Array[QualityWorkOrder] {
let result : Array[QualityWorkOrder] = []
for order in orders {
if order.lot_id == lot_id {
result.push(order)
}
}
result
}
///|
pub fn evidence_coverage(orders : Array[QualityWorkOrder]) -> Double {
if orders.length() == 0 {
0.0
} else {
let mut count = 0
for order in orders {
if order.evidence_count > 0 {
count += 1
}
}
count.to_double() / orders.length().to_double()
}
}