mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
98 lines
3.3 KiB
TypeScript
98 lines
3.3 KiB
TypeScript
import { Contribution } from '@entity/Contribution'
|
|
import { User } from '@entity/User'
|
|
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
|
|
private currentStep = 0
|
|
|
|
public constructor(
|
|
protected self: Contribution,
|
|
protected updatedAmount: Decimal,
|
|
protected updatedCreationDate: Date,
|
|
) {
|
|
if (self.confirmedAt || self.deniedAt) {
|
|
throw new LogError("this contribution isn't unconfirmed!")
|
|
}
|
|
}
|
|
|
|
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
|
|
// second, check if contribution is still valid after update
|
|
protected async validate(clientTimezoneOffset: number): Promise<void> {
|
|
// TODO: refactor frontend and remove this restriction
|
|
if (this.self.contributionDate.getMonth() !== this.updatedCreationDate.getMonth()) {
|
|
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,
|
|
true,
|
|
)
|
|
contributionLogic.checkAvailableCreationSumsNotExceeded(
|
|
this.updatedAmount,
|
|
this.updatedCreationDate,
|
|
clientTimezoneOffset,
|
|
)
|
|
}
|
|
|
|
// third, actually update entity
|
|
protected abstract update(): void
|
|
|
|
protected wasUpdateAlreadyCalled(): boolean {
|
|
return this.currentStep > 3
|
|
}
|
|
|
|
// call all steps in order
|
|
public async checkAndUpdate(context: Context): Promise<void> {
|
|
if (!context.user || !context.role) {
|
|
throw new LogError('missing user or role on context')
|
|
}
|
|
this.currentStep = 1
|
|
this.checkAuthorization(context.user, context.role)
|
|
this.currentStep = 2
|
|
await this.validate(getClientTimezoneOffset(context))
|
|
this.currentStep = 3
|
|
this.update()
|
|
this.currentStep = 4
|
|
}
|
|
|
|
public createContributionMessage(): ContributionMessageBuilder | undefined {
|
|
// must be called before call at update
|
|
if (this.wasUpdateAlreadyCalled()) {
|
|
throw new LogError('please call before call of checkAndUpdate')
|
|
}
|
|
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!')
|
|
}
|
|
return this.availableCreationSums
|
|
}
|
|
|
|
public isCreatedFromUser(): boolean {
|
|
return !this.self.moderatorId
|
|
}
|
|
}
|