import { SelectQueryBuilder } from "typeorm"; import { dataSource } from "../../../data-source"; import { member } from "../../../entity/club/member/member"; import { membership } from "../../../entity/club/member/membership"; import DatabaseActionException from "../../../exceptions/databaseActionException"; import InternalException from "../../../exceptions/internalException"; import { memberView } from "../../../views/memberView"; import { DB_TYPE } from "../../../env.defaults"; export default abstract class MemberService { /** * @description get all members * @returns {Promise<[Array, number]>} */ static async getAll({ offset = 0, count = 25, search = "", noLimit = false, ids = [], }: { offset?: number; count?: number; search?: string; noLimit?: boolean; ids?: Array; }): Promise<[Array, number]> { let query = this.applyMemberBaseJoins(); if (search != "") { search.split(" ").forEach((term, index) => { const searchQuery = `%${term}%`; const dynamic = "searchQuery" + Math.random().toString(36).substring(2); if (index == 0) { query = query.where(`member.firstname LIKE :${dynamic} OR member.lastname LIKE :${dynamic}`, { [dynamic]: searchQuery, }); } else { query = query.orWhere(`member.firstname LIKE :${dynamic} OR member.lastname LIKE :${dynamic}`, { [dynamic]: searchQuery, }); } }); } if (ids.length != 0) { query = query.where("member.id IN (:...ids)", { ids: ids }); } if (!noLimit) { query = query.offset(offset).limit(count); } return await query .orderBy("member.lastname") .addOrderBy("member.firstname") .addOrderBy("member.nameaffix") .getManyAndCount() .then((res) => { return res; }) .catch((err) => { throw new DatabaseActionException("SELECT", "member", err); }); } /** * @description get member by id * @param {string} id * @returns {Promise} */ static async getById(id: string): Promise { return this.applyMemberBaseJoins() .where("member.id = :id", { id: id }) .getOneOrFail() .then((res) => { return res; }) .catch((err) => { throw new DatabaseActionException("SELECT", "member", err); }); } /** * @description get member statistics by id * @param {string} id * @returns {Promise} */ static async getStatisticsById(id: string): Promise { return await dataSource .getRepository(memberView) .createQueryBuilder("memberView") .where("memberView.id = :id", { id: id }) .getOneOrFail() .then((res) => { return res; }) .catch((err) => { throw new DatabaseActionException("SELECT", "memberView", err); }); } /** * @description get members where membership is setz * @returns {Promise} */ static async getByRunningMembership(): Promise> { return await dataSource .getRepository(member) .createQueryBuilder("member") .leftJoinAndSelect("member.memberships", "membership") .where("membership.end IS NULL") .orderBy("member.lastname") .addOrderBy("member.firstname") .addOrderBy("member.nameaffix") .getMany() .then((res) => { return res; }) .catch((err) => { throw new DatabaseActionException("SELECT", "member", err); }); } /** * @description get newsletter by member by id * @param {string} id * @returns {Promise} */ static async getNewsletterById(id: string): Promise { return await dataSource .getRepository(member) .createQueryBuilder("member") .leftJoinAndMapOne( "member.sendNewsletter", "member.communications", "sendNewsletter", "sendNewsletter.isSendNewsletter = true" ) .where("member.id = :id", { id: id }) .getOneOrFail() .then((res) => { return res; }) .catch((err) => { throw new DatabaseActionException("SELECT", "member", err); }); } /** * @description apply member joins to query * @returns {SelectQueryBuilder} */ static applyMemberBaseJoins(): SelectQueryBuilder { return dataSource .getRepository(member) .createQueryBuilder("member") .leftJoinAndMapOne( "member.firstMembershipEntry", "member.memberships", "membership_first", DB_TYPE == "postgres" ? 'membership_first.memberId = member.id AND membership_first.start = (SELECT MIN("m_first"."start") FROM "membership" "m_first" WHERE "m_first"."memberId" = "member"."id")' : "membership_first.memberId = member.id AND membership_first.start = (SELECT MIN(m_first.start) FROM membership m_first WHERE m_first.memberId = member.id)" ) .leftJoinAndMapOne( "member.lastMembershipEntry", "member.memberships", "membership_last", DB_TYPE == "postgres" ? 'membership_last.memberId = member.id AND membership_last.start = (SELECT MAX("m_last"."start") FROM "membership" "m_last" WHERE "m_last"."memberId" = "member"."id")' : "membership_last.memberId = member.id AND membership_last.start = (SELECT MAX(m_last.start) FROM membership m_last WHERE m_last.memberId = member.id)" ) .leftJoinAndSelect("membership_first.status", "status_first") .leftJoinAndSelect("membership_last.status", "status_last") .leftJoinAndMapMany( "member.preferredCommunication", "member.communications", "preferredCommunication", "preferredCommunication.preferred = true" ) .leftJoinAndSelect("preferredCommunication.type", "communicationtype_preferred") .leftJoinAndMapOne( "member.sendNewsletter", "member.communications", "sendNewsletter", "sendNewsletter.isSendNewsletter = true" ) .leftJoinAndSelect("sendNewsletter.type", "communicationtype") .leftJoinAndMapMany( "member.smsAlarming", "member.communications", "smsAlarming", "smsAlarming.isSMSAlarming = true" ) .leftJoinAndSelect("smsAlarming.type", "communicationtype_smsAlarming") .leftJoinAndSelect("member.salutation", "salutation"); } }