Add logic to prevent multiple births for mothers in a single day: Implemented a new SQL query to check if a mother has already given birth today. Updated the FalukantFamilyWorker and UserCharacterWorker to utilize this check, enhancing the birth registration process and ensuring compliance with the new birth rule.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m35s
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m35s
This commit is contained in:
@@ -22,6 +22,7 @@ use super::sql::{
|
|||||||
QUERY_COUNT_LOVER_CHILDREN_FOR_USER, QUERY_FAMILY_SCHEMA_READY,
|
QUERY_COUNT_LOVER_CHILDREN_FOR_USER, QUERY_FAMILY_SCHEMA_READY,
|
||||||
QUERY_GET_ACTIVE_LOVER_ROWS_FOR_DAILY, QUERY_GET_ACTIVE_LOVER_ROWS_FOR_MONTHLY,
|
QUERY_GET_ACTIVE_LOVER_ROWS_FOR_DAILY, QUERY_GET_ACTIVE_LOVER_ROWS_FOR_MONTHLY,
|
||||||
QUERY_GET_ACTIVE_LOVER_ROWS_FOR_INSTALLMENT, QUERY_GET_LOVER_PREGNANCY_CANDIDATES,
|
QUERY_GET_ACTIVE_LOVER_ROWS_FOR_INSTALLMENT, QUERY_GET_LOVER_PREGNANCY_CANDIDATES,
|
||||||
|
QUERY_HAS_MOTHER_BIRTH_TODAY,
|
||||||
QUERY_GET_MARRIAGE_ROWS, QUERY_GET_USER_HOUSE_ROW_BY_USER, QUERY_INSERT_CHILD,
|
QUERY_GET_MARRIAGE_ROWS, QUERY_GET_USER_HOUSE_ROW_BY_USER, QUERY_INSERT_CHILD,
|
||||||
QUERY_INSERT_CHILD_RELATION_LOVER, QUERY_LOVER_BIRTH_PENALTY_MARRIAGE,
|
QUERY_INSERT_CHILD_RELATION_LOVER, QUERY_LOVER_BIRTH_PENALTY_MARRIAGE,
|
||||||
QUERY_LOVER_BIRTH_PENALTY_REPUTATION, QUERY_LOVER_INSTALLMENT_SCHEMA_READY,
|
QUERY_LOVER_BIRTH_PENALTY_REPUTATION, QUERY_LOVER_INSTALLMENT_SCHEMA_READY,
|
||||||
@@ -1015,6 +1016,7 @@ impl FalukantFamilyWorker {
|
|||||||
conn.prepare("insert_child_rel_lover", QUERY_INSERT_CHILD_RELATION_LOVER)?;
|
conn.prepare("insert_child_rel_lover", QUERY_INSERT_CHILD_RELATION_LOVER)?;
|
||||||
conn.prepare("pen_mar", QUERY_LOVER_BIRTH_PENALTY_MARRIAGE)?;
|
conn.prepare("pen_mar", QUERY_LOVER_BIRTH_PENALTY_MARRIAGE)?;
|
||||||
conn.prepare("pen_rep", QUERY_LOVER_BIRTH_PENALTY_REPUTATION)?;
|
conn.prepare("pen_rep", QUERY_LOVER_BIRTH_PENALTY_REPUTATION)?;
|
||||||
|
conn.prepare("has_mother_birth_today", QUERY_HAS_MOTHER_BIRTH_TODAY)?;
|
||||||
|
|
||||||
for row in rows {
|
for row in rows {
|
||||||
let father_cid = parse_i32(&row, "father_cid", -1);
|
let father_cid = parse_i32(&row, "father_cid", -1);
|
||||||
@@ -1027,6 +1029,9 @@ impl FalukantFamilyWorker {
|
|||||||
let region_id = parse_i32(&row, "region_id", 0);
|
let region_id = parse_i32(&row, "region_id", 0);
|
||||||
let father_uid = parse_opt_i32(&row, "father_uid");
|
let father_uid = parse_opt_i32(&row, "father_uid");
|
||||||
let mother_uid = parse_opt_i32(&row, "mother_uid");
|
let mother_uid = parse_opt_i32(&row, "mother_uid");
|
||||||
|
if mother_uid.is_some() && Self::mother_already_had_birth_today(&mut conn, mother_cid)? {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let gender = if self.dist.sample(&mut self.rng) < 0.5 {
|
let gender = if self.dist.sample(&mut self.rng) < 0.5 {
|
||||||
"male"
|
"male"
|
||||||
@@ -1073,6 +1078,18 @@ impl FalukantFamilyWorker {
|
|||||||
self.publish_falukant_update_family_and_status(user_id, "lover_birth");
|
self.publish_falukant_update_family_and_status(user_id, "lover_birth");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mother_already_had_birth_today(
|
||||||
|
conn: &mut crate::db::DbConnection,
|
||||||
|
mother_character_id: i32,
|
||||||
|
) -> Result<bool, DbError> {
|
||||||
|
let rows = conn.execute("has_mother_birth_today", &[&mother_character_id])?;
|
||||||
|
Ok(rows
|
||||||
|
.first()
|
||||||
|
.and_then(|r| r.get("has_birth_today"))
|
||||||
|
.map(|v| v == "t" || v == "true")
|
||||||
|
.unwrap_or(false))
|
||||||
|
}
|
||||||
|
|
||||||
/// `falukantUpdateFamily` (mit `reason`) + `falukantUpdateStatus` — für UI-Refresh.
|
/// `falukantUpdateFamily` (mit `reason`) + `falukantUpdateStatus` — für UI-Refresh.
|
||||||
fn publish_falukant_update_family_and_status(&self, user_id: i32, reason: &str) {
|
fn publish_falukant_update_family_and_status(&self, user_id: i32, reason: &str) {
|
||||||
let family = format!(
|
let family = format!(
|
||||||
|
|||||||
@@ -3886,6 +3886,16 @@ pub const QUERY_INSERT_CHILD_RELATION_LOVER: &str = r#"
|
|||||||
);
|
);
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
/// Realismus-Regel: pro Mutter maximal eine Geburt pro Kalendertag.
|
||||||
|
pub const QUERY_HAS_MOTHER_BIRTH_TODAY: &str = r#"
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM falukant_data.child_relation cr
|
||||||
|
WHERE cr.mother_character_id = $1::int
|
||||||
|
AND cr.created_at::date = CURRENT_DATE
|
||||||
|
) AS has_birth_today;
|
||||||
|
"#;
|
||||||
|
|
||||||
// --- Produktionszertifikat (Daemon Daily, Spec: Produktionszertifikate) ---
|
// --- Produktionszertifikat (Daemon Daily, Spec: Produktionszertifikate) ---
|
||||||
|
|
||||||
/// Ein Spielercharakter pro Falukant-User (bei mehreren lebenden: **höchste** `character.id`,
|
/// Ein Spielercharakter pro Falukant-User (bei mehreren lebenden: **höchste** `character.id`,
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ use crate::worker::sql::{
|
|||||||
QUERY_INSERT_CHILD,
|
QUERY_INSERT_CHILD,
|
||||||
QUERY_INSERT_CHILD_RELATION,
|
QUERY_INSERT_CHILD_RELATION,
|
||||||
QUERY_INSERT_CHILD_RELATION_PLANNED_BIRTH,
|
QUERY_INSERT_CHILD_RELATION_PLANNED_BIRTH,
|
||||||
|
QUERY_HAS_MOTHER_BIRTH_TODAY,
|
||||||
QUERY_INSERT_NOTIFICATION,
|
QUERY_INSERT_NOTIFICATION,
|
||||||
QUERY_DELETE_DIRECTOR,
|
QUERY_DELETE_DIRECTOR,
|
||||||
QUERY_DELETE_RELATIONSHIP,
|
QUERY_DELETE_RELATIONSHIP,
|
||||||
@@ -569,6 +570,7 @@ impl UserCharacterWorker {
|
|||||||
conn.prepare("insert_child_relation", QUERY_INSERT_CHILD_RELATION)?;
|
conn.prepare("insert_child_relation", QUERY_INSERT_CHILD_RELATION)?;
|
||||||
conn.prepare("insert_child_rel_planned", QUERY_INSERT_CHILD_RELATION_PLANNED_BIRTH)?;
|
conn.prepare("insert_child_rel_planned", QUERY_INSERT_CHILD_RELATION_PLANNED_BIRTH)?;
|
||||||
conn.prepare("clear_char_preg", QUERY_CLEAR_CHARACTER_PREGNANCY_AFTER_BIRTH)?;
|
conn.prepare("clear_char_preg", QUERY_CLEAR_CHARACTER_PREGNANCY_AFTER_BIRTH)?;
|
||||||
|
conn.prepare("has_mother_birth_today", QUERY_HAS_MOTHER_BIRTH_TODAY)?;
|
||||||
|
|
||||||
let use_gestation = self.marriage_pregnancy_column_ready.unwrap_or(false);
|
let use_gestation = self.marriage_pregnancy_column_ready.unwrap_or(false);
|
||||||
let planned_pregnancy_ready = self.character_planned_pregnancy_columns_ready.unwrap_or(false);
|
let planned_pregnancy_ready = self.character_planned_pregnancy_columns_ready.unwrap_or(false);
|
||||||
@@ -674,6 +676,9 @@ impl UserCharacterWorker {
|
|||||||
|
|
||||||
let father_uid = parse_opt_i32(row, "father_uid");
|
let father_uid = parse_opt_i32(row, "father_uid");
|
||||||
let mother_uid = parse_opt_i32(row, "mother_uid");
|
let mother_uid = parse_opt_i32(row, "mother_uid");
|
||||||
|
if mother_uid.is_some() && mother_already_had_birth_today(conn, mother_cid)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let birth_context = row
|
let birth_context = row
|
||||||
.get("birth_context")
|
.get("birth_context")
|
||||||
@@ -732,6 +737,9 @@ impl UserCharacterWorker {
|
|||||||
|
|
||||||
let father_uid = parse_opt_i32(row, "father_uid");
|
let father_uid = parse_opt_i32(row, "father_uid");
|
||||||
let mother_uid = parse_opt_i32(row, "mother_uid");
|
let mother_uid = parse_opt_i32(row, "mother_uid");
|
||||||
|
if mother_uid.is_some() && mother_already_had_birth_today(conn, mother_cid)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let gender = if self.dist.sample(&mut self.rng) < 0.5 {
|
let gender = if self.dist.sample(&mut self.rng) < 0.5 {
|
||||||
"male"
|
"male"
|
||||||
@@ -1193,6 +1201,18 @@ fn parse_opt_i32(row: &crate::db::Row, key: &str) -> Option<i32> {
|
|||||||
row.get(key).and_then(|v| v.parse::<i32>().ok())
|
row.get(key).and_then(|v| v.parse::<i32>().ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mother_already_had_birth_today(
|
||||||
|
conn: &mut crate::db::DbConnection,
|
||||||
|
mother_character_id: i32,
|
||||||
|
) -> Result<bool, DbError> {
|
||||||
|
let rows = conn.execute("has_mother_birth_today", &[&mother_character_id])?;
|
||||||
|
Ok(rows
|
||||||
|
.first()
|
||||||
|
.and_then(|r| r.get("has_birth_today"))
|
||||||
|
.map(|v| v == "t" || v == "true")
|
||||||
|
.unwrap_or(false))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Credit {
|
struct Credit {
|
||||||
amount: f64,
|
amount: f64,
|
||||||
|
|||||||
Reference in New Issue
Block a user