Add coa purchase and vendors
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
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 IngredientUnitConverterRepository interface {
|
||||
Create(ctx context.Context, converter *entities.IngredientUnitConverter) error
|
||||
GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error)
|
||||
GetByIDAndOrganizationID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error)
|
||||
Update(ctx context.Context, converter *entities.IngredientUnitConverter) error
|
||||
Delete(ctx context.Context, id, organizationID uuid.UUID) error
|
||||
List(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*entities.IngredientUnitConverter, int, error)
|
||||
GetByIngredientAndUnits(ctx context.Context, ingredientID, fromUnitID, toUnitID, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error)
|
||||
GetConvertersForIngredient(ctx context.Context, ingredientID, organizationID uuid.UUID) ([]*entities.IngredientUnitConverter, error)
|
||||
GetActiveConverters(ctx context.Context, organizationID uuid.UUID) ([]*entities.IngredientUnitConverter, error)
|
||||
ConvertQuantity(ctx context.Context, ingredientID, fromUnitID, toUnitID, organizationID uuid.UUID, quantity float64) (float64, error)
|
||||
}
|
||||
|
||||
type IngredientUnitConverterProcessor interface {
|
||||
CreateIngredientUnitConverter(ctx context.Context, organizationID, userID uuid.UUID, req *models.CreateIngredientUnitConverterRequest) (*models.IngredientUnitConverterResponse, error)
|
||||
UpdateIngredientUnitConverter(ctx context.Context, id, organizationID, userID uuid.UUID, req *models.UpdateIngredientUnitConverterRequest) (*models.IngredientUnitConverterResponse, error)
|
||||
DeleteIngredientUnitConverter(ctx context.Context, id, organizationID uuid.UUID) error
|
||||
GetIngredientUnitConverterByID(ctx context.Context, id, organizationID uuid.UUID) (*models.IngredientUnitConverterResponse, error)
|
||||
ListIngredientUnitConverters(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*models.IngredientUnitConverterResponse, int, error)
|
||||
GetConvertersForIngredient(ctx context.Context, ingredientID, organizationID uuid.UUID) ([]*models.IngredientUnitConverterResponse, error)
|
||||
ConvertUnit(ctx context.Context, organizationID uuid.UUID, req *models.ConvertUnitRequest) (*models.ConvertUnitResponse, error)
|
||||
}
|
||||
|
||||
type IngredientUnitConverterProcessorImpl struct {
|
||||
converterRepo IngredientUnitConverterRepository
|
||||
ingredientRepo IngredientRepository
|
||||
unitRepo UnitRepository
|
||||
}
|
||||
|
||||
func NewIngredientUnitConverterProcessorImpl(
|
||||
converterRepo IngredientUnitConverterRepository,
|
||||
ingredientRepo IngredientRepository,
|
||||
unitRepo UnitRepository,
|
||||
) *IngredientUnitConverterProcessorImpl {
|
||||
return &IngredientUnitConverterProcessorImpl{
|
||||
converterRepo: converterRepo,
|
||||
ingredientRepo: ingredientRepo,
|
||||
unitRepo: unitRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) CreateIngredientUnitConverter(ctx context.Context, organizationID, userID uuid.UUID, req *models.CreateIngredientUnitConverterRequest) (*models.IngredientUnitConverterResponse, error) {
|
||||
// Validate ingredient exists
|
||||
_, err := p.ingredientRepo.GetByID(ctx, req.IngredientID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ingredient not found: %w", err)
|
||||
}
|
||||
|
||||
// Validate units exist
|
||||
_, err = p.unitRepo.GetByID(ctx, req.FromUnitID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("from unit not found: %w", err)
|
||||
}
|
||||
|
||||
_, err = p.unitRepo.GetByID(ctx, req.ToUnitID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("to unit not found: %w", err)
|
||||
}
|
||||
|
||||
// Check if converter already exists
|
||||
existingConverter, err := p.converterRepo.GetByIngredientAndUnits(ctx, req.IngredientID, req.FromUnitID, req.ToUnitID, organizationID)
|
||||
if err == nil && existingConverter != nil {
|
||||
return nil, fmt.Errorf("converter already exists for this ingredient and unit combination")
|
||||
}
|
||||
|
||||
// Set default values
|
||||
isActive := true
|
||||
if req.IsActive != nil {
|
||||
isActive = *req.IsActive
|
||||
}
|
||||
|
||||
// Create entity
|
||||
converter := &entities.IngredientUnitConverter{
|
||||
OrganizationID: organizationID,
|
||||
IngredientID: req.IngredientID,
|
||||
FromUnitID: req.FromUnitID,
|
||||
ToUnitID: req.ToUnitID,
|
||||
ConversionFactor: req.ConversionFactor,
|
||||
IsActive: isActive,
|
||||
CreatedBy: userID,
|
||||
UpdatedBy: userID,
|
||||
}
|
||||
|
||||
err = p.converterRepo.Create(ctx, converter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create ingredient unit converter: %w", err)
|
||||
}
|
||||
|
||||
// Get the created converter with relationships
|
||||
createdConverter, err := p.converterRepo.GetByID(ctx, converter.ID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get created converter: %w", err)
|
||||
}
|
||||
|
||||
return mappers.IngredientUnitConverterEntityToResponse(createdConverter), nil
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) UpdateIngredientUnitConverter(ctx context.Context, id, organizationID, userID uuid.UUID, req *models.UpdateIngredientUnitConverterRequest) (*models.IngredientUnitConverterResponse, error) {
|
||||
// Get existing converter
|
||||
converter, err := p.converterRepo.GetByID(ctx, id, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ingredient unit converter not found: %w", err)
|
||||
}
|
||||
|
||||
// Update fields if provided
|
||||
if req.FromUnitID != nil {
|
||||
// Validate new unit exists
|
||||
_, err = p.unitRepo.GetByID(ctx, *req.FromUnitID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("from unit not found: %w", err)
|
||||
}
|
||||
converter.FromUnitID = *req.FromUnitID
|
||||
}
|
||||
|
||||
if req.ToUnitID != nil {
|
||||
// Validate new unit exists
|
||||
_, err = p.unitRepo.GetByID(ctx, *req.ToUnitID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("to unit not found: %w", err)
|
||||
}
|
||||
converter.ToUnitID = *req.ToUnitID
|
||||
}
|
||||
|
||||
if req.ConversionFactor != nil {
|
||||
converter.ConversionFactor = *req.ConversionFactor
|
||||
}
|
||||
|
||||
if req.IsActive != nil {
|
||||
converter.IsActive = *req.IsActive
|
||||
}
|
||||
|
||||
converter.UpdatedBy = userID
|
||||
|
||||
err = p.converterRepo.Update(ctx, converter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update ingredient unit converter: %w", err)
|
||||
}
|
||||
|
||||
// Get the updated converter with relationships
|
||||
updatedConverter, err := p.converterRepo.GetByID(ctx, converter.ID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get updated converter: %w", err)
|
||||
}
|
||||
|
||||
return mappers.IngredientUnitConverterEntityToResponse(updatedConverter), nil
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) DeleteIngredientUnitConverter(ctx context.Context, id, organizationID uuid.UUID) error {
|
||||
// Check if converter exists
|
||||
_, err := p.converterRepo.GetByID(ctx, id, organizationID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ingredient unit converter not found: %w", err)
|
||||
}
|
||||
|
||||
err = p.converterRepo.Delete(ctx, id, organizationID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete ingredient unit converter: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) GetIngredientUnitConverterByID(ctx context.Context, id, organizationID uuid.UUID) (*models.IngredientUnitConverterResponse, error) {
|
||||
converter, err := p.converterRepo.GetByID(ctx, id, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ingredient unit converter not found: %w", err)
|
||||
}
|
||||
|
||||
return mappers.IngredientUnitConverterEntityToResponse(converter), nil
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) ListIngredientUnitConverters(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*models.IngredientUnitConverterResponse, int, error) {
|
||||
converters, total, err := p.converterRepo.List(ctx, organizationID, filters, page, limit)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to list ingredient unit converters: %w", err)
|
||||
}
|
||||
|
||||
responses := make([]*models.IngredientUnitConverterResponse, len(converters))
|
||||
for i, converter := range converters {
|
||||
responses[i] = mappers.IngredientUnitConverterEntityToResponse(converter)
|
||||
}
|
||||
|
||||
return responses, total, nil
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) GetConvertersForIngredient(ctx context.Context, ingredientID, organizationID uuid.UUID) ([]*models.IngredientUnitConverterResponse, error) {
|
||||
converters, err := p.converterRepo.GetConvertersForIngredient(ctx, ingredientID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get converters for ingredient: %w", err)
|
||||
}
|
||||
|
||||
responses := make([]*models.IngredientUnitConverterResponse, len(converters))
|
||||
for i, converter := range converters {
|
||||
responses[i] = mappers.IngredientUnitConverterEntityToResponse(converter)
|
||||
}
|
||||
|
||||
return responses, nil
|
||||
}
|
||||
|
||||
func (p *IngredientUnitConverterProcessorImpl) ConvertUnit(ctx context.Context, organizationID uuid.UUID, req *models.ConvertUnitRequest) (*models.ConvertUnitResponse, error) {
|
||||
// Get ingredient and units for response
|
||||
ingredient, err := p.ingredientRepo.GetByID(ctx, req.IngredientID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ingredient not found: %w", err)
|
||||
}
|
||||
|
||||
fromUnit, err := p.unitRepo.GetByID(ctx, req.FromUnitID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("from unit not found: %w", err)
|
||||
}
|
||||
|
||||
toUnit, err := p.unitRepo.GetByID(ctx, req.ToUnitID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("to unit not found: %w", err)
|
||||
}
|
||||
|
||||
// Convert quantity
|
||||
convertedQuantity, err := p.converterRepo.ConvertQuantity(ctx, req.IngredientID, req.FromUnitID, req.ToUnitID, organizationID, req.Quantity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert quantity: %w", err)
|
||||
}
|
||||
|
||||
// Get conversion factor for response
|
||||
converter, err := p.converterRepo.GetByIngredientAndUnits(ctx, req.IngredientID, req.FromUnitID, req.ToUnitID, organizationID)
|
||||
var conversionFactor float64
|
||||
if err == nil {
|
||||
conversionFactor = converter.ConversionFactor
|
||||
} else {
|
||||
// Try reverse converter
|
||||
reverseConverter, err := p.converterRepo.GetByIngredientAndUnits(ctx, req.IngredientID, req.ToUnitID, req.FromUnitID, organizationID)
|
||||
if err == nil {
|
||||
conversionFactor = 1.0 / reverseConverter.ConversionFactor
|
||||
}
|
||||
}
|
||||
|
||||
response := &models.ConvertUnitResponse{
|
||||
FromQuantity: req.Quantity,
|
||||
FromUnit: mappers.MapUnitEntityToResponse(fromUnit),
|
||||
ToQuantity: convertedQuantity,
|
||||
ToUnit: mappers.MapUnitEntityToResponse(toUnit),
|
||||
ConversionFactor: conversionFactor,
|
||||
Ingredient: mappers.MapIngredientEntityToResponse(ingredient),
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
Reference in New Issue
Block a user