diff --git a/docker/Dockerfile b/docker/Dockerfile index 4c930c3..86408a2 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,17 +1,16 @@ FROM alpine as godeps -RUN apk add go +RUN apk --no-cache add go RUN go install github.com/kyleconroy/sqlc/cmd/sqlc@latest RUN go install github.com/go-task/task/v3/cmd/task@latest RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest FROM alpine -RUN apk add go -RUN apk add nodejs yarn bash curl git git-perl tmux +RUN apk --no-cache add go nodejs yarn bash curl git git-perl tmux ADD docker/build.sh / RUN yarn global add @vue/cli ENV PATH="/root/.yarn/bin/:${PATH}" WORKDIR /src -ADD web/package.json /src/web/ +ADD web/package.json web/yarn.lock /src/web/ RUN yarn COPY --from=godeps /root/go/bin/task /root/go/bin/sqlc /root/go/bin/golangci-lint /usr/local/bin/ CMD /build.sh diff --git a/server/budgeting.go b/server/budgeting.go index 0645b2b..cccbbb5 100644 --- a/server/budgeting.go +++ b/server/budgeting.go @@ -30,6 +30,16 @@ type CategoryWithBalance struct { Assigned postgres.Numeric } +func NewCategoryWithBalance(category *postgres.GetCategoriesRow) CategoryWithBalance { + return CategoryWithBalance{ + GetCategoriesRow: category, + Available: postgres.NewZeroNumeric(), + AvailableLastMonth: postgres.NewZeroNumeric(), + Activity: postgres.NewZeroNumeric(), + Assigned: postgres.NewZeroNumeric(), + } +} + func getDate(c *gin.Context) (time.Time, error) { var year, month int yearString := c.Param("year") @@ -153,30 +163,13 @@ func (h *Handler) calculateBalances(budget postgres.Budget, firstOfNextMonth time.Time, firstOfMonth time.Time, categories []postgres.GetCategoriesRow, cumultativeBalances []postgres.GetCumultativeBalancesRow) ([]CategoryWithBalance, postgres.Numeric) { categoriesWithBalance := []CategoryWithBalance{} - hiddenCategory := CategoryWithBalance{ - GetCategoriesRow: &postgres.GetCategoriesRow{ - Name: "", - Group: "Hidden Categories", - }, - Available: postgres.NewZeroNumeric(), - AvailableLastMonth: postgres.NewZeroNumeric(), - Activity: postgres.NewZeroNumeric(), - Assigned: postgres.NewZeroNumeric(), - } moneyUsed := postgres.NewZeroNumeric() for i := range categories { cat := &categories[i] // do not show hidden categories categoryWithBalance := h.CalculateCategoryBalances(cat, cumultativeBalances, - firstOfNextMonth, &moneyUsed, firstOfMonth, hiddenCategory, budget) - if cat.Group == "Hidden Categories" { - hiddenCategory.Available = hiddenCategory.Available.Add(categoryWithBalance.Available) - hiddenCategory.AvailableLastMonth = hiddenCategory.AvailableLastMonth.Add(categoryWithBalance.AvailableLastMonth) - hiddenCategory.Activity = hiddenCategory.Activity.Add(categoryWithBalance.Activity) - hiddenCategory.Assigned = hiddenCategory.Assigned.Add(categoryWithBalance.Assigned) - continue - } + firstOfNextMonth, &moneyUsed, firstOfMonth, budget) if cat.ID == budget.IncomeCategoryID { continue @@ -185,22 +178,13 @@ func (h *Handler) calculateBalances(budget postgres.Budget, categoriesWithBalance = append(categoriesWithBalance, categoryWithBalance) } - categoriesWithBalance = append(categoriesWithBalance, hiddenCategory) - return categoriesWithBalance, moneyUsed } func (*Handler) CalculateCategoryBalances(cat *postgres.GetCategoriesRow, cumultativeBalances []postgres.GetCumultativeBalancesRow, firstOfNextMonth time.Time, - moneyUsed *postgres.Numeric, firstOfMonth time.Time, hiddenCategory CategoryWithBalance, - budget postgres.Budget) CategoryWithBalance { - categoryWithBalance := CategoryWithBalance{ - GetCategoriesRow: cat, - Available: postgres.NewZeroNumeric(), - AvailableLastMonth: postgres.NewZeroNumeric(), - Activity: postgres.NewZeroNumeric(), - Assigned: postgres.NewZeroNumeric(), - } + moneyUsed *postgres.Numeric, firstOfMonth time.Time, budget postgres.Budget) CategoryWithBalance { + categoryWithBalance := NewCategoryWithBalance(cat) for _, bal := range cumultativeBalances { if bal.CategoryID != cat.ID { continue diff --git a/web/src/dialogs/NewBudget.vue b/web/src/dialogs/NewBudget.vue index c6eecb6..75e095e 100644 --- a/web/src/dialogs/NewBudget.vue +++ b/web/src/dialogs/NewBudget.vue @@ -19,17 +19,45 @@ function newBudget() {

+

-
-
-
- New Budget -
-
- -
-
- - +
+
+
+ +

New Budget

+
+ + +
+
+ + +
diff --git a/web/src/pages/Budgeting.vue b/web/src/pages/Budgeting.vue index cd3d7cd..bf00f8c 100644 --- a/web/src/pages/Budgeting.vue +++ b/web/src/pages/Budgeting.vue @@ -14,11 +14,19 @@ const props = defineProps<{ const budgetsStore = useBudgetsStore(); const CurrentBudgetID = computed(() => budgetsStore.CurrentBudgetID); -const categoriesForMonth = useAccountStore().CategoriesForMonth; -const Categories = computed(() => { - return [...categoriesForMonth(selected.value.Year, selected.value.Month)]; +const accountStore = useAccountStore(); +const categoriesForMonth = accountStore.CategoriesForMonthAndGroup; + +function GetCategories(group : string) { + return [...categoriesForMonth(selected.value.Year, selected.value.Month, group)]; +}; + +const groupsForMonth = accountStore.CategoryGroupsForMonth; +const GroupsForMonth = computed(() => { + return [...groupsForMonth(selected.value.Year, selected.value.Month)]; }); + const previous = computed(() => ({ Year: new Date(selected.value.Year, selected.value.Month - 1, 1).getFullYear(), Month: new Date(selected.value.Year, selected.value.Month - 1, 1).getMonth(), @@ -61,7 +69,6 @@ onMounted(() => {
- @@ -70,23 +77,25 @@ onMounted(() => { - - - - - - - - - - + +

{{ group }}

+ + + + + + + + + +
Group Category Activity Available
{{ category.Group }}{{ category.Name }} - - - - - - - -
{{ category.Name }} + + + + + + + +
diff --git a/web/src/pages/Settings.vue b/web/src/pages/Settings.vue index 2acb8cd..d8467a0 100644 --- a/web/src/pages/Settings.vue +++ b/web/src/pages/Settings.vue @@ -4,6 +4,7 @@ import { useRouter } from "vue-router"; import { DELETE, POST } from "../api"; import { useBudgetsStore } from "../stores/budget"; import { useSessionStore } from "../stores/session"; +import Card from "../components/Card.vue"; const transactionsFile = ref(undefined); const assignmentsFile = ref(undefined); @@ -54,72 +55,40 @@ function ynabImport() { \ No newline at end of file diff --git a/web/src/stores/budget-account.ts b/web/src/stores/budget-account.ts index d0903fe..be57f7d 100644 --- a/web/src/stores/budget-account.ts +++ b/web/src/stores/budget-account.ts @@ -54,12 +54,30 @@ export const useAccountStore = defineStore("budget/account", { AccountsList(state) { return [...state.Accounts.values()]; }, - CategoriesForMonth: (state) => (year: number, month: number) => { + AllCategoriesForMonth: (state) => (year: number, month: number) => { const yearMap = state.Months.get(year); const monthMap = yearMap?.get(month); - console.log("MTH", monthMap) return [...monthMap?.values() || []]; }, + CategoryGroupsForMonth(state) { + return (year: number, month: number) => { + const categories = this.AllCategoriesForMonth(year, month); + const categoryGroups = []; + let prev = undefined; + for (const category of categories) { + if(category.Group != prev) + categoryGroups.push(category.Group); + prev = category.Group; + } + return categoryGroups; + } + }, + CategoriesForMonthAndGroup(state) { + return (year: number, month: number, group : string) => { + const categories = this.AllCategoriesForMonth(year, month); + return categories.filter(x => x.Group == group); + } + }, CurrentAccount(state): Account | undefined { if (state.CurrentAccountID == null) return undefined; @@ -102,6 +120,8 @@ export const useAccountStore = defineStore("budget/account", { async FetchMonthBudget(budgetid: string, year: number, month: number) { const result = await GET("/budget/" + budgetid + "/" + year + "/" + month); const response = await result.json(); + if(response.Categories == undefined || response.Categories.length <= 0) + return; this.addCategoriesForMonth(year, month, response.Categories); }, addCategoriesForMonth(year: number, month: number, categories: Category[]): void {