lyh 3 år sedan
förälder
incheckning
139208b4d2

+ 2 - 1
apps/finance/models.py

@@ -101,11 +101,12 @@ class dbFinanceIncome(models.Model):
     type = models.IntegerField(choices=TYPE_CHOICES, verbose_name=u"类型")
     amount = models.BigIntegerField(verbose_name=u"金额")
     account = models.ForeignKey(Option, related_name='finance_income_ref_account',verbose_name=u"账户", on_delete=models.PROTECT)
-    purpose = models.ForeignKey(FinancePurpose, verbose_name=u"用途", on_delete=models.PROTECT)
+    purpose = models.ForeignKey(FinancePurpose, verbose_name=u"用途", on_delete=models.PROTECT, null=True)
     check_user = models.ForeignKey(User, related_name='finance_income_ref_check_user', verbose_name=u"审核人",
                                     on_delete=models.PROTECT)
     check_time = models.DateTimeField(verbose_name=u"审核时间", null=True)
     check_status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, verbose_name=u"审核状态", default=settings.DEFAULT)
+    notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
 
 
     def save(self, *args, **kwargs):

+ 2 - 2
apps/foundation/models.py

@@ -16,7 +16,7 @@ class Option(models.Model):
     CONSUMABLE_MODE = 2
     GOODS_MODE = 3
     QUALITY_REQUEST = 4
-    BANK_ACCOUNT = 5
+    PAYMENT_ACCOUNT = 5
 
     TYPE_CHOICES = (
         (PAYMENT_MODE, u'付款方式'),
@@ -24,7 +24,7 @@ class Option(models.Model):
         (CONSUMABLE_MODE, u'耗材类别'),
         (GOODS_MODE, u'成品类别'),
         (QUALITY_REQUEST, u'质量要求'),
-        (BANK_ACCOUNT, u'银行账户'),
+        (PAYMENT_ACCOUNT, u'银行账户'),
     )
 
     type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类别")

+ 29 - 3
apps/order/models.py

@@ -5,7 +5,7 @@ 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
+from django.db.models import Sum, F
 
 from apps.account.models import User, Department
 from apps.goods.models import Goods
@@ -22,8 +22,16 @@ class SaleOrder(models.Model):
     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)
+    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"
@@ -43,6 +51,8 @@ class SaleOrder(models.Model):
             ("delete_sale_order", u"删除"),
             ("export_sale_order", u"导出"),
             ("print_sale_order", u"打印"),
+            ("loss_sale_order", u"扣减"),
+            ("pay_sale_order", u"结算"),
         )
 
     @staticmethod
@@ -65,6 +75,21 @@ class SaleOrder(models.Model):
         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()
@@ -82,6 +107,7 @@ class SaleOrderDetail(models.Model):
     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'收货数量')
     price = models.BigIntegerField(u'单价')
     amount = models.BigIntegerField(u'金额', editable=False)
 

+ 12 - 1
apps/order/serializers.py

@@ -1,7 +1,7 @@
 #coding=utf-8
 
 from rest_framework import serializers
-
+from django.db.models import Q, F, Sum
 from apps.base import Formater
 from apps.exceptions import CustomError
 from apps.foundation.models import BizLog
@@ -27,8 +27,15 @@ class SaleOrderSerializer(serializers.ModelSerializer):
     customer_id = serializers.CharField(source='customer.id', read_only=True)
     customer_tel = serializers.CharField(source='customer.mobile', read_only=True)
     products = serializers.SerializerMethodField()
+    total_amount = serializers.SerializerMethodField()
     count = CountShowCharField(read_only=True)
     amount = AmountShowCharField(read_only=True)
+    receive_count = CountShowCharField(read_only=True)
+    receive_amount = AmountShowCharField(read_only=True)
+    pay_amount = AmountShowCharField(read_only=True)
+    loss_amount = AmountShowCharField(read_only=True)
+    put_amount = AmountShowCharField(read_only=True)
+    fare_amount = AmountShowCharField(read_only=True)
 
     class Meta:
         model = SaleOrder
@@ -40,6 +47,10 @@ class SaleOrderSerializer(serializers.ModelSerializer):
         data.extend([s[0] for s in rows.values_list('goods__product_base__name')])
         return ','.join(data)
 
+    def get_total_amount(self, obj):
+        amount = Formater.formatAmountShow((obj.receive_amount or 0) - (obj.loss_amount or 0))
+        return amount
+
     @staticmethod
     def factory(user, data,id=None):
         if id:

+ 3 - 0
apps/order/urls.py

@@ -11,6 +11,9 @@ urlpatterns = (
     url(r'^sale_order/detail/$', sale_order_detail),
     url(r'^sale_order/check/$', sale_order_check),
     url(r'^sale_order/delete/$', sale_order_delete),
+    url(r'^sale_order/loss_save/$', sale_order_loss_save),
+    url(r'^sale_order/pay/$', sale_order_pay),
+    url(r'^sale_order/fare_save/$', sale_order_fare_save),
     url(r'^sale_order/export_detail/$', sale_order_export_detail),
 
     url(r'^sale_order/select/$', sale_order_select),

+ 180 - 2
apps/order/views.py

@@ -29,6 +29,7 @@ from django.conf import settings
 from apps.foundation.models import BizLog, Option
 from resources import SaleOrderResource, SaleOrderDetailResource, GoodsDeliverDetailResource, GoodsDeliverResource, \
     GoodsDeliverQueryResource, GoodsDeliverReturnQueryResource
+from apps.finance.models import dbFinanceIncome
 
 
 @csrf_exempt
@@ -38,10 +39,26 @@ def sale_order_list(request):
     user_ids = request.user.getSubEmployeeIds()
     rows = SaleOrder.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
     f = SaleOrderFilter(request.GET, queryset=rows)
-    total_row = f.qs.aggregate(sum_count=Sum('count'), sum_amount=Sum('amount'))
+    total_row = f.qs.aggregate(
+        sum_count=Sum('count'),
+        sum_amount=Sum('amount'),
+        sum_receive_count=Sum('receive_count'),
+        sum_receive_amount=Sum('receive_amount'),
+        sum_pay_amount=Sum('pay_amount'),
+        sum_put_amount=Sum('put_amount'),
+        sum_fare_amount=Sum('fare_amount'),
+        sum_loss_amount=Sum('loss_amount')
+    )
     more = {
         'sum_count': Formater.formatCountShow(total_row['sum_count']),
-        'sum_amount': Formater.formatAmountShow(total_row['sum_amount'])
+        'sum_amount': Formater.formatAmountShow(total_row['sum_amount']),
+        'sum_receive_count': Formater.formatCountShow(total_row['sum_receive_count']),
+        'sum_receive_amount': Formater.formatAmountShow(total_row['sum_receive_amount']),
+        'sum_pay_amount': Formater.formatAmountShow(total_row['sum_pay_amount']),
+        'sum_put_amount': Formater.formatAmountShow(total_row['sum_put_amount']),
+        'sum_fare_amount': Formater.formatAmountShow(total_row['sum_fare_amount']),
+        'sum_loss_amount': Formater.formatAmountShow(total_row['sum_loss_amount']),
+        'sum_total_amount': Formater.formatAmountShow((total_row['sum_receive_amount'] or 0)-(total_row['sum_loss_amount'] or 0)),
     }
     rows, total = utils.get_page_data(request, f.qs)
     serializer = SaleOrderSerializer(rows, many=True)
@@ -119,6 +136,7 @@ def sale_order_detail(request):
         'no': sale_order.no,
         'total_count': Formater.formatCountShow(sale_order.count),
         'total_amount': Formater.formatAmountShow(sale_order.amount),
+        'loss_amount': Formater.formatAmountShow(sale_order.loss_amount),
         'name': sale_order.customer.name,
         'mobile': sale_order.customer.mobile,
         'customer_id': sale_order.customer.id,
@@ -129,6 +147,7 @@ def sale_order_detail(request):
         'check_time': sale_order.check_time and Formater.formatStrTime(sale_order.check_time) or '',
         'create_time': Formater.formatStrTime(sale_order.create_time),
         'notes': sale_order.notes or '',
+        'loss_notes': sale_order.loss_notes or '',
     }
     data = {
         'main_data':main_data,
@@ -147,6 +166,7 @@ def sale_order_detail(request):
             'quality_request_text': row.quality_request and row.quality_request.name or '',
             'warehouse_place': row.goods.product_base.warehouse_place,
             'count': Formater.formatCountShow(row.count),
+            'receive_count': Formater.formatCountShow(row.receive_count),
             'price': Formater.formatPriceShow(row.price),
             'amount': Formater.formatAmountShow(row.amount)
         }
@@ -195,6 +215,11 @@ def sale_order_check(request):
                 order.status = settings.PASS
                 order.check_user = request.user
                 order.check_time = timezone.now()
+
+                SaleOrderDetail.objects.filter(main_id=order.id).update(receive_count=F('count'))
+
+                order.updateReceiveAmount()
+
                 BizLog.objects.addnew(
                     request.user,
                     BizLog.CHECK,
@@ -209,6 +234,10 @@ def sale_order_check(request):
                 order.status = settings.DEFAULT
                 order.check_user = None
                 order.check_time = None
+
+                SaleOrderDetail.objects.filter(main_id=order.id).update(receive_count=0)
+                order.updateReceiveAmount()
+
                 BizLog.objects.addnew(
                     request.user,
                     BizLog.CHECK,
@@ -222,6 +251,155 @@ def sale_order_check(request):
         return JSONError(u'审核失败')
     return JSONResponse({})
 
+@csrf_exempt
+@permission_required('order.loss_sale_order')
+def sale_order_loss_save(request):
+    id = request.GET.get('id')
+    data = json.loads(request.body)
+
+    try:
+        with transaction.atomic():
+            order = SaleOrder.getById(id)
+            if order.status == settings.DEFAULT:
+                raise CustomError(u'该订单尚未审核')
+            loss_amount = data['order_data']['amount']
+            loss_notes = data['order_data']['notes']
+            for item in data['items']:
+                detail = SaleOrderDetail.objects.filter(id=item['detail_id']).first()
+                detail.receive_count = Formater.formatCount(item['receive_count'])
+                detail.save()
+
+            order.updateReceiveAmount()
+            order.loss_amount = Formater.formatAmount(loss_amount)
+            order.loss_notes = loss_notes
+            order.save()
+            BizLog.objects.addnew(
+                request.user,
+                BizLog.UPDATE,
+                u"销售订单[%s]扣减,id=%d" % (order.no, order.id),
+            )
+
+    except CustomError, e:
+        return JSONError(e.get_error_msg())
+    except Exception, e:
+        traceback.print_exc()
+        return JSONError(u'保存失败')
+    return JSONResponse({})
+
+
+@csrf_exempt
+@permission_required('order.pay_sale_order')
+def sale_order_pay(request):
+    id = request.GET.get('id')
+    data = json.loads(request.body)
+
+    try:
+        with transaction.atomic():
+            order = SaleOrder.getById(id)
+            if order.status == settings.DEFAULT:
+                raise CustomError(u'该订单尚未审核')
+            if order.cleared:
+                raise CustomError(u'该订单已结清')
+
+            order.pay_amount += Formater.formatAmount(data['actual_amount'])
+            order.save()
+            total_amount = order.receive_amount - order.loss_amount
+
+            if order.pay_amount >= total_amount:
+                order.cleared = True
+                order.save()
+
+            dbFinanceIncome.objects.create(
+                referer_no=order.no,
+                create_user=request.user,
+                department=request.user.department,
+                type=dbFinanceIncome.SALE_ENTRY_PAY,
+                amount=Formater.formatAmount(data['actual_amount']),
+                account_id=data['account'],
+                check_status=settings.PASS,
+                check_user=request.user,
+                check_time=timezone.now(),
+                notes=data['notes']
+            )
+
+            BizLog.objects.addnew(
+                request.user,
+                BizLog.UPDATE,
+                u"销售订单[%s]结算,id=%d" % (order.no, order.id),
+            )
+
+    except CustomError, e:
+        return JSONError(e.get_error_msg())
+    except Exception, e:
+        traceback.print_exc()
+        return JSONError(u'保存失败')
+    return JSONResponse({})
+
+
+@csrf_exempt
+@permission_required('order.pay_sale_order')
+def sale_order_fare_save(request):
+    id = request.GET.get('id')
+    fare_amount = request.GET.get('fare_amount')
+    fare_account = request.GET.get('fare_account')
+    put_amount = request.GET.get('put_amount')
+    put_account = request.GET.get('put_account')
+
+    try:
+        with transaction.atomic():
+            order = SaleOrder.getById(id)
+
+            if fare_amount != 0:
+                if not fare_account:
+                    raise CustomError(u'请选择运费账户')
+                fare_amount = Formater.formatAmount(fare_amount)
+                order.fare_amount += fare_amount
+
+                dbFinanceIncome.objects.create(
+                    referer_no=order.referer_no,
+                    create_user=request.user,
+                    department=request.user.department,
+                    type=dbFinanceIncome.SALE_ENTRY_FARE,
+                    amount=(-fare_amount),
+                    account_id=fare_account,
+                    check_status=settings.PASS,
+                    check_user=request.user,
+                    check_time=timezone.now()
+                )
+
+            if put_amount != 0:
+                if not put_account:
+                    raise CustomError(u'请选择装车费账户')
+                put_amount = Formater.formatAmount(put_amount)
+                order.put_amount += put_amount
+
+                dbFinanceIncome.objects.create(
+                    referer_no=order.referer_no,
+                    create_user=request.user,
+                    department=request.user.department,
+                    type=dbFinanceIncome.SALE_ENTRY_UNLOAD,
+                    amount=(-fare_amount),
+                    account_id=put_account,
+                    check_status=settings.PASS,
+                    check_user=request.user,
+                    check_time=timezone.now()
+                )
+
+            order.save()
+
+            BizLog.objects.addnew(
+                request.user,
+                BizLog.UPDATE,
+                u"销售订单[%s]添加装运费,id=%d" % (order.no, order.id),
+            )
+
+    except CustomError, e:
+        return JSONError(e.get_error_msg())
+    except Exception, e:
+        traceback.print_exc()
+        return JSONError(u'保存失败')
+    return JSONResponse({})
+
 @csrf_exempt
 @permission_required('order.export_sale_order')
 def sale_order_export_detail(request):

+ 0 - 33
requeirements.txt

@@ -1,33 +0,0 @@
-certifi==2018.11.29
-chardet==3.0.4
-defusedxml==0.5.0
-diff-match-patch==20181111
-Django==1.11.13
-django-filter==1.1.0
-django-filters==0.2.1
-django-import-export==1.0.1
-django-validator==0.2.7
-djangorestframework==3.9.0
-djangorestframework-stubs==0.3.0
-et-xmlfile==1.0.1
-factory-boy==2.11.1
-Faker==1.0.1
-idna==2.8
-ipaddress==1.0.22
-jdcal==1.4
-MySQL-python==1.2.5
-odfpy==1.4.0
-openpyxl==2.5.12
-Pillow==5.4.1
-PyMySQL==0.9.3
-python-dateutil==2.7.5
-pytz==2018.9
-PyYAML==3.13
-requests==2.21.0
-six==1.12.0
-tablib==0.11.4
-text-unidecode==1.2
-unicodecsv==0.14.1
-urllib3==1.24.1
-xlrd==1.2.0
-xlwt==1.3.0

+ 1 - 1
scj/app_settings.py

@@ -8,7 +8,7 @@ DATABASES = {
         'NAME': 'scj',
         'USER': 'carwin',  # Not used with sqlite3.
         'PASSWORD': 'carwin!@#',  # Not used with sqlite3.
-        'HOST': '39.106.109.89',
+        'HOST': '127.0.0.1',
     },
 }
 # DATABASES = {

+ 1 - 1
scj/local_settings.py

@@ -1,2 +1,2 @@
-LICENSE_KEY = 'dev-wushaodong'
+LICENSE_KEY = 'dev-luyuhang'
 # LICENSE_KEY = 'jsyc'

+ 1 - 0
scj/settings.py

@@ -63,6 +63,7 @@ INSTALLED_APPS = [
     'apps.touch',
     'apps.office',
     'apps.config',
+    'apps.finance',
 ]
 
 MIDDLEWARE_CLASSES = [

+ 98 - 2
uis/views/order/sale_order.html

@@ -27,6 +27,10 @@
             <div class="LAY-btns" style="margin-bottom: 10px;">
               <button class="layui-btn layui-btn-sm" id="btn_add" data-permission="order.add_sale_order"><i class="layui-icon layui-icon-add-circle" ></i>添加</button>
               <button class="layui-btn layui-btn-sm" id="btn_deliver" data-permission="order.add_goods_deliver"><i class="layui-icon layui-icon-add-circle" ></i>转出库</button>
+              <button class="layui-btn layui-btn-sm" id="btn_loss" data-permission="order.loss_sale_order"><i class="layui-icon layui-icon-layer" ></i>扣减</button>
+              <button class="layui-btn layui-btn-sm" id="btn_receive"><i class="layui-icon layui-icon-ok-circle" ></i>完善发货</button>
+              <button class="layui-btn layui-btn-sm" id="btn_ship" data-permission="order.pay_sale_order"><i class="layui-icon layui-icon-dollar" ></i>装运</button>
+              <button class="layui-btn layui-btn-sm" id="btn_pay" data-permission="order.pay_sale_order"><i class="layui-icon layui-icon-dollar" ></i>结算</button>
 
                 <button class="layui-nav" data-permission="order.export_sale_order">
                 <div class="layui-nav-item">
@@ -135,13 +139,21 @@
       elem: '#datagrid'
       ,url: '/order/sale_order/data/'
       ,cols: [[
-          {type:'checkbox',width:50}
+          {type:'radio',width:50}
         ,{field:'no', title:'单号', width:150}
         ,{field:'customer_name', title:'客户', width:120}
         ,{field:'customer_tel', title:'客户电话', width: 150}
         ,{field:'products', title:'产品', width:120}
         ,{field:'count', title:'合计数量', width:100, align:'right'}
         ,{field:'amount', title:'合计金额', width:100, align:'right'}
+        ,{field:'receive_count', title:'收货数量', width:100, align:'right'}
+        ,{field:'receive_amount', title:'收货金额', width:100, align:'right'}
+        ,{field:'loss_amount', title:'扣减金额', width:100, align:'right'}
+        ,{field:'total_amount', title:'应付金额', width:100, align:'right'}
+        ,{field:'pay_amount', title:'结算金额', width:100, align:'right'}
+        ,{field:'put_amount', title:'装车费用', width:100, align:'right'}
+        ,{field:'fare_amount', title:'运输费用', width:100, align:'right'}
+        ,{field:'loss_notes', title:'扣减备注', width:100, align:'right'}
         ,{field:'create_time', title:'创建时间', width:150}
         ,{field:'create_user_text', title:'创建人', width:150}
         ,{field:'check_status_text', title:'审核状态', width:120}
@@ -163,7 +175,27 @@
             if (cols[i].field == 'amount') {
                 cols[i].totalRowText = res.more.sum_amount;
             }
-
+            if (cols[i].field == 'receive_count') {
+                cols[i].totalRowText = res.more.sum_receive_count;
+            }
+            if (cols[i].field == 'receive_amount') {
+                cols[i].totalRowText = res.more.sum_receive_amount;
+            }
+            if (cols[i].field == 'loss_amount') {
+                cols[i].totalRowText = res.more.sum_loss_amount;
+            }
+            if (cols[i].field == 'total_amount') {
+                cols[i].totalRowText = res.more.sum_total_amount;
+            }
+            if (cols[i].field == 'pay_amount') {
+                cols[i].totalRowText = res.more.sum_pay_amount;
+            }
+            if (cols[i].field == 'put_amount') {
+                cols[i].totalRowText = res.more.sum_put_amount;
+            }
+            if (cols[i].field == 'fare_amount') {
+                cols[i].totalRowText = res.more.sum_fare_amount;
+            }
         }
         return {
           "code": res.code, //解析接口状态
@@ -357,6 +389,70 @@
         });
     });
 
