119 lines
2.6 KiB
Go
119 lines
2.6 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"slices"
|
||
|
|
||
|
"gitrepo.ru/neonxp/nquest/pkg/models"
|
||
|
"gorm.io/gorm"
|
||
|
"gorm.io/gorm/clause"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ErrTeamNotFound = errors.New("team not found")
|
||
|
)
|
||
|
|
||
|
type Team struct {
|
||
|
DB *gorm.DB
|
||
|
}
|
||
|
|
||
|
// NewTeam returns new Team.
|
||
|
func NewTeam(db *gorm.DB) *Team {
|
||
|
return &Team{
|
||
|
DB: db,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (ts *Team) List(ctx context.Context) ([]*models.Team, error) {
|
||
|
teams := []*models.Team{}
|
||
|
|
||
|
return teams, ts.DB.WithContext(ctx).Preload("Members").Find(&teams).Error
|
||
|
}
|
||
|
|
||
|
func (ts *Team) Create(ctx context.Context, name string, user *models.User) (*models.Team, error) {
|
||
|
t := &models.Team{
|
||
|
Name: name,
|
||
|
Members: []*models.TeamMember{{
|
||
|
User: user,
|
||
|
Role: models.Captain,
|
||
|
}},
|
||
|
}
|
||
|
|
||
|
db := ts.DB.WithContext(ctx)
|
||
|
|
||
|
if err := db.Delete(&models.TeamRequest{}, `user_id = ?`, user.ID).Error; err != nil {
|
||
|
return t, err
|
||
|
}
|
||
|
|
||
|
return t, db.Create(t).Error
|
||
|
}
|
||
|
|
||
|
func (ts *Team) GetByID(ctx context.Context, id uint) (*models.Team, error) {
|
||
|
t := new(models.Team)
|
||
|
|
||
|
err := ts.DB.
|
||
|
WithContext(ctx).
|
||
|
Preload("Members").
|
||
|
Preload("Members.User").
|
||
|
Preload("Requests").
|
||
|
Preload("Requests.User").
|
||
|
First(t, id).
|
||
|
Error
|
||
|
if err != nil {
|
||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||
|
return nil, ErrTeamNotFound
|
||
|
}
|
||
|
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return t, nil
|
||
|
}
|
||
|
|
||
|
func (ts *Team) Request(ctx context.Context, team *models.Team, user *models.User) error {
|
||
|
return ts.DB.
|
||
|
WithContext(ctx).
|
||
|
Clauses(clause.OnConflict{DoNothing: true}).
|
||
|
Create(&models.TeamRequest{
|
||
|
Team: team,
|
||
|
User: user,
|
||
|
}).
|
||
|
Error
|
||
|
}
|
||
|
|
||
|
func (ts *Team) ApproveMember(ctx context.Context, team *models.Team, user *models.User) error {
|
||
|
team.Requests = slices.DeleteFunc(team.Requests, func(tr *models.TeamRequest) bool {
|
||
|
return tr.UserID == user.ID
|
||
|
})
|
||
|
|
||
|
team.Members = append(team.Members, &models.TeamMember{
|
||
|
Team: team,
|
||
|
User: user,
|
||
|
Role: models.Member,
|
||
|
})
|
||
|
|
||
|
db := ts.DB.WithContext(ctx)
|
||
|
if err := db.Delete(&models.TeamRequest{}, `user_id = ?`, user.ID).Error; err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return db.Save(team).Error
|
||
|
}
|
||
|
|
||
|
func (ts *Team) DeclineMember(ctx context.Context, team *models.Team, user *models.User) error {
|
||
|
team.Requests = slices.DeleteFunc(team.Requests, func(tr *models.TeamRequest) bool {
|
||
|
return tr.UserID == user.ID
|
||
|
})
|
||
|
db := ts.DB.WithContext(ctx)
|
||
|
if err := db.Delete(&models.TeamRequest{}, `user_id = ?`, user.ID).Error; err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(team).Error
|
||
|
}
|
||
|
|
||
|
func (ts *Team) RemoveMember(ctx context.Context, team *models.Team, user *models.User) error {
|
||
|
return ts.DB.WithContext(ctx).Delete(&models.TeamMember{}, `user_id = ? and team_id = ?`, user.ID, team.ID).Error
|
||
|
}
|