Refactor production cost handling in DirectorWorker: Update create_single_production to return production costs instead of void, enabling aggregated cost calculations. Implement bundled money deductions for productions initiated by the director, enhancing financial accuracy and efficiency in production management.

This commit is contained in:
Torsten Schulz (local)
2026-03-23 14:10:16 +01:00
parent 195bf49d14
commit c5e78cb87f

View File

@@ -214,7 +214,9 @@ impl DirectorWorker {
conn.prepare("get_branch_capacity", QUERY_GET_BRANCH_CAPACITY)?;
// Schleife: Starte Produktionen, bis entweder die maximale Anzahl erreicht ist
// oder kein freier Lagerplatz mehr vorhanden ist
// oder kein freier Lagerplatz mehr vorhanden ist.
// Geldabbuchung gebündelt: eine money_history-Zeile pro Director-Tick statt pro gestarteter Linie.
let mut total_production_cost: f64 = 0.0;
loop {
// Aktuelle Kapazitätswerte abfragen
let capacity_rows = conn.execute("get_branch_capacity", &[&director.branch_id])?;
@@ -257,12 +259,24 @@ impl DirectorWorker {
base_plan.running_productions = running_productions;
base_plan.running_productions_quantity = running_productions_quantity;
// Eine neue Produktion starten (max. 100 Stück)
if self.create_single_production(&mut conn, &base_plan).is_err() {
break;
match self.create_single_production(&mut conn, &base_plan) {
Ok(cost) if cost > 0.0 => {
total_production_cost += cost;
}
Ok(_) => break,
Err(_) => break,
}
}
if total_production_cost > 0.0 {
let rounded = (total_production_cost * 100.0).round() / 100.0;
let _ = self.base.change_falukant_user_money(
base_plan.falukant_user_id,
-rounded,
"director starts production",
);
}
Ok(())
}
@@ -318,15 +332,17 @@ impl DirectorWorker {
/// Die äußere Schleife in `start_productions` sorgt dafür, dass mehrere Produktionen
/// gestartet werden können, bis entweder die maximale Anzahl erreicht ist oder
/// kein freier Lagerplatz mehr vorhanden ist.
/// Legt eine Produktionslinie an. Geld wird in [`start_productions`] gebündelt abgebucht.
/// Rückgabe: Kosten dieser Linie, oder `0.0` wenn nichts gestartet wurde.
fn create_single_production(
&mut self,
conn: &mut DbConnection,
plan: &ProductionPlan,
) -> Result<(), DbError> {
) -> Result<f64, DbError> {
// Hole aktuelle Kapazitätswerte direkt aus der DB, um Race Conditions zu vermeiden
let capacity_rows = conn.execute("get_branch_capacity", &[&plan.branch_id])?;
if capacity_rows.is_empty() {
return Ok(());
return Ok(0.0);
}
let row = &capacity_rows[0];
@@ -347,7 +363,7 @@ impl DirectorWorker {
let free_capacity = stock_size - used_in_stock - running_productions_quantity;
if free_capacity <= 0 {
return Ok(());
return Ok(0.0);
}
let one_piece_cost = Self::calc_one_piece_cost(plan);
@@ -356,17 +372,11 @@ impl DirectorWorker {
let to_produce = (free_capacity.min(max_money_production)).clamp(0, 100);
if to_produce < 1 {
return Ok(());
return Ok(0.0);
}
let production_cost = to_produce as f64 * one_piece_cost;
let _ = self.base.change_falukant_user_money(
plan.falukant_user_id,
-production_cost,
"director starts production",
);
conn.prepare("insert_production", QUERY_INSERT_PRODUCTION)?;
// Eine einzelne Produktion mit max. 100 Stück anlegen
@@ -382,7 +392,7 @@ impl DirectorWorker {
);
self.base.broker.publish(message);
Ok(())
Ok(production_cost)
}