import datetime
import json
import logging as logger
import re

from django.db import transaction
from rest_framework.serializers import (Serializer, IntegerField,
                                        ValidationError, ModelSerializer,
                                        SerializerMethodField, CharField,
                                        ListField, DictField, DateField,
                                        FloatField)

from common.utils.service_code import PARAMETER_ERROR
# from common.third_party_api.amap.openapi import AmapApi
from common.accounts.serializers import UsersLCSerializer
from common.utils.service_code import SERVICE_ERROR
from common.notify.message import MessageObject

from console.inspection.models import (InspectionPlan, InspectionTask, Team,
                                       InspectionTaskRecord, InspectionReport)
from console.inspection.models import InspectionData
from console.inspection.models import (StationBuilding, SafetyEquipment,
                                       InspectIn, InspectOut, Defect)
from console.inspection.services import (get_data_item_info)
from console.powerstation.models import PowerStation
from console.electrical_info.models import ElectricalInfromation
from console.customer.models import Customer, CustomerAdmin
from console.inspection.models import PowerInspectionData
from console.powerstation.models import Outline

from console.task.utils import get_serial_number

from console.customer.models import Contact

LOG = logger.getLogger()


class SpectPlanCreateSerializer(Serializer):
    data = ListField(child=DictField(), required=True, allow_null=False)

    def validate(self, attrs):
        '''

        :param attrs: 参数为列表，元素为字典，格式如{"station":1,"plan_date":2009-01-01}
        :return:
        '''
        if not isinstance(attrs, dict):
            raise ValidationError("请求数据格式不正确，应为list", code=PARAMETER_ERROR)
        for item in attrs.get("data"):
            station = PowerStation.objects.filter(
                id=item.get("station_id")).first()
            # 验证电站是否存在
            if not station:
                raise ValidationError("电站%s不存在" % item.get("station_id"),
                                      code=PARAMETER_ERROR)
            # 验证计划日期的格式是否合规
            plan_date = item.get("plan_date")
            if not isinstance(plan_date, datetime.datetime) and \
                    not re.match("[1,2][0-9]{3}-[0,1][0-9]-[0-3][0-9]",
                                 plan_date):
                raise ValidationError("日期格式不合法")
            plan = InspectionPlan.objects.filter(station=station,
                                                 plan_date=plan_date).first()
            if str(plan_date) < str(datetime.datetime.now()):
                raise ValidationError("巡检计划不能安排到已过去的时间！")
            # 验证巡检计划是否已存在
            if plan:
                raise ValidationError("电站{}在{}的巡检计划已存在".format(
                    item.get("station_id"), item.get("plan_date")),
                    code=PARAMETER_ERROR)
            plan_date = datetime.datetime.strptime(str(plan_date), "%Y-%m-%d")
            # 验证电站巡检计划是否已排满
            if not item.get("id"):
                year = plan_date.year
                month = plan_date.month
                plan_num = InspectionPlan.objects.filter(
                    station=station,
                    plan_date__year=year,
                    plan_date__month=month).count()
                if station.inspections_number - plan_num <= 0:
                    raise ValidationError("电站%s的本月巡检计划已经排满" % station.id,
                                          code=PARAMETER_ERROR)
            else:
                plan = InspectionPlan.objects.filter(id=item.get("id")).first()
                if not plan:
                    raise ValidationError("巡检计划{}不存在".format(item.get("id")))
        return attrs

    @transaction.atomic()
    def create(self, validated_data):
        plan = None
        point = transaction.savepoint()
        try:
            for item in validated_data.get("data"):
                station = PowerStation.objects.filter(
                    id=item.get("station_id")).first()
                leader = station.customer.service_staff if \
                    station.customer else \
                    station.electricity_user.customer.service_staff
                # 修改巡检计划
                if item.get("id"):
                    plan = InspectionPlan.objects.filter(
                        id=item.get("id")).first()
                    plan.plan_date = item.get("plan_date")
                    plan.save()
                    # 同步修改巡检任务
                    task = InspectionTask.objects.filter(plan=plan).first()
                    task.work_date = item.get("plan_date")
                    task.save()
                # 新增巡检计划
                else:
                    plan = InspectionPlan.objects.create(
                        station_id=item.get("station_id"),
                        leader=leader,
                        plan_date=item.get("plan_date"))
                    # 同步生成巡检任务
                    InspectionTask.objects.create(
                        name="IST-" +
                             (datetime.datetime.now().date().strftime("%Y%m") +
                              str(get_serial_number()).zfill(5)),
                        plan=plan,
                        status="waiting_dispatch"
                        if not station.inspector_ids else "pending",
                        team_id=station.inspector_ids,
                        work_date=item.get("plan_date"))
        except Exception as e:
            transaction.savepoint_rollback(point)
            raise ValidationError(e, code=SERVICE_ERROR)
        transaction.savepoint_commit(point)
        return plan


class SpectPlanStationSerializer(ModelSerializer):
    spect_plan_num = SerializerMethodField()
    surplus_plan_num = SerializerMethodField()
    customer = SerializerMethodField()

    def get_spect_plan_num(self, obj):
        return obj.inspections_number or 0

    def get_surplus_plan_num(self, obj):
        month = self.context.get("month")
        leader = self.context.get("leader")
        date = datetime.datetime.strptime(month, "%Y-%m")
        month = date.month
        year = date.year
        plan_num = InspectionPlan.objects.filter(plan_date__year=year,
                                                 plan_date__month=month,
                                                 leader_id=leader,
                                                 station=obj).count()
        surplus_plan_num = obj.inspections_number - plan_num \
            if obj.inspections_number else 0
        return surplus_plan_num if surplus_plan_num > 0 else 0

    def get_customer(self, obj):
        if not obj.customer and not obj.electricity_user.customer:
            return None
        return obj.customer.name if obj.customer else \
            obj.electricity_user.customer.name

    class Meta:
        model = PowerStation
        fields = ('id', 'name', 'spect_plan_num', 'surplus_plan_num',
                  'customer')


class InspectionStationSerializer(ModelSerializer):
    count = SerializerMethodField()
    station = SerializerMethodField()

    def get_station(self, obj):
        request = self.context.get("request")
        leader = request.GET.get("leader")
        queryset = InspectionPlan.objects.filter(
            plan_date__date=obj.get("plan_date")).prefetch_related(
            "station", "station__customer", "station__electricity_user",
            "station__electricity_user__customer")
        if leader:
            queryset = queryset.filter(leader_id=leader)
        return [{
            "id": plan.station.id,
            "name": plan.station.name,
            "customer": {
                "id": plan.station.customer.id,
                "name": plan.station.customer.name
            } if plan.station.customer else {
                "id": plan.station.electricity_user.customer.id,
                "name": plan.station.electricity_user.customer.name
            }
        } for plan in queryset]

    def get_count(self, obj):
        request = self.context.get("request")
        leader = request.GET.get("leader")
        queryset = InspectionPlan.objects.filter(
            plan_date__date=obj.get("plan_date"))
        if leader:
            queryset = queryset.filter(leader_id=leader)
        return queryset.count()

    class Meta:
        model = InspectionPlan
        fields = ('plan_date', "count", "station")


