diff --git a/src/helloasso.rs b/src/helloasso.rs index 5fea636..b2d9121 100644 --- a/src/helloasso.rs +++ b/src/helloasso.rs @@ -221,6 +221,7 @@ impl AuthentifiedClient { Ok(res.status() == 200) } + #[allow(dead_code)] pub async fn get_user_details(&self) -> Result { let res = self.client .get(self.config.base_url.join("agg/user")?) @@ -340,6 +341,7 @@ struct FormAnswer { } impl Organization { + #[allow(dead_code)] pub async fn get_details(&self) -> Result { let details = self.client.simple_fetch(format!("organizations/{}", self.slug)).await?; Ok(details) diff --git a/src/main.rs b/src/main.rs index 3fe866b..b0d57ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,45 +89,6 @@ fn load_user_cache() -> Result { Ok(cache) } -// TODO: find a better way to have the logic implemented -async fn get_auth_client_from_cache( - user_cache: &mut UserCache, - ha_client: &mut helloasso::Client, - login_payload: helloasso::LoginPayload -) -> Result { - - async fn login( - user_cache: &mut UserCache, - ha_client: &mut helloasso::Client, - login_payload: helloasso::LoginPayload - ) -> Result { - let auth_client = ha_client.login( - login_payload - ).await.context("Failed to login")?; - user_cache.helloasso_session = Some(auth_client.session.clone()); - write_user_cache(&user_cache).expect("unable to write user cache"); - println!("Logged in and wrote token to cache"); - Ok(auth_client) - } - - match &user_cache.helloasso_session { - Some(cached_session) => { - let auth_client = ha_client.authentified_client(cached_session.clone()); - - if !auth_client.verify_auth().await? { - println!("Need to relog, token invalid"); - return login(user_cache, ha_client, login_payload).await - } - println!("Used anterior token"); - Ok(auth_client) - }, - None => { - println!("First time login"); - login(user_cache, ha_client, login_payload).await - } - } -} - fn get_proxy_from_url(proxy_url: &Option) -> Result> { Ok(match proxy_url { Some(p) => Some(reqwest::Proxy::all(p) @@ -140,7 +101,7 @@ async fn launch_adapter(source: SourceType, config: &Config) -> Result<()> { let mut user_cache = load_user_cache().context("Failed to load user cache")?; - if !&config.paheko_base_url.ends_with("/") { + if !&config.paheko_base_url.ends_with('/') { return Err(anyhow!("Invalid paheko base_url, it must end with a slash")) } let mut paheko_client: paheko::Client = paheko::Client::new(paheko::ClientConfig { @@ -156,8 +117,8 @@ async fn launch_adapter(source: SourceType, config: &Config) -> Result<()> { let paheko_client: paheko::AuthentifiedClient = paheko_client.login(paheko_credentials).await?; match source { - SourceType::Csv => sync_csv::sync_csv(&paheko_client, &config, &mut user_cache).await?, - SourceType::Helloasso => sync_helloasso::sync_helloasso(&paheko_client, &config, &mut user_cache).await? + SourceType::Csv => sync_csv::sync_csv(&paheko_client, config, &mut user_cache).await?, + SourceType::Helloasso => sync_helloasso::sync_helloasso(&paheko_client, config, &mut user_cache).await? } Ok(()) diff --git a/src/paheko.rs b/src/paheko.rs index aa7901f..4bd9cbd 100644 --- a/src/paheko.rs +++ b/src/paheko.rs @@ -313,12 +313,12 @@ impl AuthentifiedClient { Ok(ids.get(0).map(|x| x.id).unwrap_or(1)+1) } - pub async fn get_transactions(&self, id_years: &Vec) + pub async fn get_transactions(&self, id_years: &[u32]) -> Result> { #[derive(Debug, Deserialize)] struct Row { - id: u64, + _id: u64, label: String, reference: String, #[serde(deserialize_with = "deserialize_json_list")] @@ -566,7 +566,7 @@ impl AuthentifiedClient { Ok(()) } - async fn show_paheko_err(&self, err_response: reqwest::Response) -> () { + async fn show_paheko_err(&self, err_response: reqwest::Response) { eprintln!("Paheko error details: {:?} {:?}", err_response.status(), err_response.text().await.unwrap()) } } diff --git a/src/sync_csv.rs b/src/sync_csv.rs index e4f6aba..35a8aac 100644 --- a/src/sync_csv.rs +++ b/src/sync_csv.rs @@ -20,7 +20,7 @@ fn process_csv_value(value: String) -> Option { if value.is_empty() { return None } - return Some(value) + Some(value) } fn process_price(value: String) -> f64 { @@ -33,7 +33,7 @@ fn process_price(value: String) -> f64 { // read csv from stdin -pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Config, user_cache: &mut UserCache) -> Result<()> { +pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Config, _user_cache: &mut UserCache) -> Result<()> { // raw row record directly from CSV #[derive(Debug, serde::Deserialize)] struct AnswerRecord { @@ -48,8 +48,6 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi #[serde(rename = "Tarif")] membership_mode: String, - #[serde(rename = "Montant (€)")] - total_amount: String, #[serde(rename = "Cotisation (€)")] subscription_amount: String, #[serde(rename = "Don (€)")] @@ -83,14 +81,14 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi for line_res in stdin.lock().lines() { let line = line_res.unwrap(); eprintln!("{:?}",&line); - if line.starts_with(",") { + if line.starts_with(',') { continue; } - if line.contains(&"\\FIN_DES_DONNES") { + if line.contains("\\FIN_DES_DONNES") { break; } intermediate_inp.push_str(&line); - intermediate_inp.push_str("\n"); + intermediate_inp.push('\n'); } let mut rdr = ReaderBuilder::new() @@ -107,8 +105,8 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi let generalized_answer = GeneralizedAnswer { first_name: Some(normalize_str(parsed_record.first_name)), last_name: normalize_str(parsed_record.last_name), - email: process_csv_value(parsed_record.email).and_then(|s| EmailAddress::is_valid(&s).then(|| s)), - phone: process_csv_value(parsed_record.phone).and_then(|s| parse_normalize_phone(s)), + email: process_csv_value(parsed_record.email).and_then(|s| EmailAddress::is_valid(&s).then_some(s)), + phone: process_csv_value(parsed_record.phone).and_then(parse_normalize_phone), skills: process_csv_value(parsed_record.skills), address: process_csv_value(parsed_record.address) .expect("Expected answer to have address"), @@ -140,7 +138,6 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi sync_paheko( paheko_client, config, - user_cache, generalized_answers, CAISSE_ACCOUNT_CODE, "Papier" diff --git a/src/sync_helloasso.rs b/src/sync_helloasso.rs index ca4b4fe..6b6cad0 100644 --- a/src/sync_helloasso.rs +++ b/src/sync_helloasso.rs @@ -89,7 +89,7 @@ pub async fn sync_helloasso(paheko_client: &paheko::AuthentifiedClient, config: let email = choose_email(&answer); // skip answers that were imported later and are stranger from helloasso - let payment = answer.payments.iter().nth(0).expect("Expected payment to exists"); + let payment = answer.payments.get(0).expect("Expected payment to exists"); if payment.extra == Some("Offline".to_string()) { continue; } @@ -119,8 +119,6 @@ pub async fn sync_helloasso(paheko_client: &paheko::AuthentifiedClient, config: birth_year: read_custom_field(&answer, HelloassoCustomFieldType::Birthday).and_then(parse_and_get_birthday_year), inception_time: answer.order.inception_time, reference: format!("HA/{}", answer.id), - // TODO: handle donation from helloasso, compare initial_amount and amount in payment - // or shareAmount donation_amount, subscription_amount, membership_mode: serde_json::from_value(serde_json::Value::String(answer.mode.clone())) @@ -141,7 +139,6 @@ pub async fn sync_helloasso(paheko_client: &paheko::AuthentifiedClient, config: sync_paheko( paheko_client, config, - user_cache, generalized_answers, "512", "HelloAsso" diff --git a/src/sync_paheko.rs b/src/sync_paheko.rs index 33c3f74..a0ab30d 100644 --- a/src/sync_paheko.rs +++ b/src/sync_paheko.rs @@ -1,8 +1,6 @@ use crate::paheko; use crate::paheko::{AccountingYear, SimpleTransaction}; -use crate::{ - Config, UserCache, -}; +use crate::Config; use crate::utils::{generate_id, normalize_first_name, normalize_last_name}; use anyhow::{Context, Result}; @@ -52,15 +50,16 @@ struct GeneralizedAnswer { linked_user_first_name: Option } -fn get_accounting_year_for_time<'a>(accounting_years: &'a Vec, time: &'a DateTime) -> Option<&'a AccountingYear> { - let date_ref = time.date_naive().clone(); +fn get_accounting_year_for_time<'a>( + accounting_years: &'a [AccountingYear], time: &'a DateTime +) -> Option<&'a AccountingYear> { + let date_ref = time.date_naive(); accounting_years.iter().find(|year| year.start_date <= date_ref && date_ref <= year.end_date) } pub async fn sync_paheko( paheko_client: &paheko::AuthentifiedClient, config: &Config, - user_cache: &mut UserCache, answers: Vec, debit_account_code: &str, via_name: &str @@ -162,10 +161,8 @@ pub async fn sync_paheko( if existing_user_opt.is_some() && existing_subscriptions.iter() - .find(|membership| membership.users_ids - .iter().find(|i| **i == pk_user_summary.id).is_some() - ) - .is_some() { + .any(|membership| membership.users_ids.iter().any(|i| *i == pk_user_summary.id)) + { eprintln!(" User is already subscribed to this activity"); } else { // add activity for first member @@ -249,7 +246,7 @@ pub async fn sync_paheko( // the linked_services, depend on a patch to paheko API code to work (see https://forge.lefuturiste.fr/mbess/paheko-fork/commit/a4fdd816112f51db23a2b02ac160b0513a5b09c5) linked_subscriptions: pk_user_service_registrations.iter().map(|x| x.id.clone()).collect() }; - let _ = paheko_client.register_transaction(transaction) + paheko_client.register_transaction(transaction) .await.context("Expected to create new paheko transaction")?; stats.transaction_created += 1; eprintln!(" Created paheko transaction for subscription"); @@ -280,7 +277,7 @@ pub async fn sync_paheko( linked_users: pk_users_summaries.iter().map(|x| x.id.clone()).collect(), linked_subscriptions: vec![] }; - let _ = paheko_client.register_transaction(transaction) + paheko_client.register_transaction(transaction) .await.context("Expected to create new paheko transaction for donation")?; stats.transaction_created += 1; eprintln!(" Created paheko transaction for donation"); diff --git a/src/utils.rs b/src/utils.rs index 4420c71..49bfe68 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -7,9 +7,9 @@ use chrono::prelude::{DateTime, Utc, NaiveDate, Datelike}; #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Hash)] pub struct Id(pub u64); -impl Into for Id { - fn into(self) -> String { - format!("{:x}", self.0) +impl From for String { + fn from(val: Id) -> Self { + format!("{:x}", val.0) } } impl fmt::Display for Id { @@ -23,14 +23,6 @@ pub fn generate_id() -> Id { } -pub fn parse_datetime(inp: &str) -> Option> { - let date = NaiveDate::parse_from_str(inp, "%d/%m/%Y").ok()?; - Some(DateTime::::from_naive_utc_and_offset( - date.and_hms_opt(0, 0, 0).unwrap(), - Utc - )) -} - pub fn parse_datetime_american(inp: &str) -> Option> { let date = NaiveDate::parse_from_str(inp, "%m/%d/%Y").ok()?; Some(DateTime::::from_naive_utc_and_offset( @@ -60,7 +52,7 @@ pub fn complete_date(inp: NaiveDate) -> DateTime { } pub fn normalize_str(subject: String) -> String { - subject.trim().replace("\n", ";").to_string() + subject.trim().replace('\n', ";").to_string() } /// remove year precision to comply with GDPR eu rules @@ -81,9 +73,9 @@ pub fn capitalize(s: &str) -> String { pub fn normalize_first_name(subject: String) -> String { subject .to_lowercase() - .replace(" ", "-") - .split("-") - .map(|x| capitalize(x)) + .replace(' ', "") + .split('-') + .map(capitalize) .collect::>() .join("-") }