示例#1
0
def doGenericFuntion(sQBE):
    """
    Se define una tabla de funciones genericas q seran ejectua dinamicamente por pyton 
    se ejectuan en el contexto actual, se deberia pasar algunas rutinas basicas en la medida q sean necesarias  
        getModels 
     
    Esta rutina servira tambien para desencadenar reglas de gestion sobre modelos y podria ser la base 
    de la ejecucion del wKflow
    
    """
    from utilsBase import explode

    # obtiene los parametros
    fCall = explode(sQBE[1:])

    # obtiene la definicion de la funcion
    from models import PtFunction, getDjangoModel
    fBase = PtFunction.objects.get(code=fCall[0])

    # Construyte las variables de entorno
    myVars = { 'model' : getDjangoModel(fBase.modelName) }

    arguments = fBase.arguments.split(',')
    params = fCall[1].split(',')
    for i  in range(0 , len(arguments)):
        myVars[ arguments[i] ] = params[i]

    # ejecta y toma la base
    exec(fBase.functionBody, myVars)
    return myVars [ 'ret' ]
示例#2
0
def doGenericFuntion(sQBE):
    """
    Se define una tabla de funciones genericas q seran ejectua dinamicamente por pyton 
    se ejectuan en el contexto actual, se deberia pasar algunas rutinas basicas en la medida q sean necesarias  
        getModels 
     
    Esta rutina servira tambien para desencadenar reglas de gestion sobre modelos y podria ser la base 
    de la ejecucion del wKflow
    
    """
    from utilsBase import explode

    # obtiene los parametros
    fCall = explode(sQBE[1:])

    # obtiene la definicion de la funcion
    from models import PtFunction, getDjangoModel
    fBase = PtFunction.objects.get(code=fCall[0])

    # Construyte las variables de entorno
    myVars = {'model': getDjangoModel(fBase.modelName)}

    arguments = fBase.arguments.split(',')
    params = fCall[1].split(',')
    for i in range(0, len(arguments)):
        myVars[arguments[i]] = params[i]

    # ejecta y toma la base
    exec(fBase.functionBody, myVars)
    return myVars['ret']
示例#3
0
def getFieldIncrement(request):
    success = False
    fieldName = request.GET['fieldName']
    viewEntity = request.GET['viewEntity']
    try: 
        model = getDjangoModel(viewEntity)
    except :
        return JsonError('model not found:' + viewEntity)
    
    fieldType = model._meta.get_field(fieldName).get_internal_type()
    increment = 0
    if fieldType == 'IntegerField':
        maxid = model.objects.aggregate(Max('id'))
        if maxid['id__max']:
            increment = maxid['id__max'] + 1
        else:
            increment = 1
    else:
        return JsonError('Invalid field type')
    
    if increment > 0:
        success = True
        
    jsondict = {
        'success': success,
        'increment': increment
    }
    
    json_data = json.dumps(jsondict)
    return HttpResponse(json_data, content_type="application/json")
示例#4
0
def getFieldIncrement(request):
    success = False
    fieldName = request.GET['fieldName']
    viewEntity = request.GET['viewEntity']
    try: 
        model = getDjangoModel(viewEntity)
    except :
        return JsonError('model not found:' + viewEntity)
    
    fieldType = model._meta.get_field(fieldName).get_internal_type()
    increment = 0
    if fieldType == 'IntegerField':
        maxid = model.objects.aggregate(Max('id'))
        if maxid['id__max']:
            increment = maxid['id__max'] + 1
        else:
            increment = 1
    else:
        return JsonError('Invalid field type')
    
    if increment > 0:
        success = True
        
    jsondict = {
        'success': success,
        'increment': increment
    }
    
    json_data = json.dumps(jsondict)
    return HttpResponse(json_data, content_type="application/json")