class PlansOfDateSerializer(ModelSerializer):
    station = SerializerMethodField()

    def get_station(self, obj):
        station = PowerStation.objects.filter(id=obj.get("station")).first()
        return StationSerializer(station).data

    class Meta:
        model = InspectionPlan
        fields = ("id", "station", "plan_date")


class StationSerializer(ModelSerializer):
    outline = SerializerMethodField()
    customer = SerializerMethodField()
    inspection_time = SerializerMethodField()
    person = SerializerMethodField()
    phone = SerializerMethodField()

    def get_person(self, obj):
        contact = Contact.objects.filter(customer=obj.customer).first()
        return contact.name if contact else None

    def get_phone(self, obj):
        contact = Contact.objects.filter(customer=obj.customer).first()
        return contact.phone if contact else None

    def get_inspection_time(sel, obj):
        return obj.inspection_time.split(",") if obj.inspection_time else None

    def get_customer(self, obj):
        if not obj.customer and not obj.electricity_user:
            return None
        return {
            "id": obj.customer.id,
            "name": obj.customer.name
        } if obj.customer else \
            {
                "id": obj.electricity_user.customer.id,
                "name": obj.electricity_user.customer.name
            } if obj.electricity_user.customer else None

    def get_outline(self, obj):
        return Outline.objects.filter(powerstation=obj).values(
            "name", "id", "power_number")

    class Meta:
        model = PowerStation
        fields = ('id', 'name', 'addr', 'status', "outline", "customer",
                  "inspection_type", "inspection_time", "phone", "location",
                  "person")


class InspectionPlanDeleteSerializer(Serializer):
    data = ListField(required=True,
                     allow_null=False,
                     child=IntegerField(),
                     help_text="巡检计划id列表")

    def validate(self, attrs):
        if not isinstance(attrs, dict):
            raise ValidationError("参数数据类型不对，应为dict", code=PARAMETER_ERROR)

        for id in attrs.get("data"):
            plan = InspectionPlan.objects.filter(id=id).first()
            if not plan:
                raise ValidationError("巡检计划-{}不存在".format(id))
            if datetime.datetime.now().date() > plan.plan_date.date():
                raise ValidationError("不能删除已经到期的巡检计划", code=PARAMETER_ERROR)
        return attrs


class InspectionPlanUpdateSerializer(Serializer):
    data = ListField(required=True, allow_null=False, child=DictField())

    def validate(self, attrs):
        for item in attrs.get("data"):
            plan = InspectionPlan.objects.filter(id=item.get("id")).first()
            if not plan:
                raise ValidationError("巡检计划%s不存在" % item.get("id"),
                                      code=PARAMETER_ERROR)
            if datetime.datetime.now().date() > plan.plan_date:
                raise ValidationError("不能修改已经到期的巡检计划", code=PARAMETER_ERROR)

            plan_date = item.get("plan_date")
            if not isinstance(plan_date, datetime.datetime):
                raise ValidationError("日期格式不合法")
            if plan_date < datetime.datetime.now():
                raise ValidationError("计划不能安排到已过去的时间", code=PARAMETER_ERROR)
        return attrs

    @transaction.atomic()
    def create(self, validated_data):
        point = transaction.savepoint()
        try:
            for item in validated_data.get("data"):
                plan = InspectionPlan.objects.filter(id=item.get("id")).first()
                plan.plan_date = item.get("plan_date")
                plan.save()
                instance = plan
                #         同步修改巡检任务的工作时间
                spect_task = InspectionTask.objects.filter(plan=plan).first()
                spect_task.work_date = item.get("plan_date")
                spect_task.save()
                transaction.savepoint_commit(point)
                return instance
        except Exception as e:
            transaction.savepoint_rollback(point)
            raise ValidationError(e, code=SERVICE_ERROR)


class SpectTaskAssignSerializer(Serializer):
    team_id = IntegerField(required=False, allow_null=True)
    date = DateField(required=False, allow_null=True)

    def validate(self, attrs):
        # 任务派发
        if attrs.get("team_id"):
            team = Team.objects.filter(id=attrs.get("team_id")).first()
            if not team:
                raise ValidationError("巡检小组%s不存在" % attrs.get("team_id"),
                                      code=PARAMETER_ERROR)
            attrs["team"] = team
        # 修改日期
        if attrs.get("date"):
            if attrs.get("date") < datetime.datetime.now().date():
                raise ValidationError("不能修改到已过去的时间", code=PARAMETER_ERROR)
            plan = InspectionPlan.objects.filter(
                station=self.context.get("plan").station,
                plan_date=attrs.get("date")).first()
            if plan:
                raise ValidationError("该电站{}已安排有巡检任务".format(
                    attrs.get("date")),
                    code=PARAMETER_ERROR)

        return attrs

    @transaction.atomic()
    def update(self, instance, validated_data):
        point = transaction.savepoint()
        try:
            # 分派任务
            if validated_data.get("team_id"):
                team = Team.objects.filter(
                    id=validated_data.get('team_id')).first()
                instance.team = team
                instance.assign_date = datetime.datetime.now()
                instance.status = "pending"
                instance.save()
                # 同步创建一条巡检任务操作记录
                InspectionTaskRecord.objects.create(
                    inspection_task=instance,
                    content="巡检任务{}分派给班组{}({})".format(
                        instance.id,
                        validated_data.get('team').name,
                        validated_data.get('team').id,
                    ),
                    operator=self.context.get("user"))
                # 发送短信通知
                sms = MessageObject()
                phone_list = [
                    member.phone
                    for member in validated_data.get('team').member.all()
                ]
                phone_list.append(
                    validated_data.get('team').team_headman.phone)
                sms.send_sms_multi(phone_list, 781494, [])
            # 修改日期
            elif validated_data.get("date"):
                instance.work_date = validated_data.get("date")
                # 同步修改巡检计划的计划时间
                instance.plan.plan_date = validated_data.get("date")
                instance.plan.save()
                instance.save()
        except Exception as e:
            transaction.savepoint_rollback(point)
            raise ValidationError(e, code=SERVICE_ERROR)
        transaction.savepoint_commit(point)
        return instance


class CustomerInfoSerializer(ModelSerializer):
    company = SerializerMethodField()
    phone = SerializerMethodField()

    def get_phone(self, obj):
        # users = CustomerAdmin.objects.filter(customer=obj).first()
        # return users.user.phone if users and users.user else None
        contact = Contact.objects.filter(customer=obj).first()
        return contact.phone if contact else None

    def get_company(self, obj):
        return obj.enterprise.name if obj.enterprise else None

    class Meta:
        model = Customer
        fields = ("id", "name", "company", "phone")


