def make_exchange(self,
                   route,
                   amount,
                   fee,
                   participant,
                   status='succeeded',
                   error='',
                   vat=0):
     amount = amount if isinstance(amount, Money) else Money(amount, 'EUR')
     fee = fee if isinstance(fee, Money) else Money(fee, amount.currency)
     vat = vat if isinstance(vat, Money) else Money(vat, fee.currency)
     if not isinstance(route, ExchangeRoute):
         network = route
         currency = amount.currency if network == 'mango-cc' else None
         routes = ExchangeRoute.from_network(participant,
                                             network,
                                             currency=currency)
         if routes:
             route = routes[0]
         else:
             from .mangopay import MangopayHarness
             address = MangopayHarness.card_id if network == 'mango-cc' else -participant.id
             route = ExchangeRoute.insert(participant,
                                          network,
                                          address,
                                          'chargeable',
                                          currency=currency)
             assert route
     e_id = record_exchange(self.db, route, amount, fee, vat, participant,
                            'pre').id
     record_exchange_result(self.db, e_id, -e_id, status, error,
                            participant)
     return e_id
Esempio n. 2
0
 def test_cbor_serialization_of_Money_with_extra_attribute(self):
     expected = Money('0.01', 'EUR')
     expected.fuzzy = True
     actual = cbor.loads(cbor.dumps(expected))
     assert expected.__dict__ == {
         'amount': Decimal('0.01'),
         'currency': 'EUR',
         'fuzzy': True,
     }
     assert expected.__dict__ == actual.__dict__
Esempio n. 3
0
 def test_cbor_serialization_of_Money_with_extra_attribute(self):
     expected = Money('0.01', 'EUR')
     expected.fuzzy = True
     actual = cbor.loads(cbor.dumps(expected))
     assert expected.__dict__ == {
         'amount': Decimal('0.01'),
         'currency': 'EUR',
         'fuzzy': True,
     }
     assert expected.__dict__ == actual.__dict__
Esempio n. 4
0
def fake_participant(db, kind=None):
    """Create a fake User.
    """
    username = faker.first_name() + fake_text_id(3)
    kind = kind or random.choice(('individual', 'organization'))
    is_a_person = kind in ('individual', 'organization')
    try:
        p = _fake_thing(
            db,
            "participants",
            username=username,
            email=username+'@example.org',
            balance=Money('0.00', 'EUR'),
            hide_giving=is_a_person and (random.randrange(5) == 0),
            hide_receiving=is_a_person and (random.randrange(5) == 0),
            status='active',
            join_time=faker.date_time_this_year(),
            kind=kind,
            mangopay_user_id=username,
            _cast=True,
        )
    except IntegrityError:
        return fake_participant(db)

    # Create wallet
    _fake_thing(
        db,
        "wallets",
        remote_id='-%i' % p.id,
        balance=p.balance,
        owner=p.id,
        remote_owner_id=p.mangopay_user_id,
    )

    return p
Esempio n. 5
0
 def add_member(self, member, cursor=None):
     """Add a member to this team.
     """
     if self.nmembers >= 149:
         raise MemberLimitReached
     if member.status != 'active':
         raise InactiveParticipantAdded
     self.set_take_for(member, Money(-1, member.main_currency), self, cursor=cursor)
Esempio n. 6
0
def fake_tip(db, tipper, tippee):
    """Create a fake tip.
    """
    period = random.choice(DONATION_PERIODS)
    limits = [l.amount for l in DONATION_LIMITS['EUR'][period]]
    periodic_amount = random_money_amount(*limits)
    amount = (periodic_amount * PERIOD_CONVERSION_RATES[period]).quantize(D_CENT)
    return _fake_thing(
        db,
        "tips",
        ctime=faker.date_time_this_year(),
        mtime=faker.date_time_this_month(),
        tipper=tipper.id,
        tippee=tippee.id,
        amount=Money(amount, 'EUR'),
        period=period,
        periodic_amount=Money(periodic_amount, 'EUR'),
    )
