use crate::eval::{ConditionResult, EvaluationContext};
pub fn followed_by_later_period(
ctx: &EvaluationContext,
tx_group: &str,
qualifiers: &[&str],
) -> ConditionResult {
let id = |path: &[(&str, usize)]| -> Option<u32> {
ctx.find_segments_at(path, "RFF").iter().find_map(|rff| {
qualifiers
.contains(&rff.get_component(0, 0))
.then(|| rff.get_component(0, 2).parse::<u32>().ok())
.flatten()
})
};
let followed = |tx: usize, sg6: usize| -> bool {
let Some(own) = id(&[(tx_group, tx), ("SG6", sg6)]) else {
return false;
};
(0..ctx.child_group_instance_count(&[tx_group], tx, "SG6"))
.filter(|other| *other != sg6)
.filter_map(|other| id(&[(tx_group, tx), ("SG6", other)]))
.any(|other| other > own)
};
if let Some(scope) = ctx.enclosing_scope("SG6") {
let at = |id: &str| scope.iter().find(|(g, _)| *g == id).map(|(_, i)| *i);
return match (at(tx_group), at("SG6")) {
(Some(tx), Some(sg6)) => ConditionResult::from(followed(tx, sg6)),
_ => ConditionResult::Unknown,
};
}
if ctx.navigator().is_none() {
return ConditionResult::Unknown;
}
ConditionResult::from((0..ctx.group_instance_count(&[tx_group])).any(|tx| {
(0..ctx.child_group_instance_count(&[tx_group], tx, "SG6")).any(|sg6| followed(tx, sg6))
}))
}
pub fn sg8_off_count_per_zeitraum(
ctx: &EvaluationContext,
tx_group: &str,
tx: usize,
seq_codes: &[&str],
status: &str,
) -> Vec<(String, usize)> {
let exactly = status.contains("[2004]");
if !exactly && !status.contains("[2005]") {
return Vec::new();
}
let ids: Vec<String> = (0..ctx.child_group_instance_count(&[tx_group], tx, "SG6"))
.flat_map(|sg6| ctx.find_segments_at(&[(tx_group, tx), ("SG6", sg6)], "RFF"))
.filter(|rff| rff.get_component(0, 0) == "Z49")
.map(|rff| rff.get_component(0, 2).to_string())
.filter(|id| !id.is_empty())
.collect();
let named: Vec<String> = (0..ctx.child_group_instance_count(&[tx_group], tx, "SG8"))
.flat_map(|sg8| ctx.find_segments_at(&[(tx_group, tx), ("SG8", sg8)], "SEQ"))
.filter(|seq| seq_codes.contains(&seq.get_component(0, 0)))
.map(|seq| seq.get_component(1, 0).to_string())
.collect();
if named.is_empty() {
return Vec::new();
}
let mut seen: Vec<&String> = Vec::new();
ids.iter()
.filter(|id| {
let first = !seen.contains(id);
seen.push(id);
first
})
.map(|id| (id.clone(), named.iter().filter(|n| *n == id).count()))
.filter(|(_, count)| if exactly { *count != 1 } else { *count == 0 })
.collect()
}