Füge neue SQL-Abfragen für die Abfrage von Lagerbeständen nach Typ hinzu: Implementiere QUERY_GET_REGION_STOCKS_BY_TYPE und QUERY_GET_USER_STOCKS_BY_TYPE, um die Abfrage von Lagerbeständen zu optimieren. Aktualisiere die Logik in events.rs, um die neuen Abfragen zu verwenden und erweitere die Struktur StorageDamageInfo, um zusätzliche Informationen zu zerstörten Einheiten und betroffenen Regionen zu speichern. Ergänze die Dokumentation in AGENTS.md mit Projektleitlinien und Entwicklungsbefehlen.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m48s
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m48s
This commit is contained in:
@@ -20,6 +20,8 @@ use crate::worker::sql::{
|
||||
QUERY_INSERT_MONEY_HISTORY,
|
||||
QUERY_GET_REGION_STOCKS,
|
||||
QUERY_GET_USER_STOCKS,
|
||||
QUERY_GET_REGION_STOCKS_BY_TYPE,
|
||||
QUERY_GET_USER_STOCKS_BY_TYPE,
|
||||
QUERY_UPDATE_STOCK_CAPACITY,
|
||||
QUERY_UPDATE_STOCK_CAPACITY_REGIONAL,
|
||||
QUERY_GET_REGION_HOUSES,
|
||||
@@ -139,6 +141,8 @@ struct StorageDamageInfo {
|
||||
storage_destruction_percent: f64,
|
||||
affected_stocks: i32,
|
||||
destroyed_stocks: i32,
|
||||
destroyed_inventory_units: i64,
|
||||
affected_region_ids: Vec<i32>,
|
||||
}
|
||||
|
||||
/// Parameter für regionale Lager-Schäden
|
||||
@@ -224,18 +228,18 @@ impl EventsWorker {
|
||||
EventEffect::StorageDamage {
|
||||
probability: 1.0,
|
||||
stock_type_label: "field".to_string(),
|
||||
inventory_damage_min_percent: 5.0,
|
||||
inventory_damage_max_percent: 75.0,
|
||||
inventory_damage_min_percent: 35.0,
|
||||
inventory_damage_max_percent: 90.0,
|
||||
storage_destruction_min_percent: 0.0,
|
||||
storage_destruction_max_percent: 50.0,
|
||||
storage_destruction_max_percent: 0.0,
|
||||
},
|
||||
EventEffect::StorageDamage {
|
||||
probability: 1.0,
|
||||
stock_type_label: "wood".to_string(),
|
||||
inventory_damage_min_percent: 0.0,
|
||||
inventory_damage_max_percent: 25.0,
|
||||
storage_destruction_min_percent: 0.0,
|
||||
storage_destruction_max_percent: 10.0,
|
||||
inventory_damage_min_percent: 20.0,
|
||||
inventory_damage_max_percent: 55.0,
|
||||
storage_destruction_min_percent: 8.0,
|
||||
storage_destruction_max_percent: 25.0,
|
||||
},
|
||||
// Verbleibende Lager können durch den Sturm beschädigt werden und Kapazität verlieren
|
||||
EventEffect::StorageCapacityChange {
|
||||
@@ -271,23 +275,32 @@ impl EventsWorker {
|
||||
title: "Lagerbrand".to_string(),
|
||||
description: "Ein Feuer hat Teile deines Lagers beschädigt.".to_string(),
|
||||
effects: vec![
|
||||
// Feldlager: Lagerbestand kann zerstört werden, Lager können zerstört werden
|
||||
// Feldlager: haeufig Inhaltsverlust, aber Lager selbst bleibt erhalten
|
||||
EventEffect::StorageDamage {
|
||||
probability: 1.0,
|
||||
stock_type_label: "field".to_string(),
|
||||
inventory_damage_min_percent: 0.0,
|
||||
inventory_damage_max_percent: 100.0,
|
||||
inventory_damage_min_percent: 45.0,
|
||||
inventory_damage_max_percent: 95.0,
|
||||
storage_destruction_min_percent: 0.0,
|
||||
storage_destruction_max_percent: 50.0,
|
||||
storage_destruction_max_percent: 0.0,
|
||||
},
|
||||
// Holzlager: Lagerbestand kann zerstört werden, Lager können zerstört werden
|
||||
// Holzlager: Brand richtet hohen Schaden an Inhalt und Lager an
|
||||
EventEffect::StorageDamage {
|
||||
probability: 1.0,
|
||||
stock_type_label: "wood".to_string(),
|
||||
inventory_damage_min_percent: 0.0,
|
||||
inventory_damage_max_percent: 100.0,
|
||||
inventory_damage_min_percent: 35.0,
|
||||
inventory_damage_max_percent: 85.0,
|
||||
storage_destruction_min_percent: 12.0,
|
||||
storage_destruction_max_percent: 35.0,
|
||||
},
|
||||
// Steinlager: nur durch Brand betroffen, selten und nur geringer Inhaltsverlust
|
||||
EventEffect::StorageDamage {
|
||||
probability: 0.25,
|
||||
stock_type_label: "stone".to_string(),
|
||||
inventory_damage_min_percent: 3.0,
|
||||
inventory_damage_max_percent: 12.0,
|
||||
storage_destruction_min_percent: 0.0,
|
||||
storage_destruction_max_percent: 50.0,
|
||||
storage_destruction_max_percent: 0.0,
|
||||
},
|
||||
// Verbleibende Lager können durch das Feuer beschädigt werden und Kapazität verlieren
|
||||
EventEffect::StorageCapacityChange {
|
||||
@@ -297,6 +310,33 @@ impl EventsWorker {
|
||||
},
|
||||
],
|
||||
},
|
||||
RandomEvent {
|
||||
id: "warehouse_raid".to_string(),
|
||||
probability_per_minute: 0.003, // 0.3% pro Minute
|
||||
event_type: EventType::Personal,
|
||||
title: "Lagerraub".to_string(),
|
||||
description: "Raeuber haben Teile deiner Lager gepluendert.".to_string(),
|
||||
effects: vec![
|
||||
// Holzlager: bei Raub oft stark betroffen, inkl. Lagerschaden
|
||||
EventEffect::StorageDamage {
|
||||
probability: 1.0,
|
||||
stock_type_label: "wood".to_string(),
|
||||
inventory_damage_min_percent: 25.0,
|
||||
inventory_damage_max_percent: 70.0,
|
||||
storage_destruction_min_percent: 6.0,
|
||||
storage_destruction_max_percent: 20.0,
|
||||
},
|
||||
// Feldlager: haeufig Inhaltsverlust, aber kein Lagerschaden
|
||||
EventEffect::StorageDamage {
|
||||
probability: 1.0,
|
||||
stock_type_label: "field".to_string(),
|
||||
inventory_damage_min_percent: 30.0,
|
||||
inventory_damage_max_percent: 80.0,
|
||||
storage_destruction_min_percent: 0.0,
|
||||
storage_destruction_max_percent: 0.0,
|
||||
},
|
||||
],
|
||||
},
|
||||
RandomEvent {
|
||||
id: "character_illness".to_string(),
|
||||
probability_per_minute: 0.004, // 0.4% pro Minute (reduziert)
|
||||
@@ -1130,6 +1170,16 @@ impl EventsWorker {
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(0);
|
||||
|
||||
let stock_type_label = row
|
||||
.get("stock_type_label")
|
||||
.map(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
|
||||
// Eisenlager sind unzerstoerbar (kein struktureller Event-Schaden)
|
||||
if stock_type_label == "iron" {
|
||||
continue;
|
||||
}
|
||||
|
||||
if current_capacity > 0 {
|
||||
conn.execute("update_stock_capacity", &[&percent_change, &stock_id])?;
|
||||
affected_stocks += 1;
|
||||
@@ -1185,6 +1235,16 @@ impl EventsWorker {
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(0);
|
||||
|
||||
let stock_type_label = row
|
||||
.get("stock_type_label")
|
||||
.map(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
|
||||
// Eisenlager sind unzerstoerbar (kein struktureller Event-Schaden)
|
||||
if stock_type_label == "iron" {
|
||||
continue;
|
||||
}
|
||||
|
||||
if current_capacity > 0 {
|
||||
conn.execute("update_stock_capacity_regional", &[&percent_change, &stock_id])?;
|
||||
affected_stocks += 1;
|
||||
@@ -1532,6 +1592,8 @@ impl EventsWorker {
|
||||
"storage_destruction_percent": damage_info.storage_destruction_percent,
|
||||
"affected_stocks": damage_info.affected_stocks,
|
||||
"destroyed_stocks": damage_info.destroyed_stocks,
|
||||
"destroyed_inventory_units": damage_info.destroyed_inventory_units,
|
||||
"affected_region_ids": damage_info.affected_region_ids,
|
||||
})));
|
||||
}
|
||||
|
||||
@@ -1571,10 +1633,13 @@ impl EventsWorker {
|
||||
return Ok(Some(json!({
|
||||
"type": "storage_damage",
|
||||
"stock_type": stock_type_label,
|
||||
"region_id": region_id,
|
||||
"inventory_damage_percent": damage_info.inventory_damage_percent,
|
||||
"storage_destruction_percent": damage_info.storage_destruction_percent,
|
||||
"affected_stocks": damage_info.affected_stocks,
|
||||
"destroyed_stocks": damage_info.destroyed_stocks,
|
||||
"destroyed_inventory_units": damage_info.destroyed_inventory_units,
|
||||
"affected_region_ids": damage_info.affected_region_ids,
|
||||
})));
|
||||
}
|
||||
|
||||
@@ -2138,8 +2203,8 @@ impl EventsWorker {
|
||||
};
|
||||
|
||||
// 2. Hole alle Stocks dieses Typs in der Region mit ihren Branches
|
||||
conn.prepare("get_region_stocks", QUERY_GET_REGION_STOCKS)?;
|
||||
let stock_rows = conn.execute("get_region_stocks", &[¶ms.region_id, &stock_type_id])?;
|
||||
conn.prepare("get_region_stocks_by_type", QUERY_GET_REGION_STOCKS_BY_TYPE)?;
|
||||
let stock_rows = conn.execute("get_region_stocks_by_type", &[¶ms.region_id, &stock_type_id])?;
|
||||
|
||||
if stock_rows.is_empty() {
|
||||
eprintln!(
|
||||
@@ -2151,6 +2216,8 @@ impl EventsWorker {
|
||||
storage_destruction_percent: 0.0,
|
||||
affected_stocks: 0,
|
||||
destroyed_stocks: 0,
|
||||
destroyed_inventory_units: 0,
|
||||
affected_region_ids: vec![params.region_id],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2161,7 +2228,7 @@ impl EventsWorker {
|
||||
rng.gen_range(params.storage_destruction_min_percent..=params.storage_destruction_max_percent);
|
||||
|
||||
let total_stocks = stock_rows.len();
|
||||
let stocks_to_destroy = ((total_stocks as f64 * storage_destruction_percent / 100.0)
|
||||
let stocks_to_destroy_requested = ((total_stocks as f64 * storage_destruction_percent / 100.0)
|
||||
.round() as usize)
|
||||
.min(total_stocks);
|
||||
|
||||
@@ -2172,6 +2239,7 @@ impl EventsWorker {
|
||||
|
||||
let mut affected_stocks = 0;
|
||||
let mut processed_stocks = std::collections::HashSet::new();
|
||||
let mut destroyed_inventory_units: i64 = 0;
|
||||
|
||||
for row in &inventory_rows {
|
||||
let inventory_id: Option<i32> = row
|
||||
@@ -2200,6 +2268,7 @@ impl EventsWorker {
|
||||
if inventory_quantity > 0 {
|
||||
let damage = (inventory_quantity as f64 * inventory_damage_percent / 100.0).round() as i32;
|
||||
let new_quantity = (inventory_quantity - damage).max(0);
|
||||
destroyed_inventory_units += (inventory_quantity - new_quantity).max(0) as i64;
|
||||
|
||||
// Reduziere Lagerbestand pro Inventar-Eintrag
|
||||
conn.prepare("reduce_inventory", QUERY_REDUCE_INVENTORY)?;
|
||||
@@ -2214,18 +2283,39 @@ impl EventsWorker {
|
||||
|
||||
// 5. Zerstöre zufällig ausgewählte Stocks
|
||||
let mut destroyed_stocks = 0;
|
||||
if stocks_to_destroy > 0 {
|
||||
// Regelwerk:
|
||||
// - Nur Holzlager koennen als Lager zerstoert werden.
|
||||
// - Niemals mehr Lager zerstoeren als Lager mit betroffenem Inhalt.
|
||||
if stocks_to_destroy_requested > 0 && params.stock_type_label == "wood" {
|
||||
// Wähle zufällige Stocks zum Zerstören
|
||||
let mut stock_ids_to_destroy: Vec<i32> = stock_rows
|
||||
.iter()
|
||||
.filter_map(|row| row.get("stock_id").and_then(|v| v.parse::<i32>().ok()))
|
||||
.collect();
|
||||
|
||||
stock_ids_to_destroy.retain(|sid| processed_stocks.contains(sid));
|
||||
let stocks_to_destroy = stocks_to_destroy_requested
|
||||
.min(stock_ids_to_destroy.len())
|
||||
.min(affected_stocks as usize);
|
||||
|
||||
// Mische die Liste zufällig
|
||||
stock_ids_to_destroy.shuffle(rng);
|
||||
stock_ids_to_destroy.truncate(stocks_to_destroy);
|
||||
|
||||
for stock_id in &stock_ids_to_destroy {
|
||||
// Restbestand im zu zerstoerenden Lager zaehlen (zusaetzlicher Verlust)
|
||||
conn.prepare("get_stock_inventory", QUERY_GET_STOCK_INVENTORY)?;
|
||||
let doomed_items = conn.execute("get_stock_inventory", &[stock_id])?;
|
||||
for item_row in doomed_items {
|
||||
let qty = item_row
|
||||
.get("quantity")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(0);
|
||||
if qty > 0 {
|
||||
destroyed_inventory_units += qty as i64;
|
||||
}
|
||||
}
|
||||
|
||||
// Lösche zuerst den Lagerbestand
|
||||
conn.prepare("delete_inventory", QUERY_DELETE_INVENTORY)?;
|
||||
conn.execute("delete_inventory", &[stock_id])?;
|
||||
@@ -2240,7 +2330,7 @@ impl EventsWorker {
|
||||
|
||||
// 6. Sicherstelle, dass Lagerbestand <= Lageranzahl für alle verbleibenden Stocks
|
||||
// Hole alle verbleibenden Stocks mit ihrem Lagerbestand
|
||||
let remaining_stock_rows = conn.execute("get_region_stocks", &[¶ms.region_id, &stock_type_id])?;
|
||||
let remaining_stock_rows = conn.execute("get_region_stocks_by_type", &[¶ms.region_id, &stock_type_id])?;
|
||||
|
||||
for row in remaining_stock_rows {
|
||||
let stock_id: Option<i32> = row
|
||||
@@ -2299,6 +2389,8 @@ impl EventsWorker {
|
||||
storage_destruction_percent,
|
||||
affected_stocks,
|
||||
destroyed_stocks,
|
||||
destroyed_inventory_units,
|
||||
affected_region_ids: vec![params.region_id],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2331,8 +2423,8 @@ impl EventsWorker {
|
||||
};
|
||||
|
||||
// 2. Hole alle Stocks dieses Typs für alle Branches des Spielers
|
||||
conn.prepare("get_user_stocks", QUERY_GET_USER_STOCKS)?;
|
||||
let stock_rows = conn.execute("get_user_stocks", &[¶ms.user_id, &stock_type_id])?;
|
||||
conn.prepare("get_user_stocks_by_type", QUERY_GET_USER_STOCKS_BY_TYPE)?;
|
||||
let stock_rows = conn.execute("get_user_stocks_by_type", &[¶ms.user_id, &stock_type_id])?;
|
||||
|
||||
if stock_rows.is_empty() {
|
||||
eprintln!(
|
||||
@@ -2344,6 +2436,8 @@ impl EventsWorker {
|
||||
storage_destruction_percent: 0.0,
|
||||
affected_stocks: 0,
|
||||
destroyed_stocks: 0,
|
||||
destroyed_inventory_units: 0,
|
||||
affected_region_ids: Vec::new(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2354,7 +2448,7 @@ impl EventsWorker {
|
||||
rng.gen_range(params.storage_destruction_min_percent..=params.storage_destruction_max_percent);
|
||||
|
||||
let total_stocks = stock_rows.len();
|
||||
let stocks_to_destroy = ((total_stocks as f64 * storage_destruction_percent / 100.0)
|
||||
let stocks_to_destroy_requested = ((total_stocks as f64 * storage_destruction_percent / 100.0)
|
||||
.round() as usize)
|
||||
.min(total_stocks);
|
||||
|
||||
@@ -2365,6 +2459,7 @@ impl EventsWorker {
|
||||
|
||||
let mut affected_stocks = 0;
|
||||
let mut processed_stocks = std::collections::HashSet::new();
|
||||
let mut destroyed_inventory_units: i64 = 0;
|
||||
|
||||
for row in &inventory_rows {
|
||||
let inventory_id: Option<i32> = row
|
||||
@@ -2393,6 +2488,7 @@ impl EventsWorker {
|
||||
if inventory_quantity > 0 {
|
||||
let damage = (inventory_quantity as f64 * inventory_damage_percent / 100.0).round() as i32;
|
||||
let new_quantity = (inventory_quantity - damage).max(0);
|
||||
destroyed_inventory_units += (inventory_quantity - new_quantity).max(0) as i64;
|
||||
|
||||
// Reduziere Lagerbestand pro Inventar-Eintrag
|
||||
conn.prepare("reduce_inventory_personal", QUERY_REDUCE_INVENTORY_PERSONAL)?;
|
||||
@@ -2405,20 +2501,38 @@ impl EventsWorker {
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Zerstöre zufällig ausgewählte Stocks (nur für field und wood)
|
||||
// 5. Zerstöre zufällig ausgewählte Stocks (nur Holzlager)
|
||||
let mut destroyed_stocks = 0;
|
||||
if stocks_to_destroy > 0 && (params.stock_type_label == "field" || params.stock_type_label == "wood") {
|
||||
if stocks_to_destroy_requested > 0 && params.stock_type_label == "wood" {
|
||||
// Wähle zufällige Stocks zum Zerstören
|
||||
let mut stock_ids_to_destroy: Vec<i32> = stock_rows
|
||||
.iter()
|
||||
.filter_map(|row| row.get("stock_id").and_then(|v| v.parse::<i32>().ok()))
|
||||
.collect();
|
||||
|
||||
stock_ids_to_destroy.retain(|sid| processed_stocks.contains(sid));
|
||||
let stocks_to_destroy = stocks_to_destroy_requested
|
||||
.min(stock_ids_to_destroy.len())
|
||||
.min(affected_stocks as usize);
|
||||
|
||||
// Mische die Liste zufällig
|
||||
stock_ids_to_destroy.shuffle(rng);
|
||||
stock_ids_to_destroy.truncate(stocks_to_destroy);
|
||||
|
||||
for stock_id in &stock_ids_to_destroy {
|
||||
// Restbestand im zu zerstoerenden Lager zaehlen (zusaetzlicher Verlust)
|
||||
conn.prepare("get_stock_inventory_personal", QUERY_GET_STOCK_INVENTORY_PERSONAL)?;
|
||||
let doomed_items = conn.execute("get_stock_inventory_personal", &[stock_id])?;
|
||||
for item_row in doomed_items {
|
||||
let qty = item_row
|
||||
.get("quantity")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(0);
|
||||
if qty > 0 {
|
||||
destroyed_inventory_units += qty as i64;
|
||||
}
|
||||
}
|
||||
|
||||
// Lösche zuerst den Lagerbestand
|
||||
conn.prepare("delete_inventory_personal", QUERY_DELETE_INVENTORY_PERSONAL)?;
|
||||
conn.execute("delete_inventory_personal", &[stock_id])?;
|
||||
@@ -2432,7 +2546,7 @@ impl EventsWorker {
|
||||
}
|
||||
|
||||
// 6. Sicherstelle, dass Lagerbestand <= Lageranzahl für alle verbleibenden Stocks
|
||||
let remaining_stock_rows = conn.execute("get_user_stocks", &[¶ms.user_id, &stock_type_id])?;
|
||||
let remaining_stock_rows = conn.execute("get_user_stocks_by_type", &[¶ms.user_id, &stock_type_id])?;
|
||||
|
||||
for row in remaining_stock_rows {
|
||||
let stock_id: Option<i32> = row
|
||||
@@ -2486,11 +2600,23 @@ impl EventsWorker {
|
||||
}
|
||||
}
|
||||
|
||||
let mut affected_region_ids = std::collections::BTreeSet::new();
|
||||
for row in &stock_rows {
|
||||
if let Some(rid) = row
|
||||
.get("region_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
affected_region_ids.insert(rid);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(StorageDamageInfo {
|
||||
inventory_damage_percent,
|
||||
storage_destruction_percent,
|
||||
affected_stocks,
|
||||
destroyed_stocks,
|
||||
destroyed_inventory_units,
|
||||
affected_region_ids: affected_region_ids.into_iter().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,9 +753,12 @@ UPDATE falukant_data.inventory SET quantity = $1 WHERE id = $2;
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_USER_STOCKS: &str = r#"
|
||||
SELECT s.id AS stock_id, s.quantity AS current_capacity
|
||||
SELECT s.id AS stock_id,
|
||||
s.quantity AS current_capacity,
|
||||
st.label_tr AS stock_type_label
|
||||
FROM falukant_data.stock s
|
||||
JOIN falukant_data.branch b ON s.branch_id = b.id
|
||||
LEFT JOIN falukant_type.stock st ON st.id = s.stock_type_id
|
||||
WHERE b.falukant_user_id = $1;
|
||||
"#;
|
||||
|
||||
@@ -766,9 +769,12 @@ UPDATE falukant_data.stock
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_REGION_STOCKS: &str = r#"
|
||||
SELECT s.id AS stock_id, s.quantity AS current_capacity
|
||||
SELECT s.id AS stock_id,
|
||||
s.quantity AS current_capacity,
|
||||
st.label_tr AS stock_type_label
|
||||
FROM falukant_data.stock s
|
||||
JOIN falukant_data.branch b ON s.branch_id = b.id
|
||||
LEFT JOIN falukant_type.stock st ON st.id = s.stock_type_id
|
||||
WHERE b.region_id = $1;
|
||||
"#;
|
||||
|
||||
@@ -2699,6 +2705,18 @@ pub const QUERY_GET_INVENTORY_ITEMS: &str = r#"
|
||||
SELECT i.id AS inventory_id, i.quantity AS inventory_quantity, i.stock_id FROM falukant_data.inventory i JOIN falukant_data.stock s ON i.stock_id = s.id JOIN falukant_data.branch b ON s.branch_id = b.id WHERE b.region_id = $1 AND s.stock_type_id = $2;
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_REGION_STOCKS_BY_TYPE: &str = r#"
|
||||
SELECT s.id AS stock_id,
|
||||
s.quantity AS stock_capacity,
|
||||
COALESCE(SUM(i.quantity), 0)::int AS inventory_quantity
|
||||
FROM falukant_data.stock s
|
||||
JOIN falukant_data.branch b ON s.branch_id = b.id
|
||||
LEFT JOIN falukant_data.inventory i ON i.stock_id = s.id
|
||||
WHERE b.region_id = $1
|
||||
AND s.stock_type_id = $2
|
||||
GROUP BY s.id, s.quantity;
|
||||
"#;
|
||||
|
||||
pub const QUERY_REDUCE_INVENTORY: &str = r#"
|
||||
UPDATE falukant_data.inventory SET quantity = $1 WHERE id = $2;
|
||||
"#;
|
||||
@@ -2726,6 +2744,19 @@ JOIN falukant_data.stock s ON i.stock_id = s.id
|
||||
JOIN falukant_data.branch b ON s.branch_id = b.id
|
||||
WHERE b.falukant_user_id = $1 AND s.stock_type_id = $2;
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_USER_STOCKS_BY_TYPE: &str = r#"
|
||||
SELECT s.id AS stock_id,
|
||||
b.region_id AS region_id,
|
||||
s.quantity AS stock_capacity,
|
||||
COALESCE(SUM(i.quantity), 0)::int AS inventory_quantity
|
||||
FROM falukant_data.stock s
|
||||
JOIN falukant_data.branch b ON s.branch_id = b.id
|
||||
LEFT JOIN falukant_data.inventory i ON i.stock_id = s.id
|
||||
WHERE b.falukant_user_id = $1
|
||||
AND s.stock_type_id = $2
|
||||
GROUP BY s.id, b.region_id, s.quantity;
|
||||
"#;
|
||||
// Produce worker queries
|
||||
pub const QUERY_GET_FINISHED_PRODUCTIONS: &str = r#"
|
||||
SELECT DISTINCT ON (p.id)
|
||||
|
||||
Reference in New Issue
Block a user