From d665bb8eaacdc169a79be8f648325007b4f40787 Mon Sep 17 00:00:00 2001 From: Matthieu Bessat Date: Fri, 19 Apr 2024 14:17:54 +0200 Subject: [PATCH] feat: include payment mode and rename CSV fields --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/paheko.rs | 16 +++++++++++++--- src/sync_csv.rs | 19 ++++++++++++++----- src/sync_helloasso.rs | 4 +++- src/sync_paheko.rs | 26 ++++++++++++++++++++++++-- src/test_utils.rs | 19 +++++++++++++++++++ 7 files changed, 84 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf93176..f5631a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1562,6 +1562,7 @@ dependencies = [ "reqwest", "serde", "serde_json", + "serde_variant", "strsim 0.11.0", "strum 0.25.0", "surf", @@ -2085,6 +2086,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_variant" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0068df419f9d9b6488fdded3f1c818522cdea328e02ce9d9f147380265a432" +dependencies = [ + "serde", +] + [[package]] name = "sha1" version = "0.6.1" diff --git a/Cargo.toml b/Cargo.toml index f9e6598..bef87a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ csv = "1.3.0" argh = "0.1.12" strsim = "0.11.0" async-recursion = "1.0.5" +serde_variant = "0.1.3" diff --git a/src/paheko.rs b/src/paheko.rs index 904fe2d..99f5689 100644 --- a/src/paheko.rs +++ b/src/paheko.rs @@ -98,7 +98,9 @@ struct SimpleTransaction { reference: Option, linked_users: Vec, linked_subscriptions: Vec, - accounting_year: Id + accounting_year: Id, + payment_reference: Option, + notes: Option } @@ -360,6 +362,8 @@ impl AuthentifiedClient { kind: TransactionKind::Expense, linked_subscriptions: vec![], linked_users: vec![], + payment_reference: None, + notes: None }).collect()) } @@ -547,8 +551,14 @@ impl AuthentifiedClient { // "Numéro pièce comptable" enregistré au niveau de la transaction ; - if let Some(reference) = transaction.reference { - form = form.text("reference", reference); + if let Some(val) = transaction.reference { + form = form.text("reference", val); + } + if let Some(val) = transaction.payment_reference { + form = form.text("reference", val); + } + if let Some(val) = transaction.notes { + form = form.text("notes", val); } for linked_id in transaction.linked_users { form = form.text("linked_users[]", format!("{}", linked_id.0)); diff --git a/src/sync_csv.rs b/src/sync_csv.rs index a2d1866..222824e 100644 --- a/src/sync_csv.rs +++ b/src/sync_csv.rs @@ -5,7 +5,7 @@ use crate::{ use anyhow::Result; use crate::utils::{normalize_str, parse_date_iso, parse_normalize_phone}; -use crate::sync_paheko::{GeneralizedAnswer, sync_paheko}; +use crate::sync_paheko::{sync_paheko, GeneralizedAnswer, PaymentMode}; use email_address::EmailAddress; use chrono::prelude::Datelike; use std::io::BufRead; @@ -45,7 +45,7 @@ pub async fn sync_csv( // Ref BP reference: String, - date: String, + inception_date: String, email: String, first_name: String, last_name: String, @@ -76,7 +76,7 @@ pub async fn sync_csv( // Don (€) donation_amount: String, - // Mode de paiement + // Mode de paiement (Espèce or Cheque, ESP or CHQ) payment_mode: String } @@ -123,7 +123,7 @@ pub async fn sync_csv( birth_year: process_csv_value(parsed_record.birth_date) .and_then(|raw_date| parse_date_iso(&raw_date)) .map(|d| d.year() as u32), - inception_time: process_csv_value(parsed_record.date) + inception_time: process_csv_value(parsed_record.inception_date) .map(|s| parse_date_iso(&s).expect("Record must have a valid date") ) @@ -133,7 +133,16 @@ pub async fn sync_csv( subscription_amount: process_price(parsed_record.subscription_amount), // FIXME: get subscription from mode membership_mode: serde_json::from_value(serde_json::Value::String(parsed_record.membership_mode.clone())) .expect("Expected a membership mode to be valid"), - linked_user_first_name: process_csv_value(parsed_record.linked_user_first_name) + linked_user_first_name: process_csv_value(parsed_record.linked_user_first_name), + payment_mode: match process_csv_value(parsed_record.payment_mode) { + Some(payment_mode_name) => serde_json::from_str( + &format!( + "\"{}\"", + payment_mode_name.to_ascii_uppercase() + ) + ).expect("Could not parse payment mode"), + None => PaymentMode::Cheque + } }; generalized_answers.push(generalized_answer); diff --git a/src/sync_helloasso.rs b/src/sync_helloasso.rs index b87d14f..2255b6a 100644 --- a/src/sync_helloasso.rs +++ b/src/sync_helloasso.rs @@ -1,5 +1,6 @@ use crate::helloasso; use crate::paheko; +use crate::sync_paheko::PaymentMode; use crate::{ Config, UserCache, get_proxy_from_url, write_user_cache @@ -168,7 +169,8 @@ pub async fn sync_helloasso( subscription_amount, membership_mode: serde_json::from_value(serde_json::Value::String(answer.mode.clone())) .expect("Expected a membership mode to be valid"), - linked_user_first_name: read_custom_field(&answer, HelloassoCustomFieldType::LinkedUserFirstName) + linked_user_first_name: read_custom_field(&answer, HelloassoCustomFieldType::LinkedUserFirstName), + payment_mode: PaymentMode::CreditCard }; // apply custom user override diff --git a/src/sync_paheko.rs b/src/sync_paheko.rs index db52250..2cf1b1f 100644 --- a/src/sync_paheko.rs +++ b/src/sync_paheko.rs @@ -24,6 +24,17 @@ enum MembershipMode { BenefactorCouple, } +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[fully_pub] +enum PaymentMode { + #[serde(rename = "ESP")] + Cash, + #[serde(rename = "CB")] + CreditCard, + #[serde(rename = "CHQ")] + Cheque +} + #[derive(Debug, Clone)] #[fully_pub] struct GeneralizedAnswer { @@ -46,6 +57,7 @@ struct GeneralizedAnswer { subscription_amount: f64, donation_amount: f64, reference: String, + payment_mode: PaymentMode, linked_user_first_name: Option } @@ -244,7 +256,12 @@ pub async fn sync_paheko( inception_time: answer.inception_time, kind: paheko::TransactionKind::Revenue, linked_users: pk_users_summaries.iter().map(|x| x.id.clone()).collect(), - 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(), + payment_reference: serde_variant::to_variant_name(&answer.payment_mode) + .map(|x| x.to_string()) + .ok(), + notes: serde_json::to_string(&answer.payment_mode) + .map(|x| format!("Mode de paiement: {}", x)).ok() }; paheko_client.register_transaction(transaction) .await.context("Expected to create new paheko transaction")?; @@ -275,7 +292,12 @@ pub async fn sync_paheko( inception_time: answer.inception_time, kind: paheko::TransactionKind::Revenue, linked_users: pk_users_summaries.iter().map(|x| x.id.clone()).collect(), - linked_subscriptions: vec![] + linked_subscriptions: vec![], + payment_reference: serde_variant::to_variant_name(&answer.payment_mode) + .map(|x| x.to_string()) + .ok(), + notes: serde_json::to_string(&answer.payment_mode) + .map(|x| format!("Mode de paiement: {}", x)).ok() }; paheko_client.register_transaction(transaction) .await.context("Expected to create new paheko transaction for donation")?; diff --git a/src/test_utils.rs b/src/test_utils.rs index 3526b49..26e1ece 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -1,4 +1,5 @@ use crate::utils::{normalize_str, normalize_first_name}; +use crate::sync_paheko::PaymentMode; #[test] fn test_normalize_str() { @@ -25,3 +26,21 @@ fn test_normalize_first_name() { assert_eq!(out, "Jeffrey"); } + +#[test] +fn test_parse_payment_mode() { + let tmp = "\"ESP\"".to_string().to_ascii_uppercase(); + dbg!(&tmp); + assert_eq!( + serde_json::from_str::(&tmp).unwrap(), + PaymentMode::Cash + ) +} + +#[test] +fn test_payment_mode_to_string() { + assert_eq!( + serde_json::to_string(&PaymentMode::Cash).unwrap(), + "\"ESP\"" + ) +}