fix: remove tax compliance env var (#5445)
* fix: remove tax compliance env var * improve tax compliance year logic * bit more tests --------- Co-authored-by: aecsocket <aecsocket@tutanota.com>
This commit is contained in:
@@ -140,8 +140,6 @@ AVALARA_1099_API_KEY=none
|
|||||||
AVALARA_1099_API_TEAM_ID=none
|
AVALARA_1099_API_TEAM_ID=none
|
||||||
AVALARA_1099_COMPANY_ID=207337084
|
AVALARA_1099_COMPANY_ID=207337084
|
||||||
|
|
||||||
COMPLIANCE_PAYOUT_THRESHOLD=disabled
|
|
||||||
|
|
||||||
ANROK_API_KEY=none
|
ANROK_API_KEY=none
|
||||||
ANROK_API_URL=none
|
ANROK_API_URL=none
|
||||||
|
|
||||||
|
|||||||
@@ -150,8 +150,6 @@ AVALARA_1099_API_KEY=none
|
|||||||
AVALARA_1099_API_TEAM_ID=none
|
AVALARA_1099_API_TEAM_ID=none
|
||||||
AVALARA_1099_COMPANY_ID=207337084
|
AVALARA_1099_COMPANY_ID=207337084
|
||||||
|
|
||||||
COMPLIANCE_PAYOUT_THRESHOLD=disabled
|
|
||||||
|
|
||||||
ANROK_API_KEY=none
|
ANROK_API_KEY=none
|
||||||
ANROK_API_URL=none
|
ANROK_API_URL=none
|
||||||
|
|
||||||
|
|||||||
@@ -242,8 +242,6 @@ vars! {
|
|||||||
ANROK_API_URL: String;
|
ANROK_API_URL: String;
|
||||||
ANROK_API_KEY: String;
|
ANROK_API_KEY: String;
|
||||||
|
|
||||||
COMPLIANCE_PAYOUT_THRESHOLD: String;
|
|
||||||
|
|
||||||
PAYOUT_ALERT_SLACK_WEBHOOK: String;
|
PAYOUT_ALERT_SLACK_WEBHOOK: String;
|
||||||
CLOUDFLARE_INTEGRATION: bool = false;
|
CLOUDFLARE_INTEGRATION: bool = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
use std::{collections::HashMap, sync::LazyLock};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{Arc, LazyLock},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::env::ENV;
|
use crate::env::ENV;
|
||||||
use actix_web::{get, web};
|
use actix_web::{get, web};
|
||||||
|
use arc_swap::ArcSwapOption;
|
||||||
|
use chrono::{Datelike, Utc};
|
||||||
|
use rust_decimal::Decimal;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub fn config(cfg: &mut utoipa_actix_web::service_config::ServiceConfig) {
|
pub fn config(cfg: &mut utoipa_actix_web::service_config::ServiceConfig) {
|
||||||
@@ -33,9 +39,82 @@ static GLOBALS: LazyLock<Globals> = LazyLock::new(|| Globals {
|
|||||||
&& ENV.HCAPTCHA_SECRET != "none",
|
&& ENV.HCAPTCHA_SECRET != "none",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
struct TaxComplianceCache {
|
||||||
|
year: i32,
|
||||||
|
value: Option<Decimal>,
|
||||||
|
}
|
||||||
|
|
||||||
|
static TAX_COMPLIANCE_CACHE: ArcSwapOption<TaxComplianceCache> =
|
||||||
|
ArcSwapOption::const_empty();
|
||||||
|
|
||||||
|
pub fn tax_compliance_payout_threshold() -> Option<Decimal> {
|
||||||
|
tax_compliance_payout_threshold_for_year(Utc::now().year())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tax_compliance_payout_threshold_for_year(
|
||||||
|
current_year: i32,
|
||||||
|
) -> Option<Decimal> {
|
||||||
|
let cache = TAX_COMPLIANCE_CACHE.load();
|
||||||
|
|
||||||
|
if let Some(cache) = &*cache
|
||||||
|
&& cache.year == current_year
|
||||||
|
{
|
||||||
|
return cache.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = (|| {
|
||||||
|
if let Some(value_this_year) = GLOBALS
|
||||||
|
.tax_compliance_thresholds
|
||||||
|
.get(&(current_year as u16))
|
||||||
|
.copied()
|
||||||
|
{
|
||||||
|
return Some(Decimal::from(value_this_year));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut years_to_values = GLOBALS
|
||||||
|
.tax_compliance_thresholds
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| (*k, *v))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
years_to_values.sort_by_key(|(year, _)| *year);
|
||||||
|
|
||||||
|
let &(_, last_value) = years_to_values.last()?;
|
||||||
|
Some(Decimal::from(last_value))
|
||||||
|
})();
|
||||||
|
|
||||||
|
TAX_COMPLIANCE_CACHE.store(Some(Arc::new(TaxComplianceCache {
|
||||||
|
year: current_year,
|
||||||
|
value,
|
||||||
|
})));
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets configured global non-secret variables for this backend instance.
|
/// Gets configured global non-secret variables for this backend instance.
|
||||||
#[utoipa::path]
|
#[utoipa::path]
|
||||||
#[get("")]
|
#[get("")]
|
||||||
pub async fn get_globals() -> web::Json<Globals> {
|
pub async fn get_globals() -> web::Json<Globals> {
|
||||||
web::Json(GLOBALS.clone())
|
web::Json(GLOBALS.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cache_rolls_over_by_year() {
|
||||||
|
TAX_COMPLIANCE_CACHE.store(None);
|
||||||
|
|
||||||
|
let first = tax_compliance_payout_threshold_for_year(2025);
|
||||||
|
assert_eq!(first, Some(Decimal::from(600_u64)));
|
||||||
|
|
||||||
|
let second = tax_compliance_payout_threshold_for_year(2026);
|
||||||
|
assert_eq!(second, Some(Decimal::from(2000_u64)));
|
||||||
|
|
||||||
|
let second = tax_compliance_payout_threshold_for_year(2027);
|
||||||
|
assert_eq!(second, Some(Decimal::from(2000_u64)));
|
||||||
|
|
||||||
|
TAX_COMPLIANCE_CACHE.store(None);
|
||||||
|
let second = tax_compliance_payout_threshold_for_year(2027);
|
||||||
|
assert_eq!(second, Some(Decimal::from(2000_u64)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::models::payouts::{PayoutMethodType, PayoutStatus, Withdrawal};
|
|||||||
use crate::queue::payouts::PayoutsQueue;
|
use crate::queue::payouts::PayoutsQueue;
|
||||||
use crate::queue::session::AuthQueue;
|
use crate::queue::session::AuthQueue;
|
||||||
use crate::routes::ApiError;
|
use crate::routes::ApiError;
|
||||||
|
use crate::routes::internal::globals::tax_compliance_payout_threshold;
|
||||||
use crate::util::avalara1099;
|
use crate::util::avalara1099;
|
||||||
use crate::util::error::Context;
|
use crate::util::error::Context;
|
||||||
use crate::util::gotenberg::GotenbergClient;
|
use crate::util::gotenberg::GotenbergClient;
|
||||||
@@ -1116,10 +1117,6 @@ async fn update_compliance_status(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tax_compliance_payout_threshold() -> Option<Decimal> {
|
|
||||||
ENV.COMPLIANCE_PAYOUT_THRESHOLD.parse().ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct RevenueQuery {
|
pub struct RevenueQuery {
|
||||||
pub start: Option<DateTime<Utc>>,
|
pub start: Option<DateTime<Utc>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user