def stats_view(request):
    """
    This view lets accountants view statistics:
    how many tickets of which category, payment status, etc.
    """
    #print("who is it? %s" % request.user.login)
    _number_of_datasets = PartyTicket.get_number()
    _number_of_tickets = PartyTicket.get_num_tickets()
    _num_passengers = PartyTicket.num_passengers()
    _num_open_tickets = int(_number_of_tickets) - int(_num_passengers)
    _num_tickets_unpaid = PartyTicket.get_num_unpaid()
    #
    _num_hobos = PartyTicket.get_num_hobos()
    _num_class_2 = PartyTicket.get_num_class_2()
    _num_class_2_food = PartyTicket.get_num_class_2_food()
    _num_class_1 = PartyTicket.get_num_class_1()
    _num_class_green = PartyTicket.get_num_class_green()
    #
    _sum_tickets_total = PartyTicket.get_sum_tickets_total()
    _sum_tickets_paid = PartyTicket.get_sum_tickets_paid()
    _sum_tickets_unpaid = PartyTicket.get_sum_tickets_unpaid()

    return {
        '_number_of_datasets': _number_of_datasets,
        '_number_of_tickets': _number_of_tickets,
        '_num_passengers': _num_passengers,
        '_num_open_tickets': _num_open_tickets,
        '_num_tickets_unpaid': _num_tickets_unpaid,
        # ticket categories
        'num_hobos': _num_hobos,
        'num_class_2': _num_class_2,
        'num_class_2_food': _num_class_2_food,
        'num_class_1': _num_class_1,
        'num_class_green': _num_class_green,
        # focus on cash
        'sum_tickets_total': _sum_tickets_total,
        'sum_tickets_paid': _sum_tickets_paid,
        'sum_tickets_unpaid': _sum_tickets_unpaid,
    }
Exemple #2
0
def party_view(request):
    """
    the view users use to order a ticket
    """
    _num_tickets = PartyTicket.get_num_tickets()
    _num_tickets_paid = PartyTicket.get_num_tickets_paid()

    class PersonalData(colander.MappingSchema):
        """
        colander schema for membership application form
        """
        locale_name = get_locale_name(request)
        firstname = colander.SchemaNode(
            colander.String(),
            title=_(u"Vorame"),
            oid="firstname",
        )
        lastname = colander.SchemaNode(
            colander.String(),
            title=_(u"Nachname"),
            oid="lastname",
        )
        email = colander.SchemaNode(
            colander.String(),
            title=_(u'Email'),
            validator=colander.Email(),
            oid="email",
        )
        # password = colander.SchemaNode(
        #     colander.String(),
        #     validator=colander.Length(min=3, max=100),
        #     widget=deform.widget.PasswordWidget(size=20),
        #     title=_(u"Password (to protect access to your data)"),
        #     description=_("We need a password to protect your data. After "
        #                   "verifying your email you will have to enter it."),
        #     oid="password",
        # )
        comment = colander.SchemaNode(
            colander.String(),
            title=_("Kommentare"),
            missing='',
            validator=colander.Length(max=250),
            widget=deform.widget.TextAreaWidget(rows=3, cols=50),
            description=_(u"Raum für Kommentare (255 Zeichen)"),
            oid="comment",
        )
        _LOCALE_ = colander.SchemaNode(
            colander.String(),
            widget=deform.widget.HiddenWidget(),
            default=locale_name
        )

    num_ticket_options = (
        ('10', _(u'10 tickets')),
        ('9', _(u'9 tickets')),
        ('8', _(u'8 tickets')),
        ('7', _(u'7 tickets')),
        ('6', _(u'6 tickets')),
        ('5', _(u'5 tickets')),
        ('4', _(u'4 tickets')),
        ('3', _(u'3 tickets')),
        ('2', _(u'2 tickets')),
        ('1', _(u'1 tickets')),
        #('0', _(u'no ticket')),
    )
    ticket_type_options = (
        (1, _(u'2. Klasse (5€: party, bands)')),
        (2, _(u'2. Klasse + Speisewagen (15€: party, bands, essen)')),
        (3, _(u'1. Klasse (50€: party, bands, essen, kaffee, shirt)')),
        (4, _(u'Grüne Mamba (100€: party, bands, essen, kaffee, jacke)')),
    )

    class PartyTickets(colander.MappingSchema):

        ticket_type = colander.SchemaNode(
            colander.Integer(),
            title=_(u"Ich reise in der folgenden Kategorie:"),
            description=_(
                u'Du kannst uns mit dem Kauf von Tickets unterstützen. '
                u'Überschüsse fliessen in die Büroausstattung.'),
            default="1",
            widget=deform.widget.RadioChoiceWidget(
                size=1, css_class='ticket_types_input',
                values=ticket_type_options,
                #inline=True
            ),
            oid="ticket_type"
        )
        num_tickets = colander.SchemaNode(
            colander.Integer(),
            title=_(u"Ich nehme die folgende Anzahl von Tickets"),
            description=_(
                u'Du kannst zwischen 1 und 10 Tickets bestellen. '
                u'Die Kosten variieren je nach Ticket-Kategorie.'),
            default="1",
            widget=deform.widget.SelectSliderWidget(
                #size=3, css_class='num_tickets_input',
                values=num_ticket_options),
            validator=colander.Range(
                min=1,
                max=10,
                min_err=_(u"Du brauchst mindestens ein Ticket, "
                          u"um die Reise anzutreten."),
                max_err=_(u"Höchstens 10 Tickets. (viel los!)"),
            ),
            oid="num_tickets")

    class TicketForm(colander.Schema):
        """
        The Form consists of
        - Personal Data
        - Ticketing Information
        - FoodInfo
        """
        person = PersonalData(
            title=_(u"Persönliche Daten"),
            #description=_(u"this is a test"),
            #css_class="thisisjustatest"
        )
        ticket_info = PartyTickets(
            title=_(u"Ticketinformationen")
        )
        #shares = FoodInfo(
        #    title=_(u"Food Stamps")
        #)

    schema = TicketForm()

    form = deform.Form(
        schema,
        buttons=[
            deform.Button('submit', _(u'Absenden')),
            deform.Button('reset', _(u'Zurücksetzen'))
        ],
        use_ajax=True,
        renderer=zpt_renderer
    )

    # if the form has NOT been used and submitted, remove error messages if any
    if not 'submit' in request.POST:
        request.session.pop_flash()

    # if the form has been used and SUBMITTED, check contents
    if 'submit' in request.POST:
        print "submitted!"
        controls = request.POST.items()
        print controls
        try:
            print 'about to validate form input'
            appstruct = form.validate(controls)
            print 'done validating form input'
            print("the appstruct from the form: %s \n") % appstruct
            for thing in appstruct:
                print("the thing: %s") % thing
                print("type: %s") % type(thing)

        except ValidationFailure, e:
            print(e)
            request.session.flash(
                _(u"Please note: There were errors, "
                  "please check the form below."),
                'message_above_form',
                allow_duplicate=False)
            return{
                'form': e.render(),
                '_num_tickets': _num_tickets,
                '_num_tickets_paid': _num_tickets_paid,
            }

        # make confirmation code
        randomstring = make_random_string()

        # calculate the total sum
        the_value = {
            1: 5,
            2: 15,
            3: 50,
            4: 100,
        }
        _the_total = appstruct['ticket_info']['num_tickets'] * the_value.get(
            appstruct['ticket_info']['ticket_type'])
        appstruct['ticket_info']['the_total'] = _the_total
        print("_the_total: %s" % _the_total)
        # to store the data in the DB, an object is created
        ticket = PartyTicket(
            firstname=appstruct['person']['firstname'],
            lastname=appstruct['person']['lastname'],
            email=appstruct['person']['email'],
            password='',  # appstruct['person']['password'],
            locale=appstruct['person']['_LOCALE_'],
            email_is_confirmed=False,
            email_confirm_code=randomstring,
            date_of_submission=datetime.now(),
            num_tickets=appstruct['ticket_info']['num_tickets'],
            ticket_type=appstruct['ticket_info']['ticket_type'],
            the_total=_the_total,
            user_comment=appstruct['person']['comment'],
        )
        dbsession = DBSession
        try:
            print "about to add ticket"
            dbsession.add(ticket)
            print "adding ticket"
            appstruct['email_confirm_code'] = randomstring  # XXX
            appstruct['email_confirm_code'] = randomstring
        except InvalidRequestError, e:  # pragma: no cover
            print("InvalidRequestError! %s") % e
