init
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
"apskel-pos-be/internal/mappers"
|
||||
"apskel-pos-be/internal/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type OrganizationProcessor interface {
|
||||
CreateOrganization(ctx context.Context, req *models.CreateOrganizationRequest) (*models.CreateOrganizationResponse, error)
|
||||
UpdateOrganization(ctx context.Context, id uuid.UUID, req *models.UpdateOrganizationRequest) (*models.OrganizationResponse, error)
|
||||
DeleteOrganization(ctx context.Context, id uuid.UUID) error
|
||||
GetOrganizationByID(ctx context.Context, id uuid.UUID) (*models.OrganizationResponse, error)
|
||||
ListOrganizations(ctx context.Context, filters map[string]interface{}, page, limit int) ([]models.OrganizationResponse, int, error)
|
||||
}
|
||||
|
||||
type OrganizationProcessorImpl struct {
|
||||
organizationRepo OrganizationRepository
|
||||
outletRepo OutletRepository
|
||||
userRepo UserRepository
|
||||
}
|
||||
|
||||
func NewOrganizationProcessorImpl(
|
||||
organizationRepo OrganizationRepository,
|
||||
outletRepo OutletRepository,
|
||||
userRepo UserRepository,
|
||||
) *OrganizationProcessorImpl {
|
||||
return &OrganizationProcessorImpl{
|
||||
organizationRepo: organizationRepo,
|
||||
outletRepo: outletRepo,
|
||||
userRepo: userRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *OrganizationProcessorImpl) CreateOrganization(ctx context.Context, req *models.CreateOrganizationRequest) (*models.CreateOrganizationResponse, error) {
|
||||
if req.OrganizationEmail != nil && *req.OrganizationEmail != "" {
|
||||
existingOrg, err := p.organizationRepo.GetByEmail(ctx, *req.OrganizationEmail)
|
||||
if err == nil && existingOrg != nil {
|
||||
return nil, fmt.Errorf("organization with email %s already exists", *req.OrganizationEmail)
|
||||
}
|
||||
}
|
||||
|
||||
existingUser, err := p.userRepo.GetByEmail(ctx, req.AdminEmail)
|
||||
if err == nil && existingUser != nil {
|
||||
return nil, fmt.Errorf("user with email %s already exists", req.AdminEmail)
|
||||
}
|
||||
|
||||
organizationEntity := &entities.Organization{
|
||||
Name: req.OrganizationName,
|
||||
Email: req.OrganizationEmail,
|
||||
PhoneNumber: req.OrganizationPhoneNumber,
|
||||
PlanType: string(req.PlanType),
|
||||
}
|
||||
|
||||
err = p.organizationRepo.Create(ctx, organizationEntity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create organization: %w", err)
|
||||
}
|
||||
|
||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.AdminPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to hash password: %w", err)
|
||||
}
|
||||
|
||||
adminUserEntity := &entities.User{
|
||||
OrganizationID: organizationEntity.ID,
|
||||
Name: req.AdminName,
|
||||
Email: req.AdminEmail,
|
||||
PasswordHash: string(passwordHash),
|
||||
Role: entities.RoleAdmin,
|
||||
IsActive: true,
|
||||
}
|
||||
|
||||
err = p.userRepo.Create(ctx, adminUserEntity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create admin user: %w", err)
|
||||
}
|
||||
|
||||
defaultOutletEntity := &entities.Outlet{
|
||||
OrganizationID: organizationEntity.ID,
|
||||
Name: req.OutletName,
|
||||
Address: req.OutletAddress,
|
||||
Timezone: req.OutletTimezone,
|
||||
Currency: req.OutletCurrency,
|
||||
TaxRate: 0.0,
|
||||
IsActive: true,
|
||||
}
|
||||
|
||||
err = p.outletRepo.Create(ctx, defaultOutletEntity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create default outlet: %w", err)
|
||||
}
|
||||
|
||||
organizationResponse := mappers.OrganizationEntityToResponse(organizationEntity)
|
||||
adminUserResponse := mappers.UserEntityToResponse(adminUserEntity)
|
||||
outletResponse := mappers.OutletEntityToResponse(defaultOutletEntity)
|
||||
|
||||
return &models.CreateOrganizationResponse{
|
||||
Organization: organizationResponse,
|
||||
AdminUser: adminUserResponse,
|
||||
DefaultOutlet: outletResponse,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *OrganizationProcessorImpl) UpdateOrganization(ctx context.Context, id uuid.UUID, req *models.UpdateOrganizationRequest) (*models.OrganizationResponse, error) {
|
||||
existingOrg, err := p.organizationRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("organization not found: %w", err)
|
||||
}
|
||||
|
||||
if req.Email != nil && (existingOrg.Email == nil || *req.Email != *existingOrg.Email) {
|
||||
existingOrgByEmail, err := p.organizationRepo.GetByEmail(ctx, *req.Email)
|
||||
if err == nil && existingOrgByEmail != nil && existingOrgByEmail.ID != id {
|
||||
return nil, fmt.Errorf("organization with email %s already exists", *req.Email)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Name != nil {
|
||||
existingOrg.Name = *req.Name
|
||||
}
|
||||
if req.Email != nil {
|
||||
existingOrg.Email = req.Email
|
||||
}
|
||||
if req.PhoneNumber != nil {
|
||||
existingOrg.PhoneNumber = req.PhoneNumber
|
||||
}
|
||||
if req.PlanType != nil {
|
||||
existingOrg.PlanType = string(*req.PlanType)
|
||||
}
|
||||
|
||||
err = p.organizationRepo.Update(ctx, existingOrg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update organization: %w", err)
|
||||
}
|
||||
|
||||
return mappers.OrganizationEntityToResponse(existingOrg), nil
|
||||
}
|
||||
|
||||
func (p *OrganizationProcessorImpl) DeleteOrganization(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := p.organizationRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("organization not found: %w", err)
|
||||
}
|
||||
|
||||
err = p.organizationRepo.Delete(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete organization: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *OrganizationProcessorImpl) GetOrganizationByID(ctx context.Context, id uuid.UUID) (*models.OrganizationResponse, error) {
|
||||
organization, err := p.organizationRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("organization not found: %w", err)
|
||||
}
|
||||
|
||||
return mappers.OrganizationEntityToResponse(organization), nil
|
||||
}
|
||||
|
||||
func (p *OrganizationProcessorImpl) ListOrganizations(ctx context.Context, filters map[string]interface{}, page, limit int) ([]models.OrganizationResponse, int, error) {
|
||||
offset := (page - 1) * limit
|
||||
|
||||
organizations, totalCount, err := p.organizationRepo.List(ctx, filters, limit, offset)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to get organizations: %w", err)
|
||||
}
|
||||
|
||||
responses := make([]models.OrganizationResponse, len(organizations))
|
||||
for i, org := range organizations {
|
||||
response := mappers.OrganizationEntityToResponse(org)
|
||||
if response != nil {
|
||||
responses[i] = *response
|
||||
}
|
||||
}
|
||||
|
||||
return responses, int(totalCount), nil
|
||||
}
|
||||
Reference in New Issue
Block a user