GetPaymentMethodsByParams

mail@pastecode.io avatar
unknown
golang
a month ago
3.0 kB
2
Indexable
Never
func (db *PGStore) GetPaymentMethodsByParams(ctx context.Context, params model.PaymentMethodParams) ([]model.PaymentMethods, error) {
	var amount *int
	if params.Amount != "" {
		parsedAmount, err := strconv.ParseFloat(params.Amount, 64)
		if err != nil || parsedAmount <= 0 {
			return nil, fmt.Errorf("invalid amount: %s", params.Amount)
		}
		intAmount := int(math.Ceil(parsedAmount))
		amount = &intAmount
	}

	if params.Currency != "" {
		active, err := isCurrencyActiveForOrganization(db.db, db.schema, params.OrganizationID, params.Currency)
		if err != nil {
			return nil, fmt.Errorf("failed to check currency activity: %s", err)
		}
		if !active {
			return nil, fmt.Errorf("currency %s is not active for organization %d", params.Currency, params.OrganizationID)
		}
	}

	var paymentMethods []model.PaymentMethodsGetResult
	//
	query := `
	with currency_accounts_data as (select distinct ca.id as id,
													ca.currency_id as c_id,
													ca.min_value as min_value,
													ca.max_value as max_value

									from "%[1]s".payment_systems_organizations pso
											 join "%[1]s".payment_systems ps on pso.payment_system_id = ps.id
											 join "%[1]s".organizations_payment_system_accounts opsa
												  on opsa.organization_id = pso.organization_id
											 join "%[1]s".currency_accounts ca
												  on ca.organizations_payment_system_account_id = opsa.id
											 join "%[1]s".organizations_currencies oc on oc.currency_id = ca.currency_id
									where oc.is_active
									  and ps.is_active
									  and oc.organization_id = ?),
		 apm_data as (select pm.name as name,
							 pm.description as description,
							 apm.id  as id
					  from "%[1]s".payment_methods pm
							   join "%[1]s".applications_payment_methods apm on apm.payment_method_id = pm.id
					  where apm.is_active
						and apm.application_id = ?)
	select DISTINCT ON (apm_data.name) apm_data.name,
									   c.iso_code,
									   pmr.payment_type,
									   apm_data.description,
									   cad.min_value,
									   cad.max_value
	from "%[1]s".payment_method_routes pmr
			 join apm_data on apm_data.id = pmr.applications_payment_method_id
			 join currency_accounts_data cad on cad.id = pmr.currency_account_id
			 join "%[1]s".currencies c on  cad.c_id = c.id;
	`

	query = fmt.Sprintf(query, db.schema)

	if err := db.db.Raw(query, params.OrganizationID, params.ActiveApplicationID).Scan(&paymentMethods).Error; err != nil {
		return nil, fmt.Errorf("failed to scan: %s", err)
	}

	filtered := make([]model.PaymentMethods, 0, len(paymentMethods))

	for _, pm := range paymentMethods {
		if len(params.Currency) > 0 && pm.IsoCode != params.Currency {
			continue
		}
		if len(params.PaymentType) > 0 && pm.PaymentType != params.PaymentType {
			continue
		}
		if amount != nil && (pm.MinValue > *amount || pm.MaxValue < *amount) {
			continue
		}
		filtered = append(filtered, pm.ToDomain())
	}

	return filtered, nil
}
Leave a Comment