codex/fix: recheck and fix purchase receive failed and farm stock not shown on recording

This commit is contained in:
Adnan Zahir
2026-04-01 11:46:44 +07:00
parent 030284a9b5
commit c4add1501d
7 changed files with 363 additions and 8 deletions
@@ -29,6 +29,7 @@ func (u *ProductWarehouseController) GetAll(c *fiber.Ctx) error {
Limit: c.QueryInt("limit", 10),
ProductId: uint(c.QueryInt("product_id", 0)),
WarehouseId: uint(c.QueryInt("warehouse_id", 0)),
LocationId: uint(c.QueryInt("location_id", 0)),
Flags: c.Query("flags", ""),
KandangId: uint(c.QueryInt("kandang_id", 0)),
TransferContext: c.Query(utils.TransferContextKey, ""),
@@ -0,0 +1,64 @@
package controller
import (
"errors"
"net/http/httptest"
"testing"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
service "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/services"
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/validations"
"gorm.io/gorm"
)
type stubProductWarehouseService struct {
lastQuery *validation.Query
}
func (s *stubProductWarehouseService) GetAll(_ *fiber.Ctx, params *validation.Query) ([]entity.ProductWarehouse, int64, error) {
s.lastQuery = params
return []entity.ProductWarehouse{}, 0, nil
}
func (s *stubProductWarehouseService) GetOne(_ *fiber.Ctx, _ uint) (*entity.ProductWarehouse, error) {
return nil, gorm.ErrRecordNotFound
}
var _ service.ProductWarehouseService = (*stubProductWarehouseService)(nil)
func TestGetAllParsesLocationID(t *testing.T) {
app := fiber.New()
stub := &stubProductWarehouseService{}
ctrl := NewProductWarehouseController(stub)
app.Get("/product-warehouses", ctrl.GetAll)
req := httptest.NewRequest("GET", "/product-warehouses?location_id=16&kandang_id=59&limit=25", nil)
resp, err := app.Test(req)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != fiber.StatusOK {
t.Fatalf("expected status 200, got %d", resp.StatusCode)
}
if stub.lastQuery == nil {
t.Fatalf("expected service to receive query")
}
if stub.lastQuery.LocationId != 16 {
t.Fatalf("expected location_id 16, got %d", stub.lastQuery.LocationId)
}
if stub.lastQuery.KandangId != 59 {
t.Fatalf("expected kandang_id 59, got %d", stub.lastQuery.KandangId)
}
if stub.lastQuery.Limit != 25 {
t.Fatalf("expected limit 25, got %d", stub.lastQuery.Limit)
}
}
func TestStubImplementsServiceContract(t *testing.T) {
validate := validator.New()
if validate == nil {
t.Fatal(errors.New("validator should not be nil"))
}
}
@@ -7,6 +7,7 @@ import (
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
"gorm.io/gorm"
)
@@ -164,10 +165,42 @@ func (r *ProductWarehouseRepositoryImpl) ApplyFlagsFilter(db *gorm.DB, flags []s
return db
}
return db.
fallbackCategoryCodes := utils.LegacyProductCategoryCodesForFlags(flags)
db = db.
Joins("JOIN products p_flag ON p_flag.id = product_warehouses.product_id").
Joins("JOIN flags f_flag ON f_flag.flagable_id = p_flag.id AND f_flag.flagable_type = ?", "products").
Where("f_flag.name IN ?", flags).
Joins("LEFT JOIN product_categories pc_flag ON pc_flag.id = p_flag.product_category_id")
actualFlagFilter := `
EXISTS (
SELECT 1
FROM flags f_flag
WHERE f_flag.flagable_id = p_flag.id
AND f_flag.flagable_type = ?
AND f_flag.name IN ?
)
`
if len(fallbackCategoryCodes) == 0 {
return db.Where(actualFlagFilter, entity.FlagableTypeProduct, flags).Distinct()
}
return db.
Where(
`(`+actualFlagFilter+`) OR (
NOT EXISTS (
SELECT 1
FROM flags f_any
WHERE f_any.flagable_id = p_flag.id
AND f_any.flagable_type = ?
)
AND pc_flag.code IN ?
)`,
entity.FlagableTypeProduct,
flags,
entity.FlagableTypeProduct,
fallbackCategoryCodes,
).
Distinct()
}
@@ -5,6 +5,7 @@ import (
"testing"
"github.com/glebarez/sqlite"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gorm.io/gorm"
)
@@ -115,3 +116,75 @@ func insertProductWarehouseTestFixtures(t *testing.T, db *gorm.DB) {
}
}
}
func TestApplyFlagsFilterIncludesLegacyCategoryFallback(t *testing.T) {
db := setupProductWarehouseFlagFilterTestDB(t)
repo := NewProductWarehouseRepository(db)
ctx := context.Background()
var ids []uint
err := repo.ApplyFlagsFilter(
db.WithContext(ctx).Model(&entity.ProductWarehouse{}),
[]string{"PAKAN"},
).Order("product_warehouses.id").Pluck("product_warehouses.id", &ids).Error
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(ids) != 2 || ids[0] != 1 || ids[1] != 2 {
t.Fatalf("expected flagged and legacy RAW rows to match, got %v", ids)
}
}
func TestApplyFlagsFilterDoesNotFallbackWhenProductAlreadyHasDifferentFlags(t *testing.T) {
db := setupProductWarehouseFlagFilterTestDB(t)
repo := NewProductWarehouseRepository(db)
ctx := context.Background()
var ids []uint
err := repo.ApplyFlagsFilter(
db.WithContext(ctx).Model(&entity.ProductWarehouse{}),
[]string{"PAKAN"},
).Where("product_warehouses.id = ?", 3).Pluck("product_warehouses.id", &ids).Error
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(ids) != 0 {
t.Fatalf("expected OVK-flagged product not to match PAKAN fallback, got %v", ids)
}
}
func setupProductWarehouseFlagFilterTestDB(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 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, warehouse_id INTEGER NOT NULL, project_flock_kandang_id INTEGER NULL, qty NUMERIC(15,3) NOT NULL DEFAULT 0)`,
`INSERT INTO product_categories (id, code) VALUES (1, 'STR'), (2, 'RAW'), (3, 'OBT')`,
`INSERT INTO products (id, product_category_id) VALUES (10, 1), (20, 2), (30, 2), (40, 3)`,
`INSERT INTO flags (id, flagable_id, flagable_type, name) VALUES
(1, 10, 'products', 'PAKAN'),
(2, 10, 'products', 'STARTER'),
(3, 40, 'products', 'OVK'),
(4, 40, 'products', 'OBAT')`,
`INSERT INTO product_warehouses (id, product_id, warehouse_id, project_flock_kandang_id, qty) VALUES
(1, 10, 1, NULL, 10),
(2, 20, 1, NULL, 20),
(3, 40, 1, NULL, 30)`,
}
for _, stmt := range statements {
if err := db.Exec(stmt).Error; err != nil {
t.Fatalf("failed preparing schema: %v", err)
}
}
return db
}