示例#5
0
def protoGetFieldTree(request):
    """ return full field tree 
    """

    if request.method != 'POST':
        return JsonError('Invalid message') 
    
    viewCode = request.POST.get('viewCode', '') 
    viewEntity = getBaseModelName(viewCode)
    
    try: 
        model = getDjangoModel(viewEntity)
    except Exception as e:
        return JsonError(getReadableError(e)) 
    
    fieldList = []
    if viewCode.startswith(PROTO_PREFIX) and viewCode != viewEntity :
        # ---------------------------------------------------              Prototipos 
        protoEntityId = request.POST.get('protoEntityId')
        if not protoEntityId >= 0:
            return JsonError('invalid idEntity')

        try:  
            from prototype.actions.viewDefinition import GetProtoFieldsTree
            fieldList = GetProtoFieldsTree(protoEntityId)
        except: 
            return JsonError('invalid idEntity')

    else: 
        # -----------------------------------------------------------------------------------------------------
        # Se crean los campos con base al modelo ( trae todos los campos del modelo 
        # for field in model._meta._fields(): # only for django 1.4
        for field in model._meta.fields:
            try: 
                addFiedToList(fieldList, field , '')
            except Exception as  e:
                traceback.print_exc()
                return JsonError(getReadableError(e)) 
            
        # Add __str__ 
        myField = { 
            'id'        : '__str__' ,
            'text'      : '__str__' ,
            'checked'   : False,
            'leaf'      : True 
         }
        
        # Defaults values
        setDefaultField(myField, model , viewCode)
        
        # FormLink redefinition to original view 
        # myField['zoomModel'] =  viewCode  
        
        fieldList.append(myField)

    # Codifica el mssage json 
    context = json.dumps(fieldList)
    return HttpResponse(context, content_type="application/json")
示例#6
0
def protoGetFieldTree(request):
    """ return full field tree 
    """

    if request.method != 'POST':
        return JsonError('Invalid message') 
    
    viewCode = request.POST.get('viewCode', '') 
    viewEntity = getBaseModelName(viewCode)
    
    try: 
        model = getDjangoModel(viewEntity)
    except Exception as e:
        return JsonError(getReadableError(e)) 
    
    fieldList = []
    if viewCode.startswith(PROTO_PREFIX) and viewCode != viewEntity :
        # ---------------------------------------------------              Prototipos 
        protoEntityId = request.POST.get('protoEntityId')
        if not protoEntityId >= 0:
            return JsonError('invalid idEntity')

        try:  
            from prototype.actions.viewDefinition import GetProtoFieldsTree
            fieldList = GetProtoFieldsTree(protoEntityId)
        except: 
            return JsonError('invalid idEntity')

    else: 
        # -----------------------------------------------------------------------------------------------------
        # Se crean los campos con base al modelo ( trae todos los campos del modelo 
        # for field in model._meta._fields(): # only for django 1.4
        for field in model._meta.fields:
            try: 
                addFiedToList(fieldList, field , '')
            except Exception as  e:
                traceback.print_exc()
                return JsonError(getReadableError(e)) 
            
        # Add __str__ 
        myField = { 
            'id'        : '__str__' ,
            'text'      : '__str__' ,
            'checked'   : False,
            'leaf'      : True 
         }
        
        # Defaults values
        setDefaultField(myField, model , viewCode)
        
        # FormLink redefinition to original view 
        # myField['zoomModel'] =  viewCode  
        
        fieldList.append(myField)

    # Codifica el mssage json 
    context = json.dumps(fieldList)
    return HttpResponse(context, content_type="application/json")
示例#7
0
def getRowById(myModelName, myId):
    """
    Retorna un registro dado un modelo y un id
    """

#   Obtiene los datos
    model = getDjangoModel(myModelName)
    myList = model.objects.filter(pk=myId)
    if len(myList) > 0:
        return myList[0]
    else:  return None
def readUdps(rowdict, regBase, cUDP, udpList, udpTypes):

    if cUDP.keyField:
        # si la creacion del detalle no es relacional,
        # se requiere hacer un verdadero Query sobre udpTable
        UdpModel = getDjangoModel(cUDP.udpTable)
        keyValue = rowdict.get(cUDP.keyField, '')
        if not keyValue:
            raise Exception('UdpError: Key not found ' + cUDP.keyField +
                            ' in masterReg')

        keyValue = smart_str(keyValue)
        bAux = True
        Qs = UdpModel.objects
        Qs = addFilter(Qs, {cUDP.propertyRef: keyValue})
        cllUDP = Qs.all()

    else:
        # Si no hay keyField, hace el query basado en el registro maestro
        try:
            bAux = eval('regBase.' + cUDP.udpTable.lower() + '_set.exists()')
            cllUDP = eval('regBase.' + cUDP.udpTable.lower() + '_set.all()')
        except:
            raise Exception('UdpError:  related_name  set not found ' +
                            cUDP.udpTable.lower())

    if bAux:

        for lUDP in cllUDP:
            udpName = cUDP.propertyPrefix + '__' + getattr(
                lUDP, cUDP.propertyName, '')
            if udpName in udpList:
                sAux = getattr(lUDP, cUDP.propertyValue, '')
                sAux = getTypedValue(sAux, udpTypes[udpName])
                sAux = smart_str(sAux)

                if udpTypes[udpName] == 'html' and type(
                        sAux).__name__ == 'string':
                    sAux = sAux.replace('\n', '<br>').replace('\r', '<br>')
                    sAux = sAux.replace('<br><br>', '<br>')
                    sAux = sAux.replace('<td><br>',
                                        '<td>').replace('</td><br>', '</td>')
                    sAux = sAux.replace('<th><br>',
                                        '<th>').replace('</th><br>', '</th>')
                    sAux = sAux.replace('<tr><br>',
                                        '<tr>').replace('</tr><br>', '</tr>')
                    sAux = sAux.replace('<br><td>',
                                        '<td>').replace('<br></td>', '</td>')
                    sAux = sAux.replace('<br><th>',
                                        '<th>').replace('<br></th>', '</th>')
                    sAux = sAux.replace('<br><tr>',
                                        '<tr>').replace('<br></tr>', '</tr>')

                rowdict[udpName] = sAux
