Exemplo n.º 1
0
def set_active():

    exposure_card_id = request.args[0]

    mylogger.debug(message='exposure_card_id:%s' % exposure_card_id)

    exposure_card_mapper = EXPOSURE_CARD_MAPPER()
    person_mapper = PERSON_MAPPER()

    # getting the auth user
    auth_user = person_mapper.find(person_id=auth.user.id)[0]

    # desactivating the current active exposure card
    active_ec = auth_user.get_active_exposure_card()
    active_ec.archive = True
    mylogger.debug(message='desactivating:%s' % active_ec)
    exposure_card_mapper.update(active_ec)

    # activating the given exposure card
    given_ec = exposure_card_mapper.find(exposure_card_id=exposure_card_id)[0]
    given_ec.archive = False
    mylogger.debug(message='activating:%s' % given_ec)
    exposure_card_mapper.update(given_ec)

    redirect(URL(request.application, 'exposure_card', 'list.html'))
Exemplo n.º 2
0
def profile():

    mylogger.debug(message='request.vars:%s' %request.vars)

    person_mapper = PERSON_MAPPER()

    _person_id = auth.user.id

    _person = person_mapper.find(person_id=_person_id)[0] # an existing PERSON

    form = PERSON_FORM(person=_person, readonly_fields=[ 'email', 'creator', 'custom_permission', 'custom_entity', 'is_admin' ]).get_form()

    if form.accepts(request.vars, session, dbio=False):

        mylogger.debug(message='form.vars:%s' %form.vars)

        _person.first_name = form.vars['first_name']
        _person.last_name = form.vars['last_name']
        _person.contact = form.vars['contact']

        # saving the user
        person_mapper.save_or_update(_person)

        session.flash=cc.get_string("PERSON_UPDATED")

        redirect(URL(request.application, 'default', 'index'))

    else:

        return dict(form = form)
Exemplo n.º 3
0
def delete():

    person_mapper = PERSON_MAPPER()

    person_id = request.args[0]

    mylogger.debug(message='person_id:%s' %person_id)

    _person = person_mapper.find(person_id=person_id)[0]

    for child in  person_mapper.find(creator_id=person_id):
        child.creator = None
        person_mapper.save_or_update(child)

    person_mapper.delete(_person)

    redirect(URL(request.application, request.controller, 'list_reload.html', args=person_id, vars=request.vars))
Exemplo n.º 4
0
def list():

    person_mapper = PERSON_MAPPER()

    # getting the auth user
    auth_user = person_mapper.find(person_id=auth.user.id)[0]

    # and his exposure cards
    exposure_cards = sorted(auth_user.exposure_cards, key=lambda x: (x.creation_datetime))

    return dict(exposure_cards=exposure_cards)
Exemplo n.º 5
0
def create():

    person_mapper = PERSON_MAPPER()
    exposure_card_mapper = EXPOSURE_CARD_MAPPER()

    # getting the auth user
    auth_user = person_mapper.find(person_id=auth.user.id)[0]

    auth_user.create_exposure_card(title=strftime("%c"))
    person_mapper.update_exposure_card(auth_user)

    redirect(URL(request.application, 'exposure_card', 'list.html'))
Exemplo n.º 6
0
def list_user():
    '''
    lists users that belongs to the entity given in parameter
    '''
    mylogger.debug(message='request.vars:%s' % request.vars)

    person_mapper = PERSON_MAPPER()

    _entity_id = request.args[0]

    # getting the entity persons
    _persons = person_mapper.find(entity_id=_entity_id)

    return dict(persons=_persons)
Exemplo n.º 7
0
def _detail():

    mylogger.debug(message='request.vars:%s' %request.vars)

    person_mapper = PERSON_MAPPER()

    _person_id = request.args[0] if len(request.args) > 0 else None # an id or None

    if _person_id is None:
        # TODO: something cleaner
        return None

    _person = person_mapper.find(person_id=_person_id)[0] # an existing PERSON

    form = PERSON_FORM(person=_person, readonly=True).get_form()

    return dict(form=form, person=_person)
