Yimaru-BackEnd/internal/services/team/team.go

165 lines
4.9 KiB
Go

package team
import (
"context"
"time"
"Yimaru-Backend/internal/domain"
"golang.org/x/crypto/bcrypt"
)
const bcryptCost = 10
func (s *Service) CreateTeamMember(ctx context.Context, req domain.CreateTeamMemberReq, createdBy *int64) (domain.TeamMember, error) {
if !domain.TeamRole(req.TeamRole).IsValid() {
return domain.TeamMember{}, domain.ErrInvalidTeamRole
}
if req.EmploymentType != "" && !domain.EmploymentType(req.EmploymentType).IsValid() {
return domain.TeamMember{}, domain.ErrInvalidEmploymentType
}
exists, err := s.teamStore.CheckTeamMemberEmailExists(ctx, req.Email)
if err != nil {
return domain.TeamMember{}, err
}
if exists {
return domain.TeamMember{}, domain.ErrTeamMemberEmailExists
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcryptCost)
if err != nil {
return domain.TeamMember{}, err
}
var hireDate *time.Time
if req.HireDate != "" {
parsed, err := time.Parse("2006-01-02", req.HireDate)
if err != nil {
return domain.TeamMember{}, err
}
hireDate = &parsed
}
member := domain.TeamMember{
FirstName: req.FirstName,
LastName: req.LastName,
Email: req.Email,
PhoneNumber: req.PhoneNumber,
Password: hashedPassword,
TeamRole: domain.TeamRole(req.TeamRole),
Department: req.Department,
JobTitle: req.JobTitle,
EmploymentType: domain.EmploymentType(req.EmploymentType),
HireDate: hireDate,
ProfilePictureURL: req.ProfilePictureURL,
Bio: req.Bio,
WorkPhone: req.WorkPhone,
EmergencyContact: req.EmergencyContact,
Status: domain.TeamMemberStatusActive,
Permissions: req.Permissions,
CreatedBy: createdBy,
}
return s.teamStore.CreateTeamMember(ctx, member)
}
func (s *Service) GetTeamMemberByID(ctx context.Context, id int64) (domain.TeamMember, error) {
return s.teamStore.GetTeamMemberByID(ctx, id)
}
func (s *Service) GetTeamMemberByEmail(ctx context.Context, email string) (domain.TeamMember, error) {
return s.teamStore.GetTeamMemberByEmail(ctx, email)
}
func (s *Service) GetAllTeamMembers(ctx context.Context, filter domain.TeamMemberFilter) ([]domain.TeamMember, int64, error) {
var limit int32 = 10
var offset int32 = 0
if filter.PageSize > 0 {
limit = int32(filter.PageSize)
}
if filter.Page > 0 && filter.PageSize > 0 {
offset = int32((filter.Page - 1) * filter.PageSize)
}
return s.teamStore.GetAllTeamMembers(ctx, filter.TeamRole, filter.Department, filter.Status, limit, offset)
}
func (s *Service) SearchTeamMembers(ctx context.Context, search string, teamRole, status *string) ([]domain.TeamMember, error) {
return s.teamStore.SearchTeamMembers(ctx, search, teamRole, status)
}
func (s *Service) UpdateTeamMember(ctx context.Context, req domain.UpdateTeamMemberReq) error {
if req.TeamRole != "" && !domain.TeamRole(req.TeamRole).IsValid() {
return domain.ErrInvalidTeamRole
}
if req.EmploymentType != "" && !domain.EmploymentType(req.EmploymentType).IsValid() {
return domain.ErrInvalidEmploymentType
}
return s.teamStore.UpdateTeamMember(ctx, req)
}
func (s *Service) UpdateTeamMemberStatus(ctx context.Context, req domain.UpdateTeamMemberStatusReq) error {
if !domain.TeamMemberStatus(req.Status).IsValid() {
return domain.ErrInvalidTeamMemberStatus
}
return s.teamStore.UpdateTeamMemberStatus(ctx, req)
}
func (s *Service) DeleteTeamMember(ctx context.Context, memberID int64) error {
return s.teamStore.DeleteTeamMember(ctx, memberID)
}
func (s *Service) GetTeamMemberStats(ctx context.Context) (domain.TeamMemberStats, error) {
return s.teamStore.CountTeamMembersByStatus(ctx)
}
func (s *Service) Login(ctx context.Context, req domain.TeamMemberLoginReq) (domain.TeamMember, error) {
member, err := s.teamStore.GetTeamMemberByEmail(ctx, req.Email)
if err != nil {
return domain.TeamMember{}, err
}
if err := bcrypt.CompareHashAndPassword(member.Password, []byte(req.Password)); err != nil {
return domain.TeamMember{}, err
}
if err := s.teamStore.UpdateTeamMemberLastLogin(ctx, member.ID); err != nil {
return domain.TeamMember{}, err
}
return member, nil
}
func (s *Service) ChangePassword(ctx context.Context, memberID int64, currentPassword, newPassword string) error {
member, err := s.teamStore.GetTeamMemberByID(ctx, memberID)
if err != nil {
return err
}
if err := bcrypt.CompareHashAndPassword(member.Password, []byte(currentPassword)); err != nil {
return err
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcryptCost)
if err != nil {
return err
}
return s.teamStore.UpdateTeamMemberPassword(ctx, memberID, string(hashedPassword))
}
func (s *Service) ResetPassword(ctx context.Context, memberID int64, newPassword string) error {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcryptCost)
if err != nil {
return err
}
return s.teamStore.UpdateTeamMemberPassword(ctx, memberID, string(hashedPassword))
}