diff --git a/admin/src/components/Tables/OpenCreationsTable.vue b/admin/src/components/Tables/OpenCreationsTable.vue
index 86c5ecce6..af9947f85 100644
--- a/admin/src/components/Tables/OpenCreationsTable.vue
+++ b/admin/src/components/Tables/OpenCreationsTable.vue
@@ -12,33 +12,42 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
d),
$store: {
commit: storeCommitMock,
+ state: {
+ moderator: {
+ firstName: 'Peter',
+ lastName: 'Lustig',
+ isAdmin: '2022-08-30T07:41:31.000Z',
+ id: 263,
+ language: 'de',
+ },
+ },
},
$apollo: {
query: apolloQueryMock,
diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts
index f4656aec8..65662e8eb 100644
--- a/backend/src/graphql/resolver/AdminResolver.ts
+++ b/backend/src/graphql/resolver/AdminResolver.ts
@@ -717,6 +717,9 @@ export class AdminResolver {
if (!contribution) {
throw new Error('Contribution not found')
}
+ if (contribution.userId === user.id) {
+ throw new Error('Admin can not answer on own contribution')
+ }
contributionMessage.contributionId = contributionId
contributionMessage.createdAt = new Date()
contributionMessage.message = message
diff --git a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts
index 6c617acb4..c0e330750 100644
--- a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts
+++ b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts
@@ -93,6 +93,38 @@ describe('ContributionMessageResolver', () => {
}),
)
})
+
+ it('throws error when contribution.userId equals user.id', async () => {
+ await query({
+ query: login,
+ variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
+ })
+ const result2 = await mutate({
+ mutation: createContribution,
+ variables: {
+ amount: 100.0,
+ memo: 'Test env contribution',
+ creationDate: new Date().toString(),
+ },
+ })
+ await expect(
+ mutate({
+ mutation: adminCreateContributionMessage,
+ variables: {
+ contributionId: result2.data.createContribution.id,
+ message: 'Test',
+ },
+ }),
+ ).resolves.toEqual(
+ expect.objectContaining({
+ errors: [
+ new GraphQLError(
+ 'ContributionMessage was not successful: Error: Admin can not answer on own contribution',
+ ),
+ ],
+ }),
+ )
+ })
})
describe('valid input', () => {
diff --git a/backend/src/graphql/resolver/StatisticsResolver.ts b/backend/src/graphql/resolver/StatisticsResolver.ts
index 4c1500839..b0c061d91 100644
--- a/backend/src/graphql/resolver/StatisticsResolver.ts
+++ b/backend/src/graphql/resolver/StatisticsResolver.ts
@@ -7,49 +7,48 @@ import { getConnection } from '@dbTools/typeorm'
import Decimal from 'decimal.js-light'
import { calculateDecay } from '@/util/decay'
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
+
@Resolver()
export class StatisticsResolver {
@Authorized([RIGHTS.COMMUNITY_STATISTICS])
@Query(() => CommunityStatistics)
async communityStatistics(): Promise {
- const allUsers = await DbUser.find({ withDeleted: true })
-
- let totalUsers = 0
- let activeUsers = 0
- let deletedUsers = 0
+ const allUsers = await DbUser.count({ withDeleted: true })
+ const totalUsers = await DbUser.count()
+ const deletedUsers = allUsers - totalUsers
let totalGradidoAvailable: Decimal = new Decimal(0)
let totalGradidoUnbookedDecayed: Decimal = new Decimal(0)
const receivedCallDate = new Date()
- for (let i = 0; i < allUsers.length; i++) {
- if (allUsers[i].deletedAt) {
- deletedUsers++
- } else {
- totalUsers++
- const lastTransaction = await DbTransaction.findOne({
- where: { userId: allUsers[i].id },
- order: { balanceDate: 'DESC' },
- })
- if (lastTransaction) {
- activeUsers++
- const decay = calculateDecay(
- lastTransaction.balance,
- lastTransaction.balanceDate,
- receivedCallDate,
- )
- if (decay) {
- totalGradidoAvailable = totalGradidoAvailable.plus(decay.balance.toString())
- totalGradidoUnbookedDecayed = totalGradidoUnbookedDecayed.plus(decay.decay.toString())
- }
- }
- }
- }
-
const queryRunner = getConnection().createQueryRunner()
await queryRunner.connect()
+ const lastUserTransactions = await queryRunner.manager
+ .createQueryBuilder(DbUser, 'user')
+ .select('transaction.balance', 'balance')
+ .addSelect('transaction.balance_date', 'balanceDate')
+ .innerJoin(DbTransaction, 'transaction', 'user.id = transaction.user_id')
+ .where(
+ `transaction.balance_date = (SELECT MAX(t.balance_date) FROM transactions AS t WHERE t.user_id = user.id)`,
+ )
+ .orderBy('transaction.balance_date', 'DESC')
+ .addOrderBy('transaction.id', 'DESC')
+ .getRawMany()
+
+ const activeUsers = lastUserTransactions.length
+
+ lastUserTransactions.forEach(({ balance, balanceDate }) => {
+ const decay = calculateDecay(new Decimal(balance), new Date(balanceDate), receivedCallDate)
+ if (decay) {
+ totalGradidoAvailable = totalGradidoAvailable.plus(decay.balance.toString())
+ totalGradidoUnbookedDecayed = totalGradidoUnbookedDecayed.plus(decay.decay.toString())
+ }
+ })
+
const { totalGradidoCreated } = await queryRunner.manager
.createQueryBuilder()
.select('SUM(transaction.amount) AS totalGradidoCreated')