Example #1
0
 def setUp(self):
     school = School(name='testschool')
     school.save()
     # country = Country(name='testcountry')
     # country.save()
     child = Child(first_name='mary', surname='jones', sex='f', school=school)
     child.save()
     contributor1 = Contributor(first_name='john', surname='doe', aard_van_de_schenker='np', street='some street',
                                street_number=4, zip_code=2010, city='city', payment_frequency='every month',
                                language='nl')
     contributor1.save()
     contributor2 = Contributor(first_name='marie', surname='evers', aard_van_de_schenker='np', street='some street',
                                street_number=4, zip_code=2010, city='city', payment_frequency='every 3 months',
                                language='nl')
     contributor2.save()
     contributor3 = Contributor(first_name='havent', surname='peeyd', aard_van_de_schenker='np', street='some street',
                                street_number=4, zip_code=2010, city='city', payment_frequency='every 3 months',
                                language='nl')
     contributor3.save()
     payments = [
         {'amount': 42.4, 'contributor': contributor1, 'child': child, 'date': date(2014, 2, 20), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor1, 'child': child, 'date': date(2014, 3, 20), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor1, 'child': child, 'date': date(2014, 1, 20), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor2, 'child': child, 'date': date(2014, 1, 14), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor2, 'child': child, 'date': date(2014, 4, 15), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor2, 'child': child, 'date': date(2014, 7, 16), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor2, 'child': child, 'date': date(2014, 10, 17), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': contributor3, 'child': child, 'date': date(2014, 10, 17), 'entitled': 'entitled', 'ptype': 'recurrent'},
     ]
     for p in payments:
         payment = Payment(**p)
         payment.save()
Example #2
0
 def setUp(self):
     """
     This fixture data set includes:
         contributor1: pays every month and therefor, should not be included in reminders report, although his next
          expected payment is in the near future.
         contributor2: pays every 3 months, and hence should show up in the overdue report.
         contributor3: pays every year and hence should show up in the reminders report.
         contributor4: pays sporadic, and hence should not be included in one of the reports
     """
     print 'installing fixture data'
     self.reference_date = date(2015, 11, 7)
     country = Country(name='Belgium', code=150)
     country.save()
     school = School(name='testschool')
     school.save()
     child = Child(first_name='mary', surname='jones', sex='f', school=school)
     child.save()
     self.contributor1 = Contributor(first_name='john', surname='doe', aard_van_de_schenker='np', street='some street',
                                street_number=4, zip_code=2010, city='city', country=country,
                                payment_frequency='every month', language='nl')
     self.contributor1.save()
     self.contributor2 = Contributor(first_name='marie', surname='evers', aard_van_de_schenker='np',
                                     street='some street', street_number=4, zip_code=2010, city='city',
                                     country=country, payment_frequency='every 3 months', language='nl')
     self.contributor2.save()
     self.contributor3 = Contributor(first_name='harvey', surname='jones', aard_van_de_schenker='np',
                                     street='some street', street_number=4, zip_code=2010, city='city',
                                     country=country, payment_frequency='every year', language='nl')
     self.contributor3.save()
     self.contributor4 = Contributor(first_name='jeff', surname='buckley', aard_van_de_schenker='np',
                                     street='some street', street_number=4, zip_code=2010, city='city',
                                     country=country, payment_frequency='sporadic', language='nl')
     self.contributor4.save()
     payments = [
         {'amount': 45, 'contributor': self.contributor1, 'child': child, 'date': date(2015, 10, 1),
          'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 45, 'contributor': self.contributor1, 'child': child, 'date': date(2015, 12, 4),
          'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 45, 'contributor': self.contributor2, 'child': child, 'date': date(2015, 8, 15),
          'expected_date': date(2015, 8, 1), 'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 42.4, 'contributor': self.contributor3, 'child': child,
          'date': date(2014, 12, 10), 'expected_date': date(2014, 11, 21),
         'entitled': 'entitled', 'ptype': 'recurrent'},
         {'amount': 30, 'contributor': self.contributor4, 'child': child,
          'date': date(2014, 12, 1), 'entitled': 'entitled', 'ptype': 'recurrent'},
     ]
     for p in payments:
         payment = Payment(**p)
         payment.save()
Example #3
0
def create_fixture():
    country = Country(name='Belgium', code=150)
    country.save()
    school = School(name='testschool')
    school.save()
    child = Child(first_name='mary', surname='jones', sex='f', school=school)
    child.save()
    contributor = Contributor(first_name='john', surname='doe', aard_van_de_schenker='np', street='some street',
                               street_number=4, zip_code=2010, city='city', country=country,
                               payment_frequency='every month', language='nl')
    contributor.save()

    payments = [
        {'amount': 48, 'contributor': contributor, 'child': child, 'date': date(2015, 10, 1),
         'entitled': 'entitled', 'ptype': 'recurrent'},
        {'amount': 49, 'contributor': contributor, 'child': child, 'date': date(2015, 12, 4),
         'entitled': 'entitled', 'ptype': 'recurrent'},
        {'amount': 49.5, 'contributor': contributor, 'child': child, 'date': date(2015, 12, 16),
         'entitled': 'entitled', 'ptype': 'single'}
    ]
    for p in payments:
        payment = Payment(**p)
        payment.save()
Example #4
0
class SimpleReportsTestCase(TestCase):
    def setUp(self):
        """
        This fixture data set includes:
            contributor1: pays every month and therefor, should not be included in reminders report, although his next
             expected payment is in the near future.
            contributor2: pays every 3 months, and hence should show up in the overdue report.
            contributor3: pays every year and hence should show up in the reminders report.
            contributor4: pays sporadic, and hence should not be included in one of the reports
        """
        print 'installing fixture data'
        self.reference_date = date(2015, 11, 7)
        country = Country(name='Belgium', code=150)
        country.save()
        school = School(name='testschool')
        school.save()
        child = Child(first_name='mary', surname='jones', sex='f', school=school)
        child.save()
        self.contributor1 = Contributor(first_name='john', surname='doe', aard_van_de_schenker='np', street='some street',
                                   street_number=4, zip_code=2010, city='city', country=country,
                                   payment_frequency='every month', language='nl')
        self.contributor1.save()
        self.contributor2 = Contributor(first_name='marie', surname='evers', aard_van_de_schenker='np',
                                        street='some street', street_number=4, zip_code=2010, city='city',
                                        country=country, payment_frequency='every 3 months', language='nl')
        self.contributor2.save()
        self.contributor3 = Contributor(first_name='harvey', surname='jones', aard_van_de_schenker='np',
                                        street='some street', street_number=4, zip_code=2010, city='city',
                                        country=country, payment_frequency='every year', language='nl')
        self.contributor3.save()
        self.contributor4 = Contributor(first_name='jeff', surname='buckley', aard_van_de_schenker='np',
                                        street='some street', street_number=4, zip_code=2010, city='city',
                                        country=country, payment_frequency='sporadic', language='nl')
        self.contributor4.save()
        payments = [
            {'amount': 45, 'contributor': self.contributor1, 'child': child, 'date': date(2015, 10, 1),
             'entitled': 'entitled', 'ptype': 'recurrent'},
            {'amount': 45, 'contributor': self.contributor1, 'child': child, 'date': date(2015, 12, 4),
             'entitled': 'entitled', 'ptype': 'recurrent'},
            {'amount': 45, 'contributor': self.contributor2, 'child': child, 'date': date(2015, 8, 15),
             'expected_date': date(2015, 8, 1), 'entitled': 'entitled', 'ptype': 'recurrent'},
            {'amount': 42.4, 'contributor': self.contributor3, 'child': child,
             'date': date(2014, 12, 10), 'expected_date': date(2014, 11, 21),
            'entitled': 'entitled', 'ptype': 'recurrent'},
            {'amount': 30, 'contributor': self.contributor4, 'child': child,
             'date': date(2014, 12, 1), 'entitled': 'entitled', 'ptype': 'recurrent'},
        ]
        for p in payments:
            payment = Payment(**p)
            payment.save()


    def test_overdue(self):
        """
        contributor 2 is overdue and should show up in the results
        """
        overdue_rep = OverdueReport()
        res = overdue_rep.getReportingValues(allowed_overdue_days=5, _reference_date=self.reference_date)
        self.assertEqual(len(res['values']), 1)
        self.assertEqual(res['values'][0][1], 'marie evers')
        self.assertEqual(res['values'][0][7], -6) # this is the days until next expected payment. Based on previous expected date and payment frequency.
        res = overdue_rep.getReportingValues(allowed_overdue_days=7, _reference_date=self.reference_date)
        self.assertAlmostEqual(len(res['values']), 0) # contributor 2 is now excluded
        new_payment = Payment(amount=45, contributor=self.contributor2, date=self.reference_date - relativedelta(days=4), entitled='entitled', ptype='single')
        new_payment.save()
        res = overdue_rep.getReportingValues(allowed_overdue_days=5, _reference_date=self.reference_date)
        self.assertEqual(len(res['values']), 1) # new payment for contributor 2 is ignored because ptype="single". Contributor 2 is still overdue
        self.assertEqual(res['values'][0][1], 'marie evers')


    def test_reminder(self):
        """
        contributor 1 should be excluded: monthly payer
        contributor 2 is overdue so should be excluded from the reminders report
        contributor 3 should pay in 15 days (based on the expected date from his last payment!)
        contributor 4 pays sporadic so should be excluded
        """
        reminders_rep = RemindersReport()
        res = reminders_rep.getReportingValues(max_days_till_next_payment=20, _reference_date=self.reference_date)
        self.assertEqual(len(res['values']), 1)
        self.assertEqual(res['values'][0][1], 'harvey jones')
        res = reminders_rep.getReportingValues(max_days_till_next_payment=14, _reference_date=self.reference_date)
        self.assertEqual(len(res['values']), 0)


    def test_individual_fiscal_report(self):
        """
        contributor 4 did not donate enough to receive a fiscal report. Only contributors 1, and 2 should receive
        a fiscal report for 2015. Contributor 3 receivers a fiscal report for 2014.
        """

        # check contributor 1
        ifr1 = IndividualFiscalReport(contributor=self.contributor1, year=self.reference_date.year)
        self.assertEqual(ifr1.full_clean(), None) # no error raised, nothing returned
        ifr1.save()
        self.assertEqual(ifr1.report_number, 1)

        # check contributor 2
        ifr2 = IndividualFiscalReport(contributor=self.contributor2, year=self.reference_date.year)
        self.assertEqual(ifr2.full_clean(), None) # no error raised, nothing returned
        ifr2.save()
        self.assertEqual(ifr2.report_number, 2)

        # check contributor 3
        ifr3 = IndividualFiscalReport(contributor=self.contributor3, year=self.reference_date.year - 1)
        self.assertEqual(ifr3.full_clean(), None) # no error raised, nothing returned
        ifr3.save()
        self.assertEqual(ifr3.report_number, 1)

        # cannot create a second report for contributor 1
        ifr4 = IndividualFiscalReport(contributor=self.contributor1, year=self.reference_date.year)
        self.assertRaises(ValidationError, ifr4.full_clean)

    def test_get_all_indiv_fiscal_reports(self):
        # just to make sure: no reports are present in the database yet
        indiv_reports = IndividualFiscalReport.objects.filter(year=self.reference_date.year)
        self.assertEqual(len(indiv_reports), 0)
        reports = IndividualFiscalReport.getAllReports(self.reference_date.year)
        self.assertEqual(len(reports), 2)
        indiv_reports = IndividualFiscalReport.objects.filter(year=self.reference_date.year)
        self.assertEqual(len(indiv_reports), 2)

    def test_fiscal_reports(self):
        """
        contributor 4 did not donate enough to receive a fiscal report. Contributor 3 only contributed the year before.
        Only contributors 1 and 2 should be included
        """

        # just to make sure: no reports are present in the database yet
        indiv_reports = IndividualFiscalReport.objects.filter(year=self.reference_date.year)
        self.assertEqual(len(indiv_reports), 0)
        report = FiscalReport.getReportingValues(year=self.reference_date.year)
        indiv_reports = IndividualFiscalReport.objects.filter(year=self.reference_date.year)
        self.assertEqual(len(indiv_reports), 2)
    def _load_contributors(self):
        """
        LOAD CONTRIBUTORS
        :return: Nothing. Happens in place
        """
        newsletter_map = {
            'WAAR': True,
            'TRUE': True,
            '1': True,
            'ONWAAR': False,
            'FALSE': False,
            '0': False
        }
        payment_frequency_map = {
            '0': 'sporadic',
            '31': 'every month',
            '92': 'every 3 months',
            '183': 'every 6 months',
            '365': 'every year',

        }
        active_map = {
            'WAAR': True,
            'ONWAAR': False,
            'True': True,
            'False': False,
            True: True,
            False: False,
            '0.0': False
        }
        def getShortenedStreet(x):
            l = 31 - len(str(x['bus'])) - len(str(x['street_number'])) - 2
            return x['street_complete'][0:l]

        self.stdout.write('\nloading contributors')
        self.contributors_data['first_name'].fillna('', inplace=True)
        self.contributors_data['first_name_complete'] = self.contributors_data['first_name']
        self.contributors_data['first_name'] = self.contributors_data['first_name_complete'].str.slice(0, 15)
        self.contributors_data['first_name_complete'] = self.contributors_data['first_name_complete'].str.encode('utf-8')
        self.contributors_data['first_name'] = self.contributors_data['first_name'].str.encode('utf-8')

        # Replace a couple of individual issues in the first name
        #     The issue is: the special character is present right at the 15 character limit. In Unicode, this is only 1
        #     character, but in utf-8, those are encoded as two characters. So if we slice the first name on the unicode
        #     name, the encoded name can still be longer than 15 characters
        for replace_tuple in settings.FIRST_NAMES_REPLACE:
            self.contributors_data['first_name'] = self.contributors_data['first_name'].str.replace(replace_tuple[0], replace_tuple[1])
        ## END OF INDIVIDUAL REPLACEMENTS

        self.contributors_data['partner_first_name'] = ''
        self.contributors_data['surname'].fillna('', inplace=True)
        self.contributors_data['surname_complete'] = self.contributors_data['surname']
        self.contributors_data['surname'] = self.contributors_data['surname_complete'].str.slice(0, 41)
        self.contributors_data['surname'] = self.contributors_data['surname'].str.encode('utf-8')
        self.contributors_data['surname_complete'] = self.contributors_data['surname_complete'].str.encode('utf-8')
        self.contributors_data['partner_surname'] = ''
        self.contributors_data['company_name'].fillna('', inplace=True)
        self.contributors_data['company_name_complete'] = self.contributors_data['company_name']
        self.contributors_data['company_name'] = self.contributors_data['company_name_complete'].str.slice(0, 41)
        self.contributors_data['company_name'] = self.contributors_data['company_name'].str.encode('utf-8')
        self.contributors_data['company_name_complete'] = self.contributors_data['company_name_complete'].str.encode('utf-8')
        self.contributors_data['email'].fillna('', inplace=True)
        self.contributors_data['email'] = self.contributors_data['email'].str.strip().str.encode('utf-8')
        self.contributors_data['bus'] = ''
        self.contributors_data['street_number'] = ''
        self.contributors_data['street'].fillna('-', inplace=True)  # TODO should have a real street
        self.contributors_data['street_complete'] = self.contributors_data['street'].str.encode('utf-8')
        self.contributors_data['street'] = self.contributors_data.apply(getShortenedStreet, axis=1)
        self.contributors_data['city_complete'] = self.contributors_data['city'].str.encode('utf-8')
        city_split = self.contributors_data['city_complete'].str.extract('^([0-9]+) *(.*)')
        city_split.columns = ['zip', 'city']
        self.contributors_data['zip_code'] = city_split['zip']
        self.contributors_data['zip_code'].fillna('-', inplace=True)  # fill again to prevent errors
        self.contributors_data['city_complete'] = city_split['city']
        self.contributors_data['city'] = self.contributors_data['city_complete'].str.slice(0, 27)
        self.contributors_data['city'].fillna('-', inplace=True)  # fill again to prevent errors
        self.contributors_data['phone'].fillna('', inplace=True)
        self.contributors_data['referred_by'].fillna('', inplace=True)
        self.contributors_data['comment'].fillna('', inplace=True)
        self.contributors_data['aard_van_de_schenker'] = 'np'
        self.contributors_data['payment_frequency'].fillna(0, inplace=True)
        self.contributors_data['payment_frequency'] = self.contributors_data['payment_frequency'].astype(int).astype(str)
        self.contributors_data['payment_frequency'] = self.contributors_data['payment_frequency'].apply(lambda x: payment_frequency_map[x])
        self.contributors_data['newsletter'].fillna('WAAR', inplace=True)
        self.contributors_data['newsletter'] = self.contributors_data['newsletter'].apply(lambda x: newsletter_map[x])
        self.contributors_data['active'].fillna('WAAR', inplace=True)
        self.contributors_data['active'] = self.contributors_data['active'].apply(lambda x: active_map[x])
        self.contributors_data['language'] = 'nl'
        self.contributors_data.drop('first_paid_date', axis=1, inplace=True)
        self.contributors_data.drop('child_received_date', axis=1, inplace=True)

        failing_contributors = {}
        self.contributor_lookup = {}
        for contributor_data in self.contributors_data.to_dict(orient='records'):
            self.stdout.write('.', ending="")
            self.stdout.flush()
            contrib_id = contributor_data['old_contributor_id']
            del contributor_data['old_contributor_id']
            contributor = Contributor(**contributor_data)
            try:
                contributor.full_clean()
                contributor.save()
                self.contributor_lookup[contrib_id] = contributor
            except ValidationError as e:
                failing_contributors[contributor_data['old_contributor_number']] = [e, contributor_data]
        if failing_contributors:
            print('Contributors failed validation:\n{0}'.format(pprint.pformat(failing_contributors, indent=4)))