feat: three nuxt frontends, demo seed, rounding + money-exponent + rate-cast fixes, archived specs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use rust_decimal::prelude::*;
|
||||
use rust_decimal::Decimal;
|
||||
use rust_decimal::{Decimal, RoundingStrategy};
|
||||
|
||||
use crate::error::ApiError;
|
||||
use crate::models::Currency;
|
||||
@@ -16,7 +16,8 @@ pub fn convert_minor(amount_minor: i64, from: &Currency, to: &Currency) -> Resul
|
||||
let to_scale = Decimal::from(10i64.pow(to.exponent as u32));
|
||||
// minor(from) -> major(from) -> major(base) -> minor(to)
|
||||
let base_major = amount / from_scale / from.rate_to_base;
|
||||
let target = (base_major * to.rate_to_base * to_scale).round_dp(0);
|
||||
let target = (base_major * to.rate_to_base * to_scale)
|
||||
.round_dp_with_strategy(0, RoundingStrategy::MidpointAwayFromZero);
|
||||
target
|
||||
.to_i64()
|
||||
.ok_or_else(|| ApiError::BadRequest("amount out of range".into()))
|
||||
|
||||
@@ -146,6 +146,15 @@ async fn currency_conversion_math() {
|
||||
assert_eq!(body["amount_minor"], 1500);
|
||||
assert_eq!(body["currency"], "JPY");
|
||||
|
||||
// midpoint rounds half-up (away from zero), not banker's rounding:
|
||||
// 1999 minor USD ($19.99) -> JPY at rate 150 => 2998.5 -> 2999
|
||||
let res = client()
|
||||
.get(app.url("/api/currencies/convert?amount_minor=1999&from=USD&to=JPY"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(res.json::<serde_json::Value>().await.unwrap()["amount_minor"], 2999);
|
||||
|
||||
// disabled currency rejected
|
||||
let admin = login_admin(&app).await;
|
||||
let res = client()
|
||||
|
||||
Reference in New Issue
Block a user