# coding=utf-8

import json
import traceback
import tablib

from django.db import transaction,IntegrityError, connection
from django.db.models import ProtectedError
from django.views.decorators.csrf import csrf_exempt
from django.utils import timezone

from apps.product.models import ProductBase
from libs import utils
from libs.http import JSONResponse, JSONError, DataGridJSONResponse
from apps.account.decorators import token_required, valid_permission, isHasPermissions
from apps.exceptions import CustomError

from apps.foundation.models import BizLog

from apps.purchase.models import GodownEntry, GodownEntryDetail
from apps.goods.models import GoodsGodownEntry, GoodsGodownEntryDetail
from models import Warehouse, WarehouseAdmin, WarehouseStock, WarehouseRecord, WarehouseStockRecord, InventoryDetail, Inventory
from filters import WarehouseFilter
from serializers import WarehouseSerializer
from apps.base import Formater

@token_required
def warehouse_list(request):
    try:
        valid_permission(request.user,Warehouse.getPermissionByType(request.GET.get('type'), 'view'))
    except:
        return DataGridJSONResponse([], 0)

    f = WarehouseFilter(request.GET, queryset=Warehouse.objects.filter())
    rows, total = utils.get_page_data(request, f.qs)
    serializer = WarehouseSerializer(rows, many=True)
    return DataGridJSONResponse(serializer.data, total)

@csrf_exempt
@token_required
def warehouse_save(request):
    id = request.GET.get('id')
    data = json.loads(request.body)

    try:
        with transaction.atomic():
            serializer = WarehouseSerializer.factory(request.user,data,id)
            ws = serializer.validSave()
            valid_permission(request.user,ws.getPermission('add'))
            ws.removeAdmins()
            for userid in data['user']:
                ws.addAdminByUserId(int(userid))
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse()

@token_required
def warehouse_delete(request):
    id = request.GET.get('id')

    try:
        with transaction.atomic():
            w = Warehouse.getById(id)
            valid_permission(request.user,w.getPermission('delete'))
            w.removeAdmins()
            w.removeStock()
            BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除仓别[%s]，id=%d" % (w.name, w.id))
            w.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({})

@token_required
def warehouse_select(request):
    data = []

    try:
        type = Warehouse.getValidType(request.GET.get('type'))
        warehouses = WarehouseAdmin.objects.filter(user=request.user, warehouse__type=type,warehouse__enabled=True).order_by('-warehouse__is_default','-warehouse_id').values('warehouse_id', 'warehouse__name')
        for row in warehouses:
            item = {
                'id': row['warehouse_id'],
                'value': row['warehouse__name']
            }
            data.append(item)
    except Exception, e:
        traceback.print_exc()

    return JSONResponse(data)

@token_required
def warehouse_all_select(request):
    type = Warehouse.getValidType(request.GET.get('type'))
    data = []

    rows = Warehouse.objects.filter(type=type)

    for row in rows:
        item = {
            'id': row.id,
            'name': row.name
        }
        data.append(item)
    return JSONResponse(data)


@csrf_exempt
@token_required
def stock_list(request):
    product_name_model = request.GET.get('product_name_model')
    warehouse = request.GET.get('warehouse')
    last_entry_time = request.GET.get('last_entry_time')
    last_deliver_time = request.GET.get('last_deliver_time')
    type = int(request.GET.get('type'))
    warehouse_place = request.GET.get('warehouse_place')
    enable = request.GET.get('product_enabled')
    stock_time = request.GET.get('stock_time')
    empty = request.GET.get('empty')
    source = request.GET.get('source')
    page, page_size = utils.get_page_info(request)

    try:
        valid_permission(request.user, WarehouseStock.getPermissionByType(type, 'view'))
    except:
        return DataGridJSONResponse([], 0)

    rows, total, stock_count, warehouse_amount = WarehouseStock.objects.fetch_stock(request.user, stock_time, product_name_model, warehouse, last_entry_time, last_deliver_time,
                                                                                   type, warehouse_place, enable, page, page_size,empty,source,)

    more = {
        'stock_count': stock_count,
        'warehouse_amount': warehouse_amount,
    }

    return DataGridJSONResponse(rows, total, more)

