package repository import ( "context" "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" "gorm.io/gorm" ) type StockAllocationRepository interface { BaseRepository[entity.StockAllocation] FindActiveByUsable(ctx context.Context, usableType string, usableID uint, modifier func(*gorm.DB) *gorm.DB) ([]entity.StockAllocation, error) ReleaseByUsable(ctx context.Context, usableType string, usableID uint, note *string, modifier func(*gorm.DB) *gorm.DB) error } type StockAllocationRepositoryImpl struct { *BaseRepositoryImpl[entity.StockAllocation] } func NewStockAllocationRepository(db *gorm.DB) StockAllocationRepository { return &StockAllocationRepositoryImpl{ BaseRepositoryImpl: NewBaseRepository[entity.StockAllocation](db), } } func (r *StockAllocationRepositoryImpl) FindActiveByUsable( ctx context.Context, usableType string, usableID uint, modifier func(*gorm.DB) *gorm.DB, ) ([]entity.StockAllocation, error) { var allocations []entity.StockAllocation q := r.DB().WithContext(ctx). Where("usable_type = ? AND usable_id = ? AND status = ? AND allocation_purpose = ?", usableType, usableID, entity.StockAllocationStatusActive, entity.StockAllocationPurposeConsume) if modifier != nil { q = modifier(q) } if err := q.Order("created_at ASC").Find(&allocations).Error; err != nil { return nil, err } return allocations, nil } func (r *StockAllocationRepositoryImpl) ReleaseByUsable( ctx context.Context, usableType string, usableID uint, note *string, modifier func(*gorm.DB) *gorm.DB, ) error { now := time.Now() updates := map[string]any{ "status": entity.StockAllocationStatusReleased, "released_at": now, } if note != nil { updates["note"] = *note } baseDB := r.DB() if modifier != nil { baseDB = modifier(baseDB) } q := baseDB.WithContext(ctx). Model(&entity.StockAllocation{}). Where("usable_type = ? AND usable_id = ? AND status = ? AND allocation_purpose = ?", usableType, usableID, entity.StockAllocationStatusActive, entity.StockAllocationPurposeConsume) return q.Updates(updates).Error }