def protoGetUserRights(request): """ return usr rights """ if request.method != 'POST': return JsonError( 'invalid message' ) userName = request.POST['login'] userPwd = request.POST['password'] errMsg = '' success = False language = None try: pUser = authenticate(username = userName, password = userPwd ) except: pUser = None userInfo = { 'userName' : userName } if pUser is not None: if pUser.is_active: login(request, pUser) success = True userInfo[ 'isStaff' ] = pUser.is_staff userInfo[ 'isSuperUser' ] = pUser.is_superuser userInfo[ 'fullName' ] = pUser.get_full_name() # Si es login retorna la lengua del usuario language = getUserProfile( pUser, 'login', userName ) else: # Return a 'disabled account' error message errMsg = "Cet utilisateur est desactivé" else: # Return an 'invalid login' error message. errMsg = "Mauvais utilisateur ou mot de passe" jsondict = { 'success': success, 'message': errMsg, 'userInfo' : userInfo, 'language' : language } # Encode json context = json.dumps( jsondict) return HttpResponse(context, mimetype="application/json")
def protoGetUserRights(request): """ return usr rights """ if request.method != 'POST': return JsonError('invalid message') userName = request.POST['login'] userPwd = request.POST['password'] errMsg = '' success = False language = None try: pUser = authenticate(username=userName, password=userPwd) except: pUser = None userInfo = {'userName': userName} if pUser is not None: if pUser.is_active: login(request, pUser) success = True userInfo['isStaff'] = pUser.is_staff userInfo['isSuperUser'] = pUser.is_superuser userInfo['fullName'] = pUser.get_full_name() # Si es login retorna la lengua del usuario language = getUserProfile(pUser, 'login', userName) else: # Return a 'disabled account' error message errMsg = "Cet utilisateur est desactivé" else: # Return an 'invalid login' error message. errMsg = "Mauvais utilisateur ou mot de passe" jsondict = { 'success': success, 'message': errMsg, 'userInfo': userInfo, 'language': language } # Encode json context = json.dumps(jsondict) return HttpResponse(context, content_type="application/json")
def doWfAction(model, selectedKeys, parameters, actionDef, viewEntity, pUser): userProfile = getUserProfile(pUser, 'wflow', viewEntity) try: changeSt = actionDef.get('change', []) stInitial = changeSt[0] stFinal = changeSt[1] Qs = model.objects.filter(pk__in=selectedKeys) Qs = Qs.filter(smWflowStatus=stInitial) # TODO transaction??? if actionDef.get('notifyOwner', False) : for wfRow in Qs : if len (parameters) > 0: strMsg = parameters[0].get('value') else : strMsg = actionDef.get('message', '') UserReponse = WflowUserReponse() UserReponse.viewEntity = viewEntity UserReponse.strKey = wfRow.__str__() UserReponse.wfAction = actionDef.get('name') UserReponse.adminMsg = strMsg try: setattr(UserReponse, 'smOwningUser', wfRow.smOwningUser ) setattr(UserReponse, 'smOwningTeam', wfRow.smOwningTeam ) setattr(UserReponse, 'smCreatedBy', userProfile.user) setattr(UserReponse, 'smRegStatus', '0') setattr(UserReponse, 'smCreatedOn', datetime.now()) except : pass UserReponse.save() if actionDef.get('setOwner', False) : Qs.update(smWflowStatus=stFinal, smOwningTeam=userProfile.userTeam) else : Qs.update(smWflowStatus=stFinal) return doReturn ({'success':True, 'message' : 'WfAction Ok'}) except Exception as e: return doReturn ({'success':False, 'message' : str(e) })
def doWfAction(model, selectedKeys, parameters, actionDef, viewEntity, pUser): userProfile = getUserProfile(pUser, 'wflow', viewEntity) try: changeSt = actionDef.get('change', []) stInitial = changeSt[0] stFinal = changeSt[1] Qs = model.objects.filter(pk__in=selectedKeys) Qs = Qs.filter(smWflowStatus=stInitial) # TODO transaction??? if actionDef.get('notifyOwner', False): for wfRow in Qs: if len(parameters) > 0: strMsg = parameters[0].get('value') else: strMsg = actionDef.get('message', '') UserReponse = WflowUserReponse() UserReponse.viewEntity = viewEntity UserReponse.strKey = wfRow.__str__() UserReponse.wfAction = actionDef.get('name') UserReponse.adminMsg = strMsg try: setattr(UserReponse, 'smOwningUser', wfRow.smOwningUser) setattr(UserReponse, 'smOwningTeam', wfRow.smOwningTeam) setattr(UserReponse, 'smCreatedBy', userProfile.user) setattr(UserReponse, 'smRegStatus', '0') setattr(UserReponse, 'smCreatedOn', datetime.now()) except: pass UserReponse.save() if actionDef.get('emailNotification', False): user = User.objects.get( username=wfRow.smOwningUser.username) if user.email: try: subject = actionDef.get('emailSubject', '') message = actionDef.get('emailTemplate', '') variableFormat = { 'sk': wfRow.__str__(), 'concept': viewEntity, 'admmessage': strMsg, 'admin': userProfile.user.username.title(), 'date': strftime('%d/%m/%Y', wfRow.smCreatedOn.timetuple()), 'User': wfRow.smOwningUser.username.title() } message = message.format(**variableFormat) user.email_user(subject, message) except: pass if actionDef.get('setOwner', False): Qs.update(smWflowStatus=stFinal, smOwningTeam=userProfile.userTeam) else: Qs.update(smWflowStatus=stFinal) return doReturn({'success': True, 'message': 'WfAction Ok'}) except Exception as e: return doReturn({'success': False, 'message': str(e)})
def protoGetPCI(request): """ return full metadata (columns, renderers, totalcount...) """ if not request.user.is_authenticated(): return JsonError('readOnly User') if request.method != 'POST': return JsonError('invalid message') viewCode = request.POST.get('viewCode', '') viewEntity = getBaseModelName(viewCode) try: model = getDjangoModel(viewEntity) except : return JsonError('model not found: {0}'.format( viewEntity)) # userProfile = getUserProfile(request.user, 'getPci', viewEntity) # PROTOTIPOS isPrototype = False if viewCode.startswith(PROTO_PREFIX) and viewCode != viewEntity : try: prototypeView = viewCode.replace(PROTO_PREFIX, '') protoDef = Prototype.objects.get(code=prototypeView, smOwningTeam=userProfile.userTeam) created = False isPrototype = True except: return JsonError('prototype not found: {0}'.format( viewCode )) else: # protoDef : PCI leida de la DB ; created : El objeto es nuevo protoDef, created = ProtoDefinition.objects.get_or_create(code=viewCode) if ( not isPrototype ) : # if ( not protoDef.active) : # return JsonError('Inactive definition : {0}'.format( viewCode )) if protoDef.overWrite : # Si la directiva es reescribirlo es como si fuera nuevo cada vez created = True # Si es nuevo lee Django if created : model_admin, protoMeta = getProtoAdmin(model) # Genera la definicion de la vista grid = protoGrid.ProtoGridFactory(model, viewCode, model_admin, protoMeta) if not createProtoMeta(model, grid, viewEntity, viewCode) : return JsonError('Document type required: {0}.???'.format( viewCode )) # Guarda o refresca la Meta y mantiene la directiva overWrite protoDef.metaDefinition = json.dumps(grid.protoMeta) protoDef.description = protoMeta['description'] protoDef.save() else: protoMeta = json.loads(protoDef.metaDefinition) protoMeta['viewCode'] = viewCode # La definicion del arbol es fija, pues las cols deben ser siempre uniformes sin importar el tipo de modelo. # pStyle = protoMeta.get( 'pciStyle', '') # if pStyle == 'tree': setTreeDefinition() customCode = '_custom.' + viewCode try: custom = CustomDefinition.objects.get(code=customCode, smOwningTeam=userProfile.userTeam) custom = json.loads(custom.metaDefinition) protoMeta['custom'] = custom['custom'] except: pass # TODO: Verificacion de la metadata # try: # protoMeta = verifyMeta(protoMeta, 'pcl') # except Exception, e: # traceback.print_exc() # message = getReadableError(e) # WorkFlow if hasattr(model , '_WorkFlow') : wflowControl = getattr(model, '_WorkFlow', {}) if request.user.is_superuser or getModelPermissions(request.user , model, 'wfadmin') : protoMeta['WFlowActions'] = wflowControl.get('transitions', []) wfFilterSet = wflowControl.get('wfFilters', []) if len(wfFilterSet) > 0: protoMeta['gridSets'] = protoMeta.get('gridSets', {}) protoMeta['gridSets']['filtersSet'] = wfFilterSet for lFilter in wfFilterSet: lFilter['customFilter'] = [{ "property": "smWflowStatus", "filterStmt": lFilter[ 'wfStatus'] }] jsondict = { 'success':True, 'message': '', 'metaData':{ # The name of the property which contains the Array of row objects. ... 'root': 'rows', # Name of the property within a row object that contains a record identifier value. ... 'idProperty': protoMeta['idProperty'], # Name of the property from which to retrieve the total number of records in t 'totalProperty':'totalCount', # Name of the property from which to retrieve the success attribute. ... 'successProperty':'success', # The name of the property which contains a response message. (optional) 'messageProperty': 'message', }, 'protoMeta': protoMeta, 'permissions': getModelPermissions(request.user, model), 'rows':[], 'totalCount': 0, } # Codifica el mssage json context = json.dumps(jsondict) return HttpResponse(context, content_type="application/json")
def protoSaveProtoObj(request): """ Save full metadata * objetos del tipo _XXX se guardan siempre en CustomDefinition * objetos del tipo prototype.protoTable se guardan siempre en Prototype * Solo los adminstradores tienen el derecho de guardar pcls custom : Los objetos de tipo custom, manejan la siguiente llave _ColSet.[viewCode] listDisplaySet _QrySet.[viewCode] filterSet _menu Para manejar el modelo en las generacion de protoPci's se usa : prototype.protoTable.[protoModel-viewCode] --> al leer la pcl se leera prototype.protoTable.[protoModel-viewCode] """ if request.method != 'POST': return JsonError('invalid message') custom = False prototype = False create = False viewCode = request.POST.get('viewCode', '') userProfile = getUserProfile(request.user, 'saveObjs', viewCode) # Reglas para definir q se guarda if viewCode.find('_') == 0 : custom = True if viewCode.startswith(PROTO_PREFIX) : prototype = True # Carga la meta sMeta = request.POST.get('protoMeta', '') # Es customProperty if custom: try: protoDef, create = CustomDefinition.objects.get_or_create(code=viewCode, smOwningTeam=userProfile.userTeam) except Exception as e: return JsonError(getReadableError(e)) # Es prototype elif prototype: try: # debe existir previamente protoCode = viewCode.replace(PROTO_PREFIX, '') protoMeta = json.loads(sMeta) entityId = protoMeta['protoEntityId'] entityObj = Entity.objects.get(id=entityId) protoDef, create = Prototype.objects.get_or_create(code=protoCode, entity=entityObj, smOwningTeam=userProfile.userTeam) except Exception as e: return JsonError(getReadableError(e)) else: # Verifica los permisos viewEntity = getBaseModelName(viewCode) model = getDjangoModel(viewEntity) if not getModelPermissions(request.user, model, 'config') : return JsonError('permission denied') try: protoDef = ProtoDefinition.objects.get_or_create(code=viewCode)[0] except Exception as e: return JsonError(getReadableError(e)) protoDef.active = True protoDef.overWrite = False # borra el custom por q confunde haecer modif en un lado y otro try: CustomDefinition.objects.filter(code='_custom.' + viewCode, smOwningTeam=userProfile.userTeam).delete() except: pass if custom or prototype: setSecurityInfo(protoDef, {}, userProfile, create) protoDef.metaDefinition = sMeta protoDef.save() return JsonSuccess({ 'message': 'Ok' })
def protoGetPCI(request): """ return full metadata (columns, renderers, totalcount...) """ if not request.user.is_authenticated(): return JsonError('readOnly User') if request.method != 'POST': return JsonError('invalid message') viewCode = request.POST.get('viewCode', '') viewEntity = getBaseModelName(viewCode) try: model = getDjangoModel(viewEntity) except : return JsonError('model not found:' + viewEntity) # userProfile = getUserProfile(request.user, 'getPci', viewEntity) # PROTOTIPOS if viewCode.startswith(PROTO_PREFIX) and viewCode != viewEntity : try: prototypeView = viewCode.replace(PROTO_PREFIX, '') protoDef = Prototype.objects.get(code=prototypeView, smOwningTeam=userProfile.userTeam) created = False except: jsondict = { 'success':False, 'message': viewCode + ' notFound' } return HttpResponse(json.dumps(jsondict), content_type="application/json") else: # created : El objeto es nuevo # protoDef : PCI leida de la DB protoDef, created = ProtoDefinition.objects.get_or_create(code=viewCode) # Verifica si es una version vieja if created: protoDef.overWrite = True # active solo viene de protoDefinition try: active = protoDef.active except: active = True # Si es nuevo o no esta activo lee Django if created or (not active) : model_admin, protoMeta = getProtoAdmin(model) version = protoMeta.get('metaVersion') # La version determina q es una carga completa de la meta y no es necesario reconstruirla # solo en caso de q la definicion no este en la Db if (version is None) or (version < PROTOVERSION): # Verifica si existe una propiedad ProtoMeta es la copia de la meta cargada a la Db, grid = protoGrid.ProtoGridFactory(model, viewCode, model_admin, protoMeta) protoMeta = createProtoMeta(model, grid, viewEntity, viewCode) # Guarda la Meta si es nuevo o si se especifica overWrite if created or protoDef.overWrite: protoDef.metaDefinition = json.dumps(protoMeta) protoDef.description = protoMeta['description'] protoDef.save() else: protoMeta = json.loads(protoDef.metaDefinition) protoMeta['viewCode'] = viewCode # La definicion del arbol es fija, pues las cols deben ser siempre uniformes sin importar el tipo de modelo. # pStyle = protoMeta.get( 'pciStyle', '') # if pStyle == 'tree': setTreeDefinition() customCode = '_custom.' + viewCode try: custom = CustomDefinition.objects.get(code=customCode, smOwningTeam=userProfile.userTeam) custom = json.loads(custom.metaDefinition) protoMeta['custom'] = custom['custom'] except: pass # TODO: Verificacion de la metadata # try: # protoMeta = verifyMeta(protoMeta, 'pcl') # except Exception, e: # traceback.print_exc() # message = getReadableError(e) # WorkFlow if hasattr(model , '_WorkFlow') : wflowControl = getattr(model, '_WorkFlow', {}) if request.user.is_superuser or getModelPermissions(request.user , model, 'wfadmin') : protoMeta['WFlowActions'] = wflowControl.get('transitions', []) wfFilterSet = wflowControl.get('wfFilters', []) if len(wfFilterSet) > 0: protoMeta['gridSets'] = protoMeta.get('gridSets', {}) protoMeta['gridSets']['filtersSet'] = wfFilterSet for lFilter in wfFilterSet: lFilter['customFilter'] = [{ "property": "smWflowStatus", "filterStmt": lFilter[ 'wfStatus'] }] jsondict = { 'success':True, 'message': '', 'metaData':{ # The name of the property which contains the Array of row objects. ... 'root': 'rows', # Name of the property within a row object that contains a record identifier value. ... 'idProperty': protoMeta['idProperty'], # Name of the property from which to retrieve the total number of records in t 'totalProperty':'totalCount', # Name of the property from which to retrieve the success attribute. ... 'successProperty':'success', # The name of the property which contains a response message. (optional) 'messageProperty': 'message', }, 'protoMeta': protoMeta, 'permissions': getModelPermissions(request.user, model), 'rows':[], 'totalCount': 0, } # Codifica el mssage json context = json.dumps(jsondict) return HttpResponse(context, content_type="application/json")
def _protoEdit(request, myAction ): if not request.user.is_authenticated(): return doReturn ({'success':False ,'message' : 'readOnly User'}) if request.method != 'POST': return doReturn ({'success':False, 'message' : 'invalid message'}) message = '' # Carga el modelo protoMeta = request.POST.get('protoMeta', '') protoMeta = json.loads( protoMeta ) viewEntity = protoMeta.get('viewEntity', '') model = getDjangoModel(viewEntity) # Autentica if not getModelPermissions( request.user, model, myAction ): return doReturn ({'success':False ,'message' : 'No ' + myAction + 'permission'}) # Obtiene el profile para saber el teamhierarchi userProfile = getUserProfile( request.user, 'edit', viewEntity ) # Verfica si es un protoModel ( maneja TeamHierarchy ) isProtoModel = hasattr( model , '_protoObj' ) # Verifica si hay registros que son solo de referencia userNodes = [] refAllow = False if myAction in ['delete', 'change'] and isProtoModel and not request.user.is_superuser : refAllow = getModelPermissions( request.user, model, 'refallow' ) if refAllow: userNodes = getUserNodes( request.user, viewEntity ) # WorkFlow hasWFlow = hasattr( model , '_WorkFlow' ) and isProtoModel if hasWFlow: wfadmin = getModelPermissions( request.user , model, 'wfadmin' ) WFlowControl = getattr( model, '_WorkFlow', {} ) initialWfStatus = WFlowControl.get( 'initialStatus', '0') # Decodifica los eltos rows = request.POST.get('rows', []) rows = json.loads( rows ) fieldsDict = list2dict( protoMeta[ 'fields' ], 'name') # JsonField jsonField = protoMeta.get('jsonField', '') if not isinstance( jsonField, (str, unicode) ): jsonField = '' # TOOD: Log # activityLog ( myAction, request.user , viewEntity, { 'protoMeta' : protoMeta , 'rows' : rows }) # Genera la clase UDP pUDP = protoMeta.get('usrDefProps', {}) cUDP = verifyUdpDefinition( pUDP ) # Verifica q sea una lista de registros, (no deberia pasar, ya desde Extjs se controla ) if type(rows).__name__=='dict': rows = [rows] pList = [] for data in rows: data['_ptStatus'] = '' if myAction == 'add': rec = model() else: try: rec = model.objects.get( pk = data['id'] ) except: data['_ptStatus'] = data['_ptStatus'] + ERR_NOEXIST + '<br>' pList.append( data ) continue # refAllow verifica si corresponde a los registros modificables ( solo es true en myAction in ['delete', 'change'] ) if refAllow and isProtoModel : if not ( str( rec.smOwningTeam_id ) in userNodes ) : data['_ptStatus'] = ERR_REFONLY + '<br>' pList.append( data ) continue if not ( myAction == 'delete' ): # Upd, Ins for key in data: key = smart_str( key ) if key in ['id', '_ptStatus', '_ptId', '__str__']: continue vFld = fieldsDict[key] if vFld.get( 'crudType' ) in ["screenOnly", "linked" ]: continue # Los campos de seguridad se manejan a nivel registro if isProtoModel: if key in ['smOwningUser','smOwningTeam','smCreatedBy','smModifiedBy', 'smWflowStatus','smRegStatus','smCreatedOn','smModifiedOn', 'smOwningUser_id','smOwningTeam_id','smCreatedBy_id','smModifiedBy_id']: continue # Udps if (cUDP.udpTable and key.startswith( cUDP.propertyPrefix + '__')): continue # JsonField if key == jsonField: continue if key.startswith( jsonField + '__'): continue try: setRegister( model, rec, key, data ) except Exception as e: data['_ptStatus'] = data['_ptStatus'] + getReadableError( e ) if isProtoModel: setSecurityInfo( rec, data, userProfile, ( myAction == 'add' ) ) if len( jsonField ) > 0: jsonInfo = {} for key in data: if not key.startswith( jsonField + '__'): continue jKey = key[ len(jsonField) + 2 : ] jsonInfo[ jKey ] = data[ key ] setattr( rec, jsonField , jsonInfo ) # Inicializa el estado del WF if hasWFlow: setattr( rec, 'smWflowStatus' , initialWfStatus ) # Guarda el idInterno para concatenar registros nuevos en la grilla try: _ptId = data['_ptId'] except: _ptId = '' try: rec.save() # Guardar las Udps if cUDP.udpTable: try: saveUDP( rec, data, cUDP ) except Exception as e: raise Exception( 'UdpError: saveActiob') # -- Los tipos complejos ie. date, generan un error, es necesario hacerlo detalladamente # Convierte el registro en una lista y luego toma solo el primer elto de la lista resultado. data = Q2Dict(protoMeta , [rec], False )[0] data['_ptId'] = _ptId except Exception as e: data['_ptStatus'] = data['_ptStatus'] + getReadableError( e ) data['_ptId'] = _ptId #traceback.print_exc() #return doReturn ({'success':False ,'message' : str( e )}) else: # Action Delete try: rec.delete() except Exception, e: data['_ptStatus'] = data['_ptStatus'] + getReadableError( e ) pass pList.append( data ) if data.get('_ptStatus', ''): message += data['_ptStatus'] + ';'
def protoGetMenuData(request): """ Cada grupo tiene su propio menu q se construye con las app a las cuales tiene derecho se guarda siempre por grupo en customDefinition, Cada usuario tendra una rama de favoritos para sus opciones frecuentes, el menu es a nivel de grupo """ global ix if not request.user.is_authenticated(): return JsonError('readOnly User') if request.method != 'POST': return JsonError('invalid message') currentUser = request.user userProfile = getUserProfile(currentUser, 'getMenu', '') app_dict = {} appAux = cAux() appAux.ixApp = 1 appAux.ixMod = 1 def getMenuItem(protoAdmin, model, menuNode): appCode = model._meta.app_label # Define la rama del menu try: menuLabel = model.protoExt["menuApp"] except: menuLabel = appCode if menuLabel in ['contenttypes', 'sites']: menuLabel = 'auth' # Verifica q el usuairo tenga permiso, considera el admin if not getModelPermissions(currentUser, model, 'menu') : return pTitle = protoAdmin.get('title', model._meta.verbose_name.title()) # Obtiene el menu de settigs.PROTO_APP try: menuDefinition = settings.PROTO_APP.get('app_menu', {}).get(menuLabel, {}) except: menuDefinition = {} if menuDefinition.get('hidden', False): return # Icono por defecto viewIcon = protoAdmin.get('viewIcon', 'icon-1') model_dict = { 'viewCode': appCode + '.' + menuNode , 'text': pTitle , 'index': appAux.ixMod , 'iconCls': viewIcon , 'leaf': True, } if menuLabel in app_dict: app_dict[menuLabel]['children'].append(model_dict) else: app_dict[menuLabel] = { 'text': menuDefinition.get('title', menuLabel) , 'expanded': menuDefinition.get('expanded', False) , 'index': menuDefinition.get('menu_index', appAux.ixApp), 'children': [model_dict], } appAux.ixApp += 1 appAux.ixMod += 1 #-- Lectura de la Db ------------------------------------------------------------- forceDefault = request.POST.get('forceDefault', '') viewCode = '__menu' protoDef = CustomDefinition.objects.get_or_create( code=viewCode, smOwningTeam=userProfile.userTeam, defaults={'active': False, 'code' : viewCode, 'smOwningTeam' : userProfile.userTeam } )[0] # El default solo parece funcionar al insertar en la Db if protoDef.active and (forceDefault == '0') : context = protoDef.metaDefinition else: for model in models.get_models(include_auto_created=True): # for model, model_admin in site._registry.items(): # protoAdmin = getattr(model_admin, 'protoExt', {}) menuNode = model._meta.object_name protoAdmin = getattr(model, 'protoExt', {}) getMenuItem(protoAdmin, model, menuNode) # Sort the apps alphabetically. app_list = app_dict.values() app_list.sort(key=lambda x: x['index']) # Sort the models alphabetically within each app. for app in app_list: app['children'].sort(key=lambda x: x['index']) #===== lee las opciones del prototipo ----------------------------------------------- prototypes = Prototype.objects.filter(smOwningTeam=userProfile.userTeam) prNodes = { 'text': 'ProtoOptions' , 'expanded': True , 'index': 1000 , 'children': [], 'leaf': False } app_list.append(prNodes) ix = 0 for option in prototypes: prBase = getNodeBaseProto(prNodes, option) prBase['children'].append({ 'text': option.code, 'expanded': True , 'viewCode': PROTO_PREFIX + option.code, 'iconCls': 'icon-proto', 'index': ix, 'leaf': True }) ix += 1 #===== lee las vistas ----------------------------------------------- prototypes = ProtoDefinition.objects.all() prNodes = { 'text': 'ProtoViews' , 'expanded': True , 'index': 2000 , 'children': [], 'leaf': False } app_list.append(prNodes) ix = 0 for option in prototypes: appName, modName = option.code.split('.')[:2] if not getOptionPermissions(currentUser, appName, modName.lower() , 'menu'): continue prBase = getNodeBaseViews(prNodes, option) if prBase is None: continue prBase['children'].append({ 'text': option.code, 'expanded': True , 'viewCode': option.code, 'iconCls': 'icon-1', 'index': ix, 'leaf': True }) ix += 1 # Pega el menu sobre la definicion anterior try: menuAux = [] menuTmp = verifyList(json.loads(protoDef.metaDefinition)) for menuOp in menuTmp: if menuOp.get( 'text', '') != 'AutoMenu': menuAux.append (menuOp) menuAux.append({ 'id': 'prototype.auto.nodes' , 'text': 'AutoMenu' , 'expanded': True, 'index': 1000 , 'children': app_list, 'leaf': False }) except: menuAux = app_list context = json.dumps(menuAux) # Lo guarda ( created : true --> new protoDef.metaDefinition = context protoDef.active = True protoDef.description = 'Menu' setSecurityInfo(protoDef, {}, userProfile, True) protoDef.save() return HttpResponse(context, content_type="application/json")
def doWfAction(model, selectedKeys, parameters, actionDef, viewEntity, pUser): userProfile = getUserProfile(pUser, 'wflow', viewEntity) try: changeSt = actionDef.get('change', []) stInitial = changeSt[0] stFinal = changeSt[1] Qs = model.objects.filter(pk__in=selectedKeys) Qs = Qs.filter(smWflowStatus=stInitial) # TODO transaction??? if actionDef.get('notifyOwner', False) : for wfRow in Qs : if len (parameters) > 0: strMsg = parameters[0].get('value') else : strMsg = actionDef.get('message', '') UserReponse = WflowUserReponse() UserReponse.viewEntity = viewEntity UserReponse.strKey = wfRow.__str__() UserReponse.wfAction = actionDef.get('name') UserReponse.adminMsg = strMsg try: setattr(UserReponse, 'smOwningUser', wfRow.smOwningUser) setattr(UserReponse, 'smOwningTeam', wfRow.smOwningTeam) setattr(UserReponse, 'smCreatedBy', userProfile.user) setattr(UserReponse, 'smRegStatus', '0') setattr(UserReponse, 'smCreatedOn', datetime.now()) except : pass UserReponse.save() if actionDef.get('emailNotification', False): user = User.objects.get(username=wfRow.smOwningUser.username) if user.email : try: subject = actionDef.get('emailSubject', '') message = actionDef.get('emailTemplate', '') variableFormat = { 'sk' : wfRow.__str__(), 'concept' : viewEntity, 'admmessage': strMsg , 'admin' : userProfile.user.username.title(), 'date' : strftime('%d/%m/%Y', wfRow.smCreatedOn.timetuple()), 'User' : wfRow.smOwningUser.username.title() } message = message.format(**variableFormat) user.email_user(subject, message) except : pass if actionDef.get('setOwner', False) : Qs.update(smWflowStatus=stFinal, smOwningTeam=userProfile.userTeam) else : Qs.update(smWflowStatus=stFinal) return doReturn ({'success':True, 'message' : 'WfAction Ok'}) except Exception as e: return doReturn ({'success':False, 'message' : str(e) })
def protoGetPCI(request): """ return full metadata (columns, renderers, totalcount...) """ if not request.user.is_authenticated(): return JsonError('readOnly User') if request.method != 'POST': return JsonError( 'invalid message' ) viewCode = request.POST.get('viewCode', '') viewEntity = getBaseModelName( viewCode ) try: model = getDjangoModel(viewEntity) except : return JsonError( 'model not found:' + viewEntity ) # userProfile = getUserProfile( request.user, 'getPci', viewEntity ) # PROTOTIPOS if viewCode.startswith( PROTO_PREFIX ) and viewCode != viewEntity : try: prototypeView = viewCode.replace( PROTO_PREFIX, '') protoDef = Prototype.objects.get(code = prototypeView, smOwningTeam = userProfile.userTeam ) created = False except: jsondict = { 'success':False, 'message': viewCode + ' notFound' } return HttpResponse( json.dumps( jsondict), mimetype="application/json") else: # created : El objeto es nuevo # protoDef : PCI leida de la DB protoDef, created = ProtoDefinition.objects.get_or_create(code = viewCode ) # Verifica si es una version vieja if created: protoDef.overWrite = True # else: # protoMeta = json.loads( protoDef.metaDefinition ) # version = protoMeta.get( 'metaVersion' ) # if ( version is None ) or ( version < PROTOVERSION ): # created = True # active solo viene de protoDefinition try: active = protoDef.active except: active = True # Si es nuevo o no esta activo lee Django if created or ( not active ) : model_admin, protoMeta = getProtoAdmin( model ) version = protoMeta.get( 'metaVersion' ) # La version determina q es una carga completa de la meta y no es necesario reconstruirla # solo en caso de q la definicion no este en la Db if ( version is None ) or ( version < PROTOVERSION ): # Verifica si existe una propiedad ProtoMeta es la copia de la meta cargada a la Db, grid = protoGrid.ProtoGridFactory( model, viewCode, model_admin, protoMeta ) protoMeta = createProtoMeta( model, grid, viewEntity, viewCode ) # Guarda la Meta si es nuevo o si se especifica overWrite if created or protoDef.overWrite: protoDef.metaDefinition = json.dumps( protoMeta ) protoDef.description = protoMeta['description'] protoDef.save() else: protoMeta = json.loads( protoDef.metaDefinition ) protoMeta['viewCode'] = viewCode # La definicion del arbol es fija, pues las cols deben ser siempre uniformes sin importar el tipo de modelo. # pStyle = protoMeta.get( 'pciStyle', '') # if pStyle == 'tree': setTreeDefinition() customCode = '_custom.' + viewCode try: custom = CustomDefinition.objects.get(code = customCode, smOwningTeam = userProfile.userTeam ) custom = json.loads( custom.metaDefinition ) protoMeta['custom'] = custom['custom'] except: pass # WorkFlow if hasattr( model , '_WorkFlow' ) : wflowControl = getattr( model, '_WorkFlow', {} ) if request.user.is_superuser or getModelPermissions( request.user , model, 'wfadmin' ) : protoMeta['WFlowActions'] = wflowControl.get( 'transitions', [] ) wfFilterSet = wflowControl.get( 'wfFilters', [] ) if len( wfFilterSet ) > 0: protoMeta['gridSets'] = protoMeta.get('gridSets', {}) protoMeta['gridSets']['filtersSet'] = wfFilterSet for lFilter in wfFilterSet: lFilter['customFilter'] = [{ "property": "smWflowStatus", "filterStmt": lFilter[ 'wfStatus'] }] jsondict = { 'success':True, 'message': '', 'metaData':{ # The name of the property which contains the Array of row objects. ... 'root': 'rows', #Name of the property within a row object that contains a record identifier value. ... 'idProperty': protoMeta['idProperty'], #Name of the property from which to retrieve the total number of records in t 'totalProperty':'totalCount', #Name of the property from which to retrieve the success attribute. ... 'successProperty':'success', #The name of the property which contains a response message. (optional) 'messageProperty': 'message', }, 'protoMeta': protoMeta, 'permissions': getModelPermissions( request.user, model ), 'rows':[], 'totalCount': 0, } # Codifica el mssage json context = json.dumps( jsondict) return HttpResponse(context, mimetype="application/json")
def protoGetMenuData(request): """ Cada grupo tiene su propio menu q se construye con las app a las cuales tiene derecho se guarda siempre por grupo en customDefinition, Cada usuario tendra una rama de favoritos para sus opciones frecuentes, el menu es a nivel de grupo """ global ix if not request.user.is_authenticated(): return JsonError('readOnly User') if request.method != 'POST': return JsonError('invalid message') currentUser = request.user userProfile = getUserProfile(currentUser, 'getMenu', '') app_dict = {} appAux = cAux() appAux.ixApp = 1 appAux.ixMod = 1 def getMenuItem(protoAdmin, model, menuNode): appCode = model._meta.app_label # Define la rama del menu try: menuLabel = model.protoExt["menuApp"] except: menuLabel = appCode if menuLabel in ['contenttypes', 'sites']: menuLabel = 'auth' # Verifica q el usuairo tenga permiso, considera el admin if not getModelPermissions(currentUser, model, 'menu') : return pTitle = protoAdmin.get('title', model._meta.verbose_name.title()) # Obtiene el menu de settigs.PROTO_APP try: menuDefinition = settings.PROTO_APP.get('app_menu', {}).get(menuLabel, {}) except: menuDefinition = {} if menuDefinition.get('hidden', False): return # Icono por defecto viewIcon = protoAdmin.get('viewIcon', 'icon-1') model_dict = { 'viewCode': appCode + '.' + menuNode , 'text': pTitle , 'index': appAux.ixMod , 'iconCls': viewIcon , 'leaf': True, } if menuLabel in app_dict: app_dict[menuLabel]['children'].append(model_dict) else: app_dict[menuLabel] = { 'text': menuDefinition.get('title', menuLabel) , 'expanded': menuDefinition.get('expanded', False) , 'index': menuDefinition.get('menu_index', appAux.ixApp), 'children': [model_dict], } appAux.ixApp += 1 appAux.ixMod += 1 #-- Lectura de la Db ------------------------------------------------------------- forceDefault = request.POST.get('forceDefault', '') viewCode = '__menu' protoDef = CustomDefinition.objects.get_or_create( code=viewCode, smOwningTeam=userProfile.userTeam, defaults={'active': False, 'code' : viewCode, 'smOwningTeam' : userProfile.userTeam } )[0] # El default solo parece funcionar al insertar en la Db if protoDef.active and (forceDefault == '0') : context = protoDef.metaDefinition else: for model in models.get_models(include_auto_created=True): # for model, model_admin in site._registry.items(): # protoAdmin = getattr(model_admin, 'protoExt', {}) menuNode = model._meta.object_name protoAdmin = getattr(model, 'protoExt', {}) getMenuItem(protoAdmin, model, menuNode) # Sort the apps alphabetically. app_list = app_dict.values() app_list.sort(key=lambda x: x['index']) # Sort the models alphabetically within each app. for app in app_list: app['children'].sort(key=lambda x: x['index']) # lee las opciones del prototipo ----------------------------------------------- prototypes = Prototype.objects.filter(smOwningTeam=userProfile.userTeam) prNodes = { 'text': 'ProtoOptions' , 'expanded': True , 'index': 1000 , 'children': [], 'leaf': False } app_list.append(prNodes) ix = 0 for option in prototypes: prBase = getNodeBaseProto(prNodes, option) prBase['children'].append({ 'text': option.code, 'expanded': True , 'viewCode': PROTO_PREFIX + option.code, 'iconCls': 'icon-proto', 'index': ix, 'leaf': True }) ix += 1 # lee las vistas prototypes = ProtoDefinition.objects.all() prNodes = { 'text': 'ProtoViews' , 'expanded': True , 'index': 2000 , 'children': [], 'leaf': False } app_list.append(prNodes) ix = 0 for option in prototypes: prBase = getNodeBaseViews(prNodes, option) prBase['children'].append({ 'text': option.code, 'expanded': True , 'viewCode': option.code, 'iconCls': 'icon-1', 'index': ix, 'leaf': True }) ix += 1 # Pega el menu sobre la definicion anterior try: menuAux = [] menuTmp = verifyList(json.loads(protoDef.metaDefinition)) for menuOp in menuTmp: if menuOp.get( 'text', '') != 'AutoMenu': menuAux.append (menuOp) menuAux.append({ 'id': 'prototype.auto.nodes' , 'text': 'AutoMenu' , 'expanded': True, 'index': 1000 , 'children': app_list, 'leaf': False }) except: menuAux = app_list context = json.dumps(menuAux) # Lo guarda ( created : true --> new protoDef.metaDefinition = context protoDef.active = True protoDef.description = 'Menu' setSecurityInfo(protoDef, {}, userProfile, True) protoDef.save() return HttpResponse(context, content_type="application/json")
def _protoEdit(request, myAction): if not request.user.is_authenticated(): return doReturn({'success': False, 'message': 'readOnly User'}) if request.method != 'POST': return doReturn({'success': False, 'message': 'invalid message'}) message = '' # Carga el modelo protoMeta = request.POST.get('protoMeta', '') protoMeta = json.loads(protoMeta) viewEntity = protoMeta.get('viewEntity', '') model = getDjangoModel(viewEntity) # Autentica if not getModelPermissions(request.user, model, myAction): return doReturn({ 'success': False, 'message': 'No ' + myAction + 'permission' }) # Obtiene el profile para saber el teamhierarchi userProfile = getUserProfile(request.user, 'edit', viewEntity) # Verfica si es un protoModel ( maneja TeamHierarchy ) isProtoModel = hasattr(model, '_protoObj') # Verifica si hay registros que son solo de referencia userNodes = [] refAllow = False if myAction in ['DEL', 'UPD' ] and isProtoModel and not request.user.is_superuser: refAllow = getModelPermissions(request.user, model, 'refallow') if refAllow: userNodes = getUserNodes(request.user, viewEntity) # WorkFlow hasWFlow = hasattr(model, '_WorkFlow') and isProtoModel if hasWFlow: wfadmin = getModelPermissions(request.user, model, 'wfadmin') WFlowControl = getattr(model, '_WorkFlow', {}) initialWfStatus = WFlowControl.get('initialStatus', '0') # Decodifica los eltos rows = request.POST.get('rows', []) rows = json.loads(rows) # LogInfo logEvent(viewEntity, rows, request.user, userProfile.userTeam, '', myAction) # Fields fieldsDict = list2dict(protoMeta['fields'], 'name') # JsonField jsonField = protoMeta.get('jsonField', '') if not isinstance(jsonField, (str, unicode)): jsonField = '' # TOOD: Log # activityLog ( myAction, request.user , viewEntity, { 'protoMeta' : protoMeta , 'rows' : rows }) # Genera la clase UDP pUDP = protoMeta.get('usrDefProps', {}) cUDP = verifyUdpDefinition(pUDP) # Verifica q sea una lista de registros, (no deberia pasar, ya desde Extjs se controla ) if type(rows).__name__ == 'dict': rows = [rows] pList = [] for data in rows: data['_ptStatus'] = '' if myAction == 'INS': rec = model() else: try: rec = model.objects.get(pk=data['id']) except: data['_ptStatus'] = data['_ptStatus'] + ERR_NOEXIST + '<br>' pList.append(data) continue # refAllow verifica si corresponde a los registros modificables ( solo es true en myAction in ['DEL', 'UPD'] ) if refAllow and isProtoModel: if not (str(rec.smOwningTeam_id) in userNodes): data['_ptStatus'] = ERR_REFONLY + '<br>' pList.append(data) continue if not (myAction == 'DEL'): # Upd, Ins for key in data: key = smart_str(key) if key in ['id', '_ptStatus', '_ptId', '__str__']: continue vFld = fieldsDict[key] if vFld.get('crudType') in ["screenOnly", "linked"]: continue # Los campos de seguridad se manejan a nivel registro if isProtoModel: if key in [ 'smOwningUser', 'smOwningTeam', 'smOwningUser_id', 'smOwningTeam_id', 'smCreatedBy', 'smModifiedBy', 'smCreatedBy_id', 'smModifiedBy_id', 'smCreatedOn', 'smModifiedOn', 'smWflowStatus', 'smRegStatus', 'smUUID' ]: continue # Udps if (cUDP.udpTable and key.startswith(cUDP.propertyPrefix + '__')): continue # JsonField if key == jsonField: continue if key.startswith(jsonField + '__'): continue try: setRegister(model, rec, key, data) except Exception as e: data['_ptStatus'] = data['_ptStatus'] + getReadableError(e) if isProtoModel: setSecurityInfo(rec, data, userProfile, (myAction == 'INS')) if len(jsonField) > 0: jsonInfo = {} for key in data: if not key.startswith(jsonField + '__'): continue jKey = key[len(jsonField) + 2:] jsonInfo[jKey] = data[key] setattr(rec, jsonField, jsonInfo) # Inicializa el estado del WF if hasWFlow: setattr(rec, 'smWflowStatus', initialWfStatus) # Guarda el idInterno para concatenar registros nuevos en la grilla try: _ptId = data['_ptId'] except: _ptId = '' try: rec.save() # Guardar las Udps if cUDP.udpTable: try: saveUDP(rec, data, cUDP) except Exception as e: raise Exception('UdpError: saveActiob') # -- Los tipos complejos ie. date, generan un error, es necesario hacerlo detalladamente # Convierte el registro en una lista y luego toma solo el primer elto de la lista resultado. data = Q2Dict(protoMeta, [rec], False)[0] data['_ptId'] = _ptId except Exception as e: data['_ptStatus'] = data['_ptStatus'] + getReadableError(e) data['_ptId'] = _ptId # traceback.print_exc() # return doReturn ({'success':False ,'message' : str( e )}) else: # Action Delete try: rec.delete() except Exception, e: data['_ptStatus'] = data['_ptStatus'] + getReadableError(e) pList.append(data) if data.get('_ptStatus', ''): message += data['_ptStatus'] + ';'