Integrate debt management features into Falukant daemon: Added falukant_debtors module for handling debtor logic, including daily processing and SQL queries for managing debtors' status and actions. Updated FalukantFamilyWorker to incorporate debtor checks and error handling, enhancing financial interactions and family dynamics.
This commit is contained in:
@@ -1144,9 +1144,278 @@ pub const QUERY_CLEANUP_CREDITS: &str = r#"
|
||||
WHERE remaining_amount <= 0.01;
|
||||
"#;
|
||||
|
||||
pub const QUERY_ADD_CHARACTER_TO_DEBTORS_PRISM: &str = r#"
|
||||
INSERT INTO falukant_data.debtors_prism (character_id)
|
||||
VALUES ($1);
|
||||
// --- Falukant: Schuldturm & Pfändung (docs/FALUKANT_DEBTORS_DAEMON.md) ---
|
||||
pub const QUERY_DEBTORS_PRISM_SCHEMA_READY: &str = r#"
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'falukant_data'
|
||||
AND table_name = 'debtors_prism'
|
||||
AND column_name = 'days_overdue'
|
||||
) AS ready;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_CREDIT_USERS_FOR_DAILY: &str = r#"
|
||||
SELECT
|
||||
c.falukant_user_id AS user_id,
|
||||
MIN(ch.id) AS character_id,
|
||||
COALESCE(fu.money, 0)::float8 AS money,
|
||||
COALESCE(SUM(
|
||||
c.amount::float8 / 10.0
|
||||
+ c.amount::float8 * c.interest_rate::float8 / 100.0
|
||||
), 0)::float8 AS total_pay_rate,
|
||||
COALESCE(SUM(c.remaining_amount), 0)::float8 AS total_credit_remaining
|
||||
FROM falukant_data.credit c
|
||||
JOIN falukant_data.falukant_user fu ON fu.id = c.falukant_user_id
|
||||
JOIN falukant_data.character ch ON ch.user_id = c.falukant_user_id AND ch.health > 0
|
||||
WHERE c.remaining_amount > 0.01
|
||||
GROUP BY c.falukant_user_id, fu.money;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_GET_PRISM_BY_CHARACTER: &str = r#"
|
||||
SELECT
|
||||
dp.id,
|
||||
dp.character_id,
|
||||
COALESCE(dp.status, '') AS status,
|
||||
COALESCE(dp.days_overdue, 0)::int AS days_overdue,
|
||||
COALESCE(dp.remaining_debt, 0)::float8 AS remaining_debt,
|
||||
dp.entered_at::text AS entered_at,
|
||||
dp.released_at::text AS released_at
|
||||
FROM falukant_data.debtors_prism dp
|
||||
WHERE dp.character_id = $1::int
|
||||
LIMIT 1;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_INSERT_DELINQUENT: &str = r#"
|
||||
INSERT INTO falukant_data.debtors_prism (
|
||||
character_id,
|
||||
status,
|
||||
days_overdue,
|
||||
remaining_debt,
|
||||
next_forced_action,
|
||||
reason,
|
||||
creditworthiness_penalty,
|
||||
public_known,
|
||||
assets_seized_json
|
||||
)
|
||||
SELECT
|
||||
$1::int,
|
||||
'delinquent',
|
||||
1,
|
||||
$2::float8,
|
||||
'reminder',
|
||||
'delinquent',
|
||||
0,
|
||||
false,
|
||||
'{}'::jsonb
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM falukant_data.debtors_prism d2 WHERE d2.character_id = $1::int
|
||||
)
|
||||
RETURNING id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_INCREMENT_DELINQUENT: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism
|
||||
SET days_overdue = COALESCE(days_overdue, 0) + 1,
|
||||
remaining_debt = $2::float8,
|
||||
next_forced_action = CASE
|
||||
WHEN COALESCE(days_overdue, 0) + 1 >= 3 THEN 'asset_seizure'
|
||||
WHEN COALESCE(days_overdue, 0) + 1 = 2 THEN 'final_warning'
|
||||
ELSE 'reminder'
|
||||
END,
|
||||
updated_at = NOW()
|
||||
WHERE character_id = $1::int
|
||||
AND status = 'delinquent'
|
||||
RETURNING id, COALESCE(days_overdue, 0) AS new_days;
|
||||
"#;
|
||||
|
||||
/// Nach abgeschlossenem Fall (`released`) neuer Verzug: Zeile wieder auf Delinquent setzen.
|
||||
pub const QUERY_DEBTORS_REACTIVATE_DELINQUENT_FROM_RELEASED: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism
|
||||
SET status = 'delinquent',
|
||||
days_overdue = 1,
|
||||
remaining_debt = $2::float8,
|
||||
next_forced_action = 'reminder',
|
||||
reason = 'delinquent',
|
||||
updated_at = NOW()
|
||||
WHERE character_id = $1::int
|
||||
AND status = 'released'
|
||||
RETURNING id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_RESET_DELINQUENCY_SOLVENT: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism
|
||||
SET days_overdue = 0,
|
||||
next_forced_action = 'reminder',
|
||||
updated_at = NOW()
|
||||
WHERE character_id = $1::int
|
||||
AND status = 'delinquent';
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_RESET_ON_PAYMENT_SUCCESS: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism
|
||||
SET days_overdue = 0,
|
||||
next_forced_action = 'reminder',
|
||||
updated_at = NOW()
|
||||
WHERE character_id = $1::int
|
||||
AND status = 'delinquent';
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_ENTER_PRISON: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism
|
||||
SET status = 'imprisoned',
|
||||
entered_at = COALESCE(entered_at, NOW()),
|
||||
released_at = NULL,
|
||||
debt_at_entry = $2::float8,
|
||||
remaining_debt = $2::float8,
|
||||
reason = 'credit_default',
|
||||
creditworthiness_penalty = COALESCE(creditworthiness_penalty, 0) + 45,
|
||||
next_forced_action = 'asset_seizure',
|
||||
public_known = true,
|
||||
updated_at = NOW()
|
||||
WHERE character_id = $1::int
|
||||
AND status = 'delinquent'
|
||||
AND COALESCE(days_overdue, 0) >= 3
|
||||
RETURNING id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_RELEASE_IF_PAID: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism dp
|
||||
SET status = 'released',
|
||||
released_at = NOW(),
|
||||
next_forced_action = NULL,
|
||||
days_overdue = 0,
|
||||
remaining_debt = 0,
|
||||
updated_at = NOW()
|
||||
FROM falukant_data.character ch
|
||||
WHERE ch.id = dp.character_id
|
||||
AND ch.user_id = $1::int
|
||||
AND dp.status = 'imprisoned'
|
||||
AND COALESCE((
|
||||
SELECT SUM(c.remaining_amount)
|
||||
FROM falukant_data.credit c
|
||||
WHERE c.falukant_user_id = $1::int
|
||||
), 0) <= 0.01
|
||||
RETURNING dp.character_id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_SUBTRACT_REPUTATION: &str = r#"
|
||||
UPDATE falukant_data.character
|
||||
SET reputation = GREATEST(0::numeric, COALESCE(reputation, 50::numeric) - $2::numeric),
|
||||
updated_at = NOW()
|
||||
WHERE id = $1::int AND user_id IS NOT NULL;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_MARRIAGE_SATISFACTION_SUB: &str = r#"
|
||||
UPDATE falukant_data.relationship r
|
||||
SET marriage_satisfaction = GREATEST(0, COALESCE(r.marriage_satisfaction, 55) - $2::int),
|
||||
updated_at = NOW()
|
||||
FROM falukant_type.relationship rt
|
||||
WHERE rt.id = r.relationship_type_id
|
||||
AND rt.tr IN ('married', 'engaged', 'wooing')
|
||||
AND (r.character1_id = $1::int OR r.character2_id = $1::int);
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_HOUSEHOLD_TENSION_ADD: &str = r#"
|
||||
UPDATE falukant_data.user_house
|
||||
SET household_tension_score = LEAST(100, COALESCE(household_tension_score, 0) + $2::int),
|
||||
updated_at = NOW()
|
||||
WHERE user_id = $1::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_LOVER_AFFECTION_SUB: &str = r#"
|
||||
UPDATE falukant_data.relationship_state rs
|
||||
SET affection = GREATEST(0, COALESCE(rs.affection, 50) - $2::int),
|
||||
updated_at = NOW()
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id AND rt.tr = 'lover'
|
||||
WHERE rs.relationship_id = r.id
|
||||
AND rs.active = true
|
||||
AND (r.character1_id = $1::int OR r.character2_id = $1::int);
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_IMPRISONED_REP_MALUS: &str = r#"
|
||||
UPDATE falukant_data.character c
|
||||
SET reputation = GREATEST(0::numeric, COALESCE(c.reputation, 50::numeric) - $2::numeric),
|
||||
updated_at = NOW()
|
||||
WHERE c.id = $1::int AND c.user_id IS NOT NULL;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_IMPRISONED_PENALTY_PLUS1: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism
|
||||
SET creditworthiness_penalty = COALESCE(creditworthiness_penalty, 0) + 1,
|
||||
updated_at = NOW()
|
||||
WHERE character_id = $1::int AND status = 'imprisoned';
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_IMPRISONED_MARRIAGE_SUB1: &str = r#"
|
||||
UPDATE falukant_data.relationship r
|
||||
SET marriage_satisfaction = GREATEST(0, COALESCE(r.marriage_satisfaction, 55) - 1),
|
||||
updated_at = NOW()
|
||||
FROM falukant_type.relationship rt
|
||||
WHERE rt.id = r.relationship_type_id
|
||||
AND rt.tr IN ('married', 'engaged', 'wooing')
|
||||
AND (r.character1_id = $1::int OR r.character2_id = $1::int);
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_IMPRISONED_TENSION_PLUS2: &str = r#"
|
||||
UPDATE falukant_data.user_house uh
|
||||
SET household_tension_score = LEAST(100, COALESCE(uh.household_tension_score, 0) + 2),
|
||||
updated_at = NOW()
|
||||
FROM falukant_data.character ch
|
||||
WHERE ch.id = $1::int AND uh.user_id = ch.user_id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_IMPRISONED_LOVER_AFF_SUB2: &str = r#"
|
||||
UPDATE falukant_data.relationship_state rs
|
||||
SET affection = GREATEST(0, COALESCE(rs.affection, 50) - 2),
|
||||
updated_at = NOW()
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id AND rt.tr = 'lover'
|
||||
WHERE rs.relationship_id = r.id AND rs.active = true
|
||||
AND (r.character1_id = $1::int OR r.character2_id = $1::int);
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_VEHICLE_FOR_SEIZURE: &str = r#"
|
||||
SELECT v.id AS vehicle_id,
|
||||
COALESCE(v.condition, 100)::int AS veh_condition,
|
||||
COALESCE(vt.cost, 0)::float8 AS type_cost
|
||||
FROM falukant_data.vehicle v
|
||||
JOIN falukant_type.vehicle vt ON vt.id = v.vehicle_type_id
|
||||
WHERE v.falukant_user_id = $1::int
|
||||
AND v.id NOT IN (
|
||||
SELECT DISTINCT t.vehicle_id FROM falukant_data.transport t
|
||||
WHERE t.vehicle_id IS NOT NULL
|
||||
)
|
||||
ORDER BY COALESCE(vt.cost, 0) ASC, v.id ASC
|
||||
LIMIT 1;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_DELETE_VEHICLE: &str = r#"
|
||||
DELETE FROM falukant_data.vehicle WHERE id = $1::int RETURNING id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_UPDATE_PRISM_REMAINING: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism dp
|
||||
SET remaining_debt = GREATEST(0, COALESCE(dp.remaining_debt, 0) - $2::float8),
|
||||
assets_seized_json = COALESCE(assets_seized_json, '{}'::jsonb)
|
||||
|| jsonb_build_object(
|
||||
'last_vehicle',
|
||||
jsonb_build_object('vehicle_id', $3::int, 'proceeds', $2::float8)
|
||||
),
|
||||
updated_at = NOW()
|
||||
WHERE dp.character_id = $1::int AND dp.status = 'imprisoned'
|
||||
RETURNING dp.remaining_debt;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEBTORS_UPDATE_PRISM_REMAINING_MONEY: &str = r#"
|
||||
UPDATE falukant_data.debtors_prism dp
|
||||
SET remaining_debt = GREATEST(0, COALESCE(dp.remaining_debt, 0) - $2::float8),
|
||||
assets_seized_json = COALESCE(assets_seized_json, '{}'::jsonb)
|
||||
|| jsonb_build_object('last_cash_seizure', $2::float8),
|
||||
updated_at = NOW()
|
||||
WHERE dp.character_id = $1::int AND dp.status = 'imprisoned'
|
||||
RETURNING dp.remaining_debt;
|
||||
"#;
|
||||
|
||||
pub const QUERY_RANDOM_HEIR: &str = r#"
|
||||
|
||||
Reference in New Issue
Block a user