mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
refactor contributionMessage with dci
This commit is contained in:
parent
4c97552dc5
commit
af1df0fabe
@ -63,6 +63,24 @@ export class ContributionMessageBuilder {
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* set contribution message type dialog and copy message
|
||||
* @param contribution
|
||||
* @param message
|
||||
* @returns
|
||||
*/
|
||||
public setDialogType(message: string): this {
|
||||
this.contributionMessage.message = message
|
||||
this.contributionMessage.type = ContributionMessageType.DIALOG
|
||||
return this
|
||||
}
|
||||
|
||||
public setMessageAndType(message: string, type: ContributionMessageType): this {
|
||||
this.contributionMessage.message = message
|
||||
this.contributionMessage.type = type
|
||||
return this
|
||||
}
|
||||
|
||||
public setUser(user: User): this {
|
||||
this.contributionMessage.user = user
|
||||
this.contributionMessage.userId = user.id
|
||||
|
||||
@ -24,4 +24,8 @@ export class AdminUpdateContributionArgs {
|
||||
@Field(() => String, { nullable: true })
|
||||
@isValidDateString()
|
||||
creationDate?: string | null
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
@isValidDateString()
|
||||
resubmissionAt?: string | null
|
||||
}
|
||||
|
||||
@ -3,8 +3,6 @@ import { ArgsType, Field, Int, InputType } from 'type-graphql'
|
||||
|
||||
import { ContributionMessageType } from '@enum/ContributionMessageType'
|
||||
|
||||
import { isValidDateString } from '@/graphql/validator/DateString'
|
||||
|
||||
@InputType()
|
||||
@ArgsType()
|
||||
export class ContributionMessageArgs {
|
||||
@ -19,8 +17,4 @@ export class ContributionMessageArgs {
|
||||
@Field(() => ContributionMessageType, { defaultValue: ContributionMessageType.DIALOG })
|
||||
@IsEnum(ContributionMessageType)
|
||||
messageType: ContributionMessageType
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
@isValidDateString()
|
||||
resubmissionAt?: string | null
|
||||
}
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import { getConnection } from '@dbTools/typeorm'
|
||||
import { Contribution as DbContribution } from '@entity/Contribution'
|
||||
import { EntityManager, FindOptionsRelations, getConnection } from '@dbTools/typeorm'
|
||||
import { Contribution, Contribution as DbContribution } from '@entity/Contribution'
|
||||
import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage'
|
||||
import { User as DbUser } from '@entity/User'
|
||||
import { UserContact as DbUserContact } from '@entity/UserContact'
|
||||
import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql'
|
||||
|
||||
import { ContributionMessageArgs } from '@arg/ContributionMessageArgs'
|
||||
import { Paginated } from '@arg/Paginated'
|
||||
import { ContributionMessageType } from '@enum/ContributionMessageType'
|
||||
import { ContributionStatus } from '@enum/ContributionStatus'
|
||||
import { Order } from '@enum/Order'
|
||||
import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage'
|
||||
|
||||
@ -19,6 +17,7 @@ import {
|
||||
EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE,
|
||||
EVENT_CONTRIBUTION_MESSAGE_CREATE,
|
||||
} from '@/event/Events'
|
||||
import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context'
|
||||
import { Context, getUser } from '@/server/context'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
@ -29,52 +28,52 @@ export class ContributionMessageResolver {
|
||||
@Authorized([RIGHTS.CREATE_CONTRIBUTION_MESSAGE])
|
||||
@Mutation(() => ContributionMessage)
|
||||
async createContributionMessage(
|
||||
@Args() { contributionId, message }: ContributionMessageArgs,
|
||||
@Args() contributionMessageArgs: ContributionMessageArgs,
|
||||
@Ctx() context: Context,
|
||||
): Promise<ContributionMessage> {
|
||||
const user = getUser(context)
|
||||
const queryRunner = getConnection().createQueryRunner()
|
||||
await queryRunner.connect()
|
||||
await queryRunner.startTransaction('REPEATABLE READ')
|
||||
const contributionMessage = DbContributionMessage.create()
|
||||
const { contributionId } = contributionMessageArgs
|
||||
const updateUnconfirmedContributionContext = new UpdateUnconfirmedContributionContext(
|
||||
contributionId,
|
||||
contributionMessageArgs,
|
||||
context,
|
||||
)
|
||||
let finalContribution: DbContribution | undefined
|
||||
let finalContributionMessage: DbContributionMessage | undefined
|
||||
|
||||
try {
|
||||
const contribution = await DbContribution.findOne({ where: { id: contributionId } })
|
||||
if (!contribution) {
|
||||
throw new LogError('Contribution not found', contributionId)
|
||||
}
|
||||
if (contribution.userId !== user.id) {
|
||||
throw new LogError(
|
||||
'Can not send message to contribution of another user',
|
||||
contribution.userId,
|
||||
user.id,
|
||||
)
|
||||
}
|
||||
await getConnection().transaction(
|
||||
'REPEATABLE READ',
|
||||
async (transactionalEntityManager: EntityManager) => {
|
||||
const { contribution, contributionMessage, contributionChanged } =
|
||||
await updateUnconfirmedContributionContext.run(transactionalEntityManager)
|
||||
|
||||
contributionMessage.contributionId = contributionId
|
||||
contributionMessage.createdAt = new Date()
|
||||
contributionMessage.message = message
|
||||
contributionMessage.userId = user.id
|
||||
contributionMessage.type = ContributionMessageType.DIALOG
|
||||
contributionMessage.isModerator = false
|
||||
await queryRunner.manager.insert(DbContributionMessage, contributionMessage)
|
||||
if (contributionChanged) {
|
||||
await transactionalEntityManager.update(
|
||||
Contribution,
|
||||
{ id: contributionId },
|
||||
contribution,
|
||||
)
|
||||
}
|
||||
await transactionalEntityManager.insert(ContributionMessage, contributionMessage)
|
||||
|
||||
if (contribution.contributionStatus === ContributionStatus.IN_PROGRESS) {
|
||||
contribution.contributionStatus = ContributionStatus.PENDING
|
||||
await queryRunner.manager.update(DbContribution, { id: contributionId }, contribution)
|
||||
}
|
||||
await queryRunner.commitTransaction()
|
||||
await EVENT_CONTRIBUTION_MESSAGE_CREATE(
|
||||
user,
|
||||
{ id: contributionMessage.contributionId } as DbContribution,
|
||||
contributionMessage,
|
||||
finalContribution = contribution
|
||||
finalContributionMessage = contributionMessage
|
||||
},
|
||||
)
|
||||
} catch (e) {
|
||||
await queryRunner.rollbackTransaction()
|
||||
throw new LogError(`ContributionMessage was not sent successfully: ${e}`, e)
|
||||
} finally {
|
||||
await queryRunner.release()
|
||||
}
|
||||
return new ContributionMessage(contributionMessage, user)
|
||||
if (!finalContribution || !finalContributionMessage) {
|
||||
throw new LogError('ContributionMessage was not sent successfully')
|
||||
}
|
||||
const user = getUser(context)
|
||||
|
||||
await EVENT_CONTRIBUTION_MESSAGE_CREATE(
|
||||
user,
|
||||
{ id: contributionId } as DbContribution,
|
||||
finalContributionMessage,
|
||||
)
|
||||
return new ContributionMessage(finalContributionMessage, user)
|
||||
}
|
||||
|
||||
@Authorized([RIGHTS.LIST_ALL_CONTRIBUTION_MESSAGES])
|
||||
@ -125,77 +124,68 @@ export class ContributionMessageResolver {
|
||||
@Authorized([RIGHTS.ADMIN_CREATE_CONTRIBUTION_MESSAGE])
|
||||
@Mutation(() => ContributionMessage)
|
||||
async adminCreateContributionMessage(
|
||||
@Args() { contributionId, message, messageType, resubmissionAt }: ContributionMessageArgs,
|
||||
@Args() contributionMessageArgs: ContributionMessageArgs,
|
||||
@Ctx() context: Context,
|
||||
): Promise<ContributionMessage> {
|
||||
const moderator = getUser(context)
|
||||
const { contributionId, messageType } = contributionMessageArgs
|
||||
const updateUnconfirmedContributionContext = new UpdateUnconfirmedContributionContext(
|
||||
contributionId,
|
||||
contributionMessageArgs,
|
||||
context,
|
||||
)
|
||||
const relations: FindOptionsRelations<DbContribution> =
|
||||
messageType === ContributionMessageType.DIALOG
|
||||
? { user: { emailContact: true } }
|
||||
: { user: true }
|
||||
let finalContribution: DbContribution | undefined
|
||||
let finalContributionMessage: DbContributionMessage | undefined
|
||||
|
||||
const queryRunner = getConnection().createQueryRunner()
|
||||
await queryRunner.connect()
|
||||
await queryRunner.startTransaction('REPEATABLE READ')
|
||||
const contributionMessage = DbContributionMessage.create()
|
||||
try {
|
||||
const contribution = await DbContribution.findOne({
|
||||
where: { id: contributionId },
|
||||
relations: ['user'],
|
||||
})
|
||||
if (!contribution) {
|
||||
throw new LogError('Contribution not found', contributionId)
|
||||
}
|
||||
if (contribution.userId === moderator.id) {
|
||||
throw new LogError('Admin can not answer on his own contribution', contributionId)
|
||||
}
|
||||
if (!contribution.user.emailContact && contribution.user.emailId) {
|
||||
contribution.user.emailContact = await DbUserContact.findOneOrFail({
|
||||
where: { id: contribution.user.emailId },
|
||||
})
|
||||
}
|
||||
contributionMessage.contributionId = contributionId
|
||||
contributionMessage.createdAt = new Date()
|
||||
contributionMessage.message = message
|
||||
contributionMessage.userId = moderator.id
|
||||
contributionMessage.type = messageType
|
||||
contributionMessage.isModerator = true
|
||||
if (resubmissionAt) {
|
||||
contributionMessage.resubmissionAt = new Date(resubmissionAt)
|
||||
}
|
||||
await queryRunner.manager.insert(DbContributionMessage, contributionMessage)
|
||||
await getConnection().transaction(
|
||||
'REPEATABLE READ',
|
||||
async (transactionalEntityManager: EntityManager) => {
|
||||
const { contribution, contributionMessage, contributionChanged } =
|
||||
await updateUnconfirmedContributionContext.run(transactionalEntityManager, relations)
|
||||
|
||||
if (messageType !== ContributionMessageType.MODERATOR) {
|
||||
// change status (does not apply to moderator messages)
|
||||
if (
|
||||
contribution.contributionStatus === ContributionStatus.DELETED ||
|
||||
contribution.contributionStatus === ContributionStatus.DENIED ||
|
||||
contribution.contributionStatus === ContributionStatus.PENDING
|
||||
) {
|
||||
contribution.contributionStatus = ContributionStatus.IN_PROGRESS
|
||||
await queryRunner.manager.update(DbContribution, { id: contributionId }, contribution)
|
||||
}
|
||||
if (contributionChanged) {
|
||||
await transactionalEntityManager.update(
|
||||
Contribution,
|
||||
{ id: contributionId },
|
||||
contribution,
|
||||
)
|
||||
}
|
||||
await transactionalEntityManager.insert(ContributionMessage, contributionMessage)
|
||||
|
||||
// send email (never for moderator messages)
|
||||
void sendAddedContributionMessageEmail({
|
||||
firstName: contribution.user.firstName,
|
||||
lastName: contribution.user.lastName,
|
||||
email: contribution.user.emailContact.email,
|
||||
language: contribution.user.language,
|
||||
senderFirstName: moderator.firstName,
|
||||
senderLastName: moderator.lastName,
|
||||
contributionMemo: contribution.memo,
|
||||
})
|
||||
}
|
||||
await queryRunner.commitTransaction()
|
||||
await EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE(
|
||||
{ id: contribution.userId } as DbUser,
|
||||
moderator,
|
||||
contribution,
|
||||
contributionMessage,
|
||||
finalContribution = contribution
|
||||
finalContributionMessage = contributionMessage
|
||||
},
|
||||
)
|
||||
} catch (e) {
|
||||
await queryRunner.rollbackTransaction()
|
||||
throw new LogError(`ContributionMessage was not sent successfully: ${e}`, e)
|
||||
} finally {
|
||||
await queryRunner.release()
|
||||
}
|
||||
return new ContributionMessage(contributionMessage, moderator)
|
||||
if (!finalContribution || !finalContributionMessage) {
|
||||
throw new LogError('ContributionMessage was not sent successfully')
|
||||
}
|
||||
const moderator = getUser(context)
|
||||
if (messageType === ContributionMessageType.DIALOG) {
|
||||
// send email (never for moderator messages)
|
||||
void sendAddedContributionMessageEmail({
|
||||
firstName: finalContribution.user.firstName,
|
||||
lastName: finalContribution.user.lastName,
|
||||
email: finalContribution.user.emailContact.email,
|
||||
language: finalContribution.user.language,
|
||||
senderFirstName: moderator.firstName,
|
||||
senderLastName: moderator.lastName,
|
||||
contributionMemo: finalContribution.memo,
|
||||
})
|
||||
}
|
||||
|
||||
await EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE(
|
||||
{ id: finalContribution.userId } as DbUser,
|
||||
moderator,
|
||||
finalContribution,
|
||||
finalContributionMessage,
|
||||
)
|
||||
return new ContributionMessage(finalContributionMessage, moderator)
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,10 +269,6 @@ export class ContributionResolver {
|
||||
])
|
||||
})
|
||||
const moderator = getUser(context)
|
||||
const user = await DbUser.findOneOrFail({
|
||||
where: { id: contribution.userId },
|
||||
relations: ['emailContact'],
|
||||
})
|
||||
|
||||
const result = new AdminUpdateContribution()
|
||||
result.amount = contribution.amount
|
||||
@ -286,6 +282,11 @@ export class ContributionResolver {
|
||||
contribution.amount,
|
||||
)
|
||||
if (createdByUserChangedByModerator && adminUpdateContributionArgs.memo) {
|
||||
const user = await DbUser.findOneOrFail({
|
||||
where: { id: contribution.userId },
|
||||
relations: ['emailContact'],
|
||||
})
|
||||
|
||||
void sendContributionChangedByModeratorEmail({
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
|
||||
@ -4,11 +4,14 @@ import { Decimal } from 'decimal.js-light'
|
||||
|
||||
import { Role } from '@/auth/Role'
|
||||
import { ContributionLogic } from '@/data/Contribution.logic'
|
||||
import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder'
|
||||
import { ContributionStatus } from '@/graphql/enum/ContributionStatus'
|
||||
import { Context, getClientTimezoneOffset } from '@/server/context'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
export abstract class AbstractUnconfirmedContributionRole {
|
||||
private availableCreationSums?: Decimal[]
|
||||
protected changed = true
|
||||
|
||||
public constructor(
|
||||
protected self: Contribution,
|
||||
@ -20,6 +23,10 @@ export abstract class AbstractUnconfirmedContributionRole {
|
||||
}
|
||||
}
|
||||
|
||||
public isChanged(): boolean {
|
||||
return this.changed
|
||||
}
|
||||
|
||||
// steps which return void throw on each error
|
||||
// first, check if it can be updated
|
||||
protected abstract checkAuthorization(user: User, role: Role): void
|
||||
@ -30,6 +37,10 @@ export abstract class AbstractUnconfirmedContributionRole {
|
||||
throw new LogError('Month of contribution can not be changed')
|
||||
}
|
||||
|
||||
if (this.self.contributionStatus === ContributionStatus.CONFIRMED) {
|
||||
throw new LogError('the contribution is already confirmed, cannot be changed anymore')
|
||||
}
|
||||
|
||||
const contributionLogic = new ContributionLogic(this.self)
|
||||
this.availableCreationSums = await contributionLogic.getAvailableCreationSums(
|
||||
clientTimezoneOffset,
|
||||
@ -55,6 +66,11 @@ export abstract class AbstractUnconfirmedContributionRole {
|
||||
this.update()
|
||||
}
|
||||
|
||||
public createContributionMessage(): ContributionMessageBuilder {
|
||||
const contributionMessageBuilder = new ContributionMessageBuilder()
|
||||
return contributionMessageBuilder.setParentContribution(this.self).setHistoryType(this.self)
|
||||
}
|
||||
|
||||
public getAvailableCreationSums(): Decimal[] {
|
||||
if (!this.availableCreationSums) {
|
||||
throw new LogError('availableCreationSums is empty, please call validate before!')
|
||||
|
||||
@ -3,6 +3,7 @@ import { User } from '@entity/User'
|
||||
|
||||
import { RIGHTS } from '@/auth/RIGHTS'
|
||||
import { Role } from '@/auth/Role'
|
||||
import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder'
|
||||
import { AdminUpdateContributionArgs } from '@/graphql/arg/AdminUpdateContributionArgs'
|
||||
import { ContributionStatus } from '@/graphql/enum/ContributionStatus'
|
||||
import { LogError } from '@/server/LogError'
|
||||
@ -29,6 +30,11 @@ export class UnconfirmedContributionAdminRole extends AbstractUnconfirmedContrib
|
||||
this.self.contributionStatus = ContributionStatus.PENDING
|
||||
this.self.updatedAt = new Date()
|
||||
this.self.updatedBy = this.moderator.id
|
||||
if (this.updateData.resubmissionAt) {
|
||||
this.self.resubmissionAt = new Date(this.updateData.resubmissionAt)
|
||||
} else {
|
||||
this.self.resubmissionAt = null
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@ -53,4 +59,8 @@ export class UnconfirmedContributionAdminRole extends AbstractUnconfirmedContrib
|
||||
throw new LogError("the contribution wasn't changed at all")
|
||||
}
|
||||
}
|
||||
|
||||
public createContributionMessage(): ContributionMessageBuilder {
|
||||
return super.createContributionMessage().setIsModerator(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
import { Contribution } from '@entity/Contribution'
|
||||
import { User } from '@entity/User'
|
||||
|
||||
import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder'
|
||||
import { ContributionMessageArgs } from '@/graphql/arg/ContributionMessageArgs'
|
||||
import { ContributionMessageType } from '@/graphql/enum/ContributionMessageType'
|
||||
import { ContributionStatus } from '@/graphql/enum/ContributionStatus'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
import { AbstractUnconfirmedContributionRole } from './AbstractUnconfirmedContribution.role'
|
||||
|
||||
export class UnconfirmedContributionAdminAddMessageRole extends AbstractUnconfirmedContributionRole {
|
||||
public constructor(contribution: Contribution, private updateData: ContributionMessageArgs) {
|
||||
super(contribution, contribution.amount, contribution.contributionDate)
|
||||
}
|
||||
|
||||
protected update(): void {
|
||||
let newStatus = this.self.contributionStatus
|
||||
// change status (does not apply to moderator messages)
|
||||
if (this.updateData.messageType !== ContributionMessageType.MODERATOR) {
|
||||
newStatus = ContributionStatus.IN_PROGRESS
|
||||
}
|
||||
if (this.self.contributionStatus !== newStatus || this.self.resubmissionAt != null) {
|
||||
this.self.contributionStatus = newStatus
|
||||
this.self.resubmissionAt = null
|
||||
} else {
|
||||
this.changed = false
|
||||
}
|
||||
}
|
||||
|
||||
protected checkAuthorization(user: User): AbstractUnconfirmedContributionRole {
|
||||
// TODO: think if there are cases in which admin comment his own contribution
|
||||
if (
|
||||
this.self.userId === user.id &&
|
||||
this.updateData.messageType === ContributionMessageType.MODERATOR
|
||||
) {
|
||||
throw new LogError(
|
||||
'Moderator|Admin can not make a moderator comment on his own contribution',
|
||||
this.self.id,
|
||||
)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
protected async validate(clientTimezoneOffset: number): Promise<void> {
|
||||
await super.validate(clientTimezoneOffset)
|
||||
}
|
||||
|
||||
public createContributionMessage(): ContributionMessageBuilder {
|
||||
return super
|
||||
.createContributionMessage()
|
||||
.setIsModerator(true)
|
||||
.setMessageAndType(this.updateData.message, this.updateData.messageType)
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import { Contribution } from '@entity/Contribution'
|
||||
import { User } from '@entity/User'
|
||||
|
||||
import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder'
|
||||
import { ContributionArgs } from '@/graphql/arg/ContributionArgs'
|
||||
import { ContributionStatus } from '@/graphql/enum/ContributionStatus'
|
||||
import { LogError } from '@/server/LogError'
|
||||
@ -20,6 +21,7 @@ export class UnconfirmedContributionUserRole extends AbstractUnconfirmedContribu
|
||||
this.self.updatedAt = new Date()
|
||||
// null because updated by user them self
|
||||
this.self.updatedBy = null
|
||||
this.self.resubmissionAt = null
|
||||
}
|
||||
|
||||
protected checkAuthorization(user: User): AbstractUnconfirmedContributionRole {
|
||||
@ -55,4 +57,8 @@ export class UnconfirmedContributionUserRole extends AbstractUnconfirmedContribu
|
||||
throw new LogError("the contribution wasn't changed at all")
|
||||
}
|
||||
}
|
||||
|
||||
public createContributionMessage(): ContributionMessageBuilder {
|
||||
return super.createContributionMessage().setIsModerator(false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
import { Contribution } from '@entity/Contribution'
|
||||
import { User } from '@entity/User'
|
||||
|
||||
import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder'
|
||||
import { ContributionMessageArgs } from '@/graphql/arg/ContributionMessageArgs'
|
||||
import { ContributionStatus } from '@/graphql/enum/ContributionStatus'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
import { AbstractUnconfirmedContributionRole } from './AbstractUnconfirmedContribution.role'
|
||||
|
||||
export class UnconfirmedContributionUserAddMessageRole extends AbstractUnconfirmedContributionRole {
|
||||
public constructor(contribution: Contribution, private updateData: ContributionMessageArgs) {
|
||||
super(contribution, contribution.amount, contribution.contributionDate)
|
||||
}
|
||||
|
||||
protected update(): void {
|
||||
if (
|
||||
this.self.contributionStatus === ContributionStatus.IN_PROGRESS ||
|
||||
this.self.resubmissionAt !== null
|
||||
) {
|
||||
this.self.contributionStatus = ContributionStatus.PENDING
|
||||
this.self.resubmissionAt = null
|
||||
} else {
|
||||
this.changed = false
|
||||
}
|
||||
}
|
||||
|
||||
protected checkAuthorization(user: User): AbstractUnconfirmedContributionRole {
|
||||
if (this.self.userId !== user.id) {
|
||||
throw new LogError('Can not update contribution of another user', this.self, user.id)
|
||||
}
|
||||
// only admins and moderators can update it when status is other than progress or pending
|
||||
if (
|
||||
this.self.contributionStatus !== ContributionStatus.IN_PROGRESS &&
|
||||
this.self.contributionStatus !== ContributionStatus.PENDING
|
||||
) {
|
||||
throw new LogError(
|
||||
'Contribution can not be updated due to status',
|
||||
this.self.contributionStatus,
|
||||
)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
public createContributionMessage(): ContributionMessageBuilder {
|
||||
return super
|
||||
.createContributionMessage()
|
||||
.setIsModerator(false)
|
||||
.setDialogType(this.updateData.message)
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import { EntityManager, FindOneOptions, FindOptionsRelations } from '@dbTools/typeorm'
|
||||
import { Contribution } from '@entity/Contribution'
|
||||
import { ContributionMessage } from '@entity/ContributionMessage'
|
||||
import { Decimal } from 'decimal.js-light'
|
||||
@ -5,13 +6,15 @@ import { Decimal } from 'decimal.js-light'
|
||||
import { AdminUpdateContributionArgs } from '@arg/AdminUpdateContributionArgs'
|
||||
import { ContributionArgs } from '@arg/ContributionArgs'
|
||||
|
||||
import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder'
|
||||
import { ContributionMessageArgs } from '@/graphql/arg/ContributionMessageArgs'
|
||||
import { Context } from '@/server/context'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
import { AbstractUnconfirmedContributionRole } from './AbstractUnconfirmedContribution.role'
|
||||
import { UnconfirmedContributionAdminRole } from './UnconfirmedContributionAdmin.role'
|
||||
import { UnconfirmedContributionAdminAddMessageRole } from './UnconfirmedContributionAdminAddMessage.role'
|
||||
import { UnconfirmedContributionUserRole } from './UnconfirmedContributionUser.role'
|
||||
import { UnconfirmedContributionUserAddMessageRole } from './UnconfirmedContributionUserAddMessage.role'
|
||||
|
||||
export class UpdateUnconfirmedContributionContext {
|
||||
private oldMemoText: string
|
||||
@ -23,7 +26,7 @@ export class UpdateUnconfirmedContributionContext {
|
||||
*/
|
||||
public constructor(
|
||||
private id: number,
|
||||
private input: ContributionArgs | AdminUpdateContributionArgs,
|
||||
private input: ContributionArgs | AdminUpdateContributionArgs | ContributionMessageArgs,
|
||||
private context: Context,
|
||||
) {
|
||||
if (!context.role || !context.user) {
|
||||
@ -31,28 +34,31 @@ export class UpdateUnconfirmedContributionContext {
|
||||
}
|
||||
}
|
||||
|
||||
public async run(): Promise<{
|
||||
public async run(
|
||||
transactionEntityManager?: EntityManager,
|
||||
relations?: FindOptionsRelations<Contribution>,
|
||||
): Promise<{
|
||||
contribution: Contribution
|
||||
contributionMessage: ContributionMessage
|
||||
availableCreationSums: Decimal[]
|
||||
createdByUserChangedByModerator: boolean
|
||||
contributionChanged: boolean
|
||||
}> {
|
||||
let createdByUserChangedByModerator = false
|
||||
if (!this.context.role || !this.context.user) {
|
||||
throw new LogError("context didn't contain role or user")
|
||||
}
|
||||
const contributionToUpdate = await Contribution.findOne({
|
||||
where: { id: this.id },
|
||||
})
|
||||
const options: FindOneOptions<Contribution> = { where: { id: this.id }, relations }
|
||||
let contributionToUpdate: Contribution | null
|
||||
if (transactionEntityManager) {
|
||||
contributionToUpdate = await transactionEntityManager.findOne(Contribution, options)
|
||||
} else {
|
||||
contributionToUpdate = await Contribution.findOne(options)
|
||||
}
|
||||
if (!contributionToUpdate) {
|
||||
throw new LogError('Contribution not found', this.id)
|
||||
}
|
||||
this.oldMemoText = contributionToUpdate.memo
|
||||
const contributionMessageBuilder = new ContributionMessageBuilder()
|
||||
contributionMessageBuilder
|
||||
.setParentContribution(contributionToUpdate)
|
||||
.setHistoryType(contributionToUpdate)
|
||||
.setUser(this.context.user)
|
||||
|
||||
// choose correct role
|
||||
let unconfirmedContributionRole: AbstractUnconfirmedContributionRole | null = null
|
||||
@ -61,7 +67,6 @@ export class UpdateUnconfirmedContributionContext {
|
||||
contributionToUpdate,
|
||||
this.input,
|
||||
)
|
||||
contributionMessageBuilder.setIsModerator(false)
|
||||
} else if (this.input instanceof AdminUpdateContributionArgs) {
|
||||
unconfirmedContributionRole = new UnconfirmedContributionAdminRole(
|
||||
contributionToUpdate,
|
||||
@ -71,7 +76,18 @@ export class UpdateUnconfirmedContributionContext {
|
||||
if (unconfirmedContributionRole.isCreatedFromUser()) {
|
||||
createdByUserChangedByModerator = true
|
||||
}
|
||||
contributionMessageBuilder.setIsModerator(true)
|
||||
} else if (this.input instanceof ContributionMessageArgs) {
|
||||
if (contributionToUpdate.userId !== this.context.user.id) {
|
||||
unconfirmedContributionRole = new UnconfirmedContributionAdminAddMessageRole(
|
||||
contributionToUpdate,
|
||||
this.input,
|
||||
)
|
||||
} else {
|
||||
unconfirmedContributionRole = new UnconfirmedContributionUserAddMessageRole(
|
||||
contributionToUpdate,
|
||||
this.input,
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!unconfirmedContributionRole) {
|
||||
throw new LogError("don't recognize input type, maybe not implemented yet?")
|
||||
@ -82,9 +98,13 @@ export class UpdateUnconfirmedContributionContext {
|
||||
|
||||
return {
|
||||
contribution: contributionToUpdate,
|
||||
contributionMessage: contributionMessageBuilder.build(),
|
||||
contributionMessage: unconfirmedContributionRole
|
||||
.createContributionMessage()
|
||||
.setUser(this.context.user)
|
||||
.build(),
|
||||
availableCreationSums: unconfirmedContributionRole.getAvailableCreationSums(),
|
||||
createdByUserChangedByModerator,
|
||||
contributionChanged: unconfirmedContributionRole.isChanged(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(`ALTER TABLE \`contribution_messages\` DROP COLUMN \`resubmission_at\`;`)
|
||||
await queryFn(
|
||||
`ALTER TABLE \`contributions\` ADD COLUMN \`resubmission_at\` datetime NULL DEFAULT NULL AFTER \`created_at \`;`,
|
||||
`ALTER TABLE \`contributions\` ADD COLUMN \`resubmission_at\` datetime NULL DEFAULT NULL AFTER \`created_at\`;`,
|
||||
)
|
||||
await queryFn(`ALTER TABLE \`contribution_messages\` DROP COLUMN \`resubmission_at\`;`)
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user