def informe_mes_empleado(): empleados = db(db.empleado.is_active is True).select(db.empleado.ALL) fempl = ([" "] + [f"{p.user_code} {p.nombre} {p.apellido}" for p in empleados]) form = FORM( CENTER( H4('Marcadas del personal'), TABLE( TR( TAG('<label class "control-label">Persona</label>'), SELECT(fempl, _name='fempleado', _type='text', _id="persona", _class="form-control string")), TR( TAG('<label class "control-label">Periodo desde</label>'), INPUT(_name='fdesde', _type='date', _id="mesanio", _class="form-control string", requires=IS_NOT_EMPTY())), TR( TAG('<label class "control-label">Periodo hasta</label>'), INPUT( _name='fhasta', _type='date', _id="mesanio", _class="form-control string", ))), BR(), INPUT(_type="submit", _class="btn btn-primary btn-medium", _value='Continuar'))) if form.accepts(request, session): session.empleado = request.vars['fempleado'] session.user_code = request.vars['fempleado'].split()[0] session.fdesde = request.vars['fdesde'] session.fhasta = request.vars['fhasta'] log(f"seleccionado {session.empleado}") log(f"desde: {session.fdesde} hasta {session.fhasta}") # selector = (db.empleado.user_code == user_code) # usuario = db(selector).select().first().as_dict() session.tdesde = datetime.datetime.strptime(session.fdesde, '%Y-%m-%d') session.thasta = datetime.datetime.strptime(session.fhasta, '%Y-%m-%d') lista = aplico_politica(session.user_code, session.fdesde, session.fhasta) nombre_archivo = f'''{session.empleado} -{session.fdesde}-{session.fhasta}''' session.table = list_dict_to_table_sortable(lista, nombre_archivo) redirect(URL('informe')) else: log(f'acceso {request.function}') return dict(form=form)
def subject_widget(field, value, **attr): """ Widget to edit and preview a notification subject line @param field: the Field @param value: the current field value @param attr: DOM attributes for the widget """ widget_id = attr.get("_id") if not widget_id: widget_id = "%s_%s" % (field._tablename, field.name) edit = INPUT(_name=attr.get("_name", field.name), _id=widget_id, _type="text", _class="subject %s" % (field.type), _placeholder=attr.get("_placeholder"), _style="display:none", value=value, requires=field.requires) preview = H6("", _class="preview") return DIV(preview, edit, _class="preview-widget")
def selector(rules): """ Generate the rule selector for anonymize-form @param rules: the list of configured rules @return: the selector (DIV) """ T = current.T selector = DIV(_class="anonymize-select", ) for rule in rules: name = rule.get("name") if not name: continue title = T(rule.get("title", name)) selector.append( DIV( INPUT( value="on", _name=s3_str(name), _type="checkbox", _class="anonymize-rule", ), LABEL(title), _class="anonymize-option", )) return selector
def html(self, widget_id=None, formkey=None): """ Render the organizer container and instantiate the UI widget @param widget_id: the container's DOM ID """ T = current.T settings = current.deployment_settings if not widget_id: widget_id = "organizer" # Parse resource configuration resources = self.resources if not isinstance(resources, (list, tuple)): resources = [resources] resource_configs = [] use_time = False for resource_config in resources: resource_use_time = resource_config.get("useTime") if resource_use_time: use_time = True resource_configs.append(resource_config) # Inject script and widget instantiation script_opts = {"resources": resource_configs, "useTime": use_time, "labelEdit": s3_str(T("Edit")), "labelDelete": s3_str(T("Delete")), "deleteConfirmation": s3_str(T("Do you want to delete this entry?")), "firstDay": settings.get_L10n_firstDOW(), } # Options from settings bhours = settings.get_ui_organizer_business_hours() if bhours: script_opts["businessHours"] = bhours tformat = settings.get_ui_organizer_time_format() if tformat: script_opts["timeFormat"] = tformat self.inject_script(widget_id, script_opts) # Add a datepicker to navigate to arbitrary dates picker = S3DateWidget()(Storage(name="date_select"), None, _type="hidden", _id="%s-date-picker" % widget_id, ) # Generate and return the HTML for the widget container return DIV(INPUT(_name = "_formkey", _type = "hidden", _value = str(formkey) if formkey else "", ), picker, _id = widget_id, _class = "s3-organizer", )
def _render_tag_input_upload(self, label, controls, help): row = DIV(_class='file-field input-field col s12') btn = DIV(_class='btn') label.tag = 'SPAN' self._append_basic_field(btn, controls, label, help) # reverse label and controls row.append(btn) row.append(DIV(INPUT(_class='file-path validate', _type='text'), _class='file-path-wrapper')) return row
def widget(cls, field, value, **attributes): """ Simple and best way to do radio boxes and/or checkboxes """ if isinstance(value, (list, tuple)): value = str(value[0]) else: value = str(value) attr = cls._attributes(field, {}, **attributes) attr['_class'] = add_class(attr.get('_class'), 'radio-widget') # attr['_class'] = 'row' requires = field.requires if not isinstance(requires, (list, tuple)): requires = [requires] if requires: if hasattr(requires[0], 'options'): options = requires[0].options() else: raise SyntaxError('widget cannot determine options of %s' % field) _type = 'checkbox' if getattr(requires[0], 'multiple') else 'radio' options = [(k, v) for k, v in options if str(v)] opts = [] cols = attributes.get('cols', 1) totals = len(options) mods = totals % cols rows = totals / cols if mods: rows += 1 parent, child, inner = DIV, DIV, P for r_index in range(rows): tds = [] for k, v in options[r_index * cols:(r_index + 1) * cols]: checked = {'_checked': 'checked'} if k == value else {} tds.append( inner(INPUT(_type=_type, _id='%s%s' % (field.name, k), _name=field.name, requires=attr.get('requires', None), hideerror=True, _value=k, value=value, **checked), LABEL(v, _for='%s%s' % (field.name, k)), _class="col s12 m%s" % (12 / cols))) opts.append(child(tds, _class='row')) if opts: opts[-1][0][0]['hideerror'] = False if len(opts) == 1: opts[0].attributes.update(attr) return opts[0] return parent(*opts, **attr)
def get_html(self): card_content = DIV(FORM( INPUT(_type="text", _name="q", _placeholder="Type some tag...", _autocomplete="off"), INPUT(_type="submit", _value="Search", _class="btn btn-default"), _action=URL("problems", "search"), _method="GET", _class="col offset-s1 s10 search-by-tag-card-submit"), _class="row") card_html = BaseCard.get_html( self, **dict(card_title=self.card_title, card_content=card_content, cta_links=self.get_cta_html(), card_color_class="white", card_text_color_class="black-text")) return card_html
def _render_tag_div(self, label, controls, help): row = DIV(_class='col s12') label.tag = 'SPAN' row.append(DIV( DIV(label, controls[0], _class='btn'), DIV(INPUT(_class='file-path validate', _type='text'), _class='file-path-wrapper'), _class='file-field input-field' )) row.append(A(controls[3], _href=controls[1][1]['_href'])) row.append(DIV( P(LABEL(controls[1][3], SPAN(controls[1][4][0]))) )) return row
def search(self): q = self.request.vars.q or None self.context.form = FORM(INPUT(_type="text", _name="q", _id="q", _value=q or ''), _method="GET") if q: query = (self.db.Article.search_index.like("%" + q + "%")) | ( self.db.Article.tags.contains(q)) self.context.results = self.db(query).select() else: self.context.results = []
def widget(cls, field, value, **attributes): """ Turn me on. lol! (or off) """ _id = str(field).replace('.', '_') attributes['_type'] = 'checkbox' return DIV(P(LABEL( 'Off', INPUT(_id=_id, _name=field.name, requires=field.requires, value=value, **attributes), SPAN(_class='lever'), 'On', _for=_id, ), _style='padding:20px'), _class='switch')
def checkbox_item(item): """ Render special active items """ name = item.label link = item.url() _id = name["id"] if "name" in name: _name = name["name"] else: _name = "" if "value" in name: _value = name["value"] else: _value = False if "request_type" in name: _request_type = name["request_type"] else: _request_type = "ajax" if link: if _request_type == "ajax": _onchange='''var val=$('#%s:checked').length;$.getS3('%s'+'?val='+val,null,false,null,false,false)''' % \ (_id, link) else: # Just load the page. Use this if the changed menu # item should alter the contents of the page, and # it's simpler just to load it. _onchange = "location.href='%s'" % link else: _onchange = None return LI( A( INPUT( _type="checkbox", _id=_id, _onchange=_onchange, value=_value, ), "%s" % _name, _nowrap="nowrap", ), _class="menu-toggle", )
def formstyle_materialize(form, fields, *args, **kwargs): """ divs only """ if not getattr(form, 'tag', None) == 'form': return DIV(form, fields, *args, **kwargs) form['_class'] = form['_class'] or 'col' form['_class'] = ' '.join(set(['col', 's12'] + form['_class'].split(' '))) table = DIV(_class="row") for id, label, controls, help in fields: _input_field = DIV(_class="input-field col s12") if help: _input_field.add_class('tooltipped') _input_field['_data-tooltip'] = help if getattr(controls, 'tag', None) == 'textarea': controls['_class'] += ' materialize-textarea' if controls['_type'] == 'file': _input_field['_class'] = 'file-field col s12 input-field' _input_field.append( DIV( SPAN(label[0]), controls, _class='btn')) _input_field.append( DIV( INPUT( _class='file-path validate', _readonly = '', _type='text'), _class='file-path-wrapper')) table.append(_input_field) continue if controls['_type'] == 'submit': controls.tag = 'button' controls.components.append(I('send', _class=('material-icons right'))) controls.components.append(controls['_value']) del controls['_value'] controls['_name'] = 'action' controls.add_class('btn right') _input_field.append(controls) _input_field.append(label) table.append(_input_field) return table
def getEditgameBtn(game, user): """ Gets a dictionary of buttons that do stuff for the edit game page. Keyword Arguments: game -- row representing the current game user -- row representing the current user Return Values: btn -- dictionary of web2py forms -- 'back' Back To Game -- 'delete' Delete Game """ from gluon import URL, INPUT, FORM, A, redirect btn = {'back': 'back', 'delete': 'delete'} link = A('Back to Game', _class='btn btn-large btn-inverse btn-block', _href=URL('default', 'game', args=game.id)) btn['back'] = link button = INPUT( _type='submit', _value='(Host) Delete Game', _class='btn btn-small btn-block abtn-small', _onclick= 'return confirm(\'Are you sure you want to delete this game?\');') formDelete = FORM(button) btn['delete'] = formDelete if btn['delete'].process().accepted: deleteGame(game.id, user) redirect(URL('default', 'current')) return btn
def apply_method(r, **attr): """ Apply method. @param r: the S3Request @param attr: controller options for this request """ if r.representation == "html": T = current.T s3db = current.s3db response = current.response table = r.table tracker = S3Trackable(table, record_id=r.id) title = T("Check-In") get_vars = r.get_vars # Are we being passed a location_id? location_id = get_vars.get("location_id", None) if not location_id: # Are we being passed a lat and lon? lat = get_vars.get("lat", None) if lat is not None: lon = get_vars.get("lon", None) if lon is not None: form_vars = Storage( lat=float(lat), lon=float(lon), ) form = Storage(vars=form_vars) s3db.gis_location_onvalidation(form) location_id = s3db.gis_location.insert(**form_vars) form = None if not location_id: # Give the user a form to check-in # Test the formstyle formstyle = current.deployment_settings.get_ui_formstyle() row = formstyle("test", "test", "test", "test") if isinstance(row, tuple): # Formstyle with separate row for label (e.g. default Eden formstyle) tuple_rows = True else: # Formstyle with just a single row (e.g. Bootstrap, Foundation or DRRPP) tuple_rows = False form_rows = [] comment = "" _id = "location_id" label = LABEL("%s:" % T("Location")) from .s3widgets import S3LocationSelector field = table.location_id #value = tracker.get_location(_fields=["id"], # as_rows=True).first().id value = None # We always want to create a new Location, not update the existing one widget = S3LocationSelector(show_latlon=True)(field, value) row = formstyle("%s__row" % _id, label, widget, comment) if tuple_rows: form_rows.append(row[0]) form_rows.append(row[1]) else: form_rows.append(row) _id = "submit" label = "" widget = INPUT(_type="submit", _value=T("Check-In")) row = formstyle("%s__row" % _id, label, widget, comment) if tuple_rows: form_rows.append(row[0]) form_rows.append(row[1]) else: form_rows.append(row) if tuple_rows: # Assume TRs form = FORM(TABLE(*form_rows)) else: form = FORM(*form_rows) if form.accepts(current.request.vars, current.session): location_id = form.vars.get("location_id", None) if location_id: # We're not Checking-in in S3Track terms (that's about interlocking with another object) #tracker.check_in() #timestmp = form.vars.get("timestmp", None) #if timestmp: # # @ToDo: Convert from string # pass #tracker.set_location(location_id, timestmp=timestmp) tracker.set_location(location_id) response.confirmation = T("Checked-In successfully!") response.view = "check-in.html" output = dict( form=form, title=title, ) return output # @ToDo: JSON representation for check-in from mobile devices else: raise HTTP(415, current.ERROR.BAD_FORMAT)
def apply_method(r, **attr): """ Apply method. @param r: the S3Request @param attr: controller options for this request """ if r.representation == "html": T = current.T response = current.response tracker = S3Trackable(r.table, record_id=r.id) title = T("Check-Out") # Give the user a form to check-out # Test the formstyle formstyle = current.deployment_settings.get_ui_formstyle() row = formstyle("test", "test", "test", "test") if isinstance(row, tuple): # Formstyle with separate row for label (e.g. default Eden formstyle) tuple_rows = True else: # Formstyle with just a single row (e.g. Bootstrap, Foundation or DRRPP) tuple_rows = False form_rows = [] comment = "" _id = "submit" label = "" widget = INPUT(_type="submit", _value=T("Check-Out")) row = formstyle("%s__row" % _id, label, widget, comment) if tuple_rows: form_rows.append(row[0]) form_rows.append(row[1]) else: form_rows.append(row) if tuple_rows: # Assume TRs form = FORM(TABLE(*form_rows)) else: form = FORM(*form_rows) if form.accepts(current.request.vars, current.session): # Check-Out # We're not Checking-out in S3Track terms (that's about removing an interlock with another object) # What we're doing is saying that we're now back at our base location #tracker.check_out() #timestmp = form_vars.get("timestmp", None) #if timestmp: # # @ToDo: Convert from string # pass #tracker.set_location(r.record.location_id, timestmp=timestmp) tracker.set_location(r.record.location_id) response.confirmation = T("Checked-Out successfully!") response.view = "check-in.html" output = dict( form=form, title=title, ) return output # @ToDo: JSON representation for check-out from mobile devices else: raise HTTP(415, current.ERROR.BAD_FORMAT)
def __call__(self, field, value, **attributes): """ Widget renderer for the input field; to be set as widget=self for the field returned by the resolve()-method. @param field: the input field @param value: the value to populate the widget @param attributes: attributes for the widget @return: the widget for this form element as HTML helper """ T = current.T settings = current.deployment_settings # Check current value if isinstance(value, str): try: value = json.loads(value) if value else {} except JSONERRORS: value = {} elif not value: value = {} delegation_id = value.get("delegationID") if value else None # Form name and widget ID formname = self._formname() widget_id = attributes.get("_id") if not widget_id: widget_id = str(field).replace(".", "_") # Ajax parameters if delegation_id: ajax_args = [delegation_id, "notifications.json"] ajax_vars = {} else: ajax_args = ["notifications.json"] dtable = current.s3db.hrm_delegation person_id = dtable.person_id.default ajax_vars = { "viewing": "pr_person.%s" % person_id } if person_id else {} # Sender and recipient types sender = self.options.get("sender") if sender: ajax_vars["sender"] = sender notifications = DeploymentNotifications(delegation_id, sender=sender) recipients = list(notifications.recipients.keys()) # Selectable organisations organisations = self.options.get("organisations") # Inject script options = { "ajaxURL": URL( c="hrm", f="delegation", args=ajax_args, vars=ajax_vars, ), "formName": formname, "recipients": recipients, "organisations": organisations, } self.inject_js(widget_id, options) # The widget widget = DIV( INPUT( _type="hidden", _name=field.name, _value=json.dumps(value), _class="notification-data", ), _id=widget_id, ) # Add field set per recipient type labels = { "organisation": T("Requesting Organisation"), "volunteer": T("Volunteer"), "office": T("Office##gov"), } formstyle = settings.get_ui_formstyle() for recipient in recipients: input_name = "%s_%s" % (formname, recipient) formfields = [ Field( "%s_email" % input_name, label=T("Email"), ), Field( "%s_subject" % input_name, label=T("Subject"), widget=self.subject_widget, ), Field( "%s_message" % input_name, "text", label=T("Message"), widget=self.message_widget, ), ] form = SQLFORM.factory(record=None, showid=False, formstyle=formstyle, buttons=[], table_name="sub", *formfields) toggle_name = "%s_notify_%s" % (formname, recipient) toggle_edit = DIV( A( T("Preview"), _class="preview-toggle action-lnk", _style="display:none", ), A( T("Edit"), _class="preview-toggle action-lnk", ), _class="preview-toggles", ) subform = DIV( FIELDSET( LEGEND( LABEL( INPUT( _type="checkbox", _class="notify-toggle", value=True, _name=toggle_name, _id=toggle_name, ), labels.get(recipient, "?"), ), ), form[0], toggle_edit, ), _class="notification", ) widget.append(subform) return widget
def materialize_form(form, fields): """ Change layout of SQLFORM forms """ form.add_class("form-horizontal center") main_div = DIV(_class="center") for field_id, label, controls, field_help in fields: curr_div = DIV(_class="row") input_field = None _controls = controls try: _name = controls.attributes["_name"] except: _name = "" try: _type = controls.attributes["_type"] except: _type = "string" try: _id = controls.attributes["_id"] except: _id = "" if isinstance(controls, INPUT): if _type == "file": # Layout for file type inputs input_field = DIV( DIV(SPAN("Upload"), INPUT(_type=_type, _id=_id), _class="btn"), DIV(INPUT(_type="text", _class="file-path", _placeholder=label.components[0]), _class="file-path-wrapper"), _class="col input-field file-field offset-s3 s6") if isinstance(controls, SPAN): # Mostly for ids which cannot be edited by user _controls = INPUT(_value=controls.components[0], _id=_id, _name=_name, _disabled="disabled") elif isinstance(controls, TEXTAREA): # Textarea inputs try: _controls = TEXTAREA(controls.components[0], _name=_name, _id=_id, _class="materialize-textarea text") except IndexError: _controls = TEXTAREA(_name=_name, _id=_id, _class="materialize-textarea text") elif isinstance(controls, SELECT): # Select inputs _controls = SELECT(OPTION(label, _value=""), _name=_name, _class="browser-default", *controls.components[1:]) # Note now label will be the first element # of Select input whose value would be "" label = "" elif isinstance(controls, A): # For the links in the bottom while updating tables like auth_user label = "" elif isinstance(controls, INPUT) is False: # If the values are readonly _controls = INPUT(_value=controls, _name=_name, _disabled="") if input_field is None: input_field = DIV(_controls, label, _class="input-field col offset-s3 s6") curr_div.append(input_field) main_div.append(curr_div) return main_div
def register(self, r, **attr): """ Register a test result @param r: the S3Request instance @param attr: controller attributes """ if r.http not in ("GET", "POST"): r.error(405, current.ERROR.BAD_METHOD) if not r.interactive: r.error(415, current.ERROR.BAD_FORMAT) T = current.T db = current.db s3db = current.s3db auth = current.auth request = current.request response = current.response s3 = response.s3 settings = current.deployment_settings # Page title and intro text title = T("Register Test Result") # Get intro text from CMS ctable = s3db.cms_post ltable = s3db.cms_post_module join = ltable.on((ltable.post_id == ctable.id) & \ (ltable.module == "disease") & \ (ltable.resource == "case_diagnostics") & \ (ltable.deleted == False)) query = (ctable.name == "TestResultRegistrationIntro") & \ (ctable.deleted == False) row = db(query).select( ctable.body, join=join, cache=s3db.cache, limitby=(0, 1), ).first() intro = row.body if row else None # Instantiate Consent Tracker consent = s3db.auth_Consent( processing_types=["CWA_ANONYMOUS", "CWA_PERSONAL"]) table = s3db.disease_case_diagnostics # Configure disease_id field = table.disease_id if field.writable: default_disease = None offset = 1 else: default_disease = field.default field.readable = False offset = 0 # Probe date is mandatory field = table.probe_date requires = field.requires if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # Configure device_id field = table.device_id field.readable = field.writable = True dtable = s3db.disease_testing_device query = (dtable.device_class == "RAT") & \ (dtable.approved == True) & \ (dtable.available == True) if default_disease: query = (dtable.disease_id == default_disease) & query field.requires = IS_ONE_OF( db(query), "disease_testing_device.id", field.represent, ) cwa_options = ( ("NO", T("Do not report")), ("ANONYMOUS", T("Issue anonymous contact tracing code")), ("PERSONAL", T("Issue personal test certificate")), ) formfields = [ # -- Test Result -- table.site_id, table.disease_id, table.probe_date, table.device_id, table.result, # -- Report to CWA -- Field( "report_to_cwa", "string", requires=IS_IN_SET(cwa_options, sort=False, zero=""), default="NO", label=T("Report test result to %(system)s") % CWA, ), Field( "last_name", label=T("Last Name"), ), Field( "first_name", label=T("First Name"), ), s3_date( "date_of_birth", label=T("Date of Birth"), month_selector=True, ), Field( "dcc_option", "boolean", default=False, label=T("Provide Digital %(title)s Certificate") % {"title": "COVID-19 Test"}, ), Field( "consent", label="", widget=consent.widget, ), ] # Required fields required_fields = [] # Subheadings subheadings = ( (0, T("Test Result")), (4 + offset, CWA["system"]), ) # Generate labels (and mark required fields in the process) labels, has_required = s3_mark_required( formfields, mark_required=required_fields, ) s3.has_required = has_required # Form buttons REGISTER = T("Submit") buttons = [ INPUT( _type="submit", _value=REGISTER, ), ] # Construct the form response.form_label_separator = "" form = SQLFORM.factory(table_name="test_result", record=None, hidden={"_next": request.vars._next}, labels=labels, separator="", showid=False, submit_button=REGISTER, delete_label=auth.messages.delete_label, formstyle=settings.get_ui_formstyle(), buttons=buttons, *formfields) # Identify form for CSS & JS Validation form.add_class("result-register") # Add Subheadings if subheadings: for pos, heading in subheadings[::-1]: form[0].insert(pos, DIV(heading, _class="subheading")) # Inject scripts script = "/%s/static/themes/RLP/js/testresult.js" % r.application if script not in s3.scripts: s3.scripts.append(script) s3.jquery_ready.append("S3EnableNavigateAwayConfirm()") if form.accepts( request.vars, current.session, formname="register", onvalidation=self.validate, ): formvars = form.vars # Create disease_case_diagnostics record testresult = { "result": formvars.get("result"), } if "site_id" in formvars: testresult["site_id"] = formvars["site_id"] if "disease_id" in formvars: testresult["disease_id"] = formvars["disease_id"] if "probe_date" in formvars: testresult["probe_date"] = formvars["probe_date"] if "device_id" in formvars: testresult["device_id"] = formvars["device_id"] record_id = table.insert(**testresult) if not record_id: raise RuntimeError("Could not create testresult record") testresult["id"] = record_id # Set record owner auth = current.auth auth.s3_set_record_owner(table, record_id) auth.s3_make_session_owner(table, record_id) # Onaccept s3db.onaccept(table, testresult, method="create") response.confirmation = T("Test Result registered") report_to_cwa = formvars.get("report_to_cwa") if report_to_cwa == "NO": # Do not report to CWA, just forward to read view self.next = r.url(id=record_id, method="read") else: # Report to CWA and show test certificate dcc_option = False if report_to_cwa == "ANONYMOUS": processing_type = "CWA_ANONYMOUS" cwa_report = CWAReport(record_id) elif report_to_cwa == "PERSONAL": dcc_option = formvars.get("dcc_option") processing_type = "CWA_PERSONAL" cwa_report = CWAReport( record_id, anonymous=False, first_name=formvars.get("first_name"), last_name=formvars.get("last_name"), dob=formvars.get("date_of_birth"), dcc=dcc_option, ) else: processing_type = cwa_report = None if cwa_report: # Register consent if processing_type: cwa_report.register_consent( processing_type, formvars.get("consent"), ) # Send to CWA success = cwa_report.send() if success: response.information = T( "Result reported to %(system)s") % CWA retry = False else: response.error = T("Report to %(system)s failed") % CWA retry = True # Store DCC data if dcc_option: cwa_data = cwa_report.data from .dcc import DCC try: hcert = DCC.from_result( cwa_data.get("hash"), record_id, cwa_data.get("fn"), cwa_data.get("ln"), cwa_data.get("dob"), ) except ValueError as e: hcert = None response.warning = str(e) if hcert: hcert.save() else: # Remove DCC flag if hcert could not be generated cwa_report.dcc = False S3CustomController._view("RLPPTM", "certificate.html") # Title field = table.disease_id if cwa_report.disease_id and field.represent: disease = field.represent(cwa_report.disease_id) title = "%s %s" % (disease, T("Test Result")) else: title = T("Test Result") return { "title": title, "intro": None, # TODO "form": cwa_report.formatted(retry=retry), } else: response.information = T( "Result not reported to %(system)s") % CWA self.next = r.url(id=record_id, method="read") return None elif form.errors: current.response.error = T( "There are errors in the form, please check your input") # Custom View S3CustomController._view("RLPPTM", "testresult.html") return { "title": title, "intro": intro, "form": form, }
def cancel_subscription(self, r, **attr): """ Cancel a subscription and trigger automated cancelation actions - interactive user confirmation is required - URL query must include the reference number ("subscription_id") @param r: the S3Request instance @param attr: controller attributes """ T = current.T settings = current.deployment_settings record = r.record if not record or not record.service_id: r.error(405, "Invalid record") onerror = r.url(method="status") try: adapter = S3PaymentService.adapter(record.service_id) except (KeyError, ValueError): r.error(405, "Invalid payment service", next=onerror) if not adapter.verify_reference(r): r.error(405, "Invalid reference", next=onerror) output = {"title": T("Cancel subscription")} # Dialog to confirm cancellation CONFIRM = T("Please check this box to confirm") formfields = [ Field( "plan", label=T("Subscription Plan"), writable=False, ), Field( "subscriber", label=T("Subscriber"), writable=False, ), Field( "date", label=T("Created on"), writable=False, ), Field("cancel", "boolean", label=T("Yes, cancel this subscription"), default=False, requires=lambda cb, record_id=None: (cb, (CONFIRM if not cb else None))), ] table = r.table data = { "id": "", "plan": table.plan_id.represent(record.plan_id), "subscriber": table.pe_id.represent(record.pe_id), "date": S3DateTime.datetime_represent(record.created_on), "cancel": False, } buttons = [ INPUT( _class="tiny primary button submit-btn", _name="submit", _type="submit", _value=T("Cancel Subscription"), ), A( T("Return"), _href=r.url(method="status"), _class="cancel-action action-lnk", ), ] resourcename = r.resource.name # Generate the form and add it to the output formstyle = settings.get_ui_formstyle() form = SQLFORM.factory( record=data, showid=False, formstyle=formstyle, table_name=resourcename, buttons=buttons, #hidden = hidden, #_id = widget_id, *formfields) output["form"] = form # Process the form formname = "%s/cancel" % resourcename if form.accepts( r.post_vars, current.session, formname=formname, keepvalues=False, hideerror=False, ): if adapter.cancel_subscription(record.id): current.response.confirmation = T("Subscription cancelled") else: current.response.error = T("Cancellation failed") self.next = r.url(method="status") current.response.view = self._view(r, "update.html") return output
def __call__(self): auth = current.auth # Redirect if already logged-in if auth.s3_logged_in(): redirect(URL(c="default", f="index")) auth_settings = auth.settings auth_messages = auth.messages self.customise_auth_messages() T = current.T db = current.db s3db = current.s3db request = current.request response = current.response session = current.session settings = current.deployment_settings utable = auth_settings.table_user # Page title and intro text title = T("Volunteer Registration") # Form Fields formfields, required_fields, subheadings = self.formfields() # Generate labels (and mark required fields in the process) labels, has_required = s3_mark_required( formfields, mark_required=required_fields, ) response.s3.has_required = has_required labels["skill_id"] = DIV( labels["skill_id"], DIV( "(%s)" % T("Select all that apply"), _class="sub-label", ), ) # Form buttons REGISTER = T("Register") buttons = [ INPUT( _type="submit", _value=REGISTER, ), # TODO cancel-button? ] # Construct the form response.form_label_separator = "" form = SQLFORM.factory(table_name=utable._tablename, record=None, hidden={"_next": request.vars._next}, labels=labels, separator="", showid=False, submit_button=REGISTER, delete_label=auth_messages.delete_label, formstyle=settings.get_ui_formstyle(), buttons=buttons, *formfields) # Identify form for CSS & JS Validation form.add_class("auth_register") # Add Subheadings if subheadings: for pos, heading in subheadings[::-1]: form[0].insert(pos, DIV(heading, _class="subheading")) # Inject client-side Validation auth.s3_register_validation() # Set default registration key, so new users are prevented # from logging in until approved key = str(uuid4()) code = uuid4().hex[-6:].upper() utable.registration_key.default = self.keyhash(key, code) if form.accepts( request.vars, session, formname="register", onvalidation=auth_settings.register_onvalidation, ): formvars = form.vars # Add default organisation organisation_id = formvars.get("organisation_id") if not organisation_id: formvars[ "organisation_id"] = settings.get_org_default_organisation # Add HR type link_user_to = formvars.get("link_user_to") if link_user_to is None: formvars["link_user_to"] = ["volunteer"] # Create the user record user_id = utable.insert( **utable._filter_fields(formvars, id=False)) formvars.id = user_id # Save temporary user fields in s3db.auth_user_temp temptable = s3db.auth_user_temp record = {"user_id": user_id} mobile = formvars.mobile_phone if mobile: record["mobile"] = mobile record["consent"] = formvars.consent # Store Custom fields custom = {#"date_of_birth": formvars.date_of_birth, "home_phone": formvars.home_phone, #"office_phone": formvars.office_phone, "location_id": formvars.location_id, "addr_street": formvars.addr_street, "addr_postcode": formvars.addr_postcode, "occupation_type_ids": formvars.occupation_type_ids, "occupation": formvars.occupation, #"start_date": formvars.start_date, #"end_date": formvars.end_date, "hours_per_week": formvars.hours_per_week, "schedule": formvars.schedule, "skill_id": formvars.skill_id, "comments": formvars.comments, } for datefield in ("date_of_birth", "start_date", "end_date"): value = formvars.get(datefield) if value: value = value.isoformat() custom[datefield] = value record["custom"] = json.dumps(custom) temptable.insert(**record) # Post-process the new user record users = db(utable.id > 0).select(utable.id, limitby=(0, 2)) if len(users) == 1: # 1st user to register doesn't need verification/approval auth.s3_approve_user(form.vars) session.confirmation = auth_messages.registration_successful # 1st user gets Admin rights admin_group_id = 1 auth.add_membership(admin_group_id, users.first().id) # Log them in if "language" not in form.vars: # Was missing from login form form.vars.language = T.accepted_language user = Storage(utable._filter_fields(form.vars, id=True)) auth.login_user(user) # Send welcome email auth.s3_send_welcome_email(form.vars) # Where to go next? register_next = request.vars._next or auth_settings.register_next else: # Request User Verify their Email # System Details for Verification Email verify_url = URL( c="default", f="index", args=["verify_email", key], scheme="https" if request.is_https else "http", ) system = { "system_name": settings.get_system_name(), "url": verify_url, #"url": "%s/default/index/verify_email/%s" % (response.s3.base_url, key), "code": code, } # Try to send the Verification Email if not auth_settings.mailer or \ not auth_settings.mailer.settings.server or \ not auth_settings.mailer.send(to = form.vars.email, subject = auth_messages.verify_email_subject % system, message = auth_messages.verify_email % system, ): response.error = auth_messages.email_verification_failed # Custom View self._view(THEME, "register.html") return { "title": title, "form": form, } # Redirect to Verification Info page register_next = URL( c="default", f="message", args=["verify_email_sent"], vars={"email": form.vars.email}, ) # Log action auth.log_event(auth_messages.register_log, form.vars) # Redirect redirect(register_next) elif form.errors: response.error = T( "There are errors in the form, please check your input") # Custom View self._view(THEME, "register.html") return { "title": title, "form": form, }
def materialize_form(form, fields): """ Change layout of SQLFORM forms @params form (FORM): FORM object representing the form DOM @params fields (List): List of fields in the form @return (DIV): Materialized form wrapped with a DIV """ form.add_class("form-horizontal center") main_div = DIV(_class="center") for _, label, controls, field_tooltip in fields: curr_div = DIV(_class="row center valign-wrapper") input_field = None _controls = controls try: _name = controls.attributes["_name"] except: _name = "" try: _type = controls.attributes["_type"] except: _type = "string" try: _id = controls.attributes["_id"] except: _id = "" if isinstance(controls, INPUT): if _type == "file": # Layout for file type inputs input_field = DIV( DIV(SPAN("Upload"), INPUT(_type=_type, _id=_id), _class="btn"), DIV(INPUT(_type="text", _class="file-path", _placeholder=label.components[0]), _class="file-path-wrapper"), _class="col input-field file-field offset-s3 s6") elif _type == "checkbox": # Checkbox input field does not require input-field class input_field = DIV(_controls, label, _class="col offset-s3 s6") if isinstance(controls, SPAN): # Mostly for ids which cannot be edited by user _controls = INPUT(_value=controls.components[0], _id=_id, _name=_name, _disabled="disabled") elif isinstance(controls, TEXTAREA): # Textarea inputs try: _controls = TEXTAREA(controls.components[0], _name=_name, _id=_id, _class="materialize-textarea text") except IndexError: _controls = TEXTAREA(_name=_name, _id=_id, _class="materialize-textarea text") elif isinstance(controls, SELECT): # Select inputs _controls = SELECT(OPTION(label, _value=""), _name=_name, _class="browser-default", *controls.components[1:]) # Note now label will be the first element # of Select input whose value would be "" input_field = DIV(_controls, _class="col offset-s3 s6") elif isinstance(controls, A): # For the links in the bottom while updating tables like auth_user label = "" elif isinstance(controls, INPUT) is False: # If the values are readonly _controls = INPUT(_value=controls, _name=_name, _disabled="") if input_field is None: input_field = DIV(_controls, label, _class="input-field col offset-s3 s6") curr_div.append(input_field) if field_tooltip: curr_div.append( DIV(I(_class="fa fa-info-circle tooltipped", data={ "position": "top", "delay": "30", "tooltip": field_tooltip }, _style="cursor: pointer;"), _class="col s1 valign")) main_div.append(curr_div) return main_div
def get_task_num_form(): form = FORM('Show:', INPUT(_name = 'task_num', _class='task_num', requires = IS_INT_IN_RANGE(1,101)), A(SPAN(_class='icon-refresh'), _onclick = 'tab_refresh();$(this).closest(\'form\').submit()', _href='#')) return form
def merge(self, r, **attr): """ Merge form for two records @param r: the S3Request @param **attr: the controller attributes for the request @note: this method can always only be POSTed, and requires both "selected" and "mode" in post_vars, as well as the duplicate bookmarks list in session.s3 """ T = current.T session = current.session response = current.response output = {} tablename = self.tablename # Get the duplicate bookmarks s3 = session.s3 DEDUPLICATE = self.DEDUPLICATE if DEDUPLICATE in s3: bookmarks = s3[DEDUPLICATE] if tablename in bookmarks: record_ids = bookmarks[tablename] # Process the post variables post_vars = r.post_vars mode = post_vars.get("mode") selected = post_vars.get("selected", "") selected = selected.split(",") if mode == "Inclusive": ids = selected elif mode == "Exclusive": ids = [i for i in record_ids if i not in selected] else: # Error ids = [] if len(ids) != 2: r.error(501, T("Please select exactly two records"), next=r.url(id=0, vars={})) # Get the selected records table = self.table query = (table._id == ids[0]) | (table._id == ids[1]) orderby = table.created_on if "created_on" in table else None rows = current.db(query).select(orderby=orderby, limitby=(0, 2)) if len(rows) != 2: r.error(404, current.ERROR.BAD_RECORD, next=r.url(id=0, vars={})) original = rows[0] duplicate = rows[1] # Prepare form construction formfields = [f for f in table if f.readable or f.writable] ORIGINAL, DUPLICATE, KEEP = self.ORIGINAL, self.DUPLICATE, self.KEEP keep_o = KEEP.o in post_vars and post_vars[KEEP.o] keep_d = KEEP.d in post_vars and post_vars[KEEP.d] trs = [] init_requires = self.init_requires index = 1 num_fields = len(formfields) for f in formfields: # Render the widgets oid = "%s_%s" % (ORIGINAL, f.name) did = "%s_%s" % (DUPLICATE, f.name) sid = "swap_%s" % f.name init_requires(f, original[f], duplicate[f]) if keep_o or not any((keep_o, keep_d)): owidget = self.widget(f, original[f], _name=oid, _id=oid, _tabindex=index) else: try: owidget = s3_represent_value(f, value=original[f]) except: owidget = s3_str(original[f]) if keep_d or not any((keep_o, keep_d)): dwidget = self.widget(f, duplicate[f], _name=did, _id=did) else: try: dwidget = s3_represent_value(f, value=duplicate[f]) except: dwidget = s3_str(duplicate[f]) # Swap button if not any((keep_o, keep_d)): swap = INPUT( _value="<-->", _class="swap-button", _id=sid, _type="button", _tabindex=index + num_fields, ) else: swap = DIV(_class="swap-button") if owidget is None or dwidget is None: continue # Render label row label = f.label trs.append( TR(TD(label, _class="w2p_fl"), TD(), TD(label, _class="w2p_fl"))) # Append widget row trs.append( TR(TD(owidget, _class="mwidget"), TD(swap), TD(dwidget, _class="mwidget"))) index = index + 1 # Show created_on/created_by for each record if "created_on" in table: original_date = original.created_on duplicate_date = duplicate.created_on if "created_by" in table: represent = table.created_by.represent original_author = represent(original.created_by) duplicate_author = represent(duplicate.created_by) created = T("Created on %s by %s") original_created = created % (original_date, original_author) duplicate_created = created % (duplicate_date, duplicate_author) else: created = T("Created on %s") original_created = created % original_date duplicate_created = created % duplicate_date else: original_created = "" duplicate_created = "" # Page title and subtitle output["title"] = T("Merge records") #output["subtitle"] = self.crud_string(tablename, "title_list") # Submit buttons if keep_o or not any((keep_o, keep_d)): submit_original = INPUT( _value=T("Keep Original"), _type="submit", _name=KEEP.o, _id=KEEP.o, ) else: submit_original = "" if keep_d or not any((keep_o, keep_d)): submit_duplicate = INPUT( _value=T("Keep Duplicate"), _type="submit", _name=KEEP.d, _id=KEEP.d, ) else: submit_duplicate = "" # Build the form form = FORM( TABLE( THEAD( TR( TH(H3(T("Original"))), TH(), TH(H3(T("Duplicate"))), ), TR( TD(original_created), TD(), TD(duplicate_created), _class="authorinfo", ), ), TBODY(trs), TFOOT(TR( TD(submit_original), TD(), TD(submit_duplicate), ), ), ), # Append mode and selected - required to get back here! hidden={ "mode": "Inclusive", "selected": ",".join(ids), }) output["form"] = form # Add RESET and CANCEL options output["reset"] = FORM( INPUT( _value=T("Reset"), _type="submit", _name="reset", _id="form-reset", ), A(T("Cancel"), _href=r.url(id=0, vars={}), _class="action-lnk"), hidden={ "mode": mode, "selected": ",".join(ids), }, ) # Process the merge form formname = "merge_%s_%s_%s" % (tablename, original[table._id], duplicate[table._id]) if form.accepts( post_vars, session, formname=formname, onvalidation=lambda form: self.onvalidation(tablename, form), keepvalues=False, hideerror=False): s3db = current.s3db if form.vars[KEEP.d]: prefix = "%s_" % DUPLICATE original, duplicate = duplicate, original else: prefix = "%s_" % ORIGINAL data = Storage() for key in form.vars: if key.startswith(prefix): fname = key.split("_", 1)[1] data[fname] = form.vars[key] search = False resource = s3db.resource(tablename) try: resource.merge(original[table._id], duplicate[table._id], update=data) except current.auth.permission.error: r.unauthorised() except KeyError: r.error(404, current.ERROR.BAD_RECORD) except Exception: import sys r.error(424, T("Could not merge records. (Internal Error: %s)") % sys.exc_info()[1], next=r.url()) else: # Cleanup bookmark list if mode == "Inclusive": bookmarks[tablename] = [ i for i in record_ids if i not in ids ] if not bookmarks[tablename]: del bookmarks[tablename] search = True elif mode == "Exclusive": bookmarks[tablename].extend(ids) if not selected: search = True # Confirmation message # @todo: Having the link to the merged record in the confirmation # message would be nice, but it's currently not clickable there :/ #result = A(T("Open the merged record"), #_href=r.url(method="read", #id=original[table._id], #vars={})) response.confirmation = T("Records merged successfully.") # Go back to bookmark list if search: self.next = r.url(method="", id=0, vars={}) else: self.next = r.url(id=0, vars={}) # View response.view = self._view(r, "merge.html") return output
def widget( cls, r, record_ids=None, _class="action-lnk", ): """ Render an action item (link or button) to anonymize the provided records @param r: the S3Request @param record_ids: The list of record_ids to act on @param _class: HTML class for the action item @returns: the action item (a HTML helper instance), or an empty string if no anonymize-rules are configured for the target table, no target record was specified or the user is not permitted to anonymize it """ T = current.T default = "" # Determine target table if r.component: resource = r.component if resource.link and not r.actuate_link(): resource = resource.link else: resource = r.resource table = resource.table # Determine target record if not record_ids: return default # Check if target is configured for anonymize rules = resource.get_config("anonymize") if not rules: return default if not isinstance(rules, (tuple, list)): # Single rule rules["name"] = "default" rules = [rules] # Determine widget ID widget_id = "%s-anonymize" % table # Dialog and Form INFO = T( "The following information will be deleted from all the selected records" ) CONFIRM = T("Are you sure you want to delete the selected details?") #SUCCESS = T("Action successful - please wait...") form = FORM( P("%s:" % INFO), cls.selector(rules), P(CONFIRM), DIV( INPUT( value="anonymize_confirm", _name="anonymize_confirm", _type="checkbox", ), LABEL(T("Yes, delete the selected details")), _class="anonymize-confirm", ), DIV( INPUT( _class="small alert button anonymize-submit", _disabled="disabled", _type="submit", _value=T("Anonymize"), ), _class="anonymize-buttons", ), _class="anonymize-form", # Store action key in form hidden={"action-key": cls.action_key(widget_id)}, ) script = '''var submitButton=$('.anonymize-submit'); $('input[name="anonymize_confirm"]').off('.anonymize').on('click.anonymize',function(){if ($(this).prop('checked')){submitButton.prop('disabled',false);}else{submitButton.prop('disabled',true);}});''' current.response.s3.jquery_ready.append(script) return form
def getGameFormBtn(game, user, gameStats): """ Gets a dictionary of form buttons that do stuff for the game page. Keyword Arguments: game -- row representing the current game user -- row representing the current user Return Values: formBtn -- dictionary of web2py forms -- 'start' Start Game button -- 'join' Join Game button -- 'leave' Leave Game button -- 'target' Target Eliminated button -- 'dead' I have been eliminated button """ from gluon import current, INPUT, FORM, redirect, URL, BUTTON db = current.db formBtn = { 'start': 'start', 'join': 'join', 'leave': 'leave', 'target': 'target', 'dead': 'dead' } if gameStats['players'] > 1: formBtn['start'] = FORM( INPUT( _type='submit', _value='(Host) Start Game', _class='btn btn-large btn-block btn-inverse abtn-large', _onclick= 'return confirm(\'Are you sure you want to start this game?\');' )) else: formBtn['start'] = BUTTON( '(Host) Start Game', _class='btn btn-large btn-block btn-inverse abtn-large', _onclick='alert(\'You need at least 2 players to start a game?\');' ) formBtn['join'] = FORM( INPUT(_type='submit', _value='Join Game', _class='btn btn-large btn-block btn-inverse abtn-large')) formBtn['leave'] = FORM( INPUT( _type='submit', _value='Leave Game', _class='btn btn-block abtn-small', _onclick= 'return confirm(\'Are you sure you want to leave this game?\');')) formBtn['target'] = FORM( INPUT(_type='submit', _value='Target Eliminated', _class='btn btn-large btn-block btn-inverse abtn-large')) formBtn['dead'] = FORM( INPUT( _type='submit', _value='I am dead.', _class='btn btn-block abtn-small', _onclick= 'return confirm(\'Are you sure you want to eliminate yourself?\');' )) if gameStats['players'] > 1 and formBtn['start'].process( formname='formBtnStart').accepted: startGameAssassins(game.id, user) redirect(URL('default', 'game', args=game.id)) if formBtn['join'].process(formname='formBtnJoin').accepted: joinGame(game.id, user) redirect(URL('default', 'game', args=game.id)) if formBtn['leave'].process(formname='formBtnLeave').accepted: leaveGame(game.id, user) redirect(URL('default', 'game', args=game.id)) if formBtn['target'].process(formname='formBtnTarget').accepted: killCompletedAssassins(game.id, user.id) redirect(URL('default', 'game', args=game.id)) if formBtn['dead'].process(formname='formBtnDead').accepted: query = db((db.player.game_id == game.id) & (db.player.player_id == user.id)).select(db.player.id)[0] killPlayer(game.id, user.id) #wasKilledAssassins() redirect(URL('default', 'game', args=game.id)) return formBtn
def widget( cls, r, label="Anonymize", ajaxURL=None, _class="action-lnk", ): """ Render an action item (link or button) to anonymize the target record of an S3Request, which can be embedded in the record view @param r: the S3Request @param label: The label for the action item @param ajaxURL: The URL for the AJAX request @param _class: HTML class for the action item @returns: the action item (a HTML helper instance), or an empty string if no anonymize-rules are configured for the target table, no target record was specified or the user is not permitted to anonymize it """ T = current.T default = "" # Determine target table if r.component: resource = r.component if resource.link and not r.actuate_link(): resource = resource.link else: resource = r.resource table = resource.table # Determine target record record_id = S3Anonymize._record_id(r) if not record_id: return default # Check if target is configured for anonymize rules = resource.get_config("anonymize") if not rules: return default if not isinstance(rules, (tuple, list)): # Single rule rules["name"] = "default" rules = [rules] # Check permissions to anonymize if not S3Anonymize.permitted(table, record_id): return default # Determine widget ID widget_id = "%s-%s-anonymize" % (table, record_id) # Inject script if ajaxURL is None: ajaxURL = r.url( method="anonymize", representation="json", ) script_options = { "ajaxURL": ajaxURL, } next_url = resource.get_config("anonymize_next") if next_url: script_options["nextURL"] = next_url cls.inject_script(widget_id, script_options) # Action button translated_label = T(label) action_button = A(translated_label, _class="anonymize-btn") if _class: action_button.add_class(_class) # Dialog and Form INFO = T("The following information will be deleted from the record") CONFIRM = T("Are you sure you want to delete the selected details?") SUCCESS = T("Action successful - please wait...") form = FORM( P("%s:" % INFO), cls.selector(rules), P(CONFIRM), DIV( INPUT( value="anonymize_confirm", _name="anonymize_confirm", _type="checkbox", ), LABEL(T("Yes, delete the selected details")), _class="anonymize-confirm", ), cls.buttons(), _class="anonymize-form", # Store action key in form hidden={"action-key": cls.action_key(widget_id)}, ) dialog = DIV( form, DIV( P(SUCCESS), _class="hide anonymize-success", ), _class="anonymize-dialog hide", _title=translated_label, ) # Assemble widget widget = DIV( action_button, dialog, _class="s3-anonymize", _id=widget_id, ) return widget
def getEditgamePlayers(game, user): """ Gets a list of players and buttons for the edit game page. Keyword Arguments: game -- row representing the current game user -- row representing the current user Return Values: out -- list containing dictionaries for each player -- 'name' string of the full name of the player -- 'status' string of the status of the player -- 'kill' '' or a button to kill the player -- 'kick' '' or a button to kick the player """ from gluon import current, INPUT, FORM, redirect, URL db = current.db #Rows for the current player's list players = db((db.player.player_id == db.auth_user.id) & (db.player.game_id == game.id)).select( db.player.status, db.player.id, db.player.player_id, db.auth_user.first_name, db.auth_user.last_name) out = [] for player in players: row = {'name': 'name', 'status': 'status', 'kill': '', 'kick': ''} action1 = 'Kill' action2 = 'Kick' if game.rules == 'Assassins': action1 = 'Eliminate' elif game.rules == 'Humans v. Zombies': action1 = 'Zombify' row['name'] = player.auth_user.first_name + ' ' + player.auth_user.last_name if game.host_id == player.player.player_id: row['name'] = row['name'] + ' (Host)' if game.game_status == "STARTED": row['status'] = player.player.status if row['status'] != 'DEAD' and game.game_status == 'STARTED': action = 'action' id = INPUT(_name='id', _type='text', _value=player.player.player_id, _class='hidden') kill = INPUT( _type='submit', _value=action1, _class='btn btn-mini', _onclick='return confirm(\'Are you sure you want to ' + action1.lower() + ' this player?\');') row['kill'] = FORM(id, kill) if row['kill'].process(formname='formBtnKill').accepted: player killPlayer(game.id, row['kill'].vars.id, user) redirect(URL('kiwi', 'editgame', args=game.id)) if player.player.player_id != user.id: id = INPUT(_name='id', _type='text', _value=player.player.id, _class='hidden') kick = INPUT( _type='submit', _value=action2, _class='btn btn-mini btn-danger', _onclick='return confirm(\'Are you sure you want to ' + action2.lower() + ' this player?\');') row['kick'] = FORM(id, kick) if row['kick'].process(formname='formBtnKick').accepted: kickPlayer(row['kick'].vars.id, user) redirect(URL('kiwi', 'editgame', args=game.id)) out.append(row) #End for player in players: #Sort players by status, then by name out.sort(key=lambda n: (n['status'], n['name'])) return out
def invite(self, r, **attr): """ Prepare and process invitation form @param r: the S3Request instance @param attr: controller attributes """ T = current.T db = current.db s3db = current.s3db response = current.response request = current.request session = current.session settings = current.deployment_settings auth = current.auth auth_settings = auth.settings auth_messages = auth.messages output = { "title": T("Invite Organisation"), } # Get all accounts that are linked to this org utable = auth_settings.table_user oltable = s3db.org_organisation_user pltable = s3db.pr_person_user organisation_id = r.record.id join = oltable.on((oltable.user_id == utable.id) & \ (oltable.deleted == False)) left = pltable.on((pltable.user_id == utable.id) & \ (pltable.deleted == False)) query = (oltable.organisation_id == organisation_id) rows = db(query).select( utable.id, utable.first_name, utable.last_name, utable.email, utable.registration_key, pltable.pe_id, join=join, left=left, ) active, disabled, invited = [], [], [] for row in rows: user = row[utable] person_link = row.pr_person_user if person_link.pe_id: if user.registration_key: disabled.append(user) else: active.append(user) else: invited.append(user) if active or disabled: response.error = T( "There are already user accounts registered for this organization" ) from gluon import UL, LI, H4, DIV from s3 import s3_format_fullname fullname = lambda user: s3_format_fullname( fname=user.first_name, lname=user.last_name, truncate=False, ) account_list = DIV(_class="org-account-list") if active: account_list.append(H4(T("Active Accounts"))) accounts = UL() for user in active: accounts.append( LI("%s <%s>" % (fullname(user), user.email))) account_list.append(accounts) if disabled: account_list.append(H4(T("Disabled Accounts"))) accounts = UL() for user in disabled: accounts.append( LI("%s <%s>" % (fullname(user), user.email))) account_list.append(accounts) output["item"] = account_list response.view = self._view(r, "display.html") return output account = invited[0] if invited else None # Look up existing invite-account email = None if account: email = account.email else: ctable = s3db.pr_contact query = (ctable.pe_id == r.record.pe_id) & \ (ctable.contact_method == "EMAIL") & \ (ctable.deleted == False) contact = db(query).select( ctable.value, orderby=ctable.priority, limitby=(0, 1), ).first() if contact: email = contact.value # Form Fields dbset = db(utable.id != account.id) if account else db formfields = [ Field("email", default=email, requires=[ IS_EMAIL(error_message=auth_messages.invalid_email), IS_LOWER(), IS_NOT_IN_DB( dbset, "%s.email" % utable._tablename, error_message=auth_messages.duplicate_email, ), ]), ] # Generate labels (and mark required fields in the process) labels, has_required = s3_mark_required(formfields, ) response.s3.has_required = has_required # Form buttons SEND_INVITATION = T("Send New Invitation") if account else T( "Send Invitation") buttons = [ INPUT( _type="submit", _value=SEND_INVITATION, ), # TODO cancel-button? ] # Construct the form response.form_label_separator = "" form = SQLFORM.factory( table_name="invite", record=None, hidden={"_next": request.vars._next}, labels=labels, separator="", showid=False, submit_button=SEND_INVITATION, #delete_label = auth_messages.delete_label, formstyle=settings.get_ui_formstyle(), buttons=buttons, *formfields) # Identify form for CSS & JS Validation form.add_class("send_invitation") if form.accepts( request.vars, session, formname="invite", #onvalidation = auth_settings.register_onvalidation, ): error = self.invite_account(r.record, form.vars.email, account=account) if error: response.error = T( "Could not send invitation (%(reason)s)") % { "reason": error } else: response.confirmation = T("Invitation sent") else: if account: response.warning = T( "This organisation has been invited before!") output["form"] = form response.view = self._view(r, "update.html") return output