@csrf_exempt
@token_required
def stock_export(request):
    product_name_model = request.GET.get('product_name_model')
    warehouse = request.GET.get('warehouse')
    last_entry_time = request.GET.get('last_entry_time')
    last_deliver_time = request.GET.get('last_deliver_time')
    type = request.GET.get('type')
    warehouse_place = request.GET.get('warehouse_place')
    enable = request.GET.get('product_enabled')
    stock_time = request.GET.get('stock_time')
    empty = request.GET.get('empty')
    page, page_size = utils.get_page_info(request)
    try:
        valid_permission(request.user, WarehouseStock.getPermissionByType(type, 'export'))
    except:
        return DataGridJSONResponse([], 0)

    rows, total, stock_count, warehouse_amount = WarehouseStock.objects.fetch_stock(request.user, stock_time, product_name_model, warehouse, last_entry_time, last_deliver_time,
                                                                                   type, warehouse_place, enable, page, page_size,empty, '',export=True)
    if int(type) == ProductBase.MATERIAL:
        perm = 'material.view_material_cost'
    elif int(type) == ProductBase.CONSUMABLE:
        perm = 'material.view_consumable_cost'
    elif int(type) == ProductBase.GOODS:
        perm = 'goods.view_goods_cost'
    is_show_cost = isHasPermissions(request.user, perm)
    if is_show_cost:
        headers = (u'名称', u'代码', u'类别', u'单位', u'规格', u'库存', u'仓别', u'存放库位', u'成本价',
                 u'库存金额', u'助记码', u'最后入库时间', u'最后出库时间', u'未出库天数')
        data = []
        for row in rows:
            item = (
                row['product_name'],
                row['product_model'],
                row['option_type_text'],
                row['product_unit'] or '',
                row['product_standard'] or '',
                row['stock'],
                row['warehouse_text'],
                row['warehouse_place'] or '',
                row['avg_cost_price'],
                row['warehouse_amount'],
                row['product_code'] or '',
                row['last_entry_time'],
                row['last_deliverd_time'],
                row['days'],
            )
            data.append(item)
    else:
        headers = (u'名称', u'代码', u'类别', u'单位', u'规格', u'库存', u'仓别', u'存放库位', u'助记码',
                   u'最后入库时间', u'最后出库时间', u'未出库天数')

        data = []
        for row in rows:
            item = (
                row['product_name'],
                row['product_model'],
                row['option_type_text'],
                row['product_unit'] or '',
                row['product_standard'] or '',
                row['stock'],
                row['warehouse_text'],
                row['warehouse_place'] or '',
                row['product_code'] or '',
                row['last_entry_time'],
                row['last_deliverd_time'],
                row['days'],
            )
            data.append(item)
    data = tablib.Dataset(*data, headers=headers, title=u"数据")
    filename = utils.attachment_save(data)
    return JSONResponse({'filename': filename})


@csrf_exempt
@token_required
def stock_ledger_list(request):
    product_type = int(request.GET.get('product_type'))
    product_name = request.GET.get('product_name')
    product_model = request.GET.get('product_model')
    date = request.GET.get('date')
    warehouse = request.GET.get('warehouse')
    exclude_zero = request.GET.get('exclude_zero')
    page, page_size = utils.get_page_info(request)

    try:
        valid_permission(request.user, WarehouseRecord.getPermissionByType(product_type, 'view'))
    except:
        return DataGridJSONResponse([], 0)

    data, total, more = WarehouseStock.objects.fetch_stock_ledger(request.user, product_type, product_name, product_model, date,
                                                            warehouse, exclude_zero, page, page_size)
    return DataGridJSONResponse(data, total, more)