def kasse(request):
    """
    This view lets cachiers do stuff
    """
    logged_in = authenticated_userid(request)
    print("authenticated_userid: " + str(logged_in))
    #log.info("check in conducted by %s" % logged_in)

    # check for input from "find dataset by confirm code" form
    if 'code_to_show' in request.POST:
        print("found code_to_show in POST: %s" % request.POST['code_to_show'])
        try:
            _code = request.POST['code_to_show']
            #print(_code)
            _entry = PartyTicket.get_by_code(_code)
            print(_entry)
            print(_entry.id)

            return HTTPFound(
                location=request.route_url(
                    'check_in',
                    event='p1402',
                    code=_entry.email_confirm_code)
            )
        except:
            # choose default
            print("barf!")
            request.session.flash('gleis 16 gibt es garnicht!')
            pass

    # prepare the autocomplete form with codes
    # get codes from another view via subrequest, see
    # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/subrequest.html
    subreq = Request.blank('/all_codes')  # see http://0.0.0.0:6543/all_codes
    response = request.invoke_subrequest(subreq)
    the_codes = json.loads(response.body)  # gotcha: json needed!

    my_autoc_wid = deform.widget.AutocompleteInputWidget(
        min_length=1,
        title="widget title",
        values=the_codes,
    )

    # prepare a form for autocomplete search for codes.
    class CodeAutocompleteForm(colander.MappingSchema):
        """
        colander schema to make deform autocomplete form
        """
        code_to_show = colander.SchemaNode(
            colander.String(),
            title="Code eingeben (autocomplete)",
            validator=colander.Length(min=1, max=8),
            widget=my_autoc_wid,
            description='start typing. use arrows. press enter. twice.'

        )

    schema = CodeAutocompleteForm()
    form = deform.Form(
        schema,
        buttons=('go!',),
        #use_ajax=True,  # <-- whoa!
        #renderer=zpt_renderer,
    )
    autoformhtml = form.render()

    _num_passengers = PartyTicket.num_passengers()
    _num_open_tickets = int(
        PartyTicket.get_num_tickets()) - int(_num_passengers)

    return {
        'autoform': autoformhtml,
        'logged_in': logged_in,
        'num_passengers': _num_passengers,
        'num_open_tickets': _num_open_tickets
    }
