# coding=utf-8
from django.utils import timezone
from apps.foundation.models import Option
from apps.customer.models import Customer
from apps.exceptions import CustomError
from django.db import models
from django.conf import settings
from django.db.models import Sum, F

from apps.account.models import User, Department
from apps.goods.models import Goods
from apps.warehouse.models import Warehouse, WarehouseStock, WarehouseRecord, WarehouseStockRecord


class SaleOrder(models.Model):
    no = models.CharField(max_length=20, verbose_name=u"单号", editable=False)
    customer = models.ForeignKey(Customer, verbose_name=u"客户", on_delete=models.PROTECT)
    status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"状态")
    notes = models.TextField(verbose_name=u"备注", blank=True, null=True)
    create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, blank=True)
    create_user = models.ForeignKey(User, related_name='sale_order_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False)
    department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT)
    check_time = models.DateTimeField(verbose_name=u"审核时间", null=True)
    check_user = models.ForeignKey(User, related_name='sale_order_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, null=True)
    count = models.BigIntegerField(u'发货数量', default=0)
    amount = models.BigIntegerField(u'发货金额', default=0)
    receive_count = models.BigIntegerField(u'收货数量', default=0)
    receive_amount = models.BigIntegerField(u'收货金额', default=0)
    pay_amount = models.BigIntegerField(u'已付金额', default=0)
    put_amount = models.BigIntegerField(u'装车费', default=0)
    fare_amount = models.BigIntegerField(u'运费', default=0)
    loss_amount = models.BigIntegerField(u'扣减金额', default=0)
    loss_notes = models.CharField(max_length=200, verbose_name=u"扣减备注", blank=True, null=True)
    cleared = models.BooleanField(verbose_name=u"结清", default=False)

    class Meta:
        db_table = "sale_order"
        verbose_name = u"订单管理"
        ordering = ('-id',)
        index_together = (
            'create_time', 'check_time', 'status'
        )
        unique_together = (
           'no',
        )
        default_permissions = ()
        permissions = ( # 销售订单管理
            ("view_sale_order", u"浏览"),
            ("add_sale_order", u"添加"),
            ("check_sale_order", u"审核"),
            ("delete_sale_order", u"删除"),
            ("export_sale_order", u"导出"),
            ("print_sale_order", u"打印"),
            ("loss_sale_order", u"扣减"),
            ("pay_sale_order", u"结算"),
        )

    @staticmethod
    def getById(id):
        instance = SaleOrder.objects.filter(pk=id).first()
        if not instance:
            raise CustomError(u'未找到相应的订单')
        return instance

    def updateAmount(self):
        sum_count = 0
        sum_amount = 0

        sum_row = SaleOrderDetail.objects.filter(main=self).aggregate(sum_count=Sum('count'), sum_amount=Sum('amount'))
        if sum_row:
            sum_count = sum_row['sum_count'] or 0
            sum_amount = sum_row['sum_amount'] or 0

        self.count = sum_count
        self.amount = sum_amount
        self.save()

    def updateReceiveAmount(self):
        sum_receive_count = 0
        sum_receive_amount = 0

        sum_row = SaleOrderDetail.objects.filter(main=self).aggregate(
            sum_receive_count=Sum('receive_count'), sum_receive_amount=Sum(F('receive_count')*F('price'))
        )
        if sum_row:
            sum_receive_count = sum_row['sum_receive_count'] or 0
            sum_receive_amount = sum_row['sum_receive_amount'] or 0

        self.receive_count = sum_receive_count
        self.receive_amount = sum_receive_amount
        self.save()

    def save(self, *args, **kwargs):
        if self.no == None or self.no == '':
            now = timezone.now()
            rows = SaleOrder.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no')
            count = rows.count()
            if count == 0:
                self.no = 'GS%s%03d' % (now.strftime('%Y%m%d'), count + 1)
            else:
                self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
        super(SaleOrder, self).save(*args, **kwargs)


class SaleOrderDetail(models.Model):
    main = models.ForeignKey(SaleOrder, verbose_name=u'销售单', on_delete=models.PROTECT)
    goods = models.ForeignKey(Goods, verbose_name=u'产品', on_delete=models.PROTECT)
    quality_request = models.ForeignKey(Option, verbose_name=u"质量标准", null=True, blank=True, on_delete=models.PROTECT)
    count = models.BigIntegerField(u'数量')
    receive_count = models.BigIntegerField(u'收货数量', default=0, editable=False)
    price = models.BigIntegerField(u'单价')
    amount = models.BigIntegerField(u'金额', editable=False)

    class Meta:
        db_table = "sale_order_detail"
        verbose_name = u"入库查询"
        ordering = ('-id',)
        default_permissions = ()
        permissions = (# 销售订单明细
            ("view_goods_godownentry_query", u"浏览"),
            ("export_goods_godownentry_query", u"导出"),
            ("print_goods_godownentry_query", u"打印"),
        )

class SaleOrderMessage(models.Model):
    main = models.ForeignKey(SaleOrder, verbose_name=u'销售单', on_delete=models.PROTECT)
    item = models.ForeignKey(Option, verbose_name=u"自定义项", on_delete=models.PROTECT)
    content = models.CharField(max_length=200, verbose_name=u"内容", blank=True, null=True)

    class Meta:
        db_table = "sale_order_message"
        verbose_name = u"发货信息"
        ordering = ('-id',)
        default_permissions = ()

class GoodsDeliver(models.Model):
    no = models.CharField(max_length=20, verbose_name=u"出库单号", editable=False)
    create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
    create_user = models.ForeignKey(User, verbose_name=u"创建人", related_name='goodsdeliver_ref_create_user',
                                    on_delete=models.PROTECT, blank=True, editable=False)
    customer = models.ForeignKey(Customer, verbose_name=u"客户", on_delete=models.PROTECT, blank=True, null=True)
    department = models.ForeignKey(Department, verbose_name=u"创建部门", related_name='goodsdeliver_ref_department',on_delete=models.PROTECT, blank=True, editable=False)
    status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, verbose_name=u"审核状态",default=settings.DEFAULT)
    check_user = models.ForeignKey(User, related_name='goodsdeliver_ref_check_user', verbose_name=u"审核人",on_delete=models.PROTECT, blank=True, null=True)
    check_time = models.DateTimeField(verbose_name=u"审核时间", blank=True, null=True)
    agent_user = models.ForeignKey(User, verbose_name=u"经办人", related_name='goodsdeliver_ref_agent_user', on_delete=models.PROTECT)
    agent_department = models.ForeignKey(Department, verbose_name=u"经办人部门", related_name='goodsdeliver_ref_agent_department', on_delete=models.PROTECT, blank=True, editable=False)
    warehouse = models.ForeignKey(Warehouse, verbose_name=u'仓别', on_delete=models.PROTECT)
    sale_order = models.ForeignKey(SaleOrder, verbose_name=u'销售订单', on_delete=models.PROTECT, blank=True, null=True)
    notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)

    total_count = models.BigIntegerField(verbose_name=u'合计数量', default=0)
    total_cost = models.BigIntegerField(verbose_name=u'合计成本', default=0)
    total_amount = models.BigIntegerField(verbose_name=u'合计销售价', default=0, blank=True)
    return_count = models.BigIntegerField(verbose_name=u"合计退库数量", default=0)
    return_cost = models.BigIntegerField(verbose_name=u"合计退库成本", default=0)

    class Meta:
        db_table = "goods_deliver"
        verbose_name = u"出库管理"
        ordering = ('-id',)
        index_together = (
            'create_time', 'check_time', 'status'
        )
        unique_together = (
            'no',
        )
        default_permissions = ()
        permissions = ( # 成品出库管理
            ("view_goods_deliver", u"浏览"),
            ("add_goods_deliver", u"添加"),
            ("check_goods_deliver", u"审核"),
            ("delete_goods_deliver", u"删除"),
            ("export_goods_deliver", u"导出"),
            ("print_goods_deliver", u"打印"),
        )

    @staticmethod
    def getById(id):
        instances = GoodsDeliver.objects.filter(id=id).first()
        if not instances:
            raise CustomError(u'未找到相应的出库单')
        return instances

    def save(self, *args, **kwargs):
        if self.no == None or self.no == '':
            now = timezone.now()
            rows = GoodsDeliver.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no')
            count = rows.count()
            if count == 0:
                self.no = 'GC%s%03d' % (now.strftime('%Y%m%d'), count + 1)
            else:
                self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
        super(GoodsDeliver, self).save(*args, **kwargs)

    def update_total(self):
        total_count = 0
        total_cost = 0
        total_amount = 0
        sum_row = GoodsDeliverDetail.objects.filter(main=self).aggregate(total_count=Sum('count'), total_cost=Sum('total_cost'), total_amount=Sum('total_amount'))
        if sum_row:
            total_count = sum_row['total_count'] or 0
            total_cost = sum_row['total_cost'] or 0
            total_amount = sum_row['total_amount'] or 0
        self.total_count = total_count
        self.total_cost = total_cost
        self.total_amount = total_amount

        self.save()

    def update_return(self):
        return_count = 0
        return_cost = 0
        sum_row = GoodsDeliverDetail.objects.filter(main=self).aggregate(return_count=Sum('return_count'),
                                                                    return_cost=Sum('return_cost'))
        if sum_row:
            return_count = sum_row['return_count'] or 0
            return_cost = sum_row['return_cost'] or 0
        self.return_count = return_count
        self.return_cost = return_cost
        self.save()


