Exemple #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'))
Exemple #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)
Exemple #3
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)
Exemple #4
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'))
Exemple #5
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)
Exemple #6
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)
Exemple #7
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)
    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
Exemple #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)
Exemple #10
0
def delete():

    exposure_card_mapper = EXPOSURE_CARD_MAPPER()
    person_mapper = PERSON_MAPPER()

    exposure_card = exposure_card_mapper.find(exposure_card_id=request.args[0])[0]

    exposure_card_mapper.delete(exposure_card)

    redirect(URL(request.application, 'exposure_card', 'list.html'))
Exemple #11
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})
Exemple #12
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)
Exemple #13
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))
Exemple #14
0
def list():

    '''
    lists users that belongs to the same ENTITY as the authenticated user
    '''
    mylogger.debug(message='request.vars:%s' %request.vars)

    person_mapper = PERSON_MAPPER()

    _person_id = auth.user.id

    # pagination stuff
    paginate_selector = PaginateSelector(anchor='main')
    paginator = Paginator(paginate=paginate_selector.paginate,
                          extra_vars={'v': 1},
                          anchor='main',
                          renderstyle=False)
    paginator.records = person_mapper.count_in_same_entity(person_id=_person_id)
    paginate_info = PaginateInfo(paginator.page, paginator.paginate, paginator.records)

    # getting the ENTITY PERSONs
    _persons = person_mapper.find_in_same_entity(person_id=_person_id, limitby=paginator.limitby())

    return dict(persons=_persons, paginator=paginator, paginate_selector=paginate_selector, paginate_info=paginate_info)
 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()
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
Exemple #17
0
def search():
    mylogger.debug(message='request.vars:%s' % str(request.vars))
    mylogger.debug(message='request.args:%s' % str(request.args))

    # some init
    query_list = []
    rows = None
    persons = None
    entities = None
    paginator = ''
    paginate_selector = ''
    paginate_info = ''
    nb_entries = 1  # number of results
    label = ''  # request title, ie. "products in the Chemical Lab.
    page = int(request.vars['page']) if 'page' in request.vars else 0
    result_per_page = int(request.vars['result_per_page']
                          ) if 'result_per_page' in request.vars else 10
    connected_user_entity_ids = db(
        db.entity.id.belongs([
            _entity.id
            for _entity in ENTITY_MAPPER().find(person_id=auth.user.id)
        ])).select(cacheable=True)

    # no way to pass the "keep_last_search" variable while clicking on a "x results per page" link
    if 'paginate' in request.vars:
        request.vars['keep_last_search'] = True

    #
    # restoring session vars if keep_last_search
    #
    if 'keep_last_search' in request.vars:
        if session.search_display_by:
            request.vars['display_by'] = session.search_display_by
        if session.search_person_id:
            request.vars['member'] = session.search_member
        if session.search_role:
            request.vars['role'] = session.search_role
        del request.vars['keep_last_search']

    #
    # and then cleaning up request vars
    #
    for key in ['search_display_by', 'search_member', 'search_role']:
        if session.has_key(key):
            mylogger.debug(message='key:%s' % str(key))
            mylogger.debug(message='session[key]:%s' % str(session[key]))
            del session[key]
    mylogger.debug(message='request.vars:%s' % str(request.vars))

    #
    # display by entity or person
    #
    if 'display_by' in request.vars and request.vars['display_by'] == 'person':
        session.search_display_by = 'person'
        display_by_person = True
    else:
        display_by_person = False

    session.search_result_per_page = result_per_page
    session.search_page = page

    #
    # building the request
    #
    if 'member' in request.vars and request.vars['member'] != '':

        mylogger.debug(message='case 1')
        session.search_member = request.vars['member']

        _person_entity_ids = db(
            db.entity.id.belongs([
                _entity.id for _entity in ENTITY_MAPPER().find(
                    person_id=request.vars['member'])
            ])).select(cacheable=True)
        _common_entity_ids = [
            _id for _id in _person_entity_ids
            if _id in connected_user_entity_ids
        ]

        if len(_common_entity_ids) > 0:
            if display_by_person:
                query_list.append(db.person.id == request.vars['member'])
            else:
                query_list.append(db.entity.id.belongs(_common_entity_ids))

    elif 'role' in request.vars and request.vars['role'] != '':

        mylogger.debug(message='case 2')
        session.search_role = request.vars['role']

        if display_by_person:
            query_list.append(
                (db.entity.role.like('%s%%' % request.vars['role'].strip()))
                | (db.entity.role.like('%%%s%%' %
                                       request.vars['role'].strip())))
            query_list.append(
                db.membership.group_id.belongs(connected_user_entity_ids))
            query_list.append(db.membership.group_id == db.entity.id)
            query_list.append(db.membership.user_id == db.person.id)
        else:
            query_list.append(
                (db.entity.role.like('%s%%' % request.vars['role'].strip()))
                | (db.entity.role.like('%%%s%%' %
                                       request.vars['role'].strip())))
            query_list.append(
                db.membership.group_id.belongs(connected_user_entity_ids))
            query_list.append(db.membership.group_id == db.entity.id)

    else:

        mylogger.debug(message='case 3')

        if display_by_person:
            # Need to get users without entities
            #query_list.append(db.membership.group_id.belongs(connected_user_entity_ids))
            query_list.append(db.membership.user_id == db.person.id)
        else:
            query_list.append(db.entity.id.belongs(connected_user_entity_ids))

        #request.vars['member'] = auth.user.id

    if len(query_list) != 0:

        finalQuery = query_list[0]

        for query in query_list[1:]:
            mylogger.debug(message='query:%s' % str(query))
            finalQuery = finalQuery.__and__(query)
        mylogger.debug(message='finalQuery:%s' % str(finalQuery))

        if display_by_person:
            _distinct = db.person.id
        else:
            _distinct = db.entity.id

        #
        # pagination
        #
        range_min = page * result_per_page
        range_max = range_min + result_per_page
        mylogger.debug(message='page:%s' % page)
        mylogger.debug(message='result_per_page:%s' % result_per_page)
        mylogger.debug(message='range_min:%s' % range_min)
        mylogger.debug(message='range_min:%s' % range_max)

        theset = db(finalQuery)
        nb_entries = theset.count(distinct=_distinct)
        mylogger.debug(message='nb_entries:%i' % nb_entries)

        paginate_selector = PaginateSelector(anchor='main')
        paginator = Paginator(paginate=paginate_selector.paginate,
                              extra_vars={'keep_last_search': True},
                              anchor='main',
                              renderstyle=False)
        paginator.records = nb_entries
        paginate_info = PaginateInfo(paginator.page, paginator.paginate,
                                     paginator.records)

        #
        # executing the query
        #
        _limitby = paginator.limitby()

        if display_by_person:
            _orderby = db.person.email
            select_fields = [db.person.ALL]
        else:
            _orderby = db.entity.role
            select_fields = [db.entity.ALL]

        allrows = theset.select(*select_fields,
                                orderby=_orderby,
                                distinct=True,
                                limitby=_limitby,
                                cacheable=True)

        rows = allrows
        mylogger.debug(message='len(rows):%s' % len(rows))
        for row in rows:
            mylogger.debug(message='row:%s' % row)

        if len(rows) > 0:
            if not display_by_person:
                entities = ENTITY_MAPPER().find(
                    entity_id=[row.id for row in rows], orderby=_orderby)
                mylogger.debug(message='len(entities):%s' % len(entities))
            else:
                persons = PERSON_MAPPER().find(
                    person_id=[row.id for row in rows], orderby=_orderby)
                mylogger.debug(message='len(persons):%s' % len(persons))

    #
    # building the search form
    #
    db.entity.role.widget = SQLFORM.widgets.string.widget
    #db.person.email.widget=CHIMITHEQUE_MULTIPLE_widget(db.person.email, configuration={'*': {'disable_validate': True}})

    # prepopulating form values + default values in the following form declaration
    db.entity.role.default = request.vars['role']
    #db.person.email.default = request.vars['member']
    db.entity.role.label = cc.get_string('SEARCH_ENTITY_NAME')
    #db.person.email.label = cc.get_string('SEARCH_PERSON_EMAIL')

    form = SQLFORM.factory(
        db.entity.role,
        Field('member',
              'reference person',
              default=request.vars['member'],
              label=cc.get_string('SEARCH_ENTITY_MEMBER'),
              widget=CHIMITHEQUE_MULTIPLE_widget(
                  db.person.email,
                  configuration={'*': {
                      'disable_validate': True
                  }})),
        _action='/%s/%s/search' % (request.application, request.controller),
        submit_button=cc.get_string("SEARCH"))

    return dict(form=form,
                persons=persons,
                entities=entities,
                nb_entries=nb_entries,
                label=label,
                paginator=paginator,
                paginate_selector=paginate_selector,
                paginate_info=paginate_info)
 def __init__(self):
     self.__name_mapper = NAME_MAPPER()
     self.__person_mapper = PERSON_MAPPER()
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()
    def __new__(cls, **kwargs):

        instance = super(PERSON_FORM, cls).__new__(cls)

        instance.person = kwargs.get('person')  # PERSON type
        instance.readonly = kwargs.get('readonly') or False
        instance.readonly_fields = kwargs.get('readonly_fields') or []
        my_logger.debug(message='instance.person:%s' % instance.person)
        my_logger.debug(message='instance.person.creator:%s' %
                        instance.person.creator)

        if instance.person is not None:
            current.db.person.first_name.default = instance.person.first_name
            if 'first_name' in instance.readonly_fields:
                current.db.person.first_name.writable = False
            current.db.person.last_name.default = instance.person.last_name
            if 'last_name' in instance.readonly_fields:
                current.db.person.last_name.writable = False
            current.db.person.email.default = instance.person.email
            if 'email' in instance.readonly_fields:
                current.db.person.email.writable = False
            current.db.person.contact.default = instance.person.contact
            if 'contact' in instance.readonly_fields:
                current.db.person.contact.writable = False

            current.db.person.email.requires = [
                IS_NOT_EMPTY(),
                IS_EMAIL(),
                IS_NOT_IN_DB(
                    current.db(current.db.person.id != instance.person.id),
                    current.db.person.email)
            ]

            # creator is a computed field and then not shown by web2py
            # we need to add it manually
            instance.form = SQLFORM.factory(Field('creator',
                                                  'string',
                                                  writable=not 'creator' in instance.readonly_fields,
                                                  label=cc.get_string("PERSON_CREATOR_LABEL"),
                                                  default=instance.person.creator.email \
                                                            if instance.person.creator is not None \
                                                            else ''),  # creator should exists - backward compatibility

                                            current.db.person,

                                    Field('is_all_entity',
                                          'boolean',
                                          label=cc.get_string("PERSON_IS_ALL_ENTITY_LABEL"),
                                          comment=cc.get_string("PERSON_IS_ALL_ENTITY_COMMENT"),
                                          represent=lambda r: current.T(str(instance.person.is_all_entity())),
                                          # disabled if the user is not admin
                                          readable=current.auth.has_membership('all_entity') or \
                                                    current.auth.has_membership('admin_entity') or \
                                                    current.auth.has_permission('admin'),  # admin_ENTITY: backward compatibility
                                          writable=(current.auth.has_membership('all_entity') or \
                                          current.auth.has_membership('admin_entity') or \
                                          current.auth.has_permission('admin')) and \
                                          not 'custom_entity' in instance.readonly_fields,
                                          # for an update request, pre populating the widget if the user is in all entities
                                          default=instance.person.is_all_entity(),
                                          ),

                                       Field('custom_entity',
                                            'list:reference entity',
                                            comment=cc.get_string("PERSON_ENTITY_COMMENT"),
                                            label=cc.get_string("PERSON_ENTITY_LABEL"),
                                            required=True,
                                            notnull=True,
                                            writable=not 'custom_entity' in instance.readonly_fields,
                                            # for an update request, pre populating the widget given the user entities
                                            default=[_entity.id for _entity in instance.person.entities] \
                                                      if instance.person.entities is not None \
                                                      else [],
                                            requires=[IS_IN_DB_AND_USER_ENTITY(current.db(current.db.entity.id > 0),
                                                                               current.db.entity.id,
                                                                               current.db.entity._format, multiple=True),
                                                       IS_ONE_SELECTED(db=current.db, table=current.db.entity, table_set=~current.db.entity.role.like('user_%'))],
                                            represent=lambda r: XML(' <br/>'.join(['%s' % (e.name) \
                                                                    for e in instance.person.entities])) \
                                            if (not instance.person.is_all_entity() and instance.person.entities is not None) else 'X',

                                            widget=lambda field, value: SQLFORM.widgets.multiple.widget(field, value, _class='required')),

                                        Field('is_admin',
                                              'boolean',
                                              label=cc.get_string("PERSON_IS_ADMIN_LABEL"),
                                              comment=cc.get_string("PERSON_IS_ADMIN_COMMENT"),
                                              represent=lambda r: current.T(str(instance.person.is_admin())),
                                              # disabled if the user is not admin
                                              readable=current.auth.has_permission('admin'),
                                              writable=current.auth.has_permission('admin') and not 'is_admin' in instance.readonly_fields,
                                              # for an update request, pre populating the widget if the user is admin
                                              default=instance.person.is_admin(),
                                              ),

                                        Field('custom_permission',
                                              'string',  # this does not matter given that we define our own permission widget
                                              label=cc.get_string("PERSON_ENTITY_PERMISSION_LABEL"),
                                              required=True,
                                              notnull=True,
                                              writable=not 'custom_permission' in instance.readonly_fields,
                                              # for an update request, pre populating the widget given the user permissions
                                              default=[_permission.name for _permission in instance.person.permissions],
                                              comment=cc.get_string("PERSON_ENTITY_PERMISSION_COMMENT"),
                                              requires=IS_CHIMITHEQUE_PERMISSION(),
                                              represent=lambda r: PermissionWidget.represent(r),
                                              widget=lambda field, value: PermissionWidget.widget(field,
                                                                                                value,
                                                                                                _class='required',
                                                                                                auth_user_permissions=[_permission.name for _permission in PERSON_MAPPER().find_permissions(current.auth.user.id)] \
                                                                                                                      if not current.auth.has_permission('admin') \
                                                                                                                      else None)),

                                       readonly=instance.readonly,
                                       comments=not instance.readonly,
                                       next=URL(current.request.application, 'user', 'list'),
                                       submit_button=cc.get_string("SUBMIT")
                                       )
        else:

            instance.form = SQLFORM.factory(
                Field('None', 'string', writable=False, readable=False))

        return instance
Exemple #21
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)