129 lines
3.5 KiB
Go
129 lines
3.5 KiB
Go
package repository
|
|
|
|
import (
|
|
"enaklo-pos-be/internal/common/mycontext"
|
|
"enaklo-pos-be/internal/entity"
|
|
"enaklo-pos-be/internal/repository/models"
|
|
"github.com/pkg/errors"
|
|
"gorm.io/gorm"
|
|
"time"
|
|
)
|
|
|
|
type CustomerRepo interface {
|
|
Create(ctx mycontext.Context, customer *entity.Customer) (*entity.Customer, error)
|
|
FindByID(ctx mycontext.Context, id int64) (*entity.Customer, error)
|
|
FindByPhone(ctx mycontext.Context, phone string) (*entity.Customer, error)
|
|
FindByEmail(ctx mycontext.Context, email string) (*entity.Customer, error)
|
|
AddPoints(ctx mycontext.Context, id int64, points int) error
|
|
}
|
|
|
|
type customerRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewCustomerRepository(db *gorm.DB) *customerRepository {
|
|
return &customerRepository{db: db}
|
|
}
|
|
|
|
func (r *customerRepository) Create(ctx mycontext.Context, customer *entity.Customer) (*entity.Customer, error) {
|
|
customerDB := r.toCustomerDBModel(customer)
|
|
|
|
if err := r.db.Create(&customerDB).Error; err != nil {
|
|
return nil, errors.Wrap(err, "failed to insert customer")
|
|
}
|
|
|
|
customer.ID = customerDB.ID
|
|
|
|
return customer, nil
|
|
}
|
|
|
|
func (r *customerRepository) FindByID(ctx mycontext.Context, id int64) (*entity.Customer, error) {
|
|
var customerDB models.CustomerDB
|
|
|
|
if err := r.db.First(&customerDB, id).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("customer not found")
|
|
}
|
|
return nil, errors.Wrap(err, "failed to find customer")
|
|
}
|
|
|
|
customer := r.toDomainCustomerModel(&customerDB)
|
|
|
|
return customer, nil
|
|
}
|
|
|
|
func (r *customerRepository) FindByPhone(ctx mycontext.Context, phone string) (*entity.Customer, error) {
|
|
var customerDB models.CustomerDB
|
|
|
|
if err := r.db.Where("phone = ?", phone).First(&customerDB).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("customer not found")
|
|
}
|
|
return nil, errors.Wrap(err, "failed to find customer by phone")
|
|
}
|
|
|
|
customer := r.toDomainCustomerModel(&customerDB)
|
|
|
|
return customer, nil
|
|
}
|
|
|
|
func (r *customerRepository) FindByEmail(ctx mycontext.Context, email string) (*entity.Customer, error) {
|
|
var customerDB models.CustomerDB
|
|
|
|
if err := r.db.Where("email = ?", email).First(&customerDB).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("customer not found")
|
|
}
|
|
return nil, errors.Wrap(err, "failed to find customer by email")
|
|
}
|
|
|
|
customer := r.toDomainCustomerModel(&customerDB)
|
|
|
|
return customer, nil
|
|
}
|
|
|
|
func (r *customerRepository) AddPoints(ctx mycontext.Context, id int64, points int) error {
|
|
now := time.Now()
|
|
|
|
result := r.db.Model(&models.CustomerDB{}).
|
|
Where("id = ?", id).
|
|
Updates(map[string]interface{}{
|
|
"points": gorm.Expr("points + ?", points),
|
|
"updated_at": now,
|
|
})
|
|
|
|
if result.Error != nil {
|
|
return errors.Wrap(result.Error, "failed to add points to customer")
|
|
}
|
|
|
|
if result.RowsAffected == 0 {
|
|
return errors.New("customer not found")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *customerRepository) toCustomerDBModel(customer *entity.Customer) models.CustomerDB {
|
|
return models.CustomerDB{
|
|
ID: customer.ID,
|
|
Name: customer.Name,
|
|
Email: customer.Email,
|
|
Phone: customer.Phone,
|
|
Points: customer.Points,
|
|
CreatedAt: customer.CreatedAt,
|
|
UpdatedAt: customer.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
func (r *customerRepository) toDomainCustomerModel(dbModel *models.CustomerDB) *entity.Customer {
|
|
return &entity.Customer{
|
|
ID: dbModel.ID,
|
|
Name: dbModel.Name,
|
|
Email: dbModel.Email,
|
|
Phone: dbModel.Phone,
|
|
Points: dbModel.Points,
|
|
CreatedAt: dbModel.CreatedAt,
|
|
UpdatedAt: dbModel.UpdatedAt,
|
|
}
|
|
}
|