Пример #1
0
    def create(cls, membership_number, shares_quantity,
               board_confirmation=None):
        """
        Create a shares package.

        Args:
            membership_number: The membership number of the member for which
                the shares package is created.
            shares_quantity: The number of shares of the package to be created.
            board_confirmation: Optional. The date on which the board of
                directors confirmed the acquisition of the shares package.

        Returns:
            The technical primary key of the created shares package.
        """
        shares = Shares(
            number=shares_quantity,
            date_of_acquisition=board_confirmation,
        )
        # pylint: disable=no-member
        member = DBSession.query(C3sMember).filter(
            C3sMember.membership_number == membership_number).first()
        # pylint: disable=no-member
        DBSession.add(shares)
        member.shares.append(shares)
        member.num_shares += shares_quantity
        DBSession.flush()
        return shares.id
Пример #2
0
 def make_member_ready_for_approval(self):
     with transaction.manager:
         member1 = C3sMember(  # german
             firstname=u'SomeFirstnäme',
             lastname=u'SomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGFOO',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         member1.signature_received = True
         member1.payment_received = True
     DBSession.add(member1)
Пример #3
0
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print("removed old DBSession ==============================")
        except:
            # print("no DBSession to remove =============================")
            pass
        # try:
        #    os.remove('test_webtest_functional.db')
        #    #print "deleted old test database"
        # except:
        #    pass
        #    #print "never mind"

        my_settings = {
            # 'sqlalchemy.url': 'sqlite:///test_webtest_functional.db',
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.mailaddr': '*****@*****.**',
            'testing.mail_to_console': 'false'
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        self.session = DBSession  # ()

        Base.metadata.create_all(engine)
        # dummy database entries for testing
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            DBSession.add(member1)
            DBSession.flush()

        from c3smembership import main
        app = main({}, **my_settings)
        app.registry.get_mailer = get_mailer

        from webtest import TestApp
        self.testapp = TestApp(app)
Пример #4
0
    def create(cls, membership_number, shares_quantity,
               board_confirmation=None):
        """
        Create a shares package.

        Args:
            membership_number: The membership number of the member for which
                the shares package is created.
            shares_quantity: The number of shares of the package to be created.
            board_confirmation: Optional. The date on which the board of
                directors confirmed the acquisition of the shares package.

        Returns:
            The technical primary key of the created shares package.
        """
        shares = Shares(
            number=shares_quantity,
            date_of_acquisition=board_confirmation,
        )
        # pylint: disable=no-member
        member = DBSession.query(C3sMember).filter(
            C3sMember.membership_number == membership_number).first()
        # pylint: disable=no-member
        DBSession.add(shares)
        member.shares.append(shares)
        member.num_shares += shares_quantity
        DBSession.flush()
        return shares.id
Пример #5
0
    def setUp(self):
        my_settings = {"sqlalchemy.url": "sqlite:///:memory:", "api_auth_token": u"SECRETAUTHTOKEN"}
        self.config = testing.setUp()
        app = main({}, **my_settings)
        # set up the database
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u"SomeFirstnäme",
                lastname=u"SomeLastnäme",
                email=u"*****@*****.**",
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u"ABCDEFGFOO",
                password=u"arandompassword",
                date_of_submission=date.today(),
                membership_type=u"normal",
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u"23",
            )
        DBSession.add(member1)
        member1.email_invite_token_bcgv16 = u"MEMBERS_TOKEN"
        DBSession.flush()

        self.testapp = TestApp(app)
Пример #6
0
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print("removed old DBSession ==============================")
        except:
            # print("no DBSession to remove =============================")
            pass
        # try:
        #    os.remove('test_webtest_functional.db')
        #    #print "deleted old test database"
        # except:
        #    pass
        #    #print "never mind"

        my_settings = {
            # 'sqlalchemy.url': 'sqlite:///test_webtest_functional.db',
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.notification_sender': '*****@*****.**',
            'testing.mail_to_console': 'false'}
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        self.session = DBSession  # ()

        Base.metadata.create_all(engine)
        # dummy database entries for testing
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            DBSession.add(member1)
            DBSession.flush()

        from c3smembership import main
        app = main({}, **my_settings)
        app.registry.get_mailer = get_mailer

        from webtest import TestApp
        self.testapp = TestApp(app)
Пример #7
0
def _initTestingDB():
    # from sqlalchemy import create_engine
    # from c3smembership.models import initialize_sql
    # session = initialize_sql(create_engine('sqlite:///memory'))
    # session = DBSession
    my_settings = {
        'sqlalchemy.url': 'sqlite:///:memory:', }
    engine = engine_from_config(my_settings)
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    with transaction.manager:
        member1 = C3sMember(  # german
            firstname=u'SomeFirstnäme',
            lastname=u'SomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFGFOO',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        member2 = C3sMember(  # german
            firstname=u'AAASomeFirstnäme',
            lastname=u'XXXSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFGBAR',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        DBSession.add(member1)
        DBSession.add(member2)

    return DBSession
    def create_general_assembly(cls, number, name, date):
        """
        Create a general assembly

        Args:
            number: Integer. The number of the general assembly as a unique
                identifier.
            name: String. The name of the general assembly.
            date: `datetime.date`. The date at which the general assembly takes
                place.
        """
        assembly = GeneralAssembly(number, name, date)
        # pylint: disable=no-member
        DBSession.add(assembly)
        DBSession.flush()
Пример #9
0
 def make_unconnected_shares(self):
     with transaction.manager:
         shares2 = Shares(
             number=23,
             date_of_acquisition=date.today(),
             reference_code=u'IJKLMNO',
             signature_received=True,
             signature_received_date=date(2014, 1, 7),
             payment_received=True,
             payment_received_date=date(2014, 1, 8),
             signature_confirmed=True,
             signature_confirmed_date=date(2014, 1, 8),
             payment_confirmed=True,
             payment_confirmed_date=date(2014, 1, 9),
             accountant_comment=u'not connected',
         )
     DBSession.add(shares2)
Пример #10
0
 def make_unconnected_shares(self):
     with transaction.manager:
         shares2 = Shares(
             number=23,
             date_of_acquisition=date.today(),
             reference_code=u'IJKLMNO',
             signature_received=True,
             signature_received_date=date(2014, 1, 7),
             payment_received=True,
             payment_received_date=date(2014, 1, 8),
             signature_confirmed=True,
             signature_confirmed_date=date(2014, 1, 8),
             payment_confirmed=True,
             payment_confirmed_date=date(2014, 1, 9),
             accountant_comment=u'not connected',
         )
     DBSession.add(shares2)
    def invite_member(cls, membership_number, general_assembly_number, token):
        """
        Store the member invitation for the general assembly

        Args:
            membership_number: Integer. The membership number of the member for
                which the general assembly invitation is stored.
            general_assembly_number: Integer. The number of the general
                assembly for which the invitation is stored for the member.
            token: String. The token set to verify the member for API access by
                the ticketing application.
        """
        # pylint: disable=no-member
        member = MemberRepository.get_member(membership_number)
        assembly = cls.get_general_assembly(general_assembly_number)
        invitation = GeneralAssemblyInvitation(
            assembly, member, cls.datetime.now(), token)
        DBSession.add(invitation)
        DBSession.flush()
Пример #12
0
    def setUp(self):
        """
        set up everything for a test case
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print("removing old DBSession ==============================")
        except:
            # print("no DBSession to remove ==============================")
            pass
        from sqlalchemy import create_engine
        # engine = create_engine('sqlite:///test_utils.db')
        engine = create_engine('sqlite:///:memory:')
        DBSession.configure(bind=engine)
        self.session = DBSession  # ()

        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            DBSession.add(member1)
            DBSession.flush()
Пример #13
0
    def setUp(self):
        """
        set up everything for a test case
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print("removing old DBSession ==============================")
        except:
            # print("no DBSession to remove ==============================")
            pass
        from sqlalchemy import create_engine
        # engine = create_engine('sqlite:///test_utils.db')
        engine = create_engine('sqlite:///:memory:')
        DBSession.configure(bind=engine)
        self.session = DBSession  # ()

        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            DBSession.add(member1)
            DBSession.flush()
Пример #14
0
    def setUp(self):
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'api_auth_token': u"SECRETAUTHTOKEN",
        }
        self.config = testing.setUp()
        app = main({}, **my_settings)
        # set up the database
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
        member1.membership_number = 'M1'
        # pylint: disable=no-member
        DBSession.add(member1)
        GeneralAssemblyRepository.invite_member(
            member1.membership_number, GENERAL_ASSEMBLY, u'MEMBERS_TOKEN')
        # pylint: disable=no-member
        DBSession.flush()

        self.testapp = TestApp(app)
    def setUp(self):
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'api_auth_token': u"SECRETAUTHTOKEN",
            'c3smembership.url': u'localhost',
            'testing.mail_to_console': u'false',
        }
        self.config = testing.setUp()
        app = main({}, **my_settings)
        self.get_mailer = GetMailerDummy()
        app.registry.get_mailer = self.get_mailer
        app.registry.membership_application.datetime = DateTimeDummy(
            datetime.datetime(2018, 4, 26, 12, 23, 34))

        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        with transaction.manager:
            # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            DBSession.add(accountants_group)
            DBSession.flush()
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            DBSession.add(accountants_group)
            DBSession.add(staffer1)
            DBSession.flush()

        self.testapp = TestApp(app)
Пример #16
0
 def make_member_with_shares2(self):
     with transaction.manager:
         member1 = C3sMember(  # german
             firstname=u'SomeFirstnäme',
             lastname=u'SomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGFOO',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         shares1 = Shares(
             number=2,
             date_of_acquisition=date.today(),
             reference_code=u'ABCDEFGH',
             signature_received=True,
             signature_received_date=date(2014, 6, 7),
             payment_received=True,
             payment_received_date=date(2014, 6, 8),
             signature_confirmed=True,
             signature_confirmed_date=date(2014, 6, 8),
             payment_confirmed=True,
             payment_confirmed_date=date(2014, 6, 9),
             accountant_comment=u'no comment',
         )
         member1.shares = [shares1]
     DBSession.add(member1)
     DBSession.add(shares1)
Пример #17
0
    def setUp(self):
        """
        Set up database and engine
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        DBSession().close()
        DBSession.remove()
        from sqlalchemy import create_engine
        engine = create_engine('sqlite:///:memory:')
        DBSession.configure(bind=engine)
        self.session = DBSession

        Base.metadata.create_all(engine)
        with transaction.manager:
            # German member
            member1 = C3sMember(
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u'addr one',
                address2=u'addr two',
                postcode=u'12345',
                city=u'Footown Mäh',
                country=u'Foocountry',
                locale=u'DE',
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u'GEMA',
                num_shares=u'23',
            )
            db_session = DBSession()
            db_session.add(member1)
            db_session.flush()
Пример #18
0
 def make_member_with_shares2(self):
     with transaction.manager:
         member1 = C3sMember(  # german
             firstname=u'SomeFirstnäme',
             lastname=u'SomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGFOO',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         shares1 = Shares(
             number=2,
             date_of_acquisition=date.today(),
             reference_code=u'ABCDEFGH',
             signature_received=True,
             signature_received_date=date(2014, 6, 7),
             payment_received=True,
             payment_received_date=date(2014, 6, 8),
             signature_confirmed=True,
             signature_confirmed_date=date(2014, 6, 8),
             payment_confirmed=True,
             payment_confirmed_date=date(2014, 6, 9),
             accountant_comment=u'no comment',
         )
         member1.shares = [shares1]
     DBSession.add(member1)
     DBSession.add(shares1)
Пример #19
0
    def setUp(self):
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'api_auth_token': u"SECRETAUTHTOKEN",
        }
        self.config = testing.setUp()
        app = main({}, **my_settings)
        # set up the database
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
        # pylint: disable=no-member
        DBSession.add(member1)
        member1.email_invite_token_bcgv18 = u'MEMBERS_TOKEN'
        # pylint: disable=no-member
        DBSession.flush()

        self.testapp = TestApp(app)
Пример #20
0
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print "closed and removed DBSession"
        except:
            pass
            # print "no session to close"
        # try:
        #    os.remove('test_webtest_accountants.db')
        #    #print "deleted old test database"
        # except:
        #    pass
        #    #print "never mind"
        # self.session = DBSession()
        my_settings = {
            # 'sqlalchemy.url': 'sqlite:///test_webtest_accountants.db',
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        self._insert_members()

        with transaction.manager:
            # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            try:
                DBSession.add(accountants_group)
                DBSession.flush()
                # print("adding group staff")
            except:
                print("could not add group staff.")
                # pass
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            try:
                DBSession.add(accountants_group)
                DBSession.add(staffer1)
                DBSession.flush()
            except:
                print("it borked! (rut)")
                # pass

        from c3smembership import main
        app = main({}, **my_settings)
        from webtest import TestApp
        self.testapp = TestApp(app)
Пример #21
0
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print "closed and removed DBSession"
        except:
            pass
            # print "no session to close"
        # try:
        #    os.remove('test_webtest_accountants.db')
        #    #print "deleted old test database"
        # except:
        #    pass
        #    #print "never mind"
        # self.session = DBSession()
        my_settings = {
            # 'sqlalchemy.url': 'sqlite:///test_webtest_accountants.db',
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'}
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        self._insert_members()

        with transaction.manager:
                # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            try:
                DBSession.add(accountants_group)
                DBSession.flush()
                # print("adding group staff")
            except:
                print("could not add group staff.")
                # pass
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            try:
                DBSession.add(accountants_group)
                DBSession.add(staffer1)
                DBSession.flush()
            except:
                print("it borked! (rut)")
                # pass

        from c3smembership import main
        app = main({}, **my_settings)
        from webtest import TestApp
        self.testapp = TestApp(app)
    def setUp(self):
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'api_auth_token': u"SECRETAUTHTOKEN",
            'c3smembership.url': u'localhost',
            'c3smembership.notification_sender': u'*****@*****.**',
            'c3smembership.status_receiver': u'*****@*****.**',
            'testing.mail_to_console': u'false',
        }
        self.config = testing.setUp()
        app = main({}, **my_settings)
        self.get_mailer = GetMailerDummy()
        app.registry.get_mailer = self.get_mailer
        app.registry.membership_application.datetime = DateTimeDummy(
            datetime.datetime(2018, 4, 26, 12, 23, 34))

        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        with transaction.manager:
            # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            DBSession.add(accountants_group)
            DBSession.flush()
            # staff personnel
            staffer1 = Staff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            DBSession.add(accountants_group)
            DBSession.add(staffer1)
            DBSession.flush()

        self.testapp = TestApp(app)
Пример #23
0
    def setUp(self):
        """
        Setup test cases
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        DBSession.close()
        DBSession.remove()
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        # self._insert_members()

        with transaction.manager:
            # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            DBSession.add(accountants_group)
            DBSession.flush()
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            DBSession.add(accountants_group)
            DBSession.add(staffer1)
            DBSession.flush()

        app = main({}, **my_settings)
        self.testapp = TestApp(app)
    def setUp(self):
        """
        Setup test cases
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        DBSession.close()
        DBSession.remove()
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'}
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        # self._insert_members()

        with transaction.manager:
                # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            DBSession.add(accountants_group)
            DBSession.flush()
            # staff personnel
            staffer1 = Staff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            DBSession.add(accountants_group)
            DBSession.add(staffer1)
            DBSession.flush()

        app = main({}, **my_settings)
        self.testapp = TestApp(app)
Пример #25
0
def init_testing_db():
    """
    Initializes the memory database with test samples.
    """

    my_settings = {
        'sqlalchemy.url': 'sqlite:///:memory:',
    }
    engine = engine_from_config(my_settings)
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)

    with transaction.manager:
        # There is a side effect of test_initialization.py after which there are
        # still records in the database although it is setup from scratch.
        # Therefore, remove all members to have an empty table.
        members = C3sMember.get_all()
        for member in members:
            DBSession.delete(member)
        DBSession.flush()

        member1 = C3sMember(  # german person
            firstname=u'SomeFirstnäme',
            lastname=u'SomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG1',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'23',
        )
        member2 = C3sMember(  # english person
            firstname=u'AAASomeFirstnäme',
            lastname=u'XXXSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG2',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'23',
        )
        member3 = C3sMember(  # german legalentity
            firstname=u'Cooles PlattenLabel',
            lastname=u'SomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG3',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'42',
        )
        member4 = C3sMember(  # english legalentity
            firstname=u'Incredible Records',
            lastname=u'XXXSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG4',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'2',
        )
        member1.membership_accepted = True
        DBSession.add(member1)
        member2.membership_accepted = True
        DBSession.add(member2)
        member3.membership_accepted = True
        DBSession.add(member3)
        member4.membership_accepted = True
        DBSession.add(member4)
        DBSession.flush()
    return DBSession
Пример #26
0
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        try:
            DBSession.close()
            DBSession.remove()
            # print "closed and removed DBSession"
        except:
            pass
            # print "no session to close"
        # try:
        #    os.remove('test_import.db')
        #    #print "deleted old test database"
        # except:
        #    pass
        #    #print "never mind"
        # self.session = DBSession()
        my_settings = {
            # 'sqlalchemy.url': 'sqlite:///test_import.db',
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30',
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            DBSession.add(member1)
            DBSession.flush()
            self.m1_last_pw_change = member1.last_password_change
        with transaction.manager:
                # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            try:
                DBSession.add(accountants_group)
                DBSession.flush()
                # print("adding group staff")
            except:
                # print("could not add group staff.")
                pass
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            try:
                DBSession.add(accountants_group)
                DBSession.add(staffer1)
                DBSession.flush()
            except:
                # print("it borked! (rut)")
                pass

        from c3smembership import main
        app = main({}, **my_settings)
        app.registry.settings['c3smembership.runmode'] = 'dev'
        from webtest import TestApp
        self.testapp = TestApp(app)
Пример #27
0
def send_dues18_invoice_email(request, m_id=None):
    """
    Send email to a member to prompt her to pay the membership dues.
    - For normal members, also send link to invoice.
    - For investing members that are legal entities,
      ask for additional support depending on yearly turnover.

    This view function works both if called via URL, e.g. /dues_invoice/123
    and if called as a function with a member id as parameter.
    The latter is useful for batch processing.

    When this function is used for the first time for one member,
    some database fields are filled:
    - Invoice number
    - Invoice amount (calculated from date of membership approval by the board)
    - Invoice token
    Also, the database table of invoices (and cancellations) is appended.

    If this function gets called the second time for a member,
    no new invoice is produced, but the same mail sent again.
    """
    # either we are given a member id via url or function parameter
    try:  # view was called via http/s
        member_id = request.matchdict['member_id']
        batch = False
    except KeyError:  # ...or was called as function with parameter (see batch)
        member_id = m_id
        batch = True

    try:  # get member from DB
        member = C3sMember.get_by_id(member_id)
        assert(member is not None)
    except AssertionError:
        if not batch:
            request.session.flash(
                "member with id {} not found in DB!".format(member_id),
                'warning')
            return HTTPFound(request.route_url('dues'))

    # sanity check:is this a member?
    try:
        assert(member.membership_accepted)  # must be accepted member!
    except AssertionError:
        request.session.flash(
            "member {} not accepted by the board!".format(member_id),
            'warning')
        return HTTPFound(request.route_url('dues'))

    if 'normal' not in member.membership_type and \
            'investing' not in member.membership_type:
        request.session.flash(
            'The membership type of member {0} is not specified! The '
            'membership type must either be "normal" or "investing" in order '
            'to be able to send an invoice email.'.format(member.id),
            'warning')
        return get_memberhip_listing_redirect(request)
    if member.membership_date >= date(2019, 1, 1) or (
                member.membership_loss_date is not None
                and member.membership_loss_date < date(2018, 1, 1)
            ):
        request.session.flash(
            'Member {0} was not a member in 2018. Therefore, you cannot send '
            'an invoice for 2018.'.format(member.id),
            'warning')
        return get_memberhip_listing_redirect(request)

    # check if invoice no already exists.
    #     if yes: just send that email again!
    #     also: offer staffers to cancel this invoice

    if member.dues18_invoice is True:
        invoice = DuesInvoiceRepository.get_by_number(
            member.dues18_invoice_no, 2018)
        member.dues18_invoice_date = datetime.now()

    else:  # if no invoice already exists:
        # make dues token and ...
        randomstring = make_random_string()
        # check if dues token is already used
        while DuesInvoiceRepository.token_exists(randomstring, 2018):
            # create a new one, if the new one already exists in the database
            randomstring = make_random_string()  # pragma: no cover

        # prepare invoice number
        try:
            # either we already have an invoice number for that client...
            invoice_no = member.dues18_invoice_no
            assert invoice_no is not None
        except AssertionError:
            # ... or we create a new one and save it
            # get max invoice no from db
            max_invoice_no = DuesInvoiceRepository.get_max_invoice_number(2018)
            # use the next free number, save it to db
            new_invoice_no = int(max_invoice_no) + 1
            DBSession.flush()  # save dataset to DB

        # calculate dues amount (maybe partial, depending on quarter)
        dues_start, dues_amount = calculate_partial_dues18(member)

        # now we have enough info to update the member info
        # and persist invoice info for bookkeeping
        # store some info in DB/member table
        member.dues18_invoice = True
        member.dues18_invoice_no = new_invoice_no  # irrelevant for investing
        member.dues18_invoice_date = datetime.now()
        member.dues18_token = randomstring
        member.dues18_start = dues_start

        if 'normal' in member.membership_type:  # only for normal members
            member.set_dues18_amount(dues_amount)
            # store some more info about invoice in invoice table
            invoice = Dues18Invoice(
                invoice_no=member.dues18_invoice_no,
                invoice_no_string=(
                    u'C3S-dues2018-' + str(member.dues18_invoice_no).zfill(4)),
                invoice_date=member.dues18_invoice_date,
                invoice_amount=u'' + str(member.dues18_amount),
                member_id=member.id,
                membership_no=member.membership_number,
                email=member.email,
                token=member.dues18_token,
            )
            DBSession.add(invoice)
        DBSession.flush()

    # now: prepare that email
    # only normal (not investing) members *have to* pay the dues.
    # only the normal members get an invoice link and PDF produced for them.
    # only investing legalentities are asked for more support.
    if 'investing' not in member.membership_type:
        start_quarter = string_start_quarter_dues18(member)
        invoice_url = (
            request.route_url(
                'make_dues18_invoice_no_pdf',
                email=member.email,
                code=member.dues18_token,
                i=str(member.dues18_invoice_no).zfill(4)
            )
        )
        email_subject, email_body = make_dues18_invoice_email(
            member,
            invoice,
            invoice_url,
            start_quarter)
        message = Message(
            subject=email_subject,
            sender=request.registry.settings[
                'c3smembership.notification_sender'],
            recipients=[member.email],
            body=email_body,
        )
    elif 'investing' in member.membership_type:
        if member.is_legalentity:
            email_subject, email_body = \
                make_dues_invoice_legalentity_email(member)
        else:
            email_subject, email_body = \
                make_dues_invoice_investing_email(member)
        message = Message(
            subject=email_subject,
            sender=request.registry.settings[
                'c3smembership.notification_sender'],
            recipients=[member.email],
            body=email_body,
        )

    # print to console or send mail
    if 'true' in request.registry.settings['testing.mail_to_console']:
        print(message.body.encode('utf-8'))  # pragma: no cover
    else:
        send_message(request, message)

    # now choose where to redirect
    if 'detail' in request.referrer:
        return HTTPFound(
            request.route_url(
                'detail',
                member_id=member.id) +
            '#dues18')
    if 'dues' in request.referrer:
        return HTTPFound(request.route_url('dues'))
    else:
        return get_memberhip_listing_redirect(request, member.id)
Пример #28
0
def _initTestingDB():
    my_settings = {'sqlalchemy.url': 'sqlite:///:memory:', }
    engine = engine_from_config(my_settings)
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    with transaction.manager:
        member1 = C3sMember(  # german
            firstname=u'SomeFirstnäme',
            lastname=u'SomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFGFOO',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        member2 = C3sMember(  # english
            firstname=u'AAASomeFirstnäme',
            lastname=u'XXXSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFGBAR',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'2',
        )
        founding_member3 = C3sMember(  # english
            firstname=u'BBBSomeFirstnäme',
            lastname=u'YYYSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCBARdungHH_',
            password=u'anotherrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'2',
        )
        DBSession.add(member1)
        DBSession.add(member2)
        DBSession.add(founding_member3)

    return DBSession
Пример #29
0
    def setUp(self):
        """
        Set up the test data.

        The test set is:

        date       amount firstname lastname reference membership_number
        ========== ====== ========= ======== ========= =================
        2015-01-01 15.11  Jane      Smith    JANE      1
        2015-01-03 15.13  Cassandra Jones    CASSANDRA 3
        2016-02-01 16.21  Jane      Smith    SMI       1
        2016-02-02 16.22  John      Smith    JOHN      2
        2016-02-03 16.23  Cassandra Jones    JONES     3
        2017-03-01 17.31  Jane      Smith    TH        1
        2017-03-02 17.32  John      Smith    SMITH     2
        2018-10-12 12.12  Cassandra Jones    CJ18      3
        2019-04-05 19.19  Jane      Smith    JS19      1
        """
        my_settings = {'sqlalchemy.url': 'sqlite:///:memory:', }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        with transaction.manager:
            # pylint: disable=no-member
            DBSession.add(self._create_member(
                membership_number=1,
                firstname=u'Jane',
                lastname=u'Smith',
                dues15_paid=True,
                dues15_payment_date=date(2015, 1, 1),
                dues15_payment_token=u'JANE',
                dues15_payment_amount=Decimal('15.11'),
                dues16_paid=True,
                dues16_payment_date=date(2016, 2, 1),
                dues16_payment_token=u'SMI',
                dues16_payment_amount=Decimal('16.21'),
                dues17_paid=True,
                dues17_payment_date=date(2017, 3, 1),
                dues17_payment_token=u'TH',
                dues17_payment_amount=Decimal('17.31'),
                dues19_paid=True,
                dues19_payment_date=date(2019, 4, 5),
                dues19_payment_token=u'JS19',
                dues19_payment_amount=Decimal('19.19'),
            ))
            DBSession.add(self._create_member(
                membership_number=2,
                firstname=u'John',
                lastname=u'Smith',
                dues15_paid=False,
                dues15_payment_date=None,
                dues15_payment_token=None,
                dues15_payment_amount=None,
                dues16_paid=True,
                dues16_payment_date=date(2016, 2, 2),
                dues16_payment_token=u'JOHN',
                dues16_payment_amount=Decimal('16.22'),
                dues17_paid=True,
                dues17_payment_date=date(2017, 3, 2),
                dues17_payment_token=u'SMITH',
                dues17_payment_amount=Decimal('17.32'),
            ))
            DBSession.add(self._create_member(
                membership_number=3,
                firstname=u'Cassandra',
                lastname=u'Jones',
                dues15_paid=True,
                dues15_payment_date=date(2015, 1, 3),
                dues15_payment_token=u'CASSANDRA',
                dues15_payment_amount=Decimal('15.13'),
                dues16_paid=True,
                dues16_payment_date=date(2016, 2, 3),
                dues16_payment_token=u'JONES',
                dues16_payment_amount=Decimal('16.23'),
                dues17_paid=False,
                dues17_payment_date=None,
                dues17_payment_token=None,
                dues17_payment_amount=None,
                dues18_paid=True,
                dues18_payment_date=date(2018, 10, 12),
                dues18_payment_token=u'CJ18',
                dues18_payment_amount=Decimal('12.12'),
            ))
    def setUp(self):
        """
        Setup test cases
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        DBSession.close()
        DBSession.remove()
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)

        # self._insert_members()

        with transaction.manager:
            # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            DBSession.add(accountants_group)
            DBSession.flush()
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            DBSession.add(accountants_group)
            DBSession.add(staffer1)
            DBSession.flush()

        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            shares1_m1 = Shares(
                number=2,
                date_of_acquisition=date.today(),
                reference_code=u'ABCDEFGH',
                signature_received=True,
                signature_received_date=date(2014, 6, 7),
                payment_received=True,
                payment_received_date=date(2014, 6, 8),
                signature_confirmed=True,
                signature_confirmed_date=date(2014, 6, 8),
                payment_confirmed=True,
                payment_confirmed_date=date(2014, 6, 9),
                accountant_comment=u'no comment',
            )
            member1.shares = [shares1_m1]
            shares2_m1 = Shares(
                number=23,
                date_of_acquisition=date.today(),
                reference_code=u'IJKLMNO',
                signature_received=True,
                signature_received_date=date(2014, 1, 7),
                payment_received=True,
                payment_received_date=date(2014, 1, 8),
                signature_confirmed=True,
                signature_confirmed_date=date(2014, 1, 8),
                payment_confirmed=True,
                payment_confirmed_date=date(2014, 1, 9),
                accountant_comment=u'not connected',
            )
            member1.shares.append(shares2_m1)
            member1.membership_accepted = True

            member2 = C3sMember(  # english
                firstname=u'AAASomeFirstnäme',
                lastname=u'XXXSomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"en",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'2',
            )
            founding_member3 = C3sMember(  # english
                firstname=u'BBBSomeFirstnäme',
                lastname=u'YYYSomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"en",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCBARdungHH_',
                password=u'anotherrandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'2',
            )
            member4_lost = C3sMember(
                firstname=u'Resigned',
                lastname=u'Smith',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"en",
                date_of_birth=date(1980, 1, 2),
                email_is_confirmed=False,
                email_confirm_code=u'RESIGNEDSMITH',
                password=u'arandompassword',
                date_of_submission=date.today() - timedelta(days=370),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'2',
            )

            DBSession.add(shares1_m1)
            DBSession.add(shares2_m1)
            DBSession.add(member1)
            DBSession.add(member2)
            DBSession.add(founding_member3)
            DBSession.add(member4_lost)

        app = main({}, **my_settings)
        self.testapp = TestApp(app)
Пример #31
0
def make_member_view(request):
    """
    Turns a membership applicant into an accepted member.

    When both the signature and the payment for the shares have arrived at
    headquarters, an application for membership can be turned into an
    **accepted membership**, if the board of directors decides so.

    This view lets staff enter a date of approval through a form.

    It also provides staff with listings of

    * members with same first name
    * members with same last name
    * members with same email address
    * members with same date of birth

    so staff can decide if this may become a proper membership
    or whether this application is a duplicate of some accepted membership
    and should be merged with some other entry.

    In case of duplicate/merge, also check if the number of shares
    when combining both entries would exceed 60,
    the maximum number of shares a member can hold.
    """
    _id = request.matchdict['afm_id']
    try:  # does that id make sense? member exists?
        member = C3sMember.get_by_id(_id)
        assert(isinstance(member, C3sMember))  # is an application
        # assert(isinstance(member.membership_number, NoneType)
        # not has number
    except AssertionError:
        return HTTPFound(
            location=request.route_url('dashboard'))
    if member.membership_accepted:
        # request.session.flash('id {} is already accepted member!')
        return HTTPFound(request.route_url('detail', memberid=member.id))

    if not (member.signature_received and member.payment_received):
        request.session.flash('signature or payment missing!', 'messages')
        return HTTPFound(request.route_url('dashboard'))

    if 'make_member' in request.POST:
        # print "yes! contents: {}".format(request.POST['make_member'])
        try:
            member.membership_date = datetime.strptime(
                request.POST['membership_date'], '%Y-%m-%d').date()
        except ValueError, value_error:
            request.session.flash(value_error.message, 'merge_message')
            return HTTPFound(
                request.route_url('make_member', afm_id=member.id))

        member.membership_accepted = True
        if member.is_legalentity:
            member.membership_type = u'investing'
        else:
            member.is_legalentity = False
        member.membership_number = C3sMember.get_next_free_membership_number()
        shares = Shares(
            number=member.num_shares,
            date_of_acquisition=member.membership_date,
            reference_code=member.email_confirm_code,
            signature_received=member.signature_received,
            signature_received_date=member.signature_received_date,
            payment_received=member.payment_received,
            payment_received_date=member.payment_received_date
        )
        DBSession.add(shares)
        member.shares = [shares]
        # return the user to the page she came from
        if 'referrer' in request.POST:
            if request.POST['referrer'] == 'dashboard':
                return HTTPFound(request.route_url('dashboard'))
            if request.POST['referrer'] == 'detail':
                return HTTPFound(
                    request.route_url('detail', memberid=member.id))
        return HTTPFound(request.route_url('detail', memberid=member.id))
Пример #32
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}
    def setUp(self):
        """
        Set up tests
        """
        datetime_mock = mock.Mock()
        GeneralAssemblyRepository.datetime = datetime_mock

        # pylint: disable=no-member
        my_settings = {'sqlalchemy.url': 'sqlite:///:memory:', }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2014,
                u'1. ordentliche Generalversammlung',
                date(2014, 8, 23)))
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2015,
                u'2. ordentliche Generalversammlung',
                date(2015, 6, 13)))
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2015_2,
                u'Außerordentliche Generalversammlung',
                date(2015, 7, 16)))
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2016,
                u'3. ordentliche Generalversammlung',
                date(2016, 4, 17)))
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2017,
                u'4. ordentliche Generalversammlung',
                date(2017, 4, 2)))
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2018,
                u'5. ordentliche Generalversammlung',
                date(2018, 6, 3)))
            DBSession.add(GeneralAssembly(
                GENERAL_ASSEMBLY_NUMBER_2018_2,
                u'Außerordentliche Generalversammlung',
                date(2018, 12, 1)))

            member1 = C3sMember(
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=35,
            )
            member2 = C3sMember(
                firstname=u'AAASomeFirstnäme',
                lastname=u'XXXSomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=45,
            )
            member3 = C3sMember(
                firstname=u'Not invited',
                lastname=u'at all',
                email=u'*****@*****.**',
                address1=u'Some',
                address2=u'Address',
                postcode=u'45678',
                city=u'Hamburg',
                country=u'Germany',
                locale=u'DE',
                date_of_birth=date(1980, 1, 2),
                email_is_confirmed=False,
                email_confirm_code=u'member3',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=45,
            )
            member1.membership_number = u'member_1'
            member1.membership_date = date(2018, 1, 1)
            member1.membership_accepted = True
            DBSession.add(member1)

            datetime_mock.now.side_effect = [datetime(2018, 9, 1, 23, 5, 15)]
            GeneralAssemblyRepository.invite_member(
                'member_1', GENERAL_ASSEMBLY_NUMBER_2018_2, u'test_token_1')

            member2.membership_number = u'member_2'
            member2.membership_date = date(2017, 1, 1)
            member2.membership_accepted = True
            DBSession.add(member2)

            datetime_mock.now.side_effect = [datetime(2018, 9, 2, 22, 3, 10)]
            GeneralAssemblyRepository.invite_member(
                'member_2', GENERAL_ASSEMBLY_NUMBER_2018_2, u'test_token_2')

            member3.membership_number = u'member_3'
            member3.membership_date = date(2016, 1, 1)
            member3.membership_accepted = True
            DBSession.add(member3)

            DBSession.flush()
