mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(router): add support to use signature_network and is_issuer_regulated as filters (#9033)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -63,8 +63,6 @@ pub struct ProcessedAmountAccumulator {
|
||||
pub struct DebitRoutingAccumulator {
|
||||
pub transaction_count: u64,
|
||||
pub savings_amount: u64,
|
||||
pub signature_network: Option<String>,
|
||||
pub is_issuer_regulated: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@ -193,13 +191,7 @@ impl PaymentMetricAccumulator for SuccessRateAccumulator {
|
||||
}
|
||||
|
||||
impl PaymentMetricAccumulator for DebitRoutingAccumulator {
|
||||
type MetricOutput = (
|
||||
Option<u64>,
|
||||
Option<u64>,
|
||||
Option<u64>,
|
||||
Option<String>,
|
||||
Option<bool>,
|
||||
);
|
||||
type MetricOutput = (Option<u64>, Option<u64>, Option<u64>);
|
||||
|
||||
fn add_metrics_bucket(&mut self, metrics: &PaymentMetricRow) {
|
||||
if let Some(count) = metrics.count {
|
||||
@ -208,12 +200,6 @@ impl PaymentMetricAccumulator for DebitRoutingAccumulator {
|
||||
if let Some(total) = metrics.total.as_ref().and_then(ToPrimitive::to_u64) {
|
||||
self.savings_amount += total;
|
||||
}
|
||||
if let Some(signature_network) = &metrics.signature_network {
|
||||
self.signature_network = Some(signature_network.clone());
|
||||
}
|
||||
if let Some(is_issuer_regulated) = metrics.is_issuer_regulated {
|
||||
self.is_issuer_regulated = Some(is_issuer_regulated);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect(self) -> Self::MetricOutput {
|
||||
@ -221,8 +207,6 @@ impl PaymentMetricAccumulator for DebitRoutingAccumulator {
|
||||
Some(self.transaction_count),
|
||||
Some(self.savings_amount),
|
||||
Some(0),
|
||||
self.signature_network,
|
||||
self.is_issuer_regulated,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -484,13 +468,8 @@ impl PaymentMetricsAccumulator {
|
||||
) = self.payments_distribution.collect();
|
||||
let (failure_reason_count, failure_reason_count_without_smart_retries) =
|
||||
self.failure_reasons_distribution.collect();
|
||||
let (
|
||||
debit_routed_transaction_count,
|
||||
debit_routing_savings,
|
||||
debit_routing_savings_in_usd,
|
||||
signature_network,
|
||||
is_issuer_regulated,
|
||||
) = self.debit_routing.collect();
|
||||
let (debit_routed_transaction_count, debit_routing_savings, debit_routing_savings_in_usd) =
|
||||
self.debit_routing.collect();
|
||||
|
||||
PaymentMetricsBucketValue {
|
||||
payment_success_rate: self.payment_success_rate.collect(),
|
||||
@ -518,8 +497,6 @@ impl PaymentMetricsAccumulator {
|
||||
debit_routed_transaction_count,
|
||||
debit_routing_savings,
|
||||
debit_routing_savings_in_usd,
|
||||
signature_network,
|
||||
is_issuer_regulated,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,6 +441,9 @@ pub async fn get_filters(
|
||||
PaymentDimensions::CardIssuer => fil.card_issuer,
|
||||
PaymentDimensions::ErrorReason => fil.error_reason,
|
||||
PaymentDimensions::RoutingApproach => fil.routing_approach.map(|i| i.as_ref().to_string()),
|
||||
PaymentDimensions::SignatureNetwork => fil.signature_network,
|
||||
PaymentDimensions::IsIssuerRegulated => fil.is_issuer_regulated.map(|b| b.to_string()),
|
||||
PaymentDimensions::IsDebitRouted => fil.is_debit_routed.map(|b| b.to_string())
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
res.query_data.push(FilterValue {
|
||||
|
||||
@ -38,6 +38,9 @@ pub struct PaymentDistributionRow {
|
||||
pub count: Option<i64>,
|
||||
pub error_message: Option<String>,
|
||||
pub routing_approach: Option<DBEnumWrapper<storage_enums::RoutingApproach>>,
|
||||
pub signature_network: Option<String>,
|
||||
pub is_issuer_regulated: Option<bool>,
|
||||
pub is_debit_routed: Option<bool>,
|
||||
#[serde(with = "common_utils::custom_serde::iso8601::option")]
|
||||
pub start_bucket: Option<PrimitiveDateTime>,
|
||||
#[serde(with = "common_utils::custom_serde::iso8601::option")]
|
||||
|
||||
@ -161,6 +161,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -66,4 +66,7 @@ pub struct PaymentFilterRow {
|
||||
pub error_reason: Option<String>,
|
||||
pub first_attempt: Option<bool>,
|
||||
pub routing_approach: Option<DBEnumWrapper<RoutingApproach>>,
|
||||
pub signature_network: Option<String>,
|
||||
pub is_issuer_regulated: Option<bool>,
|
||||
pub is_debit_routed: Option<bool>,
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@ pub struct PaymentMetricRow {
|
||||
pub routing_approach: Option<DBEnumWrapper<storage_enums::RoutingApproach>>,
|
||||
pub signature_network: Option<String>,
|
||||
pub is_issuer_regulated: Option<bool>,
|
||||
pub is_debit_routed: Option<bool>,
|
||||
#[serde(with = "common_utils::custom_serde::iso8601::option")]
|
||||
pub start_bucket: Option<PrimitiveDateTime>,
|
||||
#[serde(with = "common_utils::custom_serde::iso8601::option")]
|
||||
|
||||
@ -123,6 +123,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -118,6 +118,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -57,13 +57,6 @@ where
|
||||
.switch()?;
|
||||
query_builder.add_select_column("currency").switch()?;
|
||||
|
||||
query_builder
|
||||
.add_select_column("signature_network")
|
||||
.switch()?;
|
||||
query_builder
|
||||
.add_select_column("is_issuer_regulated")
|
||||
.switch()?;
|
||||
|
||||
query_builder
|
||||
.add_select_column(Aggregate::Min {
|
||||
field: "created_at",
|
||||
@ -93,16 +86,6 @@ where
|
||||
.switch()?;
|
||||
}
|
||||
|
||||
query_builder
|
||||
.add_group_by_clause("signature_network")
|
||||
.attach_printable("Error grouping by signature_network")
|
||||
.switch()?;
|
||||
|
||||
query_builder
|
||||
.add_group_by_clause("is_issuer_regulated")
|
||||
.attach_printable("Error grouping by is_issuer_regulated")
|
||||
.switch()?;
|
||||
|
||||
query_builder
|
||||
.add_group_by_clause("currency")
|
||||
.attach_printable("Error grouping by currency")
|
||||
@ -146,6 +129,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -109,6 +109,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -123,6 +123,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -116,6 +116,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -113,6 +113,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -124,6 +124,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -119,6 +119,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -129,6 +129,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -184,6 +184,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -110,6 +110,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -141,6 +141,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -117,6 +117,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -120,6 +120,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -113,6 +113,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -113,6 +113,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -112,6 +112,9 @@ where
|
||||
i.card_issuer.clone(),
|
||||
i.error_reason.clone(),
|
||||
i.routing_approach.as_ref().map(|i| i.0.clone()),
|
||||
i.signature_network.clone(),
|
||||
i.is_issuer_regulated,
|
||||
i.is_debit_routed,
|
||||
TimeRange {
|
||||
start_time: match (granularity, i.start_bucket) {
|
||||
(Some(g), Some(st)) => g.clip_to_start(st)?,
|
||||
|
||||
@ -119,6 +119,30 @@ where
|
||||
.attach_printable("Error adding routing approach filter")?;
|
||||
}
|
||||
|
||||
if !self.signature_network.is_empty() {
|
||||
builder
|
||||
.add_filter_in_range_clause(
|
||||
PaymentDimensions::SignatureNetwork,
|
||||
&self.signature_network,
|
||||
)
|
||||
.attach_printable("Error adding signature network filter")?;
|
||||
}
|
||||
|
||||
if !self.is_issuer_regulated.is_empty() {
|
||||
builder
|
||||
.add_filter_in_range_clause(
|
||||
PaymentDimensions::IsIssuerRegulated,
|
||||
&self.is_issuer_regulated,
|
||||
)
|
||||
.attach_printable("Error adding is issuer regulated filter")?;
|
||||
}
|
||||
|
||||
if !self.is_debit_routed.is_empty() {
|
||||
builder
|
||||
.add_filter_in_range_clause(PaymentDimensions::IsDebitRouted, &self.is_debit_routed)
|
||||
.attach_printable("Error adding is debit routed filter")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -746,6 +746,11 @@ impl<'a> FromRow<'a, PgRow> for super::payments::metrics::PaymentMetricRow {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let is_debit_routed: Option<bool> =
|
||||
row.try_get("is_debit_routed").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let total: Option<bigdecimal::BigDecimal> = row.try_get("total").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
@ -780,6 +785,7 @@ impl<'a> FromRow<'a, PgRow> for super::payments::metrics::PaymentMetricRow {
|
||||
routing_approach,
|
||||
signature_network,
|
||||
is_issuer_regulated,
|
||||
is_debit_routed,
|
||||
total,
|
||||
count,
|
||||
start_bucket,
|
||||
@ -857,6 +863,22 @@ impl<'a> FromRow<'a, PgRow> for super::payments::distribution::PaymentDistributi
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
|
||||
let signature_network: Option<String> =
|
||||
row.try_get("signature_network").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let is_issuer_regulated: Option<bool> =
|
||||
row.try_get("is_issuer_regulated").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let is_debit_routed: Option<bool> =
|
||||
row.try_get("is_debit_routed").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let total: Option<bigdecimal::BigDecimal> = row.try_get("total").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
@ -900,6 +922,9 @@ impl<'a> FromRow<'a, PgRow> for super::payments::distribution::PaymentDistributi
|
||||
count,
|
||||
error_message,
|
||||
routing_approach,
|
||||
signature_network,
|
||||
is_issuer_regulated,
|
||||
is_debit_routed,
|
||||
start_bucket,
|
||||
end_bucket,
|
||||
})
|
||||
@ -979,6 +1004,21 @@ impl<'a> FromRow<'a, PgRow> for super::payments::filters::PaymentFilterRow {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let signature_network: Option<String> =
|
||||
row.try_get("signature_network").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let is_issuer_regulated: Option<bool> =
|
||||
row.try_get("is_issuer_regulated").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
let is_debit_routed: Option<bool> =
|
||||
row.try_get("is_debit_routed").or_else(|e| match e {
|
||||
ColumnNotFound(_) => Ok(Default::default()),
|
||||
e => Err(e),
|
||||
})?;
|
||||
Ok(Self {
|
||||
currency,
|
||||
status,
|
||||
@ -996,6 +1036,9 @@ impl<'a> FromRow<'a, PgRow> for super::payments::filters::PaymentFilterRow {
|
||||
error_reason,
|
||||
first_attempt,
|
||||
routing_approach,
|
||||
signature_network,
|
||||
is_issuer_regulated,
|
||||
is_debit_routed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +45,12 @@ pub struct PaymentFilters {
|
||||
pub first_attempt: Vec<bool>,
|
||||
#[serde(default)]
|
||||
pub routing_approach: Vec<RoutingApproach>,
|
||||
#[serde(default)]
|
||||
pub signature_network: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub is_issuer_regulated: Vec<bool>,
|
||||
#[serde(default)]
|
||||
pub is_debit_routed: Vec<bool>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
@ -87,6 +93,9 @@ pub enum PaymentDimensions {
|
||||
CardIssuer,
|
||||
ErrorReason,
|
||||
RoutingApproach,
|
||||
SignatureNetwork,
|
||||
IsIssuerRegulated,
|
||||
IsDebitRouted,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
@ -208,6 +217,9 @@ pub struct PaymentMetricsBucketIdentifier {
|
||||
pub card_issuer: Option<String>,
|
||||
pub error_reason: Option<String>,
|
||||
pub routing_approach: Option<RoutingApproach>,
|
||||
pub signature_network: Option<String>,
|
||||
pub is_issuer_regulated: Option<bool>,
|
||||
pub is_debit_routed: Option<bool>,
|
||||
#[serde(rename = "time_range")]
|
||||
pub time_bucket: TimeRange,
|
||||
// Coz FE sucks
|
||||
@ -234,6 +246,9 @@ impl PaymentMetricsBucketIdentifier {
|
||||
card_issuer: Option<String>,
|
||||
error_reason: Option<String>,
|
||||
routing_approach: Option<RoutingApproach>,
|
||||
signature_network: Option<String>,
|
||||
is_issuer_regulated: Option<bool>,
|
||||
is_debit_routed: Option<bool>,
|
||||
normalized_time_range: TimeRange,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -252,6 +267,9 @@ impl PaymentMetricsBucketIdentifier {
|
||||
card_issuer,
|
||||
error_reason,
|
||||
routing_approach,
|
||||
signature_network,
|
||||
is_issuer_regulated,
|
||||
is_debit_routed,
|
||||
time_bucket: normalized_time_range,
|
||||
start_time: normalized_time_range.start_time,
|
||||
}
|
||||
@ -278,6 +296,9 @@ impl Hash for PaymentMetricsBucketIdentifier {
|
||||
.clone()
|
||||
.map(|i| i.to_string())
|
||||
.hash(state);
|
||||
self.signature_network.hash(state);
|
||||
self.is_issuer_regulated.hash(state);
|
||||
self.is_debit_routed.hash(state);
|
||||
self.time_bucket.hash(state);
|
||||
}
|
||||
}
|
||||
@ -319,8 +340,6 @@ pub struct PaymentMetricsBucketValue {
|
||||
pub debit_routed_transaction_count: Option<u64>,
|
||||
pub debit_routing_savings: Option<u64>,
|
||||
pub debit_routing_savings_in_usd: Option<u64>,
|
||||
pub signature_network: Option<String>,
|
||||
pub is_issuer_regulated: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
|
||||
Reference in New Issue
Block a user