示例#9
0
def getRowById(myModelName, myId):
    """
    Retorna un registro dado un modelo y un id
    """

    #   Obtiene los datos
    model = getDjangoModel(myModelName)
    myList = model.objects.filter(pk=myId)
    if len(myList) > 0:
        return myList[0]
    else:
        return None
示例#10
0
def saveUDP(regBase, data, cUDP):

    try:
        UdpModel = getDjangoModel(cUDP.udpTable)
    except:
        raise Exception('UdpError: Invalid model ' + UdpModel)

    # si keyField no esta definido implica una relacion MD
    if not cUDP.keyField:
        try:
            Qs = eval('regBase.' + cUDP.udpTable.lower() + '_set.all()')
        except:
            raise Exception('UdpError:  related_name  set not found ' +
                            cUDP.udpTable.lower())

    else:
        keyValue = data.get(cUDP.keyField)
        keyValue = smart_str(keyValue)

        if not keyValue:
            raise Exception('UdpError: Key not found ' + cUDP.keyField +
                            ' in masterReg')

        Qs = UdpModel.objects
        Qs = addFilter(Qs, {cUDP.propertyRef: keyValue})

    for key in data:
        key = smart_str(key)
        if (not key.startswith(cUDP.propertyPrefix + '__')):
            continue
        UdpCode = key[len(cUDP.propertyPrefix) + 2:]

        QsUdp = addFilter(Qs, {cUDP.propertyName: UdpCode})
        if QsUdp.exists():
            rUdp = QsUdp[0]
        else:
            rUdp = UdpModel()
            if not cUDP.keyField:
                setattr(rUdp, cUDP.propertyRef, regBase)
            else:
                # Fix: deberia ser un parametro
                setattr(rUdp, cUDP.propertyRef + '_id', keyValue)

            setattr(rUdp, cUDP.propertyName, UdpCode)

        # Genera el ISO para la fecha y valores estandares para numeros y booleanos
        sAux = smart_str(data[key])
        if sAux == 'None':
            sAux = ''
        setattr(rUdp, cUDP.propertyValue, sAux)
        rUdp.save()
def saveUDP(regBase, data, cUDP):

    try:
        UdpModel = getDjangoModel(cUDP.udpTable)
    except:
        raise Exception("UdpError: Invalid model " + UdpModel)

    # si keyField no esta definido implica una relacion MD
    if not cUDP.keyField:
        try:
            Qs = eval("regBase." + cUDP.udpTable.lower() + "_set.all()")
        except:
            raise Exception("UdpError:  related_name  set not found " + cUDP.udpTable.lower())

    else:
        keyValue = data.get(cUDP.keyField)
        keyValue = smart_str(keyValue)

        if not keyValue:
            raise Exception("UdpError: Key not found " + cUDP.keyField + " in masterReg")

        Qs = UdpModel.objects
        Qs = addFilter(Qs, {cUDP.propertyRef: keyValue})

    for key in data:
        key = smart_str(key)
        if not key.startswith(cUDP.propertyPrefix + "__"):
            continue
        UdpCode = key[len(cUDP.propertyPrefix) + 2 :]

        QsUdp = addFilter(Qs, {cUDP.propertyName: UdpCode})
        if QsUdp.exists():
            rUdp = QsUdp[0]
        else:
            rUdp = UdpModel()
            if not cUDP.keyField:
                setattr(rUdp, cUDP.propertyRef, regBase)
            else:
                # Fix: deberia ser un parametro
                setattr(rUdp, cUDP.propertyRef + "_id", keyValue)

            setattr(rUdp, cUDP.propertyName, UdpCode)

        # Genera el ISO para la fecha y valores estandares para numeros y booleanos
        sAux = smart_str(data[key])
        if sAux == "None":
            sAux = ""
        setattr(rUdp, cUDP.propertyValue, sAux)
        rUdp.save()
