def process_entry_save(entry: Entry) -> None: """ Once an entry is saved, process the entry if it is paid :param entry: The entry that should be processed :type entry: Entry """ if not entry or not entry.payment: return if entry.status != Entry.STATUS_ACCEPTED: return try: registration = entry.registration # Create user and member member = _create_member_from_registration(registration) except Registration.DoesNotExist: # Get member from renewal renewal = entry.renewal member = renewal.member # Send email of payment confirmation for renewal, # not needed for registration since a new member already # gets the welcome email emails.send_renewal_complete_message(entry.renewal) entry.payment.paid_by = member # This should actually be a PaymentUser, but as PaymentUser is a proxy model of Member, this doesn't break entry.payment.save() membership = _create_membership_from_entry(entry, member) entry.membership = membership entry.status = Entry.STATUS_COMPLETED entry.save()
def test_str(self): entry = Entry(registration=self.registration) self.assertEqual( str(entry), "{} {} ({})".format( self.registration.first_name, self.registration.last_name, self.registration.email, ), ) entry = Entry(renewal=self.renewal) self.assertEqual( str(entry), "{} {} ({})".format(self.member.first_name, self.member.last_name, self.member.email), )
def test_payable_attributes(self): entry = Entry( contribution=8, length=Entry.MEMBERSHIP_YEAR, registration=self.registration, ) self.assertEqual(entry.payment_amount, 8) self.assertEqual( entry.payment_notes, "Registration entry. Creation date: Jan. 1, 2019. Completion date: Jan. 1, 2019", ) with self.subTest("Without membership"): self.assertEqual(entry.payment_payer, None) with self.subTest("With membership"): entry.membership = Membership(user=self.member) self.assertEqual(entry.payment_payer, self.member)
def test_process_entry_save(self, send_renewal_email): self.e1.username = "******" self.e1.save() self.e1.status = Entry.STATUS_ACCEPTED self.e1.membership = None self.e1.payment = Payment.objects.create(amount=8) self.e1.save() self.e3.status = Entry.STATUS_ACCEPTED self.e3.membership = None self.e3.payment = Payment.objects.create(amount=8) self.e3.save() with self.subTest("No entry"): services.process_entry_save(None) with self.subTest("No payment for entry"): services.process_entry_save(Entry(payment=None)) with self.subTest("Status is not accepted"): services.process_entry_save(Entry(payment=Payment())) with self.subTest("Registration paid"): services.process_entry_save(self.e1) self.e1.refresh_from_db() self.assertIsNotNone(self.e1.membership) self.assertEqual(self.e1.status, Entry.STATUS_COMPLETED) with self.subTest("Renewal paid"): services.process_entry_save(self.e3) self.e3.refresh_from_db() self.e3.payment.refresh_from_db() send_renewal_email.assert_called_with(self.e3) self.assertEqual(self.e3.payment.paid_by, self.e3.member) self.assertIsNotNone(self.e3.membership) self.assertEqual(self.e3.status, Entry.STATUS_COMPLETED)
def revert_entry(user_id: int, entry: Entry) -> None: """ Revert status of entry to review so that it can be corrected :param user_id: Id of the user executing this action :param entry: Entry that should be reverted """ if not (entry.status in [Entry.STATUS_ACCEPTED, Entry.STATUS_REJECTED]): return payment = entry.payment entry.status = Entry.STATUS_REVIEW entry.updated_at = timezone.now() entry.payment = None entry.save() if payment is not None: payment.delete() log_obj = None try: log_obj = entry.registration except Registration.DoesNotExist: try: log_obj = entry.renewal except Renewal.DoesNotExist: pass if log_obj: LogEntry.objects.log_action( user_id=user_id, content_type_id=get_content_type_for_model(log_obj).pk, object_id=log_obj.pk, object_repr=str(log_obj), action_flag=CHANGE, change_message="Revert status to review", )
def test_save(self): entry = Entry(length=Entry.MEMBERSHIP_YEAR, registration=self.registration) entry.status = Entry.STATUS_ACCEPTED test_value = timezone.now().replace(year=1996) entry.updated_at = test_value with self.subTest("Accepted should not update `updated_at`"): entry.save() self.assertEqual(entry.updated_at, test_value) entry.status = Entry.STATUS_REJECTED with self.subTest("Rejected should not update `updated_at`"): entry.save() self.assertEqual(entry.updated_at, test_value) entry.status = Entry.STATUS_REVIEW with self.subTest("Review should update `updated_at`"): entry.save() self.assertNotEqual(entry.updated_at, test_value) entry.length = Entry.MEMBERSHIP_STUDY with self.subTest("Type `Member` should not change length"): entry.save() self.assertEqual(entry.length, Entry.MEMBERSHIP_STUDY) entry.membership_type = Membership.BENEFACTOR with self.subTest("Type `Benefactor` should set length to year"): entry.save() self.assertEqual(entry.length, Entry.MEMBERSHIP_YEAR) entry.contribution = 9 with self.subTest("Type `Benefactor` keeps contribution value"): entry.save() self.assertEqual(entry.contribution, 9) entry.membership_type = Membership.MEMBER with self.subTest("Type `Member` should set contribution by length"): entry.save() self.assertEqual(entry.contribution, settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR])
def test_clean(self): entry = Entry(registration=self.registration) entry.membership_type = Membership.MEMBER entry.contribution = None with self.subTest("Type `Member` should not require contribution"): entry.clean() entry.membership_type = Membership.BENEFACTOR with self.subTest("Type `Benefactor` should require contribution"): with self.assertRaises(ValidationError): entry.clean() entry.contribution = 7.5 entry.clean()