|
@@ -7,6 +7,7 @@
|
|
|
|
|
|
import SwiftUI
|
|
|
import Combine
|
|
|
+import CoreData
|
|
|
|
|
|
/// Shows the budget values for the selected budget, month, and year.
|
|
|
struct BudgetView: View {
|
|
@@ -25,11 +26,6 @@ struct BudgetView: View {
|
|
|
|
|
|
@Environment(\.managedObjectContext) var managedObjectContext
|
|
|
|
|
|
-// private var budgetEntriesRequest: FetchRequest<BudgetCategoryEntry>
|
|
|
-// private var budgetEntries: FetchedResults<BudgetCategoryEntry> { budgetEntriesRequest.wrappedValue }
|
|
|
-
|
|
|
- @FetchRequest<BudgetCategoryEntry> private var budgetEntries: FetchedResults<BudgetCategoryEntry>
|
|
|
-
|
|
|
init(budget: BudgetInfo, currentBudgetId: Binding<UUID?>) {
|
|
|
_budget = .init(initialValue: budget)
|
|
|
_currentBudgetId = currentBudgetId
|
|
@@ -39,20 +35,6 @@ struct BudgetView: View {
|
|
|
_month = .init(initialValue: cal.component(.month, from: now))
|
|
|
_monthName = .init(initialValue: cal.monthSymbols[self._month.wrappedValue])
|
|
|
_year = .init(initialValue: cal.component(.year, from: now))
|
|
|
-
|
|
|
- _budgetEntries = FetchRequest<BudgetCategoryEntry>(entity: BudgetCategoryEntry.entity(),
|
|
|
- sortDescriptors: [],
|
|
|
- predicate: NSPredicate(format: "(budgetId == %@) AND (month == %d) AND (year == %d)",
|
|
|
- budget.id as CVarArg, _month.wrappedValue, _year.wrappedValue))
|
|
|
-
|
|
|
-// budgetEntriesRequest = FetchRequest<BudgetCategoryEntry>(entity: BudgetCategoryEntry.entity(),
|
|
|
-// sortDescriptors: [],
|
|
|
-// predicate: NSCompoundPredicate(andPredicateWithSubpredicates: [
|
|
|
-// NSPredicate(format: "budgetId == %@", budget.id as CVarArg),
|
|
|
-// NSPredicate(format: "month == %i", month),
|
|
|
-// NSPredicate(format: "year == %i", year)
|
|
|
-// ])
|
|
|
-// )
|
|
|
}
|
|
|
|
|
|
func formatAmount(_ amount: NSNumber) -> String? {
|
|
@@ -62,122 +44,116 @@ struct BudgetView: View {
|
|
|
return f.string(from: amount)
|
|
|
}
|
|
|
|
|
|
- private func findBudgetCategoryEntry(withId: UUID) -> BudgetCategoryEntry? {
|
|
|
- return budgetEntries.first(where: { $0.budgetCategoryId == withId })
|
|
|
- }
|
|
|
+// private func findBudgetCategoryEntry(withId: UUID) -> BudgetCategoryEntry? {
|
|
|
+// return budgetEntries.first(where: { $0.budgetCategoryId == withId })
|
|
|
+// }
|
|
|
|
|
|
private func zeroBudgetEntries() -> Void {
|
|
|
- for section in budget.sections {
|
|
|
- for category in section.categories {
|
|
|
- if let entry = findBudgetCategoryEntry(withId: category.id) {
|
|
|
- entry.amount = 0
|
|
|
- } else {
|
|
|
- let newEntry = BudgetCategoryEntry(context: managedObjectContext)
|
|
|
- newEntry.budgetId = budget.id
|
|
|
- newEntry.budgetCategoryId = category.id
|
|
|
- newEntry.month = Int64(month)
|
|
|
- newEntry.year = Int64(year)
|
|
|
- newEntry.amount = 0
|
|
|
- }
|
|
|
-
|
|
|
- do {
|
|
|
- try managedObjectContext.save()
|
|
|
- } catch {
|
|
|
- print(error)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+// for section in budget.sections {
|
|
|
+// for category in section.categories {
|
|
|
+// if let entry = findBudgetCategoryEntry(withId: category.id) {
|
|
|
+// entry.amount = 0
|
|
|
+// } else {
|
|
|
+// let newEntry = BudgetCategoryEntry(context: managedObjectContext)
|
|
|
+// newEntry.budgetId = budget.id
|
|
|
+// newEntry.budgetCategoryId = category.id
|
|
|
+// newEntry.month = Int64(month)
|
|
|
+// newEntry.year = Int64(year)
|
|
|
+// newEntry.amount = 0
|
|
|
+// }
|
|
|
+//
|
|
|
+// do {
|
|
|
+// try managedObjectContext.save()
|
|
|
+// } catch {
|
|
|
+// print(error)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
}
|
|
|
|
|
|
+ @State private var refreshView: Bool = false
|
|
|
+
|
|
|
var body: some View {
|
|
|
- VStack {
|
|
|
- HStack {
|
|
|
- Button(action: { withAnimation() { showMonthPicker.toggle() } } ) {
|
|
|
- Text("\(monthName) \(String(year))")
|
|
|
- Image(systemName: showMonthPicker ? "chevron.up" : "chevron.down")
|
|
|
+ DynamicFetchView(predicate: NSPredicate(format: "budgetId == %@ AND month == %ld AND year == %ld", budget.id as CVarArg, month, year),
|
|
|
+ sortDescriptors: []) { (budgetEntries: FetchedResults<BudgetCategoryEntry>) in
|
|
|
+
|
|
|
+ VStack {
|
|
|
+ HStack {
|
|
|
+ Button(action: { withAnimation() { showMonthPicker.toggle() } } ) {
|
|
|
+ Text("\(monthName) \(String(year))")
|
|
|
+ Image(systemName: showMonthPicker ? "chevron.up" : "chevron.down")
|
|
|
+ }
|
|
|
+ Spacer()
|
|
|
+ Button(action: { showQuickBudget.toggle() }) { // TODO: Implement this
|
|
|
+ Image(systemName: "bolt.fill")
|
|
|
+ }
|
|
|
+ Button(action: { showNotImplemented.toggle() }) { // TODO: Implement this
|
|
|
+ Image(systemName: "gearshape.fill")
|
|
|
+ }.padding(.leading, 11)
|
|
|
}
|
|
|
- Spacer()
|
|
|
- Button(action: { showQuickBudget.toggle() }) { // TODO: Implement this
|
|
|
- Image(systemName: "bolt.fill")
|
|
|
+ .padding(11)
|
|
|
+
|
|
|
+ if showMonthPicker {
|
|
|
+ YearAndMonthPicker(month: $month,
|
|
|
+ monthName: $monthName,
|
|
|
+ year: $year,
|
|
|
+ locale: Locale(identifier: budget.localeIdentifier)
|
|
|
+ )
|
|
|
}
|
|
|
- Button(action: { showNotImplemented.toggle() }) { // TODO: Implement this
|
|
|
- Image(systemName: "gearshape.fill")
|
|
|
- }.padding(.leading, 11)
|
|
|
- }
|
|
|
- .padding(11)
|
|
|
-
|
|
|
- if showMonthPicker {
|
|
|
- YearAndMonthPicker(month: $month,
|
|
|
- monthName: $monthName,
|
|
|
- year: $year,
|
|
|
- locale: Locale(identifier: budget.localeIdentifier)
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- BudgetViewSummary(budget: $budget, month: $month, monthName: $monthName, year: $year)
|
|
|
- .padding([.leading, .trailing], 16)
|
|
|
-
|
|
|
- List {
|
|
|
- ForEach(budget.sections) { section in
|
|
|
- if !section.hidden {
|
|
|
- Section(header: BudgetSectionCell(section: section,
|
|
|
- amountText: "", //formatAmount(0) ?? "--",
|
|
|
- color: 0 < 0 ? Color("negativeAmount") : Color("positiveAmount"))
|
|
|
- ) {
|
|
|
- ForEach(section.categories) { category in
|
|
|
- if !category.hidden {
|
|
|
- BudgetCategoryCell(category: category,
|
|
|
- amountText: formatAmount(budgetEntries.first(where: { $0.budgetCategoryId == category.id })?.amount ?? 0) ?? "--",
|
|
|
- color: 0 < 0 ? Color("negativeAmount") : Color("positiveAmount")
|
|
|
- )
|
|
|
- .onLongPressGesture {
|
|
|
- editingCategoryEntry = findBudgetCategoryEntry(withId: category.id)
|
|
|
- showEditCategoryEntry.toggle()
|
|
|
+
|
|
|
+ BudgetViewSummary(budget: $budget, month: $month, monthName: $monthName, year: $year)
|
|
|
+ .padding([.leading, .trailing], 16)
|
|
|
+
|
|
|
+ List {
|
|
|
+ ForEach(budget.sections) { section in
|
|
|
+ if !section.hidden {
|
|
|
+ Section(header: BudgetSectionCell(section: section,
|
|
|
+ amountText: "", //formatAmount(0) ?? "--",
|
|
|
+ color: 0 < 0 ? Color("negativeAmount") : Color("positiveAmount"))
|
|
|
+ ) {
|
|
|
+ ForEach(section.categories) { category in
|
|
|
+ if !category.hidden {
|
|
|
+ BudgetCategoryCell(category: category,
|
|
|
+ amountText: String(format: "= %@ =", budgetEntries.first(where: { $0.budgetCategoryId == category.id })?.amount ?? -69 ),
|
|
|
+ color: 0 < 0 ? Color("negativeAmount") : Color("positiveAmount")
|
|
|
+ )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- .onMove { (indexSet, s) in
|
|
|
- print(indexSet, s)
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- .onMove { (indexSet, s) in
|
|
|
- print(indexSet, s)
|
|
|
+ .listStyle(PlainListStyle())
|
|
|
+// .onChange(of: month) { m in
|
|
|
+// let entries = budgetEntries
|
|
|
+// print(entries.map { $0.amount })
|
|
|
+// }
|
|
|
+ .navigationBarTitle(budget.name, displayMode: .inline)
|
|
|
+ .toolbar {
|
|
|
+ EditButton()
|
|
|
+ }
|
|
|
+ .onAppear() {
|
|
|
+ currentBudgetId = budget.id
|
|
|
+ lastLoadedBudgetId = budget.id.uuidString
|
|
|
+ }
|
|
|
+ .actionSheet(isPresented: $showQuickBudget) {
|
|
|
+ ActionSheet(
|
|
|
+ title: Text("Quick budget"),
|
|
|
+ message: Text("How would you like to set up your budget for \(monthName) \(String(year))?"),
|
|
|
+ buttons: [
|
|
|
+ .cancel { print(self.showQuickBudget) },
|
|
|
+ .default(Text("All categories to zero"), action: zeroBudgetEntries),
|
|
|
+ .default(Text("Values used the previous month"), action: { print(self) })
|
|
|
+ ]
|
|
|
+ )
|
|
|
+ }
|
|
|
+ .popover(isPresented: $showEditCategoryEntry) {
|
|
|
+ // BudgetCategoryEntryEditor(amount: $editingCategoryEntry.wrappedValue?.amount)
|
|
|
}
|
|
|
- }
|
|
|
- .listStyle(PlainListStyle())
|
|
|
- .navigationBarTitle(budget.name, displayMode: .inline)
|
|
|
- .toolbar {
|
|
|
- EditButton()
|
|
|
- }
|
|
|
- .onAppear() {
|
|
|
- currentBudgetId = budget.id
|
|
|
- lastLoadedBudgetId = budget.id.uuidString
|
|
|
- }
|
|
|
- .onChange(of: month) { e in
|
|
|
-
|
|
|
- }
|
|
|
- .onReceive(budgetEntries.publisher) { o in
|
|
|
- print(o.month)
|
|
|
- }
|
|
|
- .actionSheet(isPresented: $showQuickBudget) {
|
|
|
- ActionSheet(
|
|
|
- title: Text("Quick budget"),
|
|
|
- message: Text("How would you like to set up your budget for \(monthName) \(String(year))?"),
|
|
|
- buttons: [
|
|
|
- .cancel { print(self.showQuickBudget) },
|
|
|
- .default(Text("All categories to zero"), action: zeroBudgetEntries),
|
|
|
- .default(Text("Values used the previous month"), action: { print(self) })
|
|
|
- ]
|
|
|
- )
|
|
|
- }
|
|
|
- .popover(isPresented: $showEditCategoryEntry) {
|
|
|
-// BudgetCategoryEntryEditor(amount: $editingCategoryEntry.wrappedValue?.amount)
|
|
|
- }
|
|
|
|
|
|
- .alert(isPresented: $showNotImplemented) {
|
|
|
- Alert(title: Text("Not Implemented!"))
|
|
|
+ .alert(isPresented: $showNotImplemented) {
|
|
|
+ Alert(title: Text("Not Implemented!"))
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|