~dongpo-deng/sahana-eden/test

« back to all changes in this revision

Viewing changes to models/dvi.py

  • Committer: Deng Dongpo
  • Date: 2010-08-01 09:29:44 UTC
  • Revision ID: dongpo@dhcp-21193.iis.sinica.edu.tw-20100801092944-8t9obt4xtl7otesb
initial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
 
 
3
"""
 
4
    DVI - Management of Dead Bodies and Disaster Victim Identification
 
5
 
 
6
    @author: khushbu
 
7
    @author: nursix
 
8
"""
 
9
 
 
10
module = "dvi"
 
11
if deployment_settings.has_module(module):
 
12
 
 
13
    # Settings
 
14
    resource = "setting"
 
15
    tablename = "%s_%s" % (module, resource)
 
16
    table = db.define_table(tablename,
 
17
                            Field("audit_read", "boolean"),
 
18
                            Field("audit_write", "boolean"),
 
19
                            migrate=migrate)
 
20
 
 
21
    # -----------------------------------------------------------------------------
 
22
    # Option fields
 
23
    #
 
24
    dvi_task_status_opts = {
 
25
        1:T("New"),
 
26
        2:T("Assigned"),
 
27
        3:T("In Progress"),
 
28
        4:T("Completed"),
 
29
        5:T("Not Applicable"),
 
30
        6:T("Not Possible")
 
31
    }
 
32
 
 
33
    opt_dvi_task_status = db.Table(None, "opt_dvi_task_status",
 
34
                                   Field("opt_dvi_task_status","integer",
 
35
                                   requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
36
                                   default = 1,
 
37
                                   label = T("Task Status"),
 
38
                                   represent = lambda opt: \
 
39
                                               dvi_task_status_opts.get(opt, UNKNOWN_OPT)))
 
40
 
 
41
    # -----------------------------------------------------------------------------
 
42
    # Recovery Request
 
43
    #
 
44
    resource = "recreq"
 
45
    tablename = "%s_%s" % (module, resource)
 
46
    table = db.define_table(tablename, timestamp, uuidstamp, deletion_status,
 
47
                            Field("date", "datetime"),
 
48
                            Field("site_id", length=64),
 
49
                            location_id,
 
50
                            Field("location_details"),
 
51
                            person_id, # Finder
 
52
                            Field("description"),
 
53
                            Field("bodies_est", "integer"), # Number of bodies found
 
54
                            opt_dvi_task_status,
 
55
                            Field("bodies_rec", "integer"), # Number of bodies recovered
 
56
                            migrate=migrate)
 
57
 
 
58
    # Settings and Restrictions
 
59
    table.uuid.requires = IS_NOT_IN_DB(db, "%s.uuid" % table)
 
60
 
 
61
    table.date.label = T("Date/Time of Find")
 
62
    table.date.comment = SPAN("*", _class="req")
 
63
    table.date.requires = IS_UTC_DATETIME(utc_offset=shn_user_utc_offset(),
 
64
                                          allow_future=False)
 
65
    table.date.represent = lambda value: shn_as_local_time(value)
 
66
 
 
67
    table.site_id.label = T("Site ID")
 
68
    #table.site_id.requires = IS_EMPTY_OR(IS_NOT_IN_DB(db, table.site_id))
 
69
 
 
70
    table.location_id.label = T("Location")
 
71
    table.person_id.label = T("Finder")
 
72
 
 
73
    table.bodies_est.label = T("Bodies found")
 
74
    table.bodies_est.comment = SPAN("*", _class="req")
 
75
    table.bodies_est.requires = IS_INT_IN_RANGE(1, 99999)
 
76
    table.bodies_est.default = 0
 
77
 
 
78
    table.bodies_rec.label = T("Bodies recovered")
 
79
    table.bodies_rec.requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999))
 
80
    table.bodies_rec.default = 0
 