class InspectionTaskSerializer(ModelSerializer):
    plan = SerializerMethodField()
    team = SerializerMethodField()
    task_log = SerializerMethodField()
    defect = SerializerMethodField()
    customer = SerializerMethodField()
    electricity_user = SerializerMethodField()
    type = SerializerMethodField()

    def get_type(self, obj):
        return "值班站" if obj.type else "普通"

    def get_electricity_user(self, obj):
        try:
            electricity_user = obj.plan.station.electricity_user
            return electricity_user.number
        except Exception as e:
            LOG.error(e)
            return

    def get_customer(self, obj):
        if not obj.plan:
            return
        if not obj.plan.station:
            return
        customer = obj.plan.station.customer if obj.plan.station.customer \
            else obj.plan.station.electricity_user.customer if \
            obj.plan.station.electricity_user else None
        return CustomerInfoSerializer(customer).data

    def get_defect(self, obj):
        defect = Defect.objects.filter(spect_task=obj).first()
        return defect.id if defect else None

    def get_plan(self, obj):
        return PlanSerialzier(obj.plan).data

    def get_team(self, obj):
        return TeamSerializer(obj.team).data

    def get_task_log(self, obj):
        task_log = InspectionTaskRecord.objects.filter(inspection_task=obj)
        return SpectTaskLogSerializer(task_log, many=True).data

    class Meta:
        model = InspectionTask
        fields = ('id', 'name', 'plan', 'team', 'status', 'tag', 'work_date',
                  'assign_date', 'task_log', 'defect', "created_time",
                  "start_time", "end_time", "customer", "electricity_user",
                  "confirm", "type", "inspector", "confirm")


class TeamSerializer(ModelSerializer):
    team_headman = SerializerMethodField()
    member = SerializerMethodField()
    leader = SerializerMethodField()
    phone = SerializerMethodField()

    def get_leader(self, obj):
        return UsersLCSerializer(obj.leader).data

    def get_member(self, obj):
        members = obj.member.all()
        if not members.count():
            return
        return [member.nickname for member in members]

    def get_team_headman(self, obj):
        return obj.team_headman.nickname if obj.team_headman else None

    def get_phone(self, obj):
        return obj.team_headman.phone if obj.team_headman else None

    class Meta:
        model = Team
        fields = ('id', 'name', 'team_headman', 'type', 'car_number', 'leader',
                  'member', 'phone')


class PlanSerialzier(ModelSerializer):
    station = SerializerMethodField()
    customer = SerializerMethodField()

    def get_station(self, obj):
        return StationSerializer(obj.station).data

    def get_customer(self, obj):
        if not obj.station:
            return
        if not obj.station.customer and not obj.station.electricity_user:
            return
        return obj.station.customer.name if obj.station.customer \
            else obj.station.electricity_user.customer.name

    class Meta:
        model = InspectionPlan
        fields = ('id', 'station', 'customer')


class SpectTaskLogSerializer(ModelSerializer):
    class Meta:
        model = InspectionTaskRecord
        fields = ('id', 'content', 'created_time')


class SpectionDataSerializer(ModelSerializer):
    customer = SerializerMethodField()
    station = SerializerMethodField()
    team = SerializerMethodField()
    inspection_task = SerializerMethodField()
    building = SerializerMethodField()
    safety_equirpment = SerializerMethodField()
    power_data = SerializerMethodField()
    electricity_user = SerializerMethodField()
    file = SerializerMethodField()
    image = SerializerMethodField()
    thermal_number = SerializerMethodField()

    def get_thermal_number(self, obj):
        return json.loads(obj.thermal_number) if obj.thermal_number else None

    def get_file(self, obj):
        return json.loads(obj.file) if obj.file else None

    def get_image(self, obj):
        return json.loads(obj.image) if obj.image else None

    def get_electricity_user(self, obj):
        return obj.station.electricity_user.number \
            if obj.station and obj.station.electricity_user else None

    def get_inspection_task(self, obj):
        return {
            "id":
                obj.inspection_task.id,
            "name":
                obj.inspection_task.name,
            "work_date":
                obj.inspection_task.end_time,
            "defect":
                Defect.objects.filter(spect_task=obj.inspection_task).values("id")
        } if obj.inspection_task else None

    def get_customer(self, obj):
        return CustomerInfoSerializer(obj.station.customer).data \
            if obj.station else None

    def get_power_data(self, obj):
        power_inspection_data = PowerInspectionData.objects.filter(
            inspection_task=obj.inspection_task)
        return PowerInspectionDataSerializer(power_inspection_data,
                                             many=True).data

    def get_station(self, obj):
        return StationSerializer(obj.station).data

    def get_team(self, obj):
        return TeamSerializer(obj.team).data

    def get_building(self, obj):
        building = StationBuilding.objects.filter(station=obj.station).first()
        return StationBuildingSerialzier(building).data

    def get_safety_equirpment(self, obj):
        equ = SafetyEquipment.objects.filter(station=obj.station).first()
        return SafetyEquipmentSerializer(equ).data

    class Meta:
        model = InspectionData
        fields = ("id", "customer", "station", "team", "inspection_task",
                  "humidity", "temperature", "weather", "remarks", "building",
                  "safety_equirpment", "power_data", "electricity_user",
                  "file", "battery_voltage", "direct_voltage", "inspector",
                  "thermal_number", "image")


class PowerInspectionDataSerializer(ModelSerializer):
    spect_in = SerializerMethodField()
    spect_out = SerializerMethodField()
    power_number_code = SerializerMethodField()

    def get_power_number_code(self, obj):
        ele_info = ElectricalInfromation.objects.filter(
            id=obj.power_number).first()

        return ele_info.power_number if ele_info else None

    def get_spect_out(self, obj):
        out = InspectOut.objects.filter(inspect_task=obj.inspection_task,
                                        power_number=obj.power_number)
        return InspectOutSerializer(out, many=True).data

    def get_spect_in(self, obj):
        spect_in = InspectIn.objects.filter(inspect_task=obj.inspection_task,
                                            power_number=obj.power_number)
        return InspectInSerializer(spect_in, many=True).data

    class Meta:
        model = PowerInspectionData
        fields = ('id', "power_number", 'meter_number', 'multiplying_power',
                  'power_factor', 'total_active_power', 'peak', 'flat_1',
                  'flat_2', 'valley', 'peak_md', 'flat_1_md', 'flat_2_md',
                  'valley_md', 'max_md', 'declare_md', 'spect_in',
                  "total_capacity", "voltage_level", "real_capacity",
                  "reactive_power_1", "reactive_power_2", "real_power_factor",
                  "spect_out", "power_number_code", "pressure_check")


class StationBuildingSerialzier(ModelSerializer):
    station = SerializerMethodField()

    def get_station(self, obj):
        return StationSerializer(obj.station).data

    class Meta:
        model = StationBuilding
        fields = ('id', 'cable_conduit_status', 'frame_status',
                  'ground_status', 'window_status', 'house_status',
                  'cable_holes_status', 'station')


class SafetyEquipmentSerializer(ModelSerializer):
    station = SerializerMethodField()

    def get_station(self, obj):
        return StationSerializer(obj.station).data

    class Meta:
        model = SafetyEquipment
        fields = ('id', 'electroprobe_status', 'es_check_date', 'ground_wire',
                  'gw_check_date', 'insulating_mat', 'im_check_date',
                  'insulating_gloves', 'ig_check_date', 'insulating_shoes',
                  'is_check_date', 'extinguisher', 'ex_check_date', 'station')


