fixing filter pw for transfer, add transfer delete

This commit is contained in:
ragilap
2026-03-13 11:22:10 +07:00
parent 9dcccabc6a
commit 29956528e5
16 changed files with 1122 additions and 219 deletions
@@ -32,6 +32,7 @@ func (u *ProductWarehouseController) GetAll(c *fiber.Ctx) error {
Flags: c.Query("flags", ""),
KandangId: uint(c.QueryInt("kandang_id", 0)),
TransferContext: c.Query(utils.TransferContextKey, ""),
StockMode: c.Query("stock_mode", ""),
Type: c.Query("type", ""),
}
@@ -12,10 +12,11 @@ import (
// === DTO Structs ===
type ProductWarehouseRelationDTO struct {
Id uint `json:"id"`
ProductId uint `json:"product_id"`
WarehouseId uint `json:"warehouse_id"`
Quantity float64 `json:"quantity"`
Id uint `json:"id"`
ProductId uint `json:"product_id"`
WarehouseId uint `json:"warehouse_id"`
Quantity float64 `json:"quantity"`
AvailableQty *float64 `json:"available_qty,omitempty"`
}
type ProductWarehouseListDTO struct {
@@ -61,10 +62,11 @@ type ProjectFlockRelationDTO struct {
func ToProductWarehouseRelationDTO(e entity.ProductWarehouse) ProductWarehouseRelationDTO {
return ProductWarehouseRelationDTO{
Id: e.Id,
ProductId: e.ProductId, // Field yang benar dari entity
WarehouseId: e.WarehouseId, // Field yang benar dari entity
Quantity: e.Quantity,
Id: e.Id,
ProductId: e.ProductId, // Field yang benar dari entity
WarehouseId: e.WarehouseId, // Field yang benar dari entity
Quantity: e.Quantity,
AvailableQty: e.AvailableQty,
}
}
@@ -2,6 +2,7 @@ package service
import (
"errors"
"strings"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
@@ -12,6 +13,7 @@ import (
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/validations"
kandangrepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
"gorm.io/gorm"
)
@@ -27,6 +29,8 @@ type productWarehouseService struct {
KandangRepo kandangrepo.KandangRepository
}
const stockModeExcludeChickin = "exclude_chickin"
func NewProductWarehouseService(repo repository.ProductWarehouseRepository, validate *validator.Validate, kandangRepo kandangrepo.KandangRepository) ProductWarehouseService {
return &productWarehouseService{
Log: utils.Log,
@@ -189,6 +193,11 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
s.Log.Errorf("Failed to get productWarehouses: %+v", err)
return nil, 0, err
}
productWarehouses, err = s.applyTransferAvailableQty(c, params, productWarehouses)
if err != nil {
return nil, 0, err
}
return productWarehouses, total, nil
}
@@ -229,3 +238,80 @@ func (s productWarehouseService) GetOne(c *fiber.Ctx, id uint) (*entity.ProductW
}
return productWarehouse, nil
}
func (s productWarehouseService) applyTransferAvailableQty(c *fiber.Ctx, params *validation.Query, rows []entity.ProductWarehouse) ([]entity.ProductWarehouse, error) {
if len(rows) == 0 {
return rows, nil
}
if params == nil ||
params.TransferContext != utils.TransferContextInventoryTransfer ||
params.StockMode != stockModeExcludeChickin {
return rows, nil
}
ayamPWIDs := make([]uint, 0)
for i := range rows {
if isAyamProductByFlags(rows[i].Product.Flags) {
ayamPWIDs = append(ayamPWIDs, rows[i].Id)
}
}
if len(ayamPWIDs) == 0 {
return rows, nil
}
type usageRow struct {
ProductWarehouseID uint `gorm:"column:product_warehouse_id"`
UsedQty float64 `gorm:"column:used_qty"`
}
usageRows := make([]usageRow, 0)
if err := s.Repository.DB().WithContext(c.Context()).
Table("stock_allocations").
Select("product_warehouse_id, COALESCE(SUM(qty), 0) AS used_qty").
Where("product_warehouse_id IN ?", ayamPWIDs).
Where("usable_type = ?", fifo.UsableKeyProjectChickin.String()).
Where("status = ?", entity.StockAllocationStatusActive).
Where("allocation_purpose = ?", entity.StockAllocationPurposeConsume).
Where("deleted_at IS NULL").
Group("product_warehouse_id").
Scan(&usageRows).Error; err != nil {
s.Log.Errorf("Failed to calculate available transfer stock after chickin consumption: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal menghitung stok tersedia untuk transfer")
}
usageMap := make(map[uint]float64, len(usageRows))
for _, row := range usageRows {
usageMap[row.ProductWarehouseID] = row.UsedQty
}
filtered := make([]entity.ProductWarehouse, 0, len(rows))
for i := range rows {
row := rows[i]
if !isAyamProductByFlags(row.Product.Flags) {
filtered = append(filtered, row)
continue
}
available := row.Quantity - usageMap[row.Id]
if available < 0 {
available = 0
}
row.AvailableQty = &available
if available <= 0 {
continue
}
filtered = append(filtered, row)
}
return filtered, nil
}
func isAyamProductByFlags(flags []entity.Flag) bool {
for _, flag := range flags {
if utils.CanonicalFlagType(strings.TrimSpace(flag.Name)) == utils.FlagAyam {
return true
}
}
return false
}
@@ -20,5 +20,6 @@ type Query struct {
Flags string `query:"flags" validate:"omitempty"`
KandangId uint `query:"kandang_id" validate:"omitempty,number,min=1"`
TransferContext string `query:"transfer_context" validate:"omitempty,oneof=inventory_transfer"`
StockMode string `query:"stock_mode" validate:"omitempty,oneof=exclude_chickin"`
Type string `query:"type" validate:"omitempty"`
}