Add filter
This commit is contained in:
parent
9c7c98d64d
commit
fcce2b5070
|
@ -1,24 +1,28 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, computed } from 'vue';
|
||||
import { ref, computed, onMounted, onBeforeMount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import ItemRequestDenyForm from './ItemRequestDenyForm.vue';
|
||||
import ItemRequestFilter from './ItemRequestFilter.vue';
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { toDateFormat } from 'src/filters/date';
|
||||
import { toCurrency } from 'filters/index';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { notify } = useNotify();
|
||||
const stateStore = useStateStore();
|
||||
|
||||
let filterParams = ref({});
|
||||
const denyFormRef = ref(null);
|
||||
const denyRequestId = ref(null);
|
||||
const denyRequestIndex = ref(null);
|
||||
|
@ -169,118 +173,182 @@ const onDenyAccept = (_, responseData) => {
|
|||
denyRequestIndex.value = null;
|
||||
};
|
||||
|
||||
onMounted(async () => {});
|
||||
onMounted(async () => {
|
||||
stateStore.rightDrawer = true;
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
const today = Date.vnNew();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const nextWeek = Date.vnNew();
|
||||
nextWeek.setHours(23, 59, 59, 59);
|
||||
nextWeek.setDate(nextWeek.getDate() + 7);
|
||||
|
||||
filterParams.value = {
|
||||
from: today,
|
||||
to: nextWeek,
|
||||
state: 'pending',
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
url="TicketRequests/filter"
|
||||
:filter="{ order: ['shippedDate ASC', 'isOk ASC'] }"
|
||||
auto-load
|
||||
@on-fetch="(data) => (itemRequestsOptions = data)"
|
||||
/>
|
||||
<template v-if="stateStore.isHeaderMounted()">
|
||||
<Teleport to="#searchbar">
|
||||
<VnSearchbar
|
||||
data-key="ItemRequests"
|
||||
url="TicketRequests/filter"
|
||||
:label="t('globals.search')"
|
||||
:info="t('You can search by Id or alias')"
|
||||
:redirect="false"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
<template v-if="stateStore.isHeaderMounted()">
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<ItemRequestFilter data-key="ItemRequests" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<QTable
|
||||
:rows="itemRequestsOptions"
|
||||
:columns="columns"
|
||||
row-key="id"
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
class="full-width q-mt-md"
|
||||
:no-data-label="t('globals.noResults')"
|
||||
<VnPaginate
|
||||
ref="paginateRef"
|
||||
data-key="ItemRequests"
|
||||
url="TicketRequests/filter"
|
||||
:order="['shippedDate ASC', 'isOk ASC']"
|
||||
:user-params="filterParams"
|
||||
:limit="12"
|
||||
:offset="50"
|
||||
auto-load
|
||||
>
|
||||
<template #body-cell-id="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat color="primary"> {{ row.id }}</QBtn>
|
||||
<TicketDescriptorProxy :id="row.id" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body="{ rows }">
|
||||
<QTable
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
row-key="id"
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
class="full-width q-mt-md"
|
||||
:no-data-label="t('globals.noResults')"
|
||||
>
|
||||
<template #body-cell-id="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat color="primary"> {{ row.ticketFk }}</QBtn>
|
||||
<TicketDescriptorProxy :id="row.ticketFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
|
||||
<template #body-cell-shipped="{ row }">
|
||||
<QTd>
|
||||
<QBadge
|
||||
v-if="getDateQBadgeColor(row.shipped)"
|
||||
:color="getDateQBadgeColor(row.shipped)"
|
||||
text-color="black"
|
||||
class="q-ma-none"
|
||||
dense
|
||||
style="font-size: 14px"
|
||||
>
|
||||
{{ toDateFormat(row.shipped) }}
|
||||
</QBadge>
|
||||
<span v-else>{{ toDateFormat(row.shipped) }}</span>
|
||||
</QTd>
|
||||
<template #body-cell-shipped="{ row }">
|
||||
<QTd>
|
||||
<QBadge
|
||||
v-if="getDateQBadgeColor(row.shipped)"
|
||||
:color="getDateQBadgeColor(row.shipped)"
|
||||
text-color="black"
|
||||
class="q-ma-none"
|
||||
dense
|
||||
style="font-size: 14px"
|
||||
>
|
||||
{{ toDateFormat(row.shipped) }}
|
||||
</QBadge>
|
||||
<span v-else>{{ toDateFormat(row.shipped) }}</span>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-requester="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat dense color="primary">
|
||||
{{ row.requesterName }}</QBtn
|
||||
>
|
||||
<WorkerDescriptorProxy :id="row.requesterFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-attender="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat dense color="primary">
|
||||
{{ row.attenderName }}</QBtn
|
||||
>
|
||||
<WorkerDescriptorProxy :id="row.attenderFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-item="{ row }">
|
||||
<QTd>
|
||||
<VnInput
|
||||
class="dense"
|
||||
v-model.number="row.itemFk"
|
||||
type="number"
|
||||
:disable="row.isOk != null"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-achieved="{ row }">
|
||||
<QTd>
|
||||
<VnInput
|
||||
class="dense"
|
||||
v-model.number="row.saleQuantity"
|
||||
@change="changeQuantity(row)"
|
||||
type="number"
|
||||
:disable="!row.itemFk || row.isOk != null"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-concept="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat dense color="primary">
|
||||
{{ row.itemDescription }}</QBtn
|
||||
>
|
||||
<ItemDescriptorProxy :id="row.itemFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-state="{ row }">
|
||||
<QTd>
|
||||
<span>{{ getState(row.isOk) }}</span>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-action="{ row, rowIndex }">
|
||||
<QTd>
|
||||
<QIcon
|
||||
v-if="row.response?.length"
|
||||
name="insert_drive_file"
|
||||
color="primary"
|
||||
size="sm"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ row.response }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="row.isOk == null"
|
||||
name="thumb_down"
|
||||
color="primary"
|
||||
size="sm"
|
||||
class="cursor-pointer"
|
||||
@click="showDenyRequestForm(row.id, rowIndex)"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Discard') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
<template #body-cell-requester="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat dense color="primary"> {{ row.requesterName }}</QBtn>
|
||||
<WorkerDescriptorProxy :id="row.requesterFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-attender="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat dense color="primary"> {{ row.attenderName }}</QBtn>
|
||||
<WorkerDescriptorProxy :id="row.attenderFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-item="{ row }">
|
||||
<QTd>
|
||||
<VnInput
|
||||
class="dense"
|
||||
v-model.number="row.itemFk"
|
||||
type="number"
|
||||
:disable="row.isOk != null"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-achieved="{ row }">
|
||||
<QTd>
|
||||
<VnInput
|
||||
class="dense"
|
||||
v-model.number="row.saleQuantity"
|
||||
@change="changeQuantity(row)"
|
||||
type="number"
|
||||
:disable="!row.itemFk || row.isOk != null"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-concept="{ row }">
|
||||
<QTd>
|
||||
<QBtn flat dense color="primary"> {{ row.itemDescription }}</QBtn>
|
||||
<ItemDescriptorProxy :id="row.itemFk" />
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-state="{ row }">
|
||||
<QTd>
|
||||
<span>{{ getState(row.isOk) }}</span>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-action="{ row, rowIndex }">
|
||||
<QTd>
|
||||
<QIcon
|
||||
v-if="row.response?.length"
|
||||
name="insert_drive_file"
|
||||
color="primary"
|
||||
size="sm"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ row.response }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="row.isOk == null"
|
||||
name="thumb_down"
|
||||
color="primary"
|
||||
size="sm"
|
||||
class="cursor-pointer"
|
||||
@click="showDenyRequestForm(row.id, rowIndex)"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Discard') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
</VnPaginate>
|
||||
|
||||
<QDialog ref="denyFormRef" transition-show="scale" transition-hide="scale">
|
||||
<ItemRequestDenyForm
|
||||
:request-id="denyRequestId"
|
||||
|
@ -293,4 +361,5 @@ onMounted(async () => {});
|
|||
<i18n>
|
||||
es:
|
||||
Discard: Descartar
|
||||
You can search by Id or alias: Buscar peticiones por identificador o alias
|
||||
</i18n>
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
dataKey: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const stateOptions = [
|
||||
{ code: 'pending', name: t('Pending') },
|
||||
{ code: 'accepted', name: t('Accepted') },
|
||||
{ code: 'denied', name: t('Denied') },
|
||||
];
|
||||
|
||||
const itemTypesOptions = ref([]);
|
||||
const warehousesOptions = ref([]);
|
||||
const workersOptions = ref([]);
|
||||
|
||||
const exprBuilder = (param, value) => {
|
||||
switch (param) {
|
||||
case 'ticketFk':
|
||||
case 'quantity':
|
||||
case 'price':
|
||||
case 'isOk':
|
||||
return { [`tr.${param}`]: value };
|
||||
case 'attenderName':
|
||||
return { [`ua.name`]: value };
|
||||
case 'shipped':
|
||||
return {
|
||||
't.shipped': {
|
||||
between: dateRange(value),
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const dateRange = (value) => {
|
||||
const minHour = new Date(value);
|
||||
minHour.setHours(0, 0, 0, 0);
|
||||
const maxHour = new Date(value);
|
||||
maxHour.setHours(23, 59, 59, 59);
|
||||
|
||||
return [minHour, maxHour];
|
||||
};
|
||||
|
||||
const add = (paramsObj, key) => {
|
||||
if (paramsObj[key] === undefined) {
|
||||
paramsObj[key] = 1;
|
||||
} else {
|
||||
paramsObj[key]++;
|
||||
}
|
||||
};
|
||||
|
||||
const decrement = (paramsObj, key) => {
|
||||
if (paramsObj[key] === 0) return;
|
||||
|
||||
paramsObj[key]--;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
url="TicketRequests/getItemTypeWorker"
|
||||
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC' }"
|
||||
@on-fetch="(data) => (itemTypesOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="warehouses"
|
||||
:filter="{ order: 'name ASC' }"
|
||||
@on-fetch="(data) => (warehousesOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Workers/search"
|
||||
:filter="{
|
||||
fields: ['id', 'name'],
|
||||
order: 'name ASC',
|
||||
}"
|
||||
:params="{
|
||||
departmentCodes: ['VT'],
|
||||
}"
|
||||
@on-fetch="(data) => (workersOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<VnFilterPanel
|
||||
:data-key="props.dataKey"
|
||||
:search-button="true"
|
||||
:expr-builder="exprBuilder"
|
||||
>
|
||||
<template #tags="{ tag, formatFn }">
|
||||
<div class="q-gutter-x-xs">
|
||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
||||
<span>{{ formatFn(tag.value) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.search"
|
||||
:label="t('params.search')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.ticketFk"
|
||||
:label="t('params.ticketFk')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelectFilter
|
||||
v-model="params.attenderFk"
|
||||
:label="t('params.attenderFk')"
|
||||
@update:model-value="searchFn()"
|
||||
:options="itemTypesOptions"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.clientFk"
|
||||
:label="t('params.clientFk')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelectFilter
|
||||
:label="t('params.warehouseFk')"
|
||||
v-model="params.warehouseFk"
|
||||
@update:model-value="searchFn()"
|
||||
:options="warehousesOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelectFilter
|
||||
:label="t('params.requesterFk')"
|
||||
v-model="params.requesterFk"
|
||||
@update:model-value="searchFn()"
|
||||
:options="workersOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||
<QItemLabel caption
|
||||
>{{ scope.opt?.nickname }},
|
||||
{{ scope.opt?.code }}</QItemLabel
|
||||
>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('params.from')"
|
||||
v-model="params.from"
|
||||
@update:model-value="searchFn()"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('params.to')"
|
||||
v-model="params.to"
|
||||
@update:model-value="searchFn()"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.scopeDays"
|
||||
:label="t('params.scopeDays')"
|
||||
type="number"
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
:min="0"
|
||||
>
|
||||
<template #append>
|
||||
<QBtn
|
||||
icon="add"
|
||||
flat
|
||||
dense
|
||||
size="12px"
|
||||
@click="add(params, 'scopeDays')"
|
||||
/>
|
||||
<QBtn
|
||||
icon="remove"
|
||||
flat
|
||||
dense
|
||||
size="12px"
|
||||
@click="decrement(params, 'scopeDays')"
|
||||
/>
|
||||
</template>
|
||||
</VnInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<!-- <vn-icon color-marginal
|
||||
icon="info"
|
||||
vn-tooltip="Cannot choose a range of dates and days onward at the same time">
|
||||
</vn-icon> -->
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
:label="t('params.mine')"
|
||||
v-model="params.mine"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelectFilter
|
||||
:label="t('params.state')"
|
||||
v-model="params.state"
|
||||
@update:model-value="searchFn()"
|
||||
:options="stateOptions"
|
||||
option-value="code"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
en:
|
||||
params:
|
||||
search: General search
|
||||
ticketFk: Ticket id
|
||||
attenderFk: Atender
|
||||
clientFk: Client id
|
||||
warehouseFk: Warehouse
|
||||
requesterFk: Salesperson
|
||||
from: From
|
||||
to: To
|
||||
scopeDays: Days onward
|
||||
mine: For me
|
||||
state: State
|
||||
|
||||
es:
|
||||
params:
|
||||
search: Búsqueda general
|
||||
ticketFk: Id ticket
|
||||
attenderFk: Comprador
|
||||
clientFk: Id cliente
|
||||
warehouseFk: Almacén
|
||||
requesterFk: Comercial
|
||||
from: Desde
|
||||
to: Hasta
|
||||
scopeDays: Días adelante
|
||||
mine: Para mi
|
||||
state: Estado
|
||||
</i18n>
|
Loading…
Reference in New Issue