示例#12
0
def addDetailToList(detailList, detail, detailPath):
    """ return parcial detail tree  ( Called from protoGetFieldTree )
    
    detailList    : Lista con los detalles 
    detail        : registro del detalle 
    detailField   : jerarquia vista desde el campo  
    detailPath    : jerarquia inversa vista desde el maestro 
    """

    if len(detailPath) > 0:
        detailPath += '/'
    detailPath += detail['menuText']

    # Agrega el campo solicitado
    menuDetail = {
        "id": detailPath,
        "conceptDetail": detail['conceptDetail'],
        "detailField": detail['detailField'],
        "masterField": 'pk',
        "leaf": True
    }

    detailList.append(menuDetail)

    # Evita demasiada recursividad ( 5 niveles debe ser mas q suficiente )
    # Si el mismo campo ya aparece en el camino seguramente es una autoreferencia
    detailField = detail['detailField']
    if detailField.count('__') > 5 or detailField.count('__' +
                                                        detail['detailName'] +
                                                        '__') > 0:
        return

    else:
        detailChild = []
        model = getDjangoModel(detail['conceptDetail'])
        modelDetails = getModelDetails(model)
        for sDetail in modelDetails:
            sDetail['detailField'] = sDetail['detailName'] + '__' + detail[
                'detailField']
            addDetailToList(detailChild, sDetail, detailPath)

        # Si el modelo de base es el modelo de trabajo, no entro al loop
        if len(detailChild) > 0:
            menuDetail['leaf'] = False
            menuDetail['children'] = detailChild
示例#13
0
def readUdps( rowdict, regBase , cUDP, udpList,  udpTypes ):

    if cUDP.keyField: 
        # si la creacion del detalle no es relacional, 
        # se requiere hacer un verdadero Query sobre udpTable                    
        UdpModel = getDjangoModel( cUDP.udpTable )
        keyValue = rowdict.get( cUDP.keyField , '' )
        if not keyValue: 
            raise Exception( 'UdpError: Key not found ' + cUDP.keyField  + ' in masterReg') 
    
        keyValue = smart_str( keyValue )
        bAux = True
        Qs = UdpModel.objects
        Qs = addFilter( Qs, { cUDP.propertyRef  : keyValue  } )
        cllUDP = Qs.all()


    else:
        # Si no hay keyField, hace el query basado en el registro maestro
        try:  
            bAux = eval ( 'regBase.' + cUDP.udpTable.lower() + '_set.exists()' )
            cllUDP = eval ( 'regBase.' + cUDP.udpTable.lower() + '_set.all()' ) 
        except:  
            raise Exception( 'UdpError:  related_name  set not found ' + cUDP.udpTable.lower() ) 

    if bAux: 
        
        for lUDP in cllUDP:
            udpName = cUDP.propertyPrefix + '__' + getattr( lUDP, cUDP.propertyName  , '') 
            if udpName in udpList:
                sAux = getattr( lUDP, cUDP.propertyValue, '' )
                sAux = getTypedValue ( sAux , udpTypes[ udpName ])
                sAux = smart_str( sAux )
                
                if udpTypes[ udpName ] == 'html' and type( sAux ).__name__=='string'  : 
                    sAux = sAux.replace( '\n', '<br>').replace( '\r', '<br>')  
                    sAux = sAux.replace( '<br><br>', '<br>')
                    sAux = sAux.replace( '<td><br>', '<td>').replace( '</td><br>', '</td>')
                    sAux = sAux.replace( '<th><br>', '<th>').replace( '</th><br>', '</th>')
                    sAux = sAux.replace( '<tr><br>', '<tr>').replace( '</tr><br>', '</tr>')
                    sAux = sAux.replace( '<br><td>', '<td>').replace( '<br></td>', '</td>')
                    sAux = sAux.replace( '<br><th>', '<th>').replace( '<br></th>', '</th>')
                    sAux = sAux.replace( '<br><tr>', '<tr>').replace( '<br></tr>', '</tr>')
    
                rowdict[ udpName ] =  sAux 
