"""Collection app celery tasks.""" import logging from celery import shared_task from utils.methods import transform_into_section_name logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) def get_additional_establishment_data(section_node, establishment, guide): data = { 'restaurant_section_node_id': section_node.id, 'guide_id': guide.id, 'establishment_id': establishment.id, } if establishment.last_published_review: data.update({'review_id': establishment.last_published_review.id}) return data def get_additional_product_data(section_node, product, guide): data = { 'color_wine_section_node_id': section_node.id, 'wine_id': product.id, 'guide_id': guide.id, } if product.last_published_review: data.update({'review_id': product.last_published_review.id}) return data @shared_task def generate_establishment_guide_elements(guide_id: int, filter_set: dict): """Generate guide elements.""" from collection.models import Guide from establishment.models import Establishment guide = Guide.objects.get(id=guide_id) guide.change_state(Guide.BUILDING) queryset_values = Establishment.objects.filter(**filter_set).values() try: for instance in queryset_values: populate_establishment_guide(guide_id, instance.get('id')) except Exception as e: guide.change_state(Guide.WAITING) logger.error(f'METHOD_NAME: {generate_establishment_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - {e}') else: guide.update_count_related_objects() guide.change_state(Guide.BUILT) @shared_task def populate_establishment_guide(guide_id: int, establishment_id: int): """Extend guide.""" from collection.models import GuideElement, Guide from establishment.models import Establishment guide = Guide.objects.get(id=guide_id) guide.change_state(Guide.BUILDING) try: establishment_qs = Establishment.objects.filter(id=establishment_id) if establishment_qs.exists(): establishment = establishment_qs.first() root_node, _ = GuideElement.objects.get_or_create_root_node(guide_id) if root_node: city_node, _ = GuideElement.objects.get_or_create_city_node(root_node.id, establishment.address.city_id) if city_node: section_node, _ = GuideElement.objects.get_or_create_establishment_section_node( city_node.id, transform_into_section_name(establishment.establishment_type.index_name), guide_id, ) if section_node: GuideElement.objects.get_or_create_establishment_node( **get_additional_establishment_data(section_node=section_node, establishment=establishment, guide=guide)) else: logger.error( f'METHOD_NAME: {generate_establishment_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - SectionNode is not exists.') else: logger.error(f'METHOD_NAME: {generate_establishment_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - CityNode is not exists.') else: logger.error(f'METHOD_NAME: {generate_establishment_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - RootNode is not exists.') else: logger.error(f'METHOD_NAME: {generate_establishment_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - Establishment {establishment_id} id is not exists.') except Exception as e: guide.change_state(Guide.WAITING) logger.error(f'METHOD_NAME: {generate_establishment_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - {e}') else: guide.update_count_related_objects() guide.change_state(Guide.BUILT) @shared_task def remove_establishment_guide(guide_id: int, establishment_id: int): """Extend guide.""" from collection.models import GuideElement, Guide from establishment.models import Establishment guide = Guide.objects.get(id=guide_id) guide.change_state(Guide.REMOVING) try: establishment_qs = Establishment.objects.filter(id=establishment_id) if establishment_qs.exists(): establishment = establishment_qs.first() if hasattr(establishment, 'establishment_type') and establishment.establishment_type.index_name: establishment_node_qs = GuideElement.objects.filter(establishment=establishment, guide=guide) if establishment_node_qs.exists(): establishment_node_qs.first().delete() else: logger.error(f'METHOD_NAME: {remove_establishment_guide.__name__}\n' f'DETAIL: Guide ID {guide_id} - EstablishmentNode {establishment_id} id is not exists.') else: logger.error(f'METHOD_NAME: {remove_establishment_guide.__name__}\n' f'DETAIL: Guide ID {guide_id} - Establishment {establishment_id} ' f'has not establishment type or establishment type index name.') else: logger.error(f'METHOD_NAME: {remove_establishment_guide.__name__}\n' f'DETAIL: Guide ID {guide_id} - Establishment {establishment_id} id is not exists.') except Exception as e: guide.change_state(Guide.WAITING) logger.error(f'METHOD_NAME: {remove_establishment_guide.__name__}\n' f'DETAIL: Guide ID {guide_id} - {e}') else: guide.update_count_related_objects() guide.change_state(Guide.BUILT) @shared_task def generate_product_guide_elements(guide_id: int, filter_set: dict): """Generate guide elements.""" from collection.models import GuideElement, Guide from product.models import Product guide = Guide.objects.get(id=guide_id) guide.change_state(Guide.BUILDING) queryset_values = Product.objects.filter(**filter_set).values() try: for instance in queryset_values: wine_id = instance.get('id') wine_qs = Product.objects.filter(id=wine_id) if wine_qs.exists(): wine = wine_qs.first() root_node, _ = GuideElement.objects.get_or_create_root_node(guide_id) if root_node: wine_region_node, _ = GuideElement.objects.get_or_create_wine_region_node( root_node.id, wine.wine_region.id, guide_id) if wine_region_node: yard_node, _ = GuideElement.objects.get_or_create_yard_node( wine.id, wine_region_node.id, guide_id) if yard_node: wine_color_qs = wine.wine_colors if wine_color_qs.exists(): wine_color_section, _ = GuideElement.objects.get_or_create_color_wine_section_node( wine_color_qs.first().value, yard_node.id, guide_id ) if wine_color_section: GuideElement.objects.get_or_create_wine_node( **get_additional_product_data( wine_color_section, wine, guide)) else: logger.error( f'METHOD_NAME: {generate_product_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - Wine {wine.id} has not colors.') else: logger.error( f'METHOD_NAME: {generate_product_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - WineRegionNode is not exists.') else: logger.error(f'METHOD_NAME: {generate_product_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - RootNode is not exists.') else: logger.error(f'METHOD_NAME: {generate_product_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - Product {wine_id} id is not exists.') except Exception as e: guide.change_state(Guide.WAITING) logger.error(f'METHOD_NAME: {generate_product_guide_elements.__name__}\n' f'DETAIL: Guide ID {guide_id} - {e}') guide.update_count_related_objects() guide.change_state(Guide.BUILT) @shared_task def export_guide(guide_id, user_id, file_type='csv'): from collection.models import GuideElement, Guide from collection.serializers import GuideElementExportSerializer from account.models import User from utils.export import SendGuideExport user = User.objects.get(id=user_id) guide = Guide.objects.get(id=guide_id) root = GuideElement.objects.get_root_node(guide) if root: nodes = root.get_descendants().select_related( 'review', 'establishment', 'wine_region', 'product', 'city', 'wine_color_section', 'section', 'label_photo', 'guide', 'city__country', 'establishment__establishment_type') serializer = GuideElementExportSerializer(nodes, many=True) data = serializer.data SendGuideExport( data=data, guide=guide, user=user, file_type=file_type ).send()