244 lines
8.3 KiB
Vue
244 lines
8.3 KiB
Vue
<script setup>
|
|
import { ref, onMounted, watch } from 'vue';
|
|
import { useRoute } from 'vue-router';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useQuasar } from 'quasar';
|
|
import axios from 'axios';
|
|
import { useSession } from 'src/composables/useSession';
|
|
import { useValidator } from 'src/composables/useValidator';
|
|
import SkeletonForm from 'src/components/SkeletonForm.vue';
|
|
|
|
onMounted(() => {
|
|
fetch();
|
|
fetchWorkers();
|
|
fetchClaimStates();
|
|
});
|
|
|
|
const route = useRoute();
|
|
const quasar = useQuasar();
|
|
const { t } = useI18n();
|
|
const { validate } = useValidator();
|
|
const session = useSession();
|
|
const token = session.getToken();
|
|
|
|
const claim = ref(null);
|
|
const claimCopy = ref(null);
|
|
const hasChanges = ref(false);
|
|
|
|
function fetch() {
|
|
const id = route.params.id;
|
|
const filter = {
|
|
include: [
|
|
{
|
|
relation: 'client',
|
|
scope: {
|
|
fields: ['name'],
|
|
},
|
|
},
|
|
],
|
|
};
|
|
const options = { params: { filter } };
|
|
axios.get(`Claims/${id}`, options).then(({ data }) => {
|
|
claim.value = data;
|
|
claimCopy.value = Object.assign({}, data);
|
|
|
|
watch(claim.value, () => (hasChanges.value = true));
|
|
});
|
|
}
|
|
|
|
const workers = ref([]);
|
|
const workersCopy = ref([]);
|
|
function fetchWorkers() {
|
|
const filter = {
|
|
where: {
|
|
role: 'salesPerson',
|
|
},
|
|
};
|
|
const options = { params: { filter } };
|
|
axios.get(`Workers/activeWithRole`, options).then(({ data }) => {
|
|
workers.value = data;
|
|
workersCopy.value = data;
|
|
});
|
|
}
|
|
|
|
const claimStates = ref([]);
|
|
const claimStatesCopy = ref([]);
|
|
function fetchClaimStates() {
|
|
axios.get(`ClaimStates`).then(({ data }) => {
|
|
claimStates.value = data;
|
|
claimStatesCopy.value = data;
|
|
});
|
|
}
|
|
|
|
function filter(value, update, options, originalOptions, filter) {
|
|
update(
|
|
() => {
|
|
if (value === '') {
|
|
options.value = originalOptions.value;
|
|
|
|
return;
|
|
}
|
|
|
|
options.value = options.value.filter(filter);
|
|
},
|
|
(ref) => {
|
|
ref.setOptionIndex(-1);
|
|
ref.moveOptionSelection(1, true);
|
|
}
|
|
);
|
|
}
|
|
|
|
function filterWorkers(value, update) {
|
|
const search = value.toLowerCase();
|
|
|
|
filter(value, update, workers, workersCopy, (row) => {
|
|
const id = row.id;
|
|
const name = row.name.toLowerCase();
|
|
|
|
const idMatch = id == search;
|
|
const nameMatch = name.indexOf(search) > -1;
|
|
|
|
return idMatch || nameMatch;
|
|
});
|
|
}
|
|
|
|
function filterStates(value, update) {
|
|
const search = value.toLowerCase();
|
|
|
|
filter(value, update, claimStates, claimStatesCopy, (row) => {
|
|
const description = row.description.toLowerCase();
|
|
|
|
return description.indexOf(search) > -1;
|
|
});
|
|
}
|
|
|
|
function save() {
|
|
const id = route.params.id;
|
|
const formData = claim.value;
|
|
|
|
if (!hasChanges.value) {
|
|
return quasar.notify({
|
|
type: 'negative',
|
|
message: t('globals.noChanges'),
|
|
});
|
|
}
|
|
|
|
axios.patch(`Claims/${id}`, formData).then((hasChanges.value = false));
|
|
}
|
|
|
|
function onReset() {
|
|
claim.value = claimCopy.value;
|
|
hasChanges.value = false;
|
|
}
|
|
</script>
|
|
<template>
|
|
<q-page class="q-pa-md">
|
|
<div class="container">
|
|
<q-card class="q-pa-md">
|
|
<skeleton-form v-if="!claim" />
|
|
<q-form v-if="claim" @submit="save" @reset="onReset" greedy>
|
|
<div class="row q-gutter-md q-mb-md">
|
|
<div class="col">
|
|
<q-input v-model="claim.client.name" :label="t('claim.basicData.customer')" disable />
|
|
</div>
|
|
<div class="col">
|
|
<q-input v-model="claim.created" mask="####-##-##" fill-mask="_" autofocus>
|
|
<template #append>
|
|
<q-icon name="event" class="cursor-pointer">
|
|
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
|
<q-date v-model="claim.created" mask="YYYY-MM-DD">
|
|
<div class="row items-center justify-end">
|
|
<q-btn v-close-popup label="Close" color="primary" flat />
|
|
</div>
|
|
</q-date>
|
|
</q-popup-proxy>
|
|
</q-icon>
|
|
</template>
|
|
</q-input>
|
|
</div>
|
|
</div>
|
|
<div class="row q-gutter-md q-mb-md">
|
|
<div class="col">
|
|
<q-select
|
|
v-model="claim.workerFk"
|
|
:options="workers"
|
|
option-value="id"
|
|
option-label="name"
|
|
emit-value
|
|
:label="t('claim.basicData.assignedTo')"
|
|
map-options
|
|
use-input
|
|
@filter="filterWorkers"
|
|
:rules="validate('claim.claimStateFk')"
|
|
:input-debounce="0"
|
|
>
|
|
<template #before>
|
|
<q-avatar color="orange">
|
|
<q-img
|
|
v-if="claim.workerFk"
|
|
:src="`/api/Images/user/160x160/${claim.workerFk}/download?access_token=${token}`"
|
|
spinner-color="white"
|
|
/>
|
|
</q-avatar>
|
|
</template>
|
|
</q-select>
|
|
</div>
|
|
<div class="col">
|
|
<q-select
|
|
v-model="claim.claimStateFk"
|
|
:options="claimStates"
|
|
option-value="id"
|
|
option-label="description"
|
|
emit-value
|
|
:label="t('claim.basicData.state')"
|
|
map-options
|
|
use-input
|
|
@filter="filterStates"
|
|
:rules="validate('claim.claimStateFk')"
|
|
:input-debounce="0"
|
|
>
|
|
</q-select>
|
|
</div>
|
|
</div>
|
|
<div class="row q-gutter-md q-mb-md">
|
|
<div class="col">
|
|
<q-input
|
|
v-model="claim.packages"
|
|
:label="t('claim.basicData.packages')"
|
|
:rules="validate('claim.packages')"
|
|
/>
|
|
</div>
|
|
<div class="col">
|
|
<q-input
|
|
v-model="claim.rma"
|
|
:label="t('claim.basicData.returnOfMaterial')"
|
|
:rules="validate('claim.rma')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="row q-gutter-md q-mb-md">
|
|
<div class="col">
|
|
<q-checkbox v-model="claim.hasToPickUp" :label="t('claim.basicData.picked')" />
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
|
<q-btn :label="t('globals.reset')" type="reset" class="q-ml-sm" color="primary" flat />
|
|
</div>
|
|
</q-form>
|
|
</q-card>
|
|
</div>
|
|
</q-page>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.q-card {
|
|
width: 800px;
|
|
}
|
|
</style>
|