All files / server/src/features/assignment/utils removeOverlapLotterySignups.ts

84.61% Statements 33/39
80% Branches 16/20
100% Functions 7/7
84.61% Lines 33/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121                              44x         39x 39x   39x 39x     39x 320x   17773x     320x                 320x 6346x   320x                   320x       317x 317x   2109x   177763x   2109x 3x   2106x       2106x         317x 110x     328x             320x       2x   2x             2x 1x               39x 7x 7x         39x    
import dayjs from "dayjs";
import { logger } from "server/utils/logger";
import { findUsers } from "server/features/user/userRepository";
import { UserAssignmentResult } from "shared/types/models/result";
import {
  DeleteLotterySignupsParams,
  delLotterySignups,
} from "server/features/user/lottery-signup/lotterySignupRepository";
import { Result, makeSuccessResult } from "shared/utils/result";
import { MongoDbError } from "shared/types/api/errors";
import { ProgramItem } from "shared/types/models/programItem";
import { getUpcomingLotterySignupProgramItemIds } from "server/features/assignment/utils/getUpcomingLotterySignups";
import { config } from "shared/config";
import { RemoveLotterySignupsStrategy } from "shared/config/eventConfigTypes";
 
export const removeOverlapLotterySignups = async (
  results: readonly UserAssignmentResult[],
  programItems: readonly ProgramItem[],
  assignmentTime: string,
): Promise<Result<void, MongoDbError>> => {
  logger.debug("Find overlapping lottery signups");
  const usersToUpdate: DeleteLotterySignupsParams[] = [];
 
  const usersResult = await findUsers();
  Iif (!usersResult.ok) {
    return usersResult;
  }
  results.flatMap((result) => {
    const assignmentSignupProgramItem = programItems.find(
      (programItem) =>
        programItem.programItemId === result.assignmentSignup.programItemId,
    );
 
    Iif (!assignmentSignupProgramItem) {
      logger.error(
        new Error(
          `removeOverlapLotterySignups: Error finding assignment signup: ${result.assignmentSignup.programItemId}`,
        ),
      );
      return [];
    }
 
    const signedUser = usersResult.value.find(
      (user) => user.username === result.username,
    );
    Iif (!signedUser) {
      logger.error(
        new Error(
          `removeOverlapLotterySignups: Error finding signed user: ${result.username}`,
        ),
      );
      return [];
    }
 
    // Cancel all lottery signups that start during the lottery direct signup
    if (
      config.event().removeLotterySignupsStrategy ===
      RemoveLotterySignupsStrategy.OVERLAP
    ) {
      logger.info("Remove overlapping signups");
      const overlappingLotterySignups = signedUser.lotterySignups.filter(
        (lotterySignup) => {
          const foundProgramItem = programItems.find(
            (programItem) =>
              programItem.programItemId === lotterySignup.programItemId,
          );
          if (!foundProgramItem) {
            return false;
          }
          const startsDuring = dayjs(foundProgramItem.startTime).isBetween(
            dayjs(assignmentSignupProgramItem.startTime).add(1, "minutes"),
            dayjs(assignmentSignupProgramItem.endTime),
          );
          return startsDuring;
        },
      );
 
      // Only update users with overlapping lottery signups
      if (overlappingLotterySignups.length > 0) {
        usersToUpdate.push({
          username: signedUser.username,
          lotterySignupProgramItemIds: overlappingLotterySignups.map(
            (signup) => signup.programItemId,
          ),
        });
      }
    }
 
    // Cancel all upcoming lottery signups
    if (
      config.event().removeLotterySignupsStrategy ===
      RemoveLotterySignupsStrategy.ALL_UPCOMING
    ) {
      logger.info("Remove upcoming signups");
      const upcomingLotterySignupProgramItemIds =
        getUpcomingLotterySignupProgramItemIds(
          signedUser.lotterySignups,
          programItems,
          dayjs(assignmentTime),
        );
 
      // Only update users with upcoming lottery signups
      if (upcomingLotterySignupProgramItemIds.length > 0) {
        usersToUpdate.push({
          username: signedUser.username,
          lotterySignupProgramItemIds: upcomingLotterySignupProgramItemIds,
        });
      }
    }
  });
 
  if (usersToUpdate.length > 0) {
    const delLotterySignupsResult = await delLotterySignups(usersToUpdate);
    Iif (!delLotterySignupsResult.ok) {
      return delLotterySignupsResult;
    }
  }
 
  return makeSuccessResult();
};