Import category
This commit is contained in:
parent
674028d394
commit
495bc2b7c3
@ -17,6 +17,8 @@ type YNABImport struct {
|
|||||||
Context context.Context
|
Context context.Context
|
||||||
accounts []postgres.Account
|
accounts []postgres.Account
|
||||||
payees []postgres.Payee
|
payees []postgres.Payee
|
||||||
|
categories []postgres.GetCategoriesRow
|
||||||
|
categoryGroups []postgres.CategoryGroup
|
||||||
queries *postgres.Queries
|
queries *postgres.Queries
|
||||||
budgetID uuid.UUID
|
budgetID uuid.UUID
|
||||||
}
|
}
|
||||||
@ -32,10 +34,22 @@ func NewYNABImport(q *postgres.Queries, budgetID uuid.UUID) (*YNABImport, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
categories, err := q.GetCategories(context.Background(), budgetID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryGroups, err := q.GetCategoryGroups(context.Background(), budgetID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &YNABImport{
|
return &YNABImport{
|
||||||
Context: context.Background(),
|
Context: context.Background(),
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
payees: payees,
|
payees: payees,
|
||||||
|
categories: categories,
|
||||||
|
categoryGroups: categoryGroups,
|
||||||
queries: q,
|
queries: q,
|
||||||
budgetID: budgetID,
|
budgetID: budgetID,
|
||||||
}, nil
|
}, nil
|
||||||
@ -74,7 +88,12 @@ func (ynab *YNABImport) Import(r io.Reader) error {
|
|||||||
return fmt.Errorf("could not get payee %s: %w", payeeName, err)
|
return fmt.Errorf("could not get payee %s: %w", payeeName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//category := record[4] //also in 5 + 6 split by group/category
|
categoryGroup, categoryName := record[5], record[6] //also in 5 + 6 split by group/category
|
||||||
|
category, err := ynab.GetCategory(categoryGroup, categoryName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not get category %s: %w", payeeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
memo := record[7]
|
memo := record[7]
|
||||||
|
|
||||||
outflow := record[8]
|
outflow := record[8]
|
||||||
@ -91,6 +110,7 @@ func (ynab *YNABImport) Import(r io.Reader) error {
|
|||||||
Memo: memo,
|
Memo: memo,
|
||||||
AccountID: account.ID,
|
AccountID: account.ID,
|
||||||
PayeeID: payeeID,
|
PayeeID: payeeID,
|
||||||
|
CategoryID: category,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
}
|
}
|
||||||
_, err = ynab.queries.CreateTransaction(ynab.Context, transaction)
|
_, err = ynab.queries.CreateTransaction(ynab.Context, transaction)
|
||||||
@ -172,3 +192,54 @@ func (ynab *YNABImport) GetPayee(name string) (uuid.NullUUID, error) {
|
|||||||
ynab.payees = append(ynab.payees, payee)
|
ynab.payees = append(ynab.payees, payee)
|
||||||
return uuid.NullUUID{UUID: payee.ID, Valid: true}, nil
|
return uuid.NullUUID{UUID: payee.ID, Valid: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ynab *YNABImport) GetCategory(group string, name string) (uuid.NullUUID, error) {
|
||||||
|
if group == "" || name == "" {
|
||||||
|
return uuid.NullUUID{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, category := range ynab.categories {
|
||||||
|
if category.Name == name && category.Group == group {
|
||||||
|
return uuid.NullUUID{UUID: category.ID, Valid: true}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, categoryGroup := range ynab.categoryGroups {
|
||||||
|
if categoryGroup.Name == group {
|
||||||
|
createCategory := postgres.CreateCategoryParams{Name: name, CategoryGroupID: categoryGroup.ID}
|
||||||
|
category, err := ynab.queries.CreateCategory(ynab.Context, createCategory)
|
||||||
|
if err != nil {
|
||||||
|
return uuid.NullUUID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
getCategory := postgres.GetCategoriesRow{
|
||||||
|
ID: category.ID,
|
||||||
|
CategoryGroupID: category.CategoryGroupID,
|
||||||
|
Name: category.Name,
|
||||||
|
Group: categoryGroup.Name,
|
||||||
|
}
|
||||||
|
ynab.categories = append(ynab.categories, getCategory)
|
||||||
|
return uuid.NullUUID{UUID: category.ID, Valid: true}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryGroup, err := ynab.queries.CreateCategoryGroup(ynab.Context, postgres.CreateCategoryGroupParams{Name: name, BudgetID: ynab.budgetID})
|
||||||
|
if err != nil {
|
||||||
|
return uuid.NullUUID{}, err
|
||||||
|
}
|
||||||
|
ynab.categoryGroups = append(ynab.categoryGroups, categoryGroup)
|
||||||
|
|
||||||
|
category, err := ynab.queries.CreateCategory(ynab.Context, postgres.CreateCategoryParams{Name: name, CategoryGroupID: categoryGroup.ID})
|
||||||
|
if err != nil {
|
||||||
|
return uuid.NullUUID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
getCategory := postgres.GetCategoriesRow{
|
||||||
|
ID: category.ID,
|
||||||
|
CategoryGroupID: category.CategoryGroupID,
|
||||||
|
Name: category.Name,
|
||||||
|
Group: categoryGroup.Name,
|
||||||
|
}
|
||||||
|
ynab.categories = append(ynab.categories, getCategory)
|
||||||
|
return uuid.NullUUID{UUID: category.ID, Valid: true}, nil
|
||||||
|
}
|
||||||
|
117
postgres/categories.sql.go
Normal file
117
postgres/categories.sql.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// source: categories.sql
|
||||||
|
|
||||||
|
package postgres
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createCategory = `-- name: CreateCategory :one
|
||||||
|
INSERT INTO categories
|
||||||
|
(name, category_group_id)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING id, category_group_id, name
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateCategoryParams struct {
|
||||||
|
Name string
|
||||||
|
CategoryGroupID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateCategory(ctx context.Context, arg CreateCategoryParams) (Category, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, createCategory, arg.Name, arg.CategoryGroupID)
|
||||||
|
var i Category
|
||||||
|
err := row.Scan(&i.ID, &i.CategoryGroupID, &i.Name)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCategoryGroup = `-- name: CreateCategoryGroup :one
|
||||||
|
INSERT INTO category_groups
|
||||||
|
(name, budget_id)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING id, budget_id, name
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateCategoryGroupParams struct {
|
||||||
|
Name string
|
||||||
|
BudgetID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateCategoryGroup(ctx context.Context, arg CreateCategoryGroupParams) (CategoryGroup, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, createCategoryGroup, arg.Name, arg.BudgetID)
|
||||||
|
var i CategoryGroup
|
||||||
|
err := row.Scan(&i.ID, &i.BudgetID, &i.Name)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCategories = `-- name: GetCategories :many
|
||||||
|
SELECT categories.id, categories.category_group_id, categories.name, category_groups.name as group FROM categories
|
||||||
|
INNER JOIN category_groups ON categories.category_group_id = category_groups.id
|
||||||
|
WHERE category_groups.budget_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetCategoriesRow struct {
|
||||||
|
ID uuid.UUID
|
||||||
|
CategoryGroupID uuid.UUID
|
||||||
|
Name string
|
||||||
|
Group string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetCategories(ctx context.Context, budgetID uuid.UUID) ([]GetCategoriesRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, getCategories, budgetID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetCategoriesRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetCategoriesRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CategoryGroupID,
|
||||||
|
&i.Name,
|
||||||
|
&i.Group,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCategoryGroups = `-- name: GetCategoryGroups :many
|
||||||
|
SELECT category_groups.id, category_groups.budget_id, category_groups.name FROM category_groups
|
||||||
|
WHERE category_groups.budget_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetCategoryGroups(ctx context.Context, budgetID uuid.UUID) ([]CategoryGroup, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, getCategoryGroups, budgetID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []CategoryGroup
|
||||||
|
for rows.Next() {
|
||||||
|
var i CategoryGroup
|
||||||
|
if err := rows.Scan(&i.ID, &i.BudgetID, &i.Name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
@ -21,6 +21,18 @@ type Budget struct {
|
|||||||
LastModification sql.NullTime
|
LastModification sql.NullTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
ID uuid.UUID
|
||||||
|
CategoryGroupID uuid.UUID
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CategoryGroup struct {
|
||||||
|
ID uuid.UUID
|
||||||
|
BudgetID uuid.UUID
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
type Payee struct {
|
type Payee struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
BudgetID uuid.UUID
|
BudgetID uuid.UUID
|
||||||
@ -33,6 +45,7 @@ type Transaction struct {
|
|||||||
Memo string
|
Memo string
|
||||||
Amount Numeric
|
Amount Numeric
|
||||||
AccountID uuid.UUID
|
AccountID uuid.UUID
|
||||||
|
CategoryID uuid.NullUUID
|
||||||
PayeeID uuid.NullUUID
|
PayeeID uuid.NullUUID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
postgres/queries/categories.sql
Normal file
20
postgres/queries/categories.sql
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
-- name: CreateCategoryGroup :one
|
||||||
|
INSERT INTO category_groups
|
||||||
|
(name, budget_id)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetCategoryGroups :many
|
||||||
|
SELECT category_groups.* FROM category_groups
|
||||||
|
WHERE category_groups.budget_id = $1;
|
||||||
|
|
||||||
|
-- name: CreateCategory :one
|
||||||
|
INSERT INTO categories
|
||||||
|
(name, category_group_id)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetCategories :many
|
||||||
|
SELECT categories.*, category_groups.name as group FROM categories
|
||||||
|
INNER JOIN category_groups ON categories.category_group_id = category_groups.id
|
||||||
|
WHERE category_groups.budget_id = $1;
|
@ -1,7 +1,7 @@
|
|||||||
-- name: CreateTransaction :one
|
-- name: CreateTransaction :one
|
||||||
INSERT INTO transactions
|
INSERT INTO transactions
|
||||||
(date, memo, amount, account_id, payee_id)
|
(date, memo, amount, account_id, payee_id, category_id)
|
||||||
VALUES ($1, $2, $3, $4, $5)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetTransactionsForBudget :many
|
-- name: GetTransactionsForBudget :many
|
||||||
|
@ -33,6 +33,7 @@ CREATE TABLE payees (
|
|||||||
budget_id uuid NOT NULL,
|
budget_id uuid NOT NULL,
|
||||||
name varchar(50) NOT NULL
|
name varchar(50) NOT NULL
|
||||||
);
|
);
|
||||||
|
ALTER TABLE "payees" ADD FOREIGN KEY ("budget_id") REFERENCES "budgets" ("id");
|
||||||
|
|
||||||
CREATE TABLE transactions (
|
CREATE TABLE transactions (
|
||||||
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||||
@ -40,10 +41,27 @@ CREATE TABLE transactions (
|
|||||||
memo text NOT NULL,
|
memo text NOT NULL,
|
||||||
amount decimal(12,2) NOT NULL,
|
amount decimal(12,2) NOT NULL,
|
||||||
account_id uuid NOT NULL,
|
account_id uuid NOT NULL,
|
||||||
|
category_id uuid,
|
||||||
payee_id uuid
|
payee_id uuid
|
||||||
);
|
);
|
||||||
ALTER TABLE "transactions" ADD FOREIGN KEY ("account_id") REFERENCES "accounts" ("id");
|
ALTER TABLE "transactions" ADD FOREIGN KEY ("account_id") REFERENCES "accounts" ("id");
|
||||||
ALTER TABLE "transactions" ADD FOREIGN KEY ("payee_id") REFERENCES "payees" ("id");
|
ALTER TABLE "transactions" ADD FOREIGN KEY ("payee_id") REFERENCES "payees" ("id");
|
||||||
|
ALTER TABLE "transactions" ADD FOREIGN KEY ("category_id") REFERENCES "categories" ("id");
|
||||||
|
|
||||||
|
CREATE TABLE category_groups (
|
||||||
|
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||||
|
budget_id uuid NOT NULL,
|
||||||
|
name varchar(50) NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "category_groups" ADD FOREIGN KEY ("budget_id") REFERENCES "budgets" ("id");
|
||||||
|
|
||||||
|
CREATE TABLE categories (
|
||||||
|
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||||
|
category_group_id uuid NOT NULL,
|
||||||
|
name varchar(50) NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "categories" ADD FOREIGN KEY ("category_group_id") REFERENCES "category_group" ("id");
|
||||||
|
|
||||||
|
|
||||||
-- +goose Down
|
-- +goose Down
|
||||||
DROP TABLE transactions;
|
DROP TABLE transactions;
|
||||||
|
@ -12,9 +12,9 @@ import (
|
|||||||
|
|
||||||
const createTransaction = `-- name: CreateTransaction :one
|
const createTransaction = `-- name: CreateTransaction :one
|
||||||
INSERT INTO transactions
|
INSERT INTO transactions
|
||||||
(date, memo, amount, account_id, payee_id)
|
(date, memo, amount, account_id, payee_id, category_id)
|
||||||
VALUES ($1, $2, $3, $4, $5)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING id, date, memo, amount, account_id, payee_id
|
RETURNING id, date, memo, amount, account_id, category_id, payee_id
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateTransactionParams struct {
|
type CreateTransactionParams struct {
|
||||||
@ -23,6 +23,7 @@ type CreateTransactionParams struct {
|
|||||||
Amount Numeric
|
Amount Numeric
|
||||||
AccountID uuid.UUID
|
AccountID uuid.UUID
|
||||||
PayeeID uuid.NullUUID
|
PayeeID uuid.NullUUID
|
||||||
|
CategoryID uuid.NullUUID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionParams) (Transaction, error) {
|
func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionParams) (Transaction, error) {
|
||||||
@ -32,6 +33,7 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa
|
|||||||
arg.Amount,
|
arg.Amount,
|
||||||
arg.AccountID,
|
arg.AccountID,
|
||||||
arg.PayeeID,
|
arg.PayeeID,
|
||||||
|
arg.CategoryID,
|
||||||
)
|
)
|
||||||
var i Transaction
|
var i Transaction
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
@ -40,6 +42,7 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa
|
|||||||
&i.Memo,
|
&i.Memo,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.AccountID,
|
&i.AccountID,
|
||||||
|
&i.CategoryID,
|
||||||
&i.PayeeID,
|
&i.PayeeID,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user