Bug: [FIX] fix response for migration api 



Currently there is inconsistent response due to no validations for request body fields for the migration api.

Implementation - 
validations such as empty string check for network transaction id and empty object for connector mandate details should be enforced while evaluating the migration response.
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index ad612ed6f3b..f07634060df 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -28,7 +28,7 @@ use common_utils::{
     consts,
     crypto::{self, Encryptable},
     encryption::Encryption,
-    ext_traits::{AsyncExt, BytesExt, Encode, StringExt, ValueExt},
+    ext_traits::{AsyncExt, BytesExt, ConfigExt, Encode, StringExt, ValueExt},
     generate_id, id_type,
     request::Request,
     type_name,
@@ -55,6 +55,7 @@ use hyperswitch_domain_models::customer::CustomerUpdate;
 use kgraph_utils::transformers::IntoDirValue;
 use masking::Secret;
 use router_env::{instrument, metrics::add_attributes, tracing};
+use serde_json::json;
 use strum::IntoEnumIterator;
 
 use super::{
@@ -381,7 +382,7 @@ pub async fn migrate_payment_method(
     key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResponse<api::PaymentMethodMigrateResponse> {
     let mut req = req;
-    let card_details = req.card.as_ref().get_required_value("card")?;
+    let card_details = &req.card.get_required_value("card")?;
 
     let card_number_validation_result =
         cards::CardNumber::from_str(card_details.card_number.peek());
@@ -780,17 +781,6 @@ pub async fn skip_locker_call_and_migrate_payment_method(
 
     let network_transaction_id = req.network_transaction_id.clone();
 
-    migration_status.network_transaction_id_migrated(network_transaction_id.as_ref().map(|_| true));
-
-    migration_status.connector_mandate_details_migrated(
-        connector_mandate_details
-            .as_ref()
-            .map(|_| true)
-            .or_else(|| req.connector_mandate_details.as_ref().map(|_| false)),
-    );
-
-    migration_status.card_migrated(false);
-
     let payment_method_id = generate_id(consts::ID_LENGTH, "pm");
 
     let current_time = common_utils::date_time::now();
@@ -810,11 +800,11 @@ pub async fn skip_locker_call_and_migrate_payment_method(
                 scheme: req.card_network.clone().or(card.scheme.clone()),
                 metadata: payment_method_metadata.map(Secret::new),
                 payment_method_data: payment_method_data_encrypted.map(Into::into),
-                connector_mandate_details,
+                connector_mandate_details: connector_mandate_details.clone(),
                 customer_acceptance: None,
                 client_secret: None,
                 status: enums::PaymentMethodStatus::Active,
-                network_transaction_id,
+                network_transaction_id: network_transaction_id.clone(),
                 payment_method_issuer_code: None,
                 accepted_currency: None,
                 token: None,
@@ -843,6 +833,21 @@ pub async fn skip_locker_call_and_migrate_payment_method(
 
     logger::debug!("Payment method inserted in db");
 
+    migration_status.network_transaction_id_migrated(
+        network_transaction_id.and_then(|val| (!val.is_empty_after_trim()).then_some(true)),
+    );
+
+    migration_status.connector_mandate_details_migrated(
+        connector_mandate_details
+            .clone()
+            .and_then(|val| if val == json!({}) { None } else { Some(true) })
+            .or_else(|| {
+                req.connector_mandate_details
+                    .clone()
+                    .and_then(|val| (!val.0.is_empty()).then_some(false))
+            }),
+    );
+
     if customer.default_payment_method_id.is_none() && req.payment_method.is_some() {
         let _ = set_default_payment_method(
             state,
@@ -1166,10 +1171,14 @@ pub async fn get_client_secret_or_add_payment_method_for_migration(
         migration_status.connector_mandate_details_migrated(
             connector_mandate_details
                 .clone()
-                .map(|_| true)
-                .or_else(|| req.connector_mandate_details.clone().map(|_| false)),
+                .and_then(|val| (val != json!({})).then_some(true))
+                .or_else(|| {
+                    req.connector_mandate_details
+                        .clone()
+                        .and_then(|val| (!val.0.is_empty()).then_some(false))
+                }),
         );
-
+        //card is not migrated in this case
         migration_status.card_migrated(false);
 
         if res.status == enums::PaymentMethodStatus::AwaitingData {
@@ -1722,15 +1731,6 @@ pub async fn save_migration_payment_method(
 
     let network_transaction_id = req.network_transaction_id.clone();
 
-    migration_status.network_transaction_id_migrated(network_transaction_id.as_ref().map(|_| true));
-
-    migration_status.connector_mandate_details_migrated(
-        connector_mandate_details
-            .as_ref()
-            .map(|_| true)
-            .or_else(|| req.connector_mandate_details.as_ref().map(|_| false)),
-    );
-
     let response = match payment_method {
         #[cfg(feature = "payouts")]
         api_enums::PaymentMethod::BankTransfer => match req.bank_transfer.clone() {
@@ -1940,8 +1940,8 @@ pub async fn save_migration_payment_method(
                 pm_metadata.cloned(),
                 None,
                 locker_id,
-                connector_mandate_details,
-                network_transaction_id,
+                connector_mandate_details.clone(),
+                network_transaction_id.clone(),
                 merchant_account.storage_scheme,
                 payment_method_billing_address.map(Into::into),
                 None,
@@ -1954,6 +1954,20 @@ pub async fn save_migration_payment_method(
         }
     }
 
+    migration_status.card_migrated(true);
+    migration_status.network_transaction_id_migrated(
+        network_transaction_id.and_then(|val| (!val.is_empty_after_trim()).then_some(true)),
+    );
+
+    migration_status.connector_mandate_details_migrated(
+        connector_mandate_details
+            .and_then(|val| if val == json!({}) { None } else { Some(true) })
+            .or_else(|| {
+                req.connector_mandate_details
+                    .and_then(|val| (!val.0.is_empty()).then_some(false))
+            }),
+    );
+
     Ok(services::ApplicationResponse::Json(resp))
 }
 

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [x] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
#6300 has inconsistent response due to no validations for each field in migration api request body.

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
test case - test migration api with empty fields.
req - 
```
curl --location 'http://localhost:8080/payment_methods/migrate' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: api-key' \
--data '{
    "merchant_id": "merchant_id",
    "card": {
        "card_number": "card_number",
        "card_exp_month": "12",
        "card_exp_year": "21",
        "card_holder_name": "joseph Doe"
    },
    "customer_id": "customer_id",
    "network_transaction_id": "",
    "payment_method": "card",
    "connector_mandate_details": {},
    "network_token": {
        "network_token_data": {
            "network_token_number": "  ",
            "network_token_exp_month": "12",
            "network_token_exp_year": "21"
        },
        "network_token_requestor_ref_id": ""
    }
}'
```
<img width="880" alt="Screenshot 2024-11-11 at 11 43 58 AM" src="https://github.com/user-attachments/assets/27b1f3b6-cfe9-4917-b3e5-db44342df845">



## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
