conversions web3
This commit is contained in:
@@ -24,10 +24,6 @@ pub(crate) fn router() -> Router<AppState> {
|
||||
"/admin/exchange-rates/configuration",
|
||||
post(workspace_logic::add_configuration),
|
||||
)
|
||||
.route(
|
||||
"/admin/exchange-rates/preview",
|
||||
post(workspace_logic::preview),
|
||||
)
|
||||
.route(
|
||||
"/admin/exchange-rates/evidence",
|
||||
post(workspace_logic::evidence),
|
||||
|
||||
@@ -128,8 +128,6 @@ pub(crate) async fn load_workspace(
|
||||
settings,
|
||||
can_configure: crate::authz::can_manage(&authorization, crate::authz::STRUCT_TABLE),
|
||||
configuration: inputs.configuration,
|
||||
preview_form: inputs.preview_form,
|
||||
preview: inputs.preview,
|
||||
evidence_form: inputs.evidence_form,
|
||||
evidence: inputs.evidence,
|
||||
evidence_has_exchange: inputs.evidence_has_exchange,
|
||||
|
||||
@@ -9,10 +9,7 @@ use axum_extra::extract::Form;
|
||||
|
||||
use crate::{
|
||||
AppState,
|
||||
definitions::exchange_rates::{
|
||||
AddProfileCurrencySourceRequest, ExchangeRateDateRule, ExchangeRateSource,
|
||||
ListConversionEvidenceRequest,
|
||||
},
|
||||
definitions::exchange_rates::{AddProfileCurrencySourceRequest, ListConversionEvidenceRequest},
|
||||
services::{authenticated_request, reject_cross_site},
|
||||
};
|
||||
|
||||
@@ -20,8 +17,7 @@ use super::{
|
||||
state::LoadError,
|
||||
workspace_loader::load_workspace,
|
||||
workspace_state::{
|
||||
ConfigurationForm, EvidenceForm, EvidenceView, PreviewForm, PreviewView, WorkspaceInputs,
|
||||
WorkspaceQuery,
|
||||
ConfigurationForm, EvidenceForm, EvidenceView, WorkspaceInputs, WorkspaceQuery,
|
||||
},
|
||||
workspace_ui,
|
||||
};
|
||||
@@ -90,57 +86,6 @@ pub(crate) async fn add_configuration(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn preview(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
Form(form): Form<PreviewForm>,
|
||||
) -> Response {
|
||||
if let Some(rejection) = reject_cross_site(&headers) {
|
||||
return rejection;
|
||||
}
|
||||
let mut inputs = WorkspaceInputs::for_profile(form.profile.clone());
|
||||
inputs.preview_form = form.clone();
|
||||
let request = match form.request() {
|
||||
Ok(request) => request,
|
||||
Err(key) => {
|
||||
inputs.error = Some(crate::tr!(crate::i18n::Locale::from_headers(&headers), key));
|
||||
return render_loaded(
|
||||
&headers,
|
||||
load_workspace(state, &headers, inputs).await,
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
);
|
||||
}
|
||||
};
|
||||
let Ok(request) = authenticated_request(&headers, request) else {
|
||||
return Redirect::to("/login").into_response();
|
||||
};
|
||||
let mut exchange_rates = state.exchange_rates.clone();
|
||||
match exchange_rates.preview_direct_conversion(request).await {
|
||||
Ok(response) => {
|
||||
let response = response.into_inner();
|
||||
let locale = crate::i18n::Locale::from_headers(&headers);
|
||||
inputs.preview = Some(PreviewView {
|
||||
applied_method: crate::tr!(locale, rate_method_key(response.applied_source)),
|
||||
applied_date_rule: crate::tr!(locale, date_rule_key(response.applied_date_rule)),
|
||||
response,
|
||||
});
|
||||
render_loaded(
|
||||
&headers,
|
||||
load_workspace(state, &headers, inputs).await,
|
||||
StatusCode::OK,
|
||||
)
|
||||
}
|
||||
Err(error) => {
|
||||
inputs.error = Some(error.message().to_string());
|
||||
render_loaded(
|
||||
&headers,
|
||||
load_workspace(state, &headers, inputs).await,
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn evidence(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
@@ -204,24 +149,6 @@ pub(crate) async fn evidence(
|
||||
}
|
||||
}
|
||||
|
||||
fn rate_method_key(value: i32) -> &'static str {
|
||||
match ExchangeRateSource::try_from(value).ok() {
|
||||
Some(ExchangeRateSource::Official) => "rates-source-official",
|
||||
Some(ExchangeRateSource::SavedCustom) => "rates-source-saved",
|
||||
Some(ExchangeRateSource::Manual) => "rates-source-manual",
|
||||
_ => "rates-unknown",
|
||||
}
|
||||
}
|
||||
|
||||
fn date_rule_key(value: i32) -> &'static str {
|
||||
match ExchangeRateDateRule::try_from(value).ok() {
|
||||
Some(ExchangeRateDateRule::PreviousPublication) => "rates-rule-previous",
|
||||
Some(ExchangeRateDateRule::OnOrBeforeDate) => "rates-rule-on-or-before",
|
||||
Some(ExchangeRateDateRule::SpecificPublicationDate) => "rates-rule-specific",
|
||||
_ => "rates-unknown",
|
||||
}
|
||||
}
|
||||
|
||||
fn render_loaded(
|
||||
headers: &HeaderMap,
|
||||
result: Result<super::workspace_state::ExchangeRateWorkspaceState, LoadError>,
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
//! State and form wire formats for the provider-neutral exchange-rate workspace.
|
||||
|
||||
use crate::definitions::exchange_rates::{
|
||||
ConversionEvidence, ExchangeRateDateRule, ExchangeRateSelection, ExchangeRateSource,
|
||||
PreviewDirectConversionRequest, PreviewDirectConversionResponse,
|
||||
};
|
||||
use crate::definitions::exchange_rates::ConversionEvidence;
|
||||
|
||||
use super::state::EcbPageState;
|
||||
|
||||
@@ -25,92 +22,6 @@ pub(crate) struct ConfigurationForm {
|
||||
pub make_default: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize)]
|
||||
pub(crate) struct PreviewForm {
|
||||
#[serde(default)]
|
||||
pub profile: String,
|
||||
#[serde(default)]
|
||||
pub original_amount: String,
|
||||
#[serde(default)]
|
||||
pub original_currency: String,
|
||||
#[serde(default)]
|
||||
pub conversion_basis_date: String,
|
||||
#[serde(default = "automatic_official")]
|
||||
pub method: String,
|
||||
#[serde(default = "ordinary_context")]
|
||||
pub context: String,
|
||||
#[serde(default)]
|
||||
pub specific_rate_date: String,
|
||||
#[serde(default)]
|
||||
pub manual_foreign_units: String,
|
||||
#[serde(default)]
|
||||
pub rate_source_id: String,
|
||||
#[serde(default)]
|
||||
pub reason: String,
|
||||
}
|
||||
|
||||
fn automatic_official() -> String {
|
||||
"automatic-official".to_string()
|
||||
}
|
||||
|
||||
fn ordinary_context() -> String {
|
||||
"ordinary".to_string()
|
||||
}
|
||||
|
||||
impl Default for PreviewForm {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
profile: String::new(),
|
||||
original_amount: String::new(),
|
||||
original_currency: String::new(),
|
||||
conversion_basis_date: String::new(),
|
||||
method: automatic_official(),
|
||||
context: ordinary_context(),
|
||||
specific_rate_date: String::new(),
|
||||
manual_foreign_units: String::new(),
|
||||
rate_source_id: String::new(),
|
||||
reason: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PreviewForm {
|
||||
pub(crate) fn request(&self) -> Result<PreviewDirectConversionRequest, &'static str> {
|
||||
let date_rule = match self.method.as_str() {
|
||||
"official-specific" | "manual" => ExchangeRateDateRule::SpecificPublicationDate,
|
||||
_ if self.context == "statement" => ExchangeRateDateRule::OnOrBeforeDate,
|
||||
_ => ExchangeRateDateRule::PreviousPublication,
|
||||
};
|
||||
let source = match self.method.as_str() {
|
||||
"automatic-official" | "official-specific" => ExchangeRateSource::Official,
|
||||
"saved-custom" => ExchangeRateSource::SavedCustom,
|
||||
"manual" => ExchangeRateSource::Manual,
|
||||
_ => return Err("rates-err-preview-method"),
|
||||
};
|
||||
let use_default_selection = self.method == "automatic-official"
|
||||
&& self.context != "statement"
|
||||
&& self.rate_source_id.trim().is_empty();
|
||||
let selection = (!use_default_selection).then(|| ExchangeRateSelection {
|
||||
date_rule: date_rule as i32,
|
||||
source: source as i32,
|
||||
specific_rate_date: (!self.specific_rate_date.trim().is_empty())
|
||||
.then(|| self.specific_rate_date.trim().to_string()),
|
||||
manual_foreign_units: (!self.manual_foreign_units.trim().is_empty())
|
||||
.then(|| self.manual_foreign_units.trim().to_string()),
|
||||
reason: self.reason.trim().to_string(),
|
||||
rate_source_id: (!self.rate_source_id.trim().is_empty())
|
||||
.then(|| self.rate_source_id.trim().to_string()),
|
||||
});
|
||||
Ok(PreviewDirectConversionRequest {
|
||||
original_amount: self.original_amount.trim().to_string(),
|
||||
original_currency: self.original_currency.trim().to_ascii_uppercase(),
|
||||
conversion_basis_date: self.conversion_basis_date.trim().to_string(),
|
||||
profile_name: self.profile.clone(),
|
||||
exchange_rate_selection: selection,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, serde::Deserialize)]
|
||||
pub(crate) struct EvidenceForm {
|
||||
#[serde(default)]
|
||||
@@ -154,44 +65,6 @@ pub(crate) struct ProfileSettingsView {
|
||||
pub foreign_currencies: Vec<CurrencySettingsView>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct PreviewView {
|
||||
pub response: PreviewDirectConversionResponse,
|
||||
pub applied_method: String,
|
||||
pub applied_date_rule: String,
|
||||
}
|
||||
|
||||
impl PreviewView {
|
||||
pub(crate) fn quote(&self) -> String {
|
||||
match (
|
||||
self.response.accounting_units.as_deref(),
|
||||
self.response.foreign_units.as_deref(),
|
||||
self.response.foreign_currency.as_deref(),
|
||||
) {
|
||||
(Some(accounting_units), Some(foreign_units), Some(foreign_currency)) => format!(
|
||||
"{} {} = {} {}",
|
||||
accounting_units,
|
||||
self.response.accounting_currency,
|
||||
foreign_units,
|
||||
foreign_currency,
|
||||
),
|
||||
_ => "—".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn observation_id(&self) -> String {
|
||||
self.response
|
||||
.official_observation_id
|
||||
.map_or_else(|| "—".to_string(), |id| id.to_string())
|
||||
}
|
||||
|
||||
pub(crate) fn import_batch_id(&self) -> String {
|
||||
self.response
|
||||
.import_batch_id
|
||||
.map_or_else(|| "—".to_string(), |id| id.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct EvidenceView {
|
||||
pub evidence: ConversionEvidence,
|
||||
@@ -200,8 +73,6 @@ pub(crate) struct EvidenceView {
|
||||
pub(crate) struct WorkspaceInputs {
|
||||
pub selected_profile: String,
|
||||
pub configuration: ConfigurationForm,
|
||||
pub preview_form: PreviewForm,
|
||||
pub preview: Option<PreviewView>,
|
||||
pub evidence_form: EvidenceForm,
|
||||
pub evidence: Vec<EvidenceView>,
|
||||
pub evidence_has_exchange: Option<bool>,
|
||||
@@ -215,8 +86,6 @@ impl WorkspaceInputs {
|
||||
Self {
|
||||
selected_profile: profile,
|
||||
configuration: ConfigurationForm::default(),
|
||||
preview_form: PreviewForm::default(),
|
||||
preview: None,
|
||||
evidence_form: EvidenceForm::default(),
|
||||
evidence: Vec::new(),
|
||||
evidence_has_exchange: None,
|
||||
@@ -235,8 +104,6 @@ pub(crate) struct ExchangeRateWorkspaceState {
|
||||
pub settings: Option<ProfileSettingsView>,
|
||||
pub can_configure: bool,
|
||||
pub configuration: ConfigurationForm,
|
||||
pub preview_form: PreviewForm,
|
||||
pub preview: Option<PreviewView>,
|
||||
pub evidence_form: EvidenceForm,
|
||||
pub evidence: Vec<EvidenceView>,
|
||||
pub evidence_has_exchange: Option<bool>,
|
||||
|
||||
@@ -45,7 +45,7 @@ mod tests {
|
||||
state::{EcbPageState, ImportBatchView},
|
||||
workspace_state::{
|
||||
ConfigurationForm, CurrencySettingsView, CurrencySourceView, EvidenceForm,
|
||||
ExchangeRateWorkspaceState, PreviewForm, ProfileSettingsView,
|
||||
ExchangeRateWorkspaceState, ProfileSettingsView,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -98,8 +98,6 @@ mod tests {
|
||||
}),
|
||||
can_configure: true,
|
||||
configuration: ConfigurationForm::default(),
|
||||
preview_form: PreviewForm::default(),
|
||||
preview: None,
|
||||
evidence_form: EvidenceForm::default(),
|
||||
evidence: Vec::new(),
|
||||
evidence_has_exchange: None,
|
||||
@@ -116,7 +114,6 @@ mod tests {
|
||||
|
||||
assert!(!html.contains("Template error"), "{html}");
|
||||
assert!(html.contains("Profile configuration"), "{html}");
|
||||
assert!(html.contains("Conversion preview"), "{html}");
|
||||
assert!(html.contains("Evidence lookup"), "{html}");
|
||||
assert!(html.contains("Provider health"), "{html}");
|
||||
assert!(html.contains("CZK"), "{html}");
|
||||
|
||||
Reference in New Issue
Block a user