def send_dues17_invoice_email(request, m_id=None):
    """
    Send email to a member to prompt her to pay the membership dues.
    - For normal members, also send link to invoice.
    - For investing members that are legal entities,
      ask for additional support depending on yearly turnover.

    This view function works both if called via URL, e.g. /dues_invoice/123
    and if called as a function with a member id as parameter.
    The latter is useful for batch processing.

    When this function is used for the first time for one member,
    some database fields are filled:
    - Invoice number
    - Invoice amount (calculated from date of membership approval by the board)
    - Invoice token
    Also, the database table of invoices (and cancellations) is appended.

    If this function gets called the second time for a member,
    no new invoice is produced, but the same mail sent again.
    """
    # either we are given a member id via url or function parameter
    try:  # view was called via http/s
        member_id = request.matchdict['member_id']
        batch = False
    except KeyError:  # ...or was called as function with parameter (see batch)
        member_id = m_id
        batch = True

    try:  # get member from DB
        member = C3sMember.get_by_id(member_id)
        assert (member is not None)
    except AssertionError:
        if not batch:
            request.session.flash(
                "member with id {} not found in DB!".format(member_id),
                'message_to_staff')
            return HTTPFound(request.route_url('toolbox'))

    # sanity check:is this a member?
    try:
        assert (member.membership_accepted)  # must be accepted member!
    except AssertionError:
        request.session.flash(
            "member {} not accepted by the board!".format(member_id),
            'message_to_staff')
        return HTTPFound(request.route_url('toolbox'))

    if 'normal' not in member.membership_type and \
            'investing' not in member.membership_type:
        request.session.flash(
            'The membership type of member {0} is not specified! The '
            'membership type must either be "normal" or "investing" in order '
            'to be able to send an invoice email.'.format(member.id),
            'message_to_staff')
        return get_memberhip_listing_redirect(request)
    if member.membership_date >= date(2018,1,1) or ( \
                member.membership_loss_date is not None
                and
                member.membership_loss_date < date(2017,1,1)
            ):
        request.session.flash(
            'Member {0} was not a member in 2017. Therefore, you cannot send '
            'an invoice for 2017.'.format(member.id), 'message_to_staff')
        return get_memberhip_listing_redirect(request)

    # check if invoice no already exists.
    #     if yes: just send that email again!
    #     also: offer staffers to cancel this invoice

    if member.dues17_invoice is True:
        invoice = Dues17Invoice.get_by_invoice_no(member.dues17_invoice_no)
        member.dues17_invoice_date = datetime.now()

    else:  # if no invoice already exists:
        # make dues token and ...
        randomstring = make_random_string()
        # check if dues token is already used
        while (Dues17Invoice.check_for_existing_dues17_token(randomstring)):
            # create a new one, if the new one already exists in the database
            randomstring = make_random_string()  # pragma: no cover

        # prepare invoice number
        try:
            # either we already have an invoice number for that client...
            invoice_no = member.dues17_invoice_no
            assert invoice_no is not None
        except AssertionError:
            # ... or we create a new one and save it
            # get max invoice no from db
            max_invoice_no = Dues17Invoice.get_max_invoice_no()
            # use the next free number, save it to db
            new_invoice_no = int(max_invoice_no) + 1
            DBSession.flush()  # save dataset to DB

        # calculate dues amount (maybe partial, depending on quarter)
        dues_start, dues_amount = calculate_partial_dues17(member)

        # now we have enough info to update the member info
        # and persist invoice info for bookkeeping
        # store some info in DB/member table
        member.dues17_invoice = True
        member.dues17_invoice_no = new_invoice_no  # irrelevant for investing
        member.dues17_invoice_date = datetime.now()
        member.dues17_token = randomstring
        member.dues17_start = dues_start

        if 'normal' in member.membership_type:  # only for normal members
            member.set_dues17_amount(dues_amount)
            # store some more info about invoice in invoice table
            invoice = Dues17Invoice(
                invoice_no=member.dues17_invoice_no,
                invoice_no_string=(u'C3S-dues2017-' +
                                   str(member.dues17_invoice_no).zfill(4)),
                invoice_date=member.dues17_invoice_date,
                invoice_amount=u'' + str(member.dues17_amount),
                member_id=member.id,
                membership_no=member.membership_number,
                email=member.email,
                token=member.dues17_token,
            )
            DBSession.add(invoice)
        DBSession.flush()

    # now: prepare that email
    # only normal (not investing) members *have to* pay the dues.
    # only the normal members get an invoice link and PDF produced for them.
    # only investing legalentities are asked for more support.
    if 'investing' not in member.membership_type:
        start_quarter = string_start_quarter_dues17(member)
        invoice_url = (request.route_url(
            'make_dues17_invoice_no_pdf',
            email=member.email,
            code=member.dues17_token,
            i=str(member.dues17_invoice_no).zfill(4)))
        email_subject, email_body = make_dues17_invoice_email(
            member, invoice, invoice_url, start_quarter)
        message = Message(subject=email_subject,
                          sender='*****@*****.**',
                          recipients=[member.email],
                          body=email_body,
                          extra_headers={
                              'Reply-To': '*****@*****.**',
                          })
    elif 'investing' in member.membership_type:
        if member.is_legalentity:
            email_subject, email_body = \
                make_dues_invoice_legalentity_email(member)
        else:
            email_subject, email_body = \
                make_dues_invoice_investing_email(member)
        message = Message(subject=email_subject,
                          sender='*****@*****.**',
                          recipients=[member.email],
                          body=email_body,
                          extra_headers={
                              'Reply-To': '*****@*****.**',
                          })

    # print to console or send mail
    if 'true' in request.registry.settings['testing.mail_to_console']:
        print(message.body.encode('utf-8'))  # pragma: no cover
    else:
        send_message(request, message)

    # now choose where to redirect
    if 'detail' in request.referrer:
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')
    if 'toolbox' in request.referrer:
        return HTTPFound(request.route_url('toolbox'))
    else:
        return get_memberhip_listing_redirect(request, member.id)
