示例#1
0
def fares_available(context, fare_type, sort=None):
    """
    Restituisce l'elenco delle tariffe attive in questo momento per la
    tipologia specificata.
    """
    assert fare_type in ('all', 'conference', 'goodies', 'partner', 'hotel-room', 'hotel-room-sharing', 'other')
    if not settings.P3_FARES_ENABLED(context['user']):
        return []

    fares_list = filter(lambda f: f['valid'], cdataaccess.fares(settings.CONFERENCE_CONFERENCE))
    if fare_type == 'conference':
        fares = [ f for f in fares_list if f['code'][0] == 'T' and f['ticket_type'] == 'conference' ]
    elif fare_type == 'hotel-room-sharing':
        fares = [ f for f in fares_list if f['code'].startswith('HB') ]
    elif fare_type == 'hotel-room':
        fares = [ f for f in fares_list if f['code'].startswith('HR') ]
    elif fare_type == 'other':
        fares = [ f for f in fares_list if f['ticket_type'] in ('other', 'event') and f['code'][0] != 'H' ]
    elif fare_type == 'partner':
        fares = [ f for f in fares_list if f['ticket_type'] in 'partner' ]
    elif fare_type == 'all':
        fares = fares_list
    if sort == "price":
        fares.sort(key=lambda x: x['price'])
    return fares
示例#2
0
def fares_available(context, fare_type, sort=None):
    """
    Restituisce l'elenco delle tariffe attive in questo momento per la
    tipologia specificata.
    """
    assert fare_type in ('all', 'conference', 'goodies', 'partner', 'hotel-room', 'hotel-room-sharing', 'other')
    if not settings.P3_FARES_ENABLED(context['user']):
        return []

    fares_list = filter(lambda f: f['valid'], cdataaccess.fares(settings.CONFERENCE_CONFERENCE))
    if fare_type == 'conference':
        fares = [ f for f in fares_list if f['code'][0] == 'T' and f['ticket_type'] == 'conference' ]
    elif fare_type == 'hotel-room-sharing':
        fares = [ f for f in fares_list if f['code'].startswith('HB') ]
    elif fare_type == 'hotel-room':
        fares = [ f for f in fares_list if f['code'].startswith('HR') ]
    elif fare_type == 'other':
        fares = [ f for f in fares_list if f['ticket_type'] in ('other', 'event') and f['code'][0] != 'H' ]
    elif fare_type == 'partner':
        fares = [ f for f in fares_list if f['ticket_type'] in 'partner' ]
    elif fare_type == 'all':
        fares = fares_list
    if sort == "price":
        fares.sort(key=lambda x: x['price'])
    return fares
示例#3
0
def my_schedule(request, conference):
    qs = cmodels.Event.objects\
        .filter(eventinterest__user=request.user, eventinterest__interest__gt=0)\
        .filter(schedule__conference=conference)\
        .values('id', 'schedule')

    events = defaultdict(list)
    for x in qs:
        events[x['schedule']].append(x['id'])

    qs = cmodels.EventBooking.objects\
        .filter(user=request.user, event__schedule__conference=conference)\
        .values('event', 'event__schedule')
    for x in qs:
        events[x['event__schedule']].append(x['event'])

    qs = cmodels.Ticket.objects\
        .filter(user=request.user)\
        .filter(fare__conference=conference, fare__ticket_type='partner')\
       .values_list('fare', flat=True)

    from conference.dataaccess import fares, schedules_data
    pfares = [f for f in fares(conference) if f['id'] in qs]
    partner = _partner_as_event(pfares)

    schedules = schedules_data(events.keys())
    tts = _build_timetables(schedules, events=events, partner=partner)
    ctx = {
        'conference': conference,
        'sids': [x[0] for x in tts],
        'timetables': tts,
    }
    return render(request, 'p3/my_schedule.html', ctx)