Exemplo n.º 8
0
def list_action():
    '''
    return actions for the PERSON given in parameter
    '''
    mylogger.debug(message='request.vars:%s' %request.vars)
    mylogger.debug(message='request.args:%s' %request.args)

    person_mapper = PERSON_MAPPER()

    _person_id = request.args[0]

    _person = person_mapper.find(person_id = _person_id)[0]

    _updatable_person = False
    _deletable_person = False
    _can_be_disabled_person = False

    # if the is_updatable method throws an HTTP exception, conditions are not met
    try:
        is_updatable()
        _updatable_person = True
        mylogger.debug(message='is updatable:%s' %_person_id)
    except HTTP:
        mylogger.debug(message='is not updatable:%s' %_person_id)

    # if the is_deletable method throws an HTTP exception, conditions are not met
    try:
        is_deletable()
        _deletable_person = True
        mylogger.debug(message='is deletable:%s' %_person_id)
    except HTTP:
        mylogger.debug(message='is not deletable:%s' %_person_id)

    # if the is_deletable method throws an HTTP exception, conditions are not met
    try:
        can_be_disabled()
        _can_be_disabled_person = True
        mylogger.debug(message='can be disabled:%s' %_person_id)
    except HTTP:
        mylogger.debug(message='can not be disabled:%s' %_person_id)

    return dict(person=_person,
                updatable_person=_updatable_person,
                deletable_person=_deletable_person,
                can_be_disabled_person=_can_be_disabled_person)
Exemplo n.º 9
0
def list():
    '''
    lists entities of the authenticated user
    '''
    mylogger.debug(message='request.vars:%s' % request.vars)

    entity_mapper = ENTITY_MAPPER()
    person_mapper = PERSON_MAPPER()

    # getting the authenticated user
    auth_user = person_mapper.find(person_id=auth.user.id)[0]

    # pagination stuff
    paginate_selector = PaginateSelector(anchor='main')
    paginator = Paginator(paginate=paginate_selector.paginate,
                          extra_vars={'v': 1},
                          anchor='main',
                          renderstyle=False)
    paginator.records = entity_mapper.count_all() if auth_user.is_all_entity() \
                                                  else auth_user.compute_nb_entities()
    paginate_info = PaginateInfo(paginator.page, paginator.paginate,
                                 paginator.records)

    # if the authenticated user is in all entities (ie. 'all_entity' entity)
    # retrieving the whole entitities
    if auth_user.is_all_entity():
        auth_user_entitites = entity_mapper.find(limitby=paginator.limitby())
    # else getting the authenticated user entitities
    else:
        auth_user_entitites = entity_mapper.find(person_id=auth.user.id,
                                                 limitby=paginator.limitby())
        # adding the all_entity entity for the whole users
        auth_user_entitites.insert(0, entity_mapper.find(role='all_entity')[0])
        mylogger.debug(message='auth_user_entitites:%s' % auth_user_entitites)

    # putting 'all_entity' at the top of the list
    auth_user_entitites = sorted(
        auth_user_entitites,
        key=lambda k: k.role if k.role != 'all_entity' else '0_%s' % k.role)

    return dict(entities=auth_user_entitites,
                paginator=paginator,
                paginate_selector=paginate_selector,
                paginate_info=paginate_info)
Exemplo n.º 10
0
def toogle_disable():

    mylogger.debug(message='request.vars:%s' %request.vars)

    person_mapper = PERSON_MAPPER()

    _person_id = request.args[0] # an id
    _person = person_mapper.find(person_id=_person_id)[0] # an existing PERSON

    if _person.is_disabled():
        _person.enable()
    else:
        _person.disable()

    # saving the user
    person_mapper.save_or_update(_person)

    session.flash=cc.get_string("PERSON_UPDATED")

    return json.dumps({'success': True})
Exemplo n.º 11
0
def create():
    '''
    create a new entity
    '''
    person_mapper = PERSON_MAPPER()
    auth_user = person_mapper.find(person_id=auth.user.id)[0]

    db.entity.role.default = ''
    form = crud.create(
        db.entity,
        onaccept=lambda form:
        (auth.add_membership(group_id=form.vars.id)
         if not auth_user.is_all_entity() else None, cc.clear_menu_cache()),
        next=URL(request.application,
                 request.controller,
                 'page_reload',
                 vars=request.vars))

    cc.clear_menu_cache()

    return dict(form=form)
