Merge pull request #1153 from gradido/adminConfirmPendingCreation

Admin confirm pending creation
This commit is contained in:
Hannes Heine 2021-12-07 07:59:30 +01:00 committed by GitHub
commit 098cb64379
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 427 additions and 137 deletions

View File

@ -441,7 +441,7 @@ jobs:
report_name: Coverage Admin Interface report_name: Coverage Admin Interface
type: lcov type: lcov
result_path: ./coverage/lcov.info result_path: ./coverage/lcov.info
min_coverage: 55 min_coverage: 60
token: ${{ github.token }} token: ${{ github.token }}
############################################################################## ##############################################################################
@ -657,4 +657,4 @@ jobs:
- name: database | up - name: database | up
run: docker-compose -f docker-compose.yml run -T database yarn up run: docker-compose -f docker-compose.yml run -T database yarn up
- name: database | reset - name: database | reset
run: docker-compose -f docker-compose.yml run -T database yarn reset run: docker-compose -f docker-compose.yml run -T database yarn reset

View File

@ -11,7 +11,14 @@ const apolloMock = jest.fn().mockResolvedValue({
}, },
}, },
}) })
const apolloMutateMock = jest.fn().mockResolvedValue({
data: {
createPendingCreation: [0, 0, 0],
},
})
const stateCommitMock = jest.fn() const stateCommitMock = jest.fn()
const toastedErrorMock = jest.fn()
const toastedSuccessMock = jest.fn()
const mocks = { const mocks = {
$moment: jest.fn(() => { $moment: jest.fn(() => {
@ -26,15 +33,25 @@ const mocks = {
}), }),
$apollo: { $apollo: {
query: apolloMock, query: apolloMock,
mutate: apolloMutateMock,
}, },
$store: { $store: {
commit: stateCommitMock, commit: stateCommitMock,
state: {
moderator: {
id: 0,
name: 'test moderator',
},
},
},
$toasted: {
error: toastedErrorMock,
success: toastedSuccessMock,
}, },
} }
const propsData = { const propsData = {
type: '', type: '',
item: {},
creation: [], creation: [],
itemsMassCreation: {}, itemsMassCreation: {},
} }
@ -64,9 +81,10 @@ describe('CreationFormular', () => {
describe('server throws error for moderator data call', () => { describe('server throws error for moderator data call', () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks() jest.clearAllMocks()
apolloMock.mockRejectedValue({ message: 'Ouch!' }) apolloMock.mockRejectedValueOnce({ message: 'Ouch!' })
wrapper = Wrapper() wrapper = Wrapper()
}) })
it('has called store commit with fake data', () => { it('has called store commit with fake data', () => {
expect(stateCommitMock).toBeCalledWith('moderator', { id: 0, name: 'Test Moderator' }) expect(stateCommitMock).toBeCalledWith('moderator', { id: 0, name: 'Test Moderator' })
}) })
@ -125,6 +143,8 @@ describe('CreationFormular', () => {
jest.clearAllMocks() jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 }) await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 90 })
}) })
describe('first radio button', () => { describe('first radio button', () => {
@ -139,6 +159,66 @@ describe('CreationFormular', () => {
it('sets rangeMax to 200', () => { it('sets rangeMax to 200', () => {
expect(wrapper.vm.rangeMax).toBe(200) expect(wrapper.vm.rangeMax).toBe(200)
}) })
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalled()
})
})
describe('sendForm', () => {
beforeEach(async () => {
apolloMutateMock.mockRejectedValueOnce({ message: 'Ouch!' })
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(toastedErrorMock).toBeCalled()
})
})
describe('Negativ value', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ value: -20 })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
describe('Empty text', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: '' })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
describe('Text length less than 10', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Try this' })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
}) })
describe('second radio button', () => { describe('second radio button', () => {
@ -153,6 +233,55 @@ describe('CreationFormular', () => {
it('sets rangeMax to 400', () => { it('sets rangeMax to 400', () => {
expect(wrapper.vm.rangeMax).toBe(400) expect(wrapper.vm.rangeMax).toBe(400)
}) })
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalled()
})
})
describe('Negativ value', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ value: -20 })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
describe('Empty text', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: '' })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
describe('Text length less than 10', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Try this' })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
}) })
describe('third radio button', () => { describe('third radio button', () => {
@ -167,6 +296,63 @@ describe('CreationFormular', () => {
it('sets rangeMax to 400', () => { it('sets rangeMax to 400', () => {
expect(wrapper.vm.rangeMax).toBe(600) expect(wrapper.vm.rangeMax).toBe(600)
}) })
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends mutation to apollo', () => {
expect(apolloMutateMock).toBeCalled()
})
it('toast success message', () => {
expect(toastedSuccessMock).toBeCalled()
})
it('store commit openCreationPlus', () => {
expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 1)
})
})
describe('Negativ value', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ value: -20 })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
describe('Empty text', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: '' })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
describe('Text length less than 10', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Try this' })
})
it('has no submit button', async () => {
expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled')
})
})
}) })
}) })
}) })