class GoodsDeliverDetail(models.Model):
    main = models.ForeignKey(GoodsDeliver, verbose_name=u'出库单', on_delete=models.PROTECT, related_name='goods_deliver_details')
    product_base = models.ForeignKey(Goods, verbose_name=u'产品', on_delete=models.PROTECT)
    count = models.BigIntegerField(verbose_name=u'数量', default=0)
    price = models.BigIntegerField(verbose_name=u'单价', default=0)
    warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', editable=False, on_delete=models.PROTECT)
    warehouse_record = models.ForeignKey(WarehouseRecord, verbose_name=u'库存记录', on_delete=models.PROTECT, null=True,
                                         blank=True, related_name='goods_deliver_detail_ref_warehouse_record')
    warehouse_stockrecord = models.ForeignKey(WarehouseStockRecord, verbose_name=u'入库库存记录', on_delete=models.PROTECT,
                                              null=True, blank=True,
                                              related_name='goods_deliver_detail_ref_warehouse_stock_record')

    total_cost = models.BigIntegerField(verbose_name=u'成本合计', default=0)
    total_amount = models.BigIntegerField(verbose_name=u'销售价合计', default=0, blank=True)
    return_count = models.BigIntegerField(verbose_name=u'退库数量', default=0)
    return_cost = models.BigIntegerField(verbose_name=u'退库成本合计', default=0)
    notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)

    class Meta:
        db_table = "goods_deliver_detail"
        verbose_name = u"出库查询"
        ordering = ('-id',)
        default_permissions = ()
        permissions = (# 成品出库管理明细
            ("view_goods_deliver_query", u"浏览"),
            ("export_goods_deliver_query", u"导出"),
            ("print_goods_deliver_query", u"打印"),
        )

    def updateReturn(self):
        return_count = 0
        return_cost = 0
        sum_row = GoodsDeliverReturnDetail.objects.filter(deliver_detail=self).aggregate(return_count=Sum('return_count'),
                                                                                         return_cost=Sum('return_cost'))
        if sum_row:
            return_count = sum_row['return_count'] or 0
            return_cost = sum_row['return_cost'] or 0
        self.return_count = return_count
        self.return_cost = return_cost
        self.save()


