def get_form_kwargs(self): kwargs = super().get_form_kwargs() self.membership = Membership.objects.get(pk=self.membership_id) if self.membership.cutoff_age: kwargs['initial'].update({'membership_id': self.membership_id}) kwargs['choices'] = Membership.adult_choices(self.membership.id) else: kwargs['choices'] = Membership.adult_choices() return session.update_kwargs(self, kwargs)
def get_context_data(self, **kwargs): self.membership = Membership.objects.get(pk=self.membership_id) if self.membership.cutoff_age: kwargs['form_title'] = f'{self.full_name}: {self.membership.description} membership' kwargs['memberships'] = Membership.adult_choices(membership_id=self.membership.id, description=True) else: kwargs['form_title'] = f'Select adult membership for {self.full_name}' kwargs['memberships'] = Membership.adult_choices(description=True) kwargs['buttons'] = [Button('Back', css_class='btn-primary'), Button('Next', css_class='btn-primary')] return super().get_context_data(**kwargs)
def test_get_context_data(self): membership = Membership(pk=2, type=Membership.MEMBER) self.view.request = MagicMock() with mock.patch("members.models.Membership.objects") as _qs: Membership.objects.filter().exists.return_value = True context = self.view.get_context_data(form=MagicMock()) self.assertEqual(len(context), 7) self.assertEqual( context["year_fees"], floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR], 2), ) self.assertEqual( context["study_fees"], floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_STUDY], 2), ) self.assertEqual(context["was_member"], True) Membership.objects.filter().exists.return_value = False context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["was_member"], False) with self.subTest("With latest membership"): self.view.request.member.latest_membership = membership context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["latest_membership"], membership) with self.subTest("Without latest membership"): self.view.request.member.latest_membership = None context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["latest_membership"], None)
def _special_case_ixStxgstn56QI8jnJtcCtzMF(self, sale): mship = Membership() mship.sale = Sale(id=sale['id']) mship.membership_type = Membership.MT_REGULAR mship.ctrlid = "{}:1:1".format(sale['ctrlid']) mship.start_date = date(2014, 12, 12) mship.end_date = date(2015, 6, 11) mship.sale_price = 225.00 self.upsert(mship)
def _special_case_7cQ69ctaeYok1Ry3KOTFbyMF(self, sale): mship = Membership() mship.sale = Sale(id=sale['id']) mship.membership_type = Membership.MT_REGULAR mship.ctrlid = "{}:1:1".format(sale['ctrlid']) mship.start_date = date(2016, 4, 5) mship.end_date = date(2015, 4, 18) mship.sale_price = 25.00 self.upsert(mship)
def _special_case_0JFN0loJ0kcy8DXCvuDVwwMF(self, sale): # Verify: This was erroneously entered as a donation but was really a work-trade payment. mship = Membership() mship.sale = Sale(id=sale['id']) mship.member = Member( id=19 ) # Lookup by name would be better but I don't want to have names in the code. mship.membership_type = Membership.MT_WORKTRADE mship.ctrlid = "{}:1:1".format(sale['ctrlid']) mship.start_date = date(2015, 12, 1) mship.end_date = date(2015, 12, 31) mship.sale_price = 10.00 self.upsert(mship)
def setup_testing_members(user): from members.models import MemberSet, Membership MemberSet(pk=1, name='default set', unit_id=settings.ROOT_UNIT_PK, api_secret_key='Secret123!', handle_fees=True).save() Membership(user=user, group_id=1, payed_fees=True).save()
def _special_case_0JFN0loJ0kcy8DXCvuDVwwMF(self, sale): # Verify: This was erroneously entered as a donation but was really a work-trade payment. mship = Membership() mship.sale = Sale(id=sale['id']) mship.member = Member(id=19) # Lookup by name would be better but I don't want to have names in the code. mship.membership_type = Membership.MT_WORKTRADE mship.ctrlid = "{}:1:1".format(sale['ctrlid']) mship.start_date = date(2015, 12, 1) mship.end_date = date(2015, 12, 31) mship.sale_price = 10.00 self.upsert(mship)
def setUpTestData(cls): # Add 10 members with default membership members = [Member(id=i, username=i) for i in range(10)] Member.objects.bulk_create(members) memberships = [ Membership(user_id=i, type=Membership.MEMBER) for i in range(10) ] Membership.objects.bulk_create(memberships) profiles = [Profile(user_id=i) for i in range(10)] Profile.objects.bulk_create(profiles)
def create_user(self): """Create a new random user""" self.stdout.write("Creating a user") fakeprofile = _faker.profile() fakeprofile["password"] = "".join( random.choice(string.ascii_uppercase + string.digits) for _ in range(16)) user = get_user_model().objects.create_user(fakeprofile["username"], fakeprofile["mail"], fakeprofile["password"]) user.first_name = fakeprofile["name"].split()[0] user.last_name = " ".join(fakeprofile["name"].split()[1:]) profile = _ProfileFactory() profile.user_id = user.id profile.birthday = fakeprofile["birthdate"] profile.website = fakeprofile["website"][0] igen = IconGenerator(5, 5) # 5x5 blocks icon = igen.generate( user.username, 480, 480, padding=(10, 10, 10, 10), output_format="jpeg", ) # 620x620 pixels, with 10 pixels padding on each side profile.photo.save(fakeprofile["username"] + ".jpeg", ContentFile(icon)) membership = Membership() membership.user_id = user.id membership.since = _faker.date_time_between(start_date="-4y", end_date="now", tzinfo=None) membership.until = random.choice([ _faker.date_time_between(start_date=membership.since, end_date="+2y", tzinfo=None), None, ]) membership.type = random.choice( [t[0] for t in Membership.MEMBERSHIP_TYPES]) user.save() profile.save() membership.save()
def test_get_context_data(self): membership = Membership(pk=2, type=Membership.MEMBER) self.view.request = MagicMock() with mock.patch("members.models.Membership.objects") as _membership_qs: Membership.objects.filter().exists.return_value = True with mock.patch( "registrations.models.Renewal.objects") as _renewal_qs: Renewal.objects.filter().last.return_value = None context = self.view.get_context_data(form=MagicMock()) self.assertEqual(len(context), 8) self.assertEqual( context["year_fees"], floatformat( settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR], 2), ) self.assertEqual( context["study_fees"], floatformat( settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_STUDY], 2), ) self.assertEqual(context["was_member"], True) Membership.objects.filter().exists.return_value = False context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["was_member"], False) with self.subTest("With latest membership"): self.view.request.member.latest_membership = membership context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["latest_membership"], membership) with self.subTest("Without latest membership"): self.view.request.member.latest_membership = None context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["latest_membership"], None) with self.subTest("With renewal"): renewal = Renewal.objects.create( member=self.view.request.member, status=Entry.STATUS_ACCEPTED) Renewal.objects.filter().last.return_value = renewal context = self.view.get_context_data(form=MagicMock()) self.assertEqual(context["latest_renewal"], renewal)
def test_get_form(self): self.view.request = self.rf.get("/") self.view.request.member = None form = self.view.get_form() self.assertFalse( Entry.MEMBERSHIP_YEAR in form.fields["length"].choices) self.view.request.member = MagicMock() self.view.request.member.latest_membership = None form = self.view.get_form() self.assertFalse( Entry.MEMBERSHIP_YEAR in form.fields["length"].choices) self.view.request.member.latest_membership = Membership(until=None) form = self.view.get_form() self.assertFalse( Entry.MEMBERSHIP_YEAR in form.fields["length"].choices) self.view.request.member.latest_membership = Membership( until=timezone.now().date()) form = self.view.get_form() self.assertEqual(Entry.MEMBERSHIP_YEAR, form.fields["length"].choices[1][0])
def setUpTestData(cls): # Add 10 members with default membership members = [Member(id=i, username=i) for i in range(7)] Member.objects.bulk_create(members) profiles = [Profile(user_id=i) for i in range(7)] Profile.objects.bulk_create(profiles) Membership(user_id=0, type=Membership.HONORARY, until=date.today() + timedelta(days=1)).save() Membership( user_id=1, type=Membership.BENEFACTOR, until=date.today() + timedelta(days=1), ).save() Membership(user_id=2, type=Membership.MEMBER, until=date.today() + timedelta(days=1)).save() Membership(user_id=3, type=Membership.MEMBER, until=date.today() + timedelta(days=1)).save() Membership( user_id=3, type=Membership.MEMBER, until=date.today() - timedelta(days=365 * 10), ).save() Membership( user_id=4, type=Membership.BENEFACTOR, until=date.today() + timedelta(days=1), ).save() Membership( user_id=4, type=Membership.MEMBER, until=date.today() - timedelta(days=365 * 10), ).save() Membership( user_id=5, type=Membership.MEMBER, until=date.today() - timedelta(days=365 * 10), ).save()
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 _process_membership_sale(self, sale, checkout, months, family): mship = Membership() mship.sale = Sale(id=sale.id) mship.sale_price = sale.total_paid_by_customer if checkout['fee_payer'] == 'payer': mship.sale_price -= sale.processing_fee if family > 0: mship.sale_price -= Decimal(10.00) * Decimal(family) mship.ctrlid = "{}:{}".format(self.CTRLID_PREFIX, checkout['checkout_id']) mship.start_date = sale.sale_date mship.end_date = mship.start_date + relativedelta(months=months, days=-1) self.upsert(mship) for n in range(family): fam = Membership() fam.sale = mship.sale fam.sale_price = 10.00 fam.membership_type = Membership.MT_FAMILY fam.start_date = mship.start_date fam.end_date = mship.end_date fam.ctrlid = "{}:{}:{}".format(self.CTRLID_PREFIX, mship.ctrlid, n) self.upsert(fam)
emergency_contact = row['Emergency Contact'], emergency_phone_number = row['Emergency Phone'], stripe_customer_code = row['Stripe cus_ code']) if len(m.birth_date) == 0: m.birth_date = datetime.date.today() try: m.save() except django.core.exceptions.ValidationError: print('error: skipping', fname, lname) raise #attempt to make a membership try: #for empty strings on expire date if not row['Last day of Membership']: last_day = datetime.date.today() else: last_day = datetime.datetime.strptime(row['Last day of Membership'], '%Y-%m-%d').date() if last_day > datetime.date.today(): ms = Membership(member = m, start_date = datetime.date.today(), expire_date = last_day, stripe_subscription_code = row['Stripe Membership sub_ code']) ms.save() except ValueError: print('\t could not parse date: [', row['Last day of Membership'], ']') pass #end for loop
def _process_membership_item(self, sale, item, item_num, membership_type, dur_amt, dur_unit): month = self.month_in_str(item['name']) family = None for modifier in item["modifiers"]: lmod = modifier["name"].lower() if lmod == "just myself": family = 0 elif lmod == "1 add'l family member": family = 1 elif lmod == "2 add'l family members": family = 2 elif lmod == "3 add'l family members": family = 3 elif lmod == "4 add'l family members": family = 4 elif lmod == "5 add'l family members": family = 5 if membership_type == Membership.MT_WORKTRADE and month is None: month = self.month_in_str(lmod) if family is None: ctrlid = sale['ctrlid'] # A special case because the 12 month membership item was set up incorrectly. if ctrlid == "SQ:kZxawM1NBAxvqr2vKU2ZnzMF" and item_num == 1: family = 0 else: print("Couldn't determine family count for {}:{}".format(sale['ctrlid'], item_num)) family = 0 quantity = int(float(item['quantity'])) for n in range(1, quantity+1): mship = Membership() mship.sale = Sale(id=sale['id']) mship.membership_type = membership_type mship.ctrlid = "{}:{}:{}".format(sale['ctrlid'], item_num, n) mship.start_date = parse(sale['sale_date']).date() if mship.membership_type == Membership.MT_WORKTRADE: mship.start_date = mship.start_date.replace(day=1) # WT always starts on the 1st. if month is not None: # Hopefully, the buyer specified the month. mship.start_date = mship.start_date.replace(month=month) mship.end_date = mship.start_date + relativedelta(**{dur_unit:dur_amt, "days":-1}) mship.sale_price = Decimal(item['gross_sales_money']['amount']) / Decimal(quantity * 100.0) mship.sale_price -= Decimal(10.00) * Decimal(family) self.upsert(mship) for f in range(family): fam = Membership() fam.sale = mship.sale fam.sale_price = 10 fam.membership_type = Membership.MT_FAMILY fam.start_date = mship.start_date fam.end_date = mship.end_date fam.ctrlid = "{}:{}".format(mship.ctrlid, f) self.upsert(fam)
def _member_and_family(self, sale: Sale, months: int): primary_membership_price = Fetcher.prices[months] assert primary_membership_price <= sale.total_paid_by_customer remaining = sale.total_paid_by_customer - primary_membership_price assert remaining % Decimal( 10.00) == 0 # Additional family members should be $10/mo fam_count = int(remaining) // 10 // months mship = Membership() mship.sale = sale mship.membership_type = Membership.MT_REGULAR mship.ctrlid = "{}:P".format(sale.ctrlid) mship.start_date = sale.sale_date mship.end_date = mship.start_date + relativedelta(months=months, days=-1) mship.sale_price = Decimal(primary_membership_price) self.upsert(mship) for f in range(1, fam_count + 1): mship.membership_type = Membership.MT_FAMILY mship.ctrlid = "{}:{}".format(sale.ctrlid, f) mship.sale_price = Decimal(months * 10.00) self.upsert(mship)
def get_context_data(self, **kwargs): kwargs['form_title'] = "Adult profile: " + self.full_name kwargs['memberships'] = Membership.adult_choices(self.membership_id, description=True) kwargs['buttons'] = [Button('Back', css_class='btn-primary'), Button('Next', css_class='btn-primary')] return super().get_context_data(**kwargs)
def _process_lineitems(self, djgo_sale, lineitems): if len(lineitems) > 1: print("WARNING: More than two line items in invoice.") for lineitem in lineitems: amt = Decimal(lineitem.customer_amount) assert amt >= 50, "Didn't expect line item amount < 50." assert amt % 10 == 0, "Didn't expect line item amount that's not a multiple of 10." assert len(lineitem.options) <= 1 assert lineitem.status in ["bill", "refund"] mship = Membership() mship.sale = Sale(id=djgo_sale['id']) mship.start_date = parse(djgo_sale['sale_date']).date() # Inclusive mship.end_date = mship.start_date + relativedelta(months=+1, days=-1) # Inclusive mship.sale_price = 50 mship.ctrlid = "2CO:{}:{}".format(lineitem.invoice_id, lineitem.lineitem_id) self.upsert(mship) family = int((amt-50)/10) for n in range(family): fam = Membership() fam.sale = mship.sale fam.sale_price = 10 fam.membership_type = Membership.MT_FAMILY fam.start_date = mship.start_date fam.end_date = mship.end_date fam.ctrlid = "{}:{}".format(mship.ctrlid, n) self.upsert(fam)
def _process_membership_item(self, sale, item, item_num, membership_type, dur_amt, dur_unit): month = self.month_in_str(item['name']) family = None for modifier in item["modifiers"]: lmod = modifier["name"].lower() if lmod == "just myself": family = 0 elif lmod == "1 add'l family member": family = 1 elif lmod == "2 add'l family members": family = 2 elif lmod == "3 add'l family members": family = 3 elif lmod == "4 add'l family members": family = 4 elif lmod == "5 add'l family members": family = 5 if membership_type == Membership.MT_WORKTRADE and month is None: month = self.month_in_str(lmod) if family is None: ctrlid = sale['ctrlid'] # A special case because the 12 month membership item was set up incorrectly. if ctrlid == "SQ:kZxawM1NBAxvqr2vKU2ZnzMF" and item_num == 1: family = 0 else: print("Couldn't determine family count for {}:{}".format( sale['ctrlid'], item_num)) family = 0 quantity = int(float(item['quantity'])) for n in range(1, quantity + 1): mship = Membership() mship.sale = Sale(id=sale['id']) mship.membership_type = membership_type mship.ctrlid = "{}:{}:{}".format(sale['ctrlid'], item_num, n) mship.start_date = parse(sale['sale_date']).date() if mship.membership_type == Membership.MT_WORKTRADE: mship.start_date = mship.start_date.replace( day=1) # WT always starts on the 1st. if month is not None: # Hopefully, the buyer specified the month. mship.start_date = mship.start_date.replace(month=month) mship.end_date = mship.start_date + relativedelta(**{ dur_unit: dur_amt, "days": -1 }) mship.sale_price = Decimal( item['gross_sales_money']['amount']) / Decimal( quantity * 100.0) mship.sale_price -= Decimal(10.00) * Decimal(family) self.upsert(mship) for f in range(family): fam = Membership() fam.sale = mship.sale fam.sale_price = 10 fam.membership_type = Membership.MT_FAMILY fam.start_date = mship.start_date fam.end_date = mship.end_date fam.ctrlid = "{}:{}".format(mship.ctrlid, f) self.upsert(fam)
def _process_subscription_charges(self, charges, subscription, family): for charge in charges: state = charge["state"] if state == "refunded": refund = True elif state == "captured": refund = False elif state == "failed": continue else: print("State not handled: " + state) continue sale = Sale() sale.payer_name = subscription['payer_name'] sale.payer_email = subscription['payer_email'] if subscription['fee_payer'] == "payer": print( "Fee is paid by payer. Situation has not yet been analyzed." ) sale.payment_method = Sale.PAID_BY_WEPAY sale.sale_date = date.fromtimestamp(int( charge['create_time'])) # TODO: This is UTC timezone. sale.total_paid_by_customer = charge["amount"] sale.processing_fee = charge["fee"] sale.ctrlid = "{}:{}".format(self.CTRLID_PREFIX, charge['subscription_charge_id']) django_sale = self.upsert(sale) mship = Membership() mship.sale = Sale(id=django_sale['id']) mship.sale_price = sale.total_paid_by_customer if subscription['fee_payer'] == 'payer': mship.sale_price -= sale.processing_fee if family > 0: mship.sale_price -= Decimal(10.00) * Decimal(family) mship.ctrlid = "{}:{}".format(self.CTRLID_PREFIX, charge['subscription_charge_id']) mship.start_date = sale.sale_date mship.end_date = mship.start_date + relativedelta(months=1, days=-1) self.upsert(mship) for n in range(family): fam = Membership() fam.sale = mship.sale fam.sale_price = 10.00 fam.membership_type = Membership.MT_FAMILY fam.start_date = mship.start_date fam.end_date = mship.end_date fam.ctrlid = "{}:{}:{}".format(self.CTRLID_PREFIX, mship.ctrlid, n) self.upsert(fam)
def import_members(request, pk): from members.models import MemberSet, Membership, MemberSetLogging memberset = get_object_or_404(MemberSet, pk=pk) if not memberset.rights_can('EDIT', request.user): raise Http404 logs = [] if request.method == 'POST': form = MembershipImportForm(request.user, memberset, request.POST, request.FILES) if form.is_valid(): edition_extra_data = {} try: imp_file = json.loads( request.FILES['imported'].read().decode()) for user_data in imp_file: if isinstance(user_data, (int, str, str)): username = str(user_data) fees = False elif type(user_data) is list: username = user_data[0] fees = len(user_data) > 1 and user_data[1] else: continue try: user = TruffeUser.objects.get(username=username) except TruffeUser.DoesNotExist: if re.match(r'^\d{6}$', username): user = TruffeUser(username=username, is_active=True) user.last_name, user.first_name, user.email = get_attrs_of_sciper( username) user.save() else: logs.append( ('danger', username, _(u'Impossible de créer l\'utilisateur'))) user = None if user: if memberset.membership_set.filter( user=user, end_date=None).exists(): logs.append(( 'warning', user, _(u'L\'utilisateur est déjà membre de ce groupe' ))) else: # Copy the fees status if asked payed_fees = form.cleaned_data.get( 'copy_fees_status', False) and fees Membership(group=memberset, user=user, payed_fees=payed_fees).save() logs.append(('success', user, _(u'Utilisateur ajouté avec succès'))) edition_extra_data[user.get_full_name()] = [ "None", "Membre" ] MemberSetLogging(who=request.user, what='edited', object=memberset, extra_data=json.dumps({ 'edited': edition_extra_data })).save() except ValueError: logs.append(( 'danger', _(u'ERREUR'), _(u'Le fichier ne peut pas être lu correctement, l\'import a été annulé' ))) else: form = MembershipImportForm(request.user, memberset) logs.sort(key=lambda x: x[0]) return render(request, 'members/membership/import.html', { 'form': form, 'logs': logs, 'group': memberset, 'display_list_panel': True })
def import_members_list(request, pk): from members.models import MemberSet, Membership, MemberSetLogging memberset = get_object_or_404(MemberSet, pk=pk) if not memberset.rights_can('EDIT', request.user): raise Http404 logs = [] if request.method == 'POST': form = MembershipImportListForm(request.POST, request.FILES) if form.is_valid(): edition_extra_data = {} for username in form.cleaned_data['data'].split('\n'): username = username.strip() if username: try: user = TruffeUser.objects.get(username=username) except TruffeUser.DoesNotExist: if re.match(r'^\d{6}$', username): user = TruffeUser(username=username, is_active=True) user.last_name, user.first_name, user.email = get_attrs_of_sciper( username) user.save() else: logs.append( ('danger', username, _(u'Impossible de créer l\'utilisateur'))) user = None if user: if memberset.membership_set.filter( user=user, end_date=None).exists(): logs.append(( 'warning', user, _(u'L\'utilisateur est déjà membre de ce groupe' ))) else: Membership(group=memberset, user=user, payed_fees=form. cleaned_data['fee_status']).save() logs.append(('success', user, _(u'Utilisateur ajouté avec succès'))) edition_extra_data[user.get_full_name()] = [ "None", "Membre" ] MemberSetLogging(who=request.user, what='edited', object=memberset, extra_data=json.dumps( {'edited': edition_extra_data})).save() else: form = MembershipImportListForm() logs.sort(key=lambda x: x[0]) return render(request, 'members/membership/import_list.html', { 'form': form, 'logs': logs, 'group': memberset, 'display_list_panel': True })
def _process_subscription_charges(self, charges, subscription, family): for charge in charges: if not charge["state"].startswith("captured"): if not charge["state"] == "failed": print(charge["state"]) continue sale = Sale() sale.payer_name = subscription['payer_name'] sale.payer_email = subscription['payer_email'] if subscription['fee_payer'] == "payer": print("Fee is paid by payer. Situation has not yet been analyzed.") sale.payment_method = Sale.PAID_BY_WEPAY sale.sale_date = date.fromtimestamp(int(charge['create_time'])) # TODO: This is UTC timezone. sale.total_paid_by_customer = charge["amount"] sale.processing_fee = charge["fee"] sale.ctrlid = "{}:{}".format(self.CTRLID_PREFIX, charge['subscription_charge_id']) django_sale = self.upsert(sale) mship = Membership() mship.sale = Sale(id=django_sale['id']) mship.sale_price = sale.total_paid_by_customer if subscription['fee_payer'] == 'payer': mship.sale_price -= sale.processing_fee if family > 0: mship.sale_price -= Decimal(10.00) * Decimal(family) mship.ctrlid = "{}:{}".format(self.CTRLID_PREFIX, charge['subscription_charge_id']) mship.start_date = sale.sale_date mship.end_date = mship.start_date + relativedelta(months=1, days=-1) self.upsert(mship) for n in range(family): fam = Membership() fam.sale = mship.sale fam.sale_price = 10.00 fam.membership_type = Membership.MT_FAMILY fam.start_date = mship.start_date fam.end_date = mship.end_date fam.ctrlid = "{}:{}:{}".format(self.CTRLID_PREFIX, mship.ctrlid, n) self.upsert(fam)