Esempio n. 7
0
 def compute_max_this_week(self, member_id, last_week, currency):
     """2x the member's take last week, or the member's take last week + the
     leftover, or last week's median take, or one currency unit (e.g. €1.00).
     """
     nonzero_last_week = [a.convert(currency).amount for a in last_week.values() if a]
     member_last_week = last_week.get(member_id, Money.ZEROS[currency]).convert(currency)
     return max(
         member_last_week * 2,
         member_last_week + last_week.initial_leftover.convert(currency),
         Money(median(nonzero_last_week or (0,)), currency),
         TAKE_THROTTLING_THRESHOLD[currency]
     )
Esempio n. 8
0
    def test_convert_non_euro(self):
        original = Money('1.00', 'CHF')
        expected = Money('0.82', 'GBP')
        actual = self.db.one("SELECT convert(%s, %s)", (original, expected.currency))
        assert expected == actual
        actual = original.convert(expected.currency)
        assert expected == actual

        original = Money('1.20', 'USD')
        expected = Money('125', 'JPY')
        actual = self.db.one("SELECT convert(%s, %s)", (original, expected.currency))
        assert expected == actual
        actual = original.convert(expected.currency)
        assert expected == actual
 def test_sign_in_through_donation_form(self):
     alice = self.make_participant('alice', accepted_currencies=None)
     extra = {
         'amount': '10000',
         'currency': 'KRW',
         'period': 'weekly',
         'form.repost': 'true'
     }
     r = self.sign_in(url='/~1/tip', extra=extra)
     assert r.code == 302, r.text
     assert r.headers[b'Location'].startswith(
         b'http://localhost/bob/giving/')
     bob = Participant.from_username('bob')
     tip = bob.get_tip_to(alice)
     assert tip.amount == Money('10000', 'KRW')
     assert bob.main_currency == 'KRW'
Esempio n. 10
0
 def cast_currency_amount(v, cursor):
     return None if v in (None, '(,)') else Money(*v[1:-1].split(','))
def USD(amount):
    return Money(amount, 'USD')
def JPY(amount):
    return Money(amount, 'JPY')
def EUR(amount):
    return Money(amount, 'EUR')
Esempio n. 14
0
 def test_sorting(self):
     amounts = [JPY('130'), EUR('99.58'), Money('79', 'KRW'), USD('35.52')]
     expected = sorted(amounts, key=lambda m: -m.convert('EUR').amount)
     actual = self.db.all("SELECT x FROM unnest(%s) x ORDER BY x DESC",
                          (amounts, ))
     assert expected == actual
Esempio n. 15
0
def KRW(amount):
    return Money(amount, 'KRW')
Esempio n. 16
0
 def test_rounding(self):
     assert Money('0.001', 'EUR').round() == Money('0.00', 'EUR')
     assert Money('0.009', 'EUR').round_down() == Money('0.00', 'EUR')
     assert Money('0.002', 'EUR').round_up() == Money('0.01', 'EUR')
     assert Money('0.1', 'JPY').round() == Money('0', 'JPY')
     assert Money('0.9', 'JPY').round_down() == Money('0', 'JPY')
     assert Money('0.2', 'JPY').round_up() == Money('1', 'JPY')
Esempio n. 17
0
 def test_cbor_serialization_of_Money(self):
     expected = Money('9999999999.99', 'EUR')
     actual = cbor.loads(cbor.dumps(expected))
     assert expected == actual
Esempio n. 18
0
 def test_cbor_serialization_of_Money_with_extra_attribute(self):
     expected = Money('0.01', 'EUR', fuzzy=True)
     actual = cbor.loads(cbor.dumps(expected))
     assert expected == actual
     assert expected.fuzzy == actual.fuzzy
Esempio n. 19
0
def populate_db(website, num_participants=100, num_tips=200, num_teams=5, num_transfers=5000, num_communities=20):
    """Populate DB with fake data.
    """
    db = website.db

    # Speed things up
    db.run("""
        DO $$ BEGIN
            EXECUTE 'ALTER DATABASE '||current_database()||' SET synchronous_commit TO off';
        END $$
    """)

    print("Making Participants")
    participants = []
    for i in range(num_participants):
        participants.append(fake_participant(db))

    print("Making Teams")
    teams = []
    for i in range(num_teams):
        team = fake_participant(db, kind="group")
        # Add 1 to 3 members to the team
        members = random.sample(participants, random.randint(1, 3))
        for p in members:
            team.add_member(p)
        teams.append(team)
    participants.extend(teams)

    print("Making Elsewheres")
    platforms = [p.name for p in website.platforms]
    for p in participants:
        # All participants get between 0 and 3 elsewheres
        num_elsewheres = random.randint(0, 3)
        for platform_name in random.sample(platforms, num_elsewheres):
            fake_elsewhere(db, p, platform_name)

    print("Making Communities")
    for i in range(num_communities):
        creator = random.sample(participants, 1)
        community = fake_community(db, creator[0])

        members = random.sample(participants, random.randint(1, 3))
        for p in members:
            p.upsert_community_membership(True, community.id)

    print("Making Tips")
    tips = []
    for i in range(num_tips):
        tipper, tippee = random.sample(participants, 2)
        tips.append(fake_tip(db, tipper, tippee))

    # Transfers
    min_amount, max_amount = [l.amount for l in DONATION_LIMITS['EUR']['weekly']]
    transfers = []
    for i in range(num_transfers):
        tipper, tippee = random.sample(participants, 2)
        while tipper.kind in ('group', 'community') or \
              tippee.kind in ('group', 'community'):
            tipper, tippee = random.sample(participants, 2)
        sys.stdout.write("\rMaking Transfers (%i/%i)" % (i+1, num_transfers))
        sys.stdout.flush()
        amount = Money(random_money_amount(min_amount, max_amount), 'EUR')
        zero = amount.zero()
        ts = faker.date_time_this_year()
        fake_exchange(db, tipper, amount, zero, zero, (ts - datetime.timedelta(days=1)))
        transfers.append(fake_transfer(db, tipper, tippee, amount, ts))
    print("")

    # Paydays
    # First determine the boundaries - min and max date
    min_date = min(min(x.ctime for x in tips),
                   min(x.timestamp for x in transfers))
    max_date = max(max(x.ctime for x in tips),
                   max(x.timestamp for x in transfers))
    # iterate through min_date, max_date one week at a time
    payday_counter = 1
    date = min_date
    paydays_total = (max_date - min_date).days/7 + 1
    while date < max_date:
        sys.stdout.write("\rMaking Paydays (%i/%i)" % (payday_counter, paydays_total))
        sys.stdout.flush()
        payday_counter += 1
        end_date = date + datetime.timedelta(days=7)
        week_tips = [x for x in tips if date < x.ctime < end_date]
        week_transfers = [x for x in transfers if date < x.timestamp < end_date]
        week_participants = [x for x in participants if x.join_time < end_date]
        actives = set()
        tippers = set()
        for xfers in week_tips, week_transfers:
            actives.update(x.tipper for x in xfers)
            actives.update(x.tippee for x in xfers)
            tippers.update(x.tipper for x in xfers)
        payday = {
            'ts_start': date,
            'ts_end': end_date,
            'ntips': len(week_tips),
            'ntransfers': len(week_transfers),
            'nparticipants': len(week_participants),
            'ntippers': len(tippers),
            'nactive': len(actives),
            'transfer_volume': MoneyBasket(x.amount for x in week_transfers),
            'public_log': '',
        }
        _fake_thing(db, "paydays", **payday)
        date = end_date
    print("")