From dbc143954ce26fefa596e4852742c7b05f08ca44 Mon Sep 17 00:00:00 2001 From: efrilm Date: Tue, 11 Aug 2026 21:24:24 +0700 Subject: [PATCH] feat(purchase): unwired unit convertions --- .../processor/purchase_order_processor.go | 75 ++----------------- 1 file changed, 8 insertions(+), 67 deletions(-) diff --git a/internal/processor/purchase_order_processor.go b/internal/processor/purchase_order_processor.go index 945745a..867f833 100644 --- a/internal/processor/purchase_order_processor.go +++ b/internal/processor/purchase_order_processor.go @@ -32,6 +32,9 @@ type PurchaseOrderProcessorImpl struct { categoryRepo CategoryRepository unitRepo UnitRepository fileRepo FileRepository + // Kept wired but currently unused: purchase orders are a record of spending + // only, so nothing here moves stock or converts units. These stay so that + // tying purchases back to inventory is a change in one place. inventoryMovementService InventoryMovementService unitConverterRepo IngredientUnitConverterRepository } @@ -438,73 +441,11 @@ func (p *PurchaseOrderProcessorImpl) UpdatePurchaseOrderStatus(ctx context.Conte fmt.Println("status:", po.Status) - // Check if status is changing to "received" and current status is not "received" - if status == "received" && po.Status != "received" { - // Get purchase order with items for inventory update - poWithItems, err := p.purchaseOrderRepo.GetByID(ctx, id) - if err != nil { - return nil, fmt.Errorf("failed to get purchase order with items: %w", err) - } - - // Update inventory for each item - for _, item := range poWithItems.Items { - if item.PurchaseCategory != nil && item.PurchaseCategory.Type == entities.PurchaseCategoryTypeExpense { - continue - } - - if item.IngredientID == nil || item.UnitID == nil || item.Quantity == nil { - return nil, fmt.Errorf("purchase order item %s is missing raw material inventory fields", item.ID) - } - - // Get ingredient to find its base unit - ingredient, err := p.ingredientRepo.GetByID(ctx, *item.IngredientID, organizationID) - if err != nil { - return nil, fmt.Errorf("failed to get ingredient %s: %w", *item.IngredientID, err) - } - - // Convert quantity to ingredient's base unit if needed. An ingredient - // without a unit has no base unit to convert into, so the purchased - // quantity is taken as-is. - quantityToAdd := *item.Quantity - if ingredient.UnitID != nil && *item.UnitID != *ingredient.UnitID { - // Convert from purchase unit to ingredient's base unit - convertedQuantity, err := p.unitConverterRepo.ConvertQuantity(ctx, *item.IngredientID, *item.UnitID, *ingredient.UnitID, organizationID, *item.Quantity) - if err != nil { - return nil, fmt.Errorf("failed to convert quantity for ingredient %s from unit %s to %s: %w", *item.IngredientID, *item.UnitID, *ingredient.UnitID, err) - } - quantityToAdd = convertedQuantity - } - - // Calculate unit cost in ingredient's base unit - unitCost := 0.0 - if quantityToAdd > 0 { - unitCost = calculatePurchaseOrderItemTotal(item.Quantity, item.Amount) / quantityToAdd - } - - // Create inventory movement for ingredient purchase - reason := fmt.Sprintf("Purchase order %s received", po.PONumber) - referenceType := entities.InventoryMovementReferenceTypePurchaseOrder - referenceID := &id - - err = p.inventoryMovementService.CreateIngredientMovement( - ctx, - *item.IngredientID, - organizationID, - outletID, - userID, - entities.InventoryMovementTypePurchase, - quantityToAdd, - unitCost, - reason, - &referenceType, - referenceID, - &item.ID, - ) - if err != nil { - return nil, fmt.Errorf("failed to create inventory movement for ingredient %s: %w", *item.IngredientID, err) - } - } - } + // A purchase order is a record of spending only. Receiving one does not move + // ingredient stock, does not recalculate ingredient cost, and never converts + // units: the quantity and unit on an item are kept exactly as the user + // entered them. Raw material items are therefore treated the same way expense + // items already were, and the ingredient on an item is just a reference. // Update the purchase order status statusOutletID := po.OutletID