class InspectInSerializer(ModelSerializer):
    class Meta:
        model = InspectIn
        fields = ('id', 'v_ab', 'v_bc', 'v_ca', 'monitor_a', 'monitor_b',
                  'monitor_c', "i_a", "i_b", "i_c")


class InspectOutSerializer(ModelSerializer):
    outline = SerializerMethodField()

    def get_outline(self, obj):
        return {
            "id": obj.outline.id,
            "name": obj.outline.name
        } if obj.outline else None

    class Meta:
        model = InspectOut
        fields = ('id', 'o_ia', 'o_ib', 'o_ic', 'monitor_a', 'monitor_b',
                  'monitor_c', 'voice', 'fan', 'temperature', 'oil_leak',
                  'dry', 'abnormal', 'switch_v_ab', 'switch_v_bc', 'switch_ia',
                  'switch_ib', 'switch_v_ca', 'switch_ic', 'GGJ', "cos",
                  "power", "outline", "temperature_a", "temperature_b",
                  "temperature_c")


class DefectSerializer(ModelSerializer):
    customer = SerializerMethodField()
    station = SerializerMethodField()
    team = SerializerMethodField()
    file = SerializerMethodField()

    def get_file(self, obj):
        return json.loads(obj.file.replace("\\", "")) if obj.file else None

    def get_customer(self, obj):
        return CustomerInfoSerializer(obj.customer).data

    def get_station(self, obj):
        return StationSerializer(obj.station).data

    def get_team(self, obj):
        return TeamSerializer(obj.team).data

    class Meta:
        model = Defect
        fields = ('id', 'customer', 'station', 'team', 'status', 'name',
                  'content', 'proposal', 'level', 'possible_result', 'file',
                  'follow_up', 'remark', "type", "created_time")


class DefectHandleSerializer(Serializer):
    def update(self, instance, validated_data):
        instance.status = validated_data.get("status", "completed")
        instance.save()
        return instance


class DefectCreateSerializer(Serializer):
    spect_task = IntegerField(required=True, allow_null=False)
    team = IntegerField(required=True, allow_null=False)
    customer = IntegerField(required=True, allow_null=False)
    station = IntegerField(required=True, allow_null=False)
    level = CharField(required=False, allow_null=True)
    content = CharField(required=False, allow_null=True)
    possible_result = CharField(required=False, allow_null=True)
    proposal = CharField(required=False, allow_null=True)
    file = ListField(child=CharField(required=False, allow_null=True))
    follow_up = CharField(required=False, allow_null=True, allow_blank=True)
    type = CharField(required=False, allow_null=True, allow_blank=True)

    def validate(self, attrs):
        inspect_task = InspectionTask.objects.filter(
            id=attrs.get("spect_task")).first()
        if not inspect_task:
            raise ValidationError("巡检任务{}不存在".format(attrs.get("spect_task")))
        team = Team.objects.filter(id=attrs.get("team")).first()
        if not team:
            raise ValidationError("班组{}不存在".format(attrs.get("team")))
        customer = Customer.objects.filter(id=attrs.get("customer")).first()
        if not customer:
            raise ValidationError("客户{}不存在".format(attrs.get("customer")))
        station = PowerStation.objects.filter(id=attrs.get("station")).first()
        if not station:
            raise ValidationError("电站{}不存在".format(attrs.get("station")))
        attrs["customer"] = customer
        attrs["station"] = station
        return attrs

    def create(self, validated_data):
        defect = Defect.objects.create(
            spect_task_id=validated_data.get("spect_task"),
            team_id=validated_data.get("team"),
            customer=validated_data.get("customer"),
            station=validated_data.get("station"),
            level=validated_data.get("level"),
            content=validated_data.get("content"),
            possible_result=validated_data.get("possible_result"),
            proposal=validated_data.get("proposal"),
            follow_up=validated_data.get("follow_up"),
            status="pending",
            type=validated_data.get("type"),
            name=validated_data.get("type") + "缺陷",
            file=json.dumps(validated_data.get("file"), ensure_ascii=False))
        return defect


