feat(BE): fixing wrong perhitungan biaya

This commit is contained in:
aguhh18
2026-01-09 09:15:53 +07:00
parent 76e65704d7
commit b11f03dfda
5 changed files with 62 additions and 49 deletions
@@ -39,11 +39,12 @@ type TransferExpenseReceivingPayload struct {
}
type groupedTransferItem struct {
detail *entity.StockTransferDetail
payload TransferExpenseReceivingPayload
projectFK *uint
kandangID *uint
totalPrice float64
detail *entity.StockTransferDetail
payload TransferExpenseReceivingPayload
projectFK *uint
kandangID *uint
totalPrice float64
shippingCostTotal float64
}
func groupingKey(supplierID uint, date time.Time, warehouseID uint) string {
@@ -83,7 +84,7 @@ func (b *transferExpenseBridge) OnItemsDeleted(ctx context.Context, _ uint64, it
expenseIDs := make(map[uint64]struct{})
expenseNonstockIDs := make([]uint64, 0)
// Collect expense nonstock IDs from items
for _, item := range items {
if item.ExpenseNonstockId != nil && *item.ExpenseNonstockId != 0 {
expenseNonstockIDs = append(expenseNonstockIDs, *item.ExpenseNonstockId)
@@ -91,7 +92,7 @@ func (b *transferExpenseBridge) OnItemsDeleted(ctx context.Context, _ uint64, it
}
if len(expenseNonstockIDs) > 0 {
// Get expense IDs from expense nonstocks
for _, nsID := range expenseNonstockIDs {
var expenseID uint64
if err := tx.Model(&entity.ExpenseNonstock{}).
@@ -105,13 +106,13 @@ func (b *transferExpenseBridge) OnItemsDeleted(ctx context.Context, _ uint64, it
}
}
// Delete expense nonstocks
if err := tx.Delete(&entity.ExpenseNonstock{}, expenseNonstockIDs).Error; err != nil {
return err
}
}
// Check remaining expense nonstocks for each expense
approvalRepoTx := commonRepo.NewApprovalRepository(tx)
for expenseID := range expenseIDs {
var count int64
@@ -121,7 +122,7 @@ func (b *transferExpenseBridge) OnItemsDeleted(ctx context.Context, _ uint64, it
return err
}
// If no more expense nonstocks, delete expense and approval
if count == 0 {
if err := approvalRepoTx.DeleteByTarget(ctx, utils.ApprovalWorkflowExpense.String(), uint(expenseID)); err != nil {
return err
@@ -208,7 +209,7 @@ func (b *transferExpenseBridge) createExpenseViaService(
id := uint64(*kandangID)
expenseKandangID = &id
} else {
// For transfer, use destination warehouse location
if transfer.ToWarehouse == nil || transfer.ToWarehouse.LocationId == nil || *transfer.ToWarehouse.LocationId == 0 {
return nil, fiber.NewError(fiber.StatusBadRequest, "Destination warehouse location is required for expense")
}
@@ -218,13 +219,16 @@ func (b *transferExpenseBridge) createExpenseViaService(
costItems := make([]expenseValidation.CostItem, 0, len(items))
for _, gi := range items {
note := fmt.Sprintf("stock_transfer_detail:%d", gi.detail.Id)
price := gi.detail.TotalQty
price := gi.shippingCostTotal
if gi.payload.TransportPerItem != nil {
price = *gi.payload.TransportPerItem
price = *gi.payload.TransportPerItem * gi.payload.DeliveredQty
}
costItems = append(costItems, expenseValidation.CostItem{
NonstockID: expeditionNonstockID,
Quantity: gi.payload.DeliveredQty,
Quantity: 1,
Price: price,
Notes: note,
})
@@ -247,7 +251,7 @@ func (b *transferExpenseBridge) createExpenseViaService(
return nil, err
}
// Mark approvals up to Finance so latest is Manager Finance
action := entity.ApprovalActionApproved
actorID := uint(transfer.CreatedBy)
if actorID == 0 {
@@ -324,12 +328,14 @@ func (b *transferExpenseBridge) OnItemsDelivered(c *fiber.Ctx, transferID uint64
ctx := c.Context()
// Load transfer with details
transfer, err := b.transferRepo.GetByID(ctx, uint(transferID), func(db *gorm.DB) *gorm.DB {
return db.
Preload("Details").
Preload("Details.Product").
Preload("Details.DestProductWarehouse").
Preload("Details.DeliveryItems").
Preload("Details.DeliveryItems.StockTransferDelivery").
Preload("ToWarehouse")
})
if err != nil {
@@ -337,8 +343,18 @@ func (b *transferExpenseBridge) OnItemsDelivered(c *fiber.Ctx, transferID uint64
}
detailMap := make(map[uint64]*entity.StockTransferDetail, len(transfer.Details))
shippingCostMap := make(map[uint64]float64) // detailID -> ShippingCostTotal
for i := range transfer.Details {
detailMap[transfer.Details[i].Id] = &transfer.Details[i]
for _, deliveryItem := range transfer.Details[i].DeliveryItems {
if deliveryItem.StockTransferDelivery != nil {
shippingCostMap[transfer.Details[i].Id] = deliveryItem.StockTransferDelivery.ShippingCostTotal
break
}
}
}
groups := make(map[string][]groupedTransferItem)
@@ -379,13 +395,17 @@ func (b *transferExpenseBridge) OnItemsDelivered(c *fiber.Ctx, transferID uint64
}
}
pricePerItem := detail.TotalQty
if payload.TransportPerItem != nil {
pricePerItem = *payload.TransportPerItem
}
totalPrice := pricePerItem * payload.DeliveredQty
shippingCostTotal := shippingCostMap[detail.Id]
totalPrice := shippingCostTotal
if payload.TransportPerItem != nil {
totalPrice = *payload.TransportPerItem * payload.DeliveredQty
}
// Group by supplier:date:warehouse
warehouseID := uint(payload.WarehouseID)
if warehouseID == 0 && transfer.ToWarehouse != nil {
warehouseID = uint(transfer.ToWarehouse.Id)
@@ -396,11 +416,12 @@ func (b *transferExpenseBridge) OnItemsDelivered(c *fiber.Ctx, transferID uint64
key := groupingKey(uint(supplierID), deliveredDate, warehouseID)
groups[key] = append(groups[key], groupedTransferItem{
detail: detail,
payload: payload,
projectFK: projectFK,
kandangID: kandangID,
totalPrice: totalPrice,
detail: detail,
payload: payload,
projectFK: projectFK,
kandangID: kandangID,
totalPrice: totalPrice,
shippingCostTotal: shippingCostTotal,
})
}