class GoodsDeliverReturn(models.Model):
    no = models.CharField(max_length=20, verbose_name=u"退库单号", editable=False)
    reason = models.CharField(max_length=500, verbose_name=u"原因", blank=True, null=True)
    create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
    create_user = models.ForeignKey(User, verbose_name=u"创建人", on_delete=models.PROTECT, blank=True, editable=False)
    department = models.ForeignKey(Department, verbose_name=u"创建部门", on_delete=models.PROTECT, blank=True, editable=False)
    return_count = models.BigIntegerField(verbose_name=u'退库合计数量', default=0)
    return_cost = models.BigIntegerField(verbose_name=u'退库合计成本', default=0)

    class Meta:
        db_table = "goods_deliver_return"
        verbose_name = u"退库管理"
        ordering = ('-id',)
        index_together = (
            'create_time',
        )
        unique_together = (
            'no',
        )
        default_permissions = ()
        permissions = (
            ("view_goods_deliver_return", u"浏览"),
            ("add_goods_deliver_return", u"添加"),
            ("print_goods_deliver_return", u"打印"),
        )

    @staticmethod
    def getByIds(ids):
        return GoodsDeliverReturn.objects.filter(id__in=ids)

    @staticmethod
    def getById(id):
        instances = GoodsDeliverReturn.objects.filter(id=id).first()
        if not instances:
            raise CustomError(u'未找到相应的退库单')
        return instances

    def save(self, *args, **kwargs):
        if self.no == None or self.no == '':
            now = timezone.now()
            rows = GoodsDeliverReturn.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no')
            count = rows.count()
            if count == 0:
                self.no = 'TK%s%03d' % (now.strftime('%Y%m%d'), count + 1)
            else:
                self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
        super(GoodsDeliverReturn, self).save(*args, **kwargs)

    def update_total(self):
        return_count = 0
        return_cost = 0
        sum_row = GoodsDeliverReturnDetail.objects.filter(main=self).aggregate(return_count=Sum('return_count'),
                                                                               return_cost=Sum('return_cost'))
        if sum_row:
            return_count = sum_row['return_count'] or 0
            return_cost = sum_row['return_cost'] or 0
        self.return_count = return_count
        self.return_cost = return_cost
        self.save()


class GoodsDeliverReturnDetail(models.Model):
    main = models.ForeignKey(GoodsDeliverReturn, verbose_name=u'退库单', on_delete=models.PROTECT, related_name='goods_deliver_return_details')
    deliver_detail = models.ForeignKey(GoodsDeliverDetail, verbose_name=u'出库明细', on_delete=models.PROTECT)
    product_base = models.ForeignKey(Goods, verbose_name=u'产品', on_delete=models.PROTECT)
    return_count = models.BigIntegerField(verbose_name=u'退库数量', default=0)
    return_cost = models.BigIntegerField(verbose_name=u'退库成本合计', default=0)
    warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', on_delete=models.PROTECT, editable=False)
    warehouse_record = models.ForeignKey(WarehouseRecord, verbose_name=u'库存记录', on_delete=models.PROTECT, null=True,
                                         blank=True, related_name='goods_return_deliver_detail_ref_warehouse_record')
    notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)

    class Meta:
        db_table = "goods_deliver_detail_return"
        verbose_name = u"退库查询"
        ordering = ('-id',)
        default_permissions = ()
        permissions = (# 退库管理明细
            ("view_goods_deliver_return_query", u"浏览"),
            ("export_goods_deliver_return_query", u"导出"),
        )
