diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 573edc2..ad91064 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,6 +18,8 @@ jobs: image: idprm/fb-alert-ussd-service - dockerfile: ./Dockerfile.sms image: idprm/fb-alert-sms-service + - dockerfile: ./Dockerfile.wap + image: idprm/fb-alert-wap-service - dockerfile: ./Dockerfile.news image: idprm/fb-alert-news-service - dockerfile: ./Dockerfile.sms_alerte diff --git a/cmd/listener.go b/cmd/listener.go index a3c0096..a73fb0a 100644 --- a/cmd/listener.go +++ b/cmd/listener.go @@ -209,6 +209,7 @@ func routeUrlListener(db *gorm.DB, rds *redis.Client, rmq rmqp.AMQP, logger *log smsAlerteService := services.NewSMSAlerteService(smsAlerteRepo) h := handler.NewIncomingHandler( + rds, rmq, logger, menuService, @@ -264,6 +265,8 @@ func routeUrlListener(db *gorm.DB, rds *redis.Client, rmq rmqp.AMQP, logger *log ) r.Get("/mo", h.MessageOriginated) + r.Post("/sub", h.CreateSub) + r.Post("/otp", h.VerifySub) lp := r.Group("p") lp.Get("/:service", h.LandingPage) diff --git a/cmd/root.go b/cmd/root.go index c628ce8..0258dfe 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -111,6 +111,7 @@ const ( SMS_FLASH_NEWS_SUB string = "FLASH_NEWS_SUB" SMS_INFO string = "INFO" SMS_STOP string = "STOP" + SMS_OTP string = "OTP" ) var ( diff --git a/cmd/seeder.go b/cmd/seeder.go index a6ab007..0947d7d 100644 --- a/cmd/seeder.go +++ b/cmd/seeder.go @@ -435,6 +435,12 @@ func seederDB(db *gorm.DB) { Name: SMS_STOP, Value: "Services FFC: Vous venez d envoyer STOP. Orange vous remercie d avoir utiliser nos services! Visitez www.orangemali.com pour en savoir plus sur Football Fan Club", }, + { + Category: ACT_CONFIRMATION, + Channel: ACT_SMS, + Name: SMS_OTP, + Value: "Votre code OTP est {pin}. Services FFC", + }, } var schedules = []entity.Schedule{ diff --git a/internal/domain/entity/content.go b/internal/domain/entity/content.go index 16ebf13..5be15d1 100644 --- a/internal/domain/entity/content.go +++ b/internal/domain/entity/content.go @@ -107,3 +107,8 @@ func (e *Content) SetValueCreditGoal(home, away, score, credit, price, currency "{currency}", url.QueryEscape(currency)) e.Value = replacer.Replace(e.Value) } + +func (e *Content) SetValueOTP(pin string) { + replacer := strings.NewReplacer("{pin}", pin) + e.Value = replacer.Replace(e.Value) +} diff --git a/internal/domain/entity/news.go b/internal/domain/entity/news.go index 9bda507..dbb95b5 100644 --- a/internal/domain/entity/news.go +++ b/internal/domain/entity/news.go @@ -29,6 +29,7 @@ func (e *News) GetId() int64 { func (e *News) GetTitle() string { replacer := strings.NewReplacer( `"`, "", + `’`, "'", ) return replacer.Replace(e.Title) } diff --git a/internal/domain/entity/service.go b/internal/domain/entity/service.go index b29aede..de39062 100644 --- a/internal/domain/entity/service.go +++ b/internal/domain/entity/service.go @@ -59,6 +59,10 @@ func (s *Service) GetPrice() float64 { return s.Price } +func (s *Service) GetDiscount(discountPercentage int) float64 { + return (s.GetPrice() * float64(discountPercentage) / 100) +} + func (s *Service) GetPriceToString() string { return strconv.FormatFloat(s.GetPrice(), 'f', 0, 64) } @@ -92,7 +96,6 @@ func (e *Service) GetUrlMT() string { } func (e *Service) SetUrlMT(smsc, username, password, from, to, content string) { - replacer := strings.NewReplacer( "{smsc}", url.QueryEscape(smsc), "{username}", url.QueryEscape(username), @@ -103,3 +106,7 @@ func (e *Service) SetUrlMT(smsc, username, password, from, to, content string) { e.UrlMT = replacer.Replace(e.UrlMT) } + +func (s *Service) SetPriceWithDiscount(discountPercentage int) { + s.Price = s.GetPrice() - (s.GetPrice() * float64(discountPercentage) / 100) +} diff --git a/internal/domain/entity/transaction.go b/internal/domain/entity/transaction.go index f239a11..67046ff 100644 --- a/internal/domain/entity/transaction.go +++ b/internal/domain/entity/transaction.go @@ -11,7 +11,8 @@ type Transaction struct { Service *Service `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" json:"service,omitempty"` Msisdn string `gorm:"size:15;not null" json:"msisdn"` Keyword string `gorm:"size:50" json:"keyword,omitempty"` - Amount float64 `gorm:"default:0" json:"amount,omitempty"` + Amount float64 `gorm:"size:10;default:0" json:"amount,omitempty"` + Discount float64 `gorm:"size:10;default:0" json:"discount,omitempty"` Status string `gorm:"size:25" json:"status,omitempty"` StatusCode string `gorm:"size:85" json:"status_code,omitempty"` StatusDetail string `gorm:"size:85" json:"status_detail,omitempty"` @@ -37,6 +38,10 @@ func (t *Transaction) SetAmount(v float64) { t.Amount = v } +func (t *Transaction) SetDiscount(v float64) { + t.Discount = v +} + func (t *Transaction) SetStatus(v string) { t.Status = v } diff --git a/internal/handler/incoming_handler.go b/internal/handler/incoming_handler.go index 500c7f1..6f11942 100644 --- a/internal/handler/incoming_handler.go +++ b/internal/handler/incoming_handler.go @@ -16,6 +16,7 @@ import ( "github.com/idprm/go-football-alert/internal/logger" "github.com/idprm/go-football-alert/internal/services" "github.com/idprm/go-football-alert/internal/utils" + "github.com/redis/go-redis/v9" "github.com/sirupsen/logrus" "github.com/wiliehidayat87/rmqp" ) @@ -51,13 +52,15 @@ var ( RMQ_USSD_QUEUE string = "Q_USSD" RMQ_SMS_EXCHANGE string = "E_SMS" RMQ_SMS_QUEUE string = "Q_SMS" + RMQ_WAP_EXCHANGE string = "E_WAP" + RMQ_WAP_QUEUE string = "Q_WAP" RMQ_MT_EXCHANGE string = "E_MT" RMQ_MT_QUEUE string = "Q_MT" RMQ_NEWS_EXCHANGE string = "E_NEWS" RMQ_NEWS_QUEUE string = "Q_NEWS" MT_SMS_ALERTE string = "SMS_ALERTE" MT_CREDIT_GOAL string = "CREDIT_GOAL" - MT_PREDICTION string = "PREDICTION" + MT_PREDICT_WIN string = "PREDICT_WIN" MT_FIRSTPUSH string = "FIRSTPUSH" MT_RENEWAL string = "RENEWAL" MT_NEWS string = "NEWS" @@ -78,9 +81,11 @@ var ( ACT_NEWS string = "NEWS" CHANNEL_USSD string = "USSD" CHANNEL_SMS string = "SMS" + CHANNEL_WAP string = "WAP" ) type IncomingHandler struct { + rds *redis.Client rmq rmqp.AMQP logger *logger.Logger menuService services.IMenuService @@ -100,6 +105,7 @@ type IncomingHandler struct { } func NewIncomingHandler( + rds *redis.Client, rmq rmqp.AMQP, logger *logger.Logger, menuService services.IMenuService, @@ -118,6 +124,7 @@ func NewIncomingHandler( bettingService services.IBettingService, ) *IncomingHandler { return &IncomingHandler{ + rds: rds, rmq: rmq, logger: logger, menuService: menuService, @@ -200,6 +207,14 @@ func (h *IncomingHandler) MessageOriginated(c *fiber.Ctx) error { return c.Status(fiber.StatusOK).SendString("OK") } +func (h *IncomingHandler) CreateSub(c *fiber.Ctx) error { + return c.Status(fiber.StatusOK).JSON(fiber.Map{"": ""}) +} + +func (h *IncomingHandler) VerifySub(c *fiber.Ctx) error { + return c.Status(fiber.StatusOK).JSON(fiber.Map{"": ""}) +} + func (h *IncomingHandler) Main(c *fiber.Ctx) error { c.Set("Content-type", "text/xml; charset=utf-8") menu, err := h.menuService.GetBySlug("home") diff --git a/internal/handler/renewal_handler.go b/internal/handler/renewal_handler.go index aa721f4..d910c9a 100644 --- a/internal/handler/renewal_handler.go +++ b/internal/handler/renewal_handler.go @@ -112,6 +112,8 @@ func (h *RenewalHandler) Dailypush() { ) // is_retry set to false h.subscriptionService.UpdateNotRetry(sub) + // is_free set to false + h.subscriptionService.UpdateNotFree(sub) h.transactionService.Save( &entity.Transaction{ @@ -148,6 +150,9 @@ func (h *RenewalHandler) Dailypush() { }, ) + // is_free set to false + h.subscriptionService.UpdateNotFree(sub) + h.transactionService.Save( &entity.Transaction{ TrxId: trxId, @@ -180,6 +185,8 @@ func (h *RenewalHandler) Dailypush() { LatestPayload: string(respBal), }, ) + // is_free set to false + h.subscriptionService.UpdateNotFree(sub) h.transactionService.Save( &entity.Transaction{ diff --git a/internal/handler/retry_handler.go b/internal/handler/retry_handler.go index 1e79b73..fc11f5c 100644 --- a/internal/handler/retry_handler.go +++ b/internal/handler/retry_handler.go @@ -63,6 +63,8 @@ func (h *RetryHandler) Firstpush() { if err != nil { log.Println(err.Error()) } + // smart billing set discount based on retry + service.SetPriceWithDiscount(0) summary := &entity.Summary{ ServiceID: service.GetId(), @@ -111,6 +113,8 @@ func (h *RetryHandler) Firstpush() { // is_retry set to false h.subscriptionService.UpdateNotRetry(sub) + // is_free set to false + h.subscriptionService.UpdateNotFree(sub) h.transactionService.Update( &entity.Transaction{ @@ -119,6 +123,7 @@ func (h *RetryHandler) Firstpush() { Msisdn: h.sub.GetMsisdn(), Keyword: sub.GetLatestKeyword(), Amount: service.GetPrice(), + Discount: 0, Status: STATUS_SUCCESS, StatusCode: respDeduct.GetAcctResCode(), StatusDetail: respDeduct.GetAcctResName(), @@ -154,6 +159,8 @@ func (h *RetryHandler) Dailypush() { if err != nil { log.Println(err.Error()) } + // smart billing set discount based on retry + service.SetPriceWithDiscount(0) summary := &entity.Summary{ ServiceID: service.GetId(), @@ -201,6 +208,8 @@ func (h *RetryHandler) Dailypush() { // is_retry set to false h.subscriptionService.UpdateNotRetry(sub) + // is_free set to false + h.subscriptionService.UpdateNotFree(sub) h.transactionService.Update( &entity.Transaction{ @@ -209,6 +218,7 @@ func (h *RetryHandler) Dailypush() { Msisdn: h.sub.GetMsisdn(), Keyword: sub.GetLatestKeyword(), Amount: service.GetPrice(), + Discount: 0, Status: STATUS_SUCCESS, StatusCode: respDeduct.GetAcctResCode(), StatusDetail: respDeduct.GetAcctResName(),