Beispiel #1
0
def addQbeFilter(protoFilter, model, Qs, JsonField):

    # No hay criterios
    if len(protoFilter) == 0:
        return Qs

    protoFilter = verifyList(protoFilter)

    for sFilter in protoFilter:

        if sFilter['property'] == '_allCols':
            # debe descomponer la busqueda usando el objeto Q
            QTmp = getTextSearch(sFilter, model, JsonField)
            if QTmp is None:
                QTmp = models.Q()

            try:
                Qs = Qs.filter(QTmp)
            except:
                traceback.print_exc()

        else:
            # Los campos simples se filtran directamente, se require para el JSonField
            QTmp = addQbeFilterStmt(sFilter, model, JsonField)
            QTmp = dict((x, y) for x, y in QTmp.children)
            try:
                Qs = Qs.filter(**QTmp)
            except:
                traceback.print_exc()

    return Qs
def addQbeFilter(protoFilter, model, Qs, JsonField):

    # No hay criterios
    if len(protoFilter) == 0:
        return Qs

    protoFilter = verifyList(protoFilter)

    for sFilter in protoFilter:

        if sFilter[ 'property' ] == '_allCols':
            # debe descomponer la busqueda usando el objeto Q
            QTmp = getTextSearch(sFilter, model, JsonField)
            if QTmp is None:  
                QTmp = models.Q()

            try:
                Qs = Qs.filter(QTmp)
            except:
                traceback.print_exc()

        else:
            # Los campos simples se filtran directamente, se require para el JSonField
            QTmp = addQbeFilterStmt(sFilter, model, JsonField)
            QTmp = dict((x, y) for x, y in QTmp.children)
            try:
                Qs = Qs.filter(**QTmp)
            except:
                traceback.print_exc()


    return Qs
Beispiel #3
0
    def __init__(self, model, viewCode, model_admin, protoMeta  ):
            
        self.model = model              # the model to use as reference
        self.title = self.model._meta.verbose_name.title()
        
        # importa las definiciones del modelo y del admin 
        self.model_admin =  model_admin
        self.protoMeta =  protoMeta
        
        # garantiza la llave 
        self.viewCode = viewCode  

        # Inicializa  
        self.fields = []                
        self.fieldsDict = {}
        self.gridConfig = self.protoMeta.get( 'gridConfig', {})

        # Los campos deben ser inicialmente un diccionario para poder validarlos 
        protoMeta[ 'fields' ]  =  protoMeta.get( 'fields', [])
        if isinstance( protoMeta[ 'fields' ], list )  :  
            self.fieldsDict = list2dict( protoMeta[ 'fields' ], 'name')


        #UDPs para poder determinar el valor por defecto ROnly 
        self.pUDP = self.protoMeta.get( 'usrDefProps', {}) 
        verifyUdpDefinition( self.pUDP )

        # lista de campos para la presentacion en la grilla 
        pListDisplay = verifyList( self.gridConfig.get( 'listDisplay', []) )
        if not pListDisplay: 
            pListDisplay = verifyList( getattr(self.model_admin , 'list_display', []))

            # Por defecto solo vienen  Chk, _str_
            try: pListDisplay.remove('action_checkbox')
            except ValueError:  pass
    
            # if pListDisplay and (pListDisplay[0] == '__str__'): pListDisplay = []
            if len(pListDisplay) == 0: pListDisplay = [ '__str__' ]
            
        self.gridConfig['listDisplay'] = pListDisplay 
        
        
        # Se leen los excluidos del admin, no se requiere 
        # en la protoDef, pues los campos se enumeran explicitamente 
        protoExclude = verifyList( self.protoMeta.get( 'exclude', []))

        #Se leen los readonly fields para setear el attr readOnly = true 
        pReadOnlyFlds = verifyList( self.gridConfig.get( 'readOnlyFields', []) )
        if not pReadOnlyFlds:
            pReadOnlyFlds =  verifyList( getattr(self.model_admin , 'readonly_fields', []))   

        self.gridConfig['readOnlyFields'] = pReadOnlyFlds 

        # @@ Por alguna Ext no retiene el IdProperty ( idInternal al hacer click en las filas )     
        # idName = model._meta.pk.name   
        
        # La lista de campos del admin sirve de base, pues puede haber muchos mas campos en proto q en admin
        # Si solo queda el __str__ , asume todos los campos del modelo
        
