def generate_participation(ids=None): from random import randint eprice = 3000 parts = [1, 2, 3, 4, 0.5, 1.5] e = Event.objects.get(name="Target") users = Account.objects.filter(user__username__iregex=r'^P\d$') # generate participation participation = dict() # random count if ids is None: ids = [] for i in range(0, randint(1, 6)): # random count ids.append(randint(0, 5)) # random accounts for i in ids: participation[users[i]] = parts[i] if ids is None: print_list(participation, "used participants") add_participants(e, participation) party_pay =\ eprice / sum(participation.values()) return ( e, party_pay, participation, )
def generate_participation(ids=None): from random import randint eprice = 3000 parts = [1, 2, 3, 4, 0.5, 1.5] e = Event.objects.get(name="Target") users = Account.objects.filter(user__username__iregex=r'^P\d$') # generate participation participation = dict() # random count if ids is None: ids = [] for i in range(0, randint(1, 6)): # random count ids.append(randint(0, 5)) # random accounts for i in ids: participation[users[i]] = parts[i] if ids is None: print_list(participation, "used participants") add_participants(e, participation) party_pay =\ eprice / sum(participation.values()) return (e, party_pay, participation,)
def test_participation_uniquenest(self): e, _, participation = generate_participation([0, 1, 2]) users = list(participation.keys()) remove_participants(e, [users[0]]) self.assertEqual( e.participation_set.filter(active=False)[0].account, users[0]) add_participants(e, {users[0]: 1.0}) # participation count == users in event count self.assertEqual(len(e.participation_set.all()), 3)
def test_participation_uniquenest(self): e, _, participation = generate_participation([0, 1, 2]) users = list(participation.keys()) remove_participants(e, [users[0]]) self.assertEqual(e.participation_set.filter(active=False)[0].account, users[0]) add_participants(e, {users[0]: 1.0}) # participation count == users in event count self.assertEqual(len(e.participation_set.all()), 3)
def post(self, req, event_pk, format=None): """ Add participant to event in context. Expect array, like: [{"rate": 1, "account": 1}, ...]. account is pk. """ ser = ParticipationPostSerializer(data=req.data, context={"request": req}, many=True) if ser.is_valid(): newbies = {} for p in ser.validated_data: newbies.update({p["account"]: p["parts"]}) e = get_event(event_pk) add_participants(e, newbies) return Response(ParticipationSerializer(get_participants(e), context={"request": req}, many=True).data) return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)
def create(self, validated_data): """Create event from income data. """ # pop firstly: Event constructor don't accept 'participants' arg raw_participants = validated_data.pop('participants', []) e = Event.objects.create(**validated_data) # convert to dict participants = dict() if len(raw_participants) > 0: for p in raw_participants: participants.update({p.get('account'): p.get('parts')}) add_participants(e, participants) return e
def post(self, req, event_pk, format=None): """ Add participant to event in context. Expect array, like: [{"rate": 1, "account": 1}, ...]. account is pk. """ ser = ParticipationPostSerializer(data=req.data, context={'request': req}, many=True) if ser.is_valid(): newbies = {} for p in ser.validated_data: newbies.update({p['account']: p['parts']}) print(newbies) e = get_event(event_pk) add_participants(e, newbies) return Response(ParticipationSerializer(get_participants(e)).data) return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)
def test_sway_participants(self): e, _, participation = generate_participation([0, 1, 2]) print_list(Transaction.objects.all(), "ADDED users 0, 1, 2") users = list(participation.keys()) ######################################### # Check that event in balance self.assertEqual(e.rest(), 0) ######################################### remove_participants(e, [users[0], users[1]]) ######################################### print_list(Transaction.objects.all(), "REMOVE users 0, 1") self.assertEqual(e.rest(), 0) ######################################### add_participants(e, {users[0]: self.parts[0]}) ######################################### print_list(Transaction.objects.all(), "RETURNED user 0") self.assertEqual(e.rest(), 0) ######################################### add_participants(e, {users[1]: self.parts[1]}) ######################################### print_list(Transaction.objects.all(), "RETURNED user 1") self.assertEqual(e.rest(), 0) ######################################### remove_participants(e, [users[2]]) ######################################### print_list(Transaction.objects.all(), "REMOVE users 2") self.assertEqual(e.rest(), 0) ######################################### # unparticipated, not lose money self.assertEqual(users[2].balance(), self.ubalance) # recalc party_pay, because participants changed # users debts only on participation list party_pay =\ self.eprice / (self.parts[0] + self.parts[1]) self.assertEqual(users[0].balance(), self.ubalance - party_pay * self.parts[0]) self.assertEqual(users[1].balance(), self.ubalance - party_pay * self.parts[1])
def test_multiple_participation(self): e = Event.objects.get(name="Target") users = Account.objects.filter(user__username__iregex=r'^P\d$') ######################################### add_participants(e, { users[0]: 1, users[1]: 1, users[2]: 1, users[3]: 1 }) ######################################### party_pay = self.eprice / (len(users) - 2) self.assertEqual(users[0].balance(), self.ubalance - party_pay) self.assertEqual(users[1].balance(), self.ubalance - party_pay) self.assertEqual(users[2].balance(), self.ubalance - party_pay) self.assertEqual(users[3].balance(), self.ubalance - party_pay)
def test_recalc_debt(self): e, _, _ = generate_participation([0, 1, 4, 5]) users = Account.objects.filter(user__username__iregex=r'^P\d$') print_list(Transaction.objects.all()) newbies = { users[2]: self.parts[2], users[3]: self.parts[3], } u1_old_balance = users[0].balance() u2_old_balance = users[1].balance() ######################################### add_participants(e, newbies) ######################################### print_list(Transaction.objects.all()) party_pay =\ self.eprice / sum(self.parts) # event should be closed self.assertEqual(e.rest(), 0) self.assertLess(u1_old_balance, users[0].balance()) self.assertLess(u2_old_balance, users[1].balance()) # get from each participant summary only his party-pay self.assertEqual(users[0].balance(), self.ubalance - party_pay * self.parts[0]) self.assertEqual(users[1].balance(), self.ubalance - party_pay * self.parts[1]) self.assertEqual(users[2].balance(), self.ubalance - party_pay * self.parts[2]) self.assertEqual(users[3].balance(), self.ubalance - party_pay * self.parts[3]) self.assertEqual(users[4].balance(), self.ubalance - party_pay * self.parts[4]) self.assertEqual(users[5].balance(), self.ubalance - party_pay * self.parts[5])