forked from verdnatura/salix-front
merge with dev
This commit is contained in:
commit
d0cb96ce23
|
@ -14,5 +14,13 @@
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"cSpell.words": ["axios"]
|
"cSpell.words": ["axios"],
|
||||||
|
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"files.autoSave": "onFocusChange",
|
||||||
|
"files.trimTrailingWhitespace": true,
|
||||||
|
"editor.hover.enabled": true,
|
||||||
|
"editor.formatOnPaste": true,
|
||||||
|
"editor.wordWrapColumn": 80,
|
||||||
|
"prettier.singleQuote": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "23.40.01",
|
"version": "23.48.01",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "0.0.1",
|
"version": "23.48.01",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/cli": "^2.2.1",
|
"@quasar/cli": "^2.3.0",
|
||||||
"@quasar/extras": "^1.16.4",
|
"@quasar/extras": "^1.16.4",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"chromium": "^3.0.3",
|
"chromium": "^3.0.3",
|
||||||
|
@ -946,9 +946,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@quasar/cli": {
|
"node_modules/@quasar/cli": {
|
||||||
"version": "2.2.1",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.3.0.tgz",
|
||||||
"integrity": "sha512-PMwJ76IeeNRRBw+08hUMjhqGC6JKJ/t1zIb+IOiyR5D4rkBR26Ha/Z46OD3KfwUprq4Q8s4ieB1+d3VY8FhPKg==",
|
"integrity": "sha512-DNFDemicj3jXe5+Ib+5w9Bwj1U3yoHQkqn0bU/qysIl/p0MmGA1yqOfUF0V4fw/5or1dfCvStIA/oZxUcC+2pQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/ssl-certificate": "^1.0.0",
|
"@quasar/ssl-certificate": "^1.0.0",
|
||||||
"ci-info": "^3.8.0",
|
"ci-info": "^3.8.0",
|
||||||
|
|
|
@ -52,6 +52,16 @@ watch($props, async () => {
|
||||||
entity.value = null;
|
entity.value = null;
|
||||||
await fetch();
|
await fetch();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
'Transferir factura a ...',
|
||||||
|
'Ver factura ...',
|
||||||
|
'Enviar factura ...',
|
||||||
|
'Eliminar factura',
|
||||||
|
'Asentar factura',
|
||||||
|
'Regenerar PDF factura',
|
||||||
|
'Abono ...',
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -60,13 +70,13 @@ watch($props, async () => {
|
||||||
<div class="header bg-primary q-pa-sm">
|
<div class="header bg-primary q-pa-sm">
|
||||||
<RouterLink :to="{ name: `${module}List` }">
|
<RouterLink :to="{ name: `${module}List` }">
|
||||||
<QBtn
|
<QBtn
|
||||||
round
|
|
||||||
flat
|
|
||||||
dense
|
|
||||||
size="md"
|
|
||||||
icon="view_list"
|
|
||||||
color="white"
|
|
||||||
class="link"
|
class="link"
|
||||||
|
color="white"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
icon="view_list"
|
||||||
|
round
|
||||||
|
size="md"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.cardDescriptor.mainList') }}
|
{{ t('components.cardDescriptor.mainList') }}
|
||||||
|
@ -75,28 +85,32 @@ watch($props, async () => {
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink :to="{ name: `${module}Summary`, params: { id: entity.id } }">
|
<RouterLink :to="{ name: `${module}Summary`, params: { id: entity.id } }">
|
||||||
<QBtn
|
<QBtn
|
||||||
round
|
|
||||||
flat
|
|
||||||
dense
|
|
||||||
size="md"
|
|
||||||
icon="launch"
|
|
||||||
color="white"
|
|
||||||
class="link"
|
class="link"
|
||||||
|
color="white"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
icon="launch"
|
||||||
|
round
|
||||||
|
size="md"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QMenu auto-close>
|
||||||
{{ t('components.cardDescriptor.summary') }}
|
<QList dense v-for="option in options" :key="option">
|
||||||
</QTooltip>
|
<QItem v-ripple clickable>
|
||||||
|
{{ option }}
|
||||||
|
</QItem>
|
||||||
|
</QList>
|
||||||
|
</QMenu>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
<QBtn
|
<QBtn
|
||||||
v-if="slots.menu"
|
|
||||||
size="md"
|
|
||||||
icon="more_vert"
|
|
||||||
color="white"
|
color="white"
|
||||||
round
|
|
||||||
flat
|
|
||||||
dense
|
dense
|
||||||
|
flat
|
||||||
|
icon="more_vert"
|
||||||
|
round
|
||||||
|
size="md"
|
||||||
|
v-if="slots.menu"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
{{ t('components.cardDescriptor.moreOptions') }}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
<script setup>
|
||||||
|
const $props = defineProps({
|
||||||
|
id: { type: Number, default: null },
|
||||||
|
title: { type: String, default: null },
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QCard class="card q-mb-md cursor-pointer q-hoverable bg-white-7 q-pa-lg">
|
||||||
|
<div>
|
||||||
|
<slot name="title">
|
||||||
|
<div class="flex">
|
||||||
|
<div class="title text-primary text-weight-bold text-h5">
|
||||||
|
{{ $props.title ?? `#${$props.id}` }}
|
||||||
|
</div>
|
||||||
|
<div class="q_chip">
|
||||||
|
<QChip outline color="grey" size="sm">ID: 12345</QChip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
<div class="card-list-body">
|
||||||
|
<div class="list-items row flex-wrap-wrap">
|
||||||
|
<slot name="list-items" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<slot name="actions" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</QCard>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.title {
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q_chip {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-list-body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 10px;
|
||||||
|
.vn-label-value {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 2%;
|
||||||
|
width: 50%;
|
||||||
|
.label {
|
||||||
|
width: 35%;
|
||||||
|
color: var(--vn-label);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
width: 65%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-xs) {
|
||||||
|
.card-list-body {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
.vn-label-value {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 15px;
|
||||||
|
padding: 0 15%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card {
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
.card:hover {
|
||||||
|
background-color: var(--vn-gray);
|
||||||
|
}
|
||||||
|
.list-items {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -106,6 +106,7 @@ function formatValue(value) {
|
||||||
return `"${value}"`;
|
return `"${value}"`;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QForm @submit="search">
|
<QForm @submit="search">
|
||||||
<QList dense>
|
<QList dense>
|
||||||
|
@ -119,32 +120,32 @@ function formatValue(value) {
|
||||||
<div class="q-gutter-xs">
|
<div class="q-gutter-xs">
|
||||||
<QBtn
|
<QBtn
|
||||||
@click="clearFilters"
|
@click="clearFilters"
|
||||||
icon="filter_list_off"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
dense
|
||||||
|
flat
|
||||||
|
icon="filter_list_off"
|
||||||
padding="none"
|
padding="none"
|
||||||
round
|
round
|
||||||
flat
|
size="sm"
|
||||||
dense
|
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Remove filters') }}</QTooltip>
|
<QTooltip>{{ t('Remove filters') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
@click="reload"
|
@click="reload"
|
||||||
icon="refresh"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
dense
|
||||||
|
flat
|
||||||
|
icon="refresh"
|
||||||
padding="none"
|
padding="none"
|
||||||
round
|
round
|
||||||
flat
|
size="sm"
|
||||||
dense
|
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Refresh') }}</QTooltip>
|
<QTooltip>{{ t('Refresh') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</div>
|
</div>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem class="q-mb-sm">
|
||||||
<div
|
<div
|
||||||
v-if="tags.length === 0"
|
v-if="tags.length === 0"
|
||||||
class="text-grey font-xs text-center full-width"
|
class="text-grey font-xs text-center full-width"
|
||||||
|
@ -153,14 +154,14 @@ function formatValue(value) {
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<QChip
|
<QChip
|
||||||
v-for="chip of tags"
|
|
||||||
:key="chip.label"
|
:key="chip.label"
|
||||||
@remove="remove(chip.label)"
|
@remove="remove(chip.label)"
|
||||||
icon="label"
|
|
||||||
color="primary"
|
|
||||||
class="text-dark"
|
class="text-dark"
|
||||||
size="sm"
|
color="primary"
|
||||||
|
icon="label"
|
||||||
removable
|
removable
|
||||||
|
size="sm"
|
||||||
|
v-for="chip of tags"
|
||||||
>
|
>
|
||||||
<slot name="tags" :tag="chip" :format-fn="formatValue">
|
<slot name="tags" :tag="chip" :format-fn="formatValue">
|
||||||
<div class="q-gutter-x-xs">
|
<div class="q-gutter-x-xs">
|
||||||
|
@ -172,29 +173,29 @@ function formatValue(value) {
|
||||||
</div>
|
</div>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QSeparator />
|
<QSeparator />
|
||||||
|
</QList>
|
||||||
|
<slot name="body" :params="userParams" :search-fn="search"></slot>
|
||||||
<template v-if="props.searchButton">
|
<template v-if="props.searchButton">
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection class="q-py-sm">
|
<QItemSection class="q-py-sm">
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('Search')"
|
:label="t('Search')"
|
||||||
type="submit"
|
|
||||||
color="primary"
|
|
||||||
class="full-width"
|
class="full-width"
|
||||||
icon="search"
|
color="primary"
|
||||||
unelevated
|
|
||||||
rounded
|
|
||||||
dense
|
dense
|
||||||
|
icon="search"
|
||||||
|
rounded
|
||||||
|
type="submit"
|
||||||
|
unelevated
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QSeparator />
|
<QSeparator />
|
||||||
</template>
|
</template>
|
||||||
</QList>
|
|
||||||
<slot name="body" :params="userParams" :search-fn="search"></slot>
|
|
||||||
</QForm>
|
</QForm>
|
||||||
<QInnerLoading
|
<QInnerLoading
|
||||||
:showing="isLoading"
|
|
||||||
:label="t('globals.pleaseWait')"
|
:label="t('globals.pleaseWait')"
|
||||||
|
:showing="isLoading"
|
||||||
color="primary"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Notify } from 'quasar';
|
||||||
|
import { i18n } from 'src/boot/i18n';
|
||||||
|
|
||||||
|
export default function useNotify() {
|
||||||
|
const notify = (message, type) => {
|
||||||
|
Notify.create({
|
||||||
|
message: i18n.global.t(message),
|
||||||
|
type: type,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
notify,
|
||||||
|
};
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ const user = ref({
|
||||||
nickname: '',
|
nickname: '',
|
||||||
lang: '',
|
lang: '',
|
||||||
darkMode: null,
|
darkMode: null,
|
||||||
|
companyFk: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const roles = ref([]);
|
const roles = ref([]);
|
||||||
|
@ -23,6 +24,7 @@ export function useState() {
|
||||||
nickname: user.value.nickname,
|
nickname: user.value.nickname,
|
||||||
lang: user.value.lang,
|
lang: user.value.lang,
|
||||||
darkMode: user.value.darkMode,
|
darkMode: user.value.darkMode,
|
||||||
|
companyFk: user.value.companyFk,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -34,6 +36,7 @@ export function useState() {
|
||||||
nickname: data.nickname,
|
nickname: data.nickname,
|
||||||
lang: data.lang,
|
lang: data.lang,
|
||||||
darkMode: data.darkMode,
|
darkMode: data.darkMode,
|
||||||
|
companyFk: data.companyFk,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +62,6 @@ export function useState() {
|
||||||
delete state.value[name];
|
delete state.value[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getUser,
|
getUser,
|
||||||
setUser,
|
setUser,
|
||||||
|
@ -69,6 +71,6 @@ export function useState() {
|
||||||
get,
|
get,
|
||||||
unset,
|
unset,
|
||||||
drawer,
|
drawer,
|
||||||
headerMounted
|
headerMounted,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,17 @@ export function useUserConfig() {
|
||||||
const state = useState();
|
const state = useState();
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
|
try {
|
||||||
const { data } = await axios.get('UserConfigs/getUserConfig');
|
const { data } = await axios.get('UserConfigs/getUserConfig');
|
||||||
const user = state.getUser().value;
|
const user = state.getUser().value;
|
||||||
user.darkMode = data.darkMode;
|
user.darkMode = data.darkMode;
|
||||||
|
user.companyFk = data.companyFk;
|
||||||
state.setUser(user);
|
state.setUser(user);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching user config:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -9,13 +9,10 @@ export default function (value, symbol = 'EUR', fractionSize = 2) {
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
currency: symbol,
|
currency: symbol,
|
||||||
minimumFractionDigits: fractionSize,
|
minimumFractionDigits: fractionSize,
|
||||||
maximumFractionDigits: fractionSize
|
maximumFractionDigits: fractionSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
const lang = locale.value == 'es' ? 'de' : locale.value;
|
const lang = locale.value == 'es' ? 'de' : locale.value;
|
||||||
|
|
||||||
return new Intl.NumberFormat(lang, options)
|
return new Intl.NumberFormat(lang, options).format(value);
|
||||||
.format(value);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -348,6 +348,8 @@ export default {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
invoiceOuts: 'Invoices Out',
|
invoiceOuts: 'Invoices Out',
|
||||||
list: 'List',
|
list: 'List',
|
||||||
|
negativeBases: 'Negative Bases',
|
||||||
|
globalInvoicing: 'Global invoicing',
|
||||||
createInvoiceOut: 'Create invoice out',
|
createInvoiceOut: 'Create invoice out',
|
||||||
summary: 'Summary',
|
summary: 'Summary',
|
||||||
basicData: 'Basic Data',
|
basicData: 'Basic Data',
|
||||||
|
@ -406,6 +408,21 @@ export default {
|
||||||
streetAddress: 'Street',
|
streetAddress: 'Street',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
negativeBases: {
|
||||||
|
from: 'From',
|
||||||
|
to: 'To',
|
||||||
|
company: 'Company',
|
||||||
|
country: 'Country',
|
||||||
|
clientId: 'Client Id',
|
||||||
|
client: 'Client',
|
||||||
|
amount: 'Amount',
|
||||||
|
base: 'Base',
|
||||||
|
ticketId: 'Ticket Id',
|
||||||
|
active: 'Active',
|
||||||
|
hasToInvoice: 'Has to Invoice',
|
||||||
|
verifiedData: 'Verified Data',
|
||||||
|
comercial: 'Comercial',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
worker: {
|
worker: {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
|
|
|
@ -348,6 +348,8 @@ export default {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
invoiceOuts: 'Fact. emitidas',
|
invoiceOuts: 'Fact. emitidas',
|
||||||
list: 'Listado',
|
list: 'Listado',
|
||||||
|
negativeBases: 'Bases Negativas',
|
||||||
|
globalInvoicing: 'Facturación global',
|
||||||
createInvoiceOut: 'Crear fact. emitida',
|
createInvoiceOut: 'Crear fact. emitida',
|
||||||
summary: 'Resumen',
|
summary: 'Resumen',
|
||||||
basicData: 'Datos básicos',
|
basicData: 'Datos básicos',
|
||||||
|
@ -408,6 +410,21 @@ export default {
|
||||||
streetAddress: 'Dirección fiscal',
|
streetAddress: 'Dirección fiscal',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
negativeBases: {
|
||||||
|
from: 'Desde',
|
||||||
|
to: 'Hasta',
|
||||||
|
company: 'Empresa',
|
||||||
|
country: 'País',
|
||||||
|
clientId: 'ID Cliente',
|
||||||
|
client: 'Cliente',
|
||||||
|
amount: 'Importe',
|
||||||
|
base: 'Base',
|
||||||
|
ticketId: 'ID Ticket',
|
||||||
|
active: 'Activo',
|
||||||
|
hasToInvoice: 'Tiene que facturar',
|
||||||
|
verifiedData: 'Datos verificados',
|
||||||
|
comercial: 'Comercial',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
worker: {
|
worker: {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
|
@ -573,8 +590,8 @@ export default {
|
||||||
logOut: 'Cerrar sesión',
|
logOut: 'Cerrar sesión',
|
||||||
},
|
},
|
||||||
smartCard: {
|
smartCard: {
|
||||||
openCard: 'Ver ficha',
|
openCard: 'Ficha',
|
||||||
openSummary: 'Abrir detalles',
|
openSummary: 'Detalles',
|
||||||
viewDescription: 'Ver descripción',
|
viewDescription: 'Ver descripción',
|
||||||
},
|
},
|
||||||
cardDescriptor: {
|
cardDescriptor: {
|
||||||
|
|
|
@ -43,66 +43,72 @@ function setWorkers(data) {
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Customer ID')"
|
:label="t('Customer ID')"
|
||||||
v-model="params.clientFk"
|
class="q-mt-sm"
|
||||||
|
dense
|
||||||
lazy-rules
|
lazy-rules
|
||||||
>
|
outlined
|
||||||
<template #prepend>
|
rounded
|
||||||
<QIcon name="vn:client" size="sm"></QIcon>
|
v-model="params.clientFk"
|
||||||
</template>
|
/>
|
||||||
</QInput>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<QInput :label="t('FI')" v-model="params.fi" lazy-rules>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="badge" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</QInput>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<QInput :label="t('Amount')" v-model="params.amount" lazy-rules>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="euro" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</QInput>
|
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<QInput
|
||||||
|
:label="t('FI')"
|
||||||
|
class="q-mt-sm"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
v-model="params.fi"
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<QInput
|
||||||
|
:label="t('Amount')"
|
||||||
|
class="q-mt-sm"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
v-model="params.amount"
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem class="q-mt-sm">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Min')"
|
:label="t('Min')"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
type="number"
|
type="number"
|
||||||
v-model.number="params.min"
|
v-model.number="params.min"
|
||||||
lazy-rules
|
/>
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="euro" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</QInput>
|
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Max')"
|
:label="t('Max')"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
type="number"
|
type="number"
|
||||||
v-model.number="params.max"
|
v-model.number="params.max"
|
||||||
lazy-rules
|
/>
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="euro" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</QInput>
|
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem class="q-mb-md">
|
<QItem class="q-mb-md">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
v-model="params.hasPdf"
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
:label="t('Has PDF')"
|
:label="t('Has PDF')"
|
||||||
|
@update:model-value="searchFn()"
|
||||||
toggle-indeterminate
|
toggle-indeterminate
|
||||||
|
v-model="params.hasPdf"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -112,15 +118,18 @@ function setWorkers(data) {
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Issued')"
|
:label="t('Issued')"
|
||||||
v-model="params.issued"
|
dense
|
||||||
mask="date"
|
mask="date"
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
v-model="params.issued"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon name="event" class="cursor-pointer">
|
<QIcon name="event" class="cursor-pointer">
|
||||||
<QPopupProxy
|
<QPopupProxy
|
||||||
cover
|
cover
|
||||||
transition-show="scale"
|
|
||||||
transition-hide="scale"
|
transition-hide="scale"
|
||||||
|
transition-show="scale"
|
||||||
>
|
>
|
||||||
<QDate v-model="params.issued" landscape>
|
<QDate v-model="params.issued" landscape>
|
||||||
<div
|
<div
|
||||||
|
@ -134,9 +143,9 @@ function setWorkers(data) {
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('globals.confirm')"
|
:label="t('globals.confirm')"
|
||||||
|
@click="save"
|
||||||
color="primary"
|
color="primary"
|
||||||
flat
|
flat
|
||||||
@click="save"
|
|
||||||
v-close-popup
|
v-close-popup
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -151,15 +160,18 @@ function setWorkers(data) {
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Created')"
|
:label="t('Created')"
|
||||||
v-model="params.created"
|
dense
|
||||||
mask="date"
|
mask="date"
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
v-model="params.created"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon name="event" class="cursor-pointer">
|
<QIcon name="event" class="cursor-pointer">
|
||||||
<QPopupProxy
|
<QPopupProxy
|
||||||
cover
|
cover
|
||||||
transition-show="scale"
|
|
||||||
transition-hide="scale"
|
transition-hide="scale"
|
||||||
|
transition-show="scale"
|
||||||
>
|
>
|
||||||
<QDate v-model="params.created" landscape>
|
<QDate v-model="params.created" landscape>
|
||||||
<div
|
<div
|
||||||
|
@ -173,9 +185,9 @@ function setWorkers(data) {
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('globals.confirm')"
|
:label="t('globals.confirm')"
|
||||||
|
@click="save"
|
||||||
color="primary"
|
color="primary"
|
||||||
flat
|
flat
|
||||||
@click="save"
|
|
||||||
v-close-popup
|
v-close-popup
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -188,13 +200,20 @@ function setWorkers(data) {
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput :label="t('Dued')" v-model="params.dued" mask="date">
|
<QInput
|
||||||
|
:label="t('Dued')"
|
||||||
|
dense
|
||||||
|
mask="date"
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
v-model="params.dued"
|
||||||
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon name="event" class="cursor-pointer">
|
<QIcon name="event" class="cursor-pointer">
|
||||||
<QPopupProxy
|
<QPopupProxy
|
||||||
cover
|
cover
|
||||||
transition-show="scale"
|
|
||||||
transition-hide="scale"
|
transition-hide="scale"
|
||||||
|
transition-show="scale"
|
||||||
>
|
>
|
||||||
<QDate v-model="params.dued" landscape>
|
<QDate v-model="params.dued" landscape>
|
||||||
<div
|
<div
|
||||||
|
@ -208,9 +227,9 @@ function setWorkers(data) {
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('globals.confirm')"
|
:label="t('globals.confirm')"
|
||||||
|
@click="save"
|
||||||
color="primary"
|
color="primary"
|
||||||
flat
|
flat
|
||||||
@click="save"
|
|
||||||
v-close-popup
|
v-close-popup
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, computed } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const invoiceOutGlobalStore = useInvoiceOutGlobalStore();
|
||||||
|
|
||||||
|
// invoiceOutGlobalStore state and getters
|
||||||
|
const {
|
||||||
|
initialDataLoading,
|
||||||
|
formInitialData,
|
||||||
|
clientsOptions,
|
||||||
|
companiesOptions,
|
||||||
|
printersOptions,
|
||||||
|
invoicing,
|
||||||
|
printer,
|
||||||
|
status,
|
||||||
|
} = storeToRefs(invoiceOutGlobalStore);
|
||||||
|
|
||||||
|
// invoiceOutGlobalStore actions
|
||||||
|
const { makeInvoice, setPrinterValue, setStatusValue } = invoiceOutGlobalStore;
|
||||||
|
|
||||||
|
const formData = ref({
|
||||||
|
companyFk: null,
|
||||||
|
invoiceDate: null,
|
||||||
|
maxShipped: null,
|
||||||
|
clientId: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getPrinter = computed({
|
||||||
|
get() {
|
||||||
|
return printer.value;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
setPrinterValue(value.value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const getStatus = computed({
|
||||||
|
get() {
|
||||||
|
return status.value;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
setStatusValue(value.value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const clientsToInvoice = ref('all');
|
||||||
|
const filteredClientsOptions = ref([]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await invoiceOutGlobalStore.init();
|
||||||
|
formData.value = { ...formInitialData.value };
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputSelectfilter = (val, update) => {
|
||||||
|
if (val === '') {
|
||||||
|
update(() => {
|
||||||
|
filteredClientsOptions.value = JSON.parse(
|
||||||
|
JSON.stringify(clientsOptions.value)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(() => {
|
||||||
|
const searchQuery = val.toLowerCase();
|
||||||
|
filteredClientsOptions.value = clientsOptions.value.filter(
|
||||||
|
(option) => option.label.toLowerCase().indexOf(searchQuery) > -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QForm
|
||||||
|
v-if="!initialDataLoading"
|
||||||
|
@submit="makeInvoice(formData, clientsToInvoice)"
|
||||||
|
class="q-pa-md text-white"
|
||||||
|
>
|
||||||
|
<div class="q-gutter-md">
|
||||||
|
<QRadio
|
||||||
|
v-model="clientsToInvoice"
|
||||||
|
dense
|
||||||
|
val="all"
|
||||||
|
:label="t('allClients')"
|
||||||
|
:dark="true"
|
||||||
|
/>
|
||||||
|
<QRadio
|
||||||
|
v-model="clientsToInvoice"
|
||||||
|
dense
|
||||||
|
val="one"
|
||||||
|
:label="t('oneClient')"
|
||||||
|
:dark="true"
|
||||||
|
/>
|
||||||
|
<QSelect
|
||||||
|
v-if="clientsToInvoice === 'one'"
|
||||||
|
:options="filteredClientsOptions"
|
||||||
|
v-model="formData.clientId"
|
||||||
|
filled
|
||||||
|
use-input
|
||||||
|
:label="t('client')"
|
||||||
|
@filter="inputSelectfilter"
|
||||||
|
transition-show="jump-up"
|
||||||
|
transition-hide="jump-up"
|
||||||
|
/>
|
||||||
|
<QInput
|
||||||
|
v-model="formData.invoiceDate"
|
||||||
|
type="date"
|
||||||
|
filled
|
||||||
|
mask="date"
|
||||||
|
:label="t('invoiceDate')"
|
||||||
|
/>
|
||||||
|
<QInput
|
||||||
|
v-model="formData.maxShipped"
|
||||||
|
type="date"
|
||||||
|
filled
|
||||||
|
mask="date"
|
||||||
|
:label="t('maxShipped')"
|
||||||
|
/>
|
||||||
|
<QSelect
|
||||||
|
filled
|
||||||
|
:options="companiesOptions"
|
||||||
|
v-model="formData.companyFk"
|
||||||
|
:label="t('company')"
|
||||||
|
transition-show="jump-up"
|
||||||
|
transition-hide="jump-up"
|
||||||
|
/>
|
||||||
|
<QSelect
|
||||||
|
filled
|
||||||
|
:options="printersOptions"
|
||||||
|
v-model="getPrinter"
|
||||||
|
:label="t('printer')"
|
||||||
|
transition-show="jump-up"
|
||||||
|
transition-hide="jump-up"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<QBtn
|
||||||
|
v-if="!invoicing"
|
||||||
|
:label="t('invoiceOut')"
|
||||||
|
type="submit"
|
||||||
|
color="primary"
|
||||||
|
class="full-width q-mt-md"
|
||||||
|
unelevated
|
||||||
|
rounded
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
<QBtn
|
||||||
|
v-if="invoicing"
|
||||||
|
:label="t('stop')"
|
||||||
|
color="primary"
|
||||||
|
class="full-width q-mt-md"
|
||||||
|
unelevated
|
||||||
|
rounded
|
||||||
|
dense
|
||||||
|
@click="getStatus = 'stopping'"
|
||||||
|
/>
|
||||||
|
</QForm>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
{
|
||||||
|
"en": {
|
||||||
|
"invoiceDate": "Invoice date",
|
||||||
|
"maxShipped": "Max date",
|
||||||
|
"allClients": "All clients",
|
||||||
|
"oneClient": "One client",
|
||||||
|
"company": "Company",
|
||||||
|
"printer": "Printer",
|
||||||
|
"invoiceOut": "Invoice out",
|
||||||
|
"client": "Client",
|
||||||
|
"stop": "Stop"
|
||||||
|
},
|
||||||
|
"es": {
|
||||||
|
"invoiceDate": "Fecha de factura",
|
||||||
|
"maxShipped": "Fecha límite",
|
||||||
|
"allClients": "Todos los clientes",
|
||||||
|
"oneClient": "Un solo cliente",
|
||||||
|
"company": "Empresa",
|
||||||
|
"printer": "Impresora",
|
||||||
|
"invoiceOut": "Facturar",
|
||||||
|
"client": "Cliente",
|
||||||
|
"stop": "Parar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</i18n>
|
|
@ -10,7 +10,7 @@ import { toDate, toCurrency } from 'src/filters/index';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||||
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import CardList from 'src/components/ui/CardList.vue';
|
import CardList2 from 'src/components/ui/CardList2.vue';
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -73,7 +73,7 @@ function viewSummary(id) {
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<CardList
|
<CardList2
|
||||||
v-for="row of rows"
|
v-for="row of rows"
|
||||||
:key="row.id"
|
:key="row.id"
|
||||||
:title="row.ref"
|
:title="row.ref"
|
||||||
|
@ -111,21 +111,21 @@ function viewSummary(id) {
|
||||||
</template>
|
</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<QBtn
|
<QBtn
|
||||||
flat
|
:label="t('components.smartCard.openCard')"
|
||||||
icon="arrow_circle_right"
|
|
||||||
@click.stop="navigate(row.id)"
|
@click.stop="navigate(row.id)"
|
||||||
>
|
color="white"
|
||||||
<QTooltip>
|
outline
|
||||||
{{ t('components.smartCard.openCard') }}
|
type="reset"
|
||||||
</QTooltip>
|
/>
|
||||||
</QBtn>
|
<QBtn
|
||||||
<QBtn flat icon="preview" @click.stop="viewSummary(row.id)">
|
:label="t('components.smartCard.openSummary')"
|
||||||
<QTooltip>
|
@click.stop="viewSummary(row.id)"
|
||||||
{{ t('components.smartCard.openSummary') }}
|
color="primary"
|
||||||
</QTooltip>
|
style="margin-top: 15px"
|
||||||
</QBtn>
|
type="submit"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</CardList>
|
</CardList2>
|
||||||
</template>
|
</template>
|
||||||
</VnPaginate>
|
</VnPaginate>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,400 @@
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, computed, ref } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
/* import { QBadge, QBtn } from 'quasar';
|
||||||
|
import CustomerDescriptor from 'src/pages/Customer/Card/CustomerDescriptor.vue'; */
|
||||||
|
import invoiceOutService from 'src/services/InvoiceOut.service';
|
||||||
|
import { toCurrency } from 'src/filters';
|
||||||
|
import { QBadge, QCheckbox, exportFile } from 'quasar';
|
||||||
|
|
||||||
|
const rows = ref([]);
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// invoiceOutGlobalStore state and getters
|
||||||
|
|
||||||
|
const payload = ref({
|
||||||
|
from: new Date('2001-01-01'),
|
||||||
|
to: new Date('2001-01-31'),
|
||||||
|
});
|
||||||
|
|
||||||
|
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 = {
|
||||||
|
company: {
|
||||||
|
component: 'span',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
country: {
|
||||||
|
component: 'span',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
clientId: {
|
||||||
|
component: 'a',
|
||||||
|
props: { href: '#' },
|
||||||
|
},
|
||||||
|
client: {
|
||||||
|
component: 'span',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
amount: {
|
||||||
|
component: 'span',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
base: {
|
||||||
|
component: 'span',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
ticketId: {
|
||||||
|
component: 'span',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
component: 'span',
|
||||||
|
props: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
hasToInvoice: {
|
||||||
|
component: 'span',
|
||||||
|
props: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
verifiedData: {
|
||||||
|
component: 'span',
|
||||||
|
props: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
comercial: {
|
||||||
|
component: 'a',
|
||||||
|
props: { href: '#' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = ref([
|
||||||
|
{
|
||||||
|
label: 'company',
|
||||||
|
field: 'company',
|
||||||
|
name: 'company',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'country',
|
||||||
|
field: 'country',
|
||||||
|
name: 'country',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clientId',
|
||||||
|
field: 'clientId',
|
||||||
|
name: 'clientId',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'client',
|
||||||
|
field: 'clientSocialName',
|
||||||
|
name: 'client',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'amount',
|
||||||
|
field: 'amount',
|
||||||
|
name: 'amount',
|
||||||
|
align: 'left',
|
||||||
|
format: (value) => toCurrency(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'base',
|
||||||
|
field: 'taxableBase',
|
||||||
|
name: 'base',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'ticketId',
|
||||||
|
field: 'ticketFk',
|
||||||
|
name: 'ticketId',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'active',
|
||||||
|
field: 'isActive',
|
||||||
|
name: 'active',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'hasToInvoice',
|
||||||
|
field: 'hasToInvoice',
|
||||||
|
name: 'hasToInvoice',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'verifiedData',
|
||||||
|
field: 'isTaxDataChecked',
|
||||||
|
name: 'verifiedData',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'comercial',
|
||||||
|
field: 'comercialName',
|
||||||
|
name: 'comercial',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const wrapCsvValue = (val, formatFn, row) => {
|
||||||
|
let formatted = formatFn !== void 0 ? formatFn(val, row) : val;
|
||||||
|
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 and = [];
|
||||||
|
Object.keys(filter.value).forEach((key) => {
|
||||||
|
if (filter.value[key]) {
|
||||||
|
and.push({
|
||||||
|
[key]: filter.value[key],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
...payload.value,
|
||||||
|
filter: {
|
||||||
|
limit: 20,
|
||||||
|
where: { and },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
rows.value = await invoiceOutService.getNegativeBases(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
const refresh = () => {
|
||||||
|
payload.value = {
|
||||||
|
from: new Date('2001-01-01'),
|
||||||
|
to: new Date('2001-01-31'),
|
||||||
|
};
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QPage class="column items-center q-pa-md">
|
||||||
|
<QTable
|
||||||
|
flat
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
hide-bottom
|
||||||
|
row-key="clientId"
|
||||||
|
class="full-width q-mt-md"
|
||||||
|
>
|
||||||
|
<template #top-left>
|
||||||
|
<div class="row justify-start items-end">
|
||||||
|
<QInput
|
||||||
|
dense
|
||||||
|
v-model="payload.from"
|
||||||
|
type="date"
|
||||||
|
mask="date"
|
||||||
|
class="q-mr-md q"
|
||||||
|
:label="t('invoiceOut.negativeBases.from')"
|
||||||
|
/>
|
||||||
|
<QInput
|
||||||
|
dense
|
||||||
|
v-model="payload.to"
|
||||||
|
type="date"
|
||||||
|
mask="date"
|
||||||
|
class="q-mr-md q"
|
||||||
|
:label="t('invoiceOut.negativeBases.to')"
|
||||||
|
/>
|
||||||
|
<QBtn
|
||||||
|
color="primary"
|
||||||
|
icon-right="archive"
|
||||||
|
no-caps
|
||||||
|
@click="exportTable"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #top-right>
|
||||||
|
<div class="row justify-start items-center">
|
||||||
|
<span class="q-mr-md text-grey-7">
|
||||||
|
{{ 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}`) }}
|
||||||
|
<QInput
|
||||||
|
:disable="
|
||||||
|
[
|
||||||
|
'isActive',
|
||||||
|
'hasToInvoice',
|
||||||
|
'isTaxDataChecked',
|
||||||
|
].includes(col.field)
|
||||||
|
"
|
||||||
|
:borderless="
|
||||||
|
[
|
||||||
|
'isActive',
|
||||||
|
'hasToInvoice',
|
||||||
|
'isTaxDataChecked',
|
||||||
|
].includes(col.field)
|
||||||
|
"
|
||||||
|
dense
|
||||||
|
standout
|
||||||
|
v-model="filter[col.field]"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</QTh>
|
||||||
|
</QTr>
|
||||||
|
</template>
|
||||||
|
<template #body-cell="props">
|
||||||
|
<QTd :props="props">
|
||||||
|
<component
|
||||||
|
:is="tableColumnComponents[props.col.name].component"
|
||||||
|
class="col-content"
|
||||||
|
v-bind="tableColumnComponents[props.col.name].props"
|
||||||
|
@click="tableColumnComponents[props.col.name].event(props)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="
|
||||||
|
tableColumnComponents[props.col.name].props.type !=
|
||||||
|
'boolean'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ props.value }}
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<QBadge v-if="props.value" color="grey">
|
||||||
|
<QIcon name="check" size="xs" />
|
||||||
|
</QBadge>
|
||||||
|
|
||||||
|
<QBadge v-else color="grey" outline>
|
||||||
|
<QIcon name="" size="xs" />
|
||||||
|
</QBadge>
|
||||||
|
</span>
|
||||||
|
<QPopupProxy>
|
||||||
|
<CustomerDescriptor
|
||||||
|
v-if="selectedCustomerId === props.value"
|
||||||
|
:id="selectedCustomerId"
|
||||||
|
/>
|
||||||
|
</QPopupProxy>
|
||||||
|
</component>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</QPage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #292929;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
.card-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #aaaaaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-content {
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 6px 6px 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
{
|
||||||
|
"en": {
|
||||||
|
"status": {
|
||||||
|
"packageInvoicing": "Build packaging tickets",
|
||||||
|
"invoicing": "Invoicing client",
|
||||||
|
"stopping": "Stopping process",
|
||||||
|
"done": "Ended process"
|
||||||
|
},
|
||||||
|
"of": "of"
|
||||||
|
},
|
||||||
|
"es": {
|
||||||
|
"status":{
|
||||||
|
"packageInvoicing": "Generación de tickets de empaque",
|
||||||
|
"invoicing": "Facturando a cliente",
|
||||||
|
"stopping": "Deteniendo proceso",
|
||||||
|
"done": "Proceso detenido",
|
||||||
|
},
|
||||||
|
"of": "de"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</i18n>
|
|
@ -5,12 +5,12 @@ export default {
|
||||||
name: 'InvoiceOut',
|
name: 'InvoiceOut',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'invoiceOuts',
|
title: 'invoiceOuts',
|
||||||
icon: 'vn:invoice-out'
|
icon: 'vn:invoice-out',
|
||||||
},
|
},
|
||||||
component: RouterView,
|
component: RouterView,
|
||||||
redirect: { name: 'InvoiceOutMain' },
|
redirect: { name: 'InvoiceOutMain' },
|
||||||
menus: {
|
menus: {
|
||||||
main: ['InvoiceOutList'],
|
main: ['InvoiceOutList', 'InvoiceOutGlobal', 'InvoiceOutNegativeBases'],
|
||||||
card: [],
|
card: [],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -28,8 +28,27 @@ export default {
|
||||||
icon: 'view_list',
|
icon: 'view_list',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/InvoiceOut/InvoiceOutList.vue'),
|
component: () => import('src/pages/InvoiceOut/InvoiceOutList.vue'),
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
|
path: 'global-invoicing',
|
||||||
|
name: 'InvoiceOutGlobal',
|
||||||
|
meta: {
|
||||||
|
title: 'globalInvoicing',
|
||||||
|
icon: 'view_list',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/InvoiceOut/InvoiceOutGlobal.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'negative-bases',
|
||||||
|
name: 'InvoiceOutNegativeBases',
|
||||||
|
meta: {
|
||||||
|
title: 'negativeBases',
|
||||||
|
icon: 'view_list',
|
||||||
|
},
|
||||||
|
component: () =>
|
||||||
|
import('src/pages/InvoiceOut/InvoiceOutNegativeBases.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'InvoiceOutCard',
|
name: 'InvoiceOutCard',
|
||||||
|
@ -41,11 +60,12 @@ export default {
|
||||||
name: 'InvoiceOutSummary',
|
name: 'InvoiceOutSummary',
|
||||||
path: 'summary',
|
path: 'summary',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'summary'
|
title: 'summary',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/InvoiceOut/Card/InvoiceOutSummary.vue'),
|
component: () =>
|
||||||
}
|
import('src/pages/InvoiceOut/Card/InvoiceOutSummary.vue'),
|
||||||
]
|
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const request = async (method, url, params = {}) => {
|
||||||
|
try {
|
||||||
|
let response;
|
||||||
|
|
||||||
|
if (method === 'GET') {
|
||||||
|
response = await axios.get(url, { params });
|
||||||
|
} else if (method === 'POST') {
|
||||||
|
response = await axios.post(url, params);
|
||||||
|
}
|
||||||
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error with ${method} request to ${url}`, err);
|
||||||
|
return err.response;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const invoiceOutService = {
|
||||||
|
getNegativeBases: async (params) => {
|
||||||
|
return await request('GET', 'InvoiceOuts/negativeBases', params);
|
||||||
|
},
|
||||||
|
|
||||||
|
getInvoiceDate: async (params) => {
|
||||||
|
return await request('GET', 'InvoiceOuts/getInvoiceDate', params);
|
||||||
|
},
|
||||||
|
|
||||||
|
getFindOne: async (params) => {
|
||||||
|
return await request('GET', 'InvoiceOutConfigs/findOne', params);
|
||||||
|
},
|
||||||
|
|
||||||
|
getCompanies: async (filter) => {
|
||||||
|
return await request('GET', 'Companies', { filter });
|
||||||
|
},
|
||||||
|
|
||||||
|
getPrinters: async (filter) => {
|
||||||
|
return await request('GET', 'Printers', { filter });
|
||||||
|
},
|
||||||
|
|
||||||
|
getClients: async (filter) => {
|
||||||
|
return await request('GET', 'Clients', { filter });
|
||||||
|
},
|
||||||
|
|
||||||
|
getClientsToInvoice: async (params) => {
|
||||||
|
return await request('POST', 'InvoiceOuts/clientsToInvoice', params);
|
||||||
|
},
|
||||||
|
|
||||||
|
invoiceClient: async (params) => {
|
||||||
|
return await request('POST', 'InvoiceOuts/invoiceClient', params);
|
||||||
|
},
|
||||||
|
|
||||||
|
makePdfAndNotify: async (invoiceId, params) => {
|
||||||
|
return await request('POST', `InvoiceOuts/${invoiceId}/makePdfAndNotify`, params);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default invoiceOutService;
|
|
@ -0,0 +1,286 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { useUserConfig } from 'src/composables/useUserConfig';
|
||||||
|
import invoiceOutService from 'src/services/InvoiceOut.service.js';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
export const useInvoiceOutGlobalStore = defineStore({
|
||||||
|
id: 'invoiceOutGlobal',
|
||||||
|
|
||||||
|
state: () => ({
|
||||||
|
initialDataLoading: true,
|
||||||
|
formInitialData: {
|
||||||
|
companyFk: null,
|
||||||
|
invoiceDate: null,
|
||||||
|
maxShipped: null,
|
||||||
|
clientId: null,
|
||||||
|
},
|
||||||
|
clientsOptions: [],
|
||||||
|
companiesOptions: [],
|
||||||
|
printersOptions: [],
|
||||||
|
addresses: [],
|
||||||
|
minInvoicingDate: null,
|
||||||
|
parallelism: null,
|
||||||
|
invoicing: false,
|
||||||
|
isInvoicing: false,
|
||||||
|
status: null,
|
||||||
|
addressIndex: 0,
|
||||||
|
printer: null,
|
||||||
|
errors: [],
|
||||||
|
nRequests: 0,
|
||||||
|
nPdfs: 0,
|
||||||
|
totalPdfs: 0,
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async init() {
|
||||||
|
await this.fetchAllData();
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchAllData() {
|
||||||
|
try {
|
||||||
|
const userInfo = await useUserConfig().fetch();
|
||||||
|
const date = Date.vnNew();
|
||||||
|
this.formInitialData.maxShipped = new Date(
|
||||||
|
date.getFullYear(),
|
||||||
|
date.getMonth(),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
.toISOString()
|
||||||
|
.substring(0, 10);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
this.fetchClients(),
|
||||||
|
this.fetchParallelism(),
|
||||||
|
this.fetchCompanies(userInfo.companyFk),
|
||||||
|
this.fetchPrinters(),
|
||||||
|
this.fetchInvoiceOutConfig(userInfo.companyFk),
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.initialDataLoading = false;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error fetching invoice out global initial data');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchClients() {
|
||||||
|
const clientsFilter = { fields: ['id', 'name'], order: 'id', limit: 30 };
|
||||||
|
const clientsResponse = await invoiceOutService.getClients(clientsFilter);
|
||||||
|
this.clientsOptions = clientsResponse.map((client) => {
|
||||||
|
return { value: client.id, label: client.name };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchCompanies(companyFk) {
|
||||||
|
const companiesFilters = { order: ['code'] };
|
||||||
|
const companiesResponse = await invoiceOutService.getCompanies(
|
||||||
|
companiesFilters
|
||||||
|
);
|
||||||
|
this.companiesOptions = companiesResponse.map((company) => {
|
||||||
|
return { value: company.id, label: company.code };
|
||||||
|
});
|
||||||
|
|
||||||
|
this.formInitialData.companyFk = this.companiesOptions.find(
|
||||||
|
(company) => companyFk === company.value
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchPrinters() {
|
||||||
|
const printersFilters = {
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
where: { isLabeler: false },
|
||||||
|
order: 'name ASC',
|
||||||
|
limit: 30,
|
||||||
|
};
|
||||||
|
const printersResponse = await invoiceOutService.getPrinters(printersFilters);
|
||||||
|
this.printersOptions = printersResponse.map((printer) => {
|
||||||
|
return { value: printer.id, label: printer.name };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchInvoiceOutConfig(companyFk) {
|
||||||
|
const params = { companyFk: companyFk };
|
||||||
|
const { issued } = await invoiceOutService.getInvoiceDate(params);
|
||||||
|
|
||||||
|
const stringDate = issued.substring(0, 10);
|
||||||
|
this.minInvoicingDate = stringDate;
|
||||||
|
this.formInitialData.invoiceDate = stringDate;
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchParallelism() {
|
||||||
|
const filter = { fields: ['parallelism'] };
|
||||||
|
const { parallelism } = await invoiceOutService.getFindOne(filter);
|
||||||
|
this.parallelism = parallelism;
|
||||||
|
},
|
||||||
|
|
||||||
|
async makeInvoice(formData, clientsToInvoice) {
|
||||||
|
this.invoicing = true;
|
||||||
|
this.status = 'packageInvoicing';
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
invoiceDate: new Date(formData.invoiceDate),
|
||||||
|
maxShipped: new Date(formData.maxShipped),
|
||||||
|
clientId: formData.clientId ? formData.clientId.value : null,
|
||||||
|
companyFk: formData.companyFk.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.validateMakeInvoceParams(params, clientsToInvoice);
|
||||||
|
|
||||||
|
if (clientsToInvoice == 'all') params.clientId = undefined;
|
||||||
|
|
||||||
|
const addressesResponse = await invoiceOutService.getClientsToInvoice(
|
||||||
|
params
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addresses = addressesResponse;
|
||||||
|
|
||||||
|
if (!this.addresses || !this.addresses.length > 0) {
|
||||||
|
notify(
|
||||||
|
'invoiceOut.globalInvoices.errors.noTicketsToInvoice',
|
||||||
|
'negative'
|
||||||
|
);
|
||||||
|
throw new Error("There aren't addresses to invoice");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addresses.forEach(async (address) => {
|
||||||
|
await this.invoiceClient(address, formData);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.handleError(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
validateMakeInvoceParams(params, clientsToInvoice) {
|
||||||
|
if (clientsToInvoice === 'one' && !params.clientId) {
|
||||||
|
notify('invoiceOut.globalInvoices.errors.chooseValidClient', 'negative');
|
||||||
|
throw new Error('Invalid client');
|
||||||
|
}
|
||||||
|
if (!params.invoiceDate || !params.maxShipped) {
|
||||||
|
notify('invoiceOut.globalInvoices.errors.fillDates', 'negative');
|
||||||
|
throw new Error('Missing dates');
|
||||||
|
}
|
||||||
|
if (params.invoiceDate < params.maxShipped) {
|
||||||
|
notify(
|
||||||
|
'invoiceOut.globalInvoices.errors.invoiceDateLessThanMaxDate',
|
||||||
|
'negative'
|
||||||
|
);
|
||||||
|
throw new Error('Invalid date range');
|
||||||
|
}
|
||||||
|
|
||||||
|
const invoiceDateTime = new Date(params.invoiceDate).getTime();
|
||||||
|
const minInvoiceDateTime = new Date(this.minInvoicingDate).getTime();
|
||||||
|
|
||||||
|
if (this.minInvoicingDate && invoiceDateTime < minInvoiceDateTime) {
|
||||||
|
notify(
|
||||||
|
'invoiceOut.globalInvoices.errors.invoiceWithFutureDate',
|
||||||
|
'negative'
|
||||||
|
);
|
||||||
|
throw new Error('Invoice date in the future');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params.companyFk) {
|
||||||
|
notify('invoiceOut.globalInvoices.errors.chooseValidCompany', 'negative');
|
||||||
|
throw new Error('Invalid company');
|
||||||
|
}
|
||||||
|
if (!this.printer) {
|
||||||
|
notify('invoiceOut.globalInvoices.errors.chooseValidPrinter', 'negative');
|
||||||
|
throw new Error('Invalid printer');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async invoiceClient(address, formData) {
|
||||||
|
if (this.nRequests === this.parallelism || this.isInvoicing) return;
|
||||||
|
|
||||||
|
if (this.status === 'stopping') {
|
||||||
|
if (this.nRequests) return;
|
||||||
|
this.invoicing = false;
|
||||||
|
this.status = 'done';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
clientId: address.clientId,
|
||||||
|
addressId: address.id,
|
||||||
|
invoiceDate: new Date(formData.invoiceDate),
|
||||||
|
maxShipped: new Date(formData.maxShipped),
|
||||||
|
companyFk: formData.companyFk.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.status = 'invoicing';
|
||||||
|
this.invoicing = true;
|
||||||
|
|
||||||
|
const invoiceResponse = await invoiceOutService.invoiceClient(params);
|
||||||
|
|
||||||
|
if (invoiceResponse.data.error) {
|
||||||
|
if (invoiceResponse.status >= 400 && invoiceResponse.status < 500) {
|
||||||
|
this.invoiceClientError(address, invoiceResponse);
|
||||||
|
this.addressIndex++;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.invoicing = false;
|
||||||
|
this.status = 'done';
|
||||||
|
notify(
|
||||||
|
'invoiceOut.globalInvoices.errors.criticalInvoiceError',
|
||||||
|
'negative'
|
||||||
|
);
|
||||||
|
throw new Error('Critical invoicing error, process stopped');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.isInvoicing = false;
|
||||||
|
if (invoiceResponse.data) {
|
||||||
|
this.makePdfAndNotify(invoiceResponse.data, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async makePdfAndNotify(invoiceId, client) {
|
||||||
|
try {
|
||||||
|
this.nRequests++;
|
||||||
|
this.totalPdfs++;
|
||||||
|
const params = { printerFk: this.printer.value };
|
||||||
|
await invoiceOutService.makePdfAndNotify(invoiceId, params);
|
||||||
|
this.nPdfs++;
|
||||||
|
this.nRequests--;
|
||||||
|
} catch (err) {
|
||||||
|
this.invoiceClientError(client, err, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
invoiceClientError(client, response, isWarning) {
|
||||||
|
const message = response.data?.error?.message || response.message;
|
||||||
|
this.errors.unshift({ client, message, isWarning });
|
||||||
|
},
|
||||||
|
|
||||||
|
handleError(err) {
|
||||||
|
this.invoicing = false;
|
||||||
|
this.status = null;
|
||||||
|
throw err;
|
||||||
|
},
|
||||||
|
|
||||||
|
// State mutations actions
|
||||||
|
|
||||||
|
setPrinterValue(printer) {
|
||||||
|
this.printer = printer;
|
||||||
|
},
|
||||||
|
|
||||||
|
setStatusValue(status) {
|
||||||
|
this.status = status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
getters: {
|
||||||
|
getNAddresses(state) {
|
||||||
|
return state.addresses.length;
|
||||||
|
},
|
||||||
|
getPercentage(state) {
|
||||||
|
if (this.getNAdresses <= 0 || !state.addressIndex) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let porcentaje = (state.addressIndex / this.getNAddresses) * 100;
|
||||||
|
return porcentaje;
|
||||||
|
},
|
||||||
|
getAddressNumber(state) {
|
||||||
|
return state.addressIndex;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue