mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
refactor: Rename service package to services and move repository implementations to repository package
- Rename internal/service to internal/services in carrier-connector - Update service imports in selection_integration.go and smdp_integration.go - Move currency repository files from internal/currency to internal/repository - Move rate plan repository files from internal/rateplan to internal/repository - Update package declarations and imports for currency domain types - Add currency package imports
This commit is contained in:
@@ -8,15 +8,15 @@ import (
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/handlers"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/repository"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/service"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/services"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/smdp"
|
||||
)
|
||||
|
||||
type SelectionIntegration struct {
|
||||
manager *smdp.SMDPManager
|
||||
selectionService *service.SelectionService
|
||||
selectionService *services.SelectionService
|
||||
selectionHandler *handlers.SelectionHandler
|
||||
smdpService *service.SMDPService
|
||||
smdpService *services.SMDPService
|
||||
server *http.Server
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ func NewSelectionIntegration(repo *repository.PostgresProfileStore) *SelectionIn
|
||||
manager := smdp.NewSMDPManager(repo, config)
|
||||
|
||||
// Create selection service
|
||||
selectionService := service.NewSelectionService(manager)
|
||||
selectionService := services.NewSelectionService(manager)
|
||||
|
||||
// Create SMDP service
|
||||
smdpService := service.NewSMDPService(repo)
|
||||
smdpService := services.NewSMDPService(repo)
|
||||
|
||||
return &SelectionIntegration{
|
||||
manager: manager,
|
||||
@@ -85,7 +85,7 @@ func (si *SelectionIntegration) GetManager() *smdp.SMDPManager {
|
||||
}
|
||||
|
||||
// GetSelectionService returns the selection service for testing
|
||||
func (si *SelectionIntegration) GetSelectionService() *service.SelectionService {
|
||||
func (si *SelectionIntegration) GetSelectionService() *services.SelectionService {
|
||||
return si.selectionService
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/handlers"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/repository"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/service"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/services"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/smdp"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// SMDPIntegration integrates the multi-carrier SM-DP+ system with the existing carrier connector
|
||||
type SMDPIntegration struct {
|
||||
service *service.SMDPService
|
||||
service *services.SMDPService
|
||||
handler *handlers.SMDPHandler
|
||||
repository *repository.PostgresProfileStore
|
||||
logger *logrus.Logger
|
||||
@@ -24,7 +24,7 @@ func NewSMDPIntegration(repo *repository.PostgresProfileStore) *SMDPIntegration
|
||||
logger := logrus.New()
|
||||
logger.SetLevel(logrus.InfoLevel)
|
||||
|
||||
svc := service.NewSMDPService(repo)
|
||||
svc := services.NewSMDPService(repo)
|
||||
manager := svc.GetManager()
|
||||
hnd := handlers.NewSMDPHandler(manager)
|
||||
|
||||
@@ -148,7 +148,7 @@ func (i *SMDPIntegration) metricsHandler(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetService returns the SM-DP+ service for direct access
|
||||
func (i *SMDPIntegration) GetService() *service.SMDPService {
|
||||
func (i *SMDPIntegration) GetService() *services.SMDPService {
|
||||
return i.service
|
||||
}
|
||||
|
||||
|
||||
+18
-17
@@ -1,9 +1,10 @@
|
||||
package currency
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -23,7 +24,7 @@ func NewGormRepository(db *gorm.DB, logger *logrus.Logger) *GormRepository {
|
||||
}
|
||||
|
||||
// CreateCurrency creates a new currency
|
||||
func (r *GormRepository) CreateCurrency(ctx context.Context, currency *Currency) error {
|
||||
func (r *GormRepository) CreateCurrency(ctx context.Context, currency *currency.Currency) error {
|
||||
model := r.currencyToModel(currency)
|
||||
|
||||
if err := r.db.WithContext(ctx).Create(model).Error; err != nil {
|
||||
@@ -35,8 +36,8 @@ func (r *GormRepository) CreateCurrency(ctx context.Context, currency *Currency)
|
||||
}
|
||||
|
||||
// GetCurrency retrieves a currency by code
|
||||
func (r *GormRepository) GetCurrency(ctx context.Context, code string) (*Currency, error) {
|
||||
var model CurrencyModel
|
||||
func (r *GormRepository) GetCurrency(ctx context.Context, code string) (*currency.Currency, error) {
|
||||
var model currency.CurrencyModel
|
||||
if err := r.db.WithContext(ctx).Where("code = ?", code).First(&model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("currency not found: %s", code)
|
||||
@@ -49,7 +50,7 @@ func (r *GormRepository) GetCurrency(ctx context.Context, code string) (*Currenc
|
||||
}
|
||||
|
||||
// UpdateCurrency updates an existing currency
|
||||
func (r *GormRepository) UpdateCurrency(ctx context.Context, currency *Currency) error {
|
||||
func (r *GormRepository) UpdateCurrency(ctx context.Context, currency *currency.Currency) error {
|
||||
model := r.currencyToModel(currency)
|
||||
|
||||
if err := r.db.WithContext(ctx).Save(model).Error; err != nil {
|
||||
@@ -62,7 +63,7 @@ func (r *GormRepository) UpdateCurrency(ctx context.Context, currency *Currency)
|
||||
|
||||
// DeleteCurrency deletes a currency
|
||||
func (r *GormRepository) DeleteCurrency(ctx context.Context, code string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&CurrencyModel{}, "code = ?", code).Error; err != nil {
|
||||
if err := r.db.WithContext(ctx).Delete(¤cy.CurrencyModel{}, "code = ?", code).Error; err != nil {
|
||||
r.logger.WithError(err).Error("Failed to delete currency")
|
||||
return fmt.Errorf("failed to delete currency: %w", err)
|
||||
}
|
||||
@@ -71,8 +72,8 @@ func (r *GormRepository) DeleteCurrency(ctx context.Context, code string) error
|
||||
}
|
||||
|
||||
// ListCurrencies retrieves currencies based on filter
|
||||
func (r *GormRepository) ListCurrencies(ctx context.Context, filter *CurrencyFilter) ([]*Currency, error) {
|
||||
query := r.db.WithContext(ctx).Model(&CurrencyModel{})
|
||||
func (r *GormRepository) ListCurrencies(ctx context.Context, filter *currency.CurrencyFilter) ([]*currency.Currency, error) {
|
||||
query := r.db.WithContext(ctx).Model(¤cy.CurrencyModel{})
|
||||
|
||||
// Apply filters
|
||||
if filter.IsActive != nil {
|
||||
@@ -101,13 +102,13 @@ func (r *GormRepository) ListCurrencies(ctx context.Context, filter *CurrencyFil
|
||||
query = query.Offset(filter.Offset)
|
||||
}
|
||||
|
||||
var models []CurrencyModel
|
||||
var models []currency.CurrencyModel
|
||||
if err := query.Find(&models).Error; err != nil {
|
||||
r.logger.WithError(err).Error("Failed to list currencies")
|
||||
return nil, fmt.Errorf("failed to list currencies: %w", err)
|
||||
}
|
||||
|
||||
currencies := make([]*Currency, 0, len(models))
|
||||
currencies := make([]*currency.Currency, 0, len(models))
|
||||
for _, model := range models {
|
||||
curr, err := r.modelToCurrency(&model)
|
||||
if err != nil {
|
||||
@@ -121,8 +122,8 @@ func (r *GormRepository) ListCurrencies(ctx context.Context, filter *CurrencyFil
|
||||
}
|
||||
|
||||
// CountCurrencies counts currencies based on filter
|
||||
func (r *GormRepository) CountCurrencies(ctx context.Context, filter *CurrencyFilter) (int, error) {
|
||||
query := r.db.WithContext(ctx).Model(&CurrencyModel{})
|
||||
func (r *GormRepository) CountCurrencies(ctx context.Context, filter *currency.CurrencyFilter) (int, error) {
|
||||
query := r.db.WithContext(ctx).Model(¤cy.CurrencyModel{})
|
||||
|
||||
// Apply filters
|
||||
if filter.IsActive != nil {
|
||||
@@ -142,7 +143,7 @@ func (r *GormRepository) CountCurrencies(ctx context.Context, filter *CurrencyFi
|
||||
}
|
||||
|
||||
// CreateExchangeRate creates a new exchange rate
|
||||
func (r *GormRepository) CreateExchangeRate(ctx context.Context, rate *ExchangeRate) error {
|
||||
func (r *GormRepository) CreateExchangeRate(ctx context.Context, rate *currency.ExchangeRate) error {
|
||||
model := r.exchangeRateToModel(rate)
|
||||
|
||||
if err := r.db.WithContext(ctx).Create(model).Error; err != nil {
|
||||
@@ -154,8 +155,8 @@ func (r *GormRepository) CreateExchangeRate(ctx context.Context, rate *ExchangeR
|
||||
}
|
||||
|
||||
// GetExchangeRate retrieves an exchange rate by ID
|
||||
func (r *GormRepository) GetExchangeRate(ctx context.Context, fromCurrency, toCurrency string) (*ExchangeRate, error) {
|
||||
var model ExchangeRateModel
|
||||
func (r *GormRepository) GetExchangeRate(ctx context.Context, fromCurrency, toCurrency string) (*currency.ExchangeRate, error) {
|
||||
var model currency.ExchangeRateModel
|
||||
if err := r.db.WithContext(ctx).Where("from_currency = ? AND to_currency = ?", fromCurrency, toCurrency).First(&model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("exchange rate not found: %s to %s", fromCurrency, toCurrency)
|
||||
@@ -168,7 +169,7 @@ func (r *GormRepository) GetExchangeRate(ctx context.Context, fromCurrency, toCu
|
||||
}
|
||||
|
||||
// UpdateExchangeRate updates an existing exchange rate
|
||||
func (r *GormRepository) UpdateExchangeRate(ctx context.Context, rate *ExchangeRate) error {
|
||||
func (r *GormRepository) UpdateExchangeRate(ctx context.Context, rate *currency.ExchangeRate) error {
|
||||
model := r.exchangeRateToModel(rate)
|
||||
|
||||
if err := r.db.WithContext(ctx).Save(model).Error; err != nil {
|
||||
@@ -181,7 +182,7 @@ func (r *GormRepository) UpdateExchangeRate(ctx context.Context, rate *ExchangeR
|
||||
|
||||
// DeleteExchangeRate deletes an exchange rate
|
||||
func (r *GormRepository) DeleteExchangeRate(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&ExchangeRateModel{}, "id = ?", id).Error; err != nil {
|
||||
if err := r.db.WithContext(ctx).Delete(¤cy.ExchangeRateModel{}, "id = ?", id).Error; err != nil {
|
||||
r.logger.WithError(err).Error("Failed to delete exchange rate")
|
||||
return fmt.Errorf("failed to delete exchange rate: %w", err)
|
||||
}
|
||||
+17
-15
@@ -1,14 +1,16 @@
|
||||
package currency
|
||||
package repository
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
)
|
||||
|
||||
// currencyToModel converts currency domain model to database model
|
||||
func (r *GormRepository) currencyToModel(currency *Currency) *CurrencyModel {
|
||||
return &CurrencyModel{
|
||||
func (r *GormRepository) currencyToModel(currency *currency.Currency) *currency.CurrencyModel {
|
||||
return ¤cy.CurrencyModel{
|
||||
Code: currency.Code,
|
||||
Name: currency.Name,
|
||||
Symbol: currency.Symbol,
|
||||
@@ -21,13 +23,13 @@ func (r *GormRepository) currencyToModel(currency *Currency) *CurrencyModel {
|
||||
}
|
||||
|
||||
// modelToCurrency converts database model to currency domain model
|
||||
func (r *GormRepository) modelToCurrency(model *CurrencyModel) (*Currency, error) {
|
||||
func (r *GormRepository) modelToCurrency(model *currency.CurrencyModel) (*currency.Currency, error) {
|
||||
var regions []string
|
||||
if model.SupportedRegions != "" {
|
||||
regions = strings.Split(model.SupportedRegions, ",")
|
||||
}
|
||||
|
||||
return &Currency{
|
||||
return ¤cy.Currency{
|
||||
Code: model.Code,
|
||||
Name: model.Name,
|
||||
Symbol: model.Symbol,
|
||||
@@ -40,8 +42,8 @@ func (r *GormRepository) modelToCurrency(model *CurrencyModel) (*Currency, error
|
||||
}
|
||||
|
||||
// exchangeRateToModel converts exchange rate domain model to database model
|
||||
func (r *GormRepository) exchangeRateToModel(rate *ExchangeRate) *ExchangeRateModel {
|
||||
return &ExchangeRateModel{
|
||||
func (r *GormRepository) exchangeRateToModel(rate *currency.ExchangeRate) *currency.ExchangeRateModel {
|
||||
return ¤cy.ExchangeRateModel{
|
||||
ID: rate.ID,
|
||||
FromCurrency: rate.FromCurrency,
|
||||
ToCurrency: rate.ToCurrency,
|
||||
@@ -56,8 +58,8 @@ func (r *GormRepository) exchangeRateToModel(rate *ExchangeRate) *ExchangeRateMo
|
||||
}
|
||||
|
||||
// modelToExchangeRate converts database model to exchange rate domain model
|
||||
func (r *GormRepository) modelToExchangeRate(model *ExchangeRateModel) (*ExchangeRate, error) {
|
||||
return &ExchangeRate{
|
||||
func (r *GormRepository) modelToExchangeRate(model *currency.ExchangeRateModel) (*currency.ExchangeRate, error) {
|
||||
return ¤cy.ExchangeRate{
|
||||
ID: model.ID,
|
||||
FromCurrency: model.FromCurrency,
|
||||
ToCurrency: model.ToCurrency,
|
||||
@@ -72,7 +74,7 @@ func (r *GormRepository) modelToExchangeRate(model *ExchangeRateModel) (*Exchang
|
||||
}
|
||||
|
||||
// transactionToModel converts transaction domain model to database model
|
||||
func (r *GormRepository) transactionToModel(transaction *Transaction) *TransactionModel {
|
||||
func (r *GormRepository) transactionToModel(transaction *currency.Transaction) *currency.TransactionModel {
|
||||
metadata := ""
|
||||
if transaction.Metadata != nil {
|
||||
if data, err := json.Marshal(transaction.Metadata); err == nil {
|
||||
@@ -80,7 +82,7 @@ func (r *GormRepository) transactionToModel(transaction *Transaction) *Transacti
|
||||
}
|
||||
}
|
||||
|
||||
return &TransactionModel{
|
||||
return ¤cy.TransactionModel{
|
||||
ID: transaction.ID,
|
||||
ProfileID: transaction.ProfileID,
|
||||
SubscriptionID: transaction.SubscriptionID,
|
||||
@@ -99,7 +101,7 @@ func (r *GormRepository) transactionToModel(transaction *Transaction) *Transacti
|
||||
}
|
||||
|
||||
// modelToTransaction converts database model to transaction domain model
|
||||
func (r *GormRepository) modelToTransaction(model *TransactionModel) (*Transaction, error) {
|
||||
func (r *GormRepository) modelToTransaction(model *currency.TransactionModel) (*currency.Transaction, error) {
|
||||
var metadata map[string]interface{}
|
||||
if model.Metadata != "" {
|
||||
if err := json.Unmarshal([]byte(model.Metadata), &metadata); err != nil {
|
||||
@@ -107,18 +109,18 @@ func (r *GormRepository) modelToTransaction(model *TransactionModel) (*Transacti
|
||||
}
|
||||
}
|
||||
|
||||
return &Transaction{
|
||||
return ¤cy.Transaction{
|
||||
ID: model.ID,
|
||||
ProfileID: model.ProfileID,
|
||||
SubscriptionID: model.SubscriptionID,
|
||||
Type: TransactionType(model.Type),
|
||||
Type: currency.TransactionType(model.Type),
|
||||
Amount: model.Amount,
|
||||
Currency: model.Currency,
|
||||
BaseAmount: model.BaseAmount,
|
||||
BaseCurrency: model.BaseCurrency,
|
||||
ExchangeRate: model.ExchangeRate,
|
||||
Description: model.Description,
|
||||
Status: TransactionStatus(model.Status),
|
||||
Status: currency.TransactionStatus(model.Status),
|
||||
Metadata: metadata,
|
||||
CreatedAt: model.CreatedAt,
|
||||
UpdatedAt: model.UpdatedAt,
|
||||
+1
-15
@@ -1,27 +1,13 @@
|
||||
package rateplan
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GormRepository implements the Repository interface using GORM
|
||||
type GormRepository struct {
|
||||
db *gorm.DB
|
||||
logger *logrus.Logger
|
||||
}
|
||||
|
||||
// NewGormRepository creates a new GORM repository
|
||||
func NewGormRepository(db *gorm.DB, logger *logrus.Logger) *GormRepository {
|
||||
return &GormRepository{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
// CreateUsage creates a new usage record
|
||||
func (r *GormRepository) CreateUsage(ctx context.Context, usage *RatePlanUsage) error {
|
||||
usage.LastUpdated = time.Now()
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
package rateplan
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
|
||||
)
|
||||
|
||||
// CreateRatePlan creates a new rate plan
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
package rateplan
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CreateSubscription creates a new rate plan subscription
|
||||
func (r *GormRepository) CreateSubscription(ctx context.Context, subscription *RatePlanSubscription) error {
|
||||
now := time.Now()
|
||||
@@ -85,6 +86,7 @@ func (r *GormRepository) DeleteSubscription(ctx context.Context, id string) erro
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListSubscriptions retrieves subscriptions for a profile
|
||||
func (r *GormRepository) ListSubscriptions(ctx context.Context, profileID string, filter *SubscriptionFilter) ([]*RatePlanSubscription, error) {
|
||||
query := r.db.WithContext(ctx).Where("profile_id = ?", profileID)
|
||||
+9
-7
@@ -1,4 +1,4 @@
|
||||
package currency
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
)
|
||||
|
||||
// ListExchangeRates retrieves exchange rates based on filter
|
||||
func (r *GormRepository) ListExchangeRates(ctx context.Context, filter *ExchangeRateFilter) ([]*ExchangeRate, error) {
|
||||
query := r.db.WithContext(ctx).Model(&ExchangeRateModel{})
|
||||
func (r *GormRepository) ListExchangeRates(ctx context.Context, filter *currency.ExchangeRateFilter) ([]*currency.ExchangeRate, error) {
|
||||
query := r.db.WithContext(ctx).Model(¤cy.ExchangeRateModel{})
|
||||
|
||||
// Apply filters
|
||||
if filter.FromCurrency != "" {
|
||||
@@ -50,13 +52,13 @@ func (r *GormRepository) ListExchangeRates(ctx context.Context, filter *Exchange
|
||||
query = query.Offset(filter.Offset)
|
||||
}
|
||||
|
||||
var models []ExchangeRateModel
|
||||
var models []currency.ExchangeRateModel
|
||||
if err := query.Find(&models).Error; err != nil {
|
||||
r.logger.WithError(err).Error("Failed to list exchange rates")
|
||||
return nil, fmt.Errorf("failed to list exchange rates: %w", err)
|
||||
}
|
||||
|
||||
rates := make([]*ExchangeRate, 0, len(models))
|
||||
rates := make([]*currency.ExchangeRate, 0, len(models))
|
||||
for _, model := range models {
|
||||
rate, err := r.modelToExchangeRate(&model)
|
||||
if err != nil {
|
||||
@@ -70,9 +72,9 @@ func (r *GormRepository) ListExchangeRates(ctx context.Context, filter *Exchange
|
||||
}
|
||||
|
||||
// GetLatestExchangeRate gets the latest valid exchange rate
|
||||
func (r *GormRepository) GetLatestExchangeRate(ctx context.Context, fromCurrency, toCurrency string) (*ExchangeRate, error) {
|
||||
func (r *GormRepository) GetLatestExchangeRate(ctx context.Context, fromCurrency, toCurrency string) (*currency.ExchangeRate, error) {
|
||||
now := time.Now()
|
||||
var model ExchangeRateModel
|
||||
var model currency.ExchangeRateModel
|
||||
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("from_currency = ? AND to_currency = ? AND is_active = ?", fromCurrency, toCurrency, true).
|
||||
+14
-12
@@ -1,14 +1,16 @@
|
||||
package currency
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
)
|
||||
|
||||
// CreateTransaction creates a new transaction
|
||||
func (r *GormRepository) CreateTransaction(ctx context.Context, transaction *Transaction) error {
|
||||
func (r *GormRepository) CreateTransaction(ctx context.Context, transaction *currency.Transaction) error {
|
||||
model := r.transactionToModel(transaction)
|
||||
|
||||
if err := r.db.WithContext(ctx).Create(model).Error; err != nil {
|
||||
@@ -20,8 +22,8 @@ func (r *GormRepository) CreateTransaction(ctx context.Context, transaction *Tra
|
||||
}
|
||||
|
||||
// GetTransaction retrieves a transaction by ID
|
||||
func (r *GormRepository) GetTransaction(ctx context.Context, id string) (*Transaction, error) {
|
||||
var model TransactionModel
|
||||
func (r *GormRepository) GetTransaction(ctx context.Context, id string) (*currency.Transaction, error) {
|
||||
var model currency.TransactionModel
|
||||
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("transaction not found: %s", id)
|
||||
@@ -34,7 +36,7 @@ func (r *GormRepository) GetTransaction(ctx context.Context, id string) (*Transa
|
||||
}
|
||||
|
||||
// UpdateTransaction updates an existing transaction
|
||||
func (r *GormRepository) UpdateTransaction(ctx context.Context, transaction *Transaction) error {
|
||||
func (r *GormRepository) UpdateTransaction(ctx context.Context, transaction *currency.Transaction) error {
|
||||
model := r.transactionToModel(transaction)
|
||||
|
||||
if err := r.db.WithContext(ctx).Save(model).Error; err != nil {
|
||||
@@ -47,7 +49,7 @@ func (r *GormRepository) UpdateTransaction(ctx context.Context, transaction *Tra
|
||||
|
||||
// DeleteTransaction deletes a transaction
|
||||
func (r *GormRepository) DeleteTransaction(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&TransactionModel{}, "id = ?", id).Error; err != nil {
|
||||
if err := r.db.WithContext(ctx).Delete(¤cy.TransactionModel{}, "id = ?", id).Error; err != nil {
|
||||
r.logger.WithError(err).Error("Failed to delete transaction")
|
||||
return fmt.Errorf("failed to delete transaction: %w", err)
|
||||
}
|
||||
@@ -56,8 +58,8 @@ func (r *GormRepository) DeleteTransaction(ctx context.Context, id string) error
|
||||
}
|
||||
|
||||
// ListTransactions retrieves transactions based on filter
|
||||
func (r *GormRepository) ListTransactions(ctx context.Context, filter *TransactionFilter) ([]*Transaction, error) {
|
||||
query := r.db.WithContext(ctx).Model(&TransactionModel{})
|
||||
func (r *GormRepository) ListTransactions(ctx context.Context, filter *currency.TransactionFilter) ([]*currency.Transaction, error) {
|
||||
query := r.db.WithContext(ctx).Model(¤cy.TransactionModel{})
|
||||
|
||||
// Apply filters
|
||||
if filter.ProfileID != "" {
|
||||
@@ -107,13 +109,13 @@ func (r *GormRepository) ListTransactions(ctx context.Context, filter *Transacti
|
||||
query = query.Offset(filter.Offset)
|
||||
}
|
||||
|
||||
var models []TransactionModel
|
||||
var models []currency.TransactionModel
|
||||
if err := query.Find(&models).Error; err != nil {
|
||||
r.logger.WithError(err).Error("Failed to list transactions")
|
||||
return nil, fmt.Errorf("failed to list transactions: %w", err)
|
||||
}
|
||||
|
||||
transactions := make([]*Transaction, 0, len(models))
|
||||
transactions := make([]*currency.Transaction, 0, len(models))
|
||||
for _, model := range models {
|
||||
tx, err := r.modelToTransaction(&model)
|
||||
if err != nil {
|
||||
@@ -127,8 +129,8 @@ func (r *GormRepository) ListTransactions(ctx context.Context, filter *Transacti
|
||||
}
|
||||
|
||||
// CountTransactions counts transactions based on filter
|
||||
func (r *GormRepository) CountTransactions(ctx context.Context, filter *TransactionFilter) (int, error) {
|
||||
query := r.db.WithContext(ctx).Model(&TransactionModel{})
|
||||
func (r *GormRepository) CountTransactions(ctx context.Context, filter *currency.TransactionFilter) (int, error) {
|
||||
query := r.db.WithContext(ctx).Model(¤cy.TransactionModel{})
|
||||
|
||||
// Apply filters
|
||||
if filter.ProfileID != "" {
|
||||
+31
-44
@@ -1,21 +1,22 @@
|
||||
package currency
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// AnalyticsServiceImpl handles currency analytics operations
|
||||
type AnalyticsServiceImpl struct {
|
||||
repository Repository
|
||||
repository currency.Repository
|
||||
logger *logrus.Logger
|
||||
}
|
||||
|
||||
// NewAnalyticsService creates a new analytics service
|
||||
func NewAnalyticsService(repository Repository, logger *logrus.Logger) *AnalyticsServiceImpl {
|
||||
func NewAnalyticsService(repository currency.Repository, logger *logrus.Logger) *AnalyticsServiceImpl {
|
||||
return &AnalyticsServiceImpl{
|
||||
repository: repository,
|
||||
logger: logger,
|
||||
@@ -23,12 +24,12 @@ func NewAnalyticsService(repository Repository, logger *logrus.Logger) *Analytic
|
||||
}
|
||||
|
||||
// GetRevenueByCurrency calculates revenue breakdown by currency
|
||||
func (s *AnalyticsServiceImpl) GetRevenueByCurrency(ctx context.Context, filter *TransactionFilter) (map[string]float64, error) {
|
||||
func (s *AnalyticsServiceImpl) GetRevenueByCurrency(ctx context.Context, filter *currency.TransactionFilter) (map[string]float64, error) {
|
||||
if filter == nil {
|
||||
filter = &TransactionFilter{}
|
||||
filter = ¤cy.TransactionFilter{}
|
||||
}
|
||||
|
||||
filter.Status = TransactionStatusCompleted
|
||||
filter.Status = currency.TransactionStatusCompleted
|
||||
|
||||
transactions, err := s.repository.ListTransactions(ctx, filter)
|
||||
if err != nil {
|
||||
@@ -39,7 +40,7 @@ func (s *AnalyticsServiceImpl) GetRevenueByCurrency(ctx context.Context, filter
|
||||
revenueByCurrency := make(map[string]float64)
|
||||
|
||||
for _, tx := range transactions {
|
||||
if tx.Type == TransactionTypeSubscription || tx.Type == TransactionTypeUsage || tx.Type == TransactionTypeOverage {
|
||||
if tx.Type == currency.TransactionTypeSubscription || tx.Type == currency.TransactionTypeUsage || tx.Type == currency.TransactionTypeOverage {
|
||||
revenueByCurrency[tx.Currency] += tx.Amount
|
||||
}
|
||||
}
|
||||
@@ -48,9 +49,9 @@ func (s *AnalyticsServiceImpl) GetRevenueByCurrency(ctx context.Context, filter
|
||||
}
|
||||
|
||||
// GetTransactionVolumeByCurrency calculates transaction volume by currency
|
||||
func (s *AnalyticsServiceImpl) GetTransactionVolumeByCurrency(ctx context.Context, filter *TransactionFilter) (map[string]int64, error) {
|
||||
func (s *AnalyticsServiceImpl) GetTransactionVolumeByCurrency(ctx context.Context, filter *currency.TransactionFilter) (map[string]int64, error) {
|
||||
if filter == nil {
|
||||
filter = &TransactionFilter{}
|
||||
filter = ¤cy.TransactionFilter{}
|
||||
}
|
||||
|
||||
transactions, err := s.repository.ListTransactions(ctx, filter)
|
||||
@@ -69,8 +70,8 @@ func (s *AnalyticsServiceImpl) GetTransactionVolumeByCurrency(ctx context.Contex
|
||||
}
|
||||
|
||||
// GetExchangeRateTrends retrieves exchange rate trends for a currency pair
|
||||
func (s *AnalyticsServiceImpl) GetExchangeRateTrends(ctx context.Context, fromCurrency, toCurrency string, days int) ([]*ExchangeRate, error) {
|
||||
filter := &ExchangeRateFilter{
|
||||
func (s *AnalyticsServiceImpl) GetExchangeRateTrends(ctx context.Context, fromCurrency, toCurrency string, days int) ([]*currency.ExchangeRate, error) {
|
||||
filter := ¤cy.ExchangeRateFilter{
|
||||
FromCurrency: fromCurrency,
|
||||
ToCurrency: toCurrency,
|
||||
IsValid: &[]bool{false}[0], // Include historical rates
|
||||
@@ -89,15 +90,15 @@ func (s *AnalyticsServiceImpl) GetExchangeRateTrends(ctx context.Context, fromCu
|
||||
}
|
||||
|
||||
// GetCurrencyUsageStats retrieves currency usage statistics
|
||||
func (s *AnalyticsServiceImpl) GetCurrencyUsageStats(ctx context.Context) (*CurrencyUsageStats, error) {
|
||||
func (s *AnalyticsServiceImpl) GetCurrencyUsageStats(ctx context.Context) (*currency.CurrencyUsageStats, error) {
|
||||
// Get total currencies
|
||||
totalCurrencies, err := s.repository.CountCurrencies(ctx, &CurrencyFilter{})
|
||||
totalCurrencies, err := s.repository.CountCurrencies(ctx, ¤cy.CurrencyFilter{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to count currencies: %w", err)
|
||||
}
|
||||
|
||||
// Get active currencies
|
||||
activeCurrencies, err := s.repository.CountCurrencies(ctx, &CurrencyFilter{
|
||||
activeCurrencies, err := s.repository.CountCurrencies(ctx, ¤cy.CurrencyFilter{
|
||||
IsActive: &[]bool{true}[0],
|
||||
})
|
||||
if err != nil {
|
||||
@@ -105,14 +106,14 @@ func (s *AnalyticsServiceImpl) GetCurrencyUsageStats(ctx context.Context) (*Curr
|
||||
}
|
||||
|
||||
// Get total transactions
|
||||
totalTransactions, err := s.repository.CountTransactions(ctx, &TransactionFilter{})
|
||||
totalTransactions, err := s.repository.CountTransactions(ctx, ¤cy.TransactionFilter{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to count transactions: %w", err)
|
||||
}
|
||||
|
||||
// Get total volume
|
||||
transactions, err := s.repository.ListTransactions(ctx, &TransactionFilter{
|
||||
Status: TransactionStatusCompleted,
|
||||
transactions, err := s.repository.ListTransactions(ctx, ¤cy.TransactionFilter{
|
||||
Status: currency.TransactionStatusCompleted,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get transactions for volume: %w", err)
|
||||
@@ -138,12 +139,12 @@ func (s *AnalyticsServiceImpl) GetCurrencyUsageStats(ctx context.Context) (*Curr
|
||||
}
|
||||
|
||||
// Get exchange rate count (using ListExchangeRates for now since CountExchangeRates doesn't exist)
|
||||
exchangeRates, err := s.repository.ListExchangeRates(ctx, &ExchangeRateFilter{})
|
||||
exchangeRates, err := s.repository.ListExchangeRates(ctx, ¤cy.ExchangeRateFilter{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to count exchange rates: %w", err)
|
||||
}
|
||||
|
||||
return &CurrencyUsageStats{
|
||||
return ¤cy.CurrencyUsageStats{
|
||||
TotalCurrencies: totalCurrencies,
|
||||
ActiveCurrencies: activeCurrencies,
|
||||
TotalTransactions: int64(totalTransactions),
|
||||
@@ -160,8 +161,8 @@ func (s *AnalyticsServiceImpl) GetMonthlyRevenueTrends(ctx context.Context, mont
|
||||
endDate := time.Now()
|
||||
startDate := endDate.AddDate(0, -months, 0)
|
||||
|
||||
filter := &TransactionFilter{
|
||||
Status: TransactionStatusCompleted,
|
||||
filter := ¤cy.TransactionFilter{
|
||||
Status: currency.TransactionStatusCompleted,
|
||||
FromDate: &startDate,
|
||||
ToDate: &endDate,
|
||||
}
|
||||
@@ -183,18 +184,18 @@ func (s *AnalyticsServiceImpl) GetMonthlyRevenueTrends(ctx context.Context, mont
|
||||
}
|
||||
|
||||
// GetTopCurrenciesByRevenue returns top currencies by revenue
|
||||
func (s *AnalyticsServiceImpl) GetTopCurrenciesByRevenue(ctx context.Context, limit int) ([]*CurrencyRevenue, error) {
|
||||
revenueByCurrency, err := s.GetRevenueByCurrency(ctx, &TransactionFilter{
|
||||
Status: TransactionStatusCompleted,
|
||||
func (s *AnalyticsServiceImpl) GetTopCurrenciesByRevenue(ctx context.Context, limit int) ([]*currency.CurrencyRevenue, error) {
|
||||
revenueByCurrency, err := s.GetRevenueByCurrency(ctx, ¤cy.TransactionFilter{
|
||||
Status: currency.TransactionStatusCompleted,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert to slice and sort
|
||||
var currencyRevenues []*CurrencyRevenue
|
||||
var currencyRevenues []*currency.CurrencyRevenue
|
||||
for currency, revenue := range revenueByCurrency {
|
||||
currencyRevenues = append(currencyRevenues, &CurrencyRevenue{
|
||||
currencyRevenues = append(currencyRevenues, ¤cy.CurrencyRevenue{
|
||||
Currency: currency,
|
||||
Revenue: revenue,
|
||||
})
|
||||
@@ -208,16 +209,10 @@ func (s *AnalyticsServiceImpl) GetTopCurrenciesByRevenue(ctx context.Context, li
|
||||
return currencyRevenues, nil
|
||||
}
|
||||
|
||||
// CurrencyRevenue represents revenue for a specific currency
|
||||
type CurrencyRevenue struct {
|
||||
Currency string `json:"currency"`
|
||||
Revenue float64 `json:"revenue"`
|
||||
}
|
||||
|
||||
// GetTransactionTypeAnalytics returns analytics by transaction type
|
||||
func (s *AnalyticsServiceImpl) GetTransactionTypeAnalytics(ctx context.Context, filter *TransactionFilter) (map[string]*TransactionTypeStats, error) {
|
||||
func (s *AnalyticsServiceImpl) GetTransactionTypeAnalytics(ctx context.Context, filter *currency.TransactionFilter) (map[string]*currency.TransactionTypeStats, error) {
|
||||
if filter == nil {
|
||||
filter = &TransactionFilter{}
|
||||
filter = ¤cy.TransactionFilter{}
|
||||
}
|
||||
|
||||
transactions, err := s.repository.ListTransactions(ctx, filter)
|
||||
@@ -226,13 +221,13 @@ func (s *AnalyticsServiceImpl) GetTransactionTypeAnalytics(ctx context.Context,
|
||||
return nil, fmt.Errorf("failed to get transactions: %w", err)
|
||||
}
|
||||
|
||||
typeStats := make(map[string]*TransactionTypeStats)
|
||||
typeStats := make(map[string]*currency.TransactionTypeStats)
|
||||
|
||||
for _, tx := range transactions {
|
||||
typeKey := string(tx.Type)
|
||||
|
||||
if _, exists := typeStats[typeKey]; !exists {
|
||||
typeStats[typeKey] = &TransactionTypeStats{
|
||||
typeStats[typeKey] = ¤cy.TransactionTypeStats{
|
||||
Type: tx.Type,
|
||||
Count: 0,
|
||||
Amount: 0.0,
|
||||
@@ -247,11 +242,3 @@ func (s *AnalyticsServiceImpl) GetTransactionTypeAnalytics(ctx context.Context,
|
||||
|
||||
return typeStats, nil
|
||||
}
|
||||
|
||||
// TransactionTypeStats represents statistics for a transaction type
|
||||
type TransactionTypeStats struct {
|
||||
Type TransactionType `json:"type"`
|
||||
Count int `json:"count"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package currency
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
+18
-17
@@ -1,36 +1,37 @@
|
||||
package currency
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type ExchangeRateService struct {
|
||||
repository Repository
|
||||
repository currency.Repository
|
||||
logger *logrus.Logger
|
||||
providers []ExchangeRateProvider
|
||||
providers []currency.ExchangeRateProvider
|
||||
baseCurrency string
|
||||
}
|
||||
|
||||
func NewExchangeRateService(repository Repository, logger *logrus.Logger, baseCurrency string) *ExchangeRateService {
|
||||
func NewExchangeRateService(repository currency.Repository, logger *logrus.Logger, baseCurrency string) *ExchangeRateService {
|
||||
return &ExchangeRateService{
|
||||
repository: repository,
|
||||
logger: logger,
|
||||
providers: make([]ExchangeRateProvider, 0),
|
||||
providers: make([]currency.ExchangeRateProvider, 0),
|
||||
baseCurrency: baseCurrency,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ExchangeRateService) AddProvider(provider ExchangeRateProvider) {
|
||||
func (s *ExchangeRateService) AddProvider(provider currency.ExchangeRateProvider) {
|
||||
s.providers = append(s.providers, provider)
|
||||
}
|
||||
|
||||
func (s *ExchangeRateService) GetExchangeRate(ctx context.Context, fromCurrency, toCurrency string) (*ExchangeRate, error) {
|
||||
func (s *ExchangeRateService) GetExchangeRate(ctx context.Context, fromCurrency, toCurrency string) (*currency.ExchangeRate, error) {
|
||||
if fromCurrency == toCurrency {
|
||||
return &ExchangeRate{
|
||||
return ¤cy.ExchangeRate{
|
||||
FromCurrency: fromCurrency,
|
||||
ToCurrency: toCurrency,
|
||||
Rate: 1.0,
|
||||
@@ -48,7 +49,7 @@ func (s *ExchangeRateService) GetExchangeRate(ctx context.Context, fromCurrency,
|
||||
for _, provider := range s.providers {
|
||||
providerRate, err := provider.GetRate(ctx, fromCurrency, toCurrency)
|
||||
if err == nil {
|
||||
newRate := &ExchangeRate{
|
||||
newRate := ¤cy.ExchangeRate{
|
||||
ID: fmt.Sprintf("%s_%s_%d", fromCurrency, toCurrency, time.Now().Unix()),
|
||||
FromCurrency: fromCurrency,
|
||||
ToCurrency: toCurrency,
|
||||
@@ -69,7 +70,7 @@ func (s *ExchangeRateService) GetExchangeRate(ctx context.Context, fromCurrency,
|
||||
return nil, fmt.Errorf("exchange rate not found: %s to %s", fromCurrency, toCurrency)
|
||||
}
|
||||
|
||||
func (s *ExchangeRateService) ConvertAmount(ctx context.Context, amount float64, fromCurrency, toCurrency string) (*CurrencyConversionResponse, error) {
|
||||
func (s *ExchangeRateService) ConvertAmount(ctx context.Context, amount float64, fromCurrency, toCurrency string) (*currency.CurrencyConversionResponse, error) {
|
||||
rate, err := s.GetExchangeRate(ctx, fromCurrency, toCurrency)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get exchange rate: %w", err)
|
||||
@@ -77,7 +78,7 @@ func (s *ExchangeRateService) ConvertAmount(ctx context.Context, amount float64,
|
||||
|
||||
convertedAmount := amount * rate.Rate
|
||||
|
||||
return &CurrencyConversionResponse{
|
||||
return ¤cy.CurrencyConversionResponse{
|
||||
OriginalAmount: amount,
|
||||
OriginalCurrency: fromCurrency,
|
||||
ConvertedAmount: convertedAmount,
|
||||
@@ -101,8 +102,8 @@ func (s *ExchangeRateService) RefreshRates(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ExchangeRateService) GetRateHistory(ctx context.Context, fromCurrency, toCurrency string, days int) ([]*ExchangeRate, error) {
|
||||
filter := &ExchangeRateFilter{
|
||||
func (s *ExchangeRateService) GetRateHistory(ctx context.Context, fromCurrency, toCurrency string, days int) ([]*currency.ExchangeRate, error) {
|
||||
filter := ¤cy.ExchangeRateFilter{
|
||||
FromCurrency: fromCurrency,
|
||||
ToCurrency: toCurrency,
|
||||
IsValid: &[]bool{false}[0], // Include historical rates
|
||||
@@ -119,7 +120,7 @@ func (s *ExchangeRateService) GetRateHistory(ctx context.Context, fromCurrency,
|
||||
return rates, nil
|
||||
}
|
||||
|
||||
func (s *ExchangeRateService) UpdateExchangeRate(ctx context.Context, rate *ExchangeRate) error {
|
||||
func (s *ExchangeRateService) UpdateExchangeRate(ctx context.Context, rate *currency.ExchangeRate) error {
|
||||
if rate.Rate <= 0 {
|
||||
return fmt.Errorf("invalid exchange rate: must be positive")
|
||||
}
|
||||
@@ -132,7 +133,7 @@ func (s *ExchangeRateService) UpdateExchangeRate(ctx context.Context, rate *Exch
|
||||
rate.ValidFrom = now
|
||||
rate.IsActive = true
|
||||
|
||||
filter := &ExchangeRateFilter{
|
||||
filter := ¤cy.ExchangeRateFilter{
|
||||
FromCurrency: rate.FromCurrency,
|
||||
ToCurrency: rate.ToCurrency,
|
||||
IsValid: &[]bool{true}[0],
|
||||
@@ -163,8 +164,8 @@ func (s *ExchangeRateService) UpdateExchangeRate(ctx context.Context, rate *Exch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ExchangeRateService) GetSupportedCurrencies(ctx context.Context) ([]*Currency, error) {
|
||||
filter := &CurrencyFilter{
|
||||
func (s *ExchangeRateService) GetSupportedCurrencies(ctx context.Context) ([]*currency.Currency, error) {
|
||||
filter := ¤cy.CurrencyFilter{
|
||||
IsActive: &[]bool{true}[0],
|
||||
}
|
||||
|
||||
+28
-27
@@ -1,4 +1,4 @@
|
||||
package currency
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,21 +7,22 @@ import (
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/currency"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/rateplan"
|
||||
)
|
||||
|
||||
// RatePlanCurrencyIntegrator integrates currency system with rate plans
|
||||
type RatePlanCurrencyIntegrator struct {
|
||||
billingService BillingService
|
||||
billingService currency.BillingService
|
||||
exchangeService *ExchangeRateService
|
||||
ratePlanService rateplan.Service
|
||||
logger *logrus.Logger
|
||||
baseCurrency string
|
||||
logger *logrus.Logger
|
||||
baseCurrency string
|
||||
}
|
||||
|
||||
// NewRatePlanCurrencyIntegrator creates a new rate plan currency integrator
|
||||
func NewRatePlanCurrencyIntegrator(
|
||||
billingService BillingService,
|
||||
billingService currency.BillingService,
|
||||
exchangeService *ExchangeRateService,
|
||||
ratePlanService rateplan.Service,
|
||||
logger *logrus.Logger,
|
||||
@@ -30,9 +31,9 @@ func NewRatePlanCurrencyIntegrator(
|
||||
return &RatePlanCurrencyIntegrator{
|
||||
billingService: billingService,
|
||||
exchangeService: exchangeService,
|
||||
ratePlanService: rateplanService,
|
||||
logger: logger,
|
||||
baseCurrency: baseCurrency,
|
||||
ratePlanService: ratePlanService,
|
||||
logger: logger,
|
||||
baseCurrency: baseCurrency,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +48,7 @@ func (rpci *RatePlanCurrencyIntegrator) SubscribeToPlanWithCurrency(ctx context.
|
||||
// Convert price to requested currency if needed
|
||||
subscriptionPrice := plan.BasePrice
|
||||
exchangeRate := 1.0
|
||||
|
||||
|
||||
if currency != plan.Currency {
|
||||
conversion, err := rpci.exchangeService.ConvertAmount(ctx, plan.BasePrice, plan.Currency, currency)
|
||||
if err != nil {
|
||||
@@ -60,10 +61,10 @@ func (rpci *RatePlanCurrencyIntegrator) SubscribeToPlanWithCurrency(ctx context.
|
||||
|
||||
// Create subscription with currency information
|
||||
subscription := &rateplan.RatePlanSubscription{
|
||||
ProfileID: profileID,
|
||||
RatePlanID: planID,
|
||||
Status: rateplan.SubscriptionStatusActive,
|
||||
StartedAt: time.Now(),
|
||||
ProfileID: profileID,
|
||||
RatePlanID: planID,
|
||||
Status: rateplan.SubscriptionStatusActive,
|
||||
StartedAt: time.Now(),
|
||||
Metadata: map[string]interface{}{
|
||||
"original_currency": plan.Currency,
|
||||
"subscription_currency": currency,
|
||||
@@ -89,13 +90,13 @@ func (rpci *RatePlanCurrencyIntegrator) SubscribeToPlanWithCurrency(ctx context.
|
||||
}
|
||||
|
||||
// Process initial billing
|
||||
billingReq := &BillingRequest{
|
||||
billingReq := ¤cy.BillingRequest{
|
||||
ProfileID: profileID,
|
||||
SubscriptionID: createdSubscription.ID,
|
||||
Amount: subscriptionPrice,
|
||||
Currency: currency,
|
||||
Amount: subscriptionPrice,
|
||||
Currency: currency,
|
||||
Description: fmt.Sprintf("Initial subscription to %s", plan.Name),
|
||||
BillingDate: time.Now(),
|
||||
BillingDate: time.Now(),
|
||||
}
|
||||
|
||||
_, err = rpci.billingService.ProcessBilling(ctx, billingReq)
|
||||
@@ -115,7 +116,7 @@ func (rpci *RatePlanCurrencyIntegrator) SubscribeToPlanWithCurrency(ctx context.
|
||||
}
|
||||
|
||||
// CalculatePlanCostInCurrency calculates the cost of a rate plan in a specific currency
|
||||
func (rpci *RatePlanCurrencyIntegrator) CalculatePlanCostInCurrency(ctx context.Context, planID string, currency string, usageData *rateplan.RatePlanUsage) (*BillingSummary, error) {
|
||||
func (rpci *RatePlanCurrencyIntegrator) CalculatePlanCostInCurrency(ctx context.Context, planID string, currency string, usageData *rateplan.RatePlanUsage) (*currency.BillingSummary, error) {
|
||||
// Get the rate plan
|
||||
plan, err := rpci.ratePlanService.GetRatePlan(ctx, planID)
|
||||
if err != nil {
|
||||
@@ -138,7 +139,7 @@ func (rpci *RatePlanCurrencyIntegrator) CalculatePlanCostInCurrency(ctx context.
|
||||
// Convert to requested currency
|
||||
convertedCost := baseCost
|
||||
exchangeRate := 1.0
|
||||
|
||||
|
||||
if currency != plan.Currency {
|
||||
conversion, err := rpci.exchangeService.ConvertAmount(ctx, baseCost, plan.Currency, currency)
|
||||
if err != nil {
|
||||
@@ -149,15 +150,15 @@ func (rpci *RatePlanCurrencyIntegrator) CalculatePlanCostInCurrency(ctx context.
|
||||
}
|
||||
|
||||
// Create billing summary
|
||||
summary := &BillingSummary{
|
||||
ProfileID: usageData.ProfileID,
|
||||
TotalAmount: convertedCost,
|
||||
Currency: currency,
|
||||
BaseTotalAmount: baseCost,
|
||||
BaseCurrency: plan.Currency,
|
||||
summary := ¤cy.BillingSummary{
|
||||
ProfileID: usageData.ProfileID,
|
||||
TotalAmount: convertedCost,
|
||||
Currency: currency,
|
||||
BaseTotalAmount: baseCost,
|
||||
BaseCurrency: plan.Currency,
|
||||
TransactionCount: 1,
|
||||
FromDate: time.Now().AddDate(0, -1, 0),
|
||||
ToDate: time.Now(),
|
||||
FromDate: time.Now().AddDate(0, -1, 0),
|
||||
ToDate: time.Now(),
|
||||
Breakdown: map[string]interface{}{
|
||||
"plan_id": planID,
|
||||
"plan_name": plan.Name,
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package currency
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -85,7 +85,7 @@ func (rpci *RatePlanCurrencyIntegrator) UpdatePlanCurrency(ctx context.Context,
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update rate plan: %w", err)
|
||||
}
|
||||
|
||||
|
||||
// Use the updated plan for logging
|
||||
plan = updatedPlan
|
||||
|
||||
@@ -145,7 +145,7 @@ func (rpci *RatePlanCurrencyIntegrator) GetCurrencyUsageForPlan(ctx context.Cont
|
||||
|
||||
// Count currencies
|
||||
currencyUsage := make(map[string]int64)
|
||||
|
||||
|
||||
for _, subscription := range subscriptions {
|
||||
currency := rpci.baseCurrency // Default to base currency
|
||||
if subscription.Metadata != nil {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package rateplan
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package rateplan
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package rateplan
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package rateplan
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
Reference in New Issue
Block a user