Fix transaction creation

This commit is contained in:
William Brawner 2021-09-19 14:24:27 -06:00
parent e4caef826c
commit d0fdb0194d
8 changed files with 65 additions and 61 deletions

View file

@ -655,7 +655,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.wbrawner.budget.ios;
PRODUCT_BUNDLE_IDENTIFIER = com.wbrawner.twigs.ios;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
SWIFT_VERSION = 5.0;
@ -679,7 +679,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.wbrawner.budget.ios;
PRODUCT_BUNDLE_IDENTIFIER = com.wbrawner.twigs.ios;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
SWIFT_VERSION = 5.0;

View file

@ -23,10 +23,10 @@ class CategoryDataStore: ObservableObject {
}
}
func getCategories(budgetId: String? = nil, archived: Bool? = false, count: Int? = nil, page: Int? = nil) {
func getCategories(budgetId: String? = nil, expense: Bool? = nil, archived: Bool? = false, count: Int? = nil, page: Int? = nil) {
self.categories = .failure(.loading)
self.currentRequest = categoryRepository.getCategories(budgetId: budgetId, archived: archived, count: count, page: page)
self.currentRequest = categoryRepository.getCategories(budgetId: budgetId, expense: expense, archived: archived, count: count, page: page)
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { (completion) in
switch completion {

View file

@ -10,7 +10,7 @@ import Foundation
import Combine
protocol CategoryRepository {
func getCategories(budgetId: String?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError>
func getCategories(budgetId: String?, expense: Bool?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError>
func getCategory(_ categoryId: String) -> AnyPublisher<Category, NetworkError>
}
@ -23,14 +23,14 @@ class NetworkCategoryRepository: CategoryRepository {
self.cacheService = cacheService
}
func getCategories(budgetId: String?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
if let categories = cacheService?.getCategories(budgetId: budgetId, archived: archived, count: count, page: page) {
func getCategories(budgetId: String?, expense: Bool?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
if let categories = cacheService?.getCategories(budgetId: budgetId, expense: expense, archived: archived, count: count, page: page) {
print("Returning categories from cache")
return categories
}
print("No cached categories, fetching from network")
return apiService.getCategories(budgetId: budgetId, archived: archived, count: count, page: page).map { (categories: [Category]) in
return apiService.getCategories(budgetId: budgetId, expense: expense, archived: archived, count: count, page: page).map { (categories: [Category]) in
self.cacheService?.addCategories(categories)
return categories
}.eraseToAnyPublisher()
@ -62,7 +62,7 @@ class MockCategoryRepository: CategoryRepository {
archived: false
)
func getCategories(budgetId: String?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
func getCategories(budgetId: String?, expense: Bool?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
return Result.Publisher([MockCategoryRepository.category]).eraseToAnyPublisher()
}

View file

@ -38,7 +38,7 @@ class BudgetAppApiService {
}
func newBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError> {
return requestHelper.post("/api/budgets/new", data: budget, type: Budget.self)
return requestHelper.post("/api/budgets", data: budget, type: Budget.self)
}
func updateBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError> {
@ -86,7 +86,7 @@ class BudgetAppApiService {
}
func newTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
return requestHelper.post("/api/transactions/new", data: transaction, type: Transaction.self)
return requestHelper.post("/api/transactions", data: transaction, type: Transaction.self)
}
func updateTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
@ -99,11 +99,14 @@ class BudgetAppApiService {
// MARK: Categories
func getCategories(budgetId: String? = nil, archived: Bool? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError> {
func getCategories(budgetId: String? = nil, expense: Bool? = nil, archived: Bool? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError> {
var queries = [String: Array<String>]()
if budgetId != nil {
queries["budgetIds"] = [String(budgetId!)]
}
if expense != nil {
queries["expense"] = [String(expense!)]
}
if archived != nil {
queries["archived"] = [String(archived!)]
}
@ -125,7 +128,7 @@ class BudgetAppApiService {
}
func newCategory(_ category: Category) -> AnyPublisher<Category, NetworkError> {
return requestHelper.post("/api/categories/new", data: category, type: Category.self)
return requestHelper.post("/api/categories", data: category, type: Category.self)
}
func updateCategory(_ category: Category) -> AnyPublisher<Category, NetworkError> {
@ -149,7 +152,7 @@ class BudgetAppApiService {
func register(username: String, email: String, password: String) -> AnyPublisher<User, NetworkError> {
return requestHelper.post(
"/api/users/new",
"/api/users/register",
data: RegistrationRequest(username: username, email: email, password: password),
type: User.self
).map { (user) -> User in
@ -181,7 +184,7 @@ class BudgetAppApiService {
}
func newUser(_ user: User) -> AnyPublisher<User, NetworkError> {
return requestHelper.post("/api/users/new", data: user, type: User.self)
return requestHelper.post("/api/users", data: user, type: User.self)
}
func updateUser(_ user: User) -> AnyPublisher<User, NetworkError> {

View file

@ -61,11 +61,14 @@ class BudgetAppInMemoryCacheService {
}
// MARK: Categories
func getCategories(budgetId: String? = nil, archived: Bool? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError>? {
func getCategories(budgetId: String? = nil, expense: Bool? = nil, archived: Bool? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError>? {
var results = categories
if budgetId != nil {
results = categories.filter { $0.budgetId == budgetId }
}
if expense != nil {
results = results.filter { $0.expense == expense }
}
if archived != nil {
results = results.filter { $0.archived == archived }
}
@ -73,9 +76,7 @@ class BudgetAppInMemoryCacheService {
return nil
}
let sortedResults = results.sorted { $0.title < $1.title }
// TODO: Figure out why this crashes on transaction editing screens
// return Result.Publisher(.success(sortedResults.slice(count: count, page: page))).eraseToAnyPublisher()
return nil
return Result.Publisher(.success(sortedResults.slice(count: count, page: page))).eraseToAnyPublisher()
}
func getCategory(_ id: String) -> AnyPublisher<Category, NetworkError>? {

View file

@ -16,8 +16,8 @@ struct AddTransactionView: View {
@State var date: Date = Date()
@State var amount: String = ""
@State var type: TransactionType = .expense
@State var budgetId: String? = nil
@State var categoryId: String? = nil
@State var budgetId: String = ""
@State var categoryId: String = ""
let createdBy: String
var stateContent: AnyView {
@ -60,7 +60,7 @@ struct AddTransactionView: View {
categoryId: self.categoryId,
expense: self.type == TransactionType.expense,
createdBy: self.createdBy,
budgetId: self.budgetId!
budgetId: self.budgetId
))
})
}
@ -70,8 +70,8 @@ struct AddTransactionView: View {
self.date = Date()
self.amount = ""
self.type = .expense
self.budgetId = nil
self.categoryId = nil
self.budgetId = ""
self.categoryId = ""
}
}

View file

@ -14,8 +14,8 @@ struct EditTransactionForm: View {
@Binding var date: Date
@Binding var amount: String
@Binding var type: TransactionType
@Binding var budgetId: String?
@Binding var categoryId: String?
@Binding var budgetId: String
@Binding var categoryId: String
@State private var showingAlert = false
let dataStoreProvider: DataStoreProvider
let deleteAction: (() -> ())?
@ -33,7 +33,7 @@ struct EditTransactionForm: View {
}
}
BudgetPicker(self.dataStoreProvider, budgetId: self.$budgetId)
CategoryPicker(self.dataStoreProvider, budgetId: self.$budgetId, categoryId: self.$categoryId)
CategoryPicker(self.dataStoreProvider, budgetId: self.$budgetId, categoryId: self.$categoryId, expense: self.$type)
if deleteAction != nil {
Button(action: {
self.showingAlert = true
@ -52,7 +52,7 @@ struct EditTransactionForm: View {
}
struct BudgetPicker: View {
var budgetId: Binding<String?>
var budgetId: Binding<String>
var stateContent: AnyView {
switch self.budgetsDataStore.budgets {
case .success(let budgets):
@ -77,7 +77,7 @@ struct BudgetPicker: View {
}
@ObservedObject var budgetsDataStore: BudgetsDataStore
init(_ dataStoreProvider: DataStoreProvider, budgetId: Binding<String?>) {
init(_ dataStoreProvider: DataStoreProvider, budgetId: Binding<String>) {
let budgetsDataStore = dataStoreProvider.budgetsDataStore()
budgetsDataStore.getBudgets()
self.budgetsDataStore = budgetsDataStore
@ -86,7 +86,7 @@ struct BudgetPicker: View {
}
struct CategoryPicker: View {
var categoryId: Binding<String?>
var categoryId: Binding<String>
var stateContent: AnyView {
switch self.categoryDataStore.categories {
case .success(let categories):
@ -110,11 +110,11 @@ struct CategoryPicker: View {
}
@ObservedObject var categoryDataStore: CategoryDataStore
init(_ dataStoreProvider: DataStoreProvider, budgetId: Binding<String?>, categoryId: Binding<String?>) {
init(_ dataStoreProvider: DataStoreProvider, budgetId: Binding<String>, categoryId: Binding<String>, expense: Binding<TransactionType>) {
let categoryDataStore = dataStoreProvider.categoryDataStore()
print("Requesting categories")
if let id = budgetId.wrappedValue {
categoryDataStore.getCategories(budgetId: id, count: nil, page: nil)
if budgetId.wrappedValue != "" {
categoryDataStore.getCategories(budgetId: budgetId.wrappedValue, expense: expense.wrappedValue == TransactionType.expense, count: nil, page: nil)
}
self.categoryDataStore = categoryDataStore
self.categoryId = categoryId

View file

@ -10,13 +10,13 @@ import SwiftUI
struct TransactionEditView: View {
@Environment(\.presentationMode) var presentationMode
var title: State<String>
var description: State<String>
var date: State<Date>
var amount: State<String>
var type: State<TransactionType>
var budgetId: State<String?>
var categoryId: State<String?>
@State var title: String
@State var description: String
@State var date: Date
@State var amount: String
@State var type: TransactionType
@State var budgetId: String
@State var categoryId: String
let createdBy: String
let id: String?
var shouldNavigateUp: Binding<Bool>
@ -31,13 +31,13 @@ struct TransactionEditView: View {
return AnyView(EmbeddedLoadingView())
default:
return AnyView(EditTransactionForm(
title: self.title.projectedValue,
description: self.description.projectedValue,
date: self.date.projectedValue,
amount: self.amount.projectedValue,
type: self.type.projectedValue,
budgetId: self.budgetId.projectedValue,
categoryId: self.categoryId.projectedValue,
title: self.$title,
description: self.$description,
date: self.$date,
amount: self.$amount,
type: self.$type,
budgetId: self.$budgetId,
categoryId: self.$categoryId,
dataStoreProvider: self.dataStoreProvider,
deleteAction: {
self.transactionDataStore.deleteTransaction(self.id!)
@ -49,17 +49,17 @@ struct TransactionEditView: View {
var body: some View {
stateContent
.navigationBarItems(trailing: Button("save") {
let amount = Double(self.amount.wrappedValue) ?? 0.0
let amount = Double(self.amount) ?? 0.0
self.transactionDataStore.saveTransaction(Transaction(
id: self.id ?? "",
title: self.title.wrappedValue,
description: self.description.wrappedValue,
date: self.date.wrappedValue,
title: self.title,
description: self.description,
date: self.date,
amount: Int(amount * 100.0),
categoryId: self.categoryId.wrappedValue,
expense: self.type.wrappedValue == TransactionType.expense,
categoryId: self.categoryId,
expense: self.type == TransactionType.expense,
createdBy: self.createdBy,
budgetId: self.budgetId.wrappedValue!
budgetId: self.budgetId
))
})
}
@ -71,13 +71,13 @@ struct TransactionEditView: View {
self.transactionDataStore = dataStoreProvider.transactionDataStore()
self.createdBy = try! dataStoreProvider.authenticationDataStore().currentUser.get().id
self.id = transaction.id
self.title = State<String>(initialValue: transaction.title)
self.description = State<String>(initialValue: transaction.description ?? "")
self.date = State<Date>(initialValue: transaction.date)
self.amount = State<String>(initialValue: transaction.amountString)
self.type = State<TransactionType>(initialValue: transaction.type)
self.budgetId = State<String?>(initialValue: transaction.budgetId)
self.categoryId = State<String?>(initialValue: transaction.categoryId)
self._title = State<String>(initialValue: transaction.title)
self._description = State<String>(initialValue: transaction.description ?? "")
self._date = State<Date>(initialValue: transaction.date)
self._amount = State<String>(initialValue: transaction.amountString)
self._type = State<TransactionType>(initialValue: transaction.type)
self._budgetId = State<String>(initialValue: transaction.budgetId)
self._categoryId = State<String>(initialValue: transaction.categoryId ?? "")
self.shouldNavigateUp = shouldNavigateUp
}
}