示例#4
0
def my_schedule(request, conference):
    qs = cmodels.Event.objects\
        .filter(eventinterest__user=request.user, eventinterest__interest__gt=0)\
        .filter(schedule__conference=conference)\
        .values('id', 'schedule')

    events = defaultdict(list)
    for x in qs:
        events[x['schedule']].append(x['id'])

    qs = cmodels.EventBooking.objects\
        .filter(user=request.user, event__schedule__conference=conference)\
        .values('event', 'event__schedule')
    for x in qs:
        events[x['event__schedule']].append(x['event'])

    qs = cmodels.Ticket.objects\
        .filter(user=request.user)\
        .filter(fare__conference=conference, fare__ticket_type='partner')\
       .values_list('fare', flat=True)

    from conference.dataaccess import fares, schedules_data
    pfares = [ f for f in fares(conference) if f['id'] in qs ]
    partner = _partner_as_event(pfares)

    schedules = schedules_data(events.keys())
    tts = _build_timetables(schedules, events=events, partner=partner)
    ctx = {
        'conference': conference,
        'sids': [ x[0] for x in tts ],
        'timetables': tts,
    }
    return render(request, 'p3/my_schedule.html', ctx)
示例#5
0
def _conference_timetables(conference):
    """ Return the TimeTable about the conference."""
    # The timetables must contain both events in the db and "artificial"
    # events from partner program
    sids = cmodels.Schedule.objects\
        .filter(conference=conference)\
        .values_list('id', flat=True)

    from conference.dataaccess import fares, schedules_data
    pfares = [f for f in fares(conference) if f['ticket_type'] == 'partner']
    partner = _partner_as_event(pfares)

    schedules = schedules_data(sids)
    tts = _build_timetables(schedules, partner=partner)
    return tts
示例#6
0
def _conference_timetables(conference):
    """
    Restituisce le TimeTable relative alla conferenza.
    """
    # Le timetable devono contenere sia gli eventi presenti nel db sia degli
    # eventi "artificiali" del partner program
    sids = cmodels.Schedule.objects\
        .filter(conference=conference)\
        .values_list('id', flat=True)

    from conference.dataaccess import fares, schedules_data
    pfares = [ f for f in fares(conference) if f['ticket_type'] == 'partner' ]
    partner = _partner_as_event(pfares)

    schedules = schedules_data(sids)
    tts = _build_timetables(schedules, partner=partner)
    return tts
示例#7
0
def _conference_timetables(conference):
    """
    Restituisce le TimeTable relative alla conferenza.
    """
    # Le timetable devono contenere sia gli eventi presenti nel db sia degli
    # eventi "artificiali" del partner program
    sids = cmodels.Schedule.objects\
        .filter(conference=conference)\
        .values_list('id', flat=True)

    from conference.dataaccess import fares, schedules_data
    pfares = [f for f in fares(conference) if f['ticket_type'] == 'partner']
    partner = _partner_as_event(pfares)

    schedules = schedules_data(sids)
    tts = _build_timetables(schedules, partner=partner)
    return tts
示例#8
0
def _conference_timetables(conference):
    """
    Restituisce le TimeTable relative alla conferenza.
    """
    # The timetables must contain both events in the db and "artificial"
    # events from partner program
    sids = cmodels.Schedule.objects\
        .filter(conference=conference)\
        .values_list('id', flat=True)

    from conference.dataaccess import fares, schedules_data
    pfares = [ f for f in fares(conference) if f['ticket_type'] == 'partner' ]
    partner = _partner_as_event(pfares)

    schedules = schedules_data(sids)
    tts = _build_timetables(schedules, partner=partner)
    return tts