def new_ticket(request):
    """
    This view lets cachiers make/issue new tickets

    a form permits checkin of people, up to the amount of tickets
    """
    logged_in = authenticated_userid(request)
    print("authenticated_userid: " + str(logged_in))

    print("the request.POST: %s" % request.POST)
    add_cond = ('persons' in request.POST)
    if add_cond:
        _num = request.POST['persons']
        if 'type1' in request.POST:
            _type = request.POST['type1']
            _type_int = 1
            _type_cost = 5
        elif 'type2' in request.POST:
            _type = request.POST['type2']
            _type_int = 2
            _type_cost = 15
        elif 'type3' in request.POST:
            _type = request.POST['type3']
            _type_int = 3
            _type_cost = 50
        elif 'type4' in request.POST:
            _type = request.POST['type4']
            _type_int = 4
            _type_cost = 100
        log.info(
            "%s tickets(s) of cat. %s sold by %s" % (_num, _type, logged_in))
        _new = PartyTicket(
            firstname='anon',
            lastname='anon',
            email='anon',
            password='******',
            locale='de',
            email_is_confirmed=False,
            email_confirm_code='cash',
            num_tickets=int(_num),
            ticket_type=_type_int,
            the_total=int(_num)*_type_cost,
            user_comment='got ticket at entry',
            date_of_submission=datetime.now(),
            payment_received=True
        )
        #try:
        dbsession = DBSession()
        _new.payment_received = True
        #import pdb
        #pdb.set_trace()
        _new.checked_persons = int(_num)
        _new.payment_received_date = datetime.now()
        _new.email_confirm_code = 'CASHDESK' + make_random_string()
        _new.accountant_comment = 'issued by %s' % logged_in
        dbsession.add(_new)

        #except:
        #    print("new_ticket: something went wrong")
            #pass
    _num_passengers = PartyTicket.num_passengers()
    _num_open_tickets = int(
        PartyTicket.get_num_tickets()) - int(_num_passengers)

    return {
        'logged_in': logged_in,
        'num_passengers': _num_passengers,
        'num_open_tickets': _num_open_tickets,
    }
def check_in(request):
    """
    This view lets cachiers log in people

    a form permits checkin of people, up to the amount of tickets
    """
    logged_in = authenticated_userid(request)
    print("authenticated_userid: " + str(logged_in))
    log.info("check in conducted by %s" % logged_in)

    # check for input from checkin function POST
    #print(request.POST)
    # MultiDict([('persons', u'10'),
    #            ('checkin', u'Check in!'),
    #            ('code', u'ABCDEFGHIJ')])
    __check = ('checkin' in request.POST)
    __code = ('code' in request.POST)
    __personen = ('persons' in request.POST)
    if __check and __code and __personen:
        #print("############# check_in_cond is True.")
        _code = request.POST['code']
        _persons = request.POST['persons']
        _ticket = PartyTicket.get_by_code(_code)
        if isinstance(_ticket, NoneType):
            "if the ticket code was not found, return to base"
            request.session.flash('code not found. gleis 16 gibt es nicht.')
            return HTTPFound(
                location=request.route_url('kasse'))
        _ticket.checkin_time = datetime.now()
        #_ticket.checkin_seen = True
        _ticket.checked_persons += int(_persons)

    _num_passengers = PartyTicket.num_passengers()
    _num_open_tickets = int(
        PartyTicket.get_num_tickets()) - int(_num_passengers)

    '''
    checkin was called from a prepared URL ('/ci/{event}/{code}')
    '''
    _code = request.matchdict['code']
    # get dataset from db
    _ticket = PartyTicket.get_by_code(_code)
    if isinstance(_ticket, NoneType):  # not found
        print("ticket not found!?!")
        return {
            'logged_in': logged_in,
            'status': 'NOT FOUND',
            'code': '',
            'paid': 'Nein',
            'num_passengers': _num_passengers,
            'num_open_tickets': _num_open_tickets,
        }
    else:
        print("the ticket: %s" % _ticket)
        pass

    '''
    users may pay at the counter,
    if they forgot to transfer (and room is not full)
    '''
    if 'Bezahlt' in request.POST:
        _ticket.payment_received = True
        _ticket.payment_received_date = datetime.now()

    # types of tickets displayed in the backend
    ticket_type_options = {
        1: _(u'2. Klasse'),
        2: _(u'2. Klasse + Speisewagen'),
        3: _(u'1. Klasse'),
        4: _(u'Grüne Mamba'),
    }

    _klass = ticket_type_options.get(_ticket.ticket_type)
    _vacancies = _ticket.num_tickets - _ticket.checked_persons

    return {
        'vacancies': _vacancies,  # the free tickets of this visitor
        'logged_in': logged_in,
        'num_passengers': _num_passengers,
        'num_open_tickets': _num_open_tickets,
        'code': _code,
        'klass': _klass,
        'paid': _ticket.payment_received,
        'ticket': _ticket,
    }