Пример #1
0
def new_member(request):
    '''
    let staff create a new member entry, when receiving input via dead wood
    '''

    # XXX check if submitted, etc...

    class PersonalData(colander.MappingSchema):
        """
        colander schema for membership application form
        """
        firstname = colander.SchemaNode(
            colander.String(),
            title=u'Vorname (b. Körpersch.: Ansprechpartner)',
            oid="firstname",
        )
        lastname = colander.SchemaNode(
            colander.String(),
            title=u'Nachname (b. Körpersch.: Name der Körperschaft)',
            oid="lastname",
        )
        email = colander.SchemaNode(
            colander.String(),
            title=_(u'E-Mail'),
            validator=colander.Email(),
            oid="email",
        )
        passwort = colander.SchemaNode(
            colander.String(),
            widget=deform.widget.HiddenWidget(),
            default='NoneSet',
            missing='NoneSetPurposefully'
        )
        address1 = colander.SchemaNode(
            colander.String(),
            title='Adresse Zeile 1'
        )
        address2 = colander.SchemaNode(
            colander.String(),
            missing=unicode(''),
            title='Adresse Zeile 2'
        )
        postcode = colander.SchemaNode(
            colander.String(),
            title='Postleitzahl',
            oid="postcode"
        )
        city = colander.SchemaNode(
            colander.String(),
            title='Ort',
            oid="city",
        )
        country = colander.SchemaNode(
            colander.String(),
            title='Land',
            default=country_default,
            widget=deform.widget.SelectWidget(
                values=country_codes),
            oid="country",
        )
        date_of_birth = colander.SchemaNode(
            colander.Date(),
            title='Geburtsdatum',
            # widget=deform.widget.DatePartsWidget(
            #    inline=True),
            default=date(1970, 1, 1),
            oid="date_of_birth",
        )
        locale = colander.SchemaNode(
            colander.String(),
            widget=deform.widget.HiddenWidget(),
            default='de',
            missing='de',
        )

    class MembershipInfo(colander.Schema):

        yes_no = ((u'yes', _(u'Yes')),
                  (u'no', _(u'No')),
                  (u'dontknow', _(u'Unknown')),)

        entity_type = colander.SchemaNode(
            colander.String(),
            title=(u'Person oder Körperschaft?'),
            description=u'Bitte die Kategorie des Mitglied auswählen.',
            widget=deform.widget.RadioChoiceWidget(
                values=(
                    (u'person',
                     (u'Person')),
                    (u'legalentity',
                     u'Körperschaft'),
                ),
            ),
            missing=unicode(''),
            oid='entity_type',
        )
        membership_type = colander.SchemaNode(
            colander.String(),
            title=(u'Art der Mitgliedschaft (lt. Satzung, §4)'),
            description=u'Bitte die Art der Mitgliedschaft auswählen.',
            widget=deform.widget.RadioChoiceWidget(
                values=(
                    (u'normal',
                     (u'Normales Mitglied')),
                    (u'investing',
                     u'Investierendes Mitglied'),
                    (u'unknown',
                     u'Unbekannt.'),
                ),
            ),
            missing=unicode(''),
            oid='membership_type',
        )
        member_of_colsoc = colander.SchemaNode(
            colander.String(),
            title='Mitglied einer Verwertungsgesellschaft?',
            validator=colander.OneOf([x[0] for x in yes_no]),
            widget=deform.widget.RadioChoiceWidget(values=yes_no),
            missing=unicode(''),
            oid="other_colsoc",
            # validator=colsoc_validator
        )
        name_of_colsoc = colander.SchemaNode(
            colander.String(),
            title=(u'Falls ja, welche? (Kommasepariert)'),
            missing=unicode(''),
            oid="colsoc_name",
            # validator=colander.All(
            #    colsoc_validator,
            # )
        )

    class Shares(colander.Schema):
        """
        the number of shares a member wants to hold
        """
        num_shares = colander.SchemaNode(
            colander.Integer(),
            title='Anzahl Anteile (1-60)',
            default="1",
            validator=colander.Range(
                min=1,
                max=60,
                min_err=u'mindestens 1',
                max_err=u'höchstens 60',
            ),
            oid="num_shares")

    class MembershipForm(colander.Schema):
        """
        The Form consists of
        - Personal Data
        - Membership Information
        - Shares
        """
        person = PersonalData(
            title=_(u"Personal Data"),
            # description=_(u"this is a test"),
            # css_class="thisisjustatest"
        )
        membership_info = MembershipInfo(
            title=_(u"Membership Requirements")
        )
        shares = Shares(
            title=_(u"Shares")
        )

    schema = MembershipForm()

    form = deform.Form(
        schema,
        buttons=[
            deform.Button('submit', _(u'Submit')),
            deform.Button('reset', _(u'Reset'))
        ],
        use_ajax=True,
        # renderer=zpt_renderer
    )

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

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

            # data sanity: if not in collecting society, don't save
            #  collsoc name even if it was supplied through form
            # if 'no' in appstruct['membership_info']['member_of_colsoc']:
            #    appstruct['membership_info']['name_of_colsoc'] = ''
            #    print appstruct['membership_info']['name_of_colsoc']
            # print '-'*80

        except ValidationFailure as e:
            # print("Validation Failure!")
            # print("the request.POST: %s \n" % request.POST)
            # for thing in request.POST:
            #    print("the thing: %s") % thing
            #    print("type: %s") % type(thing)
            # print(e.args)
            # print(e.error)
            # print(e.message)
            request.session.flash(
                _(u"Please note: There were errors, "
                  "please check the form below."),
                'message_above_form',
                allow_duplicate=False)
            return{'form': e.render()}

        def make_random_string():
            """
            used as email confirmation code
            """
            import random
            import string
            return u''.join(
                random.choice(
                    string.ascii_uppercase + string.digits
                ) for x in range(10))

        # make confirmation code and
        randomstring = make_random_string()
        # check if confirmation code is already used
        while (C3sMember.check_for_existing_confirm_code(randomstring)):
            # create a new one, if the new one already exists in the database
            randomstring = make_random_string()  # pragma: no cover

        # to store the data in the DB, an objet is created
        member = C3sMember(
            firstname=appstruct['person']['firstname'],
            lastname=appstruct['person']['lastname'],
            email=appstruct['person']['email'],
            password='******',
            address1=appstruct['person']['address1'],
            address2=appstruct['person']['address2'],
            postcode=appstruct['person']['postcode'],
            city=appstruct['person']['city'],
            country=appstruct['person']['country'],
            locale=appstruct['person']['locale'],
            date_of_birth=appstruct['person']['date_of_birth'],
            email_is_confirmed=False,
            email_confirm_code=randomstring,
            # is_composer=('composer' in appstruct['activity']),
            # is_lyricist=('lyricist' in appstruct['activity']),
            # is_producer=('music producer' in appstruct['activity']),
            # is_remixer=('remixer' in appstruct['activity']),
            # is_dj=('dj' in appstruct['activity']),
            date_of_submission=datetime.now(),
            # invest_member=(
            #    appstruct['membership_info']['invest_member'] == u'yes'),
            membership_type=appstruct['membership_info']['membership_type'],
            member_of_colsoc=(
                appstruct['membership_info']['member_of_colsoc'] == u'yes'),
            name_of_colsoc=appstruct['membership_info']['name_of_colsoc'],
            # opt_band=appstruct['opt_band'],
            # opt_URL=appstruct['opt_URL'],
            num_shares=appstruct['shares']['num_shares'],
        )
        if 'legalentity' in appstruct['membership_info']['entity_type']:
            # print "this is a legal entity"
            member.membership_type = u'investing'
            member.is_legalentity = True

        dbsession = DBSession()

        try:
            _temp = request.url.split('?')[1].split('=')
            if 'id' in _temp[0]:
                _id = _temp[1]
                # print("the id we want to recreate: %s" % _id)

            # add a member with a DB id that had seen its entry deleted before
                _mem = C3sMember.get_by_id(_id)  # load from id
                if isinstance(_mem, NoneType):  # check deletion status
                    member.id = _id  # set id as specified
        except:
            # print "no splitable url params found, creating new entry"
            pass

        # add member at next free DB id (default if member.id not set)
        try:
            dbsession.add(member)
            dbsession.flush()
            # print(member.id)
            the_new_id = member.id
            # appstruct['email_confirm_code'] = randomstring  # ???
        except InvalidRequestError, e:  # pragma: no cover
            print("InvalidRequestError! %s") % e
        except IntegrityError, ie:  # pragma: no cover
            print("IntegrityError! %s") % ie
