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 }