refactor: apply clippy suggestions

This commit is contained in:
Matthieu Bessat 2024-01-21 14:52:21 +01:00
parent edb5d6a372
commit 700ba180b6
7 changed files with 32 additions and 86 deletions

View file

@ -221,6 +221,7 @@ impl AuthentifiedClient {
Ok(res.status() == 200) Ok(res.status() == 200)
} }
#[allow(dead_code)]
pub async fn get_user_details(&self) -> Result<serde_json::Value> { pub async fn get_user_details(&self) -> Result<serde_json::Value> {
let res = self.client let res = self.client
.get(self.config.base_url.join("agg/user")?) .get(self.config.base_url.join("agg/user")?)
@ -340,6 +341,7 @@ struct FormAnswer {
} }
impl Organization { impl Organization {
#[allow(dead_code)]
pub async fn get_details(&self) -> Result<serde_json::Value> { pub async fn get_details(&self) -> Result<serde_json::Value> {
let details = self.client.simple_fetch(format!("organizations/{}", self.slug)).await?; let details = self.client.simple_fetch(format!("organizations/{}", self.slug)).await?;
Ok(details) Ok(details)

View file

@ -89,45 +89,6 @@ fn load_user_cache() -> Result<UserCache, LoadError> {
Ok(cache) 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<helloasso::AuthentifiedClient> {
async fn login(
user_cache: &mut UserCache,
ha_client: &mut helloasso::Client,
login_payload: helloasso::LoginPayload
) -> Result<helloasso::AuthentifiedClient> {
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<String>) -> Result<Option<reqwest::Proxy>> { fn get_proxy_from_url(proxy_url: &Option<String>) -> Result<Option<reqwest::Proxy>> {
Ok(match proxy_url { Ok(match proxy_url {
Some(p) => Some(reqwest::Proxy::all(p) 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")?; 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")) return Err(anyhow!("Invalid paheko base_url, it must end with a slash"))
} }
let mut paheko_client: paheko::Client = paheko::Client::new(paheko::ClientConfig { 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?; let paheko_client: paheko::AuthentifiedClient = paheko_client.login(paheko_credentials).await?;
match source { match source {
SourceType::Csv => sync_csv::sync_csv(&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? SourceType::Helloasso => sync_helloasso::sync_helloasso(&paheko_client, config, &mut user_cache).await?
} }
Ok(()) Ok(())

View file

@ -313,12 +313,12 @@ impl AuthentifiedClient {
Ok(ids.get(0).map(|x| x.id).unwrap_or(1)+1) Ok(ids.get(0).map(|x| x.id).unwrap_or(1)+1)
} }
pub async fn get_transactions(&self, id_years: &Vec<u32>) pub async fn get_transactions(&self, id_years: &[u32])
-> Result<Vec<SimpleTransaction>> -> Result<Vec<SimpleTransaction>>
{ {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct Row { struct Row {
id: u64, _id: u64,
label: String, label: String,
reference: String, reference: String,
#[serde(deserialize_with = "deserialize_json_list")] #[serde(deserialize_with = "deserialize_json_list")]
@ -566,7 +566,7 @@ impl AuthentifiedClient {
Ok(()) 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()) eprintln!("Paheko error details: {:?} {:?}", err_response.status(), err_response.text().await.unwrap())
} }
} }

View file

@ -20,7 +20,7 @@ fn process_csv_value(value: String) -> Option<String> {
if value.is_empty() { if value.is_empty() {
return None return None
} }
return Some(value) Some(value)
} }
fn process_price(value: String) -> f64 { fn process_price(value: String) -> f64 {
@ -33,7 +33,7 @@ fn process_price(value: String) -> f64 {
// read csv from stdin // 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 // raw row record directly from CSV
#[derive(Debug, serde::Deserialize)] #[derive(Debug, serde::Deserialize)]
struct AnswerRecord { struct AnswerRecord {
@ -48,8 +48,6 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi
#[serde(rename = "Tarif")] #[serde(rename = "Tarif")]
membership_mode: String, membership_mode: String,
#[serde(rename = "Montant (€)")]
total_amount: String,
#[serde(rename = "Cotisation (€)")] #[serde(rename = "Cotisation (€)")]
subscription_amount: String, subscription_amount: String,
#[serde(rename = "Don (€)")] #[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() { for line_res in stdin.lock().lines() {
let line = line_res.unwrap(); let line = line_res.unwrap();
eprintln!("{:?}",&line); eprintln!("{:?}",&line);
if line.starts_with(",") { if line.starts_with(',') {
continue; continue;
} }
if line.contains(&"\\FIN_DES_DONNES") { if line.contains("\\FIN_DES_DONNES") {
break; break;
} }
intermediate_inp.push_str(&line); intermediate_inp.push_str(&line);
intermediate_inp.push_str("\n"); intermediate_inp.push('\n');
} }
let mut rdr = ReaderBuilder::new() let mut rdr = ReaderBuilder::new()
@ -107,8 +105,8 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi
let generalized_answer = GeneralizedAnswer { let generalized_answer = GeneralizedAnswer {
first_name: Some(normalize_str(parsed_record.first_name)), first_name: Some(normalize_str(parsed_record.first_name)),
last_name: normalize_str(parsed_record.last_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)), 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(|s| parse_normalize_phone(s)), phone: process_csv_value(parsed_record.phone).and_then(parse_normalize_phone),
skills: process_csv_value(parsed_record.skills), skills: process_csv_value(parsed_record.skills),
address: process_csv_value(parsed_record.address) address: process_csv_value(parsed_record.address)
.expect("Expected answer to have address"), .expect("Expected answer to have address"),
@ -140,7 +138,6 @@ pub async fn sync_csv(paheko_client: &paheko::AuthentifiedClient, config: &Confi
sync_paheko( sync_paheko(
paheko_client, paheko_client,
config, config,
user_cache,
generalized_answers, generalized_answers,
CAISSE_ACCOUNT_CODE, CAISSE_ACCOUNT_CODE,
"Papier" "Papier"

View file

@ -89,7 +89,7 @@ pub async fn sync_helloasso(paheko_client: &paheko::AuthentifiedClient, config:
let email = choose_email(&answer); let email = choose_email(&answer);
// skip answers that were imported later and are stranger from helloasso // 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()) { if payment.extra == Some("Offline".to_string()) {
continue; 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), birth_year: read_custom_field(&answer, HelloassoCustomFieldType::Birthday).and_then(parse_and_get_birthday_year),
inception_time: answer.order.inception_time, inception_time: answer.order.inception_time,
reference: format!("HA/{}", answer.id), reference: format!("HA/{}", answer.id),
// TODO: handle donation from helloasso, compare initial_amount and amount in payment
// or shareAmount
donation_amount, donation_amount,
subscription_amount, subscription_amount,
membership_mode: serde_json::from_value(serde_json::Value::String(answer.mode.clone())) 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( sync_paheko(
paheko_client, paheko_client,
config, config,
user_cache,
generalized_answers, generalized_answers,
"512", "512",
"HelloAsso" "HelloAsso"

View file

@ -1,8 +1,6 @@
use crate::paheko; use crate::paheko;
use crate::paheko::{AccountingYear, SimpleTransaction}; use crate::paheko::{AccountingYear, SimpleTransaction};
use crate::{ use crate::Config;
Config, UserCache,
};
use crate::utils::{generate_id, normalize_first_name, normalize_last_name}; use crate::utils::{generate_id, normalize_first_name, normalize_last_name};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -52,15 +50,16 @@ struct GeneralizedAnswer {
linked_user_first_name: Option<String> linked_user_first_name: Option<String>
} }
fn get_accounting_year_for_time<'a>(accounting_years: &'a Vec<AccountingYear>, time: &'a DateTime<Utc>) -> Option<&'a AccountingYear> { fn get_accounting_year_for_time<'a>(
let date_ref = time.date_naive().clone(); accounting_years: &'a [AccountingYear], time: &'a DateTime<Utc>
) -> Option<&'a AccountingYear> {
let date_ref = time.date_naive();
accounting_years.iter().find(|year| year.start_date <= date_ref && date_ref <= year.end_date) accounting_years.iter().find(|year| year.start_date <= date_ref && date_ref <= year.end_date)
} }
pub async fn sync_paheko( pub async fn sync_paheko(
paheko_client: &paheko::AuthentifiedClient, paheko_client: &paheko::AuthentifiedClient,
config: &Config, config: &Config,
user_cache: &mut UserCache,
answers: Vec<GeneralizedAnswer>, answers: Vec<GeneralizedAnswer>,
debit_account_code: &str, debit_account_code: &str,
via_name: &str via_name: &str
@ -162,10 +161,8 @@ pub async fn sync_paheko(
if if
existing_user_opt.is_some() && existing_user_opt.is_some() &&
existing_subscriptions.iter() existing_subscriptions.iter()
.find(|membership| membership.users_ids .any(|membership| membership.users_ids.iter().any(|i| *i == pk_user_summary.id))
.iter().find(|i| **i == pk_user_summary.id).is_some() {
)
.is_some() {
eprintln!(" User is already subscribed to this activity"); eprintln!(" User is already subscribed to this activity");
} else { } else {
// add activity for first member // 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) // 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() 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")?; .await.context("Expected to create new paheko transaction")?;
stats.transaction_created += 1; stats.transaction_created += 1;
eprintln!(" Created paheko transaction for subscription"); 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_users: pk_users_summaries.iter().map(|x| x.id.clone()).collect(),
linked_subscriptions: vec![] linked_subscriptions: vec![]
}; };
let _ = paheko_client.register_transaction(transaction) paheko_client.register_transaction(transaction)
.await.context("Expected to create new paheko transaction for donation")?; .await.context("Expected to create new paheko transaction for donation")?;
stats.transaction_created += 1; stats.transaction_created += 1;
eprintln!(" Created paheko transaction for donation"); eprintln!(" Created paheko transaction for donation");

View file

@ -7,9 +7,9 @@ use chrono::prelude::{DateTime, Utc, NaiveDate, Datelike};
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Hash)]
pub struct Id(pub u64); pub struct Id(pub u64);
impl Into<String> for Id { impl From<Id> for String {
fn into(self) -> String { fn from(val: Id) -> Self {
format!("{:x}", self.0) format!("{:x}", val.0)
} }
} }
impl fmt::Display for Id { impl fmt::Display for Id {
@ -23,14 +23,6 @@ pub fn generate_id() -> Id {
} }
pub fn parse_datetime(inp: &str) -> Option<DateTime<Utc>> {
let date = NaiveDate::parse_from_str(inp, "%d/%m/%Y").ok()?;
Some(DateTime::<Utc>::from_naive_utc_and_offset(
date.and_hms_opt(0, 0, 0).unwrap(),
Utc
))
}
pub fn parse_datetime_american(inp: &str) -> Option<DateTime<Utc>> { pub fn parse_datetime_american(inp: &str) -> Option<DateTime<Utc>> {
let date = NaiveDate::parse_from_str(inp, "%m/%d/%Y").ok()?; let date = NaiveDate::parse_from_str(inp, "%m/%d/%Y").ok()?;
Some(DateTime::<Utc>::from_naive_utc_and_offset( Some(DateTime::<Utc>::from_naive_utc_and_offset(
@ -60,7 +52,7 @@ pub fn complete_date(inp: NaiveDate) -> DateTime<Utc> {
} }
pub fn normalize_str(subject: String) -> String { 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 /// 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 { pub fn normalize_first_name(subject: String) -> String {
subject subject
.to_lowercase() .to_lowercase()
.replace(" ", "-") .replace(' ', "")
.split("-") .split('-')
.map(|x| capitalize(x)) .map(capitalize)
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join("-") .join("-")
} }