Enhance member management by adding postal code and contact handling
Introduced a postal code field to the member model and implemented a new MemberContact model to manage multiple phone numbers and email addresses. Updated the member service and controller to handle contact data during member creation and updates. Enhanced the MembersView component to support input for multiple contacts, ensuring better organization and accessibility of member information.
This commit is contained in:
@@ -29,13 +29,41 @@ class MemberService {
|
||||
if (!showAll || showAll === 'false') {
|
||||
where['active'] = true;
|
||||
}
|
||||
return await Member.findAll({ where })
|
||||
const MemberContact = (await import('../models/MemberContact.js')).default;
|
||||
return await Member.findAll({
|
||||
where,
|
||||
include: [{
|
||||
model: MemberContact,
|
||||
as: 'contacts',
|
||||
required: false,
|
||||
attributes: ['id', 'memberId', 'type', 'value', 'isParent', 'parentName', 'isPrimary', 'createdAt', 'updatedAt']
|
||||
}],
|
||||
raw: false // Ensure we get model instances, not plain objects, so getters are called
|
||||
})
|
||||
.then(members => {
|
||||
return members.map(member => {
|
||||
const imagePath = path.join('images', 'members', `${member.id}.jpg`);
|
||||
const hasImage = fs.existsSync(imagePath);
|
||||
const memberJson = member.toJSON();
|
||||
// Ensure contacts are properly serialized - access via model instance to trigger getters
|
||||
if (member.contacts && Array.isArray(member.contacts)) {
|
||||
memberJson.contacts = member.contacts.map(contact => {
|
||||
// Access properties through the model instance to trigger getters
|
||||
return {
|
||||
id: contact.id,
|
||||
memberId: contact.memberId,
|
||||
type: contact.type,
|
||||
value: contact.value, // Getter should decrypt this
|
||||
isParent: contact.isParent,
|
||||
parentName: contact.parentName, // Getter should decrypt this
|
||||
isPrimary: contact.isPrimary,
|
||||
createdAt: contact.createdAt,
|
||||
updatedAt: contact.updatedAt
|
||||
};
|
||||
});
|
||||
}
|
||||
return {
|
||||
...member.toJSON(),
|
||||
...memberJson,
|
||||
hasImage: hasImage
|
||||
};
|
||||
});
|
||||
@@ -49,19 +77,21 @@ class MemberService {
|
||||
});
|
||||
}
|
||||
|
||||
async setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate, phone, email, active = true, testMembership = false,
|
||||
picsInInternetAllowed = false, gender = 'unknown', ttr = null, qttr = null, memberFormHandedOver = false) {
|
||||
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 = []) {
|
||||
try {
|
||||
await checkAccess(userToken, clubId);
|
||||
let member = null;
|
||||
if (memberId) {
|
||||
member = await Member.findOne({ where: { id: memberId } });
|
||||
}
|
||||
const MemberContact = (await import('../models/MemberContact.js')).default;
|
||||
if (member) {
|
||||
member.firstName = firstName;
|
||||
member.lastName = lastName;
|
||||
member.street = street;
|
||||
member.city = city;
|
||||
if (postalCode !== undefined) member.postalCode = postalCode;
|
||||
member.birthDate = birthdate;
|
||||
member.phone = phone;
|
||||
member.email = email;
|
||||
@@ -73,12 +103,32 @@ class MemberService {
|
||||
if (qttr !== undefined) member.qttr = qttr;
|
||||
member.memberFormHandedOver = !!memberFormHandedOver;
|
||||
await member.save();
|
||||
|
||||
// Update contacts if provided
|
||||
if (Array.isArray(contacts)) {
|
||||
// Delete existing contacts
|
||||
await MemberContact.destroy({ where: { memberId: member.id } });
|
||||
// Create new contacts
|
||||
for (const contact of contacts) {
|
||||
if (contact.value && contact.type) {
|
||||
await MemberContact.create({
|
||||
memberId: member.id,
|
||||
type: contact.type,
|
||||
value: contact.value,
|
||||
isParent: contact.isParent || false,
|
||||
parentName: contact.parentName || null,
|
||||
isPrimary: contact.isPrimary || false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await Member.create({
|
||||
const newMember = await Member.create({
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
street: street,
|
||||
city: city,
|
||||
postalCode: postalCode || null,
|
||||
birthDate: birthdate,
|
||||
phone: phone,
|
||||
email: email,
|
||||
@@ -91,6 +141,22 @@ class MemberService {
|
||||
qttr: qttr,
|
||||
memberFormHandedOver: !!memberFormHandedOver,
|
||||
});
|
||||
|
||||
// Create contacts if provided
|
||||
if (Array.isArray(contacts)) {
|
||||
for (const contact of contacts) {
|
||||
if (contact.value && contact.type) {
|
||||
await MemberContact.create({
|
||||
memberId: newMember.id,
|
||||
type: contact.type,
|
||||
value: contact.value,
|
||||
isParent: contact.isParent || false,
|
||||
parentName: contact.parentName || null,
|
||||
isPrimary: contact.isPrimary || false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
status: 200,
|
||||
|
||||
Reference in New Issue
Block a user