Skip to content

Commit

Permalink
Add expense add screen
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-amisha-i committed Mar 28, 2024
1 parent a7816b9 commit ef07391
Show file tree
Hide file tree
Showing 27 changed files with 804 additions and 60 deletions.
8 changes: 4 additions & 4 deletions BaseStyle/BaseStyle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
Expand Down Expand Up @@ -663,7 +663,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
Expand Down Expand Up @@ -693,7 +693,7 @@
INFOPLIST_FILE = BaseStyle/Info.plist;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -731,7 +731,7 @@
INFOPLIST_FILE = BaseStyle/Info.plist;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
16 changes: 12 additions & 4 deletions Data/Data.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
7EF3A291581F7EA20CB1042D /* Pods_Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E91B3E23688435064A60C0C4 /* Pods_Data.framework */; };
D83B15052B9996C0004A5F4F /* Groups.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83B15042B9996C0004A5F4F /* Groups.swift */; };
D83B15092B999789004A5F4F /* GroupRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83B15082B999789004A5F4F /* GroupRepository.swift */; };
D85E86DE2BAB0292002EDF76 /* Expense.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85E86DD2BAB0292002EDF76 /* Expense.swift */; };
D85E86E52BAB088F002EDF76 /* ExpenseRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85E86E42BAB088F002EDF76 /* ExpenseRepository.swift */; };
D88721432B99F133009DC5BE /* StorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88721422B99F133009DC5BE /* StorageManager.swift */; };
D89DBE1D2B872F0B00E5F1BD /* NonceGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89DBE1C2B872F0B00E5F1BD /* NonceGenerator.swift */; };
D89DBE282B88802800E5F1BD /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89DBE272B88802800E5F1BD /* Country.swift */; };
Expand Down Expand Up @@ -56,6 +58,8 @@
BED6C37AA3F8FD2A6350DE1C /* Pods-Data.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Data.debug.xcconfig"; path = "Target Support Files/Pods-Data/Pods-Data.debug.xcconfig"; sourceTree = "<group>"; };
D83B15042B9996C0004A5F4F /* Groups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Groups.swift; sourceTree = "<group>"; };
D83B15082B999789004A5F4F /* GroupRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupRepository.swift; sourceTree = "<group>"; };
D85E86DD2BAB0292002EDF76 /* Expense.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Expense.swift; sourceTree = "<group>"; };
D85E86E42BAB088F002EDF76 /* ExpenseRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpenseRepository.swift; sourceTree = "<group>"; };
D88721422B99F133009DC5BE /* StorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageManager.swift; sourceTree = "<group>"; };
D89DBE1C2B872F0B00E5F1BD /* NonceGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonceGenerator.swift; sourceTree = "<group>"; };
D89DBE272B88802800E5F1BD /* Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -137,6 +141,7 @@
D89DBE452B8CBE0F00E5F1BD /* UserRepository.swift */,
D83B15082B999789004A5F4F /* GroupRepository.swift */,
D8D14A592BA1E6E400F45FF2 /* MemberRepository.swift */,
D85E86E42BAB088F002EDF76 /* ExpenseRepository.swift */,
D8D14A532BA092F400F45FF2 /* ShareCodeRepository.swift */,
);
path = Repository;
Expand All @@ -149,6 +154,7 @@
D89DBE472B8CBE4C00E5F1BD /* AppUser.swift */,
D83B15042B9996C0004A5F4F /* Groups.swift */,
D8D14A5B2BA1E73600F45FF2 /* Member.swift */,
D85E86DD2BAB0292002EDF76 /* Expense.swift */,
D8D14A512BA0917D00F45FF2 /* SharedCode.swift */,
);
path = Model;
Expand Down Expand Up @@ -478,11 +484,13 @@
D89DBE532B8DC9F700E5F1BD /* AppRoute.swift in Sources */,
D8A7CA752BA5AB670014EC67 /* UserStore.swift in Sources */,
D89DBE402B8C9E7400E5F1BD /* RouterView.swift in Sources */,
D85E86E52BAB088F002EDF76 /* ExpenseRepository.swift in Sources */,
D8A7CA772BA5AB800014EC67 /* GroupStore.swift in Sources */,
D8AC25BE2B7F359B00CEAAD3 /* FirebaseProvider.swift in Sources */,
D89DBE1D2B872F0B00E5F1BD /* NonceGenerator.swift in Sources */,
D8D14A5C2BA1E73600F45FF2 /* Member.swift in Sources */,
D8A7CA792BA5AB920014EC67 /* MemberStore.swift in Sources */,
D85E86DE2BAB0292002EDF76 /* Expense.swift in Sources */,
D8D42AA92B872726009B345D /* DDLogProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -559,7 +567,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
Expand Down Expand Up @@ -619,7 +627,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
Expand Down Expand Up @@ -648,7 +656,7 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -746,7 +754,7 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
42 changes: 42 additions & 0 deletions Data/Data/Model/Expense.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Expense.swift
// Data
//
// Created by Amisha Italiya on 20/03/24.
//

import FirebaseFirestore

public struct Expense: Codable {

@DocumentID public var id: String? // Automatically generated ID by Firestore

let name: String
let amount: Double
let date: Date
let paidBy: AppUser
let splitTo: [Member] // Reference to users involved in the split
let splitType: SplitType

public init(name: String, amount: Double, date: Date, paidBy: AppUser, splitTo: [Member], splitType: SplitType) {
self.name = name
self.amount = amount
self.date = date
self.paidBy = paidBy
self.splitTo = splitTo
self.splitType = splitType
}

enum CodingKeys: String, CodingKey {
case name
case amount
case date
case paidBy = "paied_by"
case splitTo = "split_to"
case splitType = "split_type"
}
}

public enum SplitType: String, Codable {
case equally
}
8 changes: 8 additions & 0 deletions Data/Data/Repository/ExpenseRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// ExpenseRepository.swift
// Data
//
// Created by Amisha Italiya on 20/03/24.
//

import Foundation
16 changes: 15 additions & 1 deletion Data/Data/Repository/GroupRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,21 @@ public class GroupRepository: ObservableObject {
}

public func fetchGroups(userId: String) -> AnyPublisher<[Groups], ServiceError> {
store.fetchGroups(userId: userId)
Future { [weak self] promise in
guard let self else { return }
self.store.fetchGroups(userId: userId)
.sink { completion in
if case .failure(let error) = completion {
promise(.failure(error))
}
} receiveValue: { [weak self] groups in
guard let self else { return }
// Show only those groups in which the user is part of
let filteredGroups = groups.filter { $0.createdBy == userId || $0.members.contains(where: { $0.userId == userId }) }
promise(.success(filteredGroups))
}.store(in: &self.cancelables)

}.eraseToAnyPublisher()
}

public func fetchGroupBy(id: String) -> AnyPublisher<Groups?, ServiceError> {
Expand Down
8 changes: 8 additions & 0 deletions Data/Data/Repository/MemberRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ public class MemberRepository: ObservableObject {
public func fetchMemberBy(id: String) -> AnyPublisher<Member?, ServiceError> {
store.fetchMemberBy(id: id)
}

public func fetchMembers() -> AnyPublisher<[Member], ServiceError> {
store.fetchMembers()
}

public func fetchMembersByGroup(id: String) -> AnyPublisher<[Member], ServiceError> {
store.fetchMembersByGroup(id: id)
}
}
5 changes: 2 additions & 3 deletions Data/Data/Repository/ShareCodeRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import Combine

public class ShareCodeRepository: ObservableObject {

public let CODE_EXPIRATION_LIMIT = 2 /// 2 days
public let CODE_EXPIRATION_LIMIT = 2 /// Limit for code expiration, in days.

@Inject private var store: ShareCodeStore

private var cancelables = Set<AnyCancellable>()
Expand Down Expand Up @@ -39,6 +39,5 @@ public class ShareCodeRepository: ObservableObject {
} receiveValue: { code in
completion(code == nil)
}.store(in: &cancelables)

}
}
6 changes: 6 additions & 0 deletions Data/Data/Router/AppRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public enum AppRoute: Hashable {
case InviteMemberView(groupId: String)
case JoinMemberView

// MARK: - Expense Button
case AddExpenseView

// MARK: - Activity Tab
case ActivityHomeView

Expand Down Expand Up @@ -68,6 +71,9 @@ public enum AppRoute: Hashable {
case .ProfileView:
"userProfileView"

case .AddExpenseView:
"addExpenseView"

case .AccountHomeView:
"accountHomeView"
}
Expand Down
69 changes: 69 additions & 0 deletions Data/Data/Store/MemberStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,73 @@ class MemberStore: ObservableObject {
}
}.eraseToAnyPublisher()
}

func fetchMembers() -> AnyPublisher<[Member], ServiceError> {
Future { [weak self] promise in
guard let self else {
promise(.failure(.unexpectedError))
return
}

self.database.collection(DATABASE_NAME).getDocuments { snapshot, error in
if let error {
LogE("MemberStore :: \(#function) error: \(error.localizedDescription)")
promise(.failure(.unexpectedError))
return
}

guard let snapshot else {
LogE("MemberStore :: \(#function) The document is not available.")
promise(.failure(.databaseError))
return
}

do {
let members = try snapshot.documents.compactMap { document -> Member? in
try document.data(as: Member.self)
}
promise(.success(members))
} catch {
LogE("MemberStore :: \(#function) Decode error: \(error.localizedDescription)")
promise(.failure(.decodingError))
}
}
}.eraseToAnyPublisher()
}

func fetchMembersByGroup(id: String) -> AnyPublisher<[Member], ServiceError> {
Future { [weak self] promise in
guard let self else {
promise(.failure(.unexpectedError))
return
}

// Construct a Firestore query to fetch documents where group_id matches the provided groupId
self.database.collection(DATABASE_NAME)
.whereField("group_id", isEqualTo: id)
.getDocuments { snapshot, error in
if let error {
LogE("MemberStore :: \(#function) error: \(error.localizedDescription)")
promise(.failure(.unexpectedError))
return
}

guard let snapshot else {
LogE("MemberStore :: \(#function) The document is not available.")
promise(.failure(.databaseError))
return
}

do {
let members = try snapshot.documents.compactMap { document -> Member? in
try document.data(as: Member.self)
}
promise(.success(members))
} catch {
LogE("MemberStore :: \(#function) Decode error: \(error.localizedDescription)")
promise(.failure(.decodingError))
}
}
}.eraseToAnyPublisher()
}
}
2 changes: 1 addition & 1 deletion Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment the next line to define a global platform for your project
platform :ios, '16'
platform :ios, '16.4'

workspace 'Splito.xcworkspace'
project 'Splito.xcodeproj'
Expand Down
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,6 @@ SPEC CHECKSUMS:
SwiftLint: c1de071d9d08c8aba837545f6254315bc900e211
Swinject: 893c9a543000ac2f10ee4cbaf0933c6992c935d5

PODFILE CHECKSUM: 577bc6b2afbbbf58b4a4b52c9694cbacdb9101c6
PODFILE CHECKSUM: b966f24309b6f1584571edcb03ef8deb0c810bc2

COCOAPODS: 1.15.0
Loading

0 comments on commit ef07391

Please sign in to comment.