Merge pull request #1548 from gradido/refactor_arithmetic_merge

Refactor arithmetic merge
This commit is contained in:
Alexander Friedland 2022-03-07 17:24:30 +01:00 committed by GitHub
commit 77f5668648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1355 additions and 627 deletions

View File

@ -28,9 +28,12 @@ import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { User } from '@entity/User'
import { TransactionTypeId } from '../enum/TransactionTypeId'
import Decimal from 'decimal.js-light'
import { Decay } from '../model/Decay'
// const EMAIL_OPT_IN_REGISTER = 1
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
const MAX_CREATION_AMOUNT = 1000
const FULL_CREATION_AVAILABLE = [MAX_CREATION_AMOUNT, MAX_CREATION_AMOUNT, MAX_CREATION_AMOUNT]
@Resolver()
export class AdminResolver {
@ -104,7 +107,7 @@ export class AdminResolver {
const userCreations = creations.find((c) => c.id === user.id)
const adminUser = new UserAdmin(
user,
userCreations ? userCreations.creations : [1000, 1000, 1000],
userCreations ? userCreations.creations : FULL_CREATION_AVAILABLE,
await hasElopageBuys(user.email),
emailConfirmationSend,
)
@ -170,7 +173,7 @@ export class AdminResolver {
if (isCreationValid(creations, amount, creationDateObj)) {
const adminPendingCreation = AdminPendingCreation.create()
adminPendingCreation.userId = user.id
adminPendingCreation.amount = BigInt(amount * 10000)
adminPendingCreation.amount = BigInt(amount)
adminPendingCreation.created = new Date()
adminPendingCreation.date = creationDateObj
adminPendingCreation.memo = memo
@ -235,7 +238,7 @@ export class AdminResolver {
if (!isCreationValid(creations, amount, creationDateObj)) {
throw new Error('Creation is not valid')
}
pendingCreationToUpdate.amount = BigInt(amount * 10000)
pendingCreationToUpdate.amount = BigInt(amount)
pendingCreationToUpdate.memo = memo
pendingCreationToUpdate.date = new Date(creationDate)
pendingCreationToUpdate.moderator = moderator
@ -270,11 +273,11 @@ export class AdminResolver {
return {
...pendingCreation,
amount: Number(parseInt(pendingCreation.amount.toString()) / 10000),
amount: Number(pendingCreation.amount.toString()),
firstName: user ? user.firstName : '',
lastName: user ? user.lastName : '',
email: user ? user.email : '',
creation: creation ? creation.creations : [1000, 1000, 1000],
creation: creation ? creation.creations : FULL_CREATION_AVAILABLE,
}
})
}
@ -300,7 +303,7 @@ export class AdminResolver {
if (user.deletedAt) throw new Error('This user was deleted. Cannot confirm a creation.')
const creations = await getUserCreation(pendingCreation.userId, false)
if (!isCreationValid(creations, Number(pendingCreation.amount) / 10000, pendingCreation.date)) {
if (!isCreationValid(creations, Number(pendingCreation.amount), pendingCreation.date)) {
throw new Error('Creation is not valid!!')
}
@ -310,25 +313,26 @@ export class AdminResolver {
const lastTransaction = await transactionRepository.findLastForUser(pendingCreation.userId)
let newBalance = new Decimal(0)
let decay: Decay | null = null
if (lastTransaction) {
newBalance = calculateDecay(
lastTransaction.balance,
lastTransaction.balanceDate,
receivedCallDate,
).balance
decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, receivedCallDate)
newBalance = decay.balance
}
// TODO pending creations decimal
newBalance = newBalance.add(new Decimal(Number(pendingCreation.amount)))
newBalance = newBalance.add(new Decimal(Number(pendingCreation.amount)).toString())
const transaction = new Transaction()
transaction.typeId = TransactionTypeId.CREATION
transaction.memo = pendingCreation.memo
transaction.userId = pendingCreation.userId
transaction.previous = lastTransaction ? lastTransaction.id : null
// TODO pending creations decimal
transaction.amount = new Decimal(Number(pendingCreation.amount))
transaction.creationDate = pendingCreation.date
transaction.balance = newBalance
transaction.balanceDate = receivedCallDate
transaction.decay = decay ? decay.decay : new Decimal(0)
transaction.decayStart = decay ? decay.start : null
await transaction.save()
await AdminPendingCreation.delete(pendingCreation)
@ -344,7 +348,7 @@ interface CreationMap {
async function getUserCreation(id: number, includePending = true): Promise<number[]> {
const creations = await getUserCreations([id], includePending)
return creations[0] ? creations[0].creations : [1000, 1000, 1000]
return creations[0] ? creations[0].creations : FULL_CREATION_AVAILABLE
}
async function getUserCreations(ids: number[], includePending = true): Promise<CreationMap[]> {
@ -384,7 +388,7 @@ async function getUserCreations(ids: number[], includePending = true): Promise<C
(raw: { month: string; id: string; creation: number[] }) =>
parseInt(raw.month) === month && parseInt(raw.id) === id,
)
return 1000 - (creation ? Number(creation.sum) / 10000 : 0)
return MAX_CREATION_AMOUNT - (creation ? Number(creation.sum) : 0)
}),
}
})

View File

@ -10,8 +10,8 @@ export class Transaction extends BaseEntity {
@Column({ name: 'user_id', unsigned: true, nullable: false })
userId: number
@Column({ unsigned: true, nullable: true, default: null })
previous: number
@Column({ type: 'int', unsigned: true, nullable: true, default: null })
previous: number | null
@Column({ name: 'type_id', unsigned: true, nullable: false })
typeId: number

View File

@ -10,7 +10,7 @@
"lint": "eslint --max-warnings=0 --ext .js,.vue .",
"dev": "yarn run serve",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
"test": "jest --coverage",
"test": "TZ=UTC jest --coverage",
"locales": "scripts/missing-keys.sh && scripts/sort.sh"
},
"dependencies": {

View File

@ -1,135 +0,0 @@
<template>
<div class="decayinformation">
<span v-if="decaytyp === 'short'">
{{ decay ? ' ' + $n(decay.balance, 'decimal') : '' }}
</span>
<div v-if="decaytyp === 'new' || decaytyp === 'decayLastTransaction'">
<div class="d-flex" v-if="!decay.decayStartBlock">
<div style="width: 100%" class="text-center pb-3">
<b-icon icon="droplet-half" height="12" class="mb-2" />
<b>{{ $t('decay.calculation_decay') }}</b>
</div>
</div>
<b-row>
<b-col cols="6" class="text-right">
<div v-if="!decay.decayStartBlock">{{ $t('decay.last_transaction') }}</div>
</b-col>
<b-col cols="6">
<div v-if="decay.decayStartBlock > 0">
<div class="display-4">{{ $t('decay.Starting_block_decay') }}</div>
<div>{{ $t('decay.decay_introduced') }} :</div>
</div>
<div>
<span v-if="decay.decayStart">
{{ $d(new Date(decay.decayStart * 1000), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</span>
</div>
</b-col>
</b-row>
<b-row>
<b-col cols="6" class="text-right">
<div v-if="!decay.decayStartBlock">{{ $t('decay.past_time') }}</div>
</b-col>
<b-col cols="6">
<div v-if="decay.decayStartBlock > 0">{{ $t('decay.since_introduction') }}</div>
<span v-if="duration">
<span v-if="duration.years > 0">{{ duration.years }} {{ $t('decay.year') }},</span>
<span v-if="duration.months > 0">{{ duration.months }} {{ $t('decay.months') }},</span>
<span v-if="duration.days > 0">{{ duration.days }} {{ $t('decay.days') }},</span>
<span v-if="duration.hours > 0">{{ duration.hours }} {{ $t('decay.hours') }},</span>
<span v-if="duration.minutes > 0">
{{ duration.minutes }} {{ $t('decay.minutes') }},
</span>
<span v-if="duration.seconds > 0">
{{ duration.seconds }} {{ $t('decay.seconds') }}
</span>
</span>
</b-col>
</b-row>
<!-- Decay-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div v-if="decaytyp === 'new'">- {{ $n(decay.balance, 'decimal') }}</div>
<div v-if="decaytyp === 'decayLastTransaction'">
{{ $n(decay.balance + gddbalance, 'decimal') }} GDD -
{{ $n(decay.balance, 'decimal') }} GDD =
<b>{{ $n(gddbalance, 'decimal') }} GDD</b>
</div>
</b-col>
</b-row>
<hr class="mt-2 mb-2" />
<b-row v-if="decaytyp === 'new'">
<b-col class="text-center pt-3 pb-2">
<b>{{ $t('decay.calculation_total') }}</b>
</b-col>
</b-row>
<!-- Type-->
<b-row v-if="decaytyp === 'new'">
<b-col cols="6" class="text-right">
<div v-if="type === 'send'">{{ $t('decay.sent') }}</div>
<div v-if="type === 'receive'">{{ $t('decay.received') }}</div>
</b-col>
<b-col cols="6">
<div v-if="type === 'send'"> {{ $n(balance, 'decimal') }}</div>
<div v-if="type === 'receive'">+ {{ $n(balance, 'decimal') }}</div>
</b-col>
</b-row>
<!-- Decay-->
<b-row v-if="decaytyp === 'new'">
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div> {{ $n(decay.balance, 'decimal') }}</div>
</b-col>
</b-row>
<!-- Total-->
<b-row v-if="decaytyp === 'new'">
<b-col cols="6" class="text-right">
<div>{{ $t('decay.total') }}</div>
</b-col>
<b-col cols="6">
<div v-if="type === 'send'">
<b> {{ $n(balance + decay.balance, 'decimal') }}</b>
</div>
<div v-if="type === 'receive'">
<b>{{ $n(balance - decay.balance, 'decimal') }}</b>
</div>
<div v-if="type === 'creation'">
<b> {{ $n(balance - decay.balance, 'decimal') }}</b>
</div>
</b-col>
</b-row>
</div>
</div>
</template>
<script>
export default {
name: 'DecayInformation',
props: {
gddbalance: { type: Number },
balance: { type: Number },
type: { type: String, default: '' },
decay: {
balance: '',
decayDuration: '',
decayStart: 0,
decayEnd: 0,
decayStartBlock: 0,
},
decaytyp: { type: String, default: '' },
},
computed: {
duration() {
return this.$moment.duration((this.decay.decayEnd - this.decay.decayStart) * 1000)._data
},
},
}
</script>

View File

@ -0,0 +1,12 @@
<template>
<div class="decayinformation-startblock">
<div class="mt-3 mb-3 text-center">
<b>{{ $t('decay.before_startblock_transaction') }}</b>
</div>
</div>
</template>
<script>
export default {
name: 'DecayInformation-StartBlock',
}
</script>

View File

@ -0,0 +1,36 @@
<template>
<div class="decayinformation-decay">
<div class="d-flex">
<div style="width: 100%" class="text-center pb-3">
<b-icon icon="droplet-half" height="12" class="mb-2" />
<b>{{ $t('decay.calculation_decay') }}</b>
</div>
</div>
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div>
{{ $n(Number(balance) - Number(decay.decay), 'decimal') }}
GDD {{ $n(Number(decay.decay) * -1, 'decimal') }} GDD =
<b>{{ $n(Number(balance), 'decimal') }} GDD</b>
</div>
</b-col>
</b-row>
</div>
</template>
<script>
export default {
name: 'DecayInformation-Decay',
props: {
balance: {
type: String,
},
decay: {
type: Object,
},
},
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<div class="decayinformation-startblock">
<b-row>
<b-col cols="12" class="text-center">
<div>
<div class="display-4">{{ $t('decay.Starting_block_decay') }}</div>
<div>{{ $t('decay.decay_introduced') }} :</div>
</div>
<div>
<span v-if="decay.start">
{{ $d(new Date(decay.start), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</span>
</div>
</b-col>
</b-row>
<!-- Decay-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div> {{ $n(decay.decay * -1, 'decimal') }}</div>
</b-col>
</b-row>
<hr class="mt-2 mb-2" />
<b-row>
<b-col class="text-center pt-3 pb-2">
<b>{{ $t('decay.calculation_total') }}</b>
</b-col>
</b-row>
<!-- Type-->
<b-row>
<b-col cols="6" class="text-right">
<div v-if="typeId === 'SEND'">{{ $t('decay.sent') }}</div>
<div v-if="typeId === 'RECEIVE'">{{ $t('decay.received') }}</div>
</b-col>
<b-col cols="6">
<div v-if="typeId === 'SEND'"> {{ $n(amount * -1, 'decimal') }}</div>
<div v-if="typeId === 'RECEIVE'">{{ $n(amount, 'decimal') }}</div>
</b-col>
</b-row>
<!-- Decay-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div> {{ $n(decay.decay * -1, 'decimal') }}</div>
</b-col>
</b-row>
<!-- Total-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.total') }}</div>
</b-col>
<b-col cols="6">
<div v-if="typeId === 'SEND'">
<b> {{ $n((Number(amount) + Number(decay.decay)) * -1, 'decimal') }}</b>
</div>
<div v-if="typeId === 'RECEIVE'">
<b>{{ $n(Number(amount) + Number(decay.decay), 'decimal') }}</b>
</div>
<div v-if="typeId === 'CREATION'">
<b>{{ $n(Number(amount) + Number(decay.decay), 'decimal') }}</b>
</div>
</b-col>
</b-row>
</div>
</template>
<script>
export default {
name: 'DecayInformation-StartBlock',
props: {
balanceDate: { type: String },
decayStartBlock: { type: Date },
amount: {
type: String,
},
decay: {
type: Object,
},
typeId: {
type: String,
},
},
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<div class="decayinformation-long">
<div class="d-flex">
<div style="width: 100%" class="text-center pb-3">
<b-icon icon="droplet-half" height="12" class="mb-2" />
<b>{{ $t('decay.calculation_decay') }}</b>
</div>
</div>
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.last_transaction') }}</div>
</b-col>
<b-col cols="6">
<div>
<span>
{{ $d(new Date(decay.start), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</span>
</div>
</b-col>
</b-row>
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.past_time') }}</div>
</b-col>
<b-col cols="6">
<span v-if="duration">
<span v-if="duration.years > 0">{{ duration.years }} {{ $t('decay.year') }},</span>
<span v-if="duration.months > 0">{{ duration.months }} {{ $t('decay.months') }},</span>
<span v-if="duration.days > 0">{{ duration.days }} {{ $t('decay.days') }},</span>
<span v-if="duration.hours > 0">{{ duration.hours }} {{ $t('decay.hours') }},</span>
<span v-if="duration.minutes > 0">{{ duration.minutes }} {{ $t('decay.minutes') }},</span>
<span v-if="duration.seconds > 0">{{ duration.seconds }} {{ $t('decay.seconds') }}</span>
</span>
</b-col>
</b-row>
<!-- Decay-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div> {{ $n(decay.decay * -1, 'decimal') }}</div>
</b-col>
</b-row>
<hr class="mt-2 mb-2" />
<b-row>
<b-col class="text-center pt-3 pb-2">
<b>{{ $t('decay.calculation_total') }}</b>
</b-col>
</b-row>
<!-- Type-->
<b-row>
<b-col cols="6" class="text-right">
<div v-if="typeId === 'SEND'">{{ $t('decay.sent') }}</div>
<div v-if="typeId === 'RECEIVE'">{{ $t('decay.received') }}</div>
</b-col>
<b-col cols="6">
<div v-if="typeId === 'SEND'"> {{ $n(amount * -1, 'decimal') }}</div>
<div v-if="typeId === 'RECEIVE'">{{ $n(amount, 'decimal') }}</div>
</b-col>
</b-row>
<!-- Decay-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.decay') }}</div>
</b-col>
<b-col cols="6">
<div> {{ $n(decay.decay * -1, 'decimal') }}</div>
</b-col>
</b-row>
<!-- Total-->
<b-row>
<b-col cols="6" class="text-right">
<div>{{ $t('decay.total') }}</div>
</b-col>
<b-col cols="6">
<div v-if="typeId === 'SEND'">
<b> {{ $n((Number(amount) + Number(decay.decay)) * -1, 'decimal') }}</b>
</div>
<div v-if="typeId === 'RECEIVE'">
<b>{{ $n(Number(amount) + Number(decay.decay), 'decimal') }}</b>
</div>
<div v-if="typeId === 'CREATION'">
<b>{{ $n(Number(amount) + Number(decay.decay), 'decimal') }}</b>
</div>
</b-col>
</b-row>
</div>
</template>
<script>
export default {
name: 'DecayInformation-Long',
props: {
amount: { type: String, default: '0' },
typeId: { type: String, default: '' },
decay: {
type: Object,
},
},
computed: {
duration() {
return this.$moment.duration(new Date(this.decay.end) - new Date(this.decay.start))._data
},
},
}
</script>

View File

@ -0,0 +1,15 @@
<template>
<div class="decayinformation-short">
<span> {{ decay ? $n(Number(decay.decay) * -1, 'decimal') : '' }}</span>
</div>
</template>
<script>
export default {
name: 'DecayInformation-Short',
props: {
decay: {
type: Object,
},
},
}
</script>

View File

@ -0,0 +1,16 @@
<template>
<div>
<slot :name="typeId"></slot>
</div>
</template>
<script>
export default {
name: 'TransactionList',
props: {
typeId: {
type: String,
required: true,
},
},
}
</script>

View File

@ -0,0 +1,52 @@
import { mount } from '@vue/test-utils'
import TransactionCreation from './TransactionCreation'
const localVue = global.localVue
const mocks = {
$i18n: {
locale: 'en',
},
$n: jest.fn((n) => n),
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
}
const propsData = {
amount: '12.45',
balance: '31.76099091058521',
balanceDate: '2022-02-28T13:55:47.000Z',
decay: {
decay: '-0.2038314055482643084',
start: '2022-02-25T07:29:26.000Z',
end: '2022-02-28T13:55:47.000Z',
duration: 282381,
__typename: 'CREATION',
},
id: 9,
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
memo: 'sadasd asdasdasdasdadadd da dad aad',
typeId: 'DECAY',
decayStartBlock: new Date('2021-05-13T17:46:31.000Z'),
}
describe('TransactionCreation', () => {
let wrapper
const Wrapper = () => {
return mount(TransactionCreation, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component transaction-slot-creation', () => {
expect(wrapper.find('div.transaction-slot-creation').exists()).toBeTruthy()
})
})
})

View File

@ -0,0 +1,147 @@
<template>
<div :class="visible ? 'bg-secondary' : ''" class="transaction-slot-creation">
<div @click="visible = !visible">
<!-- Collaps Icon -->
<div class="text-right" style="width: 95%; position: absolute">
<b-icon
:icon="visible ? 'caret-up-square' : 'caret-down-square'"
:class="visible ? 'text-black' : 'text-muted'"
/>
</div>
<div>
<b-row>
<!-- ICON -->
<b-col cols="1">
<div class="gdd-transaction-list-item-icon">
<b-icon icon="gift" class="gradido-global-color-accent m-mb-1 font2em" />
</div>
</b-col>
<b-col cols="11">
<!-- Betrag / Name Email -->
<b-row>
<b-col cols="5">
<div class="text-right">
<span class="gdd-transaction-list-item-operator">+</span>
<span class="gdd-transaction-list-item-amount">
{{ $n(amount, 'decimal') }}
</span>
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ $t('decay.decay_since_last_transaction') }}
</div>
</b-col>
</b-row>
<!-- Nachricht Memo -->
<b-row>
<b-col cols="5">
<div class="text-right">{{ $t('form.memo') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-message">{{ memo }}</div>
</b-col>
</b-row>
<!-- Datum -->
<b-row>
<b-col cols="5">
<div class="text-right">{{ $t('form.date') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-date">
{{ $d(new Date(balanceDate), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</div>
</b-col>
</b-row>
<!-- Decay -->
<b-row v-if="decay">
<b-col cols="5">
<div class="text-right">
<b-icon icon="droplet-half" height="15" class="mb-1" />
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-decay">
<decay-information-short decaytyp="short" :decay="decay" />
</div>
</b-col>
</b-row>
</b-col>
</b-row>
</div>
<b-collapse class="pb-4 pt-5" v-model="visible">
<decay-information-before-startblock v-if="decay.start === null" />
<decay-information-decay-startblock
v-else-if="isStartBlock"
:amount="amount"
:decay="decay"
:typeId="typeId"
/>
<decay-information-long v-else :amount="amount" :decay="decay" :typeId="typeId" />
</b-collapse>
</div>
</div>
</template>
<script>
import DecayInformationShort from '../DecayInformations/DecayInformation-Short'
import DecayInformationLong from '../DecayInformations/DecayInformation-Long'
import DecayInformationBeforeStartblock from '../DecayInformations/DecayInformation-BeforeStartblock'
import DecayInformationDecayStartblock from '../DecayInformations/DecayInformation-DecayStartblock'
export default {
name: 'slot-creation',
components: {
DecayInformationShort,
DecayInformationLong,
DecayInformationBeforeStartblock,
DecayInformationDecayStartblock,
},
props: {
amount: {
type: String,
},
balance: {
type: String,
},
balanceDate: {
type: String,
},
decay: {
type: Object,
},
id: {
type: Number,
},
linkedUser: {
type: Object,
},
memo: {
type: String,
},
typeId: {
type: String,
},
properties: {
type: Object,
},
decayStartBlock: { type: Date },
},
data() {
return {
visible: false,
}
},
computed: {
isStartBlock() {
return new Date(this.decay.start).getTime() === this.decayStartBlock.getTime()
},
},
}
</script>

View File

@ -0,0 +1,52 @@
import { mount } from '@vue/test-utils'
import TransactionDecay from './TransactionDecay'
const localVue = global.localVue
const mocks = {
$i18n: {
locale: 'en',
},
$n: jest.fn((n) => n),
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
}
const propsData = {
amount: '12.45',
balance: '31.76099091058521',
balanceDate: '2022-02-28T13:55:47.000Z',
decay: {
decay: '-0.2038314055482643084',
start: '2022-02-25T07:29:26.000Z',
end: '2022-02-28T13:55:47.000Z',
duration: 282381,
__typename: 'Decay',
},
id: 9,
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
memo: 'sadasd asdasdasdasdadadd da dad aad',
typeId: 'DECAY',
decayStartBlock: new Date('2021-05-13T17:46:31.000Z'),
}
describe('TransactionDecay', () => {
let wrapper
const Wrapper = () => {
return mount(TransactionDecay, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component transaction-slot-decay', () => {
expect(wrapper.find('div.transaction-slot-decay').exists()).toBeTruthy()
})
})
})

View File

@ -0,0 +1,82 @@
<template>
<div :class="visible ? 'bg-secondary' : ''" class="transaction-slot-decay">
<div @click="visible = !visible">
<!-- Collaps Icon -->
<div class="text-right" style="width: 95%; position: absolute">
<b-icon
:icon="visible ? 'caret-up-square' : 'caret-down-square'"
:class="visible ? 'text-black' : 'text-muted'"
/>
</div>
<div>
<b-row>
<!-- ICON -->
<b-col cols="1">
<div class="gdd-transaction-list-item-icon">
<b-icon icon="droplet-half" class="gradido-global-color-gray m-mb-1 font2em" />
</div>
</b-col>
<b-col cols="11">
<!-- Betrag / Name Email -->
<b-row>
<b-col cols="5">
<div class="text-right">
<span class="gdd-transaction-list-item-operator"></span>
<span class="gdd-transaction-list-item-amount">
{{ $n(Number(amount) * -1, 'decimal') }}
</span>
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ $t('decay.decay_since_last_transaction') }}
</div>
</b-col>
</b-row>
</b-col>
</b-row>
</div>
<b-collapse class="pb-4 pt-5" v-model="visible">
<decay-information-decay :balance="balance" :decay="decay" />
</b-collapse>
</div>
</div>
</template>
<script>
import DecayInformationDecay from '../DecayInformations/DecayInformation-Decay'
export default {
name: 'slot-decay',
components: {
DecayInformationDecay,
},
props: {
amount: {
type: String,
},
balance: {
type: String,
},
balanceDate: {
type: String,
},
decay: {
type: Object,
},
id: {
type: Number,
},
typeId: {
type: String,
},
},
data() {
return {
visible: false,
}
},
}
</script>

View File

@ -0,0 +1,52 @@
import { mount } from '@vue/test-utils'
import TransactionReceive from './TransactionReceive'
const localVue = global.localVue
const mocks = {
$i18n: {
locale: 'en',
},
$n: jest.fn((n) => n),
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
}
const propsData = {
amount: '12.45',
balance: '31.76099091058521',
balanceDate: '2022-02-28T13:55:47.000Z',
decay: {
decay: '-0.2038314055482643084',
start: '2022-02-25T07:29:26.000Z',
end: '2022-02-28T13:55:47.000Z',
duration: 282381,
__typename: 'Decay',
},
id: 9,
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
memo: 'sadasd asdasdasdasdadadd da dad aad',
typeId: 'RECEIVE',
decayStartBlock: new Date('2021-05-13T17:46:31.000Z'),
}
describe('TransactionReceive', () => {
let wrapper
const Wrapper = () => {
return mount(TransactionReceive, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component transaction-slot-receive', () => {
expect(wrapper.find('div.transaction-slot-receive').exists()).toBeTruthy()
})
})
})

View File

@ -0,0 +1,147 @@
<template>
<div :class="visible ? 'bg-secondary' : ''" class="transaction-slot-receive">
<div @click="visible = !visible">
<!-- Collaps Icon -->
<div class="text-right" style="width: 95%; position: absolute">
<b-icon
:icon="visible ? 'caret-up-square' : 'caret-down-square'"
:class="visible ? 'text-black' : 'text-muted'"
/>
</div>
<div>
<b-row>
<!-- ICON -->
<b-col cols="1">
<div class="gdd-transaction-list-item-icon">
<b-icon
icon="arrow-right-circle"
class="gradido-global-color-accent m-mb-1 font2em"
/>
</div>
</b-col>
<b-col cols="11">
<!-- Betrag / Name Email -->
<b-row>
<b-col cols="5">
<div class="text-right">
<span class="gdd-transaction-list-item-operator">+</span>
<span class="gdd-transaction-list-item-amount">
{{ $n(amount, 'decimal') }}
</span>
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ linkedUser.firstName + ' ' + linkedUser.lastName }}
</div>
</b-col>
</b-row>
<!-- Nachricht Memo -->
<b-row>
<b-col cols="5">
<div class="text-right">{{ $t('form.memo') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-message">{{ memo }}</div>
</b-col>
</b-row>
<!-- Datum -->
<b-row>
<b-col cols="5">
<div class="text-right">{{ $t('form.date') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-date">
{{ $d(new Date(balanceDate), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</div>
</b-col>
</b-row>
<!-- Decay -->
<b-row v-if="decay">
<b-col cols="5">
<div class="text-right">
<b-icon icon="droplet-half" height="15" class="mb-1" />
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-decay">
<decay-information-short decaytyp="short" :decay="decay" />
</div>
</b-col>
</b-row>
</b-col>
</b-row>
</div>
<b-collapse class="pb-4 pt-5" v-model="visible">
<decay-information-before-startblock v-if="decay.start === null" />
<decay-information-decay-startblock
v-else-if="isStartBlock"
:amount="amount"
:decay="decay"
:typeId="typeId"
/>
<decay-information-long v-else :amount="amount" :decay="decay" :typeId="typeId" />
</b-collapse>
</div>
</div>
</template>
<script>
import DecayInformationShort from '../DecayInformations/DecayInformation-Short'
import DecayInformationLong from '../DecayInformations/DecayInformation-Long'
import DecayInformationBeforeStartblock from '../DecayInformations/DecayInformation-BeforeStartblock'
import DecayInformationDecayStartblock from '../DecayInformations/DecayInformation-DecayStartblock'
export default {
name: 'slot-receive',
components: {
DecayInformationShort,
DecayInformationLong,
DecayInformationBeforeStartblock,
DecayInformationDecayStartblock,
},
props: {
amount: {
type: String,
},
balance: {
type: String,
},
balanceDate: {
type: String,
},
decay: {
type: Object,
},
id: {
type: Number,
},
linkedUser: {
type: Object,
},
memo: {
type: String,
},
typeId: {
type: String,
},
decayStartBlock: { type: Date },
},
data() {
return {
visible: false,
}
},
computed: {
isStartBlock() {
return new Date(this.decay.start).getTime() === this.decayStartBlock.getTime()
},
},
}
</script>

View File

@ -0,0 +1,52 @@
import { mount } from '@vue/test-utils'
import TransactionSend from './TransactionSend'
const localVue = global.localVue
const mocks = {
$i18n: {
locale: 'en',
},
$n: jest.fn((n) => n),
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
}
const propsData = {
amount: '12.45',
balance: '31.76099091058521',
balanceDate: '2022-02-28T13:55:47.000Z',
decay: {
decay: '-0.2038314055482643084',
start: '2022-02-25T07:29:26.000Z',
end: '2022-02-28T13:55:47.000Z',
duration: 282381,
__typename: 'Decay',
},
id: 9,
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
memo: 'sadasd asdasdasdasdadadd da dad aad',
typeId: 'SEND',
decayStartBlock: new Date('2021-05-13T17:46:31.000Z'),
}
describe('TransactionSend', () => {
let wrapper
const Wrapper = () => {
return mount(TransactionSend, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component transaction-slot-send', () => {
expect(wrapper.find('div.transaction-slot-send').exists()).toBeTruthy()
})
})
})

View File

@ -0,0 +1,143 @@
<template>
<div :class="visible ? 'bg-secondary' : ''" class="transaction-slot-send">
<div @click="visible = !visible">
<!-- Collaps Icon -->
<div class="text-right" style="width: 95%; position: absolute">
<b-icon
:icon="visible ? 'caret-up-square' : 'caret-down-square'"
:class="visible ? 'text-black' : 'text-muted'"
/>
</div>
<div>
<b-row>
<!-- ICON -->
<b-col cols="1">
<div class="gdd-transaction-list-item-icon">
<b-icon icon="arrow-left-circle" class="text-danger m-mb-1 font2em" />
</div>
</b-col>
<b-col cols="11">
<!-- Betrag / Name Email -->
<b-row>
<b-col cols="5">
<div class="text-right">
<span class="gdd-transaction-list-item-operator"></span>
<span class="gdd-transaction-list-item-amount">
{{ $n(Number(amount) * -1, 'decimal') }}
</span>
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ linkedUser.firstName + ' ' + linkedUser.lastName }}
</div>
</b-col>
</b-row>
<!-- Nachricht Memo -->
<b-row>
<b-col cols="5">
<div class="text-right">{{ $t('form.memo') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-message">{{ memo }}</div>
</b-col>
</b-row>
<!-- Datum -->
<b-row>
<b-col cols="5">
<div class="text-right">{{ $t('form.date') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-date">
{{ $d(new Date(balanceDate), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</div>
</b-col>
</b-row>
<!-- Decay -->
<b-row v-if="decay">
<b-col cols="5">
<div class="text-right">
<b-icon icon="droplet-half" height="15" class="mb-1" />
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-decay">
<decay-information-short decaytyp="short" :decay="decay" />
</div>
</b-col>
</b-row>
</b-col>
</b-row>
</div>
<b-collapse class="pb-4 pt-5" v-model="visible">
<decay-information-before-startblock v-if="decay.start === null" />
<decay-information-decay-startblock
v-else-if="true"
:amount="amount"
:decay="decay"
:typeId="typeId"
/>
<decay-information-long v-else :amount="amount" :decay="decay" :typeId="typeId" />
</b-collapse>
</div>
</div>
</template>
<script>
import DecayInformationShort from '../DecayInformations/DecayInformation-Short'
import DecayInformationLong from '../DecayInformations/DecayInformation-Long'
import DecayInformationBeforeStartblock from '../DecayInformations/DecayInformation-BeforeStartblock'
import DecayInformationDecayStartblock from '../DecayInformations/DecayInformation-DecayStartblock'
export default {
name: 'slot-send',
components: {
DecayInformationShort,
DecayInformationLong,
DecayInformationBeforeStartblock,
DecayInformationDecayStartblock,
},
props: {
amount: {
type: String,
},
balance: {
type: String,
},
balanceDate: {
type: String,
},
decay: {
type: Object,
},
id: {
type: Number,
},
linkedUser: {
type: Object,
},
memo: {
type: String,
},
typeId: {
type: String,
},
decayStartBlock: { type: Date },
},
data() {
return {
visible: false,
}
},
computed: {
isStartBlock() {
return new Date(this.decay.start).getTime() === this.decayStartBlock.getTime()
},
},
}
</script>

View File

@ -63,6 +63,7 @@ export const transactionsQuery = gql`
id
typeId
amount
balance
balanceDate
memo
linkedUser {

View File

@ -21,7 +21,7 @@
"switch-to-this-community": "zu dieser Gemeinschaft wechseln"
},
"decay": {
"befor_startblock_transaction": "Diese Transaktion beinhaltet keine Vergänglichkeit.",
"before_startblock_transaction": "Diese Transaktion beinhaltet keine Vergänglichkeit.",
"calculation_decay": "Berechnung der Vergänglichkeit",
"calculation_total": "Berechnung der Gesamtsumme",
"created": "Geschöpft",

View File

@ -21,7 +21,7 @@
"switch-to-this-community": "Switch to this community"
},
"decay": {
"befor_startblock_transaction": "This transaction does not include decay.",
"before_startblock_transaction": "This transaction does not include decay.",
"calculation_decay": "Calculation of Decay",
"calculation_total": "Calculation of the total Amount",
"created": "Created",

View File

@ -153,7 +153,7 @@ describe('DashboardLayoutGdd', () => {
apolloMock.mockResolvedValue({
data: {
transactionList: {
gdtSum: 100,
balanceGDT: 100,
count: 4,
balance: 1450,
decay: 1250,
@ -179,7 +179,7 @@ describe('DashboardLayoutGdd', () => {
})
it('updates balance', () => {
expect(wrapper.vm.balance).toBe(1250)
expect(wrapper.vm.balance).toBe(1450)
})
it('updates transactions', () => {

View File

@ -25,6 +25,7 @@
:transactions="transactions"
:transactionCount="transactionCount"
:pending="pending"
:decayStartBlock="decayStartBlock"
@update-balance="updateBalance"
@update-transactions="updateTransactions"
></router-view>
@ -60,6 +61,7 @@ export default {
transactionCount: 0,
pending: true,
visible: false,
decayStartBlock: new Date(),
}
},
methods: {
@ -92,11 +94,12 @@ export default {
const {
data: { transactionList },
} = result
this.GdtBalance = transactionList.gdtSum === null ? null : Number(transactionList.gdtSum)
this.GdtBalance =
transactionList.balanceGDT === null ? null : Number(transactionList.balanceGDT)
this.transactions = transactionList.transactions
this.balance = Number(transactionList.decay)
this.bookedBalance = Number(transactionList.balance)
this.balance = Number(transactionList.balance)
this.transactionCount = transactionList.count
this.decayStartBlock = new Date(transactionList.decayStartBlock)
this.pending = false
})
.catch((error) => {

View File

@ -15,10 +15,10 @@
</b-col>
</b-row>
<gdd-transaction-list
:gddbalance="balance"
:transactions="transactions"
:pageSize="5"
:timestamp="timestamp"
:decayStartBlock="decayStartBlock"
:transaction-count="transactionCount"
@update-transactions="updateTransactions"
/>
@ -46,6 +46,7 @@ export default {
props: {
balance: { type: Number, default: 0 },
GdtBalance: { type: Number, default: 0 },
decayStartBlock: { type: Date },
transactions: {
default: () => [],
},

View File

@ -52,7 +52,7 @@ describe('GddTransactionList', () => {
beforeEach(async () => {
await wrapper.setProps({
transactions: [],
transactionCount: 0,
count: 0,
})
})
it('Transactions Array is empty, 0 transactions', () => {
@ -64,7 +64,7 @@ describe('GddTransactionList', () => {
beforeEach(async () => {
await wrapper.setProps({
transactions: [],
transactionCount: -1,
count: -1,
})
})
it('renders text saying that there are error.empty-transactionlist ', () => {
@ -91,250 +91,98 @@ describe('GddTransactionList', () => {
await wrapper.setProps({
transactions: [
{
balance: 19.93,
date: '2021-05-25T17:38:13+00:00',
memo: 'Alles Gute zum Geburtstag',
name: 'Bob der Baumeister',
transaction_id: 29,
type: 'send',
decay: { balance: '0.5' },
id: -1,
typeId: 'DECAY',
amount: '-0.16778637075575395772595',
balance: '31.59320453982945549519405',
balanceDate: '2022-03-03T08:54:54.020Z',
memo: '',
linkedUser: null,
decay: {
decay: '-0.16778637075575395772595',
start: '2022-02-28T13:55:47.000Z',
end: '2022-03-03T08:54:54.020Z',
duration: 241147.02,
__typename: 'Decay',
},
__typename: 'Transaction',
},
{
balance: 1000,
date: '2021-04-29T15:34:49+00:00',
memo: 'Gut das du da bist!',
name: 'Gradido Akademie',
transaction_id: 3,
type: 'creation',
id: 9,
typeId: 'SEND',
amount: '1',
balance: '31.76099091058520945292',
balanceDate: '2022-02-28T13:55:47.000Z',
memo: 'adasd adada',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
decay: {
decay: '-0.2038314055482643084',
start: '2022-02-25T07:29:26.000Z',
end: '2022-02-28T13:55:47.000Z',
duration: 282381,
__typename: 'Decay',
},
__typename: 'Transaction',
},
{
balance: 314.98,
date: '2021-04-29T17:26:40+00:00',
memo: 'Für das Fahrrad!',
name: 'Jan Ulrich',
transaction_id: 8,
type: 'receive',
decay: { balance: '1.5' },
id: 8,
typeId: 'CREATION',
amount: '1000',
balance: '32.96482231613347376132',
balanceDate: '2022-02-25T07:29:26.000Z',
memo: 'asd adada dad',
linkedUser: {
firstName: 'Gradido',
lastName: 'Akademie',
__typename: 'User',
},
decay: {
decay: '-0.03517768386652623868',
start: '2022-02-23T10:55:30.000Z',
end: '2022-02-25T07:29:26.000Z',
duration: 160436,
__typename: 'Decay',
},
__typename: 'Transaction',
},
{
balance: 1.07,
type: 'decay',
id: 6,
typeId: 'RECEIVE',
amount: '10',
balance: '10',
balanceDate: '2022-02-23T10:55:30.000Z',
memo: 'asd adaaad adad addad ',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
decay: {
decay: '0',
start: null,
end: null,
duration: null,
__typename: 'Decay',
},
__typename: 'Transaction',
},
],
transactionCount: 12,
count: 12,
})
})
it('renders 4 transactions', () => {
expect(wrapper.findAll('div.gdd-transaction-list-item')).toHaveLength(4)
})
describe('send transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.gdd-transaction-list-item').at(0)
})
it('has a bi-caret-down-square icon', () => {
expect(transaction.findAll('svg').at(0).classes()).toEqual([
'bi-caret-down-square',
'b-icon',
'bi',
'text-muted',
])
})
// it('transaction is clicked', async () => {
// await transaction.trigger('click')
// expect(transaction.findAll('svg').at(0).classes()).toEqual([
// 'bi-caret-up-square',
// 'b-icon',
// 'bi',
// 'text-muted',
// ])
// })
it('has a bi-arrow-left-circle icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('bi-arrow-left-circle')
})
it('has text-danger color', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('text-danger')
})
it('has a minus operator', () => {
expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
'',
)
})
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'19.93',
)
})
it('shows the name of the receiver', () => {
expect(transaction.findAll('.gdd-transaction-list-item-name').at(0).text()).toContain(
'Bob der Baumeister',
)
})
it('shows the message of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-message').at(0).text()).toContain(
'Alles Gute zum Geburtstag',
)
})
it('shows the date of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-date').at(0).text()).toContain(
'Tue May 25 2021',
)
})
it('shows the decay calculation', () => {
expect(transaction.findAll('div.gdd-transaction-list-item-decay').at(0).text()).toContain(
' 0.5',
)
})
})
describe('creation transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.gdd-transaction-list-item').at(1)
})
it('has a bi-caret-down-square icon', () => {
expect(transaction.findAll('svg').at(0).classes()).toEqual([
'bi-caret-down-square',
'b-icon',
'bi',
'text-muted',
])
})
// it('transaction is clicked', async () => {
// await transaction.trigger('click')
// expect(transaction.findAll('svg').at(0).classes()).toEqual([
// 'bi-caret-up-square',
// 'b-icon',
// 'bi',
// 'text-muted',
// ])
// })
it('has a bi-gift icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('bi-gift')
})
it('has gradido-global-color-accent color', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain(
'gradido-global-color-accent',
)
})
it('has a plus operator', () => {
expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
'+',
)
})
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'1000',
)
})
it('shows the name of the receiver', () => {
expect(transaction.findAll('.gdd-transaction-list-item-name').at(0).text()).toContain(
'Gradido Akademie',
)
})
it('shows the date of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-date').at(0).text()).toContain(
'Thu Apr 29 2021',
)
})
})
describe('receive transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.gdd-transaction-list-item').at(2)
})
it('has a bi-caret-down-square icon', () => {
expect(transaction.findAll('svg').at(0).classes()).toEqual([
'bi-caret-down-square',
'b-icon',
'bi',
'text-muted',
])
})
// it('transaction is clicked', async () => {
// await transaction.trigger('click')
// expect(transaction.findAll('svg').at(0).classes()).toEqual([
// 'bi-caret-up-square',
// 'b-icon',
// 'bi',
// 'text-muted',
// ])
// })
it('has a bi-arrow-right-circle icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('bi-arrow-right-circle')
})
it('has gradido-global-color-accent color', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain(
'gradido-global-color-accent',
)
})
it('has a plus operator', () => {
expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
'+',
)
})
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'314.98',
)
})
it('shows the name of the recipient', () => {
expect(transaction.findAll('.gdd-transaction-list-item-name').at(0).text()).toContain(
'Jan Ulrich',
)
})
it('shows the message of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-message').at(0).text()).toContain(
'Für das Fahrrad!',
)
})
it('shows the date of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-date').at(0).text()).toContain(
'Thu Apr 29 2021',
)
})
it('shows the decay calculation', () => {
expect(transaction.findAll('.gdd-transaction-list-item-decay').at(0).text()).toContain(
' 1.5',
)
})
expect(wrapper.findAll('div.list-group-item')).toHaveLength(3)
})
describe('decay transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.gdd-transaction-list-item').at(3)
transaction = wrapper.findAll('div.list-group-item').at(0)
})
it('has a bi-caret-down-square icon', () => {
@ -346,16 +194,6 @@ describe('GddTransactionList', () => {
])
})
// it('transaction is clicked', async () => {
// await transaction.trigger('click')
// expect(transaction.findAll('svg').at(0).classes()).toEqual([
// 'bi-caret-up-square',
// 'b-icon',
// 'bi',
// 'text-muted',
// ])
// })
it('has a bi-droplet-half icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('bi-droplet-half')
})
@ -364,15 +202,9 @@ describe('GddTransactionList', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('gradido-global-color-gray')
})
it('has a minus operator', () => {
expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
'',
)
})
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'1.07',
'0.16778637075575395',
)
})
@ -382,38 +214,206 @@ describe('GddTransactionList', () => {
)
})
})
})
describe('with invalid transaction type', () => {
beforeEach(async () => {
await wrapper.setProps({
transactions: [
{
balance: '19.93',
date: '2021-05-25T17:38:13+00:00',
memo: 'Alles Gute zum Geburtstag',
name: 'Bob der Baumeister',
transaction_id: 29,
type: 'invalid',
},
],
describe('send transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.list-group-item').at(1)
})
it('has a bi-caret-down-square icon', () => {
expect(transaction.findAll('svg').at(0).classes()).toEqual([
'bi-caret-down-square',
'b-icon',
'bi',
'text-muted',
])
})
it('has a bi-arrow-left-circle icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('bi-arrow-left-circle')
})
it('has text-danger color', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('text-danger')
})
// it('has a minus operator', () => {
// expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
// '-',
// )
// })
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'1',
)
})
it('shows the name of the receiver', () => {
expect(transaction.findAll('.gdd-transaction-list-item-name').at(0).text()).toContain(
'Bibi Bloxberg',
)
})
it('shows the message of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-message').at(0).text()).toContain(
'adasd adada',
)
})
it('shows the date of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-date').at(0).text()).toContain(
'Mon Feb 28 2022 13:55:47 GMT+0000 (Coordinated Universal Time)',
)
})
it('shows the decay calculation', () => {
expect(transaction.findAll('div.gdd-transaction-list-item-decay').at(0).text()).toContain(
' 0.20383140554826432',
)
})
})
it('throws an error', () => {
expect(errorHandler).toHaveBeenCalled()
describe('creation transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.list-group-item').at(2)
})
it('has a bi-caret-down-square icon', () => {
expect(transaction.findAll('svg').at(0).classes()).toEqual([
'bi-caret-down-square',
'b-icon',
'bi',
'text-muted',
])
})
it('has a bi-gift icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toEqual([
'bi-arrow-right-circle',
'gradido-global-color-accent',
'm-mb-1',
'font2em',
'b-icon',
'bi',
])
})
it('has gradido-global-color-accent color', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain(
'gradido-global-color-accent',
)
})
it('has a plus operator', () => {
expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
'+',
)
})
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'10',
)
})
it('shows the name of the receiver', () => {
expect(transaction.findAll('.gdd-transaction-list-item-name').at(0).text()).toContain(
'Bibi Bloxberg',
)
})
it('shows the date of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-date').at(0).text()).toContain(
'Wed Feb 23 2022 10:55:30 GMT+0000 (Coordinated Universal Time)',
)
})
})
describe('receive transactions', () => {
let transaction
beforeEach(() => {
transaction = wrapper.findAll('div.list-group-item').at(2)
})
it('has a bi-caret-down-square icon', () => {
expect(transaction.findAll('svg').at(0).classes()).toEqual([
'bi-caret-down-square',
'b-icon',
'bi',
'text-muted',
])
})
it('has a bi-arrow-right-circle icon', () => {
expect(transaction.findAll('svg').at(1).classes()).toContain('bi-arrow-right-circle')
})
it('has gradido-global-color-accent color', () => {
expect(transaction.findAll('svg').at(1).classes()).toEqual([
'bi-arrow-right-circle',
'gradido-global-color-accent',
'm-mb-1',
'font2em',
'b-icon',
'bi',
])
})
it('has a plus operator', () => {
expect(transaction.findAll('.gdd-transaction-list-item-operator').at(0).text()).toContain(
'+',
)
})
it('shows the amount of transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-amount').at(0).text()).toContain(
'10',
)
})
it('shows the name of the recipient', () => {
expect(transaction.findAll('.gdd-transaction-list-item-name').at(0).text()).toContain(
'Bibi Bloxberg',
)
})
it('shows the message of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-message').at(0).text()).toContain(
'asd adaaad adad addad',
)
})
it('shows the date of the transaction', () => {
expect(transaction.findAll('.gdd-transaction-list-item-date').at(0).text()).toContain(
'Wed Feb 23 2022 10:55:30 GMT+0000 (Coordinated Universal Time)',
)
})
it('shows the decay calculation', () => {
expect(transaction.findAll('.gdd-transaction-list-item-decay').at(0).text()).toContain(
'0',
)
})
})
})
describe('pagination buttons', () => {
const transactions = Array.from({ length: 42 }, (_, idx) => {
return {
balance: '3.14',
date: '2021-04-29T17:26:40+00:00',
amount: '3.14',
balanceDate: '2021-04-29T17:26:40+00:00',
memo: 'Kreiszahl PI',
name: 'Euklid',
transaction_id: idx + 1,
type: 'receive',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
id: idx + 1,
typeId: 'RECEIVE',
}
})

View File

@ -11,198 +11,76 @@
<b-icon icon="exclamation-triangle" class="mr-2" variant="danger"></b-icon>
<small>{{ $t('error.empty-transactionlist') }}</small>
</div>
<div
v-for="{
decay,
transactionId,
type,
date,
balance,
name,
memo,
firstTransaction,
decayDuration,
decayEnd,
decayStart,
} in transactions"
:key="transactionId"
:style="type === 'decay' ? 'background-color:#f1e0ae3d' : ''"
>
<div
class="list-group-item gdd-transaction-list-item"
:class="getCollapseState(transactionId) ? 'bg-secondary' : ''"
v-b-toggle="'decay-' + transactionId"
>
<!-- Collaps Button -->
<div class="text-right" style="width: 95%; position: absolute">
<b-icon
:icon="getCollapseState(transactionId) ? 'caret-up-square' : 'caret-down-square'"
:class="getCollapseState(transactionId) ? 'text-black' : 'text-muted'"
<div v-for="({ id, typeId }, index) in transactions" :key="id">
<transaction-list-item :typeId="typeId">
<template #DECAY>
<transaction-decay class="list-group-item" v-bind="transactions[index]" />
</template>
<template #SEND>
<transaction-send
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
/>
</div>
<div>
<b-row>
<!-- ICON -->
<b-col cols="1">
<div class="gdd-transaction-list-item-icon">
<b-icon :icon="getProperties(type).icon" :class="getProperties(type).class" />
</div>
</b-col>
</template>
<b-col cols="11">
<!-- Betrag / Name Email -->
<b-row>
<b-col cols="5">
<div class="text-right">
<span class="gdd-transaction-list-item-operator">
{{ getProperties(type).operator }}
</span>
<span class="gdd-transaction-list-item-amount">
{{ $n(balance, 'decimal') }}
</span>
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ type !== 'decay' ? name : $t('decay.decay_since_last_transaction') }}
</div>
</b-col>
</b-row>
<template #RECEIVE>
<transaction-receive
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
/>
</template>
<!-- Nachricht -->
<b-row v-if="type !== 'decay'">
<b-col cols="5">
<div class="text-right">{{ $t('form.memo') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-message">{{ memo }}</div>
</b-col>
</b-row>
<!-- Datum -->
<b-row v-if="type !== 'decay'">
<b-col cols="5">
<div class="text-right">{{ $t('form.date') }}</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-date">
{{ $d(new Date(date), 'long') }} {{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</div>
</b-col>
</b-row>
<!-- Decay -->
<b-row v-if="decay && !decay.decayStartBlock">
<b-col cols="5">
<div class="text-right">
<b-icon v-if="type != 'decay'" icon="droplet-half" height="15" class="mb-1" />
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-decay">
<decay-information v-if="decay" decaytyp="short" :decay="decay" />
</div>
</b-col>
</b-row>
<b-row v-if="decay && decay.decayStartBlock">
<b-col cols="5">
<div class="text-right">
<b-icon v-if="type != 'decay'" icon="droplet-half" height="15" class="mb-1" />
</div>
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-decay">
<b>{{ $t('decay.Starting_block_decay') }}</b>
</div>
</b-col>
</b-row>
</b-col>
</b-row>
</div>
<!-- Collaps Start -->
<!-- v-if="
(type != 'decay' && decay) ||
firstTransaction ||
(!firstTransaction && decay === null)
" -->
<b-collapse class="pb-4" :id="'decay-' + transactionId">
<div class="pt-4 pb-4 bg-white border border-muted">
<decay-information
v-if="decay"
decaytyp="new"
:balance="balance"
:decay="decay"
:type="type"
/>
<div v-if="firstTransaction" class="mt-3 mb-3 text-center">
<b>{{ $t('decay.first_transaction') }}</b>
</div>
<div
v-if="type !== 'decay' && !firstTransaction && decay === null"
class="mt-3 mb-3 text-center"
>
<b>{{ $t('decay.befor_startblock_transaction') }}</b>
</div>
<div v-if="type === 'decay'" class="mt-3 mb-3">
<decay-information
decaytyp="decayLastTransaction"
:gddbalance="gddbalance"
:balance="balance"
:decay="{
balance: balance,
decayStart: parseInt(decayStart),
decayEnd: parseInt(decayEnd),
decayDuration: parseInt(decayDuration),
}"
:type="type"
/>
</div>
</div>
</b-collapse>
<!-- Collaps End -->
</div>
</div>
<pagination-buttons
v-if="showPagination"
v-model="currentPage"
:per-page="pageSize"
:total-rows="transactionCount"
></pagination-buttons>
<div v-if="transactionCount < 0" class="mt-4 text-center">
<span>{{ $t('transaction.nullTransactions') }}</span>
<template #CREATION>
<transaction-creation
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
/>
</template>
</transaction-list-item>
</div>
</div>
<pagination-buttons
v-if="showPagination"
v-model="currentPage"
:per-page="pageSize"
:total-rows="transactionCount"
></pagination-buttons>
<div v-if="transactionCount <= 0" class="mt-4 text-center">
<span>{{ $t('transaction.nullTransactions') }}</span>
</div>
</div>
</template>
<script>
import TransactionListItem from '../../../components/TransactionListItem'
import PaginationButtons from '../../../components/PaginationButtons'
import DecayInformation from '../../../components/DecayInformation'
const iconsByType = {
send: { icon: 'arrow-left-circle', classes: 'text-danger', operator: '' },
receive: { icon: 'arrow-right-circle', classes: 'gradido-global-color-accent', operator: '+' },
creation: { icon: 'gift', classes: 'gradido-global-color-accent', operator: '+' },
decay: { icon: 'droplet-half', classes: 'gradido-global-color-gray', operator: '' },
}
import TransactionDecay from '../../../components/Transactions/TransactionDecay'
import TransactionSend from '../../../components/Transactions/TransactionSend'
import TransactionReceive from '../../../components/Transactions/TransactionReceive'
import TransactionCreation from '../../../components/Transactions/TransactionCreation'
export default {
name: 'gdd-transaction-list',
components: {
TransactionListItem,
PaginationButtons,
DecayInformation,
TransactionDecay,
TransactionSend,
TransactionReceive,
TransactionCreation,
},
data() {
return {
currentPage: 1,
collapseStatus: [],
}
},
props: {
gddbalance: { type: Number },
decayStartBlock: { type: Date },
transactions: { default: () => [] },
pageSize: { type: Number, default: 25 },
timestamp: { type: Number, default: 0 },
@ -217,31 +95,6 @@ export default {
})
window.scrollTo(0, 0)
},
getProperties(givenType) {
const type = iconsByType[givenType]
if (type)
return {
icon: type.icon,
class: type.classes + ' m-mb-1 font2em',
operator: type.operator,
}
this.throwError('no icon to given type')
},
throwError(msg) {
throw new Error(msg)
},
getCollapseState(transactionId) {
return this.collapseStatus.includes('decay-' + transactionId)
},
},
mounted() {
this.$root.$on('bv::collapse::state', (collapseId, isJustShown) => {
if (isJustShown) {
this.collapseStatus.push(collapseId)
} else {
this.collapseStatus = this.collapseStatus.filter((id) => id !== collapseId)
}
})
},
watch: {
currentPage() {
@ -259,8 +112,4 @@ export default {
padding-left: 0px;
padding-right: 0px;
}
.gdd-transaction-list-item {
outline: none !important;
}
</style>

View File

@ -5,11 +5,11 @@
<p class="tab-tex">{{ $t('transaction.gdd-text') }}</p>
<gdd-transaction-list
:gddbalance="balance"
:timestamp="timestamp"
:transactionCount="transactionCount"
:transactions="transactions"
:show-pagination="true"
:decayStartBlock="decayStartBlock"
@update-transactions="updateTransactions"
/>
</b-tab>
@ -42,6 +42,7 @@ export default {
default: () => [],
},
transactionCount: { type: Number, default: 0 },
decayStartBlock: { type: Date },
},
data() {
return {