#coding=utf-8

from rest_framework import serializers
from django.db.models import Q, F, Sum
from apps.base import Formater
from apps.exceptions import CustomError
from apps.foundation.models import BizLog
from apps.goods.models import GoodsGodownEntryDetail
from apps.purchase.models import GodownEntryDetail
from apps.serializer_errors import dump_serializer_errors
from apps.warehouse.biz import BizWarehouse
from apps.warehouse.models import WarehouseStock, InventoryDetail
from models import SaleOrder, SaleOrderDetail, GoodsDeliver, GoodsDeliverDetail, GoodsDeliverReturn, \
    GoodsDeliverReturnDetail
from libs.booleancharfield import BooleanCharField, PriceShowCharField
from apps import base
from libs.booleancharfield import CountShowCharField, PriceShowCharField, AmountShowCharField


class SaleOrderSerializer(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    check_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    check_status_text = serializers.CharField(source='get_status_display', read_only=True)
    check_user_text = serializers.CharField(source='check_user.name', read_only=True)
    create_user_text = serializers.CharField(source='create_user.name', read_only=True)
    customer_name = serializers.CharField(source='customer.name', read_only=True)
    customer_id = serializers.CharField(source='customer.id', read_only=True)
    customer_tel = serializers.CharField(source='customer.mobile', read_only=True)
    products = serializers.SerializerMethodField()
    total_amount = serializers.SerializerMethodField()
    clear_text = serializers.SerializerMethodField()
    count = CountShowCharField(read_only=True)
    amount = AmountShowCharField(read_only=True)
    receive_count = CountShowCharField(read_only=True)
    receive_amount = AmountShowCharField(read_only=True)
    pay_amount = AmountShowCharField(read_only=True)
    loss_amount = AmountShowCharField(read_only=True)
    put_amount = AmountShowCharField(read_only=True)
    fare_amount = AmountShowCharField(read_only=True)

    class Meta:
        model = SaleOrder
        fields = '__all__'

    def get_products(self, obj):
        data = []
        rows = SaleOrderDetail.objects.filter(main=obj)
        data.extend([s[0] for s in rows.values_list('goods__product_base__name')])
        return ','.join(data)

    def get_total_amount(self, obj):
        amount = Formater.formatAmountShow((obj.receive_amount or 0) - (obj.loss_amount or 0))
        return amount

    def get_clear_text(self, obj):
        if obj.cleared:
            return u'是'
        return u'否'

    @staticmethod
    def factory(user, data,id=None):
        if id:
            instance = SaleOrder.getById(id)
        else:
            instance = None
        serializer = SaleOrderSerializer(instance, data=data)
        serializer.user = user
        return serializer

    def validSave(self):
        if self.is_valid():
            return self.save()
        else:
            raise CustomError(dump_serializer_errors(self))

    def create(self, validated_data):
        validated_data['create_user'] = self.user
        validated_data['department'] = self.user.department
        instance = super(SaleOrderSerializer, self).create(validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加订单[%s]，id=%d" % (instance.no, instance.id),
            validated_data
        )
        return instance

    def update(self, instance, validated_data):
        instance = super(SaleOrderSerializer, self).update(instance, validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.UPDATE,
            u"修改订单[%s]，id=%d" % (instance.no, instance.id),
            validated_data
        )
        return instance

class SaleOrderDetailSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='goods.product_base.name', read_only=True)
    model = serializers.CharField(source='goods.product_base.model', read_only=True)
    quality_request_text = serializers.CharField(source='quality_request.name', read_only=True)
    quality_request_id = serializers.CharField(source='quality_request.id', read_only=True)
    count = CountShowCharField()
    receive_count = CountShowCharField(read_only=True)
    price = PriceShowCharField()
    amount = AmountShowCharField(read_only=True)

    class Meta:
        model = SaleOrderDetail
        fields = '__all__'

    @staticmethod
    def factory(user, data):
        instances = None
        serializer = SaleOrderDetailSerializer(instances, data=data)
        serializer.user = user
        return serializer

    def validSave(self):
        if self.is_valid():
            return self.save()
        else:
            raise CustomError(dump_serializer_errors(self))

    def validate(self, data):
        data['price'] = Formater.formatPrice(data['price'])
        data['count'] = Formater.formatCount(data['count'])
        data['amount'] = data['count'] * data['price']
        return data

    def create(self, validated_data):
        instance = super(SaleOrderDetailSerializer, self).create(validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加订单明细[%s]，id=%d" % (instance.main.no, instance.id),
            validated_data
        )
        return instance

class GoodsDeliverSerializer(serializers.ModelSerializer):
    customer_id = serializers.CharField(source='customer.id', read_only=True)
    customer_name = serializers.CharField(source='customer.name', read_only=True)
    customer_tel = serializers.CharField(source='customer.mobile', read_only=True)
    agent_user_text = serializers.CharField(source='agent_user.name', read_only=True)
    agent_department_text = serializers.CharField(source='agent_department.name', read_only=True)
    sale_order_no = serializers.CharField(source='sale_order.no', read_only=True)
    status = serializers.CharField(read_only=True)
    status_text = serializers.CharField(source='get_status_display', read_only=True)
    create_user_text = serializers.CharField(source='create_user.name', read_only=True)
    create_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    check_user_text = serializers.CharField(source='check_user.name', read_only=True)
    check_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    warehouse_text = serializers.CharField(source='warehouse.name', read_only=True)
    total_count = CountShowCharField(read_only=True)
    total_cost = AmountShowCharField(read_only=True)
    total_amount = AmountShowCharField(read_only=True)

    class Meta:
        model = GoodsDeliver
        fields = '__all__'

    @staticmethod
    def factory(user, data, id=None):
        if id:
            instance = GoodsDeliver.getById(id)
        else:
            instance = None
        serializer =GoodsDeliverSerializer(instance, data=data)
        serializer.user = user
        return serializer

    def create(self, validated_data):
        validated_data['create_user'] = self.user
        validated_data['department'] = self.user.department
        deliver = GoodsDeliver.objects.create(**validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品出库记录[%s]，id=%d" % (deliver.no, deliver.id),
            validated_data
        )
        return deliver

    def update(self, instance, validated_data):
        instance = super(GoodsDeliverSerializer, self).update(instance, validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.UPDATE,
            u"修改成品出库记录[%s]，id=%d" % (instance.no, instance.id),
            validated_data
        )
        return instance

    def validate(self, data):
        data['agent_department'] = data['agent_user'].department
        return data

    def validSave(self):
        if self.is_valid():
            return self.save()
        else:
            raise CustomError(dump_serializer_errors(self))


class GoodsDeliverDetailSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='product_base.product_base.name', read_only=True)
    model = serializers.CharField(source='product_base.product_base.model', read_only=True)
    unit_text = serializers.CharField(source='product_base.product_base.unit', read_only=True)
    count = CountShowCharField()
    price = PriceShowCharField()
    no = serializers.SerializerMethodField()
    warehouse_stock_count = serializers.CharField(source='warehouse_stock.count', read_only=True)
    total_cost = AmountShowCharField()
    total_amount = AmountShowCharField(read_only=True)

    class Meta:
        model = GoodsDeliverDetail
        fields = '__all__'

    @staticmethod
    def factory(user, data):
        serializer = GoodsDeliverDetailSerializer(None, data=data)
        serializer.user = user
        return serializer

    def get_no(self, obj):
        instance = GoodsGodownEntryDetail.objects.filter(stock_record=obj.warehouse_stockrecord).first()
        if instance:
            no = instance.main.no
        else:
            no = InventoryDetail.objects.filter(warehouse_stock_record=obj.warehouse_stockrecord).first().main.no
        return no

    def create(self, validated_data):
        instance = GoodsDeliverDetail.objects.create(**validated_data)

        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品出库明细[%s]，id=%d" % (instance.product_base.product_base.name, instance.id),
            validated_data
        )
        return instance

    def validSave(self):
        if self.is_valid():
            return self.save()
        else:
            raise CustomError(dump_serializer_errors(self))

    def validate(self, data):
        data['count'] = Formater.formatCount(data['count'])
        data['price'] = Formater.formatPrice(data['price'])
        data['total_amount'] = data['count'] * data['price']
        data['total_cost'] = Formater.formatAmount(data['total_cost'])
        warehouse_stock = WarehouseStock.getByWarehouseAndProduct(data['main'].warehouse, data['product_base'].product_base)
        data['warehouse_stock'] = warehouse_stock

        return data


class GoodsDeliverReturnViewSerializer(serializers.ModelSerializer):
    create_user_text = serializers.CharField(source='create_user.name', read_only=True)
    create_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    customer_name = serializers.CharField(source='customer.name', read_only=True)
    customer_tel = serializers.CharField(source='customer.mobile', read_only=True)
    warehouse_text = serializers.CharField(source='warehouse.name', read_only=True)
    total_count = CountShowCharField(read_only=True)
    total_cost = AmountShowCharField(read_only=True)
    total_amount = AmountShowCharField(read_only=True)
    return_count = CountShowCharField(read_only=True)
    return_cost = AmountShowCharField(read_only=True)

    class Meta:
        model = GoodsDeliver
        fields = '__all__'


class GoodsDeliverReturnSerializer(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    class Meta:
        model = GoodsDeliverReturn
        fields = '__all__'

    @staticmethod
    def factory(user, data):
        serializer = GoodsDeliverReturnSerializer(data=data)
        serializer.user = user
        return serializer

    def create(self, validated_data):
        validated_data['create_user'] = self.user
        validated_data['department'] = self.user.department
        deliver_return = GoodsDeliverReturn.objects.create(**validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品退库记录[%s]，id=%d" % (deliver_return.no, deliver_return.id),
            validated_data
        )
        return deliver_return


    def validSave(self):
        if self.is_valid():
            return self.save()
        else:
            raise CustomError(dump_serializer_errors(self))

class GoodsDeliverReturnDetailSerializer(serializers.ModelSerializer):

    class Meta:
        model = GoodsDeliverReturnDetail
        fields = '__all__'

    @staticmethod
    def factory(user, data):
        serializer = GoodsDeliverReturnDetailSerializer(data=data)
        serializer.user = user
        return serializer

    def create(self, validated_data):
        deliver_return_detail = GoodsDeliverReturnDetail.objects.create(**validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品退库明细记录[%s]，id=%d" % (deliver_return_detail.main.no, deliver_return_detail.id),
            validated_data
        )
        return deliver_return_detail


    def validSave(self):
        if self.is_valid():
            return self.save()
        else:
            raise CustomError(dump_serializer_errors(self))

    def validate(self, data):
        data['return_count'] = Formater.formatCount(data['return_count'])
        warehouse_stock = WarehouseStock.getByWarehouseAndProduct(data['deliver_detail'].main.warehouse, data['product_base'].product_base)
        data['warehouse_stock'] = warehouse_stock
        data['warehouse_record'] = BizWarehouse.deliveredBack(data['deliver_detail'].warehouse_record, data['return_count'])
        data['return_cost'] = data['warehouse_record'].amount
        return data
