More progress on product creation, including docs

This commit is contained in:
piv
2023-02-21 19:43:14 +10:30
parent 7bce9578df
commit 9f9fbd31fb

View File

@@ -9,16 +9,36 @@ use chrono::NaiveDateTime;
use rayon::prelude::{IntoParallelRefIterator, ParallelBridge, ParallelIterator};
use serde::Serialize;
struct Filter {}
struct Filter {
// Equal/not equal
equal: bool,
field: String,
value: String,
}
struct Constraint {}
enum ConstraintType {
Equal,
GreaterThan,
GreaterThanOrEqualTo,
LessThan,
LessThanOrEqualTo,
NotEqualTo,
}
struct Constraint {
source_type: String,
field: String,
constraint_type: ConstraintType,
value: String,
}
enum Component {
Constant(String),
Field(String),
// Even extras are allowed here, just specify the field type (encounter, service, etc) and the field name (incl Extra: or Classification: as appropriate)
Field(String, String),
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone)]
enum BuildFrom {
Service,
Transfer,
@@ -27,6 +47,7 @@ enum BuildFrom {
CodingDiagnosis,
// TODO: This is hard/expensive, ignore for now as we don't have test data
LinkedDataset,
Revenue,
}
impl From<&String> for BuildFrom {
@@ -38,29 +59,101 @@ impl From<&String> for BuildFrom {
"CD" => BuildFrom::CodingDiagnosis,
"T" => BuildFrom::Transfer,
"BS" => BuildFrom::LinkedDataset,
"R" => BuildFrom::Revenue,
_ => panic!(),
}
}
}
// Frequency per type:
// Linked Dataset: One Per Area, One per Built Service code, One per source item
// Coding Diagnosis, Coding Procedure, Encounter, Revenue, Service: One per source item
// Transfer: Change in bed number, change in clinic, change in consultant, change in consultant specialty, change in consultant specialty rollup, change in unit, change in ward, daily, daily or Change in bed number, daily or change in clinic, daily or change in consultant, daily or change in consultant specialty, cdaily or hange in consultant specialty rollup, daily or change in unit, daily or change in ward, daily except on admission day, daily except on admission day (incl same day), daily except on discharge day, daily except on discharge day (incl same day), Only admission location, only discharge location, one per source item
enum Frequency {
OnePerSource,
DailyOrChangeInWard,
ChangeInBedNumber,
ChangeInClinic,
ChangeInConsultant,
ChangeInConsultantSpecialty,
ChangeInConsultantSpecialtyRollup,
ChangeInUnit,
ChangeInWard,
Daily,
DailyOrChangeInBedNumber,
DailyOrChangeInClinic,
DailyOrChangeInConsultant,
DailyOrChangeInConsultantSpecialty,
DailyOrChangeInConsultantSpecialtyRollup,
DailyOrChangeInUnit,
DailyOrChangeInWard,
DailyExceptOnAdmissionDay,
DailyExceptOnAdmissionDayInclSameDay,
DailyExceptOnDischargeDay,
DailyExceptOnDischargeDayInclSameDay,
OnlyAdmissionLocation,
OnlyDischargeLocation,
OnePerSource,
}
impl From<&String> for Frequency {
fn from(frequency: &String) -> Self {
match frequency.as_str() {
"S" => Frequency::OnePerSource,
"O" => Frequency::OnePerSource,
"DOCW" => Frequency::DailyOrChangeInWard,
"D" => Frequency::Daily,
"DOCC" => Frequency::DailyOrChangeInClinic,
"DEAD" => Frequency::DailyExceptOnAdmissionDay,
"OAL" => Frequency::OnlyAdmissionLocation,
"CIW" => Frequency::ChangeInWard,
_ => panic!(),
}
}
}
enum RoundingMode {
ToClosestWhole,
UpToClosestWhole,
DownToClosestWhole,
None,
}
impl From<&String> for RoundingMode {
fn from(rounding: &String) -> Self {
match rounding.as_str() {
"U" => RoundingMode::UpToClosestWhole,
"N" => RoundingMode::None,
"D" => RoundingMode::DownToClosestWhole,
"T" => RoundingMode::ToClosestWhole,
_ => panic!(),
}
}
}
// enum ExtraValue {
// string(String),
// numeric(f64),
// datetime(NaiveDateTime),
// }
// struct Extra {
// extraType: String,
// value: ExtraValue,
// }
// Quantities per type:
// Built Service: Constant, SourceQuantity
// Coding Diagnosis: Costant, Extra
// Coding Procedure: Costant, Extra
// Encounter: Admission Weight, Age, Constant, Days, Expected Length of Stay, Extra, Hours, ICU Hours, Length of Stay, Mech Vent Hours, Revenue, Weighted Separation
// Revenue: Constant, Extra, SourceQuantity
// Service: Constant, Extra, SourceQuantity
// Transfer: Constant, Days, Extra, Hours
enum Quantity {
Constant(f64),
// Name of the extra
Extra(String),
SourceQuantity,
Hours(RoundingMode),
Days(RoundingMode),
}
enum DurationFallback {
@@ -132,11 +225,10 @@ where
for record in definitions.deserialize::<HashMap<String, String>>() {
let record = record?;
// Get the type, then switch based on that, as that's how we determine whether we've got a definition/filter/component/constraint (definition should always come first)
let recordType = record.get("Type").unwrap();
match recordType.as_str() {
let record_type = record.get("Type").unwrap();
match record_type.as_str() {
"Definition" => {
let build_quantity =
all_definitions.insert(
let build_quantity = all_definitions.insert(
record.get("Name").unwrap().to_owned(),
Definition {
name: record.get("Name").unwrap().to_owned(),
@@ -145,19 +237,19 @@ where
constraints: vec![],
build_from: BuildFrom::from(record.get("BuildFrom").unwrap()),
frequency: Frequency::from(record.get("Frequency").unwrap()),
quantity: ,
duration_fallback: (),
quantity: Quantity::Constant(1.),
duration_fallback: DurationFallback::BuiltService,
},
);
}
"Filter" => {}
"Component" => {}
"Constraint" => {}
_ => continue,
unknown => println!("Invalid type found: {}", unknown),
}
}
let mut mapped_definitions = all_definitions
let mut mapped_definitions: HashMap<BuildFrom, Definition> = all_definitions
.into_values()
.map(|value| (value.build_from, value))
.collect();