def to_representation(self, instance: OrderPosition): if instance.order.status != Order.STATUS_PAID: if instance.order.status != Order.STATUS_PENDING or instance.order.require_approval or not instance.order.event.settings.ticket_download_pending: return [] if instance.addon_to_id and not instance.order.event.settings.ticket_download_addons: return [] if not instance.item.admission and not instance.order.event.settings.ticket_download_nonadm: return [] request = self.context['request'] res = [] responses = register_ticket_outputs.send(instance.order.event) for receiver, response in responses: provider = response(instance.order.event) if provider.is_enabled: res.append({ 'output': provider.identifier, 'url': reverse('api-v1:orderposition-download', kwargs={ 'organizer': instance.order.event.organizer.slug, 'event': instance.order.event.slug, 'pk': instance.pk, 'output': provider.identifier, }, request=request) }) return res
def to_representation(self, instance: OrderPosition): if instance.order.status != Order.STATUS_PAID: return [] if instance.addon_to_id and not instance.order.event.settings.ticket_download_addons: return [] if not instance.item.admission and not instance.order.event.settings.ticket_download_nonadm: return [] request = self.context['request'] res = [] responses = register_ticket_outputs.send(instance.order.event) for receiver, response in responses: provider = response(instance.order.event) if provider.is_enabled: res.append({ 'output': provider.identifier, 'url': reverse('api-v1:orderposition-download', kwargs={ 'organizer': instance.order.event.organizer.slug, 'event': instance.order.event.slug, 'pk': instance.pk, 'output': provider.identifier, }, request=request) }) return res
def to_representation(self, instance: Order): if instance.status != Order.STATUS_PAID: if instance.status != Order.STATUS_PENDING or instance.require_approval or not instance.event.settings.ticket_download_pending: return [] request = self.context['request'] res = [] responses = register_ticket_outputs.send(instance.event) for receiver, response in responses: provider = response(instance.event) if provider.is_enabled: res.append({ 'output': provider.identifier, 'url': reverse('api-v1:order-download', kwargs={ 'organizer': instance.event.organizer.slug, 'event': instance.event.slug, 'code': instance.code, 'output': provider.identifier, }, request=request) }) return res
def _get_output_provider(self, identifier): responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: prov = response(self.request.event) if prov.identifier == identifier: return prov raise NotFound('Unknown output provider.')
def provider_forms(self) -> list: providers = [] responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) provider.form = ProviderForm( obj=self.request.event, settingspref='ticketoutput_%s_' % provider.identifier, data=(self.request.POST if self.request.method == 'POST' else None), files=(self.request.FILES if self.request.method == 'POST' else None)) provider.form.fields = OrderedDict([ ('ticketoutput_%s_%s' % (provider.identifier, k), v) for k, v in provider.settings_form_fields.items() ]) provider.settings_content = provider.settings_content_render( self.request) provider.form.prepare_fields() provider.preview_allowed = True for k, v in provider.settings_form_fields.items(): if v.required and not self.request.event.settings.get( 'ticketoutput_%s_%s' % (provider.identifier, k)): provider.preview_allowed = False break providers.append(provider) return providers
def download_buttons(self): buttons = [] responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if not provider.is_enabled: continue buttons.append({ 'text': provider.download_button_text or 'Download', 'icon': provider.download_button_icon or 'fa-download', 'identifier': provider.identifier, 'multi': provider.multi_download_enabled, 'multi_text': provider.multi_download_button_text or 'Download', 'long_text': provider.long_download_button_text or 'Download', 'javascript_required': provider.javascript_required }) return buttons
def generate_order(order: int, provider: str): order = Order.objects.select_related('event').get(id=order) try: ct = CachedCombinedTicket.objects.get(order=order, provider=provider) except CachedCombinedTicket.MultipleObjectsReturned: CachedCombinedTicket.objects.filter(order=order, provider=provider).delete() ct = CachedCombinedTicket.objects.create(order=order, provider=provider, extension='', type='', file=None) except CachedCombinedTicket.DoesNotExist: ct = CachedCombinedTicket.objects.create(order=order, provider=provider, extension='', type='', file=None) with language(order.locale): responses = register_ticket_outputs.send(order.event) for receiver, response in responses: prov = response(order.event) if prov.identifier == provider: filename, ct.type, data = prov.generate_order(order) path, ext = os.path.splitext(filename) ct.extension = ext ct.save() ct.file.save(filename, ContentFile(data))
def preview(event: int, provider: str): event = Event.objects.get(id=event) with rolledback_transaction(), language(event.settings.locale): item = event.items.create(name=_("Sample product"), default_price=42.23, description=_("Sample product description")) item2 = event.items.create(name=_("Sample workshop"), default_price=23.40) from pretix.base.models import Order order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(), email='*****@*****.**', locale=event.settings.locale, expires=now(), code="PREVIEW1234", total=119) scheme = PERSON_NAME_SCHEMES[event.settings.name_scheme] sample = {k: str(v) for k, v in scheme['sample'].items()} p = order.positions.create(item=item, attendee_name_parts=sample, price=item.default_price) order.positions.create(item=item2, attendee_name_parts=sample, price=item.default_price, addon_to=p) order.positions.create(item=item2, attendee_name_parts=sample, price=item.default_price, addon_to=p) InvoiceAddress.objects.create(order=order, name_parts=sample, company=_("Sample company")) responses = register_ticket_outputs.send(event) for receiver, response in responses: prov = response(event) if prov.identifier == provider: return prov.generate(p)
def get_tickets_for_order(order): can_download = all([r for rr, r in allow_ticket_download.send(order.event, order=order)]) if not can_download: return [] if not order.ticket_download_available: return [] providers = [ response(order.event) for receiver, response in register_ticket_outputs.send(order.event) ] tickets = [] for p in providers: if not p.is_enabled: continue if p.multi_download_enabled: try: if len(list(order.positions_with_tickets)) == 0: continue ct = CachedCombinedTicket.objects.filter( order=order, provider=p.identifier, file__isnull=False ).last() if not ct or not ct.file: retval = generate_order(order.pk, p.identifier) if not retval: continue ct = CachedCombinedTicket.objects.get(pk=retval) tickets.append(( "{}-{}-{}{}".format( order.event.slug.upper(), order.code, ct.provider, ct.extension, ), ct )) except: logger.exception('Failed to generate ticket.') else: for pos in order.positions_with_tickets: try: ct = CachedTicket.objects.filter( order_position=pos, provider=p.identifier, file__isnull=False ).last() if not ct or not ct.file: retval = generate_orderposition(pos.pk, p.identifier) if not retval: continue ct = CachedTicket.objects.get(pk=retval) tickets.append(( "{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, ct.provider, ct.extension, ), ct )) except: logger.exception('Failed to generate ticket.') return tickets
def test_one_plugin_active(self): self.event.plugins = 'tests.testdummy' self.event.save() payload = {'foo': 'bar'} responses = register_ticket_outputs.send(self.event, **payload) self.assertEqual(len(responses), 1) self.assertIn('tests.testdummy.signals', [r[0].__module__ for r in responses])
def output(self): if not all([r for rr, r in allow_ticket_download.send(self.request.event, order=self.order)]): return None responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if provider.identifier == self.kwargs.get('output'): return provider
def download_buttons(self): buttons = [] responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if not provider.is_enabled: continue buttons.append({ 'text': provider.download_button_text or 'Download', 'identifier': provider.identifier, }) return buttons
def get_tickets_for_order(order): can_download = all( [r for rr, r in allow_ticket_download.send(order.event, order=order)]) if not can_download: return [] if not order.ticket_download_available: return [] providers = [ response(order.event) for receiver, response in register_ticket_outputs.send(order.event) ] tickets = [] for p in providers: if not p.is_enabled: continue if p.multi_download_enabled: try: ct = get_cachedticket_for_order(order, p.identifier, generate_async=False) tickets.append(("{}-{}-{}{}".format( order.event.slug.upper(), order.code, ct.provider, ct.extension, ), ct)) except: logger.exception('Failed to generate ticket.') else: for pos in order.positions.all(): if pos.addon_to and not order.event.settings.ticket_download_addons: continue if not pos.item.admission and not order.event.settings.ticket_download_nonadm: continue try: ct = get_cachedticket_for_position(pos, p.identifier, generate_async=False) tickets.append(("{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, ct.provider, ct.extension, ), ct)) except: logger.exception('Failed to generate ticket.') return tickets
def get_context_data(self, *args, **kwargs) -> dict: context = super().get_context_data(*args, **kwargs) context['providers'] = self.provider_forms context['any_enabled'] = False responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if provider.is_enabled: context['any_enabled'] = True break return context
def download_buttons(self): buttons = [] responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if not provider.is_enabled: continue buttons.append( { "icon": provider.download_button_icon or "fa-download", "text": provider.download_button_text or "fa-download", "identifier": provider.identifier, } ) return buttons
def get_tickets_for_order(order): can_download = all([r for rr, r in allow_ticket_download.send(order.event, order=order)]) if not can_download: return [] if not order.ticket_download_available: return [] providers = [ response(order.event) for receiver, response in register_ticket_outputs.send(order.event) ] tickets = [] for p in providers: if not p.is_enabled: continue if p.multi_download_enabled: try: ct = get_cachedticket_for_order(order, p.identifier, generate_async=False) tickets.append(( "{}-{}-{}{}".format( order.event.slug.upper(), order.code, ct.provider, ct.extension, ), ct )) except: logger.exception('Failed to generate ticket.') else: for pos in order.positions.all(): if pos.addon_to and not order.event.settings.ticket_download_addons: continue if not pos.item.admission and not order.event.settings.ticket_download_nonadm: continue try: ct = get_cachedticket_for_position(pos, p.identifier, generate_async=False) tickets.append(( "{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, ct.provider, ct.extension, ), ct )) except: logger.exception('Failed to generate ticket.') return tickets
def generate_order(order: int, provider: str): order = Order.objects.select_related('event').get(id=order) with language(order.locale): responses = register_ticket_outputs.send(order.event) for receiver, response in responses: prov = response(order.event) if prov.identifier == provider: filename, ttype, data = prov.generate_order(order) path, ext = os.path.splitext(filename) for ct in CachedCombinedTicket.objects.filter(order=order, provider=provider): ct.delete() ct = CachedCombinedTicket.objects.create(order=order, provider=provider, extension=ext, type=ttype, file=None) ct.file.save(filename, ContentFile(data)) return ct.pk
def preview(event: int, provider: str): event = Event.objects.get(id=event) with rolledback_transaction(), language(event.settings.locale): item = event.items.create(name=_("Sample product"), default_price=42.23) order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(), email='*****@*****.**', expires=now(), code="PREVIEW1234", total=119) p = order.positions.create(item=item, attendee_name=_("John Doe"), price=item.default_price) responses = register_ticket_outputs.send(event) for receiver, response in responses: prov = response(event) if prov.identifier == provider: return prov.generate(p)
def generate(order: str, provider: str): order = Order.objects.select_related('event').get(id=order) ct = CachedTicket.objects.get_or_create(order=order, provider=provider)[0] if not ct.cachedfile: cf = CachedFile() cf.date = now() cf.expires = order.event.date_from + timedelta(days=30) cf.save() ct.cachedfile = cf ct.save() responses = register_ticket_outputs.send(order.event) for receiver, response in responses: prov = response(order.event) if prov.identifier == provider: ct.cachedfile.filename, ct.cachedfile.type, data = prov.generate(order) ct.cachedfile.file.save(cachedfile_name(ct.cachedfile, ct.cachedfile.filename), ContentFile(data)) ct.cachedfile.save()
def generate(order, provider): order = Order.objects.current.select_related('event').get(identity=order) ct = CachedTicket.objects.get_or_create(order=order, provider=provider)[0] if not ct.cachedfile: cf = CachedFile() cf.date = now() cf.expires = order.event.date_from + timedelta(days=30) cf.save() ct.cachedfile = cf ct.save() responses = register_ticket_outputs.send(order.event) for receiver, response in responses: prov = response(order.event) if prov.identifier == provider: ct.cachedfile.filename, ct.cachedfile.type, data = prov.generate(order) ct.cachedfile.file.save(cachedfile_name(ct.cachedfile, ct.cachedfile.filename), ContentFile(data)) ct.cachedfile.save()
def provider_forms(self) -> list: providers = [] responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) provider.form = ProviderForm( obj=self.request.event, settingspref='ticketoutput_%s_' % provider.identifier, data=(self.request.POST if self.request.method == 'POST' else None) ) provider.form.fields = OrderedDict( [ ('ticketoutput_%s_%s' % (provider.identifier, k), v) for k, v in provider.settings_form_fields.items() ] ) provider.settings_content = provider.settings_content_render(self.request) provider.form.prepare_fields() providers.append(provider) return providers
def get_tickets_for_order(order, base_position=None): can_download = all([r for rr, r in allow_ticket_download.send(order.event, order=order)]) if not can_download: return [] if not order.ticket_download_available: return [] providers = [ response(order.event) for receiver, response in register_ticket_outputs.send(order.event) ] tickets = [] positions = list(order.positions_with_tickets) if base_position: # Only the given position and its children positions = [ p for p in positions if p.pk == base_position.pk or p.addon_to_id == base_position.pk ] for p in providers: if not p.is_enabled: continue if p.multi_download_enabled and not base_position: try: if len(positions) == 0: continue ct = CachedCombinedTicket.objects.filter( order=order, provider=p.identifier, file__isnull=False ).last() if not ct or not ct.file: retval = generate_order(order.pk, p.identifier) if not retval: continue ct = CachedCombinedTicket.objects.get(pk=retval) tickets.append(( "{}-{}-{}{}".format( order.event.slug.upper(), order.code, ct.provider, ct.extension, ), ct )) except: logger.exception('Failed to generate ticket.') else: for pos in positions: try: ct = CachedTicket.objects.filter( order_position=pos, provider=p.identifier, file__isnull=False ).last() if not ct or not ct.file: retval = generate_orderposition(pos.pk, p.identifier) if not retval: continue ct = CachedTicket.objects.get(pk=retval) tickets.append(( "{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, ct.provider, ct.extension, ), ct )) except: logger.exception('Failed to generate ticket.') return tickets
def output(self): responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if provider.identifier == self.kwargs.get('output'): return provider
def get_tickets_for_order(order, base_position=None): can_download = all( [r for rr, r in allow_ticket_download.send(order.event, order=order)]) if not can_download: return [] if not order.ticket_download_available: return [] providers = [ response(order.event) for receiver, response in register_ticket_outputs.send(order.event) ] tickets = [] positions = list(order.positions_with_tickets) if base_position: # Only the given position and its children positions = [ p for p in positions if p.pk == base_position.pk or p.addon_to_id == base_position.pk ] for p in providers: if not p.is_enabled: continue if p.multi_download_enabled and not base_position: try: if len(positions) == 0: continue ct = CachedCombinedTicket.objects.filter( order=order, provider=p.identifier, file__isnull=False).last() if not ct or not ct.file: retval = generate_order(order.pk, p.identifier) if not retval: continue ct = CachedCombinedTicket.objects.get(pk=retval) tickets.append(("{}-{}-{}{}".format( order.event.slug.upper(), order.code, ct.provider, ct.extension, ), ct)) except: logger.exception('Failed to generate ticket.') else: for pos in positions: try: ct = CachedTicket.objects.filter( order_position=pos, provider=p.identifier, file__isnull=False).last() if not ct or not ct.file: retval = generate_orderposition(pos.pk, p.identifier) if not retval: continue ct = CachedTicket.objects.get(pk=retval) if ct.type == 'text/uri-list': continue if pos.subevent: # Subevent date in filename improves accessibility e.g. for screen reader users fname = "{}-{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, pos.subevent.date_from.strftime('%Y_%m_%d'), ct.provider, ct.extension) else: fname = "{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, ct.provider, ct.extension) tickets.append((fname, ct)) except: logger.exception('Failed to generate ticket.') return tickets
def test_no_plugins_active(self): self.event.plugins = '' self.event.save() responses = register_ticket_outputs.send(self.event) self.assertEqual(len(responses), 0)
def get_tickets_for_order(order): can_download = all( [r for rr, r in allow_ticket_download.send(order.event, order=order)]) if not can_download: return [] if not order.ticket_download_available: return [] providers = [ response(order.event) for receiver, response in register_ticket_outputs.send(order.event) ] tickets = [] for p in providers: if not p.is_enabled: continue if p.multi_download_enabled: try: ct = CachedCombinedTicket.objects.filter( order=order, provider=p.identifier, file__isnull=False).last() if not ct or not ct.file: retval = generate.apply(args=('order', order.pk, p.identifier)) ct = CachedCombinedTicket.objects.get(pk=retval.value) tickets.append(("{}-{}-{}{}".format( order.event.slug.upper(), order.code, ct.provider, ct.extension, ), ct)) except: logger.exception('Failed to generate ticket.') else: for pos in order.positions.all(): if pos.addon_to and not order.event.settings.ticket_download_addons: continue if not pos.item.admission and not order.event.settings.ticket_download_nonadm: continue try: ct = CachedTicket.objects.filter( order_position=pos, provider=p.identifier, file__isnull=False).last() if not ct or not ct.file: retval = generate.apply(args=('orderposition', pos.pk, p.identifier)) ct = CachedTicket.objects.get(pk=retval.value) tickets.append(("{}-{}-{}-{}{}".format( order.event.slug.upper(), order.code, pos.positionid, ct.provider, ct.extension, ), ct)) except: logger.exception('Failed to generate ticket.') return tickets