0
0
Fork 0

Invoice out negative bases refactor

This commit is contained in:
William Buezas 2023-12-15 10:23:57 -03:00
parent 0097d2d7f8
commit 433823c2ac
7 changed files with 230 additions and 174 deletions

View File

@ -24,6 +24,13 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
unremovableParams: {
type: Array,
required: false,
default: () => [],
description:
'Algunos filtros vienen con parametros de búsqueda por default y necesitan tener si o si un valor, por eso de ser necesario, esta prop nos sirve para saber que filtros podemos remover y cuales no',
},
}); });
const emit = defineEmits(['refresh', 'clear', 'search']); const emit = defineEmits(['refresh', 'clear', 'search']);
@ -63,12 +70,25 @@ async function reload() {
} }
async function clearFilters() { async function clearFilters() {
userParams.value = {};
isLoading.value = true; isLoading.value = true;
await arrayData.applyFilter({ params: {} });
if (!props.showAll) store.data = [];
isLoading.value = false;
// Filtrar los params no removibles
const removableFilters = Object.keys(userParams.value).filter((param) =>
props.unremovableParams.includes(param)
);
const newParams = {};
// Conservar solo los params que no son removibles
for (const key of removableFilters) {
newParams[key] = userParams.value[key];
}
userParams.value = { ...newParams }; // Actualizar los params con los removibles
await arrayData.applyFilter({ params: userParams.value });
if (!props.showAll) {
store.data = [];
}
isLoading.value = false;
emit('clear'); emit('clear');
} }
@ -156,7 +176,7 @@ function formatValue(value) {
class="text-dark" class="text-dark"
color="primary" color="primary"
icon="label" icon="label"
removable :removable="!unremovableParams.includes(chip.label)"
size="sm" size="sm"
v-for="chip of tags" v-for="chip of tags"
> >

View File

@ -132,6 +132,7 @@ export function useArrayData(key, userOptions) {
async function applyFilter({ filter, params }) { async function applyFilter({ filter, params }) {
if (filter) store.userFilter = filter; if (filter) store.userFilter = filter;
store.filter = {};
if (params) store.userParams = Object.assign({}, params); if (params) store.userParams = Object.assign({}, params);
await fetch({ append: false }); await fetch({ append: false });
@ -155,7 +156,9 @@ export function useArrayData(key, userOptions) {
delete store.userParams[param]; delete store.userParams[param];
delete params[param]; delete params[param];
if (store.filter?.where) { if (store.filter?.where) {
delete store.filter.where[Object.keys(exprBuilder ? exprBuilder(param) : param)[0]]; delete store.filter.where[
Object.keys(exprBuilder ? exprBuilder(param) : param)[0]
];
if (Object.keys(store.filter.where).length === 0) { if (Object.keys(store.filter.where).length === 0) {
delete store.filter.where; delete store.filter.where;
} }

View File

@ -1,44 +1,54 @@
<script setup> <script setup>
import { onMounted, ref, reactive } from 'vue'; import { ref, computed, onBeforeMount } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { QCheckbox, QBtn } from 'quasar'; import { QCheckbox, QBtn } from 'quasar';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import VnInput from 'src/components/common/VnInput.vue'; import InvoiceOutNegativeFilter from './InvoiceOutNegativeBasesFilter.vue';
import invoiceOutService from 'src/services/invoiceOut.service';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js'; import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
import VnInputDate from 'components/common/VnInputDate.vue'; import { useStateStore } from 'stores/useStateStore';
import { useArrayData } from 'composables/useArrayData';
const invoiceOutGlobalStore = useInvoiceOutGlobalStore(); const invoiceOutGlobalStore = useInvoiceOutGlobalStore();
const stateStore = useStateStore();
const rows = ref([]);
const { t } = useI18n(); const { t } = useI18n();
const dateRange = reactive({ const arrayData = ref(null);
function exprBuilder(param, value) {
switch (param) {
case 'from':
case 'to':
return;
default:
return { [param]: value };
}
}
onBeforeMount(async () => {
const defaultParams = {
from: Date.vnFirstDayOfMonth().toISOString(), from: Date.vnFirstDayOfMonth().toISOString(),
to: Date.vnLastDayOfMonth().toISOString(), to: Date.vnLastDayOfMonth().toISOString(),
};
arrayData.value = useArrayData('InvoiceOutNegative', {
url: 'InvoiceOuts/negativeBases',
limit: 0,
userParams: defaultParams,
exprBuilder: exprBuilder,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
}); });
const rows = computed(() => arrayData.value.store.data);
const selectedCustomerId = ref(0); const selectedCustomerId = ref(0);
const selectedWorkerId = ref(0); const selectedWorkerId = ref(0);
const filter = ref({
company: null,
country: null,
clientId: null,
client: null,
amount: null,
base: null,
ticketId: null,
active: null,
hasToInvoice: null,
verifiedData: null,
comercial: null,
});
const tableColumnComponents = { const tableColumnComponents = {
company: { company: {
component: 'span', component: 'span',
@ -177,52 +187,10 @@ const columns = ref([
]); ]);
const downloadCSV = async () => { const downloadCSV = async () => {
await invoiceOutGlobalStore.getNegativeBasesCsv(dateRange.from, dateRange.to); await invoiceOutGlobalStore.getNegativeBasesCsv(
}; arrayData.value.store.userParams.from,
arrayData.value.store.userParams.to
const search = async () => { );
const and = [];
Object.keys(filter.value).forEach((key) => {
if (filter.value[key]) {
and.push({
[key]: filter.value[key],
});
}
});
const searchFilter = {
limit: 20,
};
if (and.length) {
searchFilter.where = {
and,
};
}
const params = {
...dateRange,
filter: JSON.stringify(searchFilter),
};
rows.value = await invoiceOutService.getNegativeBases(params);
};
const refresh = () => {
dateRange.from = Date.vnFirstDayOfMonth().toISOString();
dateRange.to = Date.vnLastDayOfMonth().toISOString();
filter.value = {
company: null,
country: null,
clientId: null,
client: null,
amount: null,
base: null,
ticketId: null,
active: null,
hasToInvoice: null,
verifiedData: null,
comercial: null,
};
search();
}; };
const selectCustomerId = (id) => { const selectCustomerId = (id) => {
@ -232,82 +200,33 @@ const selectCustomerId = (id) => {
const selectWorkerId = (id) => { const selectWorkerId = (id) => {
selectedWorkerId.value = id; selectedWorkerId.value = id;
}; };
onMounted(async () => {
refresh();
});
</script> </script>
<template> <template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtn color="primary" icon-right="archive" no-caps @click="downloadCSV()" />
</Teleport>
</template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8">
<InvoiceOutNegativeFilter data-key="InvoiceOutNegative" />
</QScrollArea>
</QDrawer>
<QToolbar class="bg-vn-dark">
<div id="st-data"></div>
<QSpace />
<div id="st-actions"></div>
</QToolbar>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<QTable <QTable
:rows="rows"
:columns="columns" :columns="columns"
:rows="rows"
hide-bottom hide-bottom
row-key="clientId" row-key="clientId"
:pagination="{ rowsPerPage: 0 }" :pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md" class="full-width q-mt-md"
> >
<template #top-left>
<div class="row justify-start items-end">
<VnInputDate
v-model="dateRange.from"
:label="t('invoiceOut.negativeBases.from')"
class="q-mr-md"
lazy-rules
is-outlined
/>
<VnInputDate
v-model="dateRange.to"
:label="t('invoiceOut.negativeBases.to')"
class="q-mr-md"
lazy-rules
is-outlined
/>
<QBtn
color="primary"
icon-right="archive"
no-caps
@click="downloadCSV()"
/>
</div>
</template>
<template #top-right>
<div class="row justify-start items-center">
<span class="q-mr-md text-results">
{{ rows.length }} {{ t('results') }}
</span>
<QBtn
color="primary"
icon-right="search"
no-caps
class="q-mr-sm"
@click="search()"
/>
<QBtn color="primary" icon-right="refresh" no-caps @click="refresh" />
</div>
</template>
<template #header="props">
<QTr :props="props" class="full-height">
<QTh v-for="col in props.cols" :key="col.name" :props="props">
<div class="column justify-start items-start full-height">
{{ t(`invoiceOut.negativeBases.${col.label}`) }}
<VnInput
:class="{
invisible:
col.field === 'isActive' ||
col.field === 'hasToInvoice' ||
col.field === 'isTaxDataChecked',
}"
v-model="filter[col.field]"
type="text"
@keyup.enter="search()"
is-outlined
/>
</div>
</QTh>
</QTr>
</template>
<template #body-cell="props"> <template #body-cell="props">
<QTd :props="props"> <QTd :props="props">
<component <component
@ -324,14 +243,8 @@ onMounted(async () => {
" "
>{{ props.value }} >{{ props.value }}
</template> </template>
<CustomerDescriptorProxy <CustomerDescriptorProxy :id="selectedCustomerId" />
v-if="props.col.name === 'clientId'" <WorkerDescriptorProxy :id="selectedWorkerId" />
:id="selectedCustomerId"
/>
<WorkerDescriptorProxy
v-if="props.col.name === 'comercial'"
:id="selectedWorkerId"
/>
</component> </component>
</QTd> </QTd>
</template> </template>
@ -344,10 +257,6 @@ onMounted(async () => {
border-radius: 4px; border-radius: 4px;
padding: 6px 6px 6px 6px; padding: 6px 6px 6px 6px;
} }
.text-results {
color: var(--vn-label);
}
</style> </style>
<i18n></i18n> <i18n></i18n>

View File

@ -0,0 +1,134 @@
<script setup>
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
</script>
<template>
<VnFilterPanel
:data-key="props.dataKey"
:search-button="true"
:unremovable-params="['from', 'to']"
>
<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 }">
<QList dense class="q-gutter-y-sm q-mt-sm">
<QItem>
<QItemSection>
<VnInputDate
v-model="params.from"
:label="t('invoiceOut.negativeBases.from')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate
v-model="params.to"
:label="t('invoiceOut.negativeBases.to')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.company"
:label="t('invoiceOut.negativeBases.company')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.country"
:label="t('invoiceOut.negativeBases.country')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.clientId"
:label="t('invoiceOut.negativeBases.clientId')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.clientSocialName"
:label="t('invoiceOut.negativeBases.client')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.amount"
:label="t('invoiceOut.negativeBases.amount')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.comercialName"
:label="t('invoiceOut.negativeBases.comercial')"
is-outlined
/>
</QItemSection>
</QItem>
</QList>
</template>
</VnFilterPanel>
</template>
<style scoped></style>
<i18n>
en:
params:
from: From
to: To
company: Company
country: Country
clientId: Client Id
clientSocialName: Client
amount: Amount
comercialName: Comercial
es:
params:
from: Desde
to: Hasta
company: Empresa
country: País
clientId: Id cliente
clientSocialName: Cliente
amount: Importe
comercialName: Comercial
Date is required: La fecha es requerida
</i18n>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { reactive } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
@ -17,15 +17,9 @@ const props = defineProps({
}, },
}); });
const filtersOptions = reactive({ const warehousesOptions = ref([]);
warehouses: [], const continentsOptions = ref([]);
continents: [], const agenciesOptions = ref([]);
agencies: [],
});
const updateFilterOptions = (data, optionKey) => {
filtersOptions[optionKey] = [...data];
};
const add = (paramsObj, key) => { const add = (paramsObj, key) => {
if (paramsObj[key] === undefined) { if (paramsObj[key] === undefined) {
@ -45,17 +39,17 @@ const decrement = (paramsObj, key) => {
<template> <template>
<FetchData <FetchData
url="Warehouses" url="Warehouses"
@on-fetch="(data) => updateFilterOptions(data, 'warehouses')" @on-fetch="(data) => (warehousesOptions = data)"
auto-load auto-load
/> />
<FetchData <FetchData
url="Continents" url="Continents"
@on-fetch="(data) => updateFilterOptions(data, 'continents')" @on-fetch="(data) => (continentsOptions = data)"
auto-load auto-load
/> />
<FetchData <FetchData
url="AgencyModes" url="AgencyModes"
@on-fetch="(data) => updateFilterOptions(data, 'agencies')" @on-fetch="(data) => (agenciesOptions = data)"
auto-load auto-load
/> />
@ -82,7 +76,7 @@ const decrement = (paramsObj, key) => {
<VnSelectFilter <VnSelectFilter
:label="t('params.agencyModeFk')" :label="t('params.agencyModeFk')"
v-model="params.agencyModeFk" v-model="params.agencyModeFk"
:options="filtersOptions.agencies" :options="agenciesOptions"
option-value="agencyFk" option-value="agencyFk"
option-label="name" option-label="name"
hide-selected hide-selected
@ -97,7 +91,7 @@ const decrement = (paramsObj, key) => {
<VnSelectFilter <VnSelectFilter
:label="t('params.warehouseOutFk')" :label="t('params.warehouseOutFk')"
v-model="params.warehouseOutFk" v-model="params.warehouseOutFk"
:options="filtersOptions.warehouses" :options="warehousesOptions"
option-value="id" option-value="id"
option-label="name" option-label="name"
hide-selected hide-selected
@ -112,7 +106,7 @@ const decrement = (paramsObj, key) => {
<VnSelectFilter <VnSelectFilter
:label="t('params.warehouseInFk')" :label="t('params.warehouseInFk')"
v-model="params.warehouseInFk" v-model="params.warehouseInFk"
:options="filtersOptions.warehouses" :options="warehousesOptions"
option-value="id" option-value="id"
option-label="name" option-label="name"
hide-selected hide-selected
@ -223,7 +217,7 @@ const decrement = (paramsObj, key) => {
<VnSelectFilter <VnSelectFilter
:label="t('params.continent')" :label="t('params.continent')"
v-model="params.continent" v-model="params.continent"
:options="filtersOptions.continents" :options="continentsOptions"
option-value="code" option-value="code"
option-label="name" option-label="name"
hide-selected hide-selected

View File

@ -8,9 +8,9 @@ import VnPaginate from 'src/components/ui/VnPaginate.vue';
import CardList from 'src/components/ui/CardList.vue'; import CardList from 'src/components/ui/CardList.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import TravelSummaryDialog from './Card/TravelSummaryDialog.vue'; import TravelSummaryDialog from './Card/TravelSummaryDialog.vue';
import TravelFilter from './TravelFilter.vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import TravelFilter from './TravelFilter.vue';
import { toDate } from 'src/filters/index'; import { toDate } from 'src/filters/index';
const router = useRouter(); const router = useRouter();

View File

@ -17,10 +17,6 @@ const request = async (method, url, params = {}) => {
}; };
const invoiceOutService = { const invoiceOutService = {
getNegativeBases: async (params) => {
return await request('GET', 'InvoiceOuts/negativeBases', params);
},
getNegativeBasesCsv: async (params) => { getNegativeBasesCsv: async (params) => {
return await request('GET', 'InvoiceOuts/negativeBasesCsv', params); return await request('GET', 'InvoiceOuts/negativeBasesCsv', params);
}, },