gradido/backend/src/graphql/resolver/ContributionLinkResolver.ts
2023-03-30 18:04:43 +02:00

152 lines
5.1 KiB
TypeScript

import { MoreThan, IsNull } from '@dbTools/typeorm'
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
import { Decimal } from 'decimal.js-light'
import { Resolver, Args, Arg, Authorized, Mutation, Query, Int, Ctx } from 'type-graphql'
// TODO: this is a strange construct
import ContributionLinkArgs from '@arg/ContributionLinkArgs'
import Paginated from '@arg/Paginated'
import { Order } from '@enum/Order'
import { ContributionLink } from '@model/ContributionLink'
import { ContributionLinkList } from '@model/ContributionLinkList'
import { RIGHTS } from '@/auth/RIGHTS'
import {
EVENT_ADMIN_CONTRIBUTION_LINK_CREATE,
EVENT_ADMIN_CONTRIBUTION_LINK_DELETE,
EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE,
} from '@/event/Event'
import { Context, getUser } from '@/server/context'
import LogError from '@/server/LogError'
import {
CONTRIBUTIONLINK_NAME_MAX_CHARS,
CONTRIBUTIONLINK_NAME_MIN_CHARS,
MEMO_MAX_CHARS,
MEMO_MIN_CHARS,
} from './const/const'
import { transactionLinkCode as contributionLinkCode } from './TransactionLinkResolver'
import { isStartEndDateValid } from './util/creations'
@Resolver()
export class ContributionLinkResolver {
@Authorized([RIGHTS.CREATE_CONTRIBUTION_LINK])
@Mutation(() => ContributionLink)
async createContributionLink(
@Args()
{
amount,
name,
memo,
cycle,
validFrom,
validTo,
maxAmountPerMonth = null,
maxPerCycle,
}: ContributionLinkArgs,
@Ctx() context: Context,
): Promise<ContributionLink> {
isStartEndDateValid(validFrom, validTo)
if (name.length < CONTRIBUTIONLINK_NAME_MIN_CHARS) {
throw new LogError('The value of name is too short', name.length)
}
if (name.length > CONTRIBUTIONLINK_NAME_MAX_CHARS) {
throw new LogError('The value of name is too long', name.length)
}
if (memo.length < MEMO_MIN_CHARS) {
throw new LogError('The value of memo is too short', memo.length)
}
if (memo.length > MEMO_MAX_CHARS) {
throw new LogError('The value of memo is too long', memo.length)
}
if (!new Decimal(amount).isPositive()) {
throw new LogError('The amount must be a positiv value', amount)
}
const dbContributionLink = new DbContributionLink()
dbContributionLink.amount = amount
dbContributionLink.name = name
dbContributionLink.memo = memo
dbContributionLink.createdAt = new Date()
dbContributionLink.code = contributionLinkCode(dbContributionLink.createdAt)
dbContributionLink.cycle = cycle
if (validFrom) dbContributionLink.validFrom = new Date(validFrom)
if (validTo) dbContributionLink.validTo = new Date(validTo)
dbContributionLink.maxAmountPerMonth = maxAmountPerMonth
dbContributionLink.maxPerCycle = maxPerCycle
await dbContributionLink.save()
await EVENT_ADMIN_CONTRIBUTION_LINK_CREATE(getUser(context), dbContributionLink, amount)
return new ContributionLink(dbContributionLink)
}
@Authorized([RIGHTS.LIST_CONTRIBUTION_LINKS])
@Query(() => ContributionLinkList)
async listContributionLinks(
@Args()
{ currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated,
): Promise<ContributionLinkList> {
const [links, count] = await DbContributionLink.findAndCount({
where: [{ validTo: MoreThan(new Date()) }, { validTo: IsNull() }],
order: { createdAt: order },
skip: (currentPage - 1) * pageSize,
take: pageSize,
})
return {
links: links.map((link: DbContributionLink) => new ContributionLink(link)),
count,
}
}
@Authorized([RIGHTS.DELETE_CONTRIBUTION_LINK])
@Mutation(() => Boolean)
async deleteContributionLink(
@Arg('id', () => Int) id: number,
@Ctx() context: Context,
): Promise<boolean> {
const dbContributionLink = await DbContributionLink.findOne(id)
if (!dbContributionLink) {
throw new LogError('Contribution Link not found', id)
}
await dbContributionLink.softRemove()
await EVENT_ADMIN_CONTRIBUTION_LINK_DELETE(getUser(context), dbContributionLink)
return true
}
@Authorized([RIGHTS.UPDATE_CONTRIBUTION_LINK])
@Mutation(() => ContributionLink)
async updateContributionLink(
@Args()
{
amount,
name,
memo,
cycle,
validFrom,
validTo,
maxAmountPerMonth = null,
maxPerCycle,
}: ContributionLinkArgs,
@Arg('id', () => Int) id: number,
@Ctx() context: Context,
): Promise<ContributionLink> {
const dbContributionLink = await DbContributionLink.findOne(id)
if (!dbContributionLink) {
throw new LogError('Contribution Link not found', id)
}
dbContributionLink.amount = amount
dbContributionLink.name = name
dbContributionLink.memo = memo
dbContributionLink.cycle = cycle
if (validFrom) dbContributionLink.validFrom = new Date(validFrom)
if (validTo) dbContributionLink.validTo = new Date(validTo)
dbContributionLink.maxAmountPerMonth = maxAmountPerMonth
dbContributionLink.maxPerCycle = maxPerCycle
await dbContributionLink.save()
await EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE(getUser(context), dbContributionLink, amount)
return new ContributionLink(dbContributionLink)
}
}