use chrono::NaiveDate;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use turnframe_core::event::ExternalStatus;
use turnframe_core::operation::Money;
use uuid::Uuid;
use crate::workflows::trip::state::{NewExtra, Payer, TripTraveler};
pub mod operations {
pub const OPEN: &str = "trip.open";
pub const SET_NAME: &str = "trip.set_name";
pub const SET_TRAVEL_DATE: &str = "trip.set_travel_date";
pub const ADD_EXTRA: &str = "trip.add_extra";
pub const ASSIGN_PAYER: &str = "trip.assign_payer";
pub const CHANGE_EXTRA: &str = "trip.change_extra";
pub const SET_TRAVELER: &str = "trip.set_traveler";
pub const CHANGE_TRAVELER: &str = "trip.change_traveler";
pub const PROTECT_LEG: &str = "trip.protect_leg";
pub const REQUEST_REBOOKING: &str = "trip.request_rebooking";
pub const REBOOK: &str = "trip.rebook";
pub const WITHDRAW: &str = "trip.withdraw";
pub const ACKNOWLEDGE_CARD: &str = "trip.acknowledge_card";
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum TripCommand {
Open,
OpenFor {
traveler: TripTraveler,
},
SetName {
value: String,
},
SetTravelDate {
value: NaiveDate,
},
AddExtra {
extra: NewExtra,
},
AssignPayer {
extra_id: Uuid,
payer: Payer,
},
ChangeExtra {
extra_id: Uuid,
#[serde(default, skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
quantity: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
unit_price_cents: Option<i64>,
},
ChangeTraveler {
traveler: TripTraveler,
},
ProtectLeg {
leg: u32,
},
Requote {
leg: u32,
flight: String,
departs: String,
fare_difference_cents: i64,
},
RequestRebooking {
leg: u32,
},
Rebook,
Withdraw,
RecordAirlineOutcome {
status: ExternalStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
ticket_number: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
reason_code: Option<String>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum TripEvent {
Opened,
NameSet {
value: String,
},
TravelDateSet {
value: NaiveDate,
},
ExtraAdded {
extra_id: Uuid,
description: String,
quantity: u32,
unit_price_cents: i64,
},
PayerAssigned {
extra_id: Uuid,
payer: Payer,
},
ExtraChanged {
extra_id: Uuid,
#[serde(default, skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
quantity: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
unit_price_cents: Option<i64>,
},
TravelerChanged {
#[serde(default, skip_serializing_if = "Option::is_none")]
previous_traveler_id: Option<Uuid>,
traveler_id: Uuid,
#[serde(default)]
display_name: String,
},
LegProtected {
leg: u32,
},
OfferQuoted {
leg: u32,
flight: String,
departs: String,
fare_difference_cents: i64,
},
RebookingRequested {
leg: u32,
},
RebookingSent,
Withdrawn,
AirlineOutcomeRecorded {
status: ExternalStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
ticket_number: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
reason_code: Option<String>,
},
}
impl TripEvent {
#[must_use]
pub fn event_type(&self) -> &'static str {
match self {
Self::Opened => "trip.opened",
Self::NameSet { .. } => "trip.name_set",
Self::TravelDateSet { .. } => "trip.travel_date_set",
Self::ExtraAdded { .. } => "trip.extra_added",
Self::PayerAssigned { .. } => "trip.payer_assigned",
Self::ExtraChanged { .. } => "trip.extra_changed",
Self::TravelerChanged { .. } => "trip.traveler_changed",
Self::LegProtected { .. } => "trip.leg_protected",
Self::OfferQuoted { .. } => "trip.offer_quoted",
Self::RebookingRequested { .. } => "trip.rebooking_requested",
Self::RebookingSent => "trip.rebooking_sent",
Self::Withdrawn => "trip.withdrawn",
Self::AirlineOutcomeRecorded { .. } => "trip.airline_outcome_recorded",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct SetNameArgs {
pub value: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct SetTravelDateArgs {
pub value: NaiveDate,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct AddExtraArgs {
pub description: String,
pub quantity: u32,
pub unit_price: Money,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct AssignPayerArgs {
pub extra: u32,
pub payer: Payer,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ChangeExtraArgs {
pub extra: u32,
#[serde(default)]
pub description: Option<String>,
#[serde(default)]
pub quantity: Option<u32>,
#[serde(default)]
pub unit_price: Option<Money>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct OpenArgs {
#[serde(default)]
pub traveler: Option<TravelerRecord>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct SetTravelerArgs {
pub traveler: TravelerRecord,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct TravelerRecord {
pub case_id: String,
#[serde(default)]
pub label: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ChangeTravelerArgs {
pub traveler: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct LegArgs {
pub leg: u32,
}