View File

@ -6,6 +6,7 @@
<label>Monat Auswählen</label> <label>Monat Auswählen</label>
<b-col class="text-left"> <b-col class="text-left">
<b-form-radio <b-form-radio
id="beforeLastMonth"
v-model="radioSelected" v-model="radioSelected"
:value="beforeLastMonth" :value="beforeLastMonth"
:disabled="creation[0] === 0" :disabled="creation[0] === 0"
@ -19,6 +20,7 @@
</b-col> </b-col>
<b-col> <b-col>
<b-form-radio <b-form-radio
id="lastMonth"
v-model="radioSelected" v-model="radioSelected"
:value="lastMonth" :value="lastMonth"
:disabled="creation[1] === 0" :disabled="creation[1] === 0"
@ -32,6 +34,7 @@
</b-col> </b-col>
<b-col class="text-right"> <b-col class="text-right">
<b-form-radio <b-form-radio
id="currentMonth"
v-model="radioSelected" v-model="radioSelected"
:value="currentMonth" :value="currentMonth"
:disabled="creation[2] === 0" :disabled="creation[2] === 0"
@ -45,7 +48,7 @@
</b-col> </b-col>
</b-row> </b-row>
<b-row class="m-4" v-show="createdIndex"> <b-row class="m-4" v-show="createdIndex != null">
<label>Betrag Auswählen</label> <label>Betrag Auswählen</label>
<div> <div>
<b-input-group prepend="GDD" append=".00"> <b-input-group prepend="GDD" append=".00">
@ -92,6 +95,7 @@
v-if="pagetype === 'PageCreationConfirm'" v-if="pagetype === 'PageCreationConfirm'"
type="button" type="button"
variant="success" variant="success"
class="test-submit"
@click="submitCreation" @click="submitCreation"
:disabled="radioSelected === '' || value <= 0 || text.length < 10" :disabled="radioSelected === '' || value <= 0 || text.length < 10"
> >
@ -102,6 +106,7 @@
v-else v-else
type="button" type="button"
variant="success" variant="success"
class="test-submit"
@click="submitCreation" @click="submitCreation"
:disabled="radioSelected === '' || value <= 0 || text.length < 10" :disabled="radioSelected === '' || value <= 0 || text.length < 10"
> >
@ -159,7 +164,7 @@ export default {
return { return {
radioSelected: '', radioSelected: '',
text: !this.creationUserData.memo ? '' : this.creationUserData.memo, text: !this.creationUserData.memo ? '' : this.creationUserData.memo,
value: !this.creationUserData.amount ? 0 : this.creationUserData.amount / 10000, value: !this.creationUserData.amount ? 0 : this.creationUserData.amount,
rangeMin: 0, rangeMin: 0,
rangeMax: 1000, rangeMax: 1000,
currentMonth: { currentMonth: {
@ -195,28 +200,12 @@ export default {
} }
}, },
submitCreation() { submitCreation() {
// Formular Prüfen ob ein Zeitraum ausgewählt wurde. Ansonsten abbrechen und Hinweis anzeigen
if (this.radioSelected === '') {
return alert('Bitte wähle einen Zeitraum!')
}
// Formular Prüfen ob der GDD Betrag grösser 0 ist. Ansonsten abbrechen und Hinweis anzeigen
if (this.value === 0) {
return alert('Bitte gib einen GDD Betrag an!')
}
// Formular Prüfen ob der Text vorhanden ist. Ansonsten abbrechen und Hinweis anzeigen
if (this.text === '') {
return alert('Bitte gib einen Text ein!')
}
// Formular Prüfen ob der Text länger als 10 Zeichen hat. Ansonsten abbrechen und Hinweis anzeigen
if (this.text.length < 10) {
return alert('Bitte gib einen Text ein der länger als 10 Zeichen ist!')
}
if (this.type === 'massCreation') { if (this.type === 'massCreation') {
// Die anzahl der Mitglieder aus der Mehrfachschöpfung // Die anzahl der Mitglieder aus der Mehrfachschöpfung
const i = Object.keys(this.itemsMassCreation).length const i = Object.keys(this.itemsMassCreation).length
// hinweis das eine Mehrfachschöpfung ausgeführt wird an (Anzahl der MItgleider an die geschöpft wird) // hinweis das eine Mehrfachschöpfung ausgeführt wird an (Anzahl der MItgleider an die geschöpft wird)
alert('SUBMIT CREATION => ' + this.type + ' >> für VIELE ' + i + ' Mitglieder') // eslint-disable-next-line no-console
console.log('SUBMIT CREATION => ' + this.type + ' >> für VIELE ' + i + ' Mitglieder')
this.submitObj = [ this.submitObj = [
{ {
item: this.itemsMassCreation, item: this.itemsMassCreation,
@ -227,7 +216,8 @@ export default {
moderator: this.$store.state.moderator.id, moderator: this.$store.state.moderator.id,
}, },
] ]
alert('MehrfachSCHÖPFUNG ABSENDEN FÜR >> ' + i + ' Mitglieder') // eslint-disable-next-line no-console
console.log('MehrfachSCHÖPFUNG ABSENDEN FÜR >> ' + i + ' Mitglieder')
// $store - offene Schöpfungen hochzählen // $store - offene Schöpfungen hochzählen
this.$store.commit('openCreationsPlus', i) this.$store.commit('openCreationsPlus', i)

View File

@ -15,6 +15,7 @@ const apolloMutateMock = jest.fn().mockResolvedValue({
}) })
const stateCommitMock = jest.fn() const stateCommitMock = jest.fn()
const toastedErrorMock = jest.fn()
const mocks = { const mocks = {
$moment: jest.fn(() => { $moment: jest.fn(() => {
@ -31,14 +32,21 @@ const mocks = {
mutate: apolloMutateMock, mutate: apolloMutateMock,
}, },
$store: { $store: {
state: {
moderator: {
id: 0,
name: 'test moderator',
},
},
commit: stateCommitMock, commit: stateCommitMock,
}, },
$toasted: {
error: toastedErrorMock,
},
} }
const propsData = { const propsData = {
type: '', type: '',
item: {},
row: [],
creation: [], creation: [],
itemsMassCreation: {}, itemsMassCreation: {},
} }
@ -69,6 +77,8 @@ describe('EditCreationFormular', () => {
jest.clearAllMocks() jest.clearAllMocks()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 }) await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 90 })
}) })
describe('first radio button', () => { describe('first radio button', () => {
@ -83,6 +93,27 @@ describe('EditCreationFormular', () => {
it('sets rangeMax to 200', () => { it('sets rangeMax to 200', () => {
expect(wrapper.vm.rangeMax).toBe(200) expect(wrapper.vm.rangeMax).toBe(200)
}) })
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
amount: 90,
creationDate: 'YYYY-MM-01',
email: undefined,
id: undefined,
memo: 'Test create coins',
moderator: 0,
},
}),
)
})
})
}) })
describe('second radio button', () => { describe('second radio button', () => {
@ -97,6 +128,27 @@ describe('EditCreationFormular', () => {
it('sets rangeMax to 400', () => { it('sets rangeMax to 400', () => {
expect(wrapper.vm.rangeMax).toBe(400) expect(wrapper.vm.rangeMax).toBe(400)
}) })
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
amount: 90,
creationDate: 'YYYY-MM-01',
email: undefined,
id: undefined,
memo: 'Test create coins',
moderator: 0,
},
}),
)
})
})
}) })
describe('third radio button', () => { describe('third radio button', () => {
@ -111,6 +163,27 @@ describe('EditCreationFormular', () => {
it('sets rangeMax to 400', () => { it('sets rangeMax to 400', () => {
expect(wrapper.vm.rangeMax).toBe(600) expect(wrapper.vm.rangeMax).toBe(600)
}) })
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
amount: 90,
creationDate: 'YYYY-MM-DD',
email: undefined,
id: undefined,
memo: 'Test create coins',
moderator: 0,
},
}),
)
})
})
}) })
}) })
}) })

