package processor import ( "apskel-pos-be/internal/appcontext" "apskel-pos-be/internal/entities" "apskel-pos-be/internal/mappers" "apskel-pos-be/internal/models" "apskel-pos-be/internal/repository" "context" "fmt" "github.com/google/uuid" ) type OutletProcessor interface { ListOutletsByOrganization(ctx context.Context, organizationID uuid.UUID, page, limit int) ([]*models.OutletResponse, int64, error) GetOutletByID(ctx context.Context, organizationID uuid.UUID, outletID uuid.UUID) (*models.OutletResponse, error) CreateOutlet(ctx context.Context, req *models.CreateOutletRequest) (*models.OutletResponse, error) UpdateOutlet(ctx context.Context, outletID uuid.UUID, req *models.UpdateOutletRequest) (*models.OutletResponse, error) DeleteOutlet(ctx context.Context, outletID uuid.UUID) error } type OutletProcessorImpl struct { outletRepo *repository.OutletRepositoryImpl } func NewOutletProcessorImpl(outletRepo *repository.OutletRepositoryImpl) *OutletProcessorImpl { return &OutletProcessorImpl{ outletRepo: outletRepo, } } func (p *OutletProcessorImpl) ListOutletsByOrganization(ctx context.Context, organizationID uuid.UUID, page, limit int) ([]*models.OutletResponse, int64, error) { offset := (page - 1) * limit outlets, total, err := p.outletRepo.GetByOrganizationIDWithPagination(ctx, organizationID, limit, offset) if err != nil { return nil, 0, fmt.Errorf("failed to get outlets: %w", err) } // Convert to response models responses := make([]*models.OutletResponse, len(outlets)) for i, outlet := range outlets { responses[i] = mappers.OutletEntityToResponse(outlet) } return responses, total, nil } func (p *OutletProcessorImpl) GetOutletByID(ctx context.Context, organizationID, outletID uuid.UUID) (*models.OutletResponse, error) { outlet, err := p.outletRepo.GetByID(ctx, outletID) if err != nil { return nil, fmt.Errorf("outlet not found: %w", err) } if outlet.OrganizationID != organizationID { return nil, fmt.Errorf("outlet does not belong to the organization") } response := mappers.OutletEntityToResponse(outlet) return response, nil } func (p *OutletProcessorImpl) CreateOutlet(ctx context.Context, req *models.CreateOutletRequest) (*models.OutletResponse, error) { // Get organization ID from context contextInfo := appcontext.FromContext(ctx) if contextInfo.OrganizationID == uuid.Nil { return nil, fmt.Errorf("organization ID not found in context") } // Set organization ID from context req.OrganizationID = contextInfo.OrganizationID // Create outlet entity outlet := &entities.Outlet{ OrganizationID: req.OrganizationID, Name: req.Name, Address: &req.Address, Currency: string(req.Currency), TaxRate: req.TaxRate, IsActive: true, } err := p.outletRepo.Create(ctx, outlet) if err != nil { return nil, fmt.Errorf("failed to create outlet: %w", err) } response := mappers.OutletEntityToResponse(outlet) return response, nil } func (p *OutletProcessorImpl) UpdateOutlet(ctx context.Context, outletID uuid.UUID, req *models.UpdateOutletRequest) (*models.OutletResponse, error) { outlet, err := p.outletRepo.GetByID(ctx, outletID) if err != nil { return nil, fmt.Errorf("outlet not found: %w", err) } if outlet.OrganizationID != req.OrganizationID { return nil, fmt.Errorf("outlet does not belong to the organization") } if req.Name != nil { outlet.Name = *req.Name } if req.Address != nil { outlet.Address = req.Address } if req.TaxRate != nil { outlet.TaxRate = *req.TaxRate } if req.IsActive != nil { outlet.IsActive = *req.IsActive } err = p.outletRepo.Update(ctx, outlet) if err != nil { return nil, fmt.Errorf("failed to update outlet: %w", err) } response := mappers.OutletEntityToResponse(outlet) return response, nil } func (p *OutletProcessorImpl) DeleteOutlet(ctx context.Context, outletID uuid.UUID) error { contextInfo := appcontext.FromContext(ctx) if contextInfo.OrganizationID == uuid.Nil { return fmt.Errorf("organization ID not found in context") } // Get existing outlet outlet, err := p.outletRepo.GetByID(ctx, outletID) if err != nil { return fmt.Errorf("outlet not found: %w", err) } if outlet.OrganizationID != contextInfo.OrganizationID { return fmt.Errorf("outlet does not belong to the organization") } err = p.outletRepo.Delete(ctx, outletID) if err != nil { return fmt.Errorf("failed to delete outlet: %w", err) } return nil }