Exemplo n.º 1
0
def share_expense_with_group_members(sw: Splitwise, desc, cost, group_id,
                                     date):
    grp = sw.getGroup(group_id)
    current_user = sw.getCurrentUser()
    other_members = [m for m in grp.getMembers() if m.id != current_user.id]
    _debug(current_user)
    _debug(other_members)
    cost_per_user = round(cost / len(grp.members), 2)

    expense = Expense()
    expense.cost = f"{cost}"
    expense.description = f"{desc}"
    expense.group_id = f"{group_id}"
    expense.setDate(date.strftime("%Y/%m/%d"))

    users = []
    for om in other_members:
        user = ExpenseUser()
        user.setId(om.id)
        user.setPaidShare(f"0")
        user.setOwedShare(f"{cost_per_user}")
        users.append(user)
    user = ExpenseUser()
    user.setId(current_user.id)
    user.setPaidShare(f"{cost}")
    user.setOwedShare(f"{cost - len(users) * cost_per_user}")
    users.append(user)
    expense.users = users
    sw.createExpense(expense)
Exemplo n.º 2
0
class GetCategoriesTestCase(unittest.TestCase):
    def setUp(self):
        self.sObj = Splitwise('consumerkey', 'consumersecret')

    def test_getGroup_default_group_success(self, mockMakeRequest):
        mockMakeRequest.return_value = '{"group":{"id":0,"name":"Non-group expenses","created_at":"2012-08-21T16:11:14Z","updated_at":"2020-06-23T09:42:10Z","members":[{"id":79774,"first_name":"Naman","last_name":"Aggarwal","picture":{"small":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/small_mypic.jpg","medium":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/medium_mypic.jpg","large":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/large_mypic.jpg"},"custom_picture":true,"email":"*****@*****.**","registration_status":"confirmed","balance":[{"amount":"115000.0","currency_code":"INR"},{"amount":"2162.82","currency_code":"SGD"}]}],"simplify_by_default":false,"original_debts":[{"to":79774,"from":18145926,"amount":"115000.0","currency_code":"INR"},{"to":79774,"from":784241,"amount":"2162.82","currency_code":"SGD"}],"simplified_debts":[{"to":79774,"from":18145926,"amount":"115000.0","currency_code":"INR"},{"to":79774,"from":784241,"amount":"2162.82","currency_code":"SGD"}],"avatar":{"original":null,"xxlarge":"https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-1000px.png","xlarge":"https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-500px.png","large":"https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-200px.png","medium":"https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-100px.png","small":"https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-50px.png"},"custom_avatar":false,"cover_photo":{"xxlarge":"https://s3.amazonaws.com/splitwise/uploads/group/default_cover_photos/coverphoto-nongroup-1000px.png","xlarge":"https://s3.amazonaws.com/splitwise/uploads/group/default_cover_photos/coverphoto-nongroup-500px.png"}}}'  # noqa: E501
        group = self.sObj.getGroup()
        mockMakeRequest.assert_called_with(
            "https://secure.splitwise.com/api/v3.0/get_group/0")
        self.assertEqual(group.getId(), 0)
        self.assertEqual(group.getName(), "Non-group expenses")
        self.assertEqual(group.getUpdatedAt(), "2020-06-23T09:42:10Z")
        self.assertEqual(len(group.getMembers()), 1)
        self.assertEqual(group.getMembers()[0].getId(), 79774)
        self.assertEqual(group.getMembers()[0].getFirstName(), "Naman")
        self.assertEqual(group.getMembers()[0].getLastName(), "Aggarwal")
        self.assertEqual(
            group.getMembers()[0].getPicture().getSmall(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/small_mypic.jpg"
        )
        self.assertEqual(
            group.getMembers()[0].getPicture().getMedium(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/medium_mypic.jpg"
        )
        self.assertEqual(
            group.getMembers()[0].getPicture().getLarge(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/large_mypic.jpg"
        )
        self.assertEqual(group.getMembers()[0].getEmail(),
                         "*****@*****.**")
        self.assertEqual(group.getMembers()[0].getRegistrationStatus(),
                         "confirmed")
        self.assertEqual(len(group.getMembers()[0].getBalances()), 2)
        self.assertEqual(group.getMembers()[0].getBalances()[0].getAmount(),
                         "115000.0")
        self.assertEqual(
            group.getMembers()[0].getBalances()[0].getCurrencyCode(), "INR")
        self.assertEqual(group.getMembers()[0].getBalances()[1].getAmount(),
                         "2162.82")
        self.assertEqual(
            group.getMembers()[0].getBalances()[1].getCurrencyCode(), "SGD")
        self.assertEqual(len(group.getOriginalDebts()), 2)
        self.assertEqual(group.getOriginalDebts()[0].getToUser(), 79774)
        self.assertEqual(group.getOriginalDebts()[0].getFromUser(), 18145926)
        self.assertEqual(group.getOriginalDebts()[0].getAmount(), "115000.0")
        self.assertEqual(group.getOriginalDebts()[0].getCurrencyCode(), "INR")
        self.assertEqual(group.getOriginalDebts()[1].getToUser(), 79774)
        self.assertEqual(group.getOriginalDebts()[1].getFromUser(), 784241)
        self.assertEqual(group.getOriginalDebts()[1].getAmount(), "2162.82")
        self.assertEqual(group.getOriginalDebts()[1].getCurrencyCode(), "SGD")
        self.assertEqual(len(group.getSimplifiedDebts()), 2)
        self.assertEqual(group.getSimplifiedDebts()[0].getToUser(), 79774)
        self.assertEqual(group.getSimplifiedDebts()[0].getFromUser(), 18145926)
        self.assertEqual(group.getSimplifiedDebts()[0].getAmount(), "115000.0")
        self.assertEqual(group.getSimplifiedDebts()[0].getCurrencyCode(),
                         "INR")
        self.assertEqual(group.getSimplifiedDebts()[1].getToUser(), 79774)
        self.assertEqual(group.getSimplifiedDebts()[1].getFromUser(), 784241)
        self.assertEqual(group.getSimplifiedDebts()[1].getAmount(), "2162.82")
        self.assertEqual(group.getSimplifiedDebts()[1].getCurrencyCode(),
                         "SGD")
        # self.assertEqual(group.getAvatar().getOriginal(), None)
        # self.assertEqual(group.getAvatar().getXxlarge(),
        # "https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-1000px.png")
        # self.assertEqual(group.getAvatar().getXlarge(),
        #  "https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-500px.png")
        # self.assertEqual(group.getAvatar().getLarge(),
        # "https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-200px.png")
        # self.assertEqual(group.getAvatar().getMedium(),
        #  "https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-100px.png")
        # self.assertEqual(group.getAvatar().getSmall(),
        # "https://s3.amazonaws.com/splitwise/uploads/group/default_avatars/avatar-nongroup-50px.png")
        # self.assertEqual(group.getCoverPhoto().getXxlarge(),
        # "https://s3.amazonaws.com/splitwise/uploads/group/default_cover_photos/coverphoto-nongroup-1000px.png")
        # self.assertEqual(group.getCoverPhoto().getXlarge(),
        # "https://s3.amazonaws.com/splitwise/uploads/group/default_cover_photos/coverphoto-nongroup-500px.png")

    def test_getGroup_success(self, mockMakeRequest):
        mockMakeRequest.return_value = '{"group":{"id":10843533,"name":"Flatmates Again","created_at":"2019-01-01T06:01:57Z","updated_at":"2020-06-23T09:33:38Z","members":[{"id":79774,"first_name":"Naman","last_name":"Aggarwal","picture":{"small":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/small_mypic.jpg","medium":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/medium_mypic.jpg","large":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/large_mypic.jpg"},"custom_picture":true,"email":"*****@*****.**","registration_status":"confirmed","balance":[{"currency_code":"SGD","amount":"-14.2"}]},{"id":281236,"first_name":"Siddharth","last_name":"Goel","picture":{"small":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/281236/small_f5fccc37-0a88-4519-9398-59c8c19b92aa.jpeg","medium":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/281236/medium_f5fccc37-0a88-4519-9398-59c8c19b92aa.jpeg","large":"https://splitwise.s3.amazonaws.com/uploads/user/avatar/281236/large_f5fccc37-0a88-4519-9398-59c8c19b92aa.jpeg"},"custom_picture":true,"email":"*****@*****.**","registration_status":"confirmed","balance":[{"currency_code":"SGD","amount":"975.05"}]},{"id":643871,"first_name":"Shantanu","last_name":"Alshi","picture":{"small":"https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-blue19-50px.png","medium":"https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-blue19-100px.png","large":"https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-blue19-200px.png"},"custom_picture":false,"email":"*****@*****.**","registration_status":"confirmed","balance":[{"currency_code":"SGD","amount":"-960.85"}]},{"id":784241,"first_name":"ruks","last_name":null,"picture":{"small":"https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-ruby47-50px.png","medium":"https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-ruby47-100px.png","large":"https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-ruby47-200px.png"},"custom_picture":false,"email":"*****@*****.**","registration_status":"confirmed","balance":[{"currency_code":"SGD","amount":"0.0"}]}],"simplify_by_default":true,"original_debts":[{"from":281236,"to":79774,"amount":"2307.23","currency_code":"SGD"},{"currency_code":"SGD","from":79774,"to":643871,"amount":"2311.77"},{"currency_code":"SGD","from":79774,"to":784241,"amount":"9.66"},{"from":643871,"to":281236,"amount":"2520.67","currency_code":"SGD"},{"from":784241,"to":281236,"amount":"761.61","currency_code":"SGD"},{"currency_code":"SGD","from":643871,"to":784241,"amount":"751.95"}],"simplified_debts":[{"from":79774,"to":281236,"amount":"14.2","currency_code":"SGD"},{"from":643871,"to":281236,"amount":"960.85","currency_code":"SGD"}],"whiteboard":null,"group_type":"apartment","invite_link":"https://www.splitwise.com/join/d7bsHriQF5A+1pjy","avatar":{"original":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg","xxlarge":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/xxlarge_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg","xlarge":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/xlarge_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg","large":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/large_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg","medium":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/medium_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg","small":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/small_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg"},"custom_avatar":true,"cover_photo":{"xxlarge":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/xxlarge_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg","xlarge":"https://splitwise.s3.amazonaws.com/uploads/group/avatar/10843533/xlarge_a3734b4d-817e-42f4-9763-8001b12e33b8.jpeg"}}}'  # noqa: E501
        group = self.sObj.getGroup(10843533)
        mockMakeRequest.assert_called_with(
            "https://secure.splitwise.com/api/v3.0/get_group/10843533")

        self.assertEqual(group.getId(), 10843533)
        self.assertEqual(group.getName(), "Flatmates Again")
        # self.assertEqual(group.getCreatedAt(), "2019-01-01T06:01:57Z")
        self.assertEqual(group.getUpdatedAt(), "2020-06-23T09:33:38Z")
        self.assertEqual(len(group.getMembers()), 4)
        self.assertEqual(group.getMembers()[0].getId(), 79774)
        self.assertEqual(group.getMembers()[0].getFirstName(), "Naman")
        self.assertEqual(group.getMembers()[0].getLastName(), "Aggarwal")
        self.assertEqual(
            group.getMembers()[0].getPicture().getSmall(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/small_mypic.jpg"
        )
        self.assertEqual(
            group.getMembers()[0].getPicture().getMedium(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/medium_mypic.jpg"
        )
        self.assertEqual(
            group.getMembers()[0].getPicture().getLarge(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/79774/large_mypic.jpg"
        )
        self.assertEqual(group.getMembers()[0].getEmail(),
                         "*****@*****.**")
        self.assertEqual(group.getMembers()[0].getRegistrationStatus(),
                         "confirmed")
        self.assertEqual(len(group.getMembers()[0].getBalances()), 1)
        self.assertEqual(
            group.getMembers()[0].getBalances()[0].getCurrencyCode(), "SGD")
        self.assertEqual(group.getMembers()[0].getBalances()[0].getAmount(),
                         "-14.2")
        self.assertEqual(group.getMembers()[1].getId(), 281236)
        self.assertEqual(group.getMembers()[1].getFirstName(), "Siddharth")
        self.assertEqual(group.getMembers()[1].getLastName(), "Goel")
        self.assertEqual(
            group.getMembers()[1].getPicture().getSmall(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/281236/small_f5fccc37-0a88-4519-9398-59c8c19b92aa.jpeg"
        )
        self.assertEqual(
            group.getMembers()[1].getPicture().getMedium(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/281236/medium_f5fccc37-0a88-4519-9398-59c8c19b92aa.jpeg"
        )
        self.assertEqual(
            group.getMembers()[1].getPicture().getLarge(),
            "https://splitwise.s3.amazonaws.com/uploads/user/avatar/281236/large_f5fccc37-0a88-4519-9398-59c8c19b92aa.jpeg"
        )
        self.assertEqual(group.getMembers()[1].getEmail(),
                         "*****@*****.**")
        self.assertEqual(group.getMembers()[1].getRegistrationStatus(),
                         "confirmed")
        self.assertEqual(len(group.getMembers()[1].getBalances()), 1)
        self.assertEqual(
            group.getMembers()[1].getBalances()[0].getCurrencyCode(), "SGD")
        self.assertEqual(group.getMembers()[1].getBalances()[0].getAmount(),
                         "975.05")
        self.assertEqual(group.getMembers()[2].getId(), 643871)
        self.assertEqual(group.getMembers()[2].getFirstName(), "Shantanu")
        self.assertEqual(group.getMembers()[2].getLastName(), "Alshi")
        self.assertEqual(
            group.getMembers()[2].getPicture().getSmall(),
            "https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-blue19-50px.png"
        )
        self.assertEqual(
            group.getMembers()[2].getPicture().getMedium(),
            "https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-blue19-100px.png"
        )
        self.assertEqual(
            group.getMembers()[2].getPicture().getLarge(),
            "https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-blue19-200px.png"
        )
        self.assertEqual(group.getMembers()[2].getEmail(),
                         "*****@*****.**")
        self.assertEqual(group.getMembers()[2].getRegistrationStatus(),
                         "confirmed")
        self.assertEqual(len(group.getMembers()[2].getBalances()), 1)
        self.assertEqual(
            group.getMembers()[2].getBalances()[0].getCurrencyCode(), "SGD")
        self.assertEqual(group.getMembers()[2].getBalances()[0].getAmount(),
                         "-960.85")
        self.assertEqual(group.getMembers()[3].getId(), 784241)
        self.assertEqual(group.getMembers()[3].getFirstName(), "ruks")
        self.assertEqual(group.getMembers()[3].getLastName(), None)
        self.assertEqual(
            group.getMembers()[3].getPicture().getSmall(),
            "https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-ruby47-50px.png"
        )
        self.assertEqual(
            group.getMembers()[3].getPicture().getMedium(),
            "https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-ruby47-100px.png"
        )
        self.assertEqual(
            group.getMembers()[3].getPicture().getLarge(),
            "https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-ruby47-200px.png"
        )

    def test_getGroup_exception(self, mockMakeRequest):
        mockMakeRequest.side_effect = Exception(
            "Invalid response %s. Please check your consumer key and secret." %
            404)
        with self.assertRaises(Exception):
            self.sObj.getGroup(123)
        mockMakeRequest.assert_called_with(
            "https://secure.splitwise.com/api/v3.0/get_group/123")
Exemplo n.º 3
0
class SplitwiseInterface:
    def __init__(self):
        self.consumer_key = getConsumerKey()
        self.consumer_secret = getConsumerSecret()
        self.oauth_verifier = None
        self.oauth_token = None
        self.access_token = getAccessToken()
        self.login_secret = None
        self.url = None
        self.sObj = Splitwise(self.consumer_key, self.consumer_secret)
        self.sObj.setAccessToken(self.access_token)

    def accessCheck(self) -> None:
        """
        Checks for access token. Starts login process if not
        """

        if self.access_token:
            return
        self.access_token = self.login()

    def login(self) -> None:
        """
        Logs into Splitwise. Requires manually entering the token and verifier
        """

        sObj = Splitwise(self.consumer_key, self.consumer_secret)
        self.url, self.login_secret = sObj.getAuthorizeURL()
        print(self.url)
        self.oauth_token = input('token: ')
        self.oauth_verifier = input('verifier: ')

    def authorize(self) -> None:
        """
        Authorizes app to Splitwise
        """

        if not self.login_secret:
            #TODO trigger error
            self.login()

        sObj = Splitwise(self.consumer_key, self.consumer_secret)
        self.access_token = sObj.getAccessToken(self.oauth_token,
                                                self.login_secret,
                                                self.oauth_verifier)

    def friends(self) -> List['Friend']:
        """
        Returns list of Friend objects for the current user
        """

        return self.sObj.getFriends()

    def getCurrentUser(self) -> 'CurrentUser':
        """
        Returns CurrentUser object for the current user
        """
        return self.sObj.getCurrentUser()

    def getGroup(self, group_id: int) -> 'Group':
        """
        Returns Group object for the given group_id
        """
        return self.sObj.getGroup(group_id)

    def getGroupMemberIDs(self, group: 'Group') -> Dict[str, int]:
        """
        Returns a dict of group members {name:id} from a given Group object
        """
        member_object_list = group.getMembers()
        member_dict = {}
        for member in member_object_list:
            member_dict[member.getFirstName()] = member.getId()
        return member_dict

    def addExpense(self, cost: float, description: str, group_id: int,
                   payer: str) -> None:
        """
        Adds expense to Splitwise group. If expenses don't evenly get 
        distributed, it will randomly assign pennies to even things off
        """
        expense = Expense()
        expense.setCost(str(cost))
        expense.setDescription(description)
        expense.setGroupId(group_id)

        group = self.sObj.getGroup(group_id)
        member_dict = self.getGroupMemberIDs(group)
        member_count = len(member_dict)
        per_person_cost = round(cost / member_count, 2)
        expense_members = []
        print(per_person_cost * member_count, cost)
        for member in member_dict:
            expense_user = ExpenseUser()
            expense_user.setId(member_dict[member])
            expense_user.setFirstName(member)
            expense_user.setOwedShare(str(per_person_cost))

            if member == payer:
                expense_user.setPaidShare(cost)
            else:
                expense_user.setPaidShare('0.00')

            expense_members.append(expense_user)

        if cost < per_person_cost * member_count:
            remainder = (per_person_cost * float(member_count)) - cost
            shuffle(expense_members)
            i = 0
            while remainder > 0.00:
                owed = float(expense_members[i].getOwedShare())
                owed -= 0.01
                expense_members[i].setOwedShare(str(owed))
                remainder -= 0.01
                if i == member_count - 1:
                    i = 0
                else:
                    i += 1

        elif cost > per_person_cost * member_count:
            remainder = round(cost - (per_person_cost * float(member_count)),
                              2)
            print(remainder)
            shuffle(expense_members)
            i = 0
            while remainder > 0.00:
                owed = float(expense_members[i].getOwedShare())
                owed += 0.01
                expense_members[i].setOwedShare(str(owed))
                remainder -= 0.01
                if i == member_count - 1:
                    i = 0
                else:
                    i += 1

        expense.setUsers(expense_members)
        expenses = self.sObj.createExpense(expense)
        print('Successfully added to Splitwise. Expense ID:', expenses.getId())
Exemplo n.º 4
0
import json
from splitwise import Splitwise
import config
import utils
from excel import generate_expenses_xlsx
import yacht_expense_details

s = Splitwise(config.consumer_key,
              config.consumer_secret,
              api_key=config.API_key)
utils.create_folder(config.json_filename)
expenses = s.getExpenses(group_id=config.group_id,
                         limit=config.expenses_list_limit)
group = s.getGroup(id=config.group_id)
members_json = group.__dict__['members']
members_array = json.loads(
    json.dumps(members_json, default=lambda o: o.__dict__, ensure_ascii=False))


def expenses_to_json(expenses):
    expenses_array = []
    for expense in expenses:
        comments = s.getComments(expense.id)
        js = json.loads(
            json.dumps(expense.__dict__,
                       default=lambda o: o.__dict__,
                       ensure_ascii=False))
        js['comments'] = json.loads(
            json.dumps(comments,
                       default=lambda o: o.__dict__,
                       ensure_ascii=False))