Пример #35
0
    def setUp(self):
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=35,
            )
            member2 = C3sMember(  # german
                firstname=u'AAASomeFirstnäme',
                lastname=u'XXXSomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=45,
            )
            member3 = C3sMember(
                firstname=u'Not Approved',
                lastname=u'Member',
                email=u'*****@*****.**',
                address1=u'Some Street 123',
                address2=u'',
                postcode=u"12345",
                city=u"Some City",
                country=u"Some Country",
                locale=u"DE",
                date_of_birth=date(1980, 1, 2),
                email_is_confirmed=False,
                email_confirm_code=u'NOT_APPROVED_MEMBER',
                password=u'not_approved_member',
                date_of_submission=date(1970, 1, 1),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u'',
                num_shares=7,
            )
            # pylint: disable=no-member
            DBSession.add(member1)
            # pylint: disable=no-member
            DBSession.add(member2)
            # pylint: disable=no-member
            DBSession.add(member3)

            member1.membership_number = u'member1'
            member1.membership_date = date(2013, 1, 1)
            member1.membership_accepted = True
            member2.membership_number = u'member2'
            member2.membership_date = date(2013, 1, 1)
            member2.membership_accepted = True
            member3.payment_received_date = date(2016, 10, 11)

            share = Shares()
            share.reference_code = u'share1'
            share.date_of_acquisition = date(2013, 1, 2)
            share.payment_received_date = date(2012, 11, 10)
            share.number = 12
            member1.shares.append(share)

            share = Shares()
            share.reference_code = u'share2'
            share.date_of_acquisition = date(2014, 2, 3)
            share.payment_received_date = date(2012, 12, 31)
            share.number = 23
            member1.shares.append(share)

            share = Shares()
            share.reference_code = u'share3'
            share.date_of_acquisition = date(2014, 3, 4)
            share.payment_received_date = date(2014, 3, 3)
            share.number = 34
            member2.shares.append(share)

            share = Shares()
            share.reference_code = u'share4'
            share.date_of_acquisition = date(2015, 4, 5)
            share.payment_received_date = date(2014, 11, 15)
            share.number = 45
            member2.shares.append(share)