示例#9
0
    def render(self, name, value, attrs=None):
        start = self.booking.booking_start

        from django.template.loader import render_to_string
        from conference import dataaccess as cdataaccess

        tpl = 'p3/fragments/form_field_hotel_reservation_widget.html'
        fares = {
            'HR': [],
            'HB': [],
        }
        for f in cdataaccess.fares(settings.CONFERENCE_CONFERENCE):
            if not f['valid']:
                continue
            if f['code'][:2] == 'HR':
                fares['HR'].append(f)
            elif f['code'][:2] == 'HB':
                fares['HB'].append(f)

        if not fares['HR'] and not fares['HB']:
            return ''

        if not value:
            value = []
            if fares['HB']:
                value.append({
                    'fare':
                    fares['HB'][0]['code'],
                    'qty':
                    0,
                    'period':
                    (self.booking.default_start, self.booking.default_end),
                })
            if fares['HR']:
                value.append({
                    'fare':
                    fares['HR'][0]['code'],
                    'qty':
                    0,
                    'period':
                    (self.booking.default_start, self.booking.default_end),
                })

        types = getattr(self, 'types', ['HR', 'HB'])
        rows = []
        for entry in value:
            k = entry['fare'][:2]
            if k not in ('HR', 'HB'):
                raise TypeError('unsupported fare')
            if k not in types:
                continue
            ctx = {
                'label': '',
                'type': '',
                'qty': entry['qty'],
                'period': map(lambda x: (x - start).days, entry['period']),
                'fare': entry['fare'],
                'fares': [],
                'minimum_night': self.booking.minimum_night,
            }
            if k == 'HB':
                ctx['label'] = _('Room sharing')
                ctx['type'] = 'bed'
                ctx['fares'] = fares['HB']
            else:
                ctx['label'] = _('Full room')
                ctx['type'] = 'room'
                ctx['fares'] = fares['HR']

            rows.append(ctx)

        # XXX crappy hack!
        # given the way I've implemented widget rendering I need to
        # know here and now if there are errors, to be able to show
        # them in the correct position.
        # Unfortunately the errors are a property of BoundField, not
        # of Field or of the widget.
        # This bad hack works just because in the templatetag I'm
        # connecting to the widget the errors of the form.
        # The clean way would be instead reimplementing the rendering
        # of subwidget as it's done for RadioInput, passing from
        # filter |field and inserting the error at that point.
        errors = [None] * len(rows)
        if hasattr(self, '_errors'):
            print self._errors
            for e in self._errors:
                try:
                    ix, msg = e.split(':', 1)
                except ValueError:
                    continue
                try:
                    errors[int(ix)] = msg
                except:
                    continue
        for e in zip(rows, errors):
            if e[1]:
                e[0]['error'] = e[1]

        ctx = {
            'start': start,
            'days': (self.booking.booking_end - start).days,
            'rows': rows,
            'name': name,
        }
        return render_to_string(tpl, ctx)
