Add SQL query to count children by user: Introduced a new query to count distinct children associated with a user across all their characters. Updated UserCharacterWorker to utilize this new query, replacing the previous count query. This enhances user-specific data retrieval capabilities.

This commit is contained in:
Torsten Schulz (local)
2026-02-02 15:25:13 +01:00
parent 460310ae89
commit 658a9034ed
5 changed files with 35 additions and 264 deletions

View File

@@ -580,6 +580,13 @@ pub const QUERY_COUNT_CHILDREN: &str = r#"
SELECT COUNT(*) AS cnt FROM falukant_data.child_relation WHERE (father_character_id = $1 OR mother_character_id = $1) AND child_character_id != $2; SELECT COUNT(*) AS cnt FROM falukant_data.child_relation WHERE (father_character_id = $1 OR mother_character_id = $1) AND child_character_id != $2;
"#; "#;
pub const QUERY_COUNT_CHILDREN_BY_USER: &str = r#"
SELECT COUNT(DISTINCT cr.child_character_id) AS cnt
FROM falukant_data.child_relation cr
JOIN falukant_data.character parent ON (parent.id = cr.father_character_id OR parent.id = cr.mother_character_id)
WHERE parent.user_id = $1;
"#;
// user_character worker queries // user_character worker queries
pub const QUERY_GET_USERS_TO_UPDATE: &str = r#" pub const QUERY_GET_USERS_TO_UPDATE: &str = r#"
SELECT id, CURRENT_DATE - birthdate::date AS age, health SELECT id, CURRENT_DATE - birthdate::date AS age, health

View File

