def __buildRotationTable(self, event):
     rotation_detail = event.event_rotation_detail
     boat_identifiers = event.event_boat_rotation_name.split(',')
     rotation_table = dict()
     schools = SchoolAPI(self.request).filterSelf(id__in=list(map(lambda x: int(x), event.event_school_ids)))
     teams = EventAPI(self.request).getEventCascadeTeams(event.id)
     team_flatten_ids = [team.id for team in teams]
     team_school_link = dict()
     team_name_link = dict()
     for team in TeamAPI(self.request).filterSelf(id__in=team_flatten_ids):
         team_school_link[team.id] = schools.get(id=team.team_school)
         team_name_link[team.id] = team_school_link[team.id].school_name + ' - ' + team.team_name
     for event_tag_id, teams in rotation_detail.items():
         event_tag_name = EventTagAPI(self.request).getSelf(id=event_tag_id).event_tag_name
         rotation_table[event_tag_name] = dict()
         for team_id, rotations in teams.items():
             team_id = int(team_id)
             rotation_table[event_tag_name][team_id] = dict()
             rotation_table[event_tag_name][team_id]['team_name'] = team_name_link[team_id]
             rotation_table[event_tag_name][team_id]['rotations'] = [
                 boat_identifiers[int(r_num)-1] for r_num in rotations
             ]
     return dict(rotation_table)
    def __buildFleetTable(self, event, force_compile):
        def __buildFleetScoreTable():
            race_table = dict()
            event_score_map = self.__compileScoreMap(event)
            for tag_id, tag in zip(event_activity_id_tags,
                                   event_activity_name_tags):
                race_table[tag] = dict()
                restricted_eas = event_activities.filter(
                    event_activity_event_tag=tag_id).order_by(
                        'event_activity_order')
                for ea in restricted_eas:
                    result = ea.event_activity_result
                    if bool(result):
                        for team, rank in result.items():
                            team_id = int(team)
                            team_name = team_name_link[team_id]
                            rank = rank if rank not in event_score_map else rank + ' (' + str(
                                event_score_map[rank]) + ')'
                            if team_id not in race_table[tag]:
                                race_table[tag][team_id] = dict(
                                    team_name=team_name,
                                    scores=list(),
                                    final_score=0)
                            race_table[tag][team_id]["scores"].append(rank)
                    else:
                        for team in team_ids[tag]:
                            team_name = team_name_link[team]
                            if team not in race_table[tag]:
                                race_table[tag][team] = dict(
                                    team_name=team_name,
                                    scores=list(),
                                    final_score=0)
                            race_table[tag][team]["scores"].append(0)

            for tag in event_activity_name_tags:
                for team in team_ids[tag]:
                    score = reduce(
                        (lambda x, y: self.__scoreAdd(x, y, event_score_map)),
                        race_table[tag][team]["scores"])
                    race_table[tag][team]["final_score"] = int(score)

            for tag in event_activity_name_tags:
                temp_table = sorted(
                    race_table[tag].items(),
                    key=lambda x: x[1]["final_score"]
                    if x[1]["final_score"] != 0 else ScoreMappingAPI(
                        self.request).getMaxSentinel())
                race_table[tag] = {data[0]: data[1] for data in temp_table}

            for tag in event_activity_name_tags:
                prevRanking = 1
                prevScore = 0
                for index, team in enumerate(race_table[tag]):
                    if race_table[tag][team]["final_score"] == 0:
                        race_table[tag][team]["rank"] = '#'
                    else:
                        if race_table[tag][team]["final_score"] > prevScore:
                            prevRanking = index + 1
                            prevScore = race_table[tag][team]["final_score"]
                        race_table[tag][team]["rank"] = prevRanking
            # Sort the race_table by rank (takes care of unassigned rank cases)
            return race_table

        def __buildFleetRankingTable():
            if not event.event_status == Event.EVENT_STATUS_DONE or force_compile:
                ranking_table = dict()
                for school in schools:
                    ranking_table[school.id] = 0
                for tag in event_activity_name_tags:
                    for team in team_ids[tag]:
                        ranking_table[team_school_link[
                            team].id] += score_table[tag][team]["final_score"]
                school_ranking_list = [
                    dict(school_id=school_id,
                         school_name=schools.get(id=school_id).school_name,
                         score=data,
                         ranking='#',
                         base_ranking='#',
                         override_ranking=0,
                         need_override=False,
                         note='-')
                    for school_id, data in ranking_table.items()
                ]
                school_ranking_list = sorted(
                    school_ranking_list,
                    key=lambda x: x['score']
                    if x['score'] != 0 else ScoreMappingAPI(self.request
                                                            ).getMaxSentinel())
                prevRanking = 1
                prevScore = 0
                for index, school_ranking_data in enumerate(
                        school_ranking_list):
                    if school_ranking_data['score'] != 0:
                        if school_ranking_data['score'] > prevScore:
                            prevRanking = index + 1
                            prevScore = school_ranking_data['score']
                        school_ranking_list[index]['ranking'] = prevRanking
                        school_ranking_list[index][
                            'base_ranking'] = prevRanking
            else:
                summaries = list(
                    SummaryAPI(self.request).filterSelf(
                        summary_event_parent=event.id))
                school_ranking_list = [
                    dict(
                        school_id=summary.summary_event_school,
                        school_name=schools.get(
                            id=summary.summary_event_school).school_name,
                        score=summary.summary_event_race_score,
                        ranking=summary.summary_event_ranking +
                        summary.summary_event_override_ranking,
                        base_ranking=summary.summary_event_ranking,
                        override_ranking=summary.
                        summary_event_override_ranking,
                        need_override=True if
                        summary.summary_event_override_ranking != 0 else False,
                        note='Tie-breaker' if
                        summary.summary_event_override_ranking != 0 else '-')
                    for index, summary in enumerate(summaries)
                ]
            # Takes care of unassigned ranking cases
            school_ranking_list = sorted(
                school_ranking_list,
                key=lambda x: x['ranking']
                if isinstance(x['ranking'], int) else ScoreMappingAPI(
                    self.request).getMaxSentinel())
            # TODO: Refactor, this code does not belong to the frontend API, it is for the backend score compilation
            # Loop to check if entry needs override
            for index, school_ranking_data in enumerate(school_ranking_list):
                duplicates = sum((1 if result['base_ranking'] ==
                                  school_ranking_data['base_ranking'] else 0)
                                 for result in school_ranking_list)
                if duplicates > 1:
                    school_ranking_list[index]['need_override'] = True
            return school_ranking_list

        event_activities = EventActivityAPI(
            self.request).filterSelf(event_activity_event_parent=event.id)
        schools = SchoolAPI(self.request).filterSelf(
            id__in=list(map(lambda x: int(x), event.event_school_ids)))
        teams = EventAPI(self.request).getEventCascadeTeams(event.id)
        event_activity_id_tags = list()
        event_activity_name_tags = list()
        team_ids = dict()
        team_school_link = dict()
        team_name_link = dict()
        distinct_eas = event_activities.distinct('event_activity_event_tag')
        team_flatten_ids = [team.id for team in teams]
        for ea in distinct_eas:
            event_tag_name = EventTagAPI(self.request).getSelf(
                id=ea.event_activity_event_tag).event_tag_name
            event_activity_name_tags.append(event_tag_name)
            event_activity_id_tags.append(ea.event_activity_event_tag)
            team_ids[event_tag_name] = [
                team.id for team in teams.filter(
                    team_tag_id=ea.event_activity_event_tag)
            ]
        for team in TeamAPI(self.request).filterSelf(id__in=team_flatten_ids):
            team_school_link[team.id] = schools.get(id=team.team_school)
            team_name_link[team.id] = team_school_link[
                team.id].school_name + ' - ' + team.team_name

        score_table = __buildFleetScoreTable()
        rank_table = __buildFleetRankingTable()
        return dict(ranking=rank_table, score=score_table)