from decimal import Decimal, ROUND_HALF_UP

from rest_framework import serializers
from .models import OrderRequests, OrderRequestFiles, CostCenter, OrderHistory, Orders, OrderStatus, OffDays, \
    ExtraCharges, LoadListConditions, IncoTerms, CustomerContacts,PriceMaster, OrderPriceLink, \
    PackingDetail, CustomerRequirement, OrderCharges
from . import models as po_models
from . import constants as po_consts
import requests
from django.conf import settings
import os
from datetime import datetime, timedelta
from django.db import connections
from django.db import connection
from .common import fetch_query_results
from . import fetch_data
from django.db.models import Sum
from rest_framework.exceptions import ValidationError, NotFound
from rest_framework.exceptions import APIException



def update_customer_requirement_data(ship_to, product_id, customer_requirement):
    """function to update CustomerRequirements modal"""

    requirement = customer_requirement.get('data')

    if requirement:
        print()
        customer_requirement, created = po_models.CustomerRequirement.objects.get_or_create(
            ShipTo=ship_to, product_id=product_id
        )
        customer_requirement.NoCustomerEmailRequired = requirement.get('customer_confirmation_mail_not_required', False)
        customer_requirement.IsSample = requirement.get('samples_required', False)
        customer_requirement.CustomText = requirement.get('additional_confirmation_text', '')
        customer_requirement.NeedVGM = requirement.get('need_vgm_form', False)
        customer_requirement.IsOutSideEU = requirement.get('is_outside_european_union', False)
        customer_requirement.NeedReturnMDGD = requirement.get('need_return_mdgd_form', False)
        customer_requirement.SendLoadReferenceToTransporter = requirement.get('include_load_reference_in_transporter_mail', False)
        customer_requirement.save()
        print('updated')
        