Пример #2
0
def join_c3s(request):
    """
    This is the main membership application form view: Join C3S as member
    """
    # if another language was chosen by clicking on a flag
    # the add_locale_to_cookie subscriber has planted an attr on the request
    if hasattr(request, '_REDIRECT_'):

        _query = request._REDIRECT_
        # set language cookie
        # ToDo: the proper cookie name is _LOCALE_ (pyramid)
        request.response.set_cookie('locale', _query)
        request.locale = _query
        locale_name = _query
        return HTTPFound(location=request.route_url('join'),
                         headers=request.response.headers)
    else:
        locale_name = get_locale_name(request)

    if DEBUG:
        print "-- locale_name: " + str(locale_name)

    # set default of Country select widget according to locale
    try:
        country_default = customization.locale_country_mapping.get(locale_name)
    except AttributeError:
        print(dir(customization))
        country_default = 'GB'
    if DEBUG:
        print("== locale is :" + str(locale_name))
        print("== choosing :" + str(country_default))

    class PersonalData(colander.MappingSchema):
        """
        colander schema for membership application form
        """
        firstname = colander.SchemaNode(
            colander.String(),
            title=_(u"(Real) First Name"),
            oid="firstname",
        )
        lastname = colander.SchemaNode(
            colander.String(),
            title=_(u"(Real) Last Name"),
            oid="lastname",
        )
        email = colander.SchemaNode(
            colander.String(),
            title=_(u'Email Address'),
            validator=colander.Email(),
            oid="email",
        )
        password = colander.SchemaNode(
            colander.String(),
            validator=colander.Length(min=5, max=100),
            widget=deform.widget.CheckedPasswordWidget(size=20),
            title=_(u'Password (to protect access to your data)'),
            description=_(u'We need a password to protect your data. After '
                          u'verifying your email you will have to enter it.'),
            oid='password',
        )
        address1 = colander.SchemaNode(colander.String(),
                                       title=_(u'Address Line 1'))
        address2 = colander.SchemaNode(colander.String(),
                                       missing=unicode(''),
                                       title=_(u'Address Line 2'))
        postcode = colander.SchemaNode(colander.String(),
                                       title=_(u'Postal Code'),
                                       oid="postcode")
        city = colander.SchemaNode(
            colander.String(),
            title=_(u'City'),
            oid="city",
        )
        country = colander.SchemaNode(
            colander.String(),
            title=_(u'Country'),
            default=country_default,
            widget=deform.widget.SelectWidget(values=country_codes),
            oid="country",
        )
        date_of_birth = colander.SchemaNode(
            colander.Date(),
            title=_(u'Date of Birth'),
            # css_class="hasDatePicker",
            widget=deform.widget.DatePartsWidget(),
            default=date(2013, 1, 1),
            validator=Range(
                min=date(1913, 1, 1),
                # max 18th birthday, no minors through web formular
                max=date(date.today().year - 18,
                         date.today().month,
                         date.today().day),
                min_err=_(u'Sorry, we do not believe that you are that old'),
                max_err=_(
                    u'Unfortunately, the membership application of an '
                    u'underaged person is currently not possible via our web '
                    u'form. Please send an email to [email protected].')),
            oid="date_of_birth",
        )
        locale = colander.SchemaNode(colander.String(),
                                     widget=deform.widget.HiddenWidget(),
                                     default=locale_name)

    class MembershipInfo(colander.Schema):
        """
        Basic member information.
        """
        yes_no = ((u'yes', _(u'Yes')), (u'no', _(u'No')))
        if len(customization.membership_types) > 1:
            membership_type = colander.SchemaNode(
                colander.String(),
                title=_(
                    u'I want to become a ... '
                    u'(choose membership type, see C3S SCE statute sec. 4)'),
                description=_(u'choose the type of membership.'),
                widget=deform.widget.RadioChoiceWidget(
                    values=((i['name'], i['description'])
                            for i in customization.membership_types), ),
                oid='membership_type')
        if customization.enable_colsoc_association:
            member_of_colsoc = colander.SchemaNode(
                colander.String(),
                title=_(u'Currently, I am a member of (at least) one other '
                        u'collecting society.'),
                validator=colander.OneOf([x[0] for x in yes_no]),
                widget=deform.widget.RadioChoiceWidget(values=yes_no),
                oid="other_colsoc",
                # validator=colsoc_validator
            )
            name_of_colsoc = colander.SchemaNode(
                colander.String(),
                title=_(u'If so, which one(s)? Please separate multiple '
                        u'collecting societies by comma.'),
                description=_(
                    u'Please tell us which collecting societies '
                    u'you are a member of. '
                    u'If more than one, please separate them by comma.'),
                missing=unicode(''),
                oid="colsoc_name",
            )

    class Fees(colander.Schema):
        member_type = colander.SchemaNode(
            colander.String(),
            title=_(u'Please tell us wether you\'re an individual, '
                    u'freelancer or company or want to support us '
                    u'generously as a sustaining member'),
            widget=deform.widget.RadioChoiceWidget(
                values=[(member_type, t_description) for fee, member_type,
                        t_description in customization.membership_fees]),
            oid='member_type')

        # not validating here: depends on ^
        # http://deformdemo.repoze.org/require_one_or_another/
        member_custom_fee = colander.SchemaNode(
            colander.Decimal('1.00'),
            title=_(u'custom membership fee'),
            widget=deform.widget.MoneyInputWidget(
                symbol=customization.currency,
                showSymbol=True,
                defaultZero=True),
            description=_(
                u'Sustaining members: You can set your fees (minimum 100 €)'),
            oid='membership_custom_fee',
            default=customization.membership_fee_custom_min,
            validator=Range(
                min=customization.membership_fee_custom_min,
                max=None,
                min_err=
                _(u'please enter at least the minimum fee for sustaining members'
                  )))

    class Shares(colander.Schema):
        """
        the number of shares a member wants to hold

        this involves a slider widget: added to deforms widgets.
        see README.Slider.rst
        """
        num_shares = colander.SchemaNode(
            colander.Integer(),
            title=_(u"I want to buy the following number "
                    u"of Shares (50 € each, up to 3000 €, see "
                    u"C3S statute sec. 5)"),
            description=_(
                u'You can choose any amount of shares between 1 and 60.'),
            default="1",
            widget=TextInputSliderWidget(size=3, css_class='num_shares_input'),
            validator=colander.Range(
                min=1,
                max=60,
                min_err=_(u'You need at least one share of 50 €.'),
                max_err=_(u'You may choose 60 shares at most (3000 €).'),
            ),
            oid="num_shares")

    class TermsInfo(colander.Schema):
        """
        some legal requirements
        """
        def statute_validator(node, value):
            """
            Validator for statute confirmation.
            """
            if not value:
                # raise without additional error message as the description
                # already explains the necessity of the checkbox
                raise Invalid(node, u'')

        got_statute = colander.SchemaNode(
            colander.Bool(true_val=u'yes'),
            #title=(u''),
            title=_(u'I acknowledge that the statutes and membership dues '
                    u'regulations determine periodic contributions '
                    u'for full members.'),
            label=_(
                u'An electronic copy of the statute of the '
                u'C3S SCE has been made available to me (see link below).'),
            description=_(u'You must confirm to have access to the statute.'),
            widget=deform.widget.CheckboxWidget(),
            validator=statute_validator,
            required=True,
            oid='got_statute',
            #label=_('Yes, really'),
        )

        def dues_regulations_validator(node, value):
            """
            Validator for dues regulations confirmation.
            """
            if not value:
                # raise without additional error message as the description
                # already explains the necessity of the checkbox
                raise Invalid(node, u'')

        got_dues_regulations = colander.SchemaNode(
            colander.Bool(true_val=u'yes'),
            title=(u''),
            label=_(
                u'An electronic copy of the temporary membership dues '
                u'regulations of the C3S SCE has been made available to me '
                u'(see link below).'),
            description=_(u'You must confirm to have access to the temporary '
                          u'membership dues regulations.'),
            widget=deform.widget.CheckboxWidget(),
            validator=dues_regulations_validator,
            required=True,
            oid='got_dues_regulations',
            #label=_('Yes'),
        )

    class MembershipForm(colander.Schema):
        """
        The Form consists of
        - Personal Data
        - Membership Information
        - Shares
        """
        person = PersonalData(title=_(u'Personal Data'), )
        if len(customization.membership_types
               ) > 1 or customization.enable_colsoc_association:
            membership_info = MembershipInfo(title=_(u'Membership Data'))
        shares = Shares(title=_(u'Shares'))
        try:
            customization.membership_fees
        except NameError:
            pass
        else:
            fees = Fees(title=_(u'Membership Fees'))
        acknowledge_terms = TermsInfo(title=_(u'Acknowledgement'))

    schema = MembershipForm()

    form = deform.Form(schema,
                       buttons=[
                           deform.Button('submit', _(u'Next')),
                           deform.Button('reset', _(u'Reset'))
                       ],
                       use_ajax=True,
                       renderer=ZPT_RENDERER)

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

    # if the form has been used and SUBMITTED, check contents
    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)

            # data sanity: if not in collecting society, don't save
            #  collsoc name even if it was supplied through form
            if customization.membership_types and len(
                    customization.membership_types
            ) > 1 and 'no' in appstruct['membership_info']['member_of_colsoc']:
                appstruct['membership_info']['name_of_colsoc'] = ''

        except ValidationFailure as validation_failure:
            request.session.flash(_(u'Please note: There were errors, '
                                    u'please check the form below.'),
                                  'message_above_form',
                                  allow_duplicate=False)

            # If the validation error was not caused by the password field,
            # manually set an error to the password field because the user
            # needs to re-enter it after a validation error.
            form = validation_failure.field
            if form['person']['password'].error is None:
                form['person']['password'].error = Invalid(
                    None, _(u'Please re-enter your password.'))
                validation_failure = ValidationFailure(form, None, form.error)

            return {'form': validation_failure.render()}

        def make_random_string():
            """
            used as email confirmation code
            """
            import random
            import string
            return u''.join(
                random.choice(string.ascii_uppercase + string.digits)
                for x in range(10))

        # make confirmation code and
        randomstring = make_random_string()
        # check if confirmation code is already used
        while C3sMember.check_for_existing_confirm_code(randomstring):
            # create a new one, if the new one already exists in the database
            randomstring = make_random_string()  # pragma: no cover

        # to store the data in the DB, an objet is created
        coopMemberArgs = dict(
            firstname=appstruct['person']['firstname'],
            lastname=appstruct['person']['lastname'],
            email=appstruct['person']['email'],
            password=appstruct['person']['password'],
            address1=appstruct['person']['address1'],
            address2=appstruct['person']['address2'],
            postcode=appstruct['person']['postcode'],
            city=appstruct['person']['city'],
            country=appstruct['person']['country'],
            locale=appstruct['person']['locale'],
            date_of_birth=appstruct['person']['date_of_birth'],
            email_is_confirmed=False,
            email_confirm_code=randomstring,
            date_of_submission=datetime.now(),
            num_shares=appstruct['shares']['num_shares'],
        )

        if customization.enable_colsoc_association:
            coopMemberArgs['member_of_colsoc'] = (
                appstruct['membership_info']['member_of_colsoc'] == u'yes'),
            coopMemberArgs['name_of_colsoc'] = appstruct['membership_info'][
                'name_of_colsoc']

        if customization.membership_types and len(
                customization.membership_types) > 1:
            coopMemberArgs['membership_type'] = appstruct['membership_info'][
                'membership_type']

        member = C3sMember(**coopMemberArgs)
        dbsession = DBSession()
        try:
            dbsession.add(member)
            appstruct['email_confirm_code'] = randomstring
            if appstruct['fees']['member_type'] == 'sustaining':
                appstruct['fees']['fee'] = appstruct['fees'][
                    'member_custom_fee']
            else:
                appstruct['fees']['fee'] = [
                    v for v, t, d in customization.membership_fees
                    if t == appstruct['fees']['member_type']
                ][0]

        except InvalidRequestError as ire:  # pragma: no cover
            print("InvalidRequestError! %s") % ire
        except IntegrityError as integrity_error:  # pragma: no cover
            print("IntegrityError! %s") % integrity_error

        # redirect to success page, then return the PDF
        # first, store appstruct in session
        request.session['appstruct'] = appstruct
        request.session['appstruct']['locale'] = \
            appstruct['person']['locale']
        # empty the messages queue (as validation worked anyways)
        deleted_msg = request.session.pop_flash()
        del deleted_msg
        return HTTPFound(  # redirect to success page
            location=request.route_url('success'), )

    # if the form was submitted and gathered info shown on the success page,
    # BUT the user wants to correct their information:
    else:
        if 'edit' in request.POST:
            print(request.POST['edit'])
        # remove annoying message from other session
        deleted_msg = request.session.pop_flash()
        del deleted_msg
        if 'appstruct' in request.session:
            appstruct = request.session['appstruct']
            # pre-fill the form with the values from last time
            form.set_appstruct(appstruct)

    html = form.render()

    return {'form': html}