#        iCount = len( pListDisplay )  
#        if ( iCount == 0  ) or ( iCount == 1 and (pListDisplay[0] == '__str__')) :

        # Se crean los campos con base al modelo ( trae todos los campos del modelo )
        for field in self.model._meta._fields():
            if field.name in protoExclude: continue
            setFieldDict (  self.fieldsDict , field )


#         for field in self.model._meta._many_to_many():
#             if field.name in protoExclude: continue
#             setFieldDict (  self.fieldsDict , field )

        # Agrega el __str__ que sirve de base para los zooms
        fName = '__str__' 
        fdict = self.fieldsDict.get( fName , {}) 
        if not fdict: 
            fdict['name'] = fName
            self.fieldsDict[ fName ] = fdict
            
            setDefaultField ( fdict, self.model, self.viewCode )
             

        # Genera la lista de campos y agrega el nombre al diccionario 
        for key in self.fieldsDict:        
            fdict = self.fieldsDict[ key ]
            if (fdict.get( 'name', '') == '') : fdict[ 'name' ] = key  

            if key in pReadOnlyFlds: fdict[ 'readOnly' ] = True

            # Repasa las propiedades de base, ver por q no esta pasando trayendo las props de base ( ie:  defaulValue )  
            if ( not ( key.startswith( 'udp__') )):
                try: 
                    field = self.model._meta.get_field( key )
                    setFieldDict ( self.fieldsDict , field )
                    fdict = self.fieldsDict[ key ]
                except: 
                    #Es posible q se puedan configuar propiedades no pertenecientes a la tabla como editables???
                    fdict[ 'readOnly' ] = True
                    pass 

            self.fields.append(fdict)
Beispiel #4
0
    def getFieldSets(self):
        """ El field set determina la distribucion de los campos en la forma
        """ 
        
        pForm = self.protoMeta.get( 'formConfig', { 'items' : [] }) 
        prFieldSet = pForm[ 'items' ]
        
        # Si no han sido definido genera por defecto  
        if ( len( prFieldSet )   == 0 ):

            # Toma la lista del field set si no existe lo crea de base, 
            baseFieldSet = verifyList( getattr(self.model_admin , 'fieldsets', []))
            
            if (len( baseFieldSet )  == 0 ):        
                # Genera la lista de campos y agrega el nombre al diccionario

                prBlank = []                
                prItems = []                
                prTexts = []
                prChecks = []
#               prIds = []
                prAdmin = []
                                
                for key in self.fieldsDict:
                    vFld = self.fieldsDict.get( key , {})
                    fType = vFld.get( 'type', 'string' )
                    
                    if  vFld.get( 'crudType' ) == 'storeOnly' : continue

                    if ( key in [ 'smOwningUser','smOwningTeam','smCreatedBy','smModifiedBy','smWflowStatus','smRegStatus','smCreatedOn','smModifiedOn' ]) :
                        prAdmin.append( { 'name' : key  , '__ptType' : 'formField'} )
                    
                    elif ( fType == 'text') :
                        prTexts.append( { 'name' : key  , '__ptType' : 'formField'} ) 
                         
                    elif ( fType in ['autofield', 'foreignid'] ) :
#                        prIds.append( { 'name' : key  , '__ptType' : 'formField'} )
                        continue

                    elif ( fType  == 'bool' ) :
                        prChecks.append( { 'name' : key  , '__ptType' : 'formField'} )

                    elif ( fType == 'protoN2N' ) :
                        continue
#                        prN2N.append( { 'name' : key  , '__ptType' : 'formField'} )

                    elif ( key  == '__str__' ) :
#                        prTexts.insert( 0, { 'name' : key  , '__ptType' : 'formField'} )
                        continue

                    elif ( vFld.get( 'required', False  )  == False ): 
                        prBlank.append( { 'name' : key  , '__ptType' : 'formField'} )
                         
                    else:  
                        prItems.append( { 'name' : key  , '__ptType' : 'formField'} )


                if prItems : 
                    prSection = { '__ptType' : 'fieldset','fsLayout' : '2col'  }
                    prSection['items'] = prItems 
                    prFieldSet.append ( prSection )

                if prChecks : 
                    prSection = { '__ptType' : 'fieldset','fsLayout' : '2col'  }
                    prSection['items'] = prChecks 
                    prFieldSet.append ( prSection )

                if prBlank : 
                    prSection = { '__ptType' : 'fieldset','fsLayout' : '2col'  }
                    prSection['items'] = prBlank 
                    prFieldSet.append ( prSection )

                if prTexts : 
                    prSection = { '__ptType' : 'fieldset','fsLayout' : '1col'  }
                    prSection['items'] = prTexts 
                    prFieldSet.append ( prSection )


                if prAdmin : 
                    prSection = { '__ptType' : 'fieldset','fsLayout' : '2col', 
                                  'title' : 'Admin', 'collapsible' : True, 'collapsed' : True  }
                    prSection['items'] = prAdmin 
                    prFieldSet.append ( prSection )