class SpectionDataCommitSerializer(Serializer):
    inspection_task = IntegerField(required=True, allow_null=False)
    team = IntegerField(required=True, allow_null=False)
    station = IntegerField(required=True, allow_null=False)
    temperature = FloatField(required=False, allow_null=True)
    humidity = IntegerField(required=False, allow_null=True)
    weather = CharField(required=False, allow_null=True, allow_blank=True)
    remarks = CharField(required=False, allow_null=True, allow_blank=True)
    file = ListField(child=CharField(), allow_null=True, required=False)
    building = DictField(required=False, allow_null=True)
    safety_equirpment = DictField(required=False, allow_null=True)
    power_data = ListField(required=True,
                           allow_null=False,
                           child=DictField(allow_null=False, required=True))
    battery_voltage = CharField(required=False, allow_null=True, allow_blank=True)
    direct_voltage = CharField(required=False, allow_null=True, allow_blank=True)
    # spect_out = ListField(required=True, allow_null=False)
    thermal_number = ListField(required=False,
                               allow_null=True,
                               child=FloatField())
    image = ListField(child=CharField(),
                      required=False,
                      allow_null=True,
                      allow_empty=True)
    inspector = CharField(required=False, allow_null=True, allow_blank=True)

    def validate(self, attrs):
        spect_task = InspectionTask.objects.filter(
            id=attrs.get("inspection_task")).first()
        if not spect_task:
            raise ValidationError("巡检任务%s不存在" % attrs.get("inspection_task"),
                                  code=PARAMETER_ERROR)
        inspection_data = InspectionData.objects.filter(
            inspection_task=spect_task).first()
        if inspection_data:
            # raise ValidationError("本次巡检数据已经提交，请不要重复提交", code=PARAMETER_ERROR)
            attrs["inspection_data"] = inspection_data
        team = Team.objects.filter(id=attrs.get("team")).first()
        if not team:
            raise ValidationError("班组%s不存在" % attrs.get("team"),
                                  code=PARAMETER_ERROR)
        station = PowerStation.objects.filter(id=attrs.get("station")).first()
        if not station:
            raise ValidationError("电站%s不存在" % attrs.get("station"),
                                  code=PARAMETER_ERROR)
        for item in attrs.get("power_data"):
            power_number = ElectricalInfromation.objects.filter(
                id=item.get("power_number")).first()
            if not power_number:
                raise ValidationError("电源编号{}不存在".format(
                    item.get("power_number")),
                    code=PARAMETER_ERROR)
        if attrs.get("safety_equirpment"):
            if attrs["safety_equirpment"]["es_check_date"] == "2021-03-32":
                attrs["safety_equirpment"]["es_check_date"] = "2021-03-31"
            if attrs["safety_equirpment"]["gw_check_date"] == "2021-03-32":
                attrs["safety_equirpment"]["gw_check_date"] = "2021-03-31"
            if attrs["safety_equirpment"]["im_check_date"] == "2021-03-32":
                attrs["safety_equirpment"]["im_check_date"] = "2021-03-31"
            if attrs["safety_equirpment"]["ig_check_date"] == "2021-03-32":
                attrs["safety_equirpment"]["ig_check_date"] = "2021-03-31"
            if attrs["safety_equirpment"]["is_check_date"] == "2021-03-32":
                attrs["safety_equirpment"]["is_check_date"] = "2021-03-31"
            if attrs["safety_equirpment"]["ex_check_date"] == "2021-03-32":
                attrs["safety_equirpment"]["ex_check_date"] = "2021-03-31"
        return attrs

    @transaction.atomic()
    def create(self, validated_data):
        LOG.info(validated_data)
        point = transaction.savepoint()
        try:
            if validated_data.get("inspection_data"):
                spect_data = validated_data.get("inspection_data")
                spect_data.inspection_task_id = validated_data.get("inspection_task")
                spect_data.station_id = validated_data.get("station")
                spect_data.team_id = validated_data.get("team")
                spect_data.temperature = validated_data.get("temperature")
                spect_data.humidity = validated_data.get("humidity")
                spect_data.weather = validated_data.get("weather")
                spect_data.remarks = validated_data.get("remarks")
                spect_data.file = json.dumps(validated_data.get("file"),
                                             ensure_ascii=False)
                spect_data.image = json.dumps(validated_data.get("image"),
                                              ensure_ascii=False)
                spect_data.battery_voltage = validated_data.get("battery_voltage")
                spect_data.direct_voltage = validated_data.get("direct_voltage")
                spect_data.thermal_number = json.dumps(
                    validated_data.get("thermal_number"))
                spect_data.inspector = validated_data.get("inspector")
                spect_data.save()
                for data in validated_data.get("power_data"):
                    power_inspection_data = PowerInspectionData.objects.filter(
                        inspection_task_id=validated_data.get('inspection_task')).first()

                    power_inspection_data.multiplying_power = data.get("multiplying_power")
                    power_inspection_data.power_factor = data.get("power_factor")
                    power_inspection_data.total_active_power = data.get("total_active_power")
                    power_inspection_data.peak = data.get("peak")
                    power_inspection_data.flat_1 = data.get("flat_1")
                    power_inspection_data.flat_2 = data.get("flat_2")
                    power_inspection_data.valley = data.get("valley")
                    power_inspection_data.peak_md = data.get("peak_md")
                    power_inspection_data.flat_1_md = data.get("flat_1_md")
                    power_inspection_data.flat_2_md = data.get("flat_2_md")
                    power_inspection_data.valley_md = data.get("valley_md")
                    power_inspection_data.max_md = data.get("max_md")
                    power_inspection_data.declare_md = data.get("declare_md")
                    power_inspection_data.total_capacity = data.get("total_capacity")
                    power_inspection_data.voltage_level = data.get("voltage_level")
                    power_inspection_data.reactive_power_1 = data.get("reactive_power_1")
                    power_inspection_data.reactive_power_2 = data.get("reactive_power_2")
                    power_inspection_data.pressure_check = data.get("pressure_check")
                    power_inspection_data.real_power_factor = data.get("real_power_factor")
                    power_inspection_data.real_capacity = data.get("real_capacity")
                    power_inspection_data.save()
                    for item in data.get("spect_in", []):
                        spe_in = InspectIn.objects.filter(
                            inspect_task_id=validated_data.get("inspection_task"),
                            power_number=data.get("power_number")).first()
                        spe_in.v_ab = item.get("v_ab")
                        spe_in.v_bc = item.get("v_bc")
                        spe_in.v_ca = item.get("v_ca")
                        spe_in.monitor_a = item.get("monitor_a")
                        spe_in.monitor_b = item.get("monitor_b")
                        spe_in.monitor_c = item.get("monitor_c")
                        spe_in.i_a = item.get("i_a")
                        spe_in.i_b = item.get("i_b")
                        spe_in.i_c = item.get("i_c")
                        spe_in.save()

                    for item in data.get("spect_out"):
                        inspect_out = InspectOut.objects.filter(
                            inspect_task_id=validated_data.get("inspection_task"),
                            power_number=data.get("power_number")).first()
                        inspect_out.o_ia = item.get("o_ia")
                        inspect_out.o_ib = item.get("o_ib")
                        inspect_out.o_ic = item.get("o_ic")
                        inspect_out.outline_id = item.get("outline_id")
                        inspect_out.monitor_a = item.get("monitor_a")
                        inspect_out.monitor_b = item.get("monitor_b")
                        inspect_out.monitor_c = item.get("monitor_c")
                        inspect_out.voice = item.get("voice")
                        inspect_out.fan = item.get("fan")
                        inspect_out.temperature = item.get("temperature")
                        inspect_out.oil_leak = item.get("oil_leak")
                        inspect_out.dry = item.get("dry")
                        inspect_out.abnormal = item.get("abnormal")
                        inspect_out.switch_v_ab = item.get("switch_v_ab")
                        inspect_out.switch_v_bc = item.get("switch_v_bc")
                        inspect_out.switch_ia = item.get("switch_ia")
                        inspect_out.switch_ib = item.get("switch_ib")
                        inspect_out.switch_v_ca = item.get("switch_v_ca")
                        inspect_out.switch_ic = item.get("switch_ic")
                        inspect_out.GGJ = item.get("GGJ")
                        inspect_out.power_station_id = validated_data.get("station")
                        inspect_out.cos = item.get("cos")
                        inspect_out.power = item.get("power")
                        inspect_out.temperature_a = item.get("temperature_a")
                        inspect_out.temperature_b = item.get("temperature_b")
                        inspect_out.temperature_c = item.get("temperature_c")
                        inspect_out.save()
            else:
                spect_data = InspectionData.objects.create(
                    inspection_task_id=validated_data.get("inspection_task"),
                    station_id=validated_data.get("station"),
                    team_id=validated_data.get("team"),
                    temperature=validated_data.get("temperature"),
                    humidity=validated_data.get("humidity"),
                    weather=validated_data.get("weather"),
                    remarks=validated_data.get("remarks"),
                    file=json.dumps(validated_data.get("file"),
                                    ensure_ascii=False),
                    image=json.dumps(validated_data.get("image"),
                                     ensure_ascii=False),
                    battery_voltage=validated_data.get("battery_voltage"),
                    direct_voltage=validated_data.get("direct_voltage"),
                    thermal_number=json.dumps(
                        validated_data.get("thermal_number")),
                    inspector=validated_data.get("inspector"))
                for data in validated_data.get("power_data"):
                    PowerInspectionData.objects.create(
                        inspection_task_id=validated_data.get('inspection_task'),
                        power_number=data.get("power_number"),
                        meter_number=data.get("meter_number"),
                        multiplying_power=data.get("multiplying_power"),
                        power_factor=data.get("power_factor"),
                        total_active_power=data.get("total_active_power"),
                        peak=data.get("peak"),
                        flat_1=data.get("flat_1"),
                        flat_2=data.get("flat_2"),
                        valley=data.get("valley"),
                        peak_md=data.get("peak_md"),
                        flat_1_md=data.get("flat_1_md"),
                        flat_2_md=data.get("flat_2_md"),
                        valley_md=data.get("valley_md"),
                        max_md=data.get("max_md"),
                        declare_md=data.get("declare_md"),
                        total_capacity=data.get("total_capacity"),
                        voltage_level=data.get("voltage_level"),
                        reactive_power_1=data.get("reactive_power_1"),
                        reactive_power_2=data.get("reactive_power_2"),
                        pressure_check=data.get("pressure_check"),
                        real_power_factor=data.get("real_power_factor"),
                        real_capacity=data.get("real_capacity"))
                    for item in data.get("spect_in", []):
                        InspectIn.objects.create(
                            inspect_task_id=validated_data.get("inspection_task"),
                            power_number=data.get("power_number"),
                            v_ab=item.get("v_ab"),
                            v_bc=item.get("v_bc"),
                            v_ca=item.get("v_ca"),
                            monitor_a=item.get("monitor_a"),
                            monitor_b=item.get("monitor_b"),
                            monitor_c=item.get("monitor_c"),
                            i_a=item.get("i_a"),
                            i_b=item.get("i_b"),
                            i_c=item.get("i_c"),
                        )
                    out = []
                    for item in data.get("spect_out"):
                        inspect_out = InspectOut(
                            inspect_task_id=validated_data.get("inspection_task"),
                            power_number=data.get("power_number"),
                            o_ia=item.get("o_ia"),
                            o_ib=item.get("o_ib"),
                            o_ic=item.get("o_ic"),
                            outline_id=item.get("outline_id"),
                            monitor_a=item.get("monitor_a"),
                            monitor_b=item.get("monitor_b"),
                            monitor_c=item.get("monitor_c"),
                            voice=item.get("voice"),
                            fan=item.get("fan"),
                            temperature=item.get("temperature"),
                            oil_leak=item.get("oil_leak"),
                            dry=item.get("dry"),
                            abnormal=item.get("abnormal"),
                            switch_v_ab=item.get("switch_v_ab"),
                            switch_v_bc=item.get("switch_v_bc"),
                            switch_ia=item.get("switch_ia"),
                            switch_ib=item.get("switch_ib"),
                            switch_v_ca=item.get("switch_v_ca"),
                            switch_ic=item.get("switch_ic"),
                            GGJ=item.get("GGJ"),
                            power_station_id=validated_data.get("station"),
                            cos=item.get("cos"),
                            power=item.get("power"),
                            temperature_a=item.get("temperature_a"),
                            temperature_b=item.get("temperature_b"),
                            temperature_c=item.get("temperature_c"),
                        )
                        out.append(inspect_out)
                    InspectOut.objects.bulk_create(out)

            # 电站土建情况检查，数据有更新
            if validated_data.get("building"):
                building = StationBuilding.objects.filter(
                    station_id=validated_data.get("station"))
                # 电站土建情况第一次录入系统
                if not building:
                    StationBuilding.objects.create(
                        cable_conduit_status=validated_data.get(
                            "building").get("cable_conduit_status"),
                        frame_status=validated_data.get("building").get(
                            "frame_status"),
                        ground_status=validated_data.get("building").get(
                            "ground_status"),
                        window_status=validated_data.get("building").get(
                            "window_status"),
                        house_status=validated_data.get("building").get(
                            "house_status"),
                        cable_holes_status=validated_data.get("building").get(
                            "cable_holes_status"),
                        station_id=validated_data.get("station"))
                else:
                    # building(**validated_data.get("building")).save()
                    StationBuilding.objects.filter(
                        station_id=validated_data.get("station")).update(
                        **validated_data.get("building"))
            # 安全器具检查，数据有更新
            if validated_data.get("safety_equirpment"):
                safe_equipment = SafetyEquipment.objects.filter(
                    station_id=validated_data.get("station")).first()
                if not safe_equipment:
                    SafetyEquipment.objects.create(
                        station_id=validated_data.get("station"),
                        electroprobe_status=validated_data.get(
                            "safety_equirpment").get("electroprobe_status"),
                        es_check_date=datetime.datetime.now().date(),
                        ground_wire=validated_data.get(
                            "safety_equirpment").get("ground_wire"),
                        gw_check_date=datetime.datetime.now().date(),
                        insulating_mat=validated_data.get(
                            "safety_equirpment").get("insulating_mat"),
                        im_check_date=datetime.datetime.now().date(),
                        insulating_gloves=validated_data.get(
                            "safety_equirpment").get("insulating_gloves"),
                        ig_check_date=datetime.datetime.now().date(),
                        insulating_shoes=validated_data.get(
                            "safety_equirpment").get("insulating_shoes"),
                        is_check_date=datetime.datetime.now().date(),
                        extinguisher=validated_data.get(
                            "safety_equirpment").get("extinguisher"),
                        ex_check_date=datetime.datetime.now().date(),
                    )
                else:
                    if validated_data.get("safety_equirpment") == "2021-04-31":
                        validated_data["safety_equirpment"] = "2021-04-30"
                    SafetyEquipment.objects.filter(
                        station_id=validated_data.get("station")).update(
                        **validated_data.get("safety_equirpment"))
            task = InspectionTask.objects.filter(
                id=validated_data.get("inspection_task")).first()
            task.end_time = datetime.datetime.now()
            task.status = "completed"
            task.inspector = validated_data.get("inspector")
            task.save()
        except Exception as e:
            transaction.savepoint_rollback(point)
            raise ValidationError(e)
        transaction.savepoint_commit(point)
        return spect_data


