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:
Calum H.
2026-03-03 17:45:28 +00:00
committed by GitHub
parent 34997bada5
commit 211ec20970
5 changed files with 81 additions and 11 deletions

View File

@@ -140,8 +140,6 @@ AVALARA_1099_API_KEY=none
AVALARA_1099_API_TEAM_ID=none
AVALARA_1099_COMPANY_ID=207337084
COMPLIANCE_PAYOUT_THRESHOLD=disabled
ANROK_API_KEY=none
ANROK_API_URL=none

View File

@@ -150,8 +150,6 @@ AVALARA_1099_API_KEY=none
AVALARA_1099_API_TEAM_ID=none
AVALARA_1099_COMPANY_ID=207337084
COMPLIANCE_PAYOUT_THRESHOLD=disabled
ANROK_API_KEY=none
ANROK_API_URL=none

View File

@@ -242,8 +242,6 @@ vars! {
ANROK_API_URL: String;
ANROK_API_KEY: String;
COMPLIANCE_PAYOUT_THRESHOLD: String;
PAYOUT_ALERT_SLACK_WEBHOOK: String;
CLOUDFLARE_INTEGRATION: bool = false;

View File

@@ -1,7 +1,13 @@
use std::{collections::HashMap, sync::LazyLock};
use std::{
collections::HashMap,
sync::{Arc, LazyLock},
};
use crate::env::ENV;
use actix_web::{get, web};
use arc_swap::ArcSwapOption;
use chrono::{Datelike, Utc};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
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",
});
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.
#[utoipa::path]
#[get("")]
pub async fn get_globals() -> web::Json<Globals> {
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)));
}
}

View File

@@ -11,6 +11,7 @@ use crate::models::payouts::{PayoutMethodType, PayoutStatus, Withdrawal};
use crate::queue::payouts::PayoutsQueue;
use crate::queue::session::AuthQueue;
use crate::routes::ApiError;
use crate::routes::internal::globals::tax_compliance_payout_threshold;
use crate::util::avalara1099;
use crate::util::error::Context;
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)]
pub struct RevenueQuery {
pub start: Option<DateTime<Utc>>,