#                if prIds : 
#                    prSection = { '__ptType' : 'fieldset','fsLayout' : '2col'  }
#                    prSection['items'] = prIds 
#                    prFieldSet.append ( prSection )

            
            # si existe un fieldset convierte la estructura                      
            else: 
                for name, opts in baseFieldSet:

                    prSection = { '__ptType' : 'fieldset', 'fsLayout' : '2col' }
                    if ( name != None ): 
                        prSection[ 'title' ]  = name.capitalize()  

                    classes = getattr( opts, 'classes', [] )
                    if ( 'collapse' in classes ): 
                        prSection['collapsible'] =  True   

                    prItems = []
                    for formField in opts['fields']:
                        getFieldsInSet( self, prItems, formField  )
                        
                    prSection['items'] =  prItems   
                    prFieldSet.append( prSection )
            
        return pForm 
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 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
Beispiel #7
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
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 __init__(self, model, viewCode, model_admin, protoMeta):

        self.model = model  # the model to use as reference
        self.title = self.model._meta.verbose_name.title()

        # importa las definiciones del modelo y del admin
        self.model_admin = model_admin
        self.protoMeta = protoMeta

        # garantiza la llave
        self.viewCode = viewCode

        # Inicializa
        self.fields = []
        self.fieldsDict = {}
        self.gridConfig = self.protoMeta.get('gridConfig', {})

        # Los campos deben ser inicialmente un diccionario para poder validarlos
        protoMeta['fields'] = protoMeta.get('fields', [])
        if isinstance(protoMeta['fields'], list):
            self.fieldsDict = list2dict(protoMeta['fields'], 'name')

        # UDPs para poder determinar el valor por defecto ROnly
        self.pUDP = self.protoMeta.get('usrDefProps', {})
        verifyUdpDefinition(self.pUDP)

        # lista de campos para la presentacion en la grilla
        pListDisplay = verifyList(self.gridConfig.get('listDisplay', []))
        if not pListDisplay:
            pListDisplay = verifyList(
                getattr(self.model_admin, 'list_display', []))

            # Por defecto solo vienen  Chk, _str_
            try:
                pListDisplay.remove('action_checkbox')
            except ValueError:
                pass

            if len(pListDisplay) == 0:
                pListDisplay = ['__str__']

        self.gridConfig['listDisplay'] = pListDisplay

        # Se leen los excluidos del admin, no se requiere
        # en la protoDef, pues los campos se enumeran explicitamente
        protoExclude = verifyList(self.protoMeta.get('exclude', []))

        # Se leen los readonly fields para setear el attr readOnly = true
        pReadOnlyFlds = verifyList(self.gridConfig.get('readOnlyFields', []))
        if not pReadOnlyFlds:
            pReadOnlyFlds = verifyList(
                getattr(self.model_admin, 'readonly_fields', []))

        self.gridConfig['readOnlyFields'] = pReadOnlyFlds

        # @@ Por alguna Ext no retiene el IdProperty ( idInternal al hacer click en las filas )
        # idName = model._meta.pk.name

        # La lista de campos del admin sirve de base, pues puede haber muchos mas campos en proto q en admin
        # Si solo queda el __str__ , asume todos los campos del modelo

        #        iCount = len( pListDisplay )
        #        if ( iCount == 0  ) or ( iCount == 1 and (pListDisplay[0] == '__str__')) :

        # Se crean los campos con base al modelo ( trae todos los campos del modelo )
        # for field in self.model._meta._fields(): #only for django 1.4
        for field in self.model._meta.fields:
            if field.name in protoExclude:
                continue
            setFieldDict(self.fieldsDict, field)

        # Agrega el __str__ que sirve de base para los zooms
        fName = '__str__'
        fdict = self.fieldsDict.get(fName, {})
        if not fdict:
            fdict['name'] = fName
            self.fieldsDict[fName] = fdict

            setDefaultField(fdict, self.model, self.viewCode)

        # Genera la lista de campos y agrega el nombre al diccionario
        for key in self.fieldsDict:
            fdict = self.fieldsDict[key]
            if (fdict.get('name', '') == ''):
                fdict['name'] = key

            if key in pReadOnlyFlds:
                fdict['readOnly'] = True

            # Repasa las propiedades de base, ver por q no esta pasando trayendo las props de base ( ie:  defaulValue )
            if (not (key.startswith('udp__'))):
                try:
                    field = self.model._meta.get_field(key)
                    setFieldDict(self.fieldsDict, field)
                    fdict = self.fieldsDict[key]
                except:
                    # Es posible q se puedan configuar propiedades no pertenecientes a la tabla como editables???
                    fdict['readOnly'] = True

            self.fields.append(fdict)
    def getFieldSets(self):
        """ El field set determina la distribucion de los campos en la forma
        """

        pForm = self.protoMeta.get('formConfig', {'items': []})
        prFieldSet = pForm['items']

        # Si no han sido definido genera por defecto
        if (len(prFieldSet) == 0):

            # Toma la lista del field set si no existe lo crea de base,
            baseFieldSet = verifyList(
                getattr(self.model_admin, 'fieldsets', []))

            if (len(baseFieldSet) == 0):
                # Genera la lista de campos y agrega el nombre al diccionario

                prBlank = []
                prItems = []
                prTexts = []
                prChecks = []
                #               prIds = []
                prAdmin = []

                for key in self.fieldsDict:
                    vFld = self.fieldsDict.get(key, {})
                    fType = vFld.get('type', 'string')

                    if vFld.get('crudType') == 'storeOnly':
                        continue

                    if (key in [
                            'smOwningUser', 'smOwningTeam', 'smCreatedBy',
                            'smCreatedOn', 'smModifiedBy', 'smModifiedOn',
                            'smWflowStatus', 'smRegStatus', 'smUUID'
                    ]):
                        prAdmin.append({'name': key, '__ptType': 'formField'})

                    elif (fType == 'text'):
                        prTexts.append({'name': key, '__ptType': 'formField'})

                    elif (fType in ['autofield', 'foreignid']):
                        continue

                    elif (fType == 'bool'):
                        prChecks.append({'name': key, '__ptType': 'formField'})

                    elif (fType == 'protoN2N'):
                        continue

                    elif (key == '__str__'):
                        continue

                    elif (vFld.get('required', False) == False):
                        prBlank.append({'name': key, '__ptType': 'formField'})

                    else:
                        prItems.append({'name': key, '__ptType': 'formField'})

                if prItems:
                    prSection = {'__ptType': 'fieldset', 'fsLayout': '2col'}
                    prSection['items'] = prItems
                    prFieldSet.append(prSection)

                if prChecks:
                    prSection = {'__ptType': 'fieldset', 'fsLayout': '2col'}
                    prSection['items'] = prChecks
                    prFieldSet.append(prSection)

                if prBlank:
                    prSection = {'__ptType': 'fieldset', 'fsLayout': '2col'}
                    prSection['items'] = prBlank
                    prFieldSet.append(prSection)

                if prTexts:
                    prSection = {'__ptType': 'fieldset', 'fsLayout': '1col'}
                    prSection['items'] = prTexts
                    prFieldSet.append(prSection)

                if prAdmin:
                    prSection = {
                        '__ptType': 'fieldset',
                        'fsLayout': '2col',
                        'title': 'Admin',
                        'collapsible': True,
                        'collapsed': True
                    }
                    prSection['items'] = prAdmin
                    prFieldSet.append(prSection)


#                if prIds :
#                    prSection = { '__ptType' : 'fieldset','fsLayout' : '2col'  }
#                    prSection['items'] = prIds
#                    prFieldSet.append ( prSection )

# si existe un fieldset convierte la estructura
            else:
                for name, opts in baseFieldSet:

                    prSection = {'__ptType': 'fieldset', 'fsLayout': '2col'}
                    if (name != None):
                        prSection['title'] = name.capitalize()

                    classes = getattr(opts, 'classes', [])
                    if ('collapse' in classes):
                        prSection['collapsible'] = True

                    prItems = []
                    for formField in opts['fields']:
                        getFieldsInSet(self, prItems, formField)

                    prSection['items'] = prItems
                    prFieldSet.append(prSection)

        return pForm