refactor: refs #6899 end invoiceOut migration with VnTable
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
parent
f78ae08550
commit
cdbbd576e3
|
@ -46,22 +46,6 @@ const onDataSaved = async (formData, requestResponse) => {
|
||||||
@on-fetch="(data) => (taxAreasOptions = data)"
|
@on-fetch="(data) => (taxAreasOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FetchData
|
|
||||||
url="Tickets"
|
|
||||||
:filter="{
|
|
||||||
fields: ['id', 'nickname'],
|
|
||||||
where: { refFk: null },
|
|
||||||
order: 'shipped DESC',
|
|
||||||
}"
|
|
||||||
@on-fetch="(data) => (ticketsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
url="Clients"
|
|
||||||
:filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
|
|
||||||
@on-fetch="(data) => (clientsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FormModelPopup
|
<FormModelPopup
|
||||||
ref="formModelPopupRef"
|
ref="formModelPopupRef"
|
||||||
:title="t('Create manual invoice')"
|
:title="t('Create manual invoice')"
|
||||||
|
@ -84,6 +68,10 @@ const onDataSaved = async (formData, requestResponse) => {
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="data.ticketFk"
|
v-model="data.ticketFk"
|
||||||
@update:model-value="data.clientFk = null"
|
@update:model-value="data.clientFk = null"
|
||||||
|
url="Tickets"
|
||||||
|
:where="{ refFk: null }"
|
||||||
|
:fields="['id', 'nickname']"
|
||||||
|
:filter-options="{ order: 'shipped DESC' }"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -105,6 +93,9 @@ const onDataSaved = async (formData, requestResponse) => {
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="data.clientFk"
|
v-model="data.clientFk"
|
||||||
@update:model-value="data.ticketFk = null"
|
@update:model-value="data.ticketFk = null"
|
||||||
|
url="Clients"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
:filter-options="{ order: 'name ASC' }"
|
||||||
/>
|
/>
|
||||||
<VnInputDate :label="t('Max date')" v-model="data.maxShipped" />
|
<VnInputDate :label="t('Max date')" v-model="data.maxShipped" />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
@ -116,7 +107,6 @@ const onDataSaved = async (formData, requestResponse) => {
|
||||||
option-label="description"
|
option-label="description"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
v-model="data.serial"
|
v-model="data.serial"
|
||||||
:required="true"
|
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Area')"
|
:label="t('Area')"
|
||||||
|
@ -125,7 +115,6 @@ const onDataSaved = async (formData, requestResponse) => {
|
||||||
option-label="code"
|
option-label="code"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
v-model="data.taxArea"
|
v-model="data.taxArea"
|
||||||
:required="true"
|
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow class="row q-gutter-md q-mb-md">
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
|
|
@ -8,7 +8,7 @@ import VnRow from 'components/ui/VnRow.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
import FormPopup from './FormPopup.vue';
|
import FormPopup from './FormPopup.vue';
|
||||||
|
import { useDialogPluginComponent } from 'quasar';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ const $props = defineProps({
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const { dialogRef } = useDialogPluginComponent();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -70,14 +70,11 @@ const makeInvoice = async () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (!response) {
|
if (!response) {
|
||||||
console.log('entra cuando no checkbox');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('params: ', params);
|
|
||||||
const { data } = await axios.post('InvoiceOuts/transferInvoice', params);
|
const { data } = await axios.post('InvoiceOuts/transferInvoice', params);
|
||||||
console.log('data: ', data);
|
|
||||||
notify(t('Transferred invoice'), 'positive');
|
notify(t('Transferred invoice'), 'positive');
|
||||||
const id = data?.[0];
|
const id = data?.[0];
|
||||||
if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
|
if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
|
||||||
|
@ -119,90 +116,92 @@ const makeInvoice = async () => {
|
||||||
@on-fetch="(data) => (invoiceCorrectionTypesOptions = data)"
|
@on-fetch="(data) => (invoiceCorrectionTypesOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FormPopup
|
<QDialog ref="dialogRef">
|
||||||
|
<FormPopup
|
||||||
@on-submit="makeInvoice()"
|
@on-submit="makeInvoice()"
|
||||||
:title="t('Transfer invoice')"
|
:title="t('Transfer invoice')"
|
||||||
:custom-submit-button-label="t('Transfer client')"
|
:custom-submit-button-label="t('Transfer client')"
|
||||||
:default-cancel-button="false"
|
:default-cancel-button="false"
|
||||||
>
|
>
|
||||||
<template #form-inputs>
|
<template #form-inputs>
|
||||||
<VnRow class="row q-gutter-md q-mb-md">
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Client')"
|
:label="t('Client')"
|
||||||
:options="clientsOptions"
|
:options="clientsOptions"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="transferInvoiceParams.newClientFk"
|
v-model="transferInvoiceParams.newClientFk"
|
||||||
:required="true"
|
:required="true"
|
||||||
url="Clients"
|
url="Clients"
|
||||||
:fields="['id', 'name', 'hasToInvoiceByAddress']"
|
:fields="['id', 'name', 'hasToInvoiceByAddress']"
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem
|
<QItem
|
||||||
v-bind="scope.itemProps"
|
v-bind="scope.itemProps"
|
||||||
@click="selectedClient(scope.opt)"
|
@click="selectedClient(scope.opt)"
|
||||||
>
|
>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QItemLabel>
|
<QItemLabel>
|
||||||
#{{ scope.opt?.id }} - {{ scope.opt?.name }}
|
#{{ scope.opt?.id }} - {{ scope.opt?.name }}
|
||||||
</QItemLabel>
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
</VnSelect>
|
</VnSelect>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Rectificative type')"
|
:label="t('Rectificative type')"
|
||||||
:options="rectificativeTypeOptions"
|
:options="rectificativeTypeOptions"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="description"
|
option-label="description"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="transferInvoiceParams.cplusRectificationTypeFk"
|
v-model="transferInvoiceParams.cplusRectificationTypeFk"
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow class="row q-gutter-md q-mb-md">
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Class')"
|
:label="t('Class')"
|
||||||
:options="siiTypeInvoiceOutsOptions"
|
:options="siiTypeInvoiceOutsOptions"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="description"
|
option-label="description"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="transferInvoiceParams.siiTypeInvoiceOutFk"
|
v-model="transferInvoiceParams.siiTypeInvoiceOutFk"
|
||||||
:required="true"
|
:required="true"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QItemLabel>
|
<QItemLabel>
|
||||||
{{ scope.opt?.code }} -
|
{{ scope.opt?.code }} -
|
||||||
{{ scope.opt?.description }}
|
{{ scope.opt?.description }}
|
||||||
</QItemLabel>
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
</VnSelect>
|
</VnSelect>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Type')"
|
:label="t('Type')"
|
||||||
:options="invoiceCorrectionTypesOptions"
|
:options="invoiceCorrectionTypesOptions"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="description"
|
option-label="description"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="transferInvoiceParams.invoiceCorrectionTypeFk"
|
v-model="transferInvoiceParams.invoiceCorrectionTypeFk"
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow class="row q-gutter-md q-mb-md">
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
<div>
|
<div>
|
||||||
<QCheckbox :label="t('Bill destination client')" v-model="checked" />
|
<QCheckbox :label="t('Bill destination client')" v-model="checked" />
|
||||||
<QIcon name="info" class="cursor-info q-ml-sm" size="sm">
|
<QIcon name="info" class="cursor-info q-ml-sm" size="sm">
|
||||||
<QTooltip>{{ t('transferInvoiceInfo') }}</QTooltip>
|
<QTooltip>{{ t('transferInvoiceInfo') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</div>
|
</div>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</template>
|
</template>
|
||||||
</FormPopup>
|
</FormPopup>
|
||||||
|
</QDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -59,6 +59,10 @@ const $props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
hasSubtoolbar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
|
@ -177,9 +181,12 @@ function columnName(col) {
|
||||||
function getColAlign(col) {
|
function getColAlign(col) {
|
||||||
return 'text-' + (col.align ?? 'left')
|
return 'text-' + (col.align ?? 'left')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||||
defineExpose({
|
defineExpose({
|
||||||
reload,
|
reload,
|
||||||
redirect: redirectFn,
|
redirect: redirectFn,
|
||||||
|
selected
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -225,11 +232,14 @@ defineExpose({
|
||||||
:search-url="searchUrl"
|
:search-url="searchUrl"
|
||||||
:disable-infinite-scroll="mode == TABLE_MODE"
|
:disable-infinite-scroll="mode == TABLE_MODE"
|
||||||
@save-changes="reload"
|
@save-changes="reload"
|
||||||
:has-subtoolbar="isEditable"
|
:has-subtoolbar="$attrs['hasSubtoolbar'] ?? isEditable"
|
||||||
>
|
>
|
||||||
|
<template v-for="(_, slotName) in $slots" #[slotName]="slotData" :key="slotName">
|
||||||
|
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
|
||||||
|
</template>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<QTable
|
<QTable
|
||||||
v-bind="$attrs['QTable']"
|
v-bind="$attrs['q-table']"
|
||||||
class="vnTable"
|
class="vnTable"
|
||||||
:columns="splittedColumns.columns"
|
:columns="splittedColumns.columns"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
|
@ -246,6 +256,7 @@ defineExpose({
|
||||||
CrudModelRef.vnPaginateRef.paginate()
|
CrudModelRef.vnPaginateRef.paginate()
|
||||||
"
|
"
|
||||||
@row-click="(_, row) => rowClickFunction(row)"
|
@row-click="(_, row) => rowClickFunction(row)"
|
||||||
|
@update:selected="$emit('update:selected', $event)"
|
||||||
>
|
>
|
||||||
<template #top-left>
|
<template #top-left>
|
||||||
<slot name="top-left"></slot>
|
<slot name="top-left"></slot>
|
||||||
|
@ -477,6 +488,7 @@ defineExpose({
|
||||||
default="input"
|
default="input"
|
||||||
v-model="data[column.name]"
|
v-model="data[column.name]"
|
||||||
:show-label="true"
|
:show-label="true"
|
||||||
|
component-prop="columnCreate"
|
||||||
/>
|
/>
|
||||||
<slot name="more-create-dialog" :data="data" />
|
<slot name="more-create-dialog" :data="data" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -46,6 +46,7 @@ let arrayData;
|
||||||
let store;
|
let store;
|
||||||
let entity;
|
let entity;
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
const menuRef = ref({});
|
||||||
|
|
||||||
defineExpose({ getData });
|
defineExpose({ getData });
|
||||||
|
|
||||||
|
@ -127,9 +128,9 @@ const emit = defineEmits(['onFetch']);
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
{{ t('components.cardDescriptor.moreOptions') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
<QMenu>
|
<QMenu ref="menuRef">
|
||||||
<QList>
|
<QList>
|
||||||
<slot name="menu" :entity="entity" />
|
<slot name="menu" :entity="entity" :menu-ref="menuRef" />
|
||||||
</QList>
|
</QList>
|
||||||
</QMenu>
|
</QMenu>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
|
|
@ -63,8 +63,8 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
data-key="invoiceOutData"
|
data-key="invoiceOutData"
|
||||||
>
|
>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity, menuRef }">
|
||||||
<InvoiceOutDescriptorMenu :invoice-out-data="entity" />
|
<InvoiceOutDescriptorMenu :invoice-out-data="entity" :menu-ref="menuRef" />
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" />
|
<VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref, onBeforeMount } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
@ -11,13 +11,20 @@ import useNotify from 'src/composables/useNotify';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import { usePrintService } from 'composables/usePrintService';
|
import { usePrintService } from 'composables/usePrintService';
|
||||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
|
import { getUrl } from 'src/composables/getUrl';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
|
onBeforeMount(async () => (salixUrl.value = await getUrl('')));
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
invoiceOutData: {
|
invoiceOutData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
menuRef: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
@ -28,8 +35,7 @@ const { t } = useI18n();
|
||||||
const { openReport, sendEmail } = usePrintService();
|
const { openReport, sendEmail } = usePrintService();
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
const salixUrl = ref();
|
||||||
const transferInvoiceDialogRef = ref();
|
|
||||||
const invoiceFormType = ref('pdf');
|
const invoiceFormType = ref('pdf');
|
||||||
const defaultEmailAddress = ref($props.invoiceOutData.client?.email);
|
const defaultEmailAddress = ref($props.invoiceOutData.client?.email);
|
||||||
|
|
||||||
|
@ -115,6 +121,7 @@ const refundInvoice = async (withWarehouse) => {
|
||||||
try {
|
try {
|
||||||
const params = { ref: $props.invoiceOutData.ref, withWarehouse: withWarehouse };
|
const params = { ref: $props.invoiceOutData.ref, withWarehouse: withWarehouse };
|
||||||
const { data } = await axios.post('InvoiceOuts/refund', params);
|
const { data } = await axios.post('InvoiceOuts/refund', params);
|
||||||
|
location.href = `${salixUrl.value}ticket/${data[0].id}/sale`;
|
||||||
notify(
|
notify(
|
||||||
t('refundInvoiceSuccessMessage', {
|
t('refundInvoiceSuccessMessage', {
|
||||||
refundTicket: data[0].id,
|
refundTicket: data[0].id,
|
||||||
|
@ -125,11 +132,21 @@ const refundInvoice = async (withWarehouse) => {
|
||||||
console.error('Error generating invoice out pdf', err);
|
console.error('Error generating invoice out pdf', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showTransferInvoiceForm = async () => {
|
||||||
|
$props.menuRef.hide();
|
||||||
|
quasar.dialog({
|
||||||
|
component: TransferInvoiceForm,
|
||||||
|
componentProps: {
|
||||||
|
invoiceOutData: $props.invoiceOutData,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QItem v-ripple clickable @click="transferInvoiceDialogRef.show()">
|
<QItem v-ripple clickable>
|
||||||
<QItemSection>{{ t('Transfer invoice to...') }}</QItemSection>
|
<QItemSection @click="showTransferInvoiceForm()">{{ t('Transfer invoice to...') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem v-ripple clickable>
|
<QItem v-ripple clickable>
|
||||||
<QItemSection>{{ t('Show invoice...') }}</QItemSection>
|
<QItemSection>{{ t('Show invoice...') }}</QItemSection>
|
||||||
|
@ -222,10 +239,6 @@ const refundInvoice = async (withWarehouse) => {
|
||||||
{{ t('Create a single ticket with all the content of the current invoice') }}
|
{{ t('Create a single ticket with all the content of the current invoice') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
|
||||||
<QDialog ref="transferInvoiceDialogRef">
|
|
||||||
<TransferInvoiceForm :invoice-out-data="invoiceOutData" />
|
|
||||||
</QDialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { onMounted, ref, computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { toCurrency, toDate } from 'src/filters';
|
import { toCurrency, toDate, toPercentage } from 'src/filters';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import { getUrl } from 'src/composables/getUrl';
|
import { getUrl } from 'src/composables/getUrl';
|
||||||
|
@ -57,12 +57,14 @@ const taxColumns = ref([
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
label: 'invoiceOut.summary.rate',
|
label: 'invoiceOut.summary.rate',
|
||||||
field: (row) => row.rate,
|
field: (row) => row.rate,
|
||||||
|
format: (value) => toPercentage(value / 100),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'invoiceOuted',
|
name: 'invoiceOuted',
|
||||||
label: 'invoiceOut.summary.fee',
|
label: 'invoiceOut.summary.fee',
|
||||||
field: (row) => row.vat,
|
field: (row) => row.vat,
|
||||||
|
format: (value) => toCurrency(value),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
@ -164,7 +166,7 @@ const ticketsColumns = ref([
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-item="{ value }">
|
<template #body-cell-item="{ value }">
|
||||||
<QTd>
|
<QTd>
|
||||||
<QBtn flat color="primary">
|
<QBtn flat class="link">
|
||||||
{{ value }}
|
{{ value }}
|
||||||
<TicketDescriptorProxy :id="value" />
|
<TicketDescriptorProxy :id="value" />
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
@ -172,7 +174,7 @@ const ticketsColumns = ref([
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-quantity="{ value, row }">
|
<template #body-cell-quantity="{ value, row }">
|
||||||
<QTd>
|
<QTd>
|
||||||
<QBtn class="no-uppercase" flat color="primary" dense>
|
<QBtn class="no-uppercase link" flat dense>
|
||||||
{{ value }}
|
{{ value }}
|
||||||
<CustomerDescriptorProxy :id="row.id" />
|
<CustomerDescriptorProxy :id="row.id" />
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
|
|
@ -41,7 +41,7 @@ function setWorkers(data) {
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ params, searchFn }">
|
<template #body="{ params }">
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@ -93,7 +93,6 @@ function setWorkers(data) {
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
:label="t('Has PDF')"
|
:label="t('Has PDF')"
|
||||||
@update:model-value="searchFn()"
|
|
||||||
toggle-indeterminate
|
toggle-indeterminate
|
||||||
v-model="params.hasPdf"
|
v-model="params.hasPdf"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -30,7 +30,7 @@ const selectedCustomerId = ref(null);
|
||||||
const tableColumnComponents = {
|
const tableColumnComponents = {
|
||||||
clientId: {
|
clientId: {
|
||||||
component: QBtn,
|
component: QBtn,
|
||||||
props: { flat: true, color: 'blue' },
|
props: { flat: true, class: 'link' },
|
||||||
event: (prop) => selectCustomerId(prop.value),
|
event: (prop) => selectCustomerId(prop.value),
|
||||||
},
|
},
|
||||||
clientName: {
|
clientName: {
|
||||||
|
@ -52,7 +52,12 @@ const tableColumnComponents = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{ label: 'Id', field: 'clientId', name: 'clientId', align: 'left' },
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'clientId',
|
||||||
|
label: 'Id',
|
||||||
|
field: 'clientId',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.globalInvoices.table.client'),
|
label: t('invoiceOut.globalInvoices.table.client'),
|
||||||
field: 'clientName',
|
field: 'clientName',
|
||||||
|
|
|
@ -1,74 +1,160 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, onUnmounted, ref } from 'vue';
|
import { onMounted, onUnmounted, ref, computed, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
|
||||||
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
|
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
|
||||||
import CardList from 'src/components/ui/CardList.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
|
||||||
import CreateManualInvoiceForm from 'src/components/CreateManualInvoiceForm.vue';
|
|
||||||
|
|
||||||
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
|
||||||
import { toDate, toCurrency } from 'src/filters/index';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
|
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
|
||||||
|
import { toCurrency, toDate } from 'src/filters/index';
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import { QBtn } from 'quasar';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const tokenMultimedia = session.getTokenMultimedia();
|
const tokenMultimedia = session.getTokenMultimedia();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
const tableRef = ref();
|
||||||
|
const invoiceOutSerialsOptions = ref([]);
|
||||||
|
const ticketsOptions = ref([]);
|
||||||
|
const customerOptions = ref([]);
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
const hasSelectedCards = computed(() => selectedRows.value.length > 0);
|
||||||
|
|
||||||
const manualInvoiceDialogRef = ref(null);
|
const columns = computed(() => [
|
||||||
const selectedCards = ref(new Map());
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'id',
|
||||||
|
label: t('invoiceOutList.tableVisibleColumns.id'),
|
||||||
|
chip: {
|
||||||
|
condition: () => true,
|
||||||
|
},
|
||||||
|
isId: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'ref',
|
||||||
|
label: t('invoiceOutList.tableVisibleColumns.ref'),
|
||||||
|
isTitle: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'InvoiceOuts',
|
||||||
|
optionLabel: 'ref',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'Issued',
|
||||||
|
label: t('invoiceOutList.tableVisibleColumns.issued'),
|
||||||
|
component: 'date',
|
||||||
|
format: (row) => toDate(row.issued),
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'clientSocialName',
|
||||||
|
label: t('invoiceOutModule.customer'),
|
||||||
|
cardVisible: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Clients',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'companyCode',
|
||||||
|
label: t('invoiceOutModule.company'),
|
||||||
|
cardVisible: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Companies',
|
||||||
|
optionLabel: 'code',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'amount',
|
||||||
|
label: t('invoiceOutModule.amount'),
|
||||||
|
cardVisible: true,
|
||||||
|
format: (row) => toCurrency(row.amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'created',
|
||||||
|
label: t('invoiceOutList.tableVisibleColumns.created'),
|
||||||
|
component: 'date',
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row) => toDate(row.created),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'dued',
|
||||||
|
label: t('invoiceOutList.tableVisibleColumns.dueDate'),
|
||||||
|
component: 'date',
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row) => toDate(row.dued),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: '',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('InvoiceOutSummary'),
|
||||||
|
icon: 'preview',
|
||||||
|
action: (row) => viewSummary(row.id, InvoiceOutSummary),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('DownloadPdf'),
|
||||||
|
icon: 'vn:ticket',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => openPdf(row.id),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
onMounted(() => (stateStore.rightDrawer = true));
|
onMounted(() => (stateStore.rightDrawer = true));
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
|
|
||||||
function navigate(id) {
|
function openPdf(id) {
|
||||||
router.push({ path: `/invoice-out/${id}` });
|
|
||||||
}
|
|
||||||
|
|
||||||
const toggleIndividualCard = (cardData) => {
|
|
||||||
if (selectedCards.value.has(cardData.id)) {
|
|
||||||
selectedCards.value.delete(cardData.id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
selectedCards.value.set(cardData.id, cardData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleAllCards = (cardsData) => {
|
|
||||||
const allSelected = selectedCards.value.size === cardsData.length;
|
|
||||||
|
|
||||||
if (!allSelected) {
|
|
||||||
// Si no todas las tarjetas están seleccionadas, selecciónalas todas
|
|
||||||
cardsData.forEach((data) => {
|
|
||||||
if (!selectedCards.value.has(data.id)) {
|
|
||||||
selectedCards.value.set(data.id, data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Si todas las tarjetas están seleccionadas, deselecciónalas todas
|
|
||||||
selectedCards.value.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const openPdf = () => {
|
|
||||||
try {
|
try {
|
||||||
if (selectedCards.value.size === 0) return;
|
const url = `api/InvoiceOuts/${id}/download?access_token=${tokenMultimedia}`;
|
||||||
const selectedCardsArray = Array.from(selectedCards.value.values());
|
|
||||||
|
|
||||||
if (selectedCards.value.size === 1) {
|
|
||||||
const [invoiceOut] = selectedCardsArray;
|
|
||||||
const url = `api/InvoiceOuts/${invoiceOut.id}/download?access_token=${tokenMultimedia}`;
|
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error opening PDF', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function downloadPdf() {
|
||||||
|
try {
|
||||||
|
if (selectedRows.value.size === 0) return;
|
||||||
|
const selectedCardsArray = Array.from(selectedRows.value.values());
|
||||||
|
|
||||||
|
if (selectedRows.value.size === 1) {
|
||||||
|
const [invoiceOut] = selectedCardsArray;
|
||||||
|
openPdf(invoiceOut.id);
|
||||||
} else {
|
} else {
|
||||||
const invoiceOutIdsArray = selectedCardsArray.map(
|
const invoiceOutIdsArray = selectedCardsArray.map(
|
||||||
(invoiceOut) => invoiceOut.id
|
(invoiceOut) => invoiceOut.id
|
||||||
|
@ -86,11 +172,9 @@ const openPdf = () => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error opening PDF');
|
console.error('Error opening PDF');
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const openCreateInvoiceModal = () => {
|
watch(selectedRows, { deep: true });
|
||||||
manualInvoiceDialogRef.value.show();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -99,115 +183,80 @@ const openCreateInvoiceModal = () => {
|
||||||
:label="t('searchInvoice')"
|
:label="t('searchInvoice')"
|
||||||
data-key="InvoiceOutList"
|
data-key="InvoiceOutList"
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
<VnSubToolbar>
|
||||||
<template #right-panel>
|
<template #st-actions>
|
||||||
<InvoiceOutFilter data-key="InvoiceOutList" />
|
<QBtn color="primary" icon-right="cloud_download" @click="downloadPdf()" :disable="!hasSelectedCards">
|
||||||
|
<QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
</RightMenu>
|
</VnSubToolbar>
|
||||||
<QPage>
|
<VnTable
|
||||||
<VnPaginate
|
ref="tableRef"
|
||||||
auto-load
|
data-key="invoiceOut"
|
||||||
data-key="InvoiceOutList"
|
url="InvoiceOuts/filter"
|
||||||
:order="['issued DESC', 'id DESC']"
|
:create="{
|
||||||
url="InvoiceOuts/filter"
|
urlCreate: 'InvoiceOuts/createManualInvoice',
|
||||||
>
|
title: t('Create Manual Invoice'),
|
||||||
<template #body="{ rows }">
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||||
<VnSubToolbar class="justify-end">
|
formInitialData: {
|
||||||
<template #st-actions>
|
active: true,
|
||||||
<QBtn
|
},
|
||||||
@click="openPdf()"
|
}"
|
||||||
class="q-mr-md"
|
v-model:selected="selectedRows"
|
||||||
color="primary"
|
order="id DESC"
|
||||||
icon="cloud_download"
|
:columns="columns"
|
||||||
:disable="selectedCards.size === 0"
|
default-mode="table"
|
||||||
>
|
redirect="invoice-out"
|
||||||
<QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
|
auto-load
|
||||||
</QBtn>
|
:q-table="{
|
||||||
<QCheckbox
|
'row-key':'id',
|
||||||
left-label
|
selection:'multiple'
|
||||||
:label="t('globals.markAll')"
|
}"
|
||||||
@click="toggleAllCards(rows)"
|
|
||||||
:model-value="selectedCards.size === rows.length"
|
|
||||||
class="q-mr-md"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VnSubToolbar>
|
|
||||||
<div class="flex flex-center q-pa-md">
|
|
||||||
<div class="vn-card-list">
|
|
||||||
<CardList
|
|
||||||
:element="row"
|
|
||||||
:id="row.id"
|
|
||||||
:show-checkbox="true"
|
|
||||||
:is-selected="selectedCards.has(row.id)"
|
|
||||||
:key="row.id"
|
|
||||||
:title="row.ref"
|
|
||||||
@click="navigate(row.id)"
|
|
||||||
@toggle-card-check="toggleIndividualCard(row)"
|
|
||||||
v-for="row of rows"
|
|
||||||
>
|
|
||||||
<template #list-items>
|
|
||||||
<VnLv
|
|
||||||
:label="t('invoiceOut.list.issued')"
|
|
||||||
:value="toDate(row.issued)"
|
|
||||||
/>
|
|
||||||
<VnLv
|
|
||||||
:label="t('invoiceOut.list.amount')"
|
|
||||||
:value="toCurrency(row.amount)"
|
|
||||||
/>
|
|
||||||
<VnLv :label="t('invoiceOut.list.client')">
|
|
||||||
<template #value>
|
|
||||||
<span class="link" @click.stop>
|
|
||||||
{{ row?.clientSocialName }}
|
|
||||||
<CustomerDescriptorProxy
|
|
||||||
:id="row?.clientFk"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</VnLv>
|
|
||||||
<VnLv
|
|
||||||
:label="t('invoiceOut.list.shortCreated')"
|
|
||||||
:title-label="t('invoiceOut.list.created')"
|
|
||||||
:value="toDate(row.created)"
|
|
||||||
/>
|
|
||||||
<VnLv
|
|
||||||
:label="t('invoiceOut.list.company')"
|
|
||||||
:value="row.companyCode"
|
|
||||||
/>
|
|
||||||
<VnLv
|
|
||||||
:label="t('invoiceOut.list.shortDued')"
|
|
||||||
:title-label="t('invoiceOut.list.dued')"
|
|
||||||
:value="toDate(row.dued)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #actions>
|
|
||||||
<QBtn
|
|
||||||
:label="t('components.smartCard.openSummary')"
|
|
||||||
@click.stop="viewSummary(row.id, InvoiceOutSummary)"
|
|
||||||
color="primary"
|
|
||||||
style="margin-top: 15px"
|
|
||||||
type="submit"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</CardList>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</VnPaginate>
|
|
||||||
<QPageSticky :offset="[20, 20]">
|
|
||||||
<QBtn fab icon="add" color="primary" @click="openCreateInvoiceModal()" />
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('createInvoice') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QPageSticky>
|
|
||||||
|
|
||||||
<QDialog
|
>
|
||||||
ref="manualInvoiceDialogRef"
|
<template #more-create-dialog="{ data }">
|
||||||
transition-show="scale"
|
<VnSelect
|
||||||
transition-hide="scale"
|
url="Tickets"
|
||||||
>
|
v-model="data.ticketFk"
|
||||||
<CreateManualInvoiceForm />
|
:label="t('invoiceOutList.tableVisibleColumns.ticket')"
|
||||||
</QDialog>
|
:options="ticketsOptions"
|
||||||
</QPage>
|
option-label="nickname"
|
||||||
|
option-value="id"
|
||||||
|
/>
|
||||||
|
<VnSelect
|
||||||
|
url="Clients"
|
||||||
|
v-model="data.clientFk"
|
||||||
|
:label="t('invoiceOutModule.customer')"
|
||||||
|
:options="customerOptions"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
/>
|
||||||
|
<VnInputDate
|
||||||
|
:label="t('invoiceOutList.tableVisibleColumns.dueDate')"
|
||||||
|
v-model="data.maxShipped"
|
||||||
|
/>
|
||||||
|
<VnSelect
|
||||||
|
url="InvoiceOutSerials"
|
||||||
|
v-model="data.invoiceOutSerial"
|
||||||
|
:label="t('invoiceOutList.tableVisibleColumns.invoiceOutSerial')"
|
||||||
|
:options="invoiceOutSerialsOptions"
|
||||||
|
option-label="description"
|
||||||
|
option-value="code"
|
||||||
|
/>
|
||||||
|
<VnSelect
|
||||||
|
url="TaxAreas"
|
||||||
|
v-model="data.area"
|
||||||
|
:label="t('invoiceOutList.tableVisibleColumns.taxArea')"
|
||||||
|
:options="taxAreasOptions"
|
||||||
|
option-label="code"
|
||||||
|
option-value="code"
|
||||||
|
/>
|
||||||
|
<QInput
|
||||||
|
v-model="data.reference"
|
||||||
|
:label="t('invoiceOutList.tableVisibleColumns.ref')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onBeforeMount } from 'vue';
|
import { computed, ref, onBeforeMount } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
|
||||||
import InvoiceOutNegativeFilter from './InvoiceOutNegativeBasesFilter.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
|
||||||
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
|
||||||
import { toCurrency } from 'src/filters';
|
import { toCurrency } from 'src/filters';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
|
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
// import useStateStore from 'src/stores/useStateStore';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
|
|
||||||
const invoiceOutGlobalStore = useInvoiceOutGlobalStore();
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const tableRef = ref();
|
||||||
|
// const userFrom = Date.vnFirstDayOfMonth().toISOString();
|
||||||
|
// const userTo = Date.vnLastDayOfMonth().toISOString();
|
||||||
|
const invoiceOutGlobalStore = useInvoiceOutGlobalStore();
|
||||||
|
// const stateStore = useStateStore();
|
||||||
const arrayData = useArrayData('InvoiceOutNegative', {
|
const arrayData = useArrayData('InvoiceOutNegative', {
|
||||||
url: 'InvoiceOuts/negativeBases',
|
url: 'InvoiceOuts/negativeBases',
|
||||||
limit: 0,
|
limit: 0,
|
||||||
|
@ -36,165 +34,170 @@ const arrayData = useArrayData('InvoiceOutNegative', {
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await arrayData.fetch({ append: false });
|
await arrayData.fetch({ append: false });
|
||||||
stateStore.rightDrawer = true;
|
// stateStore.rightDrawer = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.company'),
|
align: 'left',
|
||||||
field: 'company',
|
|
||||||
name: 'company',
|
name: 'company',
|
||||||
align: 'left',
|
label: t('invoiceOutModule.company'),
|
||||||
|
component: 'select',
|
||||||
|
cardVisible: true,
|
||||||
|
attrs: {
|
||||||
|
url: 'Companies',
|
||||||
|
optionLabel: 'code',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.country'),
|
align: 'left',
|
||||||
field: 'country',
|
|
||||||
name: 'country',
|
name: 'country',
|
||||||
align: 'left',
|
label: t('negativeBases.country'),
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Countries',
|
||||||
|
optionLabel: 'name',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.clientId'),
|
align: 'left',
|
||||||
field: 'clientId',
|
|
||||||
name: 'clientId',
|
name: 'clientId',
|
||||||
align: 'left',
|
label: t('negativeBases.clientId'),
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.client'),
|
|
||||||
field: 'clientSocialName',
|
|
||||||
name: 'client',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'clientSocialName',
|
||||||
|
label: t('invoiceOutModule.customer'),
|
||||||
|
component: 'select',
|
||||||
|
isTitle: true,
|
||||||
|
cardVisible: true,
|
||||||
|
attrs: {
|
||||||
|
url: 'Clients',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.amount'),
|
align: 'left',
|
||||||
field: 'amount',
|
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
align: 'left',
|
label: t('invoiceOutModule.amount'),
|
||||||
format: (value) => toCurrency(value),
|
format: (row) => toCurrency(row.amount),
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.base'),
|
|
||||||
field: 'taxableBase',
|
|
||||||
name: 'base',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'taxableBase',
|
||||||
|
label: t('negativeBases.base'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.ticketId'),
|
|
||||||
field: 'ticketFk',
|
|
||||||
name: 'ticketId',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'ticketFk',
|
||||||
|
label: t('negativeBases.ticketId'),
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.active'),
|
|
||||||
field: 'isActive',
|
|
||||||
name: 'active',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'isActive',
|
||||||
|
label: t('negativeBases.active'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
align: 'left',
|
||||||
field: 'hasToInvoice',
|
|
||||||
name: 'hasToInvoice',
|
name: 'hasToInvoice',
|
||||||
align: 'left',
|
label: t('negativeBases.hasToInvoice'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.verifiedData'),
|
|
||||||
field: 'isTaxDataChecked',
|
|
||||||
name: 'verifiedData',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'hasVerifiedData',
|
||||||
|
label: t('negativeBases.verifiedData'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('invoiceOut.negativeBases.comercial'),
|
|
||||||
field: 'workerName',
|
|
||||||
name: 'worker',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
|
||||||
|
name: 'workerName',
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Workers/activeWithInheritedRole',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
where: { role: 'salesPerson' },
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.workerName),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const downloadCSV = async () => {
|
const downloadCSV = async () => {
|
||||||
const params = {}; // filter.value;
|
console.log('arrayData from: ', arrayData.store.userParams.from);
|
||||||
|
console.log('arrayData to: ', arrayData.store.userParams.to);
|
||||||
const filterParams = {
|
const filterParams = {
|
||||||
limit: 20,
|
limit: 20,
|
||||||
where: {
|
where: {
|
||||||
and: [],
|
and: [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
for (const param in params) {
|
|
||||||
if (params[param]) filterParams.where.and.push({ [param]: params[param] });
|
for (const [key, value] of Object.entries(arrayData.store.userParams)) {
|
||||||
}
|
if (value) {
|
||||||
|
filterParams.where.and.push({ [key]: value });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
||||||
arrayData.value.store.userParams.from,
|
arrayData.store.userParams.from,
|
||||||
arrayData.value.store.userParams.to,
|
arrayData.store.userParams.to,
|
||||||
params
|
filterParams
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnSubToolbar>
|
<VnSubToolbar>
|
||||||
<template #st-actions>
|
<template #st-actions>
|
||||||
<QBtn color="primary" icon-right="download" no-caps @click="downloadCSV()">
|
<QBtn color="primary" icon-right="download" @click="downloadCSV()">
|
||||||
<QTooltip>{{ t('Download as CSV') }}</QTooltip>
|
<QTooltip>{{ t('Download as CSV') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
<RightMenu>
|
<VnTable
|
||||||
<template #right-panel>
|
ref="tableRef"
|
||||||
<InvoiceOutNegativeFilter data-key="InvoiceOutNegative" />
|
data-key="invoiceOut"
|
||||||
</template>
|
url="InvoiceOuts/negativeBases"
|
||||||
</RightMenu>
|
:user-params="arrayData.store.userParams"
|
||||||
<QPage class="column items-center q-pa-md">
|
:expr-builder="(param, value) => {
|
||||||
<QTable
|
switch (param) {
|
||||||
:columns="columns"
|
case 'from':
|
||||||
:rows="arrayData.store.data"
|
case 'to':
|
||||||
row-key="clientId"
|
return;
|
||||||
class="full-width q-mt-md"
|
default:
|
||||||
>
|
return { [param]: value };
|
||||||
<template #body-cell-clientId="{ row }">
|
}
|
||||||
<QTd>
|
}"
|
||||||
<QBtn flat dense class="link"> {{ row.clientId }}</QBtn>
|
:limit="0"
|
||||||
<CustomerDescriptorProxy :id="row.clientId" />
|
:columns="columns"
|
||||||
</QTd>
|
default-mode="table"
|
||||||
</template>
|
auto-load
|
||||||
<template #body-cell-ticketId="{ row }">
|
:is-editable="false"
|
||||||
<QTd>
|
:use-model="true"
|
||||||
<QBtn flat dense class="link"> {{ row.ticketFk }}</QBtn>
|
>
|
||||||
<TicketDescriptorProxy :id="row.ticketFk" />
|
<!-- <template #moreBeforeActions>
|
||||||
</QTd>
|
<QBtn color="primary" icon-right="download" @click="downloadCSV()">
|
||||||
</template>
|
<QTooltip>{{ t('Download as CSV') }}</QTooltip>
|
||||||
<template #body-cell-worker="{ row }">
|
</QBtn>
|
||||||
<QTd>
|
</template> -->
|
||||||
<QBtn class="no-uppercase link" flat dense>{{ row.workerName }}</QBtn>
|
</VnTable>
|
||||||
<WorkerDescriptorProxy :id="row.comercialId" />
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-active="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<QCheckbox :model-value="!!row.isActive" disable />
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-hasToInvoice="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<QCheckbox :model-value="!!row.hasToInvoice" disable />
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-verifiedData="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<QCheckbox :model-value="!!row.isTaxDataChecked" disable />
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.col-content {
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
.no-uppercase {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Download as CSV: Descargar como CSV
|
Download as CSV: Descargar como CSV
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
invoiceOutModule:
|
||||||
|
customer: Client
|
||||||
|
amount: Amount
|
||||||
|
company: Company
|
||||||
|
invoiceOutList:
|
||||||
|
tableVisibleColumns:
|
||||||
|
id: ID
|
||||||
|
ref: Reference
|
||||||
|
issued: Issued
|
||||||
|
created: Created
|
||||||
|
dueDate: Max date
|
||||||
|
invoiceOutSerial: Serial
|
||||||
|
ticket: Ticket
|
||||||
|
taxArea: Tax area
|
||||||
|
DownloadPdf: Download PDF
|
||||||
|
InvoiceOutSummary: Summary
|
||||||
|
negativeBases:
|
||||||
|
country: Country
|
||||||
|
clientId: Client ID
|
||||||
|
base: Base
|
||||||
|
ticketId: Ticket
|
||||||
|
active: Active
|
||||||
|
hasToInvoice: Has to invoice
|
||||||
|
verifiedData: Verified data
|
||||||
|
commercial: Commercial
|
|
@ -1,2 +1,31 @@
|
||||||
Search invoice: Buscar factura emitida
|
Search invoice: Buscar factura emitida
|
||||||
You can search by invoice reference: Puedes buscar por referencia de la factura
|
You can search by invoice reference: Puedes buscar por referencia de la factura
|
||||||
|
invoiceOutModule:
|
||||||
|
customer: Cliente
|
||||||
|
amount: Importe
|
||||||
|
company: Empresa
|
||||||
|
invoiceOutList:
|
||||||
|
tableVisibleColumns:
|
||||||
|
id: ID
|
||||||
|
ref: Referencia
|
||||||
|
issued: Fecha emisión
|
||||||
|
customer: Cliente
|
||||||
|
company: Empresa
|
||||||
|
amount: Importe
|
||||||
|
created: F. creación
|
||||||
|
dueDate: F. máxima
|
||||||
|
invoiceOutSerial: Serial
|
||||||
|
ticket: Ticket
|
||||||
|
taxArea: Area
|
||||||
|
DownloadPdf: Descargar PDF
|
||||||
|
InvoiceOutSummary: Resumen
|
||||||
|
negativeBases:
|
||||||
|
country: País
|
||||||
|
clientId: ID del cliente
|
||||||
|
client: Cliente
|
||||||
|
base: Base
|
||||||
|
ticketId: Ticket
|
||||||
|
active: Activo
|
||||||
|
hasToInvoice: Debe facturar
|
||||||
|
verifiedData: Datos verificados
|
||||||
|
commercial: Comercial
|
|
@ -35,7 +35,7 @@ export default {
|
||||||
name: 'InvoiceOutGlobal',
|
name: 'InvoiceOutGlobal',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'globalInvoicing',
|
title: 'globalInvoicing',
|
||||||
icon: 'contact_support',
|
icon: 'Date_Range',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/InvoiceOut/InvoiceOutGlobal.vue'),
|
component: () => import('src/pages/InvoiceOut/InvoiceOutGlobal.vue'),
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue