mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 21:41:55 +00:00
Merge branch 'development' of https://gitlab.com/mbugroup/lti-api into fix/filter-purchase
This commit is contained in:
@@ -2,12 +2,14 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -45,6 +47,17 @@ func reflowPurchaseScope(
|
||||
AsOf: asOf,
|
||||
Tx: tx,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fifoStockV2Svc.Recalculate(ctx, commonSvc.FifoStockV2RecalculateRequest{
|
||||
ProductWarehouseIDs: []uint{productWarehouseID},
|
||||
FlagGroupCodes: []string{flagGroupCode},
|
||||
AsOf: asOf,
|
||||
FixDrift: true,
|
||||
Tx: tx,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -76,11 +89,53 @@ func resolvePurchaseFlagGroupByProductWarehouse(ctx context.Context, tx *gorm.DB
|
||||
Order("rr.id ASC").
|
||||
Limit(1).
|
||||
Take(&selected).Error
|
||||
if err == nil {
|
||||
return strings.TrimSpace(selected.FlagGroupCode), nil
|
||||
}
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
type categoryRow struct {
|
||||
CategoryCode string `gorm:"column:category_code"`
|
||||
}
|
||||
|
||||
var category categoryRow
|
||||
err = tx.WithContext(ctx).
|
||||
Table("product_warehouses pw").
|
||||
Select("pc.code AS category_code").
|
||||
Joins("JOIN products p ON p.id = pw.product_id").
|
||||
Joins("JOIN product_categories pc ON pc.id = p.product_category_id").
|
||||
Where("pw.id = ?", productWarehouseID).
|
||||
Limit(1).
|
||||
Take(&category).Error
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return strings.TrimSpace(selected.FlagGroupCode), nil
|
||||
flagGroupCode := utils.LegacyFlagGroupCodeByProductCategoryCode(category.CategoryCode)
|
||||
if flagGroupCode == "" {
|
||||
return "", gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
var matched int64
|
||||
err = tx.WithContext(ctx).
|
||||
Table("fifo_stock_v2_route_rules rr").
|
||||
Joins("JOIN fifo_stock_v2_flag_groups fg ON fg.code = rr.flag_group_code AND fg.is_active = TRUE").
|
||||
Where("rr.is_active = TRUE").
|
||||
Where("rr.lane = ?", purchaseStockableLane).
|
||||
Where("rr.function_code = ?", purchaseInFunctionCode).
|
||||
Where("rr.source_table = ?", purchaseSourceTable).
|
||||
Where("rr.flag_group_code = ?", flagGroupCode).
|
||||
Count(&matched).Error
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if matched == 0 {
|
||||
return "", gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
return flagGroupCode, nil
|
||||
}
|
||||
|
||||
func assignEarliestAsOf(m map[uint]time.Time, productWarehouseID uint, asOf time.Time) {
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestResolvePurchaseFlagGroupByProductWarehouseFallsBackToProductCategory(t *testing.T) {
|
||||
db := setupPurchaseFifoHelperTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
flagGroupCode, err := resolvePurchaseFlagGroupByProductWarehouse(ctx, db, 1115)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if flagGroupCode != "PAKAN" {
|
||||
t.Fatalf("expected PAKAN, got %s", flagGroupCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePurchaseFlagGroupByProductWarehouseUsesProductFlagsWhenPresent(t *testing.T) {
|
||||
db := setupPurchaseFifoHelperTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
flagGroupCode, err := resolvePurchaseFlagGroupByProductWarehouse(ctx, db, 2222)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if flagGroupCode != "OVK" {
|
||||
t.Fatalf("expected OVK, got %s", flagGroupCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflowPurchaseScopeRunsRecalculateToFixWarehouseDrift(t *testing.T) {
|
||||
db := setupPurchaseFifoHelperTestDB(t)
|
||||
ctx := context.Background()
|
||||
fifo := &purchaseFifoStub{}
|
||||
|
||||
if err := reflowPurchaseScope(ctx, fifo, db, 1115, nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(fifo.reflowReqs) != 1 {
|
||||
t.Fatalf("expected 1 reflow request, got %d", len(fifo.reflowReqs))
|
||||
}
|
||||
reflowReq := fifo.reflowReqs[0]
|
||||
if reflowReq.ProductWarehouseID != 1115 {
|
||||
t.Fatalf("expected reflow product warehouse 1115, got %d", reflowReq.ProductWarehouseID)
|
||||
}
|
||||
if reflowReq.FlagGroupCode != "PAKAN" {
|
||||
t.Fatalf("expected reflow flag group PAKAN, got %s", reflowReq.FlagGroupCode)
|
||||
}
|
||||
|
||||
if len(fifo.recalculateReqs) != 1 {
|
||||
t.Fatalf("expected 1 recalculate request, got %d", len(fifo.recalculateReqs))
|
||||
}
|
||||
recalculateReq := fifo.recalculateReqs[0]
|
||||
if len(recalculateReq.ProductWarehouseIDs) != 1 || recalculateReq.ProductWarehouseIDs[0] != 1115 {
|
||||
t.Fatalf("expected recalculate for warehouse 1115, got %+v", recalculateReq.ProductWarehouseIDs)
|
||||
}
|
||||
if len(recalculateReq.FlagGroupCodes) != 1 || recalculateReq.FlagGroupCodes[0] != "PAKAN" {
|
||||
t.Fatalf("expected recalculate for PAKAN, got %+v", recalculateReq.FlagGroupCodes)
|
||||
}
|
||||
if !recalculateReq.FixDrift {
|
||||
t.Fatalf("expected recalculate FixDrift=true")
|
||||
}
|
||||
}
|
||||
|
||||
type purchaseFifoStub struct {
|
||||
reflowReqs []commonSvc.FifoStockV2ReflowRequest
|
||||
recalculateReqs []commonSvc.FifoStockV2RecalculateRequest
|
||||
}
|
||||
|
||||
func (s *purchaseFifoStub) Gather(context.Context, commonSvc.FifoStockV2GatherRequest) ([]commonSvc.FifoStockV2GatherRow, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *purchaseFifoStub) Allocate(context.Context, commonSvc.FifoStockV2AllocateRequest) (*commonSvc.FifoStockV2AllocateResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *purchaseFifoStub) Rollback(context.Context, commonSvc.FifoStockV2RollbackRequest) (*commonSvc.FifoStockV2RollbackResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *purchaseFifoStub) Reflow(_ context.Context, req commonSvc.FifoStockV2ReflowRequest) (*commonSvc.FifoStockV2ReflowResult, error) {
|
||||
s.reflowReqs = append(s.reflowReqs, req)
|
||||
return &commonSvc.FifoStockV2ReflowResult{}, nil
|
||||
}
|
||||
|
||||
func (s *purchaseFifoStub) Recalculate(_ context.Context, req commonSvc.FifoStockV2RecalculateRequest) (*commonSvc.FifoStockV2RecalculateResult, error) {
|
||||
s.recalculateReqs = append(s.recalculateReqs, req)
|
||||
return &commonSvc.FifoStockV2RecalculateResult{}, nil
|
||||
}
|
||||
|
||||
func setupPurchaseFifoHelperTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
|
||||
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=private"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("failed opening sqlite db: %v", err)
|
||||
}
|
||||
|
||||
statements := []string{
|
||||
`CREATE TABLE fifo_stock_v2_flag_groups (code TEXT PRIMARY KEY, is_active BOOLEAN NOT NULL)`,
|
||||
`CREATE TABLE fifo_stock_v2_flag_members (flag_name TEXT NOT NULL, flag_group_code TEXT NOT NULL, is_active BOOLEAN NOT NULL)`,
|
||||
`CREATE TABLE fifo_stock_v2_route_rules (
|
||||
id INTEGER PRIMARY KEY,
|
||||
flag_group_code TEXT NOT NULL,
|
||||
lane TEXT NOT NULL,
|
||||
function_code TEXT NOT NULL,
|
||||
source_table TEXT NOT NULL,
|
||||
is_active BOOLEAN NOT NULL
|
||||
)`,
|
||||
`CREATE TABLE product_categories (id INTEGER PRIMARY KEY, code TEXT NOT NULL)`,
|
||||
`CREATE TABLE products (id INTEGER PRIMARY KEY, product_category_id INTEGER NOT NULL)`,
|
||||
`CREATE TABLE flags (id INTEGER PRIMARY KEY, flagable_id INTEGER NOT NULL, flagable_type TEXT NOT NULL, name TEXT NOT NULL)`,
|
||||
`CREATE TABLE product_warehouses (id INTEGER PRIMARY KEY, product_id INTEGER NOT NULL)`,
|
||||
`INSERT INTO fifo_stock_v2_flag_groups (code, is_active) VALUES ('PAKAN', TRUE), ('OVK', TRUE)`,
|
||||
`INSERT INTO fifo_stock_v2_flag_members (flag_name, flag_group_code, is_active) VALUES ('PAKAN', 'PAKAN', TRUE), ('OVK', 'OVK', TRUE), ('OBAT', 'OVK', TRUE)`,
|
||||
`INSERT INTO fifo_stock_v2_route_rules (id, flag_group_code, lane, function_code, source_table, is_active) VALUES
|
||||
(1, 'PAKAN', 'STOCKABLE', 'PURCHASE_IN', 'purchase_items', TRUE),
|
||||
(2, 'OVK', 'STOCKABLE', 'PURCHASE_IN', 'purchase_items', TRUE)`,
|
||||
`INSERT INTO product_categories (id, code) VALUES (1, 'RAW'), (2, 'OBT')`,
|
||||
`INSERT INTO products (id, product_category_id) VALUES (37, 1), (112, 2)`,
|
||||
`INSERT INTO flags (id, flagable_id, flagable_type, name) VALUES
|
||||
(1, 112, 'products', 'OVK'),
|
||||
(2, 112, 'products', 'OBAT')`,
|
||||
`INSERT INTO product_warehouses (id, product_id) VALUES (1115, 37), (2222, 112)`,
|
||||
}
|
||||
|
||||
for _, stmt := range statements {
|
||||
if err := db.Exec(stmt).Error; err != nil {
|
||||
t.Fatalf("failed preparing schema: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
Reference in New Issue
Block a user