mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'virtual-link-transaction' into transaction-link-list-query
This commit is contained in:
commit
80201c6fb1
@ -6,6 +6,7 @@ export enum TransactionTypeId {
|
|||||||
RECEIVE = 3,
|
RECEIVE = 3,
|
||||||
// This is a virtual property, never occurring on the database
|
// This is a virtual property, never occurring on the database
|
||||||
DECAY = 4,
|
DECAY = 4,
|
||||||
|
TRANSACTION_LINK,
|
||||||
}
|
}
|
||||||
|
|
||||||
registerEnumType(TransactionTypeId, {
|
registerEnumType(TransactionTypeId, {
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import { calculateBalance, isHexPublicKey } from '@/util/validate'
|
|||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { User } from '@model/User'
|
import { User } from '@model/User'
|
||||||
import { communityUser } from '@/util/communityUser'
|
import { communityUser } from '@/util/communityUser'
|
||||||
import { virtualDecayTransaction } from '@/util/virtualDecayTransaction'
|
import { virtualLinkTransaction, virtualDecayTransaction } from '@/util/virtualTransactions'
|
||||||
import Decimal from 'decimal.js-light'
|
import Decimal from 'decimal.js-light'
|
||||||
import { calculateDecay } from '@/util/decay'
|
import { calculateDecay } from '@/util/decay'
|
||||||
|
|
||||||
@ -112,11 +112,29 @@ export class TransactionResolver {
|
|||||||
const self = new User(user)
|
const self = new User(user)
|
||||||
const transactions: Transaction[] = []
|
const transactions: Transaction[] = []
|
||||||
|
|
||||||
|
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
|
||||||
|
const { sumHoldAvailableAmount, sumAmount, lastDate, firstDate } =
|
||||||
|
await transactionLinkRepository.summary(user.id, now)
|
||||||
|
|
||||||
// decay transaction
|
// decay transaction
|
||||||
if (!onlyCreations && currentPage === 1 && order === Order.DESC) {
|
if (!onlyCreations && currentPage === 1 && order === Order.DESC) {
|
||||||
transactions.push(
|
transactions.push(
|
||||||
virtualDecayTransaction(lastTransaction.balance, lastTransaction.balanceDate, now, self),
|
virtualDecayTransaction(lastTransaction.balance, lastTransaction.balanceDate, now, self),
|
||||||
)
|
)
|
||||||
|
// virtual transaction for pending transaction-links sum
|
||||||
|
if (sumHoldAvailableAmount.greaterThan(0)) {
|
||||||
|
transactions.push(
|
||||||
|
virtualLinkTransaction(
|
||||||
|
lastTransaction.balance.minus(sumHoldAvailableAmount.toString()),
|
||||||
|
sumAmount,
|
||||||
|
sumHoldAvailableAmount,
|
||||||
|
sumHoldAvailableAmount.minus(sumAmount.toString()),
|
||||||
|
firstDate || now,
|
||||||
|
lastDate || now,
|
||||||
|
self,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// transactions
|
// transactions
|
||||||
@ -128,13 +146,10 @@ export class TransactionResolver {
|
|||||||
transactions.push(new Transaction(userTransaction, self, linkedUser))
|
transactions.push(new Transaction(userTransaction, self, linkedUser))
|
||||||
})
|
})
|
||||||
|
|
||||||
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
|
|
||||||
const toHoldAvailable = await transactionLinkRepository.sumAmountToHoldAvailable(user.id, now)
|
|
||||||
|
|
||||||
// Construct Result
|
// Construct Result
|
||||||
return new TransactionList(
|
return new TransactionList(
|
||||||
calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, now).balance.minus(
|
calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, now).balance.minus(
|
||||||
toHoldAvailable.toString(),
|
sumHoldAvailableAmount.toString(),
|
||||||
),
|
),
|
||||||
transactions,
|
transactions,
|
||||||
userTransactionsCount,
|
userTransactionsCount,
|
||||||
|
|||||||
@ -4,13 +4,33 @@ import Decimal from 'decimal.js-light'
|
|||||||
|
|
||||||
@EntityRepository(dbTransactionLink)
|
@EntityRepository(dbTransactionLink)
|
||||||
export class TransactionLinkRepository extends Repository<dbTransactionLink> {
|
export class TransactionLinkRepository extends Repository<dbTransactionLink> {
|
||||||
async sumAmountToHoldAvailable(userId: number, date: Date): Promise<Decimal> {
|
async summary(
|
||||||
const { sum } = await this.createQueryBuilder('transactionLinks')
|
userId: number,
|
||||||
.select('SUM(transactionLinks.holdAvailableAmount)', 'sum')
|
date: Date,
|
||||||
|
): Promise<{
|
||||||
|
sumHoldAvailableAmount: Decimal
|
||||||
|
sumAmount: Decimal
|
||||||
|
lastDate: Date | null
|
||||||
|
firstDate: Date | null
|
||||||
|
}> {
|
||||||
|
const { sumHoldAvailableAmount, sumAmount, lastDate, firstDate } =
|
||||||
|
await this.createQueryBuilder('transactionLinks')
|
||||||
|
.select('SUM(transactionLinks.holdAvailableAmount)', 'sumHoldAvailableAmount')
|
||||||
|
.addSelect('SUM(transactionLinks.amount)', 'sumAmount')
|
||||||
|
.addSelect('MAX(transactionLinks.validUntil)', 'lastDate')
|
||||||
|
.addSelect('MIN(transactionLinks.createdAt)', 'firstDate')
|
||||||
.where('transactionLinks.userId = :userId', { userId })
|
.where('transactionLinks.userId = :userId', { userId })
|
||||||
.andWhere('transactionLinks.redeemedAt is NULL')
|
.andWhere('transactionLinks.redeemedAt is NULL')
|
||||||
.andWhere('transactionLinks.validUntil > :date', { date })
|
.andWhere('transactionLinks.validUntil > :date', { date })
|
||||||
|
.orderBy('transactionLinks.createdAt', 'DESC')
|
||||||
.getRawOne()
|
.getRawOne()
|
||||||
return sum ? new Decimal(sum) : new Decimal(0)
|
return {
|
||||||
|
sumHoldAvailableAmount: sumHoldAvailableAmount
|
||||||
|
? new Decimal(sumHoldAvailableAmount)
|
||||||
|
: new Decimal(0),
|
||||||
|
sumAmount: sumAmount ? new Decimal(sumAmount) : new Decimal(0),
|
||||||
|
lastDate: lastDate || null,
|
||||||
|
firstDate: firstDate || null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,9 +30,9 @@ async function calculateBalance(
|
|||||||
// TODO why we have to use toString() here?
|
// TODO why we have to use toString() here?
|
||||||
const balance = decay.balance.add(amount.toString())
|
const balance = decay.balance.add(amount.toString())
|
||||||
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
|
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
|
||||||
const toHoldAvailable = await transactionLinkRepository.sumAmountToHoldAvailable(userId, time)
|
const { sumHoldAvailableAmount } = await transactionLinkRepository.summary(userId, time)
|
||||||
|
|
||||||
if (balance.minus(toHoldAvailable.toString()).lessThan(0)) {
|
if (balance.minus(sumHoldAvailableAmount.toString()).lessThan(0)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return { balance, lastTransactionId: lastTransaction.id, decay }
|
return { balance, lastTransactionId: lastTransaction.id, decay }
|
||||||
|
|||||||
@ -1,52 +0,0 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import Decimal from 'decimal.js-light'
|
|
||||||
import { SaveOptions, RemoveOptions } from '@dbTools/typeorm'
|
|
||||||
import { Transaction as dbTransaction } from '@entity/Transaction'
|
|
||||||
import { calculateDecay } from './decay'
|
|
||||||
import { TransactionTypeId } from '@enum/TransactionTypeId'
|
|
||||||
import { Transaction } from '@model/Transaction'
|
|
||||||
import { User } from '@model/User'
|
|
||||||
|
|
||||||
const virtualDecayTransaction = (
|
|
||||||
balance: Decimal,
|
|
||||||
balanceDate: Date,
|
|
||||||
time: Date = new Date(),
|
|
||||||
user: User,
|
|
||||||
): Transaction => {
|
|
||||||
const decay = calculateDecay(balance, balanceDate, time)
|
|
||||||
// const balance = decay.balance.minus(lastTransaction.balance)
|
|
||||||
const decayDbTransaction: dbTransaction = {
|
|
||||||
id: -1,
|
|
||||||
userId: -1,
|
|
||||||
previous: -1,
|
|
||||||
typeId: TransactionTypeId.DECAY,
|
|
||||||
amount: decay.decay ? decay.decay : new Decimal(0), // new Decimal(0), // this kinda is wrong, but helps with the frontend query
|
|
||||||
balance: decay.balance,
|
|
||||||
balanceDate: time,
|
|
||||||
decay: decay.decay ? decay.decay : new Decimal(0),
|
|
||||||
decayStart: decay.start,
|
|
||||||
memo: '',
|
|
||||||
creationDate: null,
|
|
||||||
hasId: function (): boolean {
|
|
||||||
throw new Error('Function not implemented.')
|
|
||||||
},
|
|
||||||
save: function (options?: SaveOptions): Promise<dbTransaction> {
|
|
||||||
throw new Error('Function not implemented.')
|
|
||||||
},
|
|
||||||
remove: function (options?: RemoveOptions): Promise<dbTransaction> {
|
|
||||||
throw new Error('Function not implemented.')
|
|
||||||
},
|
|
||||||
softRemove: function (options?: SaveOptions): Promise<dbTransaction> {
|
|
||||||
throw new Error('Function not implemented.')
|
|
||||||
},
|
|
||||||
recover: function (options?: SaveOptions): Promise<dbTransaction> {
|
|
||||||
throw new Error('Function not implemented.')
|
|
||||||
},
|
|
||||||
reload: function (): Promise<void> {
|
|
||||||
throw new Error('Function not implemented.')
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return new Transaction(decayDbTransaction, user)
|
|
||||||
}
|
|
||||||
|
|
||||||
export { virtualDecayTransaction }
|
|
||||||
82
backend/src/util/virtualTransactions.ts
Normal file
82
backend/src/util/virtualTransactions.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
import { Transaction } from '@model/Transaction'
|
||||||
|
import { SaveOptions, RemoveOptions } from '@dbTools/typeorm'
|
||||||
|
import { Transaction as dbTransaction } from '@entity/Transaction'
|
||||||
|
import { TransactionTypeId } from '@enum/TransactionTypeId'
|
||||||
|
import { calculateDecay } from './decay'
|
||||||
|
import { User } from '@model/User'
|
||||||
|
import Decimal from 'decimal.js-light'
|
||||||
|
|
||||||
|
const defaultModelFunctions = {
|
||||||
|
hasId: function (): boolean {
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
},
|
||||||
|
save: function (options?: SaveOptions): Promise<dbTransaction> {
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
},
|
||||||
|
remove: function (options?: RemoveOptions): Promise<dbTransaction> {
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
},
|
||||||
|
softRemove: function (options?: SaveOptions): Promise<dbTransaction> {
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
},
|
||||||
|
recover: function (options?: SaveOptions): Promise<dbTransaction> {
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
},
|
||||||
|
reload: function (): Promise<void> {
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const virtualLinkTransaction = (
|
||||||
|
balance: Decimal,
|
||||||
|
amount: Decimal,
|
||||||
|
holdAvailableAmount: Decimal,
|
||||||
|
decay: Decimal,
|
||||||
|
createdAt: Date,
|
||||||
|
validUntil: Date,
|
||||||
|
user: User,
|
||||||
|
): Transaction => {
|
||||||
|
const linkDbTransaction: dbTransaction = {
|
||||||
|
id: -2,
|
||||||
|
userId: -1,
|
||||||
|
previous: -1,
|
||||||
|
typeId: TransactionTypeId.TRANSACTION_LINK,
|
||||||
|
amount: amount,
|
||||||
|
balance: balance,
|
||||||
|
balanceDate: validUntil,
|
||||||
|
decayStart: createdAt,
|
||||||
|
decay: decay,
|
||||||
|
memo: '',
|
||||||
|
creationDate: null,
|
||||||
|
...defaultModelFunctions,
|
||||||
|
}
|
||||||
|
return new Transaction(linkDbTransaction, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
const virtualDecayTransaction = (
|
||||||
|
balance: Decimal,
|
||||||
|
balanceDate: Date,
|
||||||
|
time: Date = new Date(),
|
||||||
|
user: User,
|
||||||
|
): Transaction => {
|
||||||
|
const decay = calculateDecay(balance, balanceDate, time)
|
||||||
|
// const balance = decay.balance.minus(lastTransaction.balance)
|
||||||
|
const decayDbTransaction: dbTransaction = {
|
||||||
|
id: -1,
|
||||||
|
userId: -1,
|
||||||
|
previous: -1,
|
||||||
|
typeId: TransactionTypeId.DECAY,
|
||||||
|
amount: decay.decay ? decay.decay : new Decimal(0), // new Decimal(0), // this kinda is wrong, but helps with the frontend query
|
||||||
|
balance: decay.balance,
|
||||||
|
balanceDate: time,
|
||||||
|
decay: decay.decay ? decay.decay : new Decimal(0),
|
||||||
|
decayStart: decay.start,
|
||||||
|
memo: '',
|
||||||
|
creationDate: null,
|
||||||
|
...defaultModelFunctions,
|
||||||
|
}
|
||||||
|
return new Transaction(decayDbTransaction, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { virtualLinkTransaction, virtualDecayTransaction }
|
||||||
Loading…
x
Reference in New Issue
Block a user