Add Inventory Report

This commit is contained in:
Aditya Siregar
2025-08-14 00:38:26 +07:00
parent bb9a81c7c1
commit 7adba2c8f5
9 changed files with 177 additions and 85 deletions
+4 -20
View File
@@ -1334,18 +1334,8 @@ type ingredientRecipeData struct {
// prepareIngredientRecipeData prepares ingredient recipe data without making database calls
func (p *OrderProcessorImpl) prepareIngredientRecipeData(ctx context.Context, item *entities.OrderItem, order *entities.Order, payment *entities.Payment) (*ingredientRecipeData, error) {
// Check if the product has ingredients
product, err := p.productRepo.GetByID(ctx, item.ProductID)
if err != nil {
return nil, fmt.Errorf("failed to get product: %w", err)
}
if !product.HasIngredients {
return &ingredientRecipeData{}, nil // Product doesn't have ingredients
}
// Get product recipes based on variant (if any)
var recipes []*entities.ProductRecipe
var err error
if item.ProductVariantID != nil {
recipes, err = p.productRecipeRepo.GetByProductAndVariantID(ctx, item.ProductID, item.ProductVariantID, order.OrganizationID)
} else {
@@ -1363,7 +1353,6 @@ func (p *OrderProcessorImpl) prepareIngredientRecipeData(ctx context.Context, it
var ingredientUpdates []*entities.Ingredient
var movements []*entities.InventoryMovement
// Process each ingredient in the recipe
for _, recipe := range recipes {
ingredientData, err := p.prepareIngredientRecipeItem(ctx, recipe, item, order, payment)
if err != nil {
@@ -1388,20 +1377,15 @@ type ingredientRecipeItem struct {
// prepareIngredientRecipeItem prepares data for a single ingredient recipe without making database calls
func (p *OrderProcessorImpl) prepareIngredientRecipeItem(ctx context.Context, recipe *entities.ProductRecipe, item *entities.OrderItem, order *entities.Order, payment *entities.Payment) (*ingredientRecipeItem, error) {
// Calculate total ingredient quantity needed
totalIngredientQuantity := recipe.Quantity * float64(item.Quantity)
// Get current ingredient details
currentIngredient, err := p.ingredientRepo.GetByID(ctx, recipe.IngredientID, order.OrganizationID)
if err != nil {
return nil, fmt.Errorf("failed to get ingredient: %w", err)
}
// For ingredients, we typically don't track quantity in the ingredient entity itself
// Instead, we create inventory movement records to track consumption
// The ingredient entity remains unchanged, but we track the movement
currentIngredient.Stock -= totalIngredientQuantity
// Prepare movement record
movement := &entities.InventoryMovement{
OrganizationID: order.OrganizationID,
OutletID: order.OutletID,
@@ -1409,8 +1393,8 @@ func (p *OrderProcessorImpl) prepareIngredientRecipeItem(ctx context.Context, re
ItemType: "INGREDIENT",
MovementType: entities.InventoryMovementTypeIngredient,
Quantity: -totalIngredientQuantity,
PreviousQuantity: 0, // We don't track current quantity in ingredient entity
NewQuantity: 0, // We don't track current quantity in ingredient entity
PreviousQuantity: 0,
NewQuantity: 0,
UnitCost: currentIngredient.Cost,
TotalCost: totalIngredientQuantity * currentIngredient.Cost,
ReferenceType: func() *entities.InventoryMovementReferenceType {