Пример #3
0
            address2=appstruct['person']['address2'],
            postcode=appstruct['person']['postcode'],
            city=appstruct['person']['city'],
            country=appstruct['person']['country'],
            locale=appstruct['person']['locale'],
            date_of_birth=appstruct['person']['date_of_birth'],
            email_is_confirmed=False,
            email_confirm_code=email_confirm_code,
            date_of_submission=datetime.now(),
            membership_type=appstruct['membership_info']['membership_type'],
            member_of_colsoc=(
                appstruct['membership_info']['member_of_colsoc'] == u'yes'),
            name_of_colsoc=appstruct['membership_info']['name_of_colsoc'],
            num_shares=appstruct['shares']['num_shares'],
        )
        DBSession().add(member)

        # we do have valid info from the form in the session (good)
        appstruct = request.session['appstruct']
        try:
            mailer = request.registry.get_mailer(request)
        except:
            return HTTPFound(location=request.route_url('join'))

        the_mail_body = customization.address_confirmation_mail.get(appstruct['person']['locale'],'en')
        the_mail = Message(
            subject=request.localizer.translate(_(
                'check-email-paragraph-check-email-subject',
                default=u'C3S: confirm your email address and load your PDF')),
            sender="*****@*****.**",
            recipients=[appstruct['person']['email']],