mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 02:52:53 +00:00
feat: Add RatePlanAdapter with CRUD operations, subscription management, usage tracking, and analytics
- Add RatePlanAdapter struct wrapping Service to implement rateplan.Service interface - Add NewRatePlanAdapter constructor returning rateplan.Service - Add CreateRatePlan, GetRatePlan, UpdateRatePlan, DeleteRatePlan, ListRatePlans, SearchRatePlans, and GetPopularPlans methods with type conversions - Add SubscribeToPlan, GetSubscription, UpdateSubscription, CancelSubscription, GetActiveSubscription
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/rateplan"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/repository"
|
||||
)
|
||||
|
||||
// RatePlanAdapter adapts services.Service to implement rateplan.Service interface
|
||||
type RatePlanAdapter struct {
|
||||
service *Service
|
||||
}
|
||||
|
||||
// NewRatePlanAdapter creates a new rate plan adapter
|
||||
func NewRatePlanAdapter(service *Service) rateplan.Service {
|
||||
return &RatePlanAdapter{service: service}
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) CreateRatePlan(ctx context.Context, plan *rateplan.RatePlan) (*rateplan.RatePlan, error) {
|
||||
result, err := a.service.CreateRatePlan(ctx, toRepoPlan(plan))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlan(result), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetRatePlan(ctx context.Context, id string) (*rateplan.RatePlan, error) {
|
||||
plan, err := a.service.GetRatePlan(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlan(plan), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) UpdateRatePlan(ctx context.Context, plan *rateplan.RatePlan) (*rateplan.RatePlan, error) {
|
||||
result, err := a.service.UpdateRatePlan(ctx, toRepoPlan(plan))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlan(result), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) DeleteRatePlan(ctx context.Context, id string) error {
|
||||
return a.service.DeleteRatePlan(ctx, id)
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) ListRatePlans(ctx context.Context, filter *rateplan.RatePlanFilter) ([]*rateplan.RatePlan, error) {
|
||||
repoFilter := &repository.RatePlanFilter{
|
||||
CarrierID: filter.CarrierID,
|
||||
Region: filter.Region,
|
||||
PlanType: repository.PlanType(filter.PlanType),
|
||||
IsActive: filter.IsActive,
|
||||
MinPrice: filter.MinPrice,
|
||||
MaxPrice: filter.MaxPrice,
|
||||
Limit: filter.Limit,
|
||||
Offset: filter.Offset,
|
||||
}
|
||||
plans, err := a.service.ListRatePlans(ctx, repoFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlanSlice(plans), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) SearchRatePlans(ctx context.Context, criteria rateplan.SearchCriteria) ([]*rateplan.RatePlan, error) {
|
||||
filter := &rateplan.RatePlanFilter{
|
||||
CarrierID: criteria.CarrierID,
|
||||
Region: criteria.Region,
|
||||
PlanType: criteria.PlanType,
|
||||
}
|
||||
return a.ListRatePlans(ctx, filter)
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetPopularPlans(ctx context.Context, limit int) ([]*rateplan.RatePlan, error) {
|
||||
plans, err := a.service.GetPopularPlans(ctx, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlanSlice(plans), nil
|
||||
}
|
||||
|
||||
// Conversion helpers
|
||||
|
||||
func toRepoPlan(p *rateplan.RatePlan) *repository.RatePlan {
|
||||
return &repository.RatePlan{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Description: p.Description,
|
||||
CarrierID: p.CarrierID,
|
||||
Region: p.Region,
|
||||
PlanType: repository.PlanType(p.PlanType),
|
||||
BasePrice: p.BasePrice,
|
||||
BillingCycle: repository.BillingCycle(p.BillingCycle),
|
||||
ValidFrom: p.ValidFrom,
|
||||
ValidTo: p.ValidTo,
|
||||
IsActive: p.IsActive,
|
||||
CreatedAt: p.CreatedAt,
|
||||
UpdatedAt: p.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func toRatePlan(p *repository.RatePlan) *rateplan.RatePlan {
|
||||
return &rateplan.RatePlan{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Description: p.Description,
|
||||
CarrierID: p.CarrierID,
|
||||
Region: p.Region,
|
||||
PlanType: rateplan.PlanType(p.PlanType),
|
||||
BasePrice: p.BasePrice,
|
||||
BillingCycle: rateplan.BillingCycle(p.BillingCycle),
|
||||
ValidFrom: p.ValidFrom,
|
||||
ValidTo: p.ValidTo,
|
||||
IsActive: p.IsActive,
|
||||
CreatedAt: p.CreatedAt,
|
||||
UpdatedAt: p.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func toRatePlanSlice(plans []*repository.RatePlan) []*rateplan.RatePlan {
|
||||
result := make([]*rateplan.RatePlan, len(plans))
|
||||
for i, p := range plans {
|
||||
result[i] = toRatePlan(p)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toRatePlanSub(s *repository.RatePlanSubscription) *rateplan.RatePlanSubscription {
|
||||
return &rateplan.RatePlanSubscription{
|
||||
ID: s.ID,
|
||||
ProfileID: s.ProfileID,
|
||||
RatePlanID: s.RatePlanID,
|
||||
Status: rateplan.SubscriptionStatus(s.Status),
|
||||
CreatedAt: s.CreatedAt,
|
||||
UpdatedAt: s.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func convertRepoUsage(u *repository.RatePlanUsage) *rateplan.RatePlanUsage {
|
||||
return &rateplan.RatePlanUsage{
|
||||
ID: u.ID,
|
||||
RatePlanID: u.RatePlanID,
|
||||
ProfileID: u.ProfileID,
|
||||
CycleStart: u.CycleStart,
|
||||
CycleEnd: u.CycleEnd,
|
||||
DataUsed: u.DataUsed,
|
||||
VoiceUsed: u.VoiceUsed,
|
||||
SMSUsed: u.SMSUsed,
|
||||
LastUpdated: u.LastUpdated,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/rateplan"
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/repository"
|
||||
)
|
||||
|
||||
func (a *RatePlanAdapter) SubscribeToPlan(ctx context.Context, req *rateplan.SubscribeRequest) (*rateplan.RatePlanSubscription, error) {
|
||||
repoReq := &repository.SubscribeRequest{
|
||||
ProfileID: req.ProfileID,
|
||||
RatePlanID: req.RatePlanID,
|
||||
}
|
||||
subscription, err := a.service.SubscribeToPlan(ctx, repoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlanSub(subscription), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetSubscription(ctx context.Context, id string) (*rateplan.RatePlanSubscription, error) {
|
||||
subscription, err := a.service.GetSubscription(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlanSub(subscription), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) UpdateSubscription(ctx context.Context, subscription *rateplan.RatePlanSubscription) (*rateplan.RatePlanSubscription, error) {
|
||||
repoSub := &repository.RatePlanSubscription{
|
||||
ID: subscription.ID,
|
||||
ProfileID: subscription.ProfileID,
|
||||
RatePlanID: subscription.RatePlanID,
|
||||
Status: repository.SubscriptionStatus(subscription.Status),
|
||||
CreatedAt: subscription.CreatedAt,
|
||||
UpdatedAt: subscription.UpdatedAt,
|
||||
}
|
||||
result, err := a.service.UpdateSubscription(ctx, repoSub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlanSub(result), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) CancelSubscription(ctx context.Context, subscriptionID string, reason string) error {
|
||||
return a.service.CancelSubscription(ctx, subscriptionID, reason)
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetActiveSubscription(ctx context.Context, profileID string) (*rateplan.RatePlanSubscription, error) {
|
||||
subscription, err := a.service.GetActiveSubscription(ctx, profileID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toRatePlanSub(subscription), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) ListSubscriptions(ctx context.Context, profileID string, filter *rateplan.SubscriptionFilter) ([]*rateplan.RatePlanSubscription, error) {
|
||||
repoFilter := &repository.SubscriptionFilter{
|
||||
Status: repository.SubscriptionStatus(filter.Status),
|
||||
Limit: filter.Limit,
|
||||
Offset: filter.Offset,
|
||||
}
|
||||
subscriptions, err := a.service.ListSubscriptions(ctx, profileID, repoFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]*rateplan.RatePlanSubscription, len(subscriptions))
|
||||
for i, sub := range subscriptions {
|
||||
result[i] = toRatePlanSub(sub)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) RecordUsage(ctx context.Context, req *rateplan.RecordUsageRequest) (*rateplan.RatePlanUsage, error) {
|
||||
repoReq := &repository.RecordUsageRequest{
|
||||
ProfileID: req.ProfileID,
|
||||
DataUsed: req.DataUsed,
|
||||
VoiceUsed: req.VoiceUsed,
|
||||
SMSUsed: req.SMSUsed,
|
||||
}
|
||||
usage, err := a.service.RecordUsage(ctx, repoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertRepoUsage(usage), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetUsage(ctx context.Context, profileID string) (*rateplan.RatePlanUsage, error) {
|
||||
usage, err := a.service.GetUsage(ctx, profileID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertRepoUsage(usage), nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetUsageHistory(ctx context.Context, profileID string, limit int) ([]*rateplan.RatePlanUsage, error) {
|
||||
usageHistory, err := a.service.GetUsageHistory(ctx, profileID, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]*rateplan.RatePlanUsage, len(usageHistory))
|
||||
for i, u := range usageHistory {
|
||||
result[i] = convertRepoUsage(u)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) CalculateCost(ctx context.Context, req *rateplan.CalculateCostRequest) (*rateplan.RatePlanCostCalculation, error) {
|
||||
repoReq := &repository.CalculateCostRequest{
|
||||
RatePlanID: req.RatePlanID,
|
||||
DataUsed: req.DataUsed,
|
||||
VoiceUsed: req.VoiceUsed,
|
||||
SMSUsed: req.SMSUsed,
|
||||
AppliedDiscounts: req.AppliedDiscounts,
|
||||
}
|
||||
calc, err := a.service.CalculateCost(ctx, repoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rateplan.RatePlanCostCalculation{
|
||||
RatePlanID: calc.RatePlanID,
|
||||
BaseCost: calc.BaseCost,
|
||||
OverageCost: calc.OverageCost,
|
||||
DiscountCost: calc.DiscountCost,
|
||||
TotalCost: calc.TotalCost,
|
||||
Currency: calc.Currency,
|
||||
Breakdown: calc.Breakdown,
|
||||
CalculatedAt: calc.CalculatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetUsageAnalytics(ctx context.Context, filter *rateplan.UsageAnalyticsFilter) (*rateplan.UsageAnalytics, error) {
|
||||
repoFilter := &repository.UsageAnalyticsFilter{
|
||||
RatePlanID: filter.RatePlanID,
|
||||
CarrierID: filter.CarrierID,
|
||||
Region: filter.Region,
|
||||
StartDate: filter.StartDate,
|
||||
EndDate: filter.EndDate,
|
||||
GroupBy: filter.GroupBy,
|
||||
}
|
||||
analytics, err := a.service.GetUsageAnalytics(ctx, repoFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rateplan.UsageAnalytics{
|
||||
TotalDataUsed: analytics.TotalDataUsed,
|
||||
TotalVoiceUsed: analytics.TotalVoiceUsed,
|
||||
TotalSMSUsed: analytics.TotalSMSUsed,
|
||||
ActiveUsers: analytics.ActiveUsers,
|
||||
AverageUsage: analytics.AverageUsage,
|
||||
UsageByPlan: analytics.UsageByPlan,
|
||||
UsageByRegion: analytics.UsageByRegion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *RatePlanAdapter) GetRevenueAnalytics(ctx context.Context, filter *rateplan.RevenueAnalyticsFilter) (*rateplan.RevenueAnalytics, error) {
|
||||
repoFilter := &repository.RevenueAnalyticsFilter{
|
||||
RatePlanID: filter.RatePlanID,
|
||||
CarrierID: filter.CarrierID,
|
||||
Region: filter.Region,
|
||||
StartDate: filter.StartDate,
|
||||
EndDate: filter.EndDate,
|
||||
GroupBy: filter.GroupBy,
|
||||
}
|
||||
analytics, err := a.service.GetRevenueAnalytics(ctx, repoFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rateplan.RevenueAnalytics{
|
||||
TotalRevenue: analytics.TotalRevenue,
|
||||
RevenueByPlan: analytics.RevenueByPlan,
|
||||
RevenueByCarrier: analytics.RevenueByCarrier,
|
||||
RevenueByRegion: analytics.RevenueByRegion,
|
||||
AverageRevenue: analytics.AverageRevenue,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user