init
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/mappers"
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/repository"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type CustomerProcessor struct {
|
||||
customerRepo *repository.CustomerRepository
|
||||
}
|
||||
|
||||
func NewCustomerProcessor(customerRepo *repository.CustomerRepository) *CustomerProcessor {
|
||||
return &CustomerProcessor{
|
||||
customerRepo: customerRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCustomer creates a new customer
|
||||
func (p *CustomerProcessor) CreateCustomer(ctx context.Context, req *models.CreateCustomerRequest, organizationID uuid.UUID) (*models.CustomerResponse, error) {
|
||||
if req.Email != nil {
|
||||
existingCustomer, err := p.customerRepo.GetByEmail(ctx, *req.Email, organizationID)
|
||||
if err == nil && existingCustomer != nil {
|
||||
return nil, errors.New("email already exists for this organization")
|
||||
}
|
||||
}
|
||||
|
||||
// Convert request to entity
|
||||
customer := mappers.ToCustomerEntity(req, organizationID)
|
||||
|
||||
// Create customer
|
||||
err := p.customerRepo.Create(ctx, customer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create customer: %w", err)
|
||||
}
|
||||
|
||||
return mappers.ToCustomerResponse(customer), nil
|
||||
}
|
||||
|
||||
// GetCustomer retrieves a customer by ID
|
||||
func (p *CustomerProcessor) GetCustomer(ctx context.Context, customerID, organizationID uuid.UUID) (*models.CustomerResponse, error) {
|
||||
customer, err := p.customerRepo.GetByIDAndOrganization(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("customer not found: %w", err)
|
||||
}
|
||||
|
||||
return mappers.ToCustomerResponse(customer), nil
|
||||
}
|
||||
|
||||
// ListCustomers retrieves customers with pagination and filtering
|
||||
func (p *CustomerProcessor) ListCustomers(ctx context.Context, query *models.ListCustomersQuery, organizationID uuid.UUID) (*models.PaginatedResponse[models.CustomerResponse], error) {
|
||||
// Set default values
|
||||
if query.Page <= 0 {
|
||||
query.Page = 1
|
||||
}
|
||||
if query.Limit <= 0 {
|
||||
query.Limit = 10
|
||||
}
|
||||
if query.Limit > 100 {
|
||||
query.Limit = 100
|
||||
}
|
||||
|
||||
offset := (query.Page - 1) * query.Limit
|
||||
|
||||
// Get customers from repository
|
||||
customers, total, err := p.customerRepo.List(
|
||||
ctx,
|
||||
organizationID,
|
||||
offset,
|
||||
query.Limit,
|
||||
query.Search,
|
||||
query.IsActive,
|
||||
query.IsDefault,
|
||||
query.SortBy,
|
||||
query.SortOrder,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list customers: %w", err)
|
||||
}
|
||||
|
||||
// Convert to responses
|
||||
responses := mappers.ToCustomerResponses(customers)
|
||||
|
||||
// Calculate pagination info
|
||||
totalPages := int((total + int64(query.Limit) - 1) / int64(query.Limit))
|
||||
|
||||
return &models.PaginatedResponse[models.CustomerResponse]{
|
||||
Data: responses,
|
||||
Pagination: models.Pagination{
|
||||
Page: query.Page,
|
||||
Limit: query.Limit,
|
||||
Total: total,
|
||||
TotalPages: totalPages,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCustomer updates an existing customer
|
||||
func (p *CustomerProcessor) UpdateCustomer(ctx context.Context, customerID, organizationID uuid.UUID, req *models.UpdateCustomerRequest) (*models.CustomerResponse, error) {
|
||||
// Get existing customer
|
||||
customer, err := p.customerRepo.GetByIDAndOrganization(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("customer not found: %w", err)
|
||||
}
|
||||
|
||||
// Check if email is already taken by another customer within the organization
|
||||
if req.Email != nil && *req.Email != *customer.Email {
|
||||
existingCustomer, err := p.customerRepo.GetByEmail(ctx, *req.Email, organizationID)
|
||||
if err == nil && existingCustomer != nil && existingCustomer.ID != customerID {
|
||||
return nil, errors.New("email already exists for this organization")
|
||||
}
|
||||
}
|
||||
|
||||
// Update customer fields
|
||||
mappers.UpdateCustomerEntity(customer, req)
|
||||
|
||||
// Save updated customer
|
||||
err = p.customerRepo.Update(ctx, customer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update customer: %w", err)
|
||||
}
|
||||
|
||||
return mappers.ToCustomerResponse(customer), nil
|
||||
}
|
||||
|
||||
// DeleteCustomer deletes a customer
|
||||
func (p *CustomerProcessor) DeleteCustomer(ctx context.Context, customerID, organizationID uuid.UUID) error {
|
||||
// Get existing customer
|
||||
customer, err := p.customerRepo.GetByIDAndOrganization(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("customer not found: %w", err)
|
||||
}
|
||||
|
||||
// Prevent deletion of default customer
|
||||
if customer.IsDefault {
|
||||
return errors.New("cannot delete default customer")
|
||||
}
|
||||
|
||||
// Delete customer
|
||||
err = p.customerRepo.Delete(ctx, customerID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete customer: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *CustomerProcessor) SetDefaultCustomer(ctx context.Context, customerID, organizationID uuid.UUID) (*models.CustomerResponse, error) {
|
||||
_, err := p.customerRepo.GetByIDAndOrganization(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("customer not found: %w", err)
|
||||
}
|
||||
|
||||
// Set as default
|
||||
err = p.customerRepo.SetAsDefault(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set default customer: %w", err)
|
||||
}
|
||||
|
||||
// Get updated customer
|
||||
updatedCustomer, err := p.customerRepo.GetByID(ctx, customerID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get updated customer: %w", err)
|
||||
}
|
||||
|
||||
return mappers.ToCustomerResponse(updatedCustomer), nil
|
||||
}
|
||||
|
||||
func (p *CustomerProcessor) GetDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*models.CustomerResponse, error) {
|
||||
customer, err := p.customerRepo.GetDefaultCustomer(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("default customer not found: %w", err)
|
||||
}
|
||||
|
||||
return mappers.ToCustomerResponse(customer), nil
|
||||
}
|
||||
|
||||
func (p *CustomerProcessor) EnsureDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*models.CustomerResponse, error) {
|
||||
customer, err := p.customerRepo.GetDefaultCustomer(ctx, organizationID)
|
||||
if err == nil {
|
||||
return mappers.ToCustomerResponse(customer), nil
|
||||
}
|
||||
|
||||
defaultCustomer, err := p.customerRepo.CreateDefaultCustomer(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create default customer: %w", err)
|
||||
}
|
||||
|
||||
return mappers.ToCustomerResponse(defaultCustomer), nil
|
||||
}
|
||||
Reference in New Issue
Block a user