Repository: juspay/hyperswitch
File: crates/router/src/core/customers.rs (Rust)

Code before:
        let merchant_reference_id = customer_orig.merchant_reference_id.clone();

        let customer_mandates = db.find_mandate_by_global_customer_id(self).await.switch()?;

        for mandate in customer_mandates.into_iter() {
            if mandate.mandate_status == enums::MandateStatus::Active {
                Err(errors::CustomersErrorResponse::MandateActive)?
            }
        }

        match db
            .find_payment_method_list_by_global_customer_id(provider.get_key_store(), self, None)
            .await
        {
            Ok(customer_payment_methods) => {
                for pm in customer_payment_methods.into_iter() {
                    let pm_id = PaymentMethodId {
                        payment_method_id: pm.id.get_string_repr().to_string(),
                    };
                    Box::pin(delete_payment_method(
                        state.clone(),
                        pm_id,
                        platform.clone(),
                        profile.clone(),
                    ))
                    .await
                    .switch()?;
                }
            }
            Err(error) => {
                if error.current_context().is_db_not_found() {
                    Ok(())
                } else {
                    Err(error)
                        .change_context(errors::CustomersErrorResponse::InternalServerError)
                        .attach_printable(
                            "failed find_payment_method_by_customer_id_merchant_id_list",
                        )
                }?
            }
        };

        let key = provider.get_key_store().key.get_inner().peek();

        let identifier = Identifier::Merchant(provider.get_key_store().merchant_id.clone());
        let redacted_encrypted_value: Encryptable<Secret<_>> = types::crypto_operation(
            key_manager_state,
            type_name!(storage::Address),
            types::CryptoOperation::Encrypt(REDACTED.to_string().into()),
            identifier.clone(),
            key,

Review comment (refactor):
Instead of calling the entire delete_payment_method, for now we can extract the required logic from `delete_payment_method_core` into a common function and invoke it from both here and `delete_payment_method_core`.
This way, we can avoid the unnecessary payment method and customer-related database calls made by `redact_customer_details_and_generate_response` and `delete_payment_method_core`.

Code after:
        let merchant_reference_id = customer_orig.merchant_reference_id.clone();

        let customer_mandates = db.find_mandate_by_global_customer_id(self).await.switch()?;

        for mandate in customer_mandates.into_iter() {
            if mandate.mandate_status == enums::MandateStatus::Active {
                Err(errors::CustomersErrorResponse::MandateActive)?
            }
        }

        match db
            .find_payment_method_list_by_global_customer_id(provider.get_key_store(), self, None)
            .await
        {
            Ok(customer_payment_methods) => {
                for pm in customer_payment_methods.into_iter() {
                    delete_payment_method_by_record(db, state, platform, &profile, pm)
                        .await
                        .switch()?;
                }
            }
            Err(error) => {
                if error.current_context().is_db_not_found() {
                    Ok(())
                } else {
                    Err(error)
                        .change_context(errors::CustomersErrorResponse::InternalServerError)
                        .attach_printable(
                            "failed find_payment_method_by_customer_id_merchant_id_list",
                        )
                }?
            }
        };

        let key = provider.get_key_store().key.get_inner().peek();

        let identifier = Identifier::Merchant(provider.get_key_store().merchant_id.clone());
        let redacted_encrypted_value: Encryptable<Secret<_>> = types::crypto_operation(
            key_manager_state,
            type_name!(storage::Address),
            types::CryptoOperation::Encrypt(REDACTED.to_string().into()),
            identifier.clone(),
            key,
        )
        .await
        .and_then(|val| val.try_into_operation())
        .switch()?;

        let redacted_encrypted_email = Encryptable::new(
            redacted_encrypted_value
                .clone()