Untitled

 avatar
unknown
plain_text
5 months ago
21 kB
3
Indexable
from datetime import datetime
from typing import List, Optional

from sqlalchemy import update
from strawberry import mutation, type

from app.graphql.schema import Info
from app.graphql.types.product_type import (
    ProductType,
    ProductDataInput,
)
from app.graphql.types import UserType, UserRoleType
from app.models import User, FieldDetail, Validation, Product, ProductCountry
from app.actions.product_helper.product_helper import (
    authUsrAndgetRqstStusId,
    auth_and_get_delete_status,
    update_last_approved_product,
    update_product_country,
    add_update_multiple_content_for_product_downstream,
    add_downstream_product,
    save_all_published_record,
)

@type
class SaveProductDataPayload:
    field_details: List[ProductType]
    success: bool
    message: str = ""


@type
class DeleteProductDataPayload:
    field_details: List[ProductType]
    success: bool
    message: str = ""

# Mutation for inserting data into MdmProduct and MdmProductField
@type
class ProductsMutation:
    @mutation
    async def save_product_data(self, info: Info, input: ProductDataInput) -> SaveProductDataPayload:
        print("Starting save_product_data")  # Debug statement
        try:
            user_regions = []
            current_user = info.context.current_user.login

            # Fetch the user
            user = info.context.session.query(User).filter(User.login == current_user).first()
            if not user:
                return SaveProductDataPayload(field_details=[], success=False, message="User not found")
            print(f"User found: {user.id}")  # Debug statement

            # Fetch user roles
            user_roles = await info.context.load_user_roles_by_user_id.load(user.id)
            print(f"User roles: {user_roles}")  # Debug statement
            is_super_admin = 'Super Admin' in user_roles
            is_regional_admin = 'Regional Admin' in user_roles
            print(f"is_super_admin: {is_super_admin}, is_regional_admin: {is_regional_admin}")  # Debug statement

            if is_regional_admin:
                # Fetch user regions
                query_result = await info.context.load_regions_by_user_id.load(user.id)
                user_regions = [region.region_id for region in query_result]
                print(f"User regions: {user_regions}")  # Debug statement
                if not user_regions:
                    return SaveProductDataPayload(field_details=[], success=False, message="You don't have proper region/role, please logout and login again")
            
            for row in input.rows_data:
                print(f"Processing row: {row}")  # Debug statement

                # Check REGION_ID
                regionId = None if str(input.region_id).strip() == "" else int(input.region_id)
                if regionId is None:
                    return SaveProductDataPayload(field_details=[], success=False, message="There is some issue with region, please logout and login again")
                print(f"regionId : {regionId}")  # Debug statement

                # Check REQUEST_STATUS_ID
                requestStatusId = -1 if str(row.request_status_id).strip() == "" else int(row.request_status_id)
                createdById = None
                createdDate = None
                if requestStatusId in [-1, 7, 8, 10]:
                    createdById = current_user
                    createdDate = datetime.now()
                else:
                    createdById = None if str(row.created_by_id).strip() == "" else str(row.created_by_id)
                    timestamp = str(row.created_date).strip()
                    date = None
                    if timestamp:
                        try:
                            date = datetime.strptime(timestamp, "%d-%b-%Y %H:%M:%S")
                        except ValueError:
                            date = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
                    createdDate = date if date else None
                print(f"requestStatusId: {requestStatusId}, createdById: {createdById}, createdDate: {createdDate}")  # Debug statement

                # Print arguments before function call
                print(f"Calling authUsrAndgetRqstStusId with submit_type: {input.submit_type}, requestStatusId: {requestStatusId}, is_regional_admin: {is_regional_admin}, is_super_admin: {is_super_admin}")
                requestStatusId = authUsrAndgetRqstStusId(input.submit_type, requestStatusId, regionId in user_regions and is_regional_admin, is_super_admin)
                print(f"New requestStatusId: {requestStatusId}")  # Debug statement

                # Prepare static and dynamic fields (excluding record_id for static_data)
                static_data = {field: getattr(row, field) for field in row.__dict__.keys() if field != "record_id" and field != "product_fields" and field not in ["dwn_7", "dwn_8"]}
                dynamic_data = {key: getattr(row, key) for key in row.__dict__.keys() if key == "product_fields"}
                special_fields = {key: getattr(row, key) for key in row.__dict__.keys() if key in ["dwn_7", "dwn_8"]}

                print("STATIC DATA: ", static_data)
                print("DYNAMIC DATA: ", dynamic_data)
                print("SPECIAL STATIC DATA: ", special_fields)

                # Add calculated fields to static_data
                # static_data["REQUEST_STATUS_ID"] = requestStatusId
                # static_data["CREATED_BY_ID"] = createdById
                # static_data["CREATED_DATE"] = createdDate
                static_data["request_status_id"] = requestStatusId
                static_data["created_by_id"] = createdById
                static_data["created_date"] = createdDate

                # Calculate seriesId and lastActive
                series_id = int(row.series_id) if str(row.series_id).strip() else 1
                series_id = series_id + 1 if requestStatusId in [4, 6] else series_id
                last_active = 1 if requestStatusId == 7 else 0
                static_data["series_id"] = series_id
                static_data["last_active"] = last_active

                # Check if the product and country combination exists in mdm_product_country
                product_country = info.context.session.query(ProductCountry).filter(
                    ProductCountry.product_name == row.product_name,
                    ProductCountry.country_id == row.country_id,
                    ProductCountry.is_deleted == False
                ).first()

                if product_country:
                    # Use the existing MDM_ID
                    static_data["mdm_id"] = product_country.id
                else:
                    # Insert a new record into mdm_product_country
                    new_product_country = ProductCountry(
                        product_name=row.product_name,
                        country_id=row.country_id,
                        is_deleted=False
                    )
                    info.context.session.add(new_product_country)
                    info.context.session.commit()
                    info.context.session.refresh(new_product_country)
                    static_data["mdm_id"] = new_product_country.id

                # Check if MDM_ID is provided (i.e., record exists)
                if row.mdm_id:
                    stmt = update(Product).where(Product.mdm_id == row.mdm_id).values(current_record="0")
                    info.context.session.execute(stmt)
                    info.context.session.commit()

                # Insert a new product record with CURRENT_RECORD = 1
                new_product = Product(**static_data)
                new_product.current_record = "1"  # Set CURRENT_RECORD separately
                new_product.updated_date = datetime.now()
                new_product.updated_by_id = current_user
                info.context.session.add(new_product)
                info.context.session.commit()
                info.context.session.refresh(new_product)  # Refresh to get the new record ID

                # Insert dynamic fields into ProductField
                for field_name, field_value in dynamic_data.items():
                    field_detail = info.context.session.query(FieldDetail).filter_by(name=field_name).first()
                    if field_detail:
                        product_field = ProductField(
                            record_id=new_product.id,
                            field_id=field_detail.id,
                            field_value=field_value
                        )
                        info.context.session.add(product_field)
                        info.context.session.commit()
                # Call Mutation.update_last_approved_product only if requestStatusId is 7
                if requestStatusId == 7:
                    update_last_approved_product(info.context.session, static_data["mdm_id"], "insert")
            
            updated_product_field = (
                info.context.session.query(Product)
                .all()
            )

            if input.submit_type.lower() == "approve":
                if not add_update_multiple_content_for_product_downstream(info.context.session, input, current_user):
                    return SaveProductDataPayload(field_details=[], success=False, message="Failed to process downstream data")
            return SaveProductDataPayload(field_details=updated_product_field, success=True, message="Product data inserted successfully")

        except Exception as e:
            info.context.session.rollback()
            print(f"Error: {e}")
            return SaveProductDataPayload(field_details=[], success=False, message=f"Error: {str(e)}")
        finally:
            info.context.session.close()

    @mutation
    async def delete_product_data(self, info: Info, input: ProductDataInput) -> DeleteProductDataPayload:
        print("Starting delete_product_data")  # Debug statement

        try:
            user_regions = []
            current_user = info.context.current_user.login
            #if input_data.submit_type == "delete":
            print("Submit type is delete")  # Debug statement

            # Fetch the user
            user = info.context.session.query(User).filter(User.login == current_user).first()
            if not user:
                return DeleteProductDataPayload(field_details=[], success=False, message="User not found")
            print(f"User found: {user.id}")  # Debug statement

            # Fetch user roles
            user_roles = await info.context.load_user_roles_by_user_id.load(user.id)
            print(f"User roles: {user_roles}")  # Debug statement
            is_super_admin = 'Super Admin' in user_roles
            is_regional_admin = 'Regional Admin' in user_roles
            print(f"is_super_admin: {is_super_admin}, is_regional_admin: {is_regional_admin}")  # Debug statement

            if is_regional_admin:
                # Fetch user regions
                query_result = await info.context.load_regions_by_user_id.load(user.id)
                user_regions = [region.region_id for region in query_result]
                print(f"User regions: {user_regions}")  # Debug statement
                if not user_regions:
                    return DeleteProductDataPayload(field_details=[], success=False, message="You don't have proper region/role, please logout and login again")

            for row in input.rows_data:
                print(f"Processing row: {row}")  # Debug statement

                # Check REGION_ID
                regionId = None if str(input.region_id).strip() == "" else int(input.region_id)
                if regionId is None:
                    return DeleteProductDataPayload(field_details=[], success=False, message="There is some issue with region, please logout and login again")
                print(f"regionId : {regionId}")  # Debug statement

                # Check REQUEST_STATUS_ID
                requestStatusId = -1 if str(row.request_status_id).strip() == "" else int(row.request_status_id)
                print(f"requestStatusId: {requestStatusId}")  # Debug statement

                # Validate required fields
                recordId = row.record_id
                mdmId = row.mdm_id
                createdById = row.created_by_id
                timestamp = str(row.created_date).strip()
                date = None
                try:
                    date = datetime.strptime(timestamp, "%d-%b-%Y %H:%M:%S") if timestamp else None
                except ValueError:
                    try:
                        date = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
                    except ValueError:
                        print("Error parsing date")
                        return "Failed to parse date"
                createdDate = date if date else None
                countryId = row.country_id

                if not all([recordId, mdmId, requestStatusId, createdById, createdDate, countryId]):
                    return DeleteProductDataPayload(field_details=[], success=False, message="There is some technical issue, Try again later.")

                # Calculate delete status
                is_deleted = auth_and_get_delete_status(input.submit_type, requestStatusId, current_user, regionId in user_regions and is_regional_admin, is_super_admin)
                if is_deleted is None:
                    return DeleteProductDataPayload(field_details=[], success=False, message="You don't have proper privilege to do this operation for selected record(s)")
                print(f"is_deleted: {is_deleted}")  # Debug statement

                # Set currentRecord and lastActive based on is_deleted
                current_record = 1 if is_deleted <= 1 else 0
                last_active = 1 if is_deleted == 0 else 0
                print(f"current_record: {current_record}, last_active: {last_active}")  # Debug statement

                # Prepare static and dynamic fields
                static_data = {field: getattr(row, field) for field in row.__dict__.keys() if field != "record_id" and field != "product_fields" and field not in ["dwn_7", "dwn_8"]}
                dynamic_data = {key: getattr(row, key) for key in row.__dict__.keys() if key == "product_fields"}
                special_fields = {key: getattr(row, key) for key in row.__dict__.keys() if key in ["dwn_7", "dwn_8"]}

                print("STATIC DATA: ", static_data)
                print("DYNAMIC DATA: ", dynamic_data)
                print("SPECIAL STATIC DATA: ", special_fields)

                # Add calculated fields to static_data
                static_data["request_status_id"] = requestStatusId
                static_data["created_by_id"] = createdById
                static_data["created_date"] = createdDate
                static_data["current_record"] = current_record
                static_data["last_active"] = last_active
                static_data["updated_date"] = datetime.now()
                static_data["updated_by_id"] = current_user
                static_data["is_deleted"] = is_deleted

                # Update CURRENT_RECORD of all existing products with the same MDM_ID to 0
                info.context.session.query(Product).filter(Product.mdm_id == row.mdm_id).update({"current_record": "0"})
                info.context.session.commit()
                if requestStatusId in [4, 10]:
                    # Fetch the previous approved product
                    prev_product = update_last_approved_product(info.context.session, mdmId, input.submit_type)
                    if prev_product is  None:
                        return DeleteProductDataPayload(field_details=[], success=False, message="Failed to restore last approved record, please contact the administrator")

                    # Update SERIES_ID if requestStatusId is 10
                    if requestStatusId == 10:
                        prev_product.series_id += 1
                    print(f"Previous produc: {prev_product}")
                elif requestStatusId == 7:
                    prev_apr_product = update_last_approved_product(info.context.session, mdmId, input.submit_type)
                    if prev_apr_product is None:
                        return DeleteProductDataPayload(field_details=[], success=False, message="Failed to restore last approved record, please contact the administrator")
                
                # Insert the new product record
                new_product = Product(**static_data)
                info.context.session.add(new_product)
                info.context.session.commit()
                info.context.session.refresh(new_product)  # Refresh to get the new record ID

                # Insert dynamic fields into MdmProductField
                for field_name, field_value in dynamic_data.items():
                    field_detail = info.context.session.query(FieldDetails).filter_by(field_name=field_name).first()
                    if field_detail:
                        product_field = ProductField(
                            record_id=new_product.record_id,
                            field_id=field_detail.field_id,
                            field_value=field_value
                        )
                        info.context.session.add(product_field)
                        info.context.session.commit()
                if not update_product_country(info.context.session, new_product.mdm_id, requestStatusId, input.submit_type, new_product.product_name, new_product.record_id):
                    return DeleteProductDataPayload(field_details=[], success=False, message="Failed to update product country")
                if requestStatusId in [4, 10] and prev_product is not None:
                    new_prev_product = Product(
                        mdm_id=prev_product.mdm_id,
                        request_status_id=prev_product.request_status_id,
                        is_deleted=prev_product.is_deleted,
                        product_phase=prev_product.product_phase,
                        jnj_full_compound_id=prev_product.jnj_full_compound_id,
                        created_date=prev_product.created_date,
                        created_by_id=prev_product.created_by_id,
                        series_id=prev_product.series_id,
                        jnj_flag=prev_product.jnj_flag,
                        updated_date=prev_product.updated_date,
                        reltio_id=prev_product.reltio_id,
                        product_status=prev_product.product_status,
                        updated_by_id=prev_product.updated_by_id,
                        country_id=prev_product.country_id,
                        group_type=prev_product.group_type,
                        current_record=1,
                        ta_sub_type=prev_product.ta_sub_type,
                        janssen_mstr_prdct_nm=prev_product.janssen_mstr_prdct_nm,
                        product_name=prev_product.product_name,
                        last_active=1
                    )

                    info.context.session.add(new_prev_product)
                    info.context.session.commit()
                    info.context.session.refresh(new_prev_product)  # Get the new RECORD_ID

                    new_record_id = new_prev_product.record_id
                    old_record_id = prev_product.record_id

                    # Fetch related data from product_field table using old RECORD_ID
                    product_fields = info.context.session.query(ProductField).filter(ProductField.record_id == old_record_id).all()

                    # Update the fetched data with the new RECORD_ID and reinsert
                    for field in product_fields:
                        new_field = ProductField(
                            record_id=new_record_id,
                            field_id=field.field_id,
                            field_value=field.field_value
                       
                        )
                        info.context.session.add(new_field)
                    info.context.session.commit()
                    #Update product-country table
                    if not update_product_country(info.context.session, new_prev_product.mdm_id, new_prev_product.request_status_id, input.submit_type, new_prev_product.product_name, new_record_id):
                        return DeleteProductDataPayload(field_details=[], success=False, message="Failed to update product country")

            updated_product_field = (
                info.context.session.query(Product)
                .all()
            )
            return DeleteProductDataPayload(field_details=updated_product_field, success=False, message="Product data deleted successfully")

        except Exception as e:
            info.context.session.rollback()
            print(f"Error: {e}")
            raise
        finally:
            info.context.session.close()     
Editor is loading...
Leave a Comment