178 lines
6.0 KiB
Go
178 lines
6.0 KiB
Go
package processor
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"apskel-pos-be/internal/entities"
|
|
"apskel-pos-be/internal/mappers"
|
|
"apskel-pos-be/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type VendorProcessor interface {
|
|
CreateVendor(ctx context.Context, organizationID uuid.UUID, req *models.CreateVendorRequest) (*models.VendorResponse, error)
|
|
UpdateVendor(ctx context.Context, id, organizationID uuid.UUID, req *models.UpdateVendorRequest) (*models.VendorResponse, error)
|
|
DeleteVendor(ctx context.Context, id, organizationID uuid.UUID) error
|
|
GetVendorByID(ctx context.Context, id, organizationID uuid.UUID) (*models.VendorResponse, error)
|
|
ListVendors(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*models.VendorResponse, int, error)
|
|
GetActiveVendors(ctx context.Context, organizationID uuid.UUID) ([]*models.VendorResponse, error)
|
|
}
|
|
|
|
type VendorProcessorImpl struct {
|
|
vendorRepo VendorRepository
|
|
}
|
|
|
|
func NewVendorProcessorImpl(vendorRepo VendorRepository) *VendorProcessorImpl {
|
|
return &VendorProcessorImpl{
|
|
vendorRepo: vendorRepo,
|
|
}
|
|
}
|
|
|
|
func (p *VendorProcessorImpl) CreateVendor(ctx context.Context, organizationID uuid.UUID, req *models.CreateVendorRequest) (*models.VendorResponse, error) {
|
|
// Check if vendor with same name already exists in organization
|
|
if req.Name != "" {
|
|
existingVendor, err := p.vendorRepo.GetByName(ctx, req.Name, organizationID)
|
|
if err == nil && existingVendor != nil {
|
|
return nil, fmt.Errorf("vendor with name %s already exists in this organization", req.Name)
|
|
}
|
|
}
|
|
|
|
// Check if vendor with same email already exists in organization
|
|
if req.Email != nil && *req.Email != "" {
|
|
existingVendor, err := p.vendorRepo.GetByEmail(ctx, *req.Email, organizationID)
|
|
if err == nil && existingVendor != nil {
|
|
return nil, fmt.Errorf("vendor with email %s already exists in this organization", *req.Email)
|
|
}
|
|
}
|
|
|
|
vendorEntity := &entities.Vendor{
|
|
OrganizationID: organizationID,
|
|
Name: req.Name,
|
|
Email: req.Email,
|
|
PhoneNumber: req.PhoneNumber,
|
|
Address: req.Address,
|
|
ContactPerson: req.ContactPerson,
|
|
TaxNumber: req.TaxNumber,
|
|
PaymentTerms: req.PaymentTerms,
|
|
Notes: req.Notes,
|
|
IsActive: true, // Default to active
|
|
}
|
|
|
|
if req.IsActive != nil {
|
|
vendorEntity.IsActive = *req.IsActive
|
|
}
|
|
|
|
err := p.vendorRepo.Create(ctx, vendorEntity)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create vendor: %w", err)
|
|
}
|
|
|
|
return mappers.VendorEntityToResponse(vendorEntity), nil
|
|
}
|
|
|
|
func (p *VendorProcessorImpl) UpdateVendor(ctx context.Context, id, organizationID uuid.UUID, req *models.UpdateVendorRequest) (*models.VendorResponse, error) {
|
|
vendorEntity, err := p.vendorRepo.GetByIDAndOrganizationID(ctx, id, organizationID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("vendor not found: %w", err)
|
|
}
|
|
|
|
// Check if vendor with same name already exists (excluding current vendor)
|
|
if req.Name != nil && *req.Name != "" && *req.Name != vendorEntity.Name {
|
|
existingVendor, err := p.vendorRepo.GetByName(ctx, *req.Name, organizationID)
|
|
if err == nil && existingVendor != nil && existingVendor.ID != id {
|
|
return nil, fmt.Errorf("vendor with name %s already exists in this organization", *req.Name)
|
|
}
|
|
}
|
|
|
|
// Check if vendor with same email already exists (excluding current vendor)
|
|
if req.Email != nil && *req.Email != "" && (vendorEntity.Email == nil || *req.Email != *vendorEntity.Email) {
|
|
existingVendor, err := p.vendorRepo.GetByEmail(ctx, *req.Email, organizationID)
|
|
if err == nil && existingVendor != nil && existingVendor.ID != id {
|
|
return nil, fmt.Errorf("vendor with email %s already exists in this organization", *req.Email)
|
|
}
|
|
}
|
|
|
|
// Update fields
|
|
if req.Name != nil {
|
|
vendorEntity.Name = *req.Name
|
|
}
|
|
if req.Email != nil {
|
|
vendorEntity.Email = req.Email
|
|
}
|
|
if req.PhoneNumber != nil {
|
|
vendorEntity.PhoneNumber = req.PhoneNumber
|
|
}
|
|
if req.Address != nil {
|
|
vendorEntity.Address = req.Address
|
|
}
|
|
if req.ContactPerson != nil {
|
|
vendorEntity.ContactPerson = req.ContactPerson
|
|
}
|
|
if req.TaxNumber != nil {
|
|
vendorEntity.TaxNumber = req.TaxNumber
|
|
}
|
|
if req.PaymentTerms != nil {
|
|
vendorEntity.PaymentTerms = req.PaymentTerms
|
|
}
|
|
if req.Notes != nil {
|
|
vendorEntity.Notes = req.Notes
|
|
}
|
|
if req.IsActive != nil {
|
|
vendorEntity.IsActive = *req.IsActive
|
|
}
|
|
|
|
err = p.vendorRepo.Update(ctx, vendorEntity)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to update vendor: %w", err)
|
|
}
|
|
|
|
return mappers.VendorEntityToResponse(vendorEntity), nil
|
|
}
|
|
|
|
func (p *VendorProcessorImpl) DeleteVendor(ctx context.Context, id, organizationID uuid.UUID) error {
|
|
_, err := p.vendorRepo.GetByIDAndOrganizationID(ctx, id, organizationID)
|
|
if err != nil {
|
|
return fmt.Errorf("vendor not found: %w", err)
|
|
}
|
|
|
|
err = p.vendorRepo.Delete(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete vendor: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *VendorProcessorImpl) GetVendorByID(ctx context.Context, id, organizationID uuid.UUID) (*models.VendorResponse, error) {
|
|
vendorEntity, err := p.vendorRepo.GetByIDAndOrganizationID(ctx, id, organizationID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("vendor not found: %w", err)
|
|
}
|
|
|
|
return mappers.VendorEntityToResponse(vendorEntity), nil
|
|
}
|
|
|
|
func (p *VendorProcessorImpl) ListVendors(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*models.VendorResponse, int, error) {
|
|
offset := (page - 1) * limit
|
|
vendorEntities, total, err := p.vendorRepo.List(ctx, organizationID, filters, limit, offset)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to list vendors: %w", err)
|
|
}
|
|
|
|
vendorResponses := mappers.VendorEntitiesToResponses(vendorEntities)
|
|
totalPages := int((total + int64(limit) - 1) / int64(limit))
|
|
|
|
return vendorResponses, totalPages, nil
|
|
}
|
|
|
|
func (p *VendorProcessorImpl) GetActiveVendors(ctx context.Context, organizationID uuid.UUID) ([]*models.VendorResponse, error) {
|
|
vendorEntities, err := p.vendorRepo.GetActiveVendors(ctx, organizationID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get active vendors: %w", err)
|
|
}
|
|
|
|
return mappers.VendorEntitiesToResponses(vendorEntities), nil
|
|
}
|