Refactor production cost calculations and SQL query: Updated the QUERY_GET_BEST_PRODUCTION to implement a legacy formula for ranking based on effective market percentage and knowledge levels. Adjusted the calculation logic for costs and clarified documentation to ensure consistency with the new pricing strategy. Enhanced SQL query structure for improved clarity and performance in production worth assessment.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 2m41s

This commit is contained in:
Torsten Schulz (local)
2026-04-09 09:36:44 +02:00
parent bb1c1c4133
commit ebf20c4424
2 changed files with 41 additions and 51 deletions

View File

@@ -73,14 +73,13 @@ 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';
"#;
/// Bester Produktstart: **Gewinn pro Minute** ≈ `(Verkaufspreis/Stück Stückkosten) / Produktionszeit` — an
/// `DirectorWorker::compute_piece_price_for_percent` angeglichen: regionaler Basispreis
/// `sell_cost × worth/100`, dann linear **60%100%** dieser Basis je nach Wissen (0100), gleiche Idee wie
/// `min_price + (maxmin)×k/100` in `director.rs`. Wissensblend `(2×Charakter + Direktor)/3`. UI soll dieselbe
/// Logik nutzen; weicht das Node-Frontend ab (z.B. 70% statt 60%), dort angleichen.
/// Bester Produktstart: **Legacy/UI-Formel** (vormals C++ `QUERY_GET_BEST_PRODUCTION`), damit Reihenfolge zur
/// Produkt-Ertrags-Tabelle passt: Wissen geht **additiv** in den Markt-Prozentsatz
/// `(worth + (2×Char + Dir)/3) / 100`, Kosten **`6 × category`**, Skalierung **`/ (300 × production_time)`**.
/// Verkauf/Steuer im laufenden Spiel nutzt weiter `DirectorWorker::compute_piece_sell_price` — nur **Ranking** hier.
///
/// Stückkosten wie `Director::piece_production_cost`. Mit Fahrzeug: `MAX(worth_percent)` über Filialregionen;
/// ohne Fahrzeug: nur Direktor-Region. **Ohne** Steuer im Ranking.
/// `worth_percent`: mit Fahrzeug `MAX` über Filialregionen; ohne Fahrzeug nur Direktor-Region.
/// **Ein** Spielercharakter je User (`ORDER BY id DESC LIMIT 1`, `health > 0`).
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,
COALESCE(ftp.category, 1)::int AS product_category, fdb.region_id,
@@ -88,50 +87,42 @@ COALESCE(ftp.category, 1)::int AS product_category, fdb.region_id,
COALESCE((SELECT SUM(COALESCE(fdi.quantity, 0)) FROM falukant_data.stock fds JOIN falukant_data.inventory fdi ON fdi.stock_id = fds.id WHERE fds.branch_id = fdb.id), 0) AS used_in_stock,
(
(
(
ftp.sell_cost * (
CASE
WHEN EXISTS (
SELECT 1 FROM falukant_data.vehicle v
WHERE v.falukant_user_id = fdu.id
)
THEN bw.max_worth_pct
ELSE COALESCE(fdtpw_local.worth_percent::float8, 0.0)
END / 100.0
)
) * (
0.6 + 0.4 * LEAST(
100.0::float8,
GREATEST(
0.0::float8,
(
2.0 * COALESCE(fdk_character.knowledge, 0)::float8
+ COALESCE(fdk_director.knowledge, 0)::float8
) / 3.0
)
) / 100.0
)
- (
(6.0 + (GREATEST(COALESCE(ftp.category, 1), 1))::float8)
ftp.sell_cost
* (
1.0 - LEAST(
GREATEST(
(GREATEST(COALESCE(fdu.certificate, 1), 1))::float8
- (GREATEST(COALESCE(ftp.category, 1), 1))::float8,
0.0
) * 0.035,
0.14
)
)
)
) / NULLIF(ftp.production_time::float8, 0.0)
(
CASE
WHEN EXISTS (
SELECT 1 FROM falukant_data.vehicle v
WHERE v.falukant_user_id = fdu.id
)
THEN bw.max_worth_pct
ELSE COALESCE(fdtpw_local.worth_percent::float8, 0.0)
END
)
+ (
2.0 * COALESCE(fdk_character.knowledge, 0)::float8
+ COALESCE(fdk_director.knowledge, 0)::float8
)
/ 3.0
)
/ 100.0
- 6.0 * COALESCE(ftp.category, 0)::float8
) / (300.0 * NULLIF(ftp.production_time::float8, 0.0))
) AS worth,
fdb.id AS branch_id, (SELECT COUNT(id) FROM falukant_data.production WHERE branch_id = fdb.id) AS running_productions,
COALESCE((SELECT SUM(COALESCE(fdp.quantity, 0)) quantity FROM falukant_data.production fdp WHERE fdp.branch_id = fdb.id), 0) AS running_productions_quantity
FROM falukant_data.director fdd
JOIN falukant_data.character fdc ON fdc.id = fdd.director_character_id
JOIN falukant_data.falukant_user fdu ON fdd.employer_user_id = fdu.id
JOIN falukant_data.character user_character ON user_character.user_id = fdu.id
JOIN falukant_data.character user_character
ON user_character.id = (
SELECT c2.id
FROM falukant_data.character c2
WHERE c2.user_id = fdu.id
AND c2.health > 0
ORDER BY c2.id DESC
LIMIT 1
)
JOIN falukant_data.branch fdb ON fdb.falukant_user_id = fdu.id AND fdb.region_id = fdc.region_id
JOIN (
SELECT tpw.product_id,