Persist annual finance news events in runtime state
This commit is contained in:
parent
b4e23838bf
commit
fd6046a85c
8 changed files with 98 additions and 29 deletions
|
|
@ -114,7 +114,9 @@ surface too: the runtime chooses one annual-finance action per active company an
|
|||
the shellless creditor-pressure-bankruptcy, deep-distress-bankruptcy, dividend-adjustment,
|
||||
stock-repurchase, stock-issue, and bond-issue branches by mutating owned company activity,
|
||||
dividend, company stat-post, outstanding-share, issue-calendar, and live bond-slot state instead
|
||||
of stopping at reader-only diagnostics.
|
||||
of stopping at reader-only diagnostics. That same service state now also persists the last emitted
|
||||
annual-finance news events as structured runtime records carrying company id, exact selector label,
|
||||
action label, and the grounded debt/share payload totals used by the shell news layer.
|
||||
Those bankruptcy branches now follow the grounded owner semantics too: they stamp the bankruptcy
|
||||
year and halve live bond principals in place instead of treating bankruptcy as a liquidation path.
|
||||
The same save-native live bond-slot surface now also carries per-slot maturity years all the way
|
||||
|
|
|
|||
|
|
@ -13998,6 +13998,7 @@ mod tests {
|
|||
annual_stock_repurchase_last_share_count: 0,
|
||||
annual_stock_issue_last_share_count: 0,
|
||||
annual_finance_last_news_family_candidates: BTreeMap::new(),
|
||||
annual_finance_last_news_events: Vec::new(),
|
||||
chairman_issue_opinion_terms_raw_i32: BTreeMap::new(),
|
||||
chairman_personality_raw_u8: BTreeMap::new(),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ pub use runtime::{
|
|||
RUNTIME_COMPANY_STAT_SLOT_CREDIT_RATING, RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN, RUNTIME_WORLD_ISSUE_CREDIT_MARKET,
|
||||
RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE, RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE,
|
||||
RUNTIME_WORLD_ISSUE_PRIME_RATE, RuntimeCargoCatalogEntry, RuntimeCargoClass,
|
||||
RuntimeCargoPriceTarget, RuntimeCargoProductionTarget, RuntimeChairmanMetric,
|
||||
RuntimeChairmanProfile, RuntimeChairmanTarget, RuntimeCompany,
|
||||
RUNTIME_WORLD_ISSUE_PRIME_RATE, RuntimeAnnualFinanceNewsEvent, RuntimeCargoCatalogEntry,
|
||||
RuntimeCargoClass, RuntimeCargoPriceTarget, RuntimeCargoProductionTarget,
|
||||
RuntimeChairmanMetric, RuntimeChairmanProfile, RuntimeChairmanTarget, RuntimeCompany,
|
||||
RuntimeCompanyAnnualBondPolicyState, RuntimeCompanyAnnualCreditorPressureState,
|
||||
RuntimeCompanyAnnualDeepDistressState, RuntimeCompanyAnnualDividendPolicyState,
|
||||
RuntimeCompanyAnnualFinancePolicyAction, RuntimeCompanyAnnualFinancePolicyState,
|
||||
|
|
@ -124,10 +124,7 @@ pub use smp::{
|
|||
inspect_save_company_and_chairman_analysis_file, inspect_smp_bytes, inspect_smp_file,
|
||||
load_save_slice_file, load_save_slice_from_report,
|
||||
};
|
||||
pub use step::{
|
||||
AnnualFinanceNewsEvent, BoundaryEvent, ServiceEvent, StepCommand, StepResult,
|
||||
execute_step_command,
|
||||
};
|
||||
pub use step::{BoundaryEvent, ServiceEvent, StepCommand, StepResult, execute_step_command};
|
||||
pub use summary::RuntimeSummary;
|
||||
pub use win::{
|
||||
WinAnonymousSelectorRecord, WinHeaderWord, WinInspectionReport, WinReferenceDeltaFrequency,
|
||||
|
|
|
|||
|
|
@ -1214,6 +1214,17 @@ impl RuntimeEventRecordTemplate {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
pub struct RuntimeAnnualFinanceNewsEvent {
|
||||
pub company_id: u32,
|
||||
pub selector_label: String,
|
||||
pub action_label: String,
|
||||
pub retired_principal_total: u64,
|
||||
pub issued_principal_total: u64,
|
||||
pub repurchased_share_count: u64,
|
||||
pub issued_share_count: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
pub struct RuntimeServiceState {
|
||||
#[serde(default)]
|
||||
|
|
@ -1247,6 +1258,8 @@ pub struct RuntimeServiceState {
|
|||
#[serde(default)]
|
||||
pub annual_finance_last_news_family_candidates: BTreeMap<u32, String>,
|
||||
#[serde(default)]
|
||||
pub annual_finance_last_news_events: Vec<RuntimeAnnualFinanceNewsEvent>,
|
||||
#[serde(default)]
|
||||
pub chairman_issue_opinion_terms_raw_i32: BTreeMap<u32, Vec<i32>>,
|
||||
#[serde(default)]
|
||||
pub chairman_personality_raw_u8: BTreeMap<u32, u8>,
|
||||
|
|
@ -2169,6 +2182,14 @@ impl RuntimeState {
|
|||
));
|
||||
}
|
||||
}
|
||||
for news_event in &self.service_state.annual_finance_last_news_events {
|
||||
if !seen_company_ids.contains(&news_event.company_id) {
|
||||
return Err(format!(
|
||||
"service_state.annual_finance_last_news_events references unknown company_id {}",
|
||||
news_event.company_id
|
||||
));
|
||||
}
|
||||
}
|
||||
for chairman_profile_id in self
|
||||
.service_state
|
||||
.chairman_issue_opinion_terms_raw_i32
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::collections::BTreeSet;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::runtime::{
|
||||
runtime_company_bond_interest_rate_quote_f64,
|
||||
RuntimeAnnualFinanceNewsEvent, runtime_company_bond_interest_rate_quote_f64,
|
||||
runtime_company_support_adjusted_share_price_scalar_with_pressure_f64,
|
||||
runtime_round_f64_to_i64,
|
||||
};
|
||||
|
|
@ -59,17 +59,6 @@ pub struct BoundaryEvent {
|
|||
pub calendar: crate::CalendarPoint,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct AnnualFinanceNewsEvent {
|
||||
pub company_id: u32,
|
||||
pub selector_label: String,
|
||||
pub action_label: String,
|
||||
pub retired_principal_total: u64,
|
||||
pub issued_principal_total: u64,
|
||||
pub repurchased_share_count: u64,
|
||||
pub issued_share_count: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ServiceEvent {
|
||||
pub kind: String,
|
||||
|
|
@ -85,7 +74,7 @@ pub struct ServiceEvent {
|
|||
#[serde(default)]
|
||||
pub finance_news_family_candidates: BTreeMap<u32, String>,
|
||||
#[serde(default)]
|
||||
pub annual_finance_news_events: Vec<AnnualFinanceNewsEvent>,
|
||||
pub annual_finance_news_events: Vec<RuntimeAnnualFinanceNewsEvent>,
|
||||
pub dirty_rerun: bool,
|
||||
}
|
||||
|
||||
|
|
@ -520,6 +509,7 @@ fn service_company_annual_finance_policy(
|
|||
.service_state
|
||||
.annual_finance_last_news_family_candidates
|
||||
.retain(|company_id, _| active_company_id_set.contains(company_id));
|
||||
state.service_state.annual_finance_last_news_events.clear();
|
||||
state.service_state.annual_finance_service_calls += 1;
|
||||
state.service_state.annual_bond_last_retired_principal_total = 0;
|
||||
state.service_state.annual_bond_last_issued_principal_total = 0;
|
||||
|
|
@ -593,7 +583,7 @@ fn service_company_annual_finance_policy(
|
|||
.annual_finance_last_news_family_candidates
|
||||
.insert(company_id, label.to_string());
|
||||
finance_news_family_candidates.insert(company_id, label.to_string());
|
||||
annual_finance_news_events.push(AnnualFinanceNewsEvent {
|
||||
let news_event = RuntimeAnnualFinanceNewsEvent {
|
||||
company_id,
|
||||
selector_label: label.to_string(),
|
||||
action_label:
|
||||
|
|
@ -613,7 +603,12 @@ fn service_company_annual_finance_policy(
|
|||
issued_share_count: state
|
||||
.service_state
|
||||
.annual_stock_issue_last_share_count,
|
||||
});
|
||||
};
|
||||
state
|
||||
.service_state
|
||||
.annual_finance_last_news_events
|
||||
.push(news_event.clone());
|
||||
annual_finance_news_events.push(news_event);
|
||||
}
|
||||
applied_effect_count += 1;
|
||||
mutated_company_ids.insert(company_id);
|
||||
|
|
@ -699,7 +694,7 @@ fn service_company_annual_finance_policy(
|
|||
.annual_finance_last_news_family_candidates
|
||||
.insert(company_id, label.to_string());
|
||||
finance_news_family_candidates.insert(company_id, label.to_string());
|
||||
annual_finance_news_events.push(AnnualFinanceNewsEvent {
|
||||
let news_event = RuntimeAnnualFinanceNewsEvent {
|
||||
company_id,
|
||||
selector_label: label.to_string(),
|
||||
action_label:
|
||||
|
|
@ -719,7 +714,12 @@ fn service_company_annual_finance_policy(
|
|||
issued_share_count: state
|
||||
.service_state
|
||||
.annual_stock_issue_last_share_count,
|
||||
});
|
||||
};
|
||||
state
|
||||
.service_state
|
||||
.annual_finance_last_news_events
|
||||
.push(news_event.clone());
|
||||
annual_finance_news_events.push(news_event);
|
||||
}
|
||||
applied_effect_count += 1;
|
||||
mutated_company_ids.insert(company_id);
|
||||
|
|
@ -880,7 +880,7 @@ fn service_company_annual_finance_policy(
|
|||
.annual_finance_last_news_family_candidates
|
||||
.insert(company_id, label.to_string());
|
||||
finance_news_family_candidates.insert(company_id, label.to_string());
|
||||
annual_finance_news_events.push(AnnualFinanceNewsEvent {
|
||||
let news_event = RuntimeAnnualFinanceNewsEvent {
|
||||
company_id,
|
||||
selector_label: label.to_string(),
|
||||
action_label:
|
||||
|
|
@ -900,7 +900,12 @@ fn service_company_annual_finance_policy(
|
|||
issued_share_count: state
|
||||
.service_state
|
||||
.annual_stock_issue_last_share_count,
|
||||
});
|
||||
};
|
||||
state
|
||||
.service_state
|
||||
.annual_finance_last_news_events
|
||||
.push(news_event.clone());
|
||||
annual_finance_news_events.push(news_event);
|
||||
}
|
||||
applied_effect_count += 1;
|
||||
mutated_company_ids.insert(company_id);
|
||||
|
|
@ -991,7 +996,7 @@ fn service_company_annual_finance_policy(
|
|||
.annual_finance_last_news_family_candidates
|
||||
.insert(company_id, label.to_string());
|
||||
finance_news_family_candidates.insert(company_id, label.to_string());
|
||||
annual_finance_news_events.push(AnnualFinanceNewsEvent {
|
||||
let news_event = RuntimeAnnualFinanceNewsEvent {
|
||||
company_id,
|
||||
selector_label: label.to_string(),
|
||||
action_label:
|
||||
|
|
@ -1011,7 +1016,12 @@ fn service_company_annual_finance_policy(
|
|||
issued_share_count: state
|
||||
.service_state
|
||||
.annual_stock_issue_last_share_count,
|
||||
});
|
||||
};
|
||||
state
|
||||
.service_state
|
||||
.annual_finance_last_news_events
|
||||
.push(news_event.clone());
|
||||
annual_finance_news_events.push(news_event);
|
||||
}
|
||||
applied_effect_count += 1;
|
||||
mutated_company_ids.insert(company_id);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ pub struct RuntimeSummary {
|
|||
pub selected_company_dividend_eligible_for_adjustment_branch: Option<bool>,
|
||||
pub selected_company_annual_finance_policy_action: Option<String>,
|
||||
pub selected_company_annual_finance_news_family_candidate: Option<String>,
|
||||
pub selected_company_annual_finance_last_news_selector: Option<String>,
|
||||
pub annual_finance_last_news_event_count: usize,
|
||||
pub selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible: Option<bool>,
|
||||
pub selected_company_annual_finance_policy_deep_distress_bankruptcy_fallback_eligible:
|
||||
Option<bool>,
|
||||
|
|
@ -818,6 +820,21 @@ impl RuntimeSummary {
|
|||
.get(&company_id)
|
||||
})
|
||||
.cloned(),
|
||||
selected_company_annual_finance_last_news_selector: state
|
||||
.selected_company_id
|
||||
.and_then(|company_id| {
|
||||
state
|
||||
.service_state
|
||||
.annual_finance_last_news_events
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|news| news.company_id == company_id)
|
||||
})
|
||||
.map(|news| news.selector_label.clone()),
|
||||
annual_finance_last_news_event_count: state
|
||||
.service_state
|
||||
.annual_finance_last_news_events
|
||||
.len(),
|
||||
selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible:
|
||||
selected_company_annual_finance_policy_state
|
||||
.as_ref()
|
||||
|
|
@ -3392,6 +3409,15 @@ mod tests {
|
|||
14,
|
||||
"4053".to_string(),
|
||||
)]),
|
||||
annual_finance_last_news_events: vec![crate::RuntimeAnnualFinanceNewsEvent {
|
||||
company_id: 14,
|
||||
selector_label: "4053".to_string(),
|
||||
action_label: "stock_issue".to_string(),
|
||||
retired_principal_total: 0,
|
||||
issued_principal_total: 0,
|
||||
repurchased_share_count: 0,
|
||||
issued_share_count: 4_000,
|
||||
}],
|
||||
company_market_state: BTreeMap::from([(
|
||||
14,
|
||||
crate::RuntimeCompanyMarketState {
|
||||
|
|
@ -3517,6 +3543,13 @@ mod tests {
|
|||
.as_deref(),
|
||||
Some("4053")
|
||||
);
|
||||
assert_eq!(
|
||||
summary
|
||||
.selected_company_annual_finance_last_news_selector
|
||||
.as_deref(),
|
||||
Some("4053")
|
||||
);
|
||||
assert_eq!(summary.annual_finance_last_news_event_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -161,6 +161,8 @@ The highest-value next passes are now:
|
|||
equity-offering and buyback news tails; runtime summaries now also expose the grounded
|
||||
retired-versus-issued relation directly, and annual finance service now maps that same relation
|
||||
onto the exact debt headline selectors `2882..2886`
|
||||
while persisting the last emitted annual-finance news events as structured runtime-owned records
|
||||
carrying company id, selector label, action label, and the grounded debt/share payload totals
|
||||
- the project rule on the remaining closure work is now explicit too: when one runtime-facing field
|
||||
is still ambiguous, prefer rehosting the owning source state or real reader/setter family first
|
||||
instead of guessing another derived leaf field from neighboring raw offsets
|
||||
|
|
|
|||
|
|
@ -240,6 +240,9 @@ principal totals needed by the later debt-news tail, plus the issued-share and r
|
|||
counts needed by the later equity-offering and buyback news tails. Runtime summaries also expose
|
||||
the grounded retired-versus-issued relation directly, and annual finance service now maps that
|
||||
relation onto the exact debt headline selectors `2882..2886`.
|
||||
The same service state now also persists the last emitted annual-finance news events as structured
|
||||
runtime-owned records carrying company id, selector label, action label, and the grounded
|
||||
debt/share payload totals.
|
||||
The annual dividend-adjustment lane now rides that same seam too: the runtime now rehosts the
|
||||
shared year-or-control-transfer metric reader, the board-approved dividend ceiling helper, and the
|
||||
full annual dividend branch over owned cash, public float, current dividend, and building-growth
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue