forked from mirrors/homebox
feat: currency selection support (#72)
* initial UI for currency selection * add task to purge invitation tokens * group API contracts * fix type import * use auth middleware * add currency setting support (UI) * use group settings for format currency * fix casing
This commit is contained in:
parent
1cc38d6a5c
commit
461be2afca
40 changed files with 930 additions and 343 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/ent"
|
||||
"github.com/hay-kot/homebox/backend/ent/group"
|
||||
"github.com/hay-kot/homebox/backend/ent/groupinvitationtoken"
|
||||
)
|
||||
|
||||
|
@ -15,11 +16,16 @@ type GroupRepository struct {
|
|||
|
||||
type (
|
||||
Group struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Currency string
|
||||
ID uuid.UUID `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt time.Time `json:"updatedAt,omitempty"`
|
||||
Currency string `json:"currency,omitempty"`
|
||||
}
|
||||
|
||||
GroupUpdate struct {
|
||||
Name string `json:"name"`
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
|
||||
GroupInvitationCreate struct {
|
||||
|
@ -69,6 +75,17 @@ func (r *GroupRepository) GroupCreate(ctx context.Context, name string) (Group,
|
|||
Save(ctx))
|
||||
}
|
||||
|
||||
func (r *GroupRepository) GroupUpdate(ctx context.Context, ID uuid.UUID, data GroupUpdate) (Group, error) {
|
||||
currency := group.Currency(data.Currency)
|
||||
|
||||
entity, err := r.db.Group.UpdateOneID(ID).
|
||||
SetName(data.Name).
|
||||
SetCurrency(currency).
|
||||
Save(ctx)
|
||||
|
||||
return mapToGroupErr(entity, err)
|
||||
}
|
||||
|
||||
func (r *GroupRepository) GroupByID(ctx context.Context, id uuid.UUID) (Group, error) {
|
||||
return mapToGroupErr(r.db.Group.Get(ctx, id))
|
||||
}
|
||||
|
|
|
@ -18,3 +18,16 @@ func Test_Group_Create(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, g.ID, foundGroup.ID)
|
||||
}
|
||||
|
||||
func Test_Group_Update(t *testing.T) {
|
||||
g, err := tRepos.Groups.GroupCreate(context.Background(), "test")
|
||||
assert.NoError(t, err)
|
||||
|
||||
g, err = tRepos.Groups.GroupUpdate(context.Background(), g.ID, GroupUpdate{
|
||||
Name: "test2",
|
||||
Currency: "eur",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "test2", g.Name)
|
||||
assert.Equal(t, "eur", g.Currency)
|
||||
}
|
||||
|
|
|
@ -4,18 +4,20 @@ import "github.com/hay-kot/homebox/backend/internal/repo"
|
|||
|
||||
type AllServices struct {
|
||||
User *UserService
|
||||
Group *GroupService
|
||||
Location *LocationService
|
||||
Labels *LabelService
|
||||
Items *ItemService
|
||||
}
|
||||
|
||||
func NewServices(repos *repo.AllRepos) *AllServices {
|
||||
func New(repos *repo.AllRepos) *AllServices {
|
||||
if repos == nil {
|
||||
panic("repos cannot be nil")
|
||||
}
|
||||
|
||||
return &AllServices{
|
||||
User: &UserService{repos},
|
||||
Group: &GroupService{repos},
|
||||
Location: &LocationService{repos},
|
||||
Labels: &LabelService{repos},
|
||||
Items: &ItemService{
|
||||
|
|
|
@ -63,7 +63,7 @@ func TestMain(m *testing.M) {
|
|||
|
||||
tClient = client
|
||||
tRepos = repo.New(tClient, os.TempDir()+"/homebox")
|
||||
tSvc = NewServices(tRepos)
|
||||
tSvc = New(tRepos)
|
||||
defer client.Close()
|
||||
|
||||
bootstrap()
|
||||
|
|
47
backend/internal/services/service_group.go
Normal file
47
backend/internal/services/service_group.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||
)
|
||||
|
||||
type GroupService struct {
|
||||
repos *repo.AllRepos
|
||||
}
|
||||
|
||||
func (svc *GroupService) Get(ctx Context) (repo.Group, error) {
|
||||
return svc.repos.Groups.GroupByID(ctx.Context, ctx.GID)
|
||||
}
|
||||
|
||||
func (svc *GroupService) UpdateGroup(ctx Context, data repo.GroupUpdate) (repo.Group, error) {
|
||||
if data.Name == "" {
|
||||
data.Name = ctx.User.GroupName
|
||||
}
|
||||
|
||||
if data.Currency == "" {
|
||||
return repo.Group{}, errors.New("currency cannot be empty")
|
||||
}
|
||||
|
||||
data.Currency = strings.ToLower(data.Currency)
|
||||
|
||||
return svc.repos.Groups.GroupUpdate(ctx.Context, ctx.GID, data)
|
||||
}
|
||||
|
||||
func (svc *GroupService) NewInvitation(ctx Context, uses int, expiresAt time.Time) (string, error) {
|
||||
token := hasher.GenerateToken()
|
||||
|
||||
_, err := svc.repos.Groups.InvitationCreate(ctx, ctx.GID, repo.GroupInvitationCreate{
|
||||
Token: token.Hash,
|
||||
Uses: uses,
|
||||
ExpiresAt: expiresAt,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token.Raw, nil
|
||||
}
|
|
@ -186,21 +186,6 @@ func (svc *UserService) DeleteSelf(ctx context.Context, ID uuid.UUID) error {
|
|||
return svc.repos.Users.Delete(ctx, ID)
|
||||
}
|
||||
|
||||
func (svc *UserService) NewInvitation(ctx Context, uses int, expiresAt time.Time) (string, error) {
|
||||
token := hasher.GenerateToken()
|
||||
|
||||
_, err := svc.repos.Groups.InvitationCreate(ctx, ctx.GID, repo.GroupInvitationCreate{
|
||||
Token: token.Hash,
|
||||
Uses: uses,
|
||||
ExpiresAt: expiresAt,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token.Raw, nil
|
||||
}
|
||||
|
||||
func (svc *UserService) ChangePassword(ctx Context, current string, new string) (ok bool) {
|
||||
usr, err := svc.repos.Users.GetOneId(ctx, ctx.UID)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue