1 # vim: set et sw=4 sts=4 encoding=utf-8 foldmethod=marker :
5 from turbogears import controllers, expose, redirect
6 from turbogears import validate, flash, error_handler
7 from turbogears import validators as V
8 from turbogears import widgets as W
9 from turbogears import identity
10 from turbogears import paginate
11 from docutils.core import publish_parts
12 from sercom.subcontrollers import validate as val
13 from sercom.model import Curso, AlumnoInscripto, Docente, Grupo, Alumno, Miembro
14 from sqlobject import *
15 from sqlobject.dberrors import *
16 from sercom.widgets import *
19 log = logging.getLogger('sercom.tester')
22 """ Administrador de grupos, mezclar, juntar, dividir"""
31 def validate_fk(data):
32 fk = data.get(fkname + 'ID', None)
38 flash(_(u'No se pudo crear el nuevo %s porque el %s con '
39 'identificador %d no existe.' % (name, fkname, fk)))
40 raise redirect('new', **data)
41 data.pop(fkname + 'ID', None)
46 return val.validate_get(cls, name, id)
48 def validate_set(id, data):
50 return val.validate_set(cls, name, id, data)
52 def validate_new(data):
54 return val.validate_new(cls, name, data)
57 return val.validate_del(cls, name, id)
62 return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
65 return [(0, u'---')] + [(fk1.id, fk1.shortrepr()) for fk1 in Curso.select()]
68 return [(0, u'---')] + [(g.id, g.shortrepr()) for g in Grupo.select()]
71 return [(0, u'Nuevo Grupo')] + [(g.id, g.shortrepr()) for g in Grupo.select()]
74 function alumnos_agregar_a_la_lista(texto, lista)
76 t = MochiKit.DOM.getElement(texto);
78 url = "/alumno/get_alumno?padron="+t.value;
85 alert("The metadata for MochiKit.Async could not be fetched :(");
88 function procesar(result)
90 l = MochiKit.DOM.getElement('form_responsable_info');
92 l.innerHTML = result.msg;
94 l.innerHTML = result.msg.value;
99 /* TODO : Validar datos y evitar el submit si no esta completo */
101 /* Selecciono todos los miembros si no, no llegan al controllere*/
102 l = MochiKit.DOM.getElement('form_grupos_to');
103 for (i=0; i<l.options.length; i++) {
104 l.options[i].selected = true;
106 /* Selecciono todos los miembros si no, no llegan al controllere*/
107 l = MochiKit.DOM.getElement('form_grupos_from');
108 for (i=0; i<l.options.length; i++) {
109 l.options[i].selected = true;
112 return true; // Dejo hacer el submit
115 function initWidgets(disabled) {
117 MochiKit.DOM.getElement('form_listaGrupoA').selectedIndex = 0;
119 MochiKit.DOM.getElement('form_listaGrupoB').selectedIndex = 0;
120 MochiKit.DOM.getElement('form_grupos_to').options.length = 0;
121 MochiKit.DOM.getElement('form_grupos_from').options.length = 0;
122 MochiKit.DOM.getElement('form_listaGrupoB').disabled = disabled;
123 MochiKit.DOM.getElement('form_grupos_to').disabled = disabled;
124 MochiKit.DOM.getElement('form_grupos_from').disabled = disabled;
127 function onListaAChange() {
128 lista = MochiKit.DOM.getElement('form_listaGrupoA');
129 if ( lista.selectedIndex != '0' ) {
135 // carga el grupo en el multiple select
136 grupoA = MochiKit.DOM.getElement('form_grupos_from');
137 id = lista.options[lista.selectedIndex].value
138 cargarGrupo(id, grupoA);
139 //carga la lista para seleccionar un responsable
140 responsableA = MochiKit.DOM.getElement('form_responsableA');
141 responsableA.options.length = 0;
142 MochiKit.DOM.appendChildNodes(responsableA, OPTION({"value":0}, "---"));
143 cargarGrupo(id, responsableA);
146 function onListaBChange() {
147 lista = MochiKit.DOM.getElement('form_listaGrupoB');
148 listaA = MochiKit.DOM.getElement('form_listaGrupoA');
149 MochiKit.DOM.getElement('form_grupos_to').options.length = 0;
150 if ( lista.selectedIndex == 0 ) {
153 if ( lista.selectedIndex != '0' ) {
154 if ( lista.selectedIndex == listaA.selectedIndex ) {
155 window.alert('Debe seleccionar 2 grupos distintos');
156 MochiKit.DOM.getElement('form_grupos_to').options.length = 0;
159 grupoB = MochiKit.DOM.getElement('form_grupos_to');
160 id = lista.options[lista.selectedIndex].value
161 cargarGrupo(id, grupoB);
163 //carga la lista para seleccionar un responsable
164 responsableB = MochiKit.DOM.getElement('form_responsableB');
165 responsableB.options.length = 0;
166 MochiKit.DOM.appendChildNodes(responsableB, OPTION({"value":0}, "---"));
167 cargarGrupo(id, responsableB);
171 function cargarGrupo(grupoid, lista) {
172 //url = "/grupo/get_inscripto?cursoid="+cursoid+'&padron='+padron
173 var result = loadJSONDoc('/curso/grupo/get_alumnos?grupoid='+id);
174 result.addCallbacks(partial(cargarLista, lista), err)
179 alert("The metadata for MochiKit.Async could not be fetched :(");
182 function cargarLista(lista, result) {
183 var alumnos = result.msg;
185 window.alert(result.msg);
190 label = alumnos[i].label;
191 MochiKit.DOM.appendChildNodes(lista, OPTION({"value":id}, label))
197 return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
199 class GrupoAdminForm(W.TableForm):
200 class Fields(W.WidgetsList):
201 listaGrupoA = W.SingleSelectField(label=_(u'Grupo A'), options = get_gruposA, attrs = dict(onChange='onListaAChange()'), validator = V.Int(not_empty=True))
202 listaGrupoB = W.SingleSelectField(label=_(u'Grupo B'), options = get_gruposB, attrs = dict(onChange='onListaBChange()'), validator = V.Int(not_empty=True))
203 grupos = AjaxDosListasSelect(label=_(u'Grupos'),title_from="Grupo A", size=8, title_to="Grupo B", validator=V.Int(not_empty=True))
204 responsableA = W.SingleSelectField(label=_(u'Responsable A'), validator = V.Int())
205 responsableB = W.SingleSelectField(label=_(u'Responsable B'), validator = V.Int())
206 tutoresA = W.MultipleSelectField(label=_(u'Tutores A'), options = get_docentes, validator = V.Int(not_empty=True))
207 tutoresB = W.MultipleSelectField(label=_(u'Tutores B'), options = get_docentes, validator = V.Int(not_empty=True))
210 javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('curso');"), W.JSSource(ajax)]
211 form_attrs = dict(onsubmit='return onsubmit()')
213 form = GrupoAdminForm()
218 class GrupoAdminController(controllers.Controller, identity.SecureResource):
219 """Basic model admin interface"""
220 require = identity.has_permission('admin')
223 def default(self, tg_errors=None):
224 """handle non exist urls"""
225 raise redirect('list')
229 raise redirect('list')
231 @expose(template='kid:%s.templates.list' % __name__)
234 """List records in model"""
236 return dict(records=r, name=name, namepl=namepl)
239 def activate(self, id, activo):
240 """Save or create record to model"""
242 raise redirect('../../list')
244 @expose(template='kid:%s.templates.new' % __name__)
245 def new(self, cursoId, **kw):
246 """Create new records in model"""
247 #form.fields[7].attrs['value'] = cursoId
248 return dict(name=name, namepl=namepl, form=form, values=kw, cursoId=int(cursoId))
253 def update(self, cursoid, **kw):
254 """Save or create record to model"""
257 grupoAId = kw['listaGrupoA']
258 grupoBId = kw['listaGrupoB']
259 miembrosA = kw.get('grupos_from', [])
260 miembrosB = kw.get('grupos_to', [])
261 responsableA = kw['responsableA']
262 responsableB = kw['responsableB']
263 tutoresA = kw.get('tutoresA', [])
264 tutoresB = kw.get('tutoresB', [])
266 # por las dudas de que no sea una lista
267 if not isinstance(miembrosA, list):
268 miembrosA = [miembrosA]
269 if not isinstance(miembrosB, list):
270 miembrosB = [miembrosB]
271 if not isinstance(tutoresA, list):
272 tutoresA = [tutoresA]
273 if not isinstance(tutoresB, list):
274 tutoresB = [tutoresB]
277 """ levanto los grupos originales """
278 grupoAorig = validate_get(int(grupoAId))
280 log.debug(Miembro.selectBy(grupo=grupoAorig, baja=None))
281 """ Si el grupo A quedo vacio deberia eliminarlo (primero
282 genero los otros para que no elimine los alumnos)"""
283 for mA in Miembro.selectBy(grupo=grupoAorig, baja=None):
284 if str(mA.alumno.id) not in miembrosA:
285 grupoAorig.remove_miembro(mA.alumno.id)
288 grupoA = validate_get(grupoAId)
291 grupoA.add_miembro(a, baja=None)
292 except DuplicateEntryError:
296 flash(_(u'Error A %s.' % e))
297 raise redirect('/grupo/list')
298 # seteo el reponsable del grupo
299 if int(responsableA) != 0:
300 grupoA.responsable = AlumnoInscripto.get(int(responsableA))
304 grupoA.add_tutor(int(t))
306 #TODO ver por que no anda el duplicate error, por ahora cacheo silencioso
310 #Elimino el grupo si quedo vacio
311 if len(miembrosA) == 0:
313 validate_del(grupoAId)
317 # si se selecciono un grupo nuevo
318 if int(grupoBId) == 0:
319 # creo un grupo nuevo
322 nuevosMiembros.append(AlumnoInscripto.get(int(m)))
325 nuevosTutores.append(Docente.get(t))
327 Grupo(miembros = nuevosMiembros, tutores = nuevosTutores, cursoID=cursoid, nombre='NuevoGrupo'+str(cursoid))
329 grupoBorig = validate_get(int(grupoBId))
331 b = list(Miembro.selectBy(grupo=grupoBorig, baja=None))
333 #borro todos y los vuelvo a agregar
334 for mB in Miembro.selectBy(grupo=grupoBorig, baja=None):
335 if str(mB.alumno.id) not in miembrosB:
336 grupoBorig.remove_miembro(mB.alumno.id)
338 grupoB = validate_get(grupoBId)
341 grupoB.add_miembro(b, baja=None)
342 except DuplicateEntryError:
346 flash(_(u'Error B %s.' % e))
347 raise redirect('/grupo/list')
348 # seteo el reponsable del grupo
349 if int(responsableB) != 0:
350 grupoB.responsable = AlumnoInscripto.get(int(responsableB))
352 #Elimino el grupo si quedo vacio
353 if len(miembrosB) == 0:
355 validate_del(grupoBId)
361 grupoB.add_tutor(int(t))
363 #TODO ver por que no anda el duplicate error, por ahora cahceo silencioso
367 flash(_(u'Los grupos fueron actualizado.'))
368 raise redirect('/grupo/list')
370 @expose(template='kid:%s.templates.show' % __name__)
371 def show(self,id, **kw):
372 """Show record in model"""
374 return dict(name=name, namepl=namepl, record=r)
377 def delete(self, id):
378 raise redirect('../grupo/list')