예제 #1
0
def test_paybacks(collective_with_transfers_for_payback):
    collective, user_1, user_2, user_3 = collective_with_transfers_for_payback

    paybacks = calc_paybacks(collective)
    assert len(paybacks) == 3

    assert paybacks[0].debtor == user_3
    assert paybacks[0].creditor == user_1
    assert paybacks[0].amount == 48.33333333333333

    assert paybacks[1].debtor == user_3
    assert paybacks[1].creditor == user_2
    assert paybacks[1].amount == 8.333333333333329

    assert paybacks[2].debtor == user_1
    assert paybacks[2].creditor == user_2
    assert paybacks[2].amount == 50.0

    # Adding a Liquidation can flip the creditor/debtor relation,
    # as otherwise the balance would become negative.
    mommy.make("purchases.Liquidation",
               collective=collective,
               creditor=user_1,
               debtor=user_2,
               amount=60.0)
    paybacks = calc_paybacks(collective)
    assert len(paybacks) == 3

    assert paybacks[0].debtor == user_3
    assert paybacks[0].creditor == user_1
    assert paybacks[0].amount == 48.33333333333333

    assert paybacks[1].debtor == user_3
    assert paybacks[1].creditor == user_2
    assert paybacks[1].amount == 8.333333333333329

    assert paybacks[2].debtor == user_2
    assert paybacks[2].creditor == user_1
    assert paybacks[2].amount == 10.0
예제 #2
0
파일: tests.py 프로젝트: seyi/payshare
def test_calc_paybacks_with_negative_transfers(collective):
    user_1 = mommy.make("auth.User", username="******")
    user_2 = mommy.make("auth.User", username="******")
    user_3 = mommy.make("auth.User", username="******")

    collective.add_member(user_1)
    collective.add_member(user_2)
    collective.add_member(user_3)

    mommy.make("purchases.Purchase",
               collective=collective,
               buyer=user_1,
               name="Electricty Bill Refund",
               price=-90.00)

    mommy.make("purchases.Purchase",
               collective=collective,
               buyer=user_2,
               name="Pizza",
               price=15.00)

    mommy.make("purchases.Liquidation",
               collective=collective,
               creditor=user_2,
               debtor=user_3,
               name="This makes no sense, but hey",
               amount=-5.00)

    paybacks = calc_paybacks(collective)
    assert len(paybacks) == 3

    data = [(payback.debtor, payback.creditor, payback.amount)
            for payback in paybacks]
    assert (user_1, user_2, 40.00) in data
    assert (user_1, user_3, 25.00) in data
    assert (user_2, user_3, 5.00) in data
예제 #3
0
파일: api.py 프로젝트: hackerESQ/payshare
def cashup(request, key):
    collective = collective_from_key(key)
    paybacks = [payback.to_json() for payback in calc_paybacks(collective)]
    return Response(paybacks)
예제 #4
0
    def stats(self):
        """Calculate financial status for each member of the Collective.

        Returns:

            {
                'median_debt': 50.00,
                'median_purchased': 15.95,
                'overall_debt': 50.00,
                'overall_purchased': 603.45,
                'member_id_to_balance': {
                    '<member1-id>': -140.23,
                    '<member2-id>': 67.04,
                    ...
                },
                'cashup': [
                    {'debtor': ..., 'creditor': ..., 'amount': ...},
                    ...
                ],
            }

        """
        collective = self

        members = collective.members
        num_members = len(members)

        purchases = collective.purchases
        num_purchases = purchases.count()

        liquidations = collective.liquidations
        num_liquidations = liquidations.count()

        prices = [float(purchase.price.amount) for purchase in purchases]
        overall_purchased = sum(prices)
        per_member = float(overall_purchased) / float(num_members)

        debts = [
            float(liquidation.amount.amount) for liquidation in liquidations
        ]
        overall_debt = sum(debts)

        median_purchased = 0
        if prices:
            median_purchased = median(prices)

        median_debt = 0
        if debts:
            median_debt = median(debts)

        member_id_to_balance = {}
        for member in collective.members:
            member_purchased = sum([
                float(purchase.price.amount) for purchase in purchases
                if purchase.buyer == member
            ])

            credit = sum([
                float(liq.amount.amount) for liq in liquidations
                if liq.creditor == member
            ])
            debt = sum([
                float(liq.amount.amount) for liq in liquidations
                if liq.debtor == member
            ])
            has_to_pay = (per_member - float(member_purchased) -
                          float(credit) + float(debt))

            balance = has_to_pay * -1
            if balance == 0:  # Remove '-' from the display.
                balance = 0
            member_id_to_balance[member.id] = balance

        sorted_balances = sorted(member_id_to_balance.items(),
                                 key=lambda item: item[1],
                                 reverse=True)

        serialized_paybacks = [
            payback.to_json() for payback in calc_paybacks(collective)
        ]

        stats = {
            "median_debt": median_debt,
            "median_purchased": median_purchased,
            "num_liquidations": num_liquidations,
            "num_purchases": num_purchases,
            "overall_debt": overall_debt,
            "overall_purchased": overall_purchased,
            "sorted_balances": sorted_balances,
            "cashup": serialized_paybacks,
        }
        return stats