From 9f03a4118ccdd6036d27074c9126a79d6e9b0495 Mon Sep 17 00:00:00 2001
From: Suraj <105744567+Suraj3240@users.noreply.github.com>
Date: Fri, 13 Oct 2023 15:44:51 +0530
Subject: [PATCH] refactor(connector): [Worldline] Currency Unit Conversion
 (#2569)

---
 crates/router/src/connector/worldline.rs      | 12 ++-
 .../src/connector/worldline/transformers.rs   | 99 ++++++++++++++-----
 2 files changed, 88 insertions(+), 23 deletions(-)

diff --git a/crates/router/src/connector/worldline.rs b/crates/router/src/connector/worldline.rs
index 4e69fd5ca0ab..b10e3dcd74c8 100644
--- a/crates/router/src/connector/worldline.rs
+++ b/crates/router/src/connector/worldline.rs
@@ -112,6 +112,10 @@ impl ConnectorCommon for Worldline {
         "worldline"
     }
 
+    fn get_currency_unit(&self) -> api::CurrencyUnit {
+        api::CurrencyUnit::Minor
+    }
+
     fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str {
         connectors.worldline.base_url.as_ref()
     }
@@ -486,7 +490,13 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
         &self,
         req: &types::PaymentsAuthorizeRouterData,
     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
-        let connector_req = worldline::PaymentsRequest::try_from(req)?;
+        let connector_router_data = worldline::WorldlineRouterData::try_from((
+            &self.get_currency_unit(),
+            req.request.currency,
+            req.request.amount,
+            req,
+        ))?;
+        let connector_req = worldline::PaymentsRequest::try_from(&connector_router_data)?;
         let worldline_req = types::RequestBody::log_and_get_request_body(
             &connector_req,
             utils::Encode::<worldline::PaymentsRequest>::encode_to_string_of_json,
diff --git a/crates/router/src/connector/worldline/transformers.rs b/crates/router/src/connector/worldline/transformers.rs
index d02ab60c8b91..f11c23980809 100644
--- a/crates/router/src/connector/worldline/transformers.rs
+++ b/crates/router/src/connector/worldline/transformers.rs
@@ -13,6 +13,7 @@ use crate::{
         api::{self, enums as api_enums},
         storage::enums,
         transformers::ForeignFrom,
+        PaymentsAuthorizeData, PaymentsResponseData,
     },
 };
 
@@ -183,38 +184,91 @@ pub struct PaymentsRequest {
     pub shipping: Option<Shipping>,
 }
 
-impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentsRequest {
+#[derive(Debug, Serialize)]
+pub struct WorldlineRouterData<T> {
+    amount: i64,
+    router_data: T,
+}
+impl<T>
+    TryFrom<(
+        &types::api::CurrencyUnit,
+        types::storage::enums::Currency,
+        i64,
+        T,
+    )> for WorldlineRouterData<T>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        (_currency_unit, _currency, amount, item): (
+            &types::api::CurrencyUnit,
+            types::storage::enums::Currency,
+            i64,
+            T,
+        ),
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            amount,
+            router_data: item,
+        })
+    }
+}
+
+impl
+    TryFrom<
+        &WorldlineRouterData<
+            &types::RouterData<
+                types::api::payments::Authorize,
+                PaymentsAuthorizeData,
+                PaymentsResponseData,
+            >,
+        >,
+    > for PaymentsRequest
+{
     type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
-        let payment_data = match item.request.payment_method_data {
-            api::PaymentMethodData::Card(ref card) => {
+
+    fn try_from(
+        item: &WorldlineRouterData<
+            &types::RouterData<
+                types::api::payments::Authorize,
+                PaymentsAuthorizeData,
+                PaymentsResponseData,
+            >,
+        >,
+    ) -> Result<Self, Self::Error> {
+        let payment_data = match &item.router_data.request.payment_method_data {
+            api::PaymentMethodData::Card(card) => {
                 WorldlinePaymentMethod::CardPaymentMethodSpecificInput(Box::new(make_card_request(
-                    &item.request,
+                    &item.router_data.request,
                     card,
                 )?))
             }
-            api::PaymentMethodData::BankRedirect(ref bank_redirect) => {
+            api::PaymentMethodData::BankRedirect(bank_redirect) => {
                 WorldlinePaymentMethod::RedirectPaymentMethodSpecificInput(Box::new(
-                    make_bank_redirect_request(&item.request, bank_redirect)?,
+                    make_bank_redirect_request(&item.router_data.request, bank_redirect)?,
                 ))
             }
-            _ => Err(errors::ConnectorError::NotImplemented(
-                "Payment methods".to_string(),
-            ))?,
+            _ => {
+                return Err(
+                    errors::ConnectorError::NotImplemented("Payment methods".to_string()).into(),
+                )
+            }
         };
-        let customer = build_customer_info(&item.address, &item.request.email)?;
+
+        let customer =
+            build_customer_info(&item.router_data.address, &item.router_data.request.email)?;
         let order = Order {
             amount_of_money: AmountOfMoney {
-                amount: item.request.amount,
-                currency_code: item.request.currency.to_string().to_uppercase(),
+                amount: item.amount,
+                currency_code: item.router_data.request.currency.to_string().to_uppercase(),
             },
             customer,
             references: References {
-                merchant_reference: item.connector_request_reference_id.clone(),
+                merchant_reference: item.router_data.connector_request_reference_id.clone(),
             },
         };
 
         let shipping = item
+            .router_data
             .address
             .shipping
             .as_ref()
@@ -227,6 +281,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentsRequest {
         })
     }
 }
+
 #[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
 pub enum Gateway {
     Amex = 2,
@@ -276,7 +331,7 @@ impl TryFrom<&api_models::enums::BankNames> for WorldlineBic {
 }
 
 fn make_card_request(
-    req: &types::PaymentsAuthorizeData,
+    req: &PaymentsAuthorizeData,
     ccard: &payments::Card,
 ) -> Result<CardPaymentMethod, error_stack::Report<errors::ConnectorError>> {
     let expiry_year = ccard.card_exp_year.peek().clone();
@@ -303,7 +358,7 @@ fn make_card_request(
 }
 
 fn make_bank_redirect_request(
-    req: &types::PaymentsAuthorizeData,
+    req: &PaymentsAuthorizeData,
     bank_redirect: &payments::BankRedirectData,
 ) -> Result<RedirectPaymentMethod, error_stack::Report<errors::ConnectorError>> {
     let return_url = req.router_return_url.clone();
@@ -497,12 +552,12 @@ pub struct Payment {
     pub capture_method: enums::CaptureMethod,
 }
 
-impl<F, T> TryFrom<types::ResponseRouterData<F, Payment, T, types::PaymentsResponseData>>
-    for types::RouterData<F, T, types::PaymentsResponseData>
+impl<F, T> TryFrom<types::ResponseRouterData<F, Payment, T, PaymentsResponseData>>
+    for types::RouterData<F, T, PaymentsResponseData>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
-        item: types::ResponseRouterData<F, Payment, T, types::PaymentsResponseData>,
+        item: types::ResponseRouterData<F, Payment, T, PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
         Ok(Self {
             status: enums::AttemptStatus::foreign_from((
@@ -541,12 +596,12 @@ pub struct RedirectData {
     pub redirect_url: Url,
 }
 
-impl<F, T> TryFrom<types::ResponseRouterData<F, PaymentResponse, T, types::PaymentsResponseData>>
-    for types::RouterData<F, T, types::PaymentsResponseData>
+impl<F, T> TryFrom<types::ResponseRouterData<F, PaymentResponse, T, PaymentsResponseData>>
+    for types::RouterData<F, T, PaymentsResponseData>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
-        item: types::ResponseRouterData<F, PaymentResponse, T, types::PaymentsResponseData>,
+        item: types::ResponseRouterData<F, PaymentResponse, T, PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
         let redirection_data = item
             .response