forked from verdnatura/salix-front
RMA refactor
This commit is contained in:
parent
5e867a368e
commit
bd908e5e93
|
@ -61,7 +61,7 @@ function responseError(error) {
|
||||||
router.push({ path: '/login' });
|
router.push({ path: '/login' });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
axios.interceptors.response.use((response) => {
|
axios.interceptors.response.use((response) => {
|
||||||
|
|
|
@ -15,13 +15,10 @@ const $props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
limit: {
|
|
||||||
type: String,
|
|
||||||
default: '20',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['fetch-data']);
|
defineExpose({ fetch });
|
||||||
|
const emit = defineEmits(['onFetch']);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if ($props.autoLoad) {
|
if ($props.autoLoad) {
|
||||||
|
@ -34,7 +31,7 @@ async function fetch() {
|
||||||
params: { filter: $props.filter },
|
params: { filter: $props.filter },
|
||||||
});
|
});
|
||||||
|
|
||||||
return emit('fetch-data', data);
|
emit('onFetch', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const render = () => {
|
const render = () => {
|
||||||
|
|
|
@ -5,11 +5,13 @@ import { useQuasar } from 'quasar';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
|
import { useValidator } from 'src/composables/useValidator';
|
||||||
import SkeletonForm from 'src/components/SkeletonForm.vue';
|
import SkeletonForm from 'src/components/SkeletonForm.vue';
|
||||||
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
|
const { validate } = useValidator();
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
|
@ -26,7 +28,7 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['fetch-data']);
|
const emit = defineEmits(['onFetch']);
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
save,
|
save,
|
||||||
|
@ -53,7 +55,7 @@ async function fetch() {
|
||||||
|
|
||||||
watch(formData.value, () => (hasChanges.value = true));
|
watch(formData.value, () => (hasChanges.value = true));
|
||||||
|
|
||||||
return emit('fetch-data', state.get($props.model));
|
emit('onFetch', state.get($props.model));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
|
@ -64,10 +66,10 @@ async function save() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
await new Promise((resolve) => {
|
|
||||||
setTimeout(resolve, 5000);
|
|
||||||
});
|
|
||||||
await axios.patch($props.url, formData.value);
|
await axios.patch($props.url, formData.value);
|
||||||
|
|
||||||
|
originalData.value = formData.value;
|
||||||
|
hasChanges.value = false;
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,22 +77,41 @@ function reset() {
|
||||||
state.set($props.model, originalData.value);
|
state.set($props.model, originalData.value);
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filter(value, update, filterOptions) {
|
||||||
|
update(
|
||||||
|
() => {
|
||||||
|
const { options, filterFn } = filterOptions;
|
||||||
|
|
||||||
|
options.value = filterFn(options, value);
|
||||||
|
},
|
||||||
|
(ref) => {
|
||||||
|
ref.setOptionIndex(-1);
|
||||||
|
ref.moveOptionSelection(1, true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<q-banner v-if="hasChanges" inline-actions class="text-white bg-red"> You have changes pending to save </q-banner>
|
<q-banner v-if="hasChanges" class="text-white bg-warning">
|
||||||
|
<q-icon name="warning" size="md" class="q-mr-md" />
|
||||||
|
<span>{{ t('globals.changesToSave') }}</span>
|
||||||
|
</q-banner>
|
||||||
<q-form v-if="formData" @submit="save" @reset="reset" class="q-pa-md">
|
<q-form v-if="formData" @submit="save" @reset="reset" class="q-pa-md">
|
||||||
<slot name="form" :data="formData"></slot>
|
<slot name="form" :data="formData" :validate="validate" :filter="filter"></slot>
|
||||||
<slot name="actions">
|
<div class="q-mt-lg">
|
||||||
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
<slot name="actions">
|
||||||
<q-btn
|
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
||||||
:label="t('globals.reset')"
|
<q-btn
|
||||||
type="reset"
|
:label="t('globals.reset')"
|
||||||
class="q-ml-sm"
|
type="reset"
|
||||||
color="primary"
|
class="q-ml-sm"
|
||||||
flat
|
color="primary"
|
||||||
:disable="!hasChanges"
|
flat
|
||||||
/>
|
:disable="!hasChanges"
|
||||||
</slot>
|
/>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
<skeleton-form v-if="!formData" />
|
<skeleton-form v-if="!formData" />
|
||||||
<q-inner-loading :showing="isLoading" :label="t('globals.pleaseWait')" color="primary" />
|
<q-inner-loading :showing="isLoading" :label="t('globals.pleaseWait')" color="primary" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -10,6 +10,10 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
filter: {
|
filter: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
|
@ -35,6 +39,17 @@ const $props = defineProps({
|
||||||
defineEmits(['onNavigate']);
|
defineEmits(['onNavigate']);
|
||||||
defineExpose({ fetch });
|
defineExpose({ fetch });
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if ($props.autoLoad) fetch();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => $props.data,
|
||||||
|
() => {
|
||||||
|
rows.value = $props.data;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const hasMoreData = ref(false);
|
const hasMoreData = ref(false);
|
||||||
const pagination = ref({
|
const pagination = ref({
|
||||||
|
@ -42,17 +57,13 @@ const pagination = ref({
|
||||||
rowsPerPage: $props.rowsPerPage,
|
rowsPerPage: $props.rowsPerPage,
|
||||||
page: 1,
|
page: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rows = ref(null);
|
const rows = ref(null);
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if ($props.autoLoad) fetch();
|
|
||||||
else rows.value = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
const { page, rowsPerPage, sortBy, descending } = pagination.value;
|
const { page, rowsPerPage, sortBy, descending } = pagination.value;
|
||||||
|
|
||||||
|
if (!$props.url) return;
|
||||||
|
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
|
@ -89,7 +100,7 @@ async function fetch() {
|
||||||
|
|
||||||
async function onLoad(...params) {
|
async function onLoad(...params) {
|
||||||
const done = params[1];
|
const done = params[1];
|
||||||
if (!rows.value || rows.value.length === 0) return done(false);
|
if (!rows.value || rows.value.length === 0 || !$props.url) return done(false);
|
||||||
|
|
||||||
pagination.value.page = pagination.value.page + 1;
|
pagination.value.page = pagination.value.page + 1;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
||||||
yes: 'Yes',
|
yes: 'Yes',
|
||||||
no: 'No',
|
no: 'No',
|
||||||
noChanges: 'No changes to save',
|
noChanges: 'No changes to save',
|
||||||
|
changesToSave: 'You have changes pending to save',
|
||||||
confirmRemove: 'You are about to delete this row. Are you sure?',
|
confirmRemove: 'You are about to delete this row. Are you sure?',
|
||||||
rowAdded: 'Row added',
|
rowAdded: 'Row added',
|
||||||
rowRemoved: 'Row removed',
|
rowRemoved: 'Row removed',
|
||||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
||||||
yes: 'Si',
|
yes: 'Si',
|
||||||
no: 'No',
|
no: 'No',
|
||||||
noChanges: 'Sin cambios que guardar',
|
noChanges: 'Sin cambios que guardar',
|
||||||
|
changesToSave: 'Tienes cambios pendientes de guardar',
|
||||||
confirmRemove: 'Vas a eliminar este registro. ¿Continuar?',
|
confirmRemove: 'Vas a eliminar este registro. ¿Continuar?',
|
||||||
rowAdded: 'Fila añadida',
|
rowAdded: 'Fila añadida',
|
||||||
rowRemoved: 'Fila eliminada',
|
rowRemoved: 'Fila eliminada',
|
||||||
|
|
|
@ -1,231 +1,242 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
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(() => {
|
import { useSession } from 'src/composables/useSession';
|
||||||
fetch();
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
fetchWorkers();
|
import FormModel from 'src/components/FormModel.vue';
|
||||||
fetchClaimStates();
|
|
||||||
});
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const quasar = useQuasar();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { validate } = useValidator();
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
|
|
||||||
const claim = ref(null);
|
// const claim = ref(null);
|
||||||
const claimCopy = ref(null);
|
// const claimCopy = ref(null);
|
||||||
const hasChanges = ref(false);
|
// const hasChanges = ref(false);
|
||||||
|
|
||||||
function fetch() {
|
// function fetch() {
|
||||||
const id = route.params.id;
|
// const id = route.params.id;
|
||||||
const filter = {
|
// const filter = {
|
||||||
include: [
|
// include: [
|
||||||
{
|
// {
|
||||||
relation: 'client',
|
// relation: 'client',
|
||||||
scope: {
|
// scope: {
|
||||||
fields: ['name'],
|
// 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 claimFilter = {
|
||||||
|
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 workers = ref([]);
|
||||||
const workersCopy = 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 claimStates = ref([]);
|
||||||
const claimStatesCopy = ref([]);
|
const claimStatesCopy = ref([]);
|
||||||
function fetchClaimStates() {
|
|
||||||
axios.get(`ClaimStates`).then(({ data }) => {
|
// function filter(value, update, options, originalOptions, filter) {
|
||||||
claimStates.value = data;
|
// update(
|
||||||
claimStatesCopy.value = data;
|
// () => {
|
||||||
});
|
// 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 setWorkers(data) {
|
||||||
|
workers.value = data;
|
||||||
|
workersCopy.value = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filter(value, update, options, originalOptions, filter) {
|
function setClaimStates(data) {
|
||||||
update(
|
claimStates.value = data;
|
||||||
() => {
|
claimStatesCopy.value = data;
|
||||||
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 workerFilter = {
|
||||||
const search = value.toLowerCase();
|
options: workers,
|
||||||
|
filterFn: (options, value) => {
|
||||||
|
const search = value.toLowerCase();
|
||||||
|
|
||||||
filter(value, update, workers, workersCopy, (row) => {
|
if (value === '') return workersCopy.value;
|
||||||
const id = row.id;
|
|
||||||
const name = row.name.toLowerCase();
|
|
||||||
|
|
||||||
const idMatch = id == search;
|
return options.value.filter((row) => {
|
||||||
const nameMatch = name.indexOf(search) > -1;
|
const id = row.id;
|
||||||
|
const name = row.name.toLowerCase();
|
||||||
|
|
||||||
return idMatch || nameMatch;
|
const idMatches = id == search;
|
||||||
});
|
const nameMatches = name.indexOf(search) > -1;
|
||||||
}
|
|
||||||
|
|
||||||
function filterStates(value, update) {
|
return idMatches || nameMatches;
|
||||||
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));
|
const statesFilter = {
|
||||||
}
|
options: claimStates,
|
||||||
|
filterFn: (options, value) => {
|
||||||
|
const search = value.toLowerCase();
|
||||||
|
|
||||||
function onReset() {
|
if (value === '') return claimStatesCopy.value;
|
||||||
claim.value = claimCopy.value;
|
|
||||||
hasChanges.value = false;
|
return options.value.filter((row) => {
|
||||||
}
|
const description = row.description.toLowerCase();
|
||||||
|
|
||||||
|
return description.indexOf(search) > -1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
<fetch-data
|
||||||
|
url="Workers/activeWithInheritedRole"
|
||||||
|
:filter="{ where: { role: 'salesPerson' } }"
|
||||||
|
@on-fetch="setWorkers"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<fetch-data url="ClaimStates" @on-fetch="setClaimStates" auto-load />
|
||||||
<q-page class="q-pa-md">
|
<q-page class="q-pa-md">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<q-card class="q-pa-md">
|
<q-card>
|
||||||
<skeleton-form v-if="!claim" />
|
<form-model :url="`Claims/${route.params.id}`" :filter="claimFilter" model="claim">
|
||||||
<q-form v-if="claim" @submit="save" @reset="onReset" greedy>
|
<template #form="{ data, validate, filter }">
|
||||||
<div class="row q-gutter-md q-mb-md">
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<q-input v-model="claim.client.name" :label="t('claim.basicData.customer')" disable />
|
<q-input v-model="data.client.name" :label="t('claim.basicData.customer')" disable />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<q-input v-model="data.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="data.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>
|
||||||
<div class="col">
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<q-input v-model="claim.created" mask="####-##-##" fill-mask="_" autofocus>
|
<div class="col">
|
||||||
<template #append>
|
<q-select
|
||||||
<q-icon name="event" class="cursor-pointer">
|
v-model="data.workerFk"
|
||||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
:options="workers"
|
||||||
<q-date v-model="claim.created" mask="YYYY-MM-DD">
|
option-value="id"
|
||||||
<div class="row items-center justify-end">
|
option-label="name"
|
||||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
emit-value
|
||||||
</div>
|
:label="t('claim.basicData.assignedTo')"
|
||||||
</q-date>
|
map-options
|
||||||
</q-popup-proxy>
|
use-input
|
||||||
</q-icon>
|
@filter="(value, update) => filter(value, update, workerFilter)"
|
||||||
</template>
|
:rules="validate('claim.claimStateFk')"
|
||||||
</q-input>
|
:input-debounce="0"
|
||||||
|
>
|
||||||
|
<template #before>
|
||||||
|
<q-avatar color="orange">
|
||||||
|
<q-img
|
||||||
|
v-if="data.workerFk"
|
||||||
|
:src="`/api/Images/user/160x160/${data.workerFk}/download?access_token=${token}`"
|
||||||
|
spinner-color="white"
|
||||||
|
/>
|
||||||
|
</q-avatar>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<q-select
|
||||||
|
v-model="data.claimStateFk"
|
||||||
|
:options="claimStates"
|
||||||
|
option-value="id"
|
||||||
|
option-label="description"
|
||||||
|
emit-value
|
||||||
|
:label="t('claim.basicData.state')"
|
||||||
|
map-options
|
||||||
|
use-input
|
||||||
|
@filter="(value, update) => filter(value, update, statesFilter)"
|
||||||
|
:rules="validate('claim.claimStateFk')"
|
||||||
|
:input-debounce="0"
|
||||||
|
>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<div class="row q-gutter-md q-mb-md">
|
<div class="col">
|
||||||
<div class="col">
|
<q-input
|
||||||
<q-select
|
v-model="data.packages"
|
||||||
v-model="claim.workerFk"
|
:label="t('claim.basicData.packages')"
|
||||||
:options="workers"
|
:rules="validate('claim.packages')"
|
||||||
option-value="id"
|
/>
|
||||||
option-label="name"
|
</div>
|
||||||
emit-value
|
<div class="col">
|
||||||
:label="t('claim.basicData.assignedTo')"
|
<q-input
|
||||||
map-options
|
v-model="data.rma"
|
||||||
use-input
|
:label="t('claim.basicData.returnOfMaterial')"
|
||||||
@filter="filterWorkers"
|
:rules="validate('claim.rma')"
|
||||||
:rules="validate('claim.claimStateFk')"
|
/>
|
||||||
:input-debounce="0"
|
</div>
|
||||||
>
|
|
||||||
<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>
|
||||||
<div class="col">
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<q-select
|
<div class="col">
|
||||||
v-model="claim.claimStateFk"
|
<q-checkbox v-model="data.hasToPickUp" :label="t('claim.basicData.picked')" />
|
||||||
:options="claimStates"
|
</div>
|
||||||
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>
|
</template>
|
||||||
<div class="row q-gutter-md q-mb-md">
|
</form-model>
|
||||||
<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>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
</q-page>
|
</q-page>
|
||||||
|
|
|
@ -163,7 +163,7 @@ function stateColor(code) {
|
||||||
</q-scroll-area>
|
</q-scroll-area>
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
<router-view v-if="claim.id" :claim="claim"></router-view>
|
<router-view></router-view>
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,52 +1,51 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import SmartCard from 'src/components/SmartCard.vue';
|
import SmartCard from 'src/components/SmartCard.vue';
|
||||||
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import { toDate } from 'src/filters';
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
onMounted(() => fetch());
|
|
||||||
|
|
||||||
const $props = defineProps({
|
|
||||||
claim: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// const card = ref();
|
||||||
|
const claim = ref([]);
|
||||||
|
const fetcher = ref();
|
||||||
|
|
||||||
|
// const rma = computed(() => claim.value.rma);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
include: {
|
include: {
|
||||||
relation: 'worker',
|
relation: 'rmas',
|
||||||
scope: {
|
scope: {
|
||||||
include: {
|
include: {
|
||||||
relation: 'user',
|
relation: 'worker',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'user',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
where: {
|
|
||||||
code: $props.claim.rma,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function fetch() {
|
async function addRow() {
|
||||||
//console.log($props.claim);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addRow() {
|
|
||||||
const formData = {
|
const formData = {
|
||||||
code: $props.claim.rma,
|
code: claim.value.rma,
|
||||||
};
|
};
|
||||||
|
|
||||||
axios.post(`ClaimRmas`, formData).then(() => {
|
await axios.post(`ClaimRmas`, formData);
|
||||||
quasar.notify({
|
await fetcher.value.fetch();
|
||||||
type: 'positive',
|
|
||||||
message: t('globals.rowAdded'),
|
quasar.notify({
|
||||||
icon: 'check',
|
type: 'positive',
|
||||||
});
|
message: t('globals.rowAdded'),
|
||||||
|
icon: 'check',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,16 +56,17 @@ function confirmRemove(id) {
|
||||||
rmaId.value = id;
|
rmaId.value = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove() {
|
async function remove() {
|
||||||
const id = rmaId.value;
|
const id = rmaId.value;
|
||||||
axios.delete(`ClaimRmas/${id}`).then(() => {
|
|
||||||
confirmShown.value = false;
|
|
||||||
|
|
||||||
quasar.notify({
|
await axios.delete(`ClaimRmas/${id}`);
|
||||||
type: 'positive',
|
await fetcher.value.fetch();
|
||||||
message: t('globals.rowRemoved'),
|
confirmShown.value = false;
|
||||||
icon: 'check',
|
|
||||||
});
|
quasar.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message: t('globals.rowRemoved'),
|
||||||
|
icon: 'check',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,13 @@ function hide() {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
<fetch-data
|
||||||
|
ref="fetcher"
|
||||||
|
:url="`Claims/${route.params.id}`"
|
||||||
|
:filter="filter"
|
||||||
|
@on-fetch="($data) => (claim = $data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
<q-page class="q-pa-md sticky">
|
<q-page class="q-pa-md sticky">
|
||||||
<q-page-sticky expand position="top">
|
<q-page-sticky expand position="top">
|
||||||
<q-toolbar class="bg-grey-9">
|
<q-toolbar class="bg-grey-9">
|
||||||
|
@ -85,7 +92,7 @@ function hide() {
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
</q-page-sticky>
|
</q-page-sticky>
|
||||||
|
|
||||||
<smart-card ref="card" url="/ClaimRmas" :filter="filter" sort-by="id DESC" auto-load>
|
<smart-card :data="claim.rmas">
|
||||||
<template #header="{ row }">
|
<template #header="{ row }">
|
||||||
<q-item-label caption>{{ t('claim.rma.user') }}</q-item-label>
|
<q-item-label caption>{{ t('claim.rma.user') }}</q-item-label>
|
||||||
<q-item-label>{{ row.worker.user.name }}</q-item-label>
|
<q-item-label>{{ row.worker.user.name }}</q-item-label>
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { reactive, watch } from 'vue'
|
|
||||||
|
|
||||||
const customer = reactive({
|
|
||||||
name: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(() => customer.name, () => {
|
|
||||||
console.log('customer.name changed');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<q-page class="q-pa-md">
|
|
||||||
<q-card class="q-pa-md">
|
|
||||||
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-md">
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
v-model="customer.name"
|
|
||||||
label="Your name *"
|
|
||||||
hint="Name and surname"
|
|
||||||
lazy-rules
|
|
||||||
:rules="[val => val && val.length > 0 || 'Please type something']"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
type="number"
|
|
||||||
v-model="age"
|
|
||||||
label="Your age *"
|
|
||||||
lazy-rules
|
|
||||||
:rules="[
|
|
||||||
val => val !== null && val !== '' || 'Please type your age',
|
|
||||||
val => val > 0 && val < 100 || 'Please type a real age'
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<q-btn label="Submit" type="submit" color="primary" />
|
|
||||||
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
|
|
||||||
</div>
|
|
||||||
</q-form>
|
|
||||||
</q-card>
|
|
||||||
</q-page>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.card {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 60em;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,86 +1,60 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
// import { useQuasar } from 'quasar';
|
|
||||||
// import axios from 'axios';
|
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import { useValidator } from 'src/composables/useValidator';
|
|
||||||
import { useState } from 'src/composables/useState';
|
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import FormModel from 'src/components/FormModel.vue';
|
import FormModel from 'src/components/FormModel.vue';
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// fetch();
|
|
||||||
// fetchWorkers();
|
|
||||||
// fetchBusinessTypes();
|
|
||||||
// fetchContactChannels();
|
|
||||||
});
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
// const quasar = useQuasar();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { validate } = useValidator();
|
|
||||||
const state = useState();
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
const data2 = state.get('customer');
|
|
||||||
console.log(data2);
|
|
||||||
|
|
||||||
const workers = ref([]);
|
const workers = ref([]);
|
||||||
const contactChannels = ref([]);
|
const workersCopy = ref([]);
|
||||||
const businessTypes = ref([]);
|
const businessTypes = ref([]);
|
||||||
|
const contactChannels = ref([]);
|
||||||
|
|
||||||
// const customer = ref(null);
|
function setWorkers(data) {
|
||||||
// const customerCopy = ref(null);
|
workers.value = data;
|
||||||
// const hasChanges = ref(false);
|
workersCopy.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
// function filter(value, update, options, originalOptions, filter) {
|
const filterOptions = {
|
||||||
// update(
|
options: workers,
|
||||||
// () => {
|
filterFn: (options, value) => {
|
||||||
// if (value === '') {
|
const search = value.toLowerCase();
|
||||||
// options.value = originalOptions.value;
|
|
||||||
|
|
||||||
// return;
|
if (value === '') return workersCopy.value;
|
||||||
// }
|
|
||||||
|
|
||||||
// options.value = options.value.filter(filter);
|
return options.value.filter((row) => {
|
||||||
// },
|
const id = row.id;
|
||||||
// (ref) => {
|
const name = row.name.toLowerCase();
|
||||||
// ref.setOptionIndex(-1);
|
|
||||||
// ref.moveOptionSelection(1, true);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function filterWorkers(value, update) {
|
const idMatches = id == search;
|
||||||
// const search = value.toLowerCase();
|
const nameMatches = name.indexOf(search) > -1;
|
||||||
|
|
||||||
// filter(value, update, workers, workersCopy, (row) => {
|
return idMatches || nameMatches;
|
||||||
// const id = row.id;
|
});
|
||||||
// const name = row.name.toLowerCase();
|
},
|
||||||
|
};
|
||||||
// const idMatch = id == search;
|
|
||||||
// const nameMatch = name.indexOf(search) > -1;
|
|
||||||
|
|
||||||
// return idMatch || nameMatch;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<fetch-data
|
<fetch-data
|
||||||
url="Workers/activeWithRole"
|
url="Workers/activeWithInheritedRole"
|
||||||
:filter="{ where: { role: 'salesPerson' } }"
|
:filter="{ where: { role: 'salesPerson' } }"
|
||||||
@fetch-data="($data) => (workers = $data)"
|
@on-fetch="setWorkers"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<fetch-data url="ContactChannels" @fetch-data="($data) => (contactChannels = $data)" auto-load />
|
<fetch-data url="ContactChannels" @on-fetch="($data) => (contactChannels = $data)" auto-load />
|
||||||
<fetch-data url="BusinessTypes" @fetch-data="($data) => (businessTypes = $data)" auto-load />
|
<fetch-data url="BusinessTypes" @on-fetch="($data) => (businessTypes = $data)" auto-load />
|
||||||
<q-page class="q-pa-md">
|
<q-page class="q-pa-md">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<q-card>
|
<q-card>
|
||||||
<form-model :url="`Clients/${route.params.id}`" model="customer">
|
<form-model :url="`Clients/${route.params.id}`" model="customer">
|
||||||
<template #form="{ data }">
|
<template #form="{ data, validate, filter }">
|
||||||
<div class="row q-gutter-md q-mb-md">
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<q-input
|
<q-input
|
||||||
|
@ -152,7 +126,7 @@ const businessTypes = ref([]);
|
||||||
:label="t('customer.basicData.salesPerson')"
|
:label="t('customer.basicData.salesPerson')"
|
||||||
map-options
|
map-options
|
||||||
use-input
|
use-input
|
||||||
@filter="filterWorkers"
|
@filter="(value, update) => filter(value, update, filterOptions)"
|
||||||
:rules="validate('client.salesPersonFk')"
|
:rules="validate('client.salesPersonFk')"
|
||||||
:input-debounce="0"
|
:input-debounce="0"
|
||||||
>
|
>
|
||||||
|
|
|
@ -34,15 +34,6 @@ export default {
|
||||||
roles: ['claimManager']
|
roles: ['claimManager']
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Claim/ClaimRmaList.vue'),
|
component: () => import('src/pages/Claim/ClaimRmaList.vue'),
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ClaimCreate',
|
|
||||||
path: 'create',
|
|
||||||
meta: {
|
|
||||||
title: 'createClaim',
|
|
||||||
icon: 'vn:addperson',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Claim/ClaimCreate.vue'),
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -76,8 +67,7 @@ export default {
|
||||||
title: 'rma',
|
title: 'rma',
|
||||||
roles: ['claimManager']
|
roles: ['claimManager']
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Claim/Card/ClaimRma.vue'),
|
component: () => import('src/pages/Claim/Card/ClaimRma.vue')
|
||||||
props: { claim: true }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue