fix
This commit is contained in:
@@ -35,17 +35,17 @@ type OrderServiceImpl struct {
|
||||
tableRepo repository.TableRepositoryInterface
|
||||
orderIngredientTransactionService *OrderIngredientTransactionService
|
||||
orderIngredientTransactionProcessor processor.OrderIngredientTransactionProcessor
|
||||
productIngredientRepo repository.ProductIngredientRepository
|
||||
productRecipeRepo repository.ProductRecipeRepository
|
||||
txManager *repository.TxManager
|
||||
}
|
||||
|
||||
func NewOrderServiceImpl(orderProcessor processor.OrderProcessor, tableRepo repository.TableRepositoryInterface, orderIngredientTransactionService *OrderIngredientTransactionService, orderIngredientTransactionProcessor processor.OrderIngredientTransactionProcessor, productIngredientRepo repository.ProductIngredientRepository, txManager *repository.TxManager) *OrderServiceImpl {
|
||||
func NewOrderServiceImpl(orderProcessor processor.OrderProcessor, tableRepo repository.TableRepositoryInterface, orderIngredientTransactionService *OrderIngredientTransactionService, orderIngredientTransactionProcessor processor.OrderIngredientTransactionProcessor, productRecipeRepo repository.ProductRecipeRepository, txManager *repository.TxManager) *OrderServiceImpl {
|
||||
return &OrderServiceImpl{
|
||||
orderProcessor: orderProcessor,
|
||||
tableRepo: tableRepo,
|
||||
orderIngredientTransactionService: orderIngredientTransactionService,
|
||||
orderIngredientTransactionProcessor: orderIngredientTransactionProcessor,
|
||||
productIngredientRepo: productIngredientRepo,
|
||||
productRecipeRepo: productRecipeRepo,
|
||||
txManager: txManager,
|
||||
}
|
||||
}
|
||||
@@ -112,18 +112,18 @@ func (s *OrderServiceImpl) createIngredientTransactions(ctx context.Context, ord
|
||||
var allTransactions []*contract.CreateOrderIngredientTransactionRequest
|
||||
|
||||
for _, orderItem := range orderItems {
|
||||
// Get product ingredients for this product
|
||||
productIngredients, err := s.productIngredientRepo.GetByProductID(ctx, orderItem.ProductID, organizationID)
|
||||
// Get product recipes for this product
|
||||
productRecipes, err := s.productRecipeRepo.GetByProductID(ctx, orderItem.ProductID, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get product ingredients for product %s: %w", orderItem.ProductID, err)
|
||||
return nil, fmt.Errorf("failed to get product recipes for product %s: %w", orderItem.ProductID, err)
|
||||
}
|
||||
|
||||
if len(productIngredients) == 0 {
|
||||
continue // Skip if no ingredients
|
||||
if len(productRecipes) == 0 {
|
||||
continue // Skip if no recipes
|
||||
}
|
||||
|
||||
// Calculate waste quantities
|
||||
transactions, err := s.calculateWasteQuantities(productIngredients, float64(orderItem.Quantity))
|
||||
transactions, err := s.calculateWasteQuantities(productRecipes, float64(orderItem.Quantity))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to calculate waste quantities for product %s: %w", err)
|
||||
}
|
||||
@@ -646,17 +646,17 @@ func (s *OrderServiceImpl) handleTableReleaseOnVoid(ctx context.Context, orderID
|
||||
|
||||
func (s *OrderServiceImpl) createOrderIngredientTransactions(ctx context.Context, order *models.Order, orderItems []*models.OrderItem) error {
|
||||
for _, orderItem := range orderItems {
|
||||
productIngredients, err := s.productIngredientRepo.GetByProductID(ctx, orderItem.ProductID, order.OrganizationID)
|
||||
productRecipes, err := s.productRecipeRepo.GetByProductID(ctx, orderItem.ProductID, order.OrganizationID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get product ingredients for product %s: %w", orderItem.ProductID, err)
|
||||
return fmt.Errorf("failed to get product recipes for product %s: %w", orderItem.ProductID, err)
|
||||
}
|
||||
|
||||
if len(productIngredients) == 0 {
|
||||
continue // Skip if no ingredients
|
||||
if len(productRecipes) == 0 {
|
||||
continue // Skip if no recipes
|
||||
}
|
||||
|
||||
// Calculate waste quantities using the utility function
|
||||
transactions, err := s.calculateWasteQuantities(productIngredients, float64(orderItem.Quantity))
|
||||
transactions, err := s.calculateWasteQuantities(productRecipes, float64(orderItem.Quantity))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to calculate waste quantities for product %s: %w", orderItem.ProductID, err)
|
||||
}
|
||||
@@ -681,20 +681,20 @@ func (s *OrderServiceImpl) createOrderIngredientTransactions(ctx context.Context
|
||||
return nil
|
||||
}
|
||||
|
||||
// calculateWasteQuantities calculates gross, net, and waste quantities for product ingredients
|
||||
func (s *OrderServiceImpl) calculateWasteQuantities(productIngredients []*entities.ProductIngredient, quantity float64) ([]*contract.CreateOrderIngredientTransactionRequest, error) {
|
||||
if len(productIngredients) == 0 {
|
||||
// calculateWasteQuantities calculates gross, net, and waste quantities for product recipes
|
||||
func (s *OrderServiceImpl) calculateWasteQuantities(productRecipes []*entities.ProductRecipe, quantity float64) ([]*contract.CreateOrderIngredientTransactionRequest, error) {
|
||||
if len(productRecipes) == 0 {
|
||||
return []*contract.CreateOrderIngredientTransactionRequest{}, nil
|
||||
}
|
||||
|
||||
transactions := make([]*contract.CreateOrderIngredientTransactionRequest, 0, len(productIngredients))
|
||||
transactions := make([]*contract.CreateOrderIngredientTransactionRequest, 0, len(productRecipes))
|
||||
|
||||
for _, pi := range productIngredients {
|
||||
for _, pr := range productRecipes {
|
||||
// Calculate net quantity (actual quantity needed for the product)
|
||||
netQty := pi.Quantity * quantity
|
||||
netQty := pr.Quantity * quantity
|
||||
|
||||
// Calculate gross quantity (including waste)
|
||||
wasteMultiplier := 1 + (pi.WastePercentage / 100)
|
||||
wasteMultiplier := 1 + (pr.WastePercentage / 100)
|
||||
grossQty := netQty * wasteMultiplier
|
||||
|
||||
// Calculate waste quantity
|
||||
@@ -702,12 +702,12 @@ func (s *OrderServiceImpl) calculateWasteQuantities(productIngredients []*entiti
|
||||
|
||||
// Get unit name from ingredient
|
||||
unitName := "unit" // default
|
||||
if pi.Ingredient != nil && pi.Ingredient.Unit != nil {
|
||||
unitName = pi.Ingredient.Unit.Name
|
||||
if pr.Ingredient != nil && pr.Ingredient.Unit != nil {
|
||||
unitName = pr.Ingredient.Unit.Name
|
||||
}
|
||||
|
||||
transaction := &contract.CreateOrderIngredientTransactionRequest{
|
||||
IngredientID: pi.IngredientID,
|
||||
IngredientID: pr.IngredientID,
|
||||
GrossQty: util.RoundToDecimalPlaces(grossQty, 3),
|
||||
NetQty: util.RoundToDecimalPlaces(netQty, 3),
|
||||
WasteQty: util.RoundToDecimalPlaces(wasteQty, 3),
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type ProductRecipeService interface {
|
||||
Create(ctx context.Context, organizationID uuid.UUID, req *models.CreateProductRecipeRequest) (*models.ProductRecipeResponse, error)
|
||||
GetByID(ctx context.Context, id uuid.UUID, organizationID uuid.UUID) (*models.ProductRecipeResponse, error)
|
||||
GetByProductID(ctx context.Context, productID uuid.UUID, organizationID uuid.UUID) ([]*models.ProductRecipeResponse, error)
|
||||
GetByProductAndVariantID(ctx context.Context, productID uuid.UUID, variantID *uuid.UUID, organizationID uuid.UUID) ([]*models.ProductRecipeResponse, error)
|
||||
GetByIngredientID(ctx context.Context, ingredientID uuid.UUID, organizationID uuid.UUID) ([]*models.ProductRecipeResponse, error)
|
||||
Update(ctx context.Context, id uuid.UUID, organizationID uuid.UUID, req *models.UpdateProductRecipeRequest) (*models.ProductRecipeResponse, error)
|
||||
Create(ctx context.Context, organizationID uuid.UUID, req *contract.CreateProductRecipeRequest) (*contract.ProductRecipeResponse, error)
|
||||
GetByID(ctx context.Context, id uuid.UUID, organizationID uuid.UUID) (*contract.ProductRecipeResponse, error)
|
||||
GetByProductID(ctx context.Context, req *contract.GetProductRecipeByProductIDRequest, organizationID uuid.UUID) ([]*contract.ProductRecipeResponse, error)
|
||||
GetByIngredientID(ctx context.Context, ingredientID uuid.UUID, organizationID uuid.UUID) ([]*contract.ProductRecipeResponse, error)
|
||||
Update(ctx context.Context, id uuid.UUID, organizationID uuid.UUID, req *contract.UpdateProductRecipeRequest) (*contract.ProductRecipeResponse, error)
|
||||
Delete(ctx context.Context, id uuid.UUID, organizationID uuid.UUID) error
|
||||
BulkCreate(ctx context.Context, organizationID uuid.UUID, recipes []models.CreateProductRecipeRequest) ([]*models.ProductRecipeResponse, error)
|
||||
BulkCreate(ctx context.Context, organizationID uuid.UUID, req *contract.BulkCreateProductRecipeRequest) ([]*contract.ProductRecipeResponse, error)
|
||||
}
|
||||
|
||||
type ProductRecipeServiceImpl struct {
|
||||
@@ -29,34 +29,86 @@ func NewProductRecipeService(processor processor.ProductRecipeProcessor) *Produc
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) Create(ctx context.Context, organizationID uuid.UUID, req *models.CreateProductRecipeRequest) (*models.ProductRecipeResponse, error) {
|
||||
func (s *ProductRecipeServiceImpl) Create(ctx context.Context, organizationID uuid.UUID, req *contract.CreateProductRecipeRequest) (*contract.ProductRecipeResponse, error) {
|
||||
// Validate request
|
||||
if req == nil {
|
||||
return nil, fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
// Call processor to handle business logic
|
||||
return s.processor.Create(ctx, req, organizationID)
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) GetByID(ctx context.Context, id uuid.UUID, organizationID uuid.UUID) (*models.ProductRecipeResponse, error) {
|
||||
func (s *ProductRecipeServiceImpl) GetByID(ctx context.Context, id uuid.UUID, organizationID uuid.UUID) (*contract.ProductRecipeResponse, error) {
|
||||
// Validate ID
|
||||
if id == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid recipe ID")
|
||||
}
|
||||
|
||||
return s.processor.GetByID(ctx, id, organizationID)
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) GetByProductID(ctx context.Context, productID uuid.UUID, organizationID uuid.UUID) ([]*models.ProductRecipeResponse, error) {
|
||||
return s.processor.GetByProductID(ctx, productID, organizationID)
|
||||
func (s *ProductRecipeServiceImpl) GetByProductID(ctx context.Context, req *contract.GetProductRecipeByProductIDRequest, organizationID uuid.UUID) ([]*contract.ProductRecipeResponse, error) {
|
||||
// Validate request
|
||||
if req == nil {
|
||||
return nil, fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
// Validate product ID
|
||||
if req.ProductID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid product ID")
|
||||
}
|
||||
|
||||
// If variant ID is provided, get by product and variant
|
||||
if req.VariantID != nil {
|
||||
return s.processor.GetByProductAndVariantID(ctx, req.ProductID, req.VariantID, organizationID)
|
||||
}
|
||||
|
||||
// Otherwise get by product ID only
|
||||
return s.processor.GetByProductID(ctx, req.ProductID, organizationID)
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) GetByProductAndVariantID(ctx context.Context, productID uuid.UUID, variantID *uuid.UUID, organizationID uuid.UUID) ([]*models.ProductRecipeResponse, error) {
|
||||
return s.processor.GetByProductAndVariantID(ctx, productID, variantID, organizationID)
|
||||
}
|
||||
func (s *ProductRecipeServiceImpl) GetByIngredientID(ctx context.Context, ingredientID uuid.UUID, organizationID uuid.UUID) ([]*contract.ProductRecipeResponse, error) {
|
||||
// Validate ingredient ID
|
||||
if ingredientID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid ingredient ID")
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) GetByIngredientID(ctx context.Context, ingredientID uuid.UUID, organizationID uuid.UUID) ([]*models.ProductRecipeResponse, error) {
|
||||
return s.processor.GetByIngredientID(ctx, ingredientID, organizationID)
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) Update(ctx context.Context, id uuid.UUID, organizationID uuid.UUID, req *models.UpdateProductRecipeRequest) (*models.ProductRecipeResponse, error) {
|
||||
func (s *ProductRecipeServiceImpl) Update(ctx context.Context, id uuid.UUID, organizationID uuid.UUID, req *contract.UpdateProductRecipeRequest) (*contract.ProductRecipeResponse, error) {
|
||||
// Validate ID
|
||||
if id == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid recipe ID")
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if req == nil {
|
||||
return nil, fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
return s.processor.Update(ctx, id, req, organizationID)
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) Delete(ctx context.Context, id uuid.UUID, organizationID uuid.UUID) error {
|
||||
// Validate ID
|
||||
if id == uuid.Nil {
|
||||
return fmt.Errorf("invalid recipe ID")
|
||||
}
|
||||
|
||||
return s.processor.Delete(ctx, id, organizationID)
|
||||
}
|
||||
|
||||
func (s *ProductRecipeServiceImpl) BulkCreate(ctx context.Context, organizationID uuid.UUID, recipes []models.CreateProductRecipeRequest) ([]*models.ProductRecipeResponse, error) {
|
||||
return s.processor.BulkCreate(ctx, recipes, organizationID)
|
||||
}
|
||||
func (s *ProductRecipeServiceImpl) BulkCreate(ctx context.Context, organizationID uuid.UUID, req *contract.BulkCreateProductRecipeRequest) ([]*contract.ProductRecipeResponse, error) {
|
||||
// Validate request
|
||||
if req == nil {
|
||||
return nil, fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if len(req.Recipes) == 0 {
|
||||
return nil, fmt.Errorf("at least one recipe is required")
|
||||
}
|
||||
|
||||
return s.processor.BulkCreate(ctx, req.Recipes, organizationID)
|
||||
}
|
||||
@@ -34,7 +34,11 @@ func NewPurchaseOrderService(purchaseOrderProcessor processor.PurchaseOrderProce
|
||||
}
|
||||
|
||||
func (s *PurchaseOrderServiceImpl) CreatePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreatePurchaseOrderRequest) *contract.Response {
|
||||
modelReq := transformer.CreatePurchaseOrderRequestToModel(req)
|
||||
modelReq, err := transformer.CreatePurchaseOrderRequestToModel(req)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.PurchaseOrderServiceEntity, "Invalid date format. Use YYYY-MM-DD format")
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
poResponse, err := s.purchaseOrderProcessor.CreatePurchaseOrder(ctx, apctx.OrganizationID, modelReq)
|
||||
if err != nil {
|
||||
@@ -47,7 +51,11 @@ func (s *PurchaseOrderServiceImpl) CreatePurchaseOrder(ctx context.Context, apct
|
||||
}
|
||||
|
||||
func (s *PurchaseOrderServiceImpl) UpdatePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID, req *contract.UpdatePurchaseOrderRequest) *contract.Response {
|
||||
modelReq := transformer.UpdatePurchaseOrderRequestToModel(req)
|
||||
modelReq, err := transformer.UpdatePurchaseOrderRequestToModel(req)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.PurchaseOrderServiceEntity, "Invalid date format. Use YYYY-MM-DD format")
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
poResponse, err := s.purchaseOrderProcessor.UpdatePurchaseOrder(ctx, id, apctx.OrganizationID, modelReq)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user