class InspectionTaskArriveSerializer(Serializer):
    def update(self, instance, validated_data):
        instance.start_time = datetime.datetime.now()
        instance.save()
        return instance


class DefectUpdateSerializer(Serializer):
    type = CharField(required=False, allow_blank=True, allow_null=True)
    level = CharField(required=False, allow_blank=True, allow_null=True)
    content = CharField(required=False, allow_blank=True, allow_null=True)
    possible_result = CharField(required=False,
                                allow_blank=True,
                                allow_null=True)
    proposal = CharField(required=False, allow_blank=True, allow_null=True)
    file = ListField(required=False, allow_null=True, child=CharField())
    follow_up = CharField(required=False, allow_blank=True, allow_null=True)

    def update(self, instance, validated_data):
        instance.type = validated_data.get("type")
        instance.level = validated_data.get("level")
        instance.content = validated_data.get("content")
        instance.possible_result = validated_data.get("possible_result")
        instance.proposal = validated_data.get("proposal")
        instance.file = json.dumps(validated_data.get("file"),
                                   ensure_ascii=False)
        instance.follow_up = validated_data.get("follow_up")
        instance.save()
        return instance


class ConfirmSerializer(Serializer):
    def update(self, instance, validated_data):
        instance.confirm = True
        instance.save()
        return instance


class TaskExportSerialzier(ModelSerializer):
    station_name = SerializerMethodField()
    customer_name = SerializerMethodField()
    team_headman = SerializerMethodField()

    def get_team_headman(self, obj):
        return obj.team.team_headman.nickname \
            if obj.team and obj.team.team_headman else None

    def get_station_name(self, obj):
        return obj.plan.station.name \
            if obj.plan and obj.plan.station else None

    def get_customer_name(self, obj):
        return obj.plan.station.customer.name \
            if obj.plan.station and obj.plan.station.customer else None

    class Meta:
        model = InspectionTask
        fields = ("id", "name", "station_name", "customer_name", "status",
                  "team_headman", "work_date", "assign_date")