def readUdps(rowdict, regBase, cUDP, udpList, udpTypes):

    if cUDP.keyField:
        # si la creacion del detalle no es relacional,
        # se requiere hacer un verdadero Query sobre udpTable
        UdpModel = getDjangoModel(cUDP.udpTable)
        keyValue = rowdict.get(cUDP.keyField, "")
        if not keyValue:
            raise Exception("UdpError: Key not found " + cUDP.keyField + " in masterReg")

        keyValue = smart_str(keyValue)
        bAux = True
        Qs = UdpModel.objects
        Qs = addFilter(Qs, {cUDP.propertyRef: keyValue})
        cllUDP = Qs.all()

    else:
        # Si no hay keyField, hace el query basado en el registro maestro
        try:
            bAux = eval("regBase." + cUDP.udpTable.lower() + "_set.exists()")
            cllUDP = eval("regBase." + cUDP.udpTable.lower() + "_set.all()")
        except:
            raise Exception("UdpError:  related_name  set not found " + cUDP.udpTable.lower())

    if bAux:

        for lUDP in cllUDP:
            udpName = cUDP.propertyPrefix + "__" + getattr(lUDP, cUDP.propertyName, "")
            if udpName in udpList:
                sAux = getattr(lUDP, cUDP.propertyValue, "")
                sAux = getTypedValue(sAux, udpTypes[udpName])
                sAux = smart_str(sAux)

                if udpTypes[udpName] == "html" and type(sAux).__name__ == "string":
                    sAux = sAux.replace("\n", "<br>").replace("\r", "<br>")
                    sAux = sAux.replace("<br><br>", "<br>")
                    sAux = sAux.replace("<td><br>", "<td>").replace("</td><br>", "</td>")
                    sAux = sAux.replace("<th><br>", "<th>").replace("</th><br>", "</th>")
                    sAux = sAux.replace("<tr><br>", "<tr>").replace("</tr><br>", "</tr>")
                    sAux = sAux.replace("<br><td>", "<td>").replace("<br></td>", "</td>")
                    sAux = sAux.replace("<br><th>", "<th>").replace("<br></th>", "</th>")
                    sAux = sAux.replace("<br><tr>", "<tr>").replace("<br></tr>", "</tr>")

                rowdict[udpName] = sAux
def addDetailToList(  detailList , detail,  detailPath   ):
    """ return parcial detail tree  ( Called from protoGetFieldTree )
    
    detailList    : Lista con los detalles 
    detail        : registro del detalle 
    detailField   : jerarquia vista desde el campo  
    detailPath    : jerarquia inversa vista desde el maestro 
    """


    if len( detailPath ) > 0:
        detailPath += '/'  
    detailPath +=  detail[ 'menuText' ]
    

    # Agrega el campo solicitado
    menuDetail = {
        "id"            : detailPath ,  
        "conceptDetail" : detail[ 'conceptDetail' ] , 
        "detailField"   : detail[ 'detailField' ] ,                    
        "masterField"   : 'pk',                
        "leaf"          : True 
        }
    
    detailList.append( menuDetail ) 
    
    # Evita demasiada recursividad ( 5 niveles debe ser mas q suficiente )
    # Si el mismo campo ya aparece en el camino seguramente es una autoreferencia
    detailField =  detail[ 'detailField' ]
    if detailField.count( '__') > 5 or detailField.count( '__' + detail[ 'detailName' ] + '__' ) > 0:
        return 

    else: 
        detailChild= []
        model = getDjangoModel( detail[ 'conceptDetail' ]  )
        modelDetails = getModelDetails( model )
        for sDetail in modelDetails: 
            sDetail[ 'detailField' ] = sDetail[ 'detailName' ] + '__' + detail[ 'detailField' ] 
            addDetailToList( detailChild,  sDetail ,  detailPath  )
    
        # Si el modelo de base es el modelo de trabajo, no entro al loop 
        if len( detailChild ) > 0:  
            menuDetail['leaf'] = False 
            menuDetail['children'] = detailChild
示例#16
0
def protoGetDetailsTree(request):
    """ return full field tree 
    """

    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 Exception, e:
        jsondict = {'success': False, 'message': getReadableError(e)}
        context = json.dumps(jsondict)
        return HttpResponse(context, content_type="application/json")
def protoGetDetailsTree(request):
    """ return full field tree 
    """

    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 Exception,  e:
        jsondict = { 'success':False, 'message': getReadableError( e ) }
        context = json.dumps( jsondict)
        return HttpResponse(context, content_type="application/json")
