]> git.llucax.com Git - software/sercom.git/blob - sercom/subcontrollers/grupo_admin/__init__.py
Agregar finalizador de entregas a TODO.
[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
16 from sercom.widgets import *
17
18 #}}}
19 """ Administrador de grupos, mezclar, juntar, dividir"""
20 #{{{ Configuración
21 cls = Grupo
22 name = 'grupo'
23 namepl = 'grupos'
24
25 #}}}
26
27 #{{{ Validación
28 def validate_fk(data):
29     fk = data.get(fkname + 'ID', None)
30     if fk == 0: fk = None
31     if fk is not None:
32         try:
33             fk = fkcls.get(fk)
34         except LookupError:
35             flash(_(u'No se pudo crear el nuevo %s porque el %s con '
36                 'identificador %d no existe.' % (name, fkname, fk)))
37             raise redirect('new', **data)
38     data.pop(fkname + 'ID', None)
39     data[fkname] = fk
40     return fk
41
42 def validate_get(id):
43     return val.validate_get(cls, name, id)
44
45 def validate_set(id, data):
46     validate_fk(data)
47     return val.validate_set(cls, name, id, data)
48
49 def validate_new(data):
50     validate_fk(data)
51     return val.validate_new(cls, name, data)
52
53 def validate_del(id):
54     return val.validate_del(cls, name, id)
55 #}}}
56
57 #{{{ Formulario
58 def get_docentes():
59     return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
60
61 def get_cursos():
62     return [(0, u'---')] + [(fk1.id, fk1.shortrepr()) for fk1 in Curso.select()]
63
64 def get_gruposA():
65     return [(0, u'---')] + [(g.id, g.shortrepr()) for g in Grupo.select()]
66
67 def get_gruposB():
68     return [(0, u'Nuevo Grupo')] + [(g.id, g.shortrepr()) for g in Grupo.select()]
69
70 ajax = u"""
71     function alumnos_agregar_a_la_lista(texto, lista)
72     {
73         t = MochiKit.DOM.getElement(texto);
74
75         url = "/alumno/get_alumno?padron="+t.value;
76         t.value = "";
77         return url;
78     }
79
80     function err (err)
81     {
82         alert("The metadata for MochiKit.Async could not be fetched :(");
83     }
84
85     function procesar(result)
86     {
87         l = MochiKit.DOM.getElement('form_responsable_info');
88         if (result.error)
89             l.innerHTML = result.msg;
90         else
91             l.innerHTML = result.msg.value;
92     }
93
94     function onsubmit()
95     {
96         /* TODO : Validar datos y evitar el submit si no esta completo */
97
98         /* Selecciono todos los miembros si no, no llegan al controllere*/
99         l = MochiKit.DOM.getElement('form_grupos_to');
100         for (i=0; i<l.options.length; i++) {
101             l.options[i].selected = true;
102         }
103         /* Selecciono todos los miembros si no, no llegan al controllere*/
104         l = MochiKit.DOM.getElement('form_grupos_from');
105         for (i=0; i<l.options.length; i++) {
106             l.options[i].selected = true;
107         }
108
109         return true; // Dejo hacer el submit
110     }
111
112     function initWidgets(disabled) {
113         if ( disabled ) {
114             MochiKit.DOM.getElement('form_listaGrupoA').selectedIndex = 0;
115         }
116         MochiKit.DOM.getElement('form_listaGrupoB').selectedIndex = 0;
117         MochiKit.DOM.getElement('form_grupos_to').options.length = 0;
118         MochiKit.DOM.getElement('form_grupos_from').options.length = 0;
119         MochiKit.DOM.getElement('form_listaGrupoB').disabled = disabled;
120         MochiKit.DOM.getElement('form_grupos_to').disabled = disabled;
121         MochiKit.DOM.getElement('form_grupos_from').disabled = disabled;
122     }
123
124     function onListaAChange() {
125         lista = MochiKit.DOM.getElement('form_listaGrupoA');
126         if ( lista.selectedIndex != '0' ) {
127             initWidgets(false);
128         } else {
129             initWidgets(true);
130             return;
131         }
132         // carga el grupo en el multiple select
133         grupoA = MochiKit.DOM.getElement('form_grupos_from');
134         id = lista.options[lista.selectedIndex].value
135         cargarGrupo(id, grupoA);
136         //carga la lista para seleccionar un responsable
137         responsableA = MochiKit.DOM.getElement('form_responsableA');
138         responsableA.options.length = 0;
139         MochiKit.DOM.appendChildNodes(responsableA, OPTION({"value":0}, "---"));
140         cargarGrupo(id, responsableA);
141     }
142
143     function onListaBChange() {
144         lista = MochiKit.DOM.getElement('form_listaGrupoB');
145         listaA =  MochiKit.DOM.getElement('form_listaGrupoA');
146         MochiKit.DOM.getElement('form_grupos_to').options.length = 0;
147         if ( lista.selectedIndex == 0 ) {
148             return;
149         }
150         if ( lista.selectedIndex != '0' ) {
151             if ( lista.selectedIndex == listaA.selectedIndex ) {
152                 window.alert('Debe seleccionar 2 grupos distintos');
153                 MochiKit.DOM.getElement('form_grupos_to').options.length = 0;
154                 return;
155             }
156             grupoB = MochiKit.DOM.getElement('form_grupos_to');
157             id = lista.options[lista.selectedIndex].value
158             cargarGrupo(id, grupoB);
159
160             //carga la lista para seleccionar un responsable
161             responsableB = MochiKit.DOM.getElement('form_responsableB');
162             responsableB.options.length = 0;
163             MochiKit.DOM.appendChildNodes(responsableB, OPTION({"value":0}, "---"));
164             cargarGrupo(id, responsableB);
165         }
166     }
167
168     function cargarGrupo(grupoid, lista) {
169         //url = "/grupo/get_inscripto?cursoid="+cursoid+'&padron='+padron
170         var result = loadJSONDoc('/grupo/get_alumnos?grupoid='+id);
171         result.addCallbacks(partial(cargarLista, lista), err)
172     }
173
174     function err (err)
175     {
176         alert("The metadata for MochiKit.Async could not be fetched :(");
177     }
178
179     function cargarLista(lista, result) {
180         var alumnos = result.msg;
181         if (result.error) {
182             window.alert(result.msg);
183             return;
184         }
185         for (i in alumnos) {
186             id = alumnos[i].id;
187             label = alumnos[i].label;
188             MochiKit.DOM.appendChildNodes(lista, OPTION({"value":id}, label))
189         }
190     }
191
192 """
193 def get_docentes():
194     return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
195
196 class GrupoAdminForm(W.TableForm):
197     class Fields(W.WidgetsList):
198         listaGrupoA = W.SingleSelectField(label=_(u'Grupo A'), options = get_gruposA, attrs = dict(onChange='onListaAChange()'), validator = V.Int(not_empty=True))
199         listaGrupoB = W.SingleSelectField(label=_(u'Grupo B'), options = get_gruposB, attrs = dict(onChange='onListaBChange()'), validator = V.Int(not_empty=True))
200         grupos = AjaxDosListasSelect(label=_(u'Grupos'),title_from="Grupo A", title_to="Grupo B", validator=V.Int(not_empty=True))
201         responsableA = W.SingleSelectField(label=_(u'Responsable A'), validator = V.Int())
202         responsableB = W.SingleSelectField(label=_(u'Responsable B'), validator = V.Int())
203         tutoresA = W.MultipleSelectField(label=_(u'Tutores A'), options = get_docentes, validator = V.Int(not_empty=True))
204         tutoresB = W.MultipleSelectField(label=_(u'Tutores B'), options = get_docentes, validator = V.Int(not_empty=True))
205
206     fields = Fields()
207     javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('curso');"), W.JSSource(ajax)]
208     form_attrs = dict(onsubmit='return onsubmit()')
209
210 form = GrupoAdminForm()
211
212 #}}}
213
214 #{{{ Controlador
215 class GrupoAdminController(controllers.Controller, identity.SecureResource):
216     """Basic model admin interface"""
217     require = identity.has_permission('admin')
218
219     @expose()
220     def default(self, tg_errors=None):
221         """handle non exist urls"""
222         raise redirect('list')
223
224     @expose()
225     def index(self):
226         raise redirect('list')
227
228     @expose(template='kid:%s.templates.list' % __name__)
229     @paginate('records')
230     def list(self):
231         """List records in model"""
232         r = cls.select()
233         return dict(records=r, name=name, namepl=namepl)
234
235     @expose()
236     def activate(self, id, activo):
237         """Save or create record to model"""
238         r = validate_get(id)
239         raise redirect('../../list')
240
241     @expose(template='kid:%s.templates.new' % __name__)
242     def new(self, cursoId, **kw):
243         """Create new records in model"""
244         #form.fields[7].attrs['value'] = cursoId
245         return dict(name=name, namepl=namepl, form=form, values=kw, cursoId=int(cursoId))
246
247     @validate(form=form)
248     @error_handler(list)
249     @expose()
250     def update(self, cursoid, **kw):
251         """Save or create record to model"""
252
253         print kw
254         grupoAId = kw['listaGrupoA']
255         grupoBId = kw['listaGrupoB']
256         miembrosA = kw.get('grupos_from', [])
257         miembrosB = kw.get('grupos_to', [])
258         responsableA = kw['responsableA']
259         responsableB = kw['responsableB']
260         tutoresA = kw.get('tutoresA', [])
261         tutoresB = kw.get('tutoresB', [])
262
263         """ levanto los grupos originales """
264         grupoAorig = validate_get(int(grupoAId))
265
266         """ Si el grupo A quedo vacio deberia eliminarlo (primero
267             genero los otros para que no elimine los alumnos)"""
268         for mA in Miembro.selectBy(grupo=grupoAorig, baja=None):
269             if str(mA.alumno.id) not in miembrosA:
270                 grupoAorig.remove_miembro(mA.alumno.id)
271
272         for a in miembrosA:
273             try:
274                 grupoA = Grupo.get(grupoAId)
275                 grupoA.add_miembro(a)
276             except:
277                 continue
278         # seteo el reponsable del grupo
279         if int(responsableA) != 0:
280             grupoA.responsable = AlumnoInscripto.get(int(responsableA))
281
282
283         #Elimino el grupo si quedo vacio
284         if len(miembrosA) == 0:
285             try:
286                 validate_del(grupoAId)
287             except:
288                 pass
289
290         # si se selecciono un grupo nuevo
291         if int(grupoBId) == 0:
292             # creo un grupo nuevo
293             nuevosMiembros = []
294             for m in miembrosB:
295                 nuevosMiembros.append(AlumnoInscripto.get(int(m)))
296             nuevosTutores = []
297             for t in tutoresB:
298                 nuevosTutores.append(Docente.get(t))
299             #Creo el nuevo grupo
300             Grupo(miembros = nuevosMiembros, tutores = nuevosTutores, cursoID=cursoid, nombre='NuevoGrupo'+str(cursoid))
301         else:
302             grupoBorig = validate_get(int(grupoBId))
303             #borro todos y los vuelvo a agregar
304             for mB in Miembro.selectBy(grupo=grupoBorig, baja=None):
305                 if str(mB.alumno.id) not in miembrosB:
306                     grupoBorig.remove_miembro(mB.alumno.id)
307             for b in miembrosB:
308                 try:
309                     grupoB = Grupo.get(grupoBId)
310                     grupoB.add_miembro(b)
311                 except:
312                     continue
313             # seteo el reponsable del grupo
314             if int(responsableB) != 0:
315                 grupoB.responsable = AlumnoInscripto.get(int(responsableB))
316
317             #Elimino el grupo si quedo vacio
318             if len(miembrosB) == 0:
319                 validate_del(grupoBId)
320
321
322         flash(_(u'Los grupos fueron actualizado.'))
323         raise redirect('/grupo/list')
324
325     @expose(template='kid:%s.templates.show' % __name__)
326     def show(self,id, **kw):
327         """Show record in model"""
328         r = validate_get(id)
329         return dict(name=name, namepl=namepl, record=r)
330
331     @expose()
332     def delete(self, id):
333         raise redirect('../grupo/list')
334 #}}}
335