81
 
 
82
    table.opt_dvi_task_status.label = T("Task status")
 
83
 
 
84
    # CRUD Strings
 
85
    s3.crud_strings[tablename] = Storage(
 
86
        title_create = T("Body Recovery Request"),
 
87
        title_display = T("Request Details"),
 
88
        title_list = T("List of Requests"),
 
89
        title_update = T("Update Request"),
 
90
        title_search = T("Search Request"),
 
91
        subtitle_create = T("Add New Request"),
 
92
        subtitle_list = T("Body Recovery Requests"),
 
93
        label_list_button = T("List of Requests"),
 
94
        label_create_button = T("Add Request"),
 
95
        label_delete_button = T("Delete Request"),
 
96
        msg_record_created = T("Recovery Request added"),
 
97
        msg_record_modified = T("Recovery Request updated"),
 
98
        msg_record_deleted = T("Recovery Request deleted"),
 
99
        msg_list_empty = T("No requests currently registered"))
 
100
 
 
101
    dvi_recreq_id = db.Table(None, "dvi_recreq_id",
 
102
                             Field("dvi_recreq_id", table,
 
103
                                   requires = IS_NULL_OR(IS_ONE_OF(db,
 
104
                                                  "dvi_recreq.id",
 
105
                                                  "[%(site_id)s] %(date)s: %(bodies_est)s bodies")),
 
106
                                   represent = lambda id: id,
 
107
                                   ondelete = "RESTRICT"))
 
108
 
 
109
    s3xrc.model.configure(table,
 
110
                          list_fields = ["id",
 
111
                                         "date",
 
112
                                         "site_id",
 
113
                                         "location_id",
 
114
                                         "location_details",
 
115
                                         #"description",
 
116
                                         "bodies_est",
 
117
                                         "bodies_rec",
 
118
                                         "opt_dvi_task_status"])
 
119
 
 
120
    #
 
121
    # Body ------------------------------------------------------------------------
 
122
    #
 
123
    resource = "body"
 
124
    tablename = "%s_%s" % (module, resource)
 
125
    table = db.define_table(tablename, timestamp, deletion_status, uuidstamp,
 
126
                            pr_pe_fieldset,
 
127
                            dvi_recreq_id,
 
128
                            Field("date_of_recovery", "datetime"),
 
129
                            location_id,
 
130
                            Field("recovery_details","text"),
 
131
                            Field("has_major_outward_damage","boolean"),
 
132
                            Field("is_burned_or_charred","boolean"),
 
133
                            Field("is_decayed","boolean"),
 
134
                            Field("is_incomplete","boolean"),
 
135
                            opt_pr_gender,
 
136
                            opt_pr_age_group,
 
137
                            migrate = migrate)
 
138
 
 
139
    # Settings and Restrictions
 
140
    #table.pr_pe_parent.readable = True         # not visible in body registration form
 
141
    #table.pr_pe_parent.writable = True         # not visible in body registration form
 
142
    #table.pr_pe_parent.requires = IS_NULL_OR(IS_ONE_OF(db,"pr_pentity.id",shn_pentity_represent,filterby="opt_pr_entity_type",filter_opts=(3,)))
 
143
 
 
144
    table.pr_pe_label.comment = SPAN("*", _class="req")
 
145
    table.pr_pe_label.requires = [IS_NOT_EMPTY(),IS_NOT_IN_DB(db, "dvi_body.pr_pe_label")]
 
146
    table.date_of_recovery.comment = SPAN("*", _class="req")
 
147
    table.date_of_recovery.requires = IS_DATETIME()
 
148
 
 
149
    # Labels
 
150
    table.dvi_recreq_id.label = T("Recovery Request")
 
151
    table.opt_pr_gender.label=T("Apparent Gender")
 
152
    table.opt_pr_age_group.label=T("Apparent Age")
 
153
    table.location_id.label=T("Place of Recovery")
 
