use mako_engine::types::Pruefidentifikator;
use mako_engine::{
error::WorkflowError,
types::{MarktpartnerCode, MessageRef},
workflow::{CommandPayload, EventPayload, Workflow, WorkflowOutput},
};
pub const WORKFLOW_NAME: &str = "gpke-utilts";
pub const UTILTS_PIDS: &[u32] = &[25001, 25004, 25005, 25006, 25007, 25008, 25009, 25010];
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct UtiltsKonfigData {
pub pruefidentifikator: Pruefidentifikator,
pub sender: MarktpartnerCode,
pub document_date: String,
pub message_ref: MessageRef,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type", content = "data")]
pub enum UtiltsKonfigEvent {
UtiltsErhalten {
pruefidentifikator: Pruefidentifikator,
sender: MarktpartnerCode,
document_date: String,
message_ref: MessageRef,
},
ValidationPassed {
message_ref: MessageRef,
},
ValidationFailed {
reason: String,
},
}
impl EventPayload for UtiltsKonfigEvent {
fn event_type(&self) -> &'static str {
match self {
Self::UtiltsErhalten { .. } => "UtiltsKonfigErhalten",
Self::ValidationPassed { .. } => "UtiltsKonfigValidationPassed",
Self::ValidationFailed { .. } => "UtiltsKonfigValidationFailed",
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "status", content = "data")]
pub enum UtiltsKonfigState {
New,
UtiltsErhalten(UtiltsKonfigData),
ValidationPassed(UtiltsKonfigData),
ValidationFailed {
reason: String,
},
}
impl Default for UtiltsKonfigState {
fn default() -> Self {
Self::New
}
}
impl UtiltsKonfigState {
#[must_use]
pub fn label(&self) -> &'static str {
match self {
Self::New => "New",
Self::UtiltsErhalten(_) => "UtiltsErhalten",
Self::ValidationPassed(_) => "ValidationPassed",
Self::ValidationFailed { .. } => "ValidationFailed",
}
}
}
#[derive(Clone)]
pub enum UtiltsKonfigCommand {
ReceiveUtilts {
pid: Pruefidentifikator,
sender: MarktpartnerCode,
document_date: String,
message_ref: MessageRef,
validation_passed: bool,
validation_errors: Vec<String>,
},
}
impl CommandPayload for UtiltsKonfigCommand {}
pub struct GpkeUtiltsWorkflow;
impl Workflow for GpkeUtiltsWorkflow {
type State = UtiltsKonfigState;
type Event = UtiltsKonfigEvent;
type Command = UtiltsKonfigCommand;
fn apply(state: Self::State, event: &Self::Event) -> Self::State {
match event {
UtiltsKonfigEvent::UtiltsErhalten {
pruefidentifikator,
sender,
document_date,
message_ref,
} => UtiltsKonfigState::UtiltsErhalten(UtiltsKonfigData {
pruefidentifikator: *pruefidentifikator,
sender: sender.clone(),
document_date: document_date.clone(),
message_ref: message_ref.clone(),
}),
UtiltsKonfigEvent::ValidationPassed { .. } => match state {
UtiltsKonfigState::UtiltsErhalten(data) => {
UtiltsKonfigState::ValidationPassed(data)
}
other => other,
},
UtiltsKonfigEvent::ValidationFailed { reason } => UtiltsKonfigState::ValidationFailed {
reason: reason.clone(),
},
}
}
fn handle(
state: &Self::State,
command: Self::Command,
) -> Result<WorkflowOutput<Self::Event>, WorkflowError> {
match command {
UtiltsKonfigCommand::ReceiveUtilts {
pid,
sender,
document_date,
message_ref,
validation_passed,
validation_errors,
} => {
if !matches!(state, UtiltsKonfigState::New) {
return Err(WorkflowError::invalid_state("New", state.label()));
}
if !UTILTS_PIDS.contains(&pid.as_u32()) {
return Err(WorkflowError::rejected(format!(
"PID {pid} is not a handled UTILTS PID",
)));
}
let mut events = vec![UtiltsKonfigEvent::UtiltsErhalten {
pruefidentifikator: pid,
sender,
document_date,
message_ref: message_ref.clone(),
}];
if validation_passed {
events.push(UtiltsKonfigEvent::ValidationPassed { message_ref });
} else {
events.push(UtiltsKonfigEvent::ValidationFailed {
reason: validation_errors.join("; "),
});
}
Ok(events.into())
}
}
}
}