Exemplo n.º 1
0
    def search_by_name(self):
        """ Поиск пользователя по его имени и получение списка карт,
        соответствующих событию."""
        def callback(user):
            self.last_user_uuid = user.get('uuid')

        self.dialog = Searching(self,
                                mode='client',
                                apply_title=self.tr('Register'))
        self.dialog.setModal(True)
        self.dialog.setCallback(callback)
        if QDialog.Accepted == self.dialog.exec_():
            return self.visit_register(self.last_user_uuid)
Exemplo n.º 2
0
    def visitEventManual(self):
        """
        Register the visit manually through searching a client.
        """

        def callback(user_id):
            self.user_id = user_id

        params = {
            'http': self.http,
            'static': self.parent.static,
            'mode': 'client',
            'apply_title': _('Register'),
            }
        self.dialog = Searching(self, params)
        self.dialog.setModal(True)
        self.dialog.setCallback(callback)
        dlgStatus = self.dialog.exec_()

        if QDialog.Accepted == dlgStatus:
            params = {'event_id': self.schedule['id'],
                      'client_id': self.user_id}
            if not self.http.request('/manager/register_visit/', params):
                QMessageBox.critical(self, _('Register visit'), _('Unable to register: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response:
                message = _('The client is registered on this event.')
            else:
                error_msg = self.http.error_msg
                message = _('Unable to register the visit!\nReason:\n%s') % error_msg
            QMessageBox.information(self, _('Client registration'), message)
Exemplo n.º 3
0
    def search_by_name(self):
        """ Поиск пользователя по его имени и получение списка карт,
        соответствующих событию."""

        def callback(user):
            self.last_user_uuid = user.get('uuid')

        self.dialog = Searching(self, mode='client', apply_title=self.tr('Register'))
        self.dialog.setModal(True)
        self.dialog.setCallback(callback)
        if QDialog.Accepted == self.dialog.exec_():
            return self.visit_register(self.last_user_uuid)
Exemplo n.º 4
0
    def user_search_name(self, klass, mode):
        def callback(user):
            self.user = user

        if self.params.logged_in:
            self.dialog = Searching(self, mode=mode)
            self.dialog.setModal(True)
            self.dialog.setCallback(callback)
            if QDialog.Accepted == self.dialog.exec_():
                self.dialog = klass(self)
                self.dialog.setModal(True)
                self.dialog.initData(self.user)
                self.dialog.exec_()
                del (self.dialog)
Exemplo n.º 5
0
class EventInfo(UiDlgTemplate):

    ui_file = 'uis/dlg_event_info.ui'
    params = ParamStorage()
    schedule = None  # кэшируем здесь данные от сервера
    event_object = None
    event_index = None

    def __init__(self, parent=None):
        self.stream = self.params.http
        UiDlgTemplate.__init__(self, parent)

    def setupUi(self):
        UiDlgTemplate.setupUi(self)

        self.connect(self.buttonClose, SIGNAL('clicked()'), self.close)
        self.connect(self.buttonVisitors, SIGNAL('clicked()'),
                     self.show_visitors)
        self.connect(self.buttonVisitRFID, SIGNAL('clicked()'),
                     self.search_by_rfid)
        self.connect(self.buttonVisitManual, SIGNAL('clicked()'),
                     self.search_by_name)
        self.connect(self.buttonRemove, SIGNAL('clicked()'), self.removeEvent)
        self.connect(self.buttonChange, SIGNAL('clicked()'),
                     self.change_coaches)

        # временно отключим кнопку удаления
        self.buttonRemove.setDisabled(True)
        self.buttonChange.setDisabled(True)

    def initData(self, obj, index):
        """
        Метод инициализации диалога.
        """
        self.event_object = obj
        self.event_index = index

        self.editStyle.setText(self.event_object.styles)
        self.editPriceCategory.setText(self.event_object.category)
        self.editCoaches.setText(self.event_object.coaches)

        begin = self.event_object.begin
        end = self.event_object.end
        self.editBegin.setDateTime(QDateTime(begin))
        self.editEnd.setDateTime(QDateTime(end))

        for index, room in self.params.static.get('rooms_by_index').items():
            self.comboRoom.addItem(room.get('title'), QVariant(index))

        self.comboRoom.setCurrentIndex(
            self.params.static.get('rooms_by_uuid').get(
                self.event_object.room_uuid))

        statuses = dict(
            enumerate([
                self.tr('Unknown'),
                self.tr('Waits'),
                self.tr('Occurred'),
                self.tr('Cancelled')
            ]))
        self.editStatus.setText(
            statuses.get(self.event_object.fixed, self.tr('Unknown')))

        # disable controls for events in the past
        is_past = begin < datetime.now()
        is_rent = self.event_object.prototype == self.event_object.RENT
        self.buttonRemove.setDisabled(is_past or is_rent)
        self.buttonVisitRFID.setDisabled(is_past or is_rent)
        self.buttonVisitManual.setDisabled(is_past or is_rent)
        self.buttonChange.setDisabled(is_past or is_rent)
        self.buttonVisitors.setDisabled(is_rent)

    def show_visitors(self):
        dialog = ShowVisitors(self)
        dialog.setModal(True)
        dialog.initData(self.event_object.uuid)
        dialog.exec_()

    def search_by_rfid(self):
        """ Поиск пользователя по RFID и получение списка карт,
        соответствующих событию."""
        def callback(rfid):
            self.rfid_id = rfid

        # диалог rfid считывателя
        dialog = WaitingRFID(self, callback=callback)
        dialog.setModal(True)
        if QDialog.Accepted == dialog.exec_():
            http = self.params.http
            if not http.request(
                    '/api/client/%s/' % self.rfid_id, 'GET', force=True):
                QMessageBox.critical(
                    self, self.tr('Client info'),
                    self.tr('Unable to fetch: %s') % http.error_msg)
                return
            response = http.parse()

            if 0 == len(response):
                QMessageBox.warning(self, self.tr('Warning'),
                                    self.tr('This RFID belongs to nobody.'))
                return False
            else:
                self.last_user_uuid = response[0].get('uuid')
                return self.visit_register(self.last_user_uuid)

    def search_by_name(self):
        """ Поиск пользователя по его имени и получение списка карт,
        соответствующих событию."""
        def callback(user):
            self.last_user_uuid = user.get('uuid')

        self.dialog = Searching(self,
                                mode='client',
                                apply_title=self.tr('Register'))
        self.dialog.setModal(True)
        self.dialog.setCallback(callback)
        if QDialog.Accepted == self.dialog.exec_():
            return self.visit_register(self.last_user_uuid)

    def select_voucher_list(self, *args, **kwargs):
        u"""Получает список подходящих ваучеров."""
        url = '/api/voucher/%(event_id)s/%(client_id)s/%(start)s/' % kwargs
        if not self.stream.request(url, 'GET', force=True):
            raise UnableSendRequest()
        status, data = self.stream.piston()
        if not u'ALL_OK' == status:
            raise BadResponse(status)
        if 0 == len(data):
            raise EmptyVoucherList()
        return data

    def visit_register(self, user_uuid):
        u"""Регистрирует посещение события."""
        title = self.tr('Client Registration')
        event = self.event_object
        # получаем список подходящих ваучеров
        try:
            voucher_list = self.select_voucher_list(
                client_id=user_uuid,
                event_id=event.uuid,
                start=event.begin.strftime('%Y%m%d%H%M%S'))
        except (UnableSendRequest, BadResponse, EmptyVoucherList):
            msg = self.tr('No voucher for this visit.\n\nBuy one.')
            QMessageBox.information(self, title, msg)
            return False

        # показываем список менеджеру, пусть выбирает
        def callback(voucher_uuid):
            self.voucher_uuid = voucher_uuid

        def make_title(voucher):
            out = []
            card = voucher.get('_card_cache')
            if card:
                out.append(card.get('title'))
            category = voucher.get('_category_cache')
            if category:
                out.append(category.get('title'))
            return ' - '.join(out)

        dialog = WizardListDlg(params={
            'button_back': self.tr('Cancel'),
            'button_next': self.tr('Ok')
        })
        dialog.setModal(True)
        dialog.prefill(self.tr('Choose the Voucher'),
                       [(v['uuid'], make_title(v)) for v in voucher_list],
                       callback)
        # ваучер выбран, регистрируем посещение
        if QDialog.Accepted == dialog.exec_():
            params = dict(action='VISIT',
                          event=event.uuid,
                          voucher=self.voucher_uuid)
            if not self.stream.request('/api/voucher/', 'PUT', params):
                QMessageBox.warning(
                    self, title, '%s: %i\n\n%s\n\n%s' %
                    (self.tr('Error'), ERR_EVENT_REGISTERVISIT,
                     self.tr('Unable to register the visit: %s') %
                     http.error_msg, self.tr('Call support team!')))
                return False
            status, data = self.stream.piston()
            print status, data
            if u'CREATED' == status:
                msg = self.tr('The client has been registered for this event.')
                QMessageBox.information(self, title, msg)
                # распечатаем чек
                visit_uuid = data.get('uuid')
                self.print_label(visit_uuid)
                return True
            elif u'DUPLICATE_ENTRY' == status:
                msg = self.tr(
                    'The client is already registered for this event.')
            else:
                msg = self.tr('Unable to register!\nStatus: %s') % status
            QMessageBox.warning(self, title, msg)
        return False

    def print_label(self, visit_uuid):
        title = self.tr('Print')
        http = self.params.http
        if not http.request('/api/visit/%s/' % visit_uuid, 'GET', force=True):
            QMessageBox.warning(
                self, title, '%s: %i\n\n%s\n\n%s' %
                (self.tr('Error'), ERR_EVENT_PRINTLABEL,
                 self.tr('Unable to prepare label: %s') % http.error_msg,
                 self.tr('Call support team!')))
            return False
        status, response = http.piston()
        print status, response
        self.params.printer.hardcopy(response)

    def changeRoom(self, new_index):
        # Room change:
        # 1. The choosen room is empty inside whole time period.
        #    Change a room for the event.
        # 2. The choosen room is busy at all, i.e. two event are equal in time.
        #    Change the rooms.
        # 3. The choosen room is busy partially.
        #    Cancel the change, raise message.
        if new_index != self.current_room_index:
            # make room checking
            #
            pass

    def removeEvent(self):
        reply = QMessageBox.question(
            self, self.tr('Event remove'),
            self.tr('Are you sure to remove this event from the calendar?'),
            QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            params = {'id': self.schedule['id']}
            if not self.http.request('/manager/cal_event_del/', params):
                QMessageBox.critical(
                    self, self.tr('Event deletion'),
                    self.tr('Unable to delete: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response:
                index = self.comboRoom.currentIndex()
                room_id, ok = self.comboRoom.itemData(index).toInt()
                model = self.parent.schedule.model()
                model.remove(self.event_object, self.event_index, True)
                QMessageBox.information(self, self.tr('Event removing'),
                                        self.tr('Complete.'))
                self.accept()
            else:
                QMessageBox.information(
                    self, self.tr('Event removing'),
                    self.tr('Unable to remove this event!'))

    def change_coaches(self):
        """
        Метод реализует функционал замены преподавателей для события.
        """
        title = self.tr('Coaches')
        http = self.params.http
        if not http.request('/api/coach/', 'GET'):
            QMessageBox.critical(
                self, title,
                self.tr('Unable to fetch: %s') % http.error_msg)
            return
        status, coach_list = http.piston()
        if 'ALL_OK' == status:

            def coaches_callback(uuid_list):
                self.event_object.set_coaches(
                    filter(lambda x: x.get('uuid') in uuid_list, coach_list))

            dialog = ShowCoaches(self, callback=coaches_callback)
            dialog.setModal(True)
            dialog.initData(self.event_object, coach_list)
            if QDialog.Accepted == dialog.exec_():
                # отображаем изменения на интерфейсе
                self.initData(self.event_object, self.event_index)

                # update schedule model to immediate refresh this event
                model = self.event_index.model()
                model.change(self.event_object, self.event_index)
Exemplo n.º 6
0
class EventInfo(UiDlgTemplate):

    ui_file = 'uis/dlg_event_info.ui'
    title = _('Event\'s information')

    def __init__(self, parent=None, params=dict()):
        UiDlgTemplate.__init__(self, parent, params)

    def setupUi(self):
        UiDlgTemplate.setupUi(self)

        self.connect(self.buttonClose,       SIGNAL('clicked()'), self.close)
        self.connect(self.buttonVisitors,    SIGNAL('clicked()'), self.showVisitors)
        self.connect(self.buttonVisitRFID,   SIGNAL('clicked()'), self.visitEventRFID)
        self.connect(self.buttonVisitManual, SIGNAL('clicked()'), self.visitEventManual)
        self.connect(self.buttonRemove,      SIGNAL('clicked()'), self.removeEvent)
        self.connect(self.buttonFix,         SIGNAL('clicked()'), self.fixEvent)
        self.connect(self.buttonChange,      SIGNAL('clicked()'), self.changeCoaches)
        self.connect(self.comboFix, SIGNAL('currentIndexChanged(int)'),
                     lambda: self.buttonFix.setDisabled(False))

    def enableComboFix(self, index):
        self.buttonFix.setDisabled(False)

    def initData(self, obj, index):
        """ Use this method to initialize the dialog. """

        self.schedule_object = obj
        self.schedule_index = index

        # get the event's information
        if not self.http.request('/manager/get_event_info/', {'id': self.schedule_object.id}):
            QMessageBox.critical(self, _('Event info'), _('Unable to fetch: %s') % self.http.error_msg)
            return
        default_response = None
        response = self.http.parse(default_response)

        self.schedule = response['info']
        event = self.schedule['event']
        status = self.schedule.get('status', 0) # 0 means wainting
        room = self.schedule['room']
        self.editStyle.setText(event['dance_styles'])
        self.editPriceCategory.setText( event['price_category']['title'] )

        if self.schedule_object.isTeam(): # get coaches list from schedule, not from team, because of exchange
            coaches_list = self.schedule.get('coaches', None)
            if coaches_list:
                title = ', '.join([i['name'] for i in coaches_list])
            else:
                title = _('Unknown')
            self.editCoaches.setText(title)

        begin = __(self.schedule['begin_datetime'])
        end = __(self.schedule['end_datetime'])
        self.editBegin.setDateTime(QDateTime(begin))
        self.editEnd.setDateTime(QDateTime(end))

        current_id = int(room['id'])
        self.current_room_index = current_id - 1
        for title, color, room_id in self.parent.rooms:
            self.comboRoom.addItem(title, QVariant(room_id))
            if id == current_id + 100:
                current = self.comboRoom.count() - 1
        self.comboRoom.setCurrentIndex(self.current_room_index)

        # disable controls for events in the past
        is_past = begin < datetime.now()
        self.buttonRemove.setDisabled(is_past)
        self.buttonVisitRFID.setDisabled(is_past)
        self.buttonVisitManual.setDisabled(is_past)
        self.buttonChange.setDisabled(is_past)

        self._init_fix(status)

    def _init_fix(self, current):
        """ Helper method to init eventFix combo."""
        for id, title in self.parent.static['event_fix_choice']:
            self.comboFix.addItem(title, QVariant(id))
        self.comboFix.setCurrentIndex(int(current))
        self.buttonFix.setDisabled(True)

    def showVisitors(self):
        dialog = ShowVisitors(self, {'http': self.http})
        dialog.setModal(True)
        dialog.initData(self.schedule['id'])
        dialog.exec_()

    def visitEventRFID(self):
        """
        Register the visit by client's RFID label.
        """

        def callback(rfid):
            self.rfid_id = rfid

        params = {
            'http': self.http,
            'callback': callback,
            }
        dialog = WaitingRFID(self, params)
        dialog.setModal(True)
        dlgStatus = dialog.exec_()

        if QDialog.Accepted == dlgStatus:
            user_id = None

            # get user_id by rfid_code
            params = {'rfid_code': self.rfid_id, 'mode': 'client'}
            if not self.http.request('/manager/get_client_info/', params):
                QMessageBox.critical(self, _('Client info'), _('Unable to fetch: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response and 'info' in response:
                user_id = response['info'].get('id', None)
            else:
                QMessageBox.critical(self, _('Client registration'),
                                     _('Could not find user by RFID!'))
                return

            # register user on the event
            params = {'event_id': self.schedule['id'],
                      'client_id': user_id}
            if not self.http.request('/manager/register_visit/', params):
                QMessageBox.critical(self, _('Register visit'), _('Unable to register: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response:
                message = _('The client is registered on this event.')
            else:
                error_msg = self.http.error_msg
                message = _('Unable to register the visit!\nReason:\n%s') % error_msg
            QMessageBox.information(self, _('Client registration'), message)

    def visitEventManual(self):
        """
        Register the visit manually through searching a client.
        """

        def callback(user_id):
            self.user_id = user_id

        params = {
            'http': self.http,
            'static': self.parent.static,
            'mode': 'client',
            'apply_title': _('Register'),
            }
        self.dialog = Searching(self, params)
        self.dialog.setModal(True)
        self.dialog.setCallback(callback)
        dlgStatus = self.dialog.exec_()

        if QDialog.Accepted == dlgStatus:
            params = {'event_id': self.schedule['id'],
                      'client_id': self.user_id}
            if not self.http.request('/manager/register_visit/', params):
                QMessageBox.critical(self, _('Register visit'), _('Unable to register: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response:
                message = _('The client is registered on this event.')
            else:
                error_msg = self.http.error_msg
                message = _('Unable to register the visit!\nReason:\n%s') % error_msg
            QMessageBox.information(self, _('Client registration'), message)

    def changeRoom(self, new_index):
        # Room change:
        # 1. The choosen room is empty inside whole time period.
        #    Change a room for the event.
        # 2. The choosen room is busy at all, i.e. two event are equal in time.
        #    Change the rooms.
        # 3. The choosen room is busy partially.
        #    Cancel the change, raise message.
        if new_index != self.current_room_index:
            # make room checking
            #
            pass

    def removeEvent(self):
        reply = QMessageBox.question(
            self, _('Event remove'),
            _('Are you sure to remove this event from the calendar?'),
            QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            params = {'id': self.schedule['id']}
            if not self.http.request('/manager/cal_event_del/', params):
                QMessageBox.critical(self, _('Event deletion'), _('Unable to delete: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response:
                index = self.comboRoom.currentIndex()
                room_id, ok = self.comboRoom.itemData(index).toInt()
                model = self.parent.schedule.model()
                model.remove(self.schedule_object, self.schedule_index, True)
                QMessageBox.information(self, _('Event removing'),
                                        _('Complete.'))
                self.accept()
            else:
                QMessageBox.information(self, _('Event removing'),
                                        _('Unable to remove this event!'))

    def fixEvent(self):
        index = self.comboFix.currentIndex()
        fix_id, ok = self.comboFix.itemData(index).toInt()

        params = {'event_id': self.schedule['id'],
                  'fix_id': fix_id}
        if not self.http.request('/manager/register_fix/', params):
            QMessageBox.critical(self, _('Register fix'), _('Unable to fix: %s') % self.http.error_msg)
            return
        default_response = None
        response = self.http.parse(default_response)
        if response:
            message = _('The event has been fixed.')

            self.schedule_object.set_fixed(fix_id)
            model = self.parent.schedule.model()
            model.change(self.schedule_object, self.schedule_index)
            self.buttonFix.setDisabled(True)
        else:
            message = _('Unable to fix this event.')
        QMessageBox.information(self, _('Event fix registration'), message)

    def changeCoaches(self):

        def coaches_callback(coach_id_list):
            from library import dictlist_keyval
            # get the coach descriptions' list using its id list
            coaches_dictlist = dictlist_keyval(self.parent.static['coaches'], 'id', coach_id_list)
            self.schedule_object.set_coaches(coaches_dictlist)

        dialog = ShowCoaches(self, {'http': self.http})
        dialog.setCallback(coaches_callback)
        dialog.setModal(True)
        dialog.initData(self.schedule)
        dialog.exec_()

        # update the dialog's info
        self.initData(self.schedule_object, self.schedule_index)

        # update schedule model to immediate refresh this event
        model = self.parent.schedule.model()
        model.change(self.schedule_object, self.schedule_index)
Exemplo n.º 7
0
class EventInfo(UiDlgTemplate):

    ui_file = 'uis/dlg_event_info.ui'
    params = ParamStorage()
    schedule = None # кэшируем здесь данные от сервера
    event_object = None
    event_index = None

    def __init__(self, parent=None):
        self.stream = self.params.http
        UiDlgTemplate.__init__(self, parent)

    def setupUi(self):
        UiDlgTemplate.setupUi(self)

        self.connect(self.buttonClose,       SIGNAL('clicked()'), self.close)
        self.connect(self.buttonVisitors,    SIGNAL('clicked()'), self.show_visitors)
        self.connect(self.buttonVisitRFID,   SIGNAL('clicked()'), self.search_by_rfid)
        self.connect(self.buttonVisitManual, SIGNAL('clicked()'), self.search_by_name)
        self.connect(self.buttonRemove,      SIGNAL('clicked()'), self.removeEvent)
        self.connect(self.buttonChange,      SIGNAL('clicked()'), self.change_coaches)

        # временно отключим кнопку удаления
        self.buttonRemove.setDisabled(True)
        self.buttonChange.setDisabled(True)

    def initData(self, obj, index):
        """
        Метод инициализации диалога.
        """
        self.event_object = obj
        self.event_index = index

        self.editStyle.setText(self.event_object.styles)
        self.editPriceCategory.setText(self.event_object.category)
        self.editCoaches.setText(self.event_object.coaches)

        begin = self.event_object.begin
        end = self.event_object.end
        self.editBegin.setDateTime(QDateTime(begin))
        self.editEnd.setDateTime(QDateTime(end))

        for index, room in self.params.static.get('rooms_by_index').items():
            self.comboRoom.addItem(room.get('title'), QVariant(index))

        self.comboRoom.setCurrentIndex(self.params.static.get('rooms_by_uuid').get(self.event_object.room_uuid))

        statuses = dict(enumerate([
            self.tr('Unknown'),
            self.tr('Waits'),
            self.tr('Occurred'),
            self.tr('Cancelled')
            ]))
        self.editStatus.setText(statuses.get(self.event_object.fixed, self.tr('Unknown')))

        # disable controls for events in the past
        is_past = begin < datetime.now()
        is_rent = self.event_object.prototype == self.event_object.RENT
        self.buttonRemove.setDisabled(is_past or is_rent)
        self.buttonVisitRFID.setDisabled(is_past or is_rent)
        self.buttonVisitManual.setDisabled(is_past or is_rent)
        self.buttonChange.setDisabled(is_past or is_rent)
        self.buttonVisitors.setDisabled(is_rent)

    def show_visitors(self):
        dialog = ShowVisitors(self)
        dialog.setModal(True)
        dialog.initData(self.event_object.uuid)
        dialog.exec_()

    def search_by_rfid(self):
        """ Поиск пользователя по RFID и получение списка карт,
        соответствующих событию."""

        def callback(rfid):
            self.rfid_id = rfid

        # диалог rfid считывателя
        dialog = WaitingRFID(self, callback=callback)
        dialog.setModal(True)
        if QDialog.Accepted == dialog.exec_():
            http = self.params.http
            if not http.request('/api/client/%s/' % self.rfid_id, 'GET', force=True):
                QMessageBox.critical(self, self.tr('Client info'), self.tr('Unable to fetch: %s') % http.error_msg)
                return
            response = http.parse()

            if 0 == len(response):
                QMessageBox.warning(self, self.tr('Warning'), self.tr('This RFID belongs to nobody.'))
                return False
            else:
                self.last_user_uuid = response[0].get('uuid')
                return self.visit_register(self.last_user_uuid)

    def search_by_name(self):
        """ Поиск пользователя по его имени и получение списка карт,
        соответствующих событию."""

        def callback(user):
            self.last_user_uuid = user.get('uuid')

        self.dialog = Searching(self, mode='client', apply_title=self.tr('Register'))
        self.dialog.setModal(True)
        self.dialog.setCallback(callback)
        if QDialog.Accepted == self.dialog.exec_():
            return self.visit_register(self.last_user_uuid)

    def select_voucher_list(self, *args, **kwargs):
        u"""Получает список подходящих ваучеров."""
        url = '/api/voucher/%(event_id)s/%(client_id)s/%(start)s/' % kwargs
        if not self.stream.request(url, 'GET', force=True):
            raise UnableSendRequest()
        status, data = self.stream.piston()
        if not u'ALL_OK' == status:
            raise BadResponse(status)
        if 0 == len(data):
            raise EmptyVoucherList()
        return data

    def visit_register(self, user_uuid):
        u"""Регистрирует посещение события."""
        title = self.tr('Client Registration')
        event = self.event_object
        # получаем список подходящих ваучеров
        try:
            voucher_list = self.select_voucher_list(
                client_id=user_uuid, event_id=event.uuid,
                start=event.begin.strftime('%Y%m%d%H%M%S'))
        except (UnableSendRequest, BadResponse, EmptyVoucherList):
            msg = self.tr('No voucher for this visit.\n\nBuy one.')
            QMessageBox.information(self, title, msg)
            return False

        # показываем список менеджеру, пусть выбирает
        def callback(voucher_uuid):
            self.voucher_uuid = voucher_uuid
        def make_title(voucher):
            out = []
            card = voucher.get('_card_cache')
            if card:
                out.append( card.get('title') )
            category = voucher.get('_category_cache')
            if category:
                out.append( category.get('title') )
            return ' - '.join(out)

        dialog = WizardListDlg(params={'button_back': self.tr('Cancel'), 'button_next': self.tr('Ok')})
        dialog.setModal(True)
        dialog.prefill(self.tr('Choose the Voucher'),
                       [(v['uuid'], make_title(v)) for v in voucher_list],
                       callback)
        # ваучер выбран, регистрируем посещение
        if QDialog.Accepted == dialog.exec_():
            params = dict(action='VISIT', event=event.uuid, voucher=self.voucher_uuid)
            if not self.stream.request('/api/voucher/', 'PUT', params):
                QMessageBox.warning(self, title, '%s: %i\n\n%s\n\n%s' % (
                    self.tr('Error'), ERR_EVENT_REGISTERVISIT,
                    self.tr('Unable to register the visit: %s') % http.error_msg,
                    self.tr('Call support team!')))
                return False
            status, data = self.stream.piston()
            print status, data
            if u'CREATED' == status:
                msg = self.tr('The client has been registered for this event.')
                QMessageBox.information(self, title, msg)
                # распечатаем чек
                visit_uuid = data.get('uuid')
                self.print_label(visit_uuid)
                return True
            elif u'DUPLICATE_ENTRY' == status:
                msg = self.tr('The client is already registered for this event.')
            else:
                msg = self.tr('Unable to register!\nStatus: %s') % status
            QMessageBox.warning(self, title, msg)
        return False

    def print_label(self, visit_uuid):
        title=self.tr('Print')
        http = self.params.http
        if not http.request('/api/visit/%s/' % visit_uuid, 'GET', force=True):
            QMessageBox.warning(self, title, '%s: %i\n\n%s\n\n%s' % (
                self.tr('Error'), ERR_EVENT_PRINTLABEL,
                self.tr('Unable to prepare label: %s') % http.error_msg,
                self.tr('Call support team!')))
            return False
        status, response = http.piston()
        print status, response
        self.params.printer.hardcopy(response)

    def changeRoom(self, new_index):
        # Room change:
        # 1. The choosen room is empty inside whole time period.
        #    Change a room for the event.
        # 2. The choosen room is busy at all, i.e. two event are equal in time.
        #    Change the rooms.
        # 3. The choosen room is busy partially.
        #    Cancel the change, raise message.
        if new_index != self.current_room_index:
            # make room checking
            #
            pass

    def removeEvent(self):
        reply = QMessageBox.question(
            self, self.tr('Event remove'),
            self.tr('Are you sure to remove this event from the calendar?'),
            QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            params = {'id': self.schedule['id']}
            if not self.http.request('/manager/cal_event_del/', params):
                QMessageBox.critical(self, self.tr('Event deletion'), self.tr('Unable to delete: %s') % self.http.error_msg)
                return
            default_response = None
            response = self.http.parse(default_response)
            if response:
                index = self.comboRoom.currentIndex()
                room_id, ok = self.comboRoom.itemData(index).toInt()
                model = self.parent.schedule.model()
                model.remove(self.event_object, self.event_index, True)
                QMessageBox.information(self, self.tr('Event removing'),
                                        self.tr('Complete.'))
                self.accept()
            else:
                QMessageBox.information(self, self.tr('Event removing'),
                                        self.tr('Unable to remove this event!'))

    def change_coaches(self):
        """
        Метод реализует функционал замены преподавателей для события.
        """
        title=self.tr('Coaches')
        http = self.params.http
        if not http.request('/api/coach/', 'GET'):
            QMessageBox.critical(self, title, self.tr('Unable to fetch: %s') % http.error_msg)
            return
        status, coach_list = http.piston()
        if 'ALL_OK' == status:

            def coaches_callback(uuid_list):
                self.event_object.set_coaches(
                    filter(lambda x: x.get('uuid') in uuid_list, coach_list)
                    )

            dialog = ShowCoaches(self, callback=coaches_callback)
            dialog.setModal(True)
            dialog.initData(self.event_object, coach_list)
            if QDialog.Accepted == dialog.exec_():
                # отображаем изменения на интерфейсе
                self.initData(self.event_object, self.event_index)

                # update schedule model to immediate refresh this event
                model = self.event_index.model()
                model.change(self.event_object, self.event_index)