@@ -25,7 +25,7 @@ use crate::worker::sql::{
QUERY_GET_SETTLEMENT_VALUE, QUERY_GET_SETTLEMENT_VALUE,
QUERY_GET_INVENTORY_VALUE, QUERY_GET_INVENTORY_VALUE,
QUERY_GET_CREDIT_DEBT, QUERY_GET_CREDIT_DEBT,
QUERY_COUNT_CHILDREN, QUERY_COUNT_CHILDREN_BY_USER,
QUERY_GET_HEIR, QUERY_GET_HEIR,
QUERY_RANDOM_HEIR, QUERY_RANDOM_HEIR,
QUERY_SET_CHARACTER_USER, QUERY_SET_CHARACTER_USER,
@@ -795,8 +795,8 @@ impl UserCharacterWorker {
.get() .get()
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?; .map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
conn.prepare("count_children", QUERY_COUNT_CHILDREN)?; conn.prepare("count_children_by_user", QUERY_COUNT_CHILDREN_BY_USER)?;
let rows = conn.execute("count_children", &[&deceased_user_id])?; let rows = conn.execute("count_children_by_user", &[&deceased_user_id])?;
Ok(rows Ok(rows
.first() .first()

View File

@@ -158,29 +158,12 @@ impl DirectorWorker {
for director in directors { for director in directors {
if director.may_produce { if director.may_produce {
eprintln!(
"[DirectorWorker] Starte Produktionsprüfung für Director {} (branch_id={})",
director.id, director.branch_id
);
self.start_productions(&director)?; self.start_productions(&director)?;
} }
if director.may_start_transport { if director.may_start_transport {
eprintln!( if let Err(_) = self.start_transports_stub(&director) {}
"[DirectorWorker] Starte Transportprüfung für Director {} (branch_id={})",
director.id, director.branch_id
);
if let Err(err) = self.start_transports_stub(&director) {
eprintln!(
"[DirectorWorker] Fehler bei start_transports für Director {}: {err}",
director.id
);
}
} }
if director.may_sell { if director.may_sell {
eprintln!(
"[DirectorWorker] Starte Verkaufsprüfung für Director {} (branch_id={})",
director.id, director.branch_id
);
self.start_sellings(&director)?; self.start_sellings(&director)?;
} }
} }
@@ -215,33 +198,14 @@ impl DirectorWorker {
conn.prepare("get_to_produce", QUERY_GET_BEST_PRODUCTION)?; conn.prepare("get_to_produce", QUERY_GET_BEST_PRODUCTION)?;
let rows = conn.execute("get_to_produce", &[&director.id, &director.branch_id])?; let rows = conn.execute("get_to_produce", &[&director.id, &director.branch_id])?;
if rows.is_empty() { if rows.is_empty() {
eprintln!(
"[DirectorWorker] Keine Produktionskandidaten für Director {} gefunden.",
director.id
);
return Ok(()); return Ok(());
} }
let mut base_plan = match rows.first().and_then(Self::map_row_to_production_plan) { let mut base_plan = match rows.first().and_then(Self::map_row_to_production_plan) {
Some(p) => p, Some(p) => p,
None => { None => return Ok(()),
eprintln!(
"[DirectorWorker] Produktionsplan für Director {} konnte nicht gemappt werden.",
director.id
);
return Ok(());
}
}; };
eprintln!(
"[DirectorWorker] Produktionsplan: director_user_id={}, branch_id={}, product_id={}, money={}, certificate={}",
base_plan.falukant_user_id,
base_plan.branch_id,
base_plan.product_id,
base_plan.money,
base_plan.certificate
);
// Query zum Abfragen der aktuellen Kapazitätswerte vorbereiten // Query zum Abfragen der aktuellen Kapazitätswerte vorbereiten
conn.prepare("get_branch_capacity", QUERY_GET_BRANCH_CAPACITY)?; conn.prepare("get_branch_capacity", QUERY_GET_BRANCH_CAPACITY)?;
@@ -274,24 +238,12 @@ impl DirectorWorker {
// Prüfen, ob noch Produktionen gestartet werden können // Prüfen, ob noch Produktionen gestartet werden können
if running_productions >= MAX_PARALLEL_PRODUCTIONS { if running_productions >= MAX_PARALLEL_PRODUCTIONS {
eprintln!(
"[DirectorWorker] Maximale Anzahl an Produktionen ({}) erreicht für Branch {}.",
MAX_PARALLEL_PRODUCTIONS,
director.branch_id
);
break; break;
} }
// Freie Kapazität berechnen // Freie Kapazität berechnen
let free_capacity = stock_size - used_in_stock - running_productions_quantity; let free_capacity = stock_size - used_in_stock - running_productions_quantity;
if free_capacity <= 0 { if free_capacity <= 0 {
eprintln!(
"[DirectorWorker] Kein freier Lagerplatz mehr für Branch {} (stock_size={}, used={}, running_qty={}).",
director.branch_id,
stock_size,
used_in_stock,
running_productions_quantity
);
break; break;
} }
@@ -302,10 +254,7 @@ impl DirectorWorker {
base_plan.running_productions_quantity = running_productions_quantity; base_plan.running_productions_quantity = running_productions_quantity;
// Eine neue Produktion starten (max. 100 Stück) // Eine neue Produktion starten (max. 100 Stück)
if let Err(err) = self.create_single_production(&mut conn, &base_plan) { if self.create_single_production(&mut conn, &base_plan).is_err() {
eprintln!(
"[DirectorWorker] Fehler beim Starten einer Produktion: {err}"
);
break; break;
} }
} }
@@ -373,7 +322,6 @@ impl DirectorWorker {
// Hole aktuelle Kapazitätswerte direkt aus der DB, um Race Conditions zu vermeiden // Hole aktuelle Kapazitätswerte direkt aus der DB, um Race Conditions zu vermeiden
let capacity_rows = conn.execute("get_branch_capacity", &[&plan.branch_id])?; let capacity_rows = conn.execute("get_branch_capacity", &[&plan.branch_id])?;
if capacity_rows.is_empty() { if capacity_rows.is_empty() {
eprintln!("[DirectorWorker] Keine Kapazitätsdaten für Branch {} gefunden", plan.branch_id);
return Ok(()); return Ok(());
} }
@@ -395,10 +343,6 @@ impl DirectorWorker {
let free_capacity = stock_size - used_in_stock - running_productions_quantity; let free_capacity = stock_size - used_in_stock - running_productions_quantity;
if free_capacity <= 0 { if free_capacity <= 0 {
eprintln!(
"[DirectorWorker] Keine Produktion gestartet: Kein freier Lagerplatz (stock_size={}, used={}, running_qty={})",
stock_size, used_in_stock, running_productions_quantity
);
return Ok(()); return Ok(());
} }
@@ -407,42 +351,16 @@ impl DirectorWorker {
let to_produce = (free_capacity.min(max_money_production)).clamp(0, 100); let to_produce = (free_capacity.min(max_money_production)).clamp(0, 100);
eprintln!(
"[DirectorWorker] Produktionsberechnung: free_capacity={}, one_piece_cost={}, max_money_production={}, to_produce={}, running_productions={}",
free_capacity,
one_piece_cost,
max_money_production,
to_produce,
plan.running_productions
);
if to_produce < 1 { if to_produce < 1 {
eprintln!(
"[DirectorWorker] Keine Produktion gestartet: free_capacity={}, max_money_production={}, running_productions={}, running_qty={}",
free_capacity,
max_money_production,
plan.running_productions,
plan.running_productions_quantity
);
return Ok(()); return Ok(());
} }
let production_cost = to_produce as f64 * one_piece_cost; let production_cost = to_produce as f64 * one_piece_cost;
if let Err(err) = self.base.change_falukant_user_money( let _ = self.base.change_falukant_user_money(
plan.falukant_user_id, plan.falukant_user_id,
-production_cost, -production_cost,
"director starts production", "director starts production",
) {
eprintln!(
"[DirectorWorker] Fehler bei change_falukant_user_money: {err}"
);
}
// Debug: Log vor dem DB-Aufruf
eprintln!(
"[DirectorWorker] calling change_falukant_user_money for start production: user_id={}, money_change={}",
plan.falukant_user_id, -production_cost
); );
conn.prepare("insert_production", QUERY_INSERT_PRODUCTION)?; conn.prepare("insert_production", QUERY_INSERT_PRODUCTION)?;
@@ -454,11 +372,6 @@ impl DirectorWorker {
&[&plan.branch_id, &plan.product_id, &to_produce, &plan.region_id], &[&plan.branch_id, &plan.product_id, &to_produce, &plan.region_id],
)?; )?;
eprintln!(
"[DirectorWorker] Produktion angelegt: branch_id={}, product_id={}, quantity={}",
plan.branch_id, plan.product_id, to_produce
);
let message = format!( let message = format!(
r#"{{"event":"production_started","branch_id":{}}}"#, r#"{{"event":"production_started","branch_id":{}}}"#,
plan.branch_id plan.branch_id
@@ -478,10 +391,6 @@ impl DirectorWorker {
if plan.money > 0.0 { if plan.money > 0.0 {
(plan.money / one_piece_cost).floor() as i32 (plan.money / one_piece_cost).floor() as i32
} else { } else {
eprintln!(
"[DirectorWorker] Warnung: money=0 für falukant_user_id={}, verwende nur Lagerkapazität als Limit.",
plan.falukant_user_id
);
i32::MAX i32::MAX
} }
} else { } else {
@@ -505,11 +414,6 @@ impl DirectorWorker {
let mut items: Vec<InventoryItem> = let mut items: Vec<InventoryItem> =
rows.into_iter().filter_map(Self::map_row_to_inventory_item).collect(); rows.into_iter().filter_map(Self::map_row_to_inventory_item).collect();
eprintln!(
"[DirectorWorker] Transportprüfung für Director {} (branch_id={}): {} Inventar-Items gefunden",
director.id, director.branch_id, items.len()
);
// Für alle Items dieses Directors sollten die user_id-Felder identisch // Für alle Items dieses Directors sollten die user_id-Felder identisch
// sein (Arbeitgeber des Directors). // sein (Arbeitgeber des Directors).
let falukant_user_id = if items.is_empty() { let falukant_user_id = if items.is_empty() {
@@ -539,49 +443,23 @@ impl DirectorWorker {
.and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok())) .and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok()))
.unwrap_or(0); .unwrap_or(0);
// Falls es nichts zu transportieren gibt, prüfe auf leere Transporte
if items.is_empty() { if items.is_empty() {
eprintln!(
"[DirectorWorker] Keine Inventar-Items für Transporte gefunden für Director {} (branch_id={})",
director.id, director.branch_id
);
// Wenn keine Transportmittel im Branch vorhanden sind, versuche leere Transporte zu planen
if vehicles_in_branch == 0 { if vehicles_in_branch == 0 {
eprintln!( let _ = self.plan_empty_transports_for_vehicle_retrieval(
"[DirectorWorker] Keine Transportmittel im Branch {} vorhanden, prüfe auf leere Transporte zum Zurückholen",
director.branch_id
);
if let Err(err) = self.plan_empty_transports_for_vehicle_retrieval(
&mut conn, &mut conn,
falukant_user_id, falukant_user_id,
director.branch_id, director.branch_id,
) { );
eprintln!(
"[DirectorWorker] Fehler beim Planen leerer Transporte: {err}"
);
}
} }
return Ok(()); return Ok(());
} }
// Wenn keine Transportmittel im Branch vorhanden sind, aber Items vorhanden sind,
// versuche leere Transporte zu planen, um Fahrzeuge zurückzuholen
if vehicles_in_branch == 0 && !items.is_empty() { if vehicles_in_branch == 0 && !items.is_empty() {
eprintln!( let _ = self.plan_empty_transports_for_vehicle_retrieval(
"[DirectorWorker] Keine Transportmittel im Branch {} vorhanden, aber {} Items vorhanden. Prüfe auf leere Transporte zum Zurückholen",
director.branch_id, items.len()
);
if let Err(err) = self.plan_empty_transports_for_vehicle_retrieval(
&mut conn, &mut conn,
falukant_user_id, falukant_user_id,
director.branch_id, director.branch_id,
) { );
eprintln!(
"[DirectorWorker] Fehler beim Planen leerer Transporte: {err}"
);
}
// Nach dem Planen leerer Transporte erneut prüfen, ob jetzt Transportmittel vorhanden sind
let vehicle_count_rows_after = conn.execute( let vehicle_count_rows_after = conn.execute(
"count_vehicles_in_branch", "count_vehicles_in_branch",
&[&falukant_user_id, &director.branch_id], &[&falukant_user_id, &director.branch_id],
@@ -591,12 +469,7 @@ impl DirectorWorker {
.next() .next()
.and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok())) .and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok()))
.unwrap_or(0); .unwrap_or(0);
if vehicles_in_branch_after == 0 { if vehicles_in_branch_after == 0 {
eprintln!(
"[DirectorWorker] Nach Planen leerer Transporte immer noch keine Transportmittel im Branch {} vorhanden. Überspringe normale Transportplanung.",
director.branch_id
);
return Ok(()); return Ok(());
} }
} }
@@ -605,29 +478,11 @@ impl DirectorWorker {
// - ggf. Transport-Einträge erzeugt // - ggf. Transport-Einträge erzeugt
// - Inventar-Mengen reduziert // - Inventar-Mengen reduziert
for item in items.iter_mut() { for item in items.iter_mut() {
eprintln!( let _ = self.plan_transports_for_item(
"[DirectorWorker] Prüfe Transport für Item: product_id={}, quantity={}, quality={}, region_id={}, branch_id={}",
item.product_id, item.quantity, item.quality, item.region_id, item.branch_id
);
let shipped = self.plan_transports_for_item(
&mut conn, &mut conn,
falukant_user_id, falukant_user_id,
item, item,
)?; )?;
// Inventar wird bereits in plan_transports_for_item reduziert
if shipped > 0 {
eprintln!(
"[DirectorWorker] Transport geplant: {} Einheiten von Produkt {} transportiert (Inventar bereits reduziert)",
shipped, item.product_id
);
} else {
eprintln!(
"[DirectorWorker] Kein lohnender Transport gefunden für Produkt {} (region_id={})",
item.product_id, item.region_id
);
}
} }
// Nach normalen Transporten: Wenn keine Transportmittel mehr im Branch vorhanden sind, // Nach normalen Transporten: Wenn keine Transportmittel mehr im Branch vorhanden sind,
@@ -643,19 +498,11 @@ impl DirectorWorker {
.unwrap_or(0); .unwrap_or(0);
if vehicles_in_branch_final == 0 { if vehicles_in_branch_final == 0 {
eprintln!( let _ = self.plan_empty_transports_for_vehicle_retrieval(
"[DirectorWorker] Nach Transporten keine Transportmittel mehr im Branch {} vorhanden, prüfe auf leere Transporte zum Zurückholen",
director.branch_id
);
if let Err(err) = self.plan_empty_transports_for_vehicle_retrieval(
&mut conn, &mut conn,
falukant_user_id, falukant_user_id,
director.branch_id, director.branch_id,
) { );
eprintln!(
"[DirectorWorker] Fehler beim Planen leerer Transporte: {err}"
);
}
} }
Ok(()) Ok(())
@@ -841,30 +688,16 @@ impl DirectorWorker {
let tax_cents = ((profit_cents as f64) * cumulative_tax_percent / 100.0).round() as i64; let tax_cents = ((profit_cents as f64) * cumulative_tax_percent / 100.0).round() as i64;
let payout_cents = revenue_cents - tax_cents; let payout_cents = revenue_cents - tax_cents;
eprintln!("[DirectorWorker] sell: revenue={:.2}, cost={:.2}, profit_cents={}, tax%={:.2}, tax_cents={}, payout_cents={}", sell_price, one_piece_cost * item.quantity as f64, profit_cents, cumulative_tax_percent, tax_cents, payout_cents);
if tax_cents > 0 { if tax_cents > 0 {
let tax_amount = (tax_cents as f64) / 100.0; let tax_amount = (tax_cents as f64) / 100.0;
if let Err(err) = self.base.change_falukant_user_money(DEFAULT_TREASURY_USER_ID, tax_amount, &format!("tax from sale product {}", item.product_id)) { let _ = self.base.change_falukant_user_money(DEFAULT_TREASURY_USER_ID, tax_amount, &format!("tax from sale product {}", item.product_id));
eprintln!("[DirectorWorker] Fehler bei change_falukant_user_money (tax): {err}");
}
} }
let payout_amount = (payout_cents as f64) / 100.0; let payout_amount = (payout_cents as f64) / 100.0;
if payout_cents != 0 && let Err(err) = self.base.change_falukant_user_money(item.user_id, payout_amount, "sell products") { if payout_cents != 0 {
eprintln!("[DirectorWorker] Fehler bei change_falukant_user_money (sell products): {err}"); let _ = self.base.change_falukant_user_money(item.user_id, payout_amount, "sell products");
} }
// Debug: Log vor dem DB-Aufruf
eprintln!(
"[DirectorWorker] sell: user_id={}, revenue={:.2}, tax={:.2}, payout={:.2}, product_id={}",
item.user_id,
sell_price,
(tax_cents as f64) / 100.0,
payout_amount,
item.product_id
);
conn.execute( conn.execute(
"add_sell_log", "add_sell_log",
&[ &[
@@ -914,23 +747,11 @@ impl DirectorWorker {
// Load worth_percent by region for this product // Load worth_percent by region for this product
let worth_by_region = Self::get_worth_by_region(conn, falukant_user_id, item.product_id)?; let worth_by_region = Self::get_worth_by_region(conn, falukant_user_id, item.product_id)?;
if worth_by_region.is_empty() { if worth_by_region.is_empty() {
eprintln!("[DirectorWorker] Keine worth_percent-Werte für Produkt {} gefunden", item.product_id);
return Ok(0); return Ok(0);
} }
eprintln!(
"[DirectorWorker] Gefundene Regionen für Produkt {}: {} Regionen",
item.product_id,
worth_by_region.len()
);
// Compute local piece price
let local_percent = worth_by_region.get(&item.region_id).copied().unwrap_or(100.0); let local_percent = worth_by_region.get(&item.region_id).copied().unwrap_or(100.0);
let local_piece_price = Self::compute_piece_price_for_percent(item, local_percent); let local_piece_price = Self::compute_piece_price_for_percent(item, local_percent);
eprintln!(
"[DirectorWorker] Lokaler Preis für Produkt {}: {:.2} (worth_percent={:.2}, quality={})",
item.product_id, local_piece_price, local_percent, item.quality
);
let mut best_target_region: Option<i32> = None; let mut best_target_region: Option<i32> = None;
let mut best_quantity: i32 = 0; let mut best_quantity: i32 = 0;
@@ -945,16 +766,7 @@ impl DirectorWorker {
let remote_piece_price = Self::compute_piece_price_for_percent(item, remote_percent); let remote_piece_price = Self::compute_piece_price_for_percent(item, remote_percent);
let delta_per_unit = remote_piece_price - local_piece_price; let delta_per_unit = remote_piece_price - local_piece_price;
eprintln!(
"[DirectorWorker] Region {}: Preis {:.2}, Delta {:.2}",
region_id, remote_piece_price, delta_per_unit
);
if delta_per_unit <= 0.0 { if delta_per_unit <= 0.0 {
eprintln!(
"[DirectorWorker] Region {}: Kein Preisvorteil (Delta <= 0)",
region_id
);
continue; continue;
} }
@@ -966,16 +778,7 @@ impl DirectorWorker {
region_id, region_id,
)?; )?;
eprintln!(
"[DirectorWorker] Region {}: {} verfügbare Transportmittel",
region_id, vehicles.len()
);
if vehicles.is_empty() { if vehicles.is_empty() {
eprintln!(
"[DirectorWorker] Region {}: Keine verfügbaren Transportmittel",
region_id
);
continue; continue;
} }
@@ -994,24 +797,11 @@ impl DirectorWorker {
let extra_revenue = delta_per_unit * qty as f64; let extra_revenue = delta_per_unit * qty as f64;
let transport_cost = Self::calc_transport_cost(remote_piece_price, qty); let transport_cost = Self::calc_transport_cost(remote_piece_price, qty);
let net_gain = extra_revenue - transport_cost; let net_gain = extra_revenue - transport_cost;
eprintln!(
"[DirectorWorker] Region {}: extra_revenue={:.2}, transport_cost={:.2}, net_gain={:.2}, qty={}",
region_id, extra_revenue, transport_cost, net_gain, qty
);
if net_gain <= 0.0 { if net_gain <= 0.0 {
eprintln!(
"[DirectorWorker] Region {}: Netto-Gewinn <= 0, überspringe",
region_id
);
continue; continue;
} }
if net_gain > best_gain { if net_gain > best_gain {
eprintln!(
"[DirectorWorker] Region {}: Neuer bester Transport (Gewinn {:.2})",
region_id, net_gain
);
best_gain = net_gain; best_gain = net_gain;
best_target_region = Some(region_id); best_target_region = Some(region_id);
best_quantity = qty; best_quantity = qty;
@@ -1047,10 +837,6 @@ impl DirectorWorker {
item.quantity = remaining_quantity; item.quantity = remaining_quantity;
} }
eprintln!(
"[DirectorWorker] Transport geplant: {} Einheiten von Produkt {} von Region {} nach Region {} (Stückpreis lokal {:.2}, remote {:.2}). Inventar reduziert.",
shipped, item.product_id, item.region_id, target_region, local_piece_price, best_remote_piece_price
);
} }
Ok(shipped) Ok(shipped)
@@ -1075,10 +861,6 @@ impl DirectorWorker {
.and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok())) .and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok()))
.unwrap_or(0); .unwrap_or(0);
eprintln!(
"[DirectorWorker] Fahrzeuge in Region {} für User {}: {}",
source_region, falukant_user_id, vehicle_count
);
// Debug: Prüfe, ob eine Route existiert // Debug: Prüfe, ob eine Route existiert
conn.prepare("check_route", QUERY_CHECK_ROUTE)?; conn.prepare("check_route", QUERY_CHECK_ROUTE)?;
@@ -1093,10 +875,6 @@ impl DirectorWorker {
.and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok())) .and_then(|row| row.get("count").and_then(|v| v.parse::<i32>().ok()))
.unwrap_or(0) > 0; .unwrap_or(0) > 0;
eprintln!(
"[DirectorWorker] Route von Region {} nach Region {} existiert: {}",
source_region, target_region, route_exists
);
conn.prepare( conn.prepare(
"get_transport_vehicles_for_route", "get_transport_vehicles_for_route",
@@ -1123,10 +901,6 @@ impl DirectorWorker {
} }
} }
eprintln!(
"[DirectorWorker] Gefundene Transportmittel für Route {} -> {}: {}",
source_region, target_region, result.len()
);
Ok(result) Ok(result)
} }
@@ -1210,10 +984,6 @@ impl DirectorWorker {
)?; )?;
if branch_rows.is_empty() { if branch_rows.is_empty() {
eprintln!(
"[DirectorWorker] Keine anderen Branches für User {} gefunden",
falukant_user_id
);
return Ok(()); return Ok(());
} }
@@ -1292,9 +1062,6 @@ impl DirectorWorker {
} }
if branches_with_vehicles.is_empty() { if branches_with_vehicles.is_empty() {
eprintln!(
"[DirectorWorker] Keine Branches mit freien Transportmitteln gefunden"
);
return Ok(()); return Ok(());
} }
@@ -1303,10 +1070,6 @@ impl DirectorWorker {
let (target_branch_id, target_region_id, vehicle_count, price_delta) = branches_with_vehicles[0]; let (target_branch_id, target_region_id, vehicle_count, price_delta) = branches_with_vehicles[0];
eprintln!(
"[DirectorWorker] Bester Branch für Fahrzeug-Rückholung: Branch {} (Region {}), {} Fahrzeuge, Preisvorteil: {:.2}%",
target_branch_id, target_region_id, vehicle_count, price_delta
);
// Hole die Fahrzeuge nochmal für diesen Branch // Hole die Fahrzeuge nochmal für diesen Branch
let vehicles = Self::get_transport_vehicles_for_route( let vehicles = Self::get_transport_vehicles_for_route(
@@ -1326,10 +1089,6 @@ impl DirectorWorker {
transport_count += 1; transport_count += 1;
} }
eprintln!(
"[DirectorWorker] {} leere Transporte geplant: Region {} -> Region {}",
transport_count, target_region_id, current_region_id
);
Ok(()) Ok(())
} }
@@ -1368,9 +1127,6 @@ impl DirectorWorker {
-(item.income as f64), -(item.income as f64),
"director payed out", "director payed out",
) { ) {
eprintln!(
"[DirectorWorker] Fehler bei change_falukant_user_money (director payed out): {err}"
);
} }
conn.execute("set_salary_payed", &[&item.id])?; conn.execute("set_salary_payed", &[&item.id])?;

View File

@@ -580,6 +580,14 @@ pub const QUERY_COUNT_CHILDREN: &str = r#"
SELECT COUNT(*) AS cnt FROM falukant_data.child_relation WHERE (father_character_id = $1 OR mother_character_id = $1) AND child_character_id != $2; SELECT COUNT(*) AS cnt FROM falukant_data.child_relation WHERE (father_character_id = $1 OR mother_character_id = $1) AND child_character_id != $2;
"#; "#;
/// Zählt Kinder eines Users (über alle Charaktere des Users als Elternteil). Ein Parameter: user_id.
pub const QUERY_COUNT_CHILDREN_BY_USER: &str = r#"
SELECT COUNT(DISTINCT cr.child_character_id) AS cnt
FROM falukant_data.child_relation cr
JOIN falukant_data.character parent ON (parent.id = cr.father_character_id OR parent.id = cr.mother_character_id)
WHERE parent.user_id = $1;
"#;
// user_character worker queries // user_character worker queries
pub const QUERY_GET_USERS_TO_UPDATE: &str = r#" pub const QUERY_GET_USERS_TO_UPDATE: &str = r#"
SELECT id, CURRENT_DATE - birthdate::date AS age, health SELECT id, CURRENT_DATE - birthdate::date AS age, health

View File

@@ -26,7 +26,7 @@ use crate::worker::sql::{
QUERY_GET_SETTLEMENT_VALUE, QUERY_GET_SETTLEMENT_VALUE,
QUERY_GET_INVENTORY_VALUE, QUERY_GET_INVENTORY_VALUE,
QUERY_GET_CREDIT_DEBT, QUERY_GET_CREDIT_DEBT,
QUERY_COUNT_CHILDREN, QUERY_COUNT_CHILDREN_BY_USER,
QUERY_GET_HEIR, QUERY_GET_HEIR,
QUERY_RANDOM_HEIR, QUERY_RANDOM_HEIR,
QUERY_SET_CHARACTER_USER, QUERY_SET_CHARACTER_USER,
@@ -844,8 +844,8 @@ impl UserCharacterWorker {
.get() .get()
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?; .map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
conn.prepare("count_children", QUERY_COUNT_CHILDREN)?; conn.prepare("count_children_by_user", QUERY_COUNT_CHILDREN_BY_USER)?;
let rows = conn.execute("count_children", &[&deceased_user_id])?; let rows = conn.execute("count_children_by_user", &[&deceased_user_id])?;
Ok(rows Ok(rows
.first() .first()