mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
[FEAT/BE] add coloumn usage_qty and change standart ensure product
This commit is contained in:
+3
@@ -6,4 +6,7 @@ ALTER TABLE recording_depletions
|
||||
ALTER TABLE recording_depletions
|
||||
DROP COLUMN IF EXISTS total_used_qty;
|
||||
|
||||
ALTER TABLE recording_depletions
|
||||
DROP COLUMN IF EXISTS usage_qty;
|
||||
|
||||
COMMIT;
|
||||
|
||||
+2
-4
@@ -1,7 +1,8 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE recording_depletions
|
||||
ADD COLUMN IF NOT EXISTS total_used_qty numeric(15, 3) NOT NULL DEFAULT 0;
|
||||
ADD COLUMN IF NOT EXISTS total_used_qty numeric(15, 3) NOT NULL DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS usage_qty numeric(15, 3) NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE recording_depletions
|
||||
SET pending_qty = 0
|
||||
@@ -11,7 +12,4 @@ ALTER TABLE recording_depletions
|
||||
ADD CONSTRAINT chk_recording_depletions_pending_zero
|
||||
CHECK (pending_qty = 0);
|
||||
|
||||
ALTER TABLE recording_depletions
|
||||
DROP COLUMN IF EXISTS usage_qty;
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -65,9 +65,7 @@ type RecordingRepository interface {
|
||||
GetTotalEggProductionWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (totalWeightKg float64, err error)
|
||||
GetAverageTargetMetricsByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint, includeTargets bool) (RecordingTargetAverages, error)
|
||||
ResyncProjectFlockPopulationUsage(ctx context.Context, tx *gorm.DB, projectFlockKandangID uint) error
|
||||
ValidateFeedProductWarehouses(ctx context.Context, ids []uint) (uint, error)
|
||||
ValidateEggProductWarehouses(ctx context.Context, ids []uint) (uint, error)
|
||||
ValidateDepletionProductWarehouses(ctx context.Context, ids []uint) (uint, error)
|
||||
ValidateProductWarehousesByFlags(ctx context.Context, ids []uint, flags []string) (uint, error)
|
||||
}
|
||||
|
||||
type RecordingRepositoryImpl struct {
|
||||
@@ -856,36 +854,11 @@ func (r *RecordingRepositoryImpl) ResyncProjectFlockPopulationUsage(ctx context.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *RecordingRepositoryImpl) ValidateFeedProductWarehouses(ctx context.Context, ids []uint) (uint, error) {
|
||||
func (r *RecordingRepositoryImpl) ValidateProductWarehousesByFlags(ctx context.Context, ids []uint, flags []string) (uint, error) {
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var invalidIDs []uint
|
||||
feedFlags := []string{"PAKAN", "OVK"}
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Table("product_warehouses pw").
|
||||
Where("pw.id IN ?", ids).
|
||||
Where(`NOT EXISTS (
|
||||
SELECT 1 FROM flags f
|
||||
WHERE f.flagable_type = 'products'
|
||||
AND f.flagable_id = pw.product_id
|
||||
AND UPPER(f.name) IN ?
|
||||
)`, feedFlags).
|
||||
Pluck("pw.id", &invalidIDs).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(invalidIDs) > 0 {
|
||||
return invalidIDs[0], nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (r *RecordingRepositoryImpl) ValidateEggProductWarehouses(ctx context.Context, ids []uint) (uint, error) {
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
eggFlags := []string{"TELUR-UTUH", "TELUR-PECAH", "TELUR-PUTIH", "TELUR-RETAK", "TELUR"}
|
||||
var invalidIDs []uint
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Table("product_warehouses pw").
|
||||
Where("pw.id IN ?", ids).
|
||||
@@ -894,31 +867,7 @@ func (r *RecordingRepositoryImpl) ValidateEggProductWarehouses(ctx context.Conte
|
||||
WHERE f.flagable_type = 'products'
|
||||
AND f.flagable_id = pw.product_id
|
||||
AND UPPER(f.name) IN ?
|
||||
)`, eggFlags).
|
||||
Pluck("pw.id", &invalidIDs).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(invalidIDs) > 0 {
|
||||
return invalidIDs[0], nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (r *RecordingRepositoryImpl) ValidateDepletionProductWarehouses(ctx context.Context, ids []uint) (uint, error) {
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
ayamFlags := []string{"AYAM-AFKIR", "AYAM-CULLING", "AYAM-MATI"}
|
||||
var invalidIDs []uint
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Table("product_warehouses pw").
|
||||
Where("pw.id IN ?", ids).
|
||||
Where(`NOT EXISTS (
|
||||
SELECT 1 FROM flags f
|
||||
WHERE f.flagable_type = 'products'
|
||||
AND f.flagable_id = pw.product_id
|
||||
AND UPPER(f.name) IN ?
|
||||
)`, ayamFlags).
|
||||
)`, flags).
|
||||
Pluck("pw.id", &invalidIDs).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -311,13 +311,16 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent
|
||||
if err := s.ensureProductWarehousesExist(c, req.Stocks, req.Depletions, req.Eggs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.ensureFeedProductWarehouses(ctx, req.Stocks); err != nil {
|
||||
feedIDs := recordingutil.CollectWarehouseIDs(req.Stocks, func(st validation.Stock) uint { return st.ProductWarehouseId })
|
||||
if err := s.ensureProductWarehousesByFlags(ctx, feedIDs, []string{"PAKAN", "OVK"}, "feed"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.ensureDepletionProductWarehouses(ctx, req.Depletions); err != nil {
|
||||
depletionIDs := recordingutil.CollectWarehouseIDs(req.Depletions, func(d validation.Depletion) uint { return d.ProductWarehouseId })
|
||||
if err := s.ensureProductWarehousesByFlags(ctx, depletionIDs, []string{"AYAM-AFKIR", "AYAM-CULLING", "AYAM-MATI"}, "depletion"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.ensureEggProductWarehouses(ctx, req.Eggs); err != nil {
|
||||
eggIDs := recordingutil.CollectWarehouseIDs(req.Eggs, func(e validation.Egg) uint { return e.ProductWarehouseId })
|
||||
if err := s.ensureProductWarehousesByFlags(ctx, eggIDs, []string{"TELUR-UTUH", "TELUR-PECAH", "TELUR-PUTIH", "TELUR-RETAK", "TELUR"}, "egg"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
actorID, err := m.ActorIDFromContext(c)
|
||||
@@ -508,7 +511,8 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
if err := s.ensureProductWarehousesExist(c, req.Stocks, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.ensureFeedProductWarehouses(ctx, req.Stocks); err != nil {
|
||||
feedIDs := recordingutil.CollectWarehouseIDs(req.Stocks, func(st validation.Stock) uint { return st.ProductWarehouseId })
|
||||
if err := s.ensureProductWarehousesByFlags(ctx, feedIDs, []string{"PAKAN", "OVK"}, "feed"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.syncRecordingStocks(ctx, tx, recordingEntity.Id, existingStocks, req.Stocks, note, actorID); err != nil {
|
||||
@@ -536,7 +540,8 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
if err := s.ensureProductWarehousesExist(c, nil, req.Depletions, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.ensureDepletionProductWarehouses(ctx, req.Depletions); err != nil {
|
||||
depletionIDs := recordingutil.CollectWarehouseIDs(req.Depletions, func(d validation.Depletion) uint { return d.ProductWarehouseId })
|
||||
if err := s.ensureProductWarehousesByFlags(ctx, depletionIDs, []string{"AYAM-AFKIR", "AYAM-CULLING", "AYAM-MATI"}, "depletion"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.releaseRecordingDepletions(ctx, tx, existingDepletions, note, actorID); err != nil {
|
||||
@@ -607,7 +612,8 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
if err := s.ensureProductWarehousesExist(c, nil, nil, req.Eggs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.ensureEggProductWarehouses(ctx, req.Eggs); err != nil {
|
||||
eggIDs := recordingutil.CollectWarehouseIDs(req.Eggs, func(e validation.Egg) uint { return e.ProductWarehouseId })
|
||||
if err := s.ensureProductWarehousesByFlags(ctx, eggIDs, []string{"TELUR-UTUH", "TELUR-PECAH", "TELUR-PUTIH", "TELUR-RETAK", "TELUR"}, "egg"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ensureRecordingEggsUnused(existingEggs); err != nil {
|
||||
@@ -924,43 +930,14 @@ func (s *recordingService) ensureProductWarehousesExist(c *fiber.Ctx, stocks []v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *recordingService) ensureEggProductWarehouses(ctx context.Context, eggs []validation.Egg) error {
|
||||
if len(eggs) == 0 {
|
||||
func (s *recordingService) ensureProductWarehousesByFlags(ctx context.Context, ids []uint, flags []string, label string) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
ids := recordingutil.CollectWarehouseIDs(eggs, func(e validation.Egg) uint { return e.ProductWarehouseId })
|
||||
if err := s.validateWarehouseIDs(ctx, ids, func(ctx context.Context, ids []uint) error {
|
||||
return recordingutil.EnsureEggProductWarehouses(ctx, s.Repository, ids)
|
||||
}, "egg"); err != nil {
|
||||
s.Log.Errorf("Failed to validate egg product warehouses: %+v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *recordingService) ensureDepletionProductWarehouses(ctx context.Context, depletions []validation.Depletion) error {
|
||||
if len(depletions) == 0 {
|
||||
return nil
|
||||
}
|
||||
ids := recordingutil.CollectWarehouseIDs(depletions, func(d validation.Depletion) uint { return d.ProductWarehouseId })
|
||||
if err := s.validateWarehouseIDs(ctx, ids, func(ctx context.Context, ids []uint) error {
|
||||
return recordingutil.EnsureDepletionProductWarehouses(ctx, s.Repository, ids)
|
||||
}, "depletion"); err != nil {
|
||||
s.Log.Errorf("Failed to validate depletion product warehouses: %+v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *recordingService) ensureFeedProductWarehouses(ctx context.Context, stocks []validation.Stock) error {
|
||||
if len(stocks) == 0 {
|
||||
return nil
|
||||
}
|
||||
ids := recordingutil.CollectWarehouseIDs(stocks, func(st validation.Stock) uint { return st.ProductWarehouseId })
|
||||
if err := s.validateWarehouseIDs(ctx, ids, func(ctx context.Context, ids []uint) error {
|
||||
return recordingutil.EnsureFeedProductWarehouses(ctx, s.Repository, ids)
|
||||
}, "feed"); err != nil {
|
||||
s.Log.Errorf("Failed to validate feed product warehouses: %+v", err)
|
||||
return recordingutil.EnsureProductWarehousesByFlags(ctx, s.Repository, ids, flags, label)
|
||||
}, label); err != nil {
|
||||
s.Log.Errorf("Failed to validate %s product warehouses: %+v", label, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -21,9 +21,7 @@ type productWarehouseExistsRepo interface {
|
||||
}
|
||||
|
||||
type recordingValidationRepo interface {
|
||||
ValidateFeedProductWarehouses(ctx context.Context, ids []uint) (uint, error)
|
||||
ValidateEggProductWarehouses(ctx context.Context, ids []uint) (uint, error)
|
||||
ValidateDepletionProductWarehouses(ctx context.Context, ids []uint) (uint, error)
|
||||
ValidateProductWarehousesByFlags(ctx context.Context, ids []uint, flags []string) (uint, error)
|
||||
}
|
||||
|
||||
func EnsureProductWarehousesExist(ctx context.Context, repo productWarehouseExistsRepo, ids []uint) error {
|
||||
@@ -42,13 +40,11 @@ func EnsureProductWarehousesExist(ctx context.Context, repo productWarehouseExis
|
||||
return nil
|
||||
}
|
||||
|
||||
type pwValidatorFunc func(ctx context.Context, ids []uint) (uint, error)
|
||||
|
||||
func ensureProductWarehouses(ctx context.Context, ids []uint, label string, validator pwValidatorFunc) error {
|
||||
if len(ids) == 0 || validator == nil {
|
||||
func EnsureProductWarehousesByFlags(ctx context.Context, repo recordingValidationRepo, ids []uint, flags []string, label string) error {
|
||||
if repo == nil || len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
invalidID, err := validator(ctx, ids)
|
||||
invalidID, err := repo.ValidateProductWarehousesByFlags(ctx, ids, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -73,25 +69,16 @@ func CollectWarehouseIDs[T any](items []T, getID idGetter[T]) []uint {
|
||||
return ids
|
||||
}
|
||||
|
||||
func EnsureFeedProductWarehouses(ctx context.Context, repo recordingValidationRepo, ids []uint) error {
|
||||
if repo == nil {
|
||||
return nil
|
||||
}
|
||||
return ensureProductWarehouses(ctx, ids, "feed", repo.ValidateFeedProductWarehouses)
|
||||
}
|
||||
|
||||
func EnsureEggProductWarehouses(ctx context.Context, repo recordingValidationRepo, ids []uint) error {
|
||||
if repo == nil {
|
||||
return nil
|
||||
}
|
||||
return ensureProductWarehouses(ctx, ids, "egg", repo.ValidateEggProductWarehouses)
|
||||
}
|
||||
|
||||
func EnsureDepletionProductWarehouses(ctx context.Context, repo recordingValidationRepo, ids []uint) error {
|
||||
if repo == nil {
|
||||
return nil
|
||||
}
|
||||
return ensureProductWarehouses(ctx, ids, "depletion", repo.ValidateDepletionProductWarehouses)
|
||||
func EnsureProductWarehousesByFlagsForItems[T any](
|
||||
ctx context.Context,
|
||||
repo recordingValidationRepo,
|
||||
items []T,
|
||||
getID idGetter[T],
|
||||
flags []string,
|
||||
label string,
|
||||
) error {
|
||||
ids := CollectWarehouseIDs(items, getID)
|
||||
return EnsureProductWarehousesByFlags(ctx, repo, ids, flags, label)
|
||||
}
|
||||
|
||||
func ComputeDepletionRate(prevRecording *entity.Recording, currentDepletion float64, totalChick int64) float64 {
|
||||
|
||||
Reference in New Issue
Block a user