2
# SchoolTool - common information systems platform for school administration
3
# Copyright (c) 2013 Shuttleworth Foundation
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
from persistent import Persistent
24
import zope.schema.vocabulary
25
from zope.container.contained import Contained
26
from zope.container.btree import BTreeContainer
27
from zope.container.ordered import OrderedContainer
28
from zope.interface import implements, implementer, implementsOnly
29
from zope.interface import Interface
30
from zope.component import adapts, adapter
31
from zope.location.location import locate
34
import z3c.form.widget
35
import z3c.form.interfaces
36
from z3c.form.browser.select import SelectWidget
38
from schooltool.app.app import InitBase, StartUpBase
39
from schooltool.app.interfaces import IRelationshipState
40
from schooltool.app.interfaces import IRelationshipStateChoice
41
from schooltool.app.interfaces import IRelationshipStates
42
from schooltool.app.interfaces import IRelationshipStateContainer
43
from schooltool.app.interfaces import ISchoolToolApplication
44
from schooltool.relationship.temporal import ACTIVE, INACTIVE
46
from schooltool.common import SchoolToolMessage as _
49
RELATIONSHIP_STATES_APP_KEY = 'schooltool.app.relationships-states'
52
class RelationshipState(Persistent, Contained):
53
implements(IRelationshipState)
58
def __init__(self, title, active, code=None):
60
self.active = ''.join(sorted(set(active)))
69
if name == self.__name__:
71
container = self.__parent__
74
del container[self.__name__]
75
container[name] = self
78
class RelationshipStates(Persistent, Contained):
79
implements(IRelationshipStates)
84
factory = RelationshipState
86
def __init__(self, title):
88
self.states = OrderedContainer()
89
locate(self.states, self, 'states')
90
self.system_titles = OrderedContainer()
91
locate(self.system_titles, self, 'system_titles')
94
return iter(self.states.values())
96
def getState(self, state_tuple):
97
if state_tuple is None:
99
meaning, code = state_tuple
100
state = self.states.get(code)
103
def getTitle(self, state_tuple):
104
state = self.getState(state_tuple)
109
def getDescription(self, state_tuple):
110
if state_tuple is None:
112
meaning, code = state_tuple
113
state = self.system_titles.get(meaning)
117
def overlap(cls, codes, other):
123
def add(self, *args, **kw):
124
state = self.factory(*args, **kw)
125
self.states[state.code] = state
127
def describe(self, active, title):
128
active = ''.join(sorted(set(active)))
129
self.system_titles[active] = title
132
class RelationshipStateContainer(BTreeContainer):
133
implements(IRelationshipStateContainer)
136
class VivifyStateContainer(object):
139
if RELATIONSHIP_STATES_APP_KEY not in self.app:
140
self.app[RELATIONSHIP_STATES_APP_KEY] = RelationshipStateContainer()
143
class StateInit(VivifyStateContainer, InitBase):
147
class StateStartUp(VivifyStateContainer, StartUpBase):
151
class StateStartUpBase(StartUpBase):
153
after = ('schooltool.app.states', )
157
def populate(self, states):
158
states.describe(ACTIVE, _('Active'))
159
states.describe(INACTIVE, _('Inactive'))
161
def create(self, title):
162
return RelationshipStates(title)
165
if self.states_name is None:
166
raise NotImplementedError()
167
container = IRelationshipStateContainer(self.app)
168
if self.states_name not in container:
170
container[self.states_name] = self.create(self.states_title)
171
self.populate(container[self.states_name])
174
del container[self.states_name]
180
@adapter(ISchoolToolApplication)
181
@implementer(IRelationshipStateContainer)
182
def getStateContainer(app):
183
return app[RELATIONSHIP_STATES_APP_KEY]
186
class RelationshipStateTerms(z3c.form.term.Terms):
188
adapts(Interface, z3c.form.interfaces.IFormLayer, Interface,
189
IRelationshipStateChoice, z3c.form.interfaces.IWidget)
190
implementsOnly(z3c.form.interfaces.ITerms)
192
def __init__(self, context, request, form, field, widget):
193
self.context = context
194
self.request = request
198
self.terms = self.getVocabulary()
200
def getVocabulary(self):
201
app = ISchoolToolApplication(None)
202
container = IRelationshipStateContainer(app)
203
relationships = container.get(self.field.source)
205
zope.schema.vocabulary.SimpleTerm(
206
state, token=state.__name__, title=state.title)
207
for state in relationships.states.values()]
208
vocabulary = zope.schema.vocabulary.SimpleVocabulary(terms)
212
class RelationshipStateChoice(zope.schema.Field):
213
implements(IRelationshipStateChoice)
217
def __init__(self, source=None, **kw):
219
zope.schema.Field.__init__(self, **kw)
222
@adapter(IRelationshipStateChoice, z3c.form.interfaces.IFormLayer)
223
@implementer(z3c.form.interfaces.IFieldWidget)
224
def RelationshipStateFieldWidget(field, request):
225
return z3c.form.widget.FieldWidget(field, SelectWidget(request))
228
class GroupMembershipStatesStartup(StateStartUpBase):
230
states_name = 'group-membership'
231
states_title = _('Group Membership')
233
def populate(self, states):
234
super(GroupMembershipStatesStartup, self).populate(states)
235
states.add(_('Pending'), INACTIVE, 'i')
236
states.add(_('Member'), ACTIVE, 'a')
237
states.add(_('Suspended'), INACTIVE, 's')
238
states.add(_('Removed'), INACTIVE, 'r')
245
class StudentMembershipStatesStartup(StateStartUpBase):
247
states_name = 'student-enrollment'
248
states_title = _('Student Enrollment')
250
def populate(self, states):
251
super(StudentMembershipStatesStartup, self).populate(states)
252
states.add(_('Pending'), INACTIVE, 'i')
253
states.add(_('Pre-enrolled'), INACTIVE+PREENROLLED, 'p')
254
states.add(_('Enrolled'), ACTIVE, 'a')
255
states.add(_('Graduated/Active'), ACTIVE+GRADUATED, 'c')
256
states.add(_('Graduated/Inactive'), INACTIVE+GRADUATED, 'r')
257
states.add(_('Withdrawn'), INACTIVE, 'w')
258
states.describe(INACTIVE+PREENROLLED, _('Pre-enrolled'))
259
states.describe(ACTIVE+GRADUATED, _('Graduated/Active'))
260
states.describe(INACTIVE+GRADUATED, _('Graduated/Inactive'))
263
class LeadershipStatesStartUp(StateStartUpBase):
265
states_name = 'asset-leaders'
266
states_title = _('Leaders')
268
def populate(self, states):
269
super(LeadershipStatesStartUp, self).populate(states)
270
states.add(_('Active'), ACTIVE, 'a')
271
states.add(_('Inactive'), INACTIVE, 'i')
274
class StudentLevelsStatesStartup(StateStartUpBase):
276
states_name = 'student-levels'
277
states_title = _('Student Levels')
279
def populate(self, states):
280
super(StudentLevelsStatesStartup, self).populate(states)
281
states.add(_('Pre-enrolled'), INACTIVE+PREENROLLED, 'p')
282
states.add(_('Enrolled'), ACTIVE, 'a')
283
states.add(_('Graduated'), INACTIVE+GRADUATED, 'c')
284
states.add(_('Inactive'), INACTIVE, 'i')
285
states.describe(INACTIVE+PREENROLLED, _('Pre-enrolled'))
286
states.describe(INACTIVE+GRADUATED, _('Graduated'))