#coding=utf-8 import traceback import json from collections import OrderedDict from django.db import transaction,IntegrityError from django.db.models import F,ProtectedError from django.shortcuts import get_object_or_404 from django.views.decorators.csrf import csrf_exempt from django.contrib.auth.models import Permission, Group from django.utils import timezone from libs import utils from libs.utils import dump_form_errors from libs.http import JSONError, JSONResponse,DataGridJSONResponse from apps.dashboard.forms import MyAuthenticationForm from decorators import token_required,permission_required from apps.exceptions import CustomError from apps.foundation.models import BizLog from models import User, Department,SubDepartment,SubEmployee from serializers import EmployeeSerializer, EmployeeSafeSerializer, GroupSerializer,GroupComboboxSerializer from django.db.models import Q from django.conf import settings from apps.goods.models import GoodsGodownEntry from apps.material.models import Deliver from apps.order.models import SaleOrder, GoodsDeliver from apps.plan.models import SalePlan, ProductionPlan from apps.purchase.models import PurchasePlan, PurchaseOrder, GodownEntry, GodownEntryReturn from apps.warehouse.models import Warehouse, Inventory from apps.office.models import Notice,NoticeBrowseRecord @csrf_exempt def login(request): form = MyAuthenticationForm(data=request.POST, request=request) if form.is_valid(): user = form.get_user() if user.status == User.DIMISSION: BizLog.objects.addnew(user, BizLog.INSERT, u"离职账号[%s]登录,IP[%s]" % ( user.username, request.META['REMOTE_ADDR'] )) return JSONError(u'离职账号禁止登录') permissions = list(user.get_all_permissions()) BizLog.objects.addnew(user, BizLog.INSERT, u"[%s]登录,IP[%s]" % ( user.username, request.META['REMOTE_ADDR'] )) return JSONResponse({ 'user_id':user.id, 'access_token':form.access_token, 'name':user.name, 'permissions':permissions }) else: BizLog.objects.addnew(None, BizLog.INSERT, u"[%s]登录失败,密码[%s],IP[%s]" % ( request.POST['username'], request.POST['password'], request.META['REMOTE_ADDR'] )) return JSONError(dump_form_errors(form)) @permission_required('foundation.view_group') def group_list(request): rows = Group.objects.filter() rows, total = utils.get_page_data(request, rows) serializer = GroupSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total) @token_required def group_combobox_list(request): rows = Group.objects.filter() total = rows.count() #rows, total = utils.get_page_data(request, rows) serializer = GroupComboboxSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total) @csrf_exempt @permission_required('foundation.add_group') def group_save(request): id = request.GET.get('id') data = json.loads(request.body) try: with transaction.atomic(): User.objects.save_group(id, data['name'], data['permissions'], request.user) except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'保存失败') return JSONResponse() @csrf_exempt @permission_required('foundation.delete_group') def group_delete(request): id = request.GET.get('id') try: with transaction.atomic(): group = Group.objects.filter(pk=id).first() if not group: raise CustomError(u'未找到相应的权限组') BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除权限组[%s],id=%s" % (group.name, id)) group.delete() except CustomError, e: return JSONError(e.get_error_msg()) except ProtectedError: return JSONError(u'该权限组已分配给用户,禁止删除!') except IntegrityError: return JSONError(u'该权限组已分配给用户,禁止删除!') except: traceback.print_exc() return JSONError(u'删除失败') return JSONResponse() @token_required def permission_all(request): rows = Permission.objects.all().exclude(name__startswith='Can') rows = User.objects.sort_perms(rows) menus = OrderedDict() for row in rows: item = {'id': row.id, 'name': row.name} mn = User.objects.get_menuname_of_contenttype(row.content_type.app_label, row.content_type.model) if menus.has_key(mn): permissions = menus[mn] else: permissions = menus[mn] = OrderedDict() if permissions.has_key(row.content_type.name): if not item in permissions[row.content_type.name]: permissions[row.content_type.name].append(item) else: permissions[row.content_type.name] = [item, ] return JSONResponse(menus) @permission_required('account.view_user') def employee_list(request): username = request.GET.get('username') name = request.GET.get('name') rows = User.objects.filter() if username: rows = rows.filter(username__icontains=username) if name: rows = rows.filter(name__icontains=name) rows, total = utils.get_page_data(request, rows) serializer = EmployeeSafeSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total) @csrf_exempt @permission_required('account.add_user') def employee_save(request): id = request.GET.get('id') data = json.loads(request.body) try: with transaction.atomic(): serializer = EmployeeSerializer.factory(request.user, data, id) if serializer.instance: user = serializer.instance if not data['password']: data['password'] = user.password else: user.set_password(data['password']) data['password'] = user.password serializer.validSave() except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'保存失败') return JSONResponse() @csrf_exempt @token_required def employee_tree(request): def child_employee_tree(department_id,children): rows = User.objects.filter(department_id=department_id) for row in rows: item = { 'id': row.id, 'value': 'employee_' + str(row.id), 'name': row.name } children.append(item) def child_department_tree(parent_id,children): rows = Department.objects.filter(parent_id=parent_id) for row in rows: item = { 'id': row.id, 'value': 'department_' + str(row.id), 'name': row.name, 'children': [] } child_employee_tree(row.id,item['children']) child_department_tree(row.id,item['children']) children.append(item) result = [] child_department_tree(None,result) return JSONResponse(result) @csrf_exempt @permission_required('account.add_user') def manager_save(request): id = request.GET.get('id') data = json.loads(request.body) try: with transaction.atomic(): user = User.getById(id) user.removeSubs() for row in data['managers']: sub_arr = row.split('_') if sub_arr[0] == 'department': SubDepartment.objects.create(user=user,department_id=int(sub_arr[1])) elif sub_arr[0] == 'employee': SubEmployee.objects.create(user=user,employee_id=int(sub_arr[1])) BizLog.objects.addnew(request.user, BizLog.UPDATE, u"修改员工管理范围[%s],id=%s" % (user.name, user.id),data) return JSONResponse({}) except CustomError, e: return JSONError(e.get_error_msg()) except Exception,e: traceback.print_exc() return JSONError(u'保存失败') @csrf_exempt @permission_required('account.delete_user') def employee_delete(request): id = request.GET.get('id') try: with transaction.atomic(): user = User.getById(id) BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除员工[%s],id=%d" % (user.name, user.id)) user.removeSubs() user.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({}) @token_required def employee_combobox_list(request): rows = User.objects.filter(status=User.INSERVICE) total = rows.count() #rows, total = utils.get_page_data(request, rows) serializer = EmployeeSafeSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total) @token_required def employee_list_mobile(request): id = request.GET.get('id') user = User.objects.filter(id=id).first() data = { 'name': user.name, 'tel': user.tel, 'department_name': user.department.name } return JSONResponse(data) @csrf_exempt @token_required def password_save(request): data = json.loads(request.body) try: data['new_password'] = data['new_password'].strip(u' ') data['confirm_password'] = data['confirm_password'].strip(u' ') data['old_password'] = data['old_password'].strip(u' ') if data['new_password'] != data['confirm_password']: raise CustomError(u'两次输入的密码不一致, 请检查') with transaction.atomic(): if not request.user.check_password(data['old_password']): raise CustomError(u'原密码输入错误, 请检查') request.user.set_password(data['new_password']) request.user.save() except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'保存失败!') return JSONResponse() @permission_required('account.view_department') def department_list(request): result = [] rows = Department.objects.filter() for row in rows: isCompany = False if row.id == row.company_id: isCompany = True item = { 'id': row.id, 'company': row.company_id, 'product_range': row.product_range, 'product_range_text': row.product_range and Department.PRODUCT_RANGE_CHOICES[row.product_range - 1][1] or '', 'name': row.name, 'notes': row.notes, 'isCompany': isCompany, 'parent_id': row.parent_id or 0, } result.append(item) return JSONResponse(result) @csrf_exempt @permission_required('account.add_department') def department_save(request): id = request.GET.get('id') parent_id = request.GET.get('parent_id') data = json.loads(request.body) try: with transaction.atomic(): if id: department = Department.getById(id) department.name = data['name'] department.notes = data['notes'] department.save() BizLog.objects.addnew(request.user, BizLog.UPDATE, u"修改部门[%s],id=%d" % (data['name'], department.id)) else: if parent_id: parent = Department.getById(parent_id) company_id = parent.company_id parent_id = parent.id else: parent = None parent_id = None company_id = None lft = Department.getLft(parent) Department.objects.filter(rgt__gt=lft).update(rgt=F('rgt') + 2) Department.objects.filter(lft__gt=lft).update(lft=F('lft') + 2) department = Department.objects.create( name=data['name'], notes=data['notes'], parent_id=parent_id, company_id=company_id, lft=lft+1, rgt=lft+2 ) if department.company_id == None: department.company_id = department.id department.save() BizLog.objects.addnew(request.user, BizLog.INSERT, u"添加部门[%s],id=%d" % (data['name'], department.id)) if department.id == department.company_id and data['product_range']: department.product_range = int(data['product_range']) department.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('account.delete_department') def department_delete(request): id = request.GET.get('id') try: with transaction.atomic(): if Department.objects.filter(parent_id=id).count() > 0: raise CustomError(u'该部门存在子部门, 不允许删除') dep = Department.getById(id) lft = dep.lft rgt = dep.rgt total = rgt - lft + 1 BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除部门[%s],id=%d" % (dep.name, dep.id)) dep.delete() Department.objects.filter(rgt__gt=lft).update(rgt=F('rgt')-total) Department.objects.filter(lft__gt=lft).update(lft=F('lft')-total) 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 @token_required def department_tree(request): def child_department_tree(parent_id,children): rows = Department.objects.filter(parent_id=parent_id) for row in rows: item = { 'id': row.id, 'value': row.id, 'name': row.name, 'notes': row.notes, 'parent_id': row.parent_id, 'children': [] } child_department_tree(row.id,item['children']) children.append(item) result = [] child_department_tree(None,result) return JSONResponse(result) @csrf_exempt @token_required def select_department(request): result = [] rows = Department.objects.filter() for row in rows: item = { 'id': row.id, 'name': row.name } result.append(item) return JSONResponse(result) @token_required def home_count(request): department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() warehouses_ids = Warehouse.getManagerWarehouses(request.user) sale_plan_count = SalePlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() sale_order_count = SaleOrder.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() production_count = ProductionPlan.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() purchase_count = PurchasePlan.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() purchase_order_count = PurchaseOrder.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() material_godownentry_count = GodownEntry.objects.filter(product_type=GodownEntry.MATERIAL,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() material_deliver_count = Deliver.objects.filter(product_type=GodownEntry.MATERIAL,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() material_godownentry_return_count = GodownEntryReturn.objects.filter(type=GodownEntryReturn.MATERIAL, warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() material_inventory_count = Inventory.objects.filter(product_type=Inventory.MATERIAL,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(check_status=settings.DEFAULT).count() consumable_godownentry_count = GodownEntry.objects.filter(product_type=GodownEntry.CONSUMABLE,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() consumable_deliver_count = Deliver.objects.filter(product_type=GodownEntry.CONSUMABLE,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() consumable_godownentry_return_count = GodownEntryReturn.objects.filter(type=GodownEntryReturn.CONSUMABLE, warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() consumable_inventory_count = Inventory.objects.filter(product_type=Inventory.CONSUMABLE,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(check_status=settings.DEFAULT).count() goods_godownentry_count = GoodsGodownEntry.objects.filter(warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() goods_deliver_count = GoodsDeliver.objects.filter(warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(status=settings.DEFAULT).count() goods_inventory_count = Inventory.objects.filter(product_type=Inventory.GOODS,warehouse_id__in=warehouses_ids).filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)).filter(check_status=settings.DEFAULT).count() children = request.user.getSubDepartmentIds() children.append(request.user.department.id) rows = Notice.objects.filter(dendline__gte=timezone.now(), department__in=children) browsed_ids = NoticeBrowseRecord.objects.filter(browse_user_id=request.user).values_list('notice_id', flat=True) not_notices = rows.filter(~Q(id__in=browsed_ids)) data = { 'notice_unread': not_notices.count(), 'sale_plan_count': sale_plan_count, 'sale_order_count': sale_order_count, 'production_count': production_count, 'purchase_count': purchase_count, 'purchase_order_count': purchase_order_count, 'material_godownentry_count': material_godownentry_count, 'material_deliver_count': material_deliver_count, 'material_godownentry_return_count': material_godownentry_return_count, 'material_inventory_count': material_inventory_count, 'consumable_godownentry_count': consumable_godownentry_count, 'consumable_deliver_count': consumable_deliver_count, 'consumable_godownentry_return_count': consumable_godownentry_return_count, 'consumable_inventory_count': consumable_inventory_count, 'goods_godownentry_count': goods_godownentry_count, 'goods_deliver_count': goods_deliver_count, 'goods_inventory_count': goods_inventory_count, } return JSONResponse(data)