36 |
36 |
from qommon import errors
|
37 |
37 |
from qommon import ods
|
38 |
38 |
from qommon.form import *
|
39 |
|
from qommon.storage import Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or, Intersects
|
|
39 |
from qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
|
|
40 |
Intersects, ILike)
|
40 |
41 |
|
41 |
42 |
from wcs.forms.backoffice import FormDefUI
|
42 |
43 |
from wcs.forms.common import FormStatusPage
|
|
44 |
from wcs.admin.settings import UserFieldsFormDef
|
43 |
45 |
|
44 |
46 |
from wcs.categories import Category
|
45 |
47 |
from wcs.formdef import FormDef
|
46 |
48 |
from wcs.roles import logged_users_role
|
47 |
49 |
|
48 |
50 |
|
|
51 |
|
|
52 |
class UserViewDirectory(Directory):
|
|
53 |
_q_exports = ['']
|
|
54 |
|
|
55 |
user = None
|
|
56 |
|
|
57 |
def __init__(self, user):
|
|
58 |
self.user = user
|
|
59 |
|
|
60 |
def _q_index(self):
|
|
61 |
get_response().breadcrumb.append(('%s/' % self.user.id, self.user.display_name))
|
|
62 |
html_top('management', _('Management'))
|
|
63 |
# display list of open formdata for the user
|
|
64 |
user_roles = [logged_users_role().id] + (get_request().user.roles or [])
|
|
65 |
criterias = [Equal('is_at_endpoint', False),
|
|
66 |
Equal('user_id', str(self.user.id)),
|
|
67 |
Intersects('concerned_roles_array', user_roles),
|
|
68 |
]
|
|
69 |
from wcs import sql
|
|
70 |
formdatas = sql.AnyFormData.select(criterias, order_by='-receipt_time', limit=50)
|
|
71 |
|
|
72 |
r = TemplateIO(html=True)
|
|
73 |
r += htmltext('<div class="bo-block">')
|
|
74 |
r += htmltext('<h2>%s</h2>') % self.user.display_name
|
|
75 |
formdef = UserFieldsFormDef()
|
|
76 |
r += htmltext('<div class="form">')
|
|
77 |
for field in formdef.fields:
|
|
78 |
if not hasattr(field, str('get_view_value')):
|
|
79 |
continue
|
|
80 |
value = self.user.form_data.get(field.id)
|
|
81 |
if not value:
|
|
82 |
continue
|
|
83 |
r += htmltext('<div class="title">')
|
|
84 |
r += field.label
|
|
85 |
r += htmltext('</div>')
|
|
86 |
r += htmltext('<div class="StringWidget content">')
|
|
87 |
r += field.get_view_value(value)
|
|
88 |
r += htmltext('</div>')
|
|
89 |
r += htmltext('</div>')
|
|
90 |
r += htmltext('</div>')
|
|
91 |
|
|
92 |
if formdatas:
|
|
93 |
categories = {}
|
|
94 |
formdata_by_category = {}
|
|
95 |
for formdata in formdatas:
|
|
96 |
if not formdata.formdef.category_id in categories:
|
|
97 |
categories[formdata.formdef.category_id] = formdata.formdef.category
|
|
98 |
formdata_by_category[formdata.formdef.category_id] = []
|
|
99 |
formdata_by_category[formdata.formdef.category_id].append(formdata)
|
|
100 |
cats = categories.values()
|
|
101 |
Category.sort_by_position(cats)
|
|
102 |
for cat in cats:
|
|
103 |
r += htmltext('<div class="bo-block">')
|
|
104 |
if len(cats) > 1:
|
|
105 |
if cat is None:
|
|
106 |
r += htmltext('<h2>%s</h2>') % _('Misc')
|
|
107 |
cat_formdatas = formdata_by_category[None]
|
|
108 |
else:
|
|
109 |
r += htmltext('<h2>%s</h2>') % cat.name
|
|
110 |
cat_formdatas = formdata_by_category[cat.id]
|
|
111 |
else:
|
|
112 |
cat_formdatas = formdatas
|
|
113 |
r += htmltext('<ul class="biglist">')
|
|
114 |
for formdata in cat_formdatas:
|
|
115 |
status = formdata.get_status()
|
|
116 |
if status:
|
|
117 |
status_label = status.name
|
|
118 |
else:
|
|
119 |
status_label = _('Unknown')
|
|
120 |
submit_date = misc.strftime.strftime(
|
|
121 |
misc.date_format(), formdata.receipt_time)
|
|
122 |
r += htmltext('<li><a href="%s">%s, '
|
|
123 |
'<span class="datetime">%s</span> '
|
|
124 |
'<span class="status">(%s)</span></a>' % (
|
|
125 |
formdata.get_url(backoffice=True),
|
|
126 |
formdata.formdef.name,
|
|
127 |
submit_date, status_label))
|
|
128 |
r += htmltext('</ul>')
|
|
129 |
r += htmltext('</div>')
|
|
130 |
r += htmltext('</div>')
|
|
131 |
|
|
132 |
return r.getvalue()
|
|
133 |
|
|
134 |
|
|
135 |
class UsersViewDirectory(Directory):
|
|
136 |
_q_exports = ['']
|
|
137 |
|
|
138 |
def _q_traverse(self, path):
|
|
139 |
if not get_publisher().is_using_postgresql():
|
|
140 |
raise errors.TraversalError()
|
|
141 |
get_response().breadcrumb.append(('users', _('360 User View')))
|
|
142 |
return super(UsersViewDirectory, self)._q_traverse(path)
|
|
143 |
|
|
144 |
def get_search_sidebar(self, offset=None, limit=None, order_by=None):
|
|
145 |
get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'wcs.listing.js'])
|
|
146 |
get_response().add_css_include('../js/smoothness/jquery-ui-1.10.0.custom.min.css')
|
|
147 |
|
|
148 |
r = TemplateIO(html=True)
|
|
149 |
r += htmltext('<form id="listing-settings" action=".">')
|
|
150 |
if offset or limit:
|
|
151 |
if not offset:
|
|
152 |
offset = 0
|
|
153 |
r += htmltext('<input type="hidden" name="offset" value="%s"/>') % offset
|
|
154 |
if limit:
|
|
155 |
r += htmltext('<input type="hidden" name="limit" value="%s"/>') % limit
|
|
156 |
|
|
157 |
if order_by is None:
|
|
158 |
order_by = ''
|
|
159 |
r += htmltext('<input type="hidden" name="order_by" value="%s"/>') % order_by
|
|
160 |
|
|
161 |
r += htmltext('<h3>%s</h3>') % _('Search')
|
|
162 |
if get_request().form.get('q'):
|
|
163 |
q = get_request().form.get('q')
|
|
164 |
if type(q) is not unicode:
|
|
165 |
q = unicode(q, get_publisher().site_charset)
|
|
166 |
r += htmltext('<input name="q" value="%s">') % q.encode(get_publisher().site_charset)
|
|
167 |
else:
|
|
168 |
r += htmltext('<input name="q">')
|
|
169 |
r += htmltext('<input type="submit" value="%s"/>') % _('Search')
|
|
170 |
|
|
171 |
return r.getvalue()
|
|
172 |
|
|
173 |
def _q_index(self):
|
|
174 |
html_top('management', _('Management'))
|
|
175 |
r = TemplateIO(html=True)
|
|
176 |
|
|
177 |
limit = int(get_request().form.get('limit',
|
|
178 |
get_publisher().get_site_option('default-page-size')) or 20)
|
|
179 |
offset = int(get_request().form.get('offset', 0))
|
|
180 |
order_by = get_request().form.get('order_by', None) or 'name'
|
|
181 |
query = get_request().form.get('q')
|
|
182 |
|
|
183 |
get_response().filter['sidebar'] = self.get_search_sidebar(
|
|
184 |
limit=limit, offset=offset, order_by=order_by)
|
|
185 |
|
|
186 |
if not query:
|
|
187 |
r += htmltext('<div id="listing">')
|
|
188 |
r += htmltext('<div class="big-msg-info">')
|
|
189 |
r += htmltext('<p>%s</p>') % _('Use the search field on the right '
|
|
190 |
'to look for an user.')
|
|
191 |
r += htmltext('</div>')
|
|
192 |
r += htmltext('</div>')
|
|
193 |
if get_request().form.get('ajax') == 'true':
|
|
194 |
get_response().filter = None
|
|
195 |
return r.getvalue()
|
|
196 |
|
|
197 |
criterias = []
|
|
198 |
criteria_fields = [ILike('name', query), ILike('email', query)]
|
|
199 |
formdef = UserFieldsFormDef()
|
|
200 |
for field in formdef.fields:
|
|
201 |
if field.type in ('string', 'text', 'email'):
|
|
202 |
criteria_fields.append(ILike('f%s' % field.id, query))
|
|
203 |
criterias.append(Or(criteria_fields))
|
|
204 |
|
|
205 |
users = get_publisher().user_class.select(order_by=order_by,
|
|
206 |
clause=criterias, limit=limit, offset=offset)
|
|
207 |
total_count = get_publisher().user_class.count(criterias)
|
|
208 |
|
|
209 |
users_cfg = get_cfg('users', {})
|
|
210 |
include_name_column = not(users_cfg.get('field_name'))
|
|
211 |
include_email_column = not(users_cfg.get('field_email'))
|
|
212 |
r += htmltext('<div id="listing">')
|
|
213 |
r += htmltext('<table class="main">')
|
|
214 |
r += htmltext('<thead>')
|
|
215 |
r += htmltext('<tr>')
|
|
216 |
if include_name_column:
|
|
217 |
r += htmltext('<th data-field-sort-key="name"><span>%s</span></th>') % _('Name')
|
|
218 |
if include_email_column:
|
|
219 |
r += htmltext('<th data-field-sort-key="email"><span>%s</span></th>') % _('Email')
|
|
220 |
for field in formdef.fields:
|
|
221 |
if field.in_listing:
|
|
222 |
r += htmltext('<th data-field-sort-key="f%s"><span>%s</span></th>') % (
|
|
223 |
field.id, field.label)
|
|
224 |
r += htmltext('</tr>')
|
|
225 |
r += htmltext('</thead>')
|
|
226 |
r += htmltext('<tbody>')
|
|
227 |
|
|
228 |
for user in users:
|
|
229 |
r += htmltext('<tr data-link="%s/">') % user.id
|
|
230 |
if include_name_column:
|
|
231 |
r += htmltext('<td>%s</td>') % (user.name or '')
|
|
232 |
if include_email_column:
|
|
233 |
r += htmltext('<td>%s</td>') % (user.email or '')
|
|
234 |
for field in formdef.fields:
|
|
235 |
if field.in_listing:
|
|
236 |
r += htmltext('<td>%s</td>') % (user.form_data.get(field.id) or '')
|
|
237 |
r += htmltext('</tr>')
|
|
238 |
|
|
239 |
r += htmltext('</tbody>')
|
|
240 |
r += htmltext('</table>')
|
|
241 |
|
|
242 |
if (offset > 0) or (total_count > limit > 0):
|
|
243 |
r += pagination_links(offset, limit, total_count)
|
|
244 |
|
|
245 |
r += htmltext('</div>')
|
|
246 |
|
|
247 |
if get_request().form.get('ajax') == 'true':
|
|
248 |
get_response().filter = None
|
|
249 |
return r.getvalue()
|
|
250 |
|
|
251 |
return r.getvalue()
|
|
252 |
|
|
253 |
def _q_lookup(self, component):
|
|
254 |
try:
|
|
255 |
user = get_publisher().user_class.get(component)
|
|
256 |
return UserViewDirectory(user)
|
|
257 |
except KeyError:
|
|
258 |
pass
|
|
259 |
raise errors.TraversalError()
|
|
260 |
|
|
261 |
|
49 |
262 |
class ManagementDirectory(Directory):
|
50 |
|
_q_exports = ['', 'listing', 'statistics', 'code', 'count']
|
|
263 |
_q_exports = ['', 'listing', 'statistics', 'code', 'count', 'users']
|
|
264 |
|
|
265 |
users = UsersViewDirectory()
|
51 |
266 |
|
52 |
267 |
def is_accessible(self, user):
|
53 |
268 |
return user.can_go_in_backoffice()
|
... | ... | |
120 |
335 |
if get_publisher().is_using_postgresql() and \
|
121 |
336 |
get_publisher().get_site_option('postgresql_views') != 'false':
|
122 |
337 |
r += htmltext('<li><a href="listing">%s</a></li>') % _('Global View')
|
|
338 |
r += htmltext('<li><a href="users/">%s</a></li>') % _('360 User View')
|
123 |
339 |
r += htmltext('</ul>')
|
124 |
340 |
r += htmltext('</div>')
|
125 |
341 |
r += self.get_tracking_code_sidebox()
|