Explorar el Código

增加生产需求模块

firefish hace 1 año
padre
commit
22dfe2c200
Se han modificado 56 ficheros con 2102 adiciones y 160 borrados
  1. BIN
      apps/dashboard/forms.pyd
  2. 22 2
      apps/plan/filters.py
  3. 101 1
      apps/plan/models.py
  4. 63 0
      apps/plan/resources.py
  5. 110 1
      apps/plan/serializers.py
  6. 10 0
      apps/plan/urls.py
  7. 321 5
      apps/plan/views.py
  8. 10 10
      libs/http.py
  9. 53 0
      mac.py
  10. 33 0
      requeirements.txt
  11. 6 5
      scj/app_settings.py
  12. 0 2
      scj/local_settings.py
  13. 0 5
      scj/settings.py
  14. 0 30
      scj/test_settings.py
  15. BIN
      static/xls/生产需求导入模板.xlsx
  16. 6 6
      uis/layuiadmin/style/admin.css
  17. 6 6
      uis/layuiadmin/style/login.css
  18. BIN
      uis/layuiadmin/style/res/bg.png
  19. BIN
      uis/layuiadmin/style/res/favicon.ico
  20. BIN
      uis/layuiadmin/style/res/logo.png
  21. BIN
      uis/layuiadmin/style/res/pf.ico
  22. 2 2
      uis/layuiadmin/tpl/system/about.html
  23. 24 18
      uis/views/account/login.html
  24. 6 6
      uis/views/dashboard/home.html
  25. 1 1
      uis/views/goods/goods_godownentry.html
  26. 1 1
      uis/views/goods/goods_godownentry_query.html
  27. 1 1
      uis/views/goods/goods_inventory.html
  28. 4 4
      uis/views/goods/goods_stock_query.html
  29. 0 1
      uis/views/goods/search_goods_item.html
  30. 13 8
      uis/views/index.html
  31. 1 1
      uis/views/material/consumable_inventory.html
  32. 1 1
      uis/views/material/deliver_consumable_query.html
  33. 1 1
      uis/views/material/deliver_consumable_return.html
  34. 1 1
      uis/views/material/deliver_material_query.html
  35. 1 1
      uis/views/material/deliver_material_return.html
  36. 1 1
      uis/views/material/material_inventory.html
  37. 1 1
      uis/views/order/goods_deliver_query.html
  38. 1 1
      uis/views/order/goods_deliver_return.html
  39. 16 15
      uis/views/order/sale_order.html
  40. 486 0
      uis/views/plan/demand.html
  41. 98 0
      uis/views/plan/demand_detail.html
  42. 350 0
      uis/views/plan/demand_edit.html
  43. 131 0
      uis/views/plan/demand_print.html
  44. 199 0
      uis/views/plan/demand_receive.html
  45. 1 1
      uis/views/plan/production.html
  46. 1 1
      uis/views/plan/sale.html
  47. 1 1
      uis/views/purchase/consumable_godownentry.html
  48. 1 1
      uis/views/purchase/consumable_godownentry_query.html
  49. 1 1
      uis/views/purchase/consumable_godownentry_return.html
  50. 1 1
      uis/views/purchase/consumable_godownentry_return_query.html
  51. 1 1
      uis/views/purchase/material_godownentry_query.html
  52. 1 1
      uis/views/purchase/material_godownentry_return.html
  53. 1 1
      uis/views/purchase/material_godownentry_return_query.html
  54. 10 11
      uis/views/purchase/purchase.html
  55. 1 1
      uis/views/purchase/purchase_order.html
  56. 1 1
      uis/views/purchase/purchase_payment.html

BIN
apps/dashboard/forms.pyd


+ 22 - 2
apps/plan/filters.py

@@ -1,8 +1,28 @@
 #coding=utf-8
 import django_filters
-from apps.base import clean_datetime_range
-from models import ProductionPlan, SalePlan
+from apps.base import clean_datetime_range, clean_date_range
+from models import ProductionPlan, SalePlan, ProductionDemand
 
+class ProductionDemandFilter(django_filters.FilterSet):
+    create_time = django_filters.DateTimeFromToRangeFilter(field_name='create_time')
+    demand_date = django_filters.DateFromToRangeFilter(field_name='demand_date')
+    no = django_filters.CharFilter(name='no', lookup_expr='icontains')
+    cleared = django_filters.CharFilter(name='cleared')
+    create_user = django_filters.CharFilter(name='create_user__name', lookup_expr='icontains')
+    customer_name = django_filters.CharFilter(name='customer__name', lookup_expr='icontains')
+    customer_tel = django_filters.CharFilter(name='customer__mobile', lookup_expr='icontains')
+
+    class Meta:
+        model = ProductionDemand
+        fields = (
+            'create_time', 'no', 'customer_name', 'customer_tel',
+            'status', 'create_user', 'demand_date'
+        )
+
+    def __init__(self, data=None, *args, **kwargs):
+        data = clean_datetime_range(data, 'create_time', 'source')
+        data = clean_date_range(data, 'demand_date')
+        super(ProductionDemandFilter, self).__init__(data, *args, **kwargs)
 
 class ProductionPlanFilter(django_filters.FilterSet):
     no = django_filters.CharFilter(name='no',lookup_expr='icontains')

+ 101 - 1
apps/plan/models.py

@@ -1,5 +1,5 @@
 # coding=utf-8
-from django.db.models import Sum
+from django.db.models import Sum, F
 from django.utils import timezone
 from apps.foundation.models import Option
 from apps.customer.models import Customer
@@ -102,6 +102,106 @@ class SalePlanDetail(models.Model):
             raise CustomError(u'未找到相应的销售计划明细')
         return instance
 
