Bug: [FEATURE] Add is_tax_conenctor_enabled boolean in pml response



### Feature Description

Add is_tax_conenctor_enabled boolean in pml response

### Possible Implementation

Get the is_tax_connector_enabled value from business_profile and pass it to pml response

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json
index 6b9ba4afd01..783d4751bc5 100644
--- a/api-reference-v2/openapi_spec.json
+++ b/api-reference-v2/openapi_spec.json
@@ -11073,7 +11073,8 @@
           "payment_methods",
           "mandate_payment",
           "show_surcharge_breakup_screen",
-          "request_external_three_ds_authentication"
+          "request_external_three_ds_authentication",
+          "is_tax_calculation_enabled"
         ],
         "properties": {
           "redirect_url": {
@@ -11135,6 +11136,10 @@
             "type": "boolean",
             "description": "flag that indicates whether to collect billing details from wallets or from the customer",
             "nullable": true
+          },
+          "is_tax_calculation_enabled": {
+            "type": "boolean",
+            "description": "flag that indicates whether to calculate tax on the order amount"
           }
         }
       },
@@ -11923,6 +11928,11 @@
             "example": "Custom_Order_id_123",
             "nullable": true,
             "maxLength": 255
+          },
+          "skip_external_tax_calculation": {
+            "type": "boolean",
+            "description": "Whether to calculate tax for this payment intent",
+            "nullable": true
           }
         }
       },
@@ -12288,6 +12298,11 @@
             "example": "Custom_Order_id_123",
             "nullable": true,
             "maxLength": 255
+          },
+          "skip_external_tax_calculation": {
+            "type": "boolean",
+            "description": "Whether to calculate tax for this payment intent",
+            "nullable": true
           }
         }
       },
@@ -13347,6 +13362,11 @@
             "example": "Custom_Order_id_123",
             "nullable": true,
             "maxLength": 255
+          },
+          "skip_external_tax_calculation": {
+            "type": "boolean",
+            "description": "Whether to calculate tax for this payment intent",
+            "nullable": true
           }
         },
         "additionalProperties": false
@@ -14355,6 +14375,11 @@
             "example": "Custom_Order_id_123",
             "nullable": true,
             "maxLength": 255
+          },
+          "skip_external_tax_calculation": {
+            "type": "boolean",
+            "description": "Whether to calculate tax for this payment intent",
+            "nullable": true
           }
         }
       },
diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs
index 2204a7fc584..c6cf6380150 100644
--- a/crates/api_models/src/payment_methods.rs
+++ b/crates/api_models/src/payment_methods.rs
@@ -1482,6 +1482,9 @@ pub struct PaymentMethodListResponse {
 
     /// flag that indicates whether to collect billing details from wallets or from the customer
     pub collect_billing_details_from_wallets: Option<bool>,
+
+    /// flag that indicates whether to calculate tax on the order amount
+    pub is_tax_calculation_enabled: bool,
 }
 
 #[derive(Eq, PartialEq, Hash, Debug, serde::Deserialize, ToSchema)]
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index d512d487e5b..cd32c045f18 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -560,6 +560,9 @@ pub struct PaymentsRequest {
         example = "Custom_Order_id_123"
     )]
     pub merchant_order_reference_id: Option<String>,
+
+    /// Whether to calculate tax for this payment intent
+    pub skip_external_tax_calculation: Option<bool>,
 }
 
 /// Checks if the inner values of two options are equal
diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs
index c80e9e5f4da..b2f314a0fee 100644
--- a/crates/diesel_models/src/payment_intent.rs
+++ b/crates/diesel_models/src/payment_intent.rs
@@ -72,6 +72,7 @@ pub struct PaymentIntent {
     pub shipping_cost: Option<MinorUnit>,
     pub organization_id: common_utils::id_type::OrganizationId,
     pub tax_details: Option<TaxDetails>,
+    pub skip_external_tax_calculation: Option<bool>,
 }
 
 #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))]
@@ -136,6 +137,7 @@ pub struct PaymentIntent {
     pub shipping_cost: Option<MinorUnit>,
     pub organization_id: common_utils::id_type::OrganizationId,
     pub tax_details: Option<TaxDetails>,
+    pub skip_external_tax_calculation: Option<bool>,
 }
 
 #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, diesel::AsExpression)]