View File

@ -6,6 +6,7 @@
<label>Monat Auswählen</label> <label>Monat Auswählen</label>
<b-col class="text-left"> <b-col class="text-left">
<b-form-radio <b-form-radio
id="beforeLastMonth"
v-model="radioSelected" v-model="radioSelected"
:value="beforeLastMonth" :value="beforeLastMonth"
:disabled="selectedOpenCreationAmount[0] === 0" :disabled="selectedOpenCreationAmount[0] === 0"
@ -24,6 +25,7 @@
</b-col> </b-col>
<b-col> <b-col>
<b-form-radio <b-form-radio
id="lastMonth"
v-model="radioSelected" v-model="radioSelected"
:value="lastMonth" :value="lastMonth"
:disabled="selectedOpenCreationAmount[1] === 0" :disabled="selectedOpenCreationAmount[1] === 0"
@ -42,6 +44,7 @@
</b-col> </b-col>
<b-col class="text-right"> <b-col class="text-right">
<b-form-radio <b-form-radio
id="currentMonth"
v-model="radioSelected" v-model="radioSelected"
:value="currentMonth" :value="currentMonth"
:disabled="selectedOpenCreationAmount[2] === 0" :disabled="selectedOpenCreationAmount[2] === 0"
@ -106,6 +109,7 @@
<b-button <b-button
type="button" type="button"
variant="success" variant="success"
class="test-submit"
@click="submitCreation" @click="submitCreation"
:disabled="radioSelected === '' || value <= 0 || text.length < 10" :disabled="radioSelected === '' || value <= 0 || text.length < 10"
> >
@ -147,10 +151,10 @@ export default {
}, },
}, },
row: { row: {
type: Array, type: Object,
required: Object, required: false,
default() { default() {
return [] return {}
}, },
}, },
creationUserData: { creationUserData: {
@ -165,34 +169,11 @@ export default {
required: true, required: true,
}, },
}, },
created() {
if (this.pagetype === 'PageCreationConfirm' && this.creationUserData.date) {
switch (this.$moment(this.creationUserData.date).format('MMMM')) {
case this.currentMonth.short:
this.createdIndex = 2
this.radioSelected = this.currentMonth
break
case this.lastMonth.short:
this.createdIndex = 1
this.radioSelected = this.lastMonth
break
case this.beforeLastMonth.short:
this.createdIndex = 0
this.radioSelected = this.beforeLastMonth
break
default:
throw new Error('Something went wrong')
}
this.selectedOpenCreationAmount[this.createdIndex] =
this.creation[this.createdIndex] + this.creationUserData.amount / 10000
this.rangeMax = this.selectedOpenCreationAmount[this.createdIndex]
}
},
data() { data() {
return { return {
radioSelected: '', radioSelected: '',
text: !this.creationUserData.memo ? '' : this.creationUserData.memo, text: !this.creationUserData.memo ? '' : this.creationUserData.memo,
value: !this.creationUserData.amount ? 0 : this.creationUserData.amount / 10000, value: !this.creationUserData.amount ? 0 : this.creationUserData.amount,
rangeMin: 0, rangeMin: 0,
rangeMax: 1000, rangeMax: 1000,
currentMonth: { currentMonth: {
@ -221,22 +202,6 @@ export default {
this.rangeMax = this.creation[index] this.rangeMax = this.creation[index]
}, },
submitCreation() { submitCreation() {
// Formular Prüfen ob ein Zeitraum ausgewählt wurde. Ansonsten abbrechen und Hinweis anzeigen
if (this.radioSelected === '') {
return alert('Bitte wähle einen Zeitraum!')
}
// Formular Prüfen ob der GDD Betrag grösser 0 ist. Ansonsten abbrechen und Hinweis anzeigen
if (this.value <= 0) {
return alert('Bitte gib einen GDD Betrag an!')
}
// Formular Prüfen ob der Text vorhanden ist. Ansonsten abbrechen und Hinweis anzeigen
if (this.text === '') {
return alert('Bitte gib einen Text ein!')
}
// Formular Prüfen ob der Text länger als 10 Zeichen hat. Ansonsten abbrechen und Hinweis anzeigen
if (this.text.length < 10) {
return alert('Bitte gib einen Text ein der länger als 10 Zeichen ist!')
}
this.submitObj = { this.submitObj = {
id: this.item.id, id: this.item.id,
email: this.item.email, email: this.item.email,
@ -281,5 +246,28 @@ export default {
}) })
}, },
}, },
created() {
if (this.pagetype === 'PageCreationConfirm' && this.creationUserData.date) {
switch (this.$moment(this.creationUserData.date).format('MMMM')) {
case this.currentMonth.short:
this.createdIndex = 2
this.radioSelected = this.currentMonth
break
case this.lastMonth.short:
this.createdIndex = 1
this.radioSelected = this.lastMonth
break
case this.beforeLastMonth.short:
this.createdIndex = 0
this.radioSelected = this.beforeLastMonth
break
default:
throw new Error('Something went wrong')
}
this.selectedOpenCreationAmount[this.createdIndex] =
this.creation[this.createdIndex] + this.creationUserData.amount
this.rangeMax = this.selectedOpenCreationAmount[this.createdIndex]
}
},
} }
</script> </script>

