# coding=utf-8 import traceback import json from _mysql_exceptions import IntegrityError from django.db.models import ProtectedError, Q, Sum from django.utils import timezone from django.views.decorators.csrf import csrf_exempt from django.db import transaction, IntegrityError from apps.account.decorators import token_required, permission_required 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.plan.serializers import ProductionPlanSerializer, ProductionPlanDetailSerializer, SalePlanSerializer, \ SalePlanDetailSerializer from libs.http import JSONResponse, JSONError, DataGridJSONResponse from libs import utils from apps.exceptions import CustomError, ExportChange from django.conf import settings @csrf_exempt @permission_required('plan.view_production_plan') def production_list(request): department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = ProductionPlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user)) f = ProductionPlanFilter(request.GET, queryset=rows) total_row = f.qs.aggregate(total_count=Sum('total_count')) more = { 'total_count': Formater.formatCountShow(total_row['total_count']) } rows, total = utils.get_page_data(request, f.qs) serializer = ProductionPlanSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total, more) @csrf_exempt @permission_required('plan.export_production_plan') def production_export(request): id = request.GET.get('id') if id: production = ProductionPlan.getById(id) goods_rows = ProductionPlanDetail.objects.filter(production__id=production.id) serializer = ProductionPlanDetailSerializer(goods_rows, many=True) export_data = ExportChange.dict_to_obj(serializer) export_data = ProductionPlanDetailResource().export(export_data) filename = utils.attachment_save(export_data) BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产计划明细") return JSONResponse({'filename': filename}) department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = ProductionPlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user)) f = ProductionPlanFilter(request.GET, queryset=rows) serializer = ProductionPlanSerializer(f.qs, many=True) export_data = ExportChange.dict_to_obj(serializer) export_data = ProductionPlanResource().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('plan.add_production_plan') def production_save(request): id = request.GET.get('id') goods_data = json.loads(request.POST.get('items')) production_data = json.loads(request.POST.get('production')) try: with transaction.atomic(): pb = ProductionPlanSerializer.factory(request.user, production_data, id) if pb.instance and pb.instance.status == settings.PASS: raise CustomError(u'审核通过,禁止修改') pb = pb.validSave() ProductionPlanDetail.objects.filter(production=pb).delete() for good_data in goods_data: good_data['production'] = pb.id good_data['product'] = good_data['id'] if 'product_time' in good_data and not good_data['product_time']: good_data['product_time'] = None production = ProductionPlanDetailSerializer.factory(request.user, data=good_data) production.validSave() pb.updateTotalCount() 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.check_production_plan') def production_check(request): id = request.GET.get('id') c_type = request.GET.get('c_type') status = int(request.GET.get('status')) try: with transaction.atomic(): production = ProductionPlan.getById(id) if c_type == 'check': # 审核 if status == settings.PASS: if production.status == settings.CHECKING: raise CustomError(u'该生产计划已审核') production.status = settings.CHECKING production.check_user = request.user production.check_time = timezone.now() BizLog.objects.addnew( request.user, BizLog.CHECK, u"审核生产计划[%s],id=%d" % (production.name, production.id), ) else: if production.status == settings.DEFAULT: raise CustomError(u'该生产计划未审核') if production.check_user2: raise CustomError(u'该生产计划已复核') production.status = settings.DEFAULT production.check_user = None production.check_time = None BizLog.objects.addnew( request.user, BizLog.CHECK, u"取消审核生产计划[%s],id=%d" % (production.name, production.id), ) elif c_type == 'check2': #复核 if status == settings.PASS: if production.status == settings.DEFAULT: raise CustomError(u'该生产计划未审核') if production.check_user3: raise CustomError(u'该生产计划已批准') production.check_user2 = request.user production.check_time2 = timezone.now() BizLog.objects.addnew( request.user, BizLog.CHECK, u"复核生产计划[%s],id=%d" % (production.name, production.id), ) else: if not production.check_user2: raise CustomError(u'该生产计划未复核') if production.check_user3: raise CustomError(u'该生产计划已批准') production.check_user2 = None production.check_time2 = None BizLog.objects.addnew( request.user, BizLog.CHECK, u"取消复核生产计划[%s],id=%d" % (production.name, production.id), ) elif c_type == 'check3': #批准 if status == settings.PASS: if not production.check_user2: raise CustomError(u'该生产计划未复核') if production.check_user3: raise CustomError(u'该生产计划已批准') production.status = status production.check_user3 = request.user production.check_time3 = timezone.now() BizLog.objects.addnew( request.user, BizLog.CHECK, u"批准生产计划[%s],id=%d" % (production.name, production.id), ) else: if not production.check_user3: raise CustomError(u'该生产计划未批准') production.status = settings.CHECKING production.check_user3 = None production.check_time3 = None BizLog.objects.addnew( request.user, BizLog.CHECK, u"撤消批准生产计划[%s],id=%d" % (production.name, production.id), ) production.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('plan.delete_production_plan') def production_delete(request): id = int(request.GET.get('id')) try: with transaction.atomic(): production = ProductionPlan.getById(id) if production.status == settings.PASS: raise CustomError(u'该生产计划已审核,禁止删除') BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除生产计划[%s],id=%d" % (production.name, production.id)) ProductionPlanDetail.objects.filter(production__id=production.id).delete() production.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('plan.view_production_plan') def production_detail(request): id = request.GET.get('id') production = ProductionPlan.getById(id) company = production.department.getCompany() goods_rows = ProductionPlanDetail.objects.filter(production__id=production.id) data = { 'production': [], 'goods_items': [] } if production.status == settings.PASS: status_text = u'已审核' else: status_text = u'待审核' production_item = { 'id': production.id, 'name': production.name, 'company': company.name, 'no': production.no, 'total_count': Formater.formatCountShow(production.total_count), 'status': production.status, 'status_text': status_text, 'notes': production.notes, 'create_user': production.create_user.name, 'check_user': production.check_user and production.check_user.name or '', 'check_time': Formater.formatStrTime(production.check_time), 'check_user2': production.check_user2 and production.check_user2.name or '', 'check_time2': Formater.formatStrTime(production.check_time2), 'check_user3': production.check_user3 and production.check_user3.name or '', 'check_time3': Formater.formatStrTime(production.check_time3), 'create_time': Formater.formatStrTime(production.create_time), } data['production'].append(production_item) for row in goods_rows: item = { 'id': row.id, 'goods_id': row.product.id, 'name': row.product.product_base.name, 'model': row.product.product_base.model, 'unit': row.product.product_base.unit, 'quality_request_id': row.quality_request and row.quality_request.id, 'quality_request_text': row.quality_request and row.quality_request.name or '', 'count': Formater.formatCountShow(row.count), 'product_user_id': row.product_user and row.product_user.id, 'product_user_text': row.product_user and row.product_user.name or '', 'p_department_id': row.p_department and row.p_department.id, 'p_department_text': row.p_department and row.p_department.name or '', 'product_time': Formater.formatStrDate(row.product_time), 'notes': row.notes or '' } data['goods_items'].append(item) return JSONResponse(data) @csrf_exempt @token_required def plan_options(request): departments = Department.objects.filter().values('id', 'name') users = User.objects.filter(status=User.INSERVICE).values('id', 'name', 'department__name') data = { 'users': [], 'departments': [], } for row in users: data['users'].append( {'id':row['id'], 'name':row['name'], 'department_name':row['department__name']} ) for row in departments: data['departments'].append( {'id':row['id'], 'name':row['name']} ) return JSONResponse(data) @csrf_exempt @permission_required('plan.view_sale_plan') def sale_list(request): department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = SalePlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user)) f = SalePlanFilter(request.GET, queryset=rows) total_row = f.qs.aggregate(total_count=Sum('total_count'), total_amount=Sum('total_amount')) more = { 'total_count' : Formater.formatCountShow(total_row['total_count']), 'total_amount' : Formater.formatAmountShow(total_row['total_amount']) } rows, total = utils.get_page_data(request, f.qs) serializer = SalePlanSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total, more) @csrf_exempt @permission_required('plan.add_sale_plan') def sale_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': goods_data = json.loads(request.body)['item'] sale_data = json.loads(request.body)['main'] detail_id = json.loads(request.body)['detail'] else: goods_data = json.loads(request.POST.get('goods')) sale_data = json.loads(request.POST.get('sale')) try: with transaction.atomic(): serializer = SalePlanSerializer.factory(request.user, sale_data, id) if serializer.instance and serializer.instance.status == settings.PASS: raise CustomError(u'该销售计划已审核,禁止修改!') serializer = serializer.validSave() if source == 'touch' and detail_id >= 0: # 手机端保存,如果是修改,先删除要修改的明细 SalePlanDetail.objects.filter(id=int(detail_id)).delete() for item in goods_data: amount = Formater.formatPrice(item['price'])*Formater.formatCount(item['require_count']) if item['price'] else 0 require_time = item['require_time'] and item['require_time'].split('T')[0] or None instance = SalePlanDetail.objects.create( main_id=id, goods_id=item['goods'], quality_request_id=item['quality_request'], require_count=Formater.formatCount(item['require_count']), require_time=require_time, amount=amount, price=Formater.formatPrice(item['price'] or 0), ) BizLog.objects.addnew( request.user, BizLog.INSERT, u"添加销售计划明细[%s],id=%d" % (instance.goods, instance.id), item ) else: SalePlanDetail.objects.filter(main=serializer).delete() for good_data in goods_data: good_data['main'] = serializer.id if 'require_time' in good_data and not good_data['require_time']: good_data['require_time'] = None detail_serializer = SalePlanDetailSerializer.factory(request.user, data=good_data) detail_serializer.validSave() serializer.update_total() except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'保存失败!') return JSONResponse(serializer.id) @csrf_exempt @permission_required('plan.delete_sale_plan') def sale_delete(request): id = int(request.GET.get('id')) try: with transaction.atomic(): sale_plan = SalePlan.getById(id) if sale_plan.status == settings.PASS: raise CustomError(u'该销售计划已审核,禁止删除!') BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id)) SalePlanDetail.objects.filter(main=sale_plan).delete() sale_plan.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('plan.view_sale_plan') def sale_detail(request): id = request.GET.get('id') sale_plan = SalePlan.getById(id) if sale_plan.status == settings.PASS: check_status = u'已审核' else: check_status = u'待审核' company = sale_plan.department.getCompany() sale_data = { 'id': sale_plan.id, 'no': sale_plan.no, 'company': company.name, 'total_count': Formater.formatCountShow(sale_plan.total_count), 'total_amount': Formater.formatAmountShow(sale_plan.total_amount), 'name': sale_plan.customer.name, 'mobile': sale_plan.customer.mobile, 'customer_id': sale_plan.customer.id, 'company_name': sale_plan.customer.company_name or '', 'credit_code': sale_plan.customer.credit_code or '', 'company_tel': sale_plan.customer.company_tel or '', 'address': sale_plan.customer.address or '', 'status': check_status, 'status_id': sale_plan.status, 'check_user': sale_plan.check_user and sale_plan.check_user.name or '', 'create_user': sale_plan.create_user and sale_plan.create_user.name or '', 'check_time':sale_plan.check_time and Formater.formatStrTime(sale_plan.check_time) or '', 'create_time': Formater.formatStrTime(sale_plan.create_time), 'notes': sale_plan.notes or '', } data = { 'goods_items': [], 'sale_data': sale_data } is_toproduction = False goods_rows = SalePlanDetail.objects.filter(main=sale_plan) for row in goods_rows: require_product_count = 0 if row.require_count > row.goods.product_base.stock_count: require_product_count = row.require_count-row.goods.product_base.stock_count is_toproduction = True item = { 'detail_id': row.id, 'id': row.id, 'goods_id': row.goods.id, 'name': row.goods.product_base.name, 'model': row.goods.product_base.model, 'unit': row.goods.product_base.unit, 'quality_request': row.quality_request and row.quality_request.id or None, 'quality_request_text':row.quality_request and row.quality_request.name or '', 'require_count': Formater.formatCountShow(row.require_count), 'price': Formater.formatEmptyPriceShow(row.price), 'require_time': Formater.formatStrDate(row.require_time), 'current_stock_count': Formater.formatCountShow(row.goods.product_base.stock_count), 'require_product_count': Formater.formatCountShow(require_product_count), } data['goods_items'].append(item) data['sale_data']['is_toproduction'] = is_toproduction return JSONResponse(data) @csrf_exempt @permission_required('plan.check_sale_plan') def sale_check(request): id = request.GET.get('id') status = int(request.GET.get('status')) try: with transaction.atomic(): sale_plan = SalePlan.getById(id) if status == settings.PASS: if sale_plan.status == settings.PASS: raise CustomError(u'该销售计划已审核') sale_plan.status = status sale_plan.check_user = request.user sale_plan.check_time = timezone.now() BizLog.objects.addnew( request.user, BizLog.CHECK, u"审核销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id), ) else: if sale_plan.status == settings.DEFAULT: raise CustomError(u'该销售计划未审核') sale_plan.status = status sale_plan.check_user = None sale_plan.check_time = None BizLog.objects.addnew( request.user, BizLog.CHECK, u"取消审核销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id), ) sale_plan.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('plan.export_sale_plan') def sale_export_detail(request): id = request.GET.get('id') sale_plan = SalePlan.getById(id) sale_plan_detail = SalePlanDetail.objects.filter(main=sale_plan) serializer = SalePlanDetailSerializer(sale_plan_detail, many=True) export_data = ExportChange.dict_to_obj(serializer) export_data = SalePlanDetailResource().export(export_data) filename = utils.attachment_save(export_data) BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售计划[%s]明细" % (serializer.no)) return JSONResponse({'filename': filename}) @csrf_exempt @permission_required('plan.export_sale_plan') def sale_export(request): department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = SalePlan.objects.filter( Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user)) f = SalePlanFilter(request.GET, queryset=rows) serializer = SalePlanSerializer(f.qs, many=True) export_data = ExportChange.dict_to_obj(serializer) export_data = SalePlanResource().export(export_data) filename = utils.attachment_save(export_data) BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售计划") return JSONResponse({'filename': filename})