+    $('#btn_loss').on('click', function(){
+        var data = utils.getSelectedRow('datagrid');
+         if(data == false){
+             return;
+         }
+
+         if (data.status == 0) {
+             layer.msg('该订单未审核,不允许扣减');
+             return;
+         }
+
+         table.editdata = data;
+
+         layer.open({
+          type: 2,
+          title: '扣减',
+          shadeClose: false,
+          area: ['90%', '90%'],
+          btn: ['保存', '取消'],
+          yes: function(index, dom){
+              layui.onSubmitChild = function (data) {
+                  layer.close(index);
+              };
+              layui.submitChild();
+          },
+          btn2: function(index, layero){
+            layer.close(index);//关闭当前按钮
+          },
+          content: 'sale_order_loss.html?order_id='+data.id
+        });
+    });
+
+    $('#btn_pay').on('click', function(){
+        var data = utils.getSelectedRow('datagrid');
+         if(data == false){
+             return;
+         }
+
+         if (data.status == 0) {
+             layer.msg('该订单未审核,不允许收银');
+             return;
+         }
+
+         table.editdata = data;
+
+         layer.open({
+          type: 2,
+          title: '付款['+ data.no +']',
+          shadeClose: false,
+          area: ['40%', '80%'],
+          btn: ['保存', '取消'],
+          yes: function(index, dom){
+              layui.onSubmitChild = function (data) {
+                  layer.close(index);
+              };
+              layui.submitChild();
+          },
+          btn2: function(index, layero){
+            layer.close(index);//关闭当前按钮
+          },
+          content: 'sale_order_pay.html?order_id='+data.id
+        });
+    });
+
    $('#btn_query').on('click', function(){
         layer.open({
           type: 1,

+ 208 - 0
uis/views/order/sale_order_loss.html

@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<html>
+<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">
+        .table-overlay .layui-table-view,
+        .table-overlay .layui-table-header,
+        .table-overlay .layui-table-box,
+        .table-overlay .layui-table-body{overflow: visible;}
+        .table-overlay .layui-table-cell{height: auto; overflow: visible;}
+    </style>
+</head>
+<body>
+
+<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">
+
+                    <form class="layui-form" action="" lay-filter="component-form-element">
+                        <div class="layui-row layui-col-space10 layui-form-item">
+
+                            <div class="layui-col-md12">
+                                <label class="layui-form-label"><font color='red' size="4">*</font>扣减金额:</label>
+                                <div class="layui-input-block">
+                                    <div class="layui-col-sm8">
+                                        <input id="id_loss_amount" type="text" autocomplete="off" name="notes"  class="layui-input">
+                                    </div>
+                                </div>
+                            </div>
+
+                            <div class="layui-col-md12">
+                                <label class="layui-form-label">扣减备注:</label>
+                                <div class="layui-input-block">
+                                    <div class="layui-col-sm8">
+                                        <input id="id_loss_notes" type="text" autocomplete="off" name="notes"  class="layui-input">
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <fieldset class="layui-elem-field layui-field-title">
+                            <legend>产品明细&nbsp;&nbsp;</legend>
+                        </fieldset>
+
+                        <div class="table-overlay">
+                            <table id="part_dataTable" lay-filter="part_dataTable" class="layui-hide"></table>
+                        </div>
+
+                        <button id="submit_btn" lay-submit lay-filter="component-form-element" style="display: none">保存</button>
+
+                    </form>
+
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+  <script src="../../layuiadmin/layui/layui.js"></script>
+  <script>
+
+
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index'
+  }).use(['index', 'form', 'table', 'utils'], function(){
+    var $ = layui.$
+    ,admin = layui.admin
+    ,element = layui.element
+    ,form = layui.form
+    ,table = layui.table
+    ,utils = layui.utils;
+
+    var id = layui.view.getParameterByName('order_id');
+
+    admin.req({
+        url: '/foundation/search_options/?type=4',
+        done: function(res){
+            _options = res.data;
+        }
+    });
+
+    function fillData(data){
+        $('#id_loss_amount').val(data.amount);
+        $('#id_loss_notes').val(data.notes);
+    }
+
+    var part_layTableId = "part_layTable";
+	var part_tableIns = table.render({
+        elem: '#part_dataTable',
+        id: part_layTableId,
+        data: [],
+        page: false,
+        limit: 1000,
+        loading: true,
+        even: true, //不开启隔行背景
+        cols: [[
+            {title: '序号', type: 'numbers'},
+            {field: 'name', title: '产品名称', width: 150},
+            {field: 'model', title: '产品代码', width: 150},
+            {field: 'unit', title: '单位', width: 80},
+            {field: 'count', title: '数量', width: 80},
+            {field: 'price', title: '单价', width: 80},
+            {field: 'receive_count', title: '收货数量', width: 100,  templet: function (d){
+            return '<input id="receive_count'+d.id+'" type="text" value="'+d.receive_count+'" lay-verify="required|numberGtZ" autocomplete="off" class="layui-input">';
+            }},
+            {field: 'quality_request_text', title: '质量要求', width: 80},
+        ]],
+    });
+
+    table.on('tool(part_dataTable)', function (obj) {
+        var data = obj.data, event = obj.event, tr = obj.tr; //获得当前行 tr 的DOM对象;
+        switch(event){
+            case "del":
+                obj.del();
+                layer.msg('删除成功', {icon: 6});
+                break;
+        }
+    });
+
+    var getItemsData = function () {
+        var rows = table.cache[part_layTableId];
+        var items = [];
+        for(var k in rows){
+            if (rows[k] == false) {
+                continue;
+            }
+
+            var receive_count = $('#receive_count'+rows[k].id).val();
+            var item = {
+                detail_id:rows[k].id,
+                receive_count:receive_count
+            };
+            items.push(item);
+        }
+        return items
+    };
+    form.on('submit(component-form-element)', function(data){
+        var items = getItemsData();
+
+
+        var order_data = {'amount': $('#id_loss_amount').val(), 'notes': $('#id_loss_notes').val()};
+
+        data.field.order_data = order_data;
+        data.field.items = items;
+        admin.req({
+            url: '/order/sale_order/loss_save/?id='+id
+            ,data: JSON.stringify(data.field)
+            ,type: 'post'
+            ,done: function(res){
+                customer_id = null;
+                parent.layui.onSubmitChild();
+            }
+        });
+        return false;
+    });
+
+    if (id) {
+        admin.req({
+          url: '/order/sale_order/detail/?id='+id,
+          done: function(res){
+            var data = res.data.items_data;
+            var oldData = [];
+            for (var i in data) {
+                var item = data[i];
+                var newRow = {
+                    id: item.id,
+                    name: item.name,
+                    model:item.model,
+                    unit:item.unit,
+                    price: item.price,
+                    count: item.count,
+                    receive_count: item.receive_count,
+                    quality_request_text: item.quality_request_text,
+                    part_data:item
+                };
+                oldData.push(newRow);
+            }
+            part_tableIns.reload({
+                data: oldData
+            });
+
+             var orderData = JSON.parse(JSON.stringify(parent.layui.table.editdata));
+             fillData({
+                 amount:orderData.loss_amount,
+                 notes:orderData.loss_notes
+             });
+          }
+        });
+    }
+
+    parent.layui.submitChild = function () {
+      $("#submit_btn").click();
+    };
+
+  });
+  </script>
+</body>
+</html>

+ 157 - 0
uis/views/order/sale_order_pay.html

@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html>
+<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">
+        .table-overlay .layui-table-view,
+        .table-overlay .layui-table-header,
+        .table-overlay .layui-table-box,
+        .table-overlay .layui-table-body{overflow: visible;}
+        .table-overlay .layui-table-cell{height: auto; overflow: visible;}
+        .layui-form-select dl{max-height: 150px;}
+    </style>
+</head>
+<body>
+
+<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">
+
+                    <form class="layui-form" action="" lay-filter="component-form-element">
+                        <div class="layui-row layui-col-space10">
+                            <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                <label class="layui-form-label">应付金额:</label>
+                                <div class="layui-input-block" style="line-height: 36px;">
+                                    <span id="id_amount"></span>
+                                </div>
+                            </div>
+                            <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                <label class="layui-form-label">已付金额:</label>
+                                <div class="layui-input-block" style="line-height: 36px;">
+                                    <span id="id_pay_amount"></span>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="layui-row layui-col-space10">
+                            <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                <label class="layui-form-label"><font color='red' size="4">*</font>结算账户:</label>
+                                <div class="layui-input-block">
+                                    <select id="id_payment_account" name="account" lay-verify="required">
+                                        <option value="">请选择结算账户</option>
+                                    </select>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="layui-row layui-col-space10">
+                            <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                <label class="layui-form-label"><font color='red' size="4">*</font>付款金额:</label>
+                                <div class="layui-input-block">
+                                    <input id="id_actual_amount" type="text" name="actual_amount"  autocomplete="off" lay-verify="required|numberGtZ" class="layui-input">
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="layui-row layui-col-space10">
+                            <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                <label class="layui-form-label">备注:</label>
+                                <div class="layui-input-block">
+                                    <input id="id_notes" type="text" name="notes"  autocomplete="off" class="layui-input">
+                                </div>
+                            </div>
+                        </div>
+                        <button class="layui-btn" id="purchase-order-submit" lay-submit lay-filter="component-form-element" style="display: none">保存</button>
+                    </form>
+
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+  <script src="../../layuiadmin/layui/layui.js"></script>
+  <script>
+
+  layui.link('../../../layuiadmin/style/autocomplete.css');
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index',
+    autocomplete: 'autocomplete'
+  }).use(['index', 'utils','form', 'element'], function(){
+    var $ = layui.$
+    ,admin = layui.admin
+    ,element = layui.element
+    ,form = layui.form;
+
+    var editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata));
+    $('#id_amount').html(editdata.total_amount);
+    $('#id_pay_amount').html(editdata.pay_amount);
+
+    var payment_type_option = '';
+
+     admin.req({
+        url: '/foundation/search_options/?type=5',
+        done: function(res){
+            var payment_types = res.data;
+            for (var i in payment_types) {
+                 payment_type_option += "<option value="+ payment_types[i].id+">"+ payment_types[i].name+"</option>";
+            }
+            $("#id_payment_account").append(payment_type_option);
+            form.render();
+        }
+    });
+
+
+    form.render(null, 'component-form-element');
+    element.render('breadcrumb', 'breadcrumb');
+
+    form.on('submit(component-form-element)', function(data){
+        var actual_amount = $('#id_actual_amount').val();
+        var amount = parseFloat(editdata.total_amount);
+        actual_amount = parseFloat(actual_amount);
+        var actual_amount_old = parseFloat(editdata.pay_amount);
+        if (actual_amount + actual_amount_old > amount) {
+            layer.confirm('实收金额大于应收金额, 确定要付款吗?', function(index){
+                layer.close(index);
+                admin.req({
+                    url: '/order/sale_order/pay/?id='+editdata.id
+                    ,data: JSON.stringify(data.field)
+                    ,type: 'post'
+                    ,done: function(res){
+                         parent.layui.onSubmitChild();
+                    }
+                });
+            });
+        }else{
+            admin.req({
+            url: '/order/sale_order/pay/?id='+editdata.id
+                ,data: JSON.stringify(data.field)
+                ,type: 'post'
+                , done: function (res) {
+                    parent.layui.onSubmitChild();
+                }
+            });
+        }
+
+        return false;
+    });
+
+    parent.layui.submitChild = function () {
+      $("#purchase-order-submit").click();
+    };
+
+  });
+
+  </script>
+</body>
+</html>