package customer import ( "context" "errors" infrastructure "tm/infra" domain "tm/internal/customer/domain" "tm/internal/customer/domain/entity" "tm/pkg/logger" "github.com/google/uuid" ) // CustomerService implements the CustomerService interface type CustomerService struct { customerRepo domain.Repository config *infrastructure.AuthConfig logger logger.Logger } // NewCustomerService creates a new customer service func NewCustomerService( customerRepo domain.Repository, config *infrastructure.AuthConfig, logger logger.Logger, ) CustomerService { return CustomerService{ customerRepo: customerRepo, config: config, logger: logger, } } // GetCustomers retrieves customers with pagination (for panel users) func (s *CustomerService) GetCustomers(ctx context.Context, limit, offset int) ([]*entity.Customer, error) { s.logger.Info("Retrieving customers", map[string]interface{}{ "limit": limit, "offset": offset, }) customers, err := s.customerRepo.List(ctx, limit, offset) if err != nil { s.logger.Error("Failed to retrieve customers", map[string]interface{}{ "error": err.Error(), "limit": limit, "offset": offset, }) return nil, errors.New("failed to retrieve customers") } s.logger.Info("Customers retrieved successfully", map[string]interface{}{ "count": len(customers), "limit": limit, "offset": offset, }) return customers, nil } // GetCustomerByID retrieves a customer by ID (for panel users) func (s *CustomerService) GetCustomerByID(ctx context.Context, id uuid.UUID) (*entity.Customer, error) { s.logger.Info("Retrieving customer by ID", map[string]interface{}{ "customer_id": id.String(), }) customer, err := s.customerRepo.GetByID(ctx, id) if err != nil { s.logger.Error("Failed to retrieve customer", map[string]interface{}{ "error": err.Error(), "customer_id": id.String(), }) return nil, errors.New("customer not found") } s.logger.Info("Customer retrieved successfully", map[string]interface{}{ "customer_id": customer.ID.String(), "email": customer.Email, }) return customer, nil } // GetCustomersByCompany retrieves customers by company ID with pagination (for panel users) func (s *CustomerService) GetCustomersByCompany(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]*entity.Customer, error) { s.logger.Info("Retrieving customers by company", map[string]interface{}{ "company_id": companyID.String(), "limit": limit, "offset": offset, }) customers, err := s.customerRepo.GetByCompanyID(ctx, companyID, limit, offset) if err != nil { s.logger.Error("Failed to retrieve customers by company", map[string]interface{}{ "error": err.Error(), "company_id": companyID.String(), "limit": limit, "offset": offset, }) return nil, errors.New("failed to retrieve customers") } s.logger.Info("Customers by company retrieved successfully", map[string]interface{}{ "count": len(customers), "company_id": companyID.String(), "limit": limit, "offset": offset, }) return customers, nil } // UpdateCustomerStatus updates customer active status (for panel users) func (s *CustomerService) UpdateCustomerStatus(ctx context.Context, customerID uuid.UUID, isActive bool, updatedBy uuid.UUID) error { s.logger.Info("Updating customer status", map[string]interface{}{ "customer_id": customerID.String(), "is_active": isActive, "updated_by": updatedBy.String(), }) // Get customer customer, err := s.customerRepo.GetByID(ctx, customerID) if err != nil { s.logger.Error("Customer not found for status update", map[string]interface{}{ "error": err.Error(), "customer_id": customerID.String(), }) return errors.New("customer not found") } // Update status customer.IsActive = isActive // Save changes if err := s.customerRepo.Update(ctx, customer); err != nil { s.logger.Error("Failed to update customer status", map[string]interface{}{ "error": err.Error(), "customer_id": customerID.String(), "is_active": isActive, "updated_by": updatedBy.String(), }) return errors.New("failed to update customer status") } s.logger.Info("Customer status updated successfully", map[string]interface{}{ "customer_id": customerID.String(), "is_active": isActive, "updated_by": updatedBy.String(), }) return nil }