@@ -219,6 +221,7 @@ pub struct PaymentIntentNew {
     pub shipping_cost: Option<MinorUnit>,
     pub organization_id: common_utils::id_type::OrganizationId,
     pub tax_details: Option<TaxDetails>,
+    pub skip_external_tax_calculation: Option<bool>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 213687431d4..8e6c72eb5ba 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -919,6 +919,7 @@ diesel::table! {
         #[max_length = 32]
         organization_id -> Varchar,
         tax_details -> Nullable<Jsonb>,
+        skip_external_tax_calculation -> Nullable<Bool>,
     }
 }
 
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index de4adf7984f..2deaa3d4ee4 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -899,6 +899,7 @@ diesel::table! {
         #[max_length = 32]
         organization_id -> Varchar,
         tax_details -> Nullable<Jsonb>,
+        skip_external_tax_calculation -> Nullable<Bool>,
     }
 }
 
diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs
index cfc0d07e0c8..c6b76680d48 100644
--- a/crates/hyperswitch_domain_models/src/business_profile.rs
+++ b/crates/hyperswitch_domain_models/src/business_profile.rs
@@ -659,6 +659,14 @@ impl From<BusinessProfileSetter> for BusinessProfile {
 }
 
 impl BusinessProfile {
+    pub fn get_is_tax_connector_enabled(&self) -> bool {
+        let is_tax_connector_enabled = self.is_tax_connector_enabled;
+        match &self.tax_connector_id {
+            Some(_id) => is_tax_connector_enabled,
+            _ => false,
+        }
+    }
+
     #[cfg(feature = "v1")]
     pub fn get_order_fulfillment_time(&self) -> Option<i64> {
         self.intent_fulfillment_time
diff --git a/crates/hyperswitch_domain_models/src/payments.rs b/crates/hyperswitch_domain_models/src/payments.rs
index 1365a7f082c..14d7e43450d 100644
--- a/crates/hyperswitch_domain_models/src/payments.rs
+++ b/crates/hyperswitch_domain_models/src/payments.rs
@@ -71,4 +71,5 @@ pub struct PaymentIntent {
     pub is_payment_processor_token_flow: Option<bool>,
     pub organization_id: id_type::OrganizationId,
     pub tax_details: Option<TaxDetails>,
+    pub skip_external_tax_calculation: Option<bool>,
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
index 4c2a67ff126..c9854c07857 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
@@ -550,6 +550,7 @@ impl behaviour::Conversion for PaymentIntent {
             organization_id: self.organization_id,
             shipping_cost: self.shipping_cost,
             tax_details: self.tax_details,
+            skip_external_tax_calculation: self.skip_external_tax_calculation,
         })
     }
     async fn convert_back(
@@ -635,6 +636,7 @@ impl behaviour::Conversion for PaymentIntent {
                 organization_id: storage_model.organization_id,
                 shipping_cost: storage_model.shipping_cost,
                 tax_details: storage_model.tax_details,
+                skip_external_tax_calculation: storage_model.skip_external_tax_calculation,
             })
         }
         .await
@@ -696,6 +698,7 @@ impl behaviour::Conversion for PaymentIntent {
             organization_id: self.organization_id,
             shipping_cost: self.shipping_cost,
             tax_details: self.tax_details,
+            skip_external_tax_calculation: self.skip_external_tax_calculation,
         })
     }
 }
@@ -759,6 +762,7 @@ impl behaviour::Conversion for PaymentIntent {
             organization_id: self.organization_id,
             shipping_cost: self.shipping_cost,
             tax_details: self.tax_details,
+            skip_external_tax_calculation: self.skip_external_tax_calculation,
         })
     }
 
@@ -845,6 +849,7 @@ impl behaviour::Conversion for PaymentIntent {
                     .await?,
                 is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow,
                 organization_id: storage_model.organization_id,
+                skip_external_tax_calculation: storage_model.skip_external_tax_calculation,
             })
         }
         .await
@@ -906,6 +911,7 @@ impl behaviour::Conversion for PaymentIntent {
             organization_id: self.organization_id,
             shipping_cost: self.shipping_cost,
             tax_details: self.tax_details,
+            skip_external_tax_calculation: self.skip_external_tax_calculation,
         })
     }
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
index 64403cf3b9c..2057d9ba42f 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
@@ -152,6 +152,7 @@ pub struct PaymentIntentNew {
     pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
     pub is_payment_processor_token_flow: Option<bool>,
     pub organization_id: id_type::OrganizationId,
+    pub skip_external_tax_calculation: Option<bool>,
 }
 
 #[derive(Debug, Clone, Serialize)]
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index cee4e9d1dd2..c553840347d 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -3626,6 +3626,10 @@ pub async fn list_payment_methods(
         });
     }
     let currency = payment_intent.as_ref().and_then(|pi| pi.currency);
