from flask import g from typing import List from projects.services.project_history_service import ProjectHistoryService from projects.repositories.projects_repository import ProjectsRepository from services.artist_team_automation.artist_team_automation_service import ArtistTeamAutomationService from artists.repositories.artist_repository import ArtistRepository from artists.schemas import ArtistTeamLabelSchema, ArtistTeamLabel, ArtistTeamMemberParams from shared.schemas import TeamMemberResponseSchema, RoleSchema, LabelResponseModel from campaigns.repositories.campaigns_repository import CampaignsRepository from artists.repositories.artist_team_repository import ArtistTeamRepository from services.users_repository import UsersRepository from services.permissions.exceptions import ArtistTeamNotFound from models.artist_team import ArtistTeamUser, ArtistTeam from models.user_project import UserProjectRoles from utils.exceptions import BadRequest, UnprocessableEntity, NotFound from config import LABEL_IMAGE_SERVICE_URL import utils.session_utils as session_utils class ArtistTeamService: artist_repository = ArtistRepository() users_repository = UsersRepository() campaigns_repository = CampaignsRepository() projects_repository = ProjectsRepository() repository = ArtistTeamRepository() automation_service = ArtistTeamAutomationService() history_service = ProjectHistoryService() def get_artist_team_for_project(self, project_id: int) -> ArtistTeamLabelSchema: artist_team = self.repository.get_artist_team_for_project(project_id) if not artist_team: raise ArtistTeamNotFound() label = artist_team.label return ArtistTeamLabelSchema( artistTeamId=artist_team.id, label=ArtistTeamLabel(id=label.id, name=label.name, imageUrl=LABEL_IMAGE_SERVICE_URL.format(id=label.id)), users=self.__map_team_artist_user(artist_team.artist_team_users), ) def get_artist_teams(self, artist_external_id: str, user_id: int) -> List[ArtistTeamLabelSchema]: artist = self.artist_repository.get_artist_by_external_id(external_id=artist_external_id) artist_teams = self.artist_repository.get_artist_teams(artist_id=artist.id, user_id=user_id) return self.__map_artist_labels(artist_teams) def __map_artist_labels(self, artist_teams: List[ArtistTeam]) -> List[ArtistTeamLabelSchema]: mapped_artist_teams = [] for artist_team in artist_teams: label = artist_team.label mapped_artist_teams.append( ArtistTeamLabelSchema( artistTeamId=artist_team.id, label=ArtistTeamLabel( id=label.id, name=label.name, imageUrl=LABEL_IMAGE_SERVICE_URL.format(id=label.id) ), users=self.__map_team_artist_user(artist_team.artist_team_users), ) ) return mapped_artist_teams def __map_team_artist_user(self, artist_team_users: List[ArtistTeamUser]): mapped_artist_team_users = [] for artist_team_user in artist_team_users: user = artist_team_user.user mapped_artist_team_users.append( TeamMemberResponseSchema( user=user, roles=[RoleSchema( UserProjectRoles(artist_team_user.role), self.artist_repository.get_editor_categories(artist_team_user.artist_team_id, user.id), )], user_labels=[LabelResponseModel(label) for label in user.labels], ) ) return mapped_artist_team_users def update_artist_team(self, artist_external_id: str, params) -> ArtistTeamLabelSchema: artist = self.artist_repository.get_artist_by_external_id(external_id=artist_external_id) artist_team = self.artist_repository.get_artist_team_by_label(artist.id, params.labelId) self.__validate_duplications(params) if not artist_team and g.is_admin: artist_team = self.artist_repository.create_artist_team(artist.id, params.labelId) for team_member in params.added: self.__add_team_member(artist_team, team_member) for team_member in params.updated: self.__update_team_member(artist_team, team_member) for team_member in params.deleted: self.__delete_team_member(artist_team, team_member) session_utils.session_flush() if artist_team.artist_team_users: self.automation_service.autoclaim_projects_for_artist_team(artist_team) else: self.automation_service.unclaim_projects_that_have_no_project_team(artist_team) session_utils.session_commit() label = artist_team.label return ArtistTeamLabelSchema( artistTeamId=artist_team.id, label=ArtistTeamLabel(id=label.id, name=label.name, imageUrl=LABEL_IMAGE_SERVICE_URL.format(id=label.id)), users=self.__map_team_artist_user(artist_team.artist_team_users), ) def __add_team_member(self, artist_team: ArtistTeam, team_member: ArtistTeamMemberParams): self.__validate_user(team_member.userId) if self.artist_repository.get_artist_team_user(artist_team.id, team_member.userId): raise UnprocessableEntity("Artist user already exists") self.__validate_role(team_member.roleId) role = UserProjectRoles(team_member.roleId) artist_team_user = ArtistTeamUser( artist_team_id=artist_team.id, user_id=team_member.userId, role=team_member.roleId ) if role is UserProjectRoles.EDITOR: self.__assign_categories_to_editor(artist_team_user, team_member.categoryIds) self.projects_repository.delete_users_from_artists_projects( [team_member.userId], [artist_team.artist.external_id] ) session_utils.session_add(artist_team_user) def __update_team_member(self, artist_team: ArtistTeam, team_member): self.__validate_user(team_member.userId) self.__validate_role(team_member.roleId) artist_team_user = self.__get_artist_team_user(artist_team.id, team_member.userId) if artist_team_user.role != team_member.roleId: artist_team_user.role = team_member.roleId campaign_type_groups = artist_team_user.campaign_type_groups for campaign_type_group in campaign_type_groups: if campaign_type_group.id not in team_member.categoryIds: artist_team_user.campaign_type_groups.remove(campaign_type_group) if team_member.roleId == UserProjectRoles.EDITOR.value: self.__assign_categories_to_editor(artist_team_user, team_member.categoryIds) def __delete_team_member(self, artist_team: ArtistTeam, team_member): session_utils.session_delete(self.__get_artist_team_user(artist_team.id, team_member.userId)) def __validate_duplications(self, params): ids = [t.userId for t in [*params.added, *params.updated, *params.deleted]] if len(set(ids)) != len(ids): raise BadRequest("Users should be unique") def __validate_user(self, user_id: int): if not self.users_repository.is_user_exists(user_id): raise NotFound(f"User with id {user_id} does not exists") def __validate_role(self, role: int): if not UserProjectRoles.has_value(role): raise NotFound(f"Role with id {role} does not exists") def __assign_categories_to_editor(self, artist_team_user, category_ids): if not category_ids: raise BadRequest("Categories should be present for Editor") for category in self.campaigns_repository.get_campaign_type_groups_by_ids(category_ids): if category not in artist_team_user.campaign_type_groups: artist_team_user.campaign_type_groups.append(category) def __get_artist_team_user(self, artist_team_id: int, user_id: int) -> ArtistTeamUser: artist_team_user = self.artist_repository.get_artist_team_user(artist_team_id, user_id) if not artist_team_user: raise NotFound("Artist user does not exists") return artist_team_user