feat(ClubTeam): enhance club team management with lineup features and member eligibility
- Added teamGender and teamAgeGroup fields to ClubTeam model for better categorization. - Updated create and update club team endpoints to handle new fields and default values. - Implemented getClubTeamLineup and updateClubTeamLineup functions for managing team lineups. - Enhanced member management with adultReleaseApproved and adultReserveApproved fields in Member model. - Updated frontend views to support new lineup features and member eligibility flags. - Improved localization for new terms related to team management and member eligibility across multiple languages.
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
import ClubTeam from '../models/ClubTeam.js';
|
||||
import ClubTeamMember from '../models/ClubTeamMember.js';
|
||||
import League from '../models/League.js';
|
||||
import Member from '../models/Member.js';
|
||||
import Season from '../models/Season.js';
|
||||
import SeasonService from './seasonService.js';
|
||||
import { devLog } from '../utils/logger.js';
|
||||
|
||||
class ClubTeamService {
|
||||
static isMissingTeamLineupTable(error) {
|
||||
return error?.original?.code === 'ER_NO_SUCH_TABLE'
|
||||
&& String(error?.original?.sqlMessage || '').includes('club_team_member');
|
||||
}
|
||||
/**
|
||||
* Holt alle ClubTeams für einen Verein, optional gefiltert nach Saison.
|
||||
* Wenn keine Saison-ID angegeben ist, wird die aktuelle Saison verwendet.
|
||||
@@ -36,6 +42,8 @@ class ClubTeamService {
|
||||
leagueId: clubTeam.leagueId,
|
||||
seasonId: clubTeam.seasonId,
|
||||
myTischtennisTeamId: clubTeam.myTischtennisTeamId,
|
||||
teamGender: clubTeam.teamGender,
|
||||
teamAgeGroup: clubTeam.teamAgeGroup,
|
||||
createdAt: clubTeam.createdAt,
|
||||
updatedAt: clubTeam.updatedAt,
|
||||
league: { name: 'Unbekannt' },
|
||||
@@ -178,6 +186,63 @@ class ClubTeamService {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async getTeamLineup(clubTeamId, lineupHalf = 'first_half') {
|
||||
try {
|
||||
return await ClubTeamMember.findAll({
|
||||
where: { clubTeamId, lineupHalf },
|
||||
include: [
|
||||
{
|
||||
model: Member,
|
||||
as: 'member'
|
||||
}
|
||||
],
|
||||
order: [['position', 'ASC']]
|
||||
});
|
||||
} catch (error) {
|
||||
if (this.isMissingTeamLineupTable(error)) {
|
||||
return [];
|
||||
}
|
||||
console.error('[ClubTeamService.getTeamLineup] - Error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async replaceTeamLineup(clubTeamId, assignments, lineupHalf = 'first_half') {
|
||||
try {
|
||||
await ClubTeamMember.destroy({
|
||||
where: { clubTeamId, lineupHalf }
|
||||
});
|
||||
|
||||
if (!Array.isArray(assignments) || assignments.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const normalizedAssignments = assignments
|
||||
.filter((entry) => entry && entry.memberId)
|
||||
.map((entry, index) => ({
|
||||
clubTeamId,
|
||||
lineupHalf,
|
||||
memberId: Number(entry.memberId),
|
||||
position: Number(entry.position) || (index + 1)
|
||||
}));
|
||||
|
||||
if (normalizedAssignments.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
await ClubTeamMember.bulkCreate(normalizedAssignments);
|
||||
return await this.getTeamLineup(clubTeamId, lineupHalf);
|
||||
} catch (error) {
|
||||
if (this.isMissingTeamLineupTable(error)) {
|
||||
const tableMissingError = new Error('teamlineuptablemissing');
|
||||
tableMissingError.code = 'TEAM_LINEUP_TABLE_MISSING';
|
||||
throw tableMissingError;
|
||||
}
|
||||
console.error('[ClubTeamService.replaceTeamLineup] - Error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ClubTeamService;
|
||||
|
||||
@@ -106,7 +106,7 @@ class MemberService {
|
||||
}
|
||||
|
||||
async setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, postalCode, birthdate, phone, email, active = true, testMembership = false,
|
||||
picsInInternetAllowed = false, gender = 'unknown', ttr = null, qttr = null, memberFormHandedOver = false, contacts = []) {
|
||||
picsInInternetAllowed = false, gender = 'unknown', ttr = null, qttr = null, memberFormHandedOver = false, adultReleaseApproved = false, adultReserveApproved = false, contacts = []) {
|
||||
try {
|
||||
await checkAccess(userToken, clubId);
|
||||
let member = null;
|
||||
@@ -130,6 +130,8 @@ class MemberService {
|
||||
if (ttr !== undefined) member.ttr = ttr;
|
||||
if (qttr !== undefined) member.qttr = qttr;
|
||||
member.memberFormHandedOver = !!memberFormHandedOver;
|
||||
member.adultReleaseApproved = !!adultReleaseApproved;
|
||||
member.adultReserveApproved = !!adultReserveApproved;
|
||||
await member.save();
|
||||
|
||||
// Update contacts if provided
|
||||
@@ -173,6 +175,8 @@ class MemberService {
|
||||
ttr: ttr,
|
||||
qttr: qttr,
|
||||
memberFormHandedOver: !!memberFormHandedOver,
|
||||
adultReleaseApproved: !!adultReleaseApproved,
|
||||
adultReserveApproved: !!adultReserveApproved,
|
||||
});
|
||||
|
||||
// Create contacts if provided
|
||||
|
||||
Reference in New Issue
Block a user