Add coa purchase and vendors
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user