mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-23 14:55:42 +00:00
Feat[BE]: enhance chickin stock management with FIFO service integration and fix key naming inconsistencies
This commit is contained in:
@@ -39,19 +39,19 @@ func (ChickinModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
|||||||
projectFlockRepo := rProjectFlock.NewProjectflockRepository(db)
|
projectFlockRepo := rProjectFlock.NewProjectflockRepository(db)
|
||||||
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
||||||
stockAllocationRepo := commonRepo.NewStockAllocationRepository(db)
|
stockAllocationRepo := commonRepo.NewStockAllocationRepository(db)
|
||||||
|
fifoService := commonSvc.NewFifoService(db, stockAllocationRepo, productWarehouseRepo, utils.Log)
|
||||||
userRepo := rUser.NewUserRepository(db)
|
userRepo := rUser.NewUserRepository(db)
|
||||||
|
|
||||||
fifoService := commonSvc.NewFifoService(db, stockAllocationRepo, productWarehouseRepo, utils.Log)
|
// Register PROJECT_CHICKIN as usable
|
||||||
if err := fifoService.RegisterUsable(fifo.UsableConfig{
|
if err := fifoService.RegisterUsable(fifo.UsableConfig{
|
||||||
Key: fifo.UsablekeyProjectChickin,
|
Key: fifo.UsableKeyProjectChickin,
|
||||||
Table: "project_chickins",
|
Table: "project_chickins",
|
||||||
Columns: fifo.UsableColumns{
|
Columns: fifo.UsableColumns{
|
||||||
ID: "id",
|
ID: "id",
|
||||||
ProductWarehouseID: "product_warehouse_id",
|
ProductWarehouseID: "product_warehouse_id",
|
||||||
UsageQuantity: "usage_qty",
|
UsageQuantity: "usage_qty",
|
||||||
PendingQuantity: "pending_usage_qty",
|
PendingQuantity: "pending_usage_qty",
|
||||||
CreatedAt: "id",
|
CreatedAt: "created_at",
|
||||||
},
|
},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
if !strings.Contains(strings.ToLower(err.Error()), "already registered") {
|
if !strings.Contains(strings.ToLower(err.Error()), "already registered") {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var chickinUsableKey = fifo.UsablekeyProjectChickin
|
var chickinUsableKey = fifo.UsableKeyProjectChickin
|
||||||
|
|
||||||
type ChickinService interface {
|
type ChickinService interface {
|
||||||
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectChickin, int64, error)
|
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectChickin, int64, error)
|
||||||
@@ -135,8 +135,9 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newChikins := make([]*entity.ProjectChickin, 0)
|
newChikins := make([]*entity.ProjectChickin, 0)
|
||||||
|
chickinQtyMap := make(map[uint]float64) // Store desired qty for each chickin index
|
||||||
|
|
||||||
for _, chickinReq := range req.ChickinRequests {
|
for idx, chickinReq := range req.ChickinRequests {
|
||||||
|
|
||||||
productWarehouse, err := s.ProductWarehouseRepo.GetByID(c.Context(), chickinReq.ProductWarehouseId, nil)
|
productWarehouse, err := s.ProductWarehouseRepo.GetByID(c.Context(), chickinReq.ProductWarehouseId, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -164,7 +165,7 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
newChickin := &entity.ProjectChickin{
|
newChickin := &entity.ProjectChickin{
|
||||||
ProjectFlockKandangId: req.ProjectFlockKandangId,
|
ProjectFlockKandangId: req.ProjectFlockKandangId,
|
||||||
ChickInDate: chickinDate,
|
ChickInDate: chickinDate,
|
||||||
UsageQty: availableQty,
|
UsageQty: 0,
|
||||||
PendingUsageQty: 0,
|
PendingUsageQty: 0,
|
||||||
ProductWarehouseId: chickinReq.ProductWarehouseId,
|
ProductWarehouseId: chickinReq.ProductWarehouseId,
|
||||||
Notes: chickinReq.Note,
|
Notes: chickinReq.Note,
|
||||||
@@ -172,6 +173,7 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
newChikins = append(newChikins, newChickin)
|
newChikins = append(newChikins, newChickin)
|
||||||
|
chickinQtyMap[uint(idx)] = availableQty
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(newChikins) == 0 {
|
if len(newChikins) == 0 {
|
||||||
@@ -193,24 +195,14 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, chickin := range newChikins {
|
for idx, chickin := range newChikins {
|
||||||
if err := s.ConsumeChickinStocks(c.Context(), dbTransaction, chickin); err != nil {
|
desiredQty := chickinQtyMap[uint(idx)]
|
||||||
|
if err := s.ConsumeChickinStocks(c.Context(), dbTransaction, chickin, desiredQty); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if chickin.PendingUsageQty > 0 {
|
|
||||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Cannot create chickin %d - insufficient stock. Required: %.0f, Available: %.0f, Pending: %.0f", chickin.Id, chickin.UsageQty+chickin.PendingUsageQty, chickin.UsageQty, chickin.PendingUsageQty))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
warehouseDeltas := make(map[uint]float64)
|
// Note: FIFO Consume already adjusts product warehouse quantities, no need to adjust again
|
||||||
for _, chickin := range newChikins {
|
|
||||||
warehouseDeltas[chickin.ProductWarehouseId] -= chickin.UsageQty
|
|
||||||
}
|
|
||||||
if err := s.adjustProductWarehouseQuantities(c.Context(), dbTransaction, warehouseDeltas); err != nil {
|
|
||||||
s.Log.Errorf("Failed to adjust product warehouses: %+v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
latest, err := approvalSvcTx.LatestByTarget(c.Context(), utils.ApprovalWorkflowChickin, projectFlockKandang.Id, nil)
|
latest, err := approvalSvcTx.LatestByTarget(c.Context(), utils.ApprovalWorkflowChickin, projectFlockKandang.Id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -599,19 +591,20 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *chickinService) ConsumeChickinStocks(ctx context.Context, tx *gorm.DB, chickin *entity.ProjectChickin) error {
|
func (s *chickinService) ConsumeChickinStocks(ctx context.Context, tx *gorm.DB, chickin *entity.ProjectChickin, desiredQty float64) error {
|
||||||
if chickin == nil || s.FifoSvc == nil {
|
if chickin == nil || s.FifoSvc == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var desired float64 = chickin.UsageQty
|
s.Log.Infof("ConsumeChickinStocks: chickin_id=%d, product_warehouse_id=%d, desired_qty=%.3f",
|
||||||
|
chickin.Id, chickin.ProductWarehouseId, desiredQty)
|
||||||
|
|
||||||
result, err := s.FifoSvc.Consume(ctx, commonSvc.StockConsumeRequest{
|
result, err := s.FifoSvc.Consume(ctx, commonSvc.StockConsumeRequest{
|
||||||
UsableKey: chickinUsableKey,
|
UsableKey: chickinUsableKey,
|
||||||
UsableID: chickin.Id,
|
UsableID: chickin.Id,
|
||||||
ProductWarehouseID: chickin.ProductWarehouseId,
|
ProductWarehouseID: chickin.ProductWarehouseId,
|
||||||
Quantity: desired,
|
Quantity: desiredQty,
|
||||||
AllowPending: false,
|
AllowPending: true,
|
||||||
Tx: tx,
|
Tx: tx,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -619,6 +612,9 @@ func (s *chickinService) ConsumeChickinStocks(ctx context.Context, tx *gorm.DB,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.Log.Infof("ConsumeChickinStocks result: usage_qty=%.3f, pending_qty=%.3f, allocated_allocations=%d",
|
||||||
|
result.UsageQuantity, result.PendingQuantity, len(result.AddedAllocations))
|
||||||
|
|
||||||
if err := tx.Model(&entity.ProjectChickin{}).Where("id = ?", chickin.Id).Updates(map[string]interface{}{
|
if err := tx.Model(&entity.ProjectChickin{}).Where("id = ?", chickin.Id).Updates(map[string]interface{}{
|
||||||
"usage_qty": result.UsageQuantity,
|
"usage_qty": result.UsageQuantity,
|
||||||
"pending_usage_qty": result.PendingQuantity,
|
"pending_usage_qty": result.PendingQuantity,
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ import (
|
|||||||
closings "gitlab.com/mbugroup/lti-api.git/internal/modules/closings"
|
closings "gitlab.com/mbugroup/lti-api.git/internal/modules/closings"
|
||||||
constants "gitlab.com/mbugroup/lti-api.git/internal/modules/constants"
|
constants "gitlab.com/mbugroup/lti-api.git/internal/modules/constants"
|
||||||
expenses "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses"
|
expenses "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses"
|
||||||
|
finance "gitlab.com/mbugroup/lti-api.git/internal/modules/finance"
|
||||||
inventory "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory"
|
inventory "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory"
|
||||||
marketing "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing"
|
marketing "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing"
|
||||||
master "gitlab.com/mbugroup/lti-api.git/internal/modules/master"
|
master "gitlab.com/mbugroup/lti-api.git/internal/modules/master"
|
||||||
production "gitlab.com/mbugroup/lti-api.git/internal/modules/production"
|
production "gitlab.com/mbugroup/lti-api.git/internal/modules/production"
|
||||||
purchases "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases"
|
purchases "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases"
|
||||||
|
repports "gitlab.com/mbugroup/lti-api.git/internal/modules/repports"
|
||||||
ssoModule "gitlab.com/mbugroup/lti-api.git/internal/modules/sso"
|
ssoModule "gitlab.com/mbugroup/lti-api.git/internal/modules/sso"
|
||||||
users "gitlab.com/mbugroup/lti-api.git/internal/modules/users"
|
users "gitlab.com/mbugroup/lti-api.git/internal/modules/users"
|
||||||
repports "gitlab.com/mbugroup/lti-api.git/internal/modules/repports"
|
|
||||||
finance "gitlab.com/mbugroup/lti-api.git/internal/modules/finance"
|
|
||||||
// MODULE IMPORTS
|
// MODULE IMPORTS
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,8 +44,8 @@ func Routes(app *fiber.App, db *gorm.DB) {
|
|||||||
expenses.ExpenseModule{},
|
expenses.ExpenseModule{},
|
||||||
ssoModule.Module{},
|
ssoModule.Module{},
|
||||||
closings.ClosingModule{},
|
closings.ClosingModule{},
|
||||||
repports.RepportModule{},
|
repports.RepportModule{},
|
||||||
finance.FinanceModule{},
|
finance.FinanceModule{},
|
||||||
// MODULE REGISTRY
|
// MODULE REGISTRY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ package fifo
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
UsableKeyRecordingStock UsableKey = "RECORDING_STOCK"
|
UsableKeyRecordingStock UsableKey = "RECORDING_STOCK"
|
||||||
UsablekeyProjectChickin UsableKey = "PROJECT_CHICKIN"
|
UsableKeyProjectChickin UsableKey = "PROJECT_CHICKIN"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user