def prep(r): # Call standard prep result = standard_prep(r) if callable(standard_prep) else True db = current.db s3db = current.s3db # Check which programs and organisations the user can accept vouchers for program_ids, org_ids, pe_ids = s3db.fin_voucher_permitted_programs( mode="provider") resource = r.resource table = resource.table if not program_ids or not org_ids: # User is not permitted to accept vouchers for any programs/providers resource.configure(insertable=False) else: # Limit the program selector to permitted programs field = table.program_id ptable = s3db.fin_voucher_program dbset = db(ptable.id.belongs(program_ids)) field.requires = IS_ONE_OF( dbset, "fin_voucher_program.id", field.represent, sort=True, ) # Hide the program selector if only one program can be chosen rows = dbset.select(ptable.id, limitby=(0, 2)) if len(rows) == 1: field.default = rows.first().id field.writable = False # Limit the provider selector to permitted entities etable = s3db.pr_pentity field = table.pe_id dbset = db(etable.pe_id.belongs(pe_ids)) field.requires = IS_ONE_OF( dbset, "pr_pentity.pe_id", field.represent, ) # Hide the provider selector if only one entity can be chosen rows = dbset.select(etable.pe_id, limitby=(0, 2)) if len(rows) == 1: field.default = rows.first().pe_id field.readable = field.writable = False return result
def need(): """ Needs: RESTful CRUD Controller """ if settings.get_dvr_needs_hierarchical(): tablename = "dvr_need" from s3 import IS_ONE_OF, S3Represent represent = S3Represent( lookup=tablename, hierarchy=True, translate=True, ) table = s3db[tablename] field = table.parent field.represent = represent field.requires = IS_EMPTY_OR( IS_ONE_OF( db, "%s.id" % tablename, represent, orderby="%s.name" % tablename, )) return s3_rest_controller()
def custom_prep(r): # Call standard prep if callable(standard_prep): if not standard_prep(r): return False if r.controller == "deploy": # Popups in RDRT Member Profile table = r.table job_title_id = table.job_title_id job_title_id.label = T("Sector / Area of Expertise") job_title_id.comment = None jtable = current.s3db.hrm_job_title query = (jtable.type == 4) if r.method == "update" and r.record.job_title_id: # Allow to keep the current value query |= (jtable.id == r.record.job_title_id) from s3 import IS_ONE_OF job_title_id.requires = IS_ONE_OF(current.db(query), "hrm_job_title.id", job_title_id.represent, ) job_title = table.job_title job_title.readable = job_title.writable = True return True
def prep(r): component_name = r.component_name if component_name == "household": # Set the Starting Location to be that of the Area area_location = r.record.location_id if area_location: gtable = s3db.gis_location record = db(gtable.id == area_location).select( gtable.parent, limitby=(0, 1), ).first() if record: s3db.po_household.location_id.default = record.parent elif component_name == "organisation": # Filter to just referral agencies otable = s3db.org_organisation rtable = s3db.po_referral_organisation atable = s3db.po_organisation_area query = (rtable.id != None) & \ ((atable.area_id == None) | (atable.area_id != r.id)) left = [rtable.on((rtable.organisation_id == otable.id) & \ (rtable.deleted != True)), atable.on((atable.organisation_id == otable.id) & \ (atable.deleted != True)), ] from s3 import IS_ONE_OF atable.organisation_id.requires = IS_ONE_OF( db(query), "org_organisation.id", atable.organisation_id.represent, left=left, error_message=T("Agency is required")) return True
def item(): """ RESTful CRUD controller """ if "catalog_item" not in request.args: # Filter to just Assets table = s3db.supply_item ctable = s3db.supply_item_category s3.filter = (table.item_category_id == ctable.id) & \ (ctable.can_be_asset == True) # Limit the Categories to just those which can be Assets # - make category mandatory so that filter works field = s3db.supply_item.item_category_id from s3 import IS_ONE_OF field.requires = IS_ONE_OF(db, "supply_item_category.id", s3db.supply_item_category_represent, filterby = "can_be_asset", filter_opts = (True,), sort = True, ) field.comment = S3PopupLink(f = "item_category", label = T("Create Item Category"), title = T("Item Category"), tooltip = T("Only Categories of type 'Asset' will be seen in the dropdown."), ) # Defined in the Model for use from Multiple Controllers for unified menus from s3db.supply import supply_item_controller return supply_item_controller()
def _customise_assignment_fields(**attr): MEMBER = T("Member") from gluon.html import DIV hr_comment = \ DIV(_class="tooltip", _title="%s|%s" % (MEMBER, current.messages.AUTOCOMPLETE_HELP)) from s3 import IS_ONE_OF s3db = current.s3db atable = s3db.deploy_assignment atable.human_resource_id.label = MEMBER atable.human_resource_id.comment = hr_comment field = atable.job_title_id field.comment = None field.label = T("Sector") field.requires = IS_ONE_OF(current.db, "hrm_job_title.id", field.represent, filterby = "type", filter_opts = (4,), ) # Default activity_type when creating experience records from assignments activity_type = s3db.hrm_experience.activity_type activity_type.default = activity_type.update = "rdrt" return
def customise_dvr_case_resource(r, tablename): db = current.db s3db = current.s3db field = s3db.dvr_case.organisation_id # Limit to just Branches field.label = T("Branch") # Simplify Represent field.represent = represent = s3db.org_OrganisationRepresent(parent=False) otable = s3db.org_organisation btable = s3db.org_organisation_branch query = (btable.deleted != True) & \ (btable.organisation_id == otable.id) & \ (otable.name == "New Zealand Red Cross") rows = db(query).select(btable.branch_id) filter_opts = [row.branch_id for row in rows] from s3 import IS_ONE_OF field.requires = IS_ONE_OF(db, "org_organisation.id", represent, filterby = "id", filter_opts = filter_opts, updateable = True, orderby = "org_organisation.name", sort = True, ) # Don't create new branches here field.comment = None
def ns_only(f, required=True, branches=True, updateable=True): """ Function to configure an organisation_id field to be restricted to just NS/Branch """ # Label if branches: f.label = T("National Society / Branch") else: f.label = T("National Society") # Requires db = current.db ttable = db.org_organisation_type type_id = db(ttable.name == "Red Cross / Red Crescent").select( ttable.id, limitby=(0, 1)).first().id if branches: not_filterby = None not_filter_opts = [] else: btable = db.org_organisation_branch rows = db(btable.deleted != True).select(btable.branch_id) branches = [row.branch_id for row in rows] not_filterby = "id" not_filter_opts = branches requires = IS_ONE_OF(db, "org_organisation.id", current.s3db.org_OrganisationRepresent(), filterby="organisation_type_id", filter_opts=[type_id], not_filterby=not_filterby, not_filter_opts=not_filter_opts, updateable=updateable, orderby="org_organisation.name", sort=True) if not required: requires = IS_EMPTY_OR(requires) f.requires = requires # Dropdown not Autocomplete f.widget = None # Comment s3_has_role = current.auth.s3_has_role if s3_has_role("ADMIN") or \ s3_has_role("ORG_ADMIN"): # Need to do import after setting Theme from s3layouts import S3AddResourceLink f.comment = S3AddResourceLink( c="org", f="organisation", vars={ "organisation.organisation_type_id$name": "Red Cross / Red Crescent" }, label=T("Add National Society"), title=T("National Society"), ) else: # Not allowed to add NS f.comment = ""
def testExportOptionsAllOptsJSONHierarchy(self): """ Test export options, JSON, all options+hierarchy """ assertEqual = self.assertEqual assertTrue = self.assertTrue # Configure parent-field db = current.db table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF(db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db = current.s3db s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = {"name": "option3", "uuid": "OPTION3", "parent": options.keys()[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Request options resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], hierarchy=True, as_json=True) fo = json.loads(result) # Inspect result has_empty = False assertTrue(isinstance(fo, dict)) assertTrue("option" in fo) assertTrue(isinstance(fo["option"], list)) assertEqual(len(fo["option"]), len(options) + 1) for opt in fo["option"]: value = opt["@value"] if value == "": has_empty = True self.assertFalse("$" in opt) continue else: value = int(value) assertTrue(value in options) assertEqual(opt["$"], options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue("@parent" in opt) assertEqual(opt["@parent"], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def testExportOptionsLastOptJSONHierarchy(self): assertEqual = self.assertEqual assertTrue = self.assertTrue db = current.db s3db = current.s3db # Configure parent-field table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF(db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = {"name": "option3", "uuid": "OPTION3", "parent": options.keys()[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Get the last record table = db.fotest_lookup_table last = db(table.id>0).select(limitby=(0, 1), orderby=~table.id).first() self.assertNotEqual(last, None) # Request last option resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], only_last=True, hierarchy=True, as_json=True) fo = json.loads(result) # Inspect result assertTrue(isinstance(fo, dict)) assertTrue("option" in fo) assertTrue(isinstance(fo["option"], list)) assertEqual(len(fo["option"]), 1) opt = fo["option"][0] value = opt["@value"] assertEqual(options[value]["uuid"], last.uuid) assertEqual(opt["$"], options[value]["name"]) assertTrue("@parent" in opt) assertEqual(opt["@parent"], str(options[value]["parent"]))
def prep(r): from s3 import IS_ONE_OF field = r.table.parent field.requires = IS_EMPTY_OR( IS_ONE_OF( db, "%s.id" % r.tablename, field.represent, )) return True
def customise_event_incident_resource(r, tablename): from s3 import IS_ONE_OF db = current.db table = r.table table.exercise.default = True table.event_id.readable = table.event_id.writable = True represent = S3Represent(lookup=tablename) table.event_id.requires = IS_ONE_OF(db, "event_event.id", represent, filterby="closed", filter_opts=(False,), orderby="event_event.name", sort=True)
def item(): """ RESTful CRUD controller """ # Filter to just Vehicles table = s3db.supply_item ctable = s3db.supply_item_category s3.filter = (table.item_category_id == ctable.id) & \ (ctable.is_vehicle == True) # Limit the Categories to just those with vehicles in # - make category mandatory so that filter works field = s3db.supply_item.item_category_id from s3 import IS_ONE_OF field.requires = IS_ONE_OF(db, "supply_item_category.id", s3db.supply_item_category_represent, sort=True, filterby="is_vehicle", filter_opts=[True]) field.label = T("Vehicle Categories") field.comment = S3PopupLink( f="item_category", label=T("Add Vehicle Category"), info=T("Add a new vehicle category"), title=T("Vehicle Category"), tooltip=T( "Only Categories of type 'Vehicle' will be seen in the dropdown."), ) # CRUD strings s3.crud_strings["supply_item"] = Storage( label_create=T("Add New Vehicle Type"), title_display=T("Vehicle Type Details"), title_list=T("Vehicle Types"), title_update=T("Edit Vehicle Type"), label_list_button=T("List Vehicle Types"), label_delete_button=T("Delete Vehicle Type"), msg_record_created=T("Vehicle Type added"), msg_record_modified=T("Vehicle Type updated"), msg_record_deleted=T("Vehicle Type deleted"), msg_list_empty=T("No Vehicle Types currently registered"), msg_match=T("Matching Vehicle Types"), msg_no_match=T("No Matching Vehicle Types")) # Defined in the Model for use from Multiple Controllers for unified menus return s3db.supply_item_controller()
def setUpClass(cls): db = current.db s3db = current.s3db s3db.define_table("fotest_lookup_table", Field("name"), Field("parent", "reference fotest_lookup_table"), *s3_meta_fields()) data = ( { "name": "option1", "uuid": cls.uuids[0] }, { "name": "option2", "uuid": cls.uuids[1] }, ) table = db.fotest_lookup_table for item in data: table.insert(**item) options = cls.options represent = S3Represent(lookup="fotest_lookup_table") s3db.define_table( "fotest_table", Field( "fixed_set", "integer", requires=IS_EMPTY_OR(IS_IN_SET(options)), represent=S3Represent(options=options), ), Field( "lookup", "reference fotest_lookup_table", requires=IS_EMPTY_OR( IS_ONE_OF( db, "fotest_lookup_table.id", represent, )), represent=represent, ), Field("noopts"), *s3_meta_fields()) db.commit()
def customise_auth_user_controller(**attr): """ Customise admin/user() and default/user() controllers """ if current.auth.is_logged_in(): # Organisation needs to be an NS/Branch ns_only( "auth_user", required=True, branches=True, updateable=False, # Need to see all Orgs in Registration screens ) else: # Registration page db = current.db s3db = current.s3db field = db.auth_user.organisation_id # Limit to just Branches field.label = T("Branch") # Simplify Represent field.represent = represent = s3db.org_OrganisationRepresent( parent=False) otable = s3db.org_organisation btable = s3db.org_organisation_branch query = (btable.deleted != True) & \ (btable.organisation_id == otable.id) & \ (otable.name == "New Zealand Red Cross") rows = db(query).select(btable.branch_id) filter_opts = [row.branch_id for row in rows] from s3 import IS_ONE_OF field.requires = IS_ONE_OF( db, "org_organisation.id", represent, filterby="id", filter_opts=filter_opts, orderby="org_organisation.name", sort=True, ) # Don't create new branches here field.comment = None return attr
def prep(r): if settings.get_dvr_activity_use_service_type() and \ settings.get_org_services_hierarchical(): # Limit the selection to root services (case activity # threads are usually per root service type, and all # sub-categories should use a common exit type taxonomy) from s3 import IS_ONE_OF field = r.table.service_id query = (db.org_service.parent == None) field.requires = IS_EMPTY_OR( IS_ONE_OF( db(query), "org_service.id", field.represent, )) return True
def customise_hrm_credential_controller(**attr): # Currently just used by RDRT table = current.s3db.hrm_credential field = table.job_title_id field.comment = None field.label = T("Sector") from s3 import IS_ONE_OF field.requires = IS_ONE_OF(current.db, "hrm_job_title.id", field.represent, filterby = "type", filter_opts = (4,), ) table.organisation_id.readable = table.organisation_id.writable = False table.performance_rating.readable = table.performance_rating.writable = False table.start_date.readable = table.start_date.writable = False table.end_date.readable = table.end_date.writable = False return attr
def prep(r): if r.component_name == "hours": # Limit Activity Types to those for the Activity ltable = s3db.vol_activity_activity_type query = (ltable.activity_id == r.id) & \ (ltable.deleted == False) rows = db(query).select(ltable.activity_type_id) activity_types = [row.activity_type_id for row in rows] from s3 import IS_ONE_OF field = s3db.vol_activity_hours_activity_type.activity_type_id field.requires = IS_EMPTY_OR( IS_ONE_OF( db, "vol_activity_type.id", field.represent, filterby="id", filter_opts=activity_types, )) # Limit the Dates to the same as the Activity record = r.record start_date = record.date end_date = record.end_date if end_date is None or start_date == end_date: field = s3db.vol_activity_hours.date field.default = start_date field.readable = field.writable = False else: # @ToDo: Check widget options (currently this branch is never taken) from s3 import IS_UTC_DATE s3db.vol_activity_hours.date.requires = IS_UTC_DATE( calendar="Gregorian", minimum=start_date, maximum=end_date, ) return True
def prep(r): table = s3db.supply_item_category if r.get_vars.get("assets") == "1": # Category must be one that supports Assets f = table.can_be_asset # Default anyway #f.default = True f.readable = f.writable = False if r.id: # Should not be able to set the Parent to this record # @ToDo: Also prevent setting to any of the categories of which this is an ancestor from s3 import IS_ONE_OF from s3db.supply import supply_ItemCategoryRepresent the_set = db(table.id != r.id) table.parent_item_category_id.requires = IS_EMPTY_OR( IS_ONE_OF( the_set, "supply_item_category.id", supply_ItemCategoryRepresent(use_code=False), sort=True, )) return True
def customise_req_site_needs_resource(r, tablename): if r.tablename == "req_site_needs": table = r.table field = table.site_id field.label = current.T("Facility") field.readable = field.writable = True # Allow only facilities which do not have a req_site_needs # yet (single component), and filter out obsolete facilities from s3 import IS_ONE_OF, FS dbset = current.db(table.id == None) left = table.on(table.site_id == current.s3db.org_site.id) field.requires = IS_ONE_OF( dbset, "org_site.site_id", field.represent, left=left, not_filterby="obsolete", not_filter_opts=(True, ), orderby="org_site.name", sort=True, ) if not r.record: query = FS("site_id$obsolete") != True r.resource.add_filter(query) # Allow adding of facilities in popup from s3layouts import S3PopupLink field.comment = S3PopupLink( c="org", f="facility", vars={ "child": "site_id", "parent": "site_needs", }, title=T("Add New Facility"), ) # Filters from s3 import S3LocationFilter, S3TextFilter filter_widgets = [ S3TextFilter( [ "site_id$name", "vol_details", "goods_details", ], label=T("Search"), ), S3LocationFilter("site_id$location_id", ), ] # List fields list_fields = [ (T("Facility"), "site_id$name"), "site_id$location_id", ("%s?" % T("Volunteers"), "vol"), (T("Help Wanted"), "vol_details"), ("%s?" % T("Donations"), "goods"), (T("Donations Needed"), "goods_details"), "modified_on", ] current.s3db.configure( "req_site_needs", filter_widgets=filter_widgets, list_fields=list_fields, )
def comments(): """ Function accessed by AJAX from discuss() to handle Comments """ try: resourcename = request.args[0] except: raise HTTP(400) try: id = request.args[1] except: raise HTTP(400) if resourcename == "problem": problem_id = id solution_id = None elif resourcename == "solution": stable = s3db.delphi_solution query = (stable.id == id) solution = db(query).select(stable.problem_id, limitby=(0, 1)).first() if solution: problem_id = solution.problem_id solution_id = id else: raise HTTP(400) else: raise HTTP(400) table = s3db.delphi_comment field = table.problem_id field.default = problem_id field.writable = field.readable = False sfield = table.solution_id if solution_id: sfield.default = solution_id sfield.writable = sfield.readable = False else: sfield.label = T("Related to Solution (optional)") from s3 import IS_ONE_OF sfield.requires = IS_EMPTY_OR( IS_ONE_OF(db, "delphi_solution.id", s3.delphi_solution_represent, filterby="problem_id", filter_opts=(problem_id, ))) # Form to add a new Comment from gluon.tools import Crud form = Crud(db).create(table, formname="delphi_%s/%s" % (resourcename, id)) # List of existing Comments if solution_id: comments = db(sfield == solution_id).select( table.id, table.parent, table.body, table.created_by, table.created_on, ) else: comments = db(field == problem_id).select( table.id, table.parent, table.solution_id, table.body, table.created_by, table.created_on, ) output = UL(_id="comments") for comment in comments: if not comment.parent: # Show top-level threads at top-level thread = comment_parse(comment, comments, solution_id=solution_id) output.append(thread) # Also see the outer discuss() script = \ '''$('#comments').collapsible({xoffset:'-5',yoffset:'50',imagehide:img_path+'arrow-down.png',imageshow:img_path+'arrow-right.png',defaulthide:false}) $('#delphi_comment_parent__row1').hide() $('#delphi_comment_parent__row').hide() $('#delphi_comment_body').ckeditor(ck_config) $('#submit_record__row input').click(function(){$('#comment-form').hide();$('#delphi_comment_body').ckeditorGet().destroy();return true;})''' # No layout in this output! #s3.jquery_ready.append(script) output = DIV( output, DIV(H4(T("New Post"), _id="comment-title"), form, _id="comment-form", _class="clear"), SCRIPT(script)) return XML(output)
def prep(r): record = r.record if r.component_name == "person": # Configure CRUD form and list fields from s3 import S3SQLCustomForm s3db.add_components( "pr_person", po_age_group={ "joinby": "person_id", "multiple": False, }, ) crud_form = S3SQLCustomForm( "first_name", "middle_name", "last_name", "gender", "age_group.age_group", ) list_fields = [ "first_name", "middle_name", "last_name", "gender", "age_group.age_group", ] s3db.configure( "pr_person", crud_form=crud_form, list_fields=list_fields, ) # Tweak CRUD strings crud_strings = s3.crud_strings["pr_person"] crud_strings["label_create"] = T("Add Household Member") # Filter organisations to just referrals and by area # @todo: suppress area filter per deployment setting elif record and r.component_name == "organisation_household": table = r.component.table otable = s3db.org_organisation rtable = s3db.po_referral_organisation atable = s3db.po_organisation_area query = (rtable.id != None) & \ ((atable.area_id == record.area_id) | (atable.area_id == None)) left = [rtable.on((rtable.organisation_id == otable.id) & \ (rtable.deleted != True)), atable.on((atable.organisation_id == otable.id) & \ (atable.deleted != True)), ] from s3 import IS_ONE_OF table.organisation_id.requires = IS_ONE_OF( db(query), "org_organisation.id", atable.organisation_id.represent, left=left, error_message=T("Agency is required")) return True
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True controller = r.controller archived = r.get_vars.get("archived") if archived in ("1", "true", "yes"): crud_strings = s3.crud_strings["pr_person"] crud_strings["title_list"] = T("Invalid Cases") if controller == "dvr" and not r.component: table = r.table ctable = s3db.dvr_case from s3 import IS_ONE_OF, S3HierarchyWidget, S3Represent from gluon import DIV, IS_EMPTY_OR # Expose project_id field = ctable.project_id field.readable = field.writable = True represent = S3Represent( lookup="project_project", fields=["code"], ) field.represent = represent field.requires = IS_EMPTY_OR( IS_ONE_OF( current.db, "project_project.id", represent, )) field.comment = None field.label = T("Project Code") # Hierarchical Organisation Selector field = ctable.organisation_id represent = s3db.org_OrganisationRepresent(parent=False) field.widget = S3HierarchyWidget( lookup="org_organisation", represent=represent, multiple=False, leafonly=False, ) field.comment = DIV( _class="tooltip", _title="%s|%s" % ( T("Organisation"), T("The organisation/branch this case is assigned to"), ), ) user = current.auth.user if user: field.default = user.organisation_id # Individual staff assignment field = ctable.human_resource_id field.label = T("Person Responsible") field.readable = field.writable = True field.widget = None field.comment = None # Filter staff by organisation script = '''$.filterOptionsS3({ 'trigger':'sub_dvr_case_organisation_id', 'target':'sub_dvr_case_human_resource_id', 'lookupPrefix':'hrm', 'lookupResource':'human_resource', 'lookupKey':'organisation_id', 'fncRepresent': function(record){return record.person_id}, 'optional': true })''' s3.jquery_ready.append(script) # Visibility and tooltip for consent flag field = ctable.disclosure_consent field.readable = field.writable = True field.comment = DIV( _class="tooltip", _title="%s|%s" % ( T("Consenting to Data Disclosure"), T("Is the client consenting to disclosure of their data towards partner organisations and authorities?" ), ), ) # Custom label for registered-flag dtable = s3db.dvr_case_details field = dtable.registered field.default = False field.label = T("Registered with Turkish Authorities") field.comment = DIV( _class="tooltip", _title="%s|%s" % ( T("Registered with Turkish Authorities"), T("Is the client officially registered with AFAD/DGMM?" ), ), ) resource = r.resource if r.interactive: from s3 import S3DateFilter, \ S3LocationSelector, \ S3SQLCustomForm, \ S3SQLInlineComponent, \ S3TextFilter # Custom CRUD form crud_form = S3SQLCustomForm( (T("Case Status"), "dvr_case.status_id"), "dvr_case.date", "dvr_case.organisation_id", "dvr_case.human_resource_id", "dvr_case.project_id", "first_name", #"middle_name", "last_name", "person_details.nationality", "date_of_birth", "gender", "person_details.marital_status", "case_details.registered", (T("Individual ID Number"), "pe_label"), S3SQLInlineComponent( "family_id", fields=[ ("", "value"), ], filterby={ "field": "tag", "options": "FAMILY_ID", }, label=T("Family ID Number"), multiple=False, name="family_id", ), S3SQLInlineComponent( "address", label=T("Current Address"), fields=[ ("", "location_id"), ], filterby={ "field": "type", "options": "1", }, link=False, multiple=False, ), S3SQLInlineComponent( "contact", fields=[ ("", "value"), ], filterby={ "field": "contact_method", "options": "SMS", }, label=T("Mobile Phone"), multiple=False, name="phone", ), "dvr_case.disclosure_consent", "dvr_case.comments", (T("Invalid Record"), "dvr_case.archived"), ) resource.configure(crud_form=crud_form, ) # Hide Postcode in addresses (not used) atable = s3db.pr_address location_id = atable.location_id location_id.widget = S3LocationSelector( show_address=True, show_postcode=False, ) # Extend text filter with Family ID and case comments filter_widgets = resource.get_config("filter_widgets") extend_text_filter = True for fw in filter_widgets: if fw.field == "dvr_case.status_id": if fw.field == "dvr_case.status_id" and "closed" in r.get_vars: fw.opts.default = None fw.opts.hidden = True if extend_text_filter and isinstance(fw, S3TextFilter): fw.field.extend(( "family_id.value", "dvr_case.comments", )) fw.opts.comment = T( "You can search by name, ID, family ID and comments" ) extend_text_filter = False # Add filter for date of birth dob_filter = S3DateFilter( "date_of_birth", hidden=True, ) filter_widgets.append(dob_filter) # Add filter for registration date reg_filter = S3DateFilter( "dvr_case.date", hidden=True, ) filter_widgets.append(reg_filter) # Inject script to toggle Head of Household form fields #path = "/%s/static/themes/STL/js/dvr.js" % current.request.application #if path not in s3.scripts: # s3.scripts.append(path) # Custom list fields (must be outside of r.interactive) list_fields = [ (T("ID"), "pe_label"), (T("Family ID"), "family_id.value"), "first_name", #"middle_name", "last_name", "date_of_birth", "gender", "person_details.nationality", "dvr_case.date", "dvr_case.status_id", ] resource.configure(list_fields=list_fields, ) elif controller == "hrm": if not r.component: table = s3db.pr_person_details field = table.marital_status field.readable = field.writable = False field = table.religion field.readable = field.writable = False elif r.method == "record" or \ r.component_name == "human_resource": table = s3db.hrm_human_resource field = table.site_id field.readable = field.writable = False return result
def formfields(): """ Generate the form fields for the registration form @returns: a tuple (formfields, required_fields, subheadings) - formfields = list of form fields - required_fields = list of field names of required fields - subheadings = list of tuples (position, heading) to insert into the form """ T = current.T request = current.request db = current.db s3db = current.s3db auth = current.auth auth_settings = auth.settings auth_messages = auth.messages utable = auth_settings.table_user passfield = auth_settings.password_field occupation_type_represent = S3Represent( lookup="pr_occupation_type", multiple=True, ) # Instantiate Consent Tracker consent = s3db.auth_Consent(processing_types=["SHARE"]) # Last name is required utable.last_name.requires = IS_NOT_EMPTY( error_message=T("input required")) ltable = s3db.gis_location # Form fields formfields = [utable.first_name, utable.last_name, s3_date("date_of_birth", label = T("Date of Birth"), future = -156, empty = False, ), # -------------------------------------------- utable.email, utable[passfield], # Password Verification Field Field("password_two", "password", label = auth_messages.verify_password, requires = IS_EXPR("value==%s" % \ repr(request.vars.get(passfield)), error_message = auth_messages.mismatched_password, ), comment = DIV(_class = "tooltip", _title = "%s|%s" % (auth_messages.verify_password, T("Enter the same password again"), ), ), ), # -------------------------------------------- Field("home_phone", label = T("Phone"), requires = IS_EMPTY_OR(IS_PHONE_NUMBER_MULTI()), ), Field("mobile_phone", label = T("Mobile Phone"), requires = IS_EMPTY_OR(IS_PHONE_NUMBER_SINGLE()), ), #Field("office_phone", # label = T("Office Phone"), # requires = IS_EMPTY_OR(IS_PHONE_NUMBER_MULTI()), # ), # -------------------------------------------- s3db.gis_location_id("location_id", widget = S3LocationSelector( show_address = False, show_postcode = False, show_map = False, ), ), Field("addr_street", label = ltable.addr_street.label, ), Field("addr_postcode", label = ltable.addr_postcode.label, requires = IS_NOT_EMPTY(), ), # -------------------------------------------- Field("occupation_type_ids", "list:reference pr_occupation_type", label = T("Occupation Type"), requires = IS_EMPTY_OR(IS_ONE_OF(db, "pr_occupation_type.id", occupation_type_represent, multiple=True, )), represent = occupation_type_represent, widget = S3MultiSelectWidget(), comment = DIV(_class = "tooltip", _title = "%s|%s" % (T("Occupation Type"), T("Select all that apply"), ), ), ), Field("occupation", label = T("Occupation / Speciality"), comment = DIV(_class = "tooltip", _title = "%s|%s" % (T("Occupation / Speciality"), T("Specify your exact job designation"), ), ), ), # -------------------------------------------- s3_date("start_date", label = T("Available from"), default = "now", past = 0, set_min = "#auth_user_start_date", ), s3_date("end_date", label = T("Available until"), past = 0, set_max = "#auth_user_start_date", ), Field("hours_per_week", "integer", label = T("Hours per Week"), requires = IS_EMPTY_OR(IS_INT_IN_RANGE(1, 60)), comment = DIV(_class = "tooltip", _title = "%s|%s" % (T("Hours per Week"), T("Specify the maximum number of weekly hours"), ), ), ), Field("schedule", "text", label = T("Availability Schedule"), widget = s3_comments_widget, comment = DIV(_class = "tooltip", _title = "%s|%s" % (T("Availability Schedule"), T("Specify days/hours like: Monday 10-12; Tuesday 10-12 and 14-19; Friday 13-15"), ), ), ), s3db.hrm_multi_skill_id( label = T("Skills / Resources"), widget = S3GroupedOptionsWidget(cols = 1, size = None, help_field = "comments", ), ), # -------------------------------------------- Field("comments", "text", label = T("Comments"), widget = s3_comments_widget, ), # -------------------------------------------- Field("consent", label = T("Consent"), widget = consent.widget, ), ] # Required fields required_fields = [ "first_name", "last_name", ] # Subheadings subheadings = ( (3, T("User Account")), (6, T("Contact Information")), (8, T("Address")), (11, T("Occupation")), (13, T("Availability and Resources")), (18, T("Comments")), (19, T("Privacy")), ) return formfields, required_fields, subheadings
def prep(r): # Function to call for all Site Instance Types from s3db.org import org_site_prep org_site_prep(r) method = r.method if method == "create": dtable = s3db.cr_shelter_details dtable.population_day.readable = False dtable.population_night.readable = False elif method == "import": s3db.cr_shelter.organisation_id.default = None elif method == "profile": name = r.record.name site_id = r.record.site_id profile_header = settings.get_ui_profile_header(r) map_widget = {"label": T("Housing Units"), "type": "map", "icon": "globe", "colspan": 2, "height": 500, #"bbox": bbox, } ftable = s3db.gis_layer_feature query = (ftable.controller == "cr") & \ (ftable.function == "shelter_unit") layer = db(query).select(ftable.layer_id, limitby = (0, 1), ).first() try: layer = {"active": True, "layer_id": layer.layer_id, "filter": "~.site_id=%s" % site_id, "name": T("Housing Units"), "id": "profile-header-%s-%s" % (tablename, site_id), } except: # No suitable prepop found layer = None profile_widgets = [map_widget, ] s3db.configure(tablename, profile_header = profile_header, profile_layers = (layer,), profile_title = "%s : %s" % (s3_str(s3.crud_strings["cr_shelter"].title_display), name), profile_widgets = profile_widgets, ) if r.interactive: if r.component: component_name = r.component_name if component_name == "shelter_registration": if settings.get_cr_shelter_housing_unit_management(): # Filter housing units to units of this shelter from s3 import IS_ONE_OF field = s3db.cr_shelter_registration.shelter_unit_id dbset = db(s3db.cr_shelter_unit.site_id == r.record.site_id) field.requires = IS_EMPTY_OR(IS_ONE_OF(dbset, "cr_shelter_unit.id", field.represent, sort = True, )) s3db.pr_person.pe_label.label = T("Registration Number") s3.crud_strings.cr_shelter_registration = Storage( label_create = T("Register Person"), title_display = T("Registration Details"), title_list = T("Registered People"), title_update = T("Edit Registration"), label_list_button = T("List Registrations"), msg_record_created = T("Registration added"), msg_record_modified = T("Registration updated"), msg_record_deleted = T("Registration entry deleted"), msg_list_empty = T("No people currently registered in this shelter"), ) elif component_name == "shelter_allocation": s3.crud_strings.cr_shelter_allocation = Storage( label_create = T("Allocate Group"), title_display = T("Allocation Details"), title_list = T("Allocated Groups"), title_update = T("Edit Allocation"), label_list_button = T("List Allocations"), msg_record_created = T("Reservation done"), msg_record_modified = T("Reservation updated"), msg_record_deleted = T("Reservation entry deleted"), msg_list_empty = T("No groups currently allocated for this shelter"), ) return True
def testWithHierarchyInfo(self): """ Test options lookup with foreign key constraint with hierarchy info """ assertEqual = self.assertEqual assertTrue = self.assertTrue db = current.db s3db = current.s3db table = db.fotest_lookup_table # Configure parent-field represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF( db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = { "name": "option3", "uuid": "OPTION3", "parent": list(options.keys())[0], } child_id = table.insert(**child_node) options[child_id] = child_node xml = current.xml table = db.fotest_table fo = xml.get_field_options(table, "lookup", show_uids=True, hierarchy=True) assertTrue(isinstance(fo, etree._Element)) assertEqual(fo.tag, "select") ATTRIBUTE = xml.ATTRIBUTE VALUE = ATTRIBUTE.value PARENT = ATTRIBUTE.parent UID = xml.UID has_empty = False self.assertEqual(len(fo), len(options) + 1) for opt in fo: assertEqual(opt.tag, "option") attr = opt.attrib assertTrue(VALUE in attr) value = attr[VALUE] if value == "": has_empty = True self.assertFalse(UID in attr) assertEqual(opt.text, "") continue else: value = int(value) assertTrue(UID in attr) assertEqual(attr[UID], options[value]["uuid"]) assertTrue(value in options) assertEqual(opt.text, options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue(PARENT in attr) assertEqual(attr[PARENT], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def customise_req_organisation_needs_resource(r, tablename): s3db = current.s3db table = current.s3db.req_organisation_needs CASH = T("Cash Donations needed") if r.tablename == "req_organisation_needs": from s3 import IS_ONE_OF, S3DateTime # Allow only organisations which do not have a needs record # yet (single component): field = table.organisation_id dbset = current.db(table.id == None) left = table.on( table.organisation_id == current.s3db.org_organisation.id) field.requires = IS_ONE_OF( dbset, "org_organisation.id", field.represent, left=left, orderby="org_organisation.name", sort=True, ) # Format modified_on as date field = table.modified_on field.represent = lambda d: S3DateTime.date_represent(d, utc=True) if r.representation in ("html", "aadata", "iframe"): # Structured lists for interactive views from gluon import Field table.needs_skills = Field.Method(lambda row: \ organisation_needs(row, need_type="skills")) table.needs_items = Field.Method(lambda row: \ organisation_needs(row, need_type="items")) current.response.s3.stylesheets.append("../themes/RW/needs.css") needs_skills = (T("Volunteers needed"), "needs_skills") needs_items = (T("Supplies needed"), "needs_items") # Filter widgets from s3 import S3LocationFilter, S3OptionsFilter, S3TextFilter filter_widgets = [ #S3TextFilter(["organisation_id$name", # ], # label = T("Search"), # ), S3OptionsFilter("organisation_id"), S3OptionsFilter( "organisation_needs_skill.skill_id", label=T("Skills sought"), ), S3OptionsFilter( "organisation_needs_item.item_id", label=T("Supplies sought"), ), S3LocationFilter( "organisation_id$active_service_location.site_id$location_id", ), ] # CRUD form from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm( "organisation_id", S3SQLInlineComponent( "organisation_needs_skill", label=T("Volunteers needed"), fields=[ "skill_id", "demand", "comments", ], ), S3SQLInlineComponent( "organisation_needs_item", label=T("Supplies needed"), fields=[ "item_id", "demand", "comments", ], ), (CASH, "money"), "money_details", #"vol", #"vol_details", ) next_page = r.url(method="") \ if r.tablename == "req_organisation_needs" else None s3db.configure( "req_organisation_needs", crud_form=crud_form, filter_widgets=filter_widgets, create_next=next_page, update_next=next_page, ) else: # Simple fields for exports needs_skills = (T("Volunteers needed"), "organisation_needs_skill.skill_id") needs_items = (T("Supplies needed"), "organisation_needs_item.item_id") # List fields (all formats) list_fields = [ "organisation_id", needs_skills, needs_items, (CASH, "money"), (T("Cash Donation Details"), "money_details"), (T("Last Update"), "modified_on"), ] s3db.configure( "req_organisation_needs", list_fields=list_fields, )
def ns_only(tablename, fieldname = "organisation_id", required = True, branches = True, updateable = True, limit_filter_opts = True, hierarchy = True, ): """ Function to configure an organisation_id field to be restricted to just NS/Branch @param required: Field is mandatory @param branches: Include Branches @param updateable: Limit to Orgs which the user can update @param limit_filter_opts: Also limit the Filter options @param hierarchy: Use the hierarchy widget (unsuitable for use in Inline Components) NB If limit_filter_opts=True, apply in customise_xx_controller inside prep, after standard_prep is run """ # Lookup organisation_type_id for Red Cross db = current.db s3db = current.s3db ttable = s3db.org_organisation_type try: type_id = db(ttable.name == "Red Cross / Red Crescent").select(ttable.id, limitby=(0, 1), cache = s3db.cache, ).first().id except: # No IFRC prepop done - skip (e.g. testing impacts of CSS changes in this theme) return # Load standard model f = s3db[tablename][fieldname] if limit_filter_opts: # Find the relevant filter widget & limit it's options filter_widgets = s3db.get_config(tablename, "filter_widgets") filter_widget = None if filter_widgets: from s3 import FS, S3HierarchyFilter for w in filter_widgets: if isinstance(w, S3HierarchyFilter) and \ w.field == "organisation_id": filter_widget = w break if filter_widget is not None: selector = FS("organisation_organisation_type.organisation_type_id") filter_widget.opts["filter"] = (selector == type_id) # Label if branches: f.label = T("National Society / Branch") #f.label = T("Branch") else: f.label = T("National Society") # Requires # Filter by type ltable = db.org_organisation_organisation_type rows = db(ltable.organisation_type_id == type_id).select(ltable.organisation_id) filter_opts = [row.organisation_id for row in rows] auth = current.auth s3_has_role = auth.s3_has_role Admin = s3_has_role("ADMIN") if branches: if Admin: parent = True else: # @ToDo: Set the represent according to whether the user can see resources of just a single NS or multiple # @ToDo: Consider porting this into core user = auth.user if user: realms = user.realms #delegations = user.delegations if realms: parent = True else: parent = False else: parent = True else: # Keep the represent function as simple as possible parent = False # Exclude branches btable = s3db.org_organisation_branch rows = db((btable.deleted != True) & (btable.branch_id.belongs(filter_opts))).select(btable.branch_id) filter_opts = list(set(filter_opts) - set(row.branch_id for row in rows)) organisation_represent = s3db.org_OrganisationRepresent represent = organisation_represent(parent=parent) f.represent = represent from s3 import IS_ONE_OF requires = IS_ONE_OF(db, "org_organisation.id", represent, filterby = "id", filter_opts = filter_opts, updateable = updateable, orderby = "org_organisation.name", sort = True) if not required: from gluon import IS_EMPTY_OR requires = IS_EMPTY_OR(requires) f.requires = requires if parent and hierarchy: # Use hierarchy-widget from s3 import FS, S3HierarchyWidget # No need for parent in represent (it's a hierarchy view) node_represent = organisation_represent(parent=False) # Filter by type # (no need to exclude branches - we wouldn't be here if we didn't use branches) selector = FS("organisation_organisation_type.organisation_type_id") f.widget = S3HierarchyWidget(lookup="org_organisation", filter=(selector == type_id), represent=node_represent, multiple=False, leafonly=False, ) else: # Dropdown not Autocomplete f.widget = None # Comment if (Admin or s3_has_role("ORG_ADMIN")): # Need to do import after setting Theme from s3layouts import S3PopupLink from s3 import S3ScriptItem add_link = S3PopupLink(c = "org", f = "organisation", vars = {"organisation_type.name":"Red Cross / Red Crescent"}, label = T("Create National Society"), title = T("National Society"), ) comment = f.comment if not comment or isinstance(comment, S3PopupLink): f.comment = add_link elif isinstance(comment[1], S3ScriptItem): # Don't overwrite scripts f.comment[0] = add_link else: f.comment = add_link else: # Not allowed to add NS/Branch f.comment = ""
def testExportOptionsXMLHierarchy(self): """ Test Export Options (all options, XML+hierarchy) """ assertEqual = self.assertEqual assertTrue = self.assertTrue # Configure parent-field db = current.db table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF( db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db = current.s3db s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = { "name": "option3", "uuid": "OPTION3", "parent": list(options.keys())[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Request options resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], hierarchy=True) fo = etree.XML(result) # Inspect result xml = current.xml ATTRIBUTE = xml.ATTRIBUTE VALUE = ATTRIBUTE.value PARENT = ATTRIBUTE.parent UID = xml.UID has_empty = False self.assertEqual(len(fo), len(options) + 1) for opt in fo: assertEqual(opt.tag, "option") attr = opt.attrib assertTrue(VALUE in attr) value = attr[VALUE] if value == "": has_empty = True self.assertFalse(UID in attr) assertEqual(opt.text, None) continue else: value = int(value) assertTrue(value in options) assertEqual(opt.text, options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue(PARENT in attr) assertEqual(attr[PARENT], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def register(self, r, **attr): """ Register a test result @param r: the S3Request instance @param attr: controller attributes """ if r.http not in ("GET", "POST"): r.error(405, current.ERROR.BAD_METHOD) if not r.interactive: r.error(415, current.ERROR.BAD_FORMAT) T = current.T db = current.db s3db = current.s3db auth = current.auth request = current.request response = current.response s3 = response.s3 settings = current.deployment_settings # Page title and intro text title = T("Register Test Result") # Get intro text from CMS ctable = s3db.cms_post ltable = s3db.cms_post_module join = ltable.on((ltable.post_id == ctable.id) & \ (ltable.module == "disease") & \ (ltable.resource == "case_diagnostics") & \ (ltable.deleted == False)) query = (ctable.name == "TestResultRegistrationIntro") & \ (ctable.deleted == False) row = db(query).select( ctable.body, join=join, cache=s3db.cache, limitby=(0, 1), ).first() intro = row.body if row else None # Instantiate Consent Tracker consent = s3db.auth_Consent( processing_types=["CWA_ANONYMOUS", "CWA_PERSONAL"]) table = s3db.disease_case_diagnostics # Configure disease_id field = table.disease_id if field.writable: default_disease = None offset = 1 else: default_disease = field.default field.readable = False offset = 0 # Probe date is mandatory field = table.probe_date requires = field.requires if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # Configure device_id field = table.device_id field.readable = field.writable = True dtable = s3db.disease_testing_device query = (dtable.device_class == "RAT") & \ (dtable.approved == True) & \ (dtable.available == True) if default_disease: query = (dtable.disease_id == default_disease) & query field.requires = IS_ONE_OF( db(query), "disease_testing_device.id", field.represent, ) cwa_options = ( ("NO", T("Do not report")), ("ANONYMOUS", T("Issue anonymous contact tracing code")), ("PERSONAL", T("Issue personal test certificate")), ) formfields = [ # -- Test Result -- table.site_id, table.disease_id, table.probe_date, table.device_id, table.result, # -- Report to CWA -- Field( "report_to_cwa", "string", requires=IS_IN_SET(cwa_options, sort=False, zero=""), default="NO", label=T("Report test result to %(system)s") % CWA, ), Field( "last_name", label=T("Last Name"), ), Field( "first_name", label=T("First Name"), ), s3_date( "date_of_birth", label=T("Date of Birth"), month_selector=True, ), Field( "dcc_option", "boolean", default=False, label=T("Provide Digital %(title)s Certificate") % {"title": "COVID-19 Test"}, ), Field( "consent", label="", widget=consent.widget, ), ] # Required fields required_fields = [] # Subheadings subheadings = ( (0, T("Test Result")), (4 + offset, CWA["system"]), ) # Generate labels (and mark required fields in the process) labels, has_required = s3_mark_required( formfields, mark_required=required_fields, ) s3.has_required = has_required # Form buttons REGISTER = T("Submit") buttons = [ INPUT( _type="submit", _value=REGISTER, ), ] # Construct the form response.form_label_separator = "" form = SQLFORM.factory(table_name="test_result", record=None, hidden={"_next": request.vars._next}, labels=labels, separator="", showid=False, submit_button=REGISTER, delete_label=auth.messages.delete_label, formstyle=settings.get_ui_formstyle(), buttons=buttons, *formfields) # Identify form for CSS & JS Validation form.add_class("result-register") # Add Subheadings if subheadings: for pos, heading in subheadings[::-1]: form[0].insert(pos, DIV(heading, _class="subheading")) # Inject scripts script = "/%s/static/themes/RLP/js/testresult.js" % r.application if script not in s3.scripts: s3.scripts.append(script) s3.jquery_ready.append("S3EnableNavigateAwayConfirm()") if form.accepts( request.vars, current.session, formname="register", onvalidation=self.validate, ): formvars = form.vars # Create disease_case_diagnostics record testresult = { "result": formvars.get("result"), } if "site_id" in formvars: testresult["site_id"] = formvars["site_id"] if "disease_id" in formvars: testresult["disease_id"] = formvars["disease_id"] if "probe_date" in formvars: testresult["probe_date"] = formvars["probe_date"] if "device_id" in formvars: testresult["device_id"] = formvars["device_id"] record_id = table.insert(**testresult) if not record_id: raise RuntimeError("Could not create testresult record") testresult["id"] = record_id # Set record owner auth = current.auth auth.s3_set_record_owner(table, record_id) auth.s3_make_session_owner(table, record_id) # Onaccept s3db.onaccept(table, testresult, method="create") response.confirmation = T("Test Result registered") report_to_cwa = formvars.get("report_to_cwa") if report_to_cwa == "NO": # Do not report to CWA, just forward to read view self.next = r.url(id=record_id, method="read") else: # Report to CWA and show test certificate dcc_option = False if report_to_cwa == "ANONYMOUS": processing_type = "CWA_ANONYMOUS" cwa_report = CWAReport(record_id) elif report_to_cwa == "PERSONAL": dcc_option = formvars.get("dcc_option") processing_type = "CWA_PERSONAL" cwa_report = CWAReport( record_id, anonymous=False, first_name=formvars.get("first_name"), last_name=formvars.get("last_name"), dob=formvars.get("date_of_birth"), dcc=dcc_option, ) else: processing_type = cwa_report = None if cwa_report: # Register consent if processing_type: cwa_report.register_consent( processing_type, formvars.get("consent"), ) # Send to CWA success = cwa_report.send() if success: response.information = T( "Result reported to %(system)s") % CWA retry = False else: response.error = T("Report to %(system)s failed") % CWA retry = True # Store DCC data if dcc_option: cwa_data = cwa_report.data from .dcc import DCC try: hcert = DCC.from_result( cwa_data.get("hash"), record_id, cwa_data.get("fn"), cwa_data.get("ln"), cwa_data.get("dob"), ) except ValueError as e: hcert = None response.warning = str(e) if hcert: hcert.save() else: # Remove DCC flag if hcert could not be generated cwa_report.dcc = False S3CustomController._view("RLPPTM", "certificate.html") # Title field = table.disease_id if cwa_report.disease_id and field.represent: disease = field.represent(cwa_report.disease_id) title = "%s %s" % (disease, T("Test Result")) else: title = T("Test Result") return { "title": title, "intro": None, # TODO "form": cwa_report.formatted(retry=retry), } else: response.information = T( "Result not reported to %(system)s") % CWA self.next = r.url(id=record_id, method="read") return None elif form.errors: current.response.error = T( "There are errors in the form, please check your input") # Custom View S3CustomController._view("RLPPTM", "testresult.html") return { "title": title, "intro": intro, "form": form, }