fix: adjusment module depletion, chickin, recording refactor

This commit is contained in:
Hafizh A. Y
2026-02-28 21:35:07 +07:00
parent 944604adad
commit dd61b66af0
11 changed files with 1906 additions and 1343 deletions
@@ -487,16 +487,12 @@ func (s *fifoStockV2Service) Reflow(ctx context.Context, req ReflowRequest) (*Re
continue
}
asOf := usableRow.SortAt
if req.AsOf != nil && asOf.Before(*req.AsOf) {
asOf = *req.AsOf
}
allocateRes, allocateErr := s.allocateInternal(ctx, tx, AllocateRequest{
FlagGroupCode: req.FlagGroupCode,
ProductWarehouseID: req.ProductWarehouseID,
Usable: usableRow.Ref,
NeedQty: desiredQty,
AsOf: &asOf,
AsOf: nil,
})
if allocateErr != nil {
err = allocateErr
@@ -151,19 +151,29 @@ func (s *fifoStockV2Service) buildGatherSubquery(rule routeRule, trait traitRule
usedExpr := "0::numeric"
pendingExpr := "0::numeric"
availableExpr := baseQtyExpr
extraArgs := make([]any, 0, 1)
extraArgs := make([]any, 0, 2)
whereExtraArgs := make([]any, 0, 1)
if req.Lane == LaneStockable {
if rule.UsedQuantityCol != nil && strings.TrimSpace(*rule.UsedQuantityCol) != "" {
usedCol, _ := mustSafeIdentifier(*rule.UsedQuantityCol)
usedExpr = fmt.Sprintf("COALESCE(src.%s,0)::numeric", usedCol)
} else {
// NOTE:
// usedExpr is referenced twice in the generated SELECT:
// 1) as used_quantity
// 2) inside available_quantity = base - usedExpr
// plus once in stockable WHERE clause via availableExpr > 0.
// We split the args because the WHERE placeholder order appears
// after product/flag filter placeholders in the final SQL.
usedExpr = fmt.Sprintf(
"(SELECT COALESCE(SUM(sa.qty),0)::numeric FROM stock_allocations sa WHERE sa.stockable_type = ? AND sa.stockable_id = src.%s AND sa.status = '%s')",
sourceIDCol,
activeAllocationStatus(),
)
extraArgs = append(extraArgs, rule.LegacyTypeKey)
extraArgs = append(extraArgs, rule.LegacyTypeKey)
whereExtraArgs = append(whereExtraArgs, rule.LegacyTypeKey)
}
availableExpr = fmt.Sprintf("(%s - %s)", baseQtyExpr, usedExpr)
} else {
@@ -179,6 +189,12 @@ func (s *fifoStockV2Service) buildGatherSubquery(rule routeRule, trait traitRule
return "", nil, err
}
functionCodeExpr := "?::text"
functionCodeArgs := []any{rule.FunctionCode}
if rule.SourceTable == "adjustment_stocks" {
functionCodeExpr = "COALESCE(NULLIF(src.function_code,''), ?::text)"
}
whereParts := []string{
fmt.Sprintf("src.%s = ?", productWarehouseCol),
fmt.Sprintf(`EXISTS (
@@ -209,7 +225,7 @@ func (s *fifoStockV2Service) buildGatherSubquery(rule routeRule, trait traitRule
SELECT
?::text AS source_table,
?::text AS legacy_type_key,
?::text AS function_code,
%s AS function_code,
src.%s AS source_id,
src.%s AS product_warehouse_id,
%s AS sort_at,
@@ -221,20 +237,21 @@ func (s *fifoStockV2Service) buildGatherSubquery(rule routeRule, trait traitRule
FROM %s src
%s
WHERE %s
`, sourceIDCol, productWarehouseCol, sortExpr, baseQtyExpr, usedExpr, pendingExpr, availableExpr, sourceTable, joinClause, strings.Join(whereParts, " AND "))
`, functionCodeExpr, sourceIDCol, productWarehouseCol, sortExpr, baseQtyExpr, usedExpr, pendingExpr, availableExpr, sourceTable, joinClause, strings.Join(whereParts, " AND "))
args := []any{
rule.SourceTable,
rule.LegacyTypeKey,
rule.FunctionCode,
trait.SortPriority,
}
args = append(args, functionCodeArgs...)
args = append(args, trait.SortPriority)
args = append(args, extraArgs...)
args = append(args,
req.ProductWarehouseID,
entity.FlagableTypeProduct,
req.FlagGroupCode,
)
args = append(args, whereExtraArgs...)
if req.AsOf != nil {
args = append(args, *req.AsOf)