839 lines
29 KiB
Vue
839 lines
29 KiB
Vue
<script setup>
|
|
import axios from 'axios';
|
|
import { computed, ref, onBeforeMount, watch, onMounted } from 'vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { useStateStore } from 'stores/useStateStore';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useQuasar } from 'quasar';
|
|
import { toDate, toCurrency, dashIfEmpty } from 'src/filters/index';
|
|
import useNotify from 'src/composables/useNotify';
|
|
import TicketSummary from './Card/TicketSummary.vue';
|
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
import VnRow from 'src/components/ui/VnRow.vue';
|
|
import TicketFilter from './TicketFilter.vue';
|
|
import VnInput from 'src/components/common/VnInput.vue';
|
|
import FetchData from 'src/components/FetchData.vue';
|
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
|
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
|
import { toTimeFormat } from 'src/filters/date';
|
|
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
|
import VnSection from 'src/components/common/VnSection.vue';
|
|
import { getClient } from 'src/pages/Customer/composables/getClient';
|
|
import { getAddresses } from 'src/pages/Customer/composables/getAddresses';
|
|
import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies';
|
|
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const { t } = useI18n();
|
|
const { viewSummary } = useSummaryDialog();
|
|
const tableRef = ref();
|
|
const quasar = useQuasar();
|
|
const { notify } = useNotify();
|
|
const clientsOptions = ref([]);
|
|
const addressesOptions = ref([]);
|
|
const agenciesOptions = ref([]);
|
|
const selectedClient = ref();
|
|
const stateStore = useStateStore();
|
|
const from = Date.vnNew();
|
|
from.setHours(0, 0, 0, 0);
|
|
from.setDate(from.getDate() - 7);
|
|
const to = Date.vnNew();
|
|
to.setHours(23, 59, 0, 0);
|
|
to.setDate(to.getDate() + 1);
|
|
const userParams = {
|
|
from: null,
|
|
to: null,
|
|
};
|
|
onBeforeMount(() => {
|
|
initializeFromQuery();
|
|
stateStore.rightDrawer = true;
|
|
});
|
|
onMounted(async () => {
|
|
if (!route.query) return;
|
|
if (route.query?.createForm) {
|
|
formInitialData.value = JSON.parse(route.query?.createForm);
|
|
await onClientSelected(formInitialData.value);
|
|
} else if (route.query?.table) {
|
|
const query = route.query?.table;
|
|
const clientId = +JSON.parse(query)?.clientFk;
|
|
if (clientId) await onClientSelected({ clientId });
|
|
}
|
|
if (tableRef.value) tableRef.value.create.formInitialData = formInitialData.value;
|
|
});
|
|
const initializeFromQuery = () => {
|
|
if (!route) return;
|
|
const query = route.query.table ? JSON.parse(route.query.table) : {};
|
|
from.value = query.from || from.toISOString();
|
|
to.value = query.to || to.toISOString();
|
|
Object.assign(userParams, { from, to });
|
|
};
|
|
|
|
const selectedRows = ref([]);
|
|
const hasSelectedRows = computed(() => selectedRows.value.length > 0);
|
|
const showForm = ref(false);
|
|
const dialogData = ref();
|
|
const companiesOptions = ref([]);
|
|
const accountingOptions = ref([]);
|
|
const amountToReturn = ref();
|
|
const dataKey = 'TicketList';
|
|
const formInitialData = ref({});
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
align: 'left',
|
|
name: 'statusIcons',
|
|
hidden: true,
|
|
format: () => '',
|
|
columnClass: 'expand',
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'id',
|
|
label: t('ticketList.id'),
|
|
chip: {
|
|
condition: () => true,
|
|
},
|
|
isId: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('ticketList.salesPerson'),
|
|
name: 'salesPersonFk',
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'Workers/activeWithInheritedRole',
|
|
fields: ['id', 'name'],
|
|
where: { role: 'salesPerson' },
|
|
optionFilter: 'firstName',
|
|
useLike: false,
|
|
},
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
columnClass: 'expand',
|
|
cardVisible: true,
|
|
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'shipped',
|
|
cardVisible: true,
|
|
label: t('ticketList.shipped'),
|
|
columnFilter: {
|
|
component: 'date',
|
|
},
|
|
format: ({ shippedDate }) => toDate(shippedDate),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'shipped',
|
|
component: 'time',
|
|
columnFilter: false,
|
|
label: t('ticketList.hour'),
|
|
format: (row) => toTimeFormat(row.shipped),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'zoneLanding',
|
|
component: 'time',
|
|
columnFilter: false,
|
|
label: t('ticketList.closure'),
|
|
format: (row, dashIfEmpty) => dashIfEmpty(toTimeFormat(row.zoneLanding)),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'nickname',
|
|
label: t('ticketList.nickname'),
|
|
columnClass: 'expand',
|
|
isTitle: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'addressNickname',
|
|
label: t('ticketList.addressNickname'),
|
|
columnClass: 'expand',
|
|
cardVisible: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'provinceFk',
|
|
label: t('ticketList.province'),
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'Provinces',
|
|
},
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
format: (row, dashIfEmpty) => dashIfEmpty(row.province),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'stateFk',
|
|
label: t('ticketList.state'),
|
|
columnFilter: {
|
|
name: 'stateFk',
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'States',
|
|
fields: ['id', 'name'],
|
|
},
|
|
},
|
|
columnClass: 'expand',
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'zoneFk',
|
|
label: t('ticketList.zone'),
|
|
columnFilter: {
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'Zones',
|
|
fields: ['id', 'name'],
|
|
},
|
|
alias: 't',
|
|
inWhere: true,
|
|
},
|
|
columnClass: 'expand',
|
|
format: (row, dashIfEmpty) => dashIfEmpty(row.zoneName),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'warehouseFk',
|
|
label: t('globals.warehouse'),
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'warehouses',
|
|
fields: ['id', 'name'],
|
|
},
|
|
format: (row) => row.warehouse,
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
cardVisible: false,
|
|
create: false,
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'totalWithVat',
|
|
label: t('ticketList.totalWithVat'),
|
|
cardVisible: true,
|
|
columnFilter: {
|
|
component: 'number',
|
|
inWhere: true,
|
|
},
|
|
format: (row) => toCurrency(row.totalWithVat),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'packing',
|
|
label: t('ticketSale.packaging'),
|
|
format: (row, dashIfEmpty) => dashIfEmpty(row.packing),
|
|
},
|
|
{
|
|
align: 'right',
|
|
name: 'tableActions',
|
|
actions: [
|
|
{
|
|
title: t('ticketList.toLines'),
|
|
icon: 'list',
|
|
isPrimary: true,
|
|
action: (row) => redirectToLines(row.id),
|
|
},
|
|
{
|
|
title: t('components.smartCard.viewSummary'),
|
|
icon: 'preview',
|
|
isPrimary: true,
|
|
action: (row, evt) => {
|
|
if (evt && evt.ctrlKey) {
|
|
const url = router.resolve({
|
|
params: { id: row.id },
|
|
name: 'TicketCard',
|
|
}).href;
|
|
window.open(url, '_blank');
|
|
} else viewSummary(row.id, TicketSummary);
|
|
},
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
const onClientSelected = async (formData) => {
|
|
resetAgenciesSelector(formData);
|
|
await fetchAddresses(formData);
|
|
};
|
|
|
|
const fetchAddresses = async (formData) => {
|
|
const { data } = await getAddresses(formData.clientId);
|
|
formInitialData.value = { clientId: formData.clientId };
|
|
if (!data) return;
|
|
addressesOptions.value = data;
|
|
selectedClient.value = data[0].client;
|
|
formData.addressId = selectedClient.value.defaultAddressFk;
|
|
formInitialData.value.addressId = formData.addressId;
|
|
};
|
|
watch(
|
|
() => route.query.table,
|
|
async (newValue) => {
|
|
if (newValue) {
|
|
const clientId = +JSON.parse(newValue)?.clientFk;
|
|
if (clientId) await onClientSelected({ clientId });
|
|
if (tableRef.value)
|
|
tableRef.value.create.formInitialData = formInitialData.value;
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
);
|
|
function resetAgenciesSelector(formData) {
|
|
agenciesOptions.value = [];
|
|
if (formData) formData.agencyModeId = null;
|
|
}
|
|
|
|
function redirectToLines(id) {
|
|
const url = `#/ticket/${id}/sale`;
|
|
window.open(url, '_blank');
|
|
}
|
|
|
|
const fetchAvailableAgencies = async (formData) => {
|
|
resetAgenciesSelector(formData);
|
|
const response = await getAgencies(formData, selectedClient.value);
|
|
if (!response) return;
|
|
|
|
const { options, agency } = response;
|
|
if (options) agenciesOptions.value = options;
|
|
if (agency) formData.agencyModeId = agency.agencyModeFk;
|
|
};
|
|
|
|
const getColor = (row) => {
|
|
if (row.alertLevelCode === 'OK') return 'bg-success';
|
|
else if (row.alertLevelCode === 'FREE') return 'bg-notice';
|
|
else if (row.alertLevel === 1) return 'bg-warning';
|
|
else if (row.alertLevel === 0) return 'bg-alert';
|
|
};
|
|
|
|
const getDateColor = (date) => {
|
|
const today = Date.vnNew();
|
|
today.setHours(0, 0, 0, 0);
|
|
const timeTicket = new Date(date);
|
|
timeTicket.setHours(0, 0, 0, 0);
|
|
const comparation = today - timeTicket;
|
|
if (comparation == 0) return 'bg-warning';
|
|
if (comparation < 0) return 'bg-success';
|
|
};
|
|
|
|
async function makeInvoice(ticket) {
|
|
const ticketsIds = ticket.map((item) => item.id);
|
|
const { data } = await axios.post(`Tickets/invoiceTicketsAndPdf`, { ticketsIds });
|
|
const response = data;
|
|
if (response)
|
|
quasar.notify({
|
|
message: t('globals.dataSaved'),
|
|
type: 'positive',
|
|
});
|
|
}
|
|
|
|
async function sendDocuware(ticket) {
|
|
try {
|
|
let ticketIds = ticket.map((item) => item.id);
|
|
|
|
const { data } = await axios.post(`Docuwares/upload`, {
|
|
fileCabinet: 'deliveryNote',
|
|
ticketIds,
|
|
});
|
|
|
|
for (let ticket of ticketIds) {
|
|
ticket.stateFk = data.id;
|
|
ticket.state = data.name;
|
|
ticket.alertLevel = data.alertLevel;
|
|
ticket.alertLevelCode = data.code;
|
|
}
|
|
notify('globals.dataSaved', 'positive');
|
|
} catch (err) {
|
|
console.err('err: ', err);
|
|
}
|
|
}
|
|
|
|
function openBalanceDialog(ticket) {
|
|
const checkedTickets = ticket;
|
|
const amountPaid = ref(0);
|
|
const clientFk = ref(null);
|
|
const description = ref([]);
|
|
const firstTicketClientId = checkedTickets[0].clientFk;
|
|
const isSameClient = checkedTickets.every(
|
|
(ticket) => ticket.clientFk === firstTicketClientId,
|
|
);
|
|
|
|
if (!isSameClient) {
|
|
throw new Error('You cannot make a payment on account from multiple clients');
|
|
}
|
|
|
|
for (let ticketData of checkedTickets) {
|
|
amountPaid.value += ticketData.totalWithVat;
|
|
clientFk.value = ticketData.clientFk;
|
|
description.value.push(ticketData.id);
|
|
}
|
|
|
|
const balanceCreateDialog = ref({
|
|
amountPaid: amountPaid.value,
|
|
clientFk: clientFk.value,
|
|
description: `Albaran: ${description.value.join(', ')}`,
|
|
});
|
|
dialogData.value = balanceCreateDialog;
|
|
showForm.value = true;
|
|
}
|
|
|
|
async function onSubmit() {
|
|
const { data: email } = await axios.get('Clients', {
|
|
params: {
|
|
filter: JSON.stringify({ where: { id: dialogData.value.value.clientFk } }),
|
|
},
|
|
});
|
|
|
|
const { data } = await axios.post(
|
|
`Clients/${dialogData.value.value.clientFk}/createReceipt`,
|
|
{
|
|
payed: dialogData.value.payed,
|
|
companyFk: dialogData.value.companyFk,
|
|
bankFk: dialogData.value.bankFk,
|
|
amountPaid: dialogData.value.value.amountPaid,
|
|
description: dialogData.value.value.description,
|
|
clientFk: dialogData.value.value.clientFk,
|
|
email: email[0].email,
|
|
},
|
|
);
|
|
|
|
if (data) notify('globals.dataSaved', 'positive');
|
|
showForm.value = false;
|
|
}
|
|
|
|
const setAmountToReturn = (newAmountGiven) => {
|
|
const amountPaid = dialogData.value.value.amountPaid;
|
|
|
|
amountToReturn.value = newAmountGiven - amountPaid;
|
|
};
|
|
|
|
function setReference(data) {
|
|
let newDescription = '';
|
|
|
|
switch (data) {
|
|
case 1:
|
|
newDescription = `${t(
|
|
'ticketList.creditCard',
|
|
)}, ${dialogData.value.value.description.replace(
|
|
/^(Credit Card, |Cash, |Transfers, )/,
|
|
'',
|
|
)}`;
|
|
break;
|
|
case 2:
|
|
newDescription = `${t(
|
|
'ticketList.cash',
|
|
)}, ${dialogData.value.value.description.replace(
|
|
/^(Credit Card, |Cash, |Transfers, )/,
|
|
'',
|
|
)}`;
|
|
break;
|
|
case 3:
|
|
newDescription = `${newDescription.replace(
|
|
/^(Credit Card, |Cash, |Transfers, )/,
|
|
'',
|
|
)}`;
|
|
break;
|
|
case 4:
|
|
newDescription = `${t(
|
|
'ticketList.transfers',
|
|
)}, ${dialogData.value.value.description.replace(
|
|
/^(Credit Card, |Cash, |Transfers, )/,
|
|
'',
|
|
)}`;
|
|
break;
|
|
case 3317:
|
|
newDescription = '';
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
dialogData.value.value.description = newDescription;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<FetchData
|
|
url="Companies"
|
|
@on-fetch="(data) => (companiesOptions = data)"
|
|
auto-load
|
|
/>
|
|
<FetchData
|
|
url="Accountings"
|
|
@on-fetch="(data) => (accountingOptions = data)"
|
|
auto-load
|
|
/>
|
|
<VnSection
|
|
:data-key="dataKey"
|
|
:columns="columns"
|
|
prefix="card"
|
|
:array-data-props="{
|
|
url: 'Tickets/filter',
|
|
order: ['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id'],
|
|
exprBuilder,
|
|
}"
|
|
>
|
|
<template #advanced-menu>
|
|
<TicketFilter data-key="TicketList" />
|
|
</template>
|
|
<template #body>
|
|
<VnTable
|
|
ref="tableRef"
|
|
:data-key="dataKey"
|
|
:create="{
|
|
urlCreate: 'Tickets/new',
|
|
title: t('ticketList.createTicket'),
|
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
|
formInitialData,
|
|
}"
|
|
default-mode="table"
|
|
:columns="columns"
|
|
:user-params="userParams"
|
|
:right-search="false"
|
|
redirect="ticket"
|
|
v-model:selected="selectedRows"
|
|
:table="{
|
|
'row-key': 'id',
|
|
selection: 'multiple',
|
|
}"
|
|
data-cy="ticketListTable"
|
|
>
|
|
<template #column-statusIcons="{ row }">
|
|
<TicketProblems :row="row" />
|
|
</template>
|
|
<template #column-salesPersonFk="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ dashIfEmpty(row.userName) }}
|
|
<CustomerDescriptorProxy :id="row.salesPersonFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-shippedDate="{ row }">
|
|
<span v-if="getDateColor(row.shipped)">
|
|
<QChip :class="getDateColor(row.shipped)" dense square>
|
|
{{ toDate(row.shippedDate) }}
|
|
</QChip>
|
|
</span>
|
|
</template>
|
|
<template #column-nickname="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.nickname }}
|
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-addressNickname="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.addressNickname }}
|
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-stateFk="{ row }">
|
|
<span v-if="row.refFk">
|
|
<span class="link" @click.stop>
|
|
{{ row.refFk }}
|
|
<InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
|
|
</span>
|
|
</span>
|
|
<span v-else-if="getColor(row)">
|
|
<QChip :class="getColor(row)" dense square>
|
|
{{ row.state }}
|
|
</QChip>
|
|
</span>
|
|
<span v-else>
|
|
{{ row.state }}
|
|
</span>
|
|
</template>
|
|
<template #column-zoneFk="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ dashIfEmpty(row.zoneName) }}
|
|
<ZoneDescriptorProxy :id="row.zoneFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-totalWithVat="{ row }">
|
|
<QChip
|
|
v-if="row.totalWithVat > 0 && row.totalWithVat < 50"
|
|
class="bg-warning"
|
|
dense
|
|
square
|
|
>
|
|
{{ row.totalWithVat }}
|
|
</QChip>
|
|
</template>
|
|
<template #more-create-dialog="{ data }">
|
|
<VnRow>
|
|
<VnSelect
|
|
url="Clients"
|
|
:fields="['id', 'name']"
|
|
:label="t('ticketList.client')"
|
|
v-model="data.clientId"
|
|
:options="clientsOptions"
|
|
hide-selected
|
|
required
|
|
@update:model-value="() => onClientSelected(data)"
|
|
:sort-by="'id ASC'"
|
|
>
|
|
<template #option="scope">
|
|
<QItem v-bind="scope.itemProps">
|
|
<QItemSection>
|
|
<QItemLabel>
|
|
{{ scope.opt.name }}
|
|
</QItemLabel>
|
|
<QItemLabel caption>
|
|
{{ `#${scope.opt.id}` }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
</VnRow>
|
|
<VnRow>
|
|
<VnSelect
|
|
:label="t('basicData.address')"
|
|
v-model="data.addressId"
|
|
:options="addressesOptions"
|
|
option-label="nickname"
|
|
hide-selected
|
|
map-options
|
|
required
|
|
:disable="!data.clientId"
|
|
:sort-by="'isActive DESC'"
|
|
@update:model-value="() => fetchAvailableAgencies(data)"
|
|
>
|
|
<template #option="scope">
|
|
<QItem
|
|
v-bind="scope.itemProps"
|
|
:class="{ disabled: !scope.opt.isActive }"
|
|
>
|
|
<QItemSection style="min-width: min-content" avatar>
|
|
<QIcon
|
|
v-if="
|
|
scope.opt.isActive &&
|
|
selectedClient?.defaultAddressFk ===
|
|
scope.opt.id
|
|
"
|
|
size="sm"
|
|
color="grey"
|
|
name="star"
|
|
class="fill-icon"
|
|
/>
|
|
</QItemSection>
|
|
<QItemSection>
|
|
<QItemLabel
|
|
:class="{
|
|
'color-vn-label': !scope.opt?.isActive,
|
|
}"
|
|
>
|
|
{{
|
|
`${
|
|
!scope.opt?.isActive
|
|
? t('basicData.inactive')
|
|
: ''
|
|
} `
|
|
}}
|
|
<span>
|
|
{{ scope.opt?.nickname }}:
|
|
{{ scope.opt?.street }},
|
|
{{ scope.opt?.city }}
|
|
</span>
|
|
</QItemLabel>
|
|
<QItemLabel caption>
|
|
{{ `#${scope.opt?.id}` }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
</VnRow>
|
|
<VnRow>
|
|
<div class="col">
|
|
<VnInputDate
|
|
placeholder="dd-mm-aaa"
|
|
:label="t('globals.landed')"
|
|
v-model="data.landed"
|
|
@update:model-value="() => fetchAvailableAgencies(data)"
|
|
/>
|
|
</div>
|
|
</VnRow>
|
|
<VnRow>
|
|
<div class="col">
|
|
<VnSelect
|
|
url="Warehouses"
|
|
:sort-by="['name']"
|
|
:label="t('globals.warehouse')"
|
|
v-model="data.warehouseId"
|
|
:options="warehousesOptions"
|
|
hide-selected
|
|
required
|
|
@update:model-value="() => fetchAvailableAgencies(data)"
|
|
/>
|
|
</div>
|
|
</VnRow>
|
|
<VnRow>
|
|
<div class="col">
|
|
<VnSelect
|
|
:label="t('globals.agency')"
|
|
v-model="data.agencyModeId"
|
|
:options="agenciesOptions"
|
|
option-value="agencyModeFk"
|
|
option-label="agencyMode"
|
|
hide-selected
|
|
/>
|
|
</div>
|
|
</VnRow>
|
|
</template>
|
|
</VnTable>
|
|
</template>
|
|
</VnSection>
|
|
<QPageSticky :offset="[20, 80]" style="z-index: 2">
|
|
<QBtn
|
|
v-if="hasSelectedRows"
|
|
@click="makeInvoice(selectedRows)"
|
|
color="primary"
|
|
fab
|
|
icon="vn:invoice-in"
|
|
data-cy="ticketListMakeInvoiceBtn"
|
|
/>
|
|
<QTooltip>
|
|
{{ t('ticketList.createInvoice') }}
|
|
</QTooltip>
|
|
</QPageSticky>
|
|
<QPageSticky v-if="hasSelectedRows" :offset="[20, 140]" style="z-index: 2">
|
|
<QBtn
|
|
@click.stop="openBalanceDialog(selectedRows)"
|
|
color="primary"
|
|
fab
|
|
icon="vn:recovery"
|
|
/>
|
|
<QTooltip>
|
|
{{ t('ticketList.accountPayment') }}
|
|
</QTooltip>
|
|
</QPageSticky>
|
|
<QDialog ref="dialogRef" v-model="showForm">
|
|
<QCard class="q-pa-md q-mb-md">
|
|
<QForm @submit="onSubmit()" class="q-pa-sm">
|
|
{{ t('ticketList.addPayment') }}
|
|
<VnRow>
|
|
<VnInputDate
|
|
:label="t('ticketList.date')"
|
|
v-model="dialogData.payed"
|
|
/>
|
|
<VnSelect
|
|
:label="t('ticketList.company')"
|
|
v-model="dialogData.companyFk"
|
|
:options="companiesOptions"
|
|
option-label="code"
|
|
hide-selected
|
|
>
|
|
</VnSelect>
|
|
</VnRow>
|
|
<VnRow>
|
|
<VnSelect
|
|
:label="t('ticketList.bank')"
|
|
v-model="dialogData.bankFk"
|
|
:options="accountingOptions"
|
|
option-label="bank"
|
|
hide-selected
|
|
@update:model-value="setReference"
|
|
/>
|
|
<VnInput
|
|
:label="t('ticketList.amount')"
|
|
v-model="dialogData.value.amountPaid"
|
|
/>
|
|
</VnRow>
|
|
<VnRow v-if="dialogData.bankFk === 2">
|
|
<span>
|
|
{{ t('ticketList.cash') }}
|
|
</span>
|
|
</VnRow>
|
|
<VnRow v-if="dialogData.bankFk === 2">
|
|
<VnInput
|
|
:label="t('ticketList.deliveredAmount')"
|
|
v-model="dialogData.value.amountGiven"
|
|
@update:model-value="setAmountToReturn"
|
|
type="number"
|
|
/>
|
|
<VnInput
|
|
:label="t('ticketList.amountToReturn')"
|
|
:model-value="amountToReturn"
|
|
type="number"
|
|
readonly
|
|
/>
|
|
</VnRow>
|
|
<VnRow v-if="dialogData.bankFk === 3 || dialogData.bankFk === 3117">
|
|
<VnInput
|
|
:label="t('ticketList.compensation')"
|
|
v-model="dialogData.value.compensation"
|
|
type="text"
|
|
/>
|
|
</VnRow>
|
|
<VnRow>
|
|
<VnInput
|
|
:label="t('ticketList.reference')"
|
|
v-model="dialogData.value.description"
|
|
type="text"
|
|
/>
|
|
</VnRow>
|
|
<VnRow v-if="dialogData.bankFk === 2">
|
|
<QCheckbox
|
|
:label="t('ticketList.viewReceipt')"
|
|
v-model="dialogData.value.viewReceipt"
|
|
:toggle-indeterminate="false"
|
|
/>
|
|
<QCheckbox
|
|
:label="t('ticketList.sendEmail')"
|
|
v-model="dialogData.value.senEmail"
|
|
:toggle-indeterminate="false"
|
|
/>
|
|
</VnRow>
|
|
<div class="q-mt-lg row justify-end">
|
|
<QBtn
|
|
:label="t('globals.save')"
|
|
color="primary"
|
|
@click="onSubmit()"
|
|
/>
|
|
<QBtn
|
|
flat
|
|
:label="t('globals.close')"
|
|
color="primary"
|
|
v-close-popup
|
|
/>
|
|
</div>
|
|
</QForm>
|
|
</QCard>
|
|
</QDialog>
|
|
<QPageSticky v-if="hasSelectedRows" :offset="[20, 200]" style="z-index: 2">
|
|
<QBtn
|
|
@click="sendDocuware(selectedRows)"
|
|
color="primary"
|
|
fab
|
|
icon="install_mobile"
|
|
/>
|
|
<QTooltip>
|
|
{{ t('ticketList.sendDocuware') }}
|
|
</QTooltip>
|
|
</QPageSticky>
|
|
</template>
|
|
<style scoped>
|
|
.disabled,
|
|
.disabled *,
|
|
[disabled],
|
|
[disabled] * {
|
|
cursor: pointer !important;
|
|
}
|
|
</style>
|
|
<i18n>
|
|
es:
|
|
Search ticket: Buscar ticket
|
|
You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
|
Zone: Zona
|
|
New ticket: Nuevo ticket
|
|
Component lack: Faltan componentes
|
|
</i18n>
|