mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into insert-missing-contributions-migration
This commit is contained in:
commit
bd957c38f9
@ -28,7 +28,7 @@ const propsData = {
|
|||||||
amount: 210,
|
amount: 210,
|
||||||
memo: 'Aktives Grundeinkommen für Januar 2022',
|
memo: 'Aktives Grundeinkommen für Januar 2022',
|
||||||
date: '2022-01-01T00:00:00.000Z',
|
date: '2022-01-01T00:00:00.000Z',
|
||||||
moderator: 1,
|
moderator: null,
|
||||||
creation: [790, 1000, 1000],
|
creation: [790, 1000, 1000],
|
||||||
__typename: 'PendingCreation',
|
__typename: 'PendingCreation',
|
||||||
},
|
},
|
||||||
@ -66,7 +66,7 @@ const propsData = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ key: 'moderator', label: 'moderator' },
|
{ key: 'moderator', label: 'moderator' },
|
||||||
{ key: 'edit_creation', label: 'edit' },
|
{ key: 'editCreation', label: 'edit' },
|
||||||
{ key: 'confirm', label: 'save' },
|
{ key: 'confirm', label: 'save' },
|
||||||
],
|
],
|
||||||
toggleDetails: false,
|
toggleDetails: false,
|
||||||
@ -113,6 +113,10 @@ describe('OpenCreationsTable', () => {
|
|||||||
expect(wrapper.findAll('tr').at(1).find('.bi-pencil-square').exists()).toBe(true)
|
expect(wrapper.findAll('tr').at(1).find('.bi-pencil-square').exists()).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('has no button.bi-pencil-square for user contribution ', () => {
|
||||||
|
expect(wrapper.findAll('tr').at(2).find('.bi-pencil-square').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
describe('show edit details', () => {
|
describe('show edit details', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await wrapper.findAll('tr').at(1).find('.bi-pencil-square').trigger('click')
|
await wrapper.findAll('tr').at(1).find('.bi-pencil-square').trigger('click')
|
||||||
|
|||||||
@ -11,8 +11,14 @@
|
|||||||
<b-icon icon="x" variant="light"></b-icon>
|
<b-icon icon="x" variant="light"></b-icon>
|
||||||
</b-button>
|
</b-button>
|
||||||
</template>
|
</template>
|
||||||
<template #cell(edit_creation)="row">
|
<template #cell(editCreation)="row">
|
||||||
<b-button variant="info" size="md" @click="rowToggleDetails(row, 0)" class="mr-2">
|
<b-button
|
||||||
|
v-if="row.item.moderator"
|
||||||
|
variant="info"
|
||||||
|
size="md"
|
||||||
|
@click="rowToggleDetails(row, 0)"
|
||||||
|
class="mr-2"
|
||||||
|
>
|
||||||
<b-icon :icon="row.detailsShowing ? 'x' : 'pencil-square'" aria-label="Help"></b-icon>
|
<b-icon :icon="row.detailsShowing ? 'x' : 'pencil-square'" aria-label="Help"></b-icon>
|
||||||
</b-button>
|
</b-button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
"creation_form": {
|
"creation_form": {
|
||||||
"creation_failed": "Ausstehende Schöpfung für {email} konnte nicht erzeugt werden.",
|
"creation_failed": "Ausstehende Schöpfung für {email} konnte nicht erzeugt werden.",
|
||||||
"creation_for": "Aktives Grundeinkommen für",
|
"creation_for": "Aktives Grundeinkommen für",
|
||||||
|
"deleteNow": "Möchtest du diesen Beitrag zur Gemeinschaft wirklich löschen?",
|
||||||
"enter_text": "Text eintragen",
|
"enter_text": "Text eintragen",
|
||||||
"form": "Schöpfungsformular",
|
"form": "Schöpfungsformular",
|
||||||
"min_characters": "Mindestens 10 Zeichen eingeben",
|
"min_characters": "Mindestens 10 Zeichen eingeben",
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
"creation_form": {
|
"creation_form": {
|
||||||
"creation_failed": "Could not create pending creation for {email}",
|
"creation_failed": "Could not create pending creation for {email}",
|
||||||
"creation_for": "Active Basic Income for",
|
"creation_for": "Active Basic Income for",
|
||||||
|
"deleteNow": "Do you really want to delete this contribution to the community?",
|
||||||
"enter_text": "Enter text",
|
"enter_text": "Enter text",
|
||||||
"form": "Creation form",
|
"form": "Creation form",
|
||||||
"min_characters": "Enter at least 10 characters",
|
"min_characters": "Enter at least 10 characters",
|
||||||
|
|||||||
@ -18,7 +18,7 @@ const apolloQueryMock = jest.fn().mockResolvedValue({
|
|||||||
amount: 500,
|
amount: 500,
|
||||||
memo: 'Danke für alles',
|
memo: 'Danke für alles',
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
moderator: 0,
|
moderator: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
@ -28,7 +28,7 @@ const apolloQueryMock = jest.fn().mockResolvedValue({
|
|||||||
amount: 1000000,
|
amount: 1000000,
|
||||||
memo: 'Gut Ergattert',
|
memo: 'Gut Ergattert',
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
moderator: 0,
|
moderator: 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -80,28 +80,54 @@ describe('CreationConfirm', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('remove creation with success', () => {
|
describe('remove creation with success', () => {
|
||||||
beforeEach(async () => {
|
let spy
|
||||||
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('calls the adminDeleteContribution mutation', () => {
|
describe('admin confirms deletion', () => {
|
||||||
expect(apolloMutateMock).toBeCalledWith({
|
beforeEach(async () => {
|
||||||
mutation: adminDeleteContribution,
|
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
|
||||||
variables: { id: 1 },
|
spy.mockImplementation(() => Promise.resolve('some value'))
|
||||||
|
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('opens a modal', () => {
|
||||||
|
expect(spy).toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls the adminDeleteContribution mutation', () => {
|
||||||
|
expect(apolloMutateMock).toBeCalledWith({
|
||||||
|
mutation: adminDeleteContribution,
|
||||||
|
variables: { id: 1 },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits openCreationsMinus to store', () => {
|
||||||
|
expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts a success message', () => {
|
||||||
|
expect(toastSuccessSpy).toBeCalledWith('creation_form.toasted_delete')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('commits openCreationsMinus to store', () => {
|
describe('admin cancels deletion', () => {
|
||||||
expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1)
|
beforeEach(async () => {
|
||||||
})
|
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
|
||||||
|
spy.mockImplementation(() => Promise.resolve(false))
|
||||||
|
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
it('toasts a success message', () => {
|
it('does not call the adminDeleteContribution mutation', () => {
|
||||||
expect(toastSuccessSpy).toBeCalledWith('creation_form.toasted_delete')
|
expect(apolloMutateMock).not.toBeCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('remove creation with error', () => {
|
describe('remove creation with error', () => {
|
||||||
|
let spy
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
|
||||||
|
spy.mockImplementation(() => Promise.resolve('some value'))
|
||||||
apolloMutateMock.mockRejectedValue({ message: 'Ouchhh!' })
|
apolloMutateMock.mockRejectedValue({ message: 'Ouchhh!' })
|
||||||
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
|
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
|
||||||
})
|
})
|
||||||
|
|||||||
@ -34,20 +34,23 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
removeCreation(item) {
|
removeCreation(item) {
|
||||||
this.$apollo
|
this.$bvModal.msgBoxConfirm(this.$t('creation_form.deleteNow')).then(async (value) => {
|
||||||
.mutate({
|
if (value)
|
||||||
mutation: adminDeleteContribution,
|
await this.$apollo
|
||||||
variables: {
|
.mutate({
|
||||||
id: item.id,
|
mutation: adminDeleteContribution,
|
||||||
},
|
variables: {
|
||||||
})
|
id: item.id,
|
||||||
.then((result) => {
|
},
|
||||||
this.updatePendingCreations(item.id)
|
})
|
||||||
this.toastSuccess(this.$t('creation_form.toasted_delete'))
|
.then((result) => {
|
||||||
})
|
this.updatePendingCreations(item.id)
|
||||||
.catch((error) => {
|
this.toastSuccess(this.$t('creation_form.toasted_delete'))
|
||||||
this.toastError(error.message)
|
})
|
||||||
})
|
.catch((error) => {
|
||||||
|
this.toastError(error.message)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
confirmCreation() {
|
confirmCreation() {
|
||||||
this.$apollo
|
this.$apollo
|
||||||
@ -114,7 +117,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ key: 'moderator', label: this.$t('moderator') },
|
{ key: 'moderator', label: this.$t('moderator') },
|
||||||
{ key: 'edit_creation', label: this.$t('edit') },
|
{ key: 'editCreation', label: this.$t('edit') },
|
||||||
{ key: 'confirm', label: this.$t('save') },
|
{ key: 'confirm', label: this.$t('save') },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -35,12 +35,17 @@ export const creationFactory = async (
|
|||||||
if (creation.confirmed) {
|
if (creation.confirmed) {
|
||||||
await mutate({ mutation: confirmContribution, variables: { id: pendingCreation.id } })
|
await mutate({ mutation: confirmContribution, variables: { id: pendingCreation.id } })
|
||||||
|
|
||||||
|
const confirmedCreation = await Contribution.findOneOrFail({ id: pendingCreation.id })
|
||||||
|
|
||||||
if (creation.moveCreationDate) {
|
if (creation.moveCreationDate) {
|
||||||
const transaction = await Transaction.findOneOrFail({
|
const transaction = await Transaction.findOneOrFail({
|
||||||
where: { userId: user.id, creationDate: new Date(creation.creationDate) },
|
where: { userId: user.id, creationDate: new Date(creation.creationDate) },
|
||||||
order: { balanceDate: 'DESC' },
|
order: { balanceDate: 'DESC' },
|
||||||
})
|
})
|
||||||
if (transaction.decay.equals(0) && transaction.creationDate) {
|
if (transaction.decay.equals(0) && transaction.creationDate) {
|
||||||
|
confirmedCreation.contributionDate = new Date(
|
||||||
|
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
|
||||||
|
)
|
||||||
transaction.creationDate = new Date(
|
transaction.creationDate = new Date(
|
||||||
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
|
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
|
||||||
)
|
)
|
||||||
@ -48,6 +53,7 @@ export const creationFactory = async (
|
|||||||
nMonthsBefore(transaction.balanceDate, creation.moveCreationDate),
|
nMonthsBefore(transaction.balanceDate, creation.moveCreationDate),
|
||||||
)
|
)
|
||||||
await transaction.save()
|
await transaction.save()
|
||||||
|
await confirmedCreation.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -23,6 +23,9 @@ describe('ContributionForm', () => {
|
|||||||
creation: ['1000', '1000', '1000'],
|
creation: ['1000', '1000', '1000'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
$i18n: {
|
||||||
|
locale: 'en',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
id="contribution-date"
|
id="contribution-date"
|
||||||
v-model="form.date"
|
v-model="form.date"
|
||||||
size="lg"
|
size="lg"
|
||||||
|
:locale="$i18n.locale"
|
||||||
:max="maximalDate"
|
:max="maximalDate"
|
||||||
:min="minimalDate"
|
:min="minimalDate"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
@ -25,25 +26,27 @@
|
|||||||
:label-no-date-selected="$t('contribution.noDateSelected')"
|
:label-no-date-selected="$t('contribution.noDateSelected')"
|
||||||
required
|
required
|
||||||
></b-form-datepicker>
|
></b-form-datepicker>
|
||||||
<label class="mt-3">{{ $t('contribution.activity') }}</label>
|
<validation-provider
|
||||||
<b-form-textarea
|
:rules="{
|
||||||
id="contribution-memo"
|
required: true,
|
||||||
v-model="form.memo"
|
min: minlength,
|
||||||
rows="3"
|
max: maxlength,
|
||||||
max-rows="6"
|
}"
|
||||||
required
|
:name="$t('form.message')"
|
||||||
:minlength="minlength"
|
v-slot="{ errors }"
|
||||||
:maxlength="maxlength"
|
|
||||||
></b-form-textarea>
|
|
||||||
<div
|
|
||||||
v-show="form.memo.length > 0"
|
|
||||||
class="text-right"
|
|
||||||
:class="form.memo.length < minlength ? 'text-danger' : 'text-success'"
|
|
||||||
>
|
>
|
||||||
{{ form.memo.length }}
|
<label class="mt-3">{{ $t('contribution.activity') }}</label>
|
||||||
<span v-if="form.memo.length < minlength">{{ $t('math.lower') }} {{ minlength }}</span>
|
<b-form-textarea
|
||||||
<span v-else>{{ $t('math.divide') }} {{ maxlength }}</span>
|
id="contribution-memo"
|
||||||
</div>
|
v-model="form.memo"
|
||||||
|
rows="3"
|
||||||
|
max-rows="6"
|
||||||
|
required
|
||||||
|
></b-form-textarea>
|
||||||
|
<b-col v-if="errors">
|
||||||
|
<span v-for="error in errors" class="errors" :key="error">{{ error }}</span>
|
||||||
|
</b-col>
|
||||||
|
</validation-provider>
|
||||||
<label class="mt-3">{{ $t('form.amount') }}</label>
|
<label class="mt-3">{{ $t('form.amount') }}</label>
|
||||||
<b-input-group size="lg" prepend="GDD" append=".00">
|
<b-input-group size="lg" prepend="GDD" append=".00">
|
||||||
<b-form-input
|
<b-form-input
|
||||||
@ -90,7 +93,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
minlength: 50,
|
minlength: 5,
|
||||||
maxlength: 255,
|
maxlength: 255,
|
||||||
maximalDate: new Date(),
|
maximalDate: new Date(),
|
||||||
form: this.value,
|
form: this.value,
|
||||||
@ -166,3 +169,8 @@ export default {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
span.errors {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -203,10 +203,8 @@
|
|||||||
"login": "Anmeldung",
|
"login": "Anmeldung",
|
||||||
"math": {
|
"math": {
|
||||||
"aprox": "~",
|
"aprox": "~",
|
||||||
"divide": "/",
|
|
||||||
"equal": "=",
|
"equal": "=",
|
||||||
"exclaim": "!",
|
"exclaim": "!",
|
||||||
"lower": "<",
|
|
||||||
"minus": "−",
|
"minus": "−",
|
||||||
"pipe": "|"
|
"pipe": "|"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -203,10 +203,8 @@
|
|||||||
"login": "Login",
|
"login": "Login",
|
||||||
"math": {
|
"math": {
|
||||||
"aprox": "~",
|
"aprox": "~",
|
||||||
"divide": "/",
|
|
||||||
"equal": "=",
|
"equal": "=",
|
||||||
"exclaim": "!",
|
"exclaim": "!",
|
||||||
"lower": "<",
|
|
||||||
"minus": "−",
|
"minus": "−",
|
||||||
"pipe": "|"
|
"pipe": "|"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -26,6 +26,9 @@ describe('Community', () => {
|
|||||||
creation: ['1000', '1000', '1000'],
|
creation: ['1000', '1000', '1000'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
$i18n: {
|
||||||
|
locale: 'en',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user