jiaweiqi 2 vuotta sitten
vanhempi
sitoutus
4dc4612a79

+ 10 - 1
apps/rebate/bussiness.py

@@ -148,6 +148,10 @@ class CustomerRebateTransfer(object):
             raise CustomError(u'转账总金额大于收款总金额!')
             raise CustomError(u'转账总金额大于收款总金额!')
         if instance.amount == 0:
         if instance.amount == 0:
             raise CustomError(u'转账总金额为0!')
             raise CustomError(u'转账总金额为0!')
+        if instance.rebate.status != CashRebate.DEFAULT:
+            raise CustomError(u'该返利已转账,禁止重复申请!')
+        instance.rebate.status = CashRebate.TRANSFERING
+        instance.rebate.save()
 
 
         tc = TransferCashRebate.objects.create(order=instance.main.order, transfer_num=1, transfer_amount=instance.amount)
         tc = TransferCashRebate.objects.create(order=instance.main.order, transfer_num=1, transfer_amount=instance.amount)
         tc_no = 'TC{}{:0>4}'.format(timezone.now().strftime('%Y%m%d%H%M%S'), tc.id)
         tc_no = 'TC{}{:0>4}'.format(timezone.now().strftime('%Y%m%d%H%M%S'), tc.id)
@@ -172,12 +176,14 @@ class CustomerRebateTransfer(object):
             raise CustomError(u'该返利已申请转账,禁止重复申请!')
             raise CustomError(u'该返利已申请转账,禁止重复申请!')
         tc = TransferCashRebate.objects.create(order=self.order)
         tc = TransferCashRebate.objects.create(order=self.order)
         tc_no = 'TC{}{:0>4}'.format(timezone.now().strftime('%Y%m%d%H%M%S'), tc.id)
         tc_no = 'TC{}{:0>4}'.format(timezone.now().strftime('%Y%m%d%H%M%S'), tc.id)
-        rows = CashRebate.objects.filter(order=self.order)
+        rows = CashRebate.objects.filter(order=self.order, status=CashRebate.DEFAULT)
         transfer_amount = 0
         transfer_amount = 0
         transfer_num = 0
         transfer_num = 0
         for row in rows:
         for row in rows:
             if row.customer.balance < row.amount:
             if row.customer.balance < row.amount:
                 raise CustomError(u'客户[{}]余额不足!'.format(row.customer.name))
                 raise CustomError(u'客户[{}]余额不足!'.format(row.customer.name))
+            row.status = CashRebate.TRANSFERING
+            row.save()
             transfer_num += 1
             transfer_num += 1
             transfer_amount += row.amount
             transfer_amount += row.amount
             tcd = TransferCashRebateDetail.objects.create(main=tc, rebate=row, amount=row.amount, customer=row.customer)
             tcd = TransferCashRebateDetail.objects.create(main=tc, rebate=row, amount=row.amount, customer=row.customer)
@@ -335,6 +341,9 @@ def transfer_detail_refresh(detail):
             CashTransferLog.addnew(detail)
             CashTransferLog.addnew(detail)
         elif detail_status == 'FAIL':
         elif detail_status == 'FAIL':
             detail.status = TransferCashRebateDetail.FAIL
             detail.status = TransferCashRebateDetail.FAIL
+            # 转账失败 将返利表状态改回 未处理  后边手动处理或重新申请转账都可以
+            detail.rebate.status = CashRebate.DEFAULT
+            detail.rebate.save()
 
 
     if fail_reason:
     if fail_reason:
         detail.fail_reason = fail_reason
         detail.fail_reason = fail_reason

+ 20 - 3
apps/rebate/models.py

@@ -57,8 +57,17 @@ class CashLog(models.Model):
 
 
 
 
 class CashRebate(models.Model):
 class CashRebate(models.Model):
+    DEFAULT = 0      # 未处理
+    TRANSFERING = 1  # 转账中
+    TRANSFERED = 2   # 已转账
+    STATUS = (
+        (DEFAULT, u'未处理'),
+        (TRANSFERING, u'转账中'),
+        (TRANSFERED, u'已转账'),
+    )
 
 
     order = models.ForeignKey(Order, verbose_name=u'订单', related_name='cash_rebate_order', editable=False, on_delete=models.PROTECT)
     order = models.ForeignKey(Order, verbose_name=u'订单', related_name='cash_rebate_order', editable=False, on_delete=models.PROTECT)
+    status = models.PositiveSmallIntegerField(choices=STATUS, verbose_name=u"状态", default=DEFAULT)
     ratio = models.FloatField(verbose_name=u'返利比例', default=0)
     ratio = models.FloatField(verbose_name=u'返利比例', default=0)
     amount = models.BigIntegerField(verbose_name=u'返利金额', default=0)
     amount = models.BigIntegerField(verbose_name=u'返利金额', default=0)
     customer = models.ForeignKey(Customer, verbose_name=u'客户', editable=False, on_delete=models.PROTECT)
     customer = models.ForeignKey(Customer, verbose_name=u'客户', editable=False, on_delete=models.PROTECT)
@@ -74,7 +83,7 @@ class CashRebate(models.Model):
 
 
 
 
 class CashRebateLog(models.Model):
 class CashRebateLog(models.Model):
-    rebate = models.OneToOneField(CashRebate, verbose_name=u'现金返利', related_name='rebate', editable=False, on_delete=models.PROTECT)
+    rebate = models.ForeignKey(CashRebate, verbose_name=u'现金返利', related_name='rebate', editable=False, on_delete=models.PROTECT)
     log = models.OneToOneField(CashLog, verbose_name=u'日志', related_name='rebate_log', editable=False, on_delete=models.PROTECT)
     log = models.OneToOneField(CashLog, verbose_name=u'日志', related_name='rebate_log', editable=False, on_delete=models.PROTECT)
 
 
     class Meta:
     class Meta:
@@ -86,9 +95,15 @@ class CashRebateLog(models.Model):
         permissions = []
         permissions = []
 
 
     @staticmethod
     @staticmethod
-    def addnew(rebate):
+    def addnew(rebate, off=False):
+        # off = True 手动核销现金返利 记录一条日志
         customer = Customer.objects.select_for_update().filter(id=rebate.customer.id).first()
         customer = Customer.objects.select_for_update().filter(id=rebate.customer.id).first()
-        log = CashLog.addnew(customer, CashLog.CASH_REBATE, rebate.amount)
+        type = CashLog.CASH_REBATE
+        amount = rebate.amount
+        if off:
+            type = CashLog.CASH_TRANSFER
+            amount = - rebate.amount
+        log = CashLog.addnew(customer, type, amount)
         instance = CashRebateLog.objects.create(rebate=rebate, log=log)
         instance = CashRebateLog.objects.create(rebate=rebate, log=log)
         return instance
         return instance
 
 
@@ -186,6 +201,8 @@ class CashTransferLog(models.Model):
     @staticmethod
     @staticmethod
     def addnew(transfer):
     def addnew(transfer):
         customer = Customer.objects.select_for_update().filter(id=transfer.customer.id).first()
         customer = Customer.objects.select_for_update().filter(id=transfer.customer.id).first()
+        transfer.rebate.status = CashRebate.TRANSFERED
+        transfer.rebate.save()
         log = CashLog.addnew(customer, CashLog.CASH_TRANSFER, -transfer.amount)
         log = CashLog.addnew(customer, CashLog.CASH_TRANSFER, -transfer.amount)
         instance = CashTransferLog.objects.create(transfer=transfer, log=log)
         instance = CashTransferLog.objects.create(transfer=transfer, log=log)
         return instance
         return instance

+ 24 - 3
apps/rebate/serializers.py

@@ -7,7 +7,7 @@ from rest_framework import serializers
 from django.db.models import Q, Sum
 from django.db.models import Q, Sum
 
 
 from apps.order.models import Order
 from apps.order.models import Order
-from apps.rebate.models import CashRebate, PointRebate, TransferCashRebate, TransferCashRebateDetail
+from apps.rebate.models import CashRebate, PointRebate, TransferCashRebate, TransferCashRebateDetail, CashRebateLog, CashLog
 from apps.base import Formater
 from apps.base import Formater
 
 
 
 
@@ -38,13 +38,21 @@ class OrderRebateSerializer(serializers.ModelSerializer):
 
 
     def get_transfer(self, obj):
     def get_transfer(self, obj):
         transfer = TransferCashRebate.objects.filter(order=obj).count()
         transfer = TransferCashRebate.objects.filter(order=obj).count()
-        return transfer
+        cash_bate = CashRebate.objects.filter(order=obj, status=CashRebate.DEFAULT).aggregate(sum_amount=Sum('amount'))['sum_amount'] or 0
+        if transfer:  # 有转账记录 前端显示转账记录按钮
+            return 2
+        if not transfer and cash_bate > 0:  # 没有转账记录 且  未转账的返利合计大于0  前端显示申请转账按钮
+            return 1
+        return 0  # 其他情况不显示按钮
 
 
 
 
 class CashRebateSerializer(serializers.ModelSerializer):
 class CashRebateSerializer(serializers.ModelSerializer):
     amount = serializers.SerializerMethodField()
     amount = serializers.SerializerMethodField()
     create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
     create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
     customer_name = serializers.CharField(source='customer.name', read_only=True)
     customer_name = serializers.CharField(source='customer.name', read_only=True)
+    ratio = serializers.SerializerMethodField()
+    status_text = serializers.CharField(source='get_status_display', read_only=True)
+    transfer = serializers.SerializerMethodField()
 
 
     class Meta:
     class Meta:
         model = CashRebate
         model = CashRebate
@@ -53,6 +61,17 @@ class CashRebateSerializer(serializers.ModelSerializer):
     def get_amount(self, obj):
     def get_amount(self, obj):
         return Formater.formatValueShow(obj.amount)
         return Formater.formatValueShow(obj.amount)
 
 
+    def get_ratio(self, obj):
+        return str(obj.ratio) + '%'
+
+    def get_transfer(self, obj):
+        if obj.status != CashRebate.TRANSFERED:
+            return ''
+        count = CashRebateLog.objects.filter(rebate=obj, log__type=CashLog.CASH_TRANSFER).count()
+        if count:
+            return '手动核销'
+        return '自动转账'
+
 
 
 class PointRebateSerializer(serializers.ModelSerializer):
 class PointRebateSerializer(serializers.ModelSerializer):
     create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
     create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
@@ -103,4 +122,6 @@ class TransferCashRebateDetailSerializer(serializers.ModelSerializer):
 
 
     def get_transfer(self, obj):
     def get_transfer(self, obj):
         count = TransferCashRebateDetail.objects.filter(Q(rebate=obj.rebate), ~Q(status=TransferCashRebateDetail.FAIL)).count()
         count = TransferCashRebateDetail.objects.filter(Q(rebate=obj.rebate), ~Q(status=TransferCashRebateDetail.FAIL)).count()
-        return count
+        if obj.rebate.status == CashRebate.DEFAULT and not count:
+            return 0
+        return 1

+ 20 - 9
apps/rebate/views.py

@@ -16,7 +16,7 @@ from utils.custom_modelviewset import CustomModelViewSet
 from apps.log.models import BizLog
 from apps.log.models import BizLog
 from apps.order.models import Order
 from apps.order.models import Order
 from apps.order.filters import OrderFilter
 from apps.order.filters import OrderFilter
-from apps.rebate.models import PointRebate, CashRebate, TransferCashRebate, TransferCashRebateDetail
+from apps.rebate.models import PointRebate, CashRebate, TransferCashRebate, TransferCashRebateDetail, CashRebateLog
 from apps.rebate.filters import TransferCashRebateFilter, TransferCashRebateDetailFilter
 from apps.rebate.filters import TransferCashRebateFilter, TransferCashRebateDetailFilter
 from apps.rebate.serializers import OrderRebateSerializer, CashRebateSerializer, PointRebateSerializer, TransferCashRebateSerializer, TransferCashRebateDetailSerializer
 from apps.rebate.serializers import OrderRebateSerializer, CashRebateSerializer, PointRebateSerializer, TransferCashRebateSerializer, TransferCashRebateDetailSerializer
 from apps.rebate.bussiness import CustomerRebateTransfer, transfer_detail_refresh, transfer_refresh
 from apps.rebate.bussiness import CustomerRebateTransfer, transfer_detail_refresh, transfer_refresh
@@ -52,6 +52,25 @@ class OrderRebateViewSet(CustomModelViewSet):
         serializer = CashRebateSerializer(rows, many=True)
         serializer = CashRebateSerializer(rows, many=True)
         return response_ok(serializer.data)
         return response_ok(serializer.data)
 
 
+    @action(methods=['get'], detail=False)
+    def cash_rebae_off(self, request):
+        id = request.GET.get('id')
+        try:
+            id = int(id)
+        except:
+            raise CustomError(u'参数异常!')
+        rebate = CashRebate.objects.filter(id=id).first()
+        if not rebate:
+            raise CustomError(u'未找到相应的返利')
+        if rebate.status != CashRebate.DEFAULT:
+            raise CustomError(u'该返利已申请转账,禁止手动核销!')
+        with transaction.atomic():
+            rebate.status = CashRebate.TRANSFERED
+            rebate.save()
+            CashRebateLog.addnew(rebate, off=True)
+            BizLog.objects.addnew(self.request.user, BizLog.INSERT, u'手动核销返利,id=%d' % rebate.id, )
+        return response_ok()
+
     @action(methods=['get'], detail=True)
     @action(methods=['get'], detail=True)
     def point_rebate(self, request, pk):
     def point_rebate(self, request, pk):
         '''积分返利明细'''
         '''积分返利明细'''
