def customise_org_organisation_resource(r, tablename): s3db = current.s3db # Use comments field for org description table = s3db.org_organisation field = table.comments from gluon import DIV field.comment = DIV( _class="tooltip", _title="%s|%s" % (T("About"), T("Describe the organisation, e.g. mission, history and other relevant details" ))) if not current.auth.is_logged_in(): field = table.logo field.readable = field.writable = False # User can create records since we need this during registration, # but we don't want to let the user do this from the list view s3db.configure( "org_organisation", listadd=False, ) # Custom filters to match the information provided from s3 import S3LocationFilter, \ S3OptionsFilter, \ S3TextFilter, \ s3_get_filter_opts filter_widgets = [ S3TextFilter( [ "name", "acronym", #"website", #"comments", ], label=T("Search"), comment= T("Search by organization name or acronym. You can use * as wildcard." ), ), S3OptionsFilter( "organisation_organisation_type.organisation_type_id", label=T("Type"), ), S3OptionsFilter( "service_location.service_location_service.service_id", options=s3_get_filter_opts( "org_service", translate=True, ), ), S3OptionsFilter( "sector_organisation.sector_id", options=s3_get_filter_opts( "org_sector", translate=True, ), hidden=True, ), ] # CRUD Form from s3 import S3SQLCustomForm, \ S3SQLInlineComponent, \ S3SQLInlineLink, \ S3SQLVerticalSubFormLayout multitype = settings.get_org_organisation_types_multiple() crud_form = S3SQLCustomForm( "name", "acronym", S3SQLInlineLink( "organisation_type", field="organisation_type_id", filter=False, label=T("Type"), multiple=multitype, ), "country", S3SQLInlineLink( "sector", cols=3, label=T("Sectors"), field="sector_id", #required = True, ), (T("About"), "comments"), "website", S3SQLInlineComponent( "contact", name="email", label=T("Email"), #multiple = False, fields=[ ("", "value"), ], filterby=[ { "field": "contact_method", "options": "EMAIL", }, ], ), S3SQLInlineComponent( "facility", label=T("Main Office"), fields=[ "name", "phone1", "phone2", #"email", "location_id", ], layout=S3SQLVerticalSubFormLayout, filterby={ "field": "main_facility", "options": True, }, multiple=False, ), S3SQLInlineComponent( "document", fields=[ (T("Title"), "name"), "file", ], filterby={ "field": "file", "options": "", "invert": True, }, label=T("Files"), name="file", ), S3SQLInlineComponent( "document", fields=[ (T("Title"), "name"), "url", ], filterby={ "field": "url", "options": None, "invert": True, }, label=T("Links"), name="url", ), ) s3db.configure( "org_organisation", filter_widgets=filter_widgets, crud_form=crud_form, )
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 customise_dc_target_resource(r, tablename): from gluon import IS_EMPTY_OR, URL from s3 import IS_ISO639_2_LANGUAGE_CODE, S3SQLCustomForm, S3TextFilter from templates.UCCE.controllers import dc_target_list_layout from templates.UCCE.controllers import text_filter_formstyle current.response.s3.crud_strings[tablename] = Storage( label_create = T("Create Survey"), title_display = T("Survey Details"), #title_list = T("Surveys"), title_list = "", title_update = T("Edit Survey"), #title_upload = T("Import Surveys"), label_list_button = T("List Surveys"), label_delete_button = T("Delete Survey"), msg_record_created = T("Survey added"), msg_record_modified = T("Survey updated"), msg_record_deleted = T("Survey deleted"), msg_list_empty = T("No Surveys currently registered")) s3db = current.s3db # Lift mandatory link to template so that we can create the template onaccept #s3db.dc_target.template_id.requires s3db.dc_target_l10n.language.requires = IS_EMPTY_OR(IS_ISO639_2_LANGUAGE_CODE(select = l10n_options, sort = True, translate = False, zero = "", )) # Custom Component s3db.add_components("dc_target", dc_target_l10n = {"joinby": "target_id", "multiple": False, }, ) s3db.configure("dc_target", create_next = URL(c="dc", f="template", vars={"target_id": "[id]"}), crud_form = S3SQLCustomForm((T("Survey name"), "name"), (T("Translation"), "target_l10n.language"), postprocess = dc_target_postprocess, ), listadd = False, list_fields = ["name", #"status", "project_target.project_id", ], list_layout = dc_target_list_layout, ondelete = dc_target_ondelete, filter_widgets = [S3TextFilter(["name", "project.name", ], formstyle = text_filter_formstyle, label = "", _placeholder = T("Search project or survey"), ), ], )
def prep(r): # Filter to persons who have a case registered resource = r.resource resource.add_filter(FS("dvr_case.id") != None) if r.component and r.id: ctable = r.component.table if "case_id" in ctable.fields and \ str(ctable.case_id.type)[:18] == "reference dvr_case": # Find the Case ID ltable = s3db.dvr_case_person query = (ltable.person_id == r.id) & \ (ltable.deleted != True) links = db(query).select(ltable.case_id, limitby=(0, 2)) case_id = ctable.case_id if links: # Set default case_id.default = links.first().case_id if len(links) == 1: # Only one case => hide case selector case_id.readable = case_id.writable = False else: # Configure case selector case_id.requires = IS_ONE_OF(db(query), "dvr_case.id", case_id.represent, ) if r.interactive: # Adapt CRUD strings to context s3.crud_strings["pr_person"] = Storage( label_create = T("Create Case"), title_display = T("Case Details"), title_list = T("Cases"), title_update = T("Edit Case Details"), label_list_button = T("List Cases"), label_delete_button = T("Delete Case"), msg_record_created = T("Case added"), msg_record_modified = T("Case details updated"), msg_record_deleted = T("Case deleted"), msg_list_empty = T("No Cases currently registered") ) if not r.component: # Module-specific CRUD form # NB: this assumes single case per person, must use # case perspective (dvr/case) for multiple cases # per person! from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm( "dvr_case.reference", "dvr_case.organisation_id", "dvr_case.date", "dvr_case.status_id", "first_name", "middle_name", "last_name", "date_of_birth", "gender", S3SQLInlineComponent( "contact", fields = [("", "value"), ], filterby = {"field": "contact_method", "options": "EMAIL", }, label = T("Email"), multiple = False, name = "email", ), S3SQLInlineComponent( "contact", fields = [("", "value"), ], filterby = {"field": "contact_method", "options": "SMS", }, label = T("Mobile Phone"), multiple = False, name = "phone", ), "person_details.nationality", S3SQLInlineComponent( "address", label = T("Current Address"), fields = [("", "location_id"), ], filterby = {"field": "type", "options": "1", }, link = False, multiple = False, ), "dvr_case.comments", ) # Module-specific filter widgets from s3 import get_s3_filter_opts, S3TextFilter, S3OptionsFilter filter_widgets = [ S3TextFilter(["first_name", "middle_name", "last_name", #"email.value", #"phone.value", "dvr_case.reference", ], label = T("Search"), comment = T("You can search by name or case number"), ), S3OptionsFilter("dvr_case.status_id", cols = 3, default = default_status, #label = T("Case Status"), options = s3db.dvr_case_status_filter_opts, sort = False, ), S3OptionsFilter("person_details.nationality", ), ] resource.configure(crud_form = crud_form, filter_widgets = filter_widgets, ) # Module-specific list fields (must be outside of r.interactive) list_fields = ["dvr_case.reference", "first_name", "middle_name", "last_name", "date_of_birth", "gender", "dvr_case.date", "dvr_case.status_id", ] resource.configure(list_fields = list_fields, ) return True
def customise_project_activity_resource(r, tablename): s3db = current.s3db if r.tablename == "project_project": # crud_form needs modifying to filter sectors by project's from s3 import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineLink # Limit Sectors to those for the Project table = s3db.project_sector_project query = (table.project_id == r.id) & \ (table.deleted == False) rows = current.db(query).select(table.sector_id) sector_ids = [row.sector_id for row in rows] crud_form = S3SQLCustomForm("name", "status_id", S3SQLInlineLink("sector", field = "sector_id", label = T("Sectors"), filterby = "id", options = sector_ids, widget = "groupedopts", ), S3SQLInlineLink("activity_type", field = "activity_type_id", label = T("Activity Types"), widget = "groupedopts", ), "location_id", "date", "end_date", S3SQLInlineComponent("distribution", fields = ["parameter_id", "value", (T("Intended Impact"), "comments"), ], label = T("Distributed Supplies"), ), "person_id", "comments", ) s3db.configure(tablename, crud_form = crud_form, ) list_fields = s3db.get_config(tablename, "list_fields") list_fields.insert(3, (T("Distributions"), "distribution.parameter_id")) # Done automatically from settings now #list_fields.insert(2, (T("Sectors"), "sector_activity.sector_id")) #list_fields.insert(3, (T("Activity Types"), "activity_activity_type.activity_type_id")) elif r.tablename == "project_activity": # Modify list_fields for desired Report format list_fields = [("CSO", "project_id$organisation_id"), (T("Activity"), "name"), (T("Intended Impact"), "distribution.comments"), (T("Location"), "location_id"), ] s3db.configure(tablename, deletable = False, editable = False, insertable = False, list_fields = list_fields, )
def prep(r): if r.interactive: if r.record: if not r.component: if r.method in ("check", "enable", "disable"): return True deployment_id = r.record.deployment_id if deployment_id: # Open on Deployment Tab redirect(URL(c="setup", f="deployment", args = [deployment_id, "server", r.id], )) # 'External' servers just added for Monitoring from s3 import S3SQLCustomForm f = s3db.setup_server.host_ip f.requires = f.requires.other # IP is required crud_form = S3SQLCustomForm("name", "host_ip", "role", "remote_user", "private_key", (T("Monitor"), "monitor_server.enabled"), "monitor_server.status", ) s3db.configure("setup_server", crud_form = crud_form, ) else: # No Cloud in create form # - we don't deploy Servers except within Deployments from s3 import S3SQLCustomForm f = s3db.setup_server.host_ip f.requires = f.requires.other # IP is required crud_form = S3SQLCustomForm(#"deployment_id", "name", "host_ip", "role", "remote_user", "private_key", (T("Monitor"), "monitor_server.enabled"), "monitor_server.status", ) list_fields = ["deployment_id", "name", "host_ip", "role", "monitor_server.enabled", "monitor_server.status", ] s3db.configure("setup_server", create_onaccept = None, # Handled by S3SQLCustomForm crud_form = crud_form, #insertable = False, # We want to allow monitoring of external hosts list_fields = list_fields, ) return True
def prep(r): if r.interactive: if r.component_name == "answer": # CRUD Strings tablename = r.component.tablename s3.crud_strings[tablename] = Storage( label_create=T("Create Responses"), title_display=T("Response Details"), title_list=T("Responses"), title_update=T("Edit Response"), label_list_button=T("List Responses"), label_delete_button=T("Clear Response"), msg_record_created=T("Response created"), msg_record_modified=T("Response updated"), msg_record_deleted=T("Response deleted"), msg_list_empty=T("No Responses currently defined"), ) # Custom Form with Questions & Subheadings sorted correctly from s3 import S3SQLCustomForm, S3SQLDummyField crud_fields = [] cappend = crud_fields.append template_id = r.record.template_id stable = db.dc_section # Extract the Sections query = (stable.template_id == template_id) & \ (stable.deleted == False) sections = db(query).select( stable.id, stable.parent, stable.name, stable.posn, distinct=True, ) # Put them into the hierarchy root_sections = {} subsections = {} for section in sections: parent = section.parent if parent: # Store this for next parse if parent in subsections: subsections[parent].append(section) else: subsections[parent] = [section] else: # Root section root_sections[section.id] = { "id": section.id, "name": section.name, "posn": section.posn, "questions": [], "subsections": {}, } # Add the subsections subsubsections = {} for parent in subsections: _subsections = subsections[parent] if parent in root_sections: # SubSections for sub in _subsections: root_sections[parent]["subsections"][sub.id] = { "id": sub.id, "name": sub.name, "posn": sub.posn, "questions": [], "subsubsections": {}, } else: # SubSubSections - store for next parse subsubsections[parent] = _subsections # Add the subsubsections for parent in subsubsections: for root in root_sections: subsections = root_sections[root]["subsections"] if parent in subsections: _subsubsections = subsubsections[parent] for subsub in _subsubsections: subsections[parent]["subsubsections"][ subsub.id] = { "id": subsub.id, "name": subsub.name, "posn": subsub.posn, "questions": [], } # Add the Questions # Prep for Auto-Totals # Prep for Grids qtable = s3db.dc_question ftable = db.s3_field query = (qtable.template_id == r.record.template_id) & \ (qtable.deleted == False) left = [ stable.on(stable.id == qtable.section_id), ftable.on(ftable.id == qtable.field_id), ] questions = db(query).select( stable.id, qtable.posn, qtable.code, qtable.totals, qtable.grid, ftable.name, left=left, ) auto_totals = {} codes = {} grids = {} grid_children = {} root_questions = [] for question in questions: field_name = question.get("s3_field.name") code = question["dc_question.code"] if code: codes[code] = field_name totals = question["dc_question.totals"] if totals: auto_totals[field_name] = { "codes": totals, "fields": [], } grid = question["dc_question.grid"] if grid: len_grid = len(grid) if len_grid == 2: # Grid Pseudo-Question if not code: s3.error( "Code required for Grid Questions" ) # @ToDo: Make mandatory in onvalidation raise rows = [s3_str(T(v)) for v in grid[0]] cols = [s3_str(T(v)) for v in grid[1]] fields = [[0 for x in range(len(rows))] for y in range(len(cols))] grids[code] = { "r": rows, "c": cols, "f": fields, } elif len_grid == 3: # Child Question grid_children[field_name] = grid else: s3.warning("Invalid grid data for %s - ignoring" % (code or field_name)) section_id = question["dc_section.id"] question = { question["dc_question.posn"]: { "name": field_name, "code": code, }, } if not section_id: root_questions.append(question) continue if section_id in root_sections: root_sections[section_id]["questions"].append(question) continue for section in root_sections: if section_id in root_sections[section]["subsections"]: root_sections[section]["subsections"][section_id][ "questions"].append(question) continue for subsection in root_sections[section][ "subsections"]: if section_id in root_sections[section][ "subsections"][subsection][ "subsubsections"]: root_sections[section]["subsections"][ subsection]["subsubsections"][section_id][ "questions"].append(question) # Sort them by Position root_questions.sort() sections = [{v["posn"]: v} for k, v in root_sections.items()] sections.sort() for s in sections: section = s[s.items()[0][0]] subsections = [{ v["posn"]: v } for k, v in section["subsections"].items()] subsections.sort() section["subsections"] = subsections section["questions"].sort() for sub in subsections: _sub = sub[sub.items()[0][0]] subsubsections = [{ v["posn"]: v } for k, v in _sub["subsubsections"].items()] subsubsections.sort() _sub["subsubsections"] = subsubsections _sub["questions"].sort() for subsub in subsubsections: subsub[subsub.items()[0][0]]["questions"].sort() # Append questions to the form, with subheadings # 1st add those questions without a section (likely the only questions then) for question in root_questions: fname = question["name"] if fname: cappend(fname) else: # Grid Pseudo-Question fname = question["code"] cappend(S3SQLDummyField(fname)) # Next add those questions with a section (likely the only questions then) subheadings = {} for s in sections: section = s[s.items()[0][0]] section_name = section["name"] # 1st add those questions without a subsection _subheadings = { "fields": [], "subheadings": {}, } subheadings[section_name] = _subheadings questions = section["questions"] for question in questions: question = question.items()[0][1] fname = question["name"] if fname: cappend(fname) else: # Grid Pseudo-Question fname = question["code"] cappend(S3SQLDummyField(fname)) _subheadings["fields"].append(fname) # Next add those questions in a subsection subsections = section["subsections"] for sub in subsections: _sub = sub[sub.items()[0][0]] section_name = _sub["name"] __subheadings = { "fields": [], "subheadings": {}, } _subheadings["subheadings"][ section_name] = __subheadings questions = _sub["questions"] for question in questions: question = question.items()[0][1] fname = question["name"] if fname: cappend(fname) else: # Grid Pseudo-Question fname = question["code"] cappend(S3SQLDummyField(fname)) __subheadings["fields"].append(fname) # Next add those questions in a subsection subsubsections = _sub["subsubsections"] for subsub in subsubsections: _subsub = subsub[subsub.items()[0][0]] section_name = _subsub["name"] ___subheadings = { "fields": [], "subheadings": {}, } __subheadings["subheadings"][ section_name] = ___subheadings questions = _subsub["questions"] for question in questions: question = question.items()[0][1] fname = question["name"] if fname: cappend(fname) else: # Grid Pseudo-Question fname = question["code"] cappend(S3SQLDummyField(fname)) ___subheadings["fields"].append(fname) crud_form = S3SQLCustomForm(*crud_fields) s3db.configure( tablename, crud_form=crud_form, subheadings=subheadings, ) # Compact JSON encoding SEPARATORS = (",", ":") jappend = s3.jquery_ready.append # Auto-Totals for field in auto_totals: f = auto_totals[field] append = f["fields"].append for code in f["codes"]: append(codes.get(code)) jappend( '''S3.autoTotals('%s',%s,'%s')''' % (field, json.dumps(f["fields"], separators=SEPARATORS), dtablename)) # Grids # Place the child fields in the correct places in their grids if len(grids): for child in grid_children: code, row, col = grid_children[child] grids[code]["f"][col - 1][row - 1] = child jappend( '''S3.dc_grids(%s,'%s')''' % (json.dumps(grids, separators=SEPARATORS), dtablename)) # Add JS if s3.debug: s3.scripts.append("/%s/static/scripts/S3/s3.dc_answer.js" % appname) else: s3.scripts.append( "/%s/static/scripts/S3/s3.dc_answer.min.js" % appname) return True
def customise_project_activity_resource(r, tablename): s3db = current.s3db tablename = "project_activity" # Custom Filtered Components s3db.add_components( tablename, project_activity_organisation=( # Agency { "name": "agency", "joinby": "activity_id", "filterby": { "role": 1, }, #"multiple": False, }, # Partners { "name": "partner", "joinby": "activity_id", "filterby": { "role": 2, }, #"multiple": False, }, # Donors { "name": "donor", "joinby": "activity_id", "filterby": { "role": 3, }, #"multiple": False, }, ), project_activity_tag=( # Modality { "name": "modality", "joinby": "activity_id", "filterby": { "tag": "modality", }, "multiple": False, }, # Number { "name": "number", "joinby": "activity_id", "filterby": { "tag": "number", }, "multiple": False, }, )) # Individual settings for specific tag components from gluon import IS_EMPTY_OR, IS_IN_SET, IS_INT_IN_RANGE components_get = r.resource.components.get donor = components_get("donor") donor.table.organisation_id.default = None partner = components_get("partner") partner.table.organisation_id.default = None modality = components_get("modality") modality.table.value.requires = IS_EMPTY_OR( IS_IN_SET(("Cash", "In-kind"))) number = components_get("number") number.table.value.requires = IS_EMPTY_OR(IS_INT_IN_RANGE()) s3db.project_activity_data.unit.requires = IS_EMPTY_OR( IS_IN_SET(("People", "Households"))) from s3 import S3LocationFilter, S3OptionsFilter, S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineLink crud_form = S3SQLCustomForm( S3SQLInlineLink( "event", field="event_id", label=T("Disaster"), multiple=False, #required = True, ), S3SQLInlineComponent( "agency", name="agency", label=T("Agency"), fields=[ ("", "organisation_id"), ], #multiple = False, required=True, ), # @ToDo: MultiSelectWidget is nicer UI but S3SQLInlineLink # requires the link*ed* table as component (not the # link table as applied here) and linked components # cannot currently be filtered by link table fields # (=> should solve the latter rather than the former) # @ToDo: Fix Create Popups S3SQLInlineComponent( "partner", name="partner", label=T("Implementing Partner"), fields=[ ("", "organisation_id"), ], ), S3SQLInlineComponent( "donor", name="donor", label=T("Donor"), fields=[ ("", "organisation_id"), ], ), "location_id", S3SQLInlineLink( "sector", field="sector_id", filter=False, label=T("Sector"), multiple=False, ), (T("Relief Items/Activity"), "name"), S3SQLInlineComponent( "modality", name="modality", label=T("Modality"), fields=[ ("", "value"), ], multiple=False, ), S3SQLInlineComponent( "number", name="number", label=T("Number of Items/Kits/Activities"), fields=[ ("", "value"), ], multiple=False, ), (T("Activity Date (Planned/Start Date)"), "date"), (T("Activity Date (Completion Date)"), "end_date"), S3SQLInlineComponent( "activity_data", label="", fields=[ (T("People / Households"), "unit"), (T("Total Number People/HH Targeted"), "target_value"), (T("Total Number Of People/HH Reache"), "value"), ], multiple=False, ), (T("Activity Status"), "status_id"), "comments", ) filter_widgets = [ S3OptionsFilter("event.event_type_id"), S3OptionsFilter( "event__link.event_id" ), # @ToDo: Filter this list dynamically based on Event Type S3OptionsFilter("sector_activity.sector_id"), S3LocationFilter( "location_id", # These levels are for SHARE/LK levels=("L2", "L3", "L4"), ), S3OptionsFilter( "status_id", cols=4, label=T("Status"), ), ] s3db.configure( tablename, crud_form=crud_form, filter_widgets=filter_widgets, list_fields=[ (T("Disaster"), "event__link.event_id"), (T("Agency"), "agency.organisation_id"), (T("Implementing Partner"), "partner.organisation_id"), (T("Donor"), "donor.organisation_id"), (T("District"), "location_id$L1"), (T("DS Division"), "location_id$L2"), (T("GN Division"), "location_id$L3"), (T("Sector"), "sector_activity.sector_id"), (T("Relief Items/Activity"), "name"), (T("Modality"), "modality.value"), (T("Number of Items/Kits/Activities"), "number.value"), (T("Activity Date (Planned/Start Date)"), "date"), (T("Activity Date (Completion Date)"), "end_date"), (T("People / Households"), "activity_data.unit"), (T("Total Number People/HH Targeted"), "activity_data.target_value"), (T("Total Number Of People/HH Reached"), "activity_data.value"), (T("Activity Status"), "status_id"), "comments", ], )
def customise_req_need_resource(r, tablename): s3db = current.s3db tablename = "req_need" # Custom Filtered Components s3db.add_components( tablename, req_need_tag=( # Verified { "name": "verified", "joinby": "need_id", "filterby": { "tag": "verified", }, "multiple": False, }, )) # Individual settings for specific tag components from gluon import IS_EMPTY_OR, IS_IN_SET components_get = r.resource.components.get verified = components_get("verified") f = verified.table.value f.requires = IS_EMPTY_OR(IS_IN_SET((True, False))) auth = current.auth if auth.s3_has_role("ADMIN"): f.default = True else: user = auth.user if user and user.organisation_id: f.default = True else: f.default = False f.writable = False from s3 import S3LocationFilter, S3OptionsFilter, S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineLink crud_form = S3SQLCustomForm( S3SQLInlineLink( "event", field="event_id", label=T("Disaster"), multiple=False, #required = True, ), "location_id", "date", "priority", S3SQLInlineLink( "sector", field="sector_id", filter=False, label=T("Sector"), multiple=False, ), "summary", S3SQLInlineComponent( "verified", name="verified", label=T("Verified"), fields=[ ("", "value"), ], multiple=False, ), "status", "comments", ) filter_widgets = [ S3OptionsFilter("event.event_type_id"), S3OptionsFilter( "event__link.event_id" ), # @ToDo: Filter this list dynamically based on Event Type S3OptionsFilter("sector__link.sector_id"), S3LocationFilter( "location_id", # These levels are for SHARE/LK levels=("L2", "L3", "L4"), ), S3OptionsFilter( "status", cols=3, label=T("Status"), ), S3OptionsFilter( "verified.value", cols=2, label=T("Verified"), ), ] s3db.configure( tablename, crud_form=crud_form, filter_widgets=filter_widgets, list_fields=[ (T("Disaster"), "event__link.event_id"), # These levels/Labels are for SHARE/LK (T("District"), "location_id$L2"), (T("DS"), "location_id$L3"), (T("GN"), "location_id$L4"), "date", "priority", "summary", "sector__link.sector_id", (T("Status"), "status"), (T("Verified"), "verified.value"), ], )
def prep(r): if r.interactive: s3.scripts.append("/%s/static/scripts/S3/s3.setup.js" % appname) if r.component: # No new servers once deployment is created #s3db.configure("setup_server", # insertable = False # ) # Check if no scheduler task is pending itable = s3db.setup_instance sctable = db.scheduler_task query = (itable.deployment_id == r.id) & \ ((sctable.status != "COMPLETED") & \ (sctable.status != "FAILED")) & \ (itable.task_id == sctable.id) exists = db(query).select(itable.task_id, limitby = (0, 1) ).first() if exists: # Disable creation of new instances s3db.configure("setup_instance", insertable = False ) elif r.component.name == "instance": if r.method in (None, "create"): # Remove already-deployed instances from dropdown itable = db.setup_instance sctable = db.scheduler_task query = (itable.deployment_id == r.id) & \ (sctable.status == "COMPLETED") rows = db(query).select(itable.type, join = itable.on(itable.task_id == sctable.id) ) types = {1: "prod", 2: "test", 3: "demo", } for row in rows: del types[row.type] itable.type.requires = IS_IN_SET(types) elif r.method == "create": # Include Production URL in main form # Redefine Component to make 1:1 s3db.add_components("setup_deployment", setup_instance = {"joinby": "deployment_id", "multiple": False, }, ) # Attach components (we're past resource initialization) hooks = s3db.get_components("setup_deployment", names=("instance",)) for component_alias in hooks: r.resource._attach(component_alias, hooks[component_alias]) from s3 import S3SQLCustomForm crud_form = S3SQLCustomForm("name", (T("Public URL"), "instance.url"), "repo_url", "country", "template", "webserver_type", "db_type", "remote_user", "private_key", #"secret_key", #"access_key", ) s3db.configure("setup_deployment", crud_form = crud_form, ) return True
def customise_org_organisation_resource(r, tablename): s3db = current.s3db tablename = "org_organisation" # Custom Components for Verified s3db.add_components( tablename, org_organisation_tag=( # Request Number { "name": "req_number", "joinby": "organisation_id", "filterby": { "tag": "req_number", }, "multiple": False, }, # Vision { "name": "vision", "joinby": "organisation_id", "filterby": { "tag": "vision", }, "multiple": False, }, ), ) from s3 import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineLink, s3_comments_widget # Individual settings for specific tag components components_get = r.resource.components.get vision = components_get("vision") vision.table.value.widget = s3_comments_widget crud_form = S3SQLCustomForm( "name", "acronym", S3SQLInlineLink( "organisation_type", field="organisation_type_id", # Default 10 options just triggers which adds unnecessary complexity to a commonly-used form & commonly an early one (create Org when registering) filter=False, label=T("Type"), multiple=False, widget="multiselect", ), S3SQLInlineLink( "sector", columns=4, field="sector_id", label=T("Sectors"), ), #S3SQLInlineLink("service", # columns = 4, # field = "service_id", # label = T("Services"), # ), "country", "phone", "website", "logo", (T("About"), "comments"), S3SQLInlineComponent( "vision", label=T("Vision"), fields=[("", "value")], multiple=False, ), S3SQLInlineComponent( "req_number", label=T("Request Number"), fields=[("", "value")], multiple=False, ), ) s3db.configure( tablename, crud_form=crud_form, )
def prep(r): fiscal_code = s3db.evr_case.fiscal_code if r.method == "update": fiscal_code.requires = None else: fiscal_code.requires = \ IS_EMPTY_OR(IS_NOT_IN_DB(db(db.evr_case.deleted != True), fiscal_code), null="" ) r.resource.configure(list_fields = ["id", "first_name", #"middle_name", "last_name", "gender", "date_of_birth", (T("Age"), "age"), ]) if r.interactive and not r.component: resource = r.resource # Filter widgets from s3 import S3TextFilter filter_widgets = [ S3TextFilter(["first_name", #"middle_name", "last_name", #"local_name", "identity.value", "case.fiscal_code" ], label = T("Name and/or ID"), comment = T("To search for a person, enter any of the " "first, middle or last names and/or an ID " "number of a person, separated by spaces. " "You may use % as wildcard."), ), ] # Custom Form for Persons from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm("first_name", #"middle_name", "last_name", "date_of_birth", "person_details.place_of_birth", "case.fiscal_code", S3SQLInlineComponent( "identity", label = T("Identity Documents"), fields = ["type", "value", ], ), "gender", "person_details.marital_status", "person_details.nationality", #"person_details.religion", "person_details.occupation", #"person_details.company", "comments", ) resource.configure(crud_form = crud_form, filter_widgets = filter_widgets, ) elif r.representation in ("pdf", "xls"): # List fields list_fields = ["id", "first_name", #"middle_name", "last_name", "gender", #"date_of_birth", (T("Age"), "age"), "person_details.nationality", "person_details.religion", (T("Contact"), "contact.value"), (T("Shelter"), "shelter_registration.shelter_id$name") ] r.resource.configure(list_fields=list_fields) return True
def __call__(self): """ The userstats controller """ # Require ORG_GROUP_ADMIN auth = current.auth if not auth.s3_has_role("ORG_GROUP_ADMIN"): auth.permission.fail() from s3 import S3CRUD, s3_get_extension, s3_request request = current.request args = request.args # Create an S3Request r = s3_request( "org", "organisation", c="default", f="index/%s" % args[0], args=args[1:], extension=s3_get_extension(request), ) # Filter to root organisations resource = r.resource resource.add_filter(FS("id").belongs(self.root_orgs)) # Configure field methods from gluon import Field table = resource.table table.total_accounts = Field.Method("total_accounts", self.total_accounts) table.active_accounts = Field.Method("active_accounts", self.active_accounts) table.disabled_accounts = Field.Method("disabled_accounts", self.disabled_accounts) table.active30 = Field.Method("active30", self.active30) # Labels for field methods T = current.T TOTAL = T("Total User Accounts") ACTIVE = T("Active") DISABLED = T("Inactive") ACTIVE30 = T("Logged-in Last 30 Days") # Configure list_fields list_fields = ( "id", "name", (TOTAL, "total_accounts"), (ACTIVE, "active_accounts"), (DISABLED, "disabled_accounts"), (ACTIVE30, "active30"), ) # Configure form from s3 import S3SQLCustomForm, S3SQLVirtualField crud_form = S3SQLCustomForm( "name", S3SQLVirtualField( "total_accounts", label=TOTAL, ), S3SQLVirtualField( "active_accounts", label=ACTIVE, ), S3SQLVirtualField( "disabled_accounts", label=DISABLED, ), S3SQLVirtualField( "active30", label=ACTIVE30, ), ) # Configure read-only resource.configure( insertable=False, editable=False, deletable=False, crud_form=crud_form, filter_widgets=None, list_fields=list_fields, ) output = r(rheader=self.rheader) if isinstance(output, dict): output["title"] = T("User Statistics") # URL to open the resource open_url = resource.crud._linkto(r, update=False)("[id]") # Add action button for open action_buttons = S3CRUD.action_buttons action_buttons( r, deletable=False, copyable=False, editable=False, read_url=open_url, ) return output
def customise_project_project_resource(r, tablename): s3db = current.s3db table = s3db.project_project # Make project description mandatory field = table.description from gluon import IS_NOT_EMPTY field.requires = IS_NOT_EMPTY( error_message=T("Enter a project description"), ) if r.interactive: # Custom filter widgets LEAD_ROLE = settings.get_project_organisation_lead_role() org_label = settings.get_project_organisation_roles()[LEAD_ROLE] from s3 import S3DateFilter, \ S3LocationFilter, \ S3OptionsFilter, \ S3TextFilter filter_widgets = [ S3TextFilter( [ "name", "description", ], label=T("Search"), comment=T("Search for a Project by name or description."), ), S3LocationFilter("location.location_id", ), S3OptionsFilter( "sector_project.sector_id", label=T("Sector"), location_filter=True, none=True, ), S3OptionsFilter( "hazard_project.hazard_id", label=T("Hazard"), help_field=s3db.project_hazard_help_fields, cols=4, hidden=True, ), S3OptionsFilter( "status_id", label=T("Status"), cols=4, hidden=True, ), S3DateFilter( "start_date", hidden=True, ), S3DateFilter( "end_date", hidden=True, ), S3OptionsFilter( "organisation_id", label=org_label, hidden=True, ), ] # Custom CRUD form from s3 import S3SQLCustomForm, \ S3SQLInlineComponent, \ S3SQLInlineLink crud_form = S3SQLCustomForm( "organisation_id", "name", "description", "status_id", "start_date", "end_date", "budget", "currency", S3SQLInlineLink( "hazard", label=T("Hazards"), field="hazard_id", help_field=s3db.project_hazard_help_fields, cols=4, translate=True, ), S3SQLInlineLink( "sector", label=T("Sectors"), field="sector_id", cols=4, translate=True, ), "objectives", "human_resource_id", S3SQLInlineComponent( "document", fields=[ (T("Title"), "name"), "file", ], filterby={ "field": "file", "options": "", "invert": True, }, label=T("Files"), name="file", ), S3SQLInlineComponent( "document", fields=[ (T("Title"), "name"), "url", ], filterby={ "field": "url", "options": None, "invert": True, }, label=T("Links"), name="url", ), "comments", ) s3db.configure( "project_project", crud_form=crud_form, filter_widgets=filter_widgets, ) # Custom list fields list_fields = [ "name", "location.location_id", "organisation_id", (T("Sectors"), "sector_project.sector_id"), (T("Hazards"), "hazard_project.hazard_id"), "status_id", "start_date", "end_date", ] s3db.configure( "project_project", list_fields=list_fields, )
def prep(r): if r.interactive: s3.scripts.append("/%s/static/scripts/S3/s3.setup.js" % appname) if r.component: # No new servers once deployment is created #s3db.configure("setup_server", # insertable = False # ) # Check if no scheduler task is pending #itable = s3db.setup_instance #sctable = db.scheduler_task #query = (itable.deployment_id == r.id) & \ # ((sctable.status != "COMPLETED") & \ # (sctable.status != "FAILED")) & \ # (itable.task_id == sctable.id) #exists = db(query).select(itable.task_id, # limitby = (0, 1) # ).first() #if exists: # # Disable creation of new instances # s3db.configure("setup_instance", # insertable = False # ) if r.component.name == "instance": if r.method in (None, "create"): itable = db.setup_instance # Additional instances off by default itable.start.default = False # Remove already-deployed instances from dropdown sctable = db.scheduler_task query = (itable.deployment_id == r.id) & \ (sctable.status == "COMPLETED") rows = db(query).select(itable.type, join = itable.on(itable.task_id == sctable.id) ) types = {1: "prod", 2: "setup", 3: "test", 4: "demo", } for row in rows: del types[row.type] itable.type.requires = IS_IN_SET(types) elif r.method == "create": # Include Production Instance & Server details in main form from s3 import S3SQLCustomForm crud_form = S3SQLCustomForm((T("Production URL"), "production.url"), "production.sender", #"repo_url", "country", "template", "webserver_type", "db_type", "production_server.remote_user", "production_server.private_key", #"secret_key", #"access_key", ) s3db.configure("setup_deployment", crud_form = crud_form, ) return True
def needs(): """ RESTful CRUD controller """ from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_fields = [ "name", "location_id", ] cappend = crud_fields.append # Demographics field = s3db.assess_needs_demographic_data.parameter_id field.writable = False field.comment = None table = s3db.stats_demographic rows = db(table.deleted != True).select( table.parameter_id, table.name, ) label = T("Demographics") number = 0 for row in rows: name = "number%s" % number number += 1 cappend( S3SQLInlineComponent( "demographic", name=name, label=label, fields=( ("", "parameter_id"), ("", "value"), ), filterby=dict(field="parameter_id", options=row.parameter_id), multiple=False, ), ) label = "" # Needs table = s3db.assess_need rows = db(table.deleted != True).select( table.id, table.name, ) label = T("Needs") #number = 0 for row in rows: name = "number%s" % number number += 1 cappend( S3SQLInlineComponent( "need", name=name, label=label, fields=( ("", "need_id"), ("", "value"), ), filterby=dict(field="need_id", options=row.id), multiple=False, ), ) label = "" crud_form = S3SQLCustomForm(*crud_fields) s3db.configure( "assess_needs", crud_form=crud_form, ) return s3_rest_controller()
def deployment(): from s3 import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineLink #s3db.configure("setup_deployment", onvalidation=validate_deployment) crud_form = S3SQLCustomForm( "name", "distro", "remote_user", "secret_key", "access_key", "private_key", "webserver_type", "db_type", "db_password", "db_type", "db_password", "repo_url", "template", S3SQLInlineComponent( "server", label=T("Server Role"), fields=["role", "host_ip", "hostname"], ), S3SQLInlineComponent( "instance", label=T("Instance Type"), fields=["type", "url", "prepop_options"], #filterby=dict(field = "type", #options = ["prod", "demo"] #), multiple=False, ), ) s3db.configure("setup_deployment", crud_form=crud_form) def prep(r): if r.method in ("create", None): s3.scripts.append("/%s/static/scripts/S3/s3.setup.js" % appname) if r.interactive: if r.component and r.id: # Set up the prepop options according to the template prepop_options = s3db.setup_get_prepop_options( r.record.template) db.setup_instance.prepop_options.requires = IS_IN_SET( prepop_options, multiple=True) # No new servers once deployment is created s3db.configure("setup_server", insertable=False) # Check if no scheduler task is pending itable = db.setup_instance sctable = db.scheduler_task query = (itable.deployment_id == r.id) & \ ((sctable.status != "COMPLETED") & \ (sctable.status != "FAILED")) rows = db(query).select( itable.scheduler_id, join=itable.on(itable.scheduler_id == sctable.id)) if rows: # Disable creation of new instances s3db.configure("setup_instance", insertable=False) elif r.component.name == "instance": if r.method in (None, "create"): # Remove deployed instances from drop down itable = db.setup_instance sctable = db.scheduler_task query = (itable.deployment_id == r.id) & \ (sctable.status == "COMPLETED") rows = db(query).select( itable.type, join=itable.on(itable.scheduler_id == sctable.id)) types = {1: "prod", 2: "test", 3: "demo", 4: "dev"} for row in rows: del types[row.type] itable.type.requires = IS_IN_SET(types) return True s3.prep = prep def postp(r, output): if r.component is None: if r.method in (None, "read") and r.id: # get scheduler status for the last queued task itable = db.setup_instance sctable = db.scheduler_task query = (db.setup_instance.deployment_id == r.id) row = db(query).select( sctable.id, sctable.status, join=itable.on(itable.scheduler_id == sctable.id), orderby=itable.scheduler_id).last() item_append = output["item"][0].append item_append(TR(TD(LABEL("Status"), _class="w2p_fl"))) item_append(TR(TD(row.status))) if row.status == "FAILED": resource = s3db.resource("scheduler_run") task = db( resource.table.task_id == row.id).select().first() item_append(TR(TD(LABEL("Traceback"), _class="w2p_fl"))) item_append(TR(TD(task.traceback))) item_append(TR(TD(LABEL("Output"), _class="w2p_fl"))) item_append(TR(TD(task.run_output))) elif r.component.name == "instance": if r.method in (None, "read"): s3.actions = [ { "url": URL(c=module, f="management", vars={ "instance": "[id]", "type": "clean", "deployment": r.id, }), "_class": "action-btn", "label": "Clean" }, { "url": URL(c=module, f="management", vars={ "instance": "[id]", "type": "eden", "deployment": r.id }), "_class": "action-btn", "label": "Upgrade Eden" }, ] return output s3.postp = postp return s3_rest_controller(rheader=s3db.setup_rheader)
def prep(r): # Filter to persons who have a case registered resource = r.resource resource.add_filter(FS("dvr_case.id") != None) beneficiary = settings.get_dvr_label( ) # If we add more options in future then == "Beneficiary" if beneficiary: CASES = T("Beneficiaries") CURRENT = T("Current Beneficiaries") CLOSED = T("Former Beneficiaries") else: CASES = T("Cases") CURRENT = T("Current Cases") CLOSED = T("Closed Cases") # Filters to split case list if not r.record: get_vars = r.get_vars # Filter to active/archived cases archived = get_vars.get("archived") if archived == "1": archived = True CASES = T("Archived Cases") query = FS("dvr_case.archived") == True else: archived = False query = (FS("dvr_case.archived") == False) | \ (FS("dvr_case.archived") == None) # Filter to open/closed cases # (also filtering status filter opts) closed = get_vars.get("closed") get_status_opts = s3db.dvr_case_status_filter_opts if closed == "1": CASES = CLOSED query &= FS("dvr_case.status_id$is_closed") == True status_opts = lambda: get_status_opts(closed=True) elif closed == "0": CASES = CURRENT query &= (FS("dvr_case.status_id$is_closed") == False) | \ (FS("dvr_case.status_id$is_closed") == None) status_opts = lambda: get_status_opts(closed=False) else: status_opts = get_status_opts resource.add_filter(query) else: archived = False status_opts = s3db.dvr_case_status_filter_opts # Should not be able to delete records in this view resource.configure(deletable=False) if r.component and r.id: ctable = r.component.table if "case_id" in ctable.fields and \ str(ctable.case_id.type)[:18] == "reference dvr_case": # Find the Case ID dvr_case = s3db.dvr_case query = (dvr_case.person_id == r.id) & \ (dvr_case.deleted != True) cases = db(query).select(dvr_case.id, limitby=(0, 2)) case_id = ctable.case_id if cases: # Set default case_id.default = cases.first().id if len(cases) == 1: # Only one case => hide case selector case_id.readable = case_id.writable = False else: # Configure case selector case_id.requires = IS_ONE_OF( db(query), "dvr_case.id", case_id.represent, ) if r.interactive: # Adapt CRUD strings to context if beneficiary: s3.crud_strings["pr_person"] = Storage( label_create=T("Create Beneficiary"), title_display=T("Beneficiary Details"), title_list=CASES, title_update=T("Edit Beneficiary Details"), label_list_button=T("List Beneficiaries"), label_delete_button=T("Delete Beneficiary"), msg_record_created=T("Beneficiary added"), msg_record_modified=T("Beneficiary details updated"), msg_record_deleted=T("Beneficiary deleted"), msg_list_empty=T("No Beneficiaries currently registered")) else: s3.crud_strings["pr_person"] = Storage( label_create=T("Create Case"), title_display=T("Case Details"), title_list=CASES, title_update=T("Edit Case Details"), label_list_button=T("List Cases"), label_delete_button=T("Delete Case"), msg_record_created=T("Case added"), msg_record_modified=T("Case details updated"), msg_record_deleted=T("Case deleted"), msg_list_empty=T("No Cases currently registered")) if not r.component: # Expose the "archived"-flag? (update forms only) if r.record and r.method != "read": ctable = s3db.dvr_case field = ctable.archived field.readable = field.writable = True # Module-specific CRUD form # NB: this assumes single case per person, must use # case perspective (dvr/case) for multiple cases # per person! from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm( "dvr_case.reference", "dvr_case.organisation_id", "dvr_case.date", "dvr_case.status_id", "first_name", "middle_name", "last_name", "date_of_birth", "gender", S3SQLInlineComponent( "contact", fields=[ ("", "value"), ], filterby={ "field": "contact_method", "options": "EMAIL", }, label=T("Email"), multiple=False, name="email", ), S3SQLInlineComponent( "contact", fields=[ ("", "value"), ], filterby={ "field": "contact_method", "options": "SMS", }, label=T("Mobile Phone"), multiple=False, name="phone", ), "person_details.nationality", S3SQLInlineComponent( "address", label=T("Current Address"), fields=[ ("", "location_id"), ], filterby={ "field": "type", "options": "1", }, link=False, multiple=False, ), "dvr_case.comments", "dvr_case.archived", ) # Module-specific filter widgets from s3 import s3_get_filter_opts, S3TextFilter, S3OptionsFilter filter_widgets = [ S3TextFilter( [ "pe_label", "first_name", "middle_name", "last_name", #"email.value", #"phone.value", "dvr_case.reference", ], label=T("Search"), comment=T("You can search by name, ID or case number"), ), S3OptionsFilter( "dvr_case.status_id", cols=3, default=default_status, #label = T("Case Status"), options=status_opts, sort=False, ), S3OptionsFilter("person_details.nationality", ), ] # Add filter for case flags if settings.get_dvr_case_flags(): filter_widgets.append( S3OptionsFilter( "case_flag_case.flag_id", label=T("Flags"), options=s3_get_filter_opts( "dvr_case_flag", translate=True, ), cols=3, hidden=True, )) # Add filter for transferability if relevant for deployment if settings.get_dvr_manage_transferability(): filter_widgets.append( S3OptionsFilter( "dvr_case.transferable", options={ True: T("Yes"), False: T("No"), }, cols=2, hidden=True, )) resource.configure( crud_form=crud_form, filter_widgets=filter_widgets, ) elif r.component_name == "allowance" and \ r.method in (None, "update"): records = r.component.select(["status"], as_rows=True) if len(records) == 1: record = records[0] table = r.component.table readonly = [] if record.status == 2: # Can't change payment details if already paid readonly = [ "person_id", "entitlement_period", "date", "paid_on", "amount", "currency", ] for fn in readonly: if fn in table.fields: field = table[fn] field.writable = False field.comment = None elif r.component_name == "evaluation": S3SQLInlineComponent = s3base.S3SQLInlineComponent crud_fields = [ #"person_id", #"case_id", #"date", ] cappend = crud_fields.append table = s3db.dvr_evaluation_question rows = db(table.deleted != True).select( table.id, table.section, #table.header, table.number, table.name, orderby=table.number, ) #subheadings = {} section = None for row in rows: name = "number%s" % row.number if row.section != section: label = section = row.section #subheadings[T(section)] = "sub_%sdata" % name else: label = "" cappend( S3SQLInlineComponent( "data", name=name, label=label, fields=( ("", "question_id"), ("", "answer"), ), filterby=dict(field="question_id", options=row.id), multiple=False, ), ) cappend("comments") crud_form = s3base.S3SQLCustomForm(*crud_fields) s3db.configure( "dvr_evaluation", crud_form=crud_form, #subheadings = subheadings, ) # Module-specific list fields (must be outside of r.interactive) list_fields = [ "dvr_case.reference", "first_name", "middle_name", "last_name", "date_of_birth", "gender", "dvr_case.date", "dvr_case.status_id", ] resource.configure(list_fields=list_fields, ) return True
def prep(r): if r.interactive: if r.component: # No new servers once deployment is created #s3db.configure("setup_server", # insertable = False # ) # Check if no scheduler task is pending #itable = s3db.setup_instance #sctable = db.scheduler_task #query = (itable.deployment_id == r.id) & \ # ((sctable.status != "COMPLETED") & \ # (sctable.status != "FAILED")) & \ # (itable.task_id == sctable.id) #exists = db(query).select(itable.task_id, # limitby = (0, 1) # ).first() #if exists: # # Disable creation of new instances # s3db.configure("setup_instance", # insertable = False # ) cname = r.component.name if cname == "server": from s3 import S3SQLCustomForm deployment = r.record if deployment.cloud_id: # Assume AWS for now crud_form = S3SQLCustomForm("name", "host_ip", "role", "remote_user", "private_key", (T("AWS Region"), "aws_server.region"), (T("AWS Instance Type"), "aws_server.instance_type"), (T("AWS Image"), "aws_server.image"), (T("AWS Security Group"), "aws_server.security_group"), (T("AWS Instance ID"), "aws_server.instance_id"), (T("Monitor"), "monitor_server.enabled"), "monitor_server.status", ) list_fields = ["deployment_id", "name", "host_ip", "role", "monitor_server.enabled", "monitor_server.status", ] else: # No Cloud f = s3db.setup_server.host_ip f.requires = f.requires.other # IP is required crud_form = S3SQLCustomForm("name", "host_ip", "role", "remote_user", "private_key", (T("Monitor"), "monitor_server.enabled"), "monitor_server.status", ) list_fields = ["deployment_id", "name", "host_ip", "role", "monitor_server.enabled", "monitor_server.status", ] s3db.configure("setup_server", crud_form = crud_form, deletable = False, # currently we just support a single server per deployment with Role 'all' insertable = False, # currently we just support a single server per deployment with Role 'all' list_fields = list_fields, ) # Has this deployment got a deployed instance? itable = s3db.setup_instance query = (itable.deployment_id == deployment.id) & \ (itable.task_id != None) instances = db(query).select(itable.id) if len(instances): # Prevent editing fields stable = s3db.setup_server stable.name.writable = False # @ToDo: Allow switching post-deployment stable.host_ip.writable = False # @ToDo: Allow switching post-deployment if deployment.cloud_id: # Assume AWS for now astable = s3db.setup_aws_server astable.region.writable = False # @ToDo: Allow switching post-deployment astable.instance_type.writable = False # @ToDo: Allow switching post-deployment (Highest Priority) astable.image.writable = False # @ToDo: Allow switching post-deployment astable.security_group.writable = False # @ToDo: Allow switching post-deployment elif cname == "instance": if r.component_id: itable = db.setup_instance crecord = db(itable.id == r.component_id).select(itable.task_id, limitby = (0, 1) ).first() if crecord.task_id is not None: # Prevent editing fields itable.type.writable = False # @ToDo: Allow switching post-deployment itable.url.writable = False # @ToDo: Allow switching post-deployment #itable.sender.writable = False # Changes handled in setup_instance_update_onaccept #itable.start.writable = False # Changes handled in setup_instance_update_onaccept elif r.method in (None, "create"): itable = db.setup_instance # Additional instances off by default itable.start.default = False # Remove already-deployed instances from dropdown sctable = db.scheduler_task query = (itable.deployment_id == r.id) & \ (sctable.status == "COMPLETED") rows = db(query).select(itable.type, join = itable.on(itable.task_id == sctable.id) ) types = {1: "prod", 2: "setup", 3: "test", 4: "demo", } for row in rows: del types[row.type] itable.type.requires = IS_IN_SET(types) elif cname == "setting": f = s3db.setup_setting.instance_id f.requires = IS_ONE_OF(db, "setup_instance.id", f.represent, filterby = "deployment_id", filter_opts = [r.id], sort = True ) elif cname == "monitor_task": f = s3db.setup_monitor_task.server_id f.requires = IS_ONE_OF(db, "setup_server.id", f.represent, filterby = "deployment_id", filter_opts = [r.id], sort = True ) elif r.method == "create": # Dynamically update list of templates when repo is changed s3.scripts.append("/%s/static/scripts/S3/s3.setup.js" % appname) try: import requests except ImportError: response.warning = T("Cannot download list of templates from remote repo, so using list from this install") else: # Download list of templates from remote repo # - currently assumes that repo is hosted on GitHub! table = s3db.setup_deployment parts = table.repo_url.default.split("/") repo_owner = parts[3] repo = parts[4] templates_url = "https://raw.githubusercontent.com/%s/%s/master/modules/templates/templates.json" % \ (repo_owner, repo) try: r_request = requests.get(templates_url, timeout=3) except requests.exceptions.RequestException: response.warning = T("Cannot download list of templates from remote repo, so using list from this install") else: import json try: templates = json.loads(r_request.text) except JSONDecodeError: response.warning = T("Cannot download list of templates from remote repo, so using list from this install") else: table.template.requires = IS_IN_SET(templates) def deployment_create_postprocess(form): form_vars_get = form.vars.get deployment_id = form_vars_get("id") # Set server name stable = s3db.setup_server url = form_vars_get("sub_production_url") server_vars = {"name": url.split("//")[1].split(".")[0], } cloud_id = form_vars_get("cloud_id") if cloud_id: # Create AWS Server record server = db(stable.deployment_id == deployment_id).select(stable.id, limitby = (0, 1) ).first() s3db.setup_aws_server.insert(server_id = server.id) else: server_vars["host_ip"] = "127.0.0.1" db(stable.deployment_id == deployment_id).update(**server_vars) # Include Production Instance & Server details in main form from s3 import S3SQLCustomForm crud_form = S3SQLCustomForm((T("Production URL"), "production.url"), "country", "template", "template_manual", "production.sender", "webserver_type", "db_type", "repo_url", "cloud_id", "dns_id", "production_server.remote_user", "production_server.private_key", postprocess = deployment_create_postprocess, ) s3db.configure("setup_deployment", crud_form = crud_form, ) else: # Has this deployment got a deployed instance? itable = s3db.setup_instance query = (itable.deployment_id == r.id) & \ (itable.task_id != None) instances = db(query).select(itable.id) if len(instances): # Prevent editing fields table = s3db.setup_deployment table.repo_url.writable = False # @ToDo: Allow switching post-deployment (Highest Priority) table.repo_url.comment = None table.country.writable = False # @ToDo: Allow switching post-deployment table.country.comment = None table.template.writable = False # @ToDo: Allow switching post-deployment table.template_manual.writable = False # @ToDo: Allow switching post-deployment table.template_manual.comment = None table.webserver_type.writable = False # @ToDo: Allow switching post-deployment table.webserver_type.comment = None table.db_type.writable = False # @ToDo: Allow switching post-deployment table.db_type.comment = None table.cloud_id.writable = False # @ToDo: Allow switching post-deployment table.dns_id.writable = False # @ToDo: Allow switching post-deployment return True
def customise_org_organisation_resource(r, tablename): s3db = current.s3db # Simplify form table = s3db.org_organisation field = table.comments from gluon import DIV field.comment = DIV( _class="tooltip", _title="%s|%s" % (T("About"), T("Describe the organisation, e.g. mission, history and other relevant details" ))) if not current.auth.is_logged_in(): field = table.logo field.readable = field.writable = False # User can create records since we need this during registration, # but we don't want to let the user do this from the list view s3db.configure( "org_organisation", listadd=False, ) # Custom filters to match the information provided from s3 import S3LocationFilter, S3OptionsFilter, S3TextFilter filter_widgets = [ S3TextFilter( [ "name", "acronym", #"website", #"comments", ], label=T("Search"), comment= T("Search by organization name or acronym. You can use * as wildcard." ), ), #S3OptionsFilter("sector_organisation.sector_id", # ), S3OptionsFilter( "organisation_organisation_type.organisation_type_id", label=T("Type"), ), #S3LocationFilter("organisation_location.location_id", # label = T("Areas Served"), # levels = ("L1", "L2", "L3", "L4"), # #hidden = True, # ), ] # CRUD Form from s3 import S3SQLCustomForm, \ S3SQLInlineComponent, \ S3SQLInlineLink, \ S3SQLVerticalSubFormLayout multitype = settings.get_org_organisation_types_multiple() crud_form = S3SQLCustomForm( "name", "acronym", S3SQLInlineLink( "organisation_type", field="organisation_type_id", filter=False, label=T("Type"), multiple=multitype, ), "country", S3SQLInlineLink( "sector", cols=3, label=T("Sectors"), field="sector_id", #required = True, ), (T("About"), "comments"), "website", S3SQLInlineComponent( "facility", label=T("Main Facility"), fields=[ "name", "phone1", "phone2", "email", "location_id", ], layout=S3SQLVerticalSubFormLayout, filterby={ "field": "main_facility", "options": True, }, multiple=False, ), ) s3db.configure( "org_organisation", filter_widgets=filter_widgets, crud_form=crud_form, )
def prep(r): fiscal_code = s3db.evr_case.fiscal_code levels = current.gis.get_relevant_hierarchy_levels() if r.method == "update": fiscal_code.requires = None else: fiscal_code.requires = \ IS_EMPTY_OR(IS_NOT_IN_DB(db(db.evr_case.deleted != True), fiscal_code), null="" ) report_fields = ["id", "last_name", "case.organisation_id", "gender", "date_of_birth", "person_details.nationality", "person_details.marital_status", "shelter_registration.shelter_id", "shelter_registration.check_in_date", "shelter_registration.check_out_date", ] if settings.get_cr_shelter_housing_unit_management(): report_fields.append("shelter_registration.shelter_unit_id") for level in levels: lfield = "location_id$%s" % level report_fields.append(lfield) report_options = Storage( rows=report_fields, cols=report_fields, fact=report_fields, defaults=Storage( rows="shelter_registration.shelter_id", cols="gender", #totals=True, ) ) list_fields = ["id", "first_name", #"middle_name", "last_name", "gender", "date_of_birth", ] if settings.get_evr_link_to_organisation(): list_fields.append("case.organisation_id") list_fields.append("shelter_registration.shelter_id") if settings.get_cr_shelter_housing_unit_management(): list_fields.append("shelter_registration.shelter_unit_id") list_fields.append("shelter_registration.check_in_date") list_fields.append("shelter_registration.check_out_date") r.resource.configure(list_fields = list_fields, report_options = report_options) if r.interactive: if not r.component: resource = r.resource # Filter widgets from s3 import S3OptionsFilter, S3TextFilter, S3LocationFilter, S3DateFilter filter_widgets = [ S3TextFilter(["first_name", #"middle_name", "last_name", #"local_name", "identity.value", "case.fiscal_code", ], label = T("Name and/or ID"), comment = T("To search for a person, enter any of the " "first, middle or last names and/or an ID " "number of a person, separated by spaces. " "You may use % as wildcard."), ), S3LocationFilter("address.location_id", label = T("Current Residence"), levels = levels, ), S3DateFilter("date_of_birth", label = T("Date Of Birth") ), S3OptionsFilter("person_details.nationality", label = T("Nationality"), ), S3OptionsFilter("case.organisation_id", label = T("Organisation"), ), S3OptionsFilter("shelter_registration.shelter_id", label = T("Shelter"), ), S3OptionsFilter("shelter_registration.registration_status", label = T("Registration Status"), ), ] # Custom Form for Persons from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm("case.organisation_id", "first_name", #"middle_name", "last_name", "date_of_birth", "location_id", "person_details.place_of_birth", "case.fiscal_code", S3SQLInlineComponent( "identity", label = T("Identity Documents"), fields = ["type", "value", ], ), "person_details.nationality", "gender", "person_details.marital_status", "person_details.religion", "person_details.occupation", #"person_details.company", "comments", ) resource.configure(crud_form = crud_form, filter_widgets = filter_widgets, ) elif r.component_name == "shelter_registration": if settings.get_cr_shelter_housing_unit_management(): # Dynamically update options for shelter_unit_id # when a shelter_id gets selected from s3 import SEPARATORS options = {"trigger": "shelter_id", "target": "shelter_unit_id", "lookupPrefix": "cr", "lookupResource": "shelter_unit", } s3.jquery_ready.append('''$.filterOptionsS3(%s)''' % \ json.dumps(options, separators=SEPARATORS)) elif r.representation in ("pdf", "xls"): # List fields list_fields = ["id", "first_name", #"middle_name", "last_name", "gender", #"date_of_birth", (T("Age"), "age"), "person_details.nationality", "person_details.religion", (T("Contact"), "contact.value"), (T("Shelter"), "shelter_registration.shelter_id$name") ] r.resource.configure(list_fields=list_fields) return True
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True resource = r.resource if r.controller == "hrm": if r.interactive and not r.component: MOBILE = settings.get_ui_label_mobile_phone() # Custom form for contacts from s3 import S3SQLCustomForm, \ S3SQLInlineComponent, \ S3SQLVerticalSubFormLayout crud_form = S3SQLCustomForm( "first_name", "last_name", S3SQLInlineComponent( "human_resource", name="human_resource", label="", multiple=False, fields=[ "organisation_id", "job_title_id", "department_id", ], layout=S3SQLVerticalSubFormLayout, ), S3SQLInlineComponent( "contact", name="email", label=T("Email"), multiple=False, fields=[ ("", "value"), ], filterby=[ { "field": "contact_method", "options": "EMAIL", }, ], ), S3SQLInlineComponent( "contact", name="phone", label=MOBILE, multiple=False, fields=[ ("", "value"), ], filterby=[ { "field": "contact_method", "options": "SMS", }, ], ), ) resource.configure(crud_form=crud_form) return result
def prep(r): SURPLUS_MEALS = "SURPLUS-MEALS" T = current.T db = current.db s3db = current.s3db resource = r.resource # Set default SURPLUS_MEALS event type ttable = s3db.dvr_case_event_type query = (ttable.code == SURPLUS_MEALS) & \ (ttable.deleted != True) event_type = db(query).select( ttable.id, limitby=(0, 1), ).first() if not event_type: r.error(400, "No event type with code %s defined" % SURPLUS_MEALS) event_type_id = event_type.id # Filter to SURPLUS_MEALS events without person_id query = (FS("type_id") == event_type_id) & \ (FS("person_id") == None) resource.add_filter(query) # Configure fields table = resource.table field = table.person_id field.default = None field.readable = field.writable = False field = table.type_id field.default = event_type_id field.readable = field.writable = False field = table.date field.readable = field.writable = True field = table.quantity field.default = 0 # Override IS_EMPTY_OR field.requires = IS_INT_IN_RANGE(0, None) field.readable = field.writable = True field = table.modified_by field.readable = True registered_by = (T("Registered by"), "modified_by") if r.interactive: # Custom CRUD form crud_form = S3SQLCustomForm( "date", "quantity", registered_by, "comments", ) # Custom filter widgets filter_widgets = [ S3TextFilter( [ "created_by$email", "comments", ], label=T("Search"), ), S3DateFilter("date"), ] resource.configure( crud_form=crud_form, filter_widgets=filter_widgets, ) # Turn off filter manager current.deployment_settings.search.filter_manager = False # Custom list fields list_fields = [ "date", "quantity", registered_by, "comments", ] # URL of the list view list_url = URL(args=[controller], vars={}) s3.datatable_ajax_source = list_url resource.configure( insertable=True, list_fields=list_fields, # Fix redirects: create_next=list_url, update_next=list_url, delete_next=list_url, ) # Custom CRUD strings T = current.T s3.crud_strings["dvr_case_event"] = Storage( label_create=T("Register Surplus Meals Quantity"), title_display=T("Surplus Meals Quantity"), title_list=T("Surplus Meals"), title_update=T("Edit Surplus Meals Quantity"), label_list_button=T("List Surplus Meals"), label_delete_button=T("Delete Entry"), msg_record_created=T("Entry added"), msg_record_modified=T("Entry updated"), msg_record_deleted=T("Entry deleted"), msg_list_empty=T("No Surplus Meals currently registered"), ) return True
def prep(r): if r.interactive: if not r.component: # Make the UUID field editable in the form field = r.table.uuid field.label = "UUID" field.readable = True field.writable = True field.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Repository UUID"), T("Identifier which the remote site uses to authenticate at this site when sending synchronization requests."), ), ) # Inject script to show/hide relevant fields depending # on the API type selected: script = "s3.sync.js" if s3.debug else "s3.sync.min.js" path = "/%s/static/scripts/S3/%s" % (appname, script) if path not in s3.scripts: s3.scripts.append(path) elif r.id: alias = r.component.alias if alias == "task": # Configure custom CRUD form apitype = r.record.apitype if apitype == "eden": components = "components" infile_pattern = None outfile_pattern = None human_readable = None delete_input_files = None elif apitype == "filesync": components = None component_table = r.component.table for fname in ("infile_pattern", "outfile_pattern", "human_readable", "delete_input_files", ): field = component_table[fname] field.readable = field.writable = True infile_pattern = "infile_pattern" outfile_pattern = "outfile_pattern" human_readable = "human_readable" delete_input_files = "delete_input_files" else: components = None infile_pattern = None outfile_pattern = None human_readable = None delete_input_files = None from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm("resource_name", components, infile_pattern, delete_input_files, outfile_pattern, human_readable, "last_pull", "last_push", "mode", "strategy", #"update_method", "update_policy", "conflict_policy", S3SQLInlineComponent("resource_filter", label = T("Filters"), fields = ["tablename", "filter_string", ], ), ) list_fields = ["resource_name", "mode", "last_pull", "last_push", "strategy", "update_policy", "conflict_policy", ] s3db.configure("sync_task", crud_form = crud_form, list_fields = list_fields, ) elif alias == "job": # Configure sync-specific defaults for scheduler_task table s3task.configure_tasktable_crud( function="sync_synchronize", args = [r.id], vars = {"user_id": auth.user.id if auth.user else 0}, period = 600, # seconds, so 10 mins ) elif alias == "log" and r.component_id: from s3 import s3_strip_markup table = r.component.table table.message.represent = lambda msg: \ DIV(s3_strip_markup(msg), _class = "message-body", ) elif alias == "dataset": table = r.component.table tablename = r.component.tablename # Adapt CRUD strings to perspective s3.crud_strings[tablename].update( label_create = T("Add Data Set"), title_list = T("Data Sets"), label_list_button = T("List Data Sets"), msg_record_created = T("Data Set added"), msg_list_empty = T("No Data Sets currently registered"), ) # Allow the same data set code only once per repository from s3 import IS_NOT_ONE_OF from s3db.sync import sync_dataset_code_requires table.code.requires = sync_dataset_code_requires + \ [IS_NOT_ONE_OF(db(table.repository_id == r.id), "sync_dataset.code", error_message = "Code already registered for this repository", ), ] s3.cancel = URL(c = "sync", f = "repository", args = [str(r.id), alias], ) return True
def customise_org_organisation_resource(r, tablename): from gluon.html import DIV, INPUT from s3 import s3_comments_widget, \ S3LocationSelector, \ S3MultiSelectWidget, \ S3SQLCustomForm, \ S3SQLInlineComponent, \ S3SQLInlineComponentMultiSelectWidget, \ S3SQLVerticalSubFormLayout s3db = current.s3db # Filtered component to access phone number and email s3db.add_components( tablename, org_facility={ "name": "main_facility", "joinby": "organisation_id", "filterby": "main_facility", "filterfor": True, }, ) s3db.org_organisation_location.location_id.widget = S3LocationSelector( levels=("L2", "L3", "L4"), show_map=False, labels=False, ) crud_fields = [ "name", "acronym", S3SQLInlineLink( "organisation_type", field="organisation_type_id", label=T("Type"), multiple=False, ), S3SQLInlineLink( "service", label=T("Services"), field="service_id", ), S3SQLInlineComponent( "facility", label=T("Main Facility"), fields=[ "name", "phone1", "phone2", "email", "location_id", ], layout=S3SQLVerticalSubFormLayout, filterby={ "field": "main_facility", "options": True, }, multiple=False, ), "website", S3SQLInlineComponent( "contact", name="twitter", label=T("Twitter"), multiple=False, fields=[("", "value")], filterby=dict( field="contact_method", options="TWITTER", ), ), S3SQLInlineComponent( "contact", name="facebook", label=T("Facebook"), multiple=False, fields=[("", "value")], filterby=dict( field="contact_method", options="FACEBOOK", ), ), "comments", ] crud_form = S3SQLCustomForm(*crud_fields) from s3 import S3LocationFilter, S3OptionsFilter, S3TextFilter #, S3HierarchyFilter filter_widgets = [ S3TextFilter( ["name", "acronym"], label=T("Search"), comment= T("Search by organization name or acronym. You can use * as wildcard." ), _class="filter-search", ), S3LocationFilter( "org_facility.location_id", label=T("Location"), #hidden = True, ), S3OptionsFilter( "organisation_organisation_type.organisation_type_id", label=T("Type"), #hidden = True, ), S3OptionsFilter("service_organisation.service_id", #hidden = True, ), ] list_fields = [ "name", (T("Type"), "organisation_organisation_type.organisation_type_id"), (T("Services"), "service.name"), (T("Adresse"), "main_facility.location_id"), (T("Phone #"), "main_facility.phone1"), (T("Email"), "main_facility.email"), (T("Facebook"), "facebook.value"), "website", (T("Last Updated"), "modified_on"), ] s3db.configure( tablename, crud_form=crud_form, filter_widgets=filter_widgets, list_fields=list_fields, )
def customise_dc_target_resource(r, tablename): if r.controller in ( "event", "hrm", # Training Event Evaluations ): return s3db = current.s3db template_name = r.get_vars.get("~.template_id$name") if template_name: ttable = s3db.dc_template template = current.db(ttable.name == template_name).select( ttable.id, limitby=(0, 1), ).first() if template: f = s3db.dc_target.template_id f.default = template.id f.readable = f.writable = False current.response.s3.crud_strings[tablename] = Storage( label_create=T("Create %s") % template_name, title_display=T("%s Details") % template_name, title_list=T("%ss") % template_name, title_update=T("Edit %s") % template_name, #title_upload = T("Import %ss") % template_name, label_list_button=T("List %ss") % template_name, label_delete_button=T("Delete %s") % template_name, msg_record_created=T("%s added") % template_name, msg_record_modified=T("%s updated") % template_name, msg_record_deleted=T("%s deleted") % template_name, msg_list_empty=T("No %ss currently registered") % template_name) from s3 import S3DateFilter, S3LocationFilter, S3OptionsFilter, S3SQLCustomForm, S3SQLInlineLink crud_form = S3SQLCustomForm( S3SQLInlineLink( "event", field="event_id", #label = type_label, multiple=False, ), "template_id", "date", "location_id", "comments", ) filter_widgets = [ S3OptionsFilter("event__link.event_id"), S3LocationFilter(), S3DateFilter("date"), ] list_fields = [ "event__link.event_id", "location_id$L1", "location_id$L2", (T("Hazard Type"), "name"), (T("Reporting Date"), "date"), (T("Reported by"), "created_by"), ] s3db.configure( tablename, crud_form=crud_form, filter_widgets=filter_widgets, list_fields=list_fields, )
def customise_project_project_resource(r, tablename): from gluon import IS_EMPTY_OR, URL from s3 import IS_ISO639_2_LANGUAGE_CODE, S3SQLCustomForm, S3TextFilter from templates.UCCE.controllers import project_project_list_layout from templates.UCCE.controllers import text_filter_formstyle s3db = current.s3db s3db.project_l10n.language.requires = IS_EMPTY_OR(IS_ISO639_2_LANGUAGE_CODE(select = l10n_options, sort = True, translate = False, zero = "", )) # Custom Component s3db.add_components("project_project", project_l10n = {"joinby": "project_id", "multiple": False, }, ) current.response.s3.crud_strings[tablename] = Storage( label_create = T("New project"), #title_display = T("Project Details"), # Only used in /target/create? title_display = T("Editor"), #title_list = T("Projects"), title_list = "", title_update = T("Edit project name"), #title_upload = T("Import Projects"), label_list_button = T("List Projects"), label_delete_button = T("Delete Projects"), msg_record_created = T("Project added"), msg_record_modified = T("Project updated"), msg_record_deleted = T("Project deleted"), msg_list_empty = T("No Projects currently registered") ) user = current.auth.user organisation_id = user and user.organisation_id if organisation_id: f = s3db.project_project.organisation_id f.default = organisation_id f.readable = f.writable = False s3db.configure("project_project", create_next = URL(args="datalist"), # No need to chain as default one not relevant for this usecase: create_onaccept = project_project_onaccept, crud_form = S3SQLCustomForm((T("Organization"), "organisation_id"), (T("New project name"), "name"), (T("Default Translation"), "l10n.language"), ), # Ignored here as set in Prep in default controller #list_fields = ["name", # "project_target.target_id", # ], list_layout = project_project_list_layout, ondelete = project_project_ondelete, filter_widgets = [S3TextFilter(["name", "target.name", ], formstyle = text_filter_formstyle, label = "", _placeholder = T("Search project or survey"), ), ], ) s3db.configure("project_project_target", create_onaccept = project_project_target_create_onaccept, )
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True if r.controller == "dvr" and not r.component: ctable = s3db.dvr_case # Mandatory Fields from s3 import IS_NOT_EMPTY from gluon import IS_EMPTY_OR # Require a case number ctable.reference.requires = IS_NOT_EMPTY() # Require organisation, site and status for fn in ( "organisation_id", "site_id", "status_id", ): field = ctable[fn] requires = field.requires if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other root_org = current.auth.root_org() if root_org: # Set default for organisation_id and hide the field field = ctable.organisation_id field.default = root_org field.readable = field.writable = False # Hide organisation_id in list_fields, too list_fields = r.resource.get_config("list_fields") if "dvr_case.organisation_id" in list_fields: list_fields.remove("dvr_case.organisation_id") # Limit sites to root_org field = ctable.site_id requires = field.requires if requires: if isinstance(requires, IS_EMPTY_OR): requires = requires.other if hasattr(requires, "dbset"): stable = s3db.org_site query = (stable.organisation_id == root_org) requires.dbset = current.db(query) resource = r.resource if r.interactive: # Custom CRUD form from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm( "dvr_case.reference", "dvr_case.date", "dvr_case.organisation_id", "dvr_case.site_id", "dvr_case.priority", "dvr_case.case_type_id", "dvr_case.beneficiary", "dvr_case.status_id", "first_name", "middle_name", "last_name", "date_of_birth", "gender", "person_details.marital_status", S3SQLInlineComponent( "contact", fields=[ ("", "value"), ], filterby={ "field": "contact_method", "options": "EMAIL", }, label=T("Email"), multiple=False, name="email", ), S3SQLInlineComponent( "contact", fields=[ ("", "value"), ], filterby={ "field": "contact_method", "options": "SMS", }, label=T("Mobile Phone"), multiple=False, name="phone", ), "person_details.nationality", "person_details.illiterate", S3SQLInlineComponent( "case_language", fields=[ "language", "quality", "comments", ], label=T("Language / Communication Mode"), ), S3SQLInlineComponent( "contact_emergency", fields=[ "name", "relationship", "phone", ], label=T("Emergency Contact"), multiple=False, ), S3SQLInlineComponent( "identity", fields=[ "type", "description", "value", ], ), S3SQLInlineComponent( "address", label=T("Current Address"), fields=[ ("", "location_id"), ], filterby={ "field": "type", "options": "1", }, link=False, multiple=False, ), "dvr_case.head_of_household", "dvr_case.hoh_name", "dvr_case.hoh_gender", "dvr_case.hoh_relationship", "dvr_case.comments", ) # Extend filter widgets filter_widgets = resource.get_config("filter_widgets") if filter_widgets is not None: from s3 import get_s3_filter_opts, S3OptionsFilter filter_widgets.extend([ S3OptionsFilter( "dvr_case.case_type_id", options=lambda: get_s3_filter_opts( "dvr_case_type"), ), S3OptionsFilter( "dvr_case_activity.need_id", options=lambda: get_s3_filter_opts("dvr_need"), hidden=True, ), ]) resource.configure( crud_form=crud_form, filter_widgets=filter_widgets, ) # Hide Postcode in addresses (not used) atable = s3db.pr_address from s3 import S3LocationSelector location_id = atable.location_id location_id.widget = S3LocationSelector( show_address=True, show_postcode=False, ) # Inject filter script for sites (filter by selected org) if not root_org: script = '''$.filterOptionsS3({ 'trigger':'sub_dvr_case_organisation_id', 'target':'sub_dvr_case_site_id', 'lookupResource':'site', 'lookupPrefix':'org', 'lookupField':'site_id', 'lookupKey':'organisation_id' })''' s3.jquery_ready.append(script) # Expose additional case fields: fields = ("beneficiary", "head_of_household", "hoh_name", "hoh_gender", "hoh_relationship") for fname in fields: field = ctable[fname] field.readable = field.writable = True # 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 = [ "dvr_case.reference", "dvr_case.case_type_id", "dvr_case.priority", "first_name", "middle_name", "last_name", "date_of_birth", "gender", #"dvr_case.organisation_id", "dvr_case.date", "dvr_case.status_id", ] resource.configure(list_fields=list_fields, #orderby = "dvr_case.priority desc", ) return result
def prep(r): # Filter to persons who have a case registered resource = r.resource resource.add_filter(FS("dvr_case.id") != None) CASES = T("Cases") # Filters to split case list if not r.record: get_vars = r.get_vars # Filter to active/archived cases archived = get_vars.get("archived") if archived == "1": archived = True CASES = T("Archived Cases") query = FS("dvr_case.archived") == True else: archived = False query = (FS("dvr_case.archived") == False) | \ (FS("dvr_case.archived") == None) # Filter to open/closed cases # (also filtering status filter opts) closed = get_vars.get("closed") get_status_opts = s3db.dvr_case_status_filter_opts if closed == "1": CASES = T("Closed Cases") query &= FS("dvr_case.status_id$is_closed") == True status_opts = lambda: get_status_opts(closed=True) elif closed == "0": CASES = T("Current Cases") query &= (FS("dvr_case.status_id$is_closed") == False) | \ (FS("dvr_case.status_id$is_closed") == None) status_opts = lambda: get_status_opts(closed=False) else: status_opts = get_status_opts resource.add_filter(query) else: archived = False status_opts = s3db.dvr_case_status_filter_opts # Should not be able to delete records in this view resource.configure(deletable = False) if r.component and r.id: ctable = r.component.table if "case_id" in ctable.fields and \ str(ctable.case_id.type)[:18] == "reference dvr_case": # Find the Case ID dvr_case = s3db.dvr_case query = (dvr_case.person_id == r.id) & \ (dvr_case.deleted != True) cases = db(query).select(dvr_case.id, limitby=(0, 2)) case_id = ctable.case_id if cases: # Set default case_id.default = cases.first().id if len(cases) == 1: # Only one case => hide case selector case_id.readable = case_id.writable = False else: # Configure case selector case_id.requires = IS_ONE_OF(db(query), "dvr_case.id", case_id.represent, ) if r.interactive: # Adapt CRUD strings to context s3.crud_strings["pr_person"] = Storage( label_create = T("Create Case"), title_display = T("Case Details"), title_list = CASES, title_update = T("Edit Case Details"), label_list_button = T("List Cases"), label_delete_button = T("Delete Case"), msg_record_created = T("Case added"), msg_record_modified = T("Case details updated"), msg_record_deleted = T("Case deleted"), msg_list_empty = T("No Cases currently registered") ) if not r.component: # Expose the "archived"-flag? (update forms only) if r.record and r.method != "read": ctable = s3db.dvr_case field = ctable.archived field.readable = field.writable = True # Module-specific CRUD form # NB: this assumes single case per person, must use # case perspective (dvr/case) for multiple cases # per person! from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm( "dvr_case.reference", "dvr_case.organisation_id", "dvr_case.date", "dvr_case.status_id", "first_name", "middle_name", "last_name", "date_of_birth", "gender", S3SQLInlineComponent( "contact", fields = [("", "value"), ], filterby = {"field": "contact_method", "options": "EMAIL", }, label = T("Email"), multiple = False, name = "email", ), S3SQLInlineComponent( "contact", fields = [("", "value"), ], filterby = {"field": "contact_method", "options": "SMS", }, label = T("Mobile Phone"), multiple = False, name = "phone", ), "person_details.nationality", S3SQLInlineComponent( "address", label = T("Current Address"), fields = [("", "location_id"), ], filterby = {"field": "type", "options": "1", }, link = False, multiple = False, ), "dvr_case.comments", "dvr_case.archived", ) # Module-specific filter widgets from s3 import s3_get_filter_opts, S3TextFilter, S3OptionsFilter filter_widgets = [ S3TextFilter(["pe_label", "first_name", "middle_name", "last_name", #"email.value", #"phone.value", "dvr_case.reference", ], label = T("Search"), comment = T("You can search by name, ID or case number"), ), S3OptionsFilter("dvr_case.status_id", cols = 3, default = default_status, #label = T("Case Status"), options = status_opts, sort = False, ), S3OptionsFilter("person_details.nationality", ), S3OptionsFilter("case_flag_case.flag_id", label = T("Flags"), options = s3_get_filter_opts("dvr_case_flag", translate = True, ), cols = 3, hidden = True, ), ] # Add filter for transferability if relevant for deployment if settings.get_dvr_manage_transferability(): filter_widgets.append( S3OptionsFilter("dvr_case.transferable", options = {True: T("Yes"), False: T("No"), }, cols = 2, hidden = True, ) ) resource.configure(crud_form = crud_form, filter_widgets = filter_widgets, ) # Module-specific list fields (must be outside of r.interactive) list_fields = ["dvr_case.reference", "first_name", "middle_name", "last_name", "date_of_birth", "gender", "dvr_case.date", "dvr_case.status_id", ] resource.configure(list_fields = list_fields, ) return True
def prep(r): if r.interactive: if r.method in ("check", "enable", "disable"): return True record = r.record if record and not r.component: deployment_id = record.deployment_id if deployment_id: # Open on Deployment Tab redirect( URL( c="setup", f="deployment", args=[deployment_id, "server", r.id], )) # No Cloud in create form: # 'External' servers just added for Monitoring # - we don't deploy Servers except within Deployments from s3 import S3SQLCustomForm f = s3db.setup_server.host_ip f.requires = f.requires.other # IP is required f.comment = DIV( _class="tooltip", _title="%s|%s" % (T("IP Address"), T("Set to 127.0.0.1 for the localhost or set to the IP address of the remote server." ))) crud_form = S3SQLCustomForm( #"deployment_id", "name", "host_ip", "role", "remote_user", "private_key", (T("Monitor"), "monitor_server.enabled"), "monitor_server.status", ) if record: s3db.configure( "setup_server", crud_form=crud_form, ) else: list_fields = [ "deployment_id", "name", "host_ip", "role", "monitor_server.enabled", "monitor_server.status", ] s3db.configure( "setup_server", create_onaccept=None, # Handled by S3SQLCustomForm crud_form=crud_form, #insertable = False, # We want to allow monitoring of external hosts list_fields=list_fields, ) return True