use model::{ChapelAbsenceRequest, ChapelAttendance, ChapelInformation, GeneralChapelInformation};
use crate::application::utils::semester::get_selected_semester;
use crate::client::{USaintApplication, USaintClient};
use crate::{RusaintError, model::SemesterType};
use wdpe::command::WebDynproCommandExecutor;
use wdpe::element::parser::ElementParser;
use wdpe::{
body::Body,
command::element::{
action::ButtonPressEventCommand,
selection::{ComboBoxLSDataCommand, ComboBoxSelectEventCommand},
},
define_elements,
element::{action::Button, selection::ComboBox},
error::{ElementError, WebDynproError},
};
#[derive(Debug)]
pub struct ChapelApplication {
client: USaintClient,
}
impl USaintApplication for ChapelApplication {
const APP_NAME: &'static str = "ZCMW3681";
fn from_client(client: USaintClient) -> Result<Self, RusaintError> {
if client.name() != Self::APP_NAME {
Err(RusaintError::InvalidClientError)
} else {
Ok(Self { client })
}
}
}
impl<'a> ChapelApplication {
define_elements! {
SEL_PERYR: ComboBox<'a> = "ZCMW3681.ID_0001:V_MAIN.TC_SEL_PERYR";
SEL_PERID: ComboBox<'a> = "ZCMW3681.ID_0001:V_MAIN.TC_SEL_PERID";
BTN_SEL: Button<'a> = "ZCMW3681.ID_0001:V_MAIN.BTN_SEL";
}
fn semester_to_key(semester: SemesterType) -> &'static str {
match semester {
SemesterType::One => "090",
SemesterType::Summer => "091",
SemesterType::Two => "092",
SemesterType::Winter => "093",
}
}
fn body(&self) -> &Body {
self.client.body()
}
async fn select_semester(
&mut self,
year: &str,
semester: SemesterType,
) -> Result<(), RusaintError> {
let semester = Self::semester_to_key(semester);
let parser = ElementParser::new(self.body());
let year_combobox_lsdata = parser.read(ComboBoxLSDataCommand::new(Self::SEL_PERYR))?;
let semester_combobox_lsdata = parser.read(ComboBoxLSDataCommand::new(Self::SEL_PERID))?;
if year_combobox_lsdata.key().map(String::as_str) != Some(year) {
let year_select_event = parser.read(ComboBoxSelectEventCommand::new(
Self::SEL_PERYR,
year,
false,
))?;
self.client.process_event(false, year_select_event).await?;
}
if semester_combobox_lsdata.key().map(String::as_str) != Some(semester) {
let semester_select_event = parser.read(ComboBoxSelectEventCommand::new(
Self::SEL_PERID,
semester,
false,
))?;
self.client
.process_event(false, semester_select_event)
.await?;
}
let button_press_event = parser.read(ButtonPressEventCommand::new(Self::BTN_SEL))?;
self.client.process_event(false, button_press_event).await?;
Ok(())
}
pub async fn lookup(&mut self) -> Result<(), RusaintError> {
let parser = ElementParser::new(self.body());
let button_press_event = parser.read(ButtonPressEventCommand::new(Self::BTN_SEL))?;
self.client.process_event(false, button_press_event).await?;
Ok(())
}
pub async fn reload(&mut self) -> Result<(), RusaintError> {
self.client.reload().await?;
Ok(())
}
pub async fn information(
&mut self,
year: u32,
semester: SemesterType,
) -> Result<ChapelInformation, RusaintError> {
self.select_semester(&year.to_string(), semester).await?;
let parser = ElementParser::new(self.body());
let general_information = GeneralChapelInformation::with_parser(&parser)?
.pop()
.ok_or_else(|| {
Into::<RusaintError>::into(Into::<WebDynproError>::into(
ElementError::NoSuchContent {
element: "General Chapel Information".to_string(),
content: "No data provided".to_string(),
},
))
})?;
let attendances = ChapelAttendance::with_parser(&parser)?;
let absence_requests = ChapelAbsenceRequest::with_parser(&parser)?;
Ok(ChapelInformation::new(
year,
semester,
general_information,
attendances,
absence_requests,
))
}
pub fn get_selected_semester(&self) -> Result<(u32, SemesterType), RusaintError> {
Ok(get_selected_semester(
&self.client,
&Self::SEL_PERYR,
&Self::SEL_PERID,
)?)
}
}
pub mod model;