def model(self): # --------------------------------------------------------------------- # Needs <=> Organisations # organisation_id = self.org_organisation_id # Load normal model CREATE = current.response.s3.crud_strings[ "org_organisation"].label_create tablename = "req_need_organisation" self.define_table( tablename, self.req_need_id(empty=False), organisation_id( comment=S3PopupLink( c="org", f="organisation", label=CREATE, tooltip=None, vars={"prefix": "req"}, ), empty=False, ), s3_comments(), *s3_meta_fields()) self.configure( tablename, deduplicate=S3Duplicate(primary=( "need_id", "organisation_id", ), ), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return None
def model(self): T = current.T # --------------------------------------------------------------------- # Activity Groups <=> Organisations # organisation_id = self.org_organisation_id # Load normal model CREATE = current.response.s3.crud_strings[ "org_organisation"].label_create project_organisation_roles = current.deployment_settings.get_project_organisation_roles( ) tablename = "need_response_organisation" self.define_table( tablename, self.need_response_id(empty=False), organisation_id( comment=S3PopupLink( c="org", f="organisation", label=CREATE, tooltip=None, vars={"prefix": "need"}, ), empty=False, ), Field( "role", "integer", default=1, # Lead label=T("Role"), requires=IS_EMPTY_OR(IS_IN_SET(project_organisation_roles)), represent=s3_options_represent(project_organisation_roles), ), s3_comments(), *s3_meta_fields()) self.configure( tablename, deduplicate=S3Duplicate(primary=( "need_response_id", "organisation_id", "role", ), ), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return None
def person_id_comment(fieldname): T = current.T c_title = T("Person.") c_comment = T("Type the first few characters of one of the Person's names.") ADD_PERSON = T("Add Person") return S3PopupLink(c = "pr", f = "person", vars = {"child": fieldname}, label = ADD_PERSON, title = c_title, tooltip = c_comment, )
def model(self): db = current.db T = current.T s3 = current.response.s3 settings = current.deployment_settings crud_strings = s3.crud_strings define_table = self.define_table configure = self.configure add_components = self.add_components set_method = self.set_method # --------------------------------------------------------------------- tablename = "work_job_type" define_table(tablename, Field("name", label = T("Title"), requires = IS_NOT_EMPTY(), ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Create Job Type"), title_display = T("Job Type Details"), title_list = T("Job Types"), title_update = T("Edit Job Type"), label_list_button = T("List Job Types"), msg_record_created = T("Job Type added"), msg_record_modified = T("Job Type updated"), msg_record_deleted = T("Job Type deleted"), msg_list_empty = T("No Job Types currently registered") ) # Reusable field represent = S3Represent(lookup=tablename) job_type_id = S3ReusableField("job_type_id", "reference %s" % tablename, label = T("Job Type"), represent = represent, requires = IS_EMPTY_OR(IS_ONE_OF( db, "work_job_type.id", represent, )), sortby = "name", comment = S3PopupLink(c="work", f="job_type", tooltip=T("Create a new job type"), ), ) # --------------------------------------------------------------------- # Job Priorities # job_priority = {1: T("Urgent"), 2: T("High"), 3: T("Normal"), 4: T("Low"), } # --------------------------------------------------------------------- # Job Statuses # job_status = (("OPEN", T("Open")), ("STARTED", T("Started")), ("ONHOLD", T("On Hold")), ("COMPLETED", T("Completed")), ("CANCELLED", T("Cancelled")), ) # --------------------------------------------------------------------- # Job # tablename = "work_job" define_table(tablename, job_type_id(), Field("name", label = T("Title"), requires = IS_NOT_EMPTY(), ), Field("details", "text", label = T("Details"), represent = s3_text_represent, ), Field("priority", "integer", default = 3, # normal priority requires = IS_IN_SET(job_priority, zero=None), represent = S3Represent(options=job_priority), ), Field("status", default = "OPEN", requires = IS_IN_SET(job_status, zero=None, sort=False), represent = S3Represent(options=dict(job_status)), ), self.super_link("site_id", "org_site", label = T("Place"), orderby = "org_site.name", readable = True, writable = True, represent = self.org_site_represent, ), s3_datetime("start_date"), Field("duration", "double", label = T("Hours Planned"), requires = IS_EMPTY_OR(IS_FLOAT_IN_RANGE(0, None)), ), Field("workers_min", "integer", default = 1, label = T("Workers needed"), requires = IS_INT_IN_RANGE(1, None), ), # @todo: onvalidation to check max>=min Field("workers_max", "integer", label = T("Workers needed (max)"), requires = IS_EMPTY_OR(IS_INT_IN_RANGE(1, None)), ), Field("workers_assigned", "integer", default = 0, label = T("Workers assigned"), requires = IS_INT_IN_RANGE(0, None), writable = False, ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Create Job"), title_display = T("Job Details"), title_list = T("Jobs"), title_update = T("Edit Job"), label_list_button = T("List Jobs"), msg_record_created = T("Job added"), msg_record_modified = T("Job updated"), msg_record_deleted = T("Job deleted"), msg_list_empty = T("No Jobs currently registered") ) # Filter widgets filter_widgets = [S3TextFilter(["name", "details", "job_type_id$name", "site_id$name", ], label = T("Search"), ), S3OptionsFilter("job_type_id"), S3OptionsFilter("status"), S3OptionsFilter("site_id", hidden = True, ), S3DateFilter("start_date", hidden = True, ), ] # List fields list_fields = ["priority", "job_type_id", "name", "site_id", "start_date", "duration", "status", "workers_min", "workers_assigned", ] # Table configuration configure(tablename, filter_widgets = filter_widgets, list_fields = list_fields, list_layout = work_JobListLayout(), ) # Custom methods set_method("work", "job", method = "signup", action = work_SignUp, ) set_method("work", "job", method = "cancel", action = work_SignUp, ) # Components add_components(tablename, work_assignment = "job_id", ) # Reusable field represent = S3Represent(lookup=tablename, show_link=True) job_id = S3ReusableField("job_id", "reference %s" % tablename, label = T("Job"), represent = represent, requires = IS_ONE_OF(db, "work_job.id", represent, ), sortby = "name", comment = S3PopupLink(c="work", f="job", tooltip=T("Create a new job"), ), ) # --------------------------------------------------------------------- # Linktable person<=>job # auth = current.auth tablename = "work_assignment" define_table(tablename, job_id(), # @todo: move default into job controller self.pr_person_id(default = auth.s3_logged_in_person()), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Create Assignment"), title_display = T("Assignment Details"), title_list = T("Assignments"), title_update = T("Edit Assignment"), label_list_button = T("List Assignments"), msg_record_created = T("Assignment added"), msg_record_modified = T("Assignment updated"), msg_record_deleted = T("Assignment deleted"), msg_list_empty = T("No Assignments currently registered") ) # Table configuration # @todo: add onvalidation to check that the same person has not # yet been assigned to the same job configure(tablename, onaccept = self.assignment_onaccept, ondelete = self.assignment_ondelete, ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) return {"work_job_id": job_id, }
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table # ----------------------------------------------------------- # Fire Zone Types tablename = "fire_zone_type" define_table(tablename, Field("name", label = T("Name"), requires = IS_NOT_EMPTY(), ), # @ToDo: Currently unused - apply in layer_feature for now Field("style", "text", label=T("Style")), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE_TYPE = T("Create Zone Type") crud_strings[tablename] = Storage( label_create = ADD_ZONE_TYPE, title_display = T("Zone Type Details"), title_list = T("Zone Types"), title_update = T("Edit Zone Type"), title_upload = T("Import Zone Types"), label_list_button = T("List Zone Types"), label_delete_button = T("Delete Zone Type"), msg_record_created = T("Zone Type added"), msg_record_modified = T("Zone Type updated"), msg_record_deleted = T("Zone Type deleted"), msg_list_empty = T("No Zone Types currently registered")) zone_type_represent = S3Represent(lookup=tablename) self.configure(tablename, deduplicate = S3Duplicate(), ) # ----------------------------------------------------------- # Fire Zones tablename = "fire_zone" define_table(tablename, Field("name", label = T("Name"), requires = IS_NOT_EMPTY(), ), Field("zone_type_id", db.fire_zone_type, requires = IS_EMPTY_OR( IS_ONE_OF(db, "fire_zone_type.id", zone_type_represent, sort=True)), represent = zone_type_represent, comment = S3PopupLink(c = "fire", f = "zone_type", label = ADD_ZONE_TYPE, tooltip = T("Select a Zone Type from the list or click 'Add Zone Type'"), ), label=T("Type")), self.gis_location_id( widget = S3LocationSelector(catalog_layers = True, points = False, polygons = True, ) ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Create Zone"), title_display = T("Zone Details"), title_list = T("Zones"), title_update = T("Edit Zone"), title_upload = T("Import Zones"), label_list_button = T("List Zones"), label_delete_button = T("Delete Zone"), msg_record_created = T("Zone added"), msg_record_modified = T("Zone updated"), msg_record_deleted = T("Zone deleted"), msg_list_empty = T("No Zones currently registered")) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {}
def model(self): T = current.T crud_strings = current.response.s3.crud_strings # --------------------------------------------------------------------- # Needs <=> Skills # skill_id = self.hrm_skill_id # Load normal model CREATE_SKILL = crud_strings["hrm_skill"].label_create tablename = "req_need_skill" self.define_table(tablename, self.req_need_id(empty = False), skill_id(comment = S3PopupLink(c = "hrm", f = "skill", label = CREATE_SKILL, tooltip = None, vars = {"prefix": "req"}, ), empty = False, ), Field("quantity", "double", label = T("Quantity"), represent = lambda v: \ IS_FLOAT_AMOUNT.represent(v, precision=2), requires = IS_EMPTY_OR( IS_FLOAT_AMOUNT(minimum = 1.0) ), ), req_priority()(), s3_comments(), req_status()("status", label = T("Fulfilment Status"), ), *s3_meta_fields()) self.configure( tablename, deduplicate=S3Duplicate(primary=( "need_id", "skill_id", ), ), ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Add Skill"), title_list=T("Skills"), title_display=T("Skill"), title_update=T("Edit Skill"), #title_upload = T("Import Skills"), label_list_button=T("List Skills"), label_delete_button=T("Delete Skill"), msg_record_created=T("Skill added"), msg_record_modified=T("Skill updated"), msg_record_deleted=T("Skill deleted"), msg_list_empty=T( "No Skills currently registered for this Request"), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return None
def model(self): T = current.T db = current.db add_components = self.add_components crud_strings = current.response.s3.crud_strings define_table = self.define_table location_id = self.gis_location_id template_id = self.dc_template_id # ===================================================================== # Data Collection Target # - planning of Assessments / Surveys # - optional step in the process # tablename = "dc_target" define_table( tablename, template_id(), s3_date(default="now"), location_id(widget=S3LocationSelector(show_map=False)), #self.org_organisation_id(), #self.pr_person_id(), s3_comments(), *s3_meta_fields()) # Components add_components( tablename, dc_collection="target_id", ) # CRUD strings current.response.s3.crud_strings[tablename] = Storage( label_create=T("Create Data Collection Target"), title_display=T("Data Collection Target Details"), title_list=T("Data Collection Targets"), title_update=T("Edit Data Collection Target"), title_upload=T("Import Data Collection Targets"), label_list_button=T("List Data Collection Targets"), label_delete_button=T("Delete Data Collection Target"), msg_record_created=T("Data Collection Target added"), msg_record_modified=T("Data Collection Target updated"), msg_record_deleted=T("Data Collection Target deleted"), msg_list_empty=T( "No Data Collection Targets currently registered")) target_id = S3ReusableField( "target_id", "reference %s" % tablename, requires=IS_EMPTY_OR(IS_ONE_OF(db, "dc_target.id")), readable=False, writable=False, ) # ===================================================================== # Data Collections # - instances of an Assessment / Survey # tablename = "dc_collection" define_table( tablename, self.super_link("doc_id", "doc_entity"), target_id(), template_id(), s3_date(default="now"), location_id(), self.org_organisation_id(), self.pr_person_id(default=current.auth.s3_logged_in_person(), ), s3_comments(), *s3_meta_fields()) # Configuration self.configure( tablename, super_entity="doc_entity", orderby="dc_collection.date desc", ) # Components add_components( tablename, dc_answer="collection_id", ) # CRUD strings label = current.deployment_settings.get_dc_collection_label() if label == "Assessment": label = T("Assessment") crud_strings[tablename] = Storage( label_create=T("Create Assessment"), title_display=T("Assessment Details"), title_list=T("Assessments"), title_update=T("Edit Assessment"), title_upload=T("Import Assessments"), label_list_button=T("List Assessments"), label_delete_button=T("Delete Assessment"), msg_record_created=T("Assessment added"), msg_record_modified=T("Assessment updated"), msg_record_deleted=T("Assessment deleted"), msg_list_empty=T("No Assessments currently registered")) elif label == "Survey": label = T("Survey") crud_strings[tablename] = Storage( label_create=T("Create Survey"), title_display=T("Survey Details"), title_list=T("Surveys"), 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")) else: label = T("Data Collection") crud_strings[tablename] = Storage( label_create=T("Create Data Collection"), title_display=T("Data Collection Details"), title_list=T("Data Collections"), title_update=T("Edit Data Collection"), title_upload=T("Import Data Collections"), label_list_button=T("List Data Collections"), label_delete_button=T("Delete Data Collection"), msg_record_created=T("Data Collection added"), msg_record_modified=T("Data Collection updated"), msg_record_deleted=T("Data Collection deleted"), msg_list_empty=T("No Data Collections currently registered")) # @todo: representation including template name, location and date # (not currently required since always hidden) represent = S3Represent( lookup=tablename, fields=["date"], ) # Reusable field collection_id = S3ReusableField( "collection_id", "reference %s" % tablename, label=label, represent=represent, requires=IS_ONE_OF( db, "dc_collection.id", represent, ), comment=S3PopupLink(f="collection", ), ) # ===================================================================== # Data Collection Answers # - the data within Assessments / Surveys # tablename = "dc_answer" define_table( tablename, collection_id(), self.dc_question_id(), Field( "answer", "json", requires=IS_EMPTY_OR(IS_JSON()), # @todo: representation? (based the question model) # @todo: widget? (based the question model) ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Answer"), title_display=T("Answer Details"), title_list=T("Answers"), title_update=T("Edit Answer"), title_upload=T("Import Answers"), label_list_button=T("List Answers"), label_delete_button=T("Delete Answer"), msg_record_created=T("Answer added"), msg_record_modified=T("Answer updated"), msg_record_deleted=T("Answer deleted"), msg_list_empty=T("No Answers currently registered")) # ===================================================================== # Pass names back to global scope (s3.*) return dict( dc_collection_id=collection_id, dc_target_id=target_id, )
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table # ===================================================================== # Data Collection # tablename = "dc_collection" define_table(tablename, self.super_link("doc_id", "doc_entity"), self.dc_template_id(), s3_date(default = "now"), self.gis_location_id(), self.org_organisation_id(), self.pr_person_id( default = current.auth.s3_logged_in_person(), ), s3_comments(), *s3_meta_fields()) # Configuration self.configure(tablename, super_entity = "doc_entity", orderby = "dc_collection.date desc", ) # Components self.add_components(tablename, dc_answer = "collection_id", ) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Create Data Collection"), title_display = T("Data Collection Details"), title_list = T("Data Collections"), title_update = T("Edit Data Collection"), title_upload = T("Import Data Collections"), label_list_button = T("List Data Collections"), label_delete_button = T("Delete Data Collection"), msg_record_created = T("Data Collection added"), msg_record_modified = T("Data Collection updated"), msg_record_deleted = T("Data Collection deleted"), msg_list_empty = T("No Data Collections currently registered")) # @todo: representation including template name, location and date # (not currently required since always hidden) represent = S3Represent(lookup=tablename, fields=["date"], ) # Reusable field collection_id = S3ReusableField("collection_id", "reference %s" % tablename, label = T("Data Collection"), represent = represent, requires = IS_ONE_OF(db, "dc_collection.id", represent, ), comment = S3PopupLink(f="collection", tooltip=T("Add a new data collection"), ), ) # ===================================================================== # Data Collection Answer # tablename = "dc_answer" define_table(tablename, collection_id(), self.dc_question_id(), Field("answer", "json", requires = IS_EMPTY_OR(IS_JSON()), # @todo: representation? (based the question model) # @todo: widget? (based the question model) ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Create Answer"), title_display = T("Answer Details"), title_list = T("Answers"), title_update = T("Edit Answer"), title_upload = T("Import Answers"), label_list_button = T("List Answers"), label_delete_button = T("Delete Answer"), msg_record_created = T("Answer added"), msg_record_modified = T("Answer updated"), msg_record_deleted = T("Answer deleted"), msg_list_empty = T("No Answers currently registered")) # ===================================================================== # Pass names back to global scope (s3.*) return dict(dc_collection_id = collection_id, )
def model(self): T = current.T db = current.db s3 = current.response.s3 crud_strings = s3.crud_strings define_table = self.define_table configure = self.configure person_id = self.pr_person_id # --------------------------------------------------------------------- # Seized Item Types # tablename = "security_seized_item_type" define_table(tablename, Field("name", requires = IS_NOT_EMPTY(), ), s3_comments(), *s3_meta_fields()) # Table Configuration configure(tablename, deduplicate = S3Duplicate(), ) # CRUD Strings crud_strings[tablename] = Storage( label_create = T("Create Item Type"), title_display = T("Item Type Details"), title_list = T("Item Types"), title_update = T("Edit Item Type"), label_list_button = T("List Item Types"), label_delete_button = T("Delete Item Type"), msg_record_created = T("Item Type created"), msg_record_modified = T("Item Type updated"), msg_record_deleted = T("Item Type deleted"), msg_list_empty = T("No Item Types currently defined"), ) # Reusable field represent = S3Represent(lookup=tablename, translate=True) item_type_id = S3ReusableField("item_type_id", "reference %s" % tablename, label = T("Type"), represent = represent, requires = IS_EMPTY_OR( IS_ONE_OF(db, "%s.id" % tablename, represent, )), sortby = "name", comment = S3PopupLink(c="security", f="seized_item_type", tooltip=T("Create new item type"), ), ) # --------------------------------------------------------------------- # Depositories # tablename = "security_seized_item_depository" define_table(tablename, Field("name", requires = IS_NOT_EMPTY(), ), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( label_create = T("Create Depository"), title_display = T("Depository Details"), title_list = T("Depositories"), title_update = T("Edit Depository"), label_list_button = T("List Depositories"), label_delete_button = T("Delete Depository"), msg_record_created = T("Depository created"), msg_record_modified = T("Depository updated"), msg_record_deleted = T("Depository deleted"), msg_list_empty = T("No Depositories currently registered"), ) # Reusable field represent = S3Represent(lookup=tablename) depository_id = S3ReusableField("depository_id", "reference %s" % tablename, label = T("Depository"), represent = represent, requires = IS_EMPTY_OR( IS_ONE_OF(db, "%s.id" % tablename, represent, )), sortby = "name", ) # --------------------------------------------------------------------- # Seized Items # seized_item_status = {"DEP": T("deposited"), "RET": T("returned to owner"), "DIS": T("disposed of/destroyed"), "FWD": T("forwarded"), #"OTH": T("other"), } tablename = "security_seized_item" define_table(tablename, # Owner person_id(empty = False, label = T("Owner"), ondelete = "CASCADE", # Autocomplete using security controller widget = S3PersonAutocompleteWidget( controller = "security", function = "person_search", ), comment = None, ), # Type and number of items item_type_id(empty = False, ondelete = "RESTRICT", ), Field("number", "integer", label = T("Count"), requires = IS_INT_IN_RANGE(1, None), ), # Confiscated when and by whom s3_date(default = "now", label = T("Confiscated on"), ), person_id("confiscated_by", label = T("Confiscated by"), default = current.auth.s3_logged_in_person(), comment = None, ), # Status Field("status", default = "DEP", requires = IS_IN_SET(seized_item_status, zero=None), represent = S3Represent(options=seized_item_status), ), depository_id(ondelete="SET NULL", ), Field("status_comment", label = T("Status Comment"), ), # Returned-date and person responsible s3_date("returned_on", label = T("Returned on"), # Set onaccept when returned=True writable = False, ), person_id("returned_by", label = T("Returned by"), # Set onaccept when returned=True writable = False, comment = None, ), s3_comments(represent = s3_text_represent, ), *s3_meta_fields()) # Filter Widgets filter_widgets = [S3TextFilter(["person_id$pe_label", "person_id$first_name", "person_id$middle_name", "person_id$last_name", "status_comment", "comments", ], label = T("Search"), ), S3OptionsFilter("item_type_id", options = s3_get_filter_opts( "security_seized_item_type"), ), S3OptionsFilter("status", options = seized_item_status, cols = 2, default = "DEP", ), S3OptionsFilter("depository_id", options = s3_get_filter_opts( "security_seized_item_depository"), ), S3DateFilter("date", hidden = True, ), ] # List Fields list_fields = ("person_id", "date", "number", "item_type_id", #"confiscated_by", "status", "depository_id", #"returned_on", #"returned_by", "comments", ) # Table Configuration configure(tablename, filter_widgets = filter_widgets, list_fields = list_fields, onaccept = self.seized_item_onaccept, orderby = "%s.date desc" % tablename, ) # CRUD Strings crud_strings[tablename] = Storage( label_create = T("Create Seized Item"), title_display = T("Seized Item Details"), title_list = T("Seized Items"), title_update = T("Edit Seized Item"), label_list_button = T("List Seized Items"), label_delete_button = T("Delete Seized Item"), msg_record_created = T("Seized Item created"), msg_record_modified = T("Seized Item updated"), msg_record_deleted = T("Seized Item deleted"), msg_list_empty = T("No Seized Items currently registered"), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {"security_seized_item_status_opts": seized_item_status, }
def model(self): T = current.T db = current.db add_components = self.add_components crud_strings = current.response.s3.crud_strings define_table = self.define_table location_id = self.gis_location_id template_id = self.dc_template_id # ===================================================================== # Data Collection Target # - planning of Assessments / Surveys # (optional step in the process) # - can be used to analyse a group of responses # tablename = "dc_target" define_table( tablename, template_id(), s3_date(default="now"), location_id(widget=S3LocationSelector( show_map=False, show_postcode=False, )), #self.org_organisation_id(), #self.pr_person_id(), s3_comments(), *s3_meta_fields()) # Components add_components( tablename, dc_response="target_id", event_event={ "link": "event_target", "joinby": "target_id", "key": "event_id", "actuate": "replace", }, hrm_training_event={ "link": "hrm_event_target", "joinby": "target_id", "key": "training_event_id", "actuate": "replace", }, ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Data Collection Target"), title_display=T("Data Collection Target Details"), title_list=T("Data Collection Targets"), title_update=T("Edit Data Collection Target"), title_upload=T("Import Data Collection Targets"), label_list_button=T("List Data Collection Targets"), label_delete_button=T("Delete Data Collection Target"), msg_record_created=T("Data Collection Target added"), msg_record_modified=T("Data Collection Target updated"), msg_record_deleted=T("Data Collection Target deleted"), msg_list_empty=T( "No Data Collection Targets currently registered")) target_id = S3ReusableField( "target_id", "reference %s" % tablename, requires=IS_EMPTY_OR(IS_ONE_OF(db, "dc_target.id")), readable=False, writable=False, ) # ===================================================================== # Answers / Responses # - instances of an Assessment / Survey # - each of these is a record in the Template's Dynamic Table # tablename = "dc_response" define_table( tablename, self.super_link("doc_id", "doc_entity"), target_id(), template_id(), s3_datetime(default="now"), location_id(), self.org_organisation_id(), self.pr_person_id(default=current.auth.s3_logged_in_person(), ), s3_comments(), *s3_meta_fields()) # Configuration self.configure( tablename, create_next=URL(f="respnse", args=["[id]", "answer"]), # Question Answers are in a Dynamic Component # - however they all have the same component name so add correct one in controller instead! #dynamic_components = True, super_entity="doc_entity", orderby="dc_response.date desc", ) # CRUD strings label = current.deployment_settings.get_dc_response_label() if label == "Assessment": label = T("Assessment") crud_strings[tablename] = Storage( label_create=T("Create Assessment"), title_display=T("Assessment Details"), title_list=T("Assessments"), title_update=T("Edit Assessment"), title_upload=T("Import Assessments"), label_list_button=T("List Assessments"), label_delete_button=T("Delete Assessment"), msg_record_created=T("Assessment added"), msg_record_modified=T("Assessment updated"), msg_record_deleted=T("Assessment deleted"), msg_list_empty=T("No Assessments currently registered")) elif label == "Survey": label = T("Survey") crud_strings[tablename] = Storage( label_create=T("Create Survey"), title_display=T("Survey Details"), title_list=T("Surveys"), 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")) else: label = T("Response") crud_strings[tablename] = Storage( label_create=T("Create Data Collection"), title_display=T("Data Collection Details"), title_list=T("Data Collections"), title_update=T("Edit Data Collection"), title_upload=T("Import Data Collections"), label_list_button=T("List Data Collections"), label_delete_button=T("Delete Data Collection"), msg_record_created=T("Data Collection added"), msg_record_modified=T("Data Collection updated"), msg_record_deleted=T("Data Collection deleted"), msg_list_empty=T("No Data Collections currently registered")) # @todo: representation including template name, location and date # (not currently required since always hidden) represent = S3Represent( lookup=tablename, fields=["date"], ) # Reusable field response_id = S3ReusableField( "response_id", "reference %s" % tablename, label=label, represent=represent, requires=IS_ONE_OF( db, "dc_response.id", represent, ), comment=S3PopupLink(f="respnse", ), ) # Components add_components( tablename, event_event={ "link": "event_response", "joinby": "response_id", "key": "event_id", "actuate": "replace", }, ) # ===================================================================== # Pass names back to global scope (s3.*) return dict( dc_response_id=response_id, dc_target_id=target_id, )
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings settings = current.deployment_settings add_components = self.add_components configure = self.configure define_table = self.define_table UNKNOWN_OPT = current.messages.UNKNOWN_OPT # ===================================================================== # Data Collection Templates # tablename = "dc_template" define_table( tablename, Field( "name", label=T("Name"), requires=IS_NOT_EMPTY(), ), # The Dynamic Table used to store the Questions and Answers # (An alternative design would be to use Tables as reusable # Sections but this hasn't been adopted at this time for # simplicity) self.s3_table_id( readable=False, writable=False, ), s3_comments(), *s3_meta_fields()) configure( tablename, create_onaccept=self.dc_template_create_onaccept, deduplicate=S3Duplicate(), ) # Reusable field represent = S3Represent(lookup=tablename) template_id = S3ReusableField( "template_id", "reference %s" % tablename, label=T("Template"), represent=represent, requires=IS_ONE_OF( db, "dc_template.id", represent, ), sortby="name", comment=S3PopupLink( f="template", tooltip=T("Add a new data collection template"), ), ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Template"), title_display=T("Template Details"), title_list=T("Templates"), title_update=T("Edit Template"), label_list_button=T("List Templates"), label_delete_button=T("Delete Template"), msg_record_created=T("Template added"), msg_record_modified=T("Template updated"), msg_record_deleted=T("Template deleted"), msg_list_empty=T("No Templates currently registered")) # Components add_components( tablename, dc_question="template_id", dc_section="template_id", ) # ===================================================================== # Template Sections # #Currently support Sections, SubSections & SubSubSections only # hierarchical_sections = True # @ToDo: deployment_setting tablename = "dc_section" define_table( tablename, template_id(), Field( "parent", "reference dc_section", label=T("SubSection of"), ondelete="RESTRICT", readable=hierarchical_sections, writable=hierarchical_sections, ), Field( "name", label=T("Name"), requires=IS_NOT_EMPTY(), ), Field( "posn", "integer", label=T("Position"), ), s3_comments(), *s3_meta_fields()) # Reusable field represent = S3Represent(lookup=tablename) requires = IS_EMPTY_OR(IS_ONE_OF( db, "dc_section.id", represent, )) if hierarchical_sections: hierarchy = "parent" # Can't be defined in-line as otherwise get a circular reference parent = db[tablename].parent parent.represent = represent parent.requires = requires widget = S3HierarchyWidget( lookup=tablename, represent=represent, multiple=False, leafonly=True, ) else: hierarchy = None widget = None section_id = S3ReusableField( "section_id", "reference %s" % tablename, label=T("Section"), represent=represent, requires=requires, sortby="name", widget=widget, #comment = S3PopupLink(f="template", # args=["[id]", "section"], # @ToDo: Build support for this? # tooltip=T("Add a new section to the template"), # ), ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Section"), title_display=T("Section Details"), title_list=T("Sections"), title_update=T("Edit Section"), label_list_button=T("List Sections"), label_delete_button=T("Delete Section"), msg_record_created=T("Section added"), msg_record_modified=T("Section updated"), msg_record_deleted=T("Section deleted"), msg_list_empty=T("No Sections currently registered")) configure( tablename, deduplicate=S3Duplicate(primary=("name", "parent", "template_id")), hierarchy=hierarchy, orderby=tablename + ".posn", ) # ===================================================================== # Questions # type_opts = { 1: T("Text"), 2: T("Number"), #3: T("Fractional Number"), 4: T("Yes/No"), 5: T("Yes, No, Don't Know"), 6: T("Options"), 7: T("Date"), #8: T("Date/Time"), 9: T("Grid"), # Pseudo-question #: T("Organization"), #: T("Location"), #: T("Person"), } tablename = "dc_question" define_table(tablename, template_id(), section_id(), Field("posn", "integer", label = T("Position"), ), Field("name", label = T("Name"), requires = IS_NOT_EMPTY(), ), Field("code", label = T("Code"), requires = IS_EMPTY_OR( # Only really needs to be unique per Template IS_NOT_IN_DB(db, "dc_question.code") ), comment = DIV(_class="tooltip", _title="%s|%s" % (T("Code"), T("Unique code for the field - required if using Auto-Totals or Grids"), ), ), ), # The Dynamic Field used to store the Question/Answers self.s3_field_id( readable = False, writable = False, ), Field("field_type", "integer", notnull=True, default = 1, # string label = T("Field Type"), represent = lambda opt: \ type_opts.get(opt, UNKNOWN_OPT), requires = IS_IN_SET(type_opts), ), Field("options", "json", label = T("Options"), requires = IS_EMPTY_OR(IS_JSONS3()), ), # Use List to force order or Dict to alphasort #Field("sort_options", "boolean", # default = True, # label = T("Sort Options?"), # represent = s3_yes_no_represent, # comment = DIV(_class="tooltip", # _title="%s|%s" % (T("Sort Options?"), # T("Whether options should be sorted alphabetically"), # ), # ), # ), Field("grid", "json", label = T("Grid"), requires = IS_EMPTY_OR(IS_JSONS3()), comment = DIV(_class="tooltip", _title="%s|%s%s" % (T("Grid"), T("For Grid Pseudo-Question, this is the Row labels & Column labels"), T("For Questions within the Grid, this is their position in the Grid, encoded as Grid,Row,Col"), # @ToDo: Widget? ), ), ), Field("totals", "json", label = T("Totals"), requires = IS_EMPTY_OR(IS_JSONS3()), comment = DIV(_class="tooltip", _title="%s|%s" % (T("Totals"), T("List of fields (codes) which this one is the Total of"), ), ), ), Field("require_not_empty", "boolean", default = False, label = T("Required?"), represent = s3_yes_no_represent, comment = DIV(_class="tooltip", _title="%s|%s" % (T("Required?"), T("Is the field mandatory? (Cannot be left empty)"), ), ), ), s3_comments(label = T("Tooltip"), represent = s3_text_represent, comment = DIV(_class="tooltip", _title="%s|%s" % (T("Tooltip"), T("Explanation of the field to be displayed in forms"), ), ), ), *s3_meta_fields()) unique_question_names_per_template = settings.get_dc_unique_question_names_per_template( ) if unique_question_names_per_template: # Deduplicate Questions by Name/Template # - needed for importing multiple translations deduplicate = S3Duplicate(primary=("name", "template_id")) else: deduplicate = None configure( tablename, onaccept=self.dc_question_onaccept, deduplicate=deduplicate, ) # Reusable field represent = S3Represent(lookup=tablename) question_id = S3ReusableField( "question_id", "reference %s" % tablename, label=T("Question"), represent=represent, requires=IS_ONE_OF( db, "dc_question.id", represent, ), sortby="name", #comment = S3PopupLink(f="question", # tooltip=T("Add a new question"), # ), ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Question"), title_display=T("Question Details"), title_list=T("Questions"), title_update=T("Edit Question"), title_upload=T("Import Questions"), label_list_button=T("List Questions"), label_delete_button=T("Delete Question"), msg_record_created=T("Question added"), msg_record_modified=T("Question updated"), msg_record_deleted=T("Question deleted"), msg_list_empty=T("No Questions currently registered")) # Components add_components( tablename, dc_question_l10n="question_id", ) # ===================================================================== # Question Translations # l10n_languages = settings.get_L10n_languages() tablename = "dc_question_l10n" define_table(tablename, question_id(), Field("language", label = T("Language"), represent = lambda opt: \ l10n_languages.get(opt, UNKNOWN_OPT), requires = IS_ISO639_2_LANGUAGE_CODE(), ), Field("name_l10n", label = T("Translated Question"), ), Field("options_l10n", "json", label = T("Translated Options"), represent = lambda opts: ", ".join(json.loads(opts)), requires = IS_EMPTY_OR(IS_JSONS3()), ), # @ToDo: Implement this when-required Field("tooltip_l10n", label = T("Translated Tooltip"), ), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Translation"), title_display=T("Translation Details"), title_list=T("Translations"), title_update=T("Edit Translation"), title_upload=T("Import Translations"), label_list_button=T("List Translations"), label_delete_button=T("Delete Translation"), msg_record_created=T("Translation added"), msg_record_modified=T("Translation updated"), msg_record_deleted=T("Translation deleted"), msg_list_empty=T("No Translations currently registered")) configure( tablename, onaccept=self.dc_question_l10n_onaccept, ) # ===================================================================== # Pass names back to global scope (s3.*) return dict(dc_template_id=template_id, )
def ns_only(tablename, fieldname = "organisation_id", required = True, branches = True, updateable = True, limit_filter_opts = True, hierarchy = True, ): """ Function to configure an organisation_id field to be restricted to just NS/Branch @param required: Field is mandatory @param branches: Include Branches @param updateable: Limit to Orgs which the user can update @param limit_filter_opts: Also limit the Filter options @param hierarchy: Use the hierarchy widget (unsuitable for use in Inline Components) NB If limit_filter_opts=True, apply in customise_xx_controller inside prep, after standard_prep is run """ # Lookup organisation_type_id for Red Cross db = current.db s3db = current.s3db ttable = s3db.org_organisation_type try: type_id = db(ttable.name == "Red Cross / Red Crescent").select(ttable.id, limitby=(0, 1), cache = s3db.cache, ).first().id except: # No IFRC prepop done - skip (e.g. testing impacts of CSS changes in this theme) return # Load standard model f = s3db[tablename][fieldname] if limit_filter_opts: # Find the relevant filter widget & limit it's options filter_widgets = s3db.get_config(tablename, "filter_widgets") filter_widget = None if filter_widgets: from s3 import FS, S3HierarchyFilter for w in filter_widgets: if isinstance(w, S3HierarchyFilter) and \ w.field == "organisation_id": filter_widget = w break if filter_widget is not None: selector = FS("organisation_organisation_type.organisation_type_id") filter_widget.opts["filter"] = (selector == type_id) # Label if branches: f.label = T("National Society / Branch") #f.label = T("Branch") else: f.label = T("National Society") # Requires # Filter by type ltable = db.org_organisation_organisation_type rows = db(ltable.organisation_type_id == type_id).select(ltable.organisation_id) filter_opts = [row.organisation_id for row in rows] auth = current.auth s3_has_role = auth.s3_has_role Admin = s3_has_role("ADMIN") if branches: if Admin: parent = True else: # @ToDo: Set the represent according to whether the user can see resources of just a single NS or multiple # @ToDo: Consider porting this into core user = auth.user if user: realms = user.realms #delegations = user.delegations if realms: parent = True else: parent = False else: parent = True else: # Keep the represent function as simple as possible parent = False # Exclude branches btable = s3db.org_organisation_branch rows = db((btable.deleted != True) & (btable.branch_id.belongs(filter_opts))).select(btable.branch_id) filter_opts = list(set(filter_opts) - set(row.branch_id for row in rows)) organisation_represent = s3db.org_OrganisationRepresent represent = organisation_represent(parent=parent) f.represent = represent from s3 import IS_ONE_OF requires = IS_ONE_OF(db, "org_organisation.id", represent, filterby = "id", filter_opts = filter_opts, updateable = updateable, orderby = "org_organisation.name", sort = True) if not required: from gluon import IS_EMPTY_OR requires = IS_EMPTY_OR(requires) f.requires = requires if parent and hierarchy: # Use hierarchy-widget from s3 import FS, S3HierarchyWidget # No need for parent in represent (it's a hierarchy view) node_represent = organisation_represent(parent=False) # Filter by type # (no need to exclude branches - we wouldn't be here if we didn't use branches) selector = FS("organisation_organisation_type.organisation_type_id") f.widget = S3HierarchyWidget(lookup="org_organisation", filter=(selector == type_id), represent=node_represent, multiple=False, leafonly=False, ) else: # Dropdown not Autocomplete f.widget = None # Comment if (Admin or s3_has_role("ORG_ADMIN")): # Need to do import after setting Theme from s3layouts import S3PopupLink from s3 import S3ScriptItem add_link = S3PopupLink(c = "org", f = "organisation", vars = {"organisation_type.name":"Red Cross / Red Crescent"}, label = T("Create National Society"), title = T("National Society"), ) comment = f.comment if not comment or isinstance(comment, S3PopupLink): f.comment = add_link elif isinstance(comment[1], S3ScriptItem): # Don't overwrite scripts f.comment[0] = add_link else: f.comment = add_link else: # Not allowed to add NS/Branch f.comment = ""
def model(self): T = current.T db = current.db s3 = current.response.s3 crud_strings = s3.crud_strings define_table = self.define_table configure = self.configure person_id = self.pr_person_id # --------------------------------------------------------------------- # Seized Item Types # tablename = "security_seized_item_type" define_table(tablename, Field( "name", requires=IS_NOT_EMPTY(), ), s3_comments(), *s3_meta_fields()) # Table Configuration configure( tablename, deduplicate=S3Duplicate(), ) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Create Item Type"), title_display=T("Item Type Details"), title_list=T("Item Types"), title_update=T("Edit Item Type"), label_list_button=T("List Item Types"), label_delete_button=T("Delete Item Type"), msg_record_created=T("Item Type created"), msg_record_modified=T("Item Type updated"), msg_record_deleted=T("Item Type deleted"), msg_list_empty=T("No Item Types currently defined"), ) # Reusable field represent = S3Represent(lookup=tablename, translate=True) item_type_id = S3ReusableField( "item_type_id", "reference %s" % tablename, label=T("Type"), represent=represent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "%s.id" % tablename, represent, )), sortby="name", comment=S3PopupLink( c="security", f="seized_item_type", tooltip=T("Create new item type"), ), ) # --------------------------------------------------------------------- # Seized Items # tablename = "security_seized_item" define_table( tablename, # Owner person_id( empty=False, label=T("Owner"), ondelete="CASCADE", # Autocomplete using security controller widget=S3PersonAutocompleteWidget( controller="security", function="person_search", ), comment=None, ), # Type and number of items item_type_id( empty=False, ondelete="RESTRICT", ), Field( "number", "integer", label=T("Count"), requires=IS_INT_IN_RANGE(1, None), ), # Confiscated on and by whom s3_date( default="now", label=T("Confiscated on"), ), person_id( "confiscated_by", label=T("Confiscated by"), default=current.auth.s3_logged_in_person(), comment=None, ), # Returned to owner Field( "returned", "boolean", default=False, label=T("Returned"), represent=s3_yes_no_represent, ), s3_date( "returned_on", label=T("Returned on"), # Set onaccept when returned=True writable=False, ), person_id( "returned_by", label=T("Returned by"), # Set onaccept when returned=True writable=False, comment=None, ), s3_comments(represent=s3_text_represent, ), *s3_meta_fields()) # List Fields list_fields = ( "person_id", "date", "number", "item_type_id", "confiscated_by", "returned", "returned_on", "returned_by", "comments", ) # Table Configuration configure( tablename, list_fields=list_fields, onaccept=self.seized_item_onaccept, ) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Create Seized Item"), title_display=T("Seized Item Details"), title_list=T("Seized Items"), title_update=T("Edit Seized Item"), label_list_button=T("List Seized Items"), label_delete_button=T("Delete Seized Item"), msg_record_created=T("Seized Item created"), msg_record_modified=T("Seized Item updated"), msg_record_deleted=T("Seized Item deleted"), msg_list_empty=T("No Seized Items currently registered"), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {}
def model(self): T = current.T #db = current.db is_float_represent = IS_FLOAT_AMOUNT.represent float_represent = lambda v: is_float_represent(v, precision=2) modality_opts = { 1: T("Cash"), 2: T("In-kind"), } if current.s3db.table("stats_demographic"): title = current.response.s3.crud_strings[ "stats_demographic"].label_create parameter_id_comment = S3PopupLink( c="stats", f="demographic", vars={"child": "parameter_id"}, title=title, ) else: parameter_id_comment = None # --------------------------------------------------------------------- # Response Line # tablename = "need_response_line" self.define_table( tablename, self.need_response_id(), self.need_line_id(), # A less precise location for this line # Here to more easily allow multiple dropdowns within an Inline form self.gis_location_id("coarse_location_id"), # A more precise location for this line self.gis_location_id(), self.org_sector_id(), Field( "modality", "integer", label=T("Modality"), represent=s3_options_represent(modality_opts), requires=IS_IN_SET(modality_opts), ), s3_date(label=T("Date Planned")), s3_date( "end_date", label=T("Date Completed"), ), self.super_link( "parameter_id", "stats_parameter", instance_types=("stats_demographic", ), label=T("Beneficiaries"), represent=self.stats_parameter_represent, readable=True, writable=True, #empty = False, comment=parameter_id_comment, ), Field( "value", "integer", label=T("Number Planned"), #label = T("Number in Need"), represent=IS_INT_AMOUNT.represent, requires=IS_INT_IN_RANGE(0, None), ), Field( "value_reached", "integer", label=T("Number Reached"), represent=IS_INT_AMOUNT.represent, requires=IS_INT_IN_RANGE(0, None), ), self.supply_item_category_id(), self.supply_item_id( # Default: #ondelete = "RESTRICT", requires=IS_EMPTY_OR(self.supply_item_id().requires), # Filter Item dropdown based on Category script=''' $.filterOptionsS3({ 'trigger':'item_category_id', 'target':'item_id', 'lookupPrefix':'supply', 'lookupResource':'item', })''', # Don't use Auto-complete widget=None, ), self.supply_item_pack_id(requires=IS_EMPTY_OR( self.supply_item_pack_id().requires), ), Field( "quantity", "double", label=T("Quantity Planned"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), ), Field( "quantity_delivered", "double", label=T("Quantity Delivered"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), ), self.project_status_id(), s3_comments(), *s3_meta_fields()) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return None
def model(self): T = current.T db = current.db is_float_represent = IS_FLOAT_AMOUNT.represent float_represent = lambda v: is_float_represent(v, precision=2) if self.table("stats_demographic"): title = current.response.s3.crud_strings[ "stats_demographic"].label_create parameter_id_comment = S3PopupLink( c="stats", f="demographic", vars={"child": "parameter_id"}, title=title, ) else: parameter_id_comment = None # --------------------------------------------------------------------- # Lines # tablename = "need_line" self.define_table( tablename, self.need_need_id(empty=False), # A less precise location for this line # Here to more easily allow multiple dropdowns within an Inline form self.gis_location_id("coarse_location_id"), # A more precise location for this line self.gis_location_id(), self.org_sector_id(), self.super_link( "parameter_id", "stats_parameter", instance_types=("stats_demographic", ), #label = T("Demographic"), label=T("People affected"), represent=self.stats_parameter_represent, readable=True, writable=True, #empty = False, comment=parameter_id_comment, ), Field( "value", "double", label=T("Number"), #label = T("Number in Need"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), ), Field( "value_committed", "double", label=T("Number Committed"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), # Enable in templates as-required readable=False, # Normally set automatically writable=False, ), Field( "value_uncommitted", "double", label=T("Number Uncommitted"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), # Enable in templates as-required readable=False, # Normally set automatically writable=False, ), Field( "value_reached", "double", label=T("Number Reached"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), # Enable in templates as-required readable=False, # Normally set automatically writable=False, ), self.supply_item_category_id(), self.supply_item_id( # Default: #ondelete = "RESTRICT", requires=IS_EMPTY_OR(self.supply_item_id().requires), # Filter Item dropdown based on Category script=''' $.filterOptionsS3({ 'trigger':'item_category_id', 'target':'item_id', 'lookupPrefix':'supply', 'lookupResource':'item', })''', # Don't use Auto-complete widget=None, ), self.supply_item_pack_id(requires=IS_EMPTY_OR( self.supply_item_pack_id().requires), ), Field( "quantity", "double", label=T("Quantity"), #label = T("Quantity Requested"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), ), need_timeframe()(), Field( "quantity_committed", "double", label=T("Quantity Committed"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), # Enable in templates as-required readable=False, # Normally set automatically writable=False, ), Field( "quantity_uncommitted", "double", label=T("Quantity Uncommitted"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), # Enable in templates as-required readable=False, # Normally set automatically writable=False, ), Field( "quantity_delivered", "double", label=T("Quantity Delivered"), represent=float_represent, requires=IS_EMPTY_OR(IS_FLOAT_AMOUNT(minimum=1.0)), # Enable in templates as-required readable=False, # Normally set automatically writable=False, ), #s3_comments(), need_status()(), *s3_meta_fields()) # Components self.add_components( tablename, need_response_line="need_line_id", ) #represent = S3Represent(lookup = tablename) need_line_id = S3ReusableField( "need_line_id", "reference %s" % tablename, label=T("Need"), ondelete="SET NULL", #represent = represent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "need_line.id", #represent, #orderby = "need_line.date", #sort = True, )), sortby="date", ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return { "need_line_id": need_line_id, }
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table # ----------------------------------------------------------- # Security Staff Types # tablename = "security_staff_type" define_table(tablename, Field( "name", label=T("Name"), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_STAFF = T("Add Staff Type") crud_strings[tablename] = Storage( label_create=ADD_STAFF, title_display=T("Staff Type Details"), title_list=T("Staff Types"), title_update=T("Edit Staff Type"), title_upload=T("Import Staff Types"), label_list_button=T("List Staff Types"), label_delete_button=T("Delete Staff Type"), msg_record_created=T("Staff Type added"), msg_record_modified=T("Staff Type updated"), msg_record_deleted=T("Staff Type deleted"), msg_list_empty=T("No Staff Types currently registered"), ) staff_type_represent = S3Represent(lookup=tablename) # ----------------------------------------------------------- # Security Staff # org_site_represent = self.org_site_represent tablename = "security_staff" define_table( tablename, self.hrm_human_resource_id(), Field( "staff_type_id", "list:reference security_staff_type", label=T("Type"), represent=self.security_staff_type_multirepresent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "security_staff_type.id", staff_type_represent, sort=True, multiple=True, )), comment=S3PopupLink( c="security", f="staff_type", label=ADD_STAFF, tooltip= T("Select a Staff Type from the list or click 'Add Staff Type'" ), ), ), self.security_zone_id(ondelete="CASCADE", ), # FK, not Instance or Component Field( "site_id", self.org_site, label=T("Facility"), ondelete="CASCADE", represent=org_site_represent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "org_site.site_id", org_site_represent, instance_types=current.auth.org_site_types, sort=True, not_filterby="obsolete", not_filter_opts=(True, ), )), ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Add Security-Related Staff"), title_display=T("Security-Related Staff Details"), title_list=T("Security-Related Staff"), title_update=T("Edit Security-Related Staff"), title_upload=T("Import Security-Related Staff"), label_list_button=T("List Security-Related Staff"), label_delete_button=T("Delete Security-Related Staff"), msg_record_created=T("Security-Related Staff added"), msg_record_modified=T("Security-Related Staff updated"), msg_record_deleted=T("Security-Related Staff deleted"), msg_list_empty=T("No Security-Related Staff currently registered"), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {}
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table # ----------------------------------------------------------- # Security Zone Types # tablename = "security_zone_type" define_table(tablename, Field( "name", label=T("Name"), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE_TYPE = T("Create Zone Type") crud_strings[tablename] = Storage( label_create=ADD_ZONE_TYPE, title_display=T("Zone Type Details"), title_list=T("Zone Types"), title_update=T("Edit Zone Type"), title_upload=T("Import Zone Types"), label_list_button=T("List Zone Types"), label_delete_button=T("Delete Zone Type"), msg_record_created=T("Zone Type added"), msg_record_modified=T("Zone Type updated"), msg_record_deleted=T("Zone Type deleted"), msg_list_empty=T("No Zone Types currently registered"), ) self.configure( tablename, deduplicate=S3Duplicate(), ) zone_type_represent = S3Represent(lookup=tablename) # ----------------------------------------------------------- # Security Zones # tablename = "security_zone" define_table( tablename, Field( "name", label=T("Name"), ), Field( "zone_type_id", db.security_zone_type, label=T("Type"), represent=zone_type_represent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "security_zone_type.id", zone_type_represent, sort=True, )), comment=S3PopupLink( c="security", f="zone_type", label=ADD_ZONE_TYPE, tooltip= T("Select a Zone Type from the list or click 'Add Zone Type'" ), ), ), self.gis_location_id(widget=S3LocationSelector( catalog_layers=True, points=False, polygons=True, ), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE = T("Create Zone") crud_strings[tablename] = Storage( label_create=ADD_ZONE, title_display=T("Zone Details"), title_list=T("Zones"), title_update=T("Edit Zone"), title_upload=T("Import Zones"), label_list_button=T("List Zones"), label_delete_button=T("Delete Zone"), msg_record_created=T("Zone added"), msg_record_modified=T("Zone updated"), msg_record_deleted=T("Zone deleted"), msg_list_empty=T("No Zones currently registered"), ) zone_represent = S3Represent(lookup=tablename) zone_id = S3ReusableField( "zone_id", "reference %s" % tablename, label=T("Zone"), ondelete="RESTRICT", represent=zone_represent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "security_zone.id", zone_represent, sort=True)), sortby="name", comment=S3PopupLink( c="security", f="zone", label=ADD_ZONE, tooltip= T("For wardens, select a Zone from the list or click 'Add Zone'" ), ), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return { "security_zone_id": zone_id, }
def customise_req_site_needs_resource(r, tablename): if r.tablename == "req_site_needs": table = r.table field = table.site_id field.label = current.T("Facility") field.readable = field.writable = True # Allow only facilities which do not have a req_site_needs # yet (single component), and filter out obsolete facilities from s3 import IS_ONE_OF, FS dbset = current.db(table.id == None) left = table.on(table.site_id == current.s3db.org_site.id) field.requires = IS_ONE_OF( dbset, "org_site.site_id", field.represent, left=left, not_filterby="obsolete", not_filter_opts=(True, ), orderby="org_site.name", sort=True, ) if not r.record: query = FS("site_id$obsolete") != True r.resource.add_filter(query) # Allow adding of facilities in popup from s3layouts import S3PopupLink field.comment = S3PopupLink( c="org", f="facility", vars={ "child": "site_id", "parent": "site_needs", }, title=T("Add New Facility"), ) # Filters from s3 import S3LocationFilter, S3TextFilter filter_widgets = [ S3TextFilter( [ "site_id$name", "vol_details", "goods_details", ], label=T("Search"), ), S3LocationFilter("site_id$location_id", ), ] # List fields list_fields = [ (T("Facility"), "site_id$name"), "site_id$location_id", ("%s?" % T("Volunteers"), "vol"), (T("Help Wanted"), "vol_details"), ("%s?" % T("Donations"), "goods"), (T("Donations Needed"), "goods_details"), "modified_on", ] current.s3db.configure( "req_site_needs", filter_widgets=filter_widgets, list_fields=list_fields, )
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table location_id = self.gis_location_id # ----------------------------------------------------------- # Security Levels # - according to the UN Security Level System (SLS) # http://ictemergency.wfp.org/c/document_library/get_file?uuid=c025cb98-2297-4208-bcc6-76ba02719c02&groupId=10844 # http://geonode.wfp.org/layers/geonode:wld_bnd_securitylevel_wfp # level_opts = {1: T("Minimal"), 2: T("Low"), 3: T("Moderate"), 4: T("Substantial"), 5: T("High"), 6: T("Extreme"), } tablename = "security_level" define_table(tablename, location_id( #label = T("Security Level Area"), widget = S3LocationSelector(show_map = False), ), # Overall Level Field("level", "integer", label = T("Security Level"), represent = lambda v: level_opts.get(v, current.messages.UNKNOWN_OPT), requires = IS_IN_SET(level_opts), ), # Categories Field("armed_conflict", "integer", label = T("Armed Conflict"), represent = lambda v: level_opts.get(v, current.messages.UNKNOWN_OPT), requires = IS_IN_SET(level_opts), ), Field("terrorism", "integer", label = T("Terrorism"), represent = lambda v: level_opts.get(v, current.messages.UNKNOWN_OPT), requires = IS_IN_SET(level_opts), ), Field("crime", "integer", label = T("Crime"), represent = lambda v: level_opts.get(v, current.messages.UNKNOWN_OPT), requires = IS_IN_SET(level_opts), ), Field("civil_unrest", "integer", label = T("Civil Unrest"), represent = lambda v: level_opts.get(v, current.messages.UNKNOWN_OPT), requires = IS_IN_SET(level_opts), ), Field("hazards", "integer", label = T("Hazards"), represent = lambda v: level_opts.get(v, current.messages.UNKNOWN_OPT), requires = IS_IN_SET(level_opts), comment = T("e.g. earthquakes or floods"), ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Classify Area"), title_display = T("Security Level Details"), title_list = T("Security Levels"), title_update = T("Edit Security Level"), title_upload = T("Import Security Levels"), label_list_button = T("List Security Levels"), label_delete_button = T("Delete Security Level"), msg_record_created = T("Security Area classified"), msg_record_modified = T("Security Level updated"), msg_record_deleted = T("Security Level deleted"), msg_list_empty = T("No Security Areas currently classified")) # ----------------------------------------------------------- # Security Zone Types # tablename = "security_zone_type" define_table(tablename, Field("name", label = T("Name"), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE_TYPE = T("Create Zone Type") crud_strings[tablename] = Storage( label_create = ADD_ZONE_TYPE, title_display = T("Zone Type Details"), title_list = T("Zone Types"), title_update = T("Edit Zone Type"), title_upload = T("Import Zone Types"), label_list_button = T("List Zone Types"), label_delete_button = T("Delete Zone Type"), msg_record_created = T("Zone Type added"), msg_record_modified = T("Zone Type updated"), msg_record_deleted = T("Zone Type deleted"), msg_list_empty = T("No Zone Types currently registered")) zone_type_represent = S3Represent(lookup=tablename) self.configure(tablename, deduplicate = S3Duplicate(), ) # ----------------------------------------------------------- # Security Zones # tablename = "security_zone" define_table(tablename, Field("name", label = T("Name"), ), Field("zone_type_id", db.security_zone_type, label = T("Type"), represent = zone_type_represent, requires = IS_EMPTY_OR( IS_ONE_OF(db, "security_zone_type.id", zone_type_represent, sort=True)), comment = S3PopupLink(c = "security", f = "zone_type", label = ADD_ZONE_TYPE, tooltip = T("Select a Zone Type from the list or click 'Add Zone Type'"), ), ), location_id( widget = S3LocationSelector(catalog_layers = True, points = False, polygons = True, ), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE = T("Create Zone") crud_strings[tablename] = Storage( label_create = ADD_ZONE, title_display = T("Zone Details"), title_list = T("Zones"), title_update = T("Edit Zone"), title_upload = T("Import Zones"), label_list_button = T("List Zones"), label_delete_button = T("Delete Zone"), msg_record_created = T("Zone added"), msg_record_modified = T("Zone updated"), msg_record_deleted = T("Zone deleted"), msg_list_empty = T("No Zones currently registered")) zone_represent = S3Represent(lookup=tablename) # ----------------------------------------------------------- # Security Staff Types # tablename = "security_staff_type" define_table(tablename, Field("name", label=T("Name")), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_STAFF = T("Add Staff Type") crud_strings[tablename] = Storage( label_create = ADD_STAFF, title_display = T("Staff Type Details"), title_list = T("Staff Types"), title_update = T("Edit Staff Type"), title_upload = T("Import Staff Types"), label_list_button = T("List Staff Types"), label_delete_button = T("Delete Staff Type"), msg_record_created = T("Staff Type added"), msg_record_modified = T("Staff Type updated"), msg_record_deleted = T("Staff Type deleted"), msg_list_empty = T("No Staff Types currently registered")) staff_type_represent = S3Represent(lookup=tablename) # ----------------------------------------------------------- # Security Staff # tablename = "security_staff" define_table(tablename, self.hrm_human_resource_id(), Field("staff_type_id", "list:reference security_staff_type", label = T("Type"), represent = self.security_staff_type_multirepresent, requires = IS_EMPTY_OR( IS_ONE_OF(db, "security_staff_type.id", staff_type_represent, sort=True, multiple=True)), comment = S3PopupLink(c = "security", f = "staff_type", label = ADD_STAFF, tooltip = T("Select a Staff Type from the list or click 'Add Staff Type'"), ), ), Field("zone_id", db.security_zone, label = T("Zone"), represent = zone_represent, requires = IS_EMPTY_OR( IS_ONE_OF(db, "security_zone.id", zone_represent, sort=True)), comment = S3PopupLink(c = "security", f = "zone", label = ADD_ZONE, tooltip = T("For wardens, select a Zone from the list or click 'Add Zone'"), ), ), self.super_link("site_id", "org_site", label = T("Facility"), represent = self.org_site_represent, readable = True, writable = True, ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create = T("Add Security-Related Staff"), title_display = T("Security-Related Staff Details"), title_list = T("Security-Related Staff"), title_update = T("Edit Security-Related Staff"), title_upload = T("Import Security-Related Staff"), label_list_button = T("List Security-Related Staff"), label_delete_button = T("Delete Security-Related Staff"), msg_record_created = T("Security-Related Staff added"), msg_record_modified = T("Security-Related Staff updated"), msg_record_deleted = T("Security-Related Staff deleted"), msg_list_empty = T("No Security-Related Staff currently registered")) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {}
def model(self): T = current.T db = current.db define_table = self.define_table super_link = self.super_link configure = self.configure s3 = current.response.s3 crud_strings = s3.crud_strings settings = current.deployment_settings person_id = self.pr_person_id # --------------------------------------------------------------------- # Household # tablename = "po_household" define_table( tablename, super_link("doc_id", "doc_entity"), super_link("pe_id", "pr_pentity"), self.po_area_id(), # Controller (area prep) makes it inherit Lx from area self.gis_location_id( label=T("Address"), widget=S3LocationSelector( show_address=True, # Defaults: #show_map=settings.get_gis_map_selector(), #show_postcode=settings.get_gis_postcode_selector(), prevent_duplicate_addresses=True, ), ), s3_date( "date_visited", default="now", empty=False, label=T("Date visited"), ), Field( "followup", "boolean", default=False, label=T("Follow up"), represent=s3_yes_no_represent, ), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Create Household"), title_display=T("Household Details"), title_list=T("Households"), title_update=T("Edit Household"), label_list_button=T("List Households"), label_delete_button=T("Delete Household"), msg_record_created=T("Household created"), msg_record_modified=T("Household updated"), msg_record_deleted=T("Household deleted"), msg_list_empty=T("No Households currently registered"), ) # Reusable Field represent = po_HouseholdRepresent() household_id = S3ReusableField( "household_id", "reference %s" % tablename, label=T("Household"), represent=represent, requires=IS_ONE_OF( db, "po_household.id", represent, ), sortby="name", comment=S3PopupLink( f="household", tooltip=T("Create a new household"), ), ) # Filter Widgets filter_widgets = [ S3TextFilter( ( "household_member.person_id$first_name", "household_member.person_id$middle_name", "household_member.person_id$last_name", "location_id$addr_street", ), label=T("Search"), comment=T("Search by Address or Name of Household Member"), ), S3OptionsFilter("area_id", #hidden = True, ), S3DateFilter( "date_visited", label=T("Date visited"), hidden=True, ), S3OptionsFilter( "followup", cols=2, hidden=True, ), S3DateFilter( "household_followup.followup_date", label=T("Follow-up Date"), hidden=True, ), S3OptionsFilter( "household_followup.completed", cols=2, hidden=True, ), S3OptionsFilter( "organisation_household.organisation_id", hidden=True, ), ] # List fields list_fields = ( "area_id", "location_id", "date_visited", "followup", "household_followup.followup_date", "household_followup.completed", "organisation_household.organisation_id", "comments", ) # Reports report_axes = [ "area_id", "followup", "organisation_household.organisation_id", "household_followup.completed", "household_followup.evaluation", ] reports = ((T("Number of Households Visited"), "count(id)"), ) # Custom Form crud_form = S3SQLCustomForm( "area_id", "location_id", "date_visited", "followup", S3SQLInlineComponent( "contact", label=T("Contact Information"), fields=[ "priority", (T("Type"), "contact_method"), (T("Number"), "value"), "comments", ], orderby="priority", ), "household_social.language", "household_social.community", "household_dwelling.dwelling_type", "household_dwelling.type_of_use", "household_dwelling.repair_status", "comments", ) configure( tablename, create_next=self.household_create_next, crud_form=crud_form, deduplicate=S3Duplicate(primary=("location_id", )), filter_widgets=filter_widgets, list_fields=list_fields, onaccept=self.household_onaccept, report_options={ "rows": report_axes, "cols": report_axes, "fact": reports, "defaults": { "rows": "area_id", "cols": "followup", "fact": "count(id)", } }, super_entity=("doc_entity", "pr_pentity"), ) # Components self.add_components( tablename, pr_person={ "link": "po_household_member", "joinby": "household_id", "key": "person_id", "actuate": "replace", }, po_household_dwelling={ "joinby": "household_id", "multiple": False, }, po_household_social={ "joinby": "household_id", "multiple": False, }, po_household_followup={ "joinby": "household_id", "multiple": False, }, po_organisation_household="household_id", ) # --------------------------------------------------------------------- # Household Members # tablename = "po_household_member" define_table(tablename, household_id(), person_id(), s3_comments(), *s3_meta_fields()) # --------------------------------------------------------------------- # Household Member Age Groups (under 18,18-30,30-55,56-75,75+) # age_groups = ("<18", "18-30", "30-55", "56-75", "75+") tablename = "po_age_group" define_table( tablename, person_id(), Field( "age_group", label=T("Age Group"), requires=IS_EMPTY_OR(IS_IN_SET(age_groups)), ), *s3_meta_fields()) # --------------------------------------------------------------------- # Dwelling # dwelling_type = { "U": T("Unit"), "H": T("House"), "A": T("Apartment"), "S": T("Supervised House"), "O": T("Other"), } type_of_use = { "S": T("Owner-occupied"), "R": T("Renting"), "B": T("Boarding"), "O": T("Other"), } repair_status = { "W": T("waiting"), "R": T("rebuild"), "C": T("completed"), "N": T("not required"), "O": T("other"), } tablename = "po_household_dwelling" define_table( tablename, household_id(), Field( "dwelling_type", label=T("Type of Dwelling"), represent=S3Represent(options=dwelling_type), requires=IS_EMPTY_OR(IS_IN_SET(dwelling_type)), ), Field( "type_of_use", label=T("Type of Use"), represent=S3Represent(options=type_of_use), requires=IS_EMPTY_OR(IS_IN_SET(type_of_use)), ), Field( "repair_status", label=T("Stage of Repair"), represent=S3Represent(options=repair_status), requires=IS_EMPTY_OR(IS_IN_SET(repair_status)), ), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( title_update=T("Edit Dwelling Data"), ) # Table configuration configure( tablename, deduplicate=S3Duplicate(primary=("household_id", )), ) # --------------------------------------------------------------------- # Social Information # languages = dict(IS_ISO639_2_LANGUAGE_CODE.language_codes()) tablename = "po_household_social" define_table( tablename, household_id(), Field( "language", label=T("Main Language"), represent=S3Represent(options=languages), requires=IS_EMPTY_OR( IS_ISO639_2_LANGUAGE_CODE( select=None, sort=True, )), ), Field( "community", "text", label=T("Community Connections"), ), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( title_update=T("Edit Social Information"), ) # Table configuration configure( tablename, deduplicate=S3Duplicate(primary=("household_id", )), ) # --------------------------------------------------------------------- # Follow-up Details # evaluation = { "B": T("better"), "S": T("same"), "W": T("worse"), } twoweeks = current.request.utcnow + datetime.timedelta(days=14) tablename = "po_household_followup" define_table( tablename, household_id(), Field( "followup_required", label=T("Follow-up required"), ), s3_date( "followup_date", label=T("Date for Follow-up"), default=twoweeks, past=0, ), Field( "followup", "text", label=T("Follow-up made"), ), Field( "completed", "boolean", default=False, label="Follow-up completed", represent=s3_yes_no_represent, ), Field( "evaluation", label=T("Evaluation"), represent=S3Represent(options=evaluation), requires=IS_EMPTY_OR(IS_IN_SET(evaluation)), ), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( title_update=T("Edit Follow-up Details"), ) configure( tablename, deduplicate=S3Duplicate(primary=("household_id", )), deletable=False, ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return { "po_household_id": household_id, }
def model(self): T = current.T db = current.db auth = current.auth messages = current.messages NONE = messages["NONE"] configure = self.configure crud_strings = current.response.s3.crud_strings define_table = self.define_table settings = current.deployment_settings super_link = self.super_link organisation_id = self.org_organisation_id #ADMIN = current.session.s3.system_roles.ADMIN #is_admin = auth.s3_has_role(ADMIN) #root_org = auth.root_org() #if is_admin: # filter_opts = () #elif root_org: # filter_opts = (root_org, None) #else: # filter_opts = (None,) # --------------------------------------------------------------------- # School Types # #org_dependent_types = settings.get_edu_org_dependent_school_types() tablename = "edu_school_type" define_table( tablename, Field("name", length=128, notnull=True, label=T("Name"), requires=[ IS_NOT_EMPTY(), IS_LENGTH(128), ]), #organisation_id(default = root_org if org_dependent_types else None, # readable = is_admin if org_dependent_types else False, # writable = is_admin if org_dependent_types else False, # ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_SCHOOL_TYPE = T("Create School Type") crud_strings[tablename] = Storage( label_create=ADD_SCHOOL_TYPE, title_display=T("School Type Details"), title_list=T("School Types"), title_update=T("Edit School Type"), label_list_button=T("List School Types"), label_delete_button=T("Delete School Type"), msg_record_created=T("School Type added"), msg_record_modified=T("School Type updated"), msg_record_deleted=T("School Type deleted"), msg_list_empty=T("No School Types currently registered")) represent = S3Represent(lookup=tablename, translate=True) school_type_id = S3ReusableField( "school_type_id", "reference %s" % tablename, label=T("School Type"), ondelete="SET NULL", represent=represent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "edu_school_type.id", represent, #filterby="organisation_id", #filter_opts=filter_opts, sort=True)), sortby="name", comment=S3PopupLink( c="edu", f="school_type", label=ADD_SCHOOL_TYPE, title=T("School Type"), tooltip= T("If you don't see the Type in the list, you can add a new one by clicking link 'Create School Type'." ), ), ) configure( tablename, deduplicate=S3Duplicate(primary=("name", ), #secondary = ("organisation_id",), ), ) # Tags as component of School Types #self.add_components(tablename, # edu_school_type_tag={"name": "tag", # "joinby": "school_type_id", # } # ) # --------------------------------------------------------------------- # Schools # if settings.get_edu_school_code_unique(): code_requires = IS_EMPTY_OR([ IS_LENGTH(10), IS_NOT_IN_DB(db, "edu_school.code"), ]) else: code_requires = IS_LENGTH(10) tablename = "edu_school" define_table(tablename, super_link("pe_id", "pr_pentity"), super_link("site_id", "org_site"), super_link("doc_id", "doc_entity"), Field("name", notnull=True, length=64, # Mayon Compatibility label = T("Name"), requires = [IS_NOT_EMPTY(), IS_LENGTH(64), ], ), Field("code", length=10, # Mayon compatibility label = T("Code"), represent = lambda v: v or NONE, requires = code_requires, ), organisation_id( requires = self.org_organisation_requires(updateable=True), ), school_type_id(), self.gis_location_id(), Field("capacity", "integer", label = T("Capacity"), represent = lambda v: v or NONE, ), Field("contact", label = T("Contact"), represent = lambda v: v or NONE, ), Field("phone", label = T("Phone"), represent = lambda v: v or NONE, requires = IS_EMPTY_OR(s3_phone_requires) ), Field("email", label = T("Email"), represent = lambda v: v or NONE, requires = IS_EMPTY_OR(IS_EMAIL()) ), Field("website", label = T("Website"), represent = lambda url: s3_url_represent(url), requires = IS_EMPTY_OR(IS_URL()), ), Field("obsolete", "boolean", default = False, label = T("Obsolete"), represent = lambda opt: \ (opt and [T("Obsolete")] or NONE)[0], readable = False, writable = False, ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create School"), title_display=T("School Details"), title_list=T("Schools"), title_update=T("Edit School"), title_upload=T("Import Schools"), title_map=T("Map of Schools"), label_list_button=T("List Schools"), label_delete_button=T("Delete School"), msg_record_created=T("School added"), msg_record_modified=T("School updated"), msg_record_deleted=T("School deleted"), msg_list_empty=T("No Schools currently registered")) # Which levels of Hierarchy are we using? levels = current.gis.get_relevant_hierarchy_levels() list_fields = [ "name", #"organisation_id", # Filtered in Component views "school_type_id", ] text_fields = [ "name", "code", "comments", #"organisation_id$name", #"organisation_id$acronym", ] #report_fields = ["name", # "organisation_id", # ] for level in levels: lfield = "location_id$%s" % level list_fields.append(lfield) #report_fields.append(lfield) text_fields.append(lfield) list_fields += [ #(T("Address"), "location_id$addr_street"), "phone", "email", ] # Filter widgets filter_widgets = [ S3TextFilter( text_fields, label=T("Search"), #_class="filter-search", ), #S3OptionsFilter("organisation_id", # #hidden=True, # #label=T("Organization"), # # Doesn't support l10n # #represent="%(name)s", # ), S3LocationFilter( "location_id", #hidden=True, #label=T("Location"), levels=levels, ), ] configure( tablename, deduplicate=S3Duplicate( primary=("name", ), secondary=("organisation_id", ), ), filter_widgets=filter_widgets, list_fields=list_fields, #onaccept = self.edu_school_onaccept, super_entity=("pr_pentity", "org_site"), update_realm=True, ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {}
def model(self): T = current.T auth = current.auth super_link = self.super_link #root_org = auth.root_org() #ADMIN = current.session.s3.system_roles.ADMIN #is_admin = auth.s3_has_role(ADMIN) # --------------------------------------------------------------------- # Area # tablename = "po_area" self.define_table( tablename, super_link("doc_id", "doc_entity"), super_link("pe_id", "pr_pentity"), Field( "name", requires=IS_NOT_EMPTY(), ), self.gis_location_id(widget=S3LocationSelector( points=False, polygons=True, feature_required=True, ), ), # Only included to set realm entity: self.org_organisation_id( default=auth.user and auth.user.organisation_id, #default = root_org, #readable = is_admin, #writable = is_admin, ), Field( "attempted_visits", "integer", comment=DIV( _class="tooltip", _title="%s|%s" % (T("Attempted Visits"), T("Number of households in the area where nobody was at home at the time of visit" ))), default=0, label=T("Attempted Visits"), requires=IS_EMPTY_OR(IS_INT_IN_RANGE(minimum=0)), ), s3_comments(), *s3_meta_fields()) # CRUD Strings current.response.s3.crud_strings[tablename] = Storage( label_create=T("Create Area"), title_display=T("Area Details"), title_list=T("Areas"), title_update=T("Edit Area"), label_list_button=T("List Areas"), label_delete_button=T("Delete Area"), msg_record_created=T("Area created"), msg_record_modified=T("Area updated"), msg_record_deleted=T("Area deleted"), msg_list_empty=T("No Areas currently registered"), ) # Reusable field represent = S3Represent(lookup=tablename, show_link=True) area_id = S3ReusableField( "area_id", "reference %s" % tablename, label=T("Area"), represent=represent, requires=IS_ONE_OF( current.db, "po_area.id", represent, ), sortby="name", comment=S3PopupLink( f="area", tooltip=T("Create a new area"), ), ) # Components self.add_components( tablename, po_household="area_id", org_organisation={ "link": "po_organisation_area", "joinby": "area_id", "key": "organisation_id", "actuate": "hide", }, ) levels = current.gis.get_relevant_hierarchy_levels() # Filters filter_widgets = [ S3TextFilter(["name"]), S3LocationFilter("location_id", levels=levels), ] # @todo: reports # Table Configuration self.configure( tablename, deduplicate=S3Duplicate(ignore_deleted=True), filter_widgets=filter_widgets, onaccept=self.area_onaccept, ondelete=self.area_ondelete, summary=( { "common": True, "name": "add", "widgets": [{ "method": "create" }], }, { "name": "table", "label": "Table", "widgets": [{ "method": "datatable" }] }, { "name": "map", "label": "Map", "widgets": [{ "method": "map", "ajax_init": True }], }, ), super_entity=("doc_entity", "pr_pentity"), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return { "po_area_id": area_id, }
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table add_components = self.add_components # ===================================================================== # Data Collection Template # tablename = "dc_template" define_table( tablename, Field( "name", requires=IS_NOT_EMPTY(), ), # Whether to show this template in the form list # (required since form list can't use authorization) Field( "public", "boolean", default=False, ), s3_comments(), *s3_meta_fields()) self.configure( tablename, xform={ "collection": "dc_collection", "questions": "question", "answers": "answer", }, ) # Represent represent = S3Represent(lookup=tablename) # Reusable field template_id = S3ReusableField( "template_id", "reference %s" % tablename, label=T("Template"), represent=represent, requires=IS_ONE_OF( db, "dc_template.id", represent, ), sortby="name", comment=S3PopupLink( f="template", tooltip=T("Add a new data collection template"), ), ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Template"), title_display=T("Template Details"), title_list=T("Templates"), title_update=T("Edit Template"), title_upload=T("Import Templates"), label_list_button=T("List Templates"), label_delete_button=T("Delete Template"), msg_record_created=T("Template added"), msg_record_modified=T("Template updated"), msg_record_deleted=T("Template deleted"), msg_list_empty=T("No Templates currently registered")) # Components add_components( tablename, dc_question={ "link": "dc_template_question", "joinby": "template_id", "key": "question_id", "actuate": "hide", "autodelete": False, }, ) # ===================================================================== # Data Collection Question # tablename = "dc_question" define_table( tablename, Field( "question", requires=IS_NOT_EMPTY(), ), Field( "model", "json", requires=IS_EMPTY_OR(IS_JSON(native_json=True)), # @todo: representation? widget=S3QuestionWidget(), ), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Question"), title_display=T("Question Details"), title_list=T("Questions"), title_update=T("Edit Question"), title_upload=T("Import Questions"), label_list_button=T("List Questions"), label_delete_button=T("Delete Question"), msg_record_created=T("Question added"), msg_record_modified=T("Question updated"), msg_record_deleted=T("Question deleted"), msg_list_empty=T("No Questions currently registered")) # Represent represent = S3Represent( lookup=tablename, fields=["question"], show_link=True, ) # Reusable field question_id = S3ReusableField( "question_id", "reference %s" % tablename, label=T("Question"), represent=represent, requires=IS_ONE_OF( db, "dc_question.id", represent, ), sortby="name", comment=S3PopupLink( f="question", tooltip=T("Add a new data collection question"), ), ) # Components add_components( tablename, dc_question_l10n="question_id", ) # ===================================================================== # Template <=> Question link table # tablename = "dc_template_question" define_table(tablename, template_id(), question_id(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Add Question"), label_delete_button=T("Remove Question"), msg_record_created=T("Question added"), msg_record_deleted=T("Question remove"), msg_list_empty=T("No Questions currently registered")) # ===================================================================== # Questions l10n # tablename = "dc_question_l10n" define_table( tablename, question_id(ondelete="CASCADE", ), Field( "language", label=T("Language"), represent=IS_ISO639_2_LANGUAGE_CODE.represent, requires=IS_ISO639_2_LANGUAGE_CODE(sort=True), ), Field( "question", requires=IS_NOT_EMPTY(), ), Field( "model", "json", requires=IS_EMPTY_OR(IS_JSON()), # @todo: representation? # @todo: widget? ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Translation"), title_display=T("Translation"), title_list=T("Translations"), title_update=T("Edit Translation"), title_upload=T("Import Translations"), label_list_button=T("List Translations"), label_delete_button=T("Delete Translation"), msg_record_created=T("Translation added"), msg_record_modified=T("Translation updated"), msg_record_deleted=T("Translation deleted"), msg_list_empty=T("No Translations currently available")) # ===================================================================== # Pass names back to global scope (s3.*) return dict( dc_template_id=template_id, dc_question_id=question_id, )
def model(self): T = current.T db = current.db define_table = self.define_table configure = self.configure s3 = current.response.s3 crud_strings = s3.crud_strings organisation_id = self.org_organisation_id # Organisation Represent should link to po/organisation org_link = URL(c="po", f="organisation", args="[id]") org_represent = self.org_OrganisationRepresent( show_link=True, linkto=org_link, ) # Organisation AddResourceLink should go to po/organisation ADD_ORGANISATION = T("Create Agency") tooltip = T( "If you don't see the Agency in the list, you can add a new one by clicking link 'Create Agency'." ) org_comment = S3PopupLink( c="po", f="organisation", label=ADD_ORGANISATION, title=ADD_ORGANISATION, tooltip=tooltip, ) # --------------------------------------------------------------------- # Referral Agency (context link table), currently not visible # tablename = "po_referral_organisation" define_table( tablename, organisation_id( represent=org_represent, comment=org_comment, ), #s3_comments(), *s3_meta_fields()) configure( tablename, deduplicate=S3Duplicate(primary=("organisation_id", )), ) # --------------------------------------------------------------------- # Areas Served by a Referral Agency # tablename = "po_organisation_area" define_table( tablename, # @todo: AddResourceLink should go to po/organisation organisation_id( label=T("Agency"), represent=org_represent, comment=org_comment, ), self.po_area_id(), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Add Agency"), title_update=T("Edit Referral Agency"), label_list_button=T("List Agencies"), label_delete_button=T("Remove Agency"), ) # --------------------------------------------------------------------- # Referral Household=>Agency # tablename = "po_organisation_household" define_table( tablename, # @todo: AddResourceLink should go to po/organisation organisation_id( label=T("Referral Agency"), represent=org_represent, comment=org_comment, ), self.po_household_id(), s3_date( default="now", label=T("Date Referral Made"), ), s3_comments(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Add Referral"), title_update=T("Edit Referral Details"), label_delete_button=T("Delete Referral"), ) # Table Configuration configure( tablename, deduplicate=S3Duplicate(primary=( "household_id", "organisation_id", ), ), orderby="%s.date desc" % tablename, list_fields=( "date", "organisation_id", "household_id", "comments", ), )
def model(self): T = current.T db = current.db request = current.request s3 = current.response.s3 messages = current.messages UNKNOWN_OPT = messages.UNKNOWN_OPT NONE = messages["NONE"] crud_strings = s3.crud_strings define_table = self.define_table add_components = self.add_components configure = self.configure set_method = self.set_method s3_datetime_represent = lambda dt: \ S3DateTime.datetime_represent(dt, utc=True) # ------------------------------------------------------------------------- # Configuration # ------------------------------------------------------------------------- tablename = "sync_config" define_table( tablename, Field( "proxy", label=T("Proxy Server URL"), requires=IS_EMPTY_OR(IS_URL(mode="generic")), ), *s3_meta_fields()) # Field configuration # @todo: make in-line table = db[tablename] table.uuid.readable = True table.uuid.label = "UUID" table.uuid.comment = DIV( _class="tooltip", _title="%s|%s" % (T("UUID"), T("Unique identifier which THIS repository identifies itself with when sending synchronization requests." ))) table.proxy.comment = DIV( _class="tooltip", _title="%s|%s" % (T("Proxy Server URL"), T("URL of the default proxy server to connect to remote repositories (if required). If only some of the repositories require the use of a proxy server, you can configure this in the respective repository configurations." ))) # CRUD Strings crud_strings[tablename] = Storage( title_display=T("Synchronization Settings"), title_update=T("Edit Synchronization Settings"), msg_record_modified=T("Synchronization settings updated")) # Resource Configuration configure( tablename, deletable=False, insertable=False, update_next=URL(c="sync", f="config", args=["1", "update"]), ) # ------------------------------------------------------------------------- # Status # ------------------------------------------------------------------------- tablename = "sync_status" define_table( tablename, Field( "running", "boolean", default=False, readable=False, writable=False, ), Field( "manual", "boolean", default=False, readable=False, writable=False, ), Field("timestmp", "datetime", readable=False, writable=False), ) # ------------------------------------------------------------------------- # Repository # ------------------------------------------------------------------------- sync_repository_types = { "adashi": "ADASHI", "ccrm": "CiviCRM", "eden": "Sahana Eden", "filesync": "Local Filesystem", "ftp": "FTP", "mcb": "Mariner CommandBridge", "wrike": "Wrike", } # Back-ends implementing passive methods (=send and/or receive) # so that they can be used for indirect, file-based synchronization sync_backend_types = { "adashi": "ADASHI", "eden": "Sahana Eden", } password_widget = S3PasswordWidget() tablename = "sync_repository" define_table( tablename, Field( "name", length=64, notnull=True, comment=DIV( _class="tooltip", _title="%s|%s" % (T("Repository Name"), T("Name of the repository (for you own reference)"))), requires=[ IS_NOT_EMPTY(), IS_LENGTH(64), ], ), Field( "apitype", default="eden", label=T("Repository Type"), represent=S3Represent(options=sync_repository_types), requires=IS_IN_SET(sync_repository_types), ), Field( "backend", default="eden", label=T("Data Format"), represent=S3Represent(options=sync_backend_types), requires=IS_IN_SET(sync_backend_types), comment=DIV( _class="tooltip", _title="%s|%s" % (T("Data Format"), T("The data format to use for data import/export"))), ), Field( "url", label="URL", requires=IS_EMPTY_OR(IS_NOT_IN_DB(db, "sync_repository.url")), comment=DIV( _class="tooltip", _title="%s|%s" % (T("Repository URL"), T("URL of the repository including application path, e.g. http://www.example.com/eden" ))), ), Field( "path", label=T("Path"), requires=IS_EMPTY_OR(IS_NOT_IN_DB(db, "sync_repository.path")), comment=DIV( _class="tooltip", _title="%s|%s" % (T("Repository Path"), T("File system location of the repository, e.g. /var/local/example" ))), ), Field( "username", comment=DIV( _class="tooltip", _title="%s|%s" % (T("Username"), T("Username to use for authentication at the remote site." ))), ), Field( "password", "password", widget=password_widget, comment=DIV( _class="tooltip", _title="%s|%s" % (T("Password"), T("Password to use for authentication at the remote site." ))), ), Field( "client_id", label=T("Client ID"), comment=DIV( _class="tooltip", _title="%s|%s" % (T("Client ID"), T("The client ID to use for authentication at the remote site (if required for this type of repository)." ))), ), Field( "client_secret", "password", label=T("Client Secret"), widget=password_widget, comment=DIV( _class="tooltip", _title="%s|%s" % (T("Client Secret"), T("The client secret to use for authentication at the remote site (if required for this type of repository)." ))), ), Field( "site_key", label=T("Site Key"), comment=DIV( _class="tooltip", _title="%s|%s" % (T("Site Key"), T("Site Key which this site uses to authenticate at the remote site (if required for this type of repository)." ))), ), Field( "refresh_token", readable=False, writable=False, ), Field( "proxy", label=T("Proxy Server URL"), requires=IS_EMPTY_OR(IS_URL(mode="generic")), comment=DIV( _class="tooltip", _title="%s|%s" % (T("Proxy Server URL"), T("URL of the proxy server to connect to the repository (leave empty for default proxy)" ))), ), Field( "last_status", label=T("Last status"), readable=False, writable=False, ), Field( "synchronise_uuids", "boolean", default=False, label=T("Synchronize UUIDs"), represent=s3_yes_no_represent, comment=DIV( _class="tooltip", _title="%s|%s" % (T("Synchronize UUIDs"), T("Allow records to be synchronized even if the remote record has a different unique identifier (UUID), and update local identifiers. Useful in active repositories when there are known duplicates in the remote database. Must be activated before the first synchronization run to take effect." ))), ), Field( "keep_source", "boolean", default=False, label=T("Keep Source Data"), represent=s3_yes_no_represent, comment=DIV( _class="tooltip", _title="%s|%s" % (T("Keep Source Data"), T("Stores the data sent from the peer in the local file system (if supported by the adapter), for testing purposes. Enable only temporarily if and when required!" ))), ), # User-visible field for Admin s3_datetime( "last_connected", label=T("Last Connected"), writable=False, ), # System fields Field.Method("last_pull_time", self.sync_repository_last_pull_time), Field.Method("last_push_time", self.sync_repository_last_push_time), *s3_meta_fields()) # CRUD Strings ADD_REPOSITORY = T("Create Repository") crud_strings[tablename] = Storage( label_create=ADD_REPOSITORY, title_display=T("Repository Configuration"), title_list=T("Repositories"), title_update=T("Edit Repository Configuration"), label_list_button=T("List Repositories"), msg_record_created=T("Repository configured"), msg_record_modified=T("Repository configuration updated"), msg_record_deleted=T("Repository configuration deleted"), msg_list_empty=T("No repositories configured")) # Resource Configuration configure( tablename, deduplicate=S3Duplicate(), list_fields=[ "name", "uuid", "last_connected", #(T("Last Pull"), "last_pull_time"), #(T("Last Push"), "last_push_time"), ], onaccept=self.sync_repository_onaccept, ondelete=self.sync_repository_ondelete, create_next=URL( c="sync", f="repository", args=["[id]", "task"], ), update_next=URL( c="sync", f="repository", args=["[id]"], ), ) set_method("sync", "repository", method="now", action=sync_now) # Reusable Fields sync_repository_represent = S3Represent(lookup=tablename) repository_id = S3ReusableField( "repository_id", "reference %s" % tablename, comment=S3PopupLink( c="sync", f="repository", label=ADD_REPOSITORY, title=ADD_REPOSITORY, tooltip=ADD_REPOSITORY, ), label=T("Repository"), represent=sync_repository_represent, requires=IS_ONE_OF( db, "sync_repository.id", "%(name)s", ), ) # Components add_components(tablename, sync_task = "repository_id", sync_log = "repository_id", #sync_conflict = "repository_id", **{# Scheduler Jobs S3Task.TASK_TABLENAME: {"name": "job", "joinby": "repository_id", "link": "sync_job", "key": "scheduler_task_id", "actuate": "replace", }, } ) # ------------------------------------------------------------------------- # Task # ------------------------------------------------------------------------- # Synchronization mode sync_mode = { 1: T("pull"), # pull only 2: T("push"), # push only 3: T("pull and push"), # pull & push 4: T("none") # do not synchronize this resource } # Strategy (allowed import methods) sync_strategy = S3ImportItem.METHOD sync_strategy_represent = lambda opt: opt and \ ", ".join([o for o in sync_strategy.values() if o in opt]) or NONE # Update method sync_update_method = { 1: T("update"), # update the existing record 2: T("replace"), # replace the existing record } # Update/conflict resolution policy sync_policies = S3ImportItem.POLICY sync_policy = { sync_policies.OTHER: T("always update"), sync_policies.NEWER: T("update if newer"), sync_policies.MASTER: T("update if master"), sync_policies.THIS: T("never update") } sync_policy_represent = lambda opt: \ opt and sync_policy.get(opt, UNKNOWN_OPT) or NONE tablename = "sync_task" define_table(tablename, repository_id(), Field("resource_name", notnull = True, label = T("Resource Name"), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Resource Name"), T("Table name of the resource to synchronize"))), requires = IS_NOT_EMPTY(), ), Field("components", "boolean", default = False, label = T("Include Components?"), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Include Components?"), T("For Eden repositories: Whether components of the resource should be included or not"))), ), Field("infile_pattern", label = T("Input File Name"), readable = False, writable = False, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Input File Name"), T("Unix shell-style pattern for the input file name, e.g. 'example*.xml'"))), ), Field("delete_input_files", "boolean", label = T("Delete Input Files?"), default = False, readable = False, writable = False, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Delete Input Files"), T("Whether to delete input files after successful import"))), ), Field("outfile_pattern", label = T("Output File Name"), readable = False, writable = False, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Output File Name"), T("The output file name. You can use place holders like 'example${minute}.xml'. Supported placeholders are: year, month, day, hour, minute, second"))), ), Field("human_readable", "boolean", label = T("Human-readable Output?"), default = False, readable = False, writable = False, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Human-readable Output"), T("Shall XML output be formatted with whitespace and line breaks so that it is more human-readable?"))), ), Field("representation", readable = False, writable = False, ), # Multiple file per sync? Field("multiple_file", "boolean", default = False, readable = False, writable = False, ), Field("last_pull", "datetime", label = T("Last pull on"), readable = True, writable = False, ), Field("last_push", "datetime", label = T("Last push on"), readable = True, writable = False, ), Field("mode", "integer", default = 3, label = T("Mode"), represent = lambda opt: \ sync_mode.get(opt, NONE), requires = IS_IN_SET(sync_mode, zero=None), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Synchronization mode"), T("How data shall be transferred"))), ), Field("strategy", "list:string", default = sync_strategy.values(), label = T("Strategy"), represent = sync_strategy_represent, requires = IS_IN_SET(sync_strategy.values(), multiple=True, zero=None), widget = CheckboxesWidgetS3.widget, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Strategy"), T("Which methods to apply when importing data to the local repository"))), ), Field("update_method", "integer", default = 1, label = T("Update Method"), represent = lambda opt: \ sync_update_method.get(opt, NONE), requires = IS_IN_SET(sync_update_method, zero=None), # hide while not implemented readable = False, writable = False, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Update Method"), T("How local records shall be updated"))), ), Field("update_policy", default = sync_policies.NEWER, label = T("Update Policy"), represent = sync_policy_represent, requires = IS_IN_SET(sync_policies, zero=None), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Update Policy"), T("Under which conditions local records shall be updated"))), ), Field("conflict_policy", default = sync_policies.NEWER, label = T("Conflict Policy"), represent = sync_policy_represent, requires = IS_IN_SET(sync_policies, zero=None), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Conflict Policy"), T("Under which condition a local record shall be updated if it also has been modified locally since the last synchronization"))), ), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Create Resource"), title_display=T("Resource Configuration"), title_list=T("Resources"), title_update=T("Edit Resource Configuration"), label_list_button=T("List Resources"), msg_record_created=T("Resource configured"), msg_record_modified=T("Resource configuration updated"), msg_record_deleted=T("Resource configuration deleted"), msg_list_empty=T("No resources configured yet")) # Resource Configuration configure( tablename, create_onvalidation=self.sync_task_onvalidation, deduplicate=S3Duplicate(primary=( "repository_id", "resource_name", )), ) # Reusable Field task_represent = self.sync_task_represent task_id = S3ReusableField( "task_id", "reference %s" % tablename, label=T("Task"), represent=task_represent, requires=IS_ONE_OF(db, "sync_task.id", task_represent), ) # Components add_components( tablename, sync_resource_filter="task_id", ) # ------------------------------------------------------------------------- # Filters # ------------------------------------------------------------------------- tablename = "sync_resource_filter" define_table( tablename, task_id(), Field( "tablename", label=T("Table"), requires=IS_NOT_EMPTY(), ), Field( "filter_string", label=T("Filter"), requires=IS_NOT_EMPTY(), ), *s3_meta_fields()) onaccept = self.sync_resource_filter_onaccept configure( tablename, list_fields=[ "id", "task_id$repository_id", "task_id$resource_name", "tablename", "filter_string", ], onaccept=onaccept, ondelete=onaccept, ) # ------------------------------------------------------------------------- # Job # ------------------------------------------------------------------------- tablename = "sync_job" define_table(tablename, repository_id(), s3.scheduler_task_id(), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Create Job"), title_display=T("Synchronization Job"), title_list=T("Synchronization Schedule"), title_update=T("Edit Job"), label_list_button=T("List Jobs"), msg_record_created=T("Job added"), msg_record_modified=T("Job updated"), msg_record_deleted=T("Job deleted"), msg_list_empty=T("No jobs configured yet"), msg_no_match=T("No jobs configured")) # Resource Configuration set_method("sync", "repository", component_name="job", method="reset", action=sync_job_reset) # ------------------------------------------------------------------------- # Log # ------------------------------------------------------------------------- tablename = "sync_log" define_table( tablename, Field( "timestmp", "datetime", label=T("Date/Time"), represent=s3_datetime_represent, ), repository_id(), Field("resource_name"), # Synchronization mode: PULL/PUSH, IN/OUT Field("mode"), Field("action"), Field("result"), Field( "remote", "boolean", default=False, label=T("Remote Error"), represent=s3_yes_no_represent, ), Field( "message", "text", represent=s3_strip_markup, ), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( title_display=T("Log Entry"), title_list=T("Synchronization Log"), label_list_button=T("List All Entries"), msg_record_deleted=T("Log Entry Deleted"), msg_list_empty=T("No entries found"), msg_no_match=T("No entries found")) # Resource Configuration configure( tablename, deletable=True, editable=False, insertable=False, orderby="sync_log.timestmp desc", ) # --------------------------------------------------------------------- # Return global names to s3.* # return dict( sync_repository_id=repository_id, sync_repository_onaccept=self.sync_repository_onaccept, )
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table add_components = self.add_components # ===================================================================== # Data Collection Template # tablename = "dc_template" define_table( tablename, Field( "name", requires=IS_NOT_EMPTY(), ), # The Dynamic Table used to store the Questions and Answers # (An alternative design would be to use Tables as reusable # Sections but this hasn't been adopted at this time for # simplicity) self.s3_table_id( readable=False, writable=False, ), s3_comments(), *s3_meta_fields()) self.configure( tablename, create_onaccept=self.dc_template_create_onaccept, ) # Reusable field represent = S3Represent(lookup=tablename) template_id = S3ReusableField( "template_id", "reference %s" % tablename, label=T("Template"), represent=represent, requires=IS_ONE_OF( db, "dc_template.id", represent, ), sortby="name", comment=S3PopupLink( f="template", tooltip=T("Add a new data collection template"), ), ) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Template"), title_display=T("Template Details"), title_list=T("Templates"), title_update=T("Edit Template"), title_upload=T("Import Templates"), label_list_button=T("List Templates"), label_delete_button=T("Delete Template"), msg_record_created=T("Template added"), msg_record_modified=T("Template updated"), msg_record_deleted=T("Template deleted"), msg_list_empty=T("No Templates currently registered")) # Components add_components( tablename, s3_field={ "name": "question", "link": "dc_template_question", "joinby": "template_id", "key": "field_id", "actuate": "replace", "autodelete": False, }, ) # ===================================================================== # Template <=> Question link table # tablename = "dc_template_question" define_table(tablename, template_id(), self.s3_field_id(), *s3_meta_fields()) # CRUD strings - unused #crud_strings[tablename] = Storage( # label_create = T("Create Question"), # title_display = T("Question Details"), # title_list = T("Questions"), # title_update = T("Edit Question"), # title_upload = T("Import Questions"), # label_list_button = T("List Questions"), # label_delete_button = T("Delete Question"), # msg_record_created = T("Question added"), # msg_record_modified = T("Question updated"), # msg_record_deleted = T("Question deleted"), # msg_list_empty = T("No Questions currently registered")) # ===================================================================== # Pass names back to global scope (s3.*) return dict(dc_template_id=template_id, )
def model(self): T = current.T db = current.db auth = current.auth s3 = current.response.s3 settings = current.deployment_settings organisation_id = self.org_organisation_id ADMIN = current.session.s3.system_roles.ADMIN is_admin = auth.s3_has_role(ADMIN) add_components = self.add_components configure = self.configure crud_strings = s3.crud_strings define_table = self.define_table root_org = auth.root_org() if is_admin: filter_opts = () elif root_org: filter_opts = (root_org, None) else: filter_opts = (None, ) types = settings.get_member_membership_types() # --------------------------------------------------------------------- # Membership Types # tablename = "member_membership_type" define_table( tablename, Field( "name", notnull=True, length=64, label=T("Name"), requires=[ IS_NOT_EMPTY(), IS_LENGTH(64), ], ), # Only included in order to be able to set # realm_entity to filter appropriately organisation_id( default=root_org, readable=is_admin, writable=is_admin, ), s3_comments( label=T("Description"), comment=None, ), *s3_meta_fields()) ADD_MEMBERSHIP_TYPE = T("Create Membership Type") crud_strings[tablename] = Storage( label_create=ADD_MEMBERSHIP_TYPE, title_display=T("Membership Type Details"), title_list=T("Membership Types"), title_update=T("Edit Membership Type"), title_upload=T("Import Membership Types"), label_list_button=T("List Membership Types"), label_delete_button=T("Delete Membership Type"), msg_record_created=T("Membership Type added"), msg_record_modified=T("Membership Type updated"), msg_record_deleted=T("Membership Type deleted"), msg_list_empty=T("No membership types currently registered")) represent = S3Represent(lookup=tablename, translate=True) membership_type_id = S3ReusableField( "membership_type_id", "reference %s" % tablename, label=T("Type"), ondelete="SET NULL", readable=types, represent=represent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "member_membership_type.id", represent, filterby="organisation_id", filter_opts=filter_opts)), sortby="name", writable=types, comment=S3PopupLink( f="membership_type", label=ADD_MEMBERSHIP_TYPE, title=ADD_MEMBERSHIP_TYPE, tooltip=T("Add a new membership type to the catalog."), ), ) configure( tablename, deduplicate=S3Duplicate( primary=( "name", "organisation_id", ), ignore_deleted=True, ), ) # --------------------------------------------------------------------- # Members # tablename = "member_membership" define_table(tablename, organisation_id( empty = False, requires = self.org_organisation_requires( updateable = True, ), ), Field("code", label = T("Member ID"), #readable = False, #writable = False, ), self.pr_person_id( comment = None, ondelete = "CASCADE", requires = IS_ADD_PERSON_WIDGET2(), widget = S3AddPersonWidget2(controller="member"), ), membership_type_id(), # History s3_date("start_date", label = T("Date Joined"), set_min = "#member_membership_end_date", ), s3_date("end_date", label = T("Date Resigned"), set_max = "#member_membership_start_date", start_field = "member_membership_start_date", default_interval = 12, ), Field("leaving_reason", label = T("Reason for Leaving"), # Enable in template as-required readable = False, writable = False, ), s3_date("restart_date", label = T("Date Rejoined"), # Enable in template as-required readable = False, set_max = "#member_membership_end_date", writable = False, ), Field("membership_fee", "double", label = T("Membership Fee"), represent = lambda v: \ IS_FLOAT_AMOUNT.represent(v, precision=2), requires = IS_EMPTY_OR( IS_FLOAT_IN_RANGE(minimum=0.0) ), ), s3_date("membership_paid", label = T("Membership Paid"), ), s3_date("membership_due", label = T("Membership Fee Due Date"), ), Field("fee_exemption", "boolean", label = T("Exempted from Membership Fee"), default = False, # Expose in templates as needed: readable = False, writable = False, ), Field("election", label = T("Participation in the Election as a"), # Expose in templates as needed: readable = False, writable = False, ), Field("trainings", label = T("Trainings"), # Expose in templates as needed: readable = False, writable = False, ), s3_comments(), # Location (from pr_address component) self.gis_location_id(readable = False, writable = False, ), Field.Method("paid", self.member_membership_paid), *s3_meta_fields()) crud_strings[tablename] = Storage( label_create=T("Create Member"), title_display=T("Member Details"), title_list=T("Members"), title_update=T("Edit Member"), title_upload=T("Import Members"), label_list_button=T("List Members"), label_delete_button=T("Delete Member"), msg_record_created=T("Member added"), msg_record_modified=T("Member updated"), msg_record_deleted=T("Member deleted"), msg_list_empty=T("No Members currently registered")) # Which levels of Hierarchy are we using? levels = current.gis.get_relevant_hierarchy_levels() list_fields = [ "person_id", "organisation_id", ] if types: list_fields.append("membership_type_id") list_fields += [ "start_date", # useful for testing the paid virtual field #"membership_paid", (T("Paid"), "paid"), (T("Email"), "email.value"), (T("Phone"), "phone.value"), ] report_fields = [ "organisation_id", "person_id", ] if types: report_fields.append("membership_type_id") default_col = "membership.membership_type_id" else: default_col = "membership.paid" report_fields.append((T("Paid"), "paid")) text_fields = [ "organisation_id$name", "organisation_id$acronym", "person_id$first_name", "person_id$middle_name", "person_id$last_name", ] if types: text_fields.append("membership_type_id") for level in levels: lfield = "location_id$%s" % level list_fields.append(lfield) report_fields.append(lfield) text_fields.append(lfield) if settings.get_org_branches(): org_filter = S3HierarchyFilter( "organisation_id", # Can be unhidden in customise_xx_resource if there is a need to use a default_filter hidden=True, leafonly=False, ) report_fields.insert(1, (settings.get_hrm_root_organisation_label(), "organisation_id$root_organisation")) else: org_filter = S3OptionsFilter( "organisation_id", filter=True, header="", # Can be unhidden in customise_xx_resource if there is a need to use a default_filter hidden=True, ) filter_widgets = [ S3TextFilter( text_fields, label=T("Search"), ), org_filter, ] if types: filter_widgets.append( S3OptionsFilter( "membership_type_id", cols=3, hidden=True, )) filter_widgets += [ S3OptionsFilter( "paid", cols=3, label=T("Paid"), options={ T("paid"): T("paid"), T("overdue"): T("overdue"), T("expired"): T("expired"), #T("exempted"): T("exempted"), }, hidden=True, ), S3LocationFilter( "location_id", label=T("Location"), levels=levels, hidden=True, ), ] report_options = Storage(rows=report_fields, cols=report_fields, facts=report_fields, defaults=Storage( cols=default_col, rows="membership.organisation_id", fact="count(membership.person_id)", totals=True, )) configure( tablename, create_next=URL(f="person", args="address", vars={"membership.id": "[id]"}), deduplicate=S3Duplicate( primary=( "person_id", "organisation_id", ), ignore_deleted=True, ), extra_fields=( "start_date", "membership_paid", "fee_exemption", ), filter_widgets=filter_widgets, list_fields=list_fields, onaccept=self.member_onaccept, report_options=report_options, # Default summary summary=[ { "name": "addform", "common": True, "widgets": [{ "method": "create" }], }, { "name": "table", "label": "Table", "widgets": [{ "method": "datatable" }] }, { "name": "report", "label": "Report", "widgets": [{ "method": "report", "ajax_init": True }] }, { "name": "map", "label": "Map", "widgets": [{ "method": "map", "ajax_init": True }], }, ], update_realm=True, ) # Components self.add_components( tablename, # Contact Information pr_contact=( # Email { "name": "email", "link": "pr_person", "joinby": "id", "key": "pe_id", "fkey": "pe_id", "pkey": "person_id", "filterby": { "contact_method": "EMAIL", }, }, # Phone { "name": "phone", "link": "pr_person", "joinby": "id", "key": "pe_id", "fkey": "pe_id", "pkey": "person_id", "filterby": { "contact_method": ( "SMS", "HOME_PHONE", "WORK_PHONE", ), }, }, ), hrm_programme={ "link": "member_membership_programme", "joinby": "membership_id", "key": "programme_id", }, ) represent = S3Represent(lookup=tablename, fields=["code"]) membership_id = S3ReusableField( "membership_id", "reference %s" % tablename, label=T("Member"), ondelete="CASCADE", represent=represent, requires=IS_ONE_OF( db, "member_membership.id", represent, ), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return dict(member_membership_id=membership_id)
def model(self): T = current.T db = current.db s3 = current.response.s3 define_table = self.define_table crud_strings = s3.crud_strings # --------------------------------------------------------------------- # Products; represent billable products or services # # TODO provide mapping per service-type product_types = { "SERVICE": T("Service"), "PHYSICAL": T("Physical Product"), "DIGITAL": T("Digital Product"), } tablename = "fin_product" define_table( tablename, # The organisation offering the product/service self.org_organisation_id(), Field( "name", label=T("Name"), requires=IS_NOT_EMPTY(), ), Field( "description", "text", label=T("Description"), ), # TODO move into link table w/service Field( "type", label=T("Type"), default="SERVICE", requires=IS_IN_SET(product_types, zero=None), ), # TODO move into link table w/service # TODO template to override default # TODO make lookup-table, provide mapping per service-type Field( "category", label=T("Category"), default="GENERAL", writable=False, ), # TODO product image # TODO product homepage s3_comments(), *s3_meta_fields()) # Components self.add_components(tablename, fin_subscription_plan="product_id", fin_product_service="product_id") # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Create Product"), title_display=T("Product Details"), title_list=T("Products"), title_update=T("Edit Product"), label_list_button=T("List Products"), label_delete_button=T("Delete Product"), msg_record_created=T("Product created"), msg_record_modified=T("Product updated"), msg_record_deleted=T("Product deleted"), msg_list_empty=T("No Products currently registered"), ) # Reusable field represent = S3Represent(lookup=tablename, show_link=True) product_id = S3ReusableField( "product_id", "reference %s" % tablename, label=T("Product"), represent=represent, requires=IS_EMPTY_OR( IS_ONE_OF( db, "%s.id" % tablename, represent, )), sortby="name", comment=S3PopupLink( c="fin", f="product", tooltip=T("Create a new product"), ), ) # --------------------------------------------------------------------- # Link product<=>service # tablename = "fin_product_service" define_table( tablename, product_id( empty=False, ondelete="CASCADE", ), self.fin_service_id( empty=False, ondelete="CASCADE", ), Field( "is_registered", "boolean", default=False, readable=False, writable=False, ), Field( "refno", label=T("Reference Number"), writable=False, ), *s3_meta_fields()) # TODO Limit service selector to services of product-org # => in product controller prep # Table configuration self.configure( tablename, editable=False, deletable=False, # TODO must retire, not delete onaccept=self.product_service_onaccept, ondelete=self.product_service_ondelete, ) # CRUD Strings crud_strings[tablename] = Storage( label_create=T("Register Product with Payment Service"), title_display=T("Registration Details"), title_list=T("Registered Payment Services"), title_update=T("Edit Registration"), label_list_button=T("List Registrations"), label_delete_button=T("Delete Registration"), msg_record_created=T("Product registered with Payment Service"), msg_record_modified=T("Registration updated"), msg_record_deleted=T("Registration deleted"), msg_list_empty=T( "Product not currently registered with any Payment Services"), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return { "fin_product_id": product_id, }
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table location_id = self.gis_location_id # ----------------------------------------------------------- # Water Zone Types # tablename = "water_zone_type" define_table(tablename, Field( "name", label=T("Name"), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE_TYPE = T("Create Zone Type") crud_strings[tablename] = Storage( label_create=ADD_ZONE_TYPE, title_display=T("Zone Type Details"), title_list=T("Zone Types"), title_update=T("Edit Zone Type"), title_upload=T("Import Zone Types"), label_list_button=T("List Zone Types"), label_delete_button=T("Delete Zone Type"), msg_record_created=T("Zone Type added"), msg_record_modified=T("Zone Type updated"), msg_record_deleted=T("Zone Type deleted"), msg_list_empty=T("No Zone Types currently registered")) zone_type_represent = S3Represent(lookup=tablename) self.configure( tablename, deduplicate=S3Duplicate(), ) # ----------------------------------------------------------- # Water Zones # - e.g. Floods # tablename = "water_zone" define_table( tablename, Field( "name", label=T("Name"), ), Field( "zone_type_id", db.water_zone_type, label=T("Type"), represent=zone_type_represent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "water_zone_type.id", zone_type_represent, sort=True)), comment=S3PopupLink( c="water", f="zone_type", label=ADD_ZONE_TYPE, tooltip= T("Select a Zone Type from the list or click 'Add Zone Type'" ), ), ), location_id(widget=S3LocationSelector( catalog_layers=True, points=False, polygons=True, ), ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Create Zone"), title_display=T("Zone Details"), title_list=T("Zones"), title_update=T("Edit Zone"), title_upload=T("Import Zones"), label_list_button=T("List Zones"), label_delete_button=T("Delete Zone"), msg_record_created=T("Zone added"), msg_record_modified=T("Zone updated"), msg_record_deleted=T("Zone deleted"), msg_list_empty=T("No Zones currently registered")) # ----------------------------------------------------------------------------- # Rivers tablename = "water_river" define_table( tablename, Field( "name", label=T("Name"), requires=IS_NOT_EMPTY(), ), location_id(widget=S3LocationSelector( catalog_layers=True, points=False, polygons=True, )), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_RIVER = T("Create River") crud_strings[tablename] = Storage( label_create=ADD_RIVER, title_display=T("River Details"), title_list=T("Rivers"), title_update=T("Edit River"), label_list_button=T("List Rivers"), msg_record_created=T("River added"), msg_record_modified=T("River updated"), msg_record_deleted=T("River deleted"), msg_list_empty=T("No Rivers currently registered")) #represent = S3Represent(lookup = tablename) #river_id = S3ReusableField("river_id", "reference %s" % tablename, # label = T("River"), # ondelete = "RESTRICT", # represent = represent, # requires = IS_EMPTY_OR(IS_ONE_OF(db, "water_river.id", represent)), # comment = S3PopupLink(c = "water", # f = "river", # title = ADD_RIVER, # ), # ) # ----------------------------------------------------------------------------- # Gauges # # @ToDo: Link together ones on same river with upstream/downstream relationships # flowstatus_opts = { 1: T("Normal"), 2: T("High"), 3: T("Very High"), 4: T("Low") } tablename = "water_gauge" define_table(tablename, Field("name", label = T("Name"), ), Field("code", label = T("Code"), ), #super_link("source_id", "doc_source_entity"), location_id(), Field("url", label = T("URL"), represent = lambda url: \ A(url, _href=url, _target="blank"), requires = IS_EMPTY_OR(IS_URL()), ), Field("image_url", label = T("Image URL"), ), Field("discharge", "integer", label = T("Discharge (cusecs)"), ), Field("status", "integer", label = T("Flow Status"), represent = lambda opt: \ flowstatus_opts.get(opt, opt), requires = IS_EMPTY_OR(IS_IN_SET(flowstatus_opts)), ), s3_comments(), *s3_meta_fields()) crud_strings[tablename] = Storage( label_create=T("Create Gauge"), title_display=T("Gauge Details"), title_list=T("Gauges"), title_update=T("Edit Gauge"), title_map=T("Map of Gauges"), label_list_button=T("List Gauges"), msg_record_created=T("Gauge added"), msg_record_modified=T("Gauge updated"), msg_record_deleted=T("Gauge deleted"), msg_list_empty=T("No Gauges currently registered")) # ----------------------------------------------------------------------------- # Debris Basins # http://dpw.lacounty.gov/wrd/sediment/why_move_dirt.cfm # #tablename = "water_debris_basin" #define_table(tablename, # Field("name", # label = T("Name"), # ), # location_id(), # s3_comments(), # *s3_meta_fields()) #crud_strings[tablename] = Storage( # label_create = T("Create Debris Basin"), # title_display = T("Debris Basin Details"), # title_list = T("Debris Basins"), # title_update = T("Edit Debris Basin"), # title_map = T("Map of Debris Basins"), # label_list_button = T("List Debris Basins"), # msg_record_created = T("Debris Basin added"), # msg_record_modified = T("Debris Basin updated"), # msg_record_deleted = T("Debris Basin deleted"), # msg_list_empty = T("No Debris Basins currently registered")) # ----------------------------------------------------------------------------- # Reservoirs # Water Storage areas # #tablename = "water_reservoir" #define_table(tablename, # Field("name", # label = T("Name"), # ), # location_id(), # s3_comments(), # *s3_meta_fields()) #crud_strings[tablename] = Storage( # label_create = T("Create Reservoir"), # title_display = T("Reservoir Details"), # title_list = T("Reservoirs"), # title_update = T("Edit Reservoir"), # title_map = T("Map of Reservoirs"), # label_list_button = T("List Reservoirs"), # msg_record_created = T("Reservoir added"), # msg_record_modified = T("Reservoir updated"), # msg_record_deleted = T("Reservoir deleted"), # msg_list_empty = T("No Reservoirs currently registered")) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return {}
def _manage_subscriptions(self, resources, filters): """ Custom form to manage subscriptions @param resources: available resources config @param filters: filter widgets """ # Uses Default Eden formstyle from s3theme import formstyle_foundation as formstyle from gluon.validators import IS_IN_SET from s3.s3widgets import S3GroupedOptionsWidget, S3MultiSelectWidget from s3layouts import S3PopupLink # L10n T = current.T db = current.db s3db = current.s3db response = current.response labels = Storage( #RESOURCES = T("Subscribe To"), #NOTIFY_ON = T("Notify On"), #FREQUENCY = T("Frequency"), NOTIFY_BY = T("Notify By"), #MORE = T("More Options"), #LESS = T("Less Options"), ) messages = Storage( ERROR = T("Error: could not update notification settings"), SUCCESS = T("Notification settings updated"), ) # Get current subscription settings resp. form defaults subscription = self._get_subscription() # Initialize form form = FORM(_id="subscription-form", hidden={"subscription-filters": ""}) # Filters filter_form = S3FilterForm(filters, clear=False) fieldset = FIELDSET(filter_form.fields(None, subscription["get_vars"]), _id="subscription-filter-form") form.append(fieldset) # Notification options rows = [] stable = s3db.pr_subscription selector = S3GroupedOptionsWidget(cols=1) # Deactivated trigger selector #rows.append(("trigger_selector__row", # "%s:" % labels.NOTIFY_ON, # selector(stable.notify_on, # subscription["notify_on"], # _id="trigger_selector"), # "")) #switch = S3GroupedOptionsWidget(cols=1, multiple=False, sort=False) # Deactivated: frequency selector #rows.append(("frequency_selector__row", # "%s:" % labels.FREQUENCY, # switch(stable.frequency, # subscription["frequency"], # _id="frequency_selector"), # "")) methods = [("EMAIL", T("Email")), ("SMS", T("SMS")), ("Sync", T("FTP")), ] method_options = Storage(name = "method", requires = IS_IN_SET(methods)) rows.append(("method_selector__row", "%s:" % labels.NOTIFY_BY, selector(method_options, subscription["method"], _id="method_selector"), "")) # Sync Row properties = subscription["comments"] if properties: properties = json.loads(properties) synctable = s3db.sync_repository query = (synctable.apitype == "ftp") & \ (synctable.deleted != True) & \ (synctable.owned_by_user == current.auth.user.id) ftp_rows = db(query).select(synctable.id, synctable.name, orderby = synctable.id) multiselect = S3MultiSelectWidget(header = False, multiple = False, create = {"c": "sync", "f": "repository", "label": "Create Repository", }, ) if ftp_rows: if properties: user_repository_id = properties["repository_id"] else: user_repository_id = ftp_rows.first().id if current.auth.s3_has_permission("update", "sync_repository", record_id = user_repository_id): repository_comment = S3PopupLink(c = "sync", f = "repository", m = "update", args = [user_repository_id], title = T("Update Repository"), tooltip = T("You can edit your FTP repository here"), ) field = s3db.sync_task.repository_id ftp_ids = [(r.id, T(r.name)) for r in ftp_rows] field.requires = IS_IN_SET(ftp_ids) rows.append(("sync_task_repository_id__row", "", multiselect(field, user_repository_id, _id="sync_task_repository_id"), repository_comment)) else: if current.auth.s3_has_permission("create", "sync_repository"): repository_comment = S3PopupLink(c = "sync", f = "repository", title = T("Create Repository"), tooltip = T("Click on the link to begin creating your FTP repository"), ) rows.append(("sync_task_repository_id__row", "", "", repository_comment)) parent = FIELDSET() for row in rows: parent.append(formstyle(form, [row])) # Deactivated Toggle #parent.insert(0, # DIV(SPAN([I(_class="icon-reorder"), labels.MORE], # _class="toggle-text", # _style="display:none"), # SPAN([I(_class="icon-reorder"), labels.LESS], # _class="toggle-text"), # _id="notification-options", # _class="control-group")) form.append(parent) # Submit button submit_fieldset = FIELDSET(DIV("", INPUT(_type="submit", _value="Update Settings"), _id = "submit__row")) form.append(submit_fieldset) # Script (to extract filters on submit and toggle options visibility) script = URL(c="static", f="scripts", args=["S3", "s3.subscriptions.js"]) response.s3.scripts.append(script) # Script to show/hide the ftp repo row for FTP checkbox on/off repository_script = ''' if($('#method_selector option[value=Sync]').is(':selected')){ $('#sync_task_repository_id__row').show(); } else { $('#sync_task_repository_id__row').hide(); } $('#method_selector').change(function(){ if($(this).val().indexOf('Sync') != -1){ $('#sync_task_repository_id__row').show(); } else { $('#sync_task_repository_id__row').hide(); } }) ''' response.s3.jquery_ready.append(repository_script) # Accept form if form.accepts(current.request.post_vars, current.session, formname="subscription", keepvalues=True): formvars = form.vars listify = lambda x: None if not x else x if type(x) is list else [x] # Fixed resource selection: subscription["subscribe"] = [resources[0]] # Alternatively, with resource selector: #subscribe = listify(formvars.resources) #if subscribe: #subscription["subscribe"] = \ #[r for idx, r in enumerate(resources) #if str(idx) in subscribe] subscription["filters"] = form.request_vars \ .get("subscription-filters", None) # Fixed method subscription["method"] = formvars.method # Fixed Notify On and Frequency subscription["notify_on"] = ["new"] subscription["frequency"] = "immediately" # Alternatively, with notify and frequency selector #subscription["notify_on"] = listify(formvars.notify_on #subscription["frequency"] = formvars.frequency success_subscription = self._update_subscription(subscription) if "Sync" in subscription["method"] and formvars.repository_id: properties = self._update_sync(subscription["subscribe"][0]['resource'], subscription.get("filters"), int(formvars.repository_id), properties) properties = json.dumps(properties) db(stable.pe_id == current.auth.user.pe_id).update(comments=properties) else: self._remove_sync(properties) db(stable.pe_id == current.auth.user.pe_id).update(comments=None) if success_subscription: response.confirmation = messages.SUCCESS else: response.error = messages.ERROR return form