finished ##169 and ##170

user can transact a Job, if the transact accepted the user can delete his job

user can decline or accept a jobrequest
This commit is contained in:
Tim Gröger 2020-02-25 22:34:45 +01:00
parent 917690eba3
commit e90dbf6513
9 changed files with 584 additions and 18 deletions

View File

@ -0,0 +1,250 @@
<template>
<div>
<v-toolbar>
<v-toolbar-title>
Dienstanfragen
</v-toolbar-title>
</v-toolbar>
<v-card tile flat>
<v-card-title>
Gesendete Anfragen
</v-card-title>
<v-progress-circular indeterminate v-if="transactJobsLoading" />
<div v-for="job in transactJobs" :key="transactJobs.indexOf(job)">
<v-expand-transition>
<v-card tile style="margin-top: 3px">
<v-card-text>
<v-row>
<v-col>
<v-combobox
outlined
label="An"
:value="job.to_user.firstname + ' ' + job.to_user.lastname"
readonly
append-icon
>
<template v-slot:selection="data">
<v-chip>
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
<v-col>
<v-combobox
outlined
label="Datum"
:value="
job.date.getDate() +
'.' +
(job.date.getMonth() + 1) +
'.' +
job.date.getFullYear()
"
readonly
append-icon
>
<template v-slot:selection="data">
<v-chip>
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
<v-col>
<v-combobox
outlined
label="Status"
:value="acceptedStatus(job)"
readonly
append-icon
>
<template v-slot:selection="data">
<v-chip :color="statusColor(job)">
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
</v-row>
</v-card-text>
<v-card-actions v-if="!job.answerd">
<v-spacer/>
<v-btn
@click="
deleteTransactJob({
username: job.to_user.username,
year: job.date.getFullYear(),
month: job.date.getMonth() + 1,
day: job.date.getDate()
})
"
>Stornieren
</v-btn
>
</v-card-actions>
</v-card>
</v-expand-transition>
</div>
</v-card>
<v-divider />
<v-card tile flat>
<v-card-title>
Eingehende Anfragen
</v-card-title>
<v-progress-circular indeterminate v-if="requestJobsLoading" />
<div v-for="job in requestJobs" :key="requestJobs.indexOf(job)">
<v-card tile style="margin-top: 3px">
<v-card-text>
<v-row>
<v-col>
<v-combobox
outlined
label="Von"
:value="
job.from_user.firstname + ' ' + job.from_user.lastname
"
readonly
append-icon
>
<template v-slot:selection="data">
<v-chip>
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
<v-col>
<v-combobox
outlined
label="Datum"
:value="
job.date.getDate() +
'.' +
(job.date.getMonth() + 1) +
'.' +
job.date.getFullYear()
"
readonly
append-icon
>
<template v-slot:selection="data">
<v-chip>
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
<v-col>
<v-combobox
outlined
label="Status"
:value="acceptedStatus(job)"
readonly
append-icon
>
<template v-slot:selection="data">
<v-chip :color="statusColor(job)">
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
</v-row>
</v-card-text>
<v-expand-transition>
<v-card-actions v-if="!job.answerd">
<v-spacer />
<v-btn
color="red"
@click="
answerJob({
username: job.from_user.username,
year: job.date.getFullYear(),
month: job.date.getMonth() + 1,
day: job.date.getDate(),
answer: false
})
"
>Ablehnen
</v-btn>
<v-btn
color="green"
@click="
answerJob({
username: job.from_user.username,
year: job.date.getFullYear(),
month: job.date.getMonth() + 1,
day: job.date.getDate(),
answer: true
})
"
>Annehmen
</v-btn>
</v-card-actions>
</v-expand-transition>
</v-card>
</div>
</v-card>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
name: 'JobRequests',
methods: {
...mapActions({
getTransactJobs: 'requestJobs/getTransactJobs',
getRequestJobs: 'requestJobs/getRequestJobs',
answerJob: 'requestJobs/answerTransactJob',
deleteTransactJob: 'requestJobs/deleteTransactJob'
})
},
computed: {
...mapGetters({
transactJobs: 'requestJobs/transactJobs',
transactJobsLoading: 'requestJobs/transactJobsLoading',
requestJobs: 'requestJobs/requestJobs',
requestJobsLoading: 'requestJobs/requestJobsLoading'
}),
acceptedStatus() {
return job => {
if (!job.answerd) {
return 'gesendet'
}
if (job.answerd && job.accepted) {
return 'angenommen'
}
return 'abgelehnt'
}
},
statusColor() {
return job => {
if (!job.answerd) {
return
}
if (job.answerd && job.accepted) {
return 'green'
}
return 'red'
}
}
},
created() {
var now = new Date()
this.getTransactJobs({
year: now.getFullYear(),
month: now.getMonth() + 1,
day: now.getDate()
})
this.getRequestJobs({
year: now.getFullYear(),
month: now.getMonth() + 1,
day: now.getDate()
})
}
}
</script>
<style scoped></style>