Пример #36
0
    def test_join_c3s(self):
        """
        Test the join form
        """
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        DBSession().close()
        DBSession.remove()
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'}
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            accountants_group = Group(name=u"staff")
            db_session = DBSession()
            db_session.add(accountants_group)
            db_session.flush()
            staffer1 = Staff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            db_session.add(accountants_group)
            db_session.add(staffer1)
            db_session.flush()
        app = main({}, **my_settings)
        testapp = TestApp(app)

        # sucess for valid entry
        res = testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        res = form.submit(u'submit', status=302)
        res = res.follow()
        self.assertTrue('information below to be correct' in res.body)

        # success for 18th birthday
        res = testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        join.date = DummyDate(date(2018, 4, 29))
        form['year'] = u'2000'
        form['month'] = u'04'
        form['day'] = u'29'
        res = form.submit(u'submit', status=302)
        res = res.follow()
        self.assertTrue('information below to be correct' in res.body)

        # failure on test one day before 18th birthday
        res = testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        join.date = DummyDate(date(2018, 4, 29))
        form['year'] = u'2000'
        form['month'] = u'04'
        form['day'] = u'30'

        res = form.submit(u'submit', status=200)

        self.assertTrue('underaged person is currently not' in res.body)

        # failure for statute not checked
        res = testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        form['got_dues_regulations'].value__set(False)
        res = form.submit(u'submit', status=200)

        # failure for dues regulations not checked
        res = testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        form['got_dues_regulations'].value__set(False)
        res = form.submit(u'submit', status=200)

        # teardown
        DBSession().close()
        DBSession.remove()
        testing.tearDown()
Пример #37
0
    def test_membership_loss(self):
        '''
        Test the loss of membership.

        Test cases for:

        1 Editing non members

          1.1 Loss inputs must be hidden
          1.1 Hidden loss inputs should not make any problem and therefore
              submit without changes should work
          1.2 Try setting hidden values -> error

        2 Editing members

          2.1 Loss inputs must not be hidden

          2.2 Loss date and loss type must both be either set or unset

            2.2.1 Set only loss date -> error, set both
            2.2.2 Set only loss type -> error, set both
            2.2.3 Set neither loss date nor type -> success
            2.2.4 Set loss date and type to valid values -> success

          2.3 Loss date must be larger than acceptance date

            2.3.1 Set loss date prior to membership acceptance date -> error,
                  set date larger membership acceptance
            2.3.2 Set loss date after membership acceptance date -> success

          2.4 Loss date for resignation must be 31st of December

            2.4.1 Set loss type to resignation and loss date other than 31st
                  of December -> fail
            2.4.2 Set loss type to resignation and loss date to 31st but not
                  December -> fail
            2.4.3 Set loss type to resignation and loss date to December but
                  not 31st -> fail
            2.4.4 Set loss type to resignation and loss date to 31st of
                  December succeed

          2.5 Only natural persons can be set to loss type death

            2.5.1 Set loss type to death and entity type to legal entity ->
                  error
            2.5.2 Set loss type to death and entity type to natural person ->
                  success

          2.6 Only legal entites can be set to loss type winding-up

            2.6.1 Set loss type to winding-up and entity type to natural
                  person error
            2.6.2 Set loss type to winding-up and entity type to legal entity
                  -> success
        '''
        # setup
        res = self.testapp.reset()
        self.__login()
        member = EditMemberTests.__create_membership_applicant()
        DBSession.add(member)
        DBSession.flush()

        # 1 Editing non members
        res = self.__get_edit_member(member.id)
        self.assertFalse(res.form['membership_accepted'].checked)

        # 1.1 Loss inputs must be hidden
        res = self.__get_edit_member(member.id)
        self.assertTrue(
            type(res.form['membership_loss_date']) == webtest.forms.Hidden)
        self.assertTrue(res.form['membership_loss_date'].value == '')
        self.assertTrue(
            type(res.form['membership_loss_type']) == webtest.forms.Hidden)
        self.assertTrue(res.form['membership_loss_type'].value == '')

        # 1.2 Hidden loss inputs should not make any problem and therefore
        #     submit without changes should work
        res = self.__get_edit_member(member.id)
        self.__validate_successful_submit(res)

        # 1.3 Try setting hidden values -> error
        self.__validate_abortive_edit(
            member.id, {
                'membership_loss_date': date.today(),
                'membership_loss_type': u'resignation',
            },
            [u'Please note: There were errors, please check the form below.'])

        # 2 Editing members
        member = EditMemberTests.__create_accepted_member_full()
        DBSession.add(member)
        DBSession.flush()
        res = self.__get_edit_member(member.id)
        # make sure default values are valid
        self.__validate_successful_submit(res)

        # 2.1 Loss inputs must not be hidden
        res = self.__get_edit_member(member.id)
        self.assertTrue(res.form['membership_accepted'].checked)
        self.assertTrue(
            type(res.form['membership_loss_date']) == webtest.forms.Text)
        self.assertTrue(res.form['membership_loss_date'].value == '')
        self.assertTrue(
            type(res.form['membership_loss_type']) == webtest.forms.Select)
        self.assertTrue(res.form['membership_loss_type'].value == '')

        # 2.2.1 Set only loss date -> error, set both
        self.__validate_abortive_edit(
            member.id, {
                'membership_loss_date': date(2016, 12, 31),
            }, [
                'Please note: There were errors, please check the form '
                'below.',
                'Date and type of membership loss must be set both or none.',
            ])

        # 2.2.2 Set only loss type -> error, set both
        self.__validate_abortive_edit(member.id, {
            'membership_loss_type': 'resignation',
        }, [
            'Please note: There were errors, please check the form '
            'below.',
            'Date and type of membership loss must be set both or none.',
        ])

        # 2.2.3 Set neither loss date nor type -> success
        self.__validate_successful_edit(member.id, {
            'membership_loss_type': '',
            'membership_loss_date': '',
        })

        # 2.2.4 Set loss date and type to valid values -> success
        self.__validate_successful_edit(
            member.id, {
                'membership_loss_type': 'resignation',
                'membership_loss_date': date(2016, 12, 31),
            })

        # 2.3 Loss date must be larger than acceptance date

        # 2.3.1 Set loss date prior to membership acceptance date -> error,
        #       set date larger membership acceptance
        self.__validate_abortive_edit(
            member.id, {
                'membership_loss_date':
                (member.membership_date - timedelta(days=1)),
                'membership_loss_type':
                'resignation',
            }, [
                'Please note: There were errors, please check the form '
                'below.',
                'Date membership loss must be larger than membership '
                'acceptance date.',
            ])

        # 2.3.2 Set loss date after membership acceptance date -> success
        self.__validate_successful_edit(
            member.id, {
                'membership_loss_date': date(2016, 12, 31),
                'membership_loss_type': 'resignation',
            })

        # 2.4 Loss date for resignation must be 31st of December

        # 2.4.1 Set loss type to resignation and loss date other than 31st
        #       of December -> fail
        self.__validate_abortive_edit(
            member.id, {
                'membership_loss_date': date(2016, 5, 28),
                'membership_loss_type': 'resignation',
            }, [
                'Please note: There were errors, please check the form '
                'below.',
                'Resignations are only allowed to the 31st of December of a '
                'year.',
            ])

        # 2.4.2 Set loss type to resignation and loss date to 31st but not
        #       December -> fail
        self.__validate_abortive_edit(
            member.id, {
                'membership_loss_date': date(2016, 10, 31),
                'membership_loss_type': 'resignation',
            }, [
                'Please note: There were errors, please check the form '
                'below.',
                'Resignations are only allowed to the 31st of December of a '
                'year.',
            ])

        # 2.4.3 Set loss type to resignation and loss date to December but
        #       not 31st -> fail
        self.__validate_abortive_edit(
            member.id, {
                'membership_loss_date': date(2016, 12, 30),
                'membership_loss_type': 'resignation',
            }, [
                u'Resignations are only allowed to the 31st of December of a '
                'year.'
            ])

        # 2.4.4 Set loss type to resignation and loss date to 31st of
        #       December succeed
        self.__validate_successful_edit(
            member.id, {
                'membership_loss_date': date(2016, 12, 31),
                'membership_loss_type': 'resignation',
            })

        # 2.5 Only natural persons can be set to loss type death

        # 2.5.1 Set loss type to death and entity type to legal entity ->
        #       error
        self.__validate_abortive_edit(
            member.id, {
                'entity_type': 'legalentity',
                'membership_loss_date': date(2016, 3, 25),
                'membership_loss_type': 'death',
            }, [
                u'The membership loss type \'death\' is only allowed for natural '
                u'person members and not for legal entity members.'
            ])

        # 2.5.2 Set loss type to death and entity type to natural person ->
        #       success
        self.__validate_successful_edit(
            member.id, {
                'entity_type': 'person',
                'membership_loss_date': date(2016, 3, 25),
                'membership_loss_type': 'death',
            })

        # 2.6 Only legal entites can be set to loss type winding-up

        # 2.6.1 Set loss type to winding-up and entity type to natural
        #       person error
        self.__validate_abortive_edit(
            member.id, {
                'entity_type': 'person',
                'membership_loss_date': date(2016, 3, 25),
                'membership_loss_type': 'winding-up',
            }, [
                u'The membership loss type \'winding-up\' is only allowed for '
                u'legal entity members and not for natural person members.'
            ])

        # 2.6.2 Set loss type to winding-up and entity type to legal entity
        #       -> success
        self.__validate_successful_edit(
            member.id, {
                'entity_type': 'legalentity',
                'membership_loss_date': date(2016, 3, 25),
                'membership_loss_type': 'winding-up',
            })
Пример #38
0
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        engine = create_engine(u'sqlite://')
        from c3smembership.models import Base
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(
                firstname=u'firsie',
                lastname=u'lastie',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            member2 = C3sMember(  # german
                firstname=u'AAASomeFirstnäme',
                lastname=u'XXXSomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=u'23',
            )
            member3 = C3sMember(  # german
                firstname=u'BBBSomeFirstnäme',
                lastname=u'AAASomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"de",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAZ',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'investing',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=23,
            )
            DBSession.add(member1)
            DBSession.add(member2)
            DBSession.add(member3)

            accountants_group = Group(name=u"staff")
            try:
                DBSession.add(accountants_group)
                DBSession.flush()
                # print("adding group staff")
            except:
                print("could not add group staff.")
                # pass
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            try:
                DBSession.add(accountants_group)
                DBSession.add(staffer1)
                DBSession.flush()
            except:
                print("it borked! (rut)")
Пример #39
0
def _initTestingDB():
    """
    Set up a database for these tests: have some test data.
    """
    my_settings = {
        'sqlalchemy.url': 'sqlite:///:memory:',
    }
    engine = engine_from_config(my_settings)
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    with transaction.manager:
        normal_de = C3sMember(  # german normal
            firstname=u'Ada Musiziert',
            lastname=u'Traumhaft ÄÖÜ',
            email=u'*****@*****.**',
            address1=u"ada addr one",
            address2=u"ada addr two",
            postcode=u"12345",
            city=u"Foostadt Ada",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE1',
            password=u'adasrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        normal_en = C3sMember(  # english normal
            firstname=u'James',
            lastname=u'Musician',
            email=u'*****@*****.**',
            address1=u"james addr 1",
            address2=u"james appartment 2",
            postcode=u"12345",
            city=u"Jamestown",
            country=u"Jamescountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE',
            password=u'jamesrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"",
            num_shares=u'2',
        )
        investing_de = C3sMember(  # german investing
            firstname=u'Herman',
            lastname=u'Investorius',
            email=u'*****@*****.**',
            address1=u"addr one4",
            address2=u"addr two4",
            postcode=u"12344",
            city=u"Footown M44",
            country=u"Foocountr4",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_DE',
            password=u'arandompasswor4',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'60',
        )
        investing_en = C3sMember(  # english investing
            firstname=u'Britany',
            lastname=u'Investing',
            email=u'*****@*****.**',
            address1=u"aone5",
            address2=u"atwo5",
            postcode=u"12355",
            city=u"Footown M45",
            country=u"Foocountr5",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_EN',
            password=u'arandompasswor5',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'60',
        )
        legal_entity_de = C3sMember(  # german investing legal entity
            firstname=u'Deutscher',
            lastname=u'Musikverlag',
            email=u'*****@*****.**',
            address1=u"foo bulevard",
            address2=u"123-345",
            postcode=u"98765",
            city=u"Foo",
            country=u"Bar",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'VERLAG_DE',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        legal_entity_en = C3sMember(  # english investing legal entity
            firstname=u'Francoise',
            lastname=u'Company',
            email=u'*****@*****.**',
            address1=u"foo bulevard",
            address2=u"123-345",
            postcode=u"98765",
            city=u"Foo",
            country=u"Bar",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'COMPANY_EN',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        DBSession.add(normal_de)
        DBSession.add(normal_en)
        DBSession.add(investing_de)
        DBSession.add(investing_en)
        legal_entity_de.is_legalentity = True
        DBSession.add(legal_entity_en)
        legal_entity_en.is_legalentity = True
        DBSession.add(legal_entity_de)

    return DBSession
Пример #40
0
def main(argv=sys.argv):
    """
    initialize the database
    """
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    # Setup alembic database migration information.
    # This creates the alembic_version table in the database
    # which is the basis for migrations and the "alembic current"
    # command.
    alembic_cfg = Config('alembic.ini')
    command.stamp(alembic_cfg, 'head')
    # add some content
    with transaction.manager:
        # a group for accountants/staff
        accountants_group = Group(name=u"staff")
        try:
            DBSession.add(accountants_group)
            DBSession.flush()
            # print("adding group staff")
        except:  # pragma: no cover
            print("could not add group staff.")
            # pass
    with transaction.manager:
        # staff personnel
        staffer1 = C3sStaff(
            login=u"rut",
            password=u"berries",
            email=u"*****@*****.**",
        )
        staffer1.groups = [accountants_group]
        try:
            DBSession.add(staffer1)
            # print("adding staff rut")
            DBSession.flush()
        except:  # pragma: no cover
            print("it borked! (rut)")
            # pass
    # one more staffer
    with transaction.manager:
        staffer2 = C3sStaff(
            login=u"reel",
            password=u"boo",
            email=u"*****@*****.**",
        )
        staffer2.groups = [accountants_group]
        try:
            DBSession.add(staffer2)
            # print("adding staff reel")
            DBSession.flush()
        except:  # pragma: no cover
            print("it borked! (reel)")
            # pass
    # a member, actually a membership form submission
    with transaction.manager:
        member1 = C3sMember(
            firstname=u"Firstnäme",  # includes umlaut
            lastname=u"Lastname",
            email=u"*****@*****.**",
            password=u"berries",
            address1=u"address one",
            address2=u"address two",
            postcode=u"12345 foo",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date(1971, 02, 03),
            email_is_confirmed=False,
            email_confirm_code=u"ABCDEFGHIJ",
            num_shares=u'10',
            date_of_submission=datetime.now(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
        )
        try:
            DBSession.add(member1)
            # print("adding Firstnäme")
        except:  # pragma: no cover
            pass

    with transaction.manager:
        normal_de = C3sMember(  # german normal
            firstname=u'Ada Traumhaft',
            lastname=u'Musiziert',
            email=u'*****@*****.**',
            address1=u"Musikergasse 34",
            address2=u"Hinterhaus",
            postcode=u"12345",
            city=u"Foostadt Ada",
            country=u"Germany",
            locale=u"de",
            date_of_birth=date(1971, 3, 4),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE1',
            password=u'adasrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        normal_en = C3sMember(  # english normal
            firstname=u'James',
            lastname=u'Musician',
            email=u'*****@*****.**',
            address1=u"james addr 1",
            address2=u"james appartment 2",
            postcode=u"12345",
            city=u"Jamestown",
            country=u"Jamescountry",
            locale=u"en",
            date_of_birth=date(1972, 4, 5),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE',
            password=u'jamesrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"",
            num_shares=u'2',
        )
        investing_de = C3sMember(  # german investing
            firstname=u'Herman',
            lastname=u'Investor',
            email=u'*****@*****.**',
            address1=u"c/o Mutti",
            address2=u"addr two4",
            postcode=u"12344",
            city=u"Footown M44",
            country=u"Austria",
            locale=u"de",
            date_of_birth=date(1974, 9, 8),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_DE',
            password=u'arandompasswor4',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'6',
        )
        investing_en = C3sMember(  # english investing
            firstname=u'Britany',
            lastname=u'Investing',
            email=u'*****@*****.**',
            address1=u"aone5",
            address2=u"atwo5",
            postcode=u"12355",
            city=u"London",
            country=u"United Kingdom",
            locale=u"en",
            date_of_birth=date(1978, 4, 1),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_EN',
            password=u'arandompasswor5',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=True,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        legal_entity_de = C3sMember(  # german investing legal entity
            firstname=u'Günther Vorstand',
            lastname=u'Deutscher Musikverlag',
            email=u'*****@*****.**',
            address1=u"Ährenweg 1",
            address2=u"",
            postcode=u"98765",
            city=u"Teststadt",
            country=u"Germany",
            locale=u"de",
            date_of_birth=date(1987, 3, 6),
            email_is_confirmed=False,
            email_confirm_code=u'VERLAG_DE',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        legal_entity_en = C3sMember(  # english investing legal entity
            firstname=u'John BigBoss',
            lastname=u'Some Company',
            email=u'*****@*****.**',
            address1=u"foo boulevard",
            address2=u"123-345",
            postcode=u"98765",
            city=u"London",
            country=u"United Kingdom",
            locale=u"en",
            date_of_birth=date(1982, 4, 2),
            email_is_confirmed=False,
            email_confirm_code=u'COMPANY_EN',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        DBSession.add(normal_de)
        DBSession.add(normal_en)
        DBSession.add(investing_de)
        DBSession.add(investing_en)
        legal_entity_de.is_legalentity = True
        DBSession.add(legal_entity_de)
        legal_entity_en.is_legalentity = True
        DBSession.add(legal_entity_en)
Пример #41
0
    def test_edit_members(self):
        '''
        tests for the edit_member view
        '''
        # unauthorized access must be prevented
        res = self.testapp.reset()  # delete cookie
        res = self.testapp.get('/edit/1', status=403)
        self.failUnless('Access was denied to this resource' in res.body)

        self.__login()

        # no member in DB, so redirecting to dashboard
        res = self.testapp.get('/edit/1', status=302)
        self.__validate_dashboard_redirect(res)

        member = EditMemberTests.__create_membership_applicant()
        DBSession.add(member)
        DBSession.flush()
        # now there is a member in the DB

        # let's try invalid input
        res = self.testapp.get('/edit/foo', status=302)
        self.__validate_dashboard_redirect(res)

        # now try valid id
        res = self.__get_edit_member(member.id)

        # set the date correctly
        self.__validate_successful_edit(
            member.id, {
                'firstname': u'EinVörname',
                'lastname': u'EinNachname',
                'email': u'*****@*****.**',
                'address1': u'adressteil 1',
                'address2': u'adressteil 2',
                'postcode': u'12346',
                'city': u'die city',
                'country': u'FI',
                'membership_type': u'investing',
                'entity_type': u'legalentity',
                'other_colsoc': u'no',
                'name_of_colsoc': u'',
                'date_of_birth': '1999-12-30',
                'membership_date': '2013-09-24',
                'signature_received_date': '2013-09-24',
                'payment_received_date': '2013-09-24',
            }, [
                u'EinNachname',
                u'*****@*****.**',
                u'adressteil 1',
                u'adressteil 2',
                u'12346',
                u'die city',
                u'FI',
                u'investing',
            ])

        # edit again ... changing membership acceptance status
        self.__validate_successful_edit(member.id, {
            'membership_accepted': True,
        })
Пример #42
0
def init_testing_db():
    """
    Initializes the memory database with test samples.
    """

    my_settings = {
        'sqlalchemy.url': 'sqlite:///:memory:', }
    engine = engine_from_config(my_settings)
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)

    with transaction.manager:
        # There is a side effect of test_initialization.py after which there
        # are still records in the database although it is setup from scratch.
        # Therefore, remove all members to have an empty table.

        # pylint: disable=no-member
        members = C3sMember.get_all()
        for member in members:
            DBSession.delete(member)
        DBSession.flush()

        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2014,
            u'1. ordentliche Generalversammlung',
            date(2014, 8, 23)))
        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2015,
            u'2. ordentliche Generalversammlung',
            date(2015, 6, 13)))
        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2015_2,
            u'Außerordentliche Generalversammlung',
            date(2015, 7, 16)))
        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2016,
            u'3. ordentliche Generalversammlung',
            date(2016, 4, 17)))
        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2017,
            u'4. ordentliche Generalversammlung',
            date(2017, 4, 2)))
        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2018,
            u'5. ordentliche Generalversammlung',
            date(2018, 6, 3)))
        DBSession.add(GeneralAssembly(
            GENERAL_ASSEMBLY_NUMBER_2018_2,
            u'Außerordentliche Generalversammlung',
            date(2018, 12, 1)))

        # German person
        member1 = C3sMember(
            firstname=u'SomeFirstnäme',
            lastname=u'SomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG1',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'23',
        )
        # English person
        member2 = C3sMember(
            firstname=u'AAASomeFirstnäme',
            lastname=u'XXXSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG2',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'23',
        )
        # German legal entity
        member3 = C3sMember(
            firstname=u'Cooles PlattenLabel',
            lastname=u'SomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG3',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'42',
        )
        # English legal entity
        member4 = C3sMember(
            firstname=u'Incredible Records',
            lastname=u'XXXSomeLastnäme',
            email=u'*****@*****.**',
            address1=u"addr one",
            address2=u"addr two",
            postcode=u"12345",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'ABCDEFG4',
            password=u'arandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'2',
        )
        member1.membership_accepted = True
        member1.membership_number = u'11'
        DBSession.add(member1)
        member2.membership_accepted = True
        member2.membership_number = u'22'
        DBSession.add(member2)
        member3.membership_accepted = True
        member3.membership_number = u'33'
        DBSession.add(member3)
        member4.membership_accepted = True
        member4.membership_number = u'44'
        DBSession.add(member4)

        DBSession.flush()
    return DBSession
Пример #43
0
    def test_join_c3s(self):
        # setup
        self.config = testing.setUp()
        self.config.include('pyramid_mailer.testing')
        DBSession.close()
        DBSession.remove()
        my_settings = {
            'sqlalchemy.url': 'sqlite:///:memory:',
            'available_languages': 'da de en es fr',
            'c3smembership.dashboard_number': '30'
        }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            # a group for accountants/staff
            accountants_group = Group(name=u"staff")
            DBSession.add(accountants_group)
            DBSession.flush()
            # staff personnel
            staffer1 = C3sStaff(
                login=u"rut",
                password=u"berries",
                email=u"*****@*****.**",
            )
            staffer1.groups = [accountants_group]
            DBSession.add(accountants_group)
            DBSession.add(staffer1)
            DBSession.flush()
        app = main({}, **my_settings)
        self.testapp = TestApp(app)

        # sucess for valid entry
        res = self.testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        res = form.submit(u'submit', status=302)
        res = res.follow()
        self.assertTrue('information below to be correct' in res.body)

        # success for 18th birthday
        res = self.testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        form['year'] = unicode(date.today().year - 18)
        form['month'] = unicode(date.today().month)
        form['day'] = unicode(date.today().day)
        res = form.submit(u'submit', status=302)
        res = res.follow()
        self.assertTrue('information below to be correct' in res.body)

        # failure on test one day before 18th birthday
        res = self.testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        form['year'] = unicode(date.today().year - 18)
        form['month'] = unicode(date.today().month)
        form['day'] = unicode(date.today().day + 1)
        res = form.submit(u'submit', status=200)
        self.assertTrue('underaged person is currently not' in res.body)

        # failure for statute not checked
        res = self.testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        form['got_dues_regulations'].value__set(False)
        res = form.submit(u'submit', status=200)

        # failure for dues regulations not checked
        res = self.testapp.get('/', status=200)
        form = self._fill_form_valid_natural(res.form)
        form['got_dues_regulations'].value__set(False)
        res = form.submit(u'submit', status=200)

        # teardown
        DBSession.close()
        DBSession.remove()
        testing.tearDown()
Пример #44
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
        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)

    from c3smembership.utils import country_codes
    # set default of Country select widget according to locale
    locale_country_mapping = {
        'de': 'DE',
        'en': 'GB',
    }
    country_default = locale_country_mapping.get(locale_name)
    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=date(2000, 1, 1),
                min_err=_(u'${val} is earlier than earliest date ${min}'),
                max_err=_(u'${val} is later than latest date ${max}')
            ),
            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')))
        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=(
                    (
                        u'normal',
                        _(u'FULL member. Full members have to be natural '
                          u'persons who register at least three works they '
                          u'created themselves with C3S. This applies to '
                          u'composers, lyricists and remixers. They get a '
                          u'vote.')),
                    (
                        u'investing',
                        _(u'INVESTING member. Investing members can be '
                          u'natural or legal entities or private companies '
                          u'that do not register works with C3S. They do '
                          u'not get a vote, but may counsel.'))
                ),
            )
        )
        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",
            # validator=colander.All(
            #    colsoc_validator,
            # )
        )

        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'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,
            label=_('Yes'),
        )

        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'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,
            label=_('Yes'),
        )

    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 MembershipForm(colander.Schema):
        """
        The Form consists of
        - Personal Data
        - Membership Information
        - Shares
        """
        person = PersonalData(
            title=_(u'Personal Data'),
        )
        membership_info = MembershipInfo(
            title=_(u'Membership Requirements')
        )
        shares = Shares(
            title=_(u'Shares')
        )

    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 '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
        member = C3sMember(
            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(),
            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 = DBSession()
        try:
            dbsession.add(member)
            appstruct['email_confirm_code'] = randomstring
        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}
Пример #45
0
 def _insert_members(self):
     with transaction.manager:
         member1 = C3sMember(  # german
             firstname=u'SomeFirstnäme',
             lastname=u'SomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGFOO',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         member2 = C3sMember(  # german
             firstname=u'AAASomeFirstnäme',
             lastname=u'XXXSomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGBAR',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         member3 = C3sMember(  # german
             firstname=u'BBBSomeFirstnäme',
             lastname=u'AAASomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGBAZ',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         DBSession.add(member1)
         DBSession.add(member2)
         DBSession.add(member3)
         DBSession.flush()
Пример #46
0
def dues18_reduction(request):
    """
    reduce a members dues upon valid request to do so.

    * change payable amount for member
    * cancel old invoice by issuing a cancellation
    * issue a new invoice with the new amount (if new amount != 0)
    """
    member_id = request.matchdict.get('member_id')
    member = C3sMember.get_by_id(member_id)  # is in database
    if (member is None or
            not member.membership_accepted or
            not member.dues18_invoice):
        request.session.flash(
            u"Member not found or not a member or no invoice to reduce",
            'dues18_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', member_id=member.id) + '#dues18')

    # sanity check: the given amount is a positive decimal
    try:
        reduced_amount = D(request.POST['amount'])
        assert not reduced_amount.is_signed()
        if DEBUG:
            print("DEBUG: reduction to {}".format(reduced_amount))
    except (KeyError, AssertionError):  # pragma: no cover
        request.session.flash(
            (u"Invalid amount to reduce to: '{}' "
             u"Use the dot ('.') as decimal mark, e.g. '23.42'".format(
                 request.POST['amount'])),
            'dues18_message_to_staff'  # message queue for user
        )
        return HTTPFound(
            request.route_url('detail', member_id=member.id) + '#dues18')

    if DEBUG:
        print("DEBUG: member.dues18_amount: {}".format(
            member.dues18_amount))
        print("DEBUG: type(member.dues18_amount): {}".format(
            type(member.dues18_amount)))
        print("DEBUG: member.dues18_reduced: {}".format(
            member.dues18_reduced))
        print("DEBUG: member.dues18_amount_reduced: {}".format(
            member.dues18_amount_reduced))
        print("DEBUG: type(member.dues18_amount_reduced): {}".format(
            type(member.dues18_amount_reduced)))

    # The hidden input 'confirmed' must have the value 'yes' which is set by
    # the confirmation dialog.
    reduction_confirmed = request.POST['confirmed']
    if reduction_confirmed != 'yes':
        request.session.flash(
            u'Die Reduktion wurde nicht bestätigt.',
            'dues18_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', member_id=member.id) + '#dues18')

    # check the reduction amount: same as default calculated amount?
    if (not member.dues18_reduced  and
            member.dues18_amount == reduced_amount):
        request.session.flash(
            u"Dieser Beitrag ist der default-Beitrag!",
            'dues18_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', member_id=member.id) + '#dues18')

    if (member.dues18_reduced and
            reduced_amount == member.dues18_amount_reduced):
        request.session.flash(
            u"Auf diesen Beitrag wurde schon reduziert!",
            'dues18_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', member_id=member.id) + '#dues18')

    if (member.dues18_reduced and
            reduced_amount > member.dues18_amount_reduced or
            reduced_amount > member.dues18_amount):
        request.session.flash(
            u'Beitrag darf nicht über den berechneten oder bereits'
            u'reduzierten Wert gesetzt werden.',
            'dues18_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', member_id=member.id) + '#dues18')

    # prepare: get highest invoice no from db
    max_invoice_no = DuesInvoiceRepository.get_max_invoice_number(2018)

    # things to be done:
    # * change dues amount for that member
    # * cancel old invoice by issuing a reversal invoice
    # * issue a new invoice with the new amount

    member.set_dues18_reduced_amount(reduced_amount)
    request.session.flash('reduction to {}'.format(reduced_amount),
                          'dues18_message_to_staff')

    old_invoice = DuesInvoiceRepository.get_by_number(
        member.dues18_invoice_no, 2018)
    old_invoice.is_cancelled = True

    reversal_invoice_amount = -D(old_invoice.invoice_amount)

    # prepare reversal invoice number
    new_invoice_no = max_invoice_no + 1
    # create reversal invoice
    reversal_invoice = Dues18Invoice(
        invoice_no=new_invoice_no,
        invoice_no_string=(
            u'C3S-dues2018-' + str(new_invoice_no).zfill(4)) + '-S',
        invoice_date=datetime.today(),
        invoice_amount=reversal_invoice_amount.to_eng_string(),
        member_id=member.id,
        membership_no=member.membership_number,
        email=member.email,
        token=member.dues18_token,
    )
    reversal_invoice.preceding_invoice_no = old_invoice.invoice_no
    reversal_invoice.is_reversal = True
    DBSession.add(reversal_invoice)
    DBSession.flush()
    old_invoice.succeeding_invoice_no = new_invoice_no

    # check if this is an exemption (reduction to zero)
    is_exemption = False  # sane default
    # check if reduction to zero
    if reduced_amount.is_zero():
        is_exemption = True
        if DEBUG:
            print("this is an exemption: reduction to zero")
    else:
        if DEBUG:
            print("this is a reduction to {}".format(reduced_amount))

    if not is_exemption:
        # create new invoice
        new_invoice = Dues18Invoice(
            invoice_no=new_invoice_no + 1,
            invoice_no_string=(
                u'C3S-dues2018-' + str(new_invoice_no + 1).zfill(4)),
            invoice_date=datetime.today(),
            invoice_amount=u'' + str(reduced_amount),
            member_id=member.id,
            membership_no=member.membership_number,
            email=member.email,
            token=member.dues18_token,
        )
        new_invoice.is_altered = True
        new_invoice.preceding_invoice_no = reversal_invoice.invoice_no
        reversal_invoice.succeeding_invoice_no = new_invoice_no + 1
        DBSession.add(new_invoice)

        # in the members record, store the current invoice no
        member.dues18_invoice_no = new_invoice_no + 1

        DBSession.flush()  # persist newer invoices

    reversal_url = (
        request.route_url(
            'make_dues18_reversal_invoice_pdf',
            email=member.email,
            code=member.dues18_token,
            no=str(reversal_invoice.invoice_no).zfill(4)
        )
    )
    if is_exemption:
        email_subject, email_body = make_dues_exemption_email(
            member,
            reversal_url)
    else:
        invoice_url = (
            request.route_url(
                'make_dues18_invoice_no_pdf',
                email=member.email,
                code=member.dues18_token,
                i=str(new_invoice_no + 1).zfill(4)
            )
        )
        email_subject, email_body = make_dues18_reduction_email(
            member,
            new_invoice,
            invoice_url,
            reversal_url)

    message = Message(
        subject=email_subject,
        sender=request.registry.settings[
            'c3smembership.notification_sender'],
        recipients=[member.email],
        body=email_body,
    )
    if is_exemption:
        request.session.flash('exemption email was sent to user!',
                              'dues18_message_to_staff')
    else:
        request.session.flash('update email was sent to user!',
                              'dues18_message_to_staff')
    send_message(request, message)
    return HTTPFound(
        request.route_url(
            'detail',
            member_id=member_id) +
        '#dues18')
