def due_followups(): """ RESTful Controller for Due Follow-ups """ # CRUD Strings s3.crud_strings["po_household_followup"] = Storage( title_display=T("Follow-up Details"), title_list=T("Due Follow-ups"), title_update=T("Edit Follow-up Details"), label_list_button=T("List Follow-ups"), msg_record_modified=T("Follow-up Details updated"), msg_list_empty=T("No due follow-ups"), ) # Filter Widgets from s3 import S3DateFilter, S3OptionsFilter, S3TextFilter filter_widgets = [ S3TextFilter( [ "household_id$location_id$addr_street", "followup_required", "comments", ], label=T("Search"), ), S3OptionsFilter("household_id$area_id"), S3DateFilter( "household_id$date_visited", label=T("Date visited"), hidden=True, ), S3DateFilter( "followup_date", hidden=True, ), ] s3db.configure( "po_household_followup", insertable=False, deletable=False, filter_widgets=filter_widgets, list_fields=[ "followup_date", "household_id$area_id", "household_id", "followup_required", "comments", ], ) def prep(r): if not r.record: query = (FS("followup_date") <= datetime.datetime.utcnow().date()) & \ (FS("completed") != True) r.resource.add_filter(query) return True s3.prep = prep return s3_rest_controller("po", "household_followup")
def recv_filter_widgets(): """ Filter widgets for incoming shipments @returns: list of filter widgets """ T = current.T from s3 import S3DateFilter, \ S3OptionsFilter, \ S3TextFilter, \ s3_get_filter_opts from s3db.inv import SHIP_STATUS_CANCEL, \ SHIP_STATUS_RETURNING, \ inv_shipment_status_labels recv_status_opts = OrderedDict( sorted( inv_shipment_status_labels().items(), key=lambda i: i[0], )) # We don't currently use these statuses del recv_status_opts[SHIP_STATUS_CANCEL] del recv_status_opts[SHIP_STATUS_RETURNING] filter_widgets = [ S3TextFilter( [ "req_ref", #"send_ref", ], label=T("Search"), ), S3OptionsFilter( "status", cols=3, options=recv_status_opts, sort=False, ), S3DateFilter( "date", hidden=True, ), S3OptionsFilter( "track_item.item_id", hidden=True, options=lambda: s3_get_filter_opts("supply_item"), ), ] return filter_widgets
def customise_doc_sitrep_resource(r, tablename): """ All SitReps are SAVE All SitReps are National in scope """ #if not current.auth.s3_has_role("AUTHENTICATED"): # # @ToDo: Just show the External (Public) parts # pass from s3 import S3DateFilter, S3OptionsFilter, S3SQLCustomForm, S3SQLInlineComponent db = current.db s3db = current.s3db table = s3db.doc_sitrep # Always SC otable = s3db.org_organisation org = db(otable.name == SAVE).select(otable.id, cache=s3db.cache, limitby=(0, 1)).first() try: SCI = org.id except: current.log.error("Cannot find org %s - prepop not done?" % SAVE) else: f = table.organisation_id f.default = SCI # Always National PH = "Philippines" gtable = s3db.gis_location loc = db((gtable.name == PH) & (gtable.level == "L0")).select( gtable.id, cache=s3db.cache, limitby=(0, 1)).first() try: PH = loc.id except: current.log.error("Cannot find loc %s - prepop not done?" % PH) else: f = table.location_id f.default = PH # Default to currently-open Event (if just 1) s3db.event_sitrep.event_id.default = current.session.s3.event crud_form = S3SQLCustomForm( S3SQLInlineComponent( "event_sitrep", label=T("Disaster"), fields=[("", "event_id")], multiple=False, required=True, ), "date", "name", "description", "comments", ) filter_widgets = [ S3OptionsFilter("event_sitrep.event_id"), S3DateFilter("date"), ] list_fields = [ "event_sitrep.event_id", "date", "name", "comments", ] s3db.configure( "doc_sitrep", crud_form=crud_form, filter_widgets=filter_widgets, list_fields=list_fields, )
def customise_doc_image_resource(r, tablename): from s3 import S3LocationSelector, S3SQLCustomForm #, S3SQLInlineComponent s3db = current.s3db table = s3db.doc_image table.location_id.widget = S3LocationSelector() # No Street Address s3db.add_components( "doc_image", event_event="doc_id", ) crud_form = S3SQLCustomForm( "file", "name", "url", "date", # @ToDo: Have this as an event_id dropdown...defaulting to currently-open Event #S3SQLInlineComponent("event"), "organisation_id", "location_id", "comments", ) # Custom filters from s3 import S3DateFilter, \ S3LocationFilter, \ S3OptionsFilter, \ S3TextFilter filter_widgets = [ S3TextFilter( [ "name", "comments", ], label=T("Search"), comment= T("Search by disaster name or comments. You can use * as wildcard." ), ), S3OptionsFilter( "event.name", label=T("Disaster"), ), S3LocationFilter("location_id"), S3OptionsFilter("organisation_id"), S3DateFilter("date"), ] list_fields = [ "location_id$L1", "location_id$L2", "location_id$L3", "location_id$L4", ] if r.controller != "event": list_fields.append((T("Disaster"), "event.name")) list_fields += [ "organisation_id", "date", "name", ] s3db.configure( "doc_image", crud_form=crud_form, filter_widgets=filter_widgets, list_fields=list_fields, )
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 customise_disease_case_diagnostics_resource(r, tablename): db = current.db s3db = current.s3db table = s3db.disease_case_diagnostics if r.interactive and r.method != "report": # Enable project link and make it mandatory field = table.project_id field.readable = field.writable = True field.comment = None requires = field.requires if isinstance(requires, (list, tuple)): requires = requires[0] if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # If there is only one project, default the selector + make r/o ptable = s3db.project_project rows = db(ptable.deleted == False).select( ptable.id, cache=s3db.cache, limitby=(0, 2), ) if len(rows) == 1: field.default = rows[0].id field.writable = False # Enable disease link and make it mandatory field = table.disease_id field.readable = field.writable = True field.comment = None requires = field.requires if isinstance(requires, (list, tuple)): requires = requires[0] if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # If there is only one disease, default the selector + make r/o dtable = s3db.disease_disease rows = db(dtable.deleted == False).select( dtable.id, cache=s3db.cache, limitby=(0, 2), ) if len(rows) == 1: field.default = rows[0].id field.writable = False # Default result date field = table.result_date field.default = current.request.utcnow.date() # Formal test types # TODO move to lookup table? type_options = ( ("LFD", T("LFD Antigen Test")), ("PCR", T("PCR Test")), ("SER", T("Serum Antibody Test")), ("OTH", T("Other")), ) field = table.test_type field.default = "LFD" field.writable = False # fixed for now field.requires = IS_IN_SET( type_options, zero="", sort=False, ) field.represent = S3Represent(options=dict(type_options)) # Formal results result_options = ( ("NEG", T("Negative")), ("POS", T("Positive")), ("INC", T("Inconclusive")), ) field = table.result field.requires = IS_IN_SET( result_options, zero="", sort=False, ) field.represent = S3Represent(options=dict(result_options)) # Custom list_fields list_fields = [ "project_id", "disease_id", "test_type", "result_date", "result", ] # Custom form from s3 import S3SQLCustomForm crud_form = S3SQLCustomForm( "project_id", "disease_id", "test_type", "result_date", "result", ) # Filters from s3 import S3DateFilter, S3OptionsFilter filter_widgets = [ S3DateFilter( "result_date", label=T("Date"), ), S3OptionsFilter("disease_id", hidden=True), S3OptionsFilter("project_id", hidden=True), S3OptionsFilter( "test_type", options=OrderedDict(type_options), hidden=True, ), S3OptionsFilter( "result", options=OrderedDict(result_options), hidden=True, ), ] # Report options facts = ((T("Number of Tests"), "count(id)"), ) axes = [ "result", "test_type", "disease_id", "project_id", ] report_options = { "rows": axes, "cols": axes, "fact": facts, "defaults": { "rows": axes[1], "cols": axes[0], "fact": facts[0], "totals": True, }, } s3db.configure( "disease_case_diagnostics", crud_form=crud_form, filter_widgets=filter_widgets, list_fields=list_fields, report_options=report_options, ) crud_strings = current.response.s3.crud_strings crud_strings["disease_case_diagnostics"] = Storage( label_create=T("Register Test Result"), title_display=T("Test Result"), title_list=T("Test Results"), title_update=T("Edit Test Result"), title_upload=T("Import Test Results"), label_list_button=T("List Test Results"), label_delete_button=T("Delete Test Result"), msg_record_created=T("Test Result added"), msg_record_modified=T("Test Result updated"), msg_record_deleted=T("Test Result deleted"), msg_list_empty=T("No Test Results currently registered"))
def prep(r): # Filter to persons who have a case registered resource = r.resource resource.add_filter(FS("case.id") != None) labels = s3db.br_terminology() CASES = labels.CASES human_resource_id = auth.s3_logged_in_human_resource() insertable = True record = r.record if not record: # Enable bigtable strategies for better performance settings.base.bigtable = True get_vars = r.get_vars queries = [] # Filter for "my cases" mine = get_vars.get("mine") if mine == "1": if human_resource_id: queries.append( FS("case.human_resource_id") == human_resource_id) else: queries.append(FS("case.human_resource_id").belongs(set())) CURRENT = labels.CURRENT_MINE CASES = labels.CASES_MINE else: query = None CURRENT = labels.CURRENT # Filter to open/closed cases closed = get_vars.get("closed") get_status_filter_opts = s3db.br_case_status_filter_opts if closed == "1": # Only closed cases queries.append(FS("case.status_id$is_closed") == True) CASES = labels.CLOSED insertable = False status_filter_opts = lambda: get_status_filter_opts(closed=True ) elif closed == "0": # Only open cases queries.append((FS("case.status_id$is_closed") == False) | \ (FS("case.status_id$is_closed") == None)) CASES = CURRENT status_filter_opts = lambda: get_status_filter_opts(closed= False) else: status_filter_opts = get_status_filter_opts # Filter to valid/invalid cases invalid = get_vars.get("invalid") if invalid == "1": queries.append(FS("case.invalid") == True) CASES = T("Invalid Cases") insertable = False else: queries.append((FS("case.invalid") == False) | \ (FS("case.invalid") == None)) if queries: query = reduce(lambda a, b: a & b, queries) resource.add_filter(query) # Adapt CRUD strings to perspective (& terminology) crud_strings = s3db.br_crud_strings("pr_person") crud_strings.title_list = CASES s3.crud_strings["pr_person"] = crud_strings # Configure Anonymizer from s3 import S3Anonymize s3db.set_method( "pr", "person", method="anonymize", action=S3Anonymize, ) # Update resource configuration for perspective resource.configure( anonymize=s3db.br_person_anonymize(), deletable=False, insertable=insertable, ) # Configure ID Cards if id_card_export: if r.representation == "card": # Configure ID card layout resource.configure(pdf_card_layout=id_card_layout, #pdf_card_pagesize="A4", ) if not r.id and not r.component: # Add export-icon for ID cards export_formats = list(settings.get_ui_export_formats()) export_formats.append( ("card", "fa fa-id-card", T("Export ID Cards"))) settings.ui.export_formats = export_formats s3.formats["card"] = r.url(method="") if not r.component: # Module-specific field and form configuration from s3 import S3SQLInlineComponent # Adapt fields to module context table = resource.table ctable = s3db.br_case multiple_orgs = s3db.br_case_read_orgs()[0] # Configure pe_label field = table.pe_label field.label = T("ID") field.comment = None # Make gender mandatory, remove "unknown" field = table.gender field.default = None options = dict(s3db.pr_gender_opts) del options[1] # Remove "unknown" field.requires = IS_PERSON_GENDER(options, sort=True) # Configure case.organisation_id field = ctable.organisation_id field.comment = None if not field.default: default_org, selectable = s3db.br_case_default_org() if default_org and settings.get_br_case_hide_default_org(): field.writable = selectable field.readable = selectable or multiple_orgs field.default = default_org requires = field.requires if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # Configure case.human_resource_id field = ctable.human_resource_id if settings.get_br_case_manager(): if human_resource_id: field.default = human_resource_id field.readable = field.writable = True else: field.readable = field.writable = False # Size of family if settings.get_br_household_size() in (False, "auto"): field = ctable.household_size field.readable = field.writable = False # Address (optional) if settings.get_br_case_address(): address = S3SQLInlineComponent( "address", label=T("Current Address"), fields=[("", "location_id")], filterby={ "field": "type", "options": "1", }, link=False, multiple=False, ) else: address = None # Language details (optional) if settings.get_br_case_language_details(): language_details = S3SQLInlineComponent( "case_language", fields=[ "language", "quality", "comments", ], label=T("Language / Communication Mode"), ) else: language_details = None # Expose the "invalid"-flag? (update forms only) if record and r.method != "read": field = ctable.invalid field.readable = field.writable = True # Custom CRUD form crud_fields = [ "case.date", "case.organisation_id", "case.human_resource_id", "case.status_id", "pe_label", # +name fields "person_details.nationality", "date_of_birth", "gender", "person_details.marital_status", "case.household_size", address, S3SQLInlineComponent( "contact", fields=[("", "value")], filterby={ "field": "contact_method", "options": "SMS", }, label=T("Mobile Phone"), multiple=False, name="phone", ), "person_details.literacy", language_details, "case.comments", "case.invalid", ] # Custom list fields list_fields = [ "pe_label", # +name fields "gender", "date_of_birth", "person_details.nationality", "case.date", "case.status_id", ] # Add organisation if user can see cases from multiple orgs if multiple_orgs: list_fields.insert(-2, "case.organisation_id") # Insert name fields in name-format order NAMES = ("first_name", "middle_name", "last_name") keys = s3base.StringTemplateParser.keys( settings.get_pr_name_format()) name_fields = [fn for fn in keys if fn in NAMES] crud_fields[5:5] = name_fields list_fields[1:1] = name_fields resource.configure( crud_form=s3base.S3SQLCustomForm(*crud_fields), list_fields=list_fields, ) # Filter Widgets if not record: from s3 import S3TextFilter, S3DateFilter, S3OptionsFilter filter_widgets = [ S3TextFilter( name_fields + ["pe_label", "case.comments"], label=T("Search"), comment=T("You can search by name, ID or comments"), ), S3DateFilter( "date_of_birth", hidden=True, ), S3OptionsFilter( "case.status_id", cols=3, options=status_filter_opts, sort=False, hidden=True, ), S3OptionsFilter( "person_details.nationality", hidden=True, ), S3DateFilter( "case.date", hidden=True, ), ] # Org-filter if user can see cases from multiple orgs/branches if multiple_orgs: filter_widgets.insert( 1, S3OptionsFilter("case.organisation_id"), ) resource.configure(filter_widgets=filter_widgets) # Autocomplete search-method s3db.set_method( "pr", "person", method="search_ac", action=s3db.pr_PersonSearchAutocomplete(name_fields), ) elif r.component_name == "case_activity": atable = r.component.table assistance_inline = settings.get_br_manage_assistance() and \ settings.get_br_assistance_inline() mtable = s3db.br_assistance_measure # Default status if settings.get_br_case_activity_status(): s3db.br_case_activity_default_status() # Default human_resource_id if human_resource_id: # Activities if settings.get_br_case_activity_manager(): atable.human_resource_id.default = human_resource_id # Inline updates if settings.get_br_case_activity_updates(): utable = s3db.br_case_activity_update utable.human_resource_id.default = human_resource_id # Inline assistance measures if assistance_inline: mtable.human_resource_id.default = human_resource_id root_org = None org_specific_needs = settings.get_br_case_activity_need() and \ settings.get_br_needs_org_specific() if org_specific_needs: root_org = s3db.br_case_root_org(r.id) if not root_org: root_org = auth.root_org() # Limit selectable need types to the case root org if org_specific_needs and root_org: field = atable.need_id field.requires = IS_EMPTY_OR( IS_ONE_OF( db, "br_need.id", field.represent, filterby="organisation_id", filter_opts=(root_org, ), )) # Configure inline assistance measures if assistance_inline: if record: mtable.person_id.default = record.id if settings.get_br_assistance_themes() and root_org: # Limit selectable themes to the case root org field = mtable.theme_ids dbset = s3db.br_org_assistance_themes(root_org) field.requires = IS_EMPTY_OR( IS_ONE_OF( dbset, "br_assistance_theme.id", field.represent, multiple=True, )) s3db.br_assistance_default_status() elif r.component_name == "assistance_measure": mtable = r.component.table ltable = s3db.br_assistance_measure_theme # Default status s3db.br_assistance_default_status() # Default human_resource_id if human_resource_id and settings.get_br_assistance_manager(): mtable.human_resource_id.default = human_resource_id # Filter case_activity_id selector to current case field = mtable.case_activity_id if record and field.writable: requires = field.requires if isinstance(requires, IS_EMPTY_OR): requires = requires.other requires.set_filter(filterby="person_id", filter_opts=(record.id, )) # Represent for br_assistance_measure_theme.id details_per_theme = settings.get_br_assistance_details_per_theme() if details_per_theme: ltable.id.represent = s3db.br_AssistanceMeasureThemeRepresent( paragraph=True, details=True, ) # Filter theme_id selectors to case root org root_org = s3db.br_case_root_org(r.id) if not root_org: root_org = auth.root_org() if root_org: dbset = s3db.br_org_assistance_themes(root_org) field = mtable.theme_ids field.requires = IS_EMPTY_OR( IS_ONE_OF( dbset, "br_assistance_theme.id", field.represent, multiple=True, )) field = ltable.theme_id field.requires = IS_EMPTY_OR( IS_ONE_OF( dbset, "br_assistance_theme.id", field.represent, )) # Allow organizer to set an end_date if r.method == "organize" and \ settings.get_br_assistance_measures_use_time(): field = mtable.end_date field.writable = True elif r.component_name == "br_note": # Represent the note author by their name (rather than email) ntable = r.component.table ntable.modified_by.represent = s3base.s3_auth_user_represent_name return True
def req_filter_widgets(): """ Filter widgets for requests @returns: list of filter widgets """ T = current.T from s3 import S3DateFilter, \ S3LocationFilter, \ S3OptionsFilter, \ S3TextFilter, \ s3_get_filter_opts from s3db.req import req_status_opts req_status_opts = OrderedDict( sorted( req_status_opts().items(), key=lambda i: i[0], )) filter_widgets = [ S3TextFilter( ["req_ref"], label=T("Order No."), ), S3DateFilter("date"), S3OptionsFilter( "transit_status", cols=3, options=req_status_opts, sort=False, ), S3OptionsFilter( "fulfil_status", cols=3, hidden=True, options=req_status_opts, sort=False, ), S3OptionsFilter( "req_item.item_id", hidden=True, options=lambda: s3_get_filter_opts("supply_item"), ), ] if current.auth.s3_has_role("SUPPLY_COORDINATOR"): coordinator_filters = [ S3LocationFilter( "site_id$location_id", levels=["L3", "L4"], ), S3TextFilter( "site_id$location_id$addr_postcode", label=T("Postcode"), ), S3OptionsFilter("site_id", hidden=True), S3OptionsFilter( "site_id$organisation_id$delivery.value", label=T("Delivery##supplying"), options=delivery_tag_opts(), ), ] filter_widgets[2:2] = coordinator_filters return filter_widgets
def __call__(self): T = current.T output = {} s3db = current.s3db request = current.request #------------------------ # Map to display needs ftable = s3db.gis_layer_feature query = (ftable.controller == "req") & \ (ftable.function == "need") layer = current.db(query).select(ftable.layer_id, limitby=(0, 1)).first() try: layer_id = layer.layer_id except: current.log.error("Cannot find Layer for Map") layer_id = None feature_resources = [{ "name": T("Needs"), "id": "search_results", "layer_id": layer_id, "active": False, }] _map = current.gis.show_map( callback='''S3.search.s3map()''', catalogue_layers=True, collapsed=True, feature_resources=feature_resources, save=False, search=True, toolbar=True, ) output["_map"] = _map # --------------------------------------------------------------------- # Display needs list resource = s3db.resource("req_need") #resource.table.commit_status.represent = None list_id = "req_datalist" list_fields = [ #"purpose", "location_id", "priority", #"req_ref", #"site_id", "date", ] # Order with most recent request first orderby = "req_need.date" datalist, numrows = resource.datalist( fields=list_fields, limit=None, list_id=list_id, orderby=orderby, ) if numrows == 0: current.response.s3.crud_strings["req_need"].msg_no_match = T( "No needs at present.") ajax_url = URL(c="req", f="need", args="datalist.dl", vars={"list_id": list_id}) #@ToDo: Implement pagination properly output[list_id] = datalist.html( ajaxurl=ajax_url, pagesize=0, ) # ---------------------------- # Filter Form # - can we have a single form for both Activities & Needs? # filter_widgets = [ S3OptionsFilter( "priority", label=T("Priority"), ), S3DateFilter( "date", label=T("Date"), hide_time=True, ), ] filter_form = S3FilterForm( filter_widgets, ajax=True, submit=True, url=ajax_url, ) output["req_filter_form"] = filter_form.html(resource, request.get_vars, list_id) # View title output["title"] = current.deployment_settings.get_system_name() self._view(THEME, "dashboard.html") # Custom JS current.response.s3.scripts.append( "/%s/static/themes/SHARE/js/homepage.js" % request.application) return output
def custom_prep(r): # Call standard postp if callable(standard_prep): result = standard_prep(r) if r.method == "summary": # Map (only) in common area settings.ui.summary = ( { "name": "table", "label": "Table", "widgets": [{ "method": "datatable" }] }, { "name": "charts", "label": "Report", "widgets": [{ "method": "report", "ajax_init": True }] }, { "common": True, "name": "map", "label": "Map", "widgets": [{ "method": "map", "ajax_init": True }], }, ) from s3 import S3DateFilter, S3OptionsFilter, S3TextFilter from templates.WACOP.controllers import filter_formstyle_summary, text_filter_formstyle # @ToDo: This should use date/end_date not just date date_filter = S3DateFilter( "date", #formstyle = filter_formstyle_summary, label="", #hide_time = True, ) date_filter.input_labels = { "ge": "Start Time/Date", "le": "End Time/Date" } filter_widgets = [ S3TextFilter( [ "name", "comments", ], formstyle=text_filter_formstyle, label=T("Search"), _placeholder=T("Enter search term…"), ), S3OptionsFilter( "organisation_id", label="", noneSelectedText="Lead Organization", widget="multiselect", ), S3OptionsFilter( "closed", formstyle=filter_formstyle_summary, options={ "*": T("All"), False: T("Open"), True: T("Closed"), }, cols=1, multiple=False, ), S3OptionsFilter( "incident_type_id", formstyle=filter_formstyle_summary, label=T("Incident Type"), noneSelectedText="All", widget="multiselect", ), date_filter, ] list_fields = [ "closed", "name", (T("Type"), "incident_type_id"), "location_id", (T("Start"), "date"), (T("End"), "end_date"), "event_id", ] s3db.configure( "event_incident", filter_widgets=filter_widgets, list_fields=list_fields, ) # @ToDo: Configure Timeline # Last 5 days (@ToDo: Configurable Start/End & deduce appropriate unit) # Qty of Newly-opened Incidents per Unit pass elif r.method == "assign": current.menu.main = "" elif r.representation == "popup": # Popup just used to link to Event #s3.crud_strings["event_incident"].title_update = T("Add to Event") from s3 import S3SQLCustomForm crud_form = S3SQLCustomForm("event_id", ) s3db.configure( "event_incident", crud_form=crud_form, ) 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 prep(r): # Filter to persons who have a case registered resource = r.resource resource.add_filter(FS("case.id") != None) labels = s3db.br_terminology() CASES = labels.CASES human_resource_id = auth.s3_logged_in_human_resource() insertable = True if not r.record: get_vars = r.get_vars # Filter to open/closed cases closed = get_vars.get("closed") get_status_filter_opts = s3db.br_case_status_filter_opts if closed == "1": # Only closed cases query = FS("case.status_id$is_closed") == True CASES = labels.CLOSED insertable = False status_filter_opts = lambda: get_status_filter_opts(closed=True ) elif closed == "0": # Only open cases query = (FS("case.status_id$is_closed") == False) | \ (FS("case.status_id$is_closed") == None) CASES = labels.CURRENT status_filter_opts = lambda: get_status_filter_opts(closed= False) else: query = None status_filter_opts = get_status_filter_opts # TODO mine URL option # Filter to valid/invalid cases invalid = get_vars.get("invalid") if invalid == "1": q = FS("case.invalid") == True query = query & q if query is not None else q CASES = T("Invalid Cases") insertable = False else: q = (FS("case.invalid") == False) | \ (FS("case.invalid") == None) query = query & q if query is not None else q resource.add_filter(query) # Adapt CRUD strings to perspective (& terminology) crud_strings = s3db.br_crud_strings("pr_person") crud_strings.title_list = CASES s3.crud_strings["pr_person"] = crud_strings # Should not be able to delete records in this view resource.configure( deletable=False, insertable=insertable, ) if not r.component: # Module-specific field and form configuration from s3 import S3SQLInlineComponent # Adapt fields to module context table = resource.table ctable = s3db.br_case multiple_orgs = s3db.br_case_read_orgs()[0] # Configure pe_label field = table.pe_label field.label = T("ID") field.comment = None # Make gender mandatory, remove "unknown" field = table.gender field.default = None options = dict(s3db.pr_gender_opts) del options[1] # Remove "unknown" field.requires = IS_PERSON_GENDER(options, sort=True) # Configure case.organisation_id field = ctable.organisation_id field.comment = None if not field.default: default_org, selectable = s3db.br_case_default_org() if default_org and settings.get_br_case_hide_default_org(): field.writable = selectable field.readable = selectable or multiple_orgs field.default = default_org requires = field.requires if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # Configure case.human_resource_id field = ctable.human_resource_id if settings.get_br_case_manager(): if human_resource_id: field.default = human_resource_id field.readable = field.writable = True else: field.readable = field.writable = False # Size of family if settings.get_br_household_size() in (False, "auto"): field = ctable.household_size field.readable = field.writable = False # Address (optional) if settings.get_br_case_address(): address = S3SQLInlineComponent( "address", label=T("Current Address"), fields=[("", "location_id")], filterby={ "field": "type", "options": "1", }, link=False, multiple=False, ) else: address = None # Language details (optional) if settings.get_br_case_language_details(): language_details = S3SQLInlineComponent( "case_language", fields=[ "language", "quality", "comments", ], label=T("Language / Communication Mode"), ) else: language_details = None # Expose the "invalid"-flag? (update forms only) if r.record and r.method != "read": field = ctable.invalid field.readable = field.writable = True # Custom CRUD form crud_fields = [ "case.date", "case.organisation_id", "case.human_resource_id", "case.status_id", "pe_label", # +name fields "person_details.nationality", "date_of_birth", "gender", "person_details.marital_status", "case.household_size", address, S3SQLInlineComponent( "contact", fields=[("", "value")], filterby={ "field": "contact_method", "options": "SMS", }, label=T("Mobile Phone"), multiple=False, name="phone", ), "person_details.literacy", language_details, "case.comments", "case.invalid", ] # Custom list fields list_fields = [ "pe_label", # +name fields "gender", "date_of_birth", "person_details.nationality", "case.date", "case.status_id", ] # Add organisation if user can see cases from multiple orgs if multiple_orgs: list_fields.insert(-2, "case.organisation_id") # Insert name fields in name-format order NAMES = ("first_name", "middle_name", "last_name") keys = s3base.StringTemplateParser.keys( settings.get_pr_name_format()) name_fields = [fn for fn in keys if fn in NAMES] crud_fields[5:5] = name_fields list_fields[1:1] = name_fields resource.configure( crud_form=s3base.S3SQLCustomForm(*crud_fields), list_fields=list_fields, ) # Filter Widgets if not r.record: from s3 import S3TextFilter, S3DateFilter, S3OptionsFilter filter_widgets = [ S3TextFilter( name_fields + ["pe_label", "case.comments"], label=T("Search"), comment=T("You can search by name, ID or comments"), ), S3DateFilter( "date_of_birth", hidden=True, ), S3OptionsFilter( "case.status_id", cols=3, options=status_filter_opts, sort=False, hidden=True, ), S3OptionsFilter( "person_details.nationality", hidden=True, ), S3DateFilter( "case.date", hidden=True, ), ] # Org-filter if user can see cases from multiple orgs/branches if multiple_orgs: filter_widgets.insert( 1, S3OptionsFilter("case.organisation_id"), ) resource.configure(filter_widgets=filter_widgets) # Autocomplete search-method if r.function == "person_search": # Autocomplete-Widget (e.g. response actions) search_fields = tuple(name_fields) + ("pe_label", ) else: # Add-Person-Widget (family members) search_fields = tuple(name_fields) s3db.set_method( "pr", "person", method="search_ac", action=s3db.pr_PersonSearchAutocomplete(search_fields), ) elif r.component_name == "case_activity": # Configure case_activity.human_resource_id atable = r.component.table if human_resource_id: if settings.get_br_case_activity_manager(): atable.human_resource_id.default = human_resource_id if settings.get_br_case_activity_updates(): utable = s3db.br_case_activity_update utable.human_resource_id.default = human_resource_id root_org = None org_specific_needs = settings.get_br_case_activity_need() and \ settings.get_br_needs_org_specific() if org_specific_needs: root_org = s3db.br_case_root_org(r.id) if not root_org: root_org = auth.root_org() if org_specific_needs and root_org: # Limit selectable need types to the case root org field = atable.need_id field.requires = IS_EMPTY_OR( IS_ONE_OF( db, "br_need.id", field.represent, filterby="organisation_id", filter_opts=(root_org, ), )) # TODO when using inline responses, filter themes to root org return True
def customise_fin_voucher_debit_resource(r, tablename): s3db = current.s3db table = s3db.fin_voucher_debit # Customise fields field = table.comments field.label = T("Memoranda") field.comment = DIV( _class="tooltip", _title="%s|%s" % ( T("Memoranda"), T("Notes of the Provider"), ), ) field = table.balance field.label = T("Status") field.represent = lambda v: T("Redeemed##fin") if v > 0 else T( "Compensated##fin") # Custom list_fields list_fields = [ (T("Date"), "date"), "program_id", "voucher_id$signature", "balance", ] if current.auth.s3_has_role("PROGRAM_MANAGER"): list_fields[3:3] = [ "voucher_id$pe_id", "pe_id", ] if current.auth.s3_has_role("VOUCHER_PROVIDER"): list_fields.append("comments") s3db.configure( "fin_voucher_debit", list_fields=list_fields, ) # Filters if r.interactive: from s3 import S3DateFilter, S3TextFilter filter_widgets = [ S3TextFilter( [ "program_id$name", "signature", ], label=T("Search"), ), S3DateFilter( "date", label=T("Date"), ), ] s3db.configure( "fin_voucher_debit", filter_widgets=filter_widgets, ) # Report options if r.method == "report": facts = ((T("Number of Accepted Vouchers"), "count(id)"), ) axes = [ "program_id", "balance", ] if current.auth.s3_has_role("PROGRAM_MANAGER"): axes.insert(0, "pe_id") report_options = { "rows": axes, "cols": axes, "fact": facts, "defaults": { "rows": axes[0], "cols": None, "fact": facts[0], "totals": True, }, } s3db.configure( "fin_voucher_debit", report_options=report_options, )
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 issue vouchers for program_ids, org_ids, pe_ids = s3db.fin_voucher_permitted_programs( mode="issuer") resource = r.resource table = resource.table if not program_ids or not org_ids: # User is not permitted to issue vouchers for any programs/issuers resource.configure(insertable=False) else: # Limit the program selector to permitted+active 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 issuer 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 issuer 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 if r.interactive: # Hide valid_until from create-form (will be set onaccept) field = table.valid_until field.readable = bool(r.record) field.writable = False # Filter Widgets from s3 import S3DateFilter, S3TextFilter filter_widgets = [ S3TextFilter( [ "signature", "comments", "program_id$name", ], label=T("Search"), ), S3DateFilter("date", ), ] resource.configure(filter_widgets=filter_widgets, ) elif r.representation == "card": # Configure ID card layout from .vouchers import VoucherCardLayout resource.configure(pdf_card_layout = VoucherCardLayout, pdf_card_suffix = lambda record: \ s3_str(record.signature) \ if record and record.signature else None, ) return result
def send_filter_widgets(): """ Filter widgets for outgoing shipments @returns: list of filter widgets """ T = current.T from s3 import S3DateFilter, \ S3LocationFilter, \ S3OptionsFilter, \ S3TextFilter, \ s3_get_filter_opts from s3db.inv import SHIP_STATUS_CANCEL, \ SHIP_STATUS_RETURNING, \ inv_shipment_status_labels send_status_opts = OrderedDict(inv_shipment_status_labels()) # We don't currently use these statuses del send_status_opts[SHIP_STATUS_CANCEL] del send_status_opts[SHIP_STATUS_RETURNING] filter_widgets = [ S3TextFilter( [ "req_ref", #"send_ref", ], label=T("Search"), ), S3DateFilter("date"), S3OptionsFilter( "status", cols=3, options=send_status_opts, sort=False, ), S3OptionsFilter( "track_item.item_id", hidden=True, options=lambda: s3_get_filter_opts("supply_item"), ), ] if current.auth.s3_has_role("SUPPLY_COORDINATOR"): coordinator_filters = [ S3OptionsFilter( "to_site_id$organisation_id$delivery.value", label=T("Delivery##supplying"), options=delivery_tag_opts(), ), S3OptionsFilter( "site_id", label=T("Distribution Center"), ), S3OptionsFilter( "to_site_id", hidden=True, ), S3LocationFilter("to_site_id$location_id", levels=["L3", "L4"], hidden=True), S3TextFilter("to_site_id$location_id$addr_postcode", label=T("Postcode"), hidden=True), ] filter_widgets[3:3] = coordinator_filters return filter_widgets
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 customise_req_req_resource(r, tablename): from gluon import IS_EMPTY_OR, IS_IN_SET, SPAN from s3 import S3DateFilter, S3LocationFilter, S3OptionsFilter, S3Represent, S3TextFilter s3db = current.s3db req_status_opts = { 0: SPAN( T("None"), _class="req_status_none", ), 1: SPAN( T("Partial"), _class="req_status_partial", ), 2: SPAN( T("Complete"), _class="req_status_complete", ), } f = s3db.req_req.req_status f.readable = f.writable = True f.represent = S3Represent(options=req_status_opts) f.requires = IS_EMPTY_OR(IS_IN_SET(req_status_opts)) f = s3db.req_req.security_req f.readable = f.writable = True f.label = T("Needs Financing?") filter_widgets = [ S3TextFilter( [ #"committer_id$first_name", #"committer_id$middle_name", #"committer_id$last_name", "req_item.item_id", "site_id$name", "comments", #"req_id$name", #"organisation_id$name" ], label=T("Search"), #comment = T("Search for a commitment by Committer name, Request ID, Site or Organization."), comment=T("Search for a request by Item, Site or Comments"), ), S3LocationFilter( "site_id$location_id", levels=("L1", "L2"), ), S3OptionsFilter("req_item.item_id", ), S3OptionsFilter( "req_status", cols=3, options=req_status_opts, ), S3OptionsFilter( "security_req", cols=2, ), #S3OptionsFilter("commit_status", # cols = 3, # hidden = True, # ), #S3OptionsFilter("transit_status", # cols = 3, # hidden = True, # ), #S3OptionsFilter("fulfil_status", # cols = 3, # hidden = True, # ), S3OptionsFilter( "site_id", hidden=True, ), S3OptionsFilter( "created_by", label=T("Logged By"), hidden=True, ), S3DateFilter( "date", # Better to default (easier to customise/consistency) #label = T("Date Requested"), hide_time=True, input_labels={ "ge": "From", "le": "To" }, comment=T("Search for requests made between these dates."), hidden=True, ), #S3DateFilter("date_required", # # Better to default (easier to customise/consistency) # #label = T("Date Needed By"), # hide_time = True, # input_labels = {"ge": "From", "le": "To"}, # comment = T("Search for requests required between these dates."), # hidden = True, # ), ] list_fields = [ "date", "site_id", "req_status", "req_item.item_id", "security_req", ] s3db.configure( "req_req", filter_widgets=filter_widgets, list_fields=list_fields, )
def _newsfeed(): """ Custom Page - Filterable DataList of CMS Posts & a DataList of Events """ #if not current.auth.is_logged_in(): # current.auth.permission.fail() T = current.T s3db = current.s3db request = current.request response = current.response s3 = response.s3 # Ensure that filtered views translate into options which update the Widget get_vars = request.get_vars if "~.series_id$name" in get_vars: series_name = get_vars["~.series_id$name"] table = s3db.cms_series series = current.db(table.name == series_name).select(table.id, limitby=(0, 1)).first() if series: series_id = str(series.id) get_vars.pop("~.series_id$name") get_vars["~.series_id__belongs"] = series_id current.deployment_settings.customise_controller("cms_post") list_layout = s3.render_posts filter_widgets = [S3TextFilter(["body"], label="", _class="filter-search", #_placeholder=T("Search").upper(), ), S3OptionsFilter("series_id", label=T("Filter by Type"), represent="%(name)s", widget="multiselect", hidden=True, ), S3LocationFilter("location_id", label=T("Filter by Location"), levels=("L1", "L2", "L3"), widget="multiselect", hidden=True, ), S3OptionsFilter("created_by$organisation_id", label=T("Filter by Organization"), # Can't use this for integers, use field.represent instead #represent="%(name)s", widget="multiselect", hidden=True, ), S3DateFilter("created_on", label=T("Filter by Date"), hide_time=True, hidden=True, ), ] s3db.configure("cms_post", # We use a custom Advanced widget filter_advanced = False, filter_formstyle = filter_formstyle, filter_submit = (T("SEARCH"), "btn btn-primary"), filter_widgets = filter_widgets, list_layout = list_layout, # Create form comes via AJAX in a Modal insertable = False, notify_fields = [(T("Type"), "series_id"), (T("Date"), "date"), (T("Location"), "location_id"), (T("Description"), "body"), ], notify_template = "notify_post", ) s3.dl_pagelength = 6 # 5 forces an AJAX call old_args = request.args if "datalist_dl_post" in old_args: # DataList pagination or Ajax-deletion request request.args = ["datalist_f"] ajax = "list" elif "datalist_dl_filter" in old_args: # FilterForm options update request request.args = ["filter"] ajax = "filter" elif "validate.json" in old_args: # Inline component validation request request.args = [] ajax = True elif current.auth.permission.format == "msg": # Subscription lookup request request.args = [] ajax = True else: # Default request.args = ["datalist_f"] ajax = None def prep(r): if ajax == "list": r.representation = "dl" elif ajax == "filter": r.representation = "json" return True s3.prep = prep output = current.rest_controller("cms", "post", list_ajaxurl = URL(f="index", args="datalist_dl_post"), filter_ajax_url = URL(f="index", args="datalist_dl_filter", vars={}), ) request.args = old_args if ajax == "list": # Don't override view if this is an Ajax-deletion request if not "delete" in request.get_vars: response.view = "plain.html" elif not ajax: # Set Title & View after REST Controller, in order to override output["title"] = T("News Feed") view = path.join(request.folder, "modules", "templates", THEME, "views", "newsfeed.html") try: # Pass view as file not str to work in compiled mode response.view = open(view, "rb") except IOError: from gluon.http import HTTP raise HTTP(404, "Unable to open Custom View: %s" % view) s3.js_global.append('''i18n.adv_search="%s"''' % T("Advanced Search")) s3.scripts.append("/%s/static/themes/%s/js/newsfeed.js" % (request.application, THEME)) # Latest 5 Disasters resource = s3db.resource("event_event") layout = render_events list_id = "event_datalist" limit = 5 orderby = "start_date desc" list_fields = ["name", "event_type_id$name", "start_date", "closed", ] output["disasters"] = latest_records(resource, layout, list_id, limit, list_fields, orderby) return output
def __call__(self): """ Main entry point, configuration """ logged_in = current.auth.s3_logged_in() if logged_in: fn = "alert" else: fn = "public" T = current.T s3db = current.s3db request = current.request output = {} # Map ftable = s3db.gis_layer_feature query = (ftable.controller == "cap") & \ (ftable.function == fn) layer = current.db(query).select(ftable.layer_id, limitby=(0, 1) ).first() try: layer_id = layer.layer_id except: from s3 import s3_debug s3_debug("Cannot find Layer for Map") layer_id = None feature_resources = [{"name" : T("Alerts"), "id" : "search_results", "layer_id" : layer_id, "tablename" : "cap_alert", "url" : URL(c="cap", f=fn, extension="geojson"), # We activate in callback after ensuring URL is updated for current filter status "active" : False, }] _map = current.gis.show_map(callback='''S3.search.s3map()''', catalogue_layers=True, collapsed=True, feature_resources=feature_resources, save=False, search=True, toolbar=True, ) output["_map"] = _map # Filterable List of Alerts # - most recent first resource = s3db.resource("cap_alert") # Don't show Templates resource.add_filter(FS("is_template") == False) if not logged_in: # Only show Public Alerts resource.add_filter(FS("scope") == "Public") # Only show Alerts which haven't expired resource.add_filter(FS("info.expires") >= request.utcnow) list_id = "cap_alert_datalist" list_fields = ["msg_type", "info.headline", "area.name", #"info.description", "info.sender_name", "info.priority", "status", "scope", "info.event_type_id", "info.severity", "info.certainty", "info.urgency", "sent", ] # Order with most recent Alert first orderby = "cap_info.expires desc" datalist, numrows, ids = resource.datalist(fields = list_fields, #start = None, limit = None, list_id = list_id, orderby = orderby, layout = s3db.cap_alert_list_layout ) ajax_url = URL(c="cap", f=fn, args="datalist.dl", vars={"list_id": list_id}) output[list_id] = datalist.html(ajaxurl = ajax_url, pagesize = None, ) # @ToDo: Options are currently built from the full-set rather than the filtered set filter_widgets = [#S3LocationFilter("location.location_id", # label=T("Location"), # levels=("L0",), # widget="multiselect", # ), S3OptionsFilter("info.priority", #label=T("Priority"), ), S3OptionsFilter("info.event_type_id", #label=T("Event Type"), ), S3OptionsFilter("scope", #label=T("Scope"), ), S3DateFilter("info.expires", label = "", #label=T("Expiry Date"), hide_time=True, ), ] filter_form = S3FilterForm(filter_widgets, ajax=True, submit=True, url=ajax_url, ) output["alert_filter_form"] = filter_form.html(resource, request.get_vars, list_id) # Filterable News Feed # - most recent first resource = s3db.resource("cms_post") # Only show News posts (differentiate from e.g. online user guide) resource.add_filter(FS("series_id$name") == "News") list_id = "cms_post_datalist" list_fields = [#"series_id", "location_id", "date", "body", #"created_by", #"created_by$organisation_id", #"document.file", ] # Order with most recent Post first orderby = "cms_post.date desc" datalist, numrows, ids = resource.datalist(fields = list_fields, #start = None, limit = 5, list_id = list_id, orderby = orderby, # @ToDo: Custom layout with more button to expand content block layout = s3db.cms_post_list_layout ) ajax_url = URL(c="cms", f="post", args="datalist.dl", vars={"list_id": list_id}) output[list_id] = datalist.html(ajaxurl = ajax_url, pagesize = 5 ) # Truncate body #from s3 import s3_trunk8 #s3_trunk8(lines=8) #filter_widgets = [#S3LocationFilter("location_id", # # label="", # # levels=("L0",), # # widget="multiselect", # # ), # # @ToDo: Source (Series? Tag?) # #S3OptionsFilter(), # ] #filter_form = S3FilterForm(filter_widgets, # ajax=True, # submit=True, # url=ajax_url, # ) #output["news_filter_form"] = filter_form.html(resource, request.get_vars, list_id) # Title and view output["title"] = current.deployment_settings.get_system_name() self._view(THEME, "index.html") s3 = current.response.s3 # Custom CSS s3.stylesheets.append("../themes/SAMBRO/style.css") # Custom JS s3.scripts.append("/%s/static/themes/SAMBRO/js/homepage.js" % request.application) return output
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 and 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.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 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 prep(r): resource = r.resource table = resource.table labels = s3db.br_terminology() human_resource_id = auth.s3_logged_in_human_resource() # Filter for valid+open cases query = (FS("person_id$case.id") != None) & \ (FS("person_id$case.invalid") == False) & \ (FS("person_id$case.status_id$is_closed") == False) resource.add_filter(query) if not r.record: # Enable bigtable features for better performance settings.base.bigtable = True get_vars = r.get_vars crud_strings = response.s3.crud_strings["br_case_activity"] # Filter for "my activities" mine = get_vars.get("mine") if mine == "1": mine = True if human_resource_id: query = FS("human_resource_id") == human_resource_id else: query = FS("human_resource_id").belongs(set()) resource.add_filter(query) crud_strings.title_list = T("My Activities") else: mine = False # Adapt list title when filtering for priority 0 (Emergency) if get_vars.get("~.priority") == "0": crud_strings.title_list = T("Emergencies") case_activity_status = settings.get_br_case_activity_status() case_activity_need = settings.get_br_case_activity_need() # Default status if case_activity_status: s3db.br_case_activity_default_status() # Filter widgets from s3 import S3DateFilter, \ S3OptionsFilter, \ S3TextFilter, \ s3_get_filter_opts text_filter_fields = [ "person_id$pe_label", "person_id$first_name", "person_id$middle_name", "person_id$last_name", ] if settings.get_br_case_activity_subject(): text_filter_fields.append("subject") if settings.get_br_case_activity_need_details(): text_filter_fields.append("need_details") filter_widgets = [ S3TextFilter( text_filter_fields, label=T("Search"), ), ] multiple_orgs = s3db.br_case_read_orgs()[0] if multiple_orgs: filter_widgets.append( S3OptionsFilter("person_id$case.organisation_id")) if case_activity_status: stable = s3db.br_case_activity_status query = (stable.deleted == False) rows = db(query).select( stable.id, stable.name, stable.is_closed, cache=s3db.cache, orderby=stable.workflow_position, ) status_filter_options = OrderedDict( (row.id, T(row.name)) for row in rows) status_filter_defaults = [ row.id for row in rows if not row.is_closed ] filter_widgets.append( S3OptionsFilter( "status_id", options=status_filter_options, default=status_filter_defaults, cols=3, hidden=True, sort=False, )) if not mine and settings.get_br_case_activity_manager(): filter_widgets.append( S3OptionsFilter( "human_resource_id", hidden=True, )) filter_widgets.extend([ S3DateFilter( "date", hidden=True, ), S3OptionsFilter( "person_id$person_details.nationality", label=T("Client Nationality"), hidden=True, ), ]) if case_activity_need: org_specific_needs = settings.get_br_needs_org_specific() filter_widgets.append(S3OptionsFilter("need_id", hidden = True, header = True, options = lambda: \ s3_get_filter_opts( "br_need", org_filter = org_specific_needs, translate = True, ), )) resource.configure(filter_widgets=filter_widgets) # Report options if r.method == "report": facts = ( (T("Number of Activities"), "count(id)"), (labels.NUMBER_OF_CASES, "count(person_id)"), ) axes = [ "person_id$case.organisation_id", "person_id$gender", "person_id$person_details.nationality", "person_id$person_details.marital_status", "priority", ] default_rows = "person_id$case.organisation_id" default_cols = "person_id$person_details.nationality" if settings.get_br_manage_assistance() and \ settings.get_br_assistance_themes(): axes.insert(1, "assistance_measure_theme.theme_id") if case_activity_need: axes.insert(1, "need_id") default_cols = "need_id" if case_activity_status: axes.insert(4, "status_id") report_options = { "rows": axes, "cols": axes, "fact": facts, "defaults": { "rows": default_rows, "cols": default_cols, "fact": "count(id)", "totals": True, }, } resource.configure(report_options=report_options) # Set default for human_resource_ids if human_resource_id: table.human_resource_id.default = human_resource_id utable = s3db.br_case_activity_update utable.human_resource_id.default = human_resource_id # Represent person_id as link to case file field = table.person_id field.label = labels.CASE field.represent = s3db.pr_PersonRepresent(show_link=True) # Add case data to list fields list_fields = resource.get_config("list_fields") list_fields[1:1] = [ (T("ID"), "person_id$pe_label"), "person_id", ] # Create/delete must happen on case file tab, not here resource.configure( insertable=False, deletable=False, ) return True
def customise_cms_post_resource(r, tablename): db = current.db s3db = current.s3db table = s3db.cms_post table.priority.readable = table.priority.writable = True table.series_id.readable = table.series_id.writable = True table.status_id.readable = table.status_id.writable = True method = r.method if method in ("create", "update"): # Custom Form from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_fields = [ (T("Type"), "series_id"), (T("Priority"), "priority"), (T("Status"), "status_id"), (T("Title"), "title"), (T("Text"), "body"), (T("Location"), "location_id"), # Tags are added client-side S3SQLInlineComponent( "document", name="file", label=T("Files"), fields=[ ("", "file"), #"comments", ], ), ] if r.tablename != "event_incident": if r.tablename == "event_event": from gluon import IS_EMPTY_OR from s3 import IS_ONE_OF itable = s3db.event_incident query = (itable.event_id == r.id) & \ (itable.closed == False) & \ (itable.deleted == False) set = db(query) f = s3db.event_post.incident_id f.requires = IS_EMPTY_OR( IS_ONE_OF(set, "event_incident.id", f.represent, orderby="event_incident.name", sort=True)) crud_fields.insert( 0, S3SQLInlineComponent( "incident_post", fields=[("", "incident_id")], label=T("Incident"), multiple=False, )) crud_form = S3SQLCustomForm(*crud_fields) # Client support for Tags appname = r.application s3 = current.response.s3 scripts_append = s3.scripts.append if s3.debug: scripts_append("/%s/static/scripts/tag-it.js" % appname) else: scripts_append("/%s/static/scripts/tag-it.min.js" % appname) scripts_append("/%s/static/themes/WACOP/js/update_tags.js" % appname) if method == "create": s3.jquery_ready.append('''wacop_update_tags("")''') elif method == "update": ttable = s3db.cms_tag ltable = s3db.cms_tag_post if r.tablename == "cms_post": post_id = r.id else: post_id = r.component.id query = (ltable.post_id == post_id) & \ (ltable.tag_id == ttable.id) tags = db(query).select(ttable.name) tags = [tag.name for tag in tags] tags = ",".join(tags) s3.jquery_ready.append('''wacop_update_tags("%s")''' % tags) # Processing Tags default = s3db.get_config(tablename, "onaccept") if isinstance(default, list): onaccept = default onaccept.append(cms_post_onaccept) else: onaccept = [default, cms_post_onaccept] s3db.configure( tablename, crud_form=crud_form, onaccept=onaccept, ) elif method in ("custom", "datalist", "filter"): # dataList configuration from templates.WACOP.controllers import cms_post_list_layout s3 = current.response.s3 s3.dl_no_header = True s3db.configure( tablename, list_fields=[ "series_id", "priority", "status_id", "date", "title", "body", "created_by", "tag.name", "document.file", "comment.id", #"comment.body", # Extra fields come in unsorted, so can't match up to records #"comment.created_by", #"comment.created_on", ], list_layout=cms_post_list_layout, orderby="cms_post.date desc", ) if method in ("custom", "filter"): # Filter Widgets from s3 import S3DateFilter, \ S3LocationFilter, \ S3OptionsFilter, \ S3TextFilter if method == "filter": # Apply filter_vars get_vars = r.get_vars for k, v in get_vars.iteritems(): # We only expect a maximum of 1 of these, no need to append from s3 import FS s3.filter = (FS(k) == v) date_filter = S3DateFilter( "date", # If we introduce an end_date on Posts: #["date", "end_date"], label="", #hide_time = True, slider=True, ) date_filter.input_labels = { "ge": "Start Time/Date", "le": "End Time/Date" } from templates.WACOP.controllers import text_filter_formstyle filter_widgets = [ S3TextFilter( [ "body", ], formstyle=text_filter_formstyle, label=T("Search"), _placeholder=T("Enter search term…"), ), S3OptionsFilter( "series_id", label="", noneSelectedText="Type", # T() added in widget no_opts="", ), S3OptionsFilter( "priority", label="", noneSelectedText="Priority", # T() added in widget no_opts="", ), S3OptionsFilter( "status_id", label="", noneSelectedText="Status", # T() added in widget no_opts="", ), S3OptionsFilter( "created_by$organisation_id", label="", noneSelectedText="Source", # T() added in widget no_opts="", ), S3OptionsFilter( "tag_post.tag_id", label="", noneSelectedText="Tag", # T() added in widget no_opts="", ), date_filter, ] if r.tablename == "event_event" or \ (method == "filter" and get_vars.get("event_post.event_id")): # Event Profile filter_widgets.insert( 1, S3OptionsFilter( "incident_post.incident_id", label="", noneSelectedText="Incident", # T() added in widget no_opts="", )) user = current.auth.user if user: filter_widgets.insert( 1, S3OptionsFilter( "bookmark.user_id", label="", options={ "*": T("All"), user.id: T("My Bookmarks"), }, cols=2, multiple=False, table=False, )) s3db.configure( tablename, filter_widgets=filter_widgets, )