class DayInspectionTaskSerializer(ModelSerializer):
    customer = SerializerMethodField()
    power_station = SerializerMethodField()
    team = SerializerMethodField()
    data_item = SerializerMethodField()
    type = SerializerMethodField()

    def get_customer(self, obj):
        if not obj.plan.station:
            return
        if not obj.plan.station.customer and obj.plan.station.electricity_user:
            return
        return obj.plan.station.customer.name if obj.plan.station else \
            obj.plan.station.electricity_user.customer.name

    def get_power_station(self, obj):

        return {
            "name": obj.plan.station.name,
            "addr": obj.plan.station.addr,
            "location": obj.plan.station.location
        } if obj.plan.station else None

    def get_team(self, obj):
        return {
            "id": obj.team.id,
            "name": obj.team.name,
            "member": obj.team.member.all().values_list("id", "nickname")
        } if obj.team else None

    def get_type(self, obj):
        return "值班站" if obj.type else "普通"

    def get_data_item(self, obj):
        return get_data_item_info(
            obj.plan.station) if obj.plan.station else None

    class Meta:
        model = InspectionTask
        fields = ("id", "customer", "power_station", "team", "work_date",
                  "type", "data_item")


class TaskCreateSerializer(Serializer):
    customer_id = IntegerField(required=True, allow_null=False)
    station_id = IntegerField(required=True, allow_null=False)
    team_id = IntegerField(required=False, allow_null=True)
    work_date = DateField(required=True, allow_null=False)
    work_time = CharField(required=False, allow_null=True)

    def validate(self, attr):
        customer = Customer.objects.filter(
            id=attr.get("customer_id"),
            service_enterprise_id__in=self.context.get(
                "enterprise_id")).first()
        if not customer:
            raise ValidationError("客户{}不存在".format(attr.get("customer_id")))
        station = PowerStation.objects.filter(
            id=attr.get("station_id")).first()
        if not station:
            raise ValidationError("电站%s不存在" % attr.get("station_id"))
        if attr.get("team_id"):
            team = Team.objects.filter(id=attr.get("team_id")).first()
            if not team:
                raise ValidationError("班组%s不存在" % attr.get("team_id"))
        if attr.get("work_time"):
            if not re.match("[0-9]{2}:[0-9]{2}", attr.get("work_time")):
                raise ValidationError("执行时间格式不正确，必须是xx:xx的格式!")

        plan_date = (attr.get("work_date").strftime("%Y-%m-%d") + " " +
                     attr.get("work_time", "00:00:00"))
        plan = InspectionPlan.objects.filter(station_id=attr.get("station_id"),
                                             plan_date=plan_date)
        if plan:
            raise ValidationError("同一个电站的巡检时间不能安排在同一个时间")
        attr["customer"] = customer
        attr["station"] = station
        return attr

    @transaction.atomic()
    def create(self, validated_data):
        point = transaction.savepoint()
        try:
            plan_date = (validated_data.get("work_date").strftime("%Y-%m-%d") +
                         " %s:00" % validated_data.get("work_time")
                         if validated_data.get("work_time") else
                         validated_data.get("work_date"))
            plan = InspectionPlan.objects.create(
                station_id=validated_data.get("station_id"),
                plan_date=plan_date,
                leader=validated_data.get("customer").service_staff)
            # 同步生成巡检任务
            task = InspectionTask.objects.create(
                name="IST-" +
                     (datetime.datetime.now().date().strftime("%Y%m%d") +
                      str(get_serial_number()).zfill(5)),
                plan=plan,
                status="waiting_dispatch"
                if not validated_data.get("team_id") else "pending",
                work_date=plan_date,
                team_id=validated_data.get("team_id"),
                assign_date=datetime.datetime.now()
                if validated_data.get("team_id") else None,
                type=1 if validated_data.get("station").inspection_type else 0)
            transaction.savepoint_commit(point)
            return task

        except Exception:
            transaction.savepoint_rollback(point)


class TaskManyAssignSerializer(Serializer):
    task_list = ListField(child=IntegerField(),
                          required=True,
                          allow_null=False)
    team_id = IntegerField(required=True, allow_null=False)

    def validate(self, attrs):
        team = Team.objects.filter(id=attrs.get("team_id")).first()
        if not team:
            raise ValidationError("班组%s不存在" % attrs.get("team_id"))
        return attrs


class InspectionUpdateSerializer(Serializer):
    inspection_task = IntegerField(required=True, allow_null=False)
    temperature = FloatField(required=False, allow_null=True)
    humidity = FloatField(required=False, allow_null=True)
    weather = CharField(required=False, allow_null=True, allow_blank=True)
    remarks = CharField(required=False, allow_null=True, allow_blank=True)
    file = ListField(child=CharField(), allow_null=True, required=False)
    building = DictField(required=False, allow_null=True)
    safety_equirpment = DictField(required=False, allow_null=True)
    power_data = ListField(required=True,
                           allow_null=False,
                           child=DictField(allow_null=False, required=True))
    battery_voltage = FloatField(required=False, allow_null=True)
    direct_voltage = FloatField(required=False, allow_null=True)
    # spect_out = ListField(required=True, allow_null=False)
    thermal_number = ListField(required=False,
                               allow_null=True,
                               child=FloatField())
    inspector = CharField(required=False, allow_null=True, allow_blank=True)
    image = ListField(required=False, allow_null=True,
                      child=CharField(required=False, allow_null=True, allow_blank=True))

    def validate(self, attrs):
        task = InspectionTask.objects.filter(
            id=attrs.get("inspection_task")).first()
        if not task:
            raise ValidationError("巡检任务%s不存在" % attrs.get("inspection_task"))
        if task.status != "completed":
            raise ValidationError("巡检任务还没完成，不能修改")
        inspection_data = InspectionData.objects.filter(
            inspection_task_id=attrs.get("inspection_task"))
        if not inspection_data:
            raise ValidationError("巡检任务%s还没有巡检记录" %
                                  attrs.get("inspection_task"))
        return attrs

    @transaction.atomic()
    def update(self, instance, validated_data):
        # step1：更新巡检抄表数据
        inspection_data = InspectionData.objects.filter(
            inspection_task=instance).first()
        inspection_data.temperature = validated_data.get("temperature")
        inspection_data.humidity = validated_data.get("humidity")
        inspection_data.weather = validated_data.get("weather")
        inspection_data.remarks = validated_data.get("remarks")
        inspection_data.battery_voltage = validated_data.get("battery_voltage")
        inspection_data.direct_voltage = validated_data.get("direct_voltage")
        inspection_data.file = validated_data.get("file")
        inspection_data.thermal_number = json.dumps(
            validated_data.get("thermal_number"))
        inspection_data.inspector = validated_data.get("inspector")
        inspection_data.image = json.dumps(validated_data.get("image")) if validated_data.get("image") else None
        inspection_data.save()
        # step2:更新站内设施
        validated_data.get("building").pop("station")
        StationBuilding.objects.filter(station=instance.plan.station).update(
            **validated_data.get("building"))
        # step3：更新安全器具
        if validated_data.get("safety_equirpment").get("station"):
            validated_data.get("safety_equirpment").pop("station")
        SafetyEquipment.objects.filter(station=instance.plan.station).update(
            **validated_data.get("safety_equirpment"))
        # step4:更新进线侧数据
        for item in validated_data.get("power_data", []):
            spect_in = item.pop("spect_in", [])
            spect_out = item.pop("spect_out", [])
            item.pop('power_number_code')
            PowerInspectionData.objects.filter(
                inspection_task=instance,
                power_number=item.get("power_number")).update(**item)

            for data in spect_in:
                InspectIn.objects.filter(
                    inspect_task=instance,
                    power_number=item.get("power_number")).update(**data)
            # step5:更新出线侧数据
            for out in spect_out:
                if out.get("name"):
                    out.pop("name")
                outline = out.pop("outline", None)
                out.pop("id", None)
                # 'outline': {'id': 1031, 'name': '403乙-3'}
                if outline:
                    outline_id = outline.get("id")
                    InspectOut.objects.filter(
                        inspect_task=instance,
                        power_number=item.get("power_number"),
                        outline=outline_id).update(**out)
                else:
                    InspectOut.objects.filter(
                        inspect_task=instance,
                        power_number=item.get("power_number")).update(**out)
        return instance


