fix(paheko): retry in case of email duplication
This commit is contained in:
parent
978c00c1dc
commit
54bd32d57d
4 changed files with 54 additions and 14 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -292,6 +292,17 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-std"
|
||||
version = "1.12.0"
|
||||
|
@ -508,7 +519,7 @@ dependencies = [
|
|||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
"strsim 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1537,6 +1548,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"argh",
|
||||
"async-recursion",
|
||||
"base64_light",
|
||||
"chrono",
|
||||
"clap",
|
||||
|
@ -1550,6 +1562,7 @@ dependencies = [
|
|||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strsim 0.11.0",
|
||||
"strum 0.25.0",
|
||||
"surf",
|
||||
"thiserror",
|
||||
|
@ -2228,6 +2241,12 @@ version = "0.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.24.1"
|
||||
|
|
|
@ -25,3 +25,5 @@ fully_pub = "0.1.4"
|
|||
base64_light = "0.1.4"
|
||||
csv = "1.3.0"
|
||||
argh = "0.1.12"
|
||||
strsim = "0.11.0"
|
||||
async-recursion = "1.0.5"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use async_recursion::async_recursion;
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use url::Url;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
@ -53,7 +54,8 @@ struct UserSummary {
|
|||
id: Id,
|
||||
first_name: Option<String>,
|
||||
last_name: String,
|
||||
email: Option<String>
|
||||
email: Option<String>,
|
||||
phone: Option<String>
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
|
@ -293,7 +295,7 @@ impl AuthentifiedClient {
|
|||
|
||||
pub async fn get_users(&self) -> Result<Vec<UserSummary>> {
|
||||
let query: String = r#"
|
||||
SELECT id,nom AS first_name,last_name,email FROM users;
|
||||
SELECT id,nom AS first_name,last_name,email,telephone AS phone FROM users;
|
||||
"#.to_string();
|
||||
|
||||
let users_val = self.sql_query(query).await.context("Fetching users")?;
|
||||
|
@ -389,6 +391,7 @@ impl AuthentifiedClient {
|
|||
)
|
||||
}
|
||||
|
||||
#[async_recursion]
|
||||
pub async fn create_user(&self, user: &GeneralizedAnswer, next_id: u64)
|
||||
-> Result<UserSummary>
|
||||
{
|
||||
|
@ -430,7 +433,16 @@ impl AuthentifiedClient {
|
|||
.send().await?;
|
||||
|
||||
if res.status() != 200 {
|
||||
self.show_paheko_err(res).await;
|
||||
let res_text = res.text().await.unwrap();
|
||||
if res_text.contains("E-Mail") && res_text.contains("unique") {
|
||||
eprintln!("WARN: Detected duplicated email, will retry without email");
|
||||
// email detected as duplicated by paheko server
|
||||
let mut new_data = user.clone();
|
||||
new_data.email = None;
|
||||
return self.create_user(&new_data, next_id).await;
|
||||
}
|
||||
|
||||
// self.show_paheko_err(res).await;
|
||||
return Err(APIClientError::InvalidStatusCode.into());
|
||||
}
|
||||
Ok(
|
||||
|
@ -438,7 +450,8 @@ impl AuthentifiedClient {
|
|||
id: Id(next_id),
|
||||
first_name: u.first_name,
|
||||
last_name: u.last_name,
|
||||
email: u.email
|
||||
email: u.email,
|
||||
phone: u.phone
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -525,6 +538,6 @@ impl AuthentifiedClient {
|
|||
}
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ struct GeneralizedAnswer {
|
|||
|
||||
fn get_accounting_year_for_time<'a>(accounting_years: &'a Vec<AccountingYear>, time: &'a DateTime<Utc>) -> Option<&'a AccountingYear> {
|
||||
let date_ref = time.date_naive().clone();
|
||||
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(
|
||||
|
@ -93,23 +93,23 @@ pub async fn sync_paheko(
|
|||
let mut pk_next_user_service_id = paheko_client.get_next_id("services_users")
|
||||
.await.context("Get paheko services_users next id")?;
|
||||
|
||||
for answer_inp in answers {
|
||||
let mut answer = answer_inp;
|
||||
for answer_inp in &answers {
|
||||
let mut answer = answer_inp.clone();
|
||||
answer.first_name = answer.first_name.map(normalize_first_name);
|
||||
answer.last_name = normalize_last_name(answer.last_name);
|
||||
|
||||
eprintln!("Processing answer:");
|
||||
eprintln!(" email: {:?}", answer.email);
|
||||
eprintln!(" name: {} {}", &answer.last_name, answer.first_name.clone().unwrap_or("".to_string()));
|
||||
eprintln!(" email: {:?}", answer.email);
|
||||
|
||||
// list of users involved in this answer
|
||||
let mut pk_users_summaries: Vec<paheko::UserSummary> = vec![];
|
||||
let mut pk_user_service_registrations: Vec<paheko::UserServiceRegistration> = vec![];
|
||||
|
||||
// check for existing user in paheko by email
|
||||
// TODO: check user with fuzzing
|
||||
// TODO: check user with fuzzing first name and last name
|
||||
let existing_user_opt = existing_users
|
||||
.iter().find(|user| user.email == answer.email)
|
||||
.iter().find(|user| user.first_name == answer.first_name && user.last_name == answer.last_name)
|
||||
.cloned();
|
||||
|
||||
// check for existing transactions
|
||||
|
@ -123,6 +123,7 @@ pub async fn sync_paheko(
|
|||
// dbg!(&existing_subscriptions);
|
||||
let pk_user_summary = match existing_user_opt.clone() {
|
||||
Some(user) => {
|
||||
eprintln!(" Found existing paheko user by name.");
|
||||
user
|
||||
},
|
||||
None => {
|
||||
|
@ -226,8 +227,13 @@ pub async fn sync_paheko(
|
|||
|
||||
// add transaction
|
||||
let transaction = paheko::SimpleTransaction {
|
||||
accounting_year: get_accounting_year_for_time(&accounting_years, &answer.inception_time)
|
||||
.expect("Cannot find an accounting year that match the date on paheko").id.clone(),
|
||||
accounting_year: match get_accounting_year_for_time(&accounting_years, &answer.inception_time) {
|
||||
None => {
|
||||
eprintln!("Cannot find an accounting year on paheko that include the inception date {:?} given", &answer.inception_time);
|
||||
panic!();
|
||||
},
|
||||
Some(s) => s
|
||||
}.id.clone(),
|
||||
// TODO: make the label template configurable
|
||||
label: format!("{} {:?} via {}", pk_membership.service_name, pk_membership.mode_name, via_name),
|
||||
amount: pk_membership.payed_amount,
|
||||
|
|
Loading…
Reference in a new issue