package welfare_activity import ( "context" "time" ) func (s *service) ListJoinableActivitiesForUser(ctx context.Context, userID int64) ([]JoinableActivityItem, error) { now := time.Now() var activities []Activity if err := s.repo.GetDbR().WithContext(ctx).Where("deleted_at IS NULL AND status = ? AND start_time <= ? AND end_time > ? AND draw_time > ?", StatusActive, now, now, now).Order("draw_time ASC, id ASC").Find(&activities).Error; err != nil { return nil, err } if len(activities) == 0 { return []JoinableActivityItem{}, nil } activityIDs := make([]int64, 0, len(activities)) for _, activity := range activities { activityIDs = append(activityIDs, activity.ID) } var participants []Participant if err := s.repo.GetDbR().WithContext(ctx).Where("user_id = ? AND activity_id IN ?", userID, activityIDs).Find(&participants).Error; err != nil { return nil, err } joinedMap := map[int64]bool{} for _, participant := range participants { joinedMap[participant.ActivityID] = true } items := make([]JoinableActivityItem, 0, len(activities)) for _, activity := range activities { start, end, _ := activityStatsRange(activity) currentPaid, err := s.sumPaidAmount(ctx, userID, start, end) if err != nil { return nil, err } joined := joinedMap[activity.ID] canJoin := !joined && currentPaid >= activity.ThresholdAmount items = append(items, JoinableActivityItem{ ActivityID: activity.ID, Title: activity.Title, Type: activity.Type, ThresholdAmount: activity.ThresholdAmount, CurrentPaid: currentPaid, CanJoin: canJoin, Joined: joined, StartTime: activity.StartTime, EndTime: activity.EndTime, DrawTime: activity.DrawTime, }) } return items, nil }