示例#18
0
def getReportBase( viewCode ):

    viewEntity  = getBaseModelName( viewCode )

    # Obtiene el modelo
    try:
        model = getDjangoModel(viewEntity)
    except Exception as e :
        pass

    # Obtiene la definicion
    try:
        protoDef  = ProtoDefinition.objects.get (code = viewCode )
        protoMeta = json.loads( protoDef.metaDefinition )
    except Exception as e :
        pass

    # hace el QSet de los registros seleccionados
    Qs = model.objects.select_related()

    return protoMeta, Qs
示例#19
0
def getReportBase( viewCode ):

    viewEntity  = getBaseModelName( viewCode )

    # Obtiene el modelo
    try:
        model = getDjangoModel(viewEntity)
    except Exception as e:
        pass

    # Obtiene la definicion
    try:
        protoDef  = ProtoDefinition.objects.get (code = viewCode )
        protoMeta = json.loads( protoDef.metaDefinition )
    except Exception as e:
        pass

    # hace el QSet de los registros seleccionados
    Qs = model.objects.select_related(depth=1)

    return protoMeta, Qs
示例#20
0
def protoExecuteAction(request):
    """ Ejecuta una opcion
    """
    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 doAdminAction(model, selectedKeys, parameters, actionDef, modelAdmin):

        for action in modelAdmin.actions:
            if action.__name__ == actionName:
                break

        if not action:
            return doReturn({'success': False, 'message': 'Action notFound'})

        Qs = model.objects.select_related()
        Qs = Qs.filter(pk__in=selectedKeys)

        try:
            returnObj = action(modelAdmin, request, Qs, parameters)
            return doReturn(returnObj)

        except Exception as e:
            return doReturn({'success': False, 'message': str(e)})

#   ----------------------------------------

    def doAdminDetailAction(model, selectedKeys, detKeys, parameters,
                            actionDef, modelAdmin):

        for action in modelAdmin.actions:
            if action.__name__ == actionName:
                break

        if not action:
            return doReturn({'success': False, 'message': 'Action notFound'})

        try:
            returnObj = action(modelAdmin, request, selectedKeys, detKeys,
                               parameters)
            return doReturn(returnObj)

        except Exception as e:
            return doReturn({'success': False, 'message': str(e)})

#   ----------------------------------------

    if not request.user.is_authenticated():
        return doReturn({'success': False, 'message': 'readOnly User'})

    if request.method != 'POST':
        return doReturn({'success': False, 'message': 'PostAction required'})

    actionName = request.POST.get('actionName', '')

    viewCode = request.POST.get('viewCode', '')
    viewEntity = getBaseModelName(viewCode)

    selectedKeys = request.POST.get('selectedKeys', [])
    selectedKeys = json.loads(selectedKeys)

    parameters = request.POST.get('parameters', [])
    parameters = json.loads(parameters)

    actionDef = request.POST.get('actionDef', {})
    actionDef = json.loads(actionDef)

    # hace el QSet de los registros seleccionados
    if actionDef.get('selectionMode',
                     '') != 'none' and selectedKeys.__len__() == 0:
        return doReturn({'success': False, 'message': 'No record selected'})

    # Obtiene el modelo
    try:
        model = getDjangoModel(viewEntity)
        modelAdmin = site._registry.get(model)
    except:
        return doReturn({'success': False, 'message': 'Model notFound'})

    # details
    if actionDef.get('selectionMode', '') == 'details':
        detKeys = request.POST.get('detKeys', {})
        detKeys = json.loads(detKeys)

        return doAdminDetailAction(model, selectedKeys, detKeys, parameters,
                                   actionDef, modelAdmin)

    elif actionDef.get('actionType', '') == 'wflow':
        return doWfAction(model, selectedKeys, parameters, actionDef,
                          viewEntity, request.user)

    elif hasattr(modelAdmin, 'actions'):
        return doAdminAction(model, selectedKeys, parameters, actionDef,
                             modelAdmin)

    else:
        return doReturn({'success': False, 'message': 'Action notFound'})


#   ----------------------------------------
示例#21
0
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 _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'] + ';'
示例#23
0
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' })
示例#24
0
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")
示例#25
0
def getQSet(protoMeta, protoFilter, baseFilter, sort, pUser):

    #   Decodifica los eltos
    viewEntity = protoMeta.get('viewEntity', '')
    model = getDjangoModel(viewEntity)

    #   Autentica '
    if not getModelPermissions(pUser, model, 'list'):
        return model.objects.none(), [], False, False

#   modelo Administrado
    isProtoModel = hasattr(model, '_protoObj')
    if isProtoModel:
        userNodes = getUserNodes(pUser, viewEntity)

