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

Code before:
            self.subscription.client_secret.clone().map(Secret::new),
            self.subscription.customer_id.clone(),
            payment,
            invoice
                .map(
                    |invoice| -> errors::RouterResult<subscription_types::Invoice> {
                        Ok(subscription_types::Invoice {
                            id: invoice.id.clone(),
                            subscription_id: invoice.subscription_id.clone(),
                            merchant_id: invoice.merchant_id.clone(),
                            profile_id: invoice.profile_id.clone(),
                            merchant_connector_id: invoice.merchant_connector_id.clone(),
                            payment_intent_id: invoice.payment_intent_id.clone(),
                            payment_method_id: invoice.payment_method_id.clone(),
                            customer_id: invoice.customer_id.clone(),
                            amount: invoice.amount,
                            currency: api_enums::Currency::from_str(invoice.currency.as_str())
                                .change_context(errors::ApiErrorResponse::InvalidDataValue {
                                    field_name: "currency",
                                })
                                .attach_printable(format!(
                                    "unable to parse currency name {currency:?}",
                                    currency = invoice.currency
                                ))?,
                            status: invoice.status.clone(),
                        })
                    },
                )
                .transpose()?,
        ))
    }

    pub async fn update_subscription(
        &mut self,
        subscription_update: diesel_models::subscription::SubscriptionUpdate,
    ) -> errors::RouterResult<()> {
        let db = self.handler.state.store.as_ref();
        let updated_subscription = db
            .update_subscription_entry(
                self.handler
                    .merchant_context
                    .get_merchant_account()
                    .get_id(),
                self.subscription.id.get_string_repr().to_string(),
                subscription_update,
            )
            .await
            .change_context(errors::ApiErrorResponse::SubscriptionError {
                operation: "Subscription Update".to_string(),
            })
            .attach_printable("subscriptions: unable to update subscription entry in database")?;

Review comment (suggestion):
create a from implementation for this conversion by avoiding currency error. if not possible to avoid use a try_from

Code after:
            .update_subscription_entry(
                self.handler
                    .merchant_context
                    .get_merchant_account()
                    .get_id(),
                self.subscription.id.get_string_repr().to_string(),
                subscription_update,
            )
            .await
            .change_context(errors::ApiErrorResponse::SubscriptionError {
                operation: "Subscription Update".to_string(),
            })
            .attach_printable("subscriptions: unable to update subscription entry in database")?;

        self.subscription = updated_subscription;

        Ok(())
    }

    pub fn get_invoice_handler(
        &self,
        profile: hyperswitch_domain_models::business_profile::Profile,
    ) -> InvoiceHandler {
        InvoiceHandler {
            subscription: self.subscription.clone(),
            merchant_account: self.merchant_account.clone(),
            profile,
        }
    }
    pub async fn get_mca(
        &mut self,
        connector_name: &str,
    ) -> CustomResult<domain::MerchantConnectorAccount, errors::ApiErrorResponse> {
        let db = self.handler.state.store.as_ref();
        let key_manager_state = &(self.handler.state).into();

        match &self.subscription.merchant_connector_id {
            Some(merchant_connector_id) => {
                #[cfg(feature = "v1")]
                {
                    db.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
                        key_manager_state,
                        self.handler
                            .merchant_context
                            .get_merchant_account()
                            .get_id(),
                        merchant_connector_id,
                        self.handler.merchant_context.get_merchant_key_store(),
                    )
                    .await
                    .to_not_found_response(