Exemplo n.º 12
0
class STORAGE_MAPPER(object):

    def __init__(self):
        self.__product_mapper = PRODUCT_MAPPER()
        self.__person_mapper = PERSON_MAPPER()
        self.__store_location_mapper = STORE_LOCATION_MAPPER()
        self.__supplier_mapper = SUPPLIER_MAPPER()
        self.__unit_mapper = UNIT_MAPPER()

    def __storage_from_row(self, storage_row):
        return STORAGE(id=storage_row['id'],
                       volume_weight=storage_row['volume_weight'],
                       unit=lambda: self.__unit_mapper.find(unit_id=storage_row['unit']) \
                                       if storage_row['unit'] is not None \
                                       else None,
                       nb_items=storage_row['nb_items'],
                       creation_datetime=storage_row['creation_datetime'],
                       entry_datetime=storage_row['entry_datetime'],
                       exit_datetime=storage_row['exit_datetime'],
                       expiration_datetime=storage_row['expiration_datetime'],
                       opening_datetime=storage_row['opening_datetime'],
                       comment=storage_row['comment'],
                       barecode=storage_row['barecode'],
                       reference=storage_row['reference'],
                       batch_number=storage_row['batch_number'],
                       archive=storage_row['archive'],
                       to_destroy=storage_row['to_destroy'],
                       product=lambda: self.__product_mapper.find(product_id=storage_row['product'])[0],
                       person=lambda: self.__person_mapper.find(person_id=storage_row['person'])[0],
                       store_location=lambda: self.__store_location_mapper.find(store_location_id=storage_row['store_location'])[0],
                       supplier=lambda: self.__supplier_mapper.find(supplier_id=storage_row['supplier'])[0],
                       # storage history
                       modification_datetime=storage_row['modification_datetime'] if 'modification_datetime' in storage_row else None,

                       has_borrowing=lambda: self.has_borrowing(storage_row['id']),
                       retrieve_borrower=lambda: self.retrieve_borrower(storage_row['id']),
                       retrieve_borrow_datetime=lambda: self.retrieve_borrow_datetime(storage_row['id']),
                       retrieve_borrow_comment=lambda: self.retrieve_borrow_comment(storage_row['id']),
                       has_history=lambda: self.has_history(storage_row['id']))

    def find(self, storage_id=None, storage_history_id=None, entity_id=None, negate_entity_search=False, store_location_id=None, product_id=None, unit_reference_id=None, archive=False, history=False, limitby=None, orderby=None):

        my_logger.debug(message='storage_id:%s' % storage_id)

        assert (storage_history_id is not None and history) or (storage_history_id is None), "history must be True with a storage_history_id!"

        if history:
            table = 'storage_history'
        else:
            table = 'storage'

        query_list = []
        if storage_id is not None or storage_history_id is not None:
            if history:
                if storage_history_id is not None:
                    query_list.append(current.db.storage_history.id == storage_history_id)
                else:
                    query_list.append(current.db.storage_history.current_record == storage_id)
            else:
                if type(storage_id) is ListType:
                    query_list.append(current.db[table]['id'].belongs(storage_id))
                else:
                    query_list.append(current.db[table]['id'] == storage_id)
        if entity_id is not None:
            if type(entity_id) is ListType:
                if negate_entity_search:
                    query_list.append((current.db[table]['store_location']==current.db.store_location.id) &
                                      (~current.db.store_location.entity.belongs(tuple(entity_id))))
                else:
                    query_list.append((current.db[table]['store_location']==current.db.store_location.id) &
                                      (current.db.store_location.entity.belongs(tuple(entity_id))))
            else:
                if negate_entity_search:
                    query_list.append((current.db[table]['store_location']==current.db.store_location.id) &
                                      (~current.db.store_location.entity==entity_id))
                else:
                    query_list.append((current.db[table]['store_location']==current.db.store_location.id) &
                                      (current.db.store_location.entity==entity_id))
        if store_location_id is not None:
            query_list.append(current.db[table]['store_location'] == store_location_id)
        if product_id is not None:
            if type(product_id) is ListType:
                query_list.append(current.db[table]['product'].belongs(product_id))
            else:
                query_list.append(current.db[table]['product'] == product_id)
        if unit_reference_id is not None:
            query_list.append((current.db.storage.unit == current.db.unit.id) &
                              (current.db.unit.reference == unit_reference_id))

        if archive is not None:
            final_query = (current.db[table]['archive']==archive)
        else:
            final_query = (current.db[table]['id']>0)

        # building the final query
        for query in query_list:
            my_logger.debug(message='query:%s' % str(query))
            final_query = final_query.__and__(query)
        my_logger.debug(message='final_query:%s' % str(final_query))

        _storage_rows = current.db(final_query).select(current.db[table]['ALL'],
                left=(current.db.borrow.on(current.db[table]['id'] == current.db.borrow.storage)),
                limitby=limitby,
                orderby=orderby)

        my_logger.debug(message='len(_storage_rows):%s' % str(len(_storage_rows)))
        my_logger.debug(message='_storage_rows:%s' % str(_storage_rows))
        if len(_storage_rows) == 0:
            return []
        else:
            return [self.__storage_from_row(_storage_row) for _storage_row in _storage_rows]

    def has_history(self, storage_id):
        return current.db(current.db.storage_history.current_record==storage_id).count() > 0

    def has_borrowing(self, storage_id):
        return current.db(current.db.borrow.storage==storage_id).count() > 0

    def retrieve_borrower(self, storage_id):

        borrower = current.db((current.db.borrow.storage==storage_id) &
                              (current.db.borrow.borrower==current.db.person.id)).select(current.db.person.id).first()

        if borrower is not None:
            return PERSON_MAPPER().find(person_id=borrower.id)[0]
        else:
            return None

    def retrieve_borrow_comment(self, storage_id):

        borrow = current.db((current.db.borrow.storage==storage_id)).select(current.db.borrow.comment).first()

        if borrow is not None:
            return borrow.comment
        else:
            return None

    def retrieve_borrow_datetime(self, storage_id):

        borrow = current.db((current.db.borrow.storage==storage_id)).select(current.db.borrow.creation_datetime).first()

        if borrow is not None:
            return borrow.creation_datetime
        else:
            return None

    def delete(self, storage): # STORAGE type

        current.db(current.db.storage.id==storage.id).delete()
        current.db.commit()

    def update(self, storage): # STORAGE type

        row = current.db(current.db.storage.id==storage.id).select().first()

        row.update_record(product=storage.product.id,
                          store_location=storage.store_location.id,
                          volume_weight=storage.volume_weight,
                          unit=storage.unit.id if storage.unit is not None else None,
                          nb_items=storage.nb_items,
                          entry_datetime=storage.entry_datetime,
                          exit_datetime=storage.exit_datetime,
                          expiration_datetime=storage.expiration_datetime,
                          opening_datetime=storage.opening_datetime,
                          comment=storage.comment,
                          barecode=storage.barecode,
                          reference=storage.reference,
                          batch_number=storage.batch_number,
                          supplier=storage.supplier.id,
                          archive=storage.archive,
                          to_destroy=storage.to_destroy)

        current.db.commit()

    @staticmethod
    def create_barecode(product_id):
        """Return the generated barecode from a product
        """
        mylogger.debug(message='create_barecode')
        product_cas_number = current.db(current.db.product.id == product_id).select(current.db.product.cas_number).first().cas_number

        mylogger.debug(message='product_id:%s' % product_id)
        mylogger.debug(message='product_cas_number:%s' % product_cas_number)

        last_storage_id = current.db(current.db.storage).count()
        mylogger.debug(message='last_storage_id:%s' % last_storage_id)

        today = datetime.date.today()
        today = today.strftime('%Y%m%d')

        barecode = '%s_%s_%s.1' % (product_cas_number, today, last_storage_id)
        mylogger.debug(message='barecode:%s' % barecode)

        return barecode
