Update Voucher

This commit is contained in:
aditya.siregar 2025-06-06 14:48:09 +07:00
parent b5d6f7ff5b
commit 54144b2eba
7 changed files with 641 additions and 29 deletions

451
internal/entity/undian.go Normal file
View File

@ -0,0 +1,451 @@
package entity
import (
"time"
)
// =============================================
// DATABASE ENTITIES
// =============================================
type UndianEventDB struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
Title string `gorm:"size:255;not null" json:"title"`
Description *string `gorm:"type:text" json:"description"`
ImageURL *string `gorm:"size:500" json:"image_url"`
Status string `gorm:"size:20;not null;default:upcoming" json:"status"` // upcoming, active, completed, cancelled
// Event timing
StartDate time.Time `gorm:"not null" json:"start_date"`
EndDate time.Time `gorm:"not null" json:"end_date"`
DrawDate time.Time `gorm:"not null" json:"draw_date"`
// Configuration
MinimumPurchase float64 `gorm:"type:decimal(10,2);default:50000" json:"minimum_purchase"`
// Draw status
DrawCompleted bool `gorm:"default:false" json:"draw_completed"`
DrawCompletedAt *time.Time `json:"draw_completed_at"`
// Metadata
TermsAndConditions *string `gorm:"type:text" json:"terms_and_conditions"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
}
func (UndianEventDB) TableName() string {
return "undian_events"
}
type UndianPrizeDB struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
UndianEventID int64 `gorm:"not null" json:"undian_event_id"`
Rank int `gorm:"not null" json:"rank"`
PrizeName string `gorm:"size:255;not null" json:"prize_name"`
PrizeValue *float64 `gorm:"type:decimal(15,2)" json:"prize_value"`
PrizeDescription *string `gorm:"type:text" json:"prize_description"`
PrizeType string `gorm:"size:50;default:voucher" json:"prize_type"` // gold, voucher, cash, product, service
PrizeImageURL *string `gorm:"size:500" json:"prize_image_url"`
// Winner information (filled after draw)
WinningVoucherID *int64 `json:"winning_voucher_id"`
WinnerUserID *int64 `json:"winner_user_id"`
// Relations
UndianEvent UndianEventDB `gorm:"foreignKey:UndianEventID" json:"undian_event,omitempty"`
}
func (UndianPrizeDB) TableName() string {
return "undian_prizes"
}
type UndianVoucherDB struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
UndianEventID int64 `gorm:"not null" json:"undian_event_id"`
CustomerID int64 `gorm:"not null" json:"customer_id"`
OrderID *int64 `json:"order_id"`
// Voucher identification
VoucherCode string `gorm:"size:50;not null;uniqueIndex" json:"voucher_code"`
VoucherNumber *int `json:"voucher_number"`
// Winner status
IsWinner bool `gorm:"default:false" json:"is_winner"`
PrizeRank *int `json:"prize_rank"`
WonAt *time.Time `json:"won_at"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
// Relations
UndianEvent UndianEventDB `gorm:"foreignKey:UndianEventID" json:"undian_event,omitempty"`
}
func (UndianVoucherDB) TableName() string {
return "undian_vouchers"
}
// =============================================
// REQUEST/RESPONSE ENTITIES
// =============================================
type UndianEventSearch struct {
Status string `json:"status"`
IsActive bool `json:"is_active"`
IsCompleted bool `json:"is_completed"`
Search string `json:"search"`
StartDateFrom time.Time `json:"start_date_from"`
StartDateTo time.Time `json:"start_date_to"`
Limit int `json:"limit"`
Offset int `json:"offset"`
}
type CreateUndianEventRequest struct {
Title string `json:"title" validate:"required,min=3,max=255"`
Description *string `json:"description"`
ImageURL *string `json:"image_url"`
StartDate time.Time `json:"start_date" validate:"required"`
EndDate time.Time `json:"end_date" validate:"required"`
DrawDate time.Time `json:"draw_date" validate:"required"`
MinimumPurchase float64 `json:"minimum_purchase" validate:"min=0"`
TermsAndConditions *string `json:"terms_and_conditions"`
Prizes []CreateUndianPrizeRequest `json:"prizes" validate:"required,min=1"`
}
type UpdateUndianEventRequest struct {
ID int64 `json:"id" validate:"required"`
Title string `json:"title" validate:"required,min=3,max=255"`
Description *string `json:"description"`
ImageURL *string `json:"image_url"`
StartDate time.Time `json:"start_date" validate:"required"`
EndDate time.Time `json:"end_date" validate:"required"`
DrawDate time.Time `json:"draw_date" validate:"required"`
MinimumPurchase float64 `json:"minimum_purchase" validate:"min=0"`
TermsAndConditions *string `json:"terms_and_conditions"`
Status string `json:"status" validate:"oneof=upcoming active completed cancelled"`
}
type CreateUndianPrizeRequest struct {
Rank int `json:"rank" validate:"required,min=1"`
PrizeName string `json:"prize_name" validate:"required,min=3,max=255"`
PrizeValue *float64 `json:"prize_value"`
PrizeDescription *string `json:"prize_description"`
PrizeType string `json:"prize_type" validate:"oneof=gold voucher cash product service"`
PrizeImageURL *string `json:"prize_image_url"`
}
type UndianEventResponse struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description *string `json:"description"`
ImageURL *string `json:"image_url"`
Status string `json:"status"`
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
DrawDate time.Time `json:"draw_date"`
MinimumPurchase float64 `json:"minimum_purchase"`
DrawCompleted bool `json:"draw_completed"`
DrawCompletedAt *time.Time `json:"draw_completed_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Statistics (populated when needed)
TotalVouchers int64 `json:"total_vouchers,omitempty"`
TotalParticipants int64 `json:"total_participants,omitempty"`
TotalPrizes int64 `json:"total_prizes,omitempty"`
// Relations (populated when needed)
Prizes []UndianPrizeResponse `json:"prizes,omitempty"`
}
type UndianPrizeResponse struct {
ID int64 `json:"id"`
UndianEventID int64 `json:"undian_event_id"`
Rank int `json:"rank"`
PrizeName string `json:"prize_name"`
PrizeValue *float64 `json:"prize_value"`
PrizeDescription *string `json:"prize_description"`
PrizeType string `json:"prize_type"`
PrizeImageURL *string `json:"prize_image_url"`
WinningVoucherID *int64 `json:"winning_voucher_id,omitempty"`
WinnerUserID *int64 `json:"winner_user_id,omitempty"`
}
type UndianVoucherResponse struct {
ID int64 `json:"id"`
UndianEventID int64 `json:"undian_event_id"`
CustomerID int64 `json:"customer_id"`
OrderID *int64 `json:"order_id"`
VoucherCode string `json:"voucher_code"`
VoucherNumber *int `json:"voucher_number"`
IsWinner bool `json:"is_winner"`
PrizeRank *int `json:"prize_rank"`
WonAt *time.Time `json:"won_at"`
CreatedAt time.Time `json:"created_at"`
// Relations (populated when needed)
UndianEvent *UndianEventResponse `json:"undian_event,omitempty"`
Prize *UndianPrizeResponse `json:"prize,omitempty"`
}
// =============================================
// COMPOSITE ENTITIES
// =============================================
type UndianEventWithStats struct {
Event UndianEventDB `json:"event"`
TotalVouchers int64 `json:"total_vouchers"`
TotalParticipants int64 `json:"total_participants"`
TotalPrizes int64 `json:"total_prizes"`
}
type UndianEventWithPrizes struct {
Event UndianEventDB `json:"event"`
Prizes []*UndianPrizeDB `json:"prizes"`
}
type CustomerUndianSummary struct {
CustomerID int64 `json:"customer_id"`
EventID int64 `json:"event_id"`
TotalVouchers int64 `json:"total_vouchers"`
WinningVouchers int64 `json:"winning_vouchers"`
IsParticipating bool `json:"is_participating"`
}
// =============================================
// API RESPONSE ENTITIES
// =============================================
type UndianEventListResponse struct {
Events []UndianEventResponse `json:"events"`
Total int `json:"total"`
Page int `json:"page"`
Limit int `json:"limit"`
}
type CustomerUndianListResponse struct {
Events []CustomerUndianEventResponse `json:"events"`
Total int `json:"total"`
}
type CustomerUndianEventResponse struct {
Event UndianEventResponse `json:"event"`
UserVouchers []UndianVoucherResponse `json:"user_vouchers"`
TotalVouchers int `json:"total_vouchers"`
WinningVouchers int `json:"winning_vouchers"`
IsParticipating bool `json:"is_participating"`
}
type UndianEventDetailResponse struct {
Event UndianEventResponse `json:"event"`
Prizes []UndianPrizeResponse `json:"prizes"`
UserVouchers []UndianVoucherResponse `json:"user_vouchers,omitempty"`
TotalVouchers int64 `json:"total_vouchers"`
TotalParticipants int64 `json:"total_participants"`
UserParticipating bool `json:"user_participating"`
UserVoucherCount int `json:"user_voucher_count"`
}
type DrawResultResponse struct {
EventID int64 `json:"event_id"`
EventTitle string `json:"event_title"`
DrawDate time.Time `json:"draw_date"`
DrawCompleted bool `json:"draw_completed"`
Winners []DrawWinnerResponse `json:"winners"`
}
type DrawWinnerResponse struct {
Rank int `json:"rank"`
PrizeName string `json:"prize_name"`
PrizeValue *float64 `json:"prize_value"`
VoucherCode string `json:"voucher_code"`
WinnerUserID *int64 `json:"winner_user_id,omitempty"`
}
// =============================================
// ERROR RESPONSES
// =============================================
type UndianError struct {
Code string `json:"code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
func (e UndianError) Error() string {
return e.Message
}
// Common error codes
var (
ErrUndianEventNotFound = UndianError{
Code: "UNDIAN_EVENT_NOT_FOUND",
Message: "Undian event not found",
}
ErrUndianEventNotActive = UndianError{
Code: "UNDIAN_EVENT_NOT_ACTIVE",
Message: "Undian event is not active",
}
ErrDrawAlreadyCompleted = UndianError{
Code: "DRAW_ALREADY_COMPLETED",
Message: "Draw has already been completed for this event",
}
ErrDrawDateNotReached = UndianError{
Code: "DRAW_DATE_NOT_REACHED",
Message: "Draw date has not been reached yet",
}
ErrInsufficientOrderAmount = UndianError{
Code: "INSUFFICIENT_ORDER_AMOUNT",
Message: "Order amount does not meet minimum purchase requirement",
}
ErrVoucherNotFound = UndianError{
Code: "VOUCHER_NOT_FOUND",
Message: "Voucher not found",
}
ErrVoucherAlreadyExists = UndianError{
Code: "VOUCHER_ALREADY_EXISTS",
Message: "Voucher with this code already exists",
}
ErrInvalidDateRange = UndianError{
Code: "INVALID_DATE_RANGE",
Message: "Invalid date range: start_date must be before end_date, and end_date must be before draw_date",
}
)
// =============================================
// CONVERSION METHODS
// =============================================
func (e *UndianEventDB) ToResponse() UndianEventResponse {
return UndianEventResponse{
ID: e.ID,
Title: e.Title,
Description: e.Description,
ImageURL: e.ImageURL,
Status: e.Status,
StartDate: e.StartDate,
EndDate: e.EndDate,
DrawDate: e.DrawDate,
MinimumPurchase: e.MinimumPurchase,
DrawCompleted: e.DrawCompleted,
DrawCompletedAt: e.DrawCompletedAt,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
}
}
func (p *UndianPrizeDB) ToResponse() UndianPrizeResponse {
return UndianPrizeResponse{
ID: p.ID,
UndianEventID: p.UndianEventID,
Rank: p.Rank,
PrizeName: p.PrizeName,
PrizeValue: p.PrizeValue,
PrizeDescription: p.PrizeDescription,
PrizeType: p.PrizeType,
PrizeImageURL: p.PrizeImageURL,
WinningVoucherID: p.WinningVoucherID,
WinnerUserID: p.WinnerUserID,
}
}
func (v *UndianVoucherDB) ToResponse() UndianVoucherResponse {
return UndianVoucherResponse{
ID: v.ID,
UndianEventID: v.UndianEventID,
CustomerID: v.CustomerID,
OrderID: v.OrderID,
VoucherCode: v.VoucherCode,
VoucherNumber: v.VoucherNumber,
IsWinner: v.IsWinner,
PrizeRank: v.PrizeRank,
WonAt: v.WonAt,
CreatedAt: v.CreatedAt,
}
}
// Helper method to convert slice of DB entities to response entities
func UndianEventsToResponse(events []*UndianEventDB) []UndianEventResponse {
responses := make([]UndianEventResponse, len(events))
for i, event := range events {
responses[i] = event.ToResponse()
}
return responses
}
func UndianPrizesToResponse(prizes []*UndianPrizeDB) []UndianPrizeResponse {
responses := make([]UndianPrizeResponse, len(prizes))
for i, prize := range prizes {
responses[i] = prize.ToResponse()
}
return responses
}
func UndianVouchersToResponse(vouchers []*UndianVoucherDB) []UndianVoucherResponse {
responses := make([]UndianVoucherResponse, len(vouchers))
for i, voucher := range vouchers {
responses[i] = voucher.ToResponse()
}
return responses
}
// =============================================
// VALIDATION HELPERS
// =============================================
func (r *CreateUndianEventRequest) Validate() error {
if r.StartDate.After(r.EndDate) {
return ErrInvalidDateRange
}
if r.EndDate.After(r.DrawDate) {
return ErrInvalidDateRange
}
if r.MinimumPurchase < 0 {
return UndianError{
Code: "INVALID_MINIMUM_PURCHASE",
Message: "Minimum purchase must be greater than or equal to 0",
}
}
return nil
}
func (r *UpdateUndianEventRequest) Validate() error {
if r.StartDate.After(r.EndDate) {
return ErrInvalidDateRange
}
if r.EndDate.After(r.DrawDate) {
return ErrInvalidDateRange
}
if r.MinimumPurchase < 0 {
return UndianError{
Code: "INVALID_MINIMUM_PURCHASE",
Message: "Minimum purchase must be greater than or equal to 0",
}
}
return nil
}
// =============================================
// STATUS CONSTANTS
// =============================================
const (
UndianStatusUpcoming = "upcoming"
UndianStatusActive = "active"
UndianStatusCompleted = "completed"
UndianStatusCancelled = "cancelled"
)
const (
PrizeTypeGold = "gold"
PrizeTypeVoucher = "voucher"
PrizeTypeCash = "cash"
PrizeTypeProduct = "product"
PrizeTypeService = "service"
)

View File

@ -59,6 +59,7 @@ type RepoManagerImpl struct {
TransactionRepo TransactionRepo
MemberRepository MemberRepository
PartnerSetting PartnerSettingsRepository
UndianRepository UndianRepo
}
func NewRepoManagerImpl(db *gorm.DB, cfg *config.Config) *RepoManagerImpl {
@ -90,6 +91,7 @@ func NewRepoManagerImpl(db *gorm.DB, cfg *config.Config) *RepoManagerImpl {
MemberRepository: NewMemberRepository(db),
InProgressOrderRepo: NewInProgressOrderRepository(db),
PartnerSetting: NewPartnerSettingsRepository(db),
UndianRepository: NewUndianRepository(db),
}
}

View File

@ -0,0 +1,88 @@
package repository
import (
"context"
"enaklo-pos-be/internal/common/logger"
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/entity"
"fmt"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
)
type UndianRepo interface {
GetUndianEventByID(ctx context.Context, id int64) (*entity.UndianEventDB, error)
GetActiveUndianEvents(ctx context.Context) ([]*entity.UndianEventDB, error)
CreateUndianVouchers(ctx context.Context, vouchers []*entity.UndianVoucherDB) error
GetNextVoucherSequence(ctx mycontext.Context) (int64, error)
GetNextVoucherSequenceBatch(ctx mycontext.Context, count int) (int64, error)
}
type undianRepository struct {
db *gorm.DB
}
func NewUndianRepository(db *gorm.DB) *undianRepository {
return &undianRepository{
db: db,
}
}
func (r *undianRepository) GetUndianEventByID(ctx context.Context, id int64) (*entity.UndianEventDB, error) {
event := new(entity.UndianEventDB)
if err := r.db.WithContext(ctx).First(event, id).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get undian event by id", zap.Error(err))
return nil, err
}
return event, nil
}
func (r *undianRepository) GetActiveUndianEvents(ctx context.Context) ([]*entity.UndianEventDB, error) {
var events []*entity.UndianEventDB
now := time.Now()
if err := r.db.WithContext(ctx).
Where("status = 'active' AND start_date <= ? AND end_date >= ?", now, now).
Find(&events).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get active undian events", zap.Error(err))
return nil, err
}
return events, nil
}
func (r *undianRepository) CreateUndianVouchers(ctx context.Context, vouchers []*entity.UndianVoucherDB) error {
err := r.db.WithContext(ctx).Create(&vouchers).Error
if err != nil {
logger.ContextLogger(ctx).Error("error when create undian vouchers", zap.Error(err))
return err
}
return nil
}
func (r *undianRepository) GetNextVoucherSequence(ctx mycontext.Context) (int64, error) {
var sequence int64
err := r.db.WithContext(ctx).Raw("SELECT nextval('voucher_sequence')").Scan(&sequence).Error
if err != nil {
logger.ContextLogger(ctx).Error("error when get next voucher sequence", zap.Error(err))
return 0, err
}
return sequence, nil
}
func (r *undianRepository) GetNextVoucherSequenceBatch(ctx mycontext.Context, count int) (int64, error) {
var startSequence int64
query := fmt.Sprintf("SELECT nextval('voucher_sequence') + %d - %d", count-1, count-1)
err := r.db.WithContext(ctx).Raw(query).Scan(&startSequence).Error
if err != nil {
logger.ContextLogger(ctx).Error("error when get batch voucher sequence", zap.Error(err))
return 0, err
}
return startSequence, nil
}

View File

@ -59,7 +59,7 @@ func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl)
productSvcV2 := productSvc.New(repo.ProductRepo)
partnerSettings := partner_settings.NewPartnerSettingsService(repo.PartnerSetting)
orderService := orderSvc.New(repo.OrderRepo, productSvcV2, custSvcV2, repo.TransactionRepo, repo.Crypto, &cfg.Order, repo.EmailService, partnerSettings)
orderService := orderSvc.New(repo.OrderRepo, productSvcV2, custSvcV2, repo.TransactionRepo, repo.Crypto, &cfg.Order, repo.EmailService, partnerSettings, repo.UndianRepository)
inprogressOrder := inprogress_order.NewInProgressOrderService(repo.OrderRepo, orderService, productSvcV2)
return &ServiceManagerImpl{
AuthSvc: auth.New(repo.Auth, repo.Crypto, repo.User, repo.EmailService, cfg.Email, repo.Trx, repo.License),
@ -75,7 +75,7 @@ func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl)
Transaction: transaction.New(repo.Transaction, repo.Wallet, repo.Trx),
Balance: balance.NewBalanceService(repo.Wallet, repo.Trx, repo.Crypto, &cfg.Withdraw, repo.Transaction),
DiscoverService: discovery.NewDiscoveryService(repo.Site, cfg.Discovery, repo.Product),
OrderV2Svc: orderSvc.New(repo.OrderRepo, productSvcV2, custSvcV2, repo.TransactionRepo, repo.Crypto, &cfg.Order, repo.EmailService, partnerSettings),
OrderV2Svc: orderSvc.New(repo.OrderRepo, productSvcV2, custSvcV2, repo.TransactionRepo, repo.Crypto, &cfg.Order, repo.EmailService, partnerSettings, repo.UndianRepository),
MemberRegistrationSvc: member.NewMemberRegistrationService(repo.MemberRepository, repo.EmailService, custSvcV2, repo.Crypto),
CustomerV2Svc: custSvcV2,
InProgressSvc: inprogressOrder,

View File

@ -29,12 +29,17 @@ func (s *orderSvc) CreateOrderInquiry(ctx mycontext.Context,
return nil, err
}
customerID, err := s.customer.ResolveCustomer(ctx, &entity.CustomerResolutionRequest{
ID: req.CustomerID,
Name: req.CustomerName,
Email: req.CustomerEmail,
PhoneNumber: req.CustomerPhoneNumber,
})
customerID := int64(0)
if req.CustomerID != nil {
customer, err := s.customer.GetCustomer(ctx, *req.CustomerID)
if err != nil {
logger.ContextLogger(ctx).Error("customer is not found", zap.Error(err))
return nil, err
}
customerID = customer.ID
}
if err != nil {
logger.ContextLogger(ctx).Error("failed to resolve customer", zap.Error(err))
return nil, err

View File

@ -7,6 +7,7 @@ import (
"enaklo-pos-be/internal/entity"
"fmt"
"go.uber.org/zap"
"time"
)
func (s *orderSvc) ExecuteOrderInquiry(ctx mycontext.Context,
@ -52,13 +53,12 @@ func (s *orderSvc) processPostOrderActions(
}
if order.CustomerID != nil && *order.CustomerID > 0 {
err = s.addCustomerPoints(ctx, *order.CustomerID, int(order.Total/50000), fmt.Sprintf("TRX #%s", trx.ID))
err = s.addCustomerVouchers(ctx, *order.CustomerID, int64(order.Total), trx.OrderID)
if err != nil {
logger.ContextLogger(ctx).Error("error when adding points", zap.Error(err))
}
}
s.sendTransactionReceipt(ctx, order, trx, "CASH")
return nil
}
@ -79,8 +79,64 @@ func (s *orderSvc) createTransaction(ctx mycontext.Context, order *entity.Order,
return transaction, err
}
func (s *orderSvc) addCustomerPoints(ctx mycontext.Context, customerID int64, points int, reference string) error {
return s.customer.AddPoints(ctx, customerID, points, reference)
func (s *orderSvc) addCustomerVouchers(ctx mycontext.Context, customerID int64, total int64, reference int64) error {
undians, err := s.voucherUndianRepo.GetActiveUndianEvents(ctx)
if err != nil {
return err
}
eligibleVoucher := []*entity.UndianVoucherDB{}
totalVouchersNeeded := 0
for _, v := range undians {
if total >= int64(v.MinimumPurchase) {
voucherCount := int(total / int64(v.MinimumPurchase))
totalVouchersNeeded += voucherCount
}
}
if totalVouchersNeeded == 0 {
return nil
}
startSequence, err := s.voucherUndianRepo.GetNextVoucherSequenceBatch(ctx, totalVouchersNeeded)
if err != nil {
return err
}
currentSequence := startSequence
for _, v := range undians {
if total >= int64(v.MinimumPurchase) {
voucherCount := int(total / int64(v.MinimumPurchase))
for i := 0; i < voucherCount; i++ {
voucherCode := s.generateVoucherCode(v.ID, reference, currentSequence)
voucher := &entity.UndianVoucherDB{
UndianEventID: v.ID,
CustomerID: customerID,
VoucherCode: voucherCode,
VoucherNumber: &i,
IsWinner: false,
CreatedAt: time.Now(),
}
eligibleVoucher = append(eligibleVoucher, voucher)
currentSequence++
}
}
}
return s.voucherUndianRepo.CreateUndianVouchers(ctx, eligibleVoucher)
}
func (s *orderSvc) generateVoucherCode(eventID int64, reference int64, sequence int64) string {
eventPart := eventID % 100 // Last 2 digits of event ID
sequencePart := sequence % 100000 // Last 5 digits of sequence
orderPart := reference % 1000 // Last 3 digits of order ID
return fmt.Sprintf("%02d%05d%03d", eventPart, sequencePart, orderPart)
}
func (s *orderSvc) sendTransactionReceipt(ctx mycontext.Context, order *entity.Order, transaction *entity.Transaction, paymentMethod string) error {

View File

@ -116,16 +116,24 @@ type InProgressOrderRepository interface {
GetListByPartnerID(ctx mycontext.Context, partnerID int64, limit, offset int) ([]*entity.InProgressOrder, error)
}
type VoucherUndianRepo interface {
GetActiveUndianEvents(ctx context.Context) ([]*entity.UndianEventDB, error)
CreateUndianVouchers(ctx context.Context, vouchers []*entity.UndianVoucherDB) error
GetNextVoucherSequence(ctx mycontext.Context) (int64, error)
GetNextVoucherSequenceBatch(ctx mycontext.Context, count int) (int64, error)
}
type orderSvc struct {
repo Repository
product ProductService
customer CustomerService
transaction TransactionService
crypt CryptService
cfg Config
notification NotificationService
partnerSetting PartnerSettings
inprogressOrder InProgressOrderRepository
repo Repository
product ProductService
customer CustomerService
transaction TransactionService
crypt CryptService
cfg Config
notification NotificationService
partnerSetting PartnerSettings
inprogressOrder InProgressOrderRepository
voucherUndianRepo VoucherUndianRepo
}
func New(
@ -137,15 +145,17 @@ func New(
cfg Config,
notification NotificationService,
partnerSetting PartnerSettings,
voucherUndianRepo VoucherUndianRepo,
) Service {
return &orderSvc{
repo: repo,
product: product,
customer: customer,
transaction: transaction,
crypt: crypt,
cfg: cfg,
notification: notification,
partnerSetting: partnerSetting,
repo: repo,
product: product,
customer: customer,
transaction: transaction,
crypt: crypt,
cfg: cfg,
notification: notification,
partnerSetting: partnerSetting,
voucherUndianRepo: voucherUndianRepo,
}
}