]> git.llucax.com Git - software/sercom.git/blob - sercom/subcontrollers/grupo_admin/__init__.py
Permitir pasar el el archivo de configuración por línea de comandos al tester.
[software/sercom.git] / sercom / subcontrollers / grupo_admin / __init__.py
1 # vim: set et sw=4 sts=4 encoding=utf-8 foldmethod=marker :
2
3 #{{{ Imports
4 import cherrypy
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 *
17 import logging
18
19 log = logging.getLogger('sercom.tester')
20
21 #}}}
22 """ Administrador de grupos, mezclar, juntar, dividir"""
23 #{{{ Configuración
24 cls = Grupo
25 name = 'grupo'
26 namepl = 'grupos'
27
28 #}}}
29
30 #{{{ Validación
31 def validate_fk(data):
32     fk = data.get(fkname + 'ID', None)
33     if fk == 0: fk = None
34     if fk is not None:
35         try:
36             fk = fkcls.get(fk)
37         except LookupError:
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)
42     data[fkname] = fk
43     return fk
44
45 def validate_get(id):
46     return val.validate_get(cls, name, id)
47
48 def validate_set(id, data):
49     validate_fk(data)
50     return val.validate_set(cls, name, id, data)
51
52 def validate_new(data):
53     validate_fk(data)
54     return val.validate_new(cls, name, data)
55
56 def validate_del(id):
57     return val.validate_del(cls, name, id)
58 #}}}
59
60 #{{{ Formulario
61 def get_docentes():
62     return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
63
64 def get_cursos():
65     return [(0, u'---')] + [(fk1.id, fk1.shortrepr()) for fk1 in Curso.select()]
66
67 def get_gruposA():
68     return [(0, u'---')] + [(g.id, g.shortrepr()) for g in Grupo.select()]
69
70 def get_gruposB():
71     return [(0, u'Nuevo Grupo')] + [(g.id, g.shortrepr()) for g in Grupo.select()]
72
73 ajax = u"""
74     function alumnos_agregar_a_la_lista(texto, lista)
75     {
76         t = MochiKit.DOM.getElement(texto);
77
78         url = "/alumno/get_alumno?padron="+t.value;
79         t.value = "";
80         return url;
81     }
82
83     function err (err)
84     {
85         alert("The metadata for MochiKit.Async could not be fetched :(");
86     }
87
88     function procesar(result)
89     {
90         l = MochiKit.DOM.getElement('form_responsable_info');
91         if (result.error)
92             l.innerHTML = result.msg;
93         else
94             l.innerHTML = result.msg.value;
95     }
96
97     function onsubmit()
98     {
99         /* TODO : Validar datos y evitar el submit si no esta completo */
100
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;
105         }
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;
110         }
111
112         return true; // Dejo hacer el submit
113     }
114
115     function initWidgets(disabled) {
116         if ( disabled ) {
117             MochiKit.DOM.getElement('form_listaGrupoA').selectedIndex = 0;
118         }
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;
125     }
126
127     function onListaAChange() {
128         lista = MochiKit.DOM.getElement('form_listaGrupoA');
129         if ( lista.selectedIndex != '0' ) {
130             initWidgets(false);
131         } else {
132             initWidgets(true);
133             return;
134         }
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);
144     }
145
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 ) {
151             return;
152         }
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;
157                 return;
158             }
159             grupoB = MochiKit.DOM.getElement('form_grupos_to');
160             id = lista.options[lista.selectedIndex].value
161             cargarGrupo(id, grupoB);
162
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);
168         }
169     }
170
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)
175     }
176
177     function err (err)
178     {
179         alert("The metadata for MochiKit.Async could not be fetched :(");
180     }
181
182     function cargarLista(lista, result) {
183         var alumnos = result.msg;
184         if (result.error) {
185             window.alert(result.msg);
186             return;
187         }
188         for (i in alumnos) {
189             id = alumnos[i].id;
190             label = alumnos[i].label;
191             MochiKit.DOM.appendChildNodes(lista, OPTION({"value":id}, label))
192         }
193     }
194
195 """
196 def get_docentes():
197     return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
198
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))
208
209     fields = Fields()
210     javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('curso');"), W.JSSource(ajax)]
211     form_attrs = dict(onsubmit='return onsubmit()')
212
213 form = GrupoAdminForm()
214
215 #}}}
216
217 #{{{ Controlador
218 class GrupoAdminController(controllers.Controller, identity.SecureResource):
219     """Basic model admin interface"""
220     require = identity.has_permission('admin')
221
222     @expose()
223     def default(self, tg_errors=None):
224         """handle non exist urls"""
225         raise redirect('list')
226
227     @expose()
228     def index(self):
229         raise redirect('list')
230
231     @expose(template='kid:%s.templates.list' % __name__)
232     @paginate('records')
233     def list(self):
234         """List records in model"""
235         r = cls.select()
236         return dict(records=r, name=name, namepl=namepl)
237
238     @expose()
239     def activate(self, id, activo):
240         """Save or create record to model"""
241         r = validate_get(id)
242         raise redirect('../../list')
243
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))
249
250     @validate(form=form)
251     @error_handler(list)
252     @expose()
253     def update(self, cursoid, **kw):
254         """Save or create record to model"""
255
256         log.debug(kw)
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', [])
265
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]
275
276
277         """ levanto los grupos originales """
278         grupoAorig = validate_get(int(grupoAId))
279         log.debug(miembrosA)
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)
286
287         try:
288             grupoA = validate_get(grupoAId)
289             for a in miembrosA:
290                 try:
291                     grupoA.add_miembro(a, baja=None)
292                 except DuplicateEntryError:
293                     continue
294         except Exception, e:
295             log.debug(e)
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))
301
302         for t in tutoresA:
303             try:
304                 grupoA.add_tutor(int(t))
305             except:
306                 #TODO ver por que no anda el duplicate error, por ahora cacheo silencioso
307                 pass
308
309
310         #Elimino el grupo si quedo vacio
311         if len(miembrosA) == 0:
312             try:
313                 validate_del(grupoAId)
314             except:
315                 pass
316
317         # si se selecciono un grupo nuevo
318         if int(grupoBId) == 0:
319             # creo un grupo nuevo
320             nuevosMiembros = []
321             for m in miembrosB:
322                 nuevosMiembros.append(AlumnoInscripto.get(int(m)))
323             nuevosTutores = []
324             for t in tutoresB:
325                 nuevosTutores.append(Docente.get(t))
326             #Creo el nuevo grupo
327             Grupo(miembros = nuevosMiembros, tutores = nuevosTutores, cursoID=cursoid, nombre='NuevoGrupo'+str(cursoid))
328         else:
329             grupoBorig = validate_get(int(grupoBId))
330             log.debug(miembrosB)
331             b = list(Miembro.selectBy(grupo=grupoBorig, baja=None))
332             log.debug(b)
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)
337             try:
338                 grupoB = validate_get(grupoBId)
339                 for b in miembrosB:
340                     try:
341                         grupoB.add_miembro(b, baja=None)
342                     except DuplicateEntryError:
343                         continue
344             except Exception, e:
345                 log.debug(e)
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))
351
352             #Elimino el grupo si quedo vacio
353             if len(miembrosB) == 0:
354                 try:
355                     validate_del(grupoBId)
356                 except:
357                     pass
358
359             for t in tutoresB:
360                 try:
361                     grupoB.add_tutor(int(t))
362                 except:
363                     #TODO ver por que no anda el duplicate error, por ahora cahceo silencioso
364                     pass
365
366
367         flash(_(u'Los grupos fueron actualizado.'))
368         raise redirect('/grupo/list')
369
370     @expose(template='kid:%s.templates.show' % __name__)
371     def show(self,id, **kw):
372         """Show record in model"""
373         r = validate_get(id)
374         return dict(name=name, namepl=namepl, record=r)
375
376     @expose()
377     def delete(self, id):
378         raise redirect('../grupo/list')
379 #}}}
380