154
 
 
155
    # Representations
 
156
    table.has_major_outward_damage.represent = lambda opt: (opt and ["yes"] or [""])[0]
 
157
    table.is_burned_or_charred.represent =  lambda opt: (opt and ["yes"] or [""])[0]
 
158
    table.is_decayed.represent =  lambda opt: (opt and ["yes"] or [""])[0]
 
159
    table.is_incomplete.represent =  lambda opt: (opt and ["yes"] or [""])[0]
 
160
 
 
161
    # CRUD Strings
 
162
    s3.crud_strings[tablename] = Storage(
 
163
        title_create = T("Add Recovery Report"),
 
164
        title_display = T("Dead Body Details"),
 
165
        title_list = T("Body Recovery Reports"),
 
166
        title_update = T("Edit Recovery Details"),
 
167
        title_search = T("Find Recovery Report"),
 
168
        subtitle_create = T("Add New Report"),
 
169
        subtitle_list = T("List of Reports"),
 
170
        label_list_button = T("List Reports"),
 
171
        label_create_button = T("Add Recovery Report"),
 
172
        label_delete_button = T("Delete Recovery Report"),
 
173
        msg_record_created = T("Recovery report added"),
 
174
        msg_record_modified = T("Recovery report updated"),
 
175
        msg_record_deleted = T("Recovery report deleted"),
 
176
        msg_list_empty = T("No recovery reports available"))
 
177
 
 
178
    s3xrc.model.configure(table,
 
179
                          onaccept=lambda form: \
 
180
                          shn_pentity_onaccept(form, table=db.dvi_body, entity_type=3),
 
181
                          delete_onaccept=lambda form: \
 
182
                          shn_pentity_ondelete(form),
 
183
                          list_fields=["id",
 
184
                                       "pr_pe_label",
 
185
                                       "opt_pr_gender",
 
186
                                       "opt_pr_age_group",
 
187
                                       "date_of_recovery",
 
188
                                       "location_id"])
 
189
 
 
190
    #
 
191
    # Checklist of operations -----------------------------------------------------
 
192
    #
 
193
    resource = "checklist"
 
194
    tablename = "%s_%s" % (module, resource)
 
