Skip to content

Commit

Permalink
Merge pull request #38 from andreasalstrup/ExpensesBalance
Browse files Browse the repository at this point in the history
Expenses tab: Balance screen
  • Loading branch information
andreasalstrup authored Nov 22, 2023
2 parents 77609f7 + d626f1b commit a3471da
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 47 deletions.
73 changes: 56 additions & 17 deletions app/(tabs)/expenses/balance.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,71 @@
import { StyleSheet } from 'react-native';
import { Text, View, } from '../../../components/Themed';
import { FlatList } from 'react-native-gesture-handler';
import { calculateBalance } from '../../../helpers/calculateBalance';


type Expense = {
user: string;
amount: number;
};

const DATA: Expense[] = [
{ user: 'Martin', amount: 90 },
{ user: 'Andreas', amount: 30 },
{ user: 'Bisgaard', amount: 0 },
{ user: 'Mike', amount: 85 },
];

const calculatedBalances = calculateBalance(DATA);

import EditScreenInfo from '../../../components/EditScreenInfo';
import { Text, View } from '../../../components/Themed';

export default function BalanceScreen() {

const renderItem = ({ item, index }: { item: Expense; index: number }) => {
return (
<View style={[styles.container, { backgroundColor: index % 2 == 0 ? '#eeeeee' : '#D3D3D3' }]}>
<View style={styles.item}>
<Text style={styles.itemText}>{item.user}</Text>
<Text style={[styles.itemAmount, { color: item.amount >= 0 ? (item.amount == 0 ? 'black' : '#5CBCA9') : '#E35F52' }]}>
{item.amount > 0 ? "+" + item.amount.toFixed(2) : item.amount.toFixed(2)} kr.
</Text>
</View>
</View>
);
};

return (
<View style={styles.container}>
<Text style={styles.title}>Balance</Text>
<View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
<EditScreenInfo path="app/(tabs)/expenses/balance.tsx" />
<View>
<FlatList
style={{marginTop: 48}}
data={calculatedBalances}
renderItem={renderItem}
/>
</View>
);
}

const styles = StyleSheet.create({
container: {
marginTop: 48,
flex: 1,
alignItems: 'center',
justifyContent: 'center',
borderBottomColor: '#000000',
padding: 2,
},
item: {
backgroundColor: 'transparent',
borderBottomColor: '#000000',
borderBottomWidth: 0,
padding: 12,
flexDirection: 'row',
justifyContent: 'space-between'
},
title: {
fontSize: 20,
fontWeight: 'bold',
itemText: {
fontSize: 24,
color: 'black',
flexDirection: 'row',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
itemAmount: {
fontSize: 24,
flexDirection: 'row',
justifyContent: 'flex-end'
},
});
4 changes: 0 additions & 4 deletions app/(tabs)/expenses/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,6 @@ const styles = StyleSheet.create({
},
swipeIcon: {
padding: 10,
},
longBoi: {
flexDirection: 'row',
justifyContent: 'flex-end'
},
modalContainer: {
flex: 1,
Expand Down
30 changes: 30 additions & 0 deletions helpers/calculateBalance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
type Expense = {
user: string;
amount: number;
};

export const calculateBalance = (expenses: Expense[]) => {
const totalSpent: { [name: string]: number } = {};
const userCount: { [name: string]: number } = {};

expenses.forEach(({ user, amount }) => {
totalSpent[user] = (totalSpent[user] || 0) + amount;
userCount[user] = (userCount[user] || 0) + 1;
});

const users = Object.keys(totalSpent);
const totalUsers = users.length;
const averageAmount = users.reduce((acc, user) => acc + (totalSpent[user] / userCount[user]), 0) / totalUsers;

const calculatedBalances: { [name: string]: number } = {};
users.forEach((user) => {
calculatedBalances[user] = parseFloat(((totalSpent[user] / userCount[user]) - averageAmount).toFixed(2));
});

const calculatedBalancesArray: Expense[] = Object.entries(calculatedBalances).map(([user, amount]) => ({
user,
amount,
}));

return calculatedBalancesArray;
};
52 changes: 26 additions & 26 deletions helpers/calculateExpenses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,34 @@ type Transaction = {
};

export const calculateExpenses = (expenses: Expense[]): Transaction[] => {
// Calculate total spent by each user
const totalSpent: { [name: string]: number } = {};
expenses.forEach((expense) => {
totalSpent[expense.user] = (totalSpent[expense.user] || 0) + expense.amount;
});
// Calculate total spent by each user
const totalSpent: { [name: string]: number } = {};
expenses.forEach((expense) => {
totalSpent[expense.user] = (totalSpent[expense.user] || 0) + expense.amount;
});

// Calculate the average amount spent by all users
const numUsers = Object.keys(totalSpent).length;
const totalAmountSpent = Object.values(totalSpent).reduce((total, amount) => total + amount, 0);
const averageAmount = totalAmountSpent / numUsers;
// Calculate the average amount spent by all users
const numUsers = Object.keys(totalSpent).length;
const totalAmountSpent = Object.values(totalSpent).reduce((total, amount) => total + amount, 0);
const averageAmount = totalAmountSpent / numUsers;

// Calculate who owes or is owed how much
const transactions: Transaction[] = [];
Object.keys(totalSpent).forEach((creditor) => {
let amountOwed = totalSpent[creditor] - averageAmount;
// Calculate who owes or is owed how much
const transactions: Transaction[] = [];
Object.keys(totalSpent).forEach((creditor) => {
let amountOwed = totalSpent[creditor] - averageAmount;

if (amountOwed > 0) {
Object.keys(totalSpent).forEach((debitor) => {
if (creditor !== debitor && totalSpent[debitor] < averageAmount && averageAmount != totalSpent[creditor]) {
const settleAmount = Math.min(amountOwed, averageAmount - totalSpent[debitor]);
transactions.push({ to: creditor, from: debitor, amount: settleAmount });
totalSpent[creditor] -= settleAmount;
totalSpent[debitor] += settleAmount;
amountOwed -= settleAmount;
}
});
}
});
if (amountOwed > 0) {
Object.keys(totalSpent).forEach((debitor) => {
if (creditor !== debitor && totalSpent[debitor] < averageAmount && averageAmount != totalSpent[creditor]) {
const settleAmount = Math.min(amountOwed, averageAmount - totalSpent[debitor]);
transactions.push({ to: creditor, from: debitor, amount: settleAmount });
totalSpent[creditor] -= settleAmount;
totalSpent[debitor] += settleAmount;
amountOwed -= settleAmount;
}
});
}
});

return transactions;
return transactions;
};

0 comments on commit a3471da

Please sign in to comment.