+class ProductionDemand(models.Model):
+    no = models.CharField(max_length=20, verbose_name=u"单号", editable=False)
+    customer = models.ForeignKey(Customer, verbose_name=u"客户", on_delete=models.PROTECT)
+    demand_date = models.DateField(verbose_name=u"需求日期")
+    notes = models.TextField(verbose_name=u"备注", blank=True, null=True)
+
+    status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"状态")    
+    create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, blank=True)
+    create_user = models.ForeignKey(User, related_name='production_demand_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='production_demand_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)
+    receive_notes = models.CharField(max_length=200, verbose_name=u"收货备注", blank=True, null=True)
+
+    class Meta:
+        db_table = "production_demand"
+        verbose_name = u"需求管理"
+        ordering = ('-id',)
+        index_together = (
+            'create_time', 'status', 'demand_date'
+        )
+        unique_together = (
+           'no',
+        )
+        default_permissions = ()
+        permissions = ( # 生产需求管理管理
+            ("view_production_demand", u"浏览"),
+            ("add_production_demand", u"添加"),
+            ("check_production_demand", u"审核"),
+            ("delete_production_demand", u"删除"),
+            ("export_production_demand", u"导出"),
+            ("print_production_demand", u"打印"),
+            ("loss_production_demand", u"扣减"),
+        )
+
+    def save(self, *args, **kwargs):
+        if self.no == None or self.no == '':
+            now = timezone.now()
+            rows = ProductionDemand.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no')
+            count = rows.count()
+            if count == 0:
+                self.no = 'XQ%s%03d' % (now.strftime('%Y%m%d'), count + 1)
+            else:
+                self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
+        super(ProductionDemand, self).save(*args, **kwargs)        
+
+    @staticmethod
+    def getById(id):
+        instance = ProductionDemand.objects.filter(pk=id).first()
+        if not instance:
+            raise CustomError(u'未找到相应的生产需求')
+        return instance    
+
+    def updateAmount(self):
+        sum_count = 0
+        sum_amount = 0
+
+        sum_row = ProductionDemandDetail.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 = ProductionDemandDetail.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()        
+
+class ProductionDemandDetail(models.Model):
+    main = models.ForeignKey(ProductionDemand, 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 = "production_demand_detail"
+        verbose_name = u"生产需求明细"
+        ordering = ('-id',)
+        default_permissions = ()
+
 
 class ProductionPlan(models.Model):
     no = models.CharField(max_length=20, verbose_name=u"单号", editable=False)

+ 63 - 0
apps/plan/resources.py

@@ -2,6 +2,69 @@
 from __future__ import absolute_import
 from import_export import resources
 from import_export.fields import Field
+from apps.base import ExcelImporter
+
+class ProductionDemandEntryImporter(ExcelImporter):
+
+    fields = {
+        u'客户姓名': (False, ExcelImporter.formatUnicode),
+        u'客户电话': (False, ExcelImporter.formatUnicode),
+        u'产品名称': (True, ExcelImporter.formatUnicode),
+        u'产品代码': (True, ExcelImporter.formatUnicode),
+        u'数量': (True, ExcelImporter.formatFloatGtZ),
+        u'单价': (True, ExcelImporter.formatFloatGeZ),
+        u'需求时间': (True, ExcelImporter.formatDateTime),
+        u'备注': (False, ExcelImporter.formatUnicode),
+    }
+
+class ProductionDemandResource(resources.Resource):
+    def __init__(self):
+        super(ProductionDemandResource, self).__init__()
+        self.fields['no'] = Field(attribute='no')
+        self.fields['create_time'] = Field(attribute='create_time')
+        self.fields['create_user_text'] = Field(attribute='create_user_text')
+        self.fields['customer_name'] = Field(attribute='customer_name')
+        self.fields['customer_tel'] = Field(attribute='customer_tel')
+        self.fields['products'] = Field(attribute='products')
+        self.fields['check_status_text'] = Field(attribute='check_status_text')
+        self.fields['check_user_text'] = Field(attribute='check_user_text')
+        self.fields['check_time'] = Field(attribute='check_time')
+        self.fields['notes'] = Field(attribute='notes')
+        self.fields['count'] = Field(attribute='count')
+        self.fields['amount'] = Field(attribute='amount')
+        self.fields['receive_count'] = Field(attribute='receive_count')
+        self.fields['receive_amount'] = Field(attribute='loss_amount')
+
+    def get_export_headers(self):
+        return [u'单号', u'客户', u'客户电话', u'产品', u'合计数量', u'合计金额',
+                u'收货数量', u'收货金额',u'创建时间', u'创建人', u'审核状态', 
+                u'审核时间', u'审核人', u'备注']
+
+    class Meta:
+        fields = ('no', 'customer_name', 'customer_tel', 'products',
+                  'count', 'amount', 'receive_count', 'receive_amount', 
+                  'create_time', 'create_user_text', 'check_status_text',
+                  'check_time', 'check_user_text', 'notes',)
+        export_order = fields    
+
+class ProductionDemandDetailResource(resources.Resource):
+    def __init__(self):
+        super(ProductionDemandDetailResource, self).__init__()
+        self.fields['name'] = Field(attribute='name')
+        self.fields['model'] = Field(attribute='model')
+        self.fields['quality_request_text'] = Field(attribute='quality_request_text')
+        self.fields['count'] = Field(attribute='count')
+        self.fields['receive_count'] = Field(attribute='receive_count')
+        self.fields['price'] = Field(attribute='price')
+        self.fields['amount'] = Field(attribute='amount')
+
+    def get_export_headers(self):
+        return [u'产品名称', u'产品代码', u'质量标准',u'数量', u'收货数量', u'单价', u'金额',]
+
+    class Meta:
+        fields = ('name', 'model', 'quality_request_text', 'count', 'receive_count', 'price', 'amount',)
+        export_order = fields
+
 
 class ProductionPlanResource(resources.Resource):
 

+ 110 - 1
apps/plan/serializers.py

@@ -9,9 +9,118 @@ from apps.foundation.models import BizLog
 from apps.serializer_errors import dump_serializer_errors
 from libs.booleancharfield import CountShowCharField, PriceShowCharField, AmountShowCharField, EmptyPriceShowCharField, \
     EmptyAmountShowCharField
-from models import ProductionPlan, SalePlan, ProductionPlanDetail, SalePlanDetail
+from models import ProductionPlan, SalePlan, ProductionPlanDetail, SalePlanDetail, ProductionDemand, ProductionDemandDetail
 
 
+class ProductionDemandSerializer(serializers.ModelSerializer):
+    create_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
+    check_time = serializers.DateTimeField(format=base.DATETIME_FORMAT, read_only=True)
+    check_status_text = serializers.CharField(source='get_status_display', read_only=True)
+    check_user_text = serializers.CharField(source='check_user.name', read_only=True)
+    create_user_text = serializers.CharField(source='create_user.name', read_only=True)
+    customer_name = serializers.CharField(source='customer.name', read_only=True)
+    customer_id = serializers.CharField(source='customer.id', read_only=True)
+    customer_tel = serializers.CharField(source='customer.mobile', read_only=True)
+    products = serializers.SerializerMethodField()
+    count = CountShowCharField(read_only=True)
+    receive_count = CountShowCharField(read_only=True)
+    receiveable_count = serializers.SerializerMethodField()
+
+    class Meta:
+        model = ProductionDemand
+        fields = '__all__'
+
+    def get_products(self, obj):
+        data = []
+        rows = ProductionDemandDetail.objects.filter(main=obj)
+        data.extend([s[0] for s in rows.values_list('goods__product_base__name')])
+        return ','.join(data)
+
+    def get_receiveable_count(self, obj):
+        count = Formater.formatCountShow((obj.count or 0) - (obj.receive_count or 0))
+        return count
+
+    @staticmethod
+    def factory(user, data,id=None):
+        if id:
+            instance = ProductionDemand.getById(id)
+        else:
+            instance = None
+        serializer = ProductionDemandSerializer(instance, data=data)
+        serializer.user = user
+        return serializer
+
+    def validSave(self):
+        if self.is_valid():
+            return self.save()
+        else:
+            raise CustomError(dump_serializer_errors(self))
+
+    def create(self, validated_data):
+        validated_data['create_user'] = self.user
+        validated_data['department'] = self.user.department
+        instance = super(ProductionDemandSerializer, self).create(validated_data)
+        BizLog.objects.addnew(
+            self.user,
+            BizLog.INSERT,
+            u"添加生产需求[%s],id=%d" % (instance.no, instance.id),
+            validated_data
+        )
+        return instance
+
+    def update(self, instance, validated_data):
+        instance = super(ProductionDemandSerializer, self).update(instance, validated_data)
+        BizLog.objects.addnew(
+            self.user,
+            BizLog.UPDATE,
+            u"修改生产需求[%s],id=%d" % (instance.no, instance.id),
+            validated_data
+        )
+        return instance
+
+class ProductionDemandDetailSerializer(serializers.ModelSerializer):
+    name = serializers.CharField(source='goods.product_base.name', read_only=True)
+    model = serializers.CharField(source='goods.product_base.model', read_only=True)
+    quality_request_text = serializers.CharField(source='quality_request.name', read_only=True)
+    quality_request_id = serializers.CharField(source='quality_request.id', read_only=True)
+    count = CountShowCharField()
+    receive_count = CountShowCharField(read_only=True)
+    price = PriceShowCharField()
+    amount = AmountShowCharField(read_only=True)
+
+    class Meta:
+        model = ProductionDemandDetail
+        fields = '__all__'
+
+    @staticmethod
+    def factory(user, data):
+        instances = None
+        serializer = ProductionDemandDetailSerializer(instances, data=data)
+        serializer.user = user
+        return serializer
+
+    def validSave(self):
+        if self.is_valid():
+            return self.save()
+        else:
+            raise CustomError(dump_serializer_errors(self))
+
+    def validate(self, data):
+        data['price'] = Formater.formatPrice(data['price'])
+        data['count'] = Formater.formatCount(data['count'])
+        data['amount'] = data['count'] * data['price']
+        return data
+
+    def create(self, validated_data):
+        instance = super(ProductionDemandDetailSerializer, self).create(validated_data)
+        BizLog.objects.addnew(
+            self.user,
+            BizLog.INSERT,
+            u"添加生产需求明细[%s],id=%d" % (instance.main.no, instance.id),
+            validated_data
+        )
+        return instance
+    
 class ProductionPlanSerializer(serializers.ModelSerializer):
     status = serializers.CharField(read_only=True)
     status_text = serializers.CharField(source='get_status_display', read_only=True)

+ 10 - 0
apps/plan/urls.py

@@ -5,6 +5,16 @@ from django.conf.urls import url
 from views import *
 
 urlpatterns = (
+    url(r'^demand/data/$', demand_list),
+    url(r'^demand/export/$', demand_export),
+    url(r'^demand/save/$', demand_save),
+    url(r'^demand/detail/$', demand_detail),
+    url(r'^demand/check/$', demand_check),
+    url(r'^demand/delete/$', demand_delete),
+    url(r'^demand/receive_save/$', demand_receive_save),
+    url(r'^demand/export_detail/$', demand_export_detail),
+    url(r'^demand/import/$', demand_import),
+
     url(r'^production/data/$', production_list),
     url(r'^production/export/$', production_export),
     url(r'^production/save/$', production_save),

+ 321 - 5
apps/plan/views.py

@@ -3,7 +3,7 @@ import traceback
 import json
 
 from _mysql_exceptions import IntegrityError
-from django.db.models import ProtectedError, Q, Sum
+from django.db.models import ProtectedError, Q, Sum, F
 from django.utils import timezone
 from django.views.decorators.csrf import csrf_exempt
 from django.db import transaction, IntegrityError
@@ -12,11 +12,14 @@ from apps.account.models import Department, User
 from apps.base import Formater
 from apps.foundation.models import BizLog, Option
 from apps.goods.models import Goods
-from apps.plan.filters import ProductionPlanFilter, SalePlanFilter
-from apps.plan.models import ProductionPlan, SalePlan, ProductionPlanDetail, SalePlanDetail
-from apps.plan.resources import ProductionPlanResource, SalePlanResource, SalePlanDetailResource, ProductionPlanDetailResource
+from apps.product.models import ProductBase
+from apps.plan.filters import ProductionPlanFilter, SalePlanFilter, ProductionDemandFilter
+from apps.plan.models import ProductionPlan, SalePlan, ProductionPlanDetail, SalePlanDetail, ProductionDemand, ProductionDemandDetail
+from apps.plan.resources import ProductionPlanResource, SalePlanResource, SalePlanDetailResource, ProductionPlanDetailResource, \
+    ProductionDemandEntryImporter, ProductionDemandResource, ProductionDemandDetailResource
 from apps.plan.serializers import ProductionPlanSerializer, ProductionPlanDetailSerializer, SalePlanSerializer, \
-    SalePlanDetailSerializer
+    SalePlanDetailSerializer, ProductionDemandSerializer, ProductionDemandDetailSerializer
+from apps.customer.models import Customer
 
 from libs.http import JSONResponse, JSONError, DataGridJSONResponse
 from libs import utils
@@ -24,6 +27,319 @@ from apps.exceptions import CustomError, ExportChange
 from django.conf import settings
 
 
+@csrf_exempt
+@permission_required('order.view_demand')
+def demand_list(request):
+    department_ids = request.user.getSubDepartmentIds()
+    user_ids = request.user.getSubEmployeeIds()
+    rows = ProductionDemand.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
+    f = ProductionDemandFilter(request.GET, queryset=rows)
+    total_row = f.qs.aggregate(
+        sum_count=Sum('count'),
+        sum_receive_count=Sum('receive_count')
+    )
+    more = {
+        'sum_count': Formater.formatCountShow(total_row['sum_count']),
+        'sum_receive_count': Formater.formatCountShow(total_row['sum_receive_count'])
+    }
+    rows, total = utils.get_page_data(request, f.qs)
+    serializer = ProductionDemandSerializer(rows, many=True)
+    return DataGridJSONResponse(serializer.data, total, more)
+
+
+@csrf_exempt
+@permission_required('order.export_demand')
+def demand_export(request):
+    department_ids = request.user.getSubDepartmentIds()
+    user_ids = request.user.getSubEmployeeIds()
+    rows = ProductionDemand.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
+    f = ProductionDemandFilter(request.GET, queryset=rows)
+    serializer = ProductionDemandSerializer(f.qs, many=True)
+    export_data = ExportChange.dict_to_obj(serializer)
+    export_data = ProductionDemandResource().export(export_data)
+    filename = utils.attachment_save(export_data)
+    BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产需求")
+    return JSONResponse({'filename': filename})
+
+@csrf_exempt
+@permission_required('order.add_demand')
+def demand_save(request):
+    source = request.GET.get('source')
+    id = request.GET.get('id')
+    # detail_id:添加保存,销售计划直接保存,不需要添加明细detail_id=-1,添加明细保存默认detail_id=0,修改保存,detail_id=明细id
+    detail_id = -1
+    if source == 'touch':
+        detail_id = json.loads(request.body)['detail']
+    data = json.loads(request.body)
+
+    try:
+        with transaction.atomic():
+            pb = ProductionDemandSerializer.factory(request.user, data['order_data'],id)
+            if pb.instance and pb.instance.status == settings.PASS:
+                raise CustomError(u'该生产需求已审核, 不允许修改')
+            pb = pb.validSave()
+            if source == 'touch' and detail_id >= 0:
+                # 手机端保存,如果是修改,先删除要修改的明细
+                ProductionDemandDetail.objects.filter(id=int(detail_id)).delete()
+                for item in data['items']:
+                    item['main'] = pb.id
+                    pbd = ProductionDemandDetailSerializer.factory(request.user, item)
+                    pbd.validSave()
+            else:
+                ProductionDemandDetail.objects.filter(main_id=pb.id).delete()
+                for item in data['items']:
+                    item['main'] = pb.id
+                    pbd = ProductionDemandDetailSerializer.factory(request.user, item)
+                    pbd.validSave()
+
+            pb.updateAmount()
+
+    except CustomError, e:
+        return JSONError(e.get_error_msg())
+    except Exception, e:
+        traceback.print_exc()
+        return JSONError(u'保存失败')
+    return JSONResponse(pb.id)
+
+@csrf_exempt
+@token_required
+def demand_detail(request):
+    id = request.GET.get('id')
+    demand = ProductionDemand.getById(id)
+    rows = ProductionDemandDetail.objects.filter(main_id=id)
+    company = ProductionDemand.getById(id).department.getCompany()
+    if demand.status == settings.PASS:
+        check_status = u'已审核'
+    else:
+        check_status = u'待审核'
+    main_data = {
+        'id': demand.id,
+        'no': demand.no,
+        'receive_count': Formater.formatCountShow(demand.receive_count),
+        'name': demand.customer.name,
+        'mobile': demand.customer.mobile,
+        'customer_id': demand.customer.id,
+        'status': check_status,
+        'status_id': demand.status,
+        'check_user': demand.check_user and demand.check_user.name or '',
+        'create_user': demand.create_user and demand.create_user.name or '',
+        'check_time': demand.check_time and Formater.formatStrTime(demand.check_time) or '',
+        'create_time': Formater.formatStrTime(demand.create_time),
+        'notes': demand.notes or '',
+        'demand_date': demand.demand_date and Formater.formatStrDate(demand.demand_date) or '',
+        'receive_notes': demand.receive_notes or '',
+    }
+    data = {
+        'main_data':main_data,
+        'company': company.name,
+        'items_data': []
+    }
+    for row in rows:
+        item = {
+            'id': row.id,
+            'goods_id': row.goods_id,
+            'product_id': row.goods.product_base_id,
+            'unit': row.goods.product_base.unit,
+            'name': row.goods.product_base.name,
+            'model': row.goods.product_base.model,
+            'quality_request': row.quality_request and row.quality_request.id or '',
+            '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)
+        }
+        data['items_data'].append(item)
+    return JSONResponse(data)
+
+@csrf_exempt
+@permission_required('order.delete_demand')
+def demand_delete(request):
+    id = int(request.GET.get('id'))
+    try:
+        with transaction.atomic():
+            order = ProductionDemand.getById(id)
+            if order.status != settings.DEFAULT:
+                raise CustomError(u'该生产需求已审核, 不允许删除')
+            BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除生产需求[%s],id=%d" % (order.no, order.id))
+            ProductionDemandDetail.objects.filter(main=order).delete()
+            order.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('order.check_demand')
+def demand_check(request):
+    id = request.GET.get('id')
+    status = int(request.GET.get('status'))
+
+    try:
+        with transaction.atomic():
+            order = ProductionDemand.getById(id)
+            if status == settings.PASS:
+                if order.status != settings.DEFAULT:
+                    raise CustomError(u'该订单已审核')
+                order.status = settings.PASS
+                order.check_user = request.user
+                order.check_time = timezone.now()
+
+                ProductionDemandDetail.objects.filter(main_id=order.id).update(receive_count=F('count'))
+
+                order.updateReceiveAmount()
+
+                BizLog.objects.addnew(
+                    request.user,
+                    BizLog.CHECK,
+                    u"审核生产需求[%s],id=%d" % (order.no, order.id),
+                )
+            else:
+                if order.status == settings.DEFAULT:
+                    raise CustomError(u'该订单尚未审核')
+                order.status = settings.DEFAULT
+                order.check_user = None
+                order.check_time = None
+
+                ProductionDemandDetail.objects.filter(main_id=order.id).update(receive_count=0)
+                order.updateReceiveAmount()
+
+                BizLog.objects.addnew(
+                    request.user,
+                    BizLog.CHECK,
+                    u"取消审核销售订单[%s],id=%d" % (order.no, order.id),
+                )
+            order.save()
+    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.receive_demand')
+def demand_receive_save(request):
+    id = request.GET.get('id')
+    data = json.loads(request.body)
+
+    try:
+        with transaction.atomic():
+            order = ProductionDemand.getById(id)
+            if order.status == settings.DEFAULT:
+                raise CustomError(u'该生产需求尚未审核')
+            receive_notes = data['order_data']['notes']
+            for item in data['items']:
+                detail = ProductionDemandDetail.objects.filter(id=item['detail_id']).first()
+                detail.receive_count += Formater.formatCount(item['receive_count'])                
+                detail.save()
+
+            order.updateReceiveAmount()
+            order.receive_notes = receive_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.export_demand')
+def demand_export_detail(request):
+    id = request.GET.get('id')
+    queryset = ProductionDemandDetail.objects.filter()
+    if id:
+        queryset = queryset.filter(main_id=id)
+    serializer = ProductionDemandDetailSerializer(queryset, many=True)
+    export_data = ExportChange.dict_to_obj(serializer)
+    export_data = ProductionDemandDetailResource().export(export_data)
+    filename = utils.attachment_save(export_data)
+    BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产需求明细")
+    return JSONResponse({'filename': filename})
+
+@csrf_exempt
+@permission_required('order.export_demand')
+def demand_import(request):
+    file = request.FILES.get('excel_file')
+
+    try:
+        line = 2
+        importer = ProductionDemandEntryImporter()
+        excel_rows = importer.getExcelData(file)
+        with transaction.atomic():
+            for excel_row in excel_rows:
+                try:
+                    row = importer.validRow(excel_row)
+                    name = row[u'客户姓名']
+                    tel = row[u'客户电话']
+                    notes = row[u'备注'] or ''
+                    demand_date = row[u'需求时间'] or ''
+                    count = int(row[u'数量'])
+                    price = row[u'单价']
+                    customer = Customer.objects.filter(Q(mobile=tel) | Q(company_tel=tel)).first()
+                    if not customer:
+                        customer = Customer.objects.create(
+                            mobile=tel,
+                            company_tel=tel,
+                            name=name,
+                            company_name=name,
+                            create_user=request.user,
+                        )
+                    main_data = {
+                        'customer':customer.id,
+                        'demand_date':demand_date.date(),
+                        'notes':notes,
+                        'create_user':request.user,
+                        'count':0,
+                        'price':0,
+                    }
+                    serializer = ProductionDemandSerializer.factory(request.user, main_data)
+                    serializer = serializer.validSave()
+                    product = row[u'产品名称']
+                    model = row[u'产品代码']
+                    goods = Goods.objects.filter(product_base__model=model, product_base__type=ProductBase.GOODS)
+                    if goods.count() == 0:
+                        raise CustomError(u'产品代码不存在')
+                    elif goods.count() > 1:
+                        raise CustomError(u'产品代码重复,前往基础数据设置修改')
+                    else:
+                        goods = goods.first()
+                    items_data = {}
+                    items_data['goods'] = goods.id
+                    items_data['main'] = serializer.id
+                    items_data['price'] = price
+                    items_data['count'] = count
+                    detail_serializer = ProductionDemandDetailSerializer.factory(request.user, items_data)
+                    detail_serializer.validSave()
+                    serializer.updateAmount()
+                except CustomError, e:
+                    raise CustomError(u'第%d行:%s' % (line, e.get_error_msg()))
+                except Exception, e:
+                    raise CustomError(u'第%d行:%s' % (line, unicode(e)))
+                line += 1
+            BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入生产需求[%s],id=%d" % (serializer.no, serializer.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('plan.view_production_plan')
 def production_list(request):

+ 10 - 10
libs/http.py

@@ -8,7 +8,7 @@ import thread
 from django.conf import settings
 from django.http import JsonResponse as DJR
 
-from exceptionhandler import post_traceback
+#from exceptionhandler import post_traceback
 
 def JsonResponse(data=None):
     ret = {
@@ -18,15 +18,15 @@ def JsonResponse(data=None):
     return DJR(ret, safe=False)
 
 def JsonError(error_string):
-    if not 'dev' in settings.LICENSE_KEY:
-        exc_type, exc_value, exc_traceback_obj = sys.exc_info()
-        if exc_type and exc_type.__name__ != 'ValueError':
-            trace = traceback.format_exc()
-            try:
-                thread.start_new_thread(post_traceback, (exc_value, trace,))
-            except:
-                print "Error: unable to start report exception thread"
-            #print '******', exc_type.__name__, type(exc_type.__name__)
+    # if not 'dev' in settings.LICENSE_KEY:
+    #     exc_type, exc_value, exc_traceback_obj = sys.exc_info()
+    #     if exc_type and exc_type.__name__ != 'ValueError':
+    #         trace = traceback.format_exc()
+    #         try:
+    #             thread.start_new_thread(post_traceback, (exc_value, trace,))
+    #         except:
+    #             print "Error: unable to start report exception thread"
+    #         #print '******', exc_type.__name__, type(exc_type.__name__)
 
     data = {
         'code': 1,

+ 53 - 0
mac.py

@@ -0,0 +1,53 @@
+#coding=utf-8
+import uuid
+import datetime
+import os
+
+import platform
+import base64
+import hashlib
+
+XorKey = [0xB2, 0x09, 0xBB, 0x55, 0x93, 0x83, 0x03, 0x24]
+
+def enc(src):
+    j, result = 0, ""
+    for s in src:
+        result = result + hex(ord(s) ^ (XorKey[j]))[2:]
+        j = (j + 1) % 8
+    return result
+
+sysstr = platform.system()
+if (sysstr == "Windows"):
+    import _winreg
+    key = _winreg.OpenKey(
+        _winreg.HKEY_LOCAL_MACHINE,
+        "SOFTWARE\\Microsoft\\Cryptography",
+        0,
+        _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY
+    )
+    result = _winreg.QueryValueEx(key, "MachineGuid")
+    mac = result[0]
+else:
+    mac = ':'.join(['{:02x}'.format((uuid.getnode() >> i) & 0xff) for i in range(0,8*6,8)][::-1])
+
+#path = '/auth/repairwin/v2/'
+path = '/auth/pfwin/'
+mac += 'ZZLY[' + path + ']2019-04-17'
+mac = enc(mac)
+mac = base64.b64encode(mac)
+mac = hashlib.sha256(mac).hexdigest()
+
+cmd = 'echo ' + mac + '| clip'
+os.system(cmd)
+
+print u'#==================================修管佳=================================='
+print '#'
+print u'#机器码: ', mac
+print '#'
+print u'#系统时间:',datetime.datetime.now()
+print '#'
+print '#机器码已复制,可直接粘贴发送给授权人员'
+print '#'
+print u'#=============================郑州燎原版权所有============================='
+print ''
+os.system('pause')

+ 33 - 0
requeirements.txt

@@ -0,0 +1,33 @@
+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

+ 6 - 5
scj/app_settings.py

@@ -5,10 +5,11 @@ from const import *
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
-        'NAME': 'scj',
-        'USER': 'carwin',  # Not used with sqlite3.
-        'PASSWORD': 'carwin!@#',  # Not used with sqlite3.
-        'HOST': '39.106.109.89',
+        'NAME': 'rpwin_demo',
+        'USER': 'rpwin',                      # Not used with sqlite3.
+        'PASSWORD': 'rpwin!@#',                  # Not used with sqlite3.
+        'HOST': '192.168.133.233',
+        'PORT': 9306
     },
 }
 # DATABASES = {
@@ -23,7 +24,7 @@ DATABASES = {
 
 PAGE_SIZE = 20
 
-LICENSE_KEY = 'dev-luyuhang'
+LICENSE_KEY = 'dev-lichao'
 
 # 备件出库模式
 MAINT_PART_DELIVER_MODE = STOCK_MODE_FIFO

+ 0 - 2
scj/local_settings.py

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

+ 0 - 5
scj/settings.py

@@ -159,8 +159,3 @@ MEDIA_ROOT = os.path.join(BASE_DIR, "uis/media/")
 TMP_URL = '/tmp/'
 TMP_ROOT = os.path.join(BASE_DIR, "tmp/")
 
-# 导入本地设置
-try:
-    from local_settings import *
-except ImportError:
-    pass

+ 0 - 30
scj/test_settings.py

@@ -1,30 +0,0 @@
-from settings import *
-
-import sys
-
-from settings import *
-
-# MIGRATION_MODULES = {
-#     'auth': None,
-#     'contenttypes': None,
-#     'default': None,
-#     'sessions': None,
-#
-#     'core': None,
-#     'profiles': None,
-#     'snippets': None,
-#     'scaffold_templates': None,
-# }
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.mysql',
-        'NAME': 'test_db',
-        'USER': 'root',                      # Not used with sqlite3.
-        'PASSWORD': '123',                  # Not used with sqlite3.
-        'HOST': '127.0.0.1',
-        "TEST_CHARSET": "utf8",
-    },
-}
-
-MIGRATE = False

BIN
static/xls/生产需求导入模板.xlsx


+ 6 - 6
uis/layuiadmin/style/admin.css

@@ -167,7 +167,7 @@ html{background-color: #f2f2f2; color: #666;}
 }
 
 /* 侧边收缩模式 */
-.layadmin-side-shrink .layui-layout-admin .layui-logo{width: 60px; background-image: url(res/pf.ico); /*background-size: 20px;)*/}
+.layadmin-side-shrink .layui-layout-admin .layui-logo{width: 60px; background-image: url(res/favicon.ico); /*background-size: 20px;)*/}
 .layadmin-side-shrink .layui-layout-admin .layui-logo span{display: none;}
 .layadmin-side-shrink .layui-side{left: 0; width: 60px;}
 .layadmin-side-shrink .layui-layout-admin .layui-layout-left,
@@ -293,14 +293,14 @@ html{background-color: #f2f2f2; color: #666;}
 
 /* 快捷方式 */
 .layadmin-shortcut li{text-align: center;}
-.layadmin-shortcut li .layui-icon{display: inline-block; width: 100%; height: 60px; line-height: 60px; text-align: center; border-radius: 2px; font-size: 30px; background-color: #F8F8F8; color: #333; transition: all .3s; -webkit-transition: all .3s;}
-.layadmin-shortcut li cite{position: relative; top: 2px; display: block; color: #666; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size: 14px;}
+.layadmin-shortcut li .layui-icon{display: inline-block; width: 100%; height: 60px; line-height: 60px; text-align: center; border-top-left-radius: 2px; border-top-right-radius: 2px; font-size: 30px; background-color: #F8F8F8; color: #333; transition: all .3s; -webkit-transition: all .3s;}
+.layadmin-shortcut li cite{position: relative; padding: 3px; display: block; color: #666; text-overflow: ellipsis; overflow: hidden; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; white-space: nowrap; font-size: 14px; background-color: #ebf3f2;}
 .layadmin-shortcut li:hover .layui-icon{background-color: #f2f2f2;}
 
 /* 待办事项 */
-.layadmin-backlog .layadmin-backlog-body{display: block; padding: 10px 15px; background-color: #f8f8f8; color: #999; border-radius: 2px; transition: all .3s; -webkit-transition: all .3s;}
-.layadmin-backlog-body h3{padding-bottom: 10px; font-size: 12px;}
-.layadmin-backlog-body p cite{font-style: normal; font-size: 30px; font-weight: 300; color: #009688;}
+.layadmin-backlog .layadmin-backlog-body{display: block; text-align: center; padding: 10px 15px; background-color: #f8f8f8; color: #999; border-radius: 2px; transition: all .3s; -webkit-transition: all .3s; margin-right: 1px;margin-bottom: 1px;}
+.layadmin-backlog-body h3{padding-bottom: 10px; font-size: 12px; }
+.layadmin-backlog-body p cite{font-style: normal; font-size: 30px; font-weight: 300; color: #009688; }
 .layadmin-backlog-body:hover{background-color: #f2f2f2; color: #888;}
 
 /* 数据概览 */

+ 6 - 6
uis/layuiadmin/style/login.css

@@ -10,13 +10,13 @@
 html,body,#LAY_app{height:100%;}
 .layui-layout-body{overflow: auto;}
  
-#LAY-user-login,
-.layadmin-user-display-show{display: block !important;} 
-.layadmin-user-login{position: relative; left: 0; top: 0; padding: 110px 0; min-height: 100%; box-sizing: border-box;}
-.layadmin-user-login-main{width: 375px; margin: 0 auto; box-sizing: border-box;}
-.layadmin-user-login-box{padding: 20px;}
+
+.layadmin-user-login{display: flex; }
+.layadmin-user-login-banner { flex: 2; height: 100vh; border-right: #ccc solid 1px; display: flex; align-items: center; justify-content: center;}
+.layadmin-user-login-main{flex: 1; text-align: center; display: flex; align-items: center; justify-content: center; background-color: #fff;}
+.layadmin-user-login-box{margin: 20px; width: 360px; }
 .layadmin-user-login-header{text-align: center;}
-.layadmin-user-login-header h2{margin-bottom: 10px; font-weight: 300; font-size: 30px; color: #000;}
+.layadmin-user-login-header h2{margin-bottom: 50px; font-weight: 300; font-size: 30px; color: #000;}
 .layadmin-user-login-header p{font-weight: 300; color: #999;}
 
 .layadmin-user-login-body .layui-form-item{position: relative;}

BIN
uis/layuiadmin/style/res/bg.png


BIN
uis/layuiadmin/style/res/favicon.ico


BIN
uis/layuiadmin/style/res/logo.png


BIN
uis/layuiadmin/style/res/pf.ico


+ 2 - 2
uis/layuiadmin/tpl/system/about.html

@@ -2,7 +2,7 @@
 <div class="layui-card-header">版本信息</div>
 <div class="layui-card-body layui-text layadmin-about">
   <script type="text/html" template>
-    <p>当前版本:2.1.0</p>
+    <p>当前版本:2.2.0</p>
   </script>
 </div>
 
@@ -12,5 +12,5 @@
   <blockquote class="layui-elem-quote" style="border: none;">
     本软件受国家计算机软件著作权保护,未经正规渠道授权擅自使用、以及直接对产品二次出售的,我们将保留追究法律责任的权利。
   </blockquote>
-  <p>© 2021 <a href="http://www.zzliaoyuan.com/">郑州燎原计算机技术有限公司</a> 版权所有</p>
+  <p>© 2024 <a href="http://www.zzliaoyuan.com/">郑州燎原计算机技术有限公司</a> 版权所有</p>
 </div>

+ 24 - 18
uis/views/account/login.html

@@ -9,34 +9,40 @@
   <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
   <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
   <link rel="stylesheet" href="../../layuiadmin/style/login.css" media="all">
+  <link rel="icon" type="image/x-icon" href="../../layuiadmin/style/res/favicon.ico">
 </head>
 <body>
 
-  <div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login" style="display: none;">
-
+  <div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login">
+    <div class="layadmin-user-login-banner">
+      <img src="/layuiadmin/style/res/bg.png" style="width: 80%;"/>
+    </div>
     <div class="layadmin-user-login-main">
-      <div class="layadmin-user-login-box layadmin-user-login-header">
-        <h2>生产佳ERP系统</h2>
-      </div>
-      <form class="layui-form" action="" lay-filter="component-form-element">
-      <div class="layadmin-user-login-box layadmin-user-login-body layui-form">
-        <div class="layui-form-item">
-          <label class="layadmin-user-login-icon layui-icon layui-icon-username" for="LAY-user-login-username"></label>
-          <input type="text" name="username" id="LAY-user-login-username" lay-verify="required" placeholder="用户名" autocomplete="off" class="layui-input">
-        </div>
-        <div class="layui-form-item">
-          <label class="layadmin-user-login-icon layui-icon layui-icon-password" for="LAY-user-login-password"></label>
-          <input type="password" name="password" id="LAY-user-login-password" autocomplete="off" lay-verify="required" placeholder="密码" class="layui-input">
+      <div>
+        <div class="layadmin-user-login-box layadmin-user-login-header">
+          <img src="/layuiadmin/style/res/logo.png" style="width: 64px;"/>
+          <h2>生产佳ERP系统</h2>
         </div>
-        <div class="layui-form-item">
-          <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="component-form-element">登 录</button>
+        <form class="layui-form" action="" lay-filter="component-form-element">
+        <div class="layadmin-user-login-box layadmin-user-login-body layui-form">
+          <div class="layui-form-item">
+            <label class="layadmin-user-login-icon layui-icon layui-icon-username" for="LAY-user-login-username"></label>
+            <input type="text" name="username" id="LAY-user-login-username" lay-verify="required" placeholder="用户名" autocomplete="off" class="layui-input">
+          </div>
+          <div class="layui-form-item">
+            <label class="layadmin-user-login-icon layui-icon layui-icon-password" for="LAY-user-login-password"></label>
+            <input type="password" name="password" id="LAY-user-login-password" autocomplete="off" lay-verify="required" placeholder="密码" class="layui-input">
+          </div>
+          <div class="layui-form-item">
+            <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="component-form-element">登 录</button>
+          </div>
         </div>
+        </form>
       </div>
-       </form>
     </div>
     
     <div class="layui-trans layadmin-user-login-footer">
-      <p>© 2018 生产佳ERP系统 <a href="http://www.zzliaoyuan.com/" target="_blank">郑州燎原计算机技术有限公司</a></p>
+      <p>© 2024 <a href="http://www.zzliaoyuan.com/" target="_blank">郑州燎原计算机技术有限公司</a></p>
     </div>
     
     <!--<div class="ladmin-user-login-theme">

+ 6 - 6
uis/views/dashboard/home.html

@@ -19,7 +19,7 @@
         <div class="layui-row layui-col-space15">
 
           <div class="layui-col-md8">
-            <div class="layui-card">
+            <div class="layui-card" style="height: 510px;">
               <div class="layui-card-header">快捷方式</div>
               <div class="layui-card-body">
 
@@ -34,13 +34,13 @@
                       </li>
                       <li class="shortcut layui-col-md2" data-permission="plan.view_sale_plan">
                         <a lay-href="plan/sale.html">
-                          <i class="layui-icon layui-icon-form"></i>
+                          <i class="layui-icon layui-icon-release"></i>
                           <cite>销售计划</cite>
                         </a>
                       </li>
                       <li class="shortcut layui-col-md2" data-permission="plan.view_production_plan">
                         <a lay-href="plan/production.html">
-                          <i class="layui-icon layui-icon-diamond"></i>
+                          <i class="layui-icon layui-icon-util"></i>
                           <cite>生产计划</cite>
                         </a>
                       </li>
@@ -53,7 +53,7 @@
                       </li>
                       <li class="shortcut layui-col-md2" data-permission="order.view_sale_order">
                         <a lay-href="order/sale_order.html">
-                          <i class="layui-icon layui-icon-read"></i>
+                          <i class="layui-icon layui-icon-component"></i>
                           <cite>销售订单</cite>
                         </a>
                       </li>
@@ -66,12 +66,12 @@
             </div>
           </div>
           <div class="layui-col-md4">
-            <div class="layui-card">
+            <div class="layui-card" style="height: 510px;">
               <div class="layui-card-header">待处理</div>
               <div class="layui-card-body">
 
                 <div class="layui-carousel layadmin-carousel layadmin-backlog">
-                  <div carousel-item style="overflow: auto;">
+                  <div carousel-item style="overflow: auto; height: 450px;">
                     <ul id="layui-nav-child">
                       <li class="layui-col-xs4" data-permission="plan.check_sale_plan">
                         <a href="javascript:;" class="layadmin-backlog-body">

+ 1 - 1
uis/views/goods/goods_godownentry.html

@@ -44,7 +44,7 @@
                             </dl>
                         </div>
                     </button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="goods.print_goods_godown_entry"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="goods.print_goods_godown_entry"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/goods/goods_godownentry_query.html

@@ -27,7 +27,7 @@
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission="order.export_goods_godownentry_query"><i class="layui-icon layui-icon-download-circle"></i>导出</button>
 
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="order.print_goods_godownentry_query"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="order.print_goods_godownentry_query"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/goods/goods_inventory.html

@@ -33,7 +33,7 @@
                                 </dl>
                             </div>
                         </button>
-                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="goods.print_goods_inventory"><i class="layui-icon layui-icon-form"></i>打印</button>
+                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="goods.print_goods_inventory"><i class="layui-icon layui-icon-print"></i>打印</button>
                         <button class="layui-nav" data-permission="goods.export_goods_inventory">
                             <div class="layui-nav-item">
                                 <a href="javascript:;" style="color:#fff;">导出</a>

+ 4 - 4
uis/views/goods/goods_stock_query.html

@@ -94,14 +94,14 @@
       elem: '#datagrid'
       ,url: '/goods/product/data/'
       ,cols: [[
-        {field:'name', title:'名称', width:100}
-        ,{field:'model', title:'代码', width:100}
+        {field:'name', title:'名称', width:150}
+        ,{field:'model', title:'代码', width:120}
         ,{field:'option_type_text', title:'类别', width:100}
         ,{field:'standard', title:'规格', width:100}
         ,{field:'stock_count', align: 'right', title:'库存', width:100}
         ,{field:'warehouse_place', title:'存放库位', width: 120}
-        ,{field:'unit', title:'单位', width:120}
-        ,{field:'enabled_text', title:'在用', width:100}
+        ,{field:'unit', title:'单位', width:60}
+        ,{field:'enabled_text', title:'在用', width:60}
         ,{field:'code', title:'助记码', width:100}
         ,{field:'notes', title:'备注', minWidth:150}
       ]]

+ 0 - 1
uis/views/goods/search_goods_item.html

@@ -32,7 +32,6 @@
                         <div style="clear:both;height: 5px;"></div>
                     </div>
 
-
                     <div class="layui-col-md12">
                         <table id="dataTable" lay-filter="dataTable" class="layui-hide"></table>
                     </div>

+ 13 - 8
uis/views/index.html

@@ -8,6 +8,7 @@
   <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">
+  <link rel="icon" type="image/x-icon" href="../layuiadmin/style/res/favicon.ico">
 </head>
 <body class="layui-layout-body">
 
@@ -57,7 +58,8 @@
       <div class="layui-side layui-side-menu">
         <div class="layui-side-scroll">
           <div class="layui-logo">
-            <span>生产佳<span style="font-size: 12px;">erp</span></span>
+            <img src="/layuiadmin/style/res/logo.png" style="width: 20px;"/>
+            <span>生产佳<span style="font-size: 12px;">ERP</span></span>
           </div>
 
           <ul class="layui-nav layui-nav-tree" lay-shrink="all" id="LAY-system-side-muen" lay-filter="layadmin-system-side-menu">
@@ -74,7 +76,7 @@
             </li>
             <li data-name="set" class="layui-nav-item">
               <a href="javascript:;" lay-tips="销售管理" lay-direction="2">
-                <i class="layui-icon layui-icon-form"></i>
+                <i class="layui-icon layui-icon-release"></i>
                 <cite>销售管理</cite>
               </a>
               <dl class="layui-nav-child">
@@ -91,10 +93,13 @@
             </li>
             <li data-name="component" class="layui-nav-item">
               <a href="javascript:;" lay-tips="生产管理" lay-direction="2">
-                <i class="layui-icon layui-icon-read"></i>
+                <i class="layui-icon layui-icon-set-fill"></i>
                 <cite>生产管理</cite>
               </a>
               <dl class="layui-nav-child">
+                <dd data-name="nav" data-permission="plan.view_production_demand">
+                  <a lay-href="plan/demand.html">生产需求管理</a>
+                </dd>                
                 <dd data-name="nav" data-permission="plan.view_production_plan">
                   <a lay-href="plan/production.html">生产计划管理</a>
                 </dd>
@@ -125,7 +130,7 @@
             </li>
             <li data-name="component" class="layui-nav-item">
               <a href="javascript:;" lay-tips="原料管理" lay-direction="2">
-                <i class="layui-icon layui-icon-read"></i>
+                <i class="layui-icon layui-icon-form"></i>
                 <cite>原料管理</cite>
               </a>
               <dl class="layui-nav-child" >
@@ -166,7 +171,7 @@
             </li>
               <li data-name="component" class="layui-nav-item">
               <a href="javascript:;" lay-tips="耗材管理" lay-direction="2">
-                <i class="layui-icon layui-icon-read"></i>
+                <i class="layui-icon layui-icon-template-1"></i>
                 <cite>耗材管理</cite>
               </a>
               <dl class="layui-nav-child" >
@@ -207,7 +212,7 @@
             </li>
               <li data-name="component" class="layui-nav-item">
               <a href="javascript:;" lay-tips="成品管理" lay-direction="2">
-                <i class="layui-icon layui-icon-read"></i>
+                <i class="layui-icon layui-icon-diamond"></i>
                 <cite>成品管理</cite>
               </a>
               <dl class="layui-nav-child" >
@@ -243,7 +248,7 @@
             </li>
             <li data-name="component" class="layui-nav-item">
               <a href="javascript:;" lay-tips="统计报表" lay-direction="2">
-                <i class="layui-icon layui-icon-read"></i>
+                <i class="layui-icon layui-icon-rmb"></i>
                 <cite>财务管理</cite>
               </a>
               <dl class="layui-nav-child">
@@ -260,7 +265,7 @@
             </li>
             <li data-name="set" class="layui-nav-item">
               <a href="javascript:;" lay-tips="基础数据" lay-direction="2">
-                <i class="layui-icon layui-icon-set"></i>
+                <i class="layui-icon layui-icon-slider"></i>
                 <cite>基础数据</cite>
               </a>
               <dl class="layui-nav-child">

+ 1 - 1
uis/views/material/consumable_inventory.html

@@ -33,7 +33,7 @@
                   </dl>
                 </div>
               </button>
-              <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="warehouse.print_consumable_inventory"><i class="layui-icon layui-icon-form"></i>打印</button>
+              <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="warehouse.print_consumable_inventory"><i class="layui-icon layui-icon-print"></i>打印</button>
                 <button class="layui-nav" data-permission="warehouse.export_consumable_inventory">
                 <div class="layui-nav-item">
                   <a href="javascript:;" style="color:#fff;">导出</a>

+ 1 - 1
uis/views/material/deliver_consumable_query.html

@@ -27,7 +27,7 @@
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission='plan.export_consumable_deliver_query'><i class="layui-icon layui-icon-download-circle"></i>导出</button>
 
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission='plan.print_consumable_deliver_query'><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission='plan.print_consumable_deliver_query'><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/material/deliver_consumable_return.html

@@ -27,7 +27,7 @@
 
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" data-permission="material.add_consumable_deliver_return" id="btn_add"><i class="layui-icon layui-icon-add-1"></i>退料</button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="material.print_consumable_deliver_return"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="material.print_consumable_deliver_return"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query" data-permission="material.view_consumable_deliver_return"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/material/deliver_material_query.html

@@ -27,7 +27,7 @@
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission='plan.export_material_deliver_query'><i class="layui-icon layui-icon-download-circle"></i>导出</button>
 
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission='plan.print_material_deliver_query' ><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission='plan.print_material_deliver_query' ><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/material/deliver_material_return.html

@@ -27,7 +27,7 @@
 
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" data-permission="material.add_material_deliver_return" id="btn_add"><i class="layui-icon layui-icon-add-1"></i>退料</button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="material.print_material_deliver_return"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="material.print_material_deliver_return"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query" data-permission="material.view_material_deliver_return"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/material/material_inventory.html

@@ -33,7 +33,7 @@
                   </dl>
                 </div>
               </button>
-              <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="warehouse.print_material_inventory"><i class="layui-icon layui-icon-form"></i>打印</button>
+              <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="warehouse.print_material_inventory"><i class="layui-icon layui-icon-print"></i>打印</button>
                 <button class="layui-nav" data-permission="warehouse.export_material_inventory">
                 <div class="layui-nav-item">
                   <a href="javascript:;" style="color:#fff;">导出</a>

+ 1 - 1
uis/views/order/goods_deliver_query.html

@@ -27,7 +27,7 @@
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export"><i class="layui-icon layui-icon-download-circle"></i>导出</button>
 
-                    <button class="layui-btn layui-btn-sm" id="btn_print"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/order/goods_deliver_return.html

@@ -27,7 +27,7 @@
 
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" data-permission="order.add_goods_deliver_return" id="btn_add"><i class="layui-icon layui-icon-add-1"></i>退库</button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="order.print_goods_deliver_return"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="order.print_goods_deliver_return"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query" data-permission="order.view_goods_deliver_return"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 16 - 15
uis/views/order/sale_order.html

@@ -2,7 +2,7 @@
 <html>
 <head>
     <meta charset="utf-8">
-    <title>出库管理</title>
+    <title>销售订单管理</title>
     <meta name="renderer" content="webkit">
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <meta name="viewport"
@@ -53,6 +53,15 @@
                         <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-nav" data-permission="order.export_sale_order">
+                            <div class="layui-nav-item">
+                                <a href="javascript:;" style="color:#fff;">导入</a>
+                                <dl class="layui-nav-child"> <!-- 二级菜单 -->
+                                    <dd><a href="#" id="import_order">执行导入</a></dd>
+                                    <dd><a href="#" id="btn_download_tmp">下载模板</a></dd>
+                                </dl>
+                            </div>
+                        </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>转出库
@@ -61,16 +70,16 @@
                                 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>完善发货
+                                class="layui-icon layui-icon-edit"></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>装运
+                                class="layui-icon layui-icon-app"></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>结算
+                                class="layui-icon layui-icon-rmb"></i>结算
                         </button>
                         <button class="layui-btn layui-btn-sm" id="btn_clear" data-permission="order.pay_sale_order"><i
-                                class="layui-icon layui-icon-dollar"></i>结清
+                                class="layui-icon layui-icon-ok-circle"></i>结清
                         </button>
 
                         <button class="layui-nav" data-permission="order.export_sale_order">
@@ -82,17 +91,9 @@
                                 </dl>
                             </div>
                         </button>
-                        <button class="layui-nav" data-permission="order.export_sale_order">
-                            <div class="layui-nav-item">
-                                <a href="javascript:;" style="color:#fff;">导入</a>
-                                <dl class="layui-nav-child"> <!-- 二级菜单 -->
-                                    <dd><a href="#" id="import_order">执行导入</a></dd>
-                                    <dd><a href="#" id="btn_download_tmp">下载模板</a></dd>
-                                </dl>
-                            </div>
-                        </button>
+
                         <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="order.print_sale_order">
-                            <i class="layui-icon layui-icon-form"></i>打印
+                            <i class="layui-icon layui-icon-print"></i>打印
                         </button>
                         <button class="layui-btn layui-btn-sm" id="btn_query"><i
                                 class="layui-icon layui-icon-search"></i>查询

+ 486 - 0
uis/views/plan/demand.html

@@ -0,0 +1,486 @@
+<!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">
+</head>
+<style type="text/css">
+    .LAY-btns .layui-nav {
+        padding-left: 0;
+        padding-right: 10px;
+        top: -4px;
+        margin: 0 10px;
+        border: 0;
+        background-color: #009688;
+    }
+
+    .LAY-btns .layui-nav .layui-nav-item {
+        line-height: 30px;
+    }
+
+    .LAY-btns .layui-nav .layui-nav-child {
+        top: 34px;
+    }
+
+    .LAY-btns .layui-nav .layui-nav-bar {
+        display: none;
+    }
+
+    .LAY-btns .layui-nav .layui-nav-child dd.layui-this a {
+        color: #333;
+        background-color: #fff;
+    }
+
+    .LAY-btns .layui-nav .layui-nav-child dd.layui-this a:hover {
+        background-color: #f2f2f2;
+        color: #000;
+    }
+</style>
+<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">
+                    <div class="LAY-btns" style="margin-bottom: 10px;">
+                        <button class="layui-btn layui-btn-sm" id="btn_add" data-permission="plan.add_production_demand"><i
+                                class="layui-icon layui-icon-add-circle"></i>添加
+                        </button>
+                        <button class="layui-nav" data-permission="plan.export_production_demand">
+                            <div class="layui-nav-item">
+                                <a href="javascript:;" style="color:#fff;">导入</a>
+                                <dl class="layui-nav-child"> <!-- 二级菜单 -->
+                                    <dd><a href="#" id="import_order">执行导入</a></dd>
+                                    <dd><a href="#" id="btn_download_tmp">下载模板</a></dd>
+                                </dl>
+                            </div>
+                        </button>                        
+                        <button class="layui-btn layui-btn-sm" id="btn_receive" data-permission="plan.receive_production_demand"><i
+                                class="layui-icon layui-icon-download-circle"></i>收货
+                        </button>
+
+                        <button class="layui-nav" data-permission="plan.export_production_demand">
+                            <div class="layui-nav-item">
+                                <a href="javascript:;" style="color:#fff;">导出</a>
+                                <dl class="layui-nav-child"> <!-- 二级菜单 -->
+                                    <dd><a href="#" id="btn_download">导出列表</a></dd>
+                                    <dd><a href="#" id="btn_download_detail">导出明细</a></dd>
+                                    <dd><a href="#" id="btn_download_all_detail">导出全部明细</a></dd>
+                                </dl>
+                            </div>
+                        </button>
+
+                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="plan.print_production_demand">
+                            <i class="layui-icon layui-icon-print"></i>打印
+                        </button>
+                        <button class="layui-btn layui-btn-sm" id="btn_query"><i
+                                class="layui-icon layui-icon-search"></i>查询
+                        </button>
+                    </div>
+
+                    <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>
+
+                    <script type="text/html" id="datagrid-operate-bar">
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs" lay-event="detail"
+                               data-permission="plan.view_production_demand">查看</a>
+                            {{# if(d.status ==0){ }}
+                            <a class="layui-btn layui-btn-xs" lay-event="edit"
+                               data-permission="plan.add_production_demand">修改</a>
+                            <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"
+                               data-permission="plan.delete_production_demand">删除</a>
+                            <a class="layui-btn layui-btn-xs" lay-event="check_pass"
+                               data-permission="plan.check_production_demand">审核</a>
+                            {{# } }}
+                            {{# if(d.status ==1){ }}
+                            <a class="layui-btn layui-btn-xs" lay-event="check_revoke"
+                               data-permission="plan.check_production_demand">撤销审核</a>
+                            {{# } }}
+                        </div>
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div id="dlg_query" style="display: none">
+    <form class="layui-form" lay-filter="query-form-element">
+        <div class="layui-card-body" pad15>
+            <div class="layui-row layui-col-space10 layui-form-item">
+
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">下单时间</label>
+                    <div class="layui-input-inline">
+                        <input type="text" class="layui-input" autocomplete="off" name="create_time" id="create_time"
+                               placeholder=" - ">
+                    </div>
+                </div>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">下单人:</label>
+                    <div class="layui-input-block">
+                        <input type="text" autocomplete="off" name="create_user" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">状态:</label>
+                    <div class="layui-input-block">
+                        <select id="id_check_status" name="status">
+                            <option value="" selected></option>
+                            <option value="0">待审核</option>
+                            <option value="1">已审核</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">订单号:</label>
+                    <div class="layui-input-block">
+                        <input type="text" autocomplete="off" name="no" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">客户姓名:</label>
+                    <div class="layui-input-block">
+                        <input type="text" autocomplete="off" name="customer_name" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">客户电话:</label>
+                    <div class="layui-input-block">
+                        <input type="text" autocomplete="off" name="customer_tel" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">需求时间:</label>
+                    <div class="layui-input-block">
+                        <input type="text" class="layui-input" autocomplete="off" name="demand_date" id="demand_date"
+                               placeholder=" - ">
+                    </div>
+                </div>
+            </div>
+            <div class="layui-form-item" style="display: none">
+                <button id="query_search" class="layui-btn" lay-submit lay-filter="query-form-element">查询</button>
+            </div>
+        </div>
+    </form>
+</div>
+
+<script src="../../layuiadmin/layui/layui.js?t=1"></script>
+<script>
+    var _params = '';
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+    }).use(['index', 'table', 'laydate', 'form',  'upload', 'element', 'utils'], function () {
+        var $ = layui.$;
+        var table = layui.table
+            , laydate = layui.laydate
+            , form = layui.form
+            , utils = layui.utils
+            , upload = layui.upload;
+
+        table.render({
+            elem: '#datagrid'
+            , url: '/plan/demand/data/'
+            , cols: [[
+                {type: 'radio', width: 50}
+                , {field: 'no', title: '单号', width: 150}
+                , {field: 'demand_date', title: '需求时间', width: 110}
+                , {field: 'customer_name', title: '客户', width: 120}
+                , {field: 'customer_tel', title: '客户电话', width: 120}
+                , {field: 'products', title: '产品', width: 150}
+                , {field: 'count', title: '合计数量', width: 90, align: 'right'}
+                , {field: 'receive_count', title: '收货数量', width: 90, align: 'right'}
+                , {field: 'receiveable_count', title: '待收数量', width: 90, align: 'right'}
+                , {field: 'receive_notes', title: '收货备注', width: 200}
+                , {field: 'create_time', title: '创建时间', width: 145}
+                , {field: 'create_user_text', title: '创建人', width: 120}
+                , {field: 'check_status_text', title: '审核状态', width: 120}
+                , {field: 'check_time', title: '审核时间', width: 145}
+                , {field: 'check_user_text', title: '审核人', width: 120}
+                , {field: 'notes', title: '备注', minWidth: 200}
+                , {width: 200, align: 'left', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+            ]]
+            , page: true
+            , totalRow: true
+            , height: 'full-104'
+            , parseData: function (res) {
+                var cols = this.cols[0];
+                for (var i in cols) {
+                    if (cols[i].field == 'count') {
+                        cols[i].totalRowText = res.more.sum_count;
+                    }
+                    if (cols[i].field == 'receive_count') {
+                        cols[i].totalRowText = res.more.sum_receive_count;
+                    }
+                }
+                return {
+                    "code": res.code, //解析接口状态
+                    "count": res.count, //解析数据长度
+                    "data": res.data //解析数据列表
+                };
+            }
+            , done: function () {
+                layui.index.removeNoPermButtons();
+            }
+        });
+
+        //监听工具条
+        table.on('tool(datagrid-operate)', function (obj) {
+            var data = obj.data;
+            table.editdata = data;
+            if (obj.event === 'detail') {
+                layer.open({
+                    type: 2,
+                    title: '查看',
+                    shadeClose: true,
+                    area: ['90%', '90%'],
+                    content: 'demand_detail.html?id=' + data.id
+                });
+            } else if (obj.event === 'del') {
+                if (data.status != 0) {
+                    layer.msg('该订单已审核,不允许删除');
+                    return;
+                }
+                layer.confirm('确定要删除吗?', function (index) {
+                    layer.close(index);
+                    layui.admin.req({
+                        url: '/plan/demand/delete/?id=' + data.id
+                        , done: function (res) {
+                            table.reload('datagrid', {});
+                        }
+                    });
+                });
+            } else if (obj.event === 'edit') {
+                if (data.status != 0) {
+                    layer.msg('该订单已审核,不允许修改');
+                    return;
+                }
+                table.editdata = data;
+                layer.open({
+                    type: 2,
+                    title: '修改订单[' + data.no + ']',
+                    area: ['90%', '90%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        layui.onSubmitChild = function (data) {
+                            layer.close(index);
+                            table.reload('datagrid', {});
+                        };
+                        layui.submitChild();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: 'demand_edit.html?id=' + data.id
+                });
+            } else if (obj.event === 'check_pass') {
+                if (data.status != 0) {
+                    layer.msg('该出订单已审核, 禁止重复操作');
+                    return;
+                }
+                layer.confirm('确定要通过审核吗?', function (index) {
+                    layer.close(index);
+                    layui.admin.req({
+                        url: '/plan/demand/check/?id=' + data.id + '&status=1'
+                        , done: function (res) {
+                            table.reload('datagrid', {});
+                        }
+                    });
+                });
+            } else if (obj.event === 'check_revoke') {
+                if (data.status == 0) {
+                    layer.msg('该出订单尚未审核');
+                    return;
+                }
+                layer.confirm('确定要撤销审核吗?', function (index) {
+                    layer.close(index);
+                    layui.admin.req({
+                        url: '/plan/demand/check/?id=' + data.id + '&status=0'
+                        , done: function (res) {
+                            table.reload('datagrid', {});
+                        }
+                    });
+                });
+            }
+        });
+
+        $('#btn_add').on('click', function () {
+            layer.open({
+                type: 2,
+                title: '下单',
+                area: ['90%', '90%'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    layui.onSubmitChild = function (data) {
+                        layer.close(index);
+                        table.reload('datagrid', {});
+                    };
+                    layui.submitChild();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: 'demand_edit.html'
+            });
+        });
+        $('#btn_download').on('click', function () {
+            layui.admin.req({
+                url: '/plan/demand/export/',
+                data: _params,
+                done: function (res) {
+                    layui.view.download(res.data.filename);
+                }
+            });
+        });
+
+        $('#btn_download_detail').on('click', function () {
+            var data = utils.getSelectedRow('datagrid');
+            if (data == false) {
+                return;
+            }
+
+            layui.admin.req({
+                url: '/plan/demand/export_detail/?id=' + data.id,
+                done: function (res) {
+                    layui.view.download(res.data.filename);
+                }
+            });
+        });
+
+        $('#btn_download_all_detail').on('click', function () {
+            layui.admin.req({
+                url: '/plan/demand/export_detail/',
+                done: function (res) {
+                    layui.view.download(res.data.filename);
+                }
+            });
+        });        
+        $('#btn_download_tmp').on('click', function () {
+            layui.view.download("/static/xls/生产需求导入模板.xlsx");
+        });
+        upload.render({
+            elem: '#import_order'
+            , url: '/plan/demand/import/'
+            , accept: 'file'
+            , acceptMime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+            , exts: 'xlsx'
+            , field: 'excel_file'
+            , multiple: false
+            , done: function (res) {
+                if (res.code == 0) {
+                    table.reload('datagrid', {});
+                } else {
+                    layer.msg(res.msg);
+                }
+            }
+            , error: function () {
+                layer.msg('导入失败');
+            }
+        });
+        $('#btn_print').on('click', function () {
+            var data = utils.getSelectedRow('datagrid');
+            if (data == false) {
+                return;
+            }
+
+            table.editdata = data;
+
+            layer.open({
+                type: 2,
+                title: '打印',
+                shadeClose: true,
+                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: 'demand_print.html?id=' + data.id
+            });
+        });
+
+        $('#btn_receive').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: ['60%', '90%'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    layui.onSubmitChild = function (data) {
+                        layer.close(index);
+                        table.reload('datagrid', {});
+                    };
+                    layui.submitChild();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: 'demand_receive.html?order_id=' + data.id
+            });
+        });
+
+        $('#btn_query').on('click', function () {
+            layer.open({
+                type: 1,
+                shadeClose: true,
+                area: ['500px', '450px'],
+                title: '查询',
+                btn: ['查询'],
+                yes: function (index, dom) {
+                    $('#query_search').click();
+                },
+                content: $('#dlg_query')
+            });
+        });
+
+        form.on('submit(query-form-element)', function (data) {
+            //layer.msg(JSON.stringify(data.field));
+            _params = data.field;
+            table.reload('datagrid', {
+                where: data.field,
+                page: {curr: 1}
+            });
+            layer.closeAll();
+            return false
+        });
+
+        laydate.render({
+            elem: '#create_time'
+            , range: true
+        });
+        laydate.render({
+            elem: '#demand_date'
+            , range: true
+        });        
+    });
+</script>
+</body>
+</html>
+

+ 98 - 0
uis/views/plan/demand_detail.html

@@ -0,0 +1,98 @@
+<!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">
+</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">
+
+            <div id="print_div">
+                <table class="layui-table">
+                    <tr>
+                        <td id="no" class="cell">单号</td>
+                        <td id="create_time" class="cell">下单时间</td>
+                    </tr>
+                    <tr>
+                        <td id="check_status_text" class="cell">状态</td>
+                        <td id="customer_name" class="cell">客户</td>
+                    </tr>
+                    <tr>
+                        <td id="check_user_text" class="cell">审核人</td>
+                        <td id="check_time" class="cell">审核时间</td>
+                    </tr>
+                    <tr>
+                        <td id="demand_date" class="cell">需求时间</td>
+                        <td id="notes" class="cell">备注</td>
+                    </tr>
+                </table>
+                <table class="layui-table">
+                    <tr>
+                        <td>序号</td>
+                        <td>产品名称</td>
+                        <td>产品代码</td>
+                        <td>质量要求</td>
+                        <td align="right">数量</td>
+                        <td align="right">收货数量</td>
+                        <td align="right">单价</td>
+                        <td align="right">金额</td>
+                    </tr>
+
+                    <tr id="tr_item_total">
+                    </tr>
+                </table>
+            </div>
+          </div>
+        </div>
+        </div>
+    </div>
+  </div>
+
+  <script src="../../layuiadmin/layui/layui.js?t=1"></script>
+  <script>
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'table'], function(){
+    var $ = layui.$
+    ,admin = layui.admin
+    var data = JSON.parse(JSON.stringify(parent.layui.table.editdata));
+    $('.cell').each(function (index, element) {
+        element.innerHTML += ':' + (data[element.id]||'')
+    });
+
+    admin.req({
+        url: '/plan/demand/detail/?id='+data.id
+        ,done: function(data){
+            var items = data.data.items_data;
+            for(var n in items){
+                var m = parseInt(n) + 1;
+                $('#tr_item_total').before("<tr>\n" +
+                    "                        <td>"+m+"</td>\n" +
+                    "                        <td>"+items[n].name+"</td>\n" +
+                    "                        <td>"+items[n].model+"</td>\n" +
+                    "                        <td>"+items[n].quality_request_text+"</td>\n" +
+                    "                        <td align=\"right\">"+items[n].count+"</td>\n" +
+                    "                        <td align=\"right\">"+items[n].receive_count+"</td>\n" +
+                    "                        <td align=\"right\">"+items[n].price+"</td>\n" +
+                    "                        <td align=\"right\">"+items[n].amount+"</td>\n" +
+                    "                    </tr>");
+            }
+        }
+    });
+  });
+  </script>
+</body>
+</html>
+

+ 350 - 0
uis/views/plan/demand_edit.html

@@ -0,0 +1,350 @@
+<!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-xs12 layui-col-sm5">
+                                        <input id='id_customer' type="text"  autocomplete="off" lay-verify="required" class="layui-input"/>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm7" style="line-height: 37px;">
+                                        <button id="btn_add" class="layui-btn layui-btn-warm" type="button" data-permission="customer.add_customer"><i class="layui-icon layui-icon-add-circle"></i>新建</button>
+                                        <label  id="id_customer_name" style="margin-left: 10px;"></label>
+                                        <label  id="id_customer_tel" style="margin-left: 10px;"></label>
+                                        <input id="customer_id" type="hidden" name="customer">
+                                    </div>
+                                    <div style="clear: both;"></div>
+                                </div>
+                            </div>
+                            <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-sm5">
+                                        <input id="id_demand_date" name="demand_date" type="text" class="layui-input"  placeholder="yyyy-MM-dd">
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-col-md12">
+                                <label class="layui-form-label">备注:</label>
+                                <div class="layui-input-block">
+                                    <div class="layui-col-sm12">
+                                        <input id="id_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;<button type="button" id="part-btn-add" class="layui-btn layui-btn-primary layui-btn-sm"><i class="layui-icon"></i></button></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>
+
+  var customer_id=null;
+  var _options = [];
+  layui.link('../../../layuiadmin/style/autocomplete.css');
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index',
+    autocomplete: 'autocomplete'
+  }).use(['index', 'form', 'autocomplete', 'table', 'utils', 'laydate'], function(){
+    var $ = layui.$
+    ,admin = layui.admin
+    ,element = layui.element
+    ,form = layui.form
+    ,table = layui.table
+    ,utils = layui.utils
+    ,autocomplete = layui.autocomplete;
+
+    var laydate = layui.laydate;
+    laydate.render({
+        elem: '#id_demand_date'
+    });
+
+    var id = layui.view.getParameterByName('id');
+
+    admin.req({
+        url: '/foundation/search_options/?type=4',
+        done: function(res){
+            _options = res.data;
+        }
+    });
+
+    autocomplete.render({
+        elem:$('#id_customer'),
+        url:'/customer/customer/select/',
+        template_val:'{{d.name}}-{{d.mobile}}',
+        template_txt:'{{d.name}} <span class=\'layui-badge layui-bg-gray\'>{{d.mobile}}</span>',
+        onselect: function (resp) {
+            fillData(resp);
+        }
+    });
+
+    function fillData(data){
+        $('#id_customer_name').html('姓名:' + data.name);
+        $('#id_customer_tel').html('电话:' + data.mobile);
+        $('#id_demand_date').val(data.demand_date);
+        $('#id_notes').val(data.notes);
+        $('#id_customer').val(data.name + '-' + data.mobile);
+        customer_id = data.id;
+    }
+
+    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: 100,  templet: function (d){
+            return '<input id="count'+d.id+'" type="text" value="'+d.count+'" lay-verify="required|numberGtZ" autocomplete="off" class="layui-input">';
+            }},
+            {field: 'price', title: '单价', width: 100, templet: function (d){
+            return '<input id="price'+d.id+'" type="text"  value="'+d.price+'" lay-verify="required|numberGeZ" autocomplete="off" class="layui-input">';
+            }},
+            {field: 'option_type', title: '质量要求', width: 120, templet: function (d) {
+                    var options = utils.renderSelectOptions(_options, {
+                        valueField: "id",
+                        textField: "name",
+                        selectedValue: d.option_type
+                    });
+                    return '<select id="option_type'+d.id+'" lay-filter="type_select"><option value="">请选择</option>' + options + '</select>';
+                }
+            },
+            {field: 'id', title: '操作',minWidth:120, templet: function(d){
+                return '<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del" lay-id="'+ d.id +'">删除</a>';
+            }}
+        ]],
+    });
+
+    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 option_type = $('#option_type'+rows[k].id).val();
+            var count = $('#count'+rows[k].id).val();
+            var price = $('#price'+rows[k].id).val();
+            var item = {
+                id:rows[k].id,
+                goods:rows[k].id,
+                name:rows[k].name,
+                model:rows[k].model,
+                count:count,
+                price:price,
+                quality_request:option_type
+            };
+            items.push(item);
+        }
+        return items
+    };
+    form.on('submit(component-form-element)', function(data){
+        var items = getItemsData();
+
+
+        if(items.length == 0){
+            layer.msg('请添加产品!', {icon: 5});
+            return false;
+        }
+
+        if (!customer_id){
+            layer.msg('请添加客户!', {icon: 5});
+            return false;
+        }
+
+        var order_data = {'customer': customer_id, 'demand_date': $('#id_demand_date').val(), 'notes': $('#id_notes').val()};
+
+        data.field.order_data = order_data;
+        data.field.items = items;
+        admin.req({
+            url: '/plan/demand/save/?id='+id
+            ,data: JSON.stringify(data.field)
+            ,type: 'post'
+            ,done: function(res){
+                customer_id = null;
+                parent.layui.onSubmitChild();
+            }
+        });
+        return false;
+    });
+
+      $('#part-btn-add').on('click', function () {
+          layer.open({
+              type: 2,
+              title: '添加产品',
+              shadeClose: false,
+              area: ['90%', '98%'],
+              btn: ['保存', '关闭'],
+              yes: function (index, dom) {
+                  layui.onSubmitChild = function (data) {
+                      var oldData = getItemsData();
+                      if (data.length > 0) {
+                          layer.msg('添加成功!', {icon: 6});
+                      } else {
+                        layer.msg('请先选择记录!');
+                    }
+                      for (var i in data) {
+                          var is_exit = false;
+                          for (var m in oldData) {
+                              if (oldData[m].id == data[i].id) {
+                                  is_exit = true;
+                                  break;
+                              }
+                          }
+                          if (is_exit) {
+                              continue;
+                          }
+                          var newRow = {
+                              id: data[i].id,
+                              name: data[i].name,
+                              model: data[i].model,
+                              unit: data[i].unit,
+                              price: data[i].retail_price,
+                              count: 1.00,
+                              warehouse_place: data[i].warehouse_place,
+                              option_type: ''
+                          };
+                          oldData.push(newRow);
+                      }
+                      part_tableIns.reload({
+                          data: oldData
+                      });
+
+                  };
+                  layui.submitChild();
+              },
+              btn2: function (index, layero) {
+                  layer.close(index);
+              },
+              content: '../goods/search_goods_item.html'
+          });
+      });
+
+    $('#btn_add').on('click', function(){
+        layer.open({
+          type: 2,
+          title: '添加客户',
+          shadeClose: false,
+          area: ['95%', '95%'],
+          btn: ['保存', '取消'],
+          yes: function(index, dom){
+              layui.onSubmitChild = function (data) {
+              layer.close(index);
+              fillData(data)
+            };
+            layui.submitChild();
+          },
+          btn2: function(index, layero){
+            layer.close(index);//关闭当前按钮
+          },
+          content:'../customer/customer_edit.html?add=true'
+        });
+    });
+
+    if (id) {
+        admin.req({
+          url: '/plan/demand/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.goods_id,
+                    name: item.name,
+                    model:item.model,
+                    unit:item.unit,
+                    price: item.price,
+                    count: item.count,
+                    warehouse_place: '',
+                    option_type: item.quality_request,
+                    part_data:item
+                }
+                oldData.push(newRow);
+            }
+            part_tableIns.reload({
+                data: oldData
+            });
+
+             var orderData = JSON.parse(JSON.stringify(parent.layui.table.editdata));
+             fillData({
+                 name:orderData.customer_name,
+                 mobile:orderData.customer_tel,
+                 demand_date:orderData.demand_date,
+                 notes:orderData.notes,
+                 id:orderData.customer
+             });
+          }
+        });
+    }
+
+    parent.layui.submitChild = function () {
+      $("#submit_btn").click();
+    };
+
+  });
+  </script>
+</body>
+</html>

+ 131 - 0
uis/views/plan/demand_print.html

@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html style="height: 100%;min-height: 100%;">
+<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-table td{border-color:#000;}
+    </style>
+</head>
+<style>
+      h3, td, th{color: #000000}
+      .layui-table td, .layui-table th {border-color: #000000;height: 1px}
+  </style>
+<body style="background-color: #fff;height: 100%;min-height: 100%;">
+
+  <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">
+
+            <div id="print_div">
+                <h3 align="center" style="font-weight: bold;letter-spacing:8px;"><span id="company"></span></br>销售订单</h3>
+                <table class="layui-table">
+                    <tr>
+                        <td id="no" class="cell">订单号</td>
+                        <td id="customer_name" class="cell">客户姓名</td>
+                        <td id="customer_tel" class="cell">客户电话</td>
+                    </tr>
+                    <tr>
+                        <td id="create_user_text" class="cell">下单人员</td>
+                        <td id="create_time" class="cell">下单时间</td>
+                        <td id="demand_date" class="cell">需求时间</td>
+                    </tr>
+                    <tr>
+                        <td id="notes" class="cell" colspan="3">备注</td>
+                    </tr>                    
+                </table>
+                <table class="layui-table">
+                    <tr>
+                        <td>产品名称</td>
+                        <td>产品代码</td>
+                        <td>质量标准</td>
+                        <td align="right" width="70">单价</td>
+                        <td align="right" width="70">数量</td>
+                        <td align="right" width="70">金额</td>
+                    </tr>
+
+                    <tr id="tr_total">
+                        <td colspan="4" align="right">合计:</td>
+                        <td align="right" id="td_count"></td>
+                        <td align="right" id="td_amount"></td>
+                    </tr>
+                </table>
+                <table class="table-embed" border='0' width='100%' height="50px">
+                    <tr style="height: 80px;">
+                        <td align="center">制单人签字:__________</td>
+                        <td align="center">审核人签字:__________</td>
+                        <td align="center">财务签字:__________</td>
+                        <td align="center">总经理签字:__________</td>
+                    </tr>
+                </table>
+            </div>
+          </div>
+        </div>
+        </div>
+    </div>
+  </div>
+
+  <script src="../../layuiadmin/layui/layui.js?t=1"></script>
+  <script>
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'table'], function(){
+    var $ = layui.$
+    ,admin = layui.admin;
+
+    var data = JSON.parse(JSON.stringify(parent.layui.table.editdata));
+    $('.cell').each(function (index, element) {
+        element.innerHTML += ':' + (data[element.id]||'')
+    });
+
+    admin.req({
+        url: '/plan/demand/detail/?id='+data.id
+        ,done: function(data){
+            var company = data.data.company;
+            var items_data = data.data.items_data;
+            var count = 0
+                ,amount = 0;
+            for(var n in items_data){
+                count += parseFloat(items_data[n].count);
+                amount += parseFloat(items_data[n].amount);
+                $('#tr_total').before("<tr>\n" +
+                    "                        <td>"+items_data[n].name+"</td>\n" +
+                    "                        <td>"+items_data[n].model+"</td>\n" +
+                    "                        <td>"+items_data[n].quality_request_text+"</td>\n" +
+                    "                        <td align=\"right\">"+items_data[n].price+"</td>\n" +
+                    "                        <td align=\"right\">"+items_data[n].count+"</td>\n" +
+                    "                        <td align=\"right\">"+items_data[n].amount+"</td>\n" +
+                    "                    </tr>");
+            }
+            $('#td_count').html(parseFloat(count).toFixed(2));
+            $('#td_amount').html(parseFloat(amount).toFixed(4));
+            $('#company').html(company);
+        }
+    });
+
+      parent.layui.submitChild = function () {
+          window.scrollTo(0,0);
+          doPrint();
+          parent.layui.onSubmitChild();
+      };
+
+      function doPrint() {
+          var $ = layui.$;
+        document.body.innerHTML=$('#print_div').html();
+          window.print();
+      }
+  });
+
+  </script>
+</body>
+</html>
+

+ 199 - 0
uis/views/plan/demand_receive.html

@@ -0,0 +1,199 @@
+<!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">收货备注:</label>
+                                <div class="layui-input-block">
+                                    <div class="layui-col-sm8">
+                                        <input id="id_receive_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_receive_amount').val(data.amount);
+        $('#id_receive_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_receive_amount').val(), 'notes': $('#id_receive_notes').val()};
+
+        data.field.order_data = order_data;
+        data.field.items = items;
+        admin.req({
+            url: '/plan/demand/receive_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: '/plan/demand/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.receive_amount,
+                 notes:orderData.receive_notes
+             });
+          }
+        });
+    }
+
+    parent.layui.submitChild = function () {
+      $("#submit_btn").click();
+    };
+
+  });
+  </script>
+</body>
+</html>

+ 1 - 1
uis/views/plan/production.html

@@ -53,7 +53,7 @@
                                 </dl>
                             </div>
                         </button>
-                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="plan.print_production_plan"><i class="layui-icon layui-icon-form"></i>打印</button>
+                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="plan.print_production_plan"><i class="layui-icon layui-icon-print"></i>打印</button>
                         <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                     </div>
                     <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/plan/sale.html

@@ -38,7 +38,7 @@
                             </div>
                         </button>
 
-                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="plan.print_sale_plan"><i class="layui-icon layui-icon-form"></i>打印</button>
+                        <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="plan.print_sale_plan"><i class="layui-icon layui-icon-print"></i>打印</button>
                         <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                     </div>
                     <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/consumable_godownentry.html

@@ -73,7 +73,7 @@
                     </button>
                     <button class="layui-btn layui-btn-sm" data-permission="purchase.print_consumable_godown_entry"
                             id="btn_print">
-                        <i class="layui-icon layui-icon-form"></i>打印
+                        <i class="layui-icon layui-icon-print"></i>打印
                     </button>
                     <button class="layui-btn layui-btn-sm layui-hide" id="btn_pay"><i
                             class="layui-icon layui-icon-form"></i>付款

+ 1 - 1
uis/views/purchase/consumable_godownentry_query.html

@@ -27,7 +27,7 @@
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission="purchase.export_consumable_godownentry_query"><i class="layui-icon layui-icon-download-circle"></i>导出</button>
 
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_consumable_godownentry_query"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_consumable_godownentry_query"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/consumable_godownentry_return.html

@@ -35,7 +35,7 @@
                             </dl>
                         </div>
                     </button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_consumable_godown_entry_return"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_consumable_godown_entry_return"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/consumable_godownentry_return_query.html

@@ -26,7 +26,7 @@
 
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission="account.export_consumable_godownentry_return_query"><i class="layui-icon layui-icon-download-circle"></i>导出</button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="account.print_consumable_godownentry_return_query"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="account.print_consumable_godownentry_return_query"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/material_godownentry_query.html

@@ -27,7 +27,7 @@
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission="purchase.export_material_godownentry_query"><i class="layui-icon layui-icon-download-circle"></i>导出</button>
 
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_material_godownentry_query"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_material_godownentry_query"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/material_godownentry_return.html

@@ -35,7 +35,7 @@
                             </dl>
                         </div>
                     </button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_material_godown_entry_return"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_material_godown_entry_return"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/material_godownentry_return_query.html

@@ -26,7 +26,7 @@
 
                 <div class="LAY-btns" style="margin-bottom: 10px;">
                     <button class="layui-btn layui-btn-sm" id="btn_export" data-permission="account.export_material_godownentry_return_query"><i class="layui-icon layui-icon-download-circle"></i>导出</button>
-                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="account.print_material_godownentry_return_query"><i class="layui-icon layui-icon-form"></i>打印</button>
+                    <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="account.print_material_godownentry_return_query"><i class="layui-icon layui-icon-print"></i>打印</button>
                     <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                 </div>
                 <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 10 - 11
uis/views/purchase/purchase.html

@@ -26,6 +26,15 @@
 
                     <div class="LAY-btns" style="margin-bottom: 10px;">
                         <button class="layui-btn layui-btn-sm" data-permission="purchase.add_purchase_plan" id="btn_add"><i class="layui-icon layui-icon-add-1"></i>添加</button>
+                        <button class="layui-nav" data-permission="purchase.add_purchase_plan">
+                            <div class="layui-nav-item">
+                                <a href="javascript:;" style="color:#fff;">导入</a>
+                                <dl class="layui-nav-child"> <!-- 二级菜单 -->
+                                    <dd><a href="#" id="btn_import">执行导入</a></dd>
+                                    <dd><a href="#" id="btn_download">下载模板</a></dd>
+                                </dl>
+                            </div>
+                        </button>                        
                         <button class="layui-btn layui-btn-sm" data-permission="purchase.add_purchase_user_plan" id="btn_add_user"><i class="layui-icon layui-icon-add-1"></i>采购员</button>
                         <button class="layui-btn layui-btn-sm" data-permission="purchase.add_purchase_order" id="btn_add_price"><i class="layui-icon layui-icon-add-1"></i>询价汇总</button>
                         <button class="layui-btn layui-btn-sm" data-permission="purchase.edit_purchase_price" id="btn_edit_price"><i class="layui-icon layui-icon-edit"></i>修改询价</button>
@@ -57,18 +66,8 @@
                             </div>
                         </button>
 
-                        <button class="layui-nav" data-permission="purchase.add_purchase_plan">
-                            <div class="layui-nav-item">
-                                <a href="javascript:;" style="color:#fff;">导入</a>
-                                <dl class="layui-nav-child"> <!-- 二级菜单 -->
-                                    <dd><a href="#" id="btn_import">执行导入</a></dd>
-                                    <dd><a href="#" id="btn_download">下载模板</a></dd>
-                                </dl>
-                            </div>
-                        </button>
-
                         <button class="layui-btn layui-btn-sm" data-permission="purchase.export_purchase_plan_price" id="btn_export_price"><i class="layui-icon layui-icon-form"></i>导出询价汇总</button>
-                        <button class="layui-btn layui-btn-sm" data-permission="purchase.print_purchase_plan" id="btn_print"><i class="layui-icon layui-icon-form"></i>打印</button>
+                        <button class="layui-btn layui-btn-sm" data-permission="purchase.print_purchase_plan" id="btn_print"><i class="layui-icon layui-icon-print"></i>打印</button>
                         <button class="layui-btn layui-btn-sm" data-permission="purchase.view_purchase_plan" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                     </div>
                     <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>

+ 1 - 1
uis/views/purchase/purchase_order.html

@@ -45,7 +45,7 @@
               </button>
 
               <button class="layui-btn layui-btn-sm" id="btn_entry" data-permission="purchase.add_material_godown_entry|purchase.add_consumable_godown_entry"><i class="layui-icon layui-icon-form"></i>到货</button>
-              <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_purchase_order"><i class="layui-icon layui-icon-form"></i>打印</button>
+              <button class="layui-btn layui-btn-sm" id="btn_print" data-permission="purchase.print_purchase_order"><i class="layui-icon layui-icon-print"></i>打印</button>
               <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
             </div>
 

+ 1 - 1
uis/views/purchase/purchase_payment.html

@@ -38,7 +38,7 @@
                             </div>
                           </button>
 
-                        <button class="layui-btn layui-btn-sm" data-permission="purchase.print_purchase_payment" id="btn_print"><i class="layui-icon layui-icon-form"></i>打印</button>
+                        <button class="layui-btn layui-btn-sm" data-permission="purchase.print_purchase_payment" id="btn_print"><i class="layui-icon layui-icon-print"></i>打印</button>
                         <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
                     </div>
                     <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>