class TaskRecentSerialzier(ModelSerializer):
    plan = SerializerMethodField()
    team = SerializerMethodField()
    electricity_user = SerializerMethodField()

    def get_plan(self, obj):
        return PlanRecentSerializer(obj.plan).data

    def get_team(self, obj):
        return {
            "id":
                obj.team.id,
            "name":
                obj.team.name,
            "team_headman":
                obj.team.team_headman.nickname if obj.team.team_headman else None,
            "member": [item.nickname for item in obj.team.member.all()]
        } if obj.team else None

    def get_electricity_user(self, obj):
        if not obj.plan or not obj.plan.station:
            return None
        return obj.plan.station.electricity_user.number \
            if obj.plan.station.electricity_user else None

    class Meta:
        model = InspectionTask
        fields = ("id", "plan", "name", "team", "status", "work_date",
                  "assign_date", "electricity_user", "inspector")


class PlanRecentSerializer(ModelSerializer):
    station = SerializerMethodField()

    def get_station(self, obj):
        customer = obj.station.customer if obj.station.customer \
            else obj.station.electricity_user.customer \
            if obj.station.electricity_user else None
        dt = {
            "id": obj.station.id,
            "name": obj.station.name,
            "addr": obj.station.addr,
            "customer": {
                "id": customer.id,
                "name": customer.name
            } if customer else None,
            "phone": obj.station.phone,
            "location": obj.station.location,
            "person": obj.station.person
        } if obj.station else None
        return dt

    class Meta:
        model = InspectionPlan
        fields = ("id", "station")


class InspectionTaskInfoSerializer(ModelSerializer):
    plan = SerializerMethodField()
    team = SerializerMethodField()
    task_log = SerializerMethodField()
    defect = SerializerMethodField()
    customer = SerializerMethodField()
    electricity_user = SerializerMethodField()
    type = SerializerMethodField()
    last_task_info = SerializerMethodField()
    pdf_url = SerializerMethodField()

    def get_pdf_url(self, obj):
        report = InspectionReport.objects.filter(task=obj).first()
        return report.url if report else None

    def get_last_task_info(self, obj):
        plan = InspectionPlan.objects.filter(station=obj.plan.station)
        task = InspectionTask.objects.filter(
            plan__in=plan).order_by("-end_time").first()
        objects = PowerInspectionData.objects.filter(inspection_task=task)
        return InspectionDataSerializer(objects, many=True).data

    def get_type(self, obj):
        return "值班站" if obj.type else "普通"

    def get_electricity_user(self, obj):
        try:
            electricity_user = obj.plan.station.electricity_user
            return electricity_user.number
        except Exception as e:
            LOG.error(e)
            return

    def get_customer(self, obj):
        if not obj.plan:
            return
        if not obj.plan.station:
            return
        customer = obj.plan.station.customer if obj.plan.station.customer \
            else obj.plan.station.electricity_user.customer
        return CustomerInfoSerializer(customer).data

    def get_defect(self, obj):
        defect = Defect.objects.filter(spect_task=obj).first()
        return defect.id if defect else None

    def get_plan(self, obj):
        return PlanSerialzier(obj.plan).data

    def get_team(self, obj):
        return TeamSerializer(obj.team).data

    def get_task_log(self, obj):
        task_log = InspectionTaskRecord.objects.filter(inspection_task=obj)
        return SpectTaskLogSerializer(task_log, many=True).data

    class Meta:
        model = InspectionTask
        fields = ('id', 'name', 'plan', 'team', 'status', 'tag', 'work_date',
                  'assign_date', 'task_log', 'defect', "created_time",
                  "start_time", "end_time", "customer", "electricity_user",
                  "confirm", "type", "inspector", "last_task_info", "pdf_url",
                  "confirm")


class InspectionDataSerializer(ModelSerializer):
    class Meta:
        model = PowerInspectionData
        fields = ('id', "power_number", 'meter_number', 'multiplying_power',
                  'power_factor', 'total_active_power', 'peak', 'flat_1',
                  'flat_2', 'valley', 'peak_md', 'flat_1_md', 'flat_2_md',
                  'valley_md', 'max_md', 'declare_md', "total_capacity",
                  "voltage_level", "real_capacity", "reactive_power_1",
                  "reactive_power_2", "real_power_factor", "pressure_check")


class PowerInspectionDataPowerSerializer(ModelSerializer):
    class Meta:
        model = PowerInspectionData
        fields = ("id", "power_number", "total_active_power", "reactive_power_1", "reactive_power_2")


class DefectExportSerializer(ModelSerializer):
    customer = SerializerMethodField()
    ele_user = SerializerMethodField()
    status = SerializerMethodField()

    def get_customer(self, obj):
        return obj.customer.name if obj.customer else None

    def get_ele_user(self, obj):
        return obj.station.electricity_user.number if obj.station and obj.station.electricity_user else None

    def get_status(self, obj):
        return "已处理" if obj.status == "completed" else "未处理"

    class Meta:
        model = Defect
        fields = ("status", "content", "proposal", "level", "possible_result", "follow_up", "remark",
                  "customer", "ele_user", "created_time")


class SafetyEquipmentInfoSerializer(ModelSerializer):
    class Meta:
        model = SafetyEquipment
        fields = ('id', 'electroprobe_status', 'es_check_date', 'ground_wire',
                  'gw_check_date', 'insulating_mat', 'im_check_date',
                  'insulating_gloves', 'ig_check_date', 'insulating_shoes',
                  'is_check_date', 'extinguisher', 'ex_check_date')


class ReportUploadSerializer(Serializer):
    task_id = CharField(required=True, allow_blank=False, allow_null=False)
    url = CharField(required=True, allow_blank=False, allow_null=False)

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

    def update(self, instance, validated_data):
        instance.url = validated_data.get("url")
        instance.save()
        return instance
