#coding=utf-8

from rest_framework import serializers

from apps import base
from apps.base import Formater
from apps.exceptions import CustomError
from apps.foundation.models import BizLog
from apps.serializer_errors import dump_serializer_errors
from models import Goods, GoodsGodownEntry, GoodsGodownEntryDetail
from libs.booleancharfield import BooleanCharField, PriceShowCharField, CountShowCharField, AmountShowCharField
from apps.product.models import ProductBase
from apps.warehouse.models import WarehouseStock


class GoodsSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='product_base.name', read_only=True)
    model = serializers.CharField(source='product_base.model', read_only=True)
    option_type = serializers.CharField(source='product_base.option_type.id', read_only=True)
    option_type_text = serializers.CharField(source='product_base.option_type.name', read_only=True)
    warehouse_place = serializers.CharField(source='product_base.warehouse_place', allow_blank=True, read_only=True)
    retail_price = PriceShowCharField()
    enabled_text = BooleanCharField(source='product_base.enabled', read_only=True)
    enabled = serializers.BooleanField(source='product_base.enabled', read_only=True)
    notes = serializers.CharField(source='product_base.notes', allow_blank=True, read_only=True)
    unit = serializers.CharField(source='product_base.unit', read_only=True)
    code = serializers.CharField(source='product_base.code', read_only=True)
    class Meta:
        model = Goods
        fields = '__all__'

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

    def create(self, validated_data):
        product = Goods.objects.create(**validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品[%s]，id=%d" % (product.product_base.name, product.id),
            validated_data
        )
        return product

    def update(self, instance, validated_data):
        instance = super(GoodsSerializer, self).update(instance, validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.UPDATE,
            u"修改成品[%s]，id=%d" % (instance.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):
        if 'retail_price' in data:
            data['retail_price'] = Formater.formatPrice(data['retail_price'])
        return data


class GoodsGodownEntrySerializer(serializers.ModelSerializer):
    status = serializers.CharField(read_only=True)
    no = 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)
    department_text = serializers.CharField(source='department.name', read_only=True)
    total_count = CountShowCharField(read_only=True)
    total_amount = AmountShowCharField(read_only=True)
    total_invoice_amount = AmountShowCharField(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)
    create_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
    warehouse_text = serializers.CharField(source='warehouse.name', read_only=True)

    class Meta:
        model = GoodsGodownEntry
        fields = '__all__'

    @staticmethod
    def factory(user, data, id=None):
        if id:
            instance = GoodsGodownEntry.getById(id)
        else:
            instance = None
        serializer = GoodsGodownEntrySerializer(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
        instance = GoodsGodownEntry.objects.create(**validated_data)
        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品入库单[%s]，id=%d" % (instance.no, instance.id),
            validated_data
        )
        return instance

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

    def update(self, instance, validated_data):
        instance = super(GoodsGodownEntrySerializer, 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 GoodsGodownEntryDetailSerializer(serializers.ModelSerializer):
    goods_text = serializers.CharField(source='goods.product_base.name', read_only=True)
    goods_model = serializers.CharField(source='goods.product_base.model', read_only=True)
    count = CountShowCharField()
    price = PriceShowCharField()
    amount = AmountShowCharField(read_only=True)
    invoice_amount = AmountShowCharField()

    class Meta:
        model = GoodsGodownEntryDetail
        fields = '__all__'

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

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

        BizLog.objects.addnew(
            self.user,
            BizLog.INSERT,
            u"添加成品入库明细[%s]，id=%d" % (instance.goods.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['price'] = Formater.formatPrice(data['price'])
        data['count'] = Formater.formatCount(data['count'])
        data['amount'] = data['count'] * data['price']
        data['invoice_amount'] = Formater.formatAmount(data['invoice_amount'])

        warehouse = data['main'].warehouse
        product_base = data['goods'].product_base
        warehouse_stock = WarehouseStock.getByWarehouseAndProduct(warehouse, product_base)
        data['warehouse_stock'] = warehouse_stock

        return data


class GoodsProductSerializer(serializers.ModelSerializer):
    option_type_text = serializers.CharField(source='option_type.name', read_only=True)
    stock_count = CountShowCharField()
    enabled_text = BooleanCharField(source='enabled', read_only=True)

    class Meta:
        model = ProductBase
        fields = '__all__'


