from dataclasses import dataclass from anydi import singleton from fansifter_common.auth.requests import AuthRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from dmp.adapters.db import ReportingDB, transactional from dmp.shopify.dtos import CollectionArtist, ShopifyStore from dmp.shopify.exceptions import ShopifyCollectionNotFoundError from dmp.shopify.models import ShopifyCollectionArtist from dmp.shopify.repositories import ( CollectionArtistRepository, CollectionRepository, StoreAssociationRepository, ) from dmp.shopify.services import StoreAssociationService @dataclass class UpdateCollectionArtistAssociationsRequest(AuthRequest): association_id: str whole_store_global_participant_id: str | None collections: list[CollectionArtist] @singleton class UpdateCollectionArtistAssociationsHandler: permission = Permission("fan_data_channel", "connect") def __init__( self, db: ReportingDB, auth_service: AuthService, collection_repository: CollectionRepository, collection_artist_repository: CollectionArtistRepository, store_association_repository: StoreAssociationRepository, store_association_service: StoreAssociationService, ) -> None: self.db = db self.auth_service = auth_service self.collection_repository = collection_repository self.collection_artist_repository = collection_artist_repository self.store_association_repository = store_association_repository self.store_association_service = store_association_service @transactional def handle( self, request: UpdateCollectionArtistAssociationsRequest ) -> ShopifyStore: store = self.store_association_service.get_store( association_id=request.association_id, ) self.auth_service.check_account_resource( request.identity_id, account=store.account, permission=self.permission, resource_id=store.id, ) collections = self.collection_repository.find_by_association_id( association_id=store.id ) if not {collection.id for collection in collections}.issuperset( {collection.collection_id for collection in request.collections} ): raise ShopifyCollectionNotFoundError collection_artists = [] # Single-artist store -> Single-artist store if store.is_single_artist_store and request.whole_store_global_participant_id: store.global_participant_id = request.whole_store_global_participant_id # Single-artist store -> Multi-artist store elif ( store.is_single_artist_store and not request.whole_store_global_participant_id ): store.global_participant_id = None for collection in request.collections: collection_artist = ShopifyCollectionArtist( association_id=store.id, collection_id=collection.collection_id, global_participant_id=collection.global_participant_id, ) collection_artists.append(collection_artist) # Multi-artist store -> Single-artist store elif store.is_multi_artist_store and request.whole_store_global_participant_id: self.collection_artist_repository.delete_by_association_id( association_id=store.id ) store.global_participant_id = request.whole_store_global_participant_id # Multi-artist store -> Multi-artist store elif ( store.is_multi_artist_store and not request.whole_store_global_participant_id ): self.collection_artist_repository.delete_by_association_id( association_id=store.id ) for collection in request.collections: collection_artist = ShopifyCollectionArtist( association_id=store.id, collection_id=collection.collection_id, global_participant_id=collection.global_participant_id, ) collection_artists.append(collection_artist) self.store_association_repository.add(store) self.collection_artist_repository.add_all(collection_artists) artists_count = ( len({ca.global_participant_id for ca in collection_artists}) if not request.whole_store_global_participant_id else 1 ) return ShopifyStore( id=store.id, name=store.name, shop_domain=store.shop_domain, custom_domain=store.custom_domain, status=store.status, vendor_id=store.vendor_id, subaccount_id=store.subaccount_id, global_participant_id=store.global_participant_id, collections_count=store.collections_count, products_count=store.products_count, artists_count=artists_count, synced_at=store.synced_at, )