# coding=utf-8

import traceback
import json

from django.db.models import Q, Sum
from django.db.models import ProtectedError
from django.views.decorators.csrf import csrf_exempt
from django.db import transaction, IntegrityError
from django.conf import settings
from apps.base import Formater
from apps.finance.filters import FinanceCategoryFilter, FinancePurposeFilter, FinanceIncomeFilter
from apps.finance.models import FinanceCategory, FinancePurpose, dbFinanceIncome
from apps.finance.serializers import FinanceCategorySerializer, FinancePurposeSerializer, FinanceIncomeSerializer
from apps.account.decorators import token_required, permission_required
from apps.foundation.models import BizLog, Option

from libs.http import JSONResponse, JSONError, DataGridJSONResponse
from libs import utils
from apps.exceptions import CustomError


@csrf_exempt
@permission_required('finance.view_finance_category')
def finance_category_list(request):
    f = FinanceCategoryFilter(request.GET, queryset=FinanceCategory.objects.filter())
    rows, total = utils.get_page_data(request, f.qs)
    serializer = FinanceCategorySerializer(rows, many=True)
    return DataGridJSONResponse(serializer.data, total)\


@csrf_exempt
@token_required
def finance_category_dict(request):
    result = {
        'category': FinanceCategorySerializer(FinanceCategory.objects.filter(enabled=True), many=True).data,
        'purpose': FinancePurposeSerializer(FinancePurpose.objects.filter(enabled=True), many=True).data,
    }
    return JSONResponse(result)


@csrf_exempt
@permission_required('finance.add_finance_category')
def finance_category_save(request):
    id = request.GET.get('id')
    data = json.loads(request.body)

    try:
        with transaction.atomic():
            serializer = FinanceCategorySerializer.factory(request.user, data, id)
            serializer.validSave()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse({})


@csrf_exempt
@permission_required('finance.delete_finance_category')
def finance_category_delete(request):
    id = request.GET.get('id')

    try:
        with transaction.atomic():
            instance = FinanceCategory.getById(id)
            BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除财务收支类别[%s]，id=%d" % (instance.name, instance.id))
            instance.delete()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except ProtectedError:
        return JSONError(u'该财务收支类别已被使用，禁止删除！')
    except IntegrityError:
        return JSONError(u'该财务收支类别已被使用，禁止删除！')
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'删除失败！')

    return JSONResponse({})


@csrf_exempt
@permission_required('finance.view_finance_category')
def finance_purpose_list(request):
    f = FinancePurposeFilter(request.GET, queryset=FinancePurpose.objects.filter())
    rows, total = utils.get_page_data(request, f.qs)
    serializer = FinancePurposeSerializer(rows, many=True)
    return DataGridJSONResponse(serializer.data, total)


@csrf_exempt
@permission_required('finance.add_finance_category')
def finance_purpose_save(request):
    id = request.GET.get('id')
    data = json.loads(request.body)
    try:
        with transaction.atomic():
            serializer = FinancePurposeSerializer.factory(request.user, data, id)
            serializer.validSave()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse({})


@csrf_exempt
@permission_required('finance.delete_finance_category')
def finance_purpose_delete(request):
    id = request.GET.get('id')

    try:
        with transaction.atomic():
            instance = FinancePurpose.getById(id)
            BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除财务收支用途[%s]，id=%d" % (instance.name, instance.id))
            instance.delete()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except ProtectedError:
        return JSONError(u'该财务收支用途已被使用，禁止删除！')
    except IntegrityError:
        return JSONError(u'该财务收支用途已被使用，禁止删除！')
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'删除失败！')

    return JSONResponse({})

