126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package projectv1
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"slices"
|
|
|
|
"connectrpc.com/connect"
|
|
"git.kocoder.xyz/kocoded/vt/fx"
|
|
projectv1 "git.kocoder.xyz/kocoded/vt/gen/project/v1"
|
|
"git.kocoder.xyz/kocoded/vt/gen/project/v1/projectv1connect"
|
|
"git.kocoder.xyz/kocoded/vt/interceptors"
|
|
"git.kocoder.xyz/kocoded/vt/model"
|
|
"git.kocoder.xyz/kocoded/vt/query"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func NewProjectRoute(db *gorm.DB, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
|
path, handler := projectv1connect.NewProjectServiceHandler(&projectService{db: db}, connect.WithInterceptors(oidcInterceptor))
|
|
|
|
return fx.NewRoute(path, handler)
|
|
}
|
|
|
|
type projectService struct{ db *gorm.DB }
|
|
|
|
// ListProjects implements projectv1connect.ProjectServiceHandler.
|
|
func (s *projectService) ListProjects(ctx context.Context, req *projectv1.ListProjectsRequest) (*projectv1.ListProjectsResponse, error) {
|
|
session, ok := interceptors.SessionFromContext(ctx)
|
|
if !ok {
|
|
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
|
|
}
|
|
|
|
p := query.Use(s.db).Projekt
|
|
|
|
query := p.Where(p.MandantID.Eq(session.MandantId)).Limit(int(req.PerPage)).Offset(int(req.Page))
|
|
|
|
if req.OrberBy != "" {
|
|
f, ok := p.GetFieldByName(req.OrberBy)
|
|
if ok {
|
|
if !req.Asc {
|
|
query = query.Order(f.Desc())
|
|
} else {
|
|
query = query.Order(f.Asc())
|
|
}
|
|
}
|
|
} else {
|
|
query = query.Order(p.ID.Asc())
|
|
}
|
|
|
|
projects, err := query.Find()
|
|
if err != nil {
|
|
return nil, connect.NewError(connect.CodeUnknown, err)
|
|
}
|
|
|
|
cnt, err := p.Where(p.MandantID.Eq(session.MandantId)).Count()
|
|
if err != nil {
|
|
return nil, connect.NewError(connect.CodeUnimplemented, err)
|
|
}
|
|
|
|
data := make([]*projectv1.GetProjectResponse, len(projects))
|
|
for i, p := range projects {
|
|
data[i] = &projectv1.GetProjectResponse{
|
|
Id: int64(p.ID),
|
|
Name: p.Name,
|
|
Description: p.Description,
|
|
IsMaterialized: newPointerBoolean(true),
|
|
IsPersonalized: newPointerBoolean(true),
|
|
IsConfirmed: newPointerBoolean(true),
|
|
IsPaid: nil,
|
|
IsDone: s.IsDone(p),
|
|
}
|
|
}
|
|
|
|
return &projectv1.ListProjectsResponse{
|
|
Data: data,
|
|
Meta: &projectv1.Metadata{TotalCount: int32(cnt)},
|
|
}, nil
|
|
}
|
|
|
|
func newPointerBoolean(val bool) *bool {
|
|
b := val
|
|
return &b
|
|
}
|
|
|
|
func (s *projectService) IsDone(p *model.Projekt) *bool {
|
|
t := query.Use(s.db).Task
|
|
tasks, err := t.Where(t.ProjektID.Eq(p.ID)).Find()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(tasks) == 0 {
|
|
return nil
|
|
}
|
|
if i := slices.IndexFunc(tasks, func(t *model.Task) bool {
|
|
return !t.Status.IsDone()
|
|
}); i != -1 {
|
|
return newPointerBoolean(false)
|
|
}
|
|
return newPointerBoolean(true)
|
|
}
|
|
|
|
func (s *projectService) GetProject(ctx context.Context, req *projectv1.GetProjectRequest) (*projectv1.GetProjectResponse, error) {
|
|
session, ok := interceptors.SessionFromContext(ctx)
|
|
if !ok {
|
|
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
|
|
}
|
|
|
|
p := query.Use(s.db).Projekt
|
|
|
|
query, err := p.Where(p.ID.Eq(uint(req.Id))).Where(p.MandantID.Eq(session.MandantId)).First()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &projectv1.GetProjectResponse{
|
|
Id: int64(query.ID),
|
|
Name: query.Name,
|
|
Description: query.Description,
|
|
IsMaterialized: newPointerBoolean(true),
|
|
IsPersonalized: newPointerBoolean(true),
|
|
IsConfirmed: newPointerBoolean(true),
|
|
IsPaid: newPointerBoolean(true),
|
|
IsDone: newPointerBoolean(true),
|
|
}, nil
|
|
}
|