2025-05-03 10:50:41 +07:00

140 lines
4.3 KiB
Go

package repository
import (
"enaklo-pos-be/internal/common/logger"
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/constants"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/repository/models"
"errors"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
)
type MemberRepository interface {
CreateRegistration(ctx mycontext.Context, registration *entity.MemberRegistration) (*entity.MemberRegistration, error)
GetRegistrationByToken(ctx mycontext.Context, token string) (*entity.MemberRegistration, error)
UpdateRegistrationStatus(ctx mycontext.Context, token string, status constants.RegistrationStatus) error
UpdateRegistrationOTP(ctx mycontext.Context, token string, otp string, expiresAt time.Time) error
}
type memberRepository struct {
db *gorm.DB
}
func NewMemberRepository(db *gorm.DB) MemberRepository {
return &memberRepository{
db: db,
}
}
func (r *memberRepository) CreateRegistration(ctx mycontext.Context, registration *entity.MemberRegistration) (*entity.MemberRegistration, error) {
registrationDB := r.toRegistrationDBModel(registration)
if err := r.db.Create(&registrationDB).Error; err != nil {
logger.ContextLogger(ctx).Error("failed to create member registration", zap.Error(err))
return nil, errors.New("failed to insert member registration")
}
return registration, nil
}
func (r *memberRepository) GetRegistrationByToken(ctx mycontext.Context, token string) (*entity.MemberRegistration, error) {
var registrationDB models.MemberRegistrationDB
if err := r.db.Where("token = ?", token).First(&registrationDB).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("registration not found")
}
logger.ContextLogger(ctx).Error("failed to get registration by token", zap.Error(err))
return nil, errors.New("failed to get registration by token")
}
registration := r.toDomainRegistrationModel(&registrationDB)
return registration, nil
}
func (r *memberRepository) UpdateRegistrationStatus(ctx mycontext.Context, token string, status constants.RegistrationStatus) error {
now := time.Now()
result := r.db.Model(&models.MemberRegistrationDB{}).
Where("token = ?", token).
Updates(map[string]interface{}{
"status": status,
"updated_at": now,
})
if result.Error != nil {
logger.ContextLogger(ctx).Error("failed to update registration status", zap.Error(result.Error))
return errors.New("failed to update registration status")
}
if result.RowsAffected == 0 {
return errors.New("registration not found")
}
return nil
}
func (r *memberRepository) UpdateRegistrationOTP(ctx mycontext.Context, token string, otp string, expiresAt time.Time) error {
now := time.Now()
result := r.db.Model(&models.MemberRegistrationDB{}).
Where("token = ?", token).
Updates(map[string]interface{}{
"otp": otp,
"expires_at": expiresAt,
"updated_at": now,
})
if result.Error != nil {
logger.ContextLogger(ctx).Error("failed to update registration OTP", zap.Error(result.Error))
return errors.New("failed to update registration OTP")
}
if result.RowsAffected == 0 {
return errors.New("registration not found")
}
return nil
}
func (r *memberRepository) toRegistrationDBModel(registration *entity.MemberRegistration) models.MemberRegistrationDB {
return models.MemberRegistrationDB{
ID: registration.ID,
Token: registration.Token,
Name: registration.Name,
Email: registration.Email,
Phone: registration.Phone,
BirthDate: registration.BirthDate,
OTP: registration.OTP,
Status: registration.Status.String(),
ExpiresAt: registration.ExpiresAt,
CreatedAt: registration.CreatedAt,
UpdatedAt: registration.UpdatedAt,
BranchID: registration.BranchID,
CashierID: registration.CashierID,
Password: registration.Password,
}
}
func (r *memberRepository) toDomainRegistrationModel(dbModel *models.MemberRegistrationDB) *entity.MemberRegistration {
return &entity.MemberRegistration{
ID: dbModel.ID,
Token: dbModel.Token,
Name: dbModel.Name,
Email: dbModel.Email,
Phone: dbModel.Phone,
BirthDate: dbModel.BirthDate,
OTP: dbModel.OTP,
Status: constants.RegistrationStatus(dbModel.Status),
ExpiresAt: dbModel.ExpiresAt,
CreatedAt: dbModel.CreatedAt,
UpdatedAt: dbModel.UpdatedAt,
BranchID: dbModel.BranchID,
CashierID: dbModel.CashierID,
}
}