@@ -97,14 +116,6 @@ class TransferCashRebateViewSet(CustomModelViewSet):
         serializer = self.get_serializer(queryset, many=True)
         serializer = self.get_serializer(queryset, many=True)
         return response_ok(serializer.data)
         return response_ok(serializer.data)
 
 
-    @action(methods=['post'], detail=True)
-    def apply_again(self, request, pk):
-        instance = self.get_object()
-        if instance.transfer_status != TransferCashRebate.DEFAULT:
-            return
-        # 再次申请转账 但是不需要创建转账表
-        return response_ok()
-
 
 
 class TransferCashRebateDetailViewSet(CustomModelViewSet):
 class TransferCashRebateDetailViewSet(CustomModelViewSet):
     permission_classes = [IsEmployee, ]
     permission_classes = [IsEmployee, ]

+ 1 - 1
uis/views/customer/index.html

@@ -94,7 +94,7 @@
        ,{field:'total_amount', align: 'right', title:'累计消费金额',width: 120}
        ,{field:'total_amount', align: 'right', title:'累计消费金额',width: 120}
        ,{field:'total_point', align: 'right', title:'累计消费积分',width: 120}
        ,{field:'total_point', align: 'right', title:'累计消费积分',width: 120}
        ,{field:'date_join', title:'注册时间',width: 150}
        ,{field:'date_join', title:'注册时间',width: 150}
