use fathom_function::{chrono::NaiveDate, forms::deserialize_date, tracing}; use pipeline_application::{ application::{ Application, CPPractice, CoatingRepairSchedule, SoilResistivityReport, SoilType, }, serialization::{serialize_degrees_celsius, serialize_meter, serialize_ohm_centimeter}, }; use serde::{Deserialize, Serialize}; use uom::si::f64::{ElectricalResistivity, Length, ThermodynamicTemperature}; use uuid::Uuid; #[fathom_function::function] async fn upload_soil_resistivity_report(input: Input) -> Result { let app = Application::new_from_compile_env(input.org_id, input.project_id).unwrap(); for pipeline_id in input.pipeline_id { app.upload_soil_resistivity_report(pipeline_id, &input.report) .await .map_err(|err| { tracing::error!(%pipeline_id, ?err, "Error uploading soil resistivity report"); format!("{err:?}") })?; } Ok(Output { status: "Success".to_owned(), }) } #[derive(Debug, Serialize)] struct Output { status: String, } #[derive(Debug, Deserialize)] struct Input { org_id: Uuid, project_id: String, pipeline_id: Vec, #[serde(flatten)] report: Report, } #[derive(Debug, Deserialize)] struct Report { /// The log distance of the starting point of this soil type: the absolute distance measured in /// meters from the launcher. #[serde(with = "serialize_meter")] pub starting_point: Length, /// The log distance of the end point of this soil type: the absolute distance measured in /// meters from the launcher. #[serde(with = "serialize_meter")] pub ending_point: Length, /// The date of this field inspection. #[serde(deserialize_with = "deserialize_date")] pub inspection_date: NaiveDate, /// The soil type at this location. pub soil_type: SoilType, /// The measured electrical resistivity of the soil. #[serde(with = "serialize_ohm_centimeter")] pub resistivity: ElectricalResistivity, /// The measured temperature of the soil at the time of the inspection. #[serde(with = "serialize_degrees_celsius")] pub soil_temperature: ThermodynamicTemperature, /// The cathode protection practice for this section of the pipeline. pub cp_practice: CPPractice, /// The coating repair schedule for this section of the pipeline. pub coating_repair_schedule: CoatingRepairSchedule, /// The inspector name or identifier. pub inspector: String, /// And additional remarks about the inspection. pub remarks: Option, } impl From<&Report> for SoilResistivityReport { fn from(value: &Report) -> Self { Self { starting_point: value.starting_point, ending_point: value.ending_point, inspection_date: value.inspection_date.and_time(Default::default()).and_utc(), soil_type: value.soil_type, resistivity: value.resistivity, soil_temperature: value.soil_temperature, cp_practice: value.cp_practice, coating_repair_schedule: value.coating_repair_schedule, inspector: value.inspector.to_owned(), remarks: value.remarks.to_owned(), } } }