@csrf_exempt
@token_required
def stock_ledger_export(request):
    product_type = int(request.GET.get('product_type'))
    product_name = request.GET.get('product_name')
    product_model = request.GET.get('product_model')
    date = request.GET.get('date')
    warehouse = request.GET.get('warehouse')
    exclude_zero = request.GET.get('exclude_zero')
    page, page_size = utils.get_page_info(request)

    valid_permission(request.user, WarehouseRecord.getPermissionByType(product_type, 'export'))

    rows, total, more = WarehouseStock.objects.fetch_stock_ledger(request.user, product_type, product_name, product_model, date,
                                                             warehouse, exclude_zero, page, page_size, export=True)

    headers = (u'产品名称',
               u'产品代码',
               u'单位',
               u'期初结存数量',
               u'期初结存平均单价',
               u'期初结存金额',
               u'本期收入总数量',
               u'本期收入平均单价',
               u'本期收入总金额',
               u'入库数量',
               u'入库金额',
               u'盘盈数量',
               u'盘盈金额',
               u'退货数量',
               u'退货金额',
               u'本期发出总数量',
               u'本期发出平均单价',
               u'本期发出总金额',
               u'出库数量',
               u'出库金额',
               u'盘亏数量',
               u'盘亏金额',
               u'退料数量',
               u'退料金额',
               u'期末结存数量',
               u'期末结存平均单价',
               u'期末结存金额'
               )
    data = []
    for row in rows:
        item = (
            row['product_name'],
            row['product_model'],
            row['unit'],
            row['prev_count'],
            row['prev_avg'],
            row['prev_amount'],
            row['in_count'],
            row['in_avg'],
            row['in_amount'],
            row['rk_count'],
            row['rk_amount'],
            row['py_count'],
            row['py_amount'],
            row['th_count'],
            row['th_amount'],
            row['out_count'],
            row['out_avg'],
            row['out_amount'],
            row['ck_count'],
            row['ck_amount'],
            row['pk_count'],
            row['pk_amount'],
            row['tl_count'],
            row['tl_amount'],
            row['remain_count'],
            row['remain_avg'],
            row['remain_amount']
        )
        data.append(item)
    data = tablib.Dataset(*data, headers=headers, title=u"数据")
    filename = utils.attachment_save(data)
    return JSONResponse({'filename': filename})


@csrf_exempt
@token_required
def select_stock(request):
    warehouse = request.GET.get('warehouse')
    supplier = request.GET.get('supplier')
    product = request.GET.get('product')
    if warehouse:
        warehouse = int(warehouse)
    if supplier:
        supplier = int(supplier)
    if product:
        product = int(product)

    rows = WarehouseStockRecord.objects.filter(warehouse_id=warehouse, product_id=product, surplus_count__gt=0)

    if supplier:
        rows = rows.filter(supplier_id=supplier)

    data = []
    for row in rows:
        product_base = row.product
        if product_base.type == ProductBase.GOODS:
            g_row = GoodsGodownEntryDetail.objects.filter(stock_record_id=row.id).first()
        else:
            g_row = GodownEntryDetail.objects.filter(stock_record_id=row.id).first()

        if not g_row:
            g_row = InventoryDetail.objects.filter(warehouse_stock_record_id=row.id).first()

        item = {
            'stock_id': row.id,
            'no': g_row.main.no,
            'entry_price': Formater.formatPriceShow(row.entry_price),
            'surplus_count': Formater.formatCountShow(row.surplus_count),
            'detail_id': g_row.id,
            'notes': g_row.main.notes or ''
        }

        data.append(item)
    return JSONResponse(data)


@csrf_exempt
@token_required
def select_stocks(request):
    warehouse = request.GET.get('warehouse')
    supplier = request.GET.get('supplier')
    products = json.loads(request.POST.get('products'))
    data = []
    for product in products:
        product_item = {'index': product['index'], 'product_id': product['product_id'], 'items': []}
        rows = WarehouseStockRecord.objects.filter(warehouse_id=warehouse, product_id=product['product_id'], surplus_count__gt=0)

        if supplier:
            rows = rows.filter(supplier_id=supplier)

        for row in rows:
            product_base = row.product
            if product_base.type == ProductBase.GOODS:
                g_row = GoodsGodownEntryDetail.objects.filter(stock_record_id=row.id).first()
            else:
                g_row = GodownEntryDetail.objects.filter(stock_record_id=row.id).first()

            if not g_row:
                g_row = InventoryDetail.objects.filter(warehouse_stock_record_id=row.id).first()

            item = {
                'stock_id': row.id,
                'no': g_row.main.no,
                'entry_price': Formater.formatPriceShow(row.entry_price),
                'surplus_count': Formater.formatCountShow(row.surplus_count),
                'detail_id': g_row.id,
                'notes': g_row.main.notes or ''
            }

            product_item['items'].append(item)

        data.append(product_item)

    return JSONResponse(data)