View File

@ -73,10 +73,12 @@ export default {
}, },
created() { created() {
this.createMonth(this.date) this.createMonth(this.date)
this.getAllUsers()
}, },
methods: { methods: {
...mapActions({ ...mapActions({
createMonth: 'jobs/createMonth' createMonth: 'jobs/createMonth',
getAllUsers: 'jobs/getAllUsers'
}), }),
changeMonth(value) { changeMonth(value) {
if (value === -1) { if (value === -1) {

View File

@ -17,7 +17,7 @@
<div v-for="worker in day.worker" :key="day.worker.indexOf(worker)"> <div v-for="worker in day.worker" :key="day.worker.indexOf(worker)">
<v-chip <v-chip
style="margin: 3px;" style="margin: 3px;"
:close="user(worker) && !day.locked" :close="user(worker) && !day.locked || canDelete && user(worker)"
@click:close=" @click:close="
deleteJob({ deleteJob({
year: day.date.getFullYear(), year: day.date.getFullYear(),
@ -31,6 +31,35 @@
</div> </div>
</v-expand-transition> </v-expand-transition>
</v-card-text> </v-card-text>
<div v-if="userInWorker">
<v-card-actions class="text--secondary">
<v-autocomplete
return-object
v-model="requestUser"
:items="specifiedUsers"
item-text="fullName"
label="Dienstanfrage"
filled
color="green"
@input="searchInput = null"
:search-input.sync="searchInput"
>
<template v-slot:prepend-inner>
<v-icon>{{ account_add }}</v-icon>
</template>
<template v-slot:item="data">
<v-list-item-content>
<v-list-item-title>
{{ data.item.firstname }} {{ data.item.lastname }}
</v-list-item-title>
</v-list-item-content>
</template>
</v-autocomplete>
</v-card-actions>
<v-card-actions>
<v-btn text block @click="send">senden</v-btn>
</v-card-actions>
</div>
<v-card-actions class="text--secondary"> <v-card-actions class="text--secondary">
<div v-if="!userInWorker"> <div v-if="!userInWorker">
<div v-if="day.locked"> <div v-if="day.locked">
@ -45,7 +74,10 @@
</div> </div>
<v-spacer /> <v-spacer />
<v-btn <v-btn
v-if="!day.locked && !day.loading && day.worker.length < 2" v-if="!day.locked &&
!day.loading &&
day.worker.length < 2 &&
!userInWorker"
@click=" @click="
addJob({ addJob({
year: day.date.getFullYear(), year: day.date.getFullYear(),
@ -53,8 +85,8 @@
day: day.date.getDate() day: day.date.getDate()
}) })
" "
>Eintragen</v-btn >Eintragen
> </v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</div> </div>
@ -71,7 +103,8 @@ export default {
data() { data() {
return { return {
account_add: mdiAccountPlus, account_add: mdiAccountPlus,
searchInput: null searchInput: null,
requestUser: null
} }
}, },
created() { created() {
@ -83,18 +116,36 @@ export default {
month: this.day.date.getMonth() + 1, month: this.day.date.getMonth() + 1,
day: this.day.date.getDate() day: this.day.date.getDate()
}) })
this.getTransactJobs({})
this.getTransactJobs({
year: this.day.date.getFullYear(),
month: this.day.date.getMonth() + 1,
day: this.day.date.getDate()
})
}, },
methods: { methods: {
...mapActions({ ...mapActions({
getTransactJobs: 'requestJobs/getTransactJobs',
getUser: 'jobs/getUser', getUser: 'jobs/getUser',
setLoading: 'jobs/setDayLoading', setLoading: 'jobs/setDayLoading',
setNotLoading: 'jobs/setDayNotLoading', setNotLoading: 'jobs/setDayNotLoading',
addJob: 'jobs/addJob', addJob: 'jobs/addJob',
deleteJob: 'jobs/deleteJob' deleteJob: 'jobs/deleteJob',
transactJob: 'jobs/transactJob'
}), }),
test(event) { test(event) {
console.log('blur', event) console.log('blur', event)
}, },
send() {
this.transactJob({
user: this.requestUser.username,
year: this.day.date.getFullYear(),
month: this.day.date.getMonth() + 1,
day: this.day.date.getDate()
})
this.requestUser = null
this.searchInput = null
},
color: day => { color: day => {
if (day) { if (day) {
if (day.date.getDay() === 0 || day.date.getDay() === 1) { if (day.date.getDay() === 0 || day.date.getDay() === 1) {
@ -117,12 +168,38 @@ export default {
computed: { computed: {
...mapGetters({ ...mapGetters({
disabled: 'jobs/disabled', disabled: 'jobs/disabled',
activeUser: 'user' activeUser: 'user',
allUsers: 'jobs/allUsers',
transactJobs: 'requestJobs/transactJobs'
}), }),
userInWorker() { userInWorker() {
return this.day.worker.find(a => { return this.day.worker.find(a => {
return a.username === this.activeUser.username return a.username === this.activeUser.username
}) })
},
specifiedUsers() {
var users = [...this.allUsers]
for (var i in this.day.worker) {
var worker = users.find(a => {
return a.username === this.day.worker[i].username
})
var index = users.indexOf(worker)
if (worker) users.splice(index, 1)
}
return users
},
canDelete() {
console.log(this.day.date)
console.log(this.transactJobs)
var transactJob = this.transactJobs.filter(a => {
return a.date - this.day.date === 0
})
console.log('filter', transactJob)
var test = transactJob.find(a => {
return a.accepted && a.answerd
})
console.log('find', test)
return test
} }
}, },
watch: { watch: {

View File

@ -22,6 +22,14 @@
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title>Dienstübersicht</v-list-item-title> <v-list-item-title>Dienstübersicht</v-list-item-title>
</v-list-item> </v-list-item>
<v-list-item link to="/main/user/jobRequests">
<v-list-item-icon>
<v-icon>
{{ switchAccount }}
</v-icon>
</v-list-item-icon>
<v-list-item-title>Dienstanfragen</v-list-item-title>
</v-list-item>
<v-list-item link to="/main/user/config"> <v-list-item link to="/main/user/config">
<v-list-item-icon> <v-list-item-icon>
<v-icon>{{ account_card_details }}</v-icon> <v-icon>{{ account_card_details }}</v-icon>
@ -32,7 +40,13 @@
</template> </template>
<script> <script>
import {mdiAccountCardDetails, mdiHome, mdiBank, mdiBriefcase } from '@mdi/js' import {
mdiAccountCardDetails,
mdiHome,
mdiBank,
mdiBriefcase,
mdiAccountSwitch
} from '@mdi/js'
export default { export default {
name: 'UserNavigation', name: 'UserNavigation',
data() { data() {
@ -40,7 +54,8 @@ export default {
account_card_details: mdiAccountCardDetails, account_card_details: mdiAccountCardDetails,
account: mdiHome, account: mdiHome,
bank: mdiBank, bank: mdiBank,
briefcase: mdiBriefcase briefcase: mdiBriefcase,
switchAccount: mdiAccountSwitch
} }
} }
} }

View File

@ -32,7 +32,12 @@ const url = {
config: main + 'user/saveConfig', config: main + 'user/saveConfig',
job: main + 'user/job', job: main + 'user/job',
addJob: main + 'user/addJob', addJob: main + 'user/addJob',
deleteJob: main + 'user/deleteJob' deleteJob: main + 'user/deleteJob',
transactJob: main + 'user/transactJob',
answerTransactJob: main + 'user/answerTransactJob',
jobRequests: main + 'user/jobRequests',
getTransactJobs: main + 'user/getTransactJobs',
deleteTransactJobs: main + 'user/deleteTransactJob'
}, },
barU: { barU: {
storno: main + 'bar/storno' storno: main + 'bar/storno'

View File

@ -17,6 +17,7 @@ import User from '../components/finanzer/User'
import ServiceManagement from '../components/vorstand/ServiceManagement' import ServiceManagement from '../components/vorstand/ServiceManagement'
import Config from '@/components/user/Config' import Config from '@/components/user/Config'
import Jobs from '@/components/user/Jobs' import Jobs from '@/components/user/Jobs'
import JobRequests from '@/components/user/JobRequests'
Vue.use(VueRouter) Vue.use(VueRouter)
@ -55,6 +56,11 @@ const routes = [
path: 'jobs', path: 'jobs',
name: 'userJobs', name: 'userJobs',
component: Jobs component: Jobs
},
{
path: 'jobRequests',
name: 'jobRequests',
component: JobRequests
} }
] ]
}, },

View File

@ -6,6 +6,7 @@ import barUsers from '@/store/modules/barUsers'
import user from '@/store/modules/user' import user from '@/store/modules/user'
import sm from '@/store/modules/serviceManagement' import sm from '@/store/modules/serviceManagement'
import jobs from '@/store/modules/jobs' import jobs from '@/store/modules/jobs'
import requestJobs from '@/store/modules/jobRequests'
Vue.use(Vuex) Vue.use(Vuex)
@ -16,6 +17,7 @@ export default new Vuex.Store({
barUsers, barUsers,
user, user,
sm, sm,
jobs jobs,
requestJobs
} }
}) })

View File

@ -0,0 +1,161 @@
import axios from 'axios'
import url from '@/plugins/routes'
const state = {
transactJobs: [],
transactJobsLoading: false,
requestJobs: [],
requestJobsLoading: false
}
const mutations = {
setTransactJobs: (state, data) => {
var list = []
for (var i in data) {
list.push({
date: new Date(
data[i].date.year,
data[i].date.month - 1,
data[i].date.day
),
from_user: data[i].from_user,
to_user: data[i].to_user,
accepted: data[i].accepted,
answerd: data[i].answerd
})
}
state.transactJobs = list
},
setRequestJobs: (state, data) => {
var list = []
for (var i in data) {
list.push({
date: new Date(
data[i].date.year,
data[i].date.month - 1,
data[i].date.day
),
from_user: data[i].from_user,
to_user: data[i].to_user,
accepted: data[i].accepted,
answerd: data[i].answerd
})
}
state.requestJobs = list
},
setTransactJobsLoading: (state, value) => {
state.transactJobsLoading = value
},
setRequestJobsLoading: (state, value) => {
state.requestJobsLoading = value
},
updateRequestJob: (state, data) => {
const date = new Date(data.date.year, data.date.month - 1, data.date.day)
for (var i in state.requestJobs) {
if (
state.requestJobs[i].date - date === 0 &&
state.requestJobs[i].from_user.username === data.from_user.username
) {
state.requestJobs[i].accepted = data.accepted
state.requestJobs[i].answerd = data.answerd
break
}
}
},
deleteTransactJobactJob: (state, data) => {
const date = new Date(data.year, data.month - 1, data.day)
var job = state.transactJobs.find(a => {
console.log(a)
console.log(a.date, date)
return a.date - date === 0 && a.to_user.username === data.username
})
console.log(job)
var index = state.transactJobs.indexOf(job)
if (job)
state.transactJobs.splice(index, 1)
}
}
const actions = {
async getTransactJobs({ commit, rootState, dispatch }, data) {
commit('setTransactJobsLoading', true)
try {
const response = await axios.post(
url.user.getTransactJobs,
{ ...data },
{ headers: { Token: rootState.login.user.accessToken } }
)
commit('setTransactJobs', response.data)
} catch (e) {
if (e.response)
if (e.response.data === 401) dispatch('logout', null, { root: true })
commit('setTransactJobsLoading', false)
}
commit('setTransactJobsLoading', false)
},
async getRequestJobs({ commit, rootState, dispatch }, data) {
commit('setRequestJobsLoading', true)
try {
const response = await axios.post(
url.user.jobRequests,
{ ...data },
{ headers: { Token: rootState.login.user.accessToken } }
)
commit('setRequestJobs', response.data)
} catch (e) {
if (e.response)
if (e.response.data === 401) dispatch('logout', null, { root: true })
commit('setRequestJobsLoading', false)
}
commit('setRequestJobsLoading', false)
},
async answerTransactJob({ commit, rootState, dispatch }, data) {
try {
const response = await axios.post(
url.user.answerTransactJob,
{ ...data },
{ headers: { Token: rootState.login.user.accessToken } }
)
commit('updateRequestJob', response.data)
} catch (e) {
if (e.response)
if (e.response.data === 401) dispatch('logout', null, { root: true })
}
},
async deleteTransactJob({ commit, rootState, dispatch }, data) {
try {
await axios.post(
url.user.deleteTransactJobs,
{ ...data },
{ headers: { Token: rootState.login.user.accessToken } }
)
commit('deleteTransactJobactJob', data)
} catch (e) {
if (e.response)
if (e.response.data === 401) dispatch('logout', null, { root: true })
}
}
}
const getters = {
transactJobs: state => {
return state.transactJobs
},
transactJobsLoading: state => {
return state.transactJobsLoading
},
requestJobs: state => {
return state.requestJobs
},
requestJobsLoading: state => {
return state.requestJobsLoading
}
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}

View File

@ -3,10 +3,23 @@ import url from '@/plugins/routes'
const state = { const state = {
month: [], month: [],
allUsers: [],
disabled: false disabled: false
} }
const mutations = { const mutations = {
setAllUsers: (state, data) => {
state.allUsers = []
state.allUsers = data.users
const index = state.allUsers.indexOf(
state.allUsers.find(a => a.username === data.username)
)
state.allUsers.splice(index, 1)
for (let i = 0; i < state.allUsers.length; i++) {
state.allUsers[i].fullName =
state.allUsers[i].firstname + ' ' + state.allUsers[i].lastname
}
},
createMonth: (state, date) => { createMonth: (state, date) => {
let month = [] let month = []
let id = 0 let id = 0
@ -189,6 +202,22 @@ const mutations = {
} }
const actions = { const actions = {
async getAllUsers({ commit, rootState, dispatch }) {
try {
const response = await axios.post(
url.searchUser,
{ searchString: '' },
{ headers: { Token: rootState.login.user.accessToken } }
)
commit('setAllUsers', {
users: response.data,
username: rootState.login.user.username
})
} catch (e) {
if (e.response)
if (e.response.data === 401) dispatch('logout', null, { root: true })
}
},
createMonth({ commit }, date) { createMonth({ commit }, date) {
commit('setDisabled', true) commit('setDisabled', true)
commit('createMonth', date) commit('createMonth', date)
@ -248,12 +277,28 @@ const actions = {
{ ...data }, { ...data },
{ headers: { Token: rootState.login.user.accessToken } } { headers: { Token: rootState.login.user.accessToken } }
) )
commit('updateMonth', {start: {...data}, user: rootState.login.user, com: 'delete'}) commit('updateMonth', {
start: { ...data },
user: rootState.login.user,
com: 'delete'
})
console.log(response) console.log(response)
} catch (e) { } catch (e) {
if (e.response) if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true }) if (e.response.status === 401) dispatch('logout', null, { root: true })
} }
},
async transactJob({ rootState, dispatch }, data) {
try {
await axios.post(
url.user.transactJob,
{ ...data },
{ headers: { Token: rootState.login.user.accessToken } }
)
} catch (e) {
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
}
} }
} }
@ -272,6 +317,9 @@ const getters = {
}, },
disabled: state => { disabled: state => {
return state.disabled return state.disabled
},
allUsers: state => {
return state.allUsers
} }
} }