mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
fix: chickin include stock allocation, fix calculation hpp
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/config"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/database"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -181,6 +183,8 @@ func main() {
|
||||
orphanPopulationRows := int64(0)
|
||||
syncedPopulationQtyRows := int64(0)
|
||||
syncedPopulationUsedRows := int64(0)
|
||||
traceReleasedRows := int64(0)
|
||||
traceInsertedRows := int64(0)
|
||||
if rowsOrphan, rowsQty, rowsUsed, err := resyncProjectFlockPopulation(ctx, db, projectFlockKandangID); err != nil {
|
||||
fmt.Printf("FAIL population_resync project_flock_kandang_id=%d error=%v\n", projectFlockKandangID, err)
|
||||
failedApply++
|
||||
@@ -196,9 +200,22 @@ func main() {
|
||||
)
|
||||
}
|
||||
|
||||
if released, inserted, err := resyncChickinTraceByProjectFlockKandang(ctx, db, fifoStockV2Svc, projectFlockKandangID); err != nil {
|
||||
fmt.Printf("FAIL chickin_trace_resync project_flock_kandang_id=%d error=%v\n", projectFlockKandangID, err)
|
||||
failedApply++
|
||||
} else {
|
||||
traceReleasedRows = released
|
||||
traceInsertedRows = inserted
|
||||
fmt.Printf(
|
||||
"SYNC chickin_trace released=%d inserted=%d\n",
|
||||
traceReleasedRows,
|
||||
traceInsertedRows,
|
||||
)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf(
|
||||
"Summary: planned=%d skipped_pw=%d failed_resolve=%d applied=%d failed_apply=%d population_orphan=%d population_qty_synced=%d population_used_synced=%d\n",
|
||||
"Summary: planned=%d skipped_pw=%d failed_resolve=%d applied=%d failed_apply=%d population_orphan=%d population_qty_synced=%d population_used_synced=%d trace_released=%d trace_inserted=%d\n",
|
||||
len(targets),
|
||||
skippedPW,
|
||||
failedResolve,
|
||||
@@ -207,6 +224,8 @@ func main() {
|
||||
orphanPopulationRows,
|
||||
syncedPopulationQtyRows,
|
||||
syncedPopulationUsedRows,
|
||||
traceReleasedRows,
|
||||
traceInsertedRows,
|
||||
)
|
||||
if failedResolve > 0 || failedApply > 0 {
|
||||
os.Exit(1)
|
||||
@@ -448,6 +467,7 @@ func resyncProjectFlockPopulation(ctx context.Context, db *gorm.DB, projectFlock
|
||||
FROM stock_allocations sa
|
||||
WHERE sa.stockable_type = 'PROJECT_FLOCK_POPULATION'
|
||||
AND sa.status = 'ACTIVE'
|
||||
AND sa.allocation_purpose = 'CONSUME'
|
||||
GROUP BY sa.stockable_id
|
||||
)
|
||||
UPDATE project_flock_populations p
|
||||
@@ -463,3 +483,167 @@ func resyncProjectFlockPopulation(ctx context.Context, db *gorm.DB, projectFlock
|
||||
|
||||
return orphanResult.RowsAffected, qtyResult.RowsAffected, usedResult.RowsAffected, nil
|
||||
}
|
||||
|
||||
func resyncChickinTraceByProjectFlockKandang(
|
||||
ctx context.Context,
|
||||
db *gorm.DB,
|
||||
fifoStockV2Svc commonSvc.FifoStockV2Service,
|
||||
projectFlockKandangID uint,
|
||||
) (int64, int64, error) {
|
||||
if projectFlockKandangID == 0 {
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
var productWarehouseIDs []uint
|
||||
if err := db.WithContext(ctx).
|
||||
Table("project_chickins").
|
||||
Distinct("product_warehouse_id").
|
||||
Where("project_flock_kandang_id = ?", projectFlockKandangID).
|
||||
Where("deleted_at IS NULL").
|
||||
Order("product_warehouse_id ASC").
|
||||
Pluck("product_warehouse_id", &productWarehouseIDs).Error; err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if len(productWarehouseIDs) == 0 {
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
totalReleased := int64(0)
|
||||
totalInserted := int64(0)
|
||||
|
||||
for _, productWarehouseID := range productWarehouseIDs {
|
||||
var releasedRows int64
|
||||
var insertedRows int64
|
||||
|
||||
err := db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
flagGroups, err := resolveFlagGroupsByProductWarehouse(ctx, tx, productWarehouseID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(flagGroups) == 0 {
|
||||
return nil
|
||||
}
|
||||
flagGroupCode := strings.TrimSpace(flagGroups[0])
|
||||
if flagGroupCode == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
released := tx.WithContext(ctx).
|
||||
Table("stock_allocations").
|
||||
Where("product_warehouse_id = ?", productWarehouseID).
|
||||
Where("usable_type = ?", fifo.UsableKeyProjectChickin.String()).
|
||||
Where("allocation_purpose = ?", entity.StockAllocationPurposeTraceChickin).
|
||||
Where("status = ?", entity.StockAllocationStatusActive).
|
||||
Updates(map[string]any{
|
||||
"status": entity.StockAllocationStatusReleased,
|
||||
"released_at": time.Now(),
|
||||
"updated_at": time.Now(),
|
||||
"note": "chickin_trace_reflow_reset",
|
||||
})
|
||||
if released.Error != nil {
|
||||
return released.Error
|
||||
}
|
||||
releasedRows = released.RowsAffected
|
||||
|
||||
type chickinRow struct {
|
||||
ID uint `gorm:"column:id"`
|
||||
UsageQty float64 `gorm:"column:usage_qty"`
|
||||
ChickIn time.Time `gorm:"column:chick_in_date"`
|
||||
}
|
||||
chickins := make([]chickinRow, 0)
|
||||
if err := tx.WithContext(ctx).
|
||||
Table("project_chickins").
|
||||
Select("id, usage_qty, chick_in_date").
|
||||
Where("product_warehouse_id = ?", productWarehouseID).
|
||||
Where("deleted_at IS NULL").
|
||||
Where("usage_qty > 0").
|
||||
Order("chick_in_date ASC, id ASC").
|
||||
Scan(&chickins).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if len(chickins) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
gatherRows, err := fifoStockV2Svc.Gather(ctx, commonSvc.FifoStockV2GatherRequest{
|
||||
FlagGroupCode: flagGroupCode,
|
||||
Lane: "STOCKABLE",
|
||||
AllocationPurpose: entity.StockAllocationPurposeTraceChickin,
|
||||
IgnoreSourceUsed: true,
|
||||
ProductWarehouseID: productWarehouseID,
|
||||
Limit: 50000,
|
||||
Tx: tx,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(gatherRows) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
type lotKey struct {
|
||||
StockableType string
|
||||
StockableID uint
|
||||
}
|
||||
remainingByLot := make(map[lotKey]float64, len(gatherRows))
|
||||
for _, row := range gatherRows {
|
||||
key := lotKey{StockableType: row.Ref.LegacyTypeKey, StockableID: row.Ref.ID}
|
||||
remainingByLot[key] = row.AvailableQuantity
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
lotIndex := 0
|
||||
for _, chickinRow := range chickins {
|
||||
remaining := chickinRow.UsageQty
|
||||
for remaining > 1e-6 && lotIndex < len(gatherRows) {
|
||||
lot := gatherRows[lotIndex]
|
||||
key := lotKey{StockableType: lot.Ref.LegacyTypeKey, StockableID: lot.Ref.ID}
|
||||
available := remainingByLot[key]
|
||||
if available <= 1e-6 {
|
||||
lotIndex++
|
||||
continue
|
||||
}
|
||||
|
||||
portion := math.Min(remaining, available)
|
||||
if portion <= 1e-6 {
|
||||
lotIndex++
|
||||
continue
|
||||
}
|
||||
|
||||
insert := map[string]any{
|
||||
"product_warehouse_id": productWarehouseID,
|
||||
"stockable_type": lot.Ref.LegacyTypeKey,
|
||||
"stockable_id": lot.Ref.ID,
|
||||
"usable_type": fifo.UsableKeyProjectChickin.String(),
|
||||
"usable_id": chickinRow.ID,
|
||||
"qty": portion,
|
||||
"status": entity.StockAllocationStatusActive,
|
||||
"allocation_purpose": entity.StockAllocationPurposeTraceChickin,
|
||||
"engine_version": "v2",
|
||||
"flag_group_code": flagGroupCode,
|
||||
"function_code": "CHICKIN_TRACE",
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}
|
||||
if err := tx.WithContext(ctx).Table("stock_allocations").Create(insert).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
insertedRows++
|
||||
remaining -= portion
|
||||
remainingByLot[key] = available - portion
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return totalReleased, totalInserted, err
|
||||
}
|
||||
|
||||
totalReleased += releasedRows
|
||||
totalInserted += insertedRows
|
||||
}
|
||||
|
||||
return totalReleased, totalInserted, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user