diff --git a/locale/de-DE.commands.json b/locale/de-DE.commands.json index 796b2cfe60f9c257102e2f4566a69a31e690a5a8..5ccc3620d522b036dcfc3eb954105c87cedd058e 100644 --- a/locale/de-DE.commands.json +++ b/locale/de-DE.commands.json @@ -92,6 +92,13 @@ "maybe": { "commands": ["vielleicht", "vllt", "eventuell", "evtl"] }, + "moddingDistributeWichtelProfiles": + { + "commands": [ + "SteckbriefeVerteilen" + ], + "info": "Verteilt die Steckbriefe der Wichtelkinder an alle Wichtelpaten." + }, "moddingEndRegistration": { "commands": [ diff --git a/locale/de-DE.texts.json b/locale/de-DE.texts.json index 396088e5a15661a55fa022aad6707947e4237eef..8cf1332679a797f64db0c1a54a04f8fbb3d0886e 100644 --- a/locale/de-DE.texts.json +++ b/locale/de-DE.texts.json @@ -39,6 +39,7 @@ "oldInformation": "Dies findet sich aktuell dazu in meiner Datenbank:\n>>> {var.informationValue}", "moderationNeedHelp": "<@&{var.moderationRoleId}> Der Wichtel {contact.nickname} ({contact.tag}) bittet um Hilfe.", "moderationRegistrationEnded": "Registrierungsphase beendet. \nAnzahl Wartender: {var.waitingMemberCount}", + "moderationProfilesDistributed": "Alle {var.profileCount} Steckbriefe wurden verteilt.", "moderationStatus": "**Status des Wichtelns {var.currentEventName}**\nAktuelle Phase: {var.eventPhaseString}\n\nAnzahl Teilnehmer: {var.contactCount}\nDavon vollständig registriert: {var.waitingMemberCount}\n\nBewichtelungsarten:\nAls Wichtelpate: {var.analogueGiverCount} mal analog, {var.digitalGiverCount} mal digital, {var.allGiverCount} mal beides\nAls Wichtelkind: {var.analogueTakerCount} mal analog, {var.digitalTakerCount} mal digital, {var.allTakerCount} mal beides\n\nPakete: {var.parcelSentCount} versendet, {var.parcelReceivedCount} erhalten", "moderationStatusEventPhase": "{var.currentEventPhase}", "moderationStatusEventPhaseWithNextPhase": "{var.currentEventPhase} ({var.nextEventPhase} startet am {date.day}.{date.month}.{date.year} um {date.hour}:{date.minute} Uhr)", @@ -58,5 +59,6 @@ "sentComponentText": "Klicken! Du sollst klicken!", "sternenrose": "Vielen Dank, Sterni! :)", "thankYouResponse": "Bitte!", + "wichtelProfileDistribution": "Hallo {contact.nickname},\ndie Auslosung ist vorüber!\nHier ist der Steckbrief deines Wichtelkindes:", "yourAreWelcomeRespone": "🙂" } diff --git a/scripts/utility/localisation.ts b/scripts/utility/localisation.ts index f72d17661e92ba7f1aed6b70131c2eae4062ea10..97d4d5f41b916c94a047fef83af35d736489eda7 100644 --- a/scripts/utility/localisation.ts +++ b/scripts/utility/localisation.ts @@ -27,6 +27,7 @@ interface Commands informationBothAnalogueAndDigital: CommandInfo; informationDigital: CommandInfo; maybe: CommandInfo; + moddingDistributeWichtelProfiles: CommandInfo; moddingEndRegistration: CommandInfo; moddingRunAssignment: CommandInfo; // TODO: Rename "modding" commands to "moderation". moddingStatus: CommandInfo; @@ -81,6 +82,7 @@ interface Texts oldInformation: TokenString; moderationNeedHelp: TokenString; // TODO: This includes a Discord specific mention which is not portable to other implementations. moderationRegistrationEnded: TokenString; + moderationProfilesDistributed: TokenString; moderationStatus: TokenString; moderationStatusEventPhase: TokenString; moderationStatusEventPhaseWithNextPhase: TokenString; @@ -100,6 +102,7 @@ interface Texts sentComponentText: TokenString; sternenrose: TokenString; thankYouResponse: TokenString; + wichtelProfileDistribution: TokenString; yourAreWelcomeRespone: TokenString; } diff --git a/scripts/wichtelbot/database/database.ts b/scripts/wichtelbot/database/database.ts index 15a0bfb4c09c04ed337d30b35e08ddbcce0d0b77..ba090a48a00c510d5dd4f8ad08f7de3f50ceed2c 100644 --- a/scripts/wichtelbot/database/database.ts +++ b/scripts/wichtelbot/database/database.ts @@ -9,6 +9,7 @@ import { GiftTypeStatistics } from './giftTypeStatistics'; import { InformationData } from '../classes/information'; import Member from '../classes/member'; import { ParcelStatistics } from './parcelStatistics'; +import { RelationshipWithMembers } from './relationshipWithMembers'; import { State } from '../endpoint/definitions'; import Utils from '../../utility/utils'; import Sqlite = require('better-sqlite3'); @@ -569,6 +570,51 @@ export default class Database return relationships; } + public getRelationshipsWithMembers (): RelationshipWithMembers[] + { + const statement = this.mainDatabase.prepare( + `SELECT + giverContact.*, giverInformation.*, takerContact.*, takerInformation.* + FROM + relationship + LEFT JOIN + contact AS giverContact + ON giverContact.id = relationship.giverId + LEFT JOIN + information AS giverInformation + ON giverInformation.contactId = giverContact.id + LEFT JOIN + contact AS takerContact + ON takerContact.id = relationship.takerId + LEFT JOIN + information AS takerInformation + ON takerInformation.contactId = takerContact.id` + ); + + statement.expand(true); + + const resultData = statement.all() as { + giverContact: ContactData, + giverInformation: InformationData, + takerContact: ContactData, + takerInformation: InformationData + }[]; + + const relationshipsWithMembers: RelationshipWithMembers[] = []; + + for (const result of resultData) + { + const relationshipWithMembers: RelationshipWithMembers = { + giver: new Member(result.giverContact, result.giverInformation), + taker: new Member(result.takerContact, result.takerInformation), + }; + + relationshipsWithMembers.push(relationshipWithMembers); + } + + return relationshipsWithMembers; + } + public saveRelationships (relationships: RelationshipData[]): void { const statement = this.mainDatabase.prepare( diff --git a/scripts/wichtelbot/database/relationshipWithMembers.ts b/scripts/wichtelbot/database/relationshipWithMembers.ts new file mode 100644 index 0000000000000000000000000000000000000000..e924a1366aab50ec86c58ba598de2a2c072fcec3 --- /dev/null +++ b/scripts/wichtelbot/database/relationshipWithMembers.ts @@ -0,0 +1,7 @@ +import Member from "../classes/member"; + +export interface RelationshipWithMembers +{ + giver: Member; + taker: Member; +} diff --git a/scripts/wichtelbot/endpoint/definitions/state.ts b/scripts/wichtelbot/endpoint/definitions/state.ts index 8bf10af4ae75f9a1b9502fb6e34e5cf1a2a6604a..e65a0e19e137e9eab18e968ea748da294b94e54e 100644 --- a/scripts/wichtelbot/endpoint/definitions/state.ts +++ b/scripts/wichtelbot/endpoint/definitions/state.ts @@ -23,6 +23,7 @@ enum State /** While assignment is running; cannot change information. */ Assignment = 'assignment', // As wichtel: + Wichteling = 'wichteling', MessageToGiftGiver = 'messageToGiftGiver', MessageToGiftTaker = 'messageToGiftTaker', ParcelSendConsignmentNumber = 'sendParcelConsignmentNumber', diff --git a/scripts/wichtelbot/message/handlingDefinition.ts b/scripts/wichtelbot/message/handlingDefinition.ts index 5fd8953a9b424f70feb7f0a403a1c12cc233ce98..f8009ee26c590d5c2978f4617f3493b551e8cc09 100644 --- a/scripts/wichtelbot/message/handlingDefinition.ts +++ b/scripts/wichtelbot/message/handlingDefinition.ts @@ -497,6 +497,10 @@ export default class HandlingDefinition ]; public moderatorCommands: CommandDefinition[] = [ + { + commandInfo: Localisation.commands.moddingDistributeWichtelProfiles, + handlerFunction: async (message: Message): Promise<void> => this.moderationModule.distributeWichtelProfiles(message) + }, { commandInfo: Localisation.commands.moddingEndRegistration, // TODO: Remove with cron feature that does this automatically. handlerFunction: async (message: Message): Promise<void> => this.moderationModule.endRegistration(message) diff --git a/scripts/wichtelbot/message/handlingTools/handlingUtils.ts b/scripts/wichtelbot/message/handlingTools/handlingUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..2460c1da4546b2f2e5e7dca00a9abbcb5bfe144f --- /dev/null +++ b/scripts/wichtelbot/message/handlingTools/handlingUtils.ts @@ -0,0 +1,93 @@ +import { Visualisation, VisualisationType } from "../../endpoint/definitions"; +import GiftType from "../../types/giftType"; +import Localisation from "../../../utility/localisation"; +import Member from "../../classes/member"; + +export abstract class HandlingUtils +{ + public static getProfileVisualisations (member: Member): Visualisation[] + { + const visualisations: Visualisation[] = [ + { + headline: Localisation.texts.profileName.process(member), + text: member.name, + type: VisualisationType.Compact + }, + { + headline: Localisation.texts.profileGiftType.process(member), + text: Localisation.translateGiftType(member.information.giftTypeAsTaker), + type: VisualisationType.Compact + } + ]; + + const sendAnalogue = member.information.giftTypeAsTaker == GiftType.Analogue || member.information.giftTypeAsTaker == GiftType.All; + const sendDigital = member.information.giftTypeAsGiver == GiftType.Digital || member.information.giftTypeAsGiver == GiftType.All; + + if (sendAnalogue) + { + visualisations.push( + { + headline: Localisation.texts.profileCounty.process(member), + text: Localisation.translateCountry(member.information.country), + type: VisualisationType.Compact + } + ); + + visualisations.push( + { + headline: Localisation.texts.profileAddress.process(member), + text: member.information.address, + type: VisualisationType.Compact + } + ); + } + + if (sendDigital) + { + visualisations.push( + { + headline: Localisation.texts.profileDigitalAddress.process(member), + text: member.information.digitalAddress, + type: VisualisationType.Compact + } + ); + } + + visualisations.push( + { + headline: Localisation.texts.profileWishlist.process(member), + text: member.information.wishList, + type: VisualisationType.Normal + } + ); + + if (sendAnalogue) + { + visualisations.push( + { + headline: Localisation.texts.profileAllergies.process(member), + text: member.information.allergies, + type: VisualisationType.Normal + } + ); + } + + visualisations.push( + { + headline: Localisation.texts.profileExclusion.process(member), + text: member.information.giftExclusion, + type: VisualisationType.Normal + } + ); + + visualisations.push( + { + headline: Localisation.texts.profileFreeText.process(member), + text: member.information.freeText, + type: VisualisationType.Normal + } + ); + + return visualisations; + } +} diff --git a/scripts/wichtelbot/message/modules/informationModule.ts b/scripts/wichtelbot/message/modules/informationModule.ts index 6f5ac22f14a6de09d6fdc12ff71f7b343023c542..73770c1e3884c10ba31a45e93fcc1ebdf5ef1282 100644 --- a/scripts/wichtelbot/message/modules/informationModule.ts +++ b/scripts/wichtelbot/message/modules/informationModule.ts @@ -1,8 +1,8 @@ -import { Visualisation, VisualisationType } from "../../endpoint/definitions"; import Config from "../../../utility/config"; import ContactType from "../../types/contactType"; import Database from "../../database/database"; import GiftType from "../../types/giftType"; +import { HandlingUtils } from "../handlingTools/handlingUtils"; import { KeyValuePairList } from "../../../utility/keyValuePair"; import Localisation from "../../../utility/localisation"; import Member from "../../classes/member"; @@ -313,93 +313,7 @@ export default class InformationModule // Send an overview of all information gathered in the form of the own profile: const profileOverviewText = Localisation.texts.registrationProfileOverview.process(member); - const profileVisualisations = this.getProfileVisualisations(member); + const profileVisualisations = HandlingUtils.getProfileVisualisations(member); await message.reply(profileOverviewText, profileVisualisations); } - - public getProfileVisualisations (member: Member): Visualisation[] - { - const visualisations: Visualisation[] = [ - { - headline: Localisation.texts.profileName.process(member), - text: member.name, - type: VisualisationType.Compact - }, - { - headline: Localisation.texts.profileGiftType.process(member), - text: Localisation.translateGiftType(member.information.giftTypeAsTaker), - type: VisualisationType.Compact - } - ]; - - const sendAnalogue = member.information.giftTypeAsTaker == GiftType.Analogue || member.information.giftTypeAsTaker == GiftType.All; - const sendDigital = member.information.giftTypeAsGiver == GiftType.Digital || member.information.giftTypeAsGiver == GiftType.All; - - if (sendAnalogue) - { - visualisations.push( - { - headline: Localisation.texts.profileCounty.process(member), - text: Localisation.translateCountry(member.information.country), - type: VisualisationType.Compact - } - ); - - visualisations.push( - { - headline: Localisation.texts.profileAddress.process(member), - text: member.information.address, - type: VisualisationType.Compact - } - ); - } - - if (sendDigital) - { - visualisations.push( - { - headline: Localisation.texts.profileDigitalAddress.process(member), - text: member.information.digitalAddress, - type: VisualisationType.Compact - } - ); - } - - visualisations.push( - { - headline: Localisation.texts.profileWishlist.process(member), - text: member.information.wishList, - type: VisualisationType.Normal - } - ); - - if (sendAnalogue) - { - visualisations.push( - { - headline: Localisation.texts.profileAllergies.process(member), - text: member.information.allergies, - type: VisualisationType.Normal - } - ); - } - - visualisations.push( - { - headline: Localisation.texts.profileExclusion.process(member), - text: member.information.giftExclusion, - type: VisualisationType.Normal - } - ); - - visualisations.push( - { - headline: Localisation.texts.profileFreeText.process(member), - text: member.information.freeText, - type: VisualisationType.Normal - } - ); - - return visualisations; - } } diff --git a/scripts/wichtelbot/message/modules/moderationModule.ts b/scripts/wichtelbot/message/modules/moderationModule.ts index a0a6300c2cdb3802935f47738dcca768f849f475..8a9fa0de723526c27b7f2d321c57858d40681b23 100644 --- a/scripts/wichtelbot/message/modules/moderationModule.ts +++ b/scripts/wichtelbot/message/modules/moderationModule.ts @@ -1,8 +1,9 @@ +import { Message, State } from "../../endpoint/definitions"; import Config from "../../../utility/config"; import Database from "../../database/database"; +import { HandlingUtils } from "../handlingTools/handlingUtils"; import { KeyValuePairList } from "../../../utility/keyValuePair"; import Localisation from "../../../utility/localisation"; -import { Message, State } from "../../endpoint/definitions"; import Utils from "../../../utility/utils"; import WichtelEventPhase from "../../../utility/wichtelEvent"; @@ -111,4 +112,26 @@ export class ModerationModule await message.reply(answer); } + + public async distributeWichtelProfiles (message: Message): Promise<void> + { + const relationships = this.database.getRelationshipsWithMembers(); + + for (const relationship of relationships) + { + const profileOverviewText = Localisation.texts.wichtelProfileDistribution.process(relationship.giver); + const profileVisualisations = HandlingUtils.getProfileVisualisations(relationship.taker); + + await message.reply(profileOverviewText, profileVisualisations); + + relationship.giver.state = State.Wichteling; + // NOTE: We can use "updateContacts" instead of "updateMembers" because we changed the state, which is only part of the contact: + this.database.updateContact(relationship.giver); + } + + const parameters = new KeyValuePairList('profileCount', `${relationships.length}`); + const answer = Localisation.texts.moderationProfilesDistributed.process(message.author, parameters); + + await message.reply(answer); + } }