Skip to content

Commit

Permalink
chore: Update dependencies (#447)
Browse files Browse the repository at this point in the history
  • Loading branch information
azhur authored Jan 7, 2025
1 parent b17844b commit d92a231
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 72 deletions.
22 changes: 11 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ repository = "https://github.com/meteroid-oss/meteroid"
anyhow = "1.0.75"
argon2 = "0.5.2"
async-trait = "0.1.74"
axum = { version = "0.7.7", features = ["json", "query", "tower-log", "http1"] }
axum = { version = "0.8.1", features = ["json", "query", "tower-log", "http1"] }
base62 = "2.0.2"
base64 = "0.22.0"
build-info = "0.0.39"
Expand All @@ -65,8 +65,8 @@ fake = "3.0.0"
fang = { version = "0.10.4", default-features = false }
fastrand = "2.0.1"
fluent = "0.16"
fluent-static = "0.4.0"
fluent-static-codegen = "0.5.0"
fluent-static = "0.5.0"
fluent-static-codegen = "0.6.0"
futures = "0.3.28"
futures-lite = "2.3.0"
futures-util = { version = "0.3.29", features = [] }
Expand All @@ -79,7 +79,7 @@ humantime = { version = "2.1.0" }
hyper = { version = "1.4.1", default-features = false }
image = "0.25.2"
init-tracing-opentelemetry = { version = "0.25.0", features = ["tracing_subscriber_ext"] }
itertools = "0.13.0"
itertools = "0.14.0"
jsonwebtoken = "9.2.0"
lapin = "2.5.0"
log = "0.4.20"
Expand Down Expand Up @@ -107,7 +107,7 @@ rand_chacha = "0.3.1"
rand_distr = "0.4.3"
rdkafka = "0.37.0"
reqwest = { version = "0.12.5", default-features = false }
rstest = "0.23.0"
rstest = "0.24.0"
rust_decimal = "1.32.0"
rust_decimal_macros = "1.32.0"
rustls = { version = "0.23.12", default-features = false }
Expand Down Expand Up @@ -151,12 +151,12 @@ typetag = "0.2.13"
unic-langid = "0.9"
url = "2.4.1"
uuid = "1.4.1"
utoipa = { version = "5.3.0", features = ["axum_extras", "uuid", "debug", "chrono"] }
utoipa-axum = { version = "0.1.3" }
utoipa-swagger-ui = { version = "8.0.3", features = ["axum"] }
utoipa-redoc = { version = "5.0.0", features = ["axum"] }
utoipa-rapidoc = { version = "5.0.0", features = ["axum"] }
utoipa-scalar = { version = "0.2.0", features = ["axum"] }
utoipa = { version = "5.3.1", features = ["axum_extras", "uuid", "debug", "chrono"] }
utoipa-axum = { version = "0.1.4" }
utoipa-swagger-ui = { version = "8.1.1", features = ["axum"] }
utoipa-redoc = { version = "5.0.1", features = ["axum"] }
utoipa-rapidoc = { version = "5.0.1", features = ["axum"] }
utoipa-scalar = { version = "0.2.1", features = ["axum"] }

# TODO prefix it all
common-build-info = { path = "crates/common-build-info" }
Expand Down
7 changes: 0 additions & 7 deletions modules/meteroid/crates/meteroid-invoicing/build.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
use fluent_static_codegen::{generate, FunctionPerMessageCodeGenerator};
use std::env;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;

pub fn main() {
generate!(
"./l10n",
FunctionPerMessageCodeGenerator::new("en-US"),
"l10n.rs"
);

// let's generate statics for the countries.json
generate_country_translation()
}
Expand Down
86 changes: 48 additions & 38 deletions modules/meteroid/crates/meteroid-invoicing/src/html_render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@ use crate::errors::InvoicingError;
use crate::model::*;
use chrono::prelude::*;
use chrono::NaiveDate;
use fluent_static::{LanguageAware, MessageBundle};
use maud::{html, Markup, DOCTYPE};
use rust_decimal::Decimal;
use rusty_money::{iso, FormattableCurrency};

#[allow(clippy::all)]
mod l10n {
fluent_static::include_source!("l10n.rs");
use fluent_static::message_bundle;
#[message_bundle(
resources = [
("l10n/en-US/invoice.ftl", "en-US"),
("l10n/fr-FR/invoice.ftl", "fr-FR"),
],
default_language = "en-US")]
pub struct InvoiceL10n;