+    let skip_external_tax_calculation = payment_intent
+        .as_ref()
+        .and_then(|intent| intent.skip_external_tax_calculation)
+        .unwrap_or(false);
     let request_external_three_ds_authentication = payment_intent
         .as_ref()
         .and_then(|intent| intent.request_external_three_ds_authentication)
@@ -3670,6 +3674,10 @@ pub async fn list_payment_methods(
             business_profile.collect_billing_details_from_wallet_connector
         }));
 
+    let is_tax_connector_enabled = business_profile.as_ref().map_or(false, |business_profile| {
+        business_profile.get_is_tax_connector_enabled()
+    });
+
     Ok(services::ApplicationResponse::Json(
         api::PaymentMethodListResponse {
             redirect_url: business_profile
@@ -3710,6 +3718,7 @@ pub async fn list_payment_methods(
             request_external_three_ds_authentication,
             collect_shipping_details_from_wallets,
             collect_billing_details_from_wallets,
+            is_tax_calculation_enabled: is_tax_connector_enabled && !skip_external_tax_calculation,
         },
     ))
 }
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index fdec36d3b76..70055720d26 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -3105,6 +3105,7 @@ mod tests {
             organization_id: id_type::OrganizationId::default(),
             shipping_cost: None,
             tax_details: None,
+            skip_external_tax_calculation: None,
         };
         let req_cs = Some("1".to_string());
         assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent).is_ok());
@@ -3173,6 +3174,7 @@ mod tests {
             organization_id: id_type::OrganizationId::default(),
             shipping_cost: None,
             tax_details: None,
+            skip_external_tax_calculation: None,
         };
         let req_cs = Some("1".to_string());
         assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent,).is_err())