Exemplo n.º 13
0
class PRODUCT_MAPPER(object):
    """Database entity product mapper.

    Request the database to create PRODUCT instances.
    """
    def __init__(self):
        self.__name_mapper = NAME_MAPPER()
        self.__person_mapper = PERSON_MAPPER()

    def __product_from_row(self, product_row):
        """Return a PRODUCT instance from a Row"""
        my_logger.debug(message='product_row:%s' % product_row)

        _broken_reference_list = []
        for table in ['physical_state',
                      'class_of_compounds',
                      'hazard_code',
                      'symbol',
                      'signal_word',
                      'risk_phrase',
                      'safety_phrase',
                      'hazard_statement',
                      'precautionary_statement']:

            my_logger.debug(message='table:%s' % table)
            _reference_value = product_row[table]

            if not type(_reference_value) is ListType:
                _reference_value = [_reference_value]

            for _ref in _reference_value:
                if _ref is not None:
                    _count = current.db(current.db[table]['id'] == _ref).count()
                    my_logger.debug(message='_ref:%s _count:%s' % (_ref, _count))
                    if _count == 0:
                        _broken_reference_list.append(table)
                        break

        return PRODUCT(id=product_row['id'],
                       cas_number=product_row['cas_number'],
                       ce_number=product_row['ce_number'],
                       creation_datetime=product_row['creation_datetime'],
                       person=lambda: self.__person_mapper.find(person_id=product_row['person'])[0]
                       if product_row['person'] is not None
                       else None,
                       name=self.__name_mapper.find(name_id=product_row['name'])
                       if product_row['name'] is not None
                       else None,
                       synonym=[self.__name_mapper.find(name_id=n_id) for n_id in product_row['synonym']]
                       if product_row['synonym'] is not None
                       else None,
                       restricted_access=product_row['restricted_access'],
                       specificity=product_row['specificity'],
                       td_formula=product_row['tdformula'],
                       empirical_formula=product_row['empirical_formula'],
                       linear_formula=product_row['linear_formula'],
                       msds=product_row['msds'],
                       physical_state=product_row['physical_state'],
                       class_of_compounds=product_row['class_of_compounds'],
                       hazard_code=product_row['hazard_code'],
                       symbol=product_row['symbol'],
                       signal_word=product_row['signal_word'],
                       risk_phrase=product_row['risk_phrase'],
                       safety_phrase=product_row['safety_phrase'],
                       hazard_statement=product_row['hazard_statement'],
                       precautionary_statement=product_row['precautionary_statement'],
                       disposal_comment=product_row['disposal_comment'],
                       remark=product_row['remark'],
                       is_cmr=product_row['is_cmr'],
                       is_radio=product_row['is_radio'],
                       cmr_cat=product_row['cmr_cat'],

                       is_in_entity_of=lambda user_id: self.is_in_entity_of(product_id=product_row['id'], user_id=user_id),
                       is_in_entity_except_of=lambda user_id: self.is_in_entity_except_of(product_id=product_row['id'], user_id=user_id),
                       has_storage_archived=lambda product_id, user_id: self.has_storage_archived(product_id=product_row['id'], user_id=user_id),
                       has_bookmark=lambda user_id: self.has_bookmark(product_id=product_row['id'], user_id=user_id),
                       has_history=self.has_history(product_id=product_row['id']),
                       is_orphan=self.is_orphan(product_id=product_row['id']),
                       bookmark=lambda user_id: self.bookmark(product_id=product_row['id'], user_id=user_id),
                       unbookmark=lambda user_id: self.unbookmark(product_id=product_row['id'], user_id=user_id),
                       has_broken_reference=len(_broken_reference_list)>0,
                       broken_reference_list=_broken_reference_list)

    def find(self, product_id=None, history=False, limitby=None, orderby=None):
        """Select products in the database.

           product_id -- search by product id or list of ids
           limitby -- query limit as defined by Web2py
           orderby -- query order as defined by Web2py
           returns: a list of PRODUCT
        """
        my_logger.debug(message='product_id:%s' % str(product_id))
        my_logger.debug(message='limitby:%s' % str(limitby))

        if history:
            product_table = 'product_history'
        else:
            product_table = 'product'

        # join with the name table to order by name.label
        # TODO: detect dynamically from the order by parameter the tables to join
        query_list = [current.db[product_table]['name'] == current.db.name.id]

        if product_id is not None:
            if type(product_id) is ListType:
                query_list.append(current.db[product_table]['id'].belongs(tuple(product_id)))
            else:
                query_list.append(current.db[product_table]['id'] == product_id)

        final_query = (current.db[product_table]['id'] > 0)

        # building the final query
        for query in query_list:
            my_logger.debug(message='query:%s' % str(query))
            final_query = final_query.__and__(query)
        my_logger.debug(message='final_query:%s' % final_query)

        # getting the ENTITY in the db
        _product_rows = current.db(final_query).select(current.db[product_table]['ALL'], limitby=limitby, orderby=orderby)

        if len(_product_rows) == 0:
            return []
        else:
            return [self.__product_from_row(_product_row) for _product_row in _product_rows]

    def has_storage_archived(self, product_id, user_id):
        """Return True if the product has archived storage for the given product in one of the
        entities of the given user.

        product_id -- the product id
        user_id -- the user id
        """
        if current.auth.has_permission(user_id=user_id, name='admin'):
            _has_storage_archives = current.db((current.db.storage.product == product_id) &
                                               (current.db.storage.archive == True) &
                                               (current.db.storage.store_location == current.db.store_location.id) &
                                               (current.db.store_location.entity == current.db.entity.id)).count() != 0
        else:
            _has_storage_archives = current.db((current.db.storage.product == product_id) &
                                               (current.db.storage.archive == True) &
                                               (current.db.storage.store_location == current.db.store_location.id) &
                                               (current.db.store_location.entity == current.db.entity.id) &
                                               (current.db.membership.user_id == user_id) &
                                               (current.db.entity.id == current.db.membership.group_id)).count() != 0

        return _has_storage_archives

    def is_in_entity_of(self, product_id, user_id):
        """Return True if the product is stored in one of the entities of the given user.

        product_id -- the product id
        user_id -- the user id
        """
        if current.auth.has_membership(user_id=user_id, role='all_entity'):
            _product_entities_count = current.db((current.db.product.id == product_id) &
                                                 (current.db.storage.product == current.db.product.id) &
                                                 (current.db.storage.archive == False)).count()
        else:
            _product_entities_count = current.db((current.db.product.id == product_id) &
                                                 (current.db.storage.product == current.db.product.id) &
                                                 (current.db.storage.archive == False) &
                                                 (current.db.storage.store_location == current.db.store_location.id) &
                                                 (current.db.store_location.entity == current.db.entity.id) &
                                                 (current.db.membership.user_id == user_id) &
                                                 (current.db.entity.id == current.db.membership.group_id)).count()

        return _product_entities_count > 0

    def is_in_entity_except_of(self, product_id, user_id):
        """Return True if the product is stored but not in one of the entities of the given user.

        product_id -- the product id
        user_id -- the user id
        """
	# Use a subrequest to avoid joining with membership which cause a problem when no user belongs to the other entity
	own_entity = [ row.id for row in current.db((current.db.membership.user_id == user_id) & (current.db.entity.id == current.db.membership.group_id)).select(current.db.entity.id) ]
        _product_entities_count = current.db((current.db.product.id == product_id) &
                                             (current.db.storage.product == current.db.product.id) &
                                             (current.db.storage.archive == False) &
                                             (current.db.storage.store_location == current.db.store_location.id) &
                                             ~(current.db.store_location.entity.belongs(own_entity))).count()

        my_logger.debug(message='_product_entities_count:%s' % _product_entities_count)

        return _product_entities_count > 0

    def has_bookmark(self, product_id, user_id):
        """Return True if the product has been bookmarked by the given user.

        product_id -- the product id
        user_id -- the user id
        """
        return current.db((current.db.bookmark.product == product_id) &
                          (current.db.bookmark.person == user_id)).count() > 0

    def has_history(self, product_id):
        """Return True if the product has been modified."""
        return current.db(current.db.product_history.current_record == product_id).count() != 0

    def is_orphan(self, product_id):
        """Return True if the product as no associated storage cards."""
        return current.db(current.db.storage.product == product_id).count() == 0

    def bookmark(self, product_id, user_id):
        """Bookmark a product for the given user.

        product_id -- the product id
        user_id -- the user id
        """
        if not self.has_bookmark(product_id, user_id):
            current.db.bookmark.insert(product=product_id, person=user_id)

    def unbookmark(self, product_id, user_id):
        """Remove product bookmark for the given user.

        product_id -- the product id
        user_id -- the user id
        """
        current.db((current.db.bookmark.product == product_id) &
                   (current.db.bookmark.person == user_id)).delete()

    @staticmethod
    def count_all():
        """Returns the total number of product cards.
        """
        return current.db(current.db.product.archive == False).count()
