199 lines
6.4 KiB
Go
199 lines
6.4 KiB
Go
package processor
|
|
|
|
import (
|
|
"apskel-pos-be/internal/entities"
|
|
"apskel-pos-be/internal/mappers"
|
|
"apskel-pos-be/internal/models"
|
|
"apskel-pos-be/internal/repository"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type CustomerTokensProcessor struct {
|
|
customerTokensRepo *repository.CustomerTokensRepository
|
|
}
|
|
|
|
func NewCustomerTokensProcessor(customerTokensRepo *repository.CustomerTokensRepository) *CustomerTokensProcessor {
|
|
return &CustomerTokensProcessor{
|
|
customerTokensRepo: customerTokensRepo,
|
|
}
|
|
}
|
|
|
|
// CreateCustomerTokens creates a new customer tokens record
|
|
func (p *CustomerTokensProcessor) CreateCustomerTokens(ctx context.Context, req *models.CreateCustomerTokensRequest) (*models.CustomerTokensResponse, error) {
|
|
// Convert request to entity
|
|
customerTokens := mappers.ToCustomerTokensEntity(req)
|
|
|
|
// Create customer tokens
|
|
err := p.customerTokensRepo.Create(ctx, customerTokens)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create customer tokens: %w", err)
|
|
}
|
|
|
|
return mappers.ToCustomerTokensResponse(customerTokens), nil
|
|
}
|
|
|
|
// GetCustomerTokens retrieves customer tokens by ID
|
|
func (p *CustomerTokensProcessor) GetCustomerTokens(ctx context.Context, id uuid.UUID) (*models.CustomerTokensResponse, error) {
|
|
customerTokens, err := p.customerTokensRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("customer tokens not found: %w", err)
|
|
}
|
|
|
|
return mappers.ToCustomerTokensResponse(customerTokens), nil
|
|
}
|
|
|
|
// GetCustomerTokensByCustomerIDAndType retrieves customer tokens by customer ID and token type
|
|
func (p *CustomerTokensProcessor) GetCustomerTokensByCustomerIDAndType(ctx context.Context, customerID uuid.UUID, tokenType string) (*models.CustomerTokensResponse, error) {
|
|
customerTokens, err := p.customerTokensRepo.EnsureCustomerTokens(ctx, customerID, entities.TokenType(tokenType))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get customer tokens: %w", err)
|
|
}
|
|
|
|
return mappers.ToCustomerTokensResponse(customerTokens), nil
|
|
}
|
|
|
|
// ListCustomerTokens retrieves customer tokens with pagination and filtering
|
|
func (p *CustomerTokensProcessor) ListCustomerTokens(ctx context.Context, query *models.ListCustomerTokensQuery) (*models.PaginatedResponse[models.CustomerTokensResponse], 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 customer tokens from repository
|
|
customerTokens, total, err := p.customerTokensRepo.List(
|
|
ctx,
|
|
offset,
|
|
query.Limit,
|
|
query.Search,
|
|
query.TokenType,
|
|
query.SortBy,
|
|
query.SortOrder,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list customer tokens: %w", err)
|
|
}
|
|
|
|
// Convert to responses
|
|
responses := mappers.ToCustomerTokensResponses(customerTokens)
|
|
|
|
// Calculate pagination info
|
|
totalPages := int((total + int64(query.Limit) - 1) / int64(query.Limit))
|
|
|
|
return &models.PaginatedResponse[models.CustomerTokensResponse]{
|
|
Data: responses,
|
|
Pagination: models.Pagination{
|
|
Page: query.Page,
|
|
Limit: query.Limit,
|
|
Total: total,
|
|
TotalPages: totalPages,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// UpdateCustomerTokens updates an existing customer tokens record
|
|
func (p *CustomerTokensProcessor) UpdateCustomerTokens(ctx context.Context, id uuid.UUID, req *models.UpdateCustomerTokensRequest) (*models.CustomerTokensResponse, error) {
|
|
// Get existing customer tokens
|
|
customerTokens, err := p.customerTokensRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("customer tokens not found: %w", err)
|
|
}
|
|
|
|
// Update customer tokens fields
|
|
mappers.UpdateCustomerTokensEntity(customerTokens, req)
|
|
|
|
// Save updated customer tokens
|
|
err = p.customerTokensRepo.Update(ctx, customerTokens)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to update customer tokens: %w", err)
|
|
}
|
|
|
|
return mappers.ToCustomerTokensResponse(customerTokens), nil
|
|
}
|
|
|
|
// DeleteCustomerTokens deletes a customer tokens record
|
|
func (p *CustomerTokensProcessor) DeleteCustomerTokens(ctx context.Context, id uuid.UUID) error {
|
|
// Get existing customer tokens
|
|
_, err := p.customerTokensRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("customer tokens not found: %w", err)
|
|
}
|
|
|
|
// Delete customer tokens
|
|
err = p.customerTokensRepo.Delete(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete customer tokens: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddTokens adds tokens to a customer's balance
|
|
func (p *CustomerTokensProcessor) AddTokens(ctx context.Context, customerID uuid.UUID, tokenType string, tokens int64) (*models.CustomerTokensResponse, error) {
|
|
if tokens <= 0 {
|
|
return nil, errors.New("tokens must be greater than 0")
|
|
}
|
|
|
|
// Ensure customer tokens record exists
|
|
_, err := p.customerTokensRepo.EnsureCustomerTokens(ctx, customerID, entities.TokenType(tokenType))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to ensure customer tokens: %w", err)
|
|
}
|
|
|
|
// Add tokens
|
|
err = p.customerTokensRepo.AddTokens(ctx, customerID, entities.TokenType(tokenType), tokens)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to add tokens: %w", err)
|
|
}
|
|
|
|
// Get updated customer tokens
|
|
customerTokens, err := p.customerTokensRepo.GetByCustomerIDAndType(ctx, customerID, entities.TokenType(tokenType))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get updated customer tokens: %w", err)
|
|
}
|
|
|
|
return mappers.ToCustomerTokensResponse(customerTokens), nil
|
|
}
|
|
|
|
// DeductTokens deducts tokens from a customer's balance
|
|
func (p *CustomerTokensProcessor) DeductTokens(ctx context.Context, customerID uuid.UUID, tokenType string, tokens int64) (*models.CustomerTokensResponse, error) {
|
|
if tokens <= 0 {
|
|
return nil, errors.New("tokens must be greater than 0")
|
|
}
|
|
|
|
// Get current customer tokens
|
|
customerTokens, err := p.customerTokensRepo.GetByCustomerIDAndType(ctx, customerID, entities.TokenType(tokenType))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("customer tokens not found: %w", err)
|
|
}
|
|
|
|
if customerTokens.Balance < tokens {
|
|
return nil, errors.New("insufficient tokens balance")
|
|
}
|
|
|
|
// Deduct tokens
|
|
err = p.customerTokensRepo.DeductTokens(ctx, customerID, entities.TokenType(tokenType), tokens)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to deduct tokens: %w", err)
|
|
}
|
|
|
|
// Get updated customer tokens
|
|
updatedCustomerTokens, err := p.customerTokensRepo.GetByCustomerIDAndType(ctx, customerID, entities.TokenType(tokenType))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get updated customer tokens: %w", err)
|
|
}
|
|
|
|
return mappers.ToCustomerTokensResponse(updatedCustomerTokens), nil
|
|
}
|