-        ,{width:150, align:'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+        //,{width:150, align:'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
       ]]
       ]]
       ,totalRow:true
       ,totalRow:true
       ,parseData:function(res) {
       ,parseData:function(res) {

+ 74 - 117
uis/views/order_rebate/cash_rebate_detail.html

@@ -1,134 +1,91 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
-    <meta charset="utf-8">
-    <title>现金返利明细</title>
-    <meta name="renderer" content="webkit">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <meta name="viewport"
-          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
-    <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
-    <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
-    <style type="text/css">
-        /*您可以将下列样式写入自己的样式表中*/
-        /*layui 元素样式改写*/
-        .layui-btn-sm {
-            line-height: normal;
-            font-size: 12.5px;
-        }
-
-        .layui-table-view .layui-table-body {
-            min-height: 256px;
-        }
-
-        .layui-table-cell .layui-input.layui-unselect {
-            height: 30px;
-            line-height: 30px;
-        }
-
-        /*设置 layui 表格中单元格内容溢出可见样式*/
-        .table-overlay .layui-table-view,
-        .table-overlay .layui-table-box,
-        .table-overlay .layui-table-body {
-            overflow: visible;
-        }
-
-        .table-overlay .layui-table-cell {
-            height: auto;
-            overflow: visible;
-        }
-
-        .imgStyle {
-            padding-left: 10px;
-            width: 80px;
-            height: 50px;
-        }
-
-        .layui-table-cell {
-            font-size: 14px;
-            padding: 0 5px;
-            height: auto;
-            overflow: visible;
-            text-overflow: inherit;
-            white-space: normal;
-            word-break: break-all;
-        }
-    </style>
+  <meta charset="utf-8">
+  <title>门店管理</title>
+  <meta name="renderer" content="webkit">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
+  <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
+  <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
 </head>
 </head>
 <body>
 <body>
 
 
-<div class="layui-fluid">
-    <div class="layui-col-md12">
-        <div class="layui-card">
-            <div class="layui-card-body">
-                <div style="height: 5px"></div>
-                <div id="tableRes" class="table-overlay">
-                    <table id="dataTable" lay-filter="dataTable" class="layui-hide"></table>
+  <div class="layui-fluid">
+    <div class="layui-card">
+        <div class="layui-card-body" pad15>
+        <div class="layui-row layui-col-space15">
+          <div class="layui-col-md12">
+
+            <table class="layui-hide" id="datagrid-log" lay-filter="datagrid-operate"></table>
+
+            <script type="text/html" id="datagrid-operate-bar">
+                <div class="layui-btn-group">
+                    {{# if(d.status == 0){ }}
+                    <a class="layui-btn layui-btn-danger layui-btn-xs"  lay-event="detail">手动核销</a>
+                    {{# } }}
                 </div>
                 </div>
-            </div>
+            </script>
+          </div>
+        </div>
         </div>
         </div>
     </div>
     </div>
-</div>
+  </div>
 
 
-<script src="../../layuiadmin/layui/layui.js"></script>
-<script>
-    layui.config({
-        base: '../../../layuiadmin/' //静态资源所在路径
-    }).extend({
-        index: 'lib/index' //主入口模块
-    }).use(['index', 'table', 'layer',], function () {
-        var $ = layui.$
-            , admin = layui.admin
-            , table = layui.table
-            , layer = layui.layer;
+  <script src="../../layuiadmin/layui/layui.js?t=1"></script>
+  <script>
+  var _params = '';
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'table'], function(){
+    var $ = layui.$
+    ,form = layui.form;
+    var table = layui.table;
+    var id = layui.view.getParameterByName('id');
 
 
-        var id = layui.view.getParameterByName('id');
-        var editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata)); // 框架有Bug所以这么转换
-        var tbWidth = $("#tableRes").width();
-        var layTableId = "layTable";
-        var tableIns = table.render({
-            elem: '#dataTable',
-            id: layTableId,
-            data: [],
-            width: tbWidth,
-            page: false,
-            limit: 100,
-            loading: true,
-            even: true, //不开启隔行背景
-            cols: [[
-                {title: '序号', type: 'numbers'},
-                {field: 'customer_name', title: '用户名', width: '30%',},
-                {field: 'ratio', title: '返利比例', width: '20%',},
-                {field: 'amount', title: '返利', width: '20%',},
-            ]]
-        });
+    table.render({
+      elem: '#datagrid-log'
+      ,url: '/rebate/' + id + '/cash_rebate/'
+      ,where: {}
+      ,cols: [[
+        {title: '序号', type: 'numbers'},
+        {field: 'customer_name', title: '用户名', width: '200',},
+        //{field: 'batch_id', title: '微信批次号', width: '10%',},
+        {field: 'ratio', title: '返利比例', width: '100',},
+        {field: 'amount', title: '返利', width: '100',},
+        {field: 'status_text', title: '状态', width: '100',},
+        {field: 'transfer', title: '转账方式', width: '100',},
+        {width:150, align:'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+      ]]
+      ,page: false
+      ,height: 'full-104'
+      ,done: function () {
+        layui.index.removeNoPermButtons();
+      }
+    });
 
 
-        admin.req({
-            url: '/rebate/' + id + '/cash_rebate/',
-            done: function (res) {
-                if (res.code === 0) {
-                    var rows = res.data;
-                    var oldData = table.cache[layTableId];
-                    for (var k in rows) {
-                        oldData.push(
-                            {
-                                customer_name: rows[k].customer_name,
-                                ratio: rows[k].ratio + '%',
-                                amount: rows[k].amount
-                            }
-                        )
+    //监听工具条
+    table.on('tool(datagrid-operate)', function(obj){
+        var data = obj.data;
+        if(obj.event === 'detail'){
+            layer.confirm('确定要核销该笔现金返利么?', function(index){
+                layer.close(index);
+                layui.admin.req({
+                    notice: true
+                    ,url: '/rebate/cash_rebae_off/?id=' + data.id
+                    ,type: 'get'
+                    ,done: function(res){
+                        table.reload('datagrid-log',{});
                     }
                     }
-                    tableIns.reload({
-                        data: oldData
-                    });
-                }else{
-                    layer.msg('获取现金返利明细失败', {icon: 5});
-                }
-            }
-        });
-
+                });
+            });
+          }
     });
     });
 
 
-</script>
+  });
+  </script>
 </body>
 </body>
 </html>
 </html>
+

+ 2 - 2
uis/views/order_rebate/index.html

@@ -56,10 +56,10 @@
 
 
             <script type="text/html" id="datagrid-operate-bar">
             <script type="text/html" id="datagrid-operate-bar">
                 <div class="layui-btn-group">
                 <div class="layui-btn-group">
-                    {{# if(d.transfer == 0 && d.cash_rebate > 0){ }}
+                    {{# if(d.transfer == 1){ }}
                     <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="rebate_transfer">转账申请</a>
                     <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="rebate_transfer">转账申请</a>
                     {{# } }}
                     {{# } }}
-                    {{# if(d.transfer > 0){ }}
+                    {{# if(d.transfer == 2){ }}
                     <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="rebate_transfer_log">转账记录</a>
                     <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="rebate_transfer_log">转账记录</a>
                     {{# } }}
                     {{# } }}
                 </div>
                 </div>