#   WorkFlow Model
    hasWFlow = hasattr(model, '_WorkFlow')
    if hasWFlow:
        WFlowControl = getattr(model, '_WorkFlow', {})
        OkStatus = WFlowControl.get('OkStatus', 'Ok')

#   JsonField
    JsonField = protoMeta.get('jsonField', '')
    if not isinstance(JsonField, (str, unicode)):
        JsonField = ''

#   QSEt
#   Qs = model.objects.select_related(depth=1)
    Qs = model.objects

    #   Permite la lectura de todos los registros
    refAllow = getModelPermissions(pUser, model, 'refallow')

    #   Solamenete valida si es
    if isProtoModel and not pUser.is_superuser:

        # Si no tiene wflow y tampoco permiso de referencia, se limita a los nodos de su equipo
        if not refAllow:
            Qs = Qs.filter(smOwningTeam__in=userNodes)

        # Si tiene permiso de referencia y ademas WF, trae todos los propios o los demas en estado valido
        elif hasWFlow:
            Qs = Qs.filter(
                Q(smOwningTeam__in=userNodes)
                | Q(~Q(smOwningTeam__in=userNodes), Q(smWflowStatus=OkStatus)))

#   TODO: Agregar solomente los campos definidos en el safeMeta  ( only,  o defer )
#   Qs.query.select_fields = [f1, f2, .... ]

#   Le pega la meta al modelo para tomar por ejemplo searchFields
    model.protoMeta = protoMeta

    #   El filtro base viene en la configuracion MD
    try:
        Qs = addQbeFilter(baseFilter, model, Qs, JsonField)
    except Exception as e:
        traceback.print_exc()
        getReadableError(e)


#   Order by
    localSort = protoMeta.get('localSort', False)
    orderBy = []
    if not localSort:
        sort = verifyList(sort)
        for sField in sort:

            # Verificar que el campo de sort haga parte de los campos del modelo
            # blacklist = [f.name for f in instance._meta.fields] + ['id', 'user']

            # Unicode sort
            if sField['property'] == '__str__':
                try:
                    unicodeSort = getUnicodeFields(model)
                    for sAux in unicodeSort:
                        if sField['direction'] == 'DESC':
                            sAux = '-' + sAux
                        orderBy.append(sAux)
                except Exception as e:
                    pass

            else:
                if sField['direction'] == 'DESC':
                    sField['property'] = '-' + sField['property']
                orderBy.append(sField['property'])

    orderBy = tuple(orderBy)

    try:
        Qs = addQbeFilter(protoFilter, model, Qs, JsonField)
    except Exception as e:
        traceback.print_exc()
        getReadableError(e)

    # DbFirst en caso de q no exista una llave primaria
    fakeId = hasattr(model, '_fakeId')

    # Solo retorna refAllow si este es valido para la tabla ( no es un super usuario y es un modelo manejado por sm )
    refAllow = refAllow and isProtoModel and not pUser.is_superuser

    return Qs, orderBy, fakeId, refAllow
示例#26
0
文件: ZUDF.py 项目: douarime/ProtoExt
from models import getDjangoModel 

model = getDjangoModel( 'prototype.entity')
entityId = 20 
 
 
pEntity = model.objects.get( pk =  entityId )
ret = pEntity.model.project_id
ret =  projectId
def getQSet(protoMeta, protoFilter, baseFilter , sort , pUser):

#   Decodifica los eltos
    viewEntity = protoMeta.get('viewEntity', '')
    model = getDjangoModel(viewEntity)

#   Autentica '
    if not getModelPermissions(pUser, model, 'list'):
        return model.objects.none(), [], False, False 

#   modelo Administrado
    isProtoModel = hasattr(model , '_protoObj')
    if isProtoModel:
        userNodes = getUserNodes(pUser, viewEntity)

#   WorkFlow Model 
    hasWFlow = hasattr(model , '_WorkFlow')
    if hasWFlow: 
        WFlowControl = getattr(model, '_WorkFlow', {})
        OkStatus = WFlowControl.get('OkStatus', 'Ok')
        
#   JsonField
    JsonField = protoMeta.get('jsonField', '')
    if not isinstance(JsonField, (str, unicode)): 
        JsonField = ''

#   QSEt
#   Qs = model.objects.select_related(depth=1)
    Qs = model.objects

#   Permite la lectura de todos los registros 
    refAllow = getModelPermissions(pUser, model, 'refallow')
    