class OrderRequestListSerializer(serializers.ModelSerializer):
    is_immediate_delivery = serializers.BooleanField(read_only=True)
    ProductName = serializers.SerializerMethodField()
    FormattedDeliveryDate = serializers.SerializerMethodField()
    transporter_id = serializers.SerializerMethodField()
    Quantity = serializers.SerializerMethodField()
    DeliveryCompany = serializers.CharField(source='DeliveryCustomer')
    BillableCompany = serializers.CharField(source='BillToCustomer')
    BillAddress = serializers.CharField(source='BillToAddress')
    created_user_data = serializers.SerializerMethodField()
    product_data = serializers.SerializerMethodField()
    SampleRequiredCustomer = serializers.SerializerMethodField()
    ProgressData = serializers.SerializerMethodField()
    # CustomerRequirement = serializers.SerializerMethodField()

    class Meta:
        model = OrderRequests
        fields = [
            'Id',
            'is_immediate_delivery',
            'ExactOrderNo',
            'PurchaseOrderNo',
            'ProductName',
            'Quantity',
            'FormattedDeliveryDate',
            'DeliveryTimeInterval',
            'OrderedCompany',
            'OrderedAddress',
            'DeliveryCompany',
            'DeliveryAddress',
            'BillableCompany',
            'BillAddress',
            'LoadPoint',
            'LoadReference',
            'IncoTerm',
            'OrderedBy',
            'ProductId',
            'DeliverTo',
            'transporter_id',
            'CreatedBy',
            'created_user_data',
            'product_data', 
            'SampleRequiredCustomer', 
            'ProgressData', 
            # 'CustomerRequirement'
        ]

    def to_representation(self, instance):
        """Override representation function to format response data"""
        response_data = super().to_representation(instance)
        created_user_data = response_data.pop('created_user_data')
        # requirement = response_data.pop('CustomerRequirement')
        response_data['created_user'] = created_user_data['Id']
        response_data['IsTestAccount'] = created_user_data['IsTestAccount']
    
        # response_data['SampleRequiredCustomer'] = requirement.get('samples_required', None)

        product_data = response_data.pop('product_data')
        response_data['Packaging'] = product_data.get('Packaging', None)

        return response_data

    def get_field_value_or_empty(self, obj, field_name):
        """
        Utility function to check if a field value is None.
        If the field is None, return an empty string.
        Otherwise, return the field's value.
        """
        return getattr(obj, field_name, "") if getattr(obj, field_name, None) is not None else ""

    def get_ExactOrderNo(self, obj):
        return self.get_field_value_or_empty(obj, 'ExactOrderNo')

    def get_Quantity(self, obj):
        return self.get_field_value_or_empty(obj, 'Quantity')

    def get_DeliveryTimeInterval(self, obj):
        return self.get_field_value_or_empty(obj, 'DeliveryTimeInterval')

    def get_LoadReference(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadReference')

    def get_transporter_id(self, obj):
        order = Orders.objects.get(OrderNo=obj.Id)
        transporter_id = order.TransporterId
        return transporter_id
    
    # def get_CustomerRequirement(self, obj):
    #     """Function to return weather customer requires sample"""
    #     ordered_by = fetch_data.get_address_data(obj.OrderedBy)
    #     product_data = fetch_data.get_product_data(obj.ProductId)
    #     customer_requirement = None

    #     try:
    #         customer_requirement = fetch_data.get_odoo_customer_requirement_data(
    #             ordered_by['exact_erp_address_id'], product_data['article_code'])
    #     except Exception as e:
    #         raise APIException(f"Odoo API failed: {str(e)}")

    #     return customer_requirement.get('data') if customer_requirement else None


    def get_ProductName(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {}).get('NickName', None)
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_FormattedDeliveryDate(self, obj):
        # Convert the UpdatedOn datetime to the required format
        delivery_date = obj.DeliveryDate
        if delivery_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(delivery_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    delivery_date = datetime.strptime(delivery_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return delivery_date.strftime("%d.%m.%Y")
        return ""

    def get_created_user_data(self, obj):
        """function to details of created user"""
        api_url = settings.USER_API_URL + "users/"
        request = self.context.get('request')
        if request is None:
            return None
        if obj.CreatedBy != 0:
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
            }

            # Safely get the auth token
            auth_token = request.headers.get('x-auth-token', None)
            if auth_token:
                headers['x-auth-token'] = auth_token

            payload = {"user_id": obj.CreatedBy}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    user_data = response.json()
                    return user_data['data']
                else:
                    return None
            except requests.RequestException as e:
                print(f"An error occurred: {e}")
                return None
        else:
            return ""
        
    def get_product_data(self, obj):
        """function returns product details"""
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {})
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""
        
    def get_SampleRequiredCustomer(self, obj):
        """Function to return weather customer requires sample"""

        ordered_by = fetch_data.get_address_data(obj.OrderedBy)
        product_id = obj.ProductId
        if ordered_by:
            customer_requirement = CustomerRequirement.objects.filter(
                ShipTo=ordered_by['exact_erp_address_id'], IsSample=True, product_id=product_id).last()
            if customer_requirement:
                return True
            else:
                return False
        else:
            return False

    def get_ProgressData(self, obj):
        """Function to return progress data"""

        progress_data = []
        ordered_by = obj.OrderedBy
        product_id = obj.ProductId
        order = Orders.objects.filter(OrderNo=obj.Id).first()
        customer_requirement = po_models.CustomerRequirement.objects.filter(
            AddressId=ordered_by, product_id=product_id).first()

        progress_data.append({
                "label": "Order Created",
                "completed": True,
                "date": order.CreatedAt.strftime("%d.%m.%Y"),
            })


        if (customer_requirement and customer_requirement.NoCustomerEmailRequired == False) or (customer_requirement is None):

            """if customer mail has sent then add this"""
            email_log = po_models.EmailLog.objects.filter(
                order_id=obj.Id, type='customer', receipient_id=ordered_by).first()

            if email_log:
                email_sent = True
                sent_at = email_log.sent_at.strftime("%d.%m.%Y")
            else:
                email_sent = False
                sent_at = ''
            
            progress_data.append({
                    "label": "Customer Notified",
                    "completed": email_sent,
                    "date": sent_at,
                })
        
        if order and order.TransporterId and order.IncoTerm!='FCA':
            transporter_id = order.TransporterId
            email_log = po_models.EmailLog.objects.filter(
                order_id=obj.Id, type='transporter', receipient_id=transporter_id).first()

            if email_log: 
                progress_data.append({
                    "label": "Transporter Notified",
                    "completed": True,
                    "date": email_log.sent_at.strftime("%d.%m.%Y"),
                })
            else:
                progress_data.append({
                    "label": "Transporter Notified",
                    "completed": False,
                    "date": "",
                })
        

        if customer_requirement and customer_requirement.IsSample == True:
            sample_reasons = ['taken_from_other_customer', 'taken_from_same_batch', 'analyzed_by_customer', 'taken_from_truck']
            lab_email = po_models.EmailLog.objects.filter(
                order_id=obj.Id, type__in=sample_reasons).first()
            sample_request_sent = False
            if lab_email:
                sample_request_sent = True
                sent_at = lab_email.sent_at.strftime("%d.%m.%Y")
            else:
                sample_request_sent = False
                sent_at = ''

            progress_data.append({
                "label": "Sample Request",
                "completed": sample_request_sent,
                "date": sent_at,
            })

            if order.NeedSample == 'YES':
                courier_mail = po_models.EmailLog.objects.filter(
                order_id=obj.Id, type='courier').first()
                if courier_mail:
                    progress_data.append({
                        "label": "Courier Notified",
                        "completed": True,
                        "date": courier_mail.sent_at.strftime("%d.%m.%Y"),
                    })
                else:
                    progress_data.append({
                        "label": "Courier Notified",
                        "completed": False,
                        "date": "",
                    })

        is_delivered = True if order.StatusId==4 else False
        progress_data.append({
                        "label": "Delivered",
                        "completed": is_delivered,
                        "date": "",
                    })

        return progress_data


        


class RequestListSerializer(serializers.ModelSerializer):  
    is_immediate_delivery = serializers.BooleanField(read_only=True)
    ProductName = serializers.SerializerMethodField()
    FormattedDeliveryDate = serializers.SerializerMethodField()
    Quantity = serializers.SerializerMethodField()
    DeliveryCompany = serializers.CharField(source='DeliveryCustomer')
    BillableCompany = serializers.CharField(source='BillToCustomer')
    BillAddress = serializers.CharField(source='BillToAddress')
    RowId =  serializers.SerializerMethodField()
    FormattedLoadingDate = serializers.SerializerMethodField()
    created_user_data = serializers.SerializerMethodField()
    product_data = serializers.SerializerMethodField()

    class Meta:
        model = OrderRequests
        fields = [
            'Id',
            'is_immediate_delivery',
            'ExactOrderNo',
            'ProductId',
            'ProductName',
            'Quantity',
            'DeliveryDate',
            'FormattedDeliveryDate',
            'DeliveryTimeInterval',
            'OrderedBy',
            'OrderedCompany',
            'OrderedAddress',
            'DeliverTo',
            'DeliveryCompany',
            'DeliveryAddress',
            'BillTo',
            'BillableCompany',
            'BillAddress',
            'PurchaseOrderNo',
            'IncoTermsId',
            'IncoTerm',
            'LoadPointId',
            'LoadPoint',
            'LoadReference',
            'RowId',
            'LoadingDate',
            'FormattedLoadingDate',
            'CreatedBy',
            'created_user_data',
            'FillingDate',
            'no_of_packings',
            'kg_per_packaging',
            'product_data'
        ]

    def to_representation(self, instance):
        """Override representation function to format response data"""
        response_data = super().to_representation(instance)
        created_user_data = response_data.pop('created_user_data')
        product_data = response_data.pop('product_data')
        response_data['Packaging'] = product_data.get('Packaging', None)

        response_data['created_user'] = created_user_data['Id']
        response_data['IsTestAccount'] = created_user_data['IsTestAccount']
        return response_data

    def get_field_value_or_empty(self, obj, field_name):
        """
        Utility function to check if a field value is None.
        If the field is None, return an empty string.
        Otherwise, return the field's value.
        """
        return getattr(obj, field_name, "") if getattr(obj, field_name, None) is not None else ""

    def get_ExactOrderNo(self, obj):
        return self.get_field_value_or_empty(obj, 'ExactOrderNo')

    def get_Quantity(self, obj):
        return self.get_field_value_or_empty(obj, 'Quantity')

    def get_DeliveryTimeInterval(self, obj):
        return self.get_field_value_or_empty(obj, 'DeliveryTimeInterval')

    def get_LoadReference(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadReference')

    def get_ProductName(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {}).get('NickName', None)
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_product_data(self, obj):
        """function returns product details"""
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {})
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_FormattedDeliveryDate(self, obj):
        # Convert the UpdatedOn datetime to the required format
        delivery_date = obj.DeliveryDate
        if delivery_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(delivery_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    delivery_date = datetime.strptime(delivery_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return delivery_date.strftime("%d.%m.%Y")
        return ""

    def get_PurchaseOrderNo(self, obj):
        return self.get_field_value_or_empty(obj, 'PurchaseOrderNo')
    
    def get_RowId(self,obj):
        row_id = OrderPriceLink.objects.filter(
            OrderId=obj.Id,IsDeleted=0).values_list('PriceRowId',flat=True).first()
        return row_id
    
    def get_FormattedLoadingDate(self, obj):
        # Convert the UpdatedOn datetime to the required format
        loading_date = obj.LoadingDate
        if loading_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(loading_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    loading_date = datetime.strptime(loading_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return loading_date.strftime("%d.%m.%Y")
        return ""

    def get_created_user_data(self, obj):
        """function to details of created user"""
        api_url = settings.USER_API_URL + "users/"
        request = self.context.get('request')
        if request is None:
            return None
        if obj.CreatedBy != 0:
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
            }

            # Safely get the auth token
            auth_token = request.headers.get('x-auth-token', None)
            if auth_token:
                headers['x-auth-token'] = auth_token

            payload = {"user_id": obj.CreatedBy}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    user_data = response.json()
                    return user_data['data']
                else:
                    return None
            except requests.RequestException as e:
                print(f"An error occurred: {e}")
                return None
        else:
            return ""

class OrderRequestSerializer(serializers.ModelSerializer):
    is_immediate_delivery = serializers.BooleanField(read_only=True)
    ProductName = serializers.SerializerMethodField()
    ProductArticleCode = serializers.SerializerMethodField()
    CostCenterId = serializers.SerializerMethodField()
    CostCenter = serializers.SerializerMethodField()
    OrderedCompany = serializers.SerializerMethodField()
    OrderedAddress = serializers.SerializerMethodField()
    DeliveryCompany = serializers.SerializerMethodField()
    DeliveryAddress = serializers.SerializerMethodField()
    BillableCompany = serializers.SerializerMethodField()
    BillAddress = serializers.SerializerMethodField()
    IncoTerm = serializers.SerializerMethodField()
    HasOriginStatement = serializers.SerializerMethodField()
    LoadPointEmail = serializers.SerializerMethodField()
    TransportMode = serializers.CharField(source='transport_mode', read_only=True)
    TransportDeliveryLocation = serializers.CharField(
        source='transport_delivery_location', read_only=True)
    ContainerDetails = serializers.SerializerMethodField()
    LoadPoint = serializers.SerializerMethodField()
    FormattedDeliveryDate = serializers.SerializerMethodField()
    ExactOrderNo = serializers.SerializerMethodField()
    ProductId = serializers.SerializerMethodField()
    Quantity = serializers.SerializerMethodField()
    DeliveryTime = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    PurchaseOrderNo = serializers.SerializerMethodField()
    OrderedBy = serializers.SerializerMethodField()
    DeliverTo = serializers.SerializerMethodField()
    BillTo = serializers.SerializerMethodField()
    IncoTermsId = serializers.SerializerMethodField()
    LoadPointId = serializers.SerializerMethodField()
    LoadReference = serializers.SerializerMethodField()
    InvoiceCode = serializers.SerializerMethodField()
    ExactOrderedAddressId = serializers.SerializerMethodField()
    FormattedLoadingDate = serializers.SerializerMethodField()
    CustomerName = serializers.SerializerMethodField()
    product_data = serializers.SerializerMethodField()
    # SampleRequiredCustomer = serializers.SerializerMethodField()
    # IsContainerRequired = serializers.SerializerMethodField()
    # NeedMDGD = serializers.SerializerMethodField()
    # NeedVGM = serializers.SerializerMethodField()
    # NeedCustomerMail = serializers.SerializerMethodField()
    # NeedCOC = serializers.SerializerMethodField()
    # NeedReturnMDGD = serializers.SerializerMethodField()
    CustomerRequirement = serializers.SerializerMethodField()

    class Meta:
        model = OrderRequests
        fields = [
            'Id',
            'is_immediate_delivery',
            'ExactOrderNo',
            'ProductId',
            'ProductName',
            'Quantity',
            'CostCenter',
            'CostCenterId',
            'DeliveryDate',
            'HasOriginStatement',
            'LoadPointEmail',
            'TransportMode',
            'TransportDeliveryLocation',
            'ContainerDetails',
            'FormattedDeliveryDate',
            'DeliveryTime',
            'DeliveryTimeInterval',
            'PurchaseOrderNo',
            'OrderedBy',
            'CustomerName',
            'OrderedCompany',
            'OrderedAddress',
            'DeliverTo',
            'DeliveryCompany',
            'DeliveryAddress',
            'BillTo',
            'BillableCompany',
            'BillAddress',
            'IncoTermsId',
            'IncoTerm',
            'LoadPointId',
            'LoadPoint',
            'LoadReference',
            'InvoiceCode',
            'ExactOrderedAddressId',
            'LoadingDate',
            'FormattedLoadingDate',
            'Information',
            'ContainerNo',
            'ProductArticleCode',
            'FillingDate',
            'no_of_packings',
            'kg_per_packaging',
            'product_data', 
            # 'SampleRequiredCustomer', 
            # 'IsContainerRequired',
            # 'NeedMDGD', 
            # 'NeedVGM', 
            # 'NeedCustomerMail', 
            # 'NeedCOC', 
            # 'NeedReturnMDGD', 
            'CustomerRequirement'
        ]

    def to_representation(self, instance):
        response_data = super().to_representation(instance)

        product_data = response_data.pop('product_data')
        customer_requirement = response_data.pop('CustomerRequirement')

        response_data['Packaging'] = product_data.get('Packaging', None)
        
        # ---CUSTOMER BASED REQUIREMENTS----
        response_data['SampleRequiredCustomer'] = customer_requirement.get('samples_required', False)
        response_data['IsContainerRequired'] = customer_requirement.get('requires_container_number', False)
        response_data['NeedMDGD'] = customer_requirement.get('is_outside_european_union', False)
        response_data['NeedVGM'] = customer_requirement.get('need_vgm_form', False)
        response_data['NeedReturnMDGD'] = customer_requirement.get('need_return_mdgd_form', False)
        
        confirmation_mail_not_needed = customer_requirement.get('customer_confirmation_mail_not_required', False)
        response_data['NeedCOC'] = False if confirmation_mail_not_needed else True
        response_data['NeedCustomerMail'] = False if confirmation_mail_not_needed else True

        return response_data
    
    def get_product_data(self, obj):
        """function returns product details"""
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {})
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_field_value_or_empty(self, obj, field_name):
        """
        Utility function to check if a field value is None.
        If the field is None, return an empty string.
        Otherwise, return the field's value.
        """
        return getattr(obj, field_name, "") if getattr(obj, field_name, None) is not None else ""

    def get_CustomerRequirement(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedBy)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None

        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        update_customer_requirement_data(
            ordered_by['exact_erp_address_id'], obj.ProductId, customer_requirement)

        return customer_requirement.get('data') if customer_requirement else None

    
    
    # def get_SampleRequiredCustomer(self, obj):
    #     """Function to return weather customer requires sample"""
    #     ordered_by = fetch_data.get_address_data(obj.OrderedBy)
    #     product_data = fetch_data.get_product_data(obj.ProductId)
    #     customer_requirement = None

    #     try:
    #         customer_requirement = fetch_data.get_odoo_customer_requirement_data(
    #             ordered_by['exact_erp_address_id'], product_data['article_code'])
    #     except Exception as e:
    #         raise APIException(f"Odoo API failed: {str(e)}")

    #     if customer_requirement:
    #         is_sample_required = customer_requirement.get('data').get('samples_required')
    #         if is_sample_required:
    #             return True
    #         else:
    #             return False
    #     else:
    #         return False
        
    # def get_IsContainerRequired(self, obj):
    #     """function checks weather order requires container no or not"""
    #     ordered_by = fetch_data.get_address_data(obj.OrderedBy)
    #     product_data = fetch_data.get_product_data(obj.ProductId)
    #     customer_requirement = None

    #     try:
    #         customer_requirement = fetch_data.get_odoo_customer_requirement_data(
    #             ordered_by['exact_erp_address_id'], product_data['article_code'])
    #     except Exception as e:
    #         raise APIException(f"Odoo API failed: {str(e)}")

    #     if customer_requirement:
    #         requirement = customer_requirement.get('data').get('requires_container_number')
    #         if requirement:
    #             return True
    #         else:
    #             return False
    #     else:
    #         return False
    
    # def get_NeedMDGD(self, obj):
    #     """function checks weather customer is outside EU and need MDGD form"""

    #     ordered_by_id = obj.OrderedBy
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, IsOutSideEU=True)
    #     if requirement.last():
    #         return  True

    #     return False

    # def get_NeedReturnMDGD(self, obj):
    #     """function checks weather customer is outside EU and need MDGD form"""

    #     ordered_by_id = obj.OrderedBy
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, IsOutSideEU=True, NeedReturnMDGD=True)
    #     if requirement.last():
    #         return  True

    #     return False
    
    # def get_NeedVGM(self, obj):
    #     """function checks weather customer is outside EU and need VGM form"""
    #     ordered_by_id = obj.OrderedBy
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, NeedVGM=True)
    #     if requirement.last():
    #         return  True

    #     return False

    # def get_NeedCustomerMail(self, obj):
    #     """function checks customer confiration mail needs to send"""

    #     ordered_by_id = obj.OrderedBy
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, NoCustomerEmailRequired=True)
    #     if requirement.last():
    #         return  False

    #     return True

    # def get_NeedCOC(self, obj):
    #     """function checks customer confiration mail needs to send"""

    #     ordered_by_id = obj.OrderedBy
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, NoCustomerEmailRequired=True)
    #     if requirement.last():
    #         return  False

    #     return True

    
    def get_ExactOrderNo(self, obj):
        return self.get_field_value_or_empty(obj, 'ExactOrderNo')

    def get_CustomerName(self, obj):
        ship_to_id = obj.OrderedBy
        customer_query = 'select CustomerName from AddressMaster WHERE Id = %s'
        with connection.cursor() as cursor:
            cursor.execute(customer_query, [ship_to_id])
            customer = cursor.fetchone()
        if customer:
            customer_name = customer[0]
        return customer_name

    def get_ProductId(self, obj):
        return self.get_field_value_or_empty(obj, 'ProductId')

    def get_Quantity(self, obj):
        return self.get_field_value_or_empty(obj, 'Quantity')

    def get_DeliveryTime(self, obj):
        return self.get_field_value_or_empty(obj, 'DeliveryTime')

    def get_DeliveryTimeInterval(self, obj):
        return self.get_field_value_or_empty(obj, 'DeliveryTimeInterval')

    def get_PurchaseOrderNo(self, obj):
        return self.get_field_value_or_empty(obj, 'PurchaseOrderNo')

    def get_OrderedBy(self, obj):
        return self.get_field_value_or_empty(obj, 'OrderedBy')

    def get_DeliverTo(self, obj):
        return self.get_field_value_or_empty(obj, 'DeliverTo')

    def get_BillTo(self, obj):
        return self.get_field_value_or_empty(obj, 'BillTo')

    def get_IncoTermsId(self, obj):
        return self.get_field_value_or_empty(obj, 'IncoTermsId')

    def get_LoadPointId(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadPointId')

    def get_LoadReference(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadReference')

    def get_ProductName(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {}).get('NickName', None)
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_ProductArticleCode(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {}).get('ArticleCode', None)
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_company(self, address_id):
        api_url = settings.CUSTOMER_API_URL + "customers/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"address_id": address_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                result = response.json()
                address_data = result['data']
                return f"{address_data['ExactERPAddressId']}  {address_data['CustomerName']} - {address_data['City']}"
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            return ""

    def get_OrderedCompany(self, obj):
        if not obj.OrderedBy:
            return ""
        company = self.get_company(obj.OrderedBy)
        return company

    def get_address(self, address_id):
        api_url = settings.CUSTOMER_API_URL + "customers/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"address_id": address_id}  # Assuming OrderedBy is the address identifier
        try:
            # Sending POST request to the external API
            response = requests.post(api_url, json=payload, headers=headers)

            # If the response is successful (status code 200)
            if response.status_code == 200:
                data = response.json()

                # Extract the address fields from the response
                address_data = data.get('data', {})
                address_line1 = address_data.get('AddressLine1', '')
                address_line2 = address_data.get('AddressLine2', '')
                city = address_data.get('City', '')
                state = address_data.get('State', '')
                country = address_data.get('Country', '')
                postal_code = address_data.get('PostalCode', '')

                full_address = ', '.join([
                    str(field) for field in [
                        address_line1, address_line2, city, state, country, postal_code
                    ] if field  # Only include non-empty fields
                ])

                # Remove any unnecessary commas (in case some fields are empty)
                return full_address.strip(', ')

            # If response status code is not 200, return None
            else:
                return ""
        except requests.RequestException as e:
            # Handle any exception that occurs during the API request
            print(f"An error occurred: {e}")
            return ""

    def get_OrderedAddress(self, obj):
        if not obj.OrderedBy:
            return ""
        address = self.get_address(obj.OrderedBy)
        return address

    def get_DeliveryCompany(self, obj):
        if not obj.DeliverTo:
            return ""
        company = self.get_company(obj.DeliverTo)
        return company

    def get_DeliveryAddress(self, obj):
        if not obj.DeliverTo:
            return ""
        address = self.get_address(obj.DeliverTo)
        return address

    def get_BillableCompany(self, obj):
        if not obj.BillTo:
            return ""
        company = self.get_company(obj.BillTo)
        return company

    def get_BillAddress(self, obj):
        if not obj.BillTo:
            return ""
        address = self.get_address(obj.BillTo)
        return address

    def get_ContainerDetails(self, obj):
        """The sea leg and the three container appointments, or None.

        None means this order has no sea schedule - either it goes by road, or
        one was never entered. The screen shows the container block on transport
        mode, not on this, so an absent row is not an error.

        Leg 2 has no date or time of its own: that appointment is the order's own
        loading slot, so the screen mirrors LoadingDate and the loading time
        rather than reading them from here.
        """
        container = po_models.OrderContainerDetails.objects.filter(
            order_request=obj, IsDeleted=False
        ).first()
        if not container:
            return None
        return {
            'PortOfLoading': container.port_of_loading,
            'PortOfLoadingId': container.port_of_loading_id,
            'ShippingAgency': container.shipping_agency,
            'ShippingAgencyId': container.shipping_agency_id,
            'EstShipDeparture': container.est_ship_departure,
            'ContainerPickupDate': container.container_pickup_date,
            'ContainerPickupTime': container.container_pickup_time,
            'ContainerPickupPoint': container.container_pickup_point,
            'ContainerLoadLocation': container.container_load_location,
            'ContainerDropoffDate': container.container_dropoff_date,
            'ContainerDropoffTime': container.container_dropoff_time,
            'ContainerDropoffReference': container.container_dropoff_reference,
        }

    def get_LoadPointEmail(self, obj):
        """Where to reach whoever runs the loading site.

        Only meaningful for a third party station - a PVS site needs no request -
        but it is returned regardless and the screen decides, so the rule stays
        in one place.
        """
        return fetch_data.get_loadpoint_email(obj.LoadPointId)

    def get_HasOriginStatement(self, obj):
        """Whether the delivery address needs a statement of origin.

        Read from AddressMaster.HasOriginStatement on the DeliverTo address -
        the goods' destination is what decides the customs paperwork, not who
        placed the order or who is billed.
        """
        if obj.DeliverTo is None:
            return False
        address = fetch_data.get_address_data(obj.DeliverTo)
        if not address:
            return False
        return bool(address.get('has_origin_statement'))

    def get_IncoTerm(self, obj):
        if not obj.IncoTermsId:
            return ""
        api_url = settings.DELIVERY_API_URL + "incoterms/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"id": obj.IncoTermsId}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('Code', None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            return ""

    def get_LoadPoint(self, obj):
        if not obj.LoadPointId:
            return ""
        api_url = settings.DELIVERY_API_URL + "loadpoints/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"loadpoint_id": obj.LoadPointId}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('loadpoint_details', {}).get('LoadPointName', None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            return ""

    def get_CostCenter(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)

            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('CostCenter', None)
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_CostCenterId(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)

            if response.status_code == 200:
                data = response.json()
                costcenter_code = data.get('data', {}).get('CostCenter')
                if costcenter_code:
                    id = CostCenter.objects.filter(Code=costcenter_code).values_list('Id', flat=True).first()
                    return id
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def get_FormattedDeliveryDate(self, obj):
        # Convert the UpdatedOn datetime to the required format
        delivery_date = obj.DeliveryDate
        if delivery_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(delivery_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    delivery_date = datetime.strptime(delivery_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return delivery_date.strftime("%d.%m.%Y")
        return ""
    
    def get_InvoiceCode(self, obj):
        if os.environ.get('DJANGO_ENV') == 'staging':
            return "001"
        else:
            if obj.OrderedBy is not None and obj.DeliverTo is not None and obj.BillTo is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                request = self.context.get('request')
                headers = {
                    'x-api-key': os.getenv('API_KEY'),
                    'x-content-type': 'application/json',
                    'x-auth-token': request.headers.get('x-auth-token'),
                }
                payload = {"address_id": obj.OrderedBy}
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    result = response.json()
                    address_data = result['data']
                    ordered_id = address_data['ExactERPAddressId']
                else:
                    return "001"
                api_url = settings.CUSTOMER_API_URL + "customers/"
                request = self.context.get('request')
                headers = {
                    'x-api-key': os.getenv('API_KEY'),
                    'x-content-type': 'application/json',
                    'x-auth-token': request.headers.get('x-auth-token'),
                }
                payload = {"address_id": obj.DeliverTo}
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    result = response.json()
                    address_data = result['data']
                    deliver_to_id = address_data['ExactERPAddressId']
                else:
                    return "001"
                api_url = settings.CUSTOMER_API_URL + "customers/"
                request = self.context.get('request')
                headers = {
                    'x-api-key': os.getenv('API_KEY'),
                    'x-content-type': 'application/json',
                    'x-auth-token': request.headers.get('x-auth-token'),
                }
                payload = {"address_id": obj.BillTo}
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    result = response.json()
                    address_data = result['data']
                    bill_to_id = address_data['ExactERPAddressId']
                else:
                    return "001"
                if ordered_id is not None and deliver_to_id is not None and bill_to_id is not None:
                    if ordered_id==2324 and deliver_to_id==2324 and bill_to_id==2323:
                        return "010"

                    with connections['secondary'].cursor() as cursor:
                        # SQL query to fetch the result using f-string for formatting
                        query = f"select top(1) fakt_code from [101].dbo.orkrg where TRIM(debnr)={ordered_id} and TRIM(verzdebnr)={deliver_to_id} and TRIM(fakdebnr) ={bill_to_id} ORDER BY syscreated DESC"
                        cursor.execute(query)
                        result = cursor.fetchone()
                        # Check if result is not None and return the value
                        if result and result[0] is not None:
                            return result[0]  # Accessing the first column (TextField26) in the result tuple
                        else:
                            return "001"
                return "001"
            return "001"
        
    def get_ExactOrderedAddressId(self, obj):

        if obj.OrderedBy is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            request = self.context.get('request')
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
                'x-auth-token': request.headers.get('x-auth-token'),
            }
            payload = {"address_id": obj.OrderedBy}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    result = response.json()
                    address_data = result['data']
                    return address_data['ExactERPAddressId']
                else:
                    return ""
            except requests.RequestException as e:
                return ""
        return ""
    def get_FormattedLoadingDate(self, obj):
        # Convert the UpdatedOn datetime to the required format
        loading_date = obj.LoadingDate
        if loading_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(loading_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    loading_date = datetime.strptime(loading_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return loading_date.strftime("%d.%m.%Y")
        return ""
    

class OrderRequestFileSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderRequestFiles
        fields = ['Id', 'OrderId', 'FileName']


class OrderInitiateSerializer(serializers.ModelSerializer):
    ProductName = serializers.SerializerMethodField()
    OrderedCompany = serializers.SerializerMethodField()
    OrderedAddress = serializers.SerializerMethodField()
    DeliveryCompany = serializers.SerializerMethodField()
    DeliveryAddress = serializers.SerializerMethodField()
    BillableCompany = serializers.SerializerMethodField()
    BillAddress = serializers.SerializerMethodField()
    IncoTerm = serializers.SerializerMethodField()
    LoadPoint = serializers.SerializerMethodField()

    class Meta:
        model = OrderRequests
        fields = [
            'Id',
            'ExactOrderNo',
            'ProductId',
            'ProductName',
            'Quantity',
            'DeliveryDate',
            'PurchaseOrderNo',
            'OrderedBy',
            'OrderedCompany',
            'OrderedAddress',
            'DeliverTo',
            'DeliveryCompany',
            'DeliveryAddress',
            'BillTo',
            'BillableCompany',
            'BillAddress',
            'IncoTermsId',
            'IncoTerm',
            'LoadPointId',
            'LoadPoint',
            'LoadReference',
            'IsOrder'
        ]

    def get_ProductName(self, obj):
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}

        try:
            response = requests.post(api_url, json=payload, headers=headers)

            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('NickName', None)
            else:
                return None
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return None

    def get_company(self, address_id):
        api_url = settings.CUSTOMER_API_URL + "customers/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"address_id": address_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('CustomerName', None)
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            return None

    def get_OrderedCompany(self, obj):
        if not obj.OrderedBy:
            return None
        company = self.get_company(obj.OrderedBy)
        return company

    def get_address(self, address_id):
        api_url = settings.CUSTOMER_API_URL + "customers/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"address_id": address_id}  # Assuming OrderedBy is the address identifier
        try:
            # Sending POST request to the external API
            response = requests.post(api_url, json=payload, headers=headers)

            # If the response is successful (status code 200)
            if response.status_code == 200:
                data = response.json()

                # Extract the address fields from the response
                address_data = data.get('data', {})
                address_line1 = address_data.get('AddressLine1', '')
                address_line2 = address_data.get('AddressLine2', '')
                city = address_data.get('City', '')
                state = address_data.get('State', '')
                country = address_data.get('Country', '')
                postal_code = address_data.get('PostalCode', '')

                full_address = ', '.join([
                    str(field) for field in [
                        address_line1, address_line2, city, state, country, postal_code
                    ] if field  # Only include non-empty fields
                ])

                # Remove any unnecessary commas (in case some fields are empty)
                return full_address.strip(', ')

            # If response status code is not 200, return None
            else:
                return None
        except requests.RequestException as e:
            # Handle any exception that occurs during the API request
            print(f"An error occurred: {e}")
            return None

    def get_OrderedAddress(self, obj):
        if not obj.OrderedBy:
            return None
        address = self.get_address(obj.OrderedBy)
        return address

    def get_DeliveryCompany(self, obj):
        if not obj.DeliverTo:
            return None
        company = self.get_company(obj.DeliverTo)
        return company

    def get_DeliveryAddress(self, obj):
        if not obj.DeliverTo:
            return None
        address = self.get_address(obj.DeliverTo)
        return address

    def get_BillableCompany(self, obj):
        if not obj.BillTo:
            return None
        company = self.get_company(obj.BillTo)
        return company

    def get_BillAddress(self, obj):
        if not obj.BillTo:
            return None
        address = self.get_address(obj.BillTo)
        return address

    def get_IncoTerm(self, obj):
        if not obj.IncoTermsId:
            return None
        api_url = settings.DELIVERY_API_URL + "incoterms/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"id": obj.IncoTermsId}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('Code', None)
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            return None

    def get_LoadPoint(self, obj):
        if not obj.LoadPointId:
            return None
        api_url = settings.DELIVERY_API_URL + "loadpoints/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"loadpoint_id": obj.LoadPointId}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get('LoadPointName', None)
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            return None


# Function to fetch product data from the Product API based on ProductName
def get_product_id_by_name(auth_token, product_name):
    product_api_url = settings.PRODUCT_API_URL + "search_products/"  # Replace with actual Product API URL
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"search_query": product_name}
    try:
        response = requests.post(product_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            response_data = response.json()
            if response_data['data']:
                data_list = response_data.get('data', [])
                product_ids = [item.get('Id') for item in data_list]
                return product_ids
            else:
                return None
        else:
            return None
    except requests.RequestException as e:
        print(f"Error fetching product data: {e}")
        return None


# Function to fetch address data from the Address API based on the address query (e.g., OrderedCompany or OrderedAddress)
def get_address_ids_by_query(auth_token, query):
    address_api_url = settings.CUSTOMER_API_URL + "search_address/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"search_query": query}
    try:
        response = requests.post(address_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            data = response.json()
            address_ids = data.get('address_ids', [])  # Extract address IDs
            return address_ids
        else:
            print(f" addressAPI returned an error: {response.status_code} - {response.text}")
            return []
    except requests.RequestException as e:
        print(f"Error fetching address data: {e}")
        return []


def get_address_with_id(auth_token, address_id):
    address_api_url = settings.CUSTOMER_API_URL + "customers/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"address_id": address_id}
    try:
        response = requests.post(address_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            response_data = response.json()
            return response_data['data']
        else:
            print(f" addressAPI returned an error: {response.status_code} - {response.text}")
            return []
    except requests.RequestException as e:
        print(f"Error fetching address data: {e}")
        return []


def get_allowed_loading_slots_for_product(auth_token, product_id, loadpoint_id):
    loading_slot_api_url = settings.DELIVERY_API_URL + "get_loading_slots_for_product/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"product_id": product_id, 'load_point_id': loadpoint_id}
    try:
        response = requests.post(loading_slot_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            slot_data = response.json()
            extracted_data = [{"Id": item["Id"], "Slot": item["Slot"]} for item in slot_data["data"]]
            return extracted_data
        else:
            print(f"loadingslotAPI returned an error: {response.status_code} - {response.text}")
            return []
    except requests.RequestException as e:
        print(f"Error fetching slots data: {e}")
        return []


def get_available_transporters(auth_token, product_id, loadpoint_id, delivery_address_id, packaging_type, inco_term_id):
    loading_slot_api_url = settings.DELIVERY_API_URL + "get_available_transporters/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"product_id": product_id, 'load_point_id': loadpoint_id, 'delivery_address_id': delivery_address_id,
               'packaging_type': packaging_type, 'inco_term_id': inco_term_id}
    try:
        response = requests.post(loading_slot_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            transporter_data = response.json()
            extracted_data = [{"TransporterId": item["TransporterId"], "Transporter": item["Transporter"],
                               "TransportPriceId": item["PriceId"], "TransportPrice": item["TransportingPrice"]} for
                              item in transporter_data["data"]]
            return extracted_data
        else:
            print(f"transporter API returned an error: {response.status_code} - {response.text}")
            return []
    except requests.RequestException as e:
        print(f"Error fetching transporter data: {e}")
        return []


def get_preferred_delivery_time(auth_token,
                                delivery_address_id):  # fetch if any preferred time is there for customer's delivery address
    delivery_time_api_url = settings.CUSTOMER_API_URL + "customers/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"address_id": delivery_address_id}
    try:
        response = requests.post(delivery_time_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            address_data = response.json()
            extracted_data = {
                "PreferredDTime": address_data["data"].get("PreferredDeliveryTime"),
                "PreferredDTimeInterval": address_data["data"].get("PreferredDeliveryTimeInterval"),
            }
            return extracted_data
        else:
            print(f"delivery time API returned an error: {response.status_code} - {response.text}")
            return []
    except requests.RequestException as e:
        print(f"Error fetching address data: {e}")
        return []


def get_loading_datetime(auth_token, load_point_id,
                         delivery_address_id):  # fetch if any preferred time is there for customer's delivery address
    loading_datetime_api_url = settings.DELIVERY_API_URL + "get_loading_time/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"load_point_id": load_point_id, "destination_id": delivery_address_id}
    try:
        response = requests.post(loading_datetime_api_url, json=payload, headers=headers)
        if response.status_code == 200:
            loading_data = response.json()
            extracted_data = {
                "DateOffset": loading_data["data"].get("PreferredLoadingDateOffset"),
                "LoadingTime": loading_data["data"].get("PreferredLoadingTime"),
            }
            return extracted_data
        else:
            print(f" loading time API returned an error: {response.status_code} - {response.text}")
            return None
    except requests.RequestException as e:
        print(f"Error fetching loading data: {e}")
        return None


class OrderHistorySerializer(serializers.ModelSerializer):
    UserName = serializers.SerializerMethodField()
    UpdatedOn = serializers.SerializerMethodField()

    class Meta:
        model = OrderHistory
        fields = ['Updation', 'UpdatedBy', 'UpdatedOn', 'UserName']

    def get_UserName(self, obj):
        api_url = settings.USER_API_URL + "users/"
        request = self.context.get('request')  # Get the request context
        if request is None:
            return None
        if obj.UpdatedBy != 0:
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
            }

            # Safely get the auth token
            auth_token = request.headers.get('x-auth-token', None)
            if auth_token:
                headers['x-auth-token'] = auth_token

            payload = {"user_id": obj.UpdatedBy}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    data = response.json()
                    # Concatenate FirstName and LastName
                    first_name = data.get('data', {}).get('FirstName', None)
                    last_name = data.get('data', {}).get('LastName', None)
                    # Ensure both fields are non-null before concatenation
                    if first_name and last_name:
                        return first_name + " " + last_name
                    elif first_name:
                        return first_name
                    elif last_name:
                        return last_name
                    else:
                        return None
                else:
                    return None
            except requests.RequestException as e:
                print(f"An error occurred: {e}")
                return None
        else:
            return "System"

    def get_UpdatedOn(self, obj):
        # Convert the UpdatedOn datetime to the required format
        updated_on = obj.UpdatedOn
        if updated_on:
            # Format the datetime to 'dd.mm.YYYY HH:ii: AM/PM'
            return updated_on.strftime("%d.%m.%Y %I:%M:%S %p")
        return None


class OrderSerializer(serializers.ModelSerializer):
    DeliveryDate = serializers.SerializerMethodField()

    class Meta:
        model = OrderRequests
        fields = ['Id', 'DeliveryDate']

    def get_DeliveryDate(self, obj):
        # Convert the UpdatedOn datetime to the required format
        delivery_date = obj.DeliveryDate
        if delivery_date:
            return delivery_date.strftime("%d.%m.%Y")
        return None


# class OrderDetailsSerializer(serializers.ModelSerializer):
#     TransporterName = serializers.SerializerMethodField()
#     FormattedCreatedAt = serializers.SerializerMethodField()
#     class Meta:
#         model = Orders
#         fields = ['LoadingDate', 'LoadingTime','LoadingSlotId','LoadingSlot','TransporterId','TransporterName','CostCenterId','CostCenter','Price','Quarter','TotalPrice','CreatedAt','FormattedCreatedAt','StatusId']

#     def get_TransporterName(self, obj):
#         api_url = settings.DELIVERY_API_URL + "get_transporters/"
#         request = self.context.get('request')
#         headers = {
#             'x-api-key': os.getenv('API_KEY'),
#             'x-content-type': 'application/json',
#             'x-auth-token': request.headers.get('x-auth-token'),
#         }
#         payload = {"transporter_id": obj.TransporterId}
#         try:
#             response = requests.post(api_url, json=payload, headers=headers)
#             if response.status_code == 200:
#                 data = response.json()
#                 return data.get('data', {}).get('Transporter', None)
#             else:
#                 return None
#         except requests.RequestException as e:
#             print(f"An error occurred: {e}")
#             return None
#     def get_FormattedCreatedAt(self, obj):
#         # Convert the UpdatedOn datetime to the required format
#         created_date = obj.CreatedAt
#         if created_date:
#             # Format the datetime to 'dd.mm.YYYY HH:ii: AM/PM'
#             return created_date.strftime("%d.%m.%Y")
#         return None

class OrderDetailsSerializer(serializers.ModelSerializer):
    LoadingDate = serializers.SerializerMethodField()
    LoadingTime = serializers.SerializerMethodField()
    LoadingSlot = serializers.SerializerMethodField()
    LoadingSlotId = serializers.SerializerMethodField()
    TransporterId = serializers.SerializerMethodField()
    TransporterName = serializers.SerializerMethodField()
    FormattedCreatedAt = serializers.SerializerMethodField()
    CostCenterId = serializers.SerializerMethodField()
    CostCenter = serializers.SerializerMethodField()
    Price = serializers.SerializerMethodField()
    Quarter = serializers.SerializerMethodField()
    TotalPrice = serializers.SerializerMethodField()
    CreatedAt = serializers.SerializerMethodField()
    StatusId = serializers.SerializerMethodField()
    LoadingStationReference = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = ['LoadingDate', 'LoadingTime', 'LoadingSlotId', 'LoadingSlot', 'TransporterId', 'TransporterName',
                  'CostCenterId', 'CostCenter', 'Price', 'Quarter', 'TotalPrice', 'CreatedAt', 'FormattedCreatedAt',
                  'StatusId', 'Remarks', 'PaymentTerm','TransportPrice','InvoiceCode', 'NeedSample', 'SampleReason',
                  'CourierDate', 'CourierTime', 'CourierPickupDate', 'CourierPickupTime', 'SampleOrderRef', 
                  'LoadingStationReference']

    def get_field_value_or_empty(self, obj, field_name):
        """
        Utility function to check if a field value is None.
        If the field is None, return an empty string.
        Otherwise, return the field's value.
        """
        return getattr(obj, field_name, "") if getattr(obj, field_name, None) is not None else ""

    def get_LoadingDate(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadingDate')

    def get_LoadingTime(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadingTime')

    def get_LoadingSlot(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadingSlot')

    def get_LoadingSlotId(self, obj):
        return self.get_field_value_or_empty(obj, 'LoadingSlotId')

    def get_TransporterId(self, obj):
        return self.get_field_value_or_empty(obj, 'TransporterId')

    def get_CostCenterId(self, obj):
        return self.get_field_value_or_empty(obj, 'CostCenterId')

    def get_CostCenter(self, obj):
        return self.get_field_value_or_empty(obj, 'CostCenter')

    def get_Price(self, obj):
        return self.get_field_value_or_empty(obj, 'Price')

    def get_Quarter(self, obj):
        return self.get_field_value_or_empty(obj, 'Quarter')

    def get_TotalPrice(self, obj):
        return self.get_field_value_or_empty(obj, 'TotalPrice')

    def get_CreatedAt(self, obj):
        return self.get_field_value_or_empty(obj, 'CreatedAt')

    def get_StatusId(self, obj):
        return self.get_field_value_or_empty(obj, 'StatusId')

    def get_TransporterName(self, obj):
        if obj.TransporterId is not None and obj.TransporterId != '' and obj.TransporterId != 0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            request = self.context.get('request')
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
                'x-auth-token': request.headers.get('x-auth-token'),
            }
            payload = {"transporter_id": obj.TransporterId}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    data = response.json()
                    return data.get('data', {}).get('Transporter', None)
                else:
                    return ""
            except requests.RequestException as e:
                print(f"An error occurred: {e}")
                return ""
        else:
            return ""

    def get_FormattedCreatedAt(self, obj):
        # Convert the UpdatedOn datetime to the required format
        created_date = obj.CreatedAt
        if created_date:
            # Format the datetime to 'dd.mm.YYYY HH:ii: AM/PM'
            return created_date.strftime("%d.%m.%Y")
        return ""
    
    def get_LoadingStationReference(self, obj):
        # Convert the UpdatedOn datetime to the required format
        order_request_id = obj.OrderNo

        load_point_master = fetch_data.get_loadpoint_data(order_request_id)
        if load_point_master and load_point_master['required_reference_no']:
            return obj.StationReference if obj.StationReference else ''

        return None



class OrderStatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderStatus
        fields = ['OrderStatusId', 'Status', 'Remarks']


def get_address_details_from_id(auth_token,
                                address_id):  # fetch if any preferred time is there for customer's delivery address
    address_api = settings.CUSTOMER_API_URL + "customers/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"address_id": address_id}
    try:
        response = requests.post(address_api, json=payload, headers=headers)
        if response.status_code == 200:
            address_data = response.json()
            address_parts = []
            if address_data["data"].get("AddressLine1"):
                address_parts.append(address_data["data"].get("AddressLine1"))
            if address_data["data"].get("AddressLine2"):
                address_parts.append(address_data["data"].get("AddressLine2"))
            if address_data["data"].get("PostalCode"):
                address_parts.append(address_data["data"].get("PostalCode"))
            if address_data["data"].get("City"):
                address_parts.append(address_data["data"].get("City"))

            address = ",".join(address_parts)
            extracted_data = {
                "CustomerId": address_data["data"].get("Id"),
                "CustomerName": address_data["data"].get("CustomerNickName"),
                "CustomerAddress": address,
                "ExactERPAddressId":address_data["data"].get("ExactERPAddressId")
            }
            return extracted_data
        else:
            print(f" address  API returned an error: {response.status_code} - {response.text}")
            return []
    except requests.RequestException as e:
        print(f"Error fetching address data: {e}")
        return []


class UpdateOrderStatusSerializer(serializers.Serializer):
    order_status = serializers.IntegerField()
    updated_by = serializers.IntegerField()


class OrderXMLSerializer(serializers.ModelSerializer):
    ResourceNo = serializers.SerializerMethodField()
    ResourceCode = serializers.SerializerMethodField()
    ResourceFirstName = serializers.SerializerMethodField()
    ResourceLastName = serializers.SerializerMethodField()
    OrderedByDebtorCode = serializers.SerializerMethodField()
    OrderedByCompany = serializers.SerializerMethodField()
    OrderedByContactPerson = serializers.SerializerMethodField()
    OrderedByJobDescription = serializers.SerializerMethodField()
    OrderedByAddressLine1 = serializers.SerializerMethodField()
    OrderedByAddressLine2 = serializers.SerializerMethodField()
    OrderedByAddressLine3 = serializers.SerializerMethodField()
    OrderedByPostalCode = serializers.SerializerMethodField()
    OrderedByCity = serializers.SerializerMethodField()
    OrderedByStateCode = serializers.SerializerMethodField()
    OrderedByCountryCode = serializers.SerializerMethodField()
    OrderedByPhone = serializers.SerializerMethodField()
    OrderedByFax = serializers.SerializerMethodField()
    OrderedEmail = serializers.SerializerMethodField()
    DeliveryDebtorCode = serializers.SerializerMethodField()
    DeliveryCompany = serializers.SerializerMethodField()
    DeliveryContactPerson = serializers.SerializerMethodField()
    DeliveryJobDescription = serializers.SerializerMethodField()
    DeliveryAddressLine1 = serializers.SerializerMethodField()
    DeliveryAddressLine2 = serializers.SerializerMethodField()
    DeliveryAddressLine3 = serializers.SerializerMethodField()
    DeliveryPostalCode = serializers.SerializerMethodField()
    DeliveryCity = serializers.SerializerMethodField()
    DeliveryStateCode = serializers.SerializerMethodField()
    DeliveryCountryCode = serializers.SerializerMethodField()
    DeliveryPhone = serializers.SerializerMethodField()
    DeliveryFax = serializers.SerializerMethodField()
    DeliveryEmail = serializers.SerializerMethodField()
    InvoiceToDebtorCode = serializers.SerializerMethodField()
    InvoiceToCompany = serializers.SerializerMethodField()
    InvoiceToContactPerson = serializers.SerializerMethodField()
    InvoiceToJobDescription = serializers.SerializerMethodField()
    InvoiceToAddressLine1 = serializers.SerializerMethodField()
    InvoiceToAddressLine2 = serializers.SerializerMethodField()
    InvoiceToAddressLine3 = serializers.SerializerMethodField()
    InvoiceToPostalCode = serializers.SerializerMethodField()
    InvoiceToCity = serializers.SerializerMethodField()
    InvoiceToStateCode = serializers.SerializerMethodField()
    InvoiceToCountryCode = serializers.SerializerMethodField()
    InvoiceToPhone = serializers.SerializerMethodField()
    InvoiceToFax = serializers.SerializerMethodField()
    InvoiceToEmail = serializers.SerializerMethodField()
    LPCode = serializers.SerializerMethodField()
    LPName = serializers.SerializerMethodField()
    LPAddressLine1 = serializers.SerializerMethodField()
    LPAddressLine2 = serializers.SerializerMethodField()
    LPAddressLine3 = serializers.SerializerMethodField()
    LPPostalCode = serializers.SerializerMethodField()
    LPCity = serializers.SerializerMethodField()
    LPCountryCode = serializers.SerializerMethodField()
    LPPhone = serializers.SerializerMethodField()
    LPFax = serializers.SerializerMethodField()
    LPEmail = serializers.SerializerMethodField()
    IncoTerm = serializers.SerializerMethodField()
    IncoTermDesc = serializers.SerializerMethodField()
    CostCenter = serializers.SerializerMethodField()
    CostCenterDesc = serializers.SerializerMethodField()
    TransporterName = serializers.SerializerMethodField()
    TransporterCode = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = ['ExactOrderNo', 'ResourceNo', 'ResourceCode', 'ResourceFirstName', 'ResourceLastName',
                  'OrderedByDebtorCode', 'OrderedByCompany', 'OrderedByContactPerson', 'OrderedByJobDescription',
                  'OrderedByAddressLine1', 'OrderedByAddressLine2', 'OrderedByAddressLine3', 'OrderedByPostalCode',
                  'OrderedByCity', 'OrderedByStateCode', 'OrderedByCountryCode', 'OrderedByPhone', 'OrderedByPhone',
                  'OrderedByFax', 'OrderedEmail', 'UpdatedAt',
                  'DeliveryDebtorCode', 'DeliveryCompany', 'DeliveryContactPerson', 'DeliveryJobDescription',
                  'DeliveryAddressLine1', 'DeliveryAddressLine2', 'DeliveryAddressLine3', 'DeliveryPostalCode',
                  'DeliveryCity', 'DeliveryStateCode', 'DeliveryCountryCode', 'DeliveryPhone', 'DeliveryPhone',
                  'DeliveryFax', 'DeliveryEmail',
                  'InvoiceToDebtorCode', 'InvoiceToCompany', 'InvoiceToContactPerson', 'InvoiceToJobDescription',
                  'InvoiceToAddressLine1', 'InvoiceToAddressLine2', 'InvoiceToAddressLine3', 'InvoiceToPostalCode',
                  'InvoiceToCity', 'InvoiceToStateCode', 'InvoiceToCountryCode', 'InvoiceToPhone', 'InvoiceToPhone',
                  'InvoiceToFax', 'InvoiceToEmail',
                  'LPCode', 'LPName', 'LPAddressLine1', 'LPAddressLine2', 'LPAddressLine2', 'LPAddressLine3',
                  'LPPostalCode', 'LPCity', 'LPCountryCode', 'LPPhone', 'LPFax', 'LPEmail',  # LP:loadPoint
                  'IncoTerm', 'IncoTermDesc', 'CostCenter', 'CostCenterDesc',
                  'DeliveryDate', 'TransporterId', 'TransporterName', 'TransporterCode'
                  ]

    def get_ResourceNo(self, obj):
        user_data = self._get_user_data(obj)
        return user_data.get('ResourceNo') if user_data else None

    def get_ResourceCode(self, obj):
        user_data = self._get_user_data(obj)
        return user_data.get('ResourceCode') if user_data else None

    def get_ResourceFirstName(self, obj):
        user_data = self._get_user_data(obj)
        return user_data.get('FirstName') if user_data else None

    def get_ResourceLastName(self, obj):
        user_data = self._get_user_data(obj)
        return user_data.get('LastName') if user_data else None

    def _get_user_data(self, obj):
        # Fetch the most recent `UpdatedBy` for the order based on the conditions
        updated_by = OrderHistory.objects.filter(
            OrderRequestId=obj.OrderNo,
            IsDeleted=0,
            Updation__in=['Order Planned', 'Order Details Updated']
        ).order_by('-Id').values('UpdatedBy')[:1]
        if updated_by.exists():
            user_id = updated_by[0]['UpdatedBy']
            return self._fetch_user_info(user_id)
        return None

    def _fetch_user_info(self, user_id):
        api_url = settings.USER_API_URL + "users/"
        request = self.context.get('request')  # Get the request context
        if request is None:
            return None

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token
        payload = {"user_id": user_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                # Extract ResourceNo and ResourceCode from the response
                return {
                    'ResourceNo': data.get('data', {}).get('ResourceNo', None),
                    'ResourceCode': data.get('data', {}).get('ResourceCode', None),
                    'ResourceFirstName': data.get('data', {}).get('FirstName', None),
                    'ResourceLastName': data.get('data', {}).get('LastName', None)
                }
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred while fetching user info: {e}")
            return None

    def get_OrderedByDebtorCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('ExactERPAddressId') if address_data else None

    def _get_address_data(self, obj):
        # Fetch the most recent `UpdatedBy` for the order based on the conditions
        ordered_by = OrderRequests.objects.filter(
            Id=obj.OrderNo,
            IsDeleted=0,
        ).values('OrderedBy').first()
        ordered_address_id = ordered_by['OrderedBy']
        return self._fetch_order_info(ordered_address_id)

    def _fetch_order_info(self, address_id):
        api_url = settings.CUSTOMER_API_URL + "customers/"
        request = self.context.get('request')  # Get the request context
        if request is None:
            return None
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }
        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token
        payload = {"address_id": address_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                # Extract ResourceNo and ResourceCode from the response
                return {
                    'ExactERPAddressId': data.get('data', {}).get('ExactERPAddressId', None),
                    'CustomerNickName': data.get('data', {}).get('CustomerNickName', None),
                    'ContactPerson': data.get('data', {}).get('ContactPerson', None),
                    'JobDescription': data.get('data', {}).get('JobDescription', None),
                    'AddressLine1': data.get('data', {}).get('AddressLine1', None),
                    'AddressLine2': data.get('data', {}).get('AddressLine2', None),
                    'AddressLine3': data.get('data', {}).get('AddressLine3', None),
                    'PostalCode': data.get('data', {}).get('PostalCode', None),
                    'City': data.get('data', {}).get('City', None),
                    'StateCode': data.get('data', {}).get('StateCode', None),
                    'CountryCode': data.get('data', {}).get('CountryCode', None),
                    'Phone': data.get('data', {}).get('Phone', None),
                    'Fax': data.get('data', {}).get('Fax', None),
                    'Email': data.get('data', {}).get('Email', None),
                }
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred while fetching address info: {e}")
            return None

    def get_OrderedByCompany(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('CustomerNickName') if address_data else None

    def get_OrderedByContactPerson(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('ContactPerson') if address_data else None

    def get_OrderedByJobDescription(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('JobDescription') if address_data else None

    def get_OrderedByAddressLine1(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine1') if address_data else None

    def get_OrderedByAddressLine2(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine2') if address_data else None

    def get_OrderedByAddressLine3(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine3') if address_data else None

    def get_OrderedByPostalCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('PostalCode') if address_data else None

    def get_OrderedByCity(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('City') if address_data else None

    def get_OrderedByStateCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('StateCode') if address_data else None

    def get_OrderedByCountryCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('CountryCode') if address_data else None

    def get_OrderedByPhone(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Phone') if address_data else None

    def get_OrderedByFax(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Fax') if address_data else None

    def get_OrderedEmail(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Email') if address_data else None

    def get_DeliveryDebtorCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('ExactERPAddressId') if address_data else None

    def get_DeliveryCompany(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('CustomerNickName') if address_data else None

    def get_DeliveryContactPerson(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('ContactPerson') if address_data else None

    def get_DeliveryJobDescription(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('JobDescription') if address_data else None

    def get_DeliveryAddressLine1(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine1') if address_data else None

    def get_DeliveryAddressLine2(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine2') if address_data else None

    def get_DeliveryAddressLine3(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine3') if address_data else None

    def get_DeliveryPostalCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('PostalCode') if address_data else None

    def get_DeliveryCity(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('City') if address_data else None

    def get_DeliveryStateCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('StateCode') if address_data else None

    def get_DeliveryCountryCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('CountryCode') if address_data else None

    def get_DeliveryPhone(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Phone') if address_data else None

    def get_DeliveryFax(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Fax') if address_data else None

    def get_DeliveryEmail(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Email') if address_data else None

    def get_InvoiceToDebtorCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('ExactERPAddressId') if address_data else None

    def get_InvoiceToCompany(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('CustomerNickName') if address_data else None

    def get_InvoiceToContactPerson(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('ContactPerson') if address_data else None

    def get_InvoiceToJobDescription(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('JobDescription') if address_data else None

    def get_InvoiceToAddressLine1(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine1') if address_data else None

    def get_InvoiceToAddressLine2(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine2') if address_data else None

    def get_InvoiceToAddressLine3(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('AddressLine3') if address_data else None

    def get_InvoiceToPostalCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('PostalCode') if address_data else None

    def get_InvoiceToCity(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('City') if address_data else None

    def get_InvoiceToStateCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('StateCode') if address_data else None

    def get_InvoiceToCountryCode(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('CountryCode') if address_data else None

    def get_InvoiceToPhone(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Phone') if address_data else None

    def get_InvoiceToFax(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Fax') if address_data else None

    def get_InvoiceToEmail(self, obj):
        address_data = self._get_address_data(obj)
        return address_data.get('Email') if address_data else None

    def _get_lp_data(self, obj):
        # Fetch the most recent `UpdatedBy` for the order based on the conditions
        load_point_data = OrderRequests.objects.filter(
            Id=obj.OrderNo,
            IsDeleted=0,
        ).values('LoadPointId').first()
        load_point_id = load_point_data['LoadPointId']
        return self._fetch_lp_info(load_point_id)

    def _fetch_lp_info(self, loadpoint_id):
        api_url = settings.DELIVERY_API_URL + "loadpoints/"
        request = self.context.get('request')  # Get the request context
        if request is None:
            return None

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token
        payload = {"loadpoint_id": loadpoint_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                # Extract ResourceNo and ResourceCode from the response
                return {
                    'LPCode': data.get('data', {}).get('loadpoint_details', {}).get('Code', None),
                    'LPName': data.get('data', {}).get('loadpoint_details', {}).get('LoadPointName', None),
                    'LPAddressLine1': data.get('data', {}).get('loadpoint_details', {}).get('AddressLine1', None),
                    'LPAddressLine2': data.get('data', {}).get('loadpoint_details', {}).get('AddressLine2', None),
                    'LPAddressLine3': data.get('data', {}).get('loadpoint_details', {}).get('AddressLine3', None),
                    'LPPostalCode': data.get('data', {}).get('loadpoint_details', {}).get('PostalCode', None),
                    'LPCountryCode': data.get('data', {}).get('loadpoint_details', {}).get('CountryCode', None),
                    'LPCity': data.get('data', {}).get('loadpoint_details', {}).get('LoadPointCity', None),
                    'LPPhone': data.get('data', {}).get('loadpoint_details', {}).get('Phone', None),
                    'LPFax': data.get('data', {}).get('loadpoint_details', {}).get('Fax', None),
                    'LPEmail': data.get('data', {}).get('loadpoint_details', {}).get('Email', None),
                }
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred while fetching user info: {e}")
            return None

    def get_LPName(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPName') if address_data else None

    def get_LPCode(self, obj):
        loading_slot_data = Orders.objects.filter(
            OrderNo=obj.OrderNo,
            IsDeleted=0,
        ).values('LoadingSlotId').first()
        api_url = settings.DELIVERY_API_URL + "loadpoints/"
        request = self.context.get('request')  # Get the request context
        if request is None:
            return None

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token
        payload = {"loading_slot_id": loading_slot_data['LoadingSlotId']}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                loading_slot_data = response.json()
                return loading_slot_data["data"].get("WareHouseCode")
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching user info: {e}")
            return ""

    def get_LPAddressLine1(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPAddressLine1') if address_data else None

    def get_LPAddressLine2(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPAddressLine2') if address_data else None

    def get_LPAddressLine3(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPAddressLine3') if address_data else None

    def get_LPPostalCode(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPPostalCode') if address_data else None

    def get_LPCity(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPCity') if address_data else None

    def get_LPCountryCode(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPCountryCode') if address_data else None

    def get_LPPhone(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPPhone') if address_data else None

    def get_LPFax(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPFax') if address_data else None

    def get_LPEmail(self, obj):
        address_data = self._get_lp_data(obj)
        return address_data.get('LPEmail') if address_data else None

    def _get_incoterm_data(self, obj):
        # Fetch the most recent `UpdatedBy` for the order based on the conditions
        incoterm_data = OrderRequests.objects.filter(
            Id=obj.OrderNo,
            IsDeleted=0,
        ).values('IncoTermsId').first()
        inco_term_id = incoterm_data['IncoTermsId']
        return self._fetch_incoterm_info(inco_term_id)

    def _fetch_incoterm_info(self, inco_term_id):
        api_url = settings.DELIVERY_API_URL + "incoterms/"
        request = self.context.get('request')  # Get the request context
        if request is None:
            return None

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token
        payload = {"inco_term_id": inco_term_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                # Extract ResourceNo and ResourceCode from the response
                return {
                    'IncoTerm': data.get('data', [{}])[0].get('Code', None),
                    'IncoTermDesc': data.get('data', [{}])[0].get('Remarks', None),
                }
            else:
                return None
        except requests.RequestException as e:
            print(f"An error occurred while fetching user info: {e}")
            return None

    def get_IncoTerm(self, obj):
        incoterm_data = self._get_incoterm_data(obj)
        return incoterm_data.get('IncoTerm') if incoterm_data else None

    def get_IncoTermDesc(self, obj):
        incoterm_data = self._get_incoterm_data(obj)
        return incoterm_data.get('IncoTermDesc') if incoterm_data else None

    def get_CostCenter(self, obj):
        cost_center = CostCenter.objects.filter(
            Id__in=Orders.objects.filter(OrderNo=obj.OrderNo).values('CostCenterId')).values(
            'Code').first()
        if cost_center:
            code = cost_center['Code']
            return code
        else:
            return None

    def get_CostCenterDesc(self, obj):
        cost_center = CostCenter.objects.filter(
            Id__in=Orders.objects.filter(OrderNo=obj.OrderNo).values('CostCenterId')).values(
            'Description').first()
        if cost_center:
            desc = cost_center['Description']
            return desc
        else:
            return None

    def get_TransporterName(self, obj):
        if obj.TransporterId is not None and obj.TransporterId != 0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            request = self.context.get('request')  # Get the request context
            if request is None:
                return None

            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
            }

            # Safely get the auth token
            auth_token = request.headers.get('x-auth-token', None)
            if auth_token:
                headers['x-auth-token'] = auth_token
            payload = {"transporter_id": obj.TransporterId}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    data = response.json()
                    return data.get('data', {}).get('Transporter', None)
                else:
                    return None
            except requests.RequestException as e:
                print(f"An error occurred while fetching user info: {e}")
                return None
        else:
            return None

    def get_TransporterCode(self, obj):
        if obj.TransporterId is not None and obj.TransporterId != 0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            request = self.context.get('request')  # Get the request context
            if request is None:
                return None

            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
            }

            # Safely get the auth token
            auth_token = request.headers.get('x-auth-token', None)
            if auth_token:
                headers['x-auth-token'] = auth_token
            payload = {"transporter_id": obj.TransporterId}
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    data = response.json()
                    return data.get('data', {}).get('Code', None)
                else:
                    return None
            except requests.RequestException as e:
                print(f"An error occurred while fetching user info: {e}")
                return None
        else:
            return None


def convert_to_number(price_str):
    """
    This function converts a string price with commas and points to a float.
    It replaces commas with points and ensures the string can be converted to a number.

    :param price_str: The price string to convert.
    :return: The numeric value (float) of the price, or 0.0 if conversion fails.
    """
    try:
        price_str = str(price_str)
        # Step 1: Replace commas with points (thousands separator)
        price_str = price_str.replace('.', '')

        # Step 2: Replace the decimal point with a period if necessary
        price_str = price_str.replace(',', '.')

        # Step 3: Convert to float
        return float(price_str)

    except ValueError:
        print("Error: Invalid price format.")
        return 0.0  # Return 0.0 if the conversion fails


def convert_to_belgium_format(price):
    try:
        price = float(price)
        price_str = str(int(price)) if price == int(price) else f"{price:.2f}"
        return price_str.replace('.', ',')
    except (ValueError, TypeError):
        print("Error: Invalid price format.")
        return 0.0  # Return 0.0 if the conversion fails


def get_previous_non_holiday(holiday_date_str): 
    # Convert holiday_date from string to datetime object
    holiday_date = datetime.strptime(holiday_date_str, "%Y-%m-%d")

    # Loop until a valid working day (not a holiday, not Saturday, not Sunday) is found
    while (
            OffDays.objects.filter(Date=holiday_date, IsDeleted=False).exists()  # Check if it's a holiday
            or holiday_date.weekday() in [5, 6]  # 5 = Saturday, 6 = Sunday
    ):
        holiday_date -= timedelta(days=1)  # Move to the previous day

    # Return the result as a string in "YYYY-MM-DD" format
    return holiday_date.strftime("%Y-%m-%d")


def is_date_a_holiday(holiday_date_str):
    # Convert holiday_date from string to datetime object
    holiday_date = datetime.strptime(holiday_date_str, "%Y-%m-%d")

    is_holiday = int(OffDays.objects.filter(Date=holiday_date, IsDeleted=False).exists())  # Check if it's a holiday

    return is_holiday


def check_is_delivery_on_holiday(holiday_date_str):
    # Convert holiday_date from string to datetime object
    holiday_date = datetime.strptime(holiday_date_str, "%Y-%m-%d")

    is_holiday = int(OffDays.objects.filter(Date=holiday_date, IsDeleted=False).exists())  # Check if it's a holiday

    return is_holiday


class ExtraChargeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ExtraCharges
        fields = ['Id', 'Name', 'Amount', 'IsExxon', 'ArticleCode']


class LoadListSerializer(serializers.ModelSerializer):
    TransporterName = serializers.SerializerMethodField()
    CustomerName = serializers.SerializerMethodField()
    ShipToCity = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    Product = serializers.SerializerMethodField()
    ArticleCode = serializers.SerializerMethodField()
    ShipToCode = serializers.SerializerMethodField()
    PurchaseOrderNo = serializers.SerializerMethodField()
    TNC = serializers.SerializerMethodField()
    IsADR = serializers.SerializerMethodField()
    ProductNameDutch = serializers.SerializerMethodField()
    IsCOCNeeded = serializers.SerializerMethodField()
    # IsCOANeeded = serializers.SerializerMethodField()
    # IsSealingReportNeeded = serializers.SerializerMethodField()
    # IsCleaningCertificateNeeded = serializers.SerializerMethodField()
    CustomerNickName = serializers.SerializerMethodField()
    FormattedProductName = serializers.SerializerMethodField()
    # Notes = serializers.SerializerMethodField()
    LoadPointCity = serializers.SerializerMethodField()
    ProductName = serializers.SerializerMethodField()
    LoadingStationReference = serializers.SerializerMethodField()
    Quantity = serializers.FloatField()
    # Instructions = serializers.SerializerMethodField()
    CustomerRequirementData = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = ['TransporterName', 'CustomerName', 'ShipToCity', 'LoadingSlot', 'LoadingDate', 'DeliveryDate',
                  'LoadingTime', 'DeliveryTimeInterval', 'Product', 'ArticleCode', 'Quantity', 'Remarks',
                  'ExactOrderNo', 'IncoTerm', 'ShipToCode', 'LoadReference', 'PurchaseOrderNo', 'TNC', 'IsADR',
                  'ProductNameDutch', 'IsCOCNeeded', 'CustomerNickName', 'FormattedProductName',
                  'LoadPoint','ProductName', 'ProductId', 'LoadPointCity', 'FillingDate', 'LoadingStationReference', 
                  'CustomerRequirementData']

    def to_representation(self, instance):
        response_data = super().to_representation(instance)

        customer_requirement = response_data.pop('CustomerRequirementData', None)
        req_data = customer_requirement.get('data') if isinstance(customer_requirement, dict) else None

        if req_data:
            response_data['Notes'] = req_data.get('instruction_texts', [])
            response_data['InstructionMasterURL'] = req_data.get('record_url')
        else:
            response_data['Notes'] = []
            create_url = customer_requirement.get('create_url') if isinstance(customer_requirement, dict) else None
            response_data['InstructionMasterURL'] = create_url

        return response_data

    def get_CustomerRequirementData(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedCustomerId)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None

        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        return customer_requirement if customer_requirement else None


    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None
        
    def get_LoadingStationReference(self, obj):
        # Convert the UpdatedOn datetime to the required format
        order_request_id = obj.OrderNo

        load_point_master = fetch_data.get_loadpoint_data(order_request_id)
        if load_point_master and load_point_master['required_reference_no']:
            return obj.StationReference if obj.StationReference else ''

        return None

    def get_TransporterName(self, obj):
        if obj.TransporterId is not None and obj.TransporterId != 0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'Transporter')
        return None

    def get_CustomerName(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'CustomerName')
        return ""

    def get_ShipToCity(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'City')
        return ""

    def get_DeliveryTimeInterval(self, obj):
        if obj.OrderNo is not None:
            delivery_time_interval = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'DeliveryTimeInterval', flat=True).first()
            return delivery_time_interval
        return ""

    def get_Product(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'FullName')
        return ""

    def get_ArticleCode(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ArticleCode')
        return ""

    def get_ShipToCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""

    def get_PurchaseOrderNo(self, obj):
        if obj.OrderNo is not None:
            po_number = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'PurchaseOrderNo', flat=True).first()
            return po_number
        return ""

    def get_TNC(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
            if articlecode is not None and obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                    request = self.context.get('request')
                    payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                    return self.fetch_api_data(api_url, payload, 'LoadListConditions')
                return ""
            return ""
        return ""

    def get_IsADR(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'IsADR')
        return ""

    def get_ProductNameDutch(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            product = self.fetch_api_data(api_url, payload, 'DU_FullName')
            if product:
                product = product.title().replace('Trading', '')
                return product.upper()
        return ""

    def get_IsCOCNeeded(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
            if articlecode is not None and obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                    request = self.context.get('request')
                    payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                    return self.fetch_api_data(api_url, payload, 'COCNeeded')
                return ""
            return ""
        return ""

    def get_IsCOANeeded(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
            if articlecode is not None and obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                    request = self.context.get('request')
                    payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                    return self.fetch_api_data(api_url, payload, 'COANeeded')
                return ""
            return ""
        return ""

    def get_IsSealingReportNeeded(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
            if articlecode is not None and obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                    request = self.context.get('request')
                    payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                    return self.fetch_api_data(api_url, payload, 'SealingReportNeeded')
                return ""
            return ""
        return ""

    def get_IsCleaningCertificateNeeded(self, obj):
        if os.environ.get('DJANGO_ENV') == 'staging':
            if obj.ProductId is not None:
                api_url = settings.PRODUCT_API_URL + "products/"
                payload = {"product_id": obj.ProductId}
                articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
                if articlecode is not None and obj.DeliveryCustomerId is not None:
                    api_url = settings.CUSTOMER_API_URL + "customers/"
                    payload = {"address_id": obj.DeliveryCustomerId}
                    shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                    if shiptocode is not None:
                        api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                        request = self.context.get('request')
                        payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                        return self.fetch_api_data(api_url, payload, 'CleaningCertificateNeeded')
                    return ""
                return ""
            return ""
        else:
            if obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')

                if shiptocode is not None:
                    with connections['secondary'].cursor() as cursor:
                        search_terms = ['reinigungszertifikat', 'spoelcertificaat', 'reinigingscertificaat',
                                        'reinigungszertifikat',
                                        'certificate de rincage', 'cleaning certificate']
                        columns = ['textField5', 'textField8', 'textField12', 'textField21', 'textField23',
                                   'textField24', 'textField19']

                        # Start building the query
                        query = "SELECT " + ", ".join(columns)
                        query += " FROM cicmpy WHERE "

                        # Build WHERE conditions
                        conditions = []
                        for column in columns:
                            for term in search_terms:
                                conditions.append(f"LOWER({column}) LIKE '%{term}%'")

                        # Join conditions with OR
                        query += " OR ".join(conditions)
                        query += f" AND TRIM(debnr) = {shiptocode};"

                        # Execute the query
                        cursor.execute(query)

                        # Fetch all rows
                        rows = cursor.fetchall()

                        # Check if any rows are returned
                        if rows:
                            for row in rows:
                                for cell in row:
                                    if cell:
                                        text = str(cell).lower()
                                        for term in search_terms:
                                            if term in text:
                                                return cell

                        return ""
                return ""
            return ""

    def get_CustomerNickName(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'CustomerNickName')
        return ""

    def get_FormattedProductName(self, obj):
        if obj.ProductId is not None:
            # api_url = settings.PRODUCT_API_URL + "products/"
            # payload = {"product_id": obj.ProductId}
            # request = self.context.get('request')  # Get the request context
            # if request is None:
            #     return ""
            # headers = {
            #     'x-api-key': os.getenv('API_KEY'),
            #     'x-content-type': 'application/json',
            #     'x-auth-token': request.headers.get('x-auth-token', None)
            # }
            # response = requests.post(api_url, json=payload, headers=headers)
            # if response.status_code == 200:
            #     data = response.json()
            #     chemical_name = data['data'].get('ChemicalName', '')
            #     dilution = str(data['data'].get('Dilution', ''))
            #     grade = data['data'].get('Grade', '')
            #     if dilution.endswith('.00'):  # Remove '.00' from dilution and append '%' symbol
            #         dilution = dilution[:-3]
            #     product_name = f"{chemical_name} {dilution}%"
            #     if grade:  # Append grade if available
            #         product_name += f" {grade}"
            #     return product_name
            # else:
            #     return ""

            product_data = fetch_data.get_product_data_from_exact(obj.ProductId)
            if product_data:
                product_name = product_data['product_name']
                product_uncode = product_data['un_code']
                return f"{product_name} {f'({product_uncode})' if product_uncode else ''}"
            return ""
        return ""

    # def get_Notes(self, obj):
        
    #     if os.environ.get('DJANGO_ENV') == 'staging':
    #         if obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 conditions = LoadListConditions.objects.filter(ShipToCode=shiptocode, IsDeleted=0)

    #                 instructions_list = []
    #                 for condition in conditions:
    #                     if condition.Instruction1:
    #                         instructions_list.append(condition.Instruction1)
    #                     if condition.Instruction2:
    #                         instructions_list.append(condition.Instruction2)
    #                     if condition.Instruction3:
    #                         instructions_list.append(condition.Instruction3)
    #                 return instructions_list
    #         return ""
    #     else:
    #         instructions_list = []
    #         if obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 with connections['secondary'].cursor() as cursor:
    #                     # SQL query to fetch the result using f-string for formatting
    #                     query = f"SELECT textfield3,textfield4,textfield5 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
    #                     cursor.execute(query)
    #                     result = cursor.fetchone()

    #                     if result:
    #                         for condition in result:
    #                             if condition:
    #                                 instructions_list.append(condition)
    #                     return instructions_list
    #             return instructions_list
    #         return instructions_list
        
    def get_LoadPointCity(self, obj):
        if obj.LoadingSlotId is not None:
            api_url = settings.DELIVERY_API_URL + "loadpoints/"
            payload = {"loading_slot_id": obj.LoadingSlotId}
            return self.fetch_api_data(api_url, payload, 'LoadPointCity')
        return ""

    def get_ProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            product = self.fetch_api_data(api_url, payload, 'FullName')
            if product:
                product = product.title().replace('Trading', '')
                return product.upper()
        return ""

    # def get_Instructions(self, obj):
    #     """instructions to be added in the loading list if it is a packaged good"""

    #     ordered_by_id = obj.DeliveryCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     if obj.Packaging != 'Bulk':
    #         instructions = po_models.LoadListRemark.objects.filter(
    #             ship_to=ordered_ship_to, remark_type="instructions").values_list('remarks', flat=True)
    #         return instructions
    #     else:
    #         return []

class TransportMailSerializer(serializers.ModelSerializer):
    ShipToCity = serializers.SerializerMethodField()
    CustomerExactAddressId = serializers.SerializerMethodField()
    Product = serializers.SerializerMethodField()
    ProductCategory = serializers.SerializerMethodField()
    CustomerName = serializers.SerializerMethodField()
    CustomerAddress = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    ArticleCode = serializers.SerializerMethodField()
    ShipToCode = serializers.SerializerMethodField()
    BillToCode = serializers.SerializerMethodField()
    ReceipientMailIds = serializers.SerializerMethodField()
    PortalUserMailId = serializers.SerializerMethodField()
    PortalUserName = serializers.SerializerMethodField()
    DriverLanguages = serializers.SerializerMethodField()
    PurchaseOrderNo = serializers.SerializerMethodField()
    IsADR = serializers.SerializerMethodField()
    ProductNameDutch = serializers.SerializerMethodField()
    LoadPointCity = serializers.SerializerMethodField()
    FormattedProductName = serializers.SerializerMethodField()
    LoadPointAddressLine1 = serializers.SerializerMethodField()
    LoadPointAddressLine2 = serializers.SerializerMethodField()
    LoadPointId = serializers.SerializerMethodField()
    ContainerNo = serializers.SerializerMethodField()
    product_data = serializers.SerializerMethodField()
    dimension = serializers.SerializerMethodField()
    # IsContainerRequired = serializers.SerializerMethodField()
    IsDeliveryDateRequired = serializers.SerializerMethodField()
    TransportContactHistory = serializers.SerializerMethodField()
    LoadingStationReference = serializers.SerializerMethodField()
    # NeedUnLoadReference = serializers.SerializerMethodField()
    DefaultAttachments = serializers.SerializerMethodField()
    CustomerRequirementData = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = ['ShipToCity', 'LoadingDate', 'Product', 'ProductCategory', 'Quantity',
                    'CustomerName', 'CustomerAddress', 'LoadingTime', 'DeliveryDate',
                    'DeliveryTimeInterval', 'ArticleCode', 'ShipToCode', 'IncoTerm', 
                    'LoadReference', 'ReceipientMailIds', 'PortalUserMailId',
                    'PortalUserName', 'ExactOrderNo', 'DriverLanguages', 'DeliveryCustomerName',
                    'ProductName', 'LoadPoint', 'PurchaseOrderNo', 'IsADR', 'ProductNameDutch', 
                    'LoadPointCity', 'FormattedProductName', 'TransporterId','LoadPointAddressLine1', 
                    'LoadPointAddressLine2','LoadPointId', 'ContainerNo', 'product_data', 'dimension', 
                    'CustomerExactAddressId', 'OrderedCustomerId', 
                    'IsDeliveryDateRequired', 'TransportContactHistory' , 'CourierPickupDate',
                    'CourierPickupTime', 'CourierDate', 'CourierTime', 'LoadingStationReference', 
                    'DefaultAttachments', 'CustomerRequirementData', 'BillToCode'
                    ]
    
    def to_representation(self, instance):
        response_data = super().to_representation(instance)

        product_data = response_data.pop('product_data')
        response_data['Packaging'] = product_data.get('Packaging', None)

        requirement = response_data.pop('CustomerRequirementData')
        response_data['IsContainerRequired'] = requirement.get('requires_container_number', None)
        need_load_reference = requirement.get('include_load_reference_in_transporter_mail', False)
        response_data['NeedUnLoadReference'] = instance.LoadReference if  need_load_reference else None

        return response_data

    def get_CustomerRequirementData(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedCustomerId)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None

        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        return customer_requirement.get('data') if customer_requirement else None
        
    def get_product_data(self, obj):
        """function returns product details"""
        product_id = obj.ProductId
        api_url = settings.PRODUCT_API_URL + "products/"
        request = self.context.get('request')
        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
            'x-auth-token': request.headers.get('x-auth-token'),
        }
        payload = {"product_id": product_id}
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                if data is not None:
                    return data.get('data', {})
                else:
                    return ""
            else:
                return ""
        except requests.RequestException as e:
            # Handle exceptions, such as connection errors
            return ""

    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None
    
    def get_DefaultAttachments(self, obj):
        '''function to get default attachments that needs to be sent to mails'''

        saftey_attachment = []
        if obj.IncoTerm != 'FCA':
            saftey_attachment = po_models.EmailAttachment.objects.filter(
            email_type='saftey').values(
                'id', 'customer_id', 'email_type', 'file_name', 'file_path')

        return saftey_attachment
    
    def get_CustomerExactAddressId(self, obj):
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""

    def get_ShipToCity(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'City')
        return ""
    
    def get_dimension(self, obj):
        if obj.Packaging!='Bulk':
            product_id = obj.ProductId
            product_data = fetch_data.get_packaged_product_data(product_id)
            dimension = f"{product_data['dimension']} mm" if 'dimension' in product_data. keys() else ''
            return dimension
        return ""


    def get_Product(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'FullName')
        return ""

    def get_ProductCategory(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ProductCategory')
        return ""

    def get_CustomerName(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'CustomerName')
        return ""

    def get_CustomerAddress(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            request = self.context.get('request')  # Get the request context
            if request is None:
                return ""
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
            }
            auth_token = request.headers.get('x-auth-token', None)
            if auth_token:
                headers['x-auth-token'] = auth_token
            try:
                response = requests.post(api_url, json=payload, headers=headers)
                if response.status_code == 200:
                    address_data = response.json()
                    address_data.get('data', {}).get('AddressLine1', '')
                    address_combined = ", ".join(filter(None, [
                        address_data.get('data', {}).get('AddressLine1', ''),
                        address_data.get('data', {}).get('AddressLine2', ''),
                        address_data.get('data', {}).get('City', ''),
                        address_data.get('data', {}).get('PostalCode', ''),
                        address_data.get('data', {}).get('Country', ''),
                    ]))
                    return address_combined
                else:
                    return ""
            except requests.RequestException as e:
                print(f"An error occurred while fetching data: {e}")
                return None
        return ""

    def get_DeliveryTimeInterval(self, obj):
        if obj.OrderNo is not None:
            delivery_time_interval = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'DeliveryTimeInterval', flat=True).first()
            return delivery_time_interval
        return ""

    def get_ArticleCode(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ArticleCode')
        return ""
    
    # def get_IsContainerRequired(self, obj):
    #     """function checks weather order has container no or not"""
    #     product_id = obj.ProductId
        
    #     product_data = fetch_data.get_product_data(product_id)

    #     is_conatiner_required = True if product_data and product_data['article_code']=='50000' else False
        
    #     ordered_by_id = obj.DeliveryCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, IsContainerRequired=True)
    #     if requirement.last():
    #         is_conatiner_required = True

    #     return is_conatiner_required

    def get_IsDeliveryDateRequired(self, obj):
        """function checks weather Delivery date needs to show in mail table
            For PS 3 delievery date is not needed
        """
        product_id = obj.ProductId
        product_data = fetch_data.get_product_data(product_id)
        need_delivery_date = False if product_data and product_data['article_code']=='50000' else True

        return need_delivery_date

    def get_ShipToCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""

    def get_BillToCode(self, obj):
        if obj.BillToCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.BillToCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""
    
    def get_TransportContactHistory(self, obj):
        deliver_to_id = obj.OrderedCustomerId
        address_data = fetch_data.get_address_data(deliver_to_id)
        if obj.ProductId and address_data:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            category = self.fetch_api_data(api_url, payload, 'ProductCategory')
            to_emails = po_models.TransporterContact.objects.filter(
                ship_to=address_data['exact_erp_address_id'],
                product_category=category, 
                transporter_id=obj.TransporterId, 
                recipient_type='to',
                is_deleted=False).values_list('email', flat=True)

            if obj.TransporterId and len(to_emails)==0:
                transporter_data = fetch_data.get_transporter_contact_data(obj.TransporterId, category)
                if not transporter_data:
                    transporter_data = fetch_data.get_transporter_contact_data(obj.TransporterId, 'all')
                if not transporter_data:
                    transporter_data = fetch_data.get_transporter_data(obj.TransporterId)

                to_emails = transporter_data['email'].split(',')

            cc_emails = po_models.TransporterContact.objects.filter(
                ship_to=address_data['exact_erp_address_id'],
                product_category=category, 
                transporter_id=obj.TransporterId,
                recipient_type='cc', 
                is_deleted=False).values_list('email', flat=True)

            # remove duplicates mail ids
            to_emails = list(set(to_emails))
            cc_emails = list(set(cc_emails))

            return {'to_mails': to_emails, 'cc_mails': cc_emails}
        return []

    
    def get_ReceipientMailIds(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            category = self.fetch_api_data(api_url, payload, 'ProductCategory')
            if obj.TransporterId is not None and obj.TransporterId != 0:
                api_url = settings.DELIVERY_API_URL + "get_transporter_mail_ids/"
                payload = {"transporter_id": obj.TransporterId, "product_category": category}
                return self.fetch_api_data(api_url, payload, 'mail_ids')
            return ""
        return ""

    def get_PortalUserMailId(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.USER_API_URL + "get_user_data_from_authtoken/"
            request = self.context.get('request')
            payload = {"auth_token": request.headers.get('x-auth-token', None)}
            return self.fetch_api_data(api_url, payload, 'Email')
        return ""

    def get_PortalUserName(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.USER_API_URL + "get_user_data_from_authtoken/"
            request = self.context.get('request')
            payload = {"auth_token": request.headers.get('x-auth-token', None)}
            return self.fetch_api_data(api_url, payload, 'FullName')
        return ""

    def get_DriverLanguages(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
            if articlecode is not None and obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                    request = self.context.get('request')
                    payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                    return self.fetch_api_data(api_url, payload, 'DriverLanguage')
                return ""
            return ""
        return ""

    def get_PurchaseOrderNo(self, obj):
        if obj.OrderNo is not None:
            po_number = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'PurchaseOrderNo', flat=True).first()
            return po_number
        return ""

    def get_IsADR(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'IsADR')
        return ""

    def get_ProductNameDutch(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'DU_FullName')
        return ""

    def get_LoadPointCity(self, obj):
        if obj.LoadingSlotId is not None:
            api_url = settings.DELIVERY_API_URL + "loadpoints/"
            payload = {"loading_slot_id": obj.LoadingSlotId}
            return self.fetch_api_data(api_url, payload, 'LoadPointCity')
        return ""

    def get_FormattedProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            request = self.context.get('request')  # Get the request context
            if request is None:
                return ""
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
                'x-auth-token': request.headers.get('x-auth-token', None)
            }
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                chemical_name = data['data'].get('ChemicalName', '')
                dilution = str(data['data'].get('Dilution', ''))
                grade = data['data'].get('Grade', '')
                if dilution.endswith('.00'):  # Remove '.00' from dilution and append '%' symbol
                    dilution = dilution[:-3]
                product_name = f"{chemical_name} {dilution}%"
                if grade:  # Append grade if available
                    product_name += f" {grade}"
                # product_name = data['data'].get('EN_FullName', '')
                return product_name
            else:
                return ""
        return ""

    def get_LoadPointAddressLine1(self, obj):
        if obj.LoadPoint != '':
            if obj.LoadingSlotId is not None:
                api_url = settings.DELIVERY_API_URL + "loadpoints/"
                payload = {"loading_slot_id": obj.LoadingSlotId}
                return self.fetch_api_data(api_url, payload, 'AddressLine1')
            return ""
        return ""

    def get_LoadPointAddressLine2(self, obj):
        if obj.LoadPoint != '':
            if obj.LoadingSlotId is not None:
                api_url = settings.DELIVERY_API_URL + "loadpoints/"
                payload = {"loading_slot_id": obj.LoadingSlotId}
                return self.fetch_api_data(api_url, payload, 'AddressLine2')
            return ""
        return ""
    def get_LoadPointId(self, obj):
        if obj.OrderNo is not None:
            load_point_id = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'LoadPointId', flat=True).first()
            return load_point_id
        return ""

    def get_ContainerNo(self, obj):
        if obj.OrderNo is not None:
            container_no = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'ContainerNo', flat=True).first()
            return container_no
        return ""
    
    def get_LoadingStationReference(self, obj):
        # Convert the UpdatedOn datetime to the required format
        order_request_id = obj.OrderNo

        load_point_master = fetch_data.get_loadpoint_data(order_request_id)
        if load_point_master and load_point_master['required_reference_no']:
            return obj.StationReference if obj.StationReference else ''

        return None

    # def get_NeedUnLoadReference(self, obj):
    #     """function checks weather customer is outside EU and need MDGD form"""

    #     ordered_by_id = obj.DeliveryCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, SendLoadReferenceToTransporter=True)
    #     if requirement.last():
    #         return  obj.LoadReference

    #     return None


class MultipleTransportMailSerializer(serializers.ModelSerializer):

    Product = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    PurchaseOrderNo = serializers.SerializerMethodField()
    LoadPointCity = serializers.SerializerMethodField()
    LoadPointId = serializers.SerializerMethodField()
    loading_date = serializers.SerializerMethodField()
    delivery_date = serializers.SerializerMethodField()
    FormattedProductName = serializers.SerializerMethodField()
    ContainerNo = serializers.SerializerMethodField()
    Dimension = serializers.SerializerMethodField()
    # IsContainerRequired = serializers.SerializerMethodField()
    IsDeliveryDateRequired = serializers.SerializerMethodField()
    LoadingStationReference = serializers.SerializerMethodField()
    # NeedUnLoadReference = serializers.SerializerMethodField()
    DefaultAttachments = serializers.SerializerMethodField()
    CustomerRequirementData = serializers.SerializerMethodField()


    class Meta:
        model = Orders
        fields = ['Product', 'Quantity', 'PurchaseOrderNo', 'ExactOrderNo', 'LoadPointCity', 'LoadingTime', 'DeliveryTimeInterval',
                  'IncoTerm', 'LoadPointId', 'loading_date', 'delivery_date', 'LoadPoint', 'FormattedProductName',
                  'ContainerNo', 'Dimension', 'IsDeliveryDateRequired', 
                  'LoadingStationReference', 'DefaultAttachments', 'CustomerRequirementData']

    def to_representation(self, instance):
        """ Override representation function to format response data"""
        representation = super().to_representation(instance)

        representation['Quantity'] = float(representation['Quantity'])
        representation['product'] = representation['FormattedProductName']

        
        requirement = representation.pop('CustomerRequirementData')
        representation['IsContainerRequired'] = requirement.get('requires_container_number', None)
        need_load_reference = requirement.get('include_load_reference_in_transporter_mail', False)
        representation['NeedUnLoadReference'] = instance.LoadReference if  need_load_reference else None

        return representation

    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None
    
    def get_CustomerRequirementData(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedCustomerId)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None

        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        return customer_requirement.get('data') if customer_requirement else None
    
    def get_LoadingStationReference(self, obj):
        # Convert the UpdatedOn datetime to the required format
        order_request_id = obj.OrderNo

        load_point_master = fetch_data.get_loadpoint_data(order_request_id)
        if load_point_master and load_point_master['required_reference_no']:
            return obj.StationReference if obj.StationReference else ''

        return None

    def get_FormattedProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            request = self.context.get('request')  # Get the request context
            if request is None:
                return ""
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
                'x-auth-token': request.headers.get('x-auth-token', None)
            }
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                chemical_name = data['data'].get('ChemicalName', '')
                dilution = str(data['data'].get('Dilution', ''))
                grade = data['data'].get('Grade', '')
                if dilution.endswith('.00'):  # Remove '.00' from dilution and append '%' symbol
                    dilution = dilution[:-3]
                product_name = f"{chemical_name} {dilution}%"
                if grade:  # Append grade if available
                    product_name += f" {grade}"
                return product_name
            else:
                return ""
        return ""

    def get_Product(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'FullName')
        return ""
    
    def get_Dimension(self, obj):
        if obj.Packaging!='Bulk':
            product_id = obj.ProductId
            product_data = fetch_data.get_packaged_product_data(product_id)
            dimension = f"{product_data['dimension']} mm" if 'dimension' in product_data. keys() else ''
            return dimension
        return ""

    def get_ProductCategory(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ProductCategory')
        return ""


    def get_DeliveryTimeInterval(self, obj):
        if obj.OrderNo is not None:
            delivery_time_interval = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'DeliveryTimeInterval', flat=True).first()
            return delivery_time_interval
        return ""


    def get_PurchaseOrderNo(self, obj):
        if obj.OrderNo is not None:
            po_number = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'PurchaseOrderNo', flat=True).first()
            return po_number
        return ""

    def get_ProductNameDutch(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'DU_FullName')
        return ""

    def get_LoadPointCity(self, obj):
        if obj.LoadingSlotId is not None:
            api_url = settings.DELIVERY_API_URL + "loadpoints/"
            payload = {"loading_slot_id": obj.LoadingSlotId}
            return self.fetch_api_data(api_url, payload, 'LoadPointCity')
        return ""

    def get_FormattedProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            request = self.context.get('request')  # Get the request context
            if request is None:
                return ""
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
                'x-auth-token': request.headers.get('x-auth-token', None)
            }
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                chemical_name = data['data'].get('ChemicalName', '')
                dilution = str(data['data'].get('Dilution', ''))
                grade = data['data'].get('Grade', '')
                if dilution.endswith('.00'):  # Remove '.00' from dilution and append '%' symbol
                    dilution = dilution[:-3]
                product_name = f"{chemical_name} {dilution}%"
                if grade:  # Append grade if available
                    product_name += f" {grade}"
                return product_name
            else:
                return ""
        return ""

    def get_LoadPointId(self, obj):
        if obj.OrderNo is not None:
            load_point_id = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'LoadPointId', flat=True).first()
            return load_point_id
        return ""

    def get_loading_date(self, obj):
        if obj.LoadingDate is not None:
            loading_date = obj.LoadingDate.strftime("%d/%m/%Y")
            return loading_date
        return ""

    def get_delivery_date(self, obj):
        if obj.LoadingDate is not None:
            delivery_date = obj.DeliveryDate.strftime("%d/%m/%Y") if obj.DeliveryDate else ""
            return delivery_date
        return ""

    def get_ContainerNo(self, obj):
        if obj.OrderNo is not None:
            container_no = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'ContainerNo', flat=True).first()
            return container_no
        return ""
    
    # def get_IsContainerRequired(self, obj):
    #     """function checks weather order has container no or not"""
    #     product_id = obj.ProductId
        
    #     product_data = fetch_data.get_product_data(product_id)

    #     is_conatiner_required = True if product_data and product_data['article_code']=='50000' else False
        
    #     ordered_by_id = obj.DeliveryCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, IsContainerRequired=True)
    #     if requirement.last():
    #         is_conatiner_required = True

    #     return is_conatiner_required

    def get_IsDeliveryDateRequired(self, obj):
        """function checks weather Delivery date needs to show in mail table
            For PS 3 delievery date is not needed
        """
        product_id = obj.ProductId
        product_data = fetch_data.get_product_data(product_id)
        need_delivery_date = False if product_data and product_data['article_code']=='50000' else True

        return need_delivery_date

    # def get_NeedUnLoadReference(self, obj):
    #     """function checks weather customer is outside EU and need MDGD form"""

    #     ordered_by_id = obj.DeliveryCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, SendLoadReferenceToTransporter=True)
    #     if requirement.last():
    #         return  obj.LoadReference

    #     return None
    
    def get_DefaultAttachments(self, obj):
        '''function to get default attachments that needs to be sent to mails'''

        saftey_attachment = []
        if obj.IncoTerm != 'FCA':
            saftey_attachment = po_models.EmailAttachment.objects.filter(
            email_type='saftey').values(
                'id', 'customer_id', 'email_type', 'file_name', 'file_path')

        return saftey_attachment


class CustomerMailSerializer(serializers.ModelSerializer):

    ReceipientMailId = serializers.SerializerMethodField()
    PortalUserMailId = serializers.SerializerMethodField()
    PurchaseOrderNo = serializers.SerializerMethodField()
    CustomerExactAddressId = serializers.SerializerMethodField()
    CustomerName = serializers.SerializerMethodField()
    CustomerAddress = serializers.SerializerMethodField()
    CustomerCountryCode = serializers.SerializerMethodField()
    CustomerCity = serializers.SerializerMethodField()
    CustomerPostalCode = serializers.SerializerMethodField()
    Product = serializers.SerializerMethodField()
    ArticleCode = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    IsCocNeeded = serializers.SerializerMethodField()
    FormattedProductName = serializers.SerializerMethodField()
    CustomerCountry = serializers.SerializerMethodField()
    LoadPointAddressLine1 = serializers.SerializerMethodField()
    LoadPointAddressLine2 = serializers.SerializerMethodField()
    CCMailId = serializers.SerializerMethodField()
    ExtraCharges = serializers.SerializerMethodField()
    ToTalExtraCharge = serializers.SerializerMethodField()
    # NeedCustomerMail = serializers.SerializerMethodField()
    DefaultAttachments = serializers.SerializerMethodField()
    CustomerRequirementData = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = ['ReceipientMailId', 'PortalUserMailId', 'ExactOrderNo', 'PurchaseOrderNo', 'CustomerExactAddressId',
                  'CustomerName', 'CustomerAddress', 'CustomerCountryCode', 'CustomerCity', 'CustomerPostalCode',
                  'Product', 'ArticleCode', 'Price', 'Quantity', 'DeliveryDate', 'DeliveryTimeInterval', 'IncoTerm',
                  'PaymentTerm', 'IsCocNeeded', 'FormattedProductName', 'CustomerCountry', 'LoadingDate', 'LoadingTime',
                  'OrderedCustomerId','LoadPoint','LoadPointAddressLine1','LoadPointAddressLine2','CCMailId', 
                  'Packaging', 'ExtraCharges', 'ToTalExtraCharge', 'DefaultAttachments', 
                  'CustomerRequirementData']

    def to_representation(self, instance):
        """ Override representation function to format response data"""
        representation = super().to_representation(instance)

        customer_requirement = representation.pop('CustomerRequirementData')
        no_confirmation_mail = customer_requirement.get('customer_confirmation_mail_not_required')
        representation['NeedCustomerMail'] = False if no_confirmation_mail else True
        
        return representation

    def get_CustomerRequirementData(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedCustomerId)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None

        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        return customer_requirement.get('data') if customer_requirement else None
    
    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None

    def get_ReceipientMailId(self, obj):
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            exact_address_id = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
            bill_to_address_data = fetch_data.get_address_data(obj.BillToCustomerId)
            bill_to_code = bill_to_address_data.get('exact_erp_address_id')
            mailids = CustomerContacts.objects.filter(
                ExactERPAddressId=exact_address_id, BillTo=bill_to_code, IsDeleted=0,Type='to').values_list(
                'Email', flat=True)
            if not mailids:
                mailids = CustomerContacts.objects.filter(
                    ExactERPAddressId=exact_address_id, IsDeleted=0,Type='to').values_list(
                    'Email', flat=True)
            return list(set(mailids))
        return ""

    def get_DefaultAttachments(self, obj):
        '''function to get default attachments that needs to be sent to mails'''

        delivery_customer_id = obj.OrderedCustomerId
        attachments = po_models.EmailAttachment.objects.filter(
            customer_id=delivery_customer_id, email_type=po_consts.CUSTOMER_MAIL).values(
                'id', 'customer_id', 'email_type', 'file_name', 'file_path')

        # if obj.IncoTerm=='FCA':


        return attachments
    

    def get_PortalUserMailId(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.USER_API_URL + "get_user_data_from_authtoken/"
            request = self.context.get('request')
            payload = {"auth_token": request.headers.get('x-auth-token', None)}
            return self.fetch_api_data(api_url, payload, 'Email')
        return ""

    def get_PurchaseOrderNo(self, obj):
        if obj.OrderNo is not None:
            po_number = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'PurchaseOrderNo', flat=True).first()
            return po_number
        return ""

    def get_CustomerExactAddressId(self, obj):
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""

    def get_CustomerName(self, obj):
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'CustomerName')
        return ""

    def get_CustomerAddress(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'AddressLine1')
        return ""

    def get_CustomerCountryCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'CountryCode')
        return ""

    def get_CustomerCity(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'City')
        return ""

    def get_CustomerPostalCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'PostalCode')
        return ""

    def get_Product(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'FullName')
        return ""

    def get_ArticleCode(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ArticleCode')
        return ""

    def get_DeliveryTimeInterval(self, obj):
        if obj.OrderNo is not None:
            delivery_time_interval = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'DeliveryTimeInterval', flat=True).first()
            return delivery_time_interval
        return ""

    def get_IsCocNeeded(self, obj):
        if os.environ.get('DJANGO_ENV') == 'staging':
            if obj.ProductId is not None:
                api_url = settings.PRODUCT_API_URL + "products/"
                payload = {"product_id": obj.ProductId}
                articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
                if articlecode is not None and obj.DeliveryCustomerId is not None:
                    api_url = settings.CUSTOMER_API_URL + "customers/"
                    payload = {"address_id": obj.DeliveryCustomerId}
                    shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                    if shiptocode is not None:
                        api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                        request = self.context.get('request')
                        payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                        return self.fetch_api_data(api_url, payload, 'COCNeeded')
                    return ""
                return ""
            return ""
        else:
            if obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    with connections['secondary'].cursor() as cursor:
                        query = f"SELECT TextField19 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
                        cursor.execute(query)
                        result = cursor.fetchone()
                        # Check if result is not None and return the value
                        if result and result[0] is not None:
                            return 1
                        else:
                            return 0

                        return 0
                return 0
            return 0

    def get_FormattedProductName(self, obj):
        """Product name (uncode)"""
        if obj.ProductId is not None:
            # api_url = settings.PRODUCT_API_URL + "products/"
            # payload = {"product_id": obj.ProductId}
            # request = self.context.get('request')  # Get the request context
            # if request is None:
            #     return ""
            # headers = {
            #     'x-api-key': os.getenv('API_KEY'),
            #     'x-content-type': 'application/json',
            #     'x-auth-token': request.headers.get('x-auth-token', None)
            # }
            # response = requests.post(api_url, json=payload, headers=headers)
            # if response.status_code == 200:
            #     data = response.json()
            #     # chemical_name = data['data'].get('ChemicalName', '')
            #     # dilution = str(data['data'].get('Dilution', ''))
            #     # grade = data['data'].get('Grade', '')
            #     # grade = data['data'].get('EN_FullName', '')
            #     # if dilution.endswith('.00'):  # Remove '.00' from dilution and append '%' symbol
            #     #     dilution = dilution[:-3]
            #     # product_name = f"{chemical_name} {dilution}%"
            #     # if grade:  # Append grade if available
            #     #     product_name += f" {grade}"
            #     product_name = data['data'].get('EN_FullName', '')

            #     return product_name
            # else:
            #     return ""
            product_data = fetch_data.get_product_data_from_exact(obj.ProductId)
            if product_data:
                product_name = product_data['product_name']
                product_uncode = product_data['un_code']
                return f"{product_name} {f'({product_uncode})' if product_uncode else ''}"
            return ""
        return ""

    def get_CustomerCountry(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'Country')
        return ""

    def get_LoadPointAddressLine1(self, obj):
        if obj.LoadPoint != '':
            if obj.LoadingSlotId is not None:
                api_url = settings.DELIVERY_API_URL + "loadpoints/"
                payload = {"loading_slot_id": obj.LoadingSlotId}
                return self.fetch_api_data(api_url, payload, 'AddressLine1')
            return ""
        return ""

    def get_LoadPointAddressLine2(self, obj):
        if obj.LoadPoint != '':
            if obj.LoadingSlotId is not None:
                api_url = settings.DELIVERY_API_URL + "loadpoints/"
                payload = {"loading_slot_id": obj.LoadingSlotId}
                return self.fetch_api_data(api_url, payload, 'AddressLine2')
            return ""
        return ""

    def get_CCMailId(self, obj):
        """function to get cc mail id"""
        mailids = []
        # if obj.OrderedCustomerId is not None:
        #     api_url = settings.CUSTOMER_API_URL + "customers/"
        #     payload = {"address_id": obj.OrderedCustomerId}
        #     exact_address_id = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        #     mail_id = CustomerContacts.objects.filter(
        #         ExactERPAddressId=exact_address_id, IsDeleted=0,Type="cc").values_list(
        #         'Email', flat=True).distinct()
        #     mailids.extend(mail_id)

        if obj.DeliveryCustomerId is not None:
            api_url = settings.USER_API_URL + "get_user_data_from_authtoken/"
            request = self.context.get('request')
            payload = {"auth_token": request.headers.get('x-auth-token', None)}
            login_user_mail =  self.fetch_api_data(api_url, payload, 'Email')
            if login_user_mail not in mailids:
                mailids.append(login_user_mail)
        return list(mailids) if mailids else ''
    
    def get_ExtraCharges(self, obj):
        """function to get all extra charges"""
        charges = OrderCharges.objects.filter(OrderNo=obj.OrderNo, IsDeleted=False)
        extra_charges = [{'charge': charge.ChargeName , 'price': charge.Rate} for charge in charges]
        return extra_charges
    
    def get_ToTalExtraCharge(self, obj):
        """function to get total charge"""
        charges = OrderCharges.objects.filter(OrderNo=obj.OrderNo, IsDeleted=False)
        total_charge = charges.aggregate(total=Sum("Rate"))["total"] or 0
        return total_charge
    
    # def get_NeedCustomerMail(self, obj):
    #     """function checks customer confiration mail needs to send"""

    #     ordered_by_id = obj.OrderedCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, NoCustomerEmailRequired=True)
    #     if requirement.last():
    #         return  False

    #     return True





class CustomerMailMultiOrderSerializer(serializers.ModelSerializer):

    PurchaseOrderNo = serializers.SerializerMethodField()
    product_data = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    FormattedProductName = serializers.SerializerMethodField()
    customer_data = serializers.SerializerMethodField()
    loading_at = serializers.SerializerMethodField()
    load_address_data = serializers.SerializerMethodField()
    packaging_info = serializers.SerializerMethodField()
    ExtraCharges = serializers.SerializerMethodField()
    TotalExtraCharge = serializers.SerializerMethodField()
    # NeedCustomerMail = serializers.SerializerMethodField() 
    DefaultAttachments = serializers.SerializerMethodField()
    CustomerRequirementData = serializers.SerializerMethodField()

    class Meta:
        model = Orders

        fields = ['PurchaseOrderNo', 'product_data','Price', 'Quantity',
                  'DeliveryDate', 'customer_data', 'ExactOrderNo', 'OrderNo', 'LoadingDate',
                  'LoadReference', 'IncoTerm', 'PaymentTerm', 'OrderedCustomerId', 'loading_at',
                  'LoadPoint', 'load_address_data', 'LoadingTime', 'DeliveryTimeInterval',
                  'FormattedProductName', 'Packaging', 'packaging_info', 'ExtraCharges', 
                  'TotalExtraCharge', 'DefaultAttachments', 'BillToCustomerId',
                  'CustomerRequirementData' ]

    def fetch_api_data(self, api_url, payload, key, response_required=False):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data if response_required else data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None

    def to_representation(self, instance):
        """ Override representation function to format response data"""
        representation = super().to_representation(instance)

        if instance.Price != 0.00:
            price_decimal = Decimal(instance.Price).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)  # Convert and round off to 2 decimal
            price = f"{convert_to_belgium_format(price_decimal)} EUR/MT"
        else:
            price = "Price to be confirmed"
        representation['Price'] = price

        customer_data = representation.pop('customer_data')
        load_address_data = representation.pop('load_address_data')
        representation['customer_exact_id'] = customer_data['ExactERPAddressId']
        representation['client_name'] = customer_data['CustomerName']
        representation['client_address_line1'] = customer_data['AddressLine1']
        representation['client_address_line2'] = customer_data['AddressLine2']
        representation['client_address_line3'] = customer_data['Country']
        representation['CustomerCity'] = customer_data['CustomerCity']

        representation['load_point_address_line1'] = load_address_data['AddressLine1']
        representation['load_point_address_line2'] = load_address_data['AddressLine2']
        representation['LoadReference'] = f"{representation['ExactOrderNo']}/1"

        product_data = representation.pop('product_data')
        representation['ArticleCode'] = product_data['ArticleCode']
        representation['Product'] = product_data['product_name'].title().replace("Trading", "")

        if representation['IncoTerm'] == 'FCA' or representation['IncoTerm'] == 'EXW':
            load_point = representation['LoadPoint']
        else:
            load_point = ''

        representation['load_point'] = load_point
        representation['Quantity'] = float(representation['Quantity'])

        representation['LoadingDate'] = datetime.strptime(representation['LoadingDate'], "%Y-%m-%d").strftime(
            "%d/%m/%Y") if representation['LoadingDate'] else ""
        representation['DeliveryDate'] = datetime.strptime(representation['DeliveryDate'], "%Y-%m-%d").strftime(
            "%d/%m/%Y") if representation['DeliveryDate'] else ""
        # representation['LoadingTime'] = product_data['LoadingTime']
        # representation['DeliveryTimeInterval'] = product_data['DeliveryTimeInterval']

        if customer_data['ExactERPAddressId'] == 2148:
            representation[
                'coc_quality_statement'] = "We hereby certify that the quality of the above mentioned product complies with the required specifications mentioned in Algist Bruggeman’s raw material sheet GKD003v9."
        else:
            representation[
                'coc_quality_statement'] = 'We hereby certify that the quality of the above mentioned product complies with the required specifications as described in our Technical Data Sheet.'

        customer_requirement = representation.pop('CustomerRequirementData')
        no_confirmation_mail = customer_requirement.get('customer_confirmation_mail_not_required')
        representation['NeedCustomerMail'] = False if no_confirmation_mail else True

        return representation

    def get_CustomerRequirementData(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedCustomerId)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None

        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        return customer_requirement.get('data') if customer_requirement else None

    def get_customer_data(self, obj):
        """Function to get Customer data"""
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            response =  self.fetch_api_data(api_url, payload, 'CustomerName', response_required=True)
            response_data = response['data']
            address_line2 = f"{response_data['CountryCode']}-{response_data['PostalCode']} {response_data['City']}"

            customer_data = {
                'CustomerName': response_data['CustomerName'],
                'ExactERPAddressId': response_data['ExactERPAddressId'],
                'AddressLine1': response_data['AddressLine1'],
                'Country': response_data['Country'],
                'AddressLine2': address_line2,
                'CustomerCity': response_data['City'],
            }
            return customer_data
        return ""

    def get_DefaultAttachments(self, obj):
        '''function to get default attachments that needs to be sent to mails'''

        delivery_customer_id = obj.OrderedCustomerId
        attachments = po_models.EmailAttachment.objects.filter(
            customer_id=delivery_customer_id, email_type=po_consts.CUSTOMER_MAIL).values(
                'id', 'customer_id', 'email_type', 'file_name', 'file_path')
        if obj.IncoTerm == 'FCA':
            saftey_attachment = po_models.EmailAttachment.objects.filter(
            email_type='saftey').values(
                'id', 'customer_id', 'email_type', 'file_name', 'file_path')
            attachments = attachments.union(saftey_attachment)

        return attachments

    # def get_NeedCustomerMail(self, obj):
    #     """function checks customer confiration mail needs to send"""

    #     ordered_by_id = obj.OrderedCustomerId
    #     delivery_data = fetch_data.get_address_data(ordered_by_id)
    #     ordered_ship_to = delivery_data['exact_erp_address_id']

    #     requirement = CustomerRequirement.objects.filter(
    #         ShipTo=ordered_ship_to, NoCustomerEmailRequired=True)
    #     if requirement.last():
    #         return  False

    #     return True

    def get_PurchaseOrderNo(self, obj):
        if obj.OrderNo is not None:
            po_number = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'PurchaseOrderNo', flat=True).first()
            return po_number
        return ""
    
    def get_packaging_info(self, obj):
        if obj.Packaging.lower() == 'bulk':
            return obj.Packaging.capitalize()
        else:
            package_info = fetch_data.get_PackagingInfo(obj.OrderNo)
        return package_info

    def get_loading_at(self, obj):
        loading_at = f"{obj.LoadPoint} - {''}"
        return loading_at

    def get_load_address_data(self, obj):
        if obj.LoadPoint != '':
            if obj.LoadingSlotId is not None:
                api_url = settings.DELIVERY_API_URL + "loadpoints/"
                payload = {"loading_slot_id": obj.LoadingSlotId}
                response = self.fetch_api_data(api_url, payload, 'AddressLine1', response_required=True)
                load_data = response['data']
                return load_data
            return ""
        return ""

    def get_product_data(self, obj):
        """Function to get details of Product"""
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            response = self.fetch_api_data(api_url, payload, 'FullName', response_required=True)
            response_data = response['data']

            product_data = {
                'product_name': response_data['FullName'],
                'ArticleCode': response_data['ArticleCode'],
            }
            return product_data
        return ""

    def get_IsCocNeeded(self, obj):
        if os.environ.get('DJANGO_ENV') == 'staging':
            if obj.ProductId is not None:
                api_url = settings.PRODUCT_API_URL + "products/"
                payload = {"product_id": obj.ProductId}
                articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
                if articlecode is not None and obj.DeliveryCustomerId is not None:
                    api_url = settings.CUSTOMER_API_URL + "customers/"
                    payload = {"address_id": obj.DeliveryCustomerId}
                    shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                    if shiptocode is not None:
                        api_url = settings.DELIVERY_API_URL + "terms_conditions/"
                        request = self.context.get('request')
                        payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
                        return self.fetch_api_data(api_url, payload, 'COCNeeded')
                    return ""
                return ""
            return ""
        else:
            if obj.DeliveryCustomerId is not None:
                api_url = settings.CUSTOMER_API_URL + "customers/"
                payload = {"address_id": obj.DeliveryCustomerId}
                shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
                if shiptocode is not None:
                    with connections['secondary'].cursor() as cursor:
                        query = f"SELECT TextField19 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
                        cursor.execute(query)
                        result = cursor.fetchone()
                        # Check if result is not None and return the value
                        if result and result[0] is not None:
                            return 1
                        else:
                            return 0
                        return 0
                return 0
            return 0

    def get_DeliveryTimeInterval(self, obj):
        if obj.OrderNo is not None:
            delivery_time_interval = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'DeliveryTimeInterval', flat=True).first()
            return delivery_time_interval
        return ""

    def get_FormattedProductName(self, obj):
        if obj.ProductId is not None:
            # api_url = settings.PRODUCT_API_URL + "products/"
            # payload = {"product_id": obj.ProductId}
            # request = self.context.get('request')  # Get the request context
            # if request is None:
            #     return ""
            # headers = {
            #     'x-api-key': os.getenv('API_KEY'),
            #     'x-content-type': 'application/json',
            #     'x-auth-token': request.headers.get('x-auth-token', None)
            # }
            # response = requests.post(api_url, json=payload, headers=headers)
            # if response.status_code == 200:
            #     data = response.json()
            #     # chemical_name = data['data'].get('ChemicalName', '')
            #     # dilution = str(data['data'].get('Dilution', ''))
            #     # grade = data['data'].get('Grade', '')
            #     # if dilution.endswith('.00'):  # Remove '.00' from dilution and append '%' symbol
            #     #     dilution = dilution[:-3]
            #     # product_name = f"{chemical_name} {dilution}%"
            #     # if grade:  # Append grade if available
            #     #     product_name += f" {grade}"
            #     product_name = data['data'].get('EN_FullName', '')
            #     return product_name
            # else:
            #     return ""
            product_data = fetch_data.get_product_data_from_exact(obj.ProductId)
            if product_data:
                product_name = product_data['product_name']
                product_uncode = product_data['un_code']
                return f"{product_name} {f'({product_uncode})' if product_uncode else ''}"
            return ""
        return ""

    def get_ExtraCharges(self, obj):
        """function to get all extra charges"""
        charges = OrderCharges.objects.filter(OrderNo=obj.OrderNo, IsDeleted=False)
        extra_charges = [{'charge': charge.ChargeName , 'price': charge.Rate} for charge in charges]
        return extra_charges    
    
    def get_TotalExtraCharge(self, obj):
        """function to get total charge"""
        charges = OrderCharges.objects.filter(OrderNo=obj.OrderNo, IsDeleted=False)
        total_charge = charges.aggregate(total=Sum("Rate"))["total"] or 0
        return f'{convert_to_belgium_format(total_charge)} EUR'


def get_alternate_product(auth_token, product_id):
    api_url = settings.PRODUCT_API_URL + "get_alternate_product_details/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"product_id": product_id}
    try:
        response = requests.post(api_url, json=payload, headers=headers)
        if response.status_code == 200:
            result = response.json()
            final_data = {
                'alternate_article_code': result.get('data', {}).get('alternate_article_code', None),
                'alternate_product_id': result.get('data', {}).get('product_id', None),
                'alternate_product_name': result.get('data', {}).get('alternate_product_name', None),
            }
            return final_data
        else:
            return None
    except requests.RequestException as e:
        # Handle exceptions, such as connection errors
        return None


def get_costcenter_details(auth_token, product_id):
    api_url = settings.PRODUCT_API_URL + "products/"
    headers = {
        'x-api-key': os.getenv('API_KEY'),
        'x-content-type': 'application/json',
        'x-auth-token': auth_token,
    }
    payload = {"product_id": product_id}
    try:
        response = requests.post(api_url, json=payload, headers=headers)
        if response.status_code == 200:
            data = response.json()
            costcenter_code = data.get('data', {}).get('CostCenter')
            if costcenter_code:
                id = CostCenter.objects.filter(Code=costcenter_code).values_list('Id', flat=True).first()
                final_data = {
                    'costcenter_id': id,
                    'costcenter': costcenter_code
                }
                return final_data
            else:
                return ""
        else:
            return ""
    except requests.RequestException as e:
        # Handle exceptions, such as connection errors
        return ""

class CMRSerializer(serializers.ModelSerializer):
    DeliveryCustomerName = serializers.SerializerMethodField()
    DeliveryAddressLine1 = serializers.SerializerMethodField()
    DeliveryAddressLine2 = serializers.SerializerMethodField()
    DeliveryCity = serializers.SerializerMethodField()
    DeliveryPostalCode = serializers.SerializerMethodField()
    DeliveryCountryCode = serializers.SerializerMethodField()
    DeliveryPhone = serializers.SerializerMethodField()
    TransporterName = serializers.SerializerMethodField()
    TransporterAddressLine1 = serializers.SerializerMethodField()
    TransporterAddressLine2 = serializers.SerializerMethodField()
    TransporterPostalCode = serializers.SerializerMethodField()
    TransporterCity = serializers.SerializerMethodField()
    TransporterCountryCode = serializers.SerializerMethodField()
    DeliveryTimeInterval = serializers.SerializerMethodField()
    PurchaseOrderNo = serializers.SerializerMethodField()
    ArticleCode = serializers.SerializerMethodField()
    ShipToCode = serializers.SerializerMethodField()
    DU_ProductName = serializers.SerializerMethodField()
    FR_ProductName = serializers.SerializerMethodField()
    EN_ProductName = serializers.SerializerMethodField()
    # IsWeighingTicketNeeded = serializers.SerializerMethodField()
    # IsCOCNeeded = serializers.SerializerMethodField()
    # IsCOANeeded = serializers.SerializerMethodField()
    # IsSealingReportNeeded = serializers.SerializerMethodField()
    # IsCleaningCertificateNeeded = serializers.SerializerMethodField()
    # CustomText = serializers.SerializerMethodField()
    BatchNo = serializers.SerializerMethodField()
    WeightLabel = serializers.SerializerMethodField()
    GrossWeight = serializers.SerializerMethodField()
    CustomerRequirementData = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = ['DeliveryCustomerId','DeliveryCustomerName','DeliveryAddressLine1','DeliveryAddressLine2',
                  'DeliveryCity','DeliveryPostalCode','DeliveryCity','DeliveryPostalCode','DeliveryCountryCode',
                  'TransporterName','TransporterAddressLine1','TransporterAddressLine2',
                  'TransporterPostalCode', 'TransporterCity','TransporterCountryCode',
                  'LoadingDate','DeliveryDate','LoadingTime','DeliveryTimeInterval','ExactOrderNo','PurchaseOrderNo',
                  'Remarks','LoadReference','IncoTerm','ArticleCode','ShipToCode','DU_ProductName','FR_ProductName',
                  'EN_ProductName','DeliveryPhone', 'IncoTerm',
                  'BatchNo', 'WeightLabel', 'StationReference', 'GrossWeight', 'CustomerRequirementData']
        
    
    def to_representation(self, instance):
        """ Override representation function to format response data"""
        representation = super().to_representation(instance)

        customer_requirement = representation.pop('CustomerRequirementData')
        representation['cmr_documents'] = customer_requirement.get('cmr_documents', [])
        representation['TankType'] = customer_requirement.get('tank_type', '')
        representation['CustomText'] = customer_requirement.get('additional_confirmation_text', '')
        
        return representation
    
    def get_CustomerRequirementData(self, obj):
        """Function to return weather customer requires sample"""
        ordered_by = fetch_data.get_address_data(obj.OrderedCustomerId)
        product_data = fetch_data.get_product_data(obj.ProductId)
        customer_requirement = None
        print( product_data['article_code'], ordered_by['parent_ship_to'])
        try:
            customer_requirement = fetch_data.get_odoo_customer_requirement_data(
                ordered_by['parent_ship_to'], product_data['article_code'])
        except Exception as e:
            raise APIException(f"Odoo API failed: {str(e)}")

        print(customer_requirement.get('data'))
        return customer_requirement.get('data') if customer_requirement else None
    
    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token
        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None

    def get_DeliveryCustomerName(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'CustomerName')
        return ""

    def get_DeliveryAddressLine1(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'AddressLine1')
        return ""
    def get_DeliveryAddressLine2(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'AddressLine2')
        return ""
    def get_DeliveryCity(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'City')
        return ""
    def get_DeliveryPostalCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'PostalCode')
        return ""

    def get_DeliveryCountryCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'CountryCode')
        return ""

    def get_TransporterName(self, obj):
        if obj.TransporterId is not None and obj.TransporterId !=0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'Transporter')
        return ""
    def get_TransporterAddressLine1(self, obj):
        if obj.TransporterId is not None and obj.TransporterId !=0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'AddressLine1')
        return ""
    def get_TransporterAddressLine2(self, obj):
        if obj.TransporterId is not None and obj.TransporterId !=0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'AddressLine2')
        return ""
    def get_TransporterPostalCode(self, obj):
        if obj.TransporterId is not None and obj.TransporterId !=0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'PostalCode')
        return ""
    def get_TransporterCity(self, obj):
        if obj.TransporterId is not None and obj.TransporterId !=0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'City')
        return ""
    def get_TransporterCountryCode(self, obj):
        if obj.TransporterId is not None and obj.TransporterId !=0:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'CountryCode')
        return ""

    def get_DeliveryTimeInterval(self, obj):
        if obj.OrderNo is not None:
            delivery_time_interval = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'DeliveryTimeInterval', flat=True).first()
            return delivery_time_interval
        return ""

    def get_PurchaseOrderNo(self, obj):
        if obj.OrderNo is not None:
            po_number = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'PurchaseOrderNo', flat=True).first()
            return po_number
        return ""

    def get_ArticleCode(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ArticleCode')
        return ""
    def get_ShipToCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""
    def get_DU_ProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'DU_FullName')
        return ""
    def get_FR_ProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'FR_FullName')
        return ""
    def get_EN_ProductName(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'EN_FullName')
        return ""
    def get_(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'EN_FullName')
        return ""

    def get_DeliveryPhone(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'Phone')
        return ""

    def get_GrossWeight(self, obj):
        """get gross weight from product api"""
        if obj.Packaging=='Bulk':
            gross_weight = ""
        else:
            order_request = obj.get_order_request_obj()
            pack_data = fetch_data.get_quantity_summary(order_request)
            gross_weight = pack_data.get('gross_weight')
        return gross_weight

    # def get_IsWeighingTicketNeeded(self, obj):
    #     if os.environ.get('DJANGO_ENV') == 'staging':
    #         if obj.ProductId is not None:
    #             api_url = settings.PRODUCT_API_URL + "products/"
    #             payload = {"product_id": obj.ProductId}
    #             articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
    #             if articlecode is not None and obj.DeliveryCustomerId is not None:
    #                 api_url = settings.CUSTOMER_API_URL + "customers/"
    #                 payload = {"address_id": obj.DeliveryCustomerId}
    #                 shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #                 if shiptocode is not None:
    #                     api_url = settings.DELIVERY_API_URL + "terms_conditions/"
    #                     request = self.context.get('request')
    #                     payload = {"article_code": articlecode,"inco_term":obj.IncoTerm,"ship_to_code":shiptocode}
    #                     return self.fetch_api_data(api_url, payload, 'WeighingTicketNeeded')
    #                 return ""
    #             return ""
    #         return ""
    #     else:
    #         if obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 with connections['secondary'].cursor() as cursor:
    #                     query = f"SELECT TextField18 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
    #                     cursor.execute(query)
    #                     result = cursor.fetchone()
    #                     # Check if result is not None and return the value
    #                     if result and result[0] is not None:
    #                         return result[0]
    #                     else:
    #                         return ""
    #             return ""
    #         return ""

    # def get_IsCOCNeeded(self, obj):
    #     if os.environ.get('DJANGO_ENV') == 'staging':
    #         if obj.ProductId is not None:
    #             api_url = settings.PRODUCT_API_URL + "products/"
    #             payload = {"product_id": obj.ProductId}
    #             articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
    #             if articlecode is not None and obj.DeliveryCustomerId is not None:
    #                 api_url = settings.CUSTOMER_API_URL + "customers/"
    #                 payload = {"address_id": obj.DeliveryCustomerId}
    #                 shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #                 if shiptocode is not None:
    #                     api_url = settings.DELIVERY_API_URL + "terms_conditions/"
    #                     request = self.context.get('request')
    #                     payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
    #                     return self.fetch_api_data(api_url, payload, 'COCNeeded')
    #                 return ""
    #             return ""
    #         return ""
    #     else:
    #         if obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 with connections['secondary'].cursor() as cursor:
    #                     query = f"SELECT TextField19 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
    #                     cursor.execute(query)
    #                     result = cursor.fetchone()
    #                     # Check if result is not None and return the value
    #                     if result and result[0] is not None:
    #                         return result[0]
    #                     else:
    #                         return ""
    #             return ""
    #         return ""

    # def get_IsCOANeeded(self, obj):
    #     if obj.ProductId is not None:
    #         api_url = settings.PRODUCT_API_URL + "products/"
    #         payload = {"product_id": obj.ProductId}
    #         articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
    #         if articlecode is not None and obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 api_url = settings.DELIVERY_API_URL + "terms_conditions/"
    #                 request = self.context.get('request')
    #                 payload = {"article_code": articlecode,"inco_term":obj.IncoTerm,"ship_to_code":shiptocode}
    #                 return self.fetch_api_data(api_url, payload, 'COANeeded')
    #             return ""
    #         return ""
    #     return ""

    # def get_IsSealingReportNeeded(self, obj):
    #     if os.environ.get('DJANGO_ENV') == 'staging':
    #         if obj.ProductId is not None:
    #             api_url = settings.PRODUCT_API_URL + "products/"
    #             payload = {"product_id": obj.ProductId}
    #             articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
    #             if articlecode is not None and obj.DeliveryCustomerId is not None:
    #                 api_url = settings.CUSTOMER_API_URL + "customers/"
    #                 payload = {"address_id": obj.DeliveryCustomerId}
    #                 shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #                 if shiptocode is not None:
    #                     api_url = settings.DELIVERY_API_URL + "terms_conditions/"
    #                     request = self.context.get('request')
    #                     payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
    #                     return self.fetch_api_data(api_url, payload, 'SealingReportNeeded')
    #                 return ""
    #             return ""
    #         return ""
    #     else:
    #         if obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 with connections['secondary'].cursor() as cursor:
    #                     query = f"SELECT TextField20 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
    #                     cursor.execute(query)
    #                     result = cursor.fetchone()
    #                     # Check if result is not None and return the value
    #                     if result and result[0] is not None:
    #                         return result[0]
    #                     else:
    #                         return ""
    #             return ""
    #         return ""

    # def get_IsCleaningCertificateNeeded(self, obj):
    #     if os.environ.get('DJANGO_ENV') == 'staging':
    #         if obj.ProductId is not None:
    #             api_url = settings.PRODUCT_API_URL + "products/"
    #             payload = {"product_id": obj.ProductId}
    #             articlecode = self.fetch_api_data(api_url, payload, 'ArticleCode')
    #             if articlecode is not None and obj.DeliveryCustomerId is not None:
    #                 api_url = settings.CUSTOMER_API_URL + "customers/"
    #                 payload = {"address_id": obj.DeliveryCustomerId}
    #                 shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #                 if shiptocode is not None:
    #                     api_url = settings.DELIVERY_API_URL + "terms_conditions/"
    #                     request = self.context.get('request')
    #                     payload = {"article_code": articlecode, "inco_term": obj.IncoTerm, "ship_to_code": shiptocode}
    #                     return self.fetch_api_data(api_url, payload, 'CleaningCertificateNeeded')
    #                 return ""
    #             return ""
    #         return ""
    #     else:
    #         if obj.DeliveryCustomerId is not None:
    #             api_url = settings.CUSTOMER_API_URL + "customers/"
    #             payload = {"address_id": obj.DeliveryCustomerId}
    #             shiptocode = self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
    #             if shiptocode is not None:
    #                 with connections['secondary'].cursor() as cursor:
    #                     query = f"SELECT TextField21 FROM cicmpy WHERE TRIM(debnr) = {shiptocode}"
    #                     cursor.execute(query)
    #                     result = cursor.fetchone()
    #                     # Check if result is not None and return the value
    #                     if result and result[0] is not None:
    #                         return result[0]
    #                     else:
    #                         return ""
    #             return ""
    #         return ""

    def get_BatchNo(self, obj):
        if obj.ExactOrderNo:
            batch_no = f"{obj.ExactOrderNo}/1"
            return batch_no
        return ""
    
    def get_WeightLabel(self, obj):

        if obj.Packaging.lower()=='bulk':
            label = 'KGS NETTO / NET'
        else:
            label = "KGS BRUTO/GROSS"
        return label

    # def get_CustomText(self, obj):
    #     """function to get custom text for specific customers"""
    #     start = datetime.now()
    #     order_by_id = obj.OrderedCustomerId
    #     custom_text = ''
    #     if order_by_id:
    #         # with connections.cursor as cursor:
    #         select_query = f"""SELECT c1.Id, c2.ShipTo, c2.IsCMR, c2.CustomText from AddressMaster c1 
    #         join CustomerRequirements c2 on c1.ExactERPAddressId=c2.ShipTo where c1.Id={order_by_id} """
    #         # cursor.execute(select_query)
    #         # address = cursor.fetchone()
    #         requirements = fetch_query_results(select_query)
    #         if requirements and requirements[0]['IsCMR']:
    #             custom_text = requirements[0]['CustomText']
    #             ship_to = requirements[0]['ShipTo']
    #     end = datetime.now()
    #     return custom_text


def log_activity(message):
    # log_file = r"D:\diffrenz\order_pro\order_pro\pvs_gent_crm\purchase_order_service\po_app\logs\log_plan.log"
    log_file = settings.LOG_PLAN_PATH
    with open(log_file, "a") as f:
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        f.write(f"[{timestamp}] {message}\n")

class LoadPlanSerializer(serializers.ModelSerializer):
    CustomerName = serializers.SerializerMethodField()
    class Meta:
        model = Orders
        fields = ['CustomerName', 'LoadingTime', 'ExactOrderNo', 'ProductName', 'Quantity']

    def fetch_api_data(self, api_url, payload, key,  is_job=False):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        # if auth_token:
        #     headers['x-auth-token'] = auth_token
        if is_job:
            job_key = os.getenv('LOAD_PLAN_JOB_KEY')
            headers['job-token'] = job_key

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None

    def get_CustomerName(self, obj):
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            response =  self.fetch_api_data(api_url, payload, 'CustomerName', is_job=True)
            log_activity(f'customer_id: {obj.OrderedCustomerId}, Response: {response}')
            return response
        return ""


class OrderXMLSerializerNew(serializers.ModelSerializer):
    OrderedByCode = serializers.SerializerMethodField()
    ShipToCode = serializers.SerializerMethodField()
    InvoiceToCode = serializers.SerializerMethodField()
    WareHouseCode = serializers.SerializerMethodField()
    SelectionCode = serializers.SerializerMethodField()
    ResourceCode = serializers.SerializerMethodField()
    ArticleCode = serializers.SerializerMethodField()
    LoadPointId = serializers.SerializerMethodField()
    class Meta:
        model = Orders
        fields = ['ExactOrderNo','OrderedByCode','ShipToCode','InvoiceToCode','DeliveryDate','WareHouseCode','IncoTerm',
                  'CostCenter','SelectionCode','Quantity','Price','ResourceCode','ArticleCode','TransportPrice','InvoiceCode',
                  'LoadingDate','LoadPointId', 'Packaging']
    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', {}).get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None

    def get_OrderedByCode(self, obj):
        if obj.OrderedCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.OrderedCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""
    def get_ShipToCode(self, obj):
        if obj.DeliveryCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.DeliveryCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""
    def get_InvoiceToCode(self, obj):
        if obj.BillToCustomerId is not None:
            api_url = settings.CUSTOMER_API_URL + "customers/"
            payload = {"address_id": obj.BillToCustomerId}
            return self.fetch_api_data(api_url, payload, 'ExactERPAddressId')
        return ""
    def get_WareHouseCode(self, obj):
        if obj.LoadingSlotId is not None:
            api_url = settings.DELIVERY_API_URL + "loadpoints/"
            payload = {"loading_slot_id": obj.LoadingSlotId}
            return self.fetch_api_data(api_url, payload, 'WareHouseCode')
        return ""
    def get_SelectionCode(self, obj):
        if obj.TransporterId is not None:
            api_url = settings.DELIVERY_API_URL + "get_transporters/"
            payload = {"transporter_id": obj.TransporterId}
            return self.fetch_api_data(api_url, payload, 'Code')
        return ""
    def get_ResourceCode(self, obj):
        if obj.CreatedBy is not None:
            api_url = settings.USER_API_URL + "users/"
            payload = {"user_id": obj.CreatedBy}
            return self.fetch_api_data(api_url, payload, 'ExactUserID')
        return ""
    def get_ArticleCode(self, obj):
        if obj.ProductId is not None:
            api_url = settings.PRODUCT_API_URL + "products/"
            payload = {"product_id": obj.ProductId}
            return self.fetch_api_data(api_url, payload, 'ArticleCode')
        return ""

    def get_LoadPointId(self, obj):
        if obj.OrderNo is not None:
            load_point_id = OrderRequests.objects.filter(Id=obj.OrderNo, IsDeleted=False).values_list(
                'LoadPointId', flat=True).first()
            return load_point_id
        return ""

class BasePriceMasterSerializer(serializers.ModelSerializer):
    """Serializer for PriceMaster model."""
    class Meta:
        model = PriceMaster
        fields = [
            'Id','ArticelCode', 'ExactERPAddressId', 'OrderedByCustomer',
            'MinQuantity', 'Price', 'DeliveryDestination',
        ]

class PriceMasterSerializer(serializers.ModelSerializer):

    ValidityStartDate = serializers.SerializerMethodField()
    ValidityEndDate = serializers.SerializerMethodField()
    FormattedPrice = serializers.SerializerMethodField()
    DeliverTo = serializers.SerializerMethodField()
    ProductId = serializers.SerializerMethodField()
    FormattedMinQuantity = serializers.SerializerMethodField()
    IsBlocked = serializers.SerializerMethodField()

    class Meta:
        model = PriceMaster
        fields = [
            'Id','QuarterName', 'ValidityStartDate', 'ValidityEndDate', 'MinQuantity','FormattedMinQuantity',
            'ArticleCode', 'ProductId','ExactERPAddressId','DeliverTo', 'IncoTerm', 'IncotermID',
            'OrderedByCustomer', 'ProductName', 'OfferRef', 'Price','FormattedPrice', 'PaymentTerm',
            'IsBlocked','DeliveryDestination','PriceConfirmation','Packaging','Remarks', 'no_of_packings',
            'kg_per_packaging', 'packing_remarks'
        ]
    
    def to_representation(self, instance):
        rep = super().to_representation(instance)
        product_id = rep['ProductId']
        if product_id:
            product_data = fetch_data.get_product_data(product_id) 
            rep['ProductPackaging'] = product_data['packaging'] if product_data else ''
        return rep

    def fetch_api_data(self, api_url, payload, key):
        """
        Helper function to fetch data from the API.
        """
        request = self.context.get('request')  # Get the request context
        if request is None:
            return ""

        headers = {
            'x-api-key': os.getenv('API_KEY'),
            'x-content-type': 'application/json',
        }

        # Safely get the auth token
        auth_token = request.headers.get('x-auth-token', None)
        if auth_token:
            headers['x-auth-token'] = auth_token

        try:
            response = requests.post(api_url, json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', [{}])[0].get(key, None)
            else:
                return ""
        except requests.RequestException as e:
            print(f"An error occurred while fetching data: {e}")
            return None
        
    def get_ValidityStartDate(self, obj):
        validity_start_date = obj.ValidityStartDate
        if validity_start_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(validity_start_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    delivery_date = datetime.strptime(validity_start_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return validity_start_date.strftime("%d-%m-%Y")
        return ""
    
    def get_ValidityEndDate(self, obj):
        validity_end_date = obj.ValidityEndDate
        if validity_end_date:
            # Check if the delivery date is a string and convert it to a datetime object
            if isinstance(validity_end_date, str):
                try:
                    # Parse the string into a datetime object (assuming the format is YYYY-MM-DD)
                    delivery_date = datetime.strptime(validity_end_date, "%Y-%m-%d")
                except ValueError:
                    # Handle incorrect format or invalid date string
                    return ""
            return validity_end_date.strftime("%d-%m-%Y")
        return ""
    
    def get_FormattedPrice(self, obj):
        if obj.Price:
            return f"€{convert_to_belgium_format(obj.Price)}"
        return ""

    def get_ProductId(self,obj):
        if obj.ArticleCode is not None:
            api_url = settings.PRODUCT_API_URL + "search_products/"
            payload = {"search_query": obj.ArticleCode}
            return self.fetch_api_data(api_url, payload, 'Id')
        return ""

    def get_DeliverTo(self,obj):
        if obj.ExactERPAddressId is not None:
            payload = {"exact_id": obj.ExactERPAddressId}
            request = self.context.get('request')
            headers = {
                'x-api-key': os.getenv('API_KEY'),
                'x-content-type': 'application/json',
                'x-auth-token':request.headers.get('x-auth-token', None)
            }
            response = requests.post(settings.CUSTOMER_API_URL + "customers/", json=payload, headers=headers)
            if response.status_code == 200:
                data = response.json()
                return data.get('data', [{}]).get('Id', None)
        return ""

    def get_FormattedMinQuantity(self, obj):
        """function to show minimum quantity along with symbol"""
        operator = '' if obj.MinQtyOperator == '=' else obj.MinQtyOperator
        if obj.MinQuantity:
            return f"{operator}{convert_to_belgium_format(obj.MinQuantity)}"
        return ""

    def get_IsBlocked(self, obj):
        validity_end_date = obj.ValidityEndDate
        if validity_end_date:
            today = datetime.today().date()
            if validity_end_date < today:
                return 1
            else:
                return 0
        return ""
    
    def get_ProductPackaging(self, obj):
        """function to get packaging of product """
        product_id = obj.ProductId
        if product_id:
            product_data = fetch_data.get_product_data(product_id)
        return product_data['packaging'] if product_data else ''

class SimilarOrderInputSerializer(serializers.Serializer):
    order_id = serializers.IntegerField(required=True)


class ExtraChargeGeneralSerializer(serializers.ModelSerializer):
    class Meta:
        model = ExtraCharges
        fields = '__all__'

    def to_representation(self, instance):
        rep = super().to_representation(instance)
        quantity = self.context.get('quantity')

        # Rename fields
        rep['ChargeName'] = rep.pop('Name')
        rep['Rate'] = rep.pop('Amount')
        rep['IsApplied'] = False
        rep['ExtraChargeId'] = rep.pop('Id')
        rep['ArticleCode'] = rep['ArticleCode'] if rep['ArticleCode'] else ''

        if rep.get('Rate') == '':
            if rep['ChargeName'] == '€13/MT surcharge for deliveries of 20-25MT, (specifically for Exxon Group, Rotterdam, and product 30102 - H2SO4 T 96%)':
                rep['Rate'] = quantity * 13
            elif rep[
                'ChargeName'] == '€30/MT surcharge for deliveries of 15-20MT, (specifically for Exxon Group, Rotterdam, and product 30102 - H2SO4 T 96%)':
                rep['Rate'] = quantity * 30
            elif rep[
                'ChargeName'] == '€55/MT surcharge for deliveries of 10-15MT, (specifically for Exxon Group, Rotterdam, and product 30102 - H2SO4 T 96%)':
                rep['Rate'] = quantity * 55
            elif rep[
                'ChargeName'] == '€283/MT surcharge for deliveries of 5MT or less, (specifically for Exxon Group, Rotterdam, and product 30102 - H2SO4 T 96%)':
                rep['Rate'] = quantity * 283

        return rep


class UpdateOrderSerializer(serializers.Serializer):
    """serializer for update order details"""
    order_id = serializers.IntegerField(required=True)
    exact_order_no = serializers.CharField(required=False)
    IsTransporterReqestedChanges = serializers.CharField(required=False)


class MDGFormSerializer(serializers.ModelSerializer):
    """serializer for MDGD documnet in order planning screen """
    BatchNo = serializers.SerializerMethodField()
    AddressData = serializers.SerializerMethodField()
    PlaceOfDischarge = serializers.SerializerMethodField()
    ProductUnCode = serializers.SerializerMethodField()
    ProductDescription = serializers.SerializerMethodField()

    class Meta:
        model = OrderRequests
        fields = [
            'ExactOrderNo', 'PurchaseOrderNo', 'ContainerNo', 'BatchNo', 'AddressData',
            'PlaceOfDischarge', 'ProductUnCode', 'ProductDescription'
        ]

    def get_BatchNo(self, obj):
        """"""
        return f"{obj.ExactOrderNo}/1" if obj.ExactOrderNo else ""
    
    def get_AddressData(self, obj):

        ordered_by_id = obj.OrderedBy
        delivery_data = fetch_data.get_address_data(ordered_by_id)

        return delivery_data if delivery_data else None
    
    def get_PlaceOfDischarge(self, obj):
        """Place of discharge """
        product_id = obj.ProductId
        product_data = fetch_data.get_product_data(product_id)
        if not product_data:
            return None

        article_code = product_data['article_code']
        if article_code=='50000':
            place_of_discharge = 'Belfast'
        else:
            place_of_discharge = ''

        return place_of_discharge
    
    def get_ProductUnCode(self, obj):

        product_id = obj.ProductId
        product_data = fetch_data.get_product_data(product_id)
        if not product_data:
            return None
        
        product_name = product_data['en_full_name']
        return product_name
    
    def get_ProductDescription(self, obj):

        product_id = obj.ProductId
        product_data = fetch_data.get_product_data(product_id)
        if not product_data:
            return None
        
        product_name = product_data['product_name']
        return product_name


class AllOrderSerializer(serializers.ModelSerializer):
    """serializer for business case data validation from excel """

    class Meta:
        model = Orders
        fields = '__all__'


class AllOrderRequestSerializer(serializers.ModelSerializer):
    """serializer for business case data validation from excel """

    class Meta:
        model = OrderRequests
        fields = '__all__'


class PackingDetailSerializer(serializers.ModelSerializer):
    """serializer for Packing detail model """

    class Meta:
        model = PackingDetail
        fields = '__all__'

class CustomerRequirementSerializer(serializers.ModelSerializer):
    """Serializer for customer requirement"""

    class Meta:
        model = CustomerRequirement
        fields = '__all__'


class EmailDraftAttachmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = po_models.EmailDraftAttachment
        fields = ['id', 'file_name', 'attachment']


class EmailDraftSerializer(serializers.ModelSerializer):
    """Serializer for EmailDraft model"""

    attachments = serializers.SerializerMethodField()

    class Meta:
        model = po_models.EmailDraft
        fields = '__all__'

    def get_attachments(self, obj):
        attachments = po_models.EmailDraftAttachment.objects.filter(
            email_draft_id=obj.id
        )

        if attachments.exists():
            return EmailDraftAttachmentSerializer(attachments, many=True).data
        return []