#![deny(unsafe_code)]
#![deny(missing_docs)]
#![warn(clippy::pedantic, clippy::must_use_candidate)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::doc_markdown)] #![allow(clippy::too_many_lines)] #![allow(clippy::match_same_arms)] #![allow(clippy::manual_let_else)] #![allow(clippy::redundant_closure_for_method_calls)]
#![allow(clippy::unnested_or_patterns)]
#![allow(clippy::map_unwrap_or)]
#![allow(clippy::items_after_statements)]
pub mod anforderung;
pub mod bilanzkreisabrechnung;
pub mod clearingliste;
pub mod fristen;
pub mod ids;
pub mod listenabgleich;
pub mod profile;
pub mod summenzeitreihe;
pub mod zeitreihen;
pub mod zp_lifecycle;
pub mod zp_register;
pub use anforderung::{
ANFORDERUNG_PIDS, AbonnementVorgang, AnforderungCommand, AnforderungData, AnforderungEvent,
AnforderungKind, AnforderungState, MabisAnforderungWorkflow,
WORKFLOW_NAME as ANFORDERUNG_WORKFLOW_NAME,
};
pub use bilanzkreisabrechnung::{
AUSFALLARBEIT_PIDS, BillingCommand, BillingData, BillingEvent, BillingProjection,
BillingRecord, BillingState, Datenstatus, IFTSTA_ABWEISUNG_PID, IFTSTA_DATENSTATUS_PIDS,
IFTSTA_PIDS, IFTSTA_PRUEFMITTEILUNG_PIDS, InvalidSzrVersion, MabisBillingWorkflow,
Pruefergebnis, RFF_QUALIFIER_VERSION, STS_KATEGORIE_DATENSTATUS, SUMMENZEITREIHE_PID,
SzrVersion, VersionRecord, WORKFLOW_NAME as BILLING_WORKFLOW_NAME, ist_zeitreihen_pid,
};
pub use clearingliste::{
CLEARINGLISTE_PIDS, ClearinglisteCommand, ClearinglisteData, ClearinglisteEvent,
ClearinglisteKind, ClearinglisteState, MabisClearinglisteWorkflow,
WORKFLOW_NAME as CLEARINGLISTE_WORKFLOW_NAME,
};
pub use fristen::{
Abrechnungslauf, BIKO_DATENSTATUS_WERKTAGE, BIKO_WEITERLEITUNG_WERKTAGE, Bilanzierungsmonat,
CLEARING_ENDE_LABEL, Fenster, Phase, Stichtag,
};
pub use listenabgleich::{
LISTEN_FAMILIEN, ListenFamilie, ListenTyp, ListenabgleichCommand, ListenabgleichData,
ListenabgleichEvent, ListenabgleichState, MabisListenabgleichWorkflow,
WORKFLOW_NAME as LISTENABGLEICH_WORKFLOW_NAME, all_pids as listenabgleich_pids,
};
pub use zeitreihen::{
Aggregationsebene, Bezugszeitraum, CCI_BEZEICHNUNG_SUMMENZEITREIHE,
CCI_KLASSENTYP_VERANTWORTLICHER, Familie, KAPITEL_17_2_ENDE, Kategorie, Messtechnik, Rolle,
UnbekannteKategorie, Zeitreihe, aggregationsverantwortung, alle as alle_zeitreihen,
cav_aus_zeitreihe, cci_aus_rolle, rolle_aus_cci, zeitreihe_aus_cav,
};
pub use anforderung::{ABLEHNUNG_PID, all_pids as anforderung_pids};
pub use ids::{BilanzierungsgebietId, BilanzkreisId, InvalidMabisZaehlpunkt, MabisZaehlpunktId};
pub use profile::{
Bilanzierungsverfahren, ERSTLIEFERUNG_WERKTAGE, MabisProfilWorkflow, PROFIL_PIDS,
ProfilCommand, ProfilData, ProfilEvent, ProfilState, Profilart, REKLAMATION_EBD,
REKLAMATION_PID, WORKFLOW_NAME as PROFIL_WORKFLOW_NAME, all_pids as profil_pids,
};
pub use summenzeitreihe::{
MABIS_SLOT, SlotResolutionError, SumInterval, Summenzeitreihe, SummenzeitreiheBuilder,
};
pub use zp_lifecycle::{
MabisZpLifecycleWorkflow, TAEGLICHE_AAUEZ_ENDE, WORKFLOW_NAME as ZP_LIFECYCLE_WORKFLOW_NAME,
ZP_FAMILIEN, ZpFamilie, ZpLifecycleCommand, ZpLifecycleData, ZpLifecycleEvent,
ZpLifecycleState, ZpSerie, ZpVorgang, all_pids as zp_lifecycle_pids,
antwort_ist_zustimmung as zp_antwort_ist_zustimmung, familie_for, ist_antwort_pid,
ist_weiterleitung_pid, serien_fuer_pid,
};
pub struct MabisModule;
impl mako_engine::builder::EngineModule for MabisModule {
fn name(&self) -> &'static str {
"mabis"
}
fn workflow_names(&self) -> &'static [&'static str] {
&[
bilanzkreisabrechnung::WORKFLOW_NAME,
profile::WORKFLOW_NAME,
clearingliste::WORKFLOW_NAME,
zp_lifecycle::WORKFLOW_NAME,
anforderung::WORKFLOW_NAME,
listenabgleich::WORKFLOW_NAME,
]
}
fn register_pids(&self, router: &mut mako_engine::pid_router::PidRouter) {
router.register(bilanzkreisabrechnung::SUMMENZEITREIHE_PID, "mabis-billing");
for &pid in bilanzkreisabrechnung::AUSFALLARBEIT_PIDS {
router.register(pid, "mabis-billing");
}
for &pid in bilanzkreisabrechnung::IFTSTA_PIDS {
router.register(pid, "mabis-billing");
}
for pid in profile::all_pids() {
router.register(pid, profile::WORKFLOW_NAME);
}
for &pid in clearingliste::CLEARINGLISTE_PIDS {
router.register(pid, clearingliste::WORKFLOW_NAME);
}
for pid in listenabgleich::all_pids() {
router.register(pid, listenabgleich::WORKFLOW_NAME);
}
for pid in zp_lifecycle::all_pids() {
router.register(pid, zp_lifecycle::WORKFLOW_NAME);
}
for pid in anforderung::all_pids() {
router.register(pid, anforderung::WORKFLOW_NAME);
}
}
fn profile_requirements(&self) -> &'static [mako_engine::profile::ProfileRequirement] {
use mako_engine::profile::ProfileRequirement;
&[
ProfileRequirement {
message_type: "MSCONS",
label: "MSCONS Summenzeitreihen und Profile (MaBiS 13003, 13010–13012, 13020, 13023)",
},
ProfileRequirement {
message_type: "IFTSTA",
label: "IFTSTA Statusmeldung (MaBiS 21000–21005)",
},
ProfileRequirement {
message_type: "UTILMD",
label: "UTILMD MaBiS-Listen und ZP-Lifecycle (55062–55073, 55195–55224)",
},
ProfileRequirement {
message_type: "ORDERS",
label: "ORDERS MaBiS Anforderungen (17201–17208, 17210, 17211)",
},
ProfileRequirement {
message_type: "ORDRSP",
label: "ORDRSP Ablehnung Ab-/Bestellung der Aggregationsebene (19204)",
},
]
}
fn configure(&self) -> Result<(), String> {
let mut seen: Vec<(u32, &'static str)> = Vec::new();
let mut push = |pids: Vec<u32>, wf: &'static str| -> Result<(), String> {
for pid in pids {
if let Some((_, other)) = seen.iter().find(|(p, _)| *p == pid) {
return Err(format!("PID {pid} claimed by both {other} and {wf}"));
}
seen.push((pid, wf));
}
Ok(())
};
let mut billing = vec![bilanzkreisabrechnung::SUMMENZEITREIHE_PID];
billing.extend_from_slice(bilanzkreisabrechnung::AUSFALLARBEIT_PIDS);
billing.extend_from_slice(bilanzkreisabrechnung::IFTSTA_PIDS);
push(billing, "mabis-billing")?;
push(profile::all_pids(), profile::WORKFLOW_NAME)?;
push(
clearingliste::CLEARINGLISTE_PIDS.to_vec(),
clearingliste::WORKFLOW_NAME,
)?;
push(listenabgleich::all_pids(), listenabgleich::WORKFLOW_NAME)?;
push(zp_lifecycle::all_pids(), zp_lifecycle::WORKFLOW_NAME)?;
push(anforderung::all_pids(), anforderung::WORKFLOW_NAME)?;
Ok(())
}
}
#[cfg(test)]
mod module_tests {
use super::*;
use mako_engine::builder::EngineModule;
#[test]
fn no_two_workflows_claim_the_same_pid() {
MabisModule.configure().expect("PID ownership is disjoint");
}
#[test]
fn the_lieferantenclearingliste_is_not_record_only() {
assert!(!clearingliste::CLEARINGLISTE_PIDS.contains(&55065));
assert!(listenabgleich::all_pids().contains(&55065));
assert!(listenabgleich::all_pids().contains(&55066));
}
#[test]
fn the_mabis_ausfallarbeit_series_are_registered_here() {
assert_eq!(bilanzkreisabrechnung::AUSFALLARBEIT_PIDS, &[13_020, 13_023]);
}
#[test]
fn the_redispatch_only_mscons_pids_stay_out() {
let mut claimed = vec![bilanzkreisabrechnung::SUMMENZEITREIHE_PID];
claimed.extend_from_slice(bilanzkreisabrechnung::AUSFALLARBEIT_PIDS);
claimed.extend(profile::all_pids());
for pid in [13_021, 13_022, 13_026] {
assert!(!claimed.contains(&pid), "{pid} is not a MaBiS PID");
}
}
#[test]
fn the_hkn_register_ordrsp_codes_stay_out() {
for pid in [19_301_u32, 19_302] {
assert!(!anforderung::all_pids().contains(&pid));
}
}
#[test]
fn every_workflow_name_is_prefixed() {
for name in MabisModule.workflow_names() {
assert!(name.starts_with("mabis-"), "{name}");
}
}
}