|
@@ -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):
|