diff --git a/handler/transaction.go b/handler/transaction.go index 9768c90..f6d79c6 100644 --- a/handler/transaction.go +++ b/handler/transaction.go @@ -228,7 +228,7 @@ func (h TransactionImpl) getTransactionData(accounts []*types.Account, treasureC treasureChestMap := make(map[uuid.UUID]string, 0) root := "" for _, treasureChest := range treasureChests { - if treasureChest.ParentId == uuid.Nil { + if treasureChest.ParentId == nil { root = treasureChest.Name + " > " treasureChestMap[treasureChest.Id] = treasureChest.Name } else { diff --git a/migration/007_treasure_chest_parent_id_fix.up.sql b/migration/007_treasure_chest_parent_id_fix.up.sql new file mode 100644 index 0000000..c99bab3 --- /dev/null +++ b/migration/007_treasure_chest_parent_id_fix.up.sql @@ -0,0 +1,3 @@ +UPDATE treasure_chest +SET parent_id = NULL +WHERE parent_id = "00000000-0000-0000-0000-000000000000"; diff --git a/service/default.go b/service/default.go index cd71904..130f672 100644 --- a/service/default.go +++ b/service/default.go @@ -6,7 +6,7 @@ import ( ) var ( - safeInputRegex = regexp.MustCompile(`^[a-zA-Z0-9ÄÖÜäöüß, -]+$`) + safeInputRegex = regexp.MustCompile(`^[a-zA-Z0-9ÄÖÜäöüß,& -]+$`) ) func validateString(value string, fieldName string) error { diff --git a/service/transaction.go b/service/transaction.go index 6e49440..6cab62b 100644 --- a/service/transaction.go +++ b/service/transaction.go @@ -424,6 +424,7 @@ func (s TransactionImpl) RecalculateBalances(user *types.User) error { if err != nil { return err } + } } @@ -493,14 +494,17 @@ func (s TransactionImpl) validateAndEnrichTransaction(tx *sqlx.Tx, oldTransactio return nil, fmt.Errorf("could not parse treasureChestId: %w", ErrBadRequest) } treasureChestUuid = &temp - err = tx.Get(&rowCount, `SELECT COUNT(*) FROM treasure_chest WHERE id = ? AND user_id = ?`, treasureChestUuid, userId) + var treasureChest types.TreasureChest + err = tx.Get(&treasureChest, `SELECT * FROM treasure_chest WHERE id = ? AND user_id = ?`, treasureChestUuid, userId) err = db.TransformAndLogDbError("transaction validate", nil, err) if err != nil { + if err == db.ErrNotFound { + return nil, fmt.Errorf("treasure chest not found: %w", ErrBadRequest) + } return nil, err } - if rowCount == 0 { - log.Error("transaction validate: %v", err) - return nil, fmt.Errorf("treasure chest not found: %w", ErrBadRequest) + if treasureChest.ParentId == nil { + return nil, fmt.Errorf("treasure chest is a group: %w", ErrBadRequest) } } diff --git a/service/treasure_chest.go b/service/treasure_chest.go index 834d778..ab865f7 100644 --- a/service/treasure_chest.go +++ b/service/treasure_chest.go @@ -65,16 +65,16 @@ func (s TreasureChestImpl) Add(user *types.User, parentId, name string) (*types. return nil, err } - parentUuid := uuid.Nil + var parentUuid *uuid.UUID if parentId != "" { parent, err := s.Get(user, parentId) if err != nil { return nil, err } - if parent.ParentId != uuid.Nil { + if parent.ParentId != nil { return nil, fmt.Errorf("only a depth of 1 allowed: %w", ErrBadRequest) } - parentUuid = parent.Id + parentUuid = &parent.Id } treasureChest := &types.TreasureChest{ @@ -137,7 +137,7 @@ func (s TreasureChestImpl) Update(user *types.User, idStr, parentId, name string return nil, types.ErrInternal } - parentUuid := uuid.Nil + var parentUuid *uuid.UUID if parentId != "" { parent, err := s.Get(user, parentId) if err != nil { @@ -149,11 +149,11 @@ func (s TreasureChestImpl) Update(user *types.User, idStr, parentId, name string if err != nil { return nil, err } - if parent.ParentId != uuid.Nil || childCount > 0 { + if parent.ParentId != nil || childCount > 0 { return nil, fmt.Errorf("only one level allowed: %w", ErrBadRequest) } - parentUuid = parent.Id + parentUuid = &parent.Id } timestamp := s.clock.Now() @@ -292,10 +292,10 @@ func sortTree(nodes []*types.TreasureChest) []*types.TreasureChest { children := make(map[uuid.UUID][]*types.TreasureChest) for _, node := range nodes { - if node.ParentId == uuid.Nil { + if node.ParentId == nil { roots = append(roots, node) } else { - children[node.ParentId] = append(children[node.ParentId], node) + children[*node.ParentId] = append(children[*node.ParentId], node) } } diff --git a/template/transaction/transaction.templ b/template/transaction/transaction.templ index d141443..94370ca 100644 --- a/template/transaction/transaction.templ +++ b/template/transaction/transaction.templ @@ -27,10 +27,10 @@ templ Transaction(items templ.Component, filter types.TransactionItemsFilter, ac - - for _, treasureChest := range treasureChests { - + diff --git a/template/treasurechest/treasure_chest.templ b/template/treasurechest/treasure_chest.templ index d6024bb..76441c7 100644 --- a/template/treasurechest/treasure_chest.templ +++ b/template/treasurechest/treasure_chest.templ @@ -41,7 +41,9 @@ templ EditTreasureChest(treasureChest *types.TreasureChest, parents []*types.Tre } else { id = treasureChest.Id.String() name = treasureChest.Name - parentId = treasureChest.ParentId + if treasureChest.ParentId != nil { + parentId = *treasureChest.ParentId + } cancelUrl = "/treasurechest/" + id } }} @@ -93,23 +95,27 @@ templ EditTreasureChest(treasureChest *types.TreasureChest, parents []*types.Tre templ TreasureChestItem(treasureChest *types.TreasureChest) { {{ var identation string - if treasureChest.ParentId != uuid.Nil { + viewTransactions := "" + if treasureChest.ParentId != nil { identation = " mt-2 ml-36" } else { identation = " mt-8" + viewTransactions = "hidden" } }}

{ treasureChest.Name }

- if treasureChest.CurrentBalance < 0 { -

{ displayBalance(treasureChest.CurrentBalance) }

- } else { -

{ displayBalance(treasureChest.CurrentBalance) }

+ if treasureChest.ParentId != nil { + if treasureChest.CurrentBalance < 0 { +

{ displayBalance(treasureChest.CurrentBalance) }

+ } else { +

{ displayBalance(treasureChest.CurrentBalance) }

+ } } @svg.Eye() @@ -147,7 +153,7 @@ func filterNoChildNoSelf(nodes []*types.TreasureChest, selfId string) []*types.T var result []*types.TreasureChest for _, node := range nodes { - if node.ParentId == uuid.Nil && node.Id.String() != selfId { + if node.ParentId == nil && node.Id.String() != selfId { result = append(result, node) } } diff --git a/types/treasure_chest.go b/types/treasure_chest.go index 6bf5cb8..cd5369e 100644 --- a/types/treasure_chest.go +++ b/types/treasure_chest.go @@ -13,8 +13,8 @@ import ( // Imagne a TreasureChest for free time activities, where some money is spend in cash and some other with credit card type TreasureChest struct { Id uuid.UUID - ParentId uuid.UUID `db:"parent_id"` - UserId uuid.UUID `db:"user_id"` + ParentId *uuid.UUID `db:"parent_id"` + UserId uuid.UUID `db:"user_id"` Name string