@csrf_exempt
@permission_required('finance.view_finance_income')
def finance_income_list(request):
    department_ids = request.user.getSubDepartmentIds()
    user_ids = request.user.getSubEmployeeIds()
    # f = FinanceIncomeFilter(request.GET, queryset=dbFinanceIncome.objects.filter())
    rows = dbFinanceIncome.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
    f = FinanceIncomeFilter(request.GET, queryset=rows)
    total_row = f.qs.aggregate(sum_amount=Sum('amount'))
    more = {
        'sum_amount': Formater.formatAmountShow(total_row['sum_amount']),
    }

    rows, total = utils.get_page_data(request, f.qs)
    serializer = FinanceIncomeSerializer(rows, many=True)
    return DataGridJSONResponse(serializer.data, total, more)


@csrf_exempt
@permission_required('finance.add_finance_income')
def finance_income_save(request):
    id = request.GET.get('id')
    data = json.loads(request.body)

    try:
        with transaction.atomic():

            serializer = FinanceIncomeSerializer.factory(request.user, data, id)
            if serializer.instance and serializer.instance.check_status == settings.PASS:
                raise CustomError(u'该收支单已审核，禁止修改！')
            serializer.validSave()
            BizLog.objects.addnew(request.user, BizLog.DELETE, u"编辑收支单[%s]，id=%d" % (serializer.instance.no, serializer.instance.id), data)
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse({})

@csrf_exempt
@permission_required('finance.check_finance_income')
def finance_income_check(request):
    id = request.GET.get('id')
    check_status = request.GET.get('check_status')
    try:
        with transaction.atomic():
            instance = dbFinanceIncome.getById(id)
            instance.check_status = check_status
            instance.save()
            BizLog.objects.addnew(request.user, BizLog.DELETE, u"审核收支单[%s]，id=%d" % (instance.no, instance.id), check_status)
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse({})

@csrf_exempt
@permission_required('finance.view_finance_income')
def finance_bank_data(request):
    create_time = request.GET.get('create_time')
    end_time = request.GET.get('end_time')
    data = []
    more = {
        'qichu_yue': 0,
        'benqi_shouru': 0,
        'benqi_fachu': 0,
        'qimo_yue': 0,
    }
    rows = dbFinanceIncome.objects.filter(check_status=settings.PASS)
    accounts = Option.objects.filter(type=Option.PAYMENT_ACCOUNT, enabled=True)
    for account in accounts:
        qichu_yue = rows.filter(create_time__lt=create_time, account=account).aggregate(amount=Sum('amount'))['amount']
        benqi_shouru = rows.filter(Q(create_time__gte=create_time,create_time__lte=end_time,account=account,),
                                   Q(type=dbFinanceIncome.SALE_ENTRY_PAY,) | Q(purpose__type=FinancePurpose.PAY,)
                                   ).aggregate(amount=Sum('amount'))['amount']

        benqi_fachu = rows.filter(create_time__gte=create_time,create_time__lte=end_time,account=account,
                                   ).exclude(Q(type=dbFinanceIncome.SALE_ENTRY_PAY) | Q( purpose__type=FinancePurpose.PAY,)).aggregate(amount=Sum('amount'))['amount']
        qimo_yue = rows.filter(create_time__lte=end_time, account=account).aggregate(amount=Sum('amount'))['amount']

        more['qichu_yue'] += qichu_yue or 0
        more['benqi_shouru'] += benqi_shouru or 0
        more['benqi_fachu'] += benqi_fachu or 0
        more['qimo_yue'] += qimo_yue or 0
        item = {
            'name':account.name,
            'qichu_yue':Formater.formatAmountShow(qichu_yue),
            'benqi_shouru':Formater.formatAmountShow(benqi_shouru),
            'benqi_fachu':Formater.formatAmountShow(benqi_fachu),
            'qimo_yue':Formater.formatAmountShow(qimo_yue),
        }
        data.append(item)
    more = {
        'qichu_yue': Formater.formatAmountShow(more['qichu_yue']),
        'benqi_shouru': Formater.formatAmountShow(more['benqi_shouru']),
        'benqi_fachu': Formater.formatAmountShow(more['benqi_fachu']),
        'qimo_yue': Formater.formatAmountShow(more['qimo_yue']),
    }
    return DataGridJSONResponse(data, len(data), more)
