mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
fix: master product and chickin
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
DELETE FROM fifo_stock_v2_flag_members
|
||||||
|
WHERE flag_name = 'AYAM'
|
||||||
|
AND flag_group_code = 'AYAM';
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
INSERT INTO fifo_stock_v2_flag_members(flag_name, flag_group_code, priority, is_active, created_at, updated_at)
|
||||||
|
VALUES
|
||||||
|
('AYAM', 'AYAM', 5, TRUE, NOW(), NOW())
|
||||||
|
ON CONFLICT (flag_name) DO UPDATE
|
||||||
|
SET
|
||||||
|
flag_group_code = EXCLUDED.flag_group_code,
|
||||||
|
priority = EXCLUDED.priority,
|
||||||
|
is_active = TRUE,
|
||||||
|
updated_at = NOW();
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -30,6 +30,14 @@ func (u *ProductController) GetAll(c *fiber.Ctx) error {
|
|||||||
ProductCategoryID: c.QueryInt("product_category_id", 0),
|
ProductCategoryID: c.QueryInt("product_category_id", 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isDepletionParam := c.Query("is_depletion", ""); isDepletionParam != "" {
|
||||||
|
value, err := strconv.ParseBool(isDepletionParam)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid is_depletion value")
|
||||||
|
}
|
||||||
|
query.IsDepletion = &value
|
||||||
|
}
|
||||||
|
|
||||||
if query.Page < 1 || query.Limit < 1 {
|
if query.Page < 1 || query.Limit < 1 {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ type productService struct {
|
|||||||
Repository repository.ProductRepository
|
Repository repository.ProductRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var depletionProductFlags = []string{
|
||||||
|
string(utils.FlagAyamAfkir),
|
||||||
|
string(utils.FlagAyamCulling),
|
||||||
|
string(utils.FlagAyamMati),
|
||||||
|
}
|
||||||
|
|
||||||
func normalizeProductFlags(raw []string) ([]string, error) {
|
func normalizeProductFlags(raw []string) ([]string, error) {
|
||||||
normalized, invalid := utils.NormalizeFlagsForGroup(raw, utils.FlagGroupProduct)
|
normalized, invalid := utils.NormalizeFlagsForGroup(raw, utils.FlagGroupProduct)
|
||||||
if len(invalid) > 0 {
|
if len(invalid) > 0 {
|
||||||
@@ -223,12 +229,32 @@ func (s productService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity
|
|||||||
|
|
||||||
products, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
products, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
db = s.withRelations(db)
|
db = s.withRelations(db)
|
||||||
db = db.Where("is_visible = ?", true)
|
// Depletion master products are system products and often stored with is_visible = false.
|
||||||
|
// When requested explicitly via is_depletion=true, include hidden records.
|
||||||
|
if params.IsDepletion == nil || !*params.IsDepletion {
|
||||||
|
db = db.Where("is_visible = ?", true)
|
||||||
|
}
|
||||||
if params.Search != "" {
|
if params.Search != "" {
|
||||||
return db.Where("name ILIKE ?", "%"+params.Search+"%")
|
db = db.Where("name ILIKE ?", "%"+params.Search+"%")
|
||||||
}
|
}
|
||||||
if params.ProductCategoryID != 0 {
|
if params.ProductCategoryID != 0 {
|
||||||
return db.Where("product_category_id = ?", params.ProductCategoryID)
|
db = db.Where("product_category_id = ?", params.ProductCategoryID)
|
||||||
|
}
|
||||||
|
if params.IsDepletion != nil {
|
||||||
|
existsQuery := `
|
||||||
|
EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = ?
|
||||||
|
AND f.flagable_id = products.id
|
||||||
|
AND UPPER(f.name) IN ?
|
||||||
|
)
|
||||||
|
`
|
||||||
|
if *params.IsDepletion {
|
||||||
|
db = db.Where(existsQuery, entity.FlagableTypeProduct, depletionProductFlags)
|
||||||
|
} else {
|
||||||
|
db = db.Where("NOT "+existsQuery, entity.FlagableTypeProduct, depletionProductFlags)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return db.Order("created_at DESC").Order("updated_at DESC")
|
return db.Order("created_at DESC").Order("updated_at DESC")
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -44,4 +44,5 @@ type Query struct {
|
|||||||
Limit int `query:"limit" validate:"omitempty,number,min=1"`
|
Limit int `query:"limit" validate:"omitempty,number,min=1"`
|
||||||
Search string `query:"search" validate:"omitempty,max=50"`
|
Search string `query:"search" validate:"omitempty,max=50"`
|
||||||
ProductCategoryID int `query:"product_category_id" validate:"omitempty,number,min=1"`
|
ProductCategoryID int `query:"product_category_id" validate:"omitempty,number,min=1"`
|
||||||
|
IsDepletion *bool `query:"is_depletion" validate:"omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,30 +189,31 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Product warehouse %d belongs to different flock. Only product warehouses with project_flock_kandang_id = NULL or = %d can be used", chickinReq.ProductWarehouseId, req.ProjectFlockKandangId))
|
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Product warehouse %d belongs to different flock. Only product warehouses with project_flock_kandang_id = NULL or = %d can be used", chickinReq.ProductWarehouseId, req.ProjectFlockKandangId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if productWarehouse.Product.Id != 0 {
|
if productWarehouse.Product.Id != 0 {
|
||||||
|
category := strings.ToUpper(strings.TrimSpace(projectFlockKandang.ProjectFlock.Category))
|
||||||
|
if category != string(utils.ProjectFlockCategoryGrowing) && category != string(utils.ProjectFlockCategoryLaying) {
|
||||||
|
return nil, fmt.Errorf("invalid flock category for chickin")
|
||||||
|
}
|
||||||
|
|
||||||
var requiredFlag utils.FlagType
|
hasAyamFlag := false
|
||||||
if projectFlockKandang.ProjectFlock.Category == string(utils.ProjectFlockCategoryGrowing) {
|
for _, flag := range productWarehouse.Product.Flags {
|
||||||
requiredFlag = utils.FlagDOC
|
if utils.CanonicalFlagType(flag.Name) == utils.FlagAyam {
|
||||||
} else if projectFlockKandang.ProjectFlock.Category == string(utils.ProjectFlockCategoryLaying) {
|
hasAyamFlag = true
|
||||||
requiredFlag = utils.FlagPullet
|
break
|
||||||
} else {
|
}
|
||||||
return nil, fmt.Errorf("invalid flock category for chickin")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hasRequiredFlag := false
|
if !hasAyamFlag {
|
||||||
for _, flag := range productWarehouse.Product.Flags {
|
return nil, fmt.Errorf(
|
||||||
if utils.FlagType(flag.Name) == requiredFlag {
|
"product warehouse %d cannot be used for %s chickin. Product must have AYAM flag (or legacy alias DOC/PULLET/LAYER) (product ID: %d, warehouse ID: %d)",
|
||||||
hasRequiredFlag = true
|
chickinReq.ProductWarehouseId,
|
||||||
break
|
projectFlockKandang.ProjectFlock.Category,
|
||||||
|
productWarehouse.Product.Id,
|
||||||
|
productWarehouse.Id,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasRequiredFlag {
|
|
||||||
return nil, fmt.Errorf("product warehouse %d cannot be used for %s chickin. Product must have %s flag (product ID: %d, warehouse ID: %d)", chickinReq.ProductWarehouseId, projectFlockKandang.ProjectFlock.Category, requiredFlag, productWarehouse.Product.Id, productWarehouse.Id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chickinDate, err := utils.ParseDateString(chickinReq.ChickInDate)
|
chickinDate, err := utils.ParseDateString(chickinReq.ChickInDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Invalid ChickInDate format for product warehouse %d", chickinReq.ProductWarehouseId))
|
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Invalid ChickInDate format for product warehouse %d", chickinReq.ProductWarehouseId))
|
||||||
|
|||||||
Reference in New Issue
Block a user