Add vehicle repair automation in DirectorWorker: Implement functionality to automatically repair vehicles based on their condition and region. Update SQL queries to support vehicle selection and repair operations, enhancing the Director's capabilities in managing vehicle maintenance.
This commit is contained in:
@@ -35,15 +35,20 @@ use crate::worker::sql::{
|
||||
QUERY_GET_USER_OFFICES,
|
||||
QUERY_CUMULATIVE_TAX_NO_EXEMPT,
|
||||
QUERY_CUMULATIVE_TAX_WITH_EXEMPT,
|
||||
QUERY_GET_VEHICLES_TO_REPAIR_IN_REGION,
|
||||
QUERY_REPAIR_VEHICLE,
|
||||
};
|
||||
use crate::worker::publish_update_status;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Director {
|
||||
id: i32,
|
||||
branch_id: i32,
|
||||
falukant_user_id: i32,
|
||||
may_produce: bool,
|
||||
may_sell: bool,
|
||||
may_start_transport: bool,
|
||||
may_repair_vehicles: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -157,6 +162,14 @@ impl DirectorWorker {
|
||||
}
|
||||
|
||||
for director in directors {
|
||||
if director.may_repair_vehicles {
|
||||
if let Err(err) = self.repair_vehicles(&director) {
|
||||
eprintln!(
|
||||
"[DirectorWorker] Fehler bei repair_vehicles für Director {}: {err}",
|
||||
director.id
|
||||
);
|
||||
}
|
||||
}
|
||||
if director.may_produce {
|
||||
eprintln!(
|
||||
"[DirectorWorker] Starte Produktionsprüfung für Director {} (branch_id={})",
|
||||
@@ -192,15 +205,106 @@ impl DirectorWorker {
|
||||
Some(Director {
|
||||
id: row.get("id")?.parse().ok()?,
|
||||
branch_id: row.get("branch_id")?.parse().ok()?,
|
||||
falukant_user_id: row.get("falukant_user_id")?.parse().ok()?,
|
||||
may_produce: row.get("may_produce").map(|v| v == "t" || v == "true").unwrap_or(false),
|
||||
may_sell: row.get("may_sell").map(|v| v == "t" || v == "true").unwrap_or(false),
|
||||
may_start_transport: row
|
||||
.get("may_start_transport")
|
||||
.map(|v| v == "t" || v == "true")
|
||||
.unwrap_or(false),
|
||||
may_repair_vehicles: row
|
||||
.get("may_repair_vehicles")
|
||||
.map(|v| v == "t" || v == "true")
|
||||
.unwrap_or(false),
|
||||
})
|
||||
}
|
||||
|
||||
fn repair_vehicles(&mut self, director: &Director) -> Result<(), DbError> {
|
||||
self.base
|
||||
.set_current_step("DirectorWorker: repair_vehicles");
|
||||
|
||||
let mut conn = self
|
||||
.base
|
||||
.pool
|
||||
.get()
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
// Region des Directors/Branches bestimmen
|
||||
conn.prepare("get_branch_region_for_repair", QUERY_GET_BRANCH_REGION)?;
|
||||
let rows = conn.execute("get_branch_region_for_repair", &[&director.branch_id])?;
|
||||
let region_id: i32 = rows
|
||||
.first()
|
||||
.and_then(|r| r.get("region_id"))
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(-1);
|
||||
if region_id < 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
conn.prepare(
|
||||
"get_vehicles_to_repair",
|
||||
QUERY_GET_VEHICLES_TO_REPAIR_IN_REGION,
|
||||
)?;
|
||||
conn.prepare("repair_vehicle", QUERY_REPAIR_VEHICLE)?;
|
||||
|
||||
let candidates =
|
||||
conn.execute("get_vehicles_to_repair", &[&director.falukant_user_id, ®ion_id])?;
|
||||
if candidates.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut repaired = 0usize;
|
||||
for row in candidates {
|
||||
let vehicle_id = row
|
||||
.get("vehicle_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(-1);
|
||||
let condition = row
|
||||
.get("condition")
|
||||
.and_then(|v| v.parse::<f64>().ok())
|
||||
.unwrap_or(100.0);
|
||||
let type_cost = row
|
||||
.get("cost")
|
||||
.and_then(|v| v.parse::<f64>().ok())
|
||||
.unwrap_or(0.0);
|
||||
|
||||
if vehicle_id < 0 || type_cost <= 0.0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// repairCost = round(type.cost * 0.8 * (100 - condition) / 100)
|
||||
let repair_cost = (type_cost * 0.8 * (100.0 - condition) / 100.0).round();
|
||||
if repair_cost <= 0.0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Preconditions (wie Backend):
|
||||
// - sufficientFunds: wir versuchen abzubuchen und überspringen bei Fehler
|
||||
if let Err(_err) = self.base.change_falukant_user_money(
|
||||
director.falukant_user_id,
|
||||
-repair_cost,
|
||||
&format!("repair vehicle {}", vehicle_id),
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fahrzeug auf 100 setzen + available_from in Zukunft (build_time_minutes)
|
||||
let _ = conn.execute("repair_vehicle", &[&vehicle_id])?;
|
||||
repaired += 1;
|
||||
}
|
||||
|
||||
if repaired > 0 {
|
||||
eprintln!(
|
||||
"[DirectorWorker] {} Fahrzeug(e) automatisch zur Reparatur gestartet (director_id={}, region_id={})",
|
||||
repaired, director.id, region_id
|
||||
);
|
||||
// Frontend: Branches/Status neu laden
|
||||
publish_update_status(&self.base.broker, director.falukant_user_id);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_productions(&mut self, director: &Director) -> Result<(), DbError> {
|
||||
self.base
|
||||
.set_current_step("DirectorWorker: start_productions");
|
||||
|
||||
@@ -72,7 +72,14 @@ SELECT sell_cost, sell_cost AS original_sell_cost FROM falukant_type.product WHE
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_DIRECTORS: &str = r#"
|
||||
SELECT d.may_produce, d.may_sell, d.may_start_transport, b.id AS branch_id, fu.id AS falukantUserId, d.id
|
||||
SELECT
|
||||
d.may_produce,
|
||||
d.may_sell,
|
||||
d.may_start_transport,
|
||||
d.may_repair_vehicles,
|
||||
b.id AS branch_id,
|
||||
fu.id AS falukant_user_id,
|
||||
d.id
|
||||
FROM falukant_data.director d
|
||||
JOIN falukant_data.falukant_user fu ON fu.id = d.employer_user_id
|
||||
JOIN falukant_data.character c ON c.id = d.director_character_id
|
||||
@@ -80,6 +87,40 @@ JOIN falukant_data.branch b ON b.region_id = c.region_id AND b.falukant_user_id
|
||||
WHERE current_time BETWEEN '08:00:00' AND '17:00:00';
|
||||
"#;
|
||||
|
||||
// Director: vehicle repair automation
|
||||
pub const QUERY_GET_VEHICLES_TO_REPAIR_IN_REGION: &str = r#"
|
||||
SELECT
|
||||
v.id AS vehicle_id,
|
||||
v.condition,
|
||||
vt.cost,
|
||||
COALESCE(vt.build_time_minutes, 0) AS build_time_minutes
|
||||
FROM falukant_data.vehicle v
|
||||
JOIN falukant_type.vehicle vt ON vt.id = v.vehicle_type_id
|
||||
WHERE v.falukant_user_id = $1
|
||||
AND v.region_id = $2
|
||||
AND v.condition < 10
|
||||
AND v.condition < 100
|
||||
AND v.available_from <= NOW()
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM falukant_data.transport t WHERE t.vehicle_id = v.id
|
||||
)
|
||||
ORDER BY v.condition ASC, v.id ASC;
|
||||
"#;
|
||||
|
||||
pub const QUERY_REPAIR_VEHICLE: &str = r#"
|
||||
UPDATE falukant_data.vehicle v
|
||||
SET condition = 100,
|
||||
available_from = NOW() + (COALESCE(vt.build_time_minutes, 0) * INTERVAL '1 minute'),
|
||||
updated_at = NOW()
|
||||
FROM falukant_type.vehicle vt
|
||||
WHERE vt.id = v.vehicle_type_id
|
||||
AND v.id = $1
|
||||
AND v.condition < 100
|
||||
AND v.available_from <= NOW()
|
||||
AND NOT EXISTS (SELECT 1 FROM falukant_data.transport t WHERE t.vehicle_id = v.id)
|
||||
RETURNING v.id AS vehicle_id, v.available_from, COALESCE(vt.build_time_minutes, 0) AS build_time_minutes;
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_BEST_PRODUCTION: &str = r#"
|
||||
SELECT fdu.id falukant_user_id, CAST(fdu.money AS text) AS money, fdu.certificate, ftp.id product_id, ftp.label_tr, fdb.region_id,
|
||||
(SELECT SUM(quantity) FROM falukant_data.stock fds WHERE fds.branch_id = fdb.id) AS stock_size,
|
||||
|
||||
Reference in New Issue
Block a user