示例#10
0
def render_cart_rows(context, fare_type, form):
    assert fare_type in ('conference', 'goodies', 'partner', 'hotel-room', 'hotel-room-sharing', 'other')
    ctx = Context(context)
    request = ctx['request']
    try:
        company = request.user.assopy_user.account_type == 'c'
    except AttributeError:
        # anonymous user or without an assopy profile (impossible!)
        company = False

    ctx.update({
        'form': form,
        'company': company,
    })

    fares_list = filter(lambda f: f['valid'], cdataaccess.fares(settings.CONFERENCE_CONFERENCE))
    if fare_type == 'conference':
        tpl = 'p3/fragments/render_cart_conference_ticket_row.html'
        # rendering "conference" tickets is a bit complex; each row in
        # the cart corresponds to multiple "fare" (student, private, copany)
        #
        # The prices must be sorted on time + ticket type + owner
        #   early
        #       full            [Student, Private, Company]
        #       lite (standard) [Student, Private, Company]
        #       daily           [Student, Private, Company]
        #   regular (late)
        #       ...
        #   on desk
        #       ...
        #
        # The correct time ordering is guaranteed implicitly by
        # excluding expired fares (it's not permitted to have overlaps
        # of validity periods).
        #
        # Ticket code conventions:
        # - all ticket codes must start with 'T'
        # - second letter stands for ticket type:
        #   'E' - early bird
        #   'R' - normal
        #   'D' - on-desk
        # - third letter: ticket variant
        #   'S' - standard
        #   'L' - standard light (without trainings)
        #   'D' - day pass
        #   'T' - training pass
        # - fourth letter: group type
        #   'S' - student
        #   'P' - personal
        #   'C' - company
        #
        fares = dict((f['code'][2:], f) for f in fares_list if f['code'][0] == 'T')
        rows = []
        for t in ('S', 'L', 'D', 'T'):
            # To simplify the template fares are packed in triplets:
            # student, private, company.
            #
            # Each row is a tuple with three elements:
            #    1. Fare
            #    2. FormField
            #    3. Boolean flag telling if the price can be applied to the user
            row = []
            for k in ('S', 'P', 'C'):
                try:
                    f = fares[t+k]
                except KeyError:
                    row.append((None, None, None))
                else:
                    # The price is valid if the time test is passed and if the
                    # account type is compatible
                    valid = not (company ^ (f['code'][-1] == 'C'))
                    row.append((f, form.__getitem__(f['code']), valid))
            rows.append(row)
        ctx['rows'] = rows
    elif fare_type == 'hotel-room-sharing':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['bed_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'hotel-room':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['room_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'other':
        tpl = 'p3/fragments/render_cart_og_ticket_row.html'
        fares = defaultdict(dict)
        order = ('p', 'c')
        columns = set()
        for f in fares_list:
            if f['ticket_type'] in ('other', 'event') and f['code'][0] != 'H':
                columns.add(f['recipient_type'])
                fares[f['name']][f['recipient_type']] = f
        ctx['fares'] = fares.values()
        ctx['recipient_types'] = sorted(columns, key=lambda v: order.index(v))
    elif fare_type == 'partner':
        tpl = 'p3/fragments/render_cart_partner_ticket_row.html'
        ctx['fares'] = [ f for f in fares_list if f['ticket_type'] in 'partner' ]

    return render_to_string(tpl, ctx)
示例#11
0
    def render(self, name, value, attrs=None):
        start = self.booking.booking_start

        from django.template.loader import render_to_string
        from conference import dataaccess as cdataaccess

        tpl = 'p3/fragments/form_field_hotel_reservation_widget.html'
        fares = {
            'HR': [],
            'HB': [],
        }
        for f in cdataaccess.fares(settings.CONFERENCE_CONFERENCE):
            if not f['valid']:
                continue
            if f['code'][:2] == 'HR':
                fares['HR'].append(f)
            elif f['code'][:2] == 'HB':
                fares['HB'].append(f)

        if not fares['HR'] and not fares['HB']:
            return ''

        if not value:
            value = []
            if fares['HB']:
                value.append({
                    'fare': fares['HB'][0]['code'],
                    'qty': 0,
                    'period': (self.booking.default_start, self.booking.default_end),
                })
            if fares['HR']:
                value.append({
                    'fare': fares['HR'][0]['code'],
                    'qty': 0,
                    'period': (self.booking.default_start, self.booking.default_end),
                })

        types = getattr(self, 'types', ['HR', 'HB'])
        rows = []
        for entry in value:
            k = entry['fare'][:2]
            if k not in ('HR', 'HB'):
                raise TypeError('unsupported fare')
            if k not in types:
                continue
            ctx = {
                'label': '',
                'type': '',
                'qty': entry['qty'],
                'period': map(lambda x: (x-start).days, entry['period']),
                'fare': entry['fare'],
                'fares': [],
                'minimum_night': self.booking.minimum_night,
            }
            if k == 'HB':
                ctx['label'] = _('Room sharing')
                ctx['type'] = 'bed'
                ctx['fares'] = fares['HB']
            else:
                ctx['label'] = _('Full room')
                ctx['type'] = 'room'
                ctx['fares'] = fares['HR']

            rows.append(ctx)

        # XXX crappy hack!
        # given the way I've implemented widget rendering I need to
        # know here and now if there are errors, to be able to show
        # them in the correct position.
        # Unfortunately the errors are a property of BoundField, not
        # of Field or of the widget.
        # This bad hack works just because in the templatetag I'm
        # connecting to the widget the errors of the form.
        # The clean way would be instead reimplementing the rendering
        # of subwidget as it's done for RadioInput, passing from
        # filter |field and inserting the error at that point.
        errors = [None] * len(rows)
        if hasattr(self, '_errors'):
            print self._errors
            for e in self._errors:
                try:
                    ix, msg = e.split(':', 1)
                except ValueError:
                    continue
                try:
                    errors[int(ix)] = msg
                except:
                    continue
        for e in zip(rows, errors):
            if e[1]:
                e[0]['error'] = e[1]

        ctx = {
            'start': start,
            'days': (self.booking.booking_end-start).days,
            'rows': rows,
            'name': name,
        }
        return render_to_string(tpl, ctx)
示例#12
0
def render_cart_rows(context, fare_type, form):
    assert fare_type in ('conference', 'goodies', 'partner', 'hotel-room', 'hotel-room-sharing', 'other')
    ctx = Context(context)
    request = ctx['request']
    try:
        company = request.user.assopy_user.account_type == 'c'
    except AttributeError:
        # anonymous user or without an assopy profile (impossible!)
        company = False

    ctx.update({
        'form': form,
        'company': company,
    })

    fares_list = filter(lambda f: f['valid'], cdataaccess.fares(settings.CONFERENCE_CONFERENCE))
    if fare_type == 'conference':
        tpl = 'p3/fragments/render_cart_conference_ticket_row.html'
        # rendering "conference" tickets is a bit complex; each row in
        # the cart corresponds to multiple "fare" (student, private, copany)
        #
        # The prices must be sorted on time + ticket type + owner
        #   early
        #       full            [Student, Private, Company]
        #       lite (standard) [Student, Private, Company]
        #       daily           [Student, Private, Company]
        #   regular (late)
        #       ...
        #   on desk
        #       ...
        #
        # The correct time ordering is guaranteed implicitly by
        # excluding expired fares (it's not permitted to have overlaps
        # of validity periods).
        fares = dict((f['code'][2:], f) for f in fares_list if f['code'][0] == 'T')
        rows = []
        for t in ('S', 'L', 'D'):
            # To simplify the template fares are packed in triplets:
            # student, private, company.
            #
            # Each raw is a tuple with three elements:
            #    1. Fare
            #    2. FormField
            #    3. Boolean flag telling if the price can be applied to the user
            row = []
            for k in ('S', 'P', 'C'):
                try:
                    f = fares[t+k]
                except KeyError:
                    row.append((None, None, None))
                else:
                    # The price is valid if the time test is passed and if the
                    # account type is compatible
                    valid = not (company ^ (f['code'][-1] == 'C'))
                    row.append((f, form.__getitem__(f['code']), valid))
            rows.append(row)
        ctx['rows'] = rows
    elif fare_type == 'hotel-room-sharing':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['bed_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'hotel-room':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['room_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'other':
        tpl = 'p3/fragments/render_cart_og_ticket_row.html'
        fares = defaultdict(dict)
        order = ('p', 'c')
        columns = set()
        for f in fares_list:
            if f['ticket_type'] in ('other', 'event') and f['code'][0] != 'H':
                columns.add(f['recipient_type'])
                fares[f['name']][f['recipient_type']] = f
        ctx['fares'] = fares.values()
        ctx['recipient_types'] = sorted(columns, key=lambda v: order.index(v))
    elif fare_type == 'partner':
        tpl = 'p3/fragments/render_cart_partner_ticket_row.html'
        ctx['fares'] = [ f for f in fares_list if f['ticket_type'] in 'partner' ]

    return render_to_string(tpl, ctx)
示例#13
0
文件: forms.py 项目: 6502/pycon_site
    def render(self, name, value, attrs=None):
        try:
            start = settings.P3_HOTEL_RESERVATION['period'][0]
        except:
            raise TypeError('P3_HOTEL_RESERVATION not set')

        from django.template.loader import render_to_string
        from conference import dataaccess as cdataaccess

        tpl = 'p3/fragments/form_field_hotel_reservation_widget.html'
        fares = {
            'HR': [],
            'HB': [],
        }
        for f in cdataaccess.fares(settings.CONFERENCE_CONFERENCE):
            if not f['valid']:
                continue
            if f['code'][:2] == 'HR':
                fares['HR'].append(f)
            elif f['code'][:2] == 'HB':
                fares['HB'].append(f)

        if not fares['HR'] or not fares['HB']:
            return ''

        if not value:
            value = [
                {'fare': fares['HB'][0]['code'], 'qty': 0, 'period': settings.P3_HOTEL_RESERVATION['default']},
                {'fare': fares['HR'][0]['code'], 'qty': 0, 'period': settings.P3_HOTEL_RESERVATION['default']},
            ]

        types = getattr(self, 'types', ['HR', 'HB'])
        rows = []
        for entry in value:
            k = entry['fare'][:2]
            if k not in ('HR', 'HB'):
                raise TypeError('unsupported fare')
            if k not in types:
                continue
            ctx = {
                'label': '',
                'type': '',
                'qty': entry['qty'],
                'period': map(lambda x: (x-start).days, entry['period']),
                'fare': entry['fare'],
                'fares': [],
            }
            if k == 'HB':
                ctx['label'] = _('Room sharing')
                ctx['type'] = 'bed'
                ctx['fares'] = fares['HB']
            else:
                ctx['label'] = _('Full room')
                ctx['type'] = 'room'
                ctx['fares'] = fares['HR']

            rows.append(ctx)

        # XXX schifezza!
        # per come ho implementato il rendering del widget ho bisogno di sapere
        # qui e adesso se ci sono errori per mostrarli nel posto giusto.
        # Purtroppo gli errori sono una proprietà del BoundField non del field
        # ne tantomeno del widget. Questo codice è un accrocchio funziona
        # perché nel templatetag aggancio al widget gli errori della form. Il
        # modo pulito sarebbe implementare il rendering dei subwidget come
        # avviene per il RadioInput, passare dal filtro |field e inserire li
        # gli errori.
        errors = [None] * len(rows)
        if hasattr(self, '_errors'):
            print self._errors
            for e in self._errors:
                try:
                    ix, msg = e.split(':', 1)
                except ValueError:
                    continue
                try:
                    errors[int(ix)] = msg
                except:
                    continue
        for e in zip(rows, errors):
            if e[1]:
                e[0]['error'] = e[1]

        ctx = {
            'start': start,
            'days': (settings.P3_HOTEL_RESERVATION['period'][1]-start).days,
            'rows': rows,
            'name': name,
        }
        return render_to_string(tpl, ctx)
示例#14
0
文件: p3.py 项目: 6502/pycon_site
def render_cart_rows(context, fare_type, form):
    assert fare_type in ('conference', 'goodies', 'partner', 'hotel-room', 'hotel-room-sharing', 'other')
    ctx = Context(context)
    request = ctx['request']
    try:
        company = request.user.assopy_user.account_type == 'c'
    except AttributeError:
        # utente anonimo o senza il profilo assopy (impossibile!)
        company = False

    ctx.update({
        'form': form,
        'company': company,
    })

    fares_list = filter(lambda f: f['valid'], cdataaccess.fares(settings.CONFERENCE_CONFERENCE))
    if fare_type == 'conference':
        tpl = 'p3/fragments/render_cart_conference_ticket_row.html'
        # il rendering dei biglietti "conference" è un po' particolare, ogni
        # riga del carrello corrisponde a più `fare` (student, private,
        # company)

        # Le tariffe devono essere ordinate secondo l'ordine temporale + il
        # tipo di biglietto + il destinatario:
        #   early
        #       full            [Student, Private, Company]
        #       lite (standard) [Student, Private, Company]
        #       daily           [Student, Private, Company]
        #   regular (late)
        #       ...
        #   on desk
        #       ...
        #
        # L'ordine temporale viene implicitamente garantito dall'aver escluso
        # le fare non più valide (non permettiamo overlap nel range di
        # validità)
        fares = dict((f['code'][2:], f) for f in fares_list if f['code'][0] == 'T')
        rows = []
        for t in ('S', 'L', 'D'):
            # Per semplificare il template impacchetto le fare a gruppi di tre:
            # studente, privato, azienda.
            # Ogni riha è una tupla con 3 elementi:
            #       1. Fare
            #       2. FormField
            #       3. Boolean che indica se la tariffa è utilizzabile dall'utente
            row = []
            for k in ('S', 'P', 'C'):
                try:
                    f = fares[t+k]
                except KeyError:
                    row.append((None, None, None))
                else:
                    # la tariffa è valida se passa il controllo temporale e se il tipo
                    # dell'account è compatibile
                    valid = not (company ^ (f['code'][-1] == 'C'))
                    row.append((f, form.__getitem__(f['code']), valid))
            rows.append(row)
        ctx['rows'] = rows
    elif fare_type == 'hotel-room-sharing':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['bed_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'hotel-room':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['room_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'other':
        tpl = 'p3/fragments/render_cart_og_ticket_row.html'
        fares = defaultdict(dict)
        order = ('p', 'c')
        columns = set()
        for f in fares_list:
            if f['ticket_type'] in ('other', 'event') and f['code'][0] != 'H':
                columns.add(f['recipient_type'])
                fares[f['name']][f['recipient_type']] = f
        ctx['fares'] = fares.values()
        ctx['recipient_types'] = sorted(columns, key=lambda v: order.index(v))
    elif fare_type == 'partner':
        tpl = 'p3/fragments/render_cart_partner_ticket_row.html'
        ctx['fares'] = [ f for f in fares_list if f['ticket_type'] in 'partner' ]

    return render_to_string(tpl, ctx)
示例#15
0
文件: p3.py 项目: zevaverbach/epcon
def render_cart_rows(context, fare_type, form):
    assert fare_type in ('conference', 'goodies', 'partner', 'hotel-room',
                         'hotel-room-sharing', 'other')
    ctx = Context(context)
    request = ctx['request']
    try:
        company = request.user.assopy_user.account_type == 'c'
    except AttributeError:
        # utente anonimo o senza il profilo assopy (impossibile!)
        company = False

    ctx.update({
        'form': form,
        'company': company,
    })

    fares_list = filter(lambda f: f['valid'],
                        cdataaccess.fares(settings.CONFERENCE_CONFERENCE))
    if fare_type == 'conference':
        tpl = 'p3/fragments/render_cart_conference_ticket_row.html'
        # il rendering dei biglietti "conference" è un po' particolare, ogni
        # riga del carrello corrisponde a più `fare` (student, private,
        # company)

        # Le tariffe devono essere ordinate secondo l'ordine temporale + il
        # tipo di biglietto + il destinatario:
        #   early
        #       full            [Student, Private, Company]
        #       lite (standard) [Student, Private, Company]
        #       daily           [Student, Private, Company]
        #   regular (late)
        #       ...
        #   on desk
        #       ...
        #
        # L'ordine temporale viene implicitamente garantito dall'aver escluso
        # le fare non più valide (non permettiamo overlap nel range di
        # validità)
        fares = dict(
            (f['code'][2:], f) for f in fares_list if f['code'][0] == 'T')
        rows = []
        for t in ('S', 'L', 'D'):
            # Per semplificare il template impacchetto le fare a gruppi di tre:
            # studente, privato, azienda.
            # Ogni riha è una tupla con 3 elementi:
            #       1. Fare
            #       2. FormField
            #       3. Boolean che indica se la tariffa è utilizzabile dall'utente
            row = []
            for k in ('S', 'P', 'C'):
                try:
                    f = fares[t + k]
                except KeyError:
                    row.append((None, None, None))
                else:
                    # la tariffa è valida se passa il controllo temporale e se il tipo
                    # dell'account è compatibile
                    valid = not (company ^ (f['code'][-1] == 'C'))
                    row.append((f, form.__getitem__(f['code']), valid))
            rows.append(row)
        ctx['rows'] = rows
    elif fare_type == 'hotel-room-sharing':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['bed_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'hotel-room':
        tpl = 'p3/fragments/render_cart_hotel_ticket_row.html'
        ctx['field'] = form['room_reservations']
        ctx['field'].field.widget._errors = ctx['field'].errors
    elif fare_type == 'other':
        tpl = 'p3/fragments/render_cart_og_ticket_row.html'
        fares = defaultdict(dict)
        order = ('p', 'c')
        columns = set()
        for f in fares_list:
            if f['ticket_type'] in ('other', 'event') and f['code'][0] != 'H':
                columns.add(f['recipient_type'])
                fares[f['name']][f['recipient_type']] = f
        ctx['fares'] = fares.values()
        ctx['recipient_types'] = sorted(columns, key=lambda v: order.index(v))
    elif fare_type == 'partner':
        tpl = 'p3/fragments/render_cart_partner_ticket_row.html'
        ctx['fares'] = [f for f in fares_list if f['ticket_type'] in 'partner']

    return render_to_string(tpl, ctx)
示例#16
0
    def render(self, name, value, attrs=None):
        try:
            start = settings.P3_HOTEL_RESERVATION['period'][0]
        except:
            raise TypeError('P3_HOTEL_RESERVATION not set')

        from django.template.loader import render_to_string
        from conference import dataaccess as cdataaccess

        tpl = 'p3/fragments/form_field_hotel_reservation_widget.html'
        fares = {
            'HR': [],
            'HB': [],
        }
        for f in cdataaccess.fares(settings.CONFERENCE_CONFERENCE):
            if not f['valid']:
                continue
            if f['code'][:2] == 'HR':
                fares['HR'].append(f)
            elif f['code'][:2] == 'HB':
                fares['HB'].append(f)

        if not fares['HR'] or not fares['HB']:
            return ''

        if not value:
            value = [
                {
                    'fare': fares['HB'][0]['code'],
                    'qty': 0,
                    'period': settings.P3_HOTEL_RESERVATION['default']
                },
                {
                    'fare': fares['HR'][0]['code'],
                    'qty': 0,
                    'period': settings.P3_HOTEL_RESERVATION['default']
                },
            ]

        types = getattr(self, 'types', ['HR', 'HB'])
        rows = []
        for entry in value:
            k = entry['fare'][:2]
            if k not in ('HR', 'HB'):
                raise TypeError('unsupported fare')
            if k not in types:
                continue
            ctx = {
                'label': '',
                'type': '',
                'qty': entry['qty'],
                'period': map(lambda x: (x - start).days, entry['period']),
                'fare': entry['fare'],
                'fares': [],
            }
            if k == 'HB':
                ctx['label'] = _('Room sharing')
                ctx['type'] = 'bed'
                ctx['fares'] = fares['HB']
            else:
                ctx['label'] = _('Full room')
                ctx['type'] = 'room'
                ctx['fares'] = fares['HR']

            rows.append(ctx)

        # XXX schifezza!
        # per come ho implementato il rendering del widget ho bisogno di sapere
        # qui e adesso se ci sono errori per mostrarli nel posto giusto.
        # Purtroppo gli errori sono una proprietà del BoundField non del field
        # ne tantomeno del widget. Questo codice è un accrocchio funziona
        # perché nel templatetag aggancio al widget gli errori della form. Il
        # modo pulito sarebbe implementare il rendering dei subwidget come
        # avviene per il RadioInput, passare dal filtro |field e inserire li
        # gli errori.
        errors = [None] * len(rows)
        if hasattr(self, '_errors'):
            print self._errors
            for e in self._errors:
                try:
                    ix, msg = e.split(':', 1)
                except ValueError:
                    continue
                try:
                    errors[int(ix)] = msg
                except:
                    continue
        for e in zip(rows, errors):
            if e[1]:
                e[0]['error'] = e[1]

        ctx = {
            'start': start,
            'days': (settings.P3_HOTEL_RESERVATION['period'][1] - start).days,
            'rows': rows,
            'name': name,
        }
        return render_to_string(tpl, ctx)