]> git.llucax.com Git - software/sercom.git/blob - sercom/subcontrollers/grupo_admin/__init__.py
5e3676ee23acb575e5d341aa48079d7b10b0b272
[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('/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", 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         log.debug(miembrosA)
267         log.debug(miembrosB)
268         """ levanto los grupos originales """
269         grupoAorig = validate_get(int(grupoAId))
270
271         """ Si el grupo A quedo vacio deberia eliminarlo (primero
272             genero los otros para que no elimine los alumnos)"""
273         for mA in Miembro.selectBy(grupo=grupoAorig, baja=None):
274             if str(mA.alumno.id) not in miembrosA:
275                 grupoAorig.remove_miembro(mA.alumno.id)
276
277         try:
278             grupoA = validate_get(grupoAId)
279             for a in miembrosA:
280                 try:
281                     grupoA.add_miembro(a, baja=None)
282                 except DuplicateEntryError:
283                     continue
284         except Exception, e:
285             flash(_(u'Error A %s.' % e))
286             raise redirect('/grupo/list')
287         # seteo el reponsable del grupo
288         if int(responsableA) != 0:
289             grupoA.responsable = AlumnoInscripto.get(int(responsableA))
290
291         for t in tutoresA:
292             try:
293                 grupoA.add_tutor(int(t))
294             except:
295                 #TODO ver por que no anda el duplicate error, por ahora cacheo silencioso
296                 pass
297
298
299         #Elimino el grupo si quedo vacio
300         if len(miembrosA) == 0:
301             try:
302                 validate_del(grupoAId)
303             except:
304                 pass
305
306         # si se selecciono un grupo nuevo
307         if int(grupoBId) == 0:
308             # creo un grupo nuevo
309             nuevosMiembros = []
310             for m in miembrosB:
311                 nuevosMiembros.append(AlumnoInscripto.get(int(m)))
312             nuevosTutores = []
313             for t in tutoresB:
314                 nuevosTutores.append(Docente.get(t))
315             #Creo el nuevo grupo
316             Grupo(miembros = nuevosMiembros, tutores = nuevosTutores, cursoID=cursoid, nombre='NuevoGrupo'+str(cursoid))
317         else:
318             grupoBorig = validate_get(int(grupoBId))
319             #borro todos y los vuelvo a agregar
320             for mB in Miembro.selectBy(grupo=grupoBorig, baja=None):
321                 if str(mB.alumno.id) not in miembrosB:
322                     grupoBorig.remove_miembro(mB.alumno.id)
323             try:
324                 grupoB = validate_get(grupoBId)
325                 for b in miembrosB:
326                     try:
327                         grupoB.add_miembro(b, baja=None)
328                     except DuplicateEntryError:
329                         continue
330             except Exception, e:
331                 flash(_(u'Error B %s.' % e))
332                 raise redirect('/grupo/list')
333             # seteo el reponsable del grupo
334             if int(responsableB) != 0:
335                 grupoB.responsable = AlumnoInscripto.get(int(responsableB))
336
337             #Elimino el grupo si quedo vacio
338             if len(miembrosB) == 0:
339                 try:
340                     validate_del(grupoBId)
341                 except:
342                     pass
343
344             for t in tutoresB:
345                 try:
346                     grupoB.add_tutor(int(t))
347                 except:
348                     #TODO ver por que no anda el duplicate error, por ahora cahceo silencioso
349                     pass
350
351
352         flash(_(u'Los grupos fueron actualizado.'))
353         raise redirect('/grupo/list')
354
355     @expose(template='kid:%s.templates.show' % __name__)
356     def show(self,id, **kw):
357         """Show record in model"""
358         r = validate_get(id)
359         return dict(name=name, namepl=namepl, record=r)
360
361     @expose()
362     def delete(self, id):
363         raise redirect('../grupo/list')
364 #}}}
365