apskel-pos-backend/internal/repository/customer_repository.go

141 lines
4.0 KiB
Go
Raw Normal View History

2025-07-18 20:10:29 +07:00
package repository
import (
"apskel-pos-be/internal/entities"
"context"
"fmt"
"github.com/google/uuid"
"gorm.io/gorm"
)
type CustomerRepository struct {
db *gorm.DB
}
func NewCustomerRepository(db *gorm.DB) *CustomerRepository {
return &CustomerRepository{db: db}
}
func (r *CustomerRepository) Create(ctx context.Context, customer *entities.Customer) error {
return r.db.WithContext(ctx).Create(customer).Error
}
func (r *CustomerRepository) GetByID(ctx context.Context, id uuid.UUID) (*entities.Customer, error) {
var customer entities.Customer
err := r.db.WithContext(ctx).Where("id = ?", id).First(&customer).Error
if err != nil {
return nil, err
}
return &customer, nil
}
func (r *CustomerRepository) GetByIDAndOrganization(ctx context.Context, id, organizationID uuid.UUID) (*entities.Customer, error) {
var customer entities.Customer
err := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", id, organizationID).First(&customer).Error
if err != nil {
return nil, err
}
return &customer, nil
}
func (r *CustomerRepository) GetDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*entities.Customer, error) {
var customer entities.Customer
err := r.db.WithContext(ctx).Where("organization_id = ? AND is_default = ?", organizationID, true).First(&customer).Error
if err != nil {
return nil, err
}
return &customer, nil
}
func (r *CustomerRepository) List(ctx context.Context, organizationID uuid.UUID, offset, limit int, search string, isActive, isDefault *bool, sortBy, sortOrder string) ([]entities.Customer, int64, error) {
var customers []entities.Customer
var total int64
query := r.db.WithContext(ctx).Where("organization_id = ?", organizationID)
if search != "" {
searchTerm := "%" + search + "%"
query = query.Where("name ILIKE ? OR email ILIKE ? OR phone ILIKE ?", searchTerm, searchTerm, searchTerm)
}
if isActive != nil {
query = query.Where("is_active = ?", *isActive)
}
if isDefault != nil {
query = query.Where("is_default = ?", *isDefault)
}
if err := query.Model(&entities.Customer{}).Count(&total).Error; err != nil {
return nil, 0, err
}
if sortBy != "" {
if sortOrder == "" {
sortOrder = "asc"
}
query = query.Order(fmt.Sprintf("%s %s", sortBy, sortOrder))
} else {
query = query.Order("created_at DESC")
}
err := query.Offset(offset).Limit(limit).Find(&customers).Error
if err != nil {
return nil, 0, err
}
return customers, total, nil
}
func (r *CustomerRepository) Update(ctx context.Context, customer *entities.Customer) error {
return r.db.WithContext(ctx).Save(customer).Error
}
func (r *CustomerRepository) Delete(ctx context.Context, id uuid.UUID) error {
return r.db.WithContext(ctx).Delete(&entities.Customer{}, id).Error
}
func (r *CustomerRepository) SetAsDefault(ctx context.Context, customerID, organizationID uuid.UUID) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&entities.Customer{}).
Where("organization_id = ? AND is_default = ?", organizationID, true).
Update("is_default", false).Error; err != nil {
return err
}
if err := tx.Model(&entities.Customer{}).
Where("id = ? AND organization_id = ?", customerID, organizationID).
Update("is_default", true).Error; err != nil {
return err
}
return nil
})
}
func (r *CustomerRepository) CreateDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*entities.Customer, error) {
defaultCustomer := &entities.Customer{
OrganizationID: organizationID,
Name: "Walk In Customer",
IsDefault: true,
IsActive: true,
}
err := r.db.WithContext(ctx).Create(defaultCustomer).Error
if err != nil {
return nil, err
}
return defaultCustomer, nil
}
func (r *CustomerRepository) GetByEmail(ctx context.Context, email string, organizationID uuid.UUID) (*entities.Customer, error) {
var customer entities.Customer
err := r.db.WithContext(ctx).Where("email = ? AND organization_id = ?", email, organizationID).First(&customer).Error
if err != nil {
return nil, err
}
return &customer, nil
}