View File

@ -132,6 +132,7 @@
<script> <script>
import CreationFormular from '../components/CreationFormular.vue' import CreationFormular from '../components/CreationFormular.vue'
import EditCreationFormular from '../components/EditCreationFormular.vue' import EditCreationFormular from '../components/EditCreationFormular.vue'
import { confirmPendingCreation } from '../graphql/confirmPendingCreation'
export default { export default {
name: 'UserTable', name: 'UserTable',
@ -228,9 +229,19 @@ export default {
} }
}, },
bookmarkConfirm(item) { bookmarkConfirm(item) {
alert('die schöpfung bestätigen und abschließen') this.$apollo
alert(JSON.stringify(item)) .mutate({
this.$emit('remove-confirm-result', item, 'remove') mutation: confirmPendingCreation,
variables: {
id: item.id,
},
})
.then(() => {
this.$emit('remove-confirm-result', item, 'remove')
})
.catch((error) => {
this.$toasted.error(error.message)
})
}, },
editCreationUserTable(row, rowItem) { editCreationUserTable(row, rowItem) {
if (!row.detailsShowing) { if (!row.detailsShowing) {
@ -241,14 +252,6 @@ export default {
row.toggleDetails() row.toggleDetails()
}, },
updateCreationData(data) { updateCreationData(data) {
// console.log('updateCreationData this.creationUserData11=> ', this.creationUserData)
// console.log('updateCreationData data=> ', data)
// this.creationUserData = {
// ...this.creationUserData,
// ...data,
// }
// console.log('updateCreationData this.creationUserData22=> ', this.creationUserData)
this.creationUserData.amount = data.amount this.creationUserData.amount = data.amount
this.creationUserData.date = data.date this.creationUserData.date = data.date
this.creationUserData.memo = data.memo this.creationUserData.memo = data.memo

View File

@ -0,0 +1,7 @@
import gql from 'graphql-tag'
export const confirmPendingCreation = gql`
mutation ($id: Float!) {
confirmPendingCreation(id: $id)
}
`

View File

@ -1,7 +0,0 @@
import gql from 'graphql-tag'
export const countPendingCreations = gql`
query {
countPendingCreations
}
`

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div class="admin-overview">
<b-card <b-card
v-show="$store.state.openCreations > 0" v-show="$store.state.openCreations > 0"
border-variant="primary" border-variant="primary"

View File

@ -24,7 +24,7 @@ export class PendingCreation {
memo: string memo: string
@Field(() => Number) @Field(() => Number)
amount: BigInt amount: number
@Field(() => Number) @Field(() => Number)
moderator: number moderator: number

View File

@ -4,13 +4,18 @@ import { UserAdmin } from '../model/UserAdmin'
import { PendingCreation } from '../model/PendingCreation' import { PendingCreation } from '../model/PendingCreation'
import { UpdatePendingCreation } from '../model/UpdatePendingCreation' import { UpdatePendingCreation } from '../model/UpdatePendingCreation'
import { RIGHTS } from '../../auth/RIGHTS' import { RIGHTS } from '../../auth/RIGHTS'
import { TransactionRepository } from '../../typeorm/repository/Transaction'
import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation' import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation'
import { PendingCreationRepository } from '../../typeorm/repository/PendingCreation' import { PendingCreationRepository } from '../../typeorm/repository/PendingCreation'
import { UserRepository } from '../../typeorm/repository/User' import { UserRepository } from '../../typeorm/repository/User'
import CreatePendingCreationArgs from '../arg/CreatePendingCreationArgs' import CreatePendingCreationArgs from '../arg/CreatePendingCreationArgs'
import UpdatePendingCreationArgs from '../arg/UpdatePendingCreationArgs' import UpdatePendingCreationArgs from '../arg/UpdatePendingCreationArgs'
import moment from 'moment' import moment from 'moment'
import { LoginPendingTasksAdmin } from '@entity/LoginPendingTasksAdmin' import { Transaction } from '@entity/Transaction'
import { TransactionCreation } from '@entity/TransactionCreation'
import { UserTransaction } from '@entity/UserTransaction'
import { UserTransactionRepository } from '../../typeorm/repository/UserTransaction'
import { BalanceRepository } from '../../typeorm/repository/Balance'
@Resolver() @Resolver()
export class AdminResolver { export class AdminResolver {
@ -113,8 +118,11 @@ export class AdminResolver {
const userRepository = getCustomRepository(UserRepository) const userRepository = getCustomRepository(UserRepository)
const user = await userRepository.findOneOrFail({ id: pendingCreation.userId }) const user = await userRepository.findOneOrFail({ id: pendingCreation.userId })
const parsedAmount = Number(parseInt(pendingCreation.amount.toString()) / 10000)
// pendingCreation.amount = parsedAmount
const newPendingCreation = { const newPendingCreation = {
...pendingCreation, ...pendingCreation,
amount: parsedAmount,
firstName: user.firstName, firstName: user.firstName,
lastName: user.lastName, lastName: user.lastName,
email: user.email, email: user.email,
@ -134,6 +142,66 @@ export class AdminResolver {
const res = await pendingCreationRepository.delete(entity) const res = await pendingCreationRepository.delete(entity)
return !!res return !!res
} }
@Mutation(() => Boolean)
async confirmPendingCreation(@Arg('id') id: number): Promise<boolean> {
const pendingCreationRepository = getCustomRepository(PendingCreationRepository)
const pendingCreation = await pendingCreationRepository.findOneOrFail(id)
const transactionRepository = getCustomRepository(TransactionRepository)
let transaction = new Transaction()
transaction.transactionTypeId = 1
transaction.memo = pendingCreation.memo
transaction.received = new Date()
transaction.blockchainTypeId = 1
transaction = await transactionRepository.save(transaction)
if (!transaction) throw new Error('Could not create transaction')
const transactionCreationRepository = getCustomRepository(TransactionCreationRepository)
let transactionCreation = new TransactionCreation()
transactionCreation.transactionId = transaction.id
transactionCreation.userId = pendingCreation.userId
transactionCreation.amount = parseInt(pendingCreation.amount.toString())
transactionCreation.targetDate = pendingCreation.date
transactionCreation = await transactionCreationRepository.save(transactionCreation)
if (!transactionCreation) throw new Error('Could not create transactionCreation')
const userTransactionRepository = getCustomRepository(UserTransactionRepository)
const lastUserTransaction = await userTransactionRepository.findLastForUser(
pendingCreation.userId,
)
let newBalance = 0
if (!lastUserTransaction) {
newBalance = 0
} else {
newBalance = lastUserTransaction.balance
}
newBalance = Number(newBalance) + Number(parseInt(pendingCreation.amount.toString()) / 10000)
const newUserTransaction = new UserTransaction()
newUserTransaction.userId = pendingCreation.userId
newUserTransaction.transactionId = transaction.id
newUserTransaction.transactionTypeId = transaction.transactionTypeId
newUserTransaction.balance = Number(newBalance)
newUserTransaction.balanceDate = transaction.received
await userTransactionRepository.save(newUserTransaction).catch((error) => {
throw new Error('Error saving user transaction: ' + error)
})
const balanceRepository = getCustomRepository(BalanceRepository)
let userBalance = await balanceRepository.findByUser(pendingCreation.userId)
if (!userBalance) userBalance = balanceRepository.create()
userBalance.userId = pendingCreation.userId
userBalance.amount = Number(newBalance * 10000)
userBalance.modified = new Date()
userBalance.recordDate = userBalance.recordDate ? userBalance.recordDate : new Date()
await balanceRepository.save(userBalance)
await pendingCreationRepository.delete(pendingCreation)
return true
}
} }
async function getUserCreations(id: number): Promise<number[]> { async function getUserCreations(id: number): Promise<number[]> {

View File

@ -428,7 +428,7 @@ async function addUserTransaction(
if (lastUserTransaction) { if (lastUserTransaction) {
newBalance += Number( newBalance += Number(
await calculateDecay( await calculateDecay(
Number(lastUserTransaction.balance), Number(lastUserTransaction.balance * 10000),
lastUserTransaction.balanceDate, lastUserTransaction.balanceDate,
transaction.received, transaction.received,
).catch(() => { ).catch(() => {

View File

@ -1,12 +1,4 @@
import { import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm'
BaseEntity,
Entity,
PrimaryGeneratedColumn,
Column,
Timestamp,
OneToOne,
JoinColumn,
} from 'typeorm'
import { Transaction } from './Transaction' import { Transaction } from './Transaction'
@Entity('transaction_creations') @Entity('transaction_creations')
@ -24,7 +16,7 @@ export class TransactionCreation extends BaseEntity {
amount: number amount: number
@Column({ name: 'target_date', type: 'timestamp' }) @Column({ name: 'target_date', type: 'timestamp' })
targetDate: Timestamp targetDate: Date
@OneToOne(() => Transaction) @OneToOne(() => Transaction)
@JoinColumn({ name: 'transaction_id' }) @JoinColumn({ name: 'transaction_id' })

View File

@ -14,7 +14,7 @@
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(` await queryFn(`
CREATE TABLE \`user_setting\` ( CREATE TABLE IF NOT EXISTS \`user_setting\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`userId\` int(11) NOT NULL, \`userId\` int(11) NOT NULL,
\`key\` varchar(255) NOT NULL, \`key\` varchar(255) NOT NULL,
@ -25,5 +25,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
// write downgrade logic as parameter of queryFn // write downgrade logic as parameter of queryFn
await queryFn(`DROP TABLE \`user_setting\`;`) await queryFn(`DROP TABLE IF EXISTS \`user_setting\`;`)
} }

View File

@ -14,7 +14,7 @@
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(` await queryFn(`
CREATE TABLE \`login_app_access_tokens\` ( CREATE TABLE IF NOT EXISTS \`login_app_access_tokens\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int NOT NULL, \`user_id\` int NOT NULL,
\`access_code\` bigint unsigned NOT NULL, \`access_code\` bigint unsigned NOT NULL,
@ -25,7 +25,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_elopage_buys\` ( CREATE TABLE IF NOT EXISTS \`login_elopage_buys\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`elopage_user_id\` int DEFAULT NULL, \`elopage_user_id\` int DEFAULT NULL,
\`affiliate_program_id\` int NOT NULL, \`affiliate_program_id\` int NOT NULL,
@ -42,7 +42,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_email_opt_in_types\` ( CREATE TABLE IF NOT EXISTS \`login_email_opt_in_types\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(255) NOT NULL, \`name\` varchar(255) NOT NULL,
\`description\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL,
@ -50,7 +50,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_email_opt_in\` ( CREATE TABLE IF NOT EXISTS \`login_email_opt_in\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int NOT NULL, \`user_id\` int NOT NULL,
\`verification_code\` bigint unsigned NOT NULL, \`verification_code\` bigint unsigned NOT NULL,
@ -63,7 +63,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_groups\` ( CREATE TABLE IF NOT EXISTS \`login_groups\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`alias\` varchar(190) NOT NULL, \`alias\` varchar(190) NOT NULL,
\`name\` varchar(255) NOT NULL, \`name\` varchar(255) NOT NULL,
@ -76,7 +76,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_pending_tasks\` ( CREATE TABLE IF NOT EXISTS \`login_pending_tasks\` (
\`id\` int UNSIGNED NOT NULL AUTO_INCREMENT, \`id\` int UNSIGNED NOT NULL AUTO_INCREMENT,
\`user_id\` int UNSIGNED DEFAULT 0, \`user_id\` int UNSIGNED DEFAULT 0,
\`request\` varbinary(2048) NOT NULL, \`request\` varbinary(2048) NOT NULL,
@ -91,7 +91,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_roles\` ( CREATE TABLE IF NOT EXISTS \`login_roles\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(255) NOT NULL, \`name\` varchar(255) NOT NULL,
\`description\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL,
@ -100,7 +100,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_user_backups\` ( CREATE TABLE IF NOT EXISTS \`login_user_backups\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int NOT NULL, \`user_id\` int NOT NULL,
\`passphrase\` text NOT NULL, \`passphrase\` text NOT NULL,
@ -109,7 +109,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_user_roles\` ( CREATE TABLE IF NOT EXISTS \`login_user_roles\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int NOT NULL, \`user_id\` int NOT NULL,
\`role_id\` int NOT NULL, \`role_id\` int NOT NULL,
@ -117,7 +117,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`) `)
await queryFn(` await queryFn(`
CREATE TABLE \`login_users\` ( CREATE TABLE IF NOT EXISTS \`login_users\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT, \`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`email\` varchar(191) NOT NULL, \`email\` varchar(191) NOT NULL,
\`first_name\` varchar(150) NOT NULL, \`first_name\` varchar(150) NOT NULL,
@ -143,14 +143,14 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
// write downgrade logic as parameter of queryFn // write downgrade logic as parameter of queryFn
await queryFn(`DROP TABLE \`login_app_access_tokens\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_app_access_tokens\`;`)
await queryFn(`DROP TABLE \`login_elopage_buys\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_elopage_buys\`;`)
await queryFn(`DROP TABLE \`login_email_opt_in_types\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_email_opt_in_types\`;`)
await queryFn(`DROP TABLE \`login_email_opt_in\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_email_opt_in\`;`)
await queryFn(`DROP TABLE \`login_groups\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_groups\`;`)
await queryFn(`DROP TABLE \`login_pending_tasks\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_pending_tasks\`;`)
await queryFn(`DROP TABLE \`login_roles\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_roles\`;`)
await queryFn(`DROP TABLE \`login_user_backups\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_user_backups\`;`)
await queryFn(`DROP TABLE \`login_user_roles\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_user_roles\`;`)
await queryFn(`DROP TABLE \`login_users\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_users\`;`)
} }

View File

@ -63,15 +63,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
} }
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
// write downgrade logic as parameter of queryFn // TODO NO EMPTY FUNCTION
await queryFn(`DELETE FROM \`login_app_access_tokens\`;`)
await queryFn(`DELETE FROM \`login_elopage_buys\`;`)
await queryFn(`DELETE FROM \`login_email_opt_in_types\`;`)
await queryFn(`DELETE FROM \`login_email_opt_in\`;`)
await queryFn(`DELETE FROM \`login_groups\`;`)
await queryFn(`DELETE FROM \`login_pending_tasks\`;`)
await queryFn(`DELETE FROM \`login_roles\`;`)
await queryFn(`DELETE FROM \`login_user_backups\`;`)
await queryFn(`DELETE FROM \`login_user_roles\`;`)
await queryFn(`DELETE FROM \`login_users\`;`)
} }

View File

@ -11,7 +11,7 @@
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(` await queryFn(`
CREATE TABLE \`login_pending_tasks_admin\` ( CREATE TABLE IF NOT EXISTS \`login_pending_tasks_admin\` (
\`id\` int UNSIGNED NOT NULL AUTO_INCREMENT, \`id\` int UNSIGNED NOT NULL AUTO_INCREMENT,
\`userId\` int UNSIGNED DEFAULT 0, \`userId\` int UNSIGNED DEFAULT 0,
\`created\` datetime NOT NULL, \`created\` datetime NOT NULL,
@ -25,5 +25,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
} }
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) { export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`DROP TABLE \`login_pending_tasks_admin\`;`) await queryFn(`DROP TABLE IF EXISTS \`login_pending_tasks_admin\`;`)
} }