def reject_reservation(self, request): collection = ResourceCollection(request.app.libres_context) resource = collection.by_id(self.resource) scheduler = resource.get_scheduler(request.app.libres_context) reservations = scheduler.reservations_by_token(self.token.hex) forms = FormCollection(request.app.session()) submission = forms.submissions.by_id(self.token.hex) send_html_mail( request=request, template='mail_reservation_rejected.pt', subject=_("Your reservation was rejected"), receivers=(self.email, ), content={ 'model': self, 'resource': resource, 'reservations': reservations } ) # create a snapshot of the ticket to keep the useful information tickets = TicketCollection(request.app.session()) ticket = tickets.by_handler_id(self.token.hex) ticket.create_snapshot(request) scheduler.remove_reservation(self.token.hex) if submission: forms.submissions.delete(submission) request.success(_("The reservation was rejected")) # return none on intercooler js requests if not request.headers.get('X-IC-Request'): return morepath.redirect(request.params['return-to'])
def report_person_change(self, request, form): if form.submitted(request): session = request.session with session.no_autoflush: ticket = TicketCollection(session).open_ticket( handler_code='PER', handler_id=uuid4().hex, handler_data={ 'id': str(self.id), 'submitter_email': form.email.data, 'submitter_message': form.message.data }) TicketMessage.create(ticket, request, 'opened') ticket.create_snapshot(request) send_ticket_mail(request=request, template='mail_ticket_opened.pt', subject=_("Your ticket has been opened"), receivers=(form.email.data, ), ticket=ticket) request.success(_("Thank you for your submission!")) return redirect(request.link(ticket, 'status')) layout = ExtendedPersonLayout(self, request) layout.breadcrumbs.append(Link(_("Report change"), '#')) return { 'layout': layout, 'title': _("Report change"), 'lead': self.title, 'form': form }
def test_random_ticket_number(): collection = TicketCollection(session=object()) collection.random_number = Mock(return_value=10000000) assert collection.random_ticket_number('ABC') == 'ABC-1000-0000' collection.random_number = Mock(return_value=99999999) assert collection.random_ticket_number('XXX') == 'XXX-9999-9999'
def test_snapshot_ticket(session, handlers): @handlers.registered_handler('FOO') class FooHandler(Handler): @property def deleted(self): return False @property def title(self): return 'Foo' @property def subtitle(self): return '0xdeadbeef' @property def group(self): return 'Bar' @property def handler_id(self): return 1 @property def handler_data(self): return {} @property def email(self): return '*****@*****.**' def get_summary(self, request): return 'foobar' collection = TicketCollection(session) ticket = collection.open_ticket( handler_id='1', handler_code='FOO' ) ticket.create_snapshot(request=object()) assert ticket.snapshot['email'] == '*****@*****.**' assert ticket.snapshot['summary'] == 'foobar'
def test_issue_unique_ticket_number(session, handlers): handlers.register('ABC', EchoHandler) collection = TicketCollection(session) collection.random_number = Mock(return_value=10000000) assert collection.issue_unique_ticket_number('ABC') == 'ABC-1000-0000' session.add(Ticket( number='ABC-1000-0000', title='Test', group='Test', handler_code='ABC', handler_id='1' )) collection.random_number = Mock(side_effect=[10000000, 10000001, 10000002]) assert collection.issue_unique_ticket_number('ABC') == 'ABC-1000-0001' assert collection.issue_unique_ticket_number('ABC') == 'ABC-1000-0002' assert len(collection.random_number.mock_calls) == 3
def test_available_groups(session): session.add(Ticket( number='FOO-1000-0001', title='test', group='one', handler_code='FOO', handler_id='1', state='open' )) session.add(Ticket( number='BAR-1000-0001', title='test', group='two', handler_code='BAR', handler_id='2', state='open' )) collection = TicketCollection(session) assert collection.subset().count() == 2 assert collection.for_group('one').subset().count() == 1 assert collection.for_group('two').subset().count() == 1 assert collection.available_groups() == ('one', 'two') assert collection.for_group('one').available_groups() == ('one', 'two') assert collection.for_group('two').available_groups() == ('one', 'two') assert collection.available_groups('FOO') == ('one', ) assert collection.available_groups('BAR') == ('two', )
def handle_delete_event(self, request): """ Delete an event. """ request.assert_valid_csrf_token() # Create a snapshot of the ticket to keep the useful information. tickets = TicketCollection(request.app.session()) ticket = tickets.by_handler_id(self.id.hex) if ticket: ticket.create_snapshot(request) if self.meta.get('submitter_email'): send_html_mail( request=request, template='mail_event_rejected.pt', subject=_("Your event was rejected"), receivers=(self.meta.get('submitter_email'), ), content={ 'model': self, 'ticket': ticket } ) EventCollection(request.app.session()).delete(self)
def propose_activity(self, request): assert request.app.active_period, "An active period is required" # if the latest request has been done in the last minute, this is a # duplicate and should be ignored latest = self.latest_request if latest and (sedate.utcnow() - timedelta(seconds=60)) < latest.created: return session = request.session with session.no_autoflush: self.propose() publication_request = self.create_publication_request( request.app.active_period) ticket = TicketCollection(session).open_ticket( handler_code='FER', handler_id=publication_request.id.hex ) TicketMessage.create(ticket, request, 'opened') send_ticket_mail( request=request, template='mail_ticket_opened.pt', subject=_("Your ticket has been opened"), receivers=(self.username, ), ticket=ticket, force=( request.is_organiser_only or request.current_username != self.username ) ) request.success(_("Thank you for your proposal!")) @request.after def redirect_intercooler(response): response.headers.add('X-IC-Redirect', request.link(ticket, 'status')) # do not redirect here, intercooler doesn't deal well with that... return
def test_open_ticket(session, handlers): handlers.register('ECO', EchoHandler) collection = TicketCollection(session) ticket = collection.open_ticket( handler_id='1', handler_code='ECO', title="Title", subtitle="Subtitle", group="Group", summary="Summary", links=[("Link", '#')], email="*****@*****.**" ) assert ticket.number.startswith('ECO-') assert ticket.title == "Title" assert ticket.group == "Group" assert ticket.handler_id == '1' assert ticket.handler_code == 'ECO' assert ticket.handler_data == { 'title': "Title", 'subtitle': "Subtitle", 'group': "Group", 'summary': "Summary", 'links': [("Link", '#')], 'email': "*****@*****.**" } assert ticket.handler.get_summary(request=object()) == "Summary" assert ticket.handler.get_links(request=object()) == [("Link", '#')] ticket.handler_data['title'] = "Test" assert ticket.title == "Title" ticket.handler.refresh() assert ticket.title == "Test" assert len(collection.by_handler_code("ECO")) == 1 assert collection.by_id(ticket.id) assert collection.by_id(ticket.id, ensure_handler_code='FOO') is None assert collection.by_handler_id('1') is not None
def send_daily_ticket_statistics(request): today = replace_timezone(datetime.utcnow(), 'UTC') today = to_timezone(today, 'Europe/Zurich') if today.weekday() in (SAT, SUN): return args = {} # get the current ticket count collection = TicketCollection(request.app.session()) count = collection.get_count() args['currently_open'] = count.open args['currently_pending'] = count.pending args['currently_closed'] = count.closed # get tickets created yesterday or on the weekend end = datetime(today.year, today.month, today.day, tzinfo=today.tzinfo) if today.weekday() == MON: start = end - timedelta(days=2) else: start = end - timedelta(days=1) query = collection.query() query = query.filter(Ticket.created >= start) query = query.filter(Ticket.created <= end) args['opened'] = query.count() query = collection.query() query = query.filter(Ticket.modified >= start) query = query.filter(Ticket.modified <= end) query = query.filter(Ticket.state == 'pending') args['pending'] = query.count() query = collection.query() query = query.filter(Ticket.modified >= start) query = query.filter(Ticket.modified <= end) query = query.filter(Ticket.state == 'closed') args['closed'] = query.count() # render the email args['title'] = request.translate( _("${town} OneGov Cloud Status", mapping={ 'town': request.app.town.name }) ) args['layout'] = DefaultMailLayout(object(), request) args['is_monday'] = today.weekday() == MON args['town'] = request.app.town.name content = render_template('mail_daily_ticket_statistics.pt', request, args) # send one e-mail per user users = UserCollection(request.app.session()).query() users = users.options(undefer('data')) users = users.all() for user in users: if user.data and not user.data.get('daily_ticket_statistics'): continue request.app.send_email( subject=args['title'], receivers=(user.username, ), content=content )
def relevant_ticket(activity, request): pr = activity.request_by_period(request.app.active_period) \ or activity.latest_request if pr: return TicketCollection(request.session).by_handler_id(pr.id.hex)
def test_ticket_statistics(town_app, smtp, handlers): register_echo_handler(handlers) client = Client(town_app) job = get_cronjob_by_name(town_app, 'ticket_statistics') job.app = town_app url = get_cronjob_url(job) tz = ensure_timezone('Europe/Zurich') assert len(smtp.outbox) == 0 # do not run on the weekends with freeze_time(datetime(2016, 1, 2, tzinfo=tz)): client.get(url) with freeze_time(datetime(2016, 1, 3, tzinfo=tz)): client.get(url) assert len(smtp.outbox) == 0 session = town_app.session() collection = TicketCollection(session) tickets = [ collection.open_ticket( handler_id='1', handler_code='ECO', title="Title", group="Group", email="*****@*****.**", created=datetime(2016, 1, 2, 10, tzinfo=tz), ), collection.open_ticket( handler_id='2', handler_code='ECO', title="Title", group="Group", email="*****@*****.**", created=datetime(2016, 1, 2, 10, tzinfo=tz) ), collection.open_ticket( handler_id='3', handler_code='ECO', title="Title", group="Group", email="*****@*****.**", created=datetime(2016, 1, 2, 10, tzinfo=tz) ), collection.open_ticket( handler_id='4', handler_code='ECO', title="Title", group="Group", email="*****@*****.**", created=datetime(2016, 1, 2, 10, tzinfo=tz) ), collection.open_ticket( handler_id='5', handler_code='ECO', title="Title", group="Group", email="*****@*****.**", created=datetime(2016, 1, 2, 10, tzinfo=tz) ), collection.open_ticket( handler_id='6', handler_code='ECO', title="Title", group="Group", email="*****@*****.**", created=datetime(2016, 1, 2, 10, tzinfo=tz) ) ] users = UserCollection(session).query().all() user = users[0] users[1].data = {'daily_ticket_statistics': False} for ticket in tickets: ticket.created = datetime(2016, 1, 2, 10, tzinfo=tz) for pending in tickets[1:3]: pending.accept_ticket(user) pending.modified = datetime(2016, 1, 2, 10, tzinfo=tz) for closed in tickets[3:6]: closed.accept_ticket(user) closed.close_ticket() closed.modified = datetime(2016, 1, 2, 10, tzinfo=tz) transaction.commit() with freeze_time(datetime(2016, 1, 4, tzinfo=tz)): client.get(url) assert len(smtp.outbox) == 1 message = get_mail(smtp.outbox, 0) assert message['subject'] == 'Govikon OneGov Cloud Status' txt = message['text'] assert "Folgendes ist während des Wochenendes auf der Govikon" in txt assert "6 Tickets wurden eröffnet." in txt assert "2 Tickets wurden angenommen." in txt assert "3 Tickets wurden geschlossen." in txt assert "Zur Zeit ist 1 Ticket offen" in txt assert "2 Tickets sind in Bearbeitung" in txt assert "Wir wünschen Ihnen eine schöne Woche!" in txt assert "Das OneGov Cloud Team" in txt assert "über das Benutzerprofil abbestellen" in txt
def ticket(self): if self.latest_request: tickets = TicketCollection(self.request.session) return tickets.by_handler_id(self.latest_request.id.hex)
def test_random_number(): collection = TicketCollection(session=object()) assert 10000000 <= collection.random_number(length=8) <= 99999999
def test_handle_extra_options(session, handlers): handlers.register('LTD', LimitingHandler) collection = TicketCollection(session) collection.handlers = handlers collection.open_ticket(handler_id='1', handler_code='LTD') collection.open_ticket(handler_id='2', handler_code='LTD') collection.open_ticket(handler_id='3', handler_code='LTD') assert collection.subset().count() == 3 collection.extra_parameters = {'limit': 1} assert collection.subset().count() == 3 collection.handler = 'LTD' assert collection.subset().count() == 1 collection.extra_parameters = {'limit': 2} assert collection.subset().count() == 2
def event_deletable(self, event): tickets = TicketCollection(self.app.session()) ticket = tickets.by_handler_id(event.id.hex) return False if ticket else True