diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index aab84e911..479d020ea 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -63,6 +63,7 @@ import ContributionMessageArgs from '@arg/ContributionMessageArgs' import { ContributionMessageType } from '@enum/MessageType' import { ContributionMessage } from '@model/ContributionMessage' import { sendContributionConfirmedEmail } from '@/mailer/sendContributionConfirmedEmail' +import { sendContributionRejectedEmail } from '@/mailer/sendContributionRejectedEmail' import { sendAddedContributionMessageEmail } from '@/mailer/sendAddedContributionMessageEmail' import { eventProtocol } from '@/event/EventProtocolEmitter' import { @@ -455,6 +456,10 @@ export class AdminResolver { ) { throw new Error('Own contribution can not be deleted as admin') } + const user = await dbUser.findOneOrFail( + { id: contribution.userId }, + { relations: ['emailContact'] }, + ) contribution.contributionStatus = ContributionStatus.DELETED contribution.deletedBy = moderator.id await contribution.save() @@ -468,6 +473,16 @@ export class AdminResolver { await eventProtocol.writeEvent( event.setEventAdminContributionDelete(eventAdminContributionDelete), ) + sendContributionRejectedEmail({ + senderFirstName: moderator.firstName, + senderLastName: moderator.lastName, + recipientEmail: user.emailContact.email, + recipientFirstName: user.firstName, + recipientLastName: user.lastName, + contributionMemo: contribution.memo, + contributionAmount: contribution.amount, + overviewURL: CONFIG.EMAIL_LINK_OVERVIEW, + }) return !!res } diff --git a/backend/src/mailer/sendContributionRejectedEmail.test.ts b/backend/src/mailer/sendContributionRejectedEmail.test.ts new file mode 100644 index 000000000..fb044692b --- /dev/null +++ b/backend/src/mailer/sendContributionRejectedEmail.test.ts @@ -0,0 +1,38 @@ +import Decimal from 'decimal.js-light' +import { sendContributionRejectedEmail } from './sendContributionRejectedEmail' +import { sendEMail } from './sendEMail' + +jest.mock('./sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) + +describe('sendContributionConfirmedEmail', () => { + beforeEach(async () => { + await sendContributionRejectedEmail({ + senderFirstName: 'Peter', + senderLastName: 'Lustig', + recipientFirstName: 'Bibi', + recipientLastName: 'Bloxberg', + recipientEmail: 'bibi@bloxberg.de', + contributionMemo: 'Vielen herzlichen Dank für den neuen Hexenbesen!', + contributionAmount: new Decimal(200.0), + overviewURL: 'http://localhost/overview', + }) + }) + + it('calls sendEMail', () => { + expect(sendEMail).toBeCalledWith({ + to: 'Bibi Bloxberg ', + subject: 'Schöpfung wurde abgelehnt', + text: + expect.stringContaining('Hallo Bibi Bloxberg') && + expect.stringContaining( + 'Dein Gradido Schöpfungsantrag "Vielen herzlichen Dank für den neuen Hexenbesen!" wurde soeben von Peter Lustig abgelehnt.', + ) && + expect.stringContaining('Link zu deinem Konto: http://localhost/overview'), + }) + }) +}) diff --git a/backend/src/mailer/sendContributionRejectedEmail.ts b/backend/src/mailer/sendContributionRejectedEmail.ts new file mode 100644 index 000000000..9edb5ba2a --- /dev/null +++ b/backend/src/mailer/sendContributionRejectedEmail.ts @@ -0,0 +1,26 @@ +import { backendLogger as logger } from '@/server/logger' +import Decimal from 'decimal.js-light' +import { sendEMail } from './sendEMail' +import { contributionRejected } from './text/contributionRejected' + +export const sendContributionRejectedEmail = (data: { + senderFirstName: string + senderLastName: string + recipientFirstName: string + recipientLastName: string + recipientEmail: string + contributionMemo: string + contributionAmount: Decimal + overviewURL: string +}): Promise => { + logger.info( + `sendEmail(): to=${data.recipientFirstName} ${data.recipientLastName} <${data.recipientEmail}>, + subject=${contributionRejected.de.subject}, + text=${contributionRejected.de.text(data)}`, + ) + return sendEMail({ + to: `${data.recipientFirstName} ${data.recipientLastName} <${data.recipientEmail}>`, + subject: contributionRejected.de.subject, + text: contributionRejected.de.text(data), + }) +} diff --git a/backend/src/mailer/text/contributionRejected.ts b/backend/src/mailer/text/contributionRejected.ts new file mode 100644 index 000000000..a101e7a25 --- /dev/null +++ b/backend/src/mailer/text/contributionRejected.ts @@ -0,0 +1,27 @@ +import Decimal from 'decimal.js-light' + +export const contributionRejected = { + de: { + subject: 'Schöpfung wurde abgelehnt', + text: (data: { + senderFirstName: string + senderLastName: string + recipientFirstName: string + recipientLastName: string + contributionMemo: string + contributionAmount: Decimal + overviewURL: string + }): string => + `Hallo ${data.recipientFirstName} ${data.recipientLastName}, + +Dein eingereichter Gemeinwohl-Beitrag "${data.contributionMemo}" wurde soeben von ${data.senderFirstName} ${data.senderLastName} abgelehnt. + +Bitte antworte nicht auf diese E-Mail! + +Mit freundlichen Grüßen, +dein Gradido-Team + + +Link zu deinem Konto: ${data.overviewURL}`, + }, +}