mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Feat[BE]: integrate FIFO service for chickin stock management
This commit is contained in:
@@ -2,6 +2,7 @@ package chickins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
||||
|
||||
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||
rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||
@@ -36,16 +38,44 @@ func (ChickinModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
||||
projectflockpopulationrepo := rProjectFlock.NewProjectFlockPopulationRepository(db)
|
||||
projectFlockRepo := rProjectFlock.NewProjectflockRepository(db)
|
||||
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
||||
stockAllocationRepo := commonRepo.NewStockAllocationRepository(db)
|
||||
|
||||
userRepo := rUser.NewUserRepository(db)
|
||||
|
||||
fifoService := commonSvc.NewFifoService(db, stockAllocationRepo, productWarehouseRepo, utils.Log)
|
||||
if err := fifoService.RegisterUsable(fifo.UsableConfig{
|
||||
Key: fifo.UsablekeyProjectChickin,
|
||||
Table: "project_chickins",
|
||||
Columns: fifo.UsableColumns{
|
||||
ID: "id",
|
||||
ProductWarehouseID: "product_warehouse_id",
|
||||
UsageQuantity: "usage_qty",
|
||||
PendingQuantity: "pending_usage_qty",
|
||||
CreatedAt: "id",
|
||||
},
|
||||
}); err != nil {
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "already registered") {
|
||||
panic(fmt.Sprintf("failed to register chickin usable workflow: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||
approvalService := commonSvc.NewApprovalService(approvalRepo)
|
||||
if err := approvalService.RegisterWorkflowSteps(utils.ApprovalWorkflowChickin, utils.ChickinApprovalSteps); err != nil {
|
||||
panic(fmt.Sprintf("failed to register chickin approval workflow: %v", err))
|
||||
}
|
||||
|
||||
chickinService := sChickin.NewChickinService(chickinRepo, kandangRepo, warehouseRepo, productWarehouseRepo, projectFlockRepo, projectflockkandangrepo, projectflockpopulationrepo, chickinDetailRepo, validate)
|
||||
chickinService := sChickin.NewChickinService(
|
||||
chickinRepo,
|
||||
kandangRepo,
|
||||
warehouseRepo,
|
||||
productWarehouseRepo,
|
||||
projectFlockRepo,
|
||||
projectflockkandangrepo,
|
||||
projectflockpopulationrepo,
|
||||
chickinDetailRepo,
|
||||
validate,
|
||||
fifoService)
|
||||
userService := sUser.NewUserService(userRepo, validate)
|
||||
|
||||
ChickinRoutes(router, userService, chickinService)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/validations"
|
||||
rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
@@ -23,6 +25,8 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var chickinUsableKey = fifo.UsablekeyProjectChickin
|
||||
|
||||
type ChickinService interface {
|
||||
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectChickin, int64, error)
|
||||
GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectChickin, error)
|
||||
@@ -43,9 +47,10 @@ type chickinService struct {
|
||||
ProjectflockKandangRepo rProjectFlock.ProjectFlockKandangRepository
|
||||
ProjectflockPopulationRepo rProjectFlock.ProjectFlockPopulationRepository
|
||||
ProjectChickinDetailRepo repository.ProjectChickinDetailRepository
|
||||
FifoSvc commonSvc.FifoService
|
||||
}
|
||||
|
||||
func NewChickinService(repo repository.ProjectChickinRepository, kandangRepo KandangRepo.KandangRepository, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, projectFlockRepo rProjectFlock.ProjectflockRepository, projectflockkandangRepo rProjectFlock.ProjectFlockKandangRepository, projectflockpopulationRepo rProjectFlock.ProjectFlockPopulationRepository, projectChickinDetailRepo repository.ProjectChickinDetailRepository, validate *validator.Validate) ChickinService {
|
||||
func NewChickinService(repo repository.ProjectChickinRepository, kandangRepo KandangRepo.KandangRepository, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, projectFlockRepo rProjectFlock.ProjectflockRepository, projectflockkandangRepo rProjectFlock.ProjectFlockKandangRepository, projectflockpopulationRepo rProjectFlock.ProjectFlockPopulationRepository, projectChickinDetailRepo repository.ProjectChickinDetailRepository, validate *validator.Validate, fifoSvc commonSvc.FifoService) ChickinService {
|
||||
return &chickinService{
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
@@ -57,6 +62,7 @@ func NewChickinService(repo repository.ProjectChickinRepository, kandangRepo Kan
|
||||
ProjectflockKandangRepo: projectflockkandangRepo,
|
||||
ProjectflockPopulationRepo: projectflockpopulationRepo,
|
||||
ProjectChickinDetailRepo: projectChickinDetailRepo,
|
||||
FifoSvc: fifoSvc,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,8 +130,6 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Warehouse for Kandang not found")
|
||||
}
|
||||
|
||||
category := strings.ToUpper(strings.TrimSpace(projectFlockKandang.ProjectFlock.Category))
|
||||
|
||||
actorID, err := m.ActorIDFromContext(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -152,20 +156,16 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Invalid ChickInDate format for product warehouse %d", chickinReq.ProductWarehouseId))
|
||||
}
|
||||
|
||||
availableQty, err := s.calculateAvailableQuantity(c, req.ProjectFlockKandangId, productWarehouse, category)
|
||||
if err != nil {
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to calculate available quantity for product warehouse %d", chickinReq.ProductWarehouseId))
|
||||
}
|
||||
|
||||
availableQty := productWarehouse.Quantity
|
||||
if availableQty <= 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("No available quantity for product warehouse %d", chickinReq.ProductWarehouseId))
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("No available stock in product warehouse %d for chickin", chickinReq.ProductWarehouseId))
|
||||
}
|
||||
|
||||
newChickin := &entity.ProjectChickin{
|
||||
ProjectFlockKandangId: req.ProjectFlockKandangId,
|
||||
ChickInDate: chickinDate,
|
||||
UsageQty: 0,
|
||||
PendingUsageQty: availableQty,
|
||||
UsageQty: availableQty,
|
||||
PendingUsageQty: 0,
|
||||
ProductWarehouseId: chickinReq.ProductWarehouseId,
|
||||
Notes: chickinReq.Note,
|
||||
CreatedBy: actorID,
|
||||
@@ -193,6 +193,25 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
|
||||
}
|
||||
|
||||
for _, chickin := range newChikins {
|
||||
if err := s.ConsumeChickinStocks(c.Context(), dbTransaction, chickin); err != nil {
|
||||
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)
|
||||
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)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get latest approval")
|
||||
@@ -287,6 +306,27 @@ func (s chickinService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint)
|
||||
|
||||
func (s chickinService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
|
||||
chickin, err := s.Repository.GetByID(c.Context(), id, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, "Chickin not found")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if chickin.UsageQty > 0 {
|
||||
if err := s.ReleaseChickinStocks(c.Context(), s.Repository.DB(), chickin); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
warehouseDeltas := make(map[uint]float64)
|
||||
warehouseDeltas[chickin.ProductWarehouseId] += chickin.UsageQty
|
||||
if err := s.adjustProductWarehouseQuantities(c.Context(), s.Repository.DB(), warehouseDeltas); err != nil {
|
||||
s.Log.Errorf("Failed to adjust product warehouses for deleted chickin %d: %+v", chickin.Id, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, "Chickin not found")
|
||||
@@ -297,54 +337,6 @@ func (s chickinService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s chickinService) calculateAvailableQuantity(ctx *fiber.Ctx, projectFlockKandangID uint, productWarehouse *entity.ProductWarehouse, category string) (float64, error) {
|
||||
availableQty := productWarehouse.Quantity
|
||||
|
||||
if category == string(utils.ProjectFlockCategoryGrowing) {
|
||||
var totalPendingQty float64
|
||||
|
||||
chickins, err := s.Repository.GetByProjectFlockKandangID(ctx.Context(), projectFlockKandangID)
|
||||
if err == nil {
|
||||
for _, chickin := range chickins {
|
||||
|
||||
if chickin.ProductWarehouseId == productWarehouse.Id && chickin.DeletedAt.Time.IsZero() && chickin.PendingUsageQty > 0 {
|
||||
totalPendingQty += chickin.PendingUsageQty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
availableQty = productWarehouse.Quantity - totalPendingQty
|
||||
if availableQty < 0 {
|
||||
availableQty = 0
|
||||
}
|
||||
} else if category == string(utils.ProjectFlockCategoryLaying) {
|
||||
var totalPopulation float64
|
||||
var totalPendingQty float64
|
||||
|
||||
populations, err := s.ProjectflockPopulationRepo.GetByProjectFlockKandangIDAndProductWarehouseID(ctx.Context(), projectFlockKandangID, productWarehouse.Id)
|
||||
if err == nil {
|
||||
for _, pop := range populations {
|
||||
totalPopulation += pop.TotalQty
|
||||
}
|
||||
}
|
||||
chickins, err := s.Repository.GetByProjectFlockKandangID(ctx.Context(), projectFlockKandangID)
|
||||
if err == nil {
|
||||
for _, chickin := range chickins {
|
||||
|
||||
if chickin.ProductWarehouseId == productWarehouse.Id && chickin.DeletedAt.Time.IsZero() && chickin.PendingUsageQty > 0 {
|
||||
totalPendingQty += chickin.PendingUsageQty
|
||||
}
|
||||
}
|
||||
}
|
||||
availableQty = productWarehouse.Quantity - totalPopulation - totalPendingQty
|
||||
if availableQty < 0 {
|
||||
availableQty = 0
|
||||
}
|
||||
}
|
||||
|
||||
return availableQty, nil
|
||||
}
|
||||
|
||||
func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entity.ProjectChickin, error) {
|
||||
if err := s.Validate.Struct(req); err != nil {
|
||||
return nil, err
|
||||
@@ -373,11 +365,10 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
||||
}
|
||||
|
||||
for _, id := range approvableIDs {
|
||||
idCopy := id
|
||||
if err := commonSvc.EnsureRelations(c.Context(), commonSvc.RelationCheck{Name: "ProjectFlockKandang", ID: &idCopy, Exists: s.ProjectflockKandangRepo.IdExists}); err != nil {
|
||||
|
||||
if err := commonSvc.EnsureRelations(c.Context(), commonSvc.RelationCheck{Name: "ProjectFlockKandang", ID: &id, Exists: s.ProjectflockKandangRepo.IdExists}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
latestApproval, err := approvalSvc.LatestByTarget(c.Context(), utils.ApprovalWorkflowChickin, id, nil)
|
||||
|
||||
if err != nil {
|
||||
@@ -400,7 +391,6 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
||||
|
||||
approvalSvc := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||
chickinRepoTx := repository.NewChickinRepository(dbTransaction)
|
||||
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
|
||||
for _, approvableID := range approvableIDs {
|
||||
if _, err := approvalSvc.CreateApproval(
|
||||
@@ -477,27 +467,17 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
||||
continue
|
||||
}
|
||||
|
||||
kandangForRejection, err := s.ProjectflockKandangRepo.GetByID(c.Context(), approvableID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
|
||||
}
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get ProjectFlockKandang")
|
||||
}
|
||||
|
||||
categoryForRejection := strings.ToUpper(strings.TrimSpace(kandangForRejection.ProjectFlock.Category))
|
||||
|
||||
for _, chickin := range chickins {
|
||||
|
||||
if categoryForRejection == string(utils.ProjectFlockCategoryGrowing) {
|
||||
updates := map[string]any{"qty": gorm.Expr("qty + ?", chickin.PendingUsageQty)}
|
||||
if err := s.ReleaseChickinStocks(c.Context(), dbTransaction, &chickin); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to release stock for rejected chickin %d: %v", chickin.Id, err))
|
||||
}
|
||||
|
||||
if err := productWarehouseTx.PatchOne(c.Context(), chickin.ProductWarehouseId, updates, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Product warehouse %d not found during rejection", chickin.ProductWarehouseId))
|
||||
}
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to restore product warehouse quantity for chickin %d", chickin.Id))
|
||||
}
|
||||
warehouseDeltas := make(map[uint]float64)
|
||||
warehouseDeltas[chickin.ProductWarehouseId] += chickin.UsageQty
|
||||
if err := s.adjustProductWarehouseQuantities(c.Context(), dbTransaction, warehouseDeltas); err != nil {
|
||||
s.Log.Errorf("Failed to adjust product warehouses for rejected chickin %d: %+v", chickin.Id, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := chickinRepoTx.DeleteOne(c.Context(), chickin.Id); err != nil {
|
||||
@@ -558,7 +538,6 @@ func (s *chickinService) getOrCreateProductWarehouse(ctx *fiber.Ctx, warehouseId
|
||||
WarehouseId: warehouseId,
|
||||
ProjectFlockKandangId: projectFlockKandangId,
|
||||
Quantity: 0,
|
||||
// CreatedBy: actorID,
|
||||
}
|
||||
|
||||
if err := s.ProductWarehouseRepo.WithTx(dbTransaction).CreateOne(ctx.Context(), newPW, nil); err != nil {
|
||||
@@ -574,10 +553,10 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
||||
return fmt.Errorf("invalid target product warehouse")
|
||||
}
|
||||
|
||||
chickinRepoTx := repository.NewChickinRepository(dbTransaction)
|
||||
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
ProjectFlockPopulationRepotx := s.ProjectflockPopulationRepo.WithTx(dbTransaction)
|
||||
|
||||
var totalQuantityAdded float64
|
||||
|
||||
for _, chickin := range chickins {
|
||||
|
||||
populationExists, err := ProjectFlockPopulationRepotx.ExistsByProjectChickinID(ctx.Context(), chickin.Id)
|
||||
@@ -590,34 +569,7 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
||||
continue
|
||||
}
|
||||
|
||||
quantityToConvert := chickin.PendingUsageQty
|
||||
|
||||
if err := chickinRepoTx.PatchOne(ctx.Context(), chickin.Id, map[string]any{
|
||||
"usage_qty": quantityToConvert,
|
||||
"pending_usage_qty": 0,
|
||||
}, nil); err != nil {
|
||||
return fmt.Errorf("failed to update chickin %d qty: %w", chickin.Id, err)
|
||||
}
|
||||
|
||||
if chickin.ProductWarehouseId != targetPW.Id {
|
||||
if err := productWarehouseTx.PatchOne(ctx.Context(), chickin.ProductWarehouseId, map[string]any{
|
||||
"qty": gorm.Expr("qty - ?", quantityToConvert),
|
||||
}, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Source product warehouse %d not found", chickin.ProductWarehouseId))
|
||||
}
|
||||
return fmt.Errorf("failed to deduct source warehouse quantity for chickin %d: %w", chickin.Id, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := productWarehouseTx.PatchOne(ctx.Context(), targetPW.Id, map[string]any{
|
||||
"qty": gorm.Expr("qty + ?", quantityToConvert),
|
||||
}, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Target product warehouse %d not found", targetPW.Id))
|
||||
}
|
||||
return fmt.Errorf("failed to update target warehouse quantity: %w", err)
|
||||
}
|
||||
quantityToConvert := chickin.UsageQty
|
||||
|
||||
population := &entity.ProjectFlockPopulation{
|
||||
ProjectChickinId: chickin.Id,
|
||||
@@ -630,7 +582,80 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
||||
if err := ProjectFlockPopulationRepotx.CreateOne(ctx.Context(), population, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
totalQuantityAdded += quantityToConvert
|
||||
}
|
||||
|
||||
if totalQuantityAdded > 0 {
|
||||
if err := s.ProductWarehouseRepo.AdjustQuantities(ctx.Context(), map[uint]float64{
|
||||
targetPW.Id: totalQuantityAdded,
|
||||
}, func(db *gorm.DB) *gorm.DB {
|
||||
return dbTransaction
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to update target product warehouse quantity: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *chickinService) ConsumeChickinStocks(ctx context.Context, tx *gorm.DB, chickin *entity.ProjectChickin) error {
|
||||
if chickin == nil || s.FifoSvc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var desired float64 = chickin.UsageQty
|
||||
|
||||
result, err := s.FifoSvc.Consume(ctx, commonSvc.StockConsumeRequest{
|
||||
UsableKey: chickinUsableKey,
|
||||
UsableID: chickin.Id,
|
||||
ProductWarehouseID: chickin.ProductWarehouseId,
|
||||
Quantity: desired,
|
||||
AllowPending: false,
|
||||
Tx: tx,
|
||||
})
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to consume FIFO stock for chickin %d: %+v", chickin.Id, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Model(&entity.ProjectChickin{}).Where("id = ?", chickin.Id).Updates(map[string]interface{}{
|
||||
"usage_qty": result.UsageQuantity,
|
||||
"pending_usage_qty": result.PendingQuantity,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *chickinService) ReleaseChickinStocks(ctx context.Context, tx *gorm.DB, chickin *entity.ProjectChickin) error {
|
||||
if chickin == nil || s.FifoSvc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.FifoSvc.ReleaseUsage(ctx, commonSvc.StockReleaseRequest{
|
||||
UsableKey: chickinUsableKey,
|
||||
UsableID: chickin.Id,
|
||||
Tx: tx,
|
||||
}); err != nil {
|
||||
s.Log.Errorf("Failed to release FIFO stock for chickin %d: %+v", chickin.Id, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Model(&entity.ProjectChickin{}).Where("id = ?", chickin.Id).Updates(map[string]interface{}{
|
||||
"usage_qty": 0,
|
||||
"pending_usage_qty": 0,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *chickinService) adjustProductWarehouseQuantities(ctx context.Context, tx *gorm.DB, deltas map[uint]float64) error {
|
||||
if len(deltas) == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.ProductWarehouseRepo.AdjustQuantities(ctx, deltas, func(*gorm.DB) *gorm.DB { return tx })
|
||||
}
|
||||
|
||||
@@ -2,4 +2,5 @@ package fifo
|
||||
|
||||
const (
|
||||
UsableKeyRecordingStock UsableKey = "RECORDING_STOCK"
|
||||
UsablekeyProjectChickin UsableKey = "PROJECT_CHICKIN"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user