Add csv download feature and add descriptors
This commit is contained in:
parent
df00ec99eb
commit
7646934431
|
@ -2,10 +2,17 @@ import { Notify } from 'quasar';
|
||||||
import { i18n } from 'src/boot/i18n';
|
import { i18n } from 'src/boot/i18n';
|
||||||
|
|
||||||
export default function useNotify() {
|
export default function useNotify() {
|
||||||
const notify = (message, type) => {
|
const notify = (message, type, icon) => {
|
||||||
|
const defaultIcons = {
|
||||||
|
warning: 'warning',
|
||||||
|
negative: 'error',
|
||||||
|
positive: 'check',
|
||||||
|
};
|
||||||
|
|
||||||
Notify.create({
|
Notify.create({
|
||||||
message: i18n.global.t(message),
|
message: i18n.global.t(message),
|
||||||
type: type,
|
type: type,
|
||||||
|
icon: icon ? icon : defaultIcons[type],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ export default {
|
||||||
basicData: 'Basic data',
|
basicData: 'Basic data',
|
||||||
},
|
},
|
||||||
noSelectedRows: `You don't have any line selected`,
|
noSelectedRows: `You don't have any line selected`,
|
||||||
|
downloadCSVSuccess: 'CSV downloaded successfully',
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
statusUnauthorized: 'Access denied',
|
statusUnauthorized: 'Access denied',
|
||||||
|
@ -422,6 +423,9 @@ export default {
|
||||||
hasToInvoice: 'Has to Invoice',
|
hasToInvoice: 'Has to Invoice',
|
||||||
verifiedData: 'Verified Data',
|
verifiedData: 'Verified Data',
|
||||||
comercial: 'Comercial',
|
comercial: 'Comercial',
|
||||||
|
errors: {
|
||||||
|
downloadCsvFailed: 'CSV download failed',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shelving: {
|
shelving: {
|
||||||
|
|
|
@ -37,6 +37,7 @@ export default {
|
||||||
basicData: 'Datos básicos',
|
basicData: 'Datos básicos',
|
||||||
},
|
},
|
||||||
noSelectedRows: `No tienes ninguna línea seleccionada`,
|
noSelectedRows: `No tienes ninguna línea seleccionada`,
|
||||||
|
downloadCSVSuccess: 'Descarga de CSV exitosa',
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
statusUnauthorized: 'Acceso denegado',
|
statusUnauthorized: 'Acceso denegado',
|
||||||
|
@ -424,6 +425,9 @@ export default {
|
||||||
hasToInvoice: 'Facturar',
|
hasToInvoice: 'Facturar',
|
||||||
verifiedData: 'Datos comprobados',
|
verifiedData: 'Datos comprobados',
|
||||||
comercial: 'Comercial',
|
comercial: 'Comercial',
|
||||||
|
errors: {
|
||||||
|
downloadCsvFailed: 'Error al descargar CSV',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shelving: {
|
shelving: {
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, computed, ref } from 'vue';
|
import { onMounted, ref, reactive } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
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 invoiceOutService from 'src/services/invoiceOut.service';
|
import invoiceOutService from 'src/services/invoiceOut.service';
|
||||||
import { toCurrency } from 'src/filters';
|
import { toCurrency } from 'src/filters';
|
||||||
import { QBadge, QBtn, exportFile } from 'quasar';
|
import { QBadge, QBtn } from 'quasar';
|
||||||
|
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
|
||||||
import { toDate } from 'src/filters';
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
|
const invoiceOutGlobalStore = useInvoiceOutGlobalStore();
|
||||||
|
|
||||||
const rows = ref([]);
|
const rows = ref([]);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const payload = ref({
|
const dateRange = reactive({
|
||||||
from: Date.vnFirstDayOfMonth(),
|
from: Date.vnFirstDayOfMonth(),
|
||||||
to: Date.vnLastDayOfMonth(),
|
to: Date.vnLastDayOfMonth(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedCustomerId = ref(0);
|
const selectedCustomerId = ref(0);
|
||||||
|
const selectedWorkerId = ref(0);
|
||||||
|
|
||||||
const filter = ref({
|
const filter = ref({
|
||||||
company: null,
|
company: null,
|
||||||
|
@ -35,10 +40,12 @@ const tableColumnComponents = {
|
||||||
company: {
|
company: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: {},
|
props: {},
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
country: {
|
country: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: {},
|
props: {},
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
clientId: {
|
clientId: {
|
||||||
component: QBtn,
|
component: QBtn,
|
||||||
|
@ -48,34 +55,42 @@ const tableColumnComponents = {
|
||||||
client: {
|
client: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: {},
|
props: {},
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: {},
|
props: {},
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
base: {
|
base: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: {},
|
props: {},
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
ticketId: {
|
ticketId: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: {},
|
props: {},
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
active: {
|
active: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: { type: 'boolean' },
|
props: { type: 'boolean' },
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
hasToInvoice: {
|
hasToInvoice: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: { type: 'boolean' },
|
props: { type: 'boolean' },
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
verifiedData: {
|
verifiedData: {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
props: { type: 'boolean' },
|
props: { type: 'boolean' },
|
||||||
|
event: () => {},
|
||||||
},
|
},
|
||||||
comercial: {
|
comercial: {
|
||||||
component: QBtn,
|
component: QBtn,
|
||||||
props: { flat: true, color: 'blue' },
|
props: { flat: true, color: 'blue' },
|
||||||
|
event: (prop) => selectWorkerId(prop.row.comercialId),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,37 +164,8 @@ const columns = ref([
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const wrapCsvValue = (val, formatFn, row) => {
|
const downloadCSV = async () => {
|
||||||
let formatted = formatFn !== void 0 ? formatFn(val, row) : val;
|
invoiceOutGlobalStore.getNegativeBasesCsv(dateRange.from, dateRange.to);
|
||||||
formatted = formatted === void 0 || formatted === null ? '' : String(formatted);
|
|
||||||
formatted = formatted.split('"').join('""');
|
|
||||||
return `"${formatted}"`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const exportTable = () => {
|
|
||||||
const content = [columns.value.map((col) => wrapCsvValue(col.label))]
|
|
||||||
.concat(
|
|
||||||
rows.value.map((row) =>
|
|
||||||
columns.value
|
|
||||||
.map((col) =>
|
|
||||||
wrapCsvValue(
|
|
||||||
typeof col.field === 'function'
|
|
||||||
? col.field(row)
|
|
||||||
: row[col.field === void 0 ? col.name : col.field],
|
|
||||||
col.format,
|
|
||||||
row
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.join(',')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.join('\r\n');
|
|
||||||
|
|
||||||
const status = exportFile('table-export.csv', content, 'text/csv');
|
|
||||||
|
|
||||||
if (status !== true) {
|
|
||||||
console.log('Browser denied file download...');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
|
@ -193,7 +179,7 @@ const search = async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
...payload.value,
|
...dateRange,
|
||||||
filter: {
|
filter: {
|
||||||
limit: 20,
|
limit: 20,
|
||||||
where: { and },
|
where: { and },
|
||||||
|
@ -203,10 +189,8 @@ const search = async () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
payload.value = {
|
dateRange.from = Date.vnFirstDayOfMonth();
|
||||||
from: Date.vnFirstDayOfMonth(),
|
dateRange.to = Date.vnLastDayOfMonth();
|
||||||
to: Date.vnLastDayOfMonth(),
|
|
||||||
};
|
|
||||||
filter.value = {
|
filter.value = {
|
||||||
company: null,
|
company: null,
|
||||||
country: null,
|
country: null,
|
||||||
|
@ -227,6 +211,10 @@ const selectCustomerId = (id) => {
|
||||||
selectedCustomerId.value = id;
|
selectedCustomerId.value = id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const selectWorkerId = (id) => {
|
||||||
|
selectedWorkerId.value = id;
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
refresh();
|
refresh();
|
||||||
});
|
});
|
||||||
|
@ -252,7 +240,7 @@ onMounted(async () => {
|
||||||
placeholder="dd-mm-aaa"
|
placeholder="dd-mm-aaa"
|
||||||
:label="t('invoiceOut.negativeBases.from')"
|
:label="t('invoiceOut.negativeBases.from')"
|
||||||
class="q-mr-md q"
|
class="q-mr-md q"
|
||||||
:model-value="toDate(payload.from)"
|
:model-value="toDate(dateRange.from)"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon name="event" class="cursor-pointer">
|
<QIcon name="event" class="cursor-pointer">
|
||||||
|
@ -261,7 +249,7 @@ onMounted(async () => {
|
||||||
transition-show="scale"
|
transition-show="scale"
|
||||||
transition-hide="scale"
|
transition-hide="scale"
|
||||||
>
|
>
|
||||||
<QDate v-model="payload.from">
|
<QDate v-model="dateRange.from">
|
||||||
<div class="row items-center justify-end">
|
<div class="row items-center justify-end">
|
||||||
<QBtn
|
<QBtn
|
||||||
v-close-popup
|
v-close-popup
|
||||||
|
@ -275,7 +263,6 @@ onMounted(async () => {
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</template>
|
</template>
|
||||||
</QInput>
|
</QInput>
|
||||||
|
|
||||||
<QInput
|
<QInput
|
||||||
dense
|
dense
|
||||||
lazy-rules
|
lazy-rules
|
||||||
|
@ -284,7 +271,7 @@ onMounted(async () => {
|
||||||
placeholder="dd-mm-aaa"
|
placeholder="dd-mm-aaa"
|
||||||
:label="t('invoiceOut.negativeBases.to')"
|
:label="t('invoiceOut.negativeBases.to')"
|
||||||
class="q-mr-md q"
|
class="q-mr-md q"
|
||||||
:model-value="toDate(payload.to)"
|
:model-value="toDate(dateRange.to)"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon name="event" class="cursor-pointer">
|
<QIcon name="event" class="cursor-pointer">
|
||||||
|
@ -293,7 +280,7 @@ onMounted(async () => {
|
||||||
transition-show="scale"
|
transition-show="scale"
|
||||||
transition-hide="scale"
|
transition-hide="scale"
|
||||||
>
|
>
|
||||||
<QDate v-model="payload.to">
|
<QDate v-model="dateRange.to">
|
||||||
<div class="row items-center justify-end">
|
<div class="row items-center justify-end">
|
||||||
<QBtn
|
<QBtn
|
||||||
v-close-popup
|
v-close-popup
|
||||||
|
@ -311,7 +298,7 @@ onMounted(async () => {
|
||||||
color="primary"
|
color="primary"
|
||||||
icon-right="archive"
|
icon-right="archive"
|
||||||
no-caps
|
no-caps
|
||||||
@click="exportTable"
|
@click="downloadCSV()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -384,7 +371,15 @@ onMounted(async () => {
|
||||||
<QIcon name="" size="xs" />
|
<QIcon name="" size="xs" />
|
||||||
</QBadge>
|
</QBadge>
|
||||||
</span>
|
</span>
|
||||||
<CustomerDescriptorProxy :id="selectedCustomerId" />
|
|
||||||
|
<CustomerDescriptorProxy
|
||||||
|
v-if="props.col.name === 'clientId'"
|
||||||
|
:id="selectedCustomerId"
|
||||||
|
/>
|
||||||
|
<WorkerDescriptorProxy
|
||||||
|
v-if="props.col.name === 'comercial'"
|
||||||
|
:id="selectedWorkerId"
|
||||||
|
/>
|
||||||
</component>
|
</component>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -73,8 +73,8 @@ const isAdministrative = computed(() => {
|
||||||
<span class="link">
|
<span class="link">
|
||||||
{{ supplier.worker?.user?.nickname || '-' }}
|
{{ supplier.worker?.user?.nickname || '-' }}
|
||||||
<WorkerDescriptorProxy
|
<WorkerDescriptorProxy
|
||||||
:id="supplier.worker?.user?.id"
|
|
||||||
v-if="supplier.worker?.user?.id"
|
v-if="supplier.worker?.user?.id"
|
||||||
|
:id="supplier.worker?.user?.id"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -21,6 +21,10 @@ const invoiceOutService = {
|
||||||
return await request('GET', 'InvoiceOuts/negativeBases', params);
|
return await request('GET', 'InvoiceOuts/negativeBases', params);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getNegativeBasesCsv: async (params) => {
|
||||||
|
return await request('GET', 'InvoiceOuts/negativeBasesCsv', params);
|
||||||
|
},
|
||||||
|
|
||||||
getInvoiceDate: async (params) => {
|
getInvoiceDate: async (params) => {
|
||||||
return await request('GET', 'InvoiceOuts/getInvoiceDate', params);
|
return await request('GET', 'InvoiceOuts/getInvoiceDate', params);
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { defineStore } from 'pinia';
|
||||||
import { useUserConfig } from 'src/composables/useUserConfig';
|
import { useUserConfig } from 'src/composables/useUserConfig';
|
||||||
import invoiceOutService from 'src/services/invoiceOut.service';
|
import invoiceOutService from 'src/services/invoiceOut.service';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import { exportFile } from 'quasar';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
@ -257,6 +258,26 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
throw err;
|
throw err;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getNegativeBasesCsv(from, to) {
|
||||||
|
try {
|
||||||
|
const params = { from: from, to: to };
|
||||||
|
const CSVResponse = await invoiceOutService.getNegativeBasesCsv(params);
|
||||||
|
|
||||||
|
if (CSVResponse.data && CSVResponse.data.error) throw new Error();
|
||||||
|
|
||||||
|
const status = exportFile('negativeBases.csv', CSVResponse, {
|
||||||
|
encoding: 'windows-1252',
|
||||||
|
mimeType: 'text/csv;charset=windows-1252;',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
notify('globals.downloadCSVSuccess', 'positive');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
notify('invoiceOut.negativeBases.errors.downloadCsvFailed', 'negative');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// State mutations actions
|
// State mutations actions
|
||||||
|
|
||||||
setPrinterValue(printer) {
|
setPrinterValue(printer) {
|
||||||
|
|
Loading…
Reference in New Issue