@@ -3239,6 +3241,7 @@ mod tests {
             organization_id: id_type::OrganizationId::default(),
             shipping_cost: None,
             tax_details: None,
+            skip_external_tax_calculation: None,
         };
         let req_cs = Some("1".to_string());
         assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent).is_err())
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 257a3156bbc..9a662dc589b 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -1283,6 +1283,8 @@ impl PaymentCreate {
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Unable to encrypt customer details")?;
 
+        let skip_external_tax_calculation = request.skip_external_tax_calculation;
+
         Ok(storage::PaymentIntent {
             payment_id: payment_id.to_owned(),
             merchant_id: merchant_account.get_id().to_owned(),
@@ -1338,6 +1340,7 @@ impl PaymentCreate {
             organization_id: merchant_account.organization_id.clone(),
             shipping_cost: request.shipping_cost,
             tax_details: None,
+            skip_external_tax_calculation,
         })
     }
 
diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs
index 07bfe74f1d5..32728fd8fcc 100644
--- a/crates/router/src/utils/user/sample_data.rs
+++ b/crates/router/src/utils/user/sample_data.rs
@@ -250,6 +250,7 @@ pub async fn generate_sample_data(
             organization_id: org_id.clone(),
             shipping_cost: None,
             tax_details: None,
+            skip_external_tax_calculation: None,
         };
         let payment_attempt = PaymentAttemptBatchNew {
             attempt_id: attempt_id.clone(),
diff --git a/migrations/2024-08-28-044317_add_skip_external_tax_calcualtion_in_payment_intent_table/down.sql b/migrations/2024-08-28-044317_add_skip_external_tax_calcualtion_in_payment_intent_table/down.sql
new file mode 100644
index 00000000000..4ca933a4e36
--- /dev/null
+++ b/migrations/2024-08-28-044317_add_skip_external_tax_calcualtion_in_payment_intent_table/down.sql
@@ -0,0 +1,2 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE payment_intent DROP COLUMN if EXISTS skip_external_tax_calculation;
\ No newline at end of file
diff --git a/migrations/2024-08-28-044317_add_skip_external_tax_calcualtion_in_payment_intent_table/up.sql b/migrations/2024-08-28-044317_add_skip_external_tax_calcualtion_in_payment_intent_table/up.sql
new file mode 100644
index 00000000000..cf185dcdb7a
--- /dev/null
+++ b/migrations/2024-08-28-044317_add_skip_external_tax_calcualtion_in_payment_intent_table/up.sql
@@ -0,0 +1,2 @@
+-- Your SQL goes here
+ALTER TABLE payment_intent ADD COLUMN IF NOT EXISTS skip_external_tax_calculation BOOLEAN;
\ No newline at end of file

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

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

## Description
Added `skip_external_tax_calculation` boolean in payments create request that indicates whether tax to be calculated for this intent or not.
Added `is_tax_calculation_enabled` boolean value in `payment_methods_list` call response that checks both this `skip_external_tax_calculation` and `is_tax_connector_enabled` in business profile.

Payments create request:
```curl
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_OcQoFePRNVjYvsA9YGWKITq1BEHtInBKEtW9IRbKyBbOaBjwc6WYGwuxnyBVuhZh' \
--data-raw '{
    "amount": 1800,
    "currency": "USD",
    "confirm": false,
    "capture_method": "automatic",
    "customer_id": "cus_NwicjmCJbgafjhjfhHr6",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "three_ds",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "9123456789",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "return_url": "https://duck.com",
    "statement_descriptor_name": "Juspay",
    "statement_descriptor_suffix": "Router",
    "payment_method": "pay_later",
    "payment_method_type": "klarna",
    "payment_experience": "invoke_sdk_client",
    "payment_method_data": {
        "pay_later": {
            "klarna_sdk": {
                "token": "65bfb654-ef2c-6b39-942e-ffdc9a105d3c"
            }
        }
    },
    "billing": {
        "address": {
            "line1": "444, Stelar Enclave",
            "line2": "California",
            "line3": "Groningen",
            "city": "Groningen",
            "state": "Groningen",
            "zip": "94105",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "+4901761428434",
            "country_code": "+1"
        }
    },
    "shipping": {
        "address": {
            "line1": "444, Stelar Enclave",
            "line2": "California",
            "line3": "Groningen",
            "city": "Groningen",
            "state": "Groningen",
            "zip": "94105",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "446681800",
            "country_code": "+41"
        }
    },
    "metadata": {},
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 180000,
            "account_name": "transaction_processing"
        }
    ],
      "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "128.0.0.1"
    },
    "skip_external_tax_calculation": true
}'
```

PML call response:
```json
{
    "redirect_url": "https://google.com/success",
    "currency": "USD",
    "payment_methods": [
        {
            "payment_method": "pay_later",
            "payment_method_types": [
                {
                    "payment_method_type": "klarna",
                    "payment_experience": [
                        {
                            "payment_experience_type": "redirect_to_url",
                            "eligible_connectors": [
                                "klarna"
                            ]
                        },
                        {
                            "payment_experience_type": "invoke_sdk_client",
                            "eligible_connectors": [
                                "klarna"
                            ]
                        }
                    ],
                    "card_networks": null,
                    "bank_names": null,
                    "bank_debits": null,
                    "bank_transfers": null,
                    "required_fields": {
                        "billing.address.country": {
                            "required_field": "payment_method_data.billing.address.country",
                            "display_name": "country",
                            "field_type": {
                                "user_address_country": {
                                    "options": [
                                        "AU",
                                        "AT",
                                        "BE",
                                        "CA",
                                        "CZ",
                                        "DK",
                                        "FI",
                                        "FR",
                                        "DE",
                                        "GR",
                                        "IE",
                                        "IT",
                                        "NL",
                                        "NZ",
                                        "NO",
                                        "PL",
                                        "PT",
                                        "ES",
                                        "SE",
                                        "CH",
                                        "GB",
                                        "US"
                                    ]
                                }
                            },
                            "value": "US"
                        }
                    },
                    "surcharge_details": null,
                    "pm_auth_connector": null
                }
            ]
        }
    ],
    "mandate_payment": null,
    "merchant_name": "NewAge Retailer",
    "show_surcharge_breakup_screen": false,
    "payment_type": "normal",
    "request_external_three_ds_authentication": false,
    "collect_shipping_details_from_wallets": false,
    "collect_billing_details_from_wallets": false,
    "is_tax_calculation_enabled": false
}
```

We are preventing to update the value of `skip_external_tax_calculation` during payment update


### Additional Changes

- [x] This PR modifies the API contract
- [x] 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)?
-->


## 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