195
    table = db.define_table(tablename, timestamp, uuidstamp, deletion_status,
 
196
                    pr_pe_id,
 
197
                    Field("personal_effects","integer",
 
198
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
199
                        default = 1,
 
200
                        label = T("Inventory of Effects"),
 
201
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
202
                    Field("body_radiology","integer",
 
203
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
204
                        default = 1,
 
205
                        label = T("Radiology"),
 
206
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
207
                    Field("fingerprints","integer",
 
208
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
209
                        default = 1,
 
210
                        label = T("Fingerprinting"),
 
211
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
212
                    Field("anthropology","integer",
 
213
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
214
                        default = 1,
 
215
                        label = T("Anthropolgy"),
 
216
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
217
                    Field("pathology","integer",
 
218
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
219
                        default = 1,
 
220
                        label = T("Pathology"),
 
221
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
222
                    Field("embalming","integer",
 
223
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
224
                        default = 1,
 
225
                        label = T("Embalming"),
 
226
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
227
                    Field("dna","integer",
 
228
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
229
                        default = 1,
 
230
                        label = T("DNA Profiling"),
 
231
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
232
                    Field("dental","integer",
 
233
                        requires = IS_IN_SET(dvi_task_status_opts, zero=None),
 
234
                        default = 1,
 
235
                        label = T("Dental Examination"),
 
236
                        represent = lambda opt: dvi_task_status_opts.get(opt, T("not specified"))),
 
237
                    migrate = migrate)
 
238
 
 
239
    # Setting and restrictions
 
240
 
 
241
    # CRUD Strings
 
242
    CREATE_CHECKLIST = T("Create Checklist")
 
243
    s3.crud_strings[tablename] = Storage(
 
244
        title_create = CREATE_CHECKLIST,
 
245
        title_display = T("Checklist of Operations"),
 
246
        title_list = T("List Checklists"),
 
247
        title_update = T("Update Task Status"),
 
248
        title_search = T("Search Checklists"),
 
249
        subtitle_create = T("New Checklist"),
 
250
        subtitle_list = T("Checklist of Operations"),
 
251
        label_list_button = T("Show Checklist"),
 
252
        label_create_button = CREATE_CHECKLIST,
 
253
        msg_record_created = T("Checklist created"),
 
254
        msg_record_modified = T("Checklist updated"),
 
255
        msg_record_deleted = T("Checklist deleted"),
 
256
        msg_list_empty = T("No Checklist available"))
 
257
 
 
258
    # Joined Resource
 
259
    s3xrc.model.add_component(module, resource,
 
260
                              multiple = False,
 
261
                              joinby = "pr_pe_id",
 
262
                              deletable = True,
 
263
                              editable = True)
 
264
 
 
265
    s3xrc.model.configure(table, list_fields = ["id"])
 
266
 
 
267
    #
 
268
    # Personal Effects ------------------------------------------------------------------------
 
269
    #
 
270
    resource = "effects"
 
271
    tablename = "%s_%s" % (module, resource)
 
272
    table = db.define_table(tablename, timestamp, uuidstamp, deletion_status,
 
273
                    pr_pe_id,
 
274
    #                person_id,
 
275
                    Field("clothing", "text"),    #TODO: elaborate
 
276
                    Field("jewellery", "text"),   #TODO: elaborate
 
277
                    Field("footwear", "text"),    #TODO: elaborate
 
278
                    Field("watch", "text"),       #TODO: elaborate
 
279
                    Field("other", "text"),
 
280
                    migrate = migrate)
 
281
 
 
282
    # Settings and Restrictions
 
283
 
 
284
    # Labels
 
285
    #table.person_id.label = T("Reporter")
 
286
 
 
287
    # CRUD Strings
 
288
    ADD_PERSONAL_EFFECTS = T("Add Personal Effects")
 
289
    s3.crud_strings[tablename] = Storage(
 
290
        title_create = ADD_PERSONAL_EFFECTS,
 
291
        title_display = T("Personal Effects Details"),
 
292
        title_list = T("List Personal Effects"),
 
293
        title_update = T("Edit Personal Effects Details"),
 
294
        title_search = T("Search Personal Effects"),
 
295
        subtitle_create = T("Add New Entry"),
 
296
        subtitle_list = T("Personal Effects"),
 
297
        label_list_button = T("List Records"),
 
298
        label_create_button = ADD_PERSONAL_EFFECTS,
 
299
        msg_record_created = T("Record added"),
 
300
        msg_record_modified = T("Record updated"),
 
301
        msg_record_deleted = T("Record deleted"),
 
302
        msg_list_empty = T("No Details currently registered"))
 
303
 
 
304
    # Joined Resource
 
305
    s3xrc.model.add_component(module, resource,
 
306
                              multiple = False,
 
307
                              joinby = "pr_pe_id",
 
308
                              deletable = True,
 
309
                              editable = True)
 
310
 
 
311
    s3xrc.model.configure(table, list_fields = ["id"])
 
312
 
 
313
    #
 
314
    # Identification --------------------------------------------------------------
 
315
    #
 
316
    dvi_id_status_opts = {
 
317
        1:T("Unidentified"),
 
318
        2:T("Preliminary"),
 
319
        3:T("Confirmed"),
 
320
        }
 
321
 
 
322
    opt_dvi_id_status = db.Table(None, "opt_dvi_id_status",
 
323
                        Field("opt_dvi_id_status","integer",
 
324
                        requires = IS_IN_SET(dvi_id_status_opts, zero=None),
 
325
                        default = 1,
 
326
                        label = T("Identification Status"),
 
327
                        represent = lambda opt: dvi_id_status_opts.get(opt, UNKNOWN_OPT)))
 
328
 
 
329
    dvi_id_method_opts = {
 
330
        1:T("Visual Recognition"),
 
331
        2:T("Physical Description"),
 
332
        3:T("Fingerprints"),
 
333
        4:T("Dental Profile"),
 
334
        5:T("DNA Profile"),
 
335
        6:T("Combined Method"),
 
336
        99:T("Other Evidence")
 
337
        }
 
338
 
 
339
    opt_dvi_id_method = db.Table(None, "opt_dvi_id_method",
 
340
                        Field("opt_dvi_id_method","integer",
 
341
                        requires = IS_IN_SET(dvi_id_method_opts, zero=None),
 
342
                        default = 99,
 
343
                        label = T("Method used"),
 
344
                        represent = lambda opt: dvi_id_method_opts.get(opt, UNKNOWN_OPT)))
 
345
 
 
346
    resource = "identification"
 
347
    tablename = "%s_%s" % (module, resource)
 
348
    table = db.define_table(tablename, timestamp, uuidstamp, deletion_status,
 
349
                    pr_pe_id,
 
350
                    Field("identified_by", db.pr_person),  # Person identifying the body
 
351
                    Field("reported_by", db.pr_person),    # Person reporting
 
352
                    opt_dvi_id_status,                     # Identity status
 
353
                    opt_dvi_id_method,                     # Method used
 
354
                    Field("identity", db.pr_person),       # Identity of the body
 
355
                    Field("comment", "text"),              # Comment (optional)
 
356
                    migrate = migrate)
 
357
 
 
358
    # Settings and Restrictions
 
359
    table.identified_by.requires = IS_NULL_OR(IS_ONE_OF(db, "pr_person.id", shn_pr_person_represent))
 
360
    table.identified_by.represent = lambda id: (id and [shn_pr_person_represent(id)] or ["None"])[0]
 
361
    table.identified_by.comment = shn_person_comment
 
362
    table.identified_by.ondelete = "RESTRICT"
 
363
 
 
364
    table.reported_by.requires = IS_NULL_OR(IS_ONE_OF(db, "pr_person.id", shn_pr_person_represent))
 
365
    table.reported_by.represent = lambda id: (id and [shn_pr_person_represent(id)] or ["None"])[0]
 
366
    table.reported_by.comment = shn_person_comment
 
367
    table.reported_by.ondelete = "RESTRICT"
 
368
 
 
369
    table.identity.requires = IS_NULL_OR(IS_ONE_OF(db, "pr_person.id", shn_pr_person_represent))
 
370
    table.identity.represent = lambda id: (id and [shn_pr_person_represent(id)] or ["None"])[0]
 
371
    table.identity.comment = shn_person_comment
 
372
    table.identity.ondelete = "RESTRICT"
 
373
 
 
374
    # Labels
 
375
 
 
376
    # CRUD Strings
 
377
    s3.crud_strings[tablename] = Storage(
 
378
        title_create = T("Add Identification Report"),
 
379
        title_display = T("Identification Report"),
 
380
        title_list = T("List Reports"),
 
381
        title_update = T("Edit Identification Report"),
 
382
        title_search = T("Search Report"),
 
383
        subtitle_create = T("Add New Report"),
 
384
        subtitle_list = T("Identification Reports"),
 
385
        label_list_button = T("List Reports"),
 
386
        label_create_button = T("Add Identification Report"),
 
387
        msg_record_created = T("Report added"),
 
388
        msg_record_modified = T("Report updated"),
 
389
        msg_record_deleted = T("Report deleted"),
 
390
        msg_list_empty = T("No Identification Report Available"))
 
391
 
 
392
    # Joined Resource
 
393
    s3xrc.model.add_component(module, resource,
 
394
                              multiple = False,
 
395
                              joinby = "pr_pe_id",
 
396
                              deletable = True,
 
397
                              editable = True)
 
398
 
 
399
    s3xrc.model.configure(table, list_fields = ["id"])
 
400
 
 
401
    # -----------------------------------------------------------------------------
 
402
    #
 
403
    def shn_dvi_rheader(jr, tabs=[]):
 
404
 
 
405
        """ Page header for component pages """
 
406
 
 
407
        if jr.name == "body":
 
408
            if jr.representation == "html":
 
409
                _next = jr.here()
 
410
                _same = jr.same()
 
411
 
 
412
                rheader_tabs = shn_rheader_tabs(jr, tabs)
 
413
 
 
414
                body = jr.record
 
415
                if body:
 
416
                    rheader = DIV(TABLE(
 
417
 
 
418
                        TR(TH(T("ID Label: ")),
 
419
                           "%(pr_pe_label)s" % body,
 
420
                           TH(""),
 
421
                           ""),
 
422
 
 
423
                        TR(TH(T("Gender: ")),
 
424
                           "%s" % pr_person_gender_opts[body.opt_pr_gender],
 
425
                           TH(""),
 
426
                           ""),
 
427
 
 
428
                        TR(TH(T("Age Group: ")),
 
429
                           "%s" % pr_person_age_group_opts[body.opt_pr_age_group],
 
430
                           TH(""),
 
431
                           ""),
 
432
 
 
433
                        ), rheader_tabs
 
434
                    )
 
435
                    return rheader
 
436
 
 
437
        return None
 
438
 
 
439
    # -----------------------------------------------------------------------------
 
440
    #
 
441
    def shn_dvi_get_body_id(label, fields=None, filterby=None):
 
442
 
 
443
        """" find IDs for all body records matching a label """
 
444
 
 
445
        if fields and isinstance(fields, (list,tuple)):
 
446
            search_fields = []
 
447
            for f in fields:
 
448
                if db.dvi_body.has_key(f):     # TODO: check for field type?
 
449
                    search_fields.append(f)
 
450
            if not len(search_fields):
 
451
                # Error: none of the specified search fields exists
 
452
                return None
 
453
        else:
 
454
            # No search fields specified at all => fallback
 
455
            search_fields = ["pr_pe_label"]
 
456
 
 
457
        if label and isinstance(label,str):
 
458
            labels = label.split()
 
459
            results = []
 
460
            query = None
 
461
            # TODO: make a more sophisticated search function (levenshtein?)
 
462
            for l in labels:
 
463
 
 
464
                # append wildcards
 
465
                wc = "%"
 
466
                _l = "%s%s%s" % (wc, l, wc)
 
467
 
 
468
                # build query
 
469
                for f in search_fields:
 
470
                    if query:
 
471
                        query = (db.dvi_body[f].like(_l)) | query
 
472
                    else:
 
473
                        query = (db.dvi_body[f].like(_l))
 
474
 
 
475
                # undeleted records only
 
476
                query = (db.dvi_body.deleted==False) & (query)
 
477
                # restrict to prior results (AND)
 
478
                if len(results):
 
479
                    query = (db.dvi_body.id.belongs(results)) & query
 
480
                if filterby:
 
481
                    query = (filterby) & (query)
 
482
                records = db(query).select(db.dvi_body.id)
 
483
                # rebuild result list
 
484
                results = [r.id for r in records]
 
485
                # any results left?
 
486
                if not len(results):
 
487
                    return None
 
488
            return results
 
489
        else:
 
490
            # no label given or wrong parameter type
 
491
            return None
 
492
 
 
493
    # -----------------------------------------------------------------------------
 
494
    #
 
495
    def shn_dvi_body_search_simple(xrequest, **attr):
 
496
 
 
497
        """ Simple Search form for body recovery reports """
 
498
 
 
499
        if attr is None:
 
500
            attr = {}
 
501
 
 
502
        if not shn_has_permission("read", db.dvi_body):
 
503
            session.error = UNAUTHORISED
 
504
            redirect(URL(r=request, c="default", f="user", args="login", vars={"_next":URL(r=request, args="search_simple", vars=request.vars)}))
 
505
 
 
506
        if xrequest.representation=="html":
 
507
            # Check for redirection
 
508
            if request.vars._next:
 
509
                next = str.lower(request.vars._next)
 
510
            else:
 
511
                next = str.lower(URL(r=request, f="body", args="[id]"))
 
512
 
 
513
            # Custom view
 
514
            response.view = "%s/body_search.html" % xrequest.prefix
 
515
 
 
516
            # Title and subtitle
 
517
            title = T("Find Recovery Report")
 
518
            subtitle = T("Matching Records")
 
519
 
 
520
            # Select form
 
521
            form = FORM(TABLE(
 
522
                    TR(T("ID Label: "),
 
523
                    INPUT(_type="text", _name="label", _size="40"),
 
524
                    DIV( _class="tooltip", _title=Tstr("ID Label") + "|" + Tstr("To search for a body, enter the ID label of the body. You may use % as wildcard. Press 'Search' without input to list all bodies."))),
 
525
                    TR("", INPUT(_type="submit", _value="Search"))
 
526
                    ))
 
527
 
 
528
            output = dict(title=title, subtitle=subtitle, form=form, vars=form.vars)
 
529
 
 
530
            # Accept action
 
531
            items = None
 
532
            if form.accepts(request.vars, session):
 
533
 
 
534
                if form.vars.label == "":
 
535
                    form.vars.label = "%"
 
536
 
 
537
                results = shn_dvi_get_body_id(form.vars.label)
 
538
 
 
539
                if results and len(results):
 
540
                    rows = db(db.dvi_body.id.belongs(results)).select()
 
541
                else:
 
542
                    rows = None
 
543
 
 
544
                # Build table rows from matching records
 
545
                if rows:
 
546
                    records = []
 
547
                    for row in rows:
 
548
                        href = next.replace("%5bid%5d", "%s" % row.id)
 
549
                        records.append(TR(
 
550
                            A(row.pr_pe_label or "[no label]", _href=href),
 
551
                            row.opt_pr_gender and pr_person_gender_opts[row.opt_pr_gender] or "unknown",
 
552
                            row.opt_pr_age_group and pr_person_age_group_opts[row.opt_pr_age_group] or "unknown",
 
553
                            row.date_of_recovery,
 
554
                            (row.location_id and [db.gis_location[row.location_id].name] or [""])[0],
 
555
    #                        location_id.location_id.represent(row.location_id)
 
556
                            ))
 
557
                    items=DIV(TABLE(THEAD(TR(
 
558
                        TH("ID Label"),
 
559
                        TH("Gender"),
 
560
                        TH("Age Group"),
 
561
                        TH("Recovery Date"),
 
562
                        TH("Recovery Site"))),
 
563
                        TBODY(records), _id="list", _class="display"))
 
564
                else:
 
565
                    items = T("None")
 
566
 
 
567
            try:
 
568
                label_create_button = s3.crud_strings["dvi_body"].label_create_button
 
569
            except:
 
570
                label_create_button = s3.crud_strings.label_create_button
 
571
 
 
572
            add_btn = A(label_create_button, _href=URL(r=request, f="body", args="create"), _class="action-btn")
 
573
 
 
574
            output.update(dict(items=items, add_btn=add_btn))
 
575
            return output
 
576
 
 
577
        else:
 
578
            session.error = BADFORMAT
 
579
            redirect(URL(r=request))
 
580
 
 
581
    # Plug into REST controller
 
582
    s3xrc.model.set_method(module, "body", method="search_simple", action=shn_dvi_body_search_simple )
 
583
 
 
584
    # -----------------------------------------------------------------------------