def dues17_reduction(request):
    """
    reduce a members dues upon valid request to do so.

    * change payable amount for member
    * cancel old invoice by issuing a cancellation
    * issue a new invoice with the new amount (if new amount != 0)

    this will only work for *normal* members.
    """
    # member: sanity checks
    try:
        member_id = request.matchdict['member_id']
        member = C3sMember.get_by_id(member_id)  # is in database
        assert member.membership_accepted  # is a member
        assert 'investing' not in member.membership_type  # is normal member
    except (KeyError, AssertionError):  # pragma: no cover
        request.session.flash(
            u"No member OR not accepted OR not normal member",
            'dues17_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')

    # sanity check: the given amount is a positive decimal
    try:
        reduced_amount = D(request.POST['amount'])
        assert not reduced_amount.is_signed()
        if DEBUG:
            print("DEBUG: reduction to {}".format(reduced_amount))
    except (KeyError, AssertionError):  # pragma: no cover
        request.session.flash(
            (u"Invalid amount to reduce to: '{}' "
             u"Use the dot ('.') as decimal mark, e.g. '23.42'".format(
                 request.POST['amount'])),
            'dues17_message_to_staff'  # message queue for user
        )
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')

    if DEBUG:
        print("DEBUG: member.dues17_amount: {}".format(member.dues17_amount))
        print("DEBUG: type(member.dues17_amount): {}".format(
            type(member.dues17_amount)))
        print("DEBUG: member.dues17_reduced: {}".format(member.dues17_reduced))
        print("DEBUG: member.dues17_amount_reduced: {}".format(
            member.dues17_amount_reduced))
        print("DEBUG: type(member.dues17_amount_reduced): {}".format(
            type(member.dues17_amount_reduced)))

    # The hidden input 'confirmed' must have the value 'yes' which is set by
    # the confirmation dialog.
    reduction_confirmed = request.POST['confirmed']
    if reduction_confirmed != 'yes':
        request.session.flash(
            u'Die Reduktion wurde nicht bestätigt.',
            'dues17_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')

    # check the reduction amount: same as default calculated amount?
    if ((member.dues17_reduced is False)
            and (member.dues17_amount == reduced_amount)):
        request.session.flash(
            u"Dieser Beitrag ist der default-Beitrag!",
            'dues17_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')

    if reduced_amount == member.dues17_amount_reduced:
        request.session.flash(
            u"Auf diesen Beitrag wurde schon reduziert!",
            'dues17_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')

    if member.dues17_reduced \
            and reduced_amount > member.dues17_amount_reduced \
            or reduced_amount > member.dues17_amount:
        request.session.flash(
            u'Beitrag darf nicht über den berechneten oder bereits'
            u'reduzierten Wert gesetzt werden.',
            'dues17_message_to_staff'  # message queue for staff
        )
        return HTTPFound(
            request.route_url('detail', memberid=member.id) + '#dues17')

    # prepare: get highest invoice no from db
    max_invoice_no = Dues17Invoice.get_max_invoice_no()

    # things to be done:
    # * change dues amount for that member
    # * cancel old invoice by issuing a reversal invoice
    # * issue a new invoice with the new amount

    member.set_dues17_reduced_amount(reduced_amount)
    request.session.flash('reduction to {}'.format(reduced_amount),
                          'dues17_message_to_staff')

    old_invoice = Dues17Invoice.get_by_invoice_no(member.dues17_invoice_no)
    old_invoice.is_cancelled = True

    reversal_invoice_amount = -D(old_invoice.invoice_amount)

    # prepare reversal invoice number
    new_invoice_no = max_invoice_no + 1
    # create reversal invoice
    reversal_invoice = Dues17Invoice(
        invoice_no=new_invoice_no,
        invoice_no_string=(u'C3S-dues2017-' + str(new_invoice_no).zfill(4)) +
        '-S',
        invoice_date=datetime.today(),
        invoice_amount=reversal_invoice_amount.to_eng_string(),
        member_id=member.id,
        membership_no=member.membership_number,
        email=member.email,
        token=member.dues17_token,
    )
    reversal_invoice.preceding_invoice_no = old_invoice.invoice_no
    reversal_invoice.is_reversal = True
    DBSession.add(reversal_invoice)
    DBSession.flush()
    old_invoice.succeeding_invoice_no = new_invoice_no

    # check if this is an exemption (reduction to zero)
    is_exemption = False  # sane default
    # check if reduction to zero
    if reduced_amount.is_zero():
        is_exemption = True
        if DEBUG:
            print("this is an exemption: reduction to zero")
    else:
        if DEBUG:
            print("this is a reduction to {}".format(reduced_amount))

    if not is_exemption:
        # create new invoice
        new_invoice = Dues17Invoice(
            invoice_no=new_invoice_no + 1,
            invoice_no_string=(u'C3S-dues2017-' +
                               str(new_invoice_no + 1).zfill(4)),
            invoice_date=datetime.today(),
            invoice_amount=u'' + str(reduced_amount),
            member_id=member.id,
            membership_no=member.membership_number,
            email=member.email,
            token=member.dues17_token,
        )
        new_invoice.is_altered = True
        new_invoice.preceding_invoice_no = reversal_invoice.invoice_no
        reversal_invoice.succeeding_invoice_no = new_invoice_no + 1
        DBSession.add(new_invoice)

        # in the members record, store the current invoice no
        member.dues17_invoice_no = new_invoice_no + 1

        DBSession.flush()  # persist newer invoices

    reversal_url = (request.route_url(
        'make_dues17_reversal_invoice_pdf',
        email=member.email,
        code=member.dues17_token,
        no=str(reversal_invoice.invoice_no).zfill(4)))
    if is_exemption:
        email_subject, email_body = make_dues_exemption_email(
            member, reversal_url)
    else:
        invoice_url = (request.route_url('make_dues17_invoice_no_pdf',
                                         email=member.email,
                                         code=member.dues17_token,
                                         i=str(new_invoice_no + 1).zfill(4)))
        email_subject, email_body = make_dues17_reduction_email(
            member, new_invoice, invoice_url, reversal_url)

    message = Message(subject=email_subject,
                      sender='*****@*****.**',
                      recipients=[member.email],
                      body=email_body,
                      extra_headers={
                          'Reply-To': '*****@*****.**',
                      })
    if is_exemption:
        request.session.flash('exemption email was sent to user!',
                              'dues17_message_to_staff')
    else:
        request.session.flash('update email was sent to user!',
                              'dues17_message_to_staff')
    send_message(request, message)
    return HTTPFound(
        request.route_url('detail', memberid=member_id) + '#dues17')
Пример #48
0
 def _insert_members(self):
     with transaction.manager:
         member1 = C3sMember(  # german
             firstname=u'SomeFirstnäme',
             lastname=u'SomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGFOO',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         member2 = C3sMember(  # german
             firstname=u'AAASomeFirstnäme',
             lastname=u'XXXSomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGBAR',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         member3 = C3sMember(  # german
             firstname=u'BBBSomeFirstnäme',
             lastname=u'AAASomeLastnäme',
             email=u'*****@*****.**',
             address1=u"addr one",
             address2=u"addr two",
             postcode=u"12345",
             city=u"Footown Mäh",
             country=u"Foocountry",
             locale=u"DE",
             date_of_birth=date.today(),
             email_is_confirmed=False,
             email_confirm_code=u'ABCDEFGBAZ',
             password=u'arandompassword',
             date_of_submission=date.today(),
             membership_type=u'normal',
             member_of_colsoc=True,
             name_of_colsoc=u"GEMA",
             num_shares=u'23',
         )
         DBSession.add(member1)
         DBSession.add(member2)
         DBSession.add(member3)
         DBSession.flush()
Пример #49
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
Пример #50
0
    def setUp(self):
        my_settings = {'sqlalchemy.url': 'sqlite:///:memory:', }
        engine = engine_from_config(my_settings)
        DBSession.configure(bind=engine)
        Base.metadata.create_all(engine)
        with transaction.manager:
            member1 = C3sMember(  # german
                firstname=u'SomeFirstnäme',
                lastname=u'SomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGFOO',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=35,
            )
            member2 = C3sMember(  # german
                firstname=u'AAASomeFirstnäme',
                lastname=u'XXXSomeLastnäme',
                email=u'*****@*****.**',
                address1=u"addr one",
                address2=u"addr two",
                postcode=u"12345",
                city=u"Footown Mäh",
                country=u"Foocountry",
                locale=u"DE",
                date_of_birth=date.today(),
                email_is_confirmed=False,
                email_confirm_code=u'ABCDEFGBAR',
                password=u'arandompassword',
                date_of_submission=date.today(),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u"GEMA",
                num_shares=45,
            )
            member3 = C3sMember(
                firstname=u'Not Approved',
                lastname=u'Member',
                email=u'*****@*****.**',
                address1=u'Some Street 123',
                address2=u'',
                postcode=u"12345",
                city=u"Some City",
                country=u"Some Country",
                locale=u"DE",
                date_of_birth=date(1980, 1, 2),
                email_is_confirmed=False,
                email_confirm_code=u'NOT_APPROVED_MEMBER',
                password=u'not_approved_member',
                date_of_submission=date(1970, 1, 1),
                membership_type=u'normal',
                member_of_colsoc=True,
                name_of_colsoc=u'',
                num_shares=7,
            )
            # pylint: disable=no-member
            DBSession.add(member1)
            # pylint: disable=no-member
            DBSession.add(member2)
            # pylint: disable=no-member
            DBSession.add(member3)

            member1.membership_number = u'member1'
            member1.membership_date = date(2013, 1, 1)
            member1.membership_accepted = True
            member2.membership_number = u'member2'
            member2.membership_date = date(2013, 1, 1)
            member2.membership_accepted = True
            member3.payment_received_date = date(2016, 10, 11)

            share = Shares()
            share.reference_code = u'share1'
            share.date_of_acquisition = date(2013, 1, 2)
            share.payment_received_date = date(2012, 11, 10)
            share.number = 12
            member1.shares.append(share)

            share = Shares()
            share.reference_code = u'share2'
            share.date_of_acquisition = date(2014, 2, 3)
            share.payment_received_date = date(2012, 12, 31)
            share.number = 23
            member1.shares.append(share)

            share = Shares()
            share.reference_code = u'share3'
            share.date_of_acquisition = date(2014, 3, 4)
            share.payment_received_date = date(2014, 3, 3)
            share.number = 34
            member2.shares.append(share)

            share = Shares()
            share.reference_code = u'share4'
            share.date_of_acquisition = date(2015, 4, 5)
            share.payment_received_date = date(2014, 11, 15)
            share.number = 45
            member2.shares.append(share)
Пример #51
0
def main(argv=sys.argv):
    """
    initialize the database
    """
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    # Setup alembic database migration information.
    # This creates the alembic_version table in the database
    # which is the basis for migrations and the "alembic current"
    # command.
    alembic_cfg = Config('alembic.ini')
    command.stamp(alembic_cfg, 'head')
    # add some content
    with transaction.manager:
        # a group for accountants/staff
        accountants_group = Group(name=u"staff")
        try:
            DBSession.add(accountants_group)
            DBSession.flush()
        except:  # pragma: no cover
            print("could not add group staff.")
            # pass
    with transaction.manager:
        # staff personnel
        staffer1 = C3sStaff(
            login=u"rut",
            password=u"berries",
            email=u"*****@*****.**",
        )
        staffer1.groups = [accountants_group]
        try:
            DBSession.add(staffer1)
            DBSession.flush()
        except:  # pragma: no cover
            print("it borked! (rut)")
    # one more staffer
    with transaction.manager:
        staffer2 = C3sStaff(
            login=u"reel",
            password=u"boo",
            email=u"*****@*****.**",
        )
        staffer2.groups = [accountants_group]
        try:
            DBSession.add(staffer2)
            DBSession.flush()
        except:  # pragma: no cover
            print("it borked! (reel)")
    # a member, actually a membership form submission
    with transaction.manager:
        member1 = C3sMember(
            firstname=u"Firstnäme",  # includes umlaut
            lastname=u"Lastname",
            email=u"*****@*****.**",
            password=u"berries",
            address1=u"address one",
            address2=u"address two",
            postcode=u"12345 foo",
            city=u"Footown Mäh",
            country=u"Foocountry",
            locale=u"en",
            date_of_birth=date(1971, 02, 03),
            email_is_confirmed=False,
            email_confirm_code=u"ABCDEFGHIJ",
            num_shares=u'10',
            date_of_submission=datetime.now(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
        )
        try:
            DBSession.add(member1)
        except:  # pragma: no cover
            pass

    with transaction.manager:
        normal_de = C3sMember(  # german normal
            firstname=u'Ada Traumhaft',
            lastname=u'Musiziert',
            email=u'*****@*****.**',
            address1=u"Musikergasse 34",
            address2=u"Hinterhaus",
            postcode=u"12345",
            city=u"Foostadt Ada",
            country=u"Germany",
            locale=u"de",
            date_of_birth=date(1971, 3, 4),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE1',
            password=u'adasrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        normal_en = C3sMember(  # english normal
            firstname=u'James',
            lastname=u'Musician',
            email=u'*****@*****.**',
            address1=u"james addr 1",
            address2=u"james appartment 2",
            postcode=u"12345",
            city=u"Jamestown",
            country=u"Jamescountry",
            locale=u"en",
            date_of_birth=date(1972, 4, 5),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE',
            password=u'jamesrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"",
            num_shares=u'2',
        )
        investing_de = C3sMember(  # german investing
            firstname=u'Herman',
            lastname=u'Investor',
            email=u'*****@*****.**',
            address1=u"c/o Mutti",
            address2=u"addr two4",
            postcode=u"12344",
            city=u"Footown M44",
            country=u"Austria",
            locale=u"de",
            date_of_birth=date(1974, 9, 8),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_DE',
            password=u'arandompasswor4',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'6',
        )
        investing_en = C3sMember(  # english investing
            firstname=u'Britany',
            lastname=u'Investing',
            email=u'*****@*****.**',
            address1=u"aone5",
            address2=u"atwo5",
            postcode=u"12355",
            city=u"London",
            country=u"United Kingdom",
            locale=u"en",
            date_of_birth=date(1978, 4, 1),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_EN',
            password=u'arandompasswor5',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=True,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        legal_entity_de = C3sMember(  # german investing legal entity
            firstname=u'Günther Vorstand',
            lastname=u'Deutscher Musikverlag',
            email=u'*****@*****.**',
            address1=u"Ährenweg 1",
            address2=u"",
            postcode=u"98765",
            city=u"Teststadt",
            country=u"Germany",
            locale=u"de",
            date_of_birth=date(1987, 3, 6),
            email_is_confirmed=False,
            email_confirm_code=u'VERLAG_DE',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        legal_entity_en = C3sMember(  # english investing legal entity
            firstname=u'John BigBoss',
            lastname=u'Some Company',
            email=u'*****@*****.**',
            address1=u"foo boulevard",
            address2=u"123-345",
            postcode=u"98765",
            city=u"London",
            country=u"United Kingdom",
            locale=u"en",
            date_of_birth=date(1982, 4, 2),
            email_is_confirmed=False,
            email_confirm_code=u'COMPANY_EN',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        DBSession.add(normal_de)
        DBSession.add(normal_en)
        DBSession.add(investing_de)
        DBSession.add(investing_en)
        legal_entity_de.is_legalentity = True
        DBSession.add(legal_entity_de)
        legal_entity_en.is_legalentity = True
        DBSession.add(legal_entity_en)
Пример #52
0
def _initTestingDB():
    """
    Set up a database for these tests: have some test data.
    """
    my_settings = {'sqlalchemy.url': 'sqlite:///:memory:', }
    engine = engine_from_config(my_settings)
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    with transaction.manager:
        normal_de = C3sMember(  # german normal
            firstname=u'Ada Musiziert',
            lastname=u'Traumhaft ÄÖÜ',
            email=u'*****@*****.**',
            address1=u"ada addr one",
            address2=u"ada addr two",
            postcode=u"12345",
            city=u"Foostadt Ada",
            country=u"Foocountry",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE1',
            password=u'adasrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'23',
        )
        normal_en = C3sMember(  # english normal
            firstname=u'James',
            lastname=u'Musician',
            email=u'*****@*****.**',
            address1=u"james addr 1",
            address2=u"james appartment 2",
            postcode=u"12345",
            city=u"Jamestown",
            country=u"Jamescountry",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'NORMAL_DE',
            password=u'jamesrandompassword',
            date_of_submission=date.today(),
            membership_type=u'normal',
            member_of_colsoc=True,
            name_of_colsoc=u"",
            num_shares=u'2',
        )
        investing_de = C3sMember(  # german investing
            firstname=u'Herman',
            lastname=u'Investorius',
            email=u'*****@*****.**',
            address1=u"addr one4",
            address2=u"addr two4",
            postcode=u"12344",
            city=u"Footown M44",
            country=u"Foocountr4",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_DE',
            password=u'arandompasswor4',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'60',
        )
        investing_en = C3sMember(  # english investing
            firstname=u'Britany',
            lastname=u'Investing',
            email=u'*****@*****.**',
            address1=u"aone5",
            address2=u"atwo5",
            postcode=u"12355",
            city=u"Footown M45",
            country=u"Foocountr5",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'INVESTING_EN',
            password=u'arandompasswor5',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=True,
            name_of_colsoc=u"GEMA",
            num_shares=u'60',
        )
        legal_entity_de = C3sMember(  # german investing legal entity
            firstname=u'Deutscher',
            lastname=u'Musikverlag',
            email=u'*****@*****.**',
            address1=u"foo bulevard",
            address2=u"123-345",
            postcode=u"98765",
            city=u"Foo",
            country=u"Bar",
            locale=u"de",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'VERLAG_DE',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        legal_entity_en = C3sMember(  # english investing legal entity
            firstname=u'Francoise',
            lastname=u'Company',
            email=u'*****@*****.**',
            address1=u"foo bulevard",
            address2=u"123-345",
            postcode=u"98765",
            city=u"Foo",
            country=u"Bar",
            locale=u"en",
            date_of_birth=date.today(),
            email_is_confirmed=False,
            email_confirm_code=u'COMPANY_EN',
            password=u'arandompasswor6',
            date_of_submission=date.today(),
            membership_type=u'investing',
            member_of_colsoc=False,
            name_of_colsoc=u"",
            num_shares=u'60',
        )
        DBSession.add(normal_de)
        DBSession.add(normal_en)
        DBSession.add(investing_de)
        DBSession.add(investing_en)
        legal_entity_de.is_legalentity = True
        DBSession.add(legal_entity_en)
        legal_entity_en.is_legalentity = True
        DBSession.add(legal_entity_de)

    return DBSession
Пример #53
0
def merge_member_view(request):
    """
    Merges member duplicates into one member record.

    Some people have more than one entry in our C3SMember table,
    e.g. because they used the application form more than once
    to acquire more shares.

    They shall not, however, become members twice and get more than one
    membership number. So we try and merge them:

    If a person is already a member and acquires a second package of shares,
    this package of shares is added to the former membership entry.
    The second entry in the C3sMember table is given the 'is_duplicate' flag
    and also the 'duplicate_of' is given the *id* of the original entry.
    """
    _id = request.matchdict['afm_id']
    _mid = request.matchdict['mid']
    if DEBUG:  # pragma: no cover
        print "shall merge {} to {}".format(_id, _mid)

    orig = C3sMember.get_by_id(_mid)
    merg = C3sMember.get_by_id(_id)

    if not orig.membership_accepted:
        request.session.flash(
            'you can only merge to accepted members!',
            'merge_message')
        HTTPFound(request.route_url('make_member', afm_id=_id))
    exceeds_60 = int(orig.num_shares) + int(merg.num_shares) > 60
    if exceeds_60:
        request.session.flash(
            'merger would exceed 60 shares!',
            'merge_message')
        return HTTPFound(request.route_url('make_member', afm_id=_id))

    # TODO: this needs fixing!!!
    # date must be set manually according to date of approval of the board
    _date_for_shares = merg.signature_received_date if (
        merg.signature_received_date > merg.payment_received_date
    ) else merg.payment_received_date
    # print "the date for the shares: {} (s: {}; p: {})".format(
    #    _date_for_shares,
    #    merg.signature_received_date,
    #    merg.payment_received_date
    # )
    shares = Shares(
        number=merg.num_shares,
        date_of_acquisition=_date_for_shares,
        reference_code=merg.email_confirm_code,
        signature_received=merg.signature_received,
        signature_received_date=merg.signature_received_date,
        payment_received=merg.payment_received,
        payment_received_date=merg.payment_received_date,
    )
    DBSession.add(shares)  # persist
    orig.shares.append(shares)
    orig.num_shares += merg.num_shares
    DBSession.delete(merg)

    return HTTPFound(request.route_url('detail', memberid=_mid))