def setUp(self):
     super().setUp()
     test_users = make_test_users()
     self.security_staff = test_users['security_staff']
     load_random_prisoner_locations()
     generate_payments(payment_batch=200, days_of_history=3)
     generate_disbursements(disbursement_batch=200, days_of_history=3)
    def test_get_events(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)
        user = self.security_staff[0]

        for credit in Credit.objects.all():
            if RULES['HA'].triggered(credit):
                RULES['HA'].create_event(credit)
        for disbursement in Disbursement.objects.filter(resolution=DISBURSEMENT_RESOLUTION.SENT):
            if RULES['HA'].triggered(disbursement):
                RULES['HA'].create_event(disbursement)

        response = self.client.get(
            reverse('event-list'), format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(user)
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertGreater(response.data['count'], 0)

        triggering_credits = Credit.objects.filter(
            amount__gte=12000,
        )
        triggering_disbursements = Disbursement.objects.filter(
            amount__gte=12000, resolution=DISBURSEMENT_RESOLUTION.SENT
        )
        self.assertEqual(
            response.data['count'],
            triggering_credits.count() + triggering_disbursements.count()
        )
    def test_get_events_grouped_by_profile_and_filtered(self):
        generate_payments(payment_batch=200, days_of_history=5)
        call_command('update_security_profiles')
        user = self.security_staff[0]

        lt = timezone.now() - timedelta(days=2)
        gte = lt - timedelta(days=3)
        response = self.client.get(
            reverse('event-list'),
            {'rule': 'CSFREQ', 'group_by': 'sender_profile',
             'triggered_at__lt': lt, 'triggered_at__gte': gte},
            format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(user)
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertGreater(response.data['count'], 0)

        latest = {}
        for event in Event.objects.filter(
            rule='CSFREQ', triggered_at__gte=gte, triggered_at__lt=lt
        ):
            profile_id = event.sender_profile_event.sender_profile.id
            if profile_id not in latest:
                latest[profile_id] = event
            else:
                if latest[profile_id].triggered_at < event.triggered_at:
                    latest[profile_id] = event

        latest_ids = [e.id for e in latest.values()]
        self.assertEqual(response.data['count'], len(latest_ids))
        for event in response.data['results']:
            if event['id'] not in latest_ids:
                self.fail()
    def setUp(self):
        super().setUp()
        self.users = make_test_users(clerks_per_prison=1)
        prisoner_locations = load_random_prisoner_locations(number_of_prisoners=1)
        generate_payments(payment_batch=1)
        prisoner_profiles = generate_prisoner_profiles_from_prisoner_locations(prisoner_locations)
        sender_profiles = generate_sender_profiles_from_payments(number_of_senders=1, reassign_dcsd=True)
        prisoner_profiles[0].monitoring_users.add(self.users['security_fiu_users'][0].id)
        sender_profiles[0].debit_card_details.first().monitoring_users.add(self.users['security_fiu_users'][0].id)

        response = self.client.post(
            reverse(
                'security-check-auto-accept-list'
            ),
            data={
                'prisoner_profile_id': prisoner_profiles[0].id,
                'debit_card_sender_details_id': sender_profiles[0].debit_card_details.first().id,
                'states': [
                    {
                        'reason': 'This person has amazing hair',
                    }
                ]
            },
            format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(self.users['security_fiu_users'][0]),
        )
        self.assertEqual(response.status_code, 201)
        self.auto_accept_rule = CheckAutoAcceptRule.objects.get(id=response.json()['id'])
    def test_cannot_accept_check_with_rejection_reason(self):
        # Setup
        users = make_test_users(clerks_per_prison=1)
        prisoner_locations = load_random_prisoner_locations()
        generate_payments(payment_batch=50)
        generate_prisoner_profiles_from_prisoner_locations(prisoner_locations)
        generate_sender_profiles_from_payments(number_of_senders=1, reassign_dcsd=True)
        generate_checks(number_of_checks=1, create_invalid_checks=False, overrides={'status': 'pending'})
        check = Check.objects.filter(status='pending').first()

        # Execute
        response = self.client.post(
            reverse('security-check-accept', kwargs={'pk': check.id}),
            {
                'decision_reason': 'computer says no',
                'rejection_reasons': {
                    'payment_source_linked_other_prisoners': True,
                }
            },
            format='json', HTTP_AUTHORIZATION=self.get_http_authorization_for_user(users['security_fiu_users'][0])
        )

        # Assert Response
        self.assertEqual(response.status_code, 400)
        self.assertEqual(
            response.json(),
            {'non_field_errors': ['You cannot give rejection reasons when accepting a check']}
        )

        # Assert Lack of State Change
        check.refresh_from_db()
        self.assertEqual(check.status, 'pending')
        self.assertEqual(check.rejection_reasons, {})
        self.assertEqual(check.decision_reason, '')
    def test_filter_by_last_week_credit_count(self):
        generate_transactions(transaction_batch=300, days_of_history=30)
        generate_payments(payment_batch=300, days_of_history=30)
        call_command('update_security_profiles')

        minimum_credit_count = 3

        data = self._get_list(
            self._get_authorised_user(),
            totals__time_period=TIME_PERIOD.LAST_7_DAYS,
            credit_count__gte=minimum_credit_count,
        )

        self.assertEqual(
            SenderProfile.objects.filter(
                totals__time_period=TIME_PERIOD.LAST_7_DAYS,
                totals__credit_count__gte=minimum_credit_count
            ).count(),
            data['count']
        )

        pks = [item['id'] for item in data['results']]
        for profile in SenderProfile.objects.filter(pk__in=pks):
            for totals in profile.totals.all():
                if totals.time_period == TIME_PERIOD.LAST_7_DAYS:
                    self.assertGreaterEqual(totals.credit_count, minimum_credit_count)

        for profile in SenderProfile.objects.exclude(pk__in=pks):
            for totals in profile.totals.all():
                if totals.time_period == TIME_PERIOD.LAST_7_DAYS:
                    self.assertLess(totals.credit_count, minimum_credit_count)
 def setUp(self):
     super().setUp()
     test_users = make_test_users()
     self.prison_clerks = test_users['prison_clerks']
     self.send_money_users = test_users['send_money_users']
     load_random_prisoner_locations(50)
     generate_payments(50, days_of_history=1)
    def test_get_events_filtered_by_date(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)
        user = self.security_staff[0]

        for credit in Credit.objects.all():
            if RULES['HA'].triggered(credit):
                RULES['HA'].create_event(credit)
        for disbursement in Disbursement.objects.filter(resolution=DISBURSEMENT_RESOLUTION.SENT):
            if RULES['HA'].triggered(disbursement):
                RULES['HA'].create_event(disbursement)

        lt = timezone.now()
        gte = lt - timedelta(days=2)
        response = self.client.get(
            reverse('event-list'),
            {'triggered_at__lt': lt, 'triggered_at__gte': gte},
            format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(user)
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertGreater(response.data['count'], 0)

        self.assertEqual(
            response.data['count'],
            Event.objects.filter(triggered_at__gte=gte, triggered_at__lt=lt).count()
        )
示例#9
0
 def make_2days_of_random_models(self):
     test_users = make_test_users()
     load_random_prisoner_locations()
     generate_payments(payment_batch=20, days_of_history=2)
     while not Disbursement.objects.sent().exists():
         generate_disbursements(disbursement_batch=20, days_of_history=2)
     return test_users['security_staff']
 def setUp(self):
     super().setUp()
     test_users = make_test_users()
     self.prison_clerks = test_users['prison_clerks']
     self.send_money_users = test_users['send_money_users']
     load_random_prisoner_locations(50)
     generate_payments(50, days_of_history=1)
    def test_update_security_profiles_subsequent_bank_transfer(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update = SenderProfile.objects.filter(
            bank_transfer_details__isnull=False,
            prisoners__isnull=False
        ).first()
        bank_details = sender_to_update.bank_transfer_details.first()
        prisoner_to_update = sender_to_update.prisoners.first()

        initial_sender_credit_count = sender_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_count
        initial_sender_credit_total = sender_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_total
        initial_prisoner_credit_count = prisoner_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_count
        initial_prisoner_credit_total = prisoner_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_total

        new_transactions = generate_initial_transactions_data(
            tot=1, include_debits=False,
            include_administrative_credits=False,
            include_unidentified_credits=False, days_of_history=0
        )

        new_transactions[0]['received_at'] = timezone.now()

        new_transactions[0]['sender_name'] = bank_details.sender_name
        new_transactions[0]['sender_sort_code'] = bank_details.sender_bank_account.sort_code
        new_transactions[0]['sender_account_number'] = bank_details.sender_bank_account.account_number
        new_transactions[0]['sender_roll_number'] = bank_details.sender_bank_account.roll_number

        new_transactions[0]['prisoner_number'] = prisoner_to_update.prisoner_number
        new_transactions[0]['prisoner_dob'] = prisoner_to_update.prisoner_dob

        create_transactions(new_transactions)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update.refresh_from_db()
        self.assertEqual(
            sender_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_count,
            initial_sender_credit_count + 1
        )
        self.assertEqual(
            sender_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_total,
            initial_sender_credit_total + new_transactions[0]['amount']
        )

        prisoner_to_update.refresh_from_db()
        self.assertEqual(
            prisoner_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_count,
            initial_prisoner_credit_count + 1
        )
        self.assertEqual(
            prisoner_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_total,
            initial_prisoner_credit_total + new_transactions[0]['amount']
        )
示例#12
0
    def test_update_security_profiles_subsequent_card_payment(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update = SenderProfile.objects.filter(
            debit_card_details__isnull=False, prisoners__isnull=False).first()
        card_details = sender_to_update.debit_card_details.first()
        prisoner_to_update = sender_to_update.prisoners.first()

        initial_sender_credit_count = sender_to_update.credit_count
        initial_sender_credit_total = sender_to_update.credit_total
        initial_sender_cardholder_names = list(
            card_details.cardholder_names.values_list('name', flat=True))
        initial_sender_emails = list(
            card_details.sender_emails.values_list('email', flat=True))
        initial_prisoner_credit_count = prisoner_to_update.credit_count
        initial_prisoner_credit_total = prisoner_to_update.credit_total

        new_payments = generate_initial_payment_data(tot=1, days_of_history=0)

        new_payments[0]['created'] = timezone.now()

        new_payments[0]['email'] = '*****@*****.**'
        new_payments[0]['cardholder_name'] = 'other name'
        new_payments[0][
            'card_number_last_digits'] = card_details.card_number_last_digits
        new_payments[0]['card_expiry_date'] = card_details.card_expiry_date
        new_payments[0]['billing_address']['postcode'] = card_details.postcode

        new_payments[0]['prisoner_number'] = prisoner_to_update.prisoner_number
        new_payments[0]['prisoner_dob'] = prisoner_to_update.prisoner_dob

        create_payments(new_payments, overrides={'credited': True})
        call_command('update_security_profiles', verbosity=0)

        sender_to_update.refresh_from_db()
        self.assertEqual(sender_to_update.credit_count,
                         initial_sender_credit_count + 1)
        self.assertEqual(
            sender_to_update.credit_total,
            initial_sender_credit_total + new_payments[0]['amount'])
        card_details.refresh_from_db()
        self.assertEqual(
            sorted(card_details.cardholder_names.values_list('name',
                                                             flat=True)),
            sorted(initial_sender_cardholder_names + ['other name']))
        self.assertEqual(
            sorted(card_details.sender_emails.values_list('email', flat=True)),
            sorted(initial_sender_emails + ['*****@*****.**']))

        prisoner_to_update.refresh_from_db()
        self.assertEqual(prisoner_to_update.credit_count,
                         initial_prisoner_credit_count + 1)
        self.assertEqual(
            prisoner_to_update.credit_total,
            initial_prisoner_credit_total + new_payments[0]['amount'])
    def test_will_not_check_non_initial_credits(self):
        make_test_users(clerks_per_prison=1)
        load_random_prisoner_locations(number_of_prisoners=1)
        generate_payments()

        for credit in Credit.objects.credit_pending():
            self.assertFalse(credit.should_check())
        for credit in Credit.objects.credited():
            self.assertFalse(credit.should_check())
    def test_update_security_profiles_subsequent_disbursement(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        recipient_to_update = RecipientProfile.objects.filter(
            bank_transfer_details__isnull=False,
            prisoners__isnull=False
        ).first()
        bank_details = recipient_to_update.bank_transfer_details.first()
        prisoner_to_update = recipient_to_update.prisoners.first()

        initial_recipient_disbursement_count = recipient_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).disbursement_count
        initial_recipient_disbursement_total = recipient_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).disbursement_total
        initial_prisoner_disbursement_count = prisoner_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).disbursement_count
        initial_prisoner_disbursement_total = prisoner_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).disbursement_total

        new_disbursements = generate_initial_disbursement_data(
            tot=1, days_of_history=0
        )

        new_disbursements[0]['method'] = DISBURSEMENT_METHOD.BANK_TRANSFER
        new_disbursements[0]['sort_code'] = bank_details.recipient_bank_account.sort_code
        new_disbursements[0]['account_number'] = bank_details.recipient_bank_account.account_number
        new_disbursements[0]['roll_number'] = bank_details.recipient_bank_account.roll_number

        new_disbursements[0]['prisoner_number'] = prisoner_to_update.prisoner_number
        new_disbursements[0]['prisoner_name'] = prisoner_to_update.prisoner_name
        new_disbursements[0]['resolution'] = DISBURSEMENT_RESOLUTION.SENT

        create_disbursements(new_disbursements)
        call_command('update_security_profiles', verbosity=0)

        recipient_to_update.refresh_from_db()
        self.assertEqual(
            recipient_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_count,
            initial_recipient_disbursement_count + 1
        )
        self.assertEqual(
            recipient_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_total,
            initial_recipient_disbursement_total + new_disbursements[0]['amount']
        )

        prisoner_to_update.refresh_from_db()
        self.assertEqual(
            prisoner_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_count,
            initial_prisoner_disbursement_count + 1
        )
        self.assertEqual(
            prisoner_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_total,
            initial_prisoner_disbursement_total + new_disbursements[0]['amount']
        )
示例#15
0
 def setUp(self):
     super().setUp()
     test_users = make_test_users()
     self.prison_clerks = test_users['prison_clerks']
     self.security_staff = test_users['security_staff']
     load_random_prisoner_locations()
     generate_transactions(transaction_batch=100, days_of_history=5)
     generate_payments(payment_batch=100, days_of_history=5)
     call_command('update_security_profiles')
 def setUp(self):
     super().setUp()
     test_users = make_test_users()
     self.prison_clerks = test_users['prison_clerks']
     self.security_staff = test_users['security_staff']
     load_random_prisoner_locations()
     generate_transactions(transaction_batch=100, days_of_history=5)
     generate_payments(payment_batch=100, days_of_history=5)
     generate_disbursements(disbursement_batch=150, days_of_history=5)
     call_command('update_security_profiles')
 def test_will_not_check_non_pending_payments(self):
     make_test_users(clerks_per_prison=1)
     load_random_prisoner_locations(number_of_prisoners=1)
     generate_payments(10)
     credit = Credit.objects.credited().first()
     credit.owner = None
     credit.resolution = CREDIT_RESOLUTION.INITIAL
     credit.payment.status = PAYMENT_STATUS.FAILED
     credit.save()
     self.assertFalse(credit.should_check())
    def test_debit_card_and_bank_transfer_data_included_in_export(self):
        self.basic_setup()
        generate_transactions(transaction_batch=1)
        generate_payments(payment_batch=1)

        with tempfile.NamedTemporaryFile() as export_file:
            call_command('dump_for_ap', 'credits', export_file.name)
            jsonlines = open(export_file.name).read()

        self.assertIn('"Payment method": "Bank transfer"', jsonlines)
        self.assertIn('"Payment method": "Debit card"', jsonlines)
 def _make_candidate_credit(self):
     make_test_users(clerks_per_prison=1)
     load_random_prisoner_locations(number_of_prisoners=1)
     generate_payments(10)
     call_command('update_security_profiles')
     credit = Credit.objects.credited().first()
     credit.owner = None
     credit.resolution = CREDIT_RESOLUTION.INITIAL
     payment = credit.payment
     payment.status = PAYMENT_STATUS.PENDING
     credit.log_set.filter(action=CREDIT_LOG_ACTIONS.CREDITED).delete()
     return credit
示例#20
0
 def setUp(self):
     super().setUp()
     test_users = make_test_users()
     self.security_staff = test_users['security_staff']
     load_random_prisoner_locations()
     generate_payments(payment_batch=20,
                       days_of_history=2,
                       overrides={
                           'status': PAYMENT_STATUS.TAKEN,
                           'credited': True
                       })
     generate_disbursements(disbursement_batch=20, days_of_history=1)
示例#21
0
    def test_update_security_profiles_subsequent_bank_transfer(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update = SenderProfile.objects.filter(
            bank_transfer_details__isnull=False,
            prisoners__isnull=False
        ).first()
        bank_details = sender_to_update.bank_transfer_details.first()
        prisoner_to_update = sender_to_update.prisoners.first()

        initial_sender_credit_count = sender_to_update.credit_count
        initial_sender_credit_total = sender_to_update.credit_total
        initial_prisoner_credit_count = prisoner_to_update.credit_count
        initial_prisoner_credit_total = prisoner_to_update.credit_total

        new_transactions = generate_initial_transactions_data(
            tot=1, include_debits=False,
            include_administrative_credits=False,
            include_unidentified_credits=False, days_of_history=0
        )

        new_transactions[0]['received_at'] = timezone.now()

        new_transactions[0]['sender_name'] = bank_details.sender_name
        new_transactions[0]['sender_sort_code'] = bank_details.sender_bank_account.sort_code
        new_transactions[0]['sender_account_number'] = bank_details.sender_bank_account.account_number
        new_transactions[0]['sender_roll_number'] = bank_details.sender_bank_account.roll_number

        new_transactions[0]['prisoner_number'] = prisoner_to_update.prisoner_number
        new_transactions[0]['prisoner_dob'] = prisoner_to_update.prisoner_dob

        create_transactions(new_transactions)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update.refresh_from_db()
        self.assertEqual(
            sender_to_update.credit_count, initial_sender_credit_count + 1
        )
        self.assertEqual(
            sender_to_update.credit_total,
            initial_sender_credit_total + new_transactions[0]['amount']
        )

        prisoner_to_update.refresh_from_db()
        self.assertEqual(
            prisoner_to_update.credit_count, initial_prisoner_credit_count + 1
        )
        self.assertEqual(
            prisoner_to_update.credit_total,
            initial_prisoner_credit_total + new_transactions[0]['amount']
        )
示例#22
0
    def test_update_security_profiles_subsequent_disbursement(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        recipient_to_update = RecipientProfile.objects.filter(
            bank_transfer_details__isnull=False,
            prisoners__isnull=False
        ).first()
        bank_details = recipient_to_update.bank_transfer_details.first()
        prisoner_to_update = recipient_to_update.prisoners.first()

        initial_recipient_disbursement_count = recipient_to_update.disbursement_count
        initial_recipient_disbursement_total = recipient_to_update.disbursement_total
        initial_prisoner_disbursement_count = prisoner_to_update.disbursement_count
        initial_prisoner_disbursement_total = prisoner_to_update.disbursement_total

        new_disbursements = generate_initial_disbursement_data(
            tot=1, days_of_history=0
        )

        new_disbursements[0]['method'] = DISBURSEMENT_METHOD.BANK_TRANSFER
        new_disbursements[0]['sort_code'] = bank_details.recipient_bank_account.sort_code
        new_disbursements[0]['account_number'] = bank_details.recipient_bank_account.account_number
        new_disbursements[0]['roll_number'] = bank_details.recipient_bank_account.roll_number

        new_disbursements[0]['prisoner_number'] = prisoner_to_update.prisoner_number
        new_disbursements[0]['prisoner_name'] = prisoner_to_update.prisoner_name

        create_disbursements(new_disbursements)
        call_command('update_security_profiles', verbosity=0)

        recipient_to_update.refresh_from_db()
        self.assertEqual(
            recipient_to_update.disbursement_count,
            initial_recipient_disbursement_count + 1
        )
        self.assertEqual(
            recipient_to_update.disbursement_total,
            initial_recipient_disbursement_total + new_disbursements[0]['amount']
        )

        prisoner_to_update.refresh_from_db()
        self.assertEqual(
            prisoner_to_update.disbursement_count,
            initial_prisoner_disbursement_count + 1
        )
        self.assertEqual(
            prisoner_to_update.disbursement_total,
            initial_prisoner_disbursement_total + new_disbursements[0]['amount']
        )
    def test_update_security_profiles_initial(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        for sender_profile in SenderProfile.objects.all():
            SenderTotals.objects.filter(sender_profile=sender_profile).update_all_totals()
            self.assertEqual(
                len(sender_profile.credits.all()),
                sender_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_count
            )
            self.assertEqual(
                sum([credit.amount for credit in sender_profile.credits.all()]),
                sender_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_total
            )

        for recipient_profile in RecipientProfile.objects.filter(
            bank_transfer_details__isnull=False
        ):
            self.assertEqual(
                sum([disbursement.amount for disbursement in recipient_profile.disbursements.all()]),
                recipient_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_total
            )
            self.assertEqual(
                len(recipient_profile.disbursements.all()),
                recipient_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_count
            )

        for prisoner_profile in PrisonerProfile.objects.all():
            if prisoner_profile.credits.count():
                self.assertTrue(prisoner_profile.single_offender_id)

            self.assertEqual(
                sum([credit.amount for credit in prisoner_profile.credits.all()]),
                prisoner_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_total
            )
            self.assertEqual(
                len(prisoner_profile.credits.all()),
                prisoner_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_count
            )

            self.assertEqual(
                sum([disbursement.amount for disbursement in prisoner_profile.disbursements.all()]),
                prisoner_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_total
            )
            self.assertEqual(
                len(prisoner_profile.disbursements.all()),
                prisoner_profile.totals.get(time_period=TIME_PERIOD.ALL_TIME).disbursement_count
            )
示例#24
0
    def setUp(self):
        super().setUp()
        test_users = make_test_users()
        self.user = test_users['security_staff'][0]
        load_random_prisoner_locations()
        # generate random data which may or may not match amount rules
        generate_transactions(transaction_batch=200, days_of_history=3)
        generate_payments(payment_batch=200, days_of_history=3)
        generate_disbursements(disbursement_batch=200, days_of_history=3)

        # £1 does not match NWN or HA rules and no monitoring exists, i.e. no non-counting rules can trigger
        Payment.objects.update(amount=100)
        Transaction.objects.update(amount=100)
        Credit.objects.update(amount=100)
        Disbursement.objects.update(amount=100)
    def setUp(self):
        super().setUp()

        self.private_prison = mommy.make(Prison, name='Private', private_estate=True)
        self.private_bank_account = mommy.make(PrisonBankAccount, prison=self.private_prison)

        test_users = make_test_users(clerks_per_prison=2)
        self.prison_clerks = test_users['prison_clerks']
        self.bank_admins = test_users['bank_admins']
        load_random_prisoner_locations()

        transaction_credits = [
            t.credit for t in generate_transactions(transaction_batch=20, days_of_history=4)
            if t.credit
        ]
        payment_credits = [
            p.credit for p in generate_payments(payment_batch=20, days_of_history=4)
            if p.credit and p.credit.resolution != 'initial'
        ]
        self.credits = transaction_credits + payment_credits
        self.prisons = Prison.objects.all()

        self.latest_date = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
        date = Credit.objects.earliest().received_at.replace(hour=0, minute=0, second=0, microsecond=0)
        while date < self.latest_date:
            end_of_date = date + datetime.timedelta(days=1)
            PrivateEstateBatch.objects.create_batches(date, end_of_date)
            date = end_of_date
    def test_get_batch(self):
        user = self.bank_admins[0]

        batch = Batch(date=date(2016, 3, 3))
        batch.save()

        other_batch = Batch(date=date(2016, 3, 4))
        other_batch.save()

        for i, payment in enumerate(generate_payments(50, days_of_history=1)):
            if i % 2:
                payment.batch = batch
            else:
                payment.batch = other_batch
            payment.save()

        response = self.client.get(
            reverse('batch-list'), {'date': date(2016, 3, 3)}, format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(user)
        )

        batches = response.data['results']
        self.assertEqual(len(batches), 1)
        self.assertEqual(batches[0]['id'], batch.id)
        self.assertEqual(batches[0]['date'], batch.date.isoformat())
        self.assertEqual(batches[0]['payment_amount'], batch.payment_amount)
示例#27
0
    def test_update_prisoner_profiles(self):
        payments = generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        valid_payments = filter(lambda payment: payment.status == PAYMENT_STATUS.TAKEN and payment.credit.prison,
                                payments)
        prisoner_numbers = set(payment.prisoner_number for payment in valid_payments)
        self.assertEqual(PrisonerProfile.objects.all().count(), len(prisoner_numbers))

        sender_profile = SenderProfile.objects.filter(
            debit_card_details__isnull=False,
            prisoners__isnull=False,
        ).first()
        debit_card_details = sender_profile.debit_card_details.first()
        prisoner_profile = PrisonerProfile.objects.first()

        new_payments = generate_initial_payment_data(tot=1, days_of_history=0)

        new_payments[0]['created'] = timezone.now()

        new_payments[0]['email'] = '*****@*****.**'
        new_payments[0]['cardholder_name'] = 'other name'
        new_payments[0]['card_number_last_digits'] = debit_card_details.card_number_last_digits
        new_payments[0]['card_expiry_date'] = debit_card_details.card_expiry_date
        new_payments[0]['recipient_name'] = 'Mr. John Doe'

        new_payments[0]['prisoner_number'] = prisoner_profile.prisoner_number
        new_payments[0]['prisoner_dob'] = prisoner_profile.prisoner_dob

        create_payments(new_payments)
        call_command('update_security_profiles', verbosity=0)

        prisoner_profile.refresh_from_db()
        recipient_names = list(recipient_name.name for recipient_name in prisoner_profile.provided_names.all())
        self.assertEqual(recipient_names[-1], 'Mr. John Doe')
    def test_payment_for_pair_with_inactive_auto_accept_caught_by_delayed_capture(self):
        self.client.patch(
            reverse(
                'security-check-auto-accept-detail',
                args=[self.auto_accept_rule.id]
            ),
            data={
                'states': [
                    {
                        'active': False,
                        'reason': 'Ignore that they cut off their hair',
                    }
                ]
            },
            format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(self.users['security_fiu_users'][0]),
        )
        payments = generate_payments(
            payment_batch=1,
            overrides={
                'credit': {
                    'prisoner_profile_id': self.auto_accept_rule.prisoner_profile_id,
                    'sender_profile_id': self.auto_accept_rule.debit_card_sender_details.sender.id
                }
            }
        )
        credit = payments[0].credit

        # Call
        check = Check.objects.create_for_credit(credit)

        # Assert
        self.assertEqual(check.auto_accept_rule_state, None)
        self.assertEqual(check.rules, ['FIUMONP', 'FIUMONS'])
        self.assertEqual(check.status, CHECK_STATUS.PENDING)
    def test_get_batch(self):
        user = self.bank_admins[0]

        batch = Batch(date=date(2016, 3, 3))
        batch.save()

        other_batch = Batch(date=date(2016, 3, 4))
        other_batch.save()

        for i, payment in enumerate(generate_payments(50, days_of_history=1)):
            if i % 2:
                payment.batch = batch
            else:
                payment.batch = other_batch
            payment.save()

        response = self.client.get(
            reverse('batch-list'), {'date': date(2016, 3, 3)},
            format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization_for_user(user))

        batches = response.data['results']
        self.assertEqual(len(batches), 1)
        self.assertEqual(batches[0]['id'], batch.id)
        self.assertEqual(batches[0]['date'], batch.date.isoformat())
        self.assertEqual(batches[0]['payment_amount'], batch.payment_amount)
    def test_list_credits_for_prisoner_includes_not_completed(self):
        payments = generate_payments(
            10,
            days_of_history=1,
            overrides={'status': PAYMENT_STATUS.REJECTED})
        prisoner_profile_id = list(
            filter(lambda p: p.credit.prisoner_profile_id,
                   payments))[0].credit.prisoner_profile_id
        credits = Credit.objects_all.filter(
            prisoner_profile_id=prisoner_profile_id)
        data = self._get_list(self._get_authorised_user(),
                              path_params=[prisoner_profile_id],
                              only_completed=False)['results']
        self.assertTrue(len(data) > 0)

        self.assertEqual(len(credits), len(data))
        for credit in credits:
            self.assertTrue(credit.id in [d['id'] for d in data])

        self.assertTrue(
            any([
                d['resolution']
                in (CREDIT_RESOLUTION.FAILED, CREDIT_RESOLUTION.INITIAL)
                for d in data
            ]))
    def setUp(self):
        super().setUp()

        test_users = make_test_users(clerks_per_prison=2)
        self.prison_clerks = test_users['prison_clerks']
        self.prisoner_location_admins = test_users['prisoner_location_admins']
        self.bank_admins = test_users['bank_admins']
        self.refund_bank_admins = test_users['refund_bank_admins']
        self.send_money_users = test_users['send_money_users']
        self.security_staff = test_users['security_staff']

        self.latest_transaction_date = latest_transaction_date()
        self.latest_payment_date = latest_payment_date()
        load_random_prisoner_locations()
        transaction_credits = [
            t.credit for t in generate_transactions(
                transaction_batch=self.transaction_batch, days_of_history=5)
            if t.credit
        ]
        payment_credits = [
            p.credit
            for p in generate_payments(payment_batch=self.transaction_batch,
                                       days_of_history=5)
            if p.credit and p.credit.resolution != 'initial'
        ]
        self.credits = transaction_credits + payment_credits
        self.prisons = Prison.objects.all()
    def test_update_prisoner_profiles(self):
        payments = generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        valid_payments = filter(lambda payment: payment.status == PAYMENT_STATUS.TAKEN and payment.credit.prison,
                                payments)
        prisoner_numbers = set(payment.prisoner_number for payment in valid_payments)
        self.assertEqual(PrisonerProfile.objects.all().count(), len(prisoner_numbers))

        sender_profile = SenderProfile.objects.filter(
            debit_card_details__isnull=False,
            prisoners__isnull=False,
        ).first()
        debit_card_details = sender_profile.debit_card_details.first()
        prisoner_profile = PrisonerProfile.objects.first()

        new_payments = generate_initial_payment_data(tot=1, days_of_history=0)

        new_payments[0]['created'] = timezone.now()

        new_payments[0]['email'] = '*****@*****.**'
        new_payments[0]['cardholder_name'] = 'other name'
        new_payments[0]['card_number_last_digits'] = debit_card_details.card_number_last_digits
        new_payments[0]['card_expiry_date'] = debit_card_details.card_expiry_date
        new_payments[0]['recipient_name'] = 'Mr. John Doe'

        new_payments[0]['prisoner_number'] = prisoner_profile.prisoner_number
        new_payments[0]['prisoner_dob'] = prisoner_profile.prisoner_dob

        create_payments(new_payments)
        call_command('update_security_profiles', verbosity=0)

        prisoner_profile.refresh_from_db()
        recipient_names = list(recipient_name.name for recipient_name in prisoner_profile.provided_names.all())
        self.assertEqual(recipient_names[-1], 'Mr. John Doe')
    def test_update_current_prisons(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        def check_locations():
            for prisoner_profile in PrisonerProfile.objects.all():
                current_location = PrisonerLocation.objects.get(
                    prisoner_number=prisoner_profile.prisoner_number,
                    active=True
                )
                self.assertEqual(prisoner_profile.current_prison, current_location.prison)

        check_locations()

        for location in PrisonerLocation.objects.all():
            location.prison = Prison.objects.all().order_by('?').first()

        call_command('update_current_prisons')
        check_locations()
示例#34
0
    def test_update_current_prisons(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        def check_locations():
            for prisoner_profile in PrisonerProfile.objects.all():
                current_location = PrisonerLocation.objects.get(
                    prisoner_number=prisoner_profile.prisoner_number,
                    active=True
                )
                self.assertEqual(prisoner_profile.current_prison, current_location.prison)

        check_locations()

        for location in PrisonerLocation.objects.all():
            location.prison = Prison.objects.all().order_by('?').first()

        call_command('update_current_prisons')
        check_locations()
示例#35
0
    def test_update_security_profiles_initial(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        for sender_profile in SenderProfile.objects.all():
            credits = Credit.objects.filter(sender_profile.credit_filters)
            self.assertEqual(
                sum([credit.amount for credit in credits]),
                sender_profile.credit_total
            )
            self.assertEqual(len(credits), sender_profile.credit_count)

        for recipient_profile in RecipientProfile.objects.filter(
            bank_transfer_details__isnull=False
        ):
            disbursements = Disbursement.objects.filter(recipient_profile.disbursement_filters)
            self.assertEqual(
                sum([disbursement.amount for disbursement in disbursements]),
                recipient_profile.disbursement_total
            )
            self.assertEqual(len(disbursements), recipient_profile.disbursement_count)

        for prisoner_profile in PrisonerProfile.objects.all():
            if prisoner_profile.credits.count():
                self.assertTrue(prisoner_profile.single_offender_id)

            credits = Credit.objects.filter(prisoner_profile.credit_filters)
            self.assertEqual(
                sum([credit.amount for credit in credits]),
                prisoner_profile.credit_total
            )
            self.assertEqual(len(credits), prisoner_profile.credit_count)

            disbursements = Disbursement.objects.filter(prisoner_profile.disbursement_filters)
            self.assertEqual(
                sum([disbursement.amount for disbursement in disbursements]),
                prisoner_profile.disbursement_total
            )
            self.assertEqual(len(disbursements), prisoner_profile.disbursement_count)
    def test_credits_dump_for_ap(self):
        self.basic_setup()
        generate_payments(payment_batch=20, days_of_history=2)

        with tempfile.NamedTemporaryFile() as export_file:
            call_command('dump_for_ap', 'credits', export_file.name)
            jsonlines = open(export_file.name).read().splitlines()

            credit_ids = []
            for record in jsonlines:
                parsedjson = json.loads(record)
                credit_ids.append(parsedjson['Internal ID'])

        completed_payments = Payment.objects.exclude(status__in=(
            PAYMENT_STATUS.PENDING,
            PAYMENT_STATUS.REJECTED,
            PAYMENT_STATUS.EXPIRED,
        ))
        expected_credit_ids = sorted(payment.credit_id
                                     for payment in completed_payments)
        self.assertListEqual(credit_ids, expected_credit_ids)
    def setUp(self):
        super().setUp()

        self.private_prison = mommy.make(Prison,
                                         name='Private',
                                         private_estate=True)
        self.private_bank_account = mommy.make(PrisonBankAccount,
                                               prison=self.private_prison)

        test_users = make_test_users(clerks_per_prison=2)
        self.prison_clerks = test_users['prison_clerks']
        self.bank_admins = test_users['bank_admins']
        load_random_prisoner_locations()

        transaction_credits = [
            t.credit for t in generate_transactions(transaction_batch=20,
                                                    days_of_history=4)
            if t.credit
        ]
        payment_credits = [
            p.credit
            for p in generate_payments(payment_batch=20, days_of_history=4)
            if p.credit and p.credit.resolution != 'initial'
        ]
        self.credits = transaction_credits + payment_credits
        self.prisons = Prison.objects.all()

        creditable = Credit.STATUS_LOOKUP[
            CREDIT_STATUS.CREDITED] | Credit.STATUS_LOOKUP[
                CREDIT_STATUS.CREDIT_PENDING]
        private_estate_credit_set = Credit.objects.filter(
            prison__private_estate=True).filter(creditable)
        if not private_estate_credit_set.exists():
            public_estate_credits = Credit.objects.filter(
                prison__private_estate=False).filter(creditable)
            public_estate_credits[public_estate_credits.count() //
                                  2:].update(prison=self.private_prison)

        self.latest_date = timezone.now().replace(hour=0,
                                                  minute=0,
                                                  second=0,
                                                  microsecond=0)
        date = Credit.objects.earliest().received_at.replace(hour=0,
                                                             minute=0,
                                                             second=0,
                                                             microsecond=0)
        while date < self.latest_date:
            end_of_date = date + datetime.timedelta(days=1)
            PrivateEstateBatch.objects.create_batches(date, end_of_date)
            date = end_of_date
示例#38
0
    def test_profile_update_minimum_viable_data(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        generate_disbursements(disbursement_batch=100, days_of_history=5)

        delete_non_related_nullable_fields(Payment.objects.all(),
                                           null_fields_to_leave_populated=set([
                                               'email',
                                               'cardholder_name',
                                               'card_number_first_digits',
                                               'card_number_last_digits',
                                               'card_expiry_date',
                                               'billing_address',
                                           ]))
        delete_non_related_nullable_fields(Transaction.objects.all(),
                                           null_fields_to_leave_populated=set([
                                               'sender_name',
                                               'sender_sort_code',
                                               'sender_account_number'
                                           ]))
        delete_non_related_nullable_fields(
            Credit.objects.all(),
            null_fields_to_leave_populated=set([
                'prison',
                'prisoner_name',
                'prisoner_number',  # Needed to populate PrisonerProfile
            ]))
        delete_non_related_nullable_fields(
            Disbursement.objects.all(),
            null_fields_to_leave_populated=set([
                'sort_code',  # Needed to populate BankAccount
                'account_number'  # Needed to populate BankAccount
            ]))

        call_command('update_security_profiles', verbosity=0)

        self._assert_counts()
    def test_payment_for_pair_with_active_auto_accept_progresses_immediately(self):
        # Set up
        payments = generate_payments(
            payment_batch=1,
            overrides={
                'credit': {
                    'prisoner_profile_id': self.auto_accept_rule.prisoner_profile_id,
                    'sender_profile_id': self.auto_accept_rule.debit_card_sender_details.sender.id
                }
            }
        )
        credit = payments[0].credit

        # Call
        check = Check.objects.create_for_credit(credit)

        # Assert
        self.assertEqual(check.auto_accept_rule_state, self.auto_accept_rule.get_latest_state())
        self.assertEqual(check.rules, ['FIUMONP', 'FIUMONS'])
        self.assertEqual(check.status, CHECK_STATUS.ACCEPTED)
    def setUp(self):
        super().setUp()

        test_users = make_test_users(clerks_per_prison=2)
        self.prison_clerks = test_users['prison_clerks']
        self.prisoner_location_admins = test_users['prisoner_location_admins']
        self.bank_admins = test_users['bank_admins']
        self.refund_bank_admins = test_users['refund_bank_admins']
        self.send_money_users = test_users['send_money_users']
        self.security_staff = test_users['security_staff']

        self.latest_transaction_date = latest_transaction_date()
        self.latest_payment_date = latest_payment_date()
        load_random_prisoner_locations()
        transaction_credits = [t.credit for t in generate_transactions(
            transaction_batch=self.transaction_batch, days_of_history=5
        ) if t.credit]
        payment_credits = [p.credit for p in generate_payments(
            payment_batch=self.transaction_batch, days_of_history=5
        ) if p.credit and p.credit.resolution != 'initial']
        self.credits = transaction_credits + payment_credits
        self.prisons = Prison.objects.all()
    def test_payment_where_prisoner_not_on_auto_accept_caught_by_delayed_capture(self):
        prisoner_profile_id = PrisonerProfile.objects.exclude(
            id=self.auto_accept_rule.prisoner_profile_id
        ).first().id
        payments = generate_payments(
            payment_batch=1,
            overrides={
                'credit': {
                    'prisoner_profile_id': prisoner_profile_id,
                    'sender_profile_id': self.auto_accept_rule.debit_card_sender_details.sender.id
                }
            }
        )
        credit = payments[0].credit

        # Call
        check = Check.objects.create_for_credit(credit)

        # Assert
        self.assertEqual(check.auto_accept_rule_state, None)
        self.assertEqual(check.rules, ['FIUMONS'])
        self.assertEqual(check.status, CHECK_STATUS.PENDING)
def generate_checks(number_of_checks=1,
                    specific_payments_to_check=tuple(),
                    create_invalid_checks=True,
                    number_of_prisoners_to_use=5,
                    number_of_senders_to_use=5,
                    overrides=None):
    fake_prisoner_names = {
        pp_id[0]: fake.name()
        for pp_id in PrisonerProfile.objects.values_list('id')
    }
    fake_sender_names = {
        sp_id[0]: fake.name()
        for sp_id in SenderProfile.objects.values_list('id')
    }

    fiu = Group.objects.get(name='FIU').user_set.first()

    billing_address_sender_profile_id_mapping = {}

    if create_invalid_checks:
        filters = [PAYMENT_FILTERS_FOR_INVALID_CHECK]
    else:
        filters = []
    filters.extend([
        *([PAYMENT_FILTERS_FOR_VALID_CHECK] * number_of_checks),
        *specific_payments_to_check
    ])

    for j, filter_set in enumerate(filters):
        sender_profile, cardholder_name = _get_sender_profile(
            j, filter_set, number_of_senders_to_use, fake_sender_names,
            billing_address_sender_profile_id_mapping, fiu)
        filter_set = filter_set.copy()
        prisoner_profile, prisoner_name = _get_prisoner_profile(
            j, filter_set, number_of_prisoners_to_use, fake_prisoner_names,
            fiu)
        credit_filters = filter_set.pop('credit', {})
        candidate_payment = Payment.objects.filter(
            credit=Credit.objects.filter(**credit_filters).get_or_create(
                **_get_credit_values(
                    credit_filters, sender_profile.id if sender_profile else
                    None, prisoner_profile.id if prisoner_profile else None,
                    prisoner_name))[0],
            **filter_set).first()
        if not candidate_payment:
            candidate_payment = generate_payments(
                payment_batch=1,
                overrides=dict(credit=_get_credit_values(
                    credit_filters,
                    sender_profile.id if sender_profile else None,
                    prisoner_profile.id if prisoner_profile else None,
                    prisoner_name),
                               **_get_payment_values(filter_set,
                                                     cardholder_name)))[0]
            if sender_profile:
                candidate_payment.billing_address = billing_address_sender_profile_id_mapping.get(
                    sender_profile.id)
                # We ensure that the sender profile includes the cardholder name
                # In the test data there should only be one debit_card_details per sender_profile, we use get_or_create
                CardholderName.objects.get_or_create(
                    name=candidate_payment.cardholder_name,
                    debit_card_sender_details=sender_profile.
                    debit_card_details.first())
            candidate_payment.save()

        candidate_payment.credit.log_set.filter(
            action=CREDIT_LOG_ACTIONS.CREDITED).delete()
        # Checks already get created in the payment saving process for applicable credits
        # (see payment/models.py::create_security_check_if_needed_and_attach_profiles
        if not hasattr(candidate_payment.credit, 'security_check'):
            check = Check.objects.create_for_credit(candidate_payment.credit)
        else:
            check = candidate_payment.credit.security_check
            if (not overrides or 'state' not in overrides) and j % 5:
                check.status = random.choice(
                    [CHECK_STATUS.ACCEPTED, CHECK_STATUS.REJECTED])
                check.actioned_at = datetime.now(tz=pytz.utc)
                check.actioned_by = random.choice(
                    list(
                        Group.objects.filter(
                            name='FIU').first().user_set.all()))
                check.save()
        if overrides:
            for k, v in overrides.items():
                setattr(check, k, v)
            check.save()
    generate_auto_accept_rules()
    return Check.objects.all()
 def setUp(self):
     make_test_users(1)
     load_random_prisoner_locations(1)
     self.payments = generate_payments(self.payment_count, days_of_history=10)
示例#44
0
    def handle(self, *args, **options):  # noqa: C901
        if settings.ENVIRONMENT == 'prod':
            return self.handle_prod(**options)

        verbosity = options.get('verbosity', 1)
        no_protect_superusers = options['no_protect_superusers']
        protect_usernames = options['protect_usernames']
        protect_credits = options['protect_credits']
        prisons = options['prisons']
        prisoners = options['prisoners']
        number_of_prisoners = options['number_of_prisoners']
        number_of_senders = options['number_of_senders']
        clerks_per_prison = options['clerks_per_prison']
        credits = options['credits']
        number_of_transactions = options['number_of_transactions']
        number_of_payments = options['number_of_payments']
        number_of_disbursements = options['number_of_disbursements']
        number_of_checks = options['number_of_checks']
        days_of_history = options['days_of_history']
        extra_generate_checks_args = {}

        print_message = self.stdout.write if verbosity else lambda m: m

        if not protect_credits and credits != 'production-scale':
            print_message('Deleting all credits')
            Balance.objects.all().delete()
            Transaction.objects.all().delete()
            Payment.objects.all().delete()
            Credit.objects_all.all().delete()
            Batch.objects.all().delete()
            SenderProfile.objects.all().delete()
            PrisonerProfile.objects.all().delete()
            SavedSearch.objects.all().delete()
            Disbursement.objects.all().delete()
            RecipientProfile.objects.all().delete()
            Check.objects.all().delete()

        if credits == 'production-scale':
            # N.B. This scenario will eat your RAM like there's no tomorrow. ~13GB usage is
            # about as far as I've got before it's keeled over and i've had to rerun
            # If running it outside your development environment, be sure that it's not using the same
            # resource pool as a production service
            # If running it on your development environment you may need to tweak oom-killer so it
            # doesn't kill this process as soon as you near the memory limit of your system
            number_of_existing_transactions = Transaction.objects.count()
            number_of_existing_payments = Payment.objects.count()
            number_of_existing_prisoner_locations = PrisonerLocation.objects.count()
            number_of_existing_prisoners_profiles = PrisonerProfile.objects.count()
            number_of_existing_disbursements = Disbursement.objects.count()
            number_of_existing_checks = Check.objects.count()
            number_of_existing_senders = SenderProfile.objects.count()

            number_of_existing_prisoners = min(
                [number_of_existing_prisoner_locations, number_of_existing_prisoners_profiles]
            )

            number_of_desired_transactions = 300000
            number_of_desired_payments = 3000000
            number_of_desired_prisoners = 80000
            number_of_desired_senders = 700000
            number_of_desired_disbursements = 20000
            number_of_desired_checks = 900000

            number_of_prisoners = max(
                0, number_of_desired_prisoners - number_of_existing_prisoners
            )
            print_message(
                f'Number of prisoners to be created is {number_of_desired_prisoners} - {number_of_existing_prisoners}'
                f' <= {number_of_prisoners}'
            )
            number_of_transactions = max(
                0, number_of_desired_transactions - number_of_existing_transactions
            )
            print_message(
                f'Number of transactions to be created is {number_of_desired_transactions} - '
                f'{number_of_existing_transactions} <= {number_of_transactions}'
            )
            number_of_payments = max(
                0, number_of_desired_payments - number_of_existing_payments
            )
            print_message(
                f'Number of payments to be created is {number_of_desired_payments} - {number_of_existing_payments}'
                f' <= {number_of_payments}'
            )
            number_of_disbursements = max(
                0, number_of_desired_disbursements - number_of_existing_disbursements
            )
            print_message(
                f'Number of disbursements to be created is {number_of_desired_disbursements} - '
                f'{number_of_existing_disbursements} <= {number_of_disbursements}'
            )
            number_of_senders = max(
                0, number_of_desired_senders - number_of_existing_senders
            )
            print_message(
                f'Number of senders to be created is {number_of_desired_senders} - {number_of_existing_senders}'
                f' <= {number_of_senders}'
            )
            number_of_checks = max(
                0, number_of_desired_checks - number_of_existing_checks
            )
            print_message(
                f'Number of checks to be created is {number_of_desired_checks} - {number_of_existing_checks}'
                f' <= {number_of_checks}'
            )
            assert number_of_desired_checks <= 3 * number_of_desired_payments, (
                'Due to constraints on the number of payments with a billing address '
                'in mtp_api/payments/tests/utils.py::setup_payment you must have checks <= 3*payments'
            )
            days_of_history = 1300
            prisons.append('nomis-api-dev')
            prisoners.append('sample')
        else:
            user_set = get_user_model().objects.exclude(username__in=protect_usernames or [])
            if not no_protect_superusers:
                user_set = user_set.exclude(is_superuser=True)
            print_message('Deleting %d users' % user_set.count())
            user_set.delete()

            print_message('Deleting all prisons')
            Prison.objects.all().delete()

        fixtures = ['initial_groups.json', 'initial_types.json']
        if 'sample' in prisons:
            fixtures.append('test_prisons.json')
        if 'nomis' in prisons:
            fixtures.append('test_nomis_prisons.json')
        if 'mtp' in prisons:
            fixtures.append('test_nomis_mtp_prisons.json')
        if 'nomis-api-dev' in prisons:
            fixtures.append('dev_nomis_api_prisons.json')
        if 'dev-prison-api' in prisons:
            fixtures.append('dev_prison_api_prisons.json')
        print_message('Loading default user group and selected prison fixtures')
        call_command('loaddata', *fixtures, verbosity=verbosity)

        print_message('Giving super users full API access')
        create_super_admin(self.stdout, self.style.SUCCESS)
        give_superusers_full_access()

        if credits != 'production-scale' or User.objects.count() < 2:
            print_message('Making test users')
            make_test_users(clerks_per_prison=clerks_per_prison)
            print_message('Making test user admins')
            make_test_user_admins()
            print_message('Making token retrieval user')

        prisoner_locations = None
        if 'nomis' in prisoners:
            prisoner_locations = load_prisoner_locations_from_file('test_nomis_prisoner_locations.csv')
        if 'nomis-api-dev' in prisoners:
            prisoner_locations = load_prisoner_locations_from_file('dev_nomis_api_prisoner_locations.csv')
        if 'dev-prison-api' in prisoners:
            prisoner_locations = load_prisoner_locations_from_dev_prison_api(number_of_prisoners=number_of_prisoners)
        if 'sample' in prisoners:
            prisoner_locations = load_random_prisoner_locations(number_of_prisoners=number_of_prisoners)
        if not prisoner_locations:
            prisoner_locations = PrisonerLocation.objects.all()

        if credits == 'random':
            print_message('Generating random credits')
            generate_transactions(transaction_batch=number_of_transactions)
            generate_payments(payment_batch=number_of_payments)
        elif credits == 'nomis':
            print_message('Generating test NOMIS credits')
            generate_transactions(
                transaction_batch=number_of_transactions,
                predetermined_transactions=True,
                consistent_history=True,
                include_debits=False,
                include_administrative_credits=False,
                include_unidentified_credits=True,
                days_of_history=days_of_history
            )
            generate_payments(
                payment_batch=number_of_payments,
                consistent_history=True,
                days_of_history=days_of_history
            )
        elif credits == 'production-scale':
            print_message('Generating production-like transactions')
            generate_transactions(
                transaction_batch=number_of_transactions,
                predetermined_transactions=True,
                consistent_history=True,
                include_debits=True,
                include_administrative_credits=True,
                include_unidentified_credits=True,
                days_of_history=days_of_history
            )
            print_message('Generating production-like payments/credits')
            generate_payments(
                payment_batch=number_of_payments,
                consistent_history=True,
                days_of_history=days_of_history,
                attach_profiles_to_individual_credits=False,
                number_of_senders=number_of_senders
            )
            print_message(f'Generating (at least) {number_of_prisoners} prisoner profiles')
            prisoner_profiles = generate_prisoner_profiles_from_prisoner_locations(prisoner_locations)
            print_message(f'Generated {len(prisoner_profiles)} prisoner profiles')

            print_message(f'Generating {number_of_senders} sender profiles')
            sender_profiles = generate_sender_profiles_from_payments(number_of_senders)
            print_message(f'Generated {len(sender_profiles)} sender profiles')

            prisoner_profiles_count = PrisonerProfile.objects.count()
            sender_profiles_count = SenderProfile.objects.count()
            extra_generate_checks_args.update({
                'create_invalid_checks': False,
                'number_of_senders_to_use': int((number_of_checks * 5) / sender_profiles_count),
                'number_of_prisoners_to_use': int((number_of_checks * 5) / prisoner_profiles_count)
            })

        print_message('Generating disbursements')
        generate_disbursements(
            disbursement_batch=number_of_disbursements,
            days_of_history=days_of_history
        )
        print_message('Generating checks')
        generate_checks(
            number_of_checks=number_of_checks,
            **extra_generate_checks_args
        )
        print_message('Associating credits with profiles')
        with silence_logger(level=logging.WARNING):
            call_command('update_security_profiles')

        digital_takeup = options['digital_takeup']
        if digital_takeup:
            print_message('Generating digital take-up')
            generate_digital_takeup(days_of_history=days_of_history)
 def setUp(self):
     make_test_users(1)
     load_random_prisoner_locations(1)
     self.payments = generate_payments(self.payment_count,
                                       days_of_history=10)
示例#46
0
 def setUp(self):
     super().setUp()
     make_test_users(clerks_per_prison=1)
     load_random_prisoner_locations(number_of_prisoners=1)
     generate_transactions(transaction_batch=1)
     generate_payments(payment_batch=1)
    def handle(self, *args, **options):
        if settings.ENVIRONMENT == 'prod':
            return self.handle_prod(**options)

        verbosity = options.get('verbosity', 1)
        protect_superusers = options['protect_superusers']
        protect_usernames = options['protect_usernames']
        protect_credits = options['protect_credits']
        prisons = options['prisons']
        prisoners = options['prisoners']
        number_of_prisoners = options['number_of_prisoners']
        clerks_per_prison = options['clerks_per_prison']
        credits = options['credits']

        print_message = self.stdout.write if verbosity else lambda m: m

        if not protect_credits:
            print_message('Deleting all credits')
            Balance.objects.all().delete()
            Transaction.objects.all().delete()
            Payment.objects.all().delete()
            Credit.objects_all.all().delete()
            Batch.objects.all().delete()
            SenderProfile.objects.all().delete()
            PrisonerProfile.objects.all().delete()
            SavedSearch.objects.all().delete()
            Disbursement.objects.all().delete()
            RecipientProfile.objects.all().delete()

        user_set = get_user_model().objects.exclude(username__in=protect_usernames or [])
        if protect_superusers:
            user_set = user_set.exclude(is_superuser=True)
        print_message('Deleting %d users' % user_set.count())
        user_set.delete()

        print_message('Deleting all prisons')
        Prison.objects.all().delete()

        fixtures = ['initial_groups.json', 'initial_types.json']
        if 'sample' in prisons:
            fixtures.append('test_prisons.json')
        if 'nomis' in prisons:
            fixtures.append('test_nomis_prisons.json')
        if 'mtp' in prisons:
            fixtures.append('test_nomis_mtp_prisons.json')
        if 'nomis-api-dev' in prisons:
            fixtures.append('dev_nomis_api_prisons.json')
        print_message('Loading default user group and selected prison fixtures')
        call_command('loaddata', *fixtures, verbosity=verbosity)

        print_message('Giving super users full API access')
        give_superusers_full_access()

        print_message('Making test users')
        make_test_users(clerks_per_prison=clerks_per_prison)
        print_message('Making test user admins')
        make_test_user_admins()
        print_message('Making token retrieval user')
        make_token_retrieval_user()

        if 'nomis' in prisoners:
            load_prisoner_locations_from_file('test_nomis_prisoner_locations.csv')
        if 'nomis-api-dev' in prisoners:
            load_prisoner_locations_from_file('dev_nomis_api_prisoner_locations.csv')
        if 'sample' in prisoners:
            load_random_prisoner_locations(number_of_prisoners=number_of_prisoners)

        number_of_transactions = options['number_of_transactions']
        number_of_payments = options['number_of_payments']
        number_of_disbursements = options['number_of_disbursements']
        days_of_history = options['days_of_history']
        if credits == 'random':
            print_message('Generating random credits')
            generate_transactions(transaction_batch=number_of_transactions)
            generate_payments(payment_batch=number_of_payments)
        elif credits == 'nomis':
            print_message('Generating test NOMIS credits')
            generate_transactions(
                transaction_batch=number_of_transactions,
                predetermined_transactions=True,
                consistent_history=True,
                include_debits=False,
                include_administrative_credits=False,
                include_unidentified_credits=True,
                days_of_history=days_of_history
            )
            generate_payments(
                payment_batch=number_of_payments,
                consistent_history=True,
                days_of_history=days_of_history
            )
        generate_disbursements(
            disbursement_batch=number_of_disbursements,
            days_of_history=days_of_history
        )
        call_command('update_security_profiles')

        digital_takeup = options['digital_takeup']
        if digital_takeup:
            print_message('Generating digital take-up')
            generate_digital_takeup(days_of_history=days_of_history)
    def test_update_security_profiles_subsequent_card_payment(self):
        generate_transactions(transaction_batch=100, days_of_history=5)
        generate_payments(payment_batch=100, days_of_history=5)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update = SenderProfile.objects.filter(
            debit_card_details__isnull=False,
            prisoners__isnull=False
        ).first()
        card_details = sender_to_update.debit_card_details.first()
        prisoner_to_update = sender_to_update.prisoners.first()

        initial_sender_credit_count = sender_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_count
        initial_sender_credit_total = sender_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_total
        initial_sender_cardholder_names = list(card_details.cardholder_names.values_list('name', flat=True))
        initial_sender_emails = list(card_details.sender_emails.values_list('email', flat=True))
        initial_prisoner_credit_count = prisoner_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_count
        initial_prisoner_credit_total = prisoner_to_update.totals.get(
            time_period=TIME_PERIOD.ALL_TIME).credit_total

        new_payments = generate_initial_payment_data(tot=1, days_of_history=0)

        new_payments[0]['created'] = timezone.now()

        new_payments[0]['email'] = '*****@*****.**'
        new_payments[0]['cardholder_name'] = 'other name'
        new_payments[0]['card_number_last_digits'] = card_details.card_number_last_digits
        new_payments[0]['card_expiry_date'] = card_details.card_expiry_date
        new_payments[0]['billing_address']['postcode'] = card_details.postcode

        new_payments[0]['prisoner_number'] = prisoner_to_update.prisoner_number
        new_payments[0]['prisoner_dob'] = prisoner_to_update.prisoner_dob

        create_payments(new_payments)
        call_command('update_security_profiles', verbosity=0)

        sender_to_update.refresh_from_db()
        self.assertEqual(
            sender_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_count,
            initial_sender_credit_count + 1
        )
        self.assertEqual(
            sender_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_total,
            initial_sender_credit_total + new_payments[0]['amount']
        )
        card_details.refresh_from_db()
        self.assertEqual(
            sorted(card_details.cardholder_names.values_list('name', flat=True)),
            sorted(initial_sender_cardholder_names + ['other name'])
        )
        self.assertEqual(
            sorted(card_details.sender_emails.values_list('email', flat=True)),
            sorted(initial_sender_emails + ['*****@*****.**'])
        )

        prisoner_to_update.refresh_from_db()
        self.assertEqual(
            prisoner_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_count,
            initial_prisoner_credit_count + 1
        )
        self.assertEqual(
            prisoner_to_update.totals.get(time_period=TIME_PERIOD.ALL_TIME).credit_total,
            initial_prisoner_credit_total + new_payments[0]['amount']
        )