include!(concat!(env!("OUT_DIR"), "/i18n_data.rs"));

pub fn get_country_local_name<'a>(lang: &str, country_code: &str) -> Option<&'a str> {
Expand Down Expand Up @@ -38,13 +47,15 @@ pub fn render_invoice(invoice: &Invoice) -> Result<Markup, InvoicingError> {
_ => "en-US",
};

let invoice_l10n = &l10n::InvoiceL10N::get(lang).unwrap_or(l10n::InvoiceL10N::default());

Ok(html! {
(DOCTYPE)
html lang="en" {
head {
meta charset="UTF-8";
meta name="viewport" content="width=device-width, initial-scale=1.0";
title { (l10n::invoice::invoice_title(lang) )};
title { (invoice_l10n.invoice_title() )};
link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"; // TODO include it in docker
style {
(CSS)
Expand All @@ -61,62 +72,61 @@ pub fn render_invoice(invoice: &Invoice) -> Result<Markup, InvoicingError> {
}
body class="" {
div class="container mx-auto px-2 py-4 bg-white text-sm" {
(render_header(lang, &invoice.organization, &invoice.metadata)?)
(render_billing_info(lang, &invoice.organization, &invoice.customer, &invoice.metadata)?)
(render_invoice_lines(lang, &invoice.lines, &invoice.metadata.currency)?)
(render_invoice_summary(lang, &invoice.metadata ))
(render_legal_info(lang, &invoice.organization, &invoice.metadata)?)
(render_header(invoice_l10n, &invoice.organization, &invoice.metadata)?)
(render_billing_info(invoice_l10n, &invoice.organization, &invoice.customer, &invoice.metadata)?)
(render_invoice_lines(invoice_l10n, &invoice.lines, &invoice.metadata.currency)?)
(render_invoice_summary(invoice_l10n, &invoice.metadata ))
(render_legal_info(invoice_l10n, &invoice.organization, &invoice.metadata)?)
}
}
}
})
}

fn render_header(
lang: &str,
invoice_l10n: &l10n::InvoiceL10N,
organization: &Organization,
invoice: &InvoiceMetadata,
) -> Result<Markup, InvoicingError> {
Ok(html! {
div class="px-2 flex justify-between items-center border-b pb-4" {
h1 class="text-xl font-semibold text-gray-800" { (l10n::invoice::invoice_number(lang, &invoice.number)
.map_err(|_| InvoicingError::I18nError(format!("Failed to localise invoice number for value: {}", &invoice.number)))? )
h1 class="text-xl font-semibold text-gray-800" { (invoice_l10n.invoice_number(&invoice.number))
}
@if let Some(logo_url) = &organization.logo_url {
img src=(logo_url) alt=(l10n::invoice::company_logo_alt(lang));
img src=(logo_url) alt=(invoice_l10n.company_logo_alt());
}
}
})
}

fn render_billing_info(
lang: &str,
invoice_l10n: &l10n::InvoiceL10N,
organization: &Organization,
customer: &Customer,
invoice: &InvoiceMetadata,
) -> Result<Markup, InvoicingError> {
Ok(html! {
div class="grid grid-cols-3 mb-8" {
div class="flex flex-col p-4 border-b border-r border-gray-200" {
h2 class="text-md mb-2 text-gray-700" { (l10n::invoice::bill_from(lang)) }
(render_address( organization, lang))
h2 class="text-md mb-2 text-gray-700" { (invoice_l10n.bill_from()) }
(render_address( organization, invoice_l10n.language_id()))
}
div class="flex flex-col p-4 border-b border-gray-200" {
h2 class="text-md mb-2 text-gray-700" { (l10n::invoice::bill_to(lang)) }
(render_address( customer, lang))
h2 class="text-md mb-2 text-gray-700" { (invoice_l10n.bill_to()) }
(render_address( customer, invoice_l10n.language_id()))
}
div class="p-4 border-b border-l border-gray-200" {
h2 class="text-right text-md mb-2 text-gray-700" { (l10n::invoice::amount_due(lang)) }
h2 class="text-right text-md mb-2 text-gray-700" { (invoice_l10n.amount_due()) }
p class="text-right mb-2 text-xl font-bold text-green-600" { (format_currency_minor(invoice.total_amount, &invoice.currency)) }

div class="grid grid-cols-2 text-xs " {
div {
p class="text-gray-600" { (l10n::invoice::issue_date(lang)) }
p class="font-medium" { (format_date(lang, &invoice.issue_date)?) }
p class="text-gray-600" { (invoice_l10n.issue_date()) }
p class="font-medium" { (format_date(invoice_l10n.language_id(), &invoice.issue_date)?) }
}
div{
p class="text-gray-600" { (l10n::invoice::due_date(lang)) }
p class="font-medium" { (format_date(lang, &invoice.due_date)?) }
p class="text-gray-600" { (invoice_l10n.due_date()) }
p class="font-medium" { (format_date(invoice_l10n.language_id(), &invoice.due_date)?) }
}
}
}
Expand All @@ -128,21 +138,21 @@ fn render_billing_info(
}

fn render_invoice_lines(
lang: &str,
invoice_l10n: &l10n::InvoiceL10N,
lines: &[InvoiceLine],
currency: &iso::Currency,
) -> Result<Markup, InvoicingError> {
Ok(html! {
div class="mb-8" {
h2 class="px-2 text-md font-semibold mb-4 text-gray-700 uppercase" { (l10n::invoice::invoice_lines(lang)) }
h2 class="px-2 text-md font-semibold mb-4 text-gray-700 uppercase" { (invoice_l10n.invoice_lines()) }
table class="w-full border-collapse" {
thead {
tr class="text-gray-500 text-sm" {
th class="p-2 text-left" { (l10n::invoice::description(lang)) }
th class="p-2 text-right" { (l10n::invoice::quantity(lang)) }
th class="p-2 text-right" { (l10n::invoice::unit_price(lang)) }
th class="p-2 text-right" { (l10n::invoice::tax_rate(lang)) }
th class="p-2 text-right" { (l10n::invoice::amount(lang)) }
th class="p-2 text-left" { (invoice_l10n.description()) }
th class="p-2 text-right" { (invoice_l10n.quantity()) }
th class="p-2 text-right" { (invoice_l10n.unit_price()) }
th class="p-2 text-right" { (invoice_l10n.tax_rate()) }
th class="p-2 text-right" { (invoice_l10n.amount()) }
}
}
tbody {
Expand All @@ -154,7 +164,7 @@ fn render_invoice_lines(
div class="text-sm text-gray-500" { (desc) }
}
div class="text-sm text-gray-500" {
(format!("{} → {}", format_date_short(lang, &line.start_date)?, format_date_short(lang, &line.end_date)?))
(format!("{} → {}", format_date_short(invoice_l10n.language_id(), &line.start_date)?, format_date_short(invoice_l10n.language_id(), &line.end_date)?))
}
}
td class="p-2 text-right text-gray-600" {
Expand Down Expand Up @@ -199,22 +209,22 @@ fn render_invoice_lines(
})
}

fn render_invoice_summary(lang: &str, invoice: &InvoiceMetadata) -> Markup {
fn render_invoice_summary(invoice_l10n: &l10n::InvoiceL10N, invoice: &InvoiceMetadata) -> Markup {
html! {
div class="grid grid-cols-2 border-b border-gray-200 mb-8" {
div {}
div class="mb-4 rounded-lg p-4 bg-gray-50" {
table class="w-full" {
tr class="font-semibold" {
td class="p-2" { (l10n::invoice::subtotal(lang)) }
td class="p-2" { (invoice_l10n.subtotal()) }
td class="p-2 text-right font-medium" { (format_currency_minor(invoice.subtotal, &invoice.currency)) }
}
tr {
td class="p-2 text-gray-600" { (l10n::invoice::tax(lang)) " " (format_percentage_minor(invoice.tax_rate)) }
td class="p-2 text-gray-600" { (invoice_l10n.tax()) " " (format_percentage_minor(invoice.tax_rate)) }
td class="p-2 text-right font-medium text-gray-800" { (format_currency_minor(invoice.tax_amount, &invoice.currency)) }
}
tr class="border-t border-gray-200" {
td class="p-2 text-lg font-semibold text-gray-700" { (l10n::invoice::total_due(lang)) }
td class="p-2 text-lg font-semibold text-gray-700" { (invoice_l10n.total_due()) }
td class="p-2 text-right text-lg font-bold text-green-600" { (format_currency_minor(invoice.total_amount, &invoice.currency)) }
}
}
Expand All @@ -224,13 +234,13 @@ fn render_invoice_summary(lang: &str, invoice: &InvoiceMetadata) -> Markup {
}

fn render_legal_info(
lang: &str,
invoice_l10n: &l10n::InvoiceL10N,
organization: &Organization,
invoice: &InvoiceMetadata,
) -> Result<Markup, InvoicingError> {
let exchange_rate_text = match organization.exchange_rate {
Some(rate) => {
let date = format_date(lang, &invoice.issue_date)
let date = format_date(invoice_l10n.language_id(), &invoice.issue_date)
.map_err(|_| InvoicingError::I18nError("Failed to format date".to_string()))?;
let equality = format!(
"1 {} = {} {}",
Expand All @@ -243,18 +253,18 @@ fn render_legal_info(
&organization.accounting_currency,
);

l10n::invoice::exchange_rate_info(lang, &equality, &amount_converted, &date).ok()
Some(invoice_l10n.exchange_rate_info(&date, &equality, &amount_converted))
}
None => None,
};

Ok(html! {
div class="px-2 mb-8 text-gray-700" {
h2 class="text-md font-semibold mb-4 text-gray-700 uppercase" { (l10n::invoice::legal_info(lang)) }
h2 class="text-md font-semibold mb-4 text-gray-700 uppercase" { (invoice_l10n.legal_info()) }

// TODO need proper tax info engine for other EU countries
@if invoice.tax_rate == 0 {
p { (l10n::invoice::vat_exempt_legal(lang)) }
p { (invoice_l10n.vat_exempt_legal()) }
}
@if let Some(footer_info) = &organization.footer_info {
p { (footer_info) }
Expand Down
4 changes: 2 additions & 2 deletions modules/meteroid/src/adapters/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct ParsedRequest {
pub query_params: Option<String>,
}

#[axum::async_trait]
#[async_trait::async_trait]
pub trait WebhookAdapter: AdapterCommon + Sync {
async fn verify_webhook(
&self,
Expand All @@ -40,7 +40,7 @@ pub trait WebhookAdapter: AdapterCommon + Sync {
) -> Result<bool, errors::AdapterWebhookError>;
}

#[axum::async_trait]
#[async_trait::async_trait]
pub trait InvoicingAdapter: AdapterCommon + Sync {
async fn send_invoice(
&self,
Expand Down
2 changes: 1 addition & 1 deletion modules/meteroid/src/api_rest/customers/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub(crate) async fn list_customers(
#[utoipa::path(
get,
tag = "customer",
path = "/api/v1/customers/:id_or_alias",
path = "/api/v1/customers/{id_or_alias}",
params(
("id_or_alias" = String, Path, description = "customer ID or alias")
),
Expand Down
4 changes: 2 additions & 2 deletions modules/meteroid/src/api_rest/files/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ pub use router::FileApi;

pub fn file_routes() -> Router<AppState> {
Router::new()
.route("/v1/logo/:uuid", get(router::get_logo))
.route("/v1/invoice/pdf/:uuid", get(router::get_invoice_pdf))
.route("/v1/logo/{uuid}", get(router::get_logo))
.route("/v1/invoice/pdf/{uuid}", get(router::get_invoice_pdf))
}
4 changes: 2 additions & 2 deletions modules/meteroid/src/api_rest/files/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct FileApi;
#[utoipa::path(
get,
tag = "file",
path = "/v1/logo/:uuid",
path = "/v1/logo/{uuid}",
params(
("uuid" = Uuid, Path, description = "Logo database UUID")
),
Expand Down Expand Up @@ -83,7 +83,7 @@ pub struct TokenParams {
#[utoipa::path(
get,
tag = "file",
path = "/v1/invoice/pdf/:uid",
path = "/v1/invoice/pdf/{uid}",
params(
("uid" = String, Path, description = "Invoice database UID"),
("token" = str, Query, description = "Security token"),
Expand Down
2 changes: 1 addition & 1 deletion modules/meteroid/src/api_rest/subscriptions/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ async fn list_subscriptions_handler(
#[utoipa::path(
get,
tag = "subscription",
path = "/api/v1/subscriptions/:id",
path = "/api/v1/subscriptions/{id}",
params(
("id" = String, Path, description = "subscription ID")
),
Expand Down
5 changes: 1 addition & 4 deletions modules/meteroid/src/api_rest/webhooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ mod router;

pub fn webhook_routes() -> Router<AppState> {
Router::new()
.route(
"/v1/:provider/:endpoint_uid",
post(crate::api_rest::webhooks::router::axum_handler),
)
.route("/v1/{provider}/{endpoint_uid}", post(router::axum_handler))
.layer(DefaultBodyLimit::max(4096))
}
Loading

0 comments on commit d92a231

Please sign in to comment.