Exemplo n.º 14
0
def _create():

    mylogger.debug(message='request.vars:%s' %request.vars)
    mylogger.debug(message='request.args:%s' %request.args)

    person_mapper = PERSON_MAPPER()
    entity_mapper = ENTITY_MAPPER()

    _person_id = request.args[0] if len(request.args) > 0 else None # an id or None
    if _person_id is None:
        _person = person_mapper.create()
    else:
        _person = person_mapper.find(person_id=_person_id)[0]

    _all_entity_id = entity_mapper.find(role='all_entity')[0].id

    form = PERSON_FORM(person=_person).get_form()

    if form.accepts(request.vars, session, dbio=False):
        mylogger.debug(message='form.vars:%s' %form.vars)

        is_virtual = 'is_virtual' in request.vars
        mylogger.debug(message='is_virtual:%s' %is_virtual)

        _person.first_name = form.vars['first_name']
        _person.last_name = form.vars['last_name']
        _person.email = form.vars['email']
        _person.contact = form.vars['email'] # initializing the contact with the email address

        if 'custom_permission' in form.vars.keys():
            _person.permissions = [ PERMISSION(name=_permission_name) for _permission_name in form.vars['custom_permission'] ]

        if 'custom_entity' in form.vars.keys():
            _custom_entity = form.vars['custom_entity']
            if type(_custom_entity) is not ListType:
                _custom_entity = [ _custom_entity ]

            if str(_all_entity_id) in _custom_entity:
                _custom_entity = [ _all_entity_id ]
            _person.entities = [ entity_mapper.find(entity_id=_entity_id)[0] for _entity_id in _custom_entity ]

        if is_virtual:
            # this is a new person
            # sending an email to the creator
            message = cc.get_string("PERSON_VIRTUAL_CREATION_MESSAGE_BODY") %(_person.first_name + ' ' + \
                                                                              _person.last_name, \
                                                                              _person.email, \
                                                                              _person.password)

            _creator = person_mapper.find(person_id=auth.user.id)[0]

            # enabling the new person
            _person.enable()
            _person.virtual=True

            mail_sent = mail.send(_creator.email, subject= cc.get_string("PERSON_VIRTUAL_CREATION_MESSAGE_SUBJECT"), message=message)

            if mail_sent:
                # saving the user
                _new_person_id = person_mapper.save_or_update(_person)

                session.flash=cc.get_string("EMAIL_SENT")
            else:
                del(_person)

                session.flash=cc.get_string("ERROR") + mail.error

        # sending an email to the new user
        elif _person.new_person:

            message = cc.get_string("PERSON_CREATION_MESSAGE_BODY") %(_person.first_name + ' ' + \
                                                        _person.last_name, \
                                                        _person.email, \
                                                        settings['application_url'], \
                                                        _person.password_key)

            mail_sent = mail.send(_person.email, subject= cc.get_string("PERSON_CREATION_MESSAGE_SUBJECT"), message=message)

            if mail_sent:
                # saving the user
                _new_person_id = person_mapper.save_or_update(_person)

                session.flash=cc.get_string("EMAIL_SENT")
            else:
                del(_person)

                mylogger.error(message='mail.error:%s' % mail.error)
                session.flash=cc.get_string("ERROR") + str(mail.error)

                redirect(URL(request.application, request.controller, 'page_reload'))
        else:
            # saving the user
            _new_person_id = person_mapper.save_or_update(_person)

            session.flash=cc.get_string("PERSON_UPDATED")

        mylogger.debug(message='_person:%s' %_person)
        cc.clear_menu_cache()

        if _person_id is not None:
            redirect(URL(request.application, request.controller, 'list_reload', args=_person.id, vars=request.vars))
        else:
            redirect(URL(request.application, request.controller, 'page_reload', vars={'member': _new_person_id, 'display_by': 'person'}))

    else:

        return dict(form=form, all_entities_id=_all_entity_id)