Skip to content

Commit bab9b8c

Browse files
committed
Initial Anrok integration
1 parent af3b829 commit bab9b8c

File tree

10 files changed

+1207
-444
lines changed

10 files changed

+1207
-444
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
ALTER TABLE charges ADD COLUMN tax_amount BIGINT NOT NULL DEFAULT 0;
2+
ALTER TABLE charges ADD COLUMN tax_platform_id TEXT;
3+
4+
ALTER TABLE users_subscriptions ADD COLUMN user_aware_of_tax_changes BOOLEAN NOT NULL DEFAULT FALSE;
5+
6+
CREATE TABLE products_tax_identifiers (
7+
id SERIAL PRIMARY KEY,
8+
tax_processor_id TEXT NOT NULL,
9+
product_id BIGINT REFERENCES products(id) NOT NULL
10+
);

apps/labrinth/src/database/models/charge_item.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ pub struct DBCharge {
2626

2727
pub parent_charge_id: Option<DBChargeId>,
2828

29+
pub tax_amount: i64,
30+
pub tax_platform_id: Option<String>,
31+
2932
// Net is always in USD
3033
pub net: Option<i64>,
3134
}
@@ -45,6 +48,8 @@ struct ChargeQueryResult {
4548
payment_platform: String,
4649
payment_platform_id: Option<String>,
4750
parent_charge_id: Option<i64>,
51+
tax_amount: i64,
52+
tax_platform_id: Option<String>,
4853
net: Option<i64>,
4954
}
5055

@@ -69,6 +74,8 @@ impl TryFrom<ChargeQueryResult> for DBCharge {
6974
payment_platform: PaymentPlatform::from_string(&r.payment_platform),
7075
payment_platform_id: r.payment_platform_id,
7176
parent_charge_id: r.parent_charge_id.map(DBChargeId),
77+
tax_amount: r.tax_amount,
78+
tax_platform_id: r.tax_platform_id,
7279
net: r.net,
7380
})
7481
}
@@ -81,7 +88,7 @@ macro_rules! select_charges_with_predicate {
8188
r#"
8289
SELECT
8390
id, user_id, price_id, amount, currency_code, status, due, last_attempt,
84-
charge_type, subscription_id,
91+
charge_type, subscription_id, tax_amount, tax_platform_id,
8592
-- Workaround for https://github.com/launchbadge/sqlx/issues/3336
8693
subscription_interval AS "subscription_interval?",
8794
payment_platform,
@@ -103,8 +110,8 @@ impl DBCharge {
103110
) -> Result<DBChargeId, DatabaseError> {
104111
sqlx::query!(
105112
r#"
106-
INSERT INTO charges (id, user_id, price_id, amount, currency_code, charge_type, status, due, last_attempt, subscription_id, subscription_interval, payment_platform, payment_platform_id, parent_charge_id, net)
107-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
113+
INSERT INTO charges (id, user_id, price_id, amount, currency_code, charge_type, status, due, last_attempt, subscription_id, subscription_interval, payment_platform, payment_platform_id, parent_charge_id, net, tax_amount, tax_platform_id)
114+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
108115
ON CONFLICT (id)
109116
DO UPDATE
110117
SET status = EXCLUDED.status,
@@ -116,6 +123,8 @@ impl DBCharge {
116123
payment_platform_id = EXCLUDED.payment_platform_id,
117124
parent_charge_id = EXCLUDED.parent_charge_id,
118125
net = EXCLUDED.net,
126+
tax_amount = EXCLUDED.tax_amount,
127+
tax_platform_id = EXCLUDED.tax_platform_id,
119128
price_id = EXCLUDED.price_id,
120129
amount = EXCLUDED.amount,
121130
currency_code = EXCLUDED.currency_code,
@@ -136,6 +145,8 @@ impl DBCharge {
136145
self.payment_platform_id.as_deref(),
137146
self.parent_charge_id.map(|x| x.0),
138147
self.net,
148+
self.tax_amount,
149+
self.tax_platform_id.as_deref(),
139150
)
140151
.execute(&mut **transaction)
141152
.await?;

apps/labrinth/src/database/models/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub mod organization_item;
1717
pub mod pat_item;
1818
pub mod payout_item;
1919
pub mod product_item;
20+
pub mod products_tax_identifier_item;
2021
pub mod project_item;
2122
pub mod report_item;
2223
pub mod session_item;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use crate::database::models::ids::{DBProductId, DBProductPriceId};
2+
use crate::models::billing::ProductMetadata;
3+
use crate::routes::ApiError;
4+
5+
pub struct DBProductsTaxIdentifier {
6+
pub id: i32,
7+
pub tax_processor_id: String,
8+
pub product_id: DBProductId,
9+
}
10+
11+
pub struct ProductInfo {
12+
pub tax_identifier: DBProductsTaxIdentifier,
13+
pub product_metadata: ProductMetadata,
14+
}
15+
16+
impl DBProductsTaxIdentifier {
17+
pub async fn get_product(
18+
product_id: DBProductId,
19+
exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
20+
) -> Result<Option<Self>, ApiError> {
21+
let maybe_row = sqlx::query!(
22+
"SELECT * FROM products_tax_identifiers WHERE product_id = $1",
23+
product_id.0,
24+
)
25+
.fetch_optional(exec)
26+
.await?;
27+
28+
Ok(maybe_row.map(|row| DBProductsTaxIdentifier {
29+
id: row.id,
30+
tax_processor_id: row.tax_processor_id,
31+
product_id: DBProductId(row.product_id),
32+
}))
33+
}
34+
}
35+
36+
pub async fn product_info_by_product_price_id(
37+
product_price_id: DBProductPriceId,
38+
exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
39+
) -> Result<Option<ProductInfo>, ApiError> {
40+
let maybe_row = sqlx::query!(
41+
r#"
42+
SELECT
43+
products_tax_identifiers.*,
44+
products.metadata product_metadata
45+
FROM products_prices
46+
LEFT JOIN products ON products.id = products_prices.product_id
47+
LEFT JOIN products_tax_identifiers ON products_tax_identifiers.product_id = products.id
48+
WHERE products_prices.id = $1
49+
"#,
50+
product_price_id.0 as i64,
51+
)
52+
.fetch_optional(exec)
53+
.await?;
54+
55+
match maybe_row {
56+
None => Ok(None),
57+
Some(row) => Ok(Some(ProductInfo {
58+
tax_identifier: DBProductsTaxIdentifier {
59+
id: row.id,
60+
tax_processor_id: row.tax_processor_id,
61+
product_id: DBProductId(row.product_id),
62+
},
63+
product_metadata: serde_json::from_value(row.product_metadata)?,
64+
})),
65+
}
66+
}

apps/labrinth/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ pub fn check_env_vars() -> bool {
487487
failed |= check_var::<String>("AVALARA_1099_API_TEAM_ID");
488488
failed |= check_var::<String>("AVALARA_1099_COMPANY_ID");
489489

490+
failed |= check_var::<String>("ANROK_API_URL");
491+
failed |= check_var::<String>("ANROK_API_KEY");
492+
490493
failed |= check_var::<String>("COMPLIANCE_PAYOUT_THRESHOLD");
491494

492495
failed |= check_var::<String>("ARCHON_URL");

0 commit comments

Comments
 (0)