import BaseService from './BaseService.js'; import UserParamType from '../models/type/user_param.js'; import SettingsType from '../models/type/settings.js'; import UserParam from '../models/community/user_param.js'; import User from '../models/community/user.js'; import UserParamValue from '../models/type/user_param_value.js'; import Interest from '../models/type/interest.js'; import UserInterest from '../models/community/interest.js'; import InterestTranslation from '../models/type/interest_translation.js'; import { Op } from 'sequelize'; import UserParamVisibilityType from '../models/type/user_param_visibility.js'; import UserParamVisibility from '../models/community/user_param_visibility.js'; import { generateIv } from '../utils/encryption.js'; class SettingsService extends BaseService{ async getUserParams(userId, paramDescriptions) { return await UserParam.findAll({ where: { userId }, include: [ { model: UserParamType, as: 'paramType', where: { description: { [Op.in]: paramDescriptions } }, order: [[ 'order_id', 'asc' ]] } ] }); } async getFieldOptions(field) { if (['singleselect', 'multiselect'].includes(field.datatype)) { return await UserParamValue.findAll({ where: { userParamTypeId: field.id }, order: [[ 'order_id', 'asc' ]] }); } return []; } async filterSettings(hashedUserId, type) { const user = await this.getUserByHashedId(hashedUserId); const userParams = await this.getUserParams(user.id, ['birthdate', 'gender']); let birthdate = null; let gender = null; for (const param of userParams) { if (param.paramType.description === 'birthdate') { birthdate = param.value; } if (param.paramType.description === 'gender') { const genderResult = await UserParamValue.findOne({ where: { id: param.value } }); gender = genderResult ? genderResult.dataValues?.value : null; } } const age = birthdate ? this.calculateAge(birthdate) : null; const fields = await UserParamType.findAll({ include: [ { model: SettingsType, as: 'settings_type', where: { name: type } }, { model: UserParam, as: 'user_params', required: false, include: [ { model: User, as: 'user', where: { id: user.id } }, { model: UserParamVisibility, as: 'param_visibilities', required: false, include: [ { model: UserParamVisibilityType, as: 'visibility_type' } ] } ] } ], where: { [Op.and]: [ { minAge: { [Op.or]: [null, { [Op.lte]: age }] } }, { gender: { [Op.or]: [null, gender] } } ] } }); return await Promise.all(fields.map(async (field) => { const options = await this.getFieldOptions(field); const visibilityData = field.user_params[0]?.param_visibilities?.[0]; const visibility = visibilityData ? { id: visibilityData.visibility_type?.id, description: visibilityData.visibility_type?.description } : { id: null, description: 'Invisible' }; return { id: field.id, name: field.description, minAge: field.minAge, gender: field.gender, datatype: field.datatype, unit: field.unit, value: field.user_params.length > 0 ? field.user_params[0].value : null, options: options.map(opt => ({ id: opt.id, value: opt.value })), visibility }; })); } async updateSetting(hashedUserId, settingId, value) { try { const user = await this.getUserByHashedId(hashedUserId); const paramType = await UserParamType.findOne({ where: { id: settingId } }); if (!paramType) { throw new Error('Parameter type not found'); } const userParam = await UserParam.findOne({ where: { userId: user.id, paramTypeId: settingId } }); if (userParam) { console.log('update param with ', value) if (typeof value === 'boolean') { value = value ? 'true' : 'false'; } await userParam.update({value: value}); } else { await UserParam.create( { userId: user.id, paramTypeId: settingId, value: value } ); } } catch (error) { console.error('Error updating setting:', hashedUserId, settingId, value, error); throw error; } } async getTypeParamValueId(paramValue) { const userParamValueObject = await UserParamValue.findOne({ where: { value: paramValue } }); if (!userParamValueObject) { throw new Error('Parameter value not found'); } return userParamValueObject.id; } async getTypeParamValues(type) { const userParamValues = await UserParamValue.findAll({ include: [ { model: UserParamType, as: 'user_param_type', where: { description: type } } ] }); return userParamValues.map(type => ({ id: type.dataValues.id, name: type.dataValues.value })); } async getTypeParamValue(id) { const userParamValueObject = await UserParamValue.findOne({ where: { id } }); if (!userParamValueObject) { throw new Error('Parameter value not found'); } return userParamValueObject.value; } async addInterest(hashedUserId, name) { try { const user = await this.getUserByHashedId(hashedUserId); const existingInterests = await Interest.findAll({ where: { name: name.toLowerCase() } }); if (existingInterests.length > 0) { throw new Error('Interest already exists'); } const userParam = await this.getUserParams(user.id, ['language']); let language = 'en'; if (userParam.length > 0) { const userParamValue = await UserParamValue.findOne({ where: { id: userParam[0].value } }); language = userParamValue ? userParamValue.value : 'en'; } const languageParam = await UserParamValue.findOne({ where: { value: language } }); const languageId = languageParam.id; const interest = await Interest.create({ name: name.toLowerCase(), allowed: false, adultOnly: true }); await InterestTranslation.create({ interestsId: interest.id, language: languageId, translation: name }); return interest; } catch (error) { console.error('Error adding interest:', error); throw error; } } async addUserInterest(hashedUserId, interestId) { try { const user = await this.getUserByHashedId(hashedUserId); const userParams = await this.getUserParams(user.id, ['birthdate']); let birthdate = null; for (const param of userParams) { if (param.paramType.description === 'birthdate') { birthdate = param.value; } } const age = birthdate ? this.calculateAge(birthdate) : 0; const interestsFilter = { id: interestId, allowed: true }; if (age < 18) { interestsFilter[Op.or] = [ { adultOnly: false }, { adultOnly: { [Op.eq]: null } } ]; } const existingInterests = await Interest.findAll({ where: interestsFilter }); if (existingInterests.length === 0) { throw new Error('Interest not found'); }; const interest = await UserInterest.findAll({ where: { userId: user.id, userinterestId: interestId } }); if (interest.length > 0) { throw new Error('Interest already exists'); } await UserInterest.create({ userId: user.id, userinterestId: interestId }); } catch (error) { console.error('Error adding user interest:', error); throw error; } } async removeInterest(hashedUserId, interestId) { try { const user = await this.getUserByHashedId(hashedUserId); const interests = await UserInterest.findAll({ where: { userId: user.id, userinterestId: interestId } }); for (const interest of interests) { await interest.destroy(); } } catch (error) { console.error('Error removing interest:', error); throw error; } } async getVisibilities() { return UserParamVisibilityType.findAll(); } async updateVisibility(hashedUserId, userParamTypeId, visibilityId) { try { const user = await this.getUserByHashedId(hashedUserId); console.log(JSON.stringify(user)); if (!user) { throw new Error('User not found'); } const userParam = await UserParam.findOne({ where: { paramTypeId: userParamTypeId, userId: user.id } }); if (!userParam) { console.error(`UserParam not found for settingId: ${userParamTypeId} and userId: ${user.id}`); throw new Error('User parameter not found or does not belong to the user'); } let userParamVisibility = await UserParamVisibility.findOne({ where: { param_id: userParam.id } }); if (userParamVisibility) { userParamVisibility.visibility = visibilityId; await userParamVisibility.save(); } else { await UserParamVisibility.create({ param_id: userParam.id, visibility: visibilityId }); } console.log(`Visibility updated for settingId: ${userParamTypeId} with visibilityId: ${visibilityId}`); } catch (error) { console.error('Error updating visibility:', error.message); throw error; } } } export default new SettingsService();