#   Solamenete valida si es     
    if isProtoModel and not pUser.is_superuser :

        # Si no tiene wflow y tampoco permiso de referencia, se limita a los nodos de su equipo    
        if not refAllow :
            Qs = Qs.filter(smOwningTeam__in=userNodes)

        # Si tiene permiso de referencia y ademas WF, trae todos los propios o los demas en estado valido 
        elif hasWFlow:
            Qs = Qs.filter(Q(smOwningTeam__in=userNodes) | Q(~Q(smOwningTeam__in=userNodes) , Q(smWflowStatus=OkStatus))) 

#   TODO: Agregar solomente los campos definidos en el safeMeta  ( only,  o defer )
#   Qs.query.select_fields = [f1, f2, .... ]


#   Le pega la meta al modelo para tomar por ejemplo searchFields
    model.protoMeta = protoMeta

#   El filtro base viene en la configuracion MD
    try:
        Qs = addQbeFilter(baseFilter, model, Qs , JsonField)
    except Exception as e:
        traceback.print_exc()
        getReadableError(e)

#   Order by
    localSort = protoMeta.get('localSort', False)
    orderBy = []
    if not localSort :
        sort = verifyList(sort)
        for sField in sort:

            # Verificar que el campo de sort haga parte de los campos del modelo
            # blacklist = [f.name for f in instance._meta.fields] + ['id', 'user']

            # Unicode sort
            if sField['property'] == '__str__' :
                try:
                    unicodeSort = getUnicodeFields(model)
                    for sAux in unicodeSort:
                        if sField['direction'] == 'DESC': 
                            sAux = '-' + sAux
                        orderBy.append(sAux)
                except Exception as e:
                    pass 
                
            else:
                if sField['direction'] == 'DESC': 
                    sField['property'] = '-' + sField['property']
                orderBy.append(sField['property'])

    orderBy = tuple(orderBy)

    try:
        Qs = addQbeFilter(protoFilter, model, Qs, JsonField)
    except Exception as e:
        traceback.print_exc()
        getReadableError(e)

    # DbFirst en caso de q no exista una llave primaria
    fakeId = hasattr(model , '_fakeId')

    # Solo retorna refAllow si este es valido para la tabla ( no es un super usuario y es un modelo manejado por sm )  
    refAllow = refAllow and isProtoModel and not pUser.is_superuser 

    return Qs, orderBy, fakeId, refAllow
示例#28
0
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")
示例#29
0
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' })
示例#30
0
def protoExecuteAction(request):
    """ Ejecuta una opcion
    """

    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 doAdminAction(model, selectedKeys, parameters, actionDef, modelAdmin):

        for action in modelAdmin.actions:
            if action.__name__ == actionName: break;
    
        if not action:
            return doReturn ({'success':False, 'message' : 'Action notFound'})
    
    
        Qs = model.objects.select_related(depth=1)
        Qs = Qs.filter(pk__in=selectedKeys)
    
        try:
            returnObj = action(modelAdmin, request, Qs , parameters)
            return doReturn (returnObj)
    
        except Exception as e:
            return doReturn ({'success':False, 'message' : str(e) })


#   ----------------------------------------
    if not request.user.is_authenticated():
        return doReturn ({'success':False , 'message' : 'readOnly User'})

    if request.method != 'POST':
        return doReturn ({'success':False , 'message' : 'PostAction required'})

    actionName = request.POST.get('actionName', '')

    viewCode = request.POST.get('viewCode', '')
    viewEntity = getBaseModelName(viewCode)

    selectedKeys = request.POST.get('selectedKeys', [])
    selectedKeys = json.loads(selectedKeys)

    parameters = request.POST.get('parameters', [])
    parameters = json.loads(parameters)

    actionDef = request.POST.get('actionDef', {})
    actionDef = json.loads(actionDef)

    # hace el QSet de los registros seleccionados
    if actionDef.get('selectionMode', '') != 'none' and selectedKeys.__len__() == 0:
        return doReturn ({'success':False, 'message' : 'No record selected'})


    # Obtiene el modelo
    try:
        model = getDjangoModel(viewEntity)
        modelAdmin = site._registry.get(model)
    except :
        return doReturn ({'success':False, 'message' : 'Model notFound'})


    if actionDef.get('actionType', '') == 'wflow': 
        return doWfAction(model, selectedKeys, parameters, actionDef, viewEntity, request.user)
         
    elif hasattr(modelAdmin, 'actions'):          
        return doAdminAction (model, selectedKeys, parameters, actionDef, modelAdmin)

    else: 
        return doReturn ({'success':False, 'message' : 'Action notFound'})
示例#31
0
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']  + ';'