Merge pull request 'The negative bases view was created for invoices out module.' (#4) from feature/ms-17-invoices-out-negative-bases-view into dev

Reviewed-on: hyervoni/salix-front-mindshore#4
This commit is contained in:
Carlos Fonseca 2023-11-22 15:31:37 +00:00
commit 1e1382184e
7 changed files with 459 additions and 8 deletions

10
.vscode/settings.json vendored
View File

@ -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
} }

View File

@ -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);
} }

View File

@ -348,6 +348,7 @@ export default {
pageTitles: { pageTitles: {
invoiceOuts: 'Invoices Out', invoiceOuts: 'Invoices Out',
list: 'List', list: 'List',
negativeBases: 'Negative Bases',
globalInvoicing: 'Global invoicing', globalInvoicing: 'Global invoicing',
createInvoiceOut: 'Create invoice out', createInvoiceOut: 'Create invoice out',
summary: 'Summary', summary: 'Summary',
@ -402,6 +403,21 @@ export default {
criticalInvoiceError: 'Critical invoicing error, process stopped', criticalInvoiceError: 'Critical invoicing error, process stopped',
}, },
}, },
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: {

View File

@ -348,6 +348,7 @@ export default {
pageTitles: { pageTitles: {
invoiceOuts: 'Fact. emitidas', invoiceOuts: 'Fact. emitidas',
list: 'Listado', list: 'Listado',
negativeBases: 'Bases Negativas',
globalInvoicing: 'Facturación global', globalInvoicing: 'Facturación global',
createInvoiceOut: 'Crear fact. emitida', createInvoiceOut: 'Crear fact. emitida',
summary: 'Resumen', summary: 'Resumen',
@ -404,6 +405,21 @@ export default {
criticalInvoiceError: 'Error crítico en la facturación, proceso detenido', criticalInvoiceError: 'Error crítico en la facturación, proceso detenido',
}, },
}, },
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: {

View File

@ -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>

View File

@ -10,7 +10,7 @@ export default {
component: RouterView, component: RouterView,
redirect: { name: 'InvoiceOutMain' }, redirect: { name: 'InvoiceOutMain' },
menus: { menus: {
main: ['InvoiceOutList', 'InvoiceOutGlobal'], main: ['InvoiceOutList', 'InvoiceOutGlobal', 'InvoiceOutNegativeBases'],
card: [], card: [],
}, },
children: [ children: [
@ -38,6 +38,16 @@ export default {
}, },
component: () => import('src/pages/InvoiceOut/InvoiceOutGlobal.vue'), 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'),
},
], ],
}, },
{ {

View File

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