@@ -23,6 +23,7 @@ class GroupBalancesViewModel: BaseViewModel, ObservableObject {
23
23
@Published var payerId : String ?
24
24
@Published var receiverId : String ?
25
25
@Published var amount : Double ?
26
+ @Published var amountCurrency : String ?
26
27
27
28
private var groupMemberData : [ AppUser ] = [ ]
28
29
let router : Router < AppRoute >
@@ -47,7 +48,7 @@ class GroupBalancesViewModel: BaseViewModel, ObservableObject {
47
48
// MARK: - Data Loading
48
49
func fetchGroupWithMembers( ) async {
49
50
do {
50
- self . group = try await groupRepository. fetchGroupBy ( id: groupId)
51
+ group = try await groupRepository. fetchGroupBy ( id: groupId)
51
52
guard let group else {
52
53
viewState = . initial
53
54
return
@@ -72,42 +73,46 @@ class GroupBalancesViewModel: BaseViewModel, ObservableObject {
72
73
73
74
let filteredBalances = group. balances. filter { group. members. contains ( $0. id) }
74
75
75
- let memberBalances = filteredBalances. flatMap { balance in
76
- balance. balanceByCurrency. map { ( currency, balanceDetails) in
77
- // Create a combined balance for each currency
78
- MembersCombinedBalance ( id: balance. id, totalOwedAmount: [ currency: balanceDetails. balance] ,
79
- balances: [ currency: [ balance. id: balanceDetails. balance] ] )
76
+ let memberBalances = filteredBalances. map { balance in
77
+ var totalOwedAmount : [ String : Double ] = [ : ]
78
+ var balances : [ String : [ String : Double ] ] = [ : ]
79
+
80
+ for (currency, balanceDetails) in balance. balanceByCurrency {
81
+ totalOwedAmount [ currency] = balanceDetails. balance
82
+ balances [ currency, default: [ : ] ] [ balance. id] = balanceDetails. balance
80
83
}
84
+
85
+ return MembersCombinedBalance ( id: balance. id, totalOwedAmount: totalOwedAmount, balances: balances)
81
86
}
82
87
83
88
// Calculate settlements between group members
84
89
let settlements = calculateSettlements ( balances: filteredBalances)
85
90
86
- // Merge settlements with member balances
87
- let combinedBalances = settlements. reduce ( into: memberBalances) { balances, settlement in
88
- // Find sender and receiver indices in the balances list
89
- if let senderIndex = balances. firstIndex ( where: { $0. id == settlement. sender } ) ,
90
- let receiverIndex = balances. firstIndex ( where: { $0. id == settlement. receiver } ) {
91
-
92
- // Handle sender's balance update
93
- if balances [ senderIndex] . balances [ settlement. currency] != nil {
94
- // If currency balance exists for sender, subtract the settlement amount
95
- balances [ senderIndex] . balances [ settlement. currency] ? [ settlement. receiver, default: 0.0 ] -= settlement. amount
96
- } else {
97
- // If no balance exists, initialize the currency balance for the sender
98
- balances [ senderIndex] . balances [ settlement. currency] = [ settlement. receiver: - settlement. amount]
99
- }
100
-
101
- // Handle receiver's balance update
102
- if balances [ receiverIndex] . balances [ settlement. currency] != nil {
103
- balances [ receiverIndex] . balances [ settlement. currency] ? [ settlement. sender, default: 0.0 ] += settlement. amount
104
- } else {
105
- balances [ receiverIndex] . balances [ settlement. currency] = [ settlement. sender: settlement. amount]
106
- }
91
+ // Merge settlements into member balances
92
+ var combinedBalances = memberBalances
93
+ for settlement in settlements {
94
+ guard let senderIndex = combinedBalances. firstIndex ( where: { $0. id == settlement. sender } ) ,
95
+ let receiverIndex = combinedBalances. firstIndex ( where: { $0. id == settlement. receiver } ) else {
96
+ continue
107
97
}
98
+
99
+ combinedBalances [ senderIndex] . balances [ settlement. currency, default: [ : ] ] [ settlement. receiver] = - settlement. amount
100
+ combinedBalances [ receiverIndex] . balances [ settlement. currency, default: [ : ] ] [ settlement. sender] = settlement. amount
101
+ }
102
+
103
+ // Remove self-referencing balances
104
+ combinedBalances = combinedBalances. map { memberBalance in
105
+ var filteredBalances : [ String : [ String : Double ] ] = [ : ]
106
+ for (currency, balanceDetails) in memberBalance. balances {
107
+ filteredBalances [ currency] = balanceDetails. filter { $0. key != memberBalance. id }
108
+ }
109
+
110
+ return MembersCombinedBalance ( id: memberBalance. id, isExpanded: memberBalance. isExpanded,
111
+ totalOwedAmount: memberBalance. totalOwedAmount,
112
+ balances: filteredBalances)
108
113
}
109
114
110
- self . sortMemberBalances ( memberBalances: combinedBalances)
115
+ sortMemberBalances ( memberBalances: combinedBalances)
111
116
}
112
117
113
118
private func sortMemberBalances( memberBalances: [ MembersCombinedBalance ] ) {
@@ -153,10 +158,11 @@ class GroupBalancesViewModel: BaseViewModel, ObservableObject {
153
158
}
154
159
}
155
160
156
- func handleSettleUpTap( payerId: String , receiverId: String , amount: Double ) {
161
+ func handleSettleUpTap( payerId: String , receiverId: String , amount: Double , currency : String ) {
157
162
self . payerId = payerId
158
163
self . receiverId = receiverId
159
164
self . amount = amount
165
+ self . amountCurrency = currency
160
166
showSettleUpSheet = true
161
167
}
162
168
@@ -179,10 +185,10 @@ class GroupBalancesViewModel: BaseViewModel, ObservableObject {
179
185
180
186
// MARK: - Struct to hold combined expense and user owe amount
181
187
struct MembersCombinedBalance {
182
- let id : String
188
+ let id : String /// member id
183
189
var isExpanded : Bool = false
184
- var totalOwedAmount : [ String : Double ] = [ : ]
185
- var balances : [ String : [ String : Double ] ] = [ : ]
190
+ var totalOwedAmount : [ String : Double ] = [ : ] /// [currency: amount]
191
+ var balances : [ String : [ String : Double ] ] = [ : ] /// [currency: [memberId: amount]]
186
192
}
187
193
188
194
// MARK: - View States
0 commit comments