2023-11-01 23:21:12 +03:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-11-05 22:22:54 +03:00
|
|
|
func (ts *Team) Delete(ctx context.Context, id uint) error {
|
|
|
|
if err := ts.DB.WithContext(ctx).Delete(&models.Team{}, id).Error; err != nil {
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
return ErrTeamNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-11-01 23:21:12 +03:00
|
|
|
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
|
|
|
|
}
|