<!--
 -
 -  $Id$
 -
 -  This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
 -  project.
 -
 -  Copyright (C) 1998-2018 OpenLink Software
 -
 -  This project is free software; you can redistribute it and/or modify it
 -  under the terms of the GNU General Public License as published by the
 -  Free Software Foundation; only version 2 of the License, dated June 1991.
 -
 -  This program is distributed in the hope that it will be useful, but
 -  WITHOUT ANY WARRANTY; without even the implied warranty of
 -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 -  General Public License for more details.
 -
 -  You should have received a copy of the GNU General Public License along
 -  with this program; if not, write to the Free Software Foundation, Inc.,
 -  51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 -
-->
<v:page name="members_page"
        fast-render="1"
        xmlns:vm="http://www.openlinksw.com/vspx/ods/"
        xmlns:v="http://www.openlinksw.com/vspx/"
        style="index.xsl"
        doctype="-//W3C//DTD XHTML 1.0 Transitional//EN"
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <vm:page>
    <vm:header>
      <script type="text/javascript" src="tbl.js">;</script>
      <script type="text/javascript" src="typeahead.js">;</script>
      <link rel="stylesheet" type="text/css" href="typeahead.css" />
      <link rel="stylesheet" type="text/css" href="common.css" />
      <vm:title>Application Members</vm:title>
    </vm:header>
    <v:on-init>
      <![CDATA[
        select WAI_MEMBER_MODEL, WAI_IS_PUBLIC, WAI_MEMBERS_VISIBLE, WAI_INST, WAI_NAME, WAI_TYPE_NAME, WAI_DESCRIPTION, deserialize(WAI_ACL)
          into self.imodel, self.is_public, self.is_visible, self.inst, self.iname, self.wa_type, self.idesc, self.iacl
          from DB.DBA.WA_INSTANCE
         where WAI_ID = self.iid;
        if (self.instance_descr is null)
          self.instance_descr := WA_GET_APP_NAME (coalesce(get_keyword('wa_name', self.vc_event.ve_params), (select WAI_TYPE_NAME from WA_INSTANCE where WAI_ID = get_keyword('wai_id', self.vc_event.ve_params)), ''));
        if (self.instance_descr = 'Blog')
        {
          self.ihome := self.inst.wa_home_url();
        }
      ]]>
    </v:on-init>
    <v:after-data-bind>
      <![CDATA[
        declare freeze varchar;
        freeze := (select WAI_IS_FROZEN from DB.DBA.WA_INSTANCE where WAI_ID = self.iid);
        if (freeze = 1 and not wa_user_is_dba (self.u_name, self.u_group))
        {
          http_request_status('HTTP/1.1 302 Found');
          http_header(sprintf('Location: services.vspx?sid=%s&realm=%s\r\n', self.sid, self.realm));
          return;
        }
      ]]>
    </v:after-data-bind>
    <vm:pagewrapper>
      <vm:variable name="inst" type="db.dba.web_app" default="null" persist="0" />
      <vm:variable name="wa_name" type="varchar" default="null" persist="0" param-name="wa_name"/>
      <vm:variable name="wa_type" type="varchar" default="null" persist="0"/>
      <vm:variable name="imodel" type="integer" default="null" persist="0"/>
      <vm:variable name="is_public" type="integer" default="null" persist="0"/>
      <vm:variable name="is_visible" type="integer" default="null" persist="0"/>
      <vm:variable name="iid" type="integer" default="null" persist="0" param-name="wai_id"/>
      <vm:variable name="iname" type="varchar" default="null" persist="0"/>
      <vm:variable name="idesc" type="varchar" default="null" persist="0"/>
      <vm:variable name="ihome" type="varchar" default="null" persist="0"/>
      <vm:variable name="instance_descr" type="varchar" default="null" persist="0" />
      <vm:variable name="iacl" type="any" default="null" persist="0" />
      <vm:variable name="wa_domain" type="varchar" default="null" persist="0"/>
      <vm:variable name="member_filter" type="varchar" default="'%'" persist="0"/>
      <vm:navigation on="settings"/>
      <vm:navigation1 on="services"/>
      <vm:body>
        <vm:login redirect="login.vspx"/>
        <h3 class="page_title">
          <v:label value="--self.iname"/>
        </h3>
  		  <v:button name="mem_Back" value="''" action="simple" style="url" xhtml_class="img_button">
          <v:before-render>
            <![CDATA[
              control.ufl_value := '<img src="images/icons/go_16.png" border="0" /> Back to Applications';
            ]]>
          </v:before-render>
 		      <v:on-post>
     			  self.vc_redirect ('services.vspx');
 		      </v:on-post>
  		  </v:button>
  		  <br /><br />
        <v:template name="template_01" type="simple" enabled="--case when self.wa_type in ('oDrive', 'oMail', 'IM') or (self.imodel = 1) then 0 else 1 end">
          <fieldset>
            <legend><b>Members</b></legend>
        <div>
          <?vsp
            declare cnt, cnt1 int;
            select count(*) into cnt from WA_INVITATIONS where WI_U_ID = self.u_id and WI_INSTANCE = self.iname;
            select count(*) into cnt1 from WA_MEMBER where WAM_INST = self.iname and WAM_STATUS > 2;
            cnt := cnt + cnt1;
            if (cnt > 0)
            {
          ?>
          <img src="images/icons/go_16.png" border="0" alt="Sent Invitations" /> <v:url name="app_inv_url" url="--sprintf ('app_sent_inv.vspx?wai_name=%U&wai_id=%d', self.iname, self.iid)" value="--sprintf ('You have %d pending Invitation(s)', cnt)" render-only="1"/>
          <?vsp
            }
          ?>
          <img src="images/icons/go_16.png" border="0" alt="Invite" /> <v:url name="app_inv1_url" url="--sprintf ('members_inv.vspx?wai_id=%d', self.iid)" value="Invite someone to join" render-only="1"/>
        </div>
        <v:form name="regf2" method="POST" type="simple">
          <div class="ctl_grp">
            <img src="images/icons/filter_24.png" alt="Filter" hspace="3" border="0"/>Filter
            <v:text name="filt" value=""/>
            <v:button name="filt_bts" action="simple" value="Filter" >
              <v:on-post>
                <![CDATA[
                  self.member_filter := self.filt.ufl_value || '%';
                  self.dss_members.ds_parameters := null;
                  self.dss_members.vc_data_bind (e);
                  self.ds_members.vc_data_bind (e);
                ]]>
              </v:on-post>
            </v:button>
          </div>
          <div class="<?V case when self.dss_members.ds_rows_fetched &gt; 10 then 'scroll_area' else '' end ?>">
            <table class="listing">
              <tr class="listing_header_row">
                <th>User</th>
                <th>Membership Type(status)</th>
                <th>Member Specific Data</th>
                <th>Action</th>
              </tr>
              <v:data-source name="dss_members" nrows="1000" scrollable="1" edit="0" expression-type="sql" initial-offset="0">
                <v:expression>
                  <![CDATA[
                    select
                      U_NAME,
                      WMT_NAME,
                      WAM_USER,
                      WAM_MEMBER_TYPE,
                      WAM_STATUS
                    from
                      WA_MEMBER,
                      SYS_USERS,
                      WA_MEMBER_TYPE,
                      WA_TYPES
                    where
                      WMT_APP = WAM_APP_TYPE and
                      WAT_NAME = WMT_APP and
                      WMT_ID = WAM_MEMBER_TYPE and
                      U_ID = WAM_USER and
                      WAM_INST = ? and
                      WAM_STATUS <> 1 and U_NAME like ?
                  ]]>
                </v:expression>
                <v:column name="U_NAME" />
                <v:column name="WMT_NAME" />
                <v:column name="WAM_USER" />
                <v:column name="WAM_MEMBER_TYPE" />
                <v:column name="WAM_STATUS" />
                <v:param name="iname" value="--self.iname"/>
                <v:param name="member_filt" value="--self.member_filter"/>
                <v:after-data-bind>
                  control.ds_make_statistic ();
                </v:after-data-bind>
              </v:data-source>
              <v:data-set name="ds_members" nrows="1000" scrollable="1" cursor-type="keyset" edit="1" data-source="self.dss_members">
                <v:before-render>
                  control.vc_enabled := length((control as vspx_data_set).ds_rows_cache);
                </v:before-render>

                    <v:template name="ds_members_repeat" type="repeat">

                      <v:template name="ds_members_empty" type="if-not-exists">
                        <tr>
                          <td colspan="4">No matching records</td>
                        </tr>
                  </v:template>

                      <v:template name="ds_members_edit2" type="edit">
                    <v:form name="upf" type="update" method="POST"  table="WA_MEMBER" if-not-exists="nothing">
                      <v:key name="upd_WAM_USER" column="WAM_USER" value="--self.ds_members.ds_current_row.te_rowset[2]" default="null"/>
                      <v:key name="upd_WAM_INST" column="WAM_INST" value="--self.iname" default="null"/>
                      <v:template name="template6" type="simple">
                      <tr>
                        <td>
                              <v:label format="%s" value="--self.ds_members.ds_current_row.te_rowset[0]"/>
                        </td>
                        <td>
                          <v:data-list
                            xhtml_style="width:100%"
                            name="membership_type1"
                            sql="select * from WA_MEMBER_TYPE where WMT_APP = (select WAI_TYPE_NAME from WA_INSTANCE where WAI_NAME = self.iname) and WMT_ID <> 1 and WMT_ID <> -1"
                            key-column="WMT_ID"
                            value-column="WMT_NAME"
                            column="WAM_MEMBER_TYPE"
                          >
                          </v:data-list>
                        </td>
                        <td>
                          <?vsp
                            {
                              declare _u_id, _u_name, _ss, _h any;
                              declare _inst web_app;
                              _inst := (select WAI_INST from WA_INSTANCE where WAI_NAME = self.iname);
                              _u_name := self.ds_members.ds_current_row.te_rowset[0];
                              _u_id := (select U_ID from SYS_USERS where U_NAME = _u_name);
                              _ss := null;
                              _h := udt_implements_method(_inst, 'wa_member_data');
                              if(_h)
                                http (call (_h) (_inst, _u_id, _ss));
                            }
                          ?>
                        </td>
                        <td>
                          <v:button name="ds_members_update_btn" action="submit" value="Update" style="url"/>
                          <a href="#" onclick="javascript: doPostValue('page_form', 'ds_members_cancel', 'Cancel')">Cancel</a>
                        </td>
                      </tr>
                    </v:template>
                  </v:form>
                </v:template>

                    <v:template name="ds_members_browse" type="browse">
                  <tr>
                    <td nowrap="1" width="20%">
                          <v:label value="--(control.vc_parent as vspx_row_template).te_rowset[0]" format="%s"/>
                    </td>
                    <td nowrap="1">
                          <v:label value="" format="%s" >
                        <v:after-data-bind>
                          <![CDATA[
                            declare _type_name, _status any;
                            _type_name := (control.vc_parent as vspx_row_template).te_rowset[1];
                            _status := (control.vc_parent as vspx_row_template).te_rowset[4];
                            if(_status > 2) {
                              control.ufl_value := concat(_type_name, ' [', WA_STATUS_NAME(_status), ']');
                            }
                            else {
                              control.ufl_value := _type_name;
                            }
                          ]]>
                        </v:after-data-bind>
                      </v:label>
                    </td>
                    <td nowrap="1">
                      <?vsp
                        {
                          declare _u_id, _u_name, _ss, _h any;
                          declare _inst web_app;
                          _inst := (select WAI_INST from WA_INSTANCE where WAI_NAME = self.iname);
                          _u_name := self.ds_members.ds_current_row.te_rowset[0];
                          _u_id := (select U_ID from SYS_USERS where U_NAME = _u_name);
                          _ss := null;
                          _h := udt_implements_method(_inst, 'wa_member_data');
                          if(_h)
                            http (call (_h) (_inst, _u_id, _ss));
                        }
                      ?>
                    </td>
                    <td nowrap="1">
                      <v:button style="url" name="ds_members_delete" action="simple" value="Terminate">
                        <v:after-data-bind>
                          <![CDATA[
                            declare _status any;
                            _status := (control.vc_parent as vspx_row_template).te_rowset[4];
                            if(_status <> 2 and _status <> 4)
                            {
                              control.vc_enabled := 0;
                            }
                          ]]>
                        </v:after-data-bind>
                        <v:on-post>
                          <![CDATA[
                            {
                              declare exit handler for sqlstate '*' {
                                signal(__SQL_STATE, __SQL_MESSAGE);
                                self.vc_error_message := WA_RETRIEVE_MESSAGE(concat(__SQL_STATE,' ',__SQL_MESSAGE));
                                self.vc_is_valid := 0;
                                rollback work;
                                return;
                              };
                              -- delete member
                              declare _u_id, _u_name, _wam_inst any;
                              _u_name := self.ds_members.ds_current_row.te_rowset[0];
                              _u_id := (select U_ID from SYS_USERS where U_NAME = _u_name);
                              _wam_inst := self.iname;
                              connection_set('action_reason', 'owner');
                              delete
                                from WA_MEMBER
                              where
                                WAM_USER = _u_id and
                                WAM_INST = _wam_inst;

                              -- refresh dataset
                              self.dss_members.ds_parameters := null;
                              self.dss_members.vc_data_bind (e);
                              self.ds_members.vc_data_bind(e);
                            }
                          ]]>
                        </v:on-post>
                      </v:button>
                      <v:button style="url" name="ds_members_change" action="simple" value="Change Attributes">
                        <v:before-render>
                          <![CDATA[
                            declare _u_id, _ss any;
                            _ss := null;
                            _u_id := (select U_ID from SYS_USERS where U_NAME = (control.vc_parent as vspx_row_template).te_rowset[0]);
                            declare _inst web_app;
                            _inst := (select WAI_INST from WA_INSTANCE where WAI_NAME = self.iname);
                            if('N/A' = _inst.wa_member_data(_u_id, _ss))
                            {
                              control.vc_enabled := 0;
                            }
                          ]]>
                        </v:before-render>
                        <v:on-post>
                          <![CDATA[
                            {
                              declare _u_id, _u_name, _ss, _h any;
                              declare _inst web_app;
                              _inst := (select WAI_INST from WA_INSTANCE where WAI_NAME = self.iname);
                              _u_name := (control.vc_parent as vspx_row_template).te_rowset[0];
                              _u_id := (select U_ID from SYS_USERS where U_NAME = _u_name);
                              _ss := null;
                              _h := udt_implements_method(_inst, 'wa_member_data_edit_form');
                              if(_h) {
                                call (_h) (_inst, _u_id, _ss);
                              }
                            }
                          ]]>
                        </v:on-post>
                      </v:button>
                      <v:button action="simple" value="Edit" name="ds_members_edit" style="url" >
                        <v:after-data-bind>
                          <![CDATA[
                            declare _status any;
                            _status := (control.vc_parent as vspx_row_template).te_rowset[4];
                            if (_status <> 2)
                            {
                              control.vc_enabled := 0;
                            }
                          ]]>
                        </v:after-data-bind>
                      </v:button>
                      <v:button action="simple" name="ds_members_join_approval" style="url" value="Approve">
                        <v:after-data-bind>
                          <![CDATA[
                            declare _status any;
                            _status := (control.vc_parent as vspx_row_template).te_rowset[4];
                            if (_status in (2,4))
                            {
                              control.vc_enabled := 0;
                            }
                          ]]>
                        </v:after-data-bind>
                        <v:on-post>
                          <![CDATA[
                            declare exit handler for sqlstate '*' {
                              self.vc_error_message := WA_RETRIEVE_MESSAGE(concat(__SQL_STATE,' ',__SQL_MESSAGE));
                              self.vc_is_valid := 0;
                              rollback work;
                              return;
                            };
                            update
                              WA_MEMBER
                            set
                              WAM_STATUS = 2
                            where
                              WAM_USER = (control.vc_parent as vspx_row_template).te_rowset[2] and
                              WAM_INST = self.iname;

                            self.dss_members.ds_parameters := null;
                            self.dss_members.vc_data_bind (e);
                            self.ds_members.vc_data_bind(e);
                          ]]>
                        </v:on-post>
                      </v:button>
                      <v:button action="simple" name="ds_members_join_reject" style="url" value="Reject">
                        <v:after-data-bind>
                          <![CDATA[
                            declare _status any;
                            _status := (control.vc_parent as vspx_row_template).te_rowset[4];
                            if (_status in (2,4))
                            {
                              control.vc_enabled := 0;
                            }
                          ]]>
                        </v:after-data-bind>
                        <v:on-post>
                          <![CDATA[
                            declare exit handler for sqlstate '*' {
                              self.vc_error_message := WA_RETRIEVE_MESSAGE(concat(__SQL_STATE,' ',__SQL_MESSAGE));
                              self.vc_is_valid := 0;
                              rollback work;
                              return;
                            };
                            delete from
                              WA_MEMBER
                            where
                              WAM_USER = (control.vc_parent as vspx_row_template).te_rowset[2] and
                              WAM_INST = self.iname;

                            self.dss_members.ds_parameters := null;
                            self.dss_members.vc_data_bind (e);
                            self.ds_members.vc_data_bind(e);
                          ]]>
                        </v:on-post>
                      </v:button>
                    </td>
                    </tr>
                  </v:template>
                </v:template>
                <v:template name="template3" type="simple">
                  <tr>
                    <td colspan="4" class="ctrl">
                      <vm:ds-navigation data-set="ds_members" />
                    </td>
                  </tr>
                </v:template>
              </v:data-set>
            </table>
          </div>
          <table class="listing">
            <v:form type="simple" method="POST" name="add_form_1">
            </v:form>
            <tr>
              <td colspan="4">
                <v:method name="add_member" arglist="in userName varchar">
                  <![CDATA[
                    declare N integer;
                    declare userDescr varchar;

                    if (
                        lcase(self.u_name) = lcase(userName) or
                        strstr(self.str_alreadymembers,userName) IS NOT NULL
                        )
                    {
                      self.str_alreadyinlist := self.str_alreadyinlist||', '||userName;

                      return;
                    }

                    N := (select U_ID from DB.DBA.SYS_USERS where U_NAME = userName);
                    if (isnull(N))
                      return;

                    userDescr := coalesce((select U_FULL_NAME from DB.DBA.SYS_USERS where U_NAME = userName), '');
                    if (isnull(self.d_added))
                      self.d_added := vector();
                    self.delete_member(userName, 0);
                    for (N := 0; N < length(self.d_added); N := N + 1)
                      if (lcase(self.d_added[N][0]) = lcase(userName))
                        return;
                    self.d_added := vector_concat(self.d_added, vector(vector(userName, userDescr)));
                  ]]>
                </v:method>
                <v:method name="delete_member" arglist="in userName varchar, in mode integer">
                  <![CDATA[
                    declare N integer;

                    if (isnull(self.d_deleted))
                      self.d_deleted := vector();
                        if (mode)
                        {
                      declare tmp any;
                      tmp := vector();
                      for (N := 0; N < length(self.d_added); N := N + 1)
                        if (lcase(self.d_added[N][0]) <> lcase(userName))
                          tmp := vector_concat(tmp, vector(self.d_added[N]));
                      self.d_added := tmp;
                    }
                    for (N := 0; N < length(self.d_deleted); N := N + 1)
                      if (lcase(self.d_deleted[N]) = lcase(userName))
                        return;
                    self.d_deleted := vector_concat(self.d_deleted, vector(lcase(userName)));
                  ]]>
                </v:method>
                <v:before-data-bind>
                  <![CDATA[

                    self.str_alreadymembers := '';
                    for (select U_NAME from DB.DBA.WA_MEMBER,DB.DBA.SYS_USERS where U_ID = WAM_USER and WAM_STATUS <> 1  and WAM_INST = self.iname) do
                    {
                      self.str_alreadymembers:=self.str_alreadymembers||','||U_NAME;
                        }
                    self.str_alreadyinlist :=  '';

                    declare exit handler for not found { goto _end; };

                    declare N, I integer;

                    if (get_keyword('member_name', self.vc_page.vc_event.ve_params, '') <> '')
                    {
                      declare tmp any;

                      tmp := split_and_decode (get_keyword('member_name', self.vc_page.vc_event.ve_params, ''), 0, '\0\0,');
                      for (I := 0; I < length(tmp); I := I + 1)
                      {
                        self.add_member(trim(tmp[I]));
                      }
                    }
                    for (N := 0; N < length(self.vc_page.vc_event.ve_params); N := N + 2)
                    {
                      if (self.vc_page.vc_event.ve_params[N] like 'delete_%')
                      {
                        self.delete_member(replace(self.vc_page.vc_event.ve_params[N], 'delete_', ''), 1);
                      }
                    }
                  _end:;
                  ]]>
                </v:before-data-bind>
                <vm:variable name="d_added" type="any" default="null" persist="0" />
                <vm:variable name="d_deleted" type="any" default="null" persist="0" />
                <vm:variable name="str_alreadyinlist" type="varchar" default="''" persist="0" />
                <vm:variable name="str_alreadymembers" type="varchar" default="''" persist="0" />
                <div style="padding: 0 0 0.5em 0;">
                  <v:text name="member_name" type="hidden" value="--''" format="%s"/>
                      <input type="button" value="Add member(s) to invite list" onClick="javascript:windowShow('users_select.vspx?mode=u&dst=mc&src=s&params=member_name:s1;', 600)" class="button"/>
                </div>
                <?vsp
                  if(length(self.d_added)>0)
                  {
                ?>
                <table class="listing" id="members" cellspacing="0" width="98%">
                  <tr class="listing_header_row">
                    <th> Name </th>
                    <th>Description </th>
                    <th width="180px">Membership Type(status)</th>
                    <th align="center" width="1%">Action </th>
                  </tr>
                  <?vsp
                    declare member_type_options varchar;
                    member_type_options:='';
                    for (select * from WA_MEMBER_TYPE where WMT_APP = (select WAI_TYPE_NAME from WA_INSTANCE where WAI_NAME = self.iname) and WMT_ID <> 1 and WMT_ID <> -1) do
                    {
                      member_type_options:=member_type_options||sprintf('<option value="%d" >%s</option>',WMT_ID,WMT_NAME);
                    }

                    declare N integer;
                    declare _U_NAME,_U_FULL_NAME varchar;

                    N := 0;
                    _U_NAME:='';
                    _U_FULL_NAME:='';

                    for (N := 0; N < length(self.d_added); N := N + 1)
                    {
                      _U_NAME:=self.d_added[N][0];
                      _U_FULL_NAME:=self.d_added[N][1];

                      http('<tr class="'||(case when mod(N,2) = 0 then 'listing_row_odd' else 'listing_row_even' end)||'" >');
                      http('<td nowrap="nowrap">');
                      http(_U_NAME);
                      http('</td>');
                      http('<td nowrap="nowrap">');
                      http(_U_FULL_NAME);
                      http('</td>');
                      http('<td nowrap="nowrap" align="center">');
                      http('<select name="membership_type_'||_U_NAME||'" id="membership_type_'||_U_NAME||'" style="width:90%">');
                      http(member_type_options);
                      http('</select>');
                      http('</td>');
                      http('<td nowrap="nowrap">');
                      http(sprintf('<input type="submit" name="delete_%s" value="Delete" class="button" />', _U_NAME));
                      http('</td>');
                      http('</tr>');
                    }
                    if (not N)
                      http('<tr align="left"><td colspan="4">No members to invite</td></tr>');
                  }
                  if (length(self.str_alreadyinlist)>2)
                    self.str_alreadyinlist:=subseq(self.str_alreadyinlist,1);
                  ?>
                </table>
                <?vsp
                  if (length(self.str_alreadyinlist)>0)
                  {
                ?>
                <div style="color:red;">You have selected users that were already in the list:<?Vself.str_alreadyinlist?></div>
                <?vsp
                  }
                ?>
                <div class="new-form-footer">
                  <v:button name="btn_invite" action="simple" value="Invite member(s)" xhtml_class="form-button" enabled="--length(self.d_added)">
                    <v:on-post>
                      <![CDATA[
                        -- check if user exists
                        declare _u_id, _u_name any;
                        declare model_type integer;
                        declare N integer;
                        for (N := 0; N < length(self.d_added); N := N + 1)
                        {
                          _u_name :=self.d_added[N][0];
                          model_type := cast(get_keyword('membership_type_'||_u_name, self.vc_page.vc_event.ve_params, -1) as integer);
                          if ( model_type < 1)
                          {
                            self.vc_is_valid := 0;
                            self.vc_error_message := 'Incorrect Membership type';
                            goto nextcycle;
                          }
                          if (_u_name is null or _u_name = '')
                          {
                            self.vc_is_valid := 0;
                            self.vc_error_message := 'Login Name cannot be empty.';
                            -- return 0;
                            goto nextcycle;
                          }
                          _u_id := (select U_ID from SYS_USERS where U_NAME = _u_name and U_DAV_ENABLE = 1 and U_IS_ROLE = 0);
                          if (_u_id is null)
                          {
                            self.vc_is_valid := 0;
                            self.vc_error_message := 'Entered user does not exist.';
                            -- return 0;
                            goto nextcycle;
                          }
                          if (_u_id = self.u_id)
                          {
                            self.vc_is_valid := 0;
                            self.vc_error_message := 'You are owner of this application.';
                            -- return 0;
                            goto nextcycle;
                          }
                          if (exists(select 1 from WA_MEMBER where WAM_USER = _u_id and WAM_INST = self.iname and WAM_STATUS = 2))
                          {
                            self.vc_error_message := 'User is already member of application';
                            self.vc_is_valid := 0;
                            -- return;
                            goto nextcycle;
                          }
                          if (exists(select 1 from WA_MEMBER where WAM_USER = _u_id and WAM_INST = self.iname and WAM_STATUS = 4))
                          {
                            self.vc_error_message := 'User is already pending';
                            self.vc_is_valid := 0;
                            --  return;
                            goto nextcycle;
                          }
                          -- create session
                          declare _expire, _sid any;
                              if (self.imodel = 2)
                          {
                            _sid := md5 (concat (datestring (dateadd ('second', N, now())), http_client_ip(), http_path()));
                            _expire := coalesce((select top 1 WS_REGISTRATION_EMAIL_EXPIRY from WA_SETTINGS), 1);
                            insert into VSPX_SESSION ( VS_REALM, VS_SID, VS_UID, VS_STATE, VS_EXPIRY)
                              values ( 'wa', _sid, _u_name, serialize (vector ('vspx_user', _u_name)), dateadd ('hour', _expire, now()));
                            connection_set('__sid', _sid);
                          }
                          -- add member
                          declare exit handler for sqlstate '*'
                          {
                            self.vc_error_message := WA_RETRIEVE_MESSAGE(concat(__SQL_STATE,' ',__SQL_MESSAGE));
                            self.vc_is_valid := 0;
                            rollback work;
                            -- return;
                            goto nextcycle;
                          };
                          {
                            declare exit handler for sqlstate '*'
                            {
                              self.vc_is_valid := 0;
                              declare _use_sys_errors, _sys_error, _error any;
                              _sys_error := concat (__SQL_STATE,' ',__SQL_MESSAGE);
                              _error := _u_name||' - Due to a transient problem in the system, your invitation could not be
                                   processed at the moment. The system administrators have been notified. Please
                                   try again later.';
                              _use_sys_errors := (select top 1 WS_SHOW_SYSTEM_ERRORS from WA_SETTINGS);
                              if (_use_sys_errors)
                              {
                                self.vc_error_message := self.vc_error_message||_error || ' ' || _sys_error||' ';
                              } else {
                                self.vc_error_message :=self.vc_error_message || _error||' ';
                              }
                              rollback work;
                              -- return;
                              goto nextcycle;
                            };

                                if (self.imodel = 2)
                            {
                              insert soft WA_MEMBER(WAM_USER, WAM_INST, WAM_MEMBER_TYPE, WAM_STATUS)
                                values(_u_id, self.iname, model_type, 4);
                            }
                            else
                            {
                              insert soft WA_MEMBER(WAM_USER, WAM_INST, WAM_MEMBER_TYPE, WAM_STATUS)
                                values(_u_id, self.iname, model_type, 2);
                            }
                          }
                        nextcycle:;
                        }
                        -- refresh dataset
                        self.dss_members.ds_parameters := null;
                        self.dss_members.vc_data_bind (e);
                        self.ds_members.vc_data_bind(e);

                        self.d_added:=vector();
                        self.btn_invite.vc_data_bind (e);
                        self.btn_invite_cancel.vc_data_bind (e);
                      ]]>
                    </v:on-post>
                  </v:button>
                 <v:button name="btn_invite_cancel" action="simple" value="Cancel" xhtml_class="form-button" enabled="--length(self.d_added)">
                   <v:on-post>
                     <![CDATA[
                       self.vc_redirect('members.vspx?wai_id='||cast(self.iid as varchar));
                     ]]>
                   </v:on-post>
                 </v:button>
               </div>
             </td>
           </tr>
        </table>
      </v:form>
          </fieldset>
        </v:template>
        <v:template name="template_02" type="simple">
          <fieldset>
            <legend><b>ACL</b></legend>
            <table>
              <tr>
                <td width="100%">
                  <table id="s_tbl" class="ODS_grid">
                    <thead>
                      <tr>
                        <th width="1%">Type</th>
                        <th>Value</th>
                        <th width="1%" nowrap="nowrap">ACL: (R)ead, (W)rite</th>
                        <th class="action">Action</th>
                      </tr>
                    </thead>
                    <tbody id="s_tbody">
                    <tr id="s_tr_no"><td colspan="4"><b>No WebID Security</b></td></tr>
              		  <![CDATA[
              		    <script type="text/javascript">
               		        OAT.Loader.load(["ajax", "json", "calendar", "combolist"]);
      <?vsp
                        declare N integer;

                        if (self.wa_type in ('oDrive'))
                          self.iacl := ODRIVE.WA.aci_load (sprintf('/DAV/home/%s/', self.u_name));

                        for (N := 0; N < length (self.iacl); N := N + 1)
                        {
                            http (sprintf ('ODSInitArray.push(function(){TBL.createRow("s", null, {fld_1: {mode: 50, value: "%s", onchange: function(){TBL.changeCell50(this);}}, fld_2: {mode: 51, className: "_validate_ _webid_", value: %s, readOnly: %s, imgCssText: "%s"}, fld_3: {mode: 52, value: [%d, %d, %d], tdCssText: "width: 1%%; text-align: center;"}});});', self.iacl[N][2], ODS..obj2json (self.iacl[N][1]), case when self.iacl[N][2] = 'public' then 'true' else 'false' end, case when self.iacl[N][2] = 'public' then 'display: none;' else '' end, self.iacl[N][3], self.iacl[N][4], self.iacl[N][5]));
        }
      ?>
              		    </script>
              		  ]]>
                    </tbody>
                  </table>
                </td>
                <td valign="top" nowrap="nowrap">
                  <span class="button pointer" onclick="javascript: TBL.createRow('s', null, {fld_1: {mode: 50, onchange: function(){TBL.changeCell50(this);}}, fld_2: {mode: 51, className: '_validate_ _webid_'}, fld_3: {mode: 52, value: [1, 0, 0], tdCssText: 'width: 1%; text-align: center;'}});"><img src="/ods/images/icons/add_16.png" border="0" class="button" alt="Add Security" title="Add Security" /> Add</span><br /><br />
                </td>
              </tr>
            </table>
            <v:button name="btn_acl_update" action="simple" value="Update" xhtml_class="form-button">
              <v:on-post>
                <![CDATA[
                  declare exit handler for SQLSTATE '*'
                  {
                    -- dbg_obj_print ('__SQL_MESSAGE', __SQL_MESSAGE);
                    if (__SQL_STATE = 'TEST')
                    {
                      self.vc_error_message := ODRIVE.WA.test_clear (__SQL_MESSAGE);
                      self.vc_is_valid := 0;
                      return;
                    }
                    resignal;
                  };

                  -- validate ACL rules
                  DB.DBA.wa_aci_validate (DB.DBA.wa_aci_params (e.ve_params));

                  self.iacl := DB.DBA.wa_aci_params (e.ve_params);
                  update DB.DBA.WA_INSTANCE
                     set WAI_ACL = serialize (self.iacl)
                   where WAI_ID = self.iid;

                  if (self.wa_type in ('oDrive'))
                    ODRIVE.WA.DAV_PROP_SET (sprintf('/DAV/home/%s/', self.u_name), 'virt:aci_meta_n3', ODRIVE.WA.aci_n3 (self.iacl));

                  commit work;

       		        self.vc_data_bind(e);
                ]]>
              </v:on-post>
            </v:button>
          </fieldset>
        </v:template>
      </vm:body>
    </vm:pagewrapper>
  </vm:page>
</v:page>
