From c5e78cb87f0073d5d472120daebe017da4996ff0 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 23 Mar 2026 14:10:16 +0100 Subject: [PATCH] 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. --- src/worker/director.rs | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/worker/director.rs b/src/worker/director.rs index 26cae7f..822698d 100644 --- a/src/worker/director.rs +++ b/src/worker/director.rs @@ -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 { // 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) }