881 lines
28 KiB
Vue
881 lines
28 KiB
Vue
<script setup>
|
|
import axios from 'axios';
|
|
import { computed, onMounted, ref, toRefs, watch } from 'vue';
|
|
import { useQuasar } from 'quasar';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRouter } from 'vue-router';
|
|
import { usePrintService } from 'composables/usePrintService';
|
|
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
|
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
|
import VnSmsDialog from 'components/common/VnSmsDialog.vue';
|
|
import toDate from 'filters/toDate';
|
|
import FormPopup from 'components/FormPopup.vue';
|
|
import VnSelect from 'components/common/VnSelect.vue';
|
|
import FetchData from 'components/FetchData.vue';
|
|
import VnInputTime from 'src/components/common/VnInputTime.vue';
|
|
import { useAcl } from 'src/composables/useAcl';
|
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
|
import { useArrayData } from 'src/composables/useArrayData';
|
|
|
|
const props = defineProps({
|
|
ticket: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
});
|
|
|
|
onMounted(() => {
|
|
restoreTicket();
|
|
});
|
|
|
|
watch(
|
|
() => props.ticket,
|
|
() => restoreTicket
|
|
);
|
|
|
|
const { push, currentRoute } = useRouter();
|
|
const { dialog, notify } = useQuasar();
|
|
const { t } = useI18n();
|
|
const { openReport, sendEmail } = usePrintService();
|
|
const ticketSummary = useArrayData('TicketSummary');
|
|
const { ticket } = toRefs(props);
|
|
const ticketId = computed(() => props.ticket.id ?? currentRoute.value.params.id);
|
|
const client = ref();
|
|
const address = ref();
|
|
const addressesOptions = ref([]);
|
|
const selectedClient = ref();
|
|
const showTransferDialog = ref(false);
|
|
const showTurnDialog = ref(false);
|
|
const showChangeTimeDialog = ref(false);
|
|
const dialogRef = ref();
|
|
const isEditable = ref();
|
|
const hasInvoicing = useAcl('invoicing');
|
|
const hasPdf = ref();
|
|
const weight = ref();
|
|
const hasDocuwareFile = ref();
|
|
const quasar = useQuasar();
|
|
const canRestoreTicket = ref(false);
|
|
|
|
const onClientSelected = async(clientId) =>{
|
|
await fetchClient(clientId);
|
|
await fetchAddresses(clientId);
|
|
};
|
|
|
|
const fetchClient = async (clientId) => {
|
|
const filter = {
|
|
include: {
|
|
relation: 'defaultAddress',
|
|
scope: {
|
|
fields: ['id', 'nickname'],
|
|
},
|
|
},
|
|
where: { id: clientId },
|
|
};
|
|
const params = { filter: JSON.stringify(filter) };
|
|
const { data } = await axios.get('Clients', { params });
|
|
const [client] = data;
|
|
selectedClient.value = client;
|
|
};
|
|
|
|
const fetchAddresses = async (clientId) => {
|
|
if (!clientId) return;
|
|
|
|
const filter = {
|
|
fields: ['nickname', 'street', 'city', 'id', 'isActive'],
|
|
order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'],
|
|
};
|
|
const params = { filter: JSON.stringify(filter) };
|
|
const { data } = await axios.get(`Clients/${clientId}/addresses`, {
|
|
params,
|
|
});
|
|
addressesOptions.value = data;
|
|
|
|
const { defaultAddress } = selectedClient.value;
|
|
address.value = defaultAddress.id;
|
|
};
|
|
|
|
const actions = {
|
|
clone: async () => {
|
|
const opts = { message: t('Ticket cloned'), type: 'positive' };
|
|
let clonedTicketId;
|
|
|
|
try {
|
|
const { data } = await axios.post(`Tickets/cloneAll`, {
|
|
ticketsIds: [ticket.value.id],
|
|
withWarehouse: true,
|
|
negative: false,
|
|
});
|
|
clonedTicketId = data[0].id;
|
|
} catch (e) {
|
|
opts.message = t('It was not able to clone the ticket');
|
|
opts.type = 'negative';
|
|
} finally {
|
|
notify(opts);
|
|
|
|
if (clonedTicketId)
|
|
push({ name: 'TicketSummary', params: { id: clonedTicketId } });
|
|
}
|
|
},
|
|
setWeight: async () => {
|
|
try {
|
|
const invoiceIds = (
|
|
await axios.post(`Tickets/${ticketId.value}/setWeight`, {
|
|
weight: weight.value,
|
|
})
|
|
).data;
|
|
|
|
notify({ message: t('Weight set'), type: 'positive' });
|
|
if (invoiceIds.length)
|
|
notify({
|
|
message: t('invoiceIds', { invoiceIds: invoiceIds.join() }),
|
|
type: 'positive',
|
|
});
|
|
await ticketSummary.fetch({ updateRouter: false });
|
|
} catch (e) {
|
|
notify({ message: e.message, type: 'negative' });
|
|
}
|
|
},
|
|
remove: async () => {
|
|
try {
|
|
await axios.post(`Tickets/${ticketId.value}/setDeleted`);
|
|
|
|
notify({ message: t('Ticket deleted'), type: 'positive' });
|
|
notify({
|
|
message: t('You can undo this action within the first hour'),
|
|
icon: 'info',
|
|
type: 'warning',
|
|
});
|
|
|
|
push({ name: 'TicketList' });
|
|
} catch (e) {
|
|
notify({ message: e.message, type: 'negative' });
|
|
}
|
|
},
|
|
};
|
|
|
|
function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
|
|
const path = `Tickets/${ticket.value.id}/delivery-note-${documentType}`;
|
|
openReport(
|
|
path,
|
|
{
|
|
recipientId: ticket.value.clientFk,
|
|
type: type,
|
|
},
|
|
'_blank'
|
|
);
|
|
}
|
|
|
|
function sendDeliveryNoteConfirmation(type = 'deliveryNote', documentType = 'pdf') {
|
|
const customer = ticket.value.client;
|
|
dialog({
|
|
component: SendEmailDialog,
|
|
componentProps: {
|
|
data: {
|
|
address: customer.email,
|
|
type: type,
|
|
documentType: documentType,
|
|
},
|
|
promise: sendDeliveryNote,
|
|
},
|
|
});
|
|
}
|
|
|
|
async function sendDeliveryNote({ address, type, documentType }) {
|
|
const id = ticket.value.id;
|
|
const customer = ticket.value.client;
|
|
let pathName = 'delivery-note-email';
|
|
if (documentType == 'csv') pathName = 'delivery-note-csv-email';
|
|
|
|
const path = `Tickets/${id}/${pathName}`;
|
|
return sendEmail(path, {
|
|
recipientId: customer.id,
|
|
recipient: address,
|
|
type: type,
|
|
});
|
|
}
|
|
|
|
const shipped = toDate(ticket.value.shipped);
|
|
function showSmsDialog(template, customData) {
|
|
const address = ticket.value.address;
|
|
const client = ticket.value.client;
|
|
const phone =
|
|
currentRoute.value.params.phone ||
|
|
address.mobile ||
|
|
address.phone ||
|
|
client.mobile ||
|
|
client.phone;
|
|
|
|
const data = {
|
|
orderId: ticket.value.id,
|
|
shipped: shipped,
|
|
};
|
|
|
|
if (typeof customData === 'object') {
|
|
Object.assign(data, customData);
|
|
}
|
|
|
|
dialog({
|
|
component: VnSmsDialog,
|
|
componentProps: {
|
|
phone: phone,
|
|
template: template,
|
|
locale: client?.user?.lang ?? 'default_locale',
|
|
data: data,
|
|
promise: sendSms,
|
|
},
|
|
});
|
|
}
|
|
|
|
async function showSmsDialogWithChanges() {
|
|
const query = `TicketLogs/${ticketId.value}/getChanges`;
|
|
const response = await axios.get(query);
|
|
|
|
showSmsDialog('orderChanges', { changes: response.data });
|
|
}
|
|
|
|
async function sendSms(body) {
|
|
await axios.post(`Tickets/${ticketId.value}/sendSms`, body);
|
|
notify({
|
|
message: 'Notification sent',
|
|
type: 'positive',
|
|
});
|
|
}
|
|
|
|
function openConfirmDialog(callback) {
|
|
dialog({
|
|
component: VnConfirm,
|
|
componentProps: {
|
|
title: t('This ticket will be removed from current route! Continue anyway?'),
|
|
message: t('You are going to delete this ticket'),
|
|
promise: actions[callback],
|
|
},
|
|
});
|
|
}
|
|
|
|
function generatePdfDialog() {
|
|
dialog({
|
|
component: VnConfirm,
|
|
componentProps: {
|
|
promise: generatePdfInvoice,
|
|
},
|
|
});
|
|
}
|
|
|
|
async function generatePdfInvoice() {
|
|
const { data } = await axios.get('invoiceOuts', {
|
|
params: {
|
|
filter: JSON.stringify({
|
|
where: { ref: ticket.value.refFk },
|
|
}),
|
|
},
|
|
});
|
|
const invoiceId = data[0].id;
|
|
const { response } = await axios.post(`InvoiceOuts/${invoiceId}/createPdf`);
|
|
if (!response) {
|
|
notify({
|
|
message: 'The invoice PDF document has been regenerated',
|
|
type: 'positive',
|
|
});
|
|
}
|
|
}
|
|
|
|
function makeInvoiceDialog() {
|
|
dialog({
|
|
component: VnConfirm,
|
|
componentProps: {
|
|
title: t('Are you sure you want to invoice this ticket?'),
|
|
message: t('You are going to invoice this ticket'),
|
|
promise: makeInvoice,
|
|
},
|
|
});
|
|
}
|
|
async function makeInvoice() {
|
|
const params = {
|
|
ticketsIds: [parseInt(ticketId.value)],
|
|
};
|
|
await axios.post(`Tickets/invoiceTicketsAndPdf`, params);
|
|
|
|
notify({
|
|
message: t('Ticket invoiced'),
|
|
type: 'positive',
|
|
});
|
|
window.location.reload();
|
|
}
|
|
|
|
async function transferClient(client, address) {
|
|
const params = {
|
|
clientFk: client,
|
|
addressFk: address,
|
|
};
|
|
|
|
await axios.patch( `Tickets/${ticketId.value}/transferClient`, params );
|
|
window.location.reload();
|
|
}
|
|
|
|
async function addTurn(day) {
|
|
const params = {
|
|
ticketFk: parseInt(ticketId.value),
|
|
weekDay: day,
|
|
agencyModeFk: ticket.value.agencyModeFk,
|
|
};
|
|
await axios.patch(`TicketWeeklies`, params);
|
|
|
|
notify({
|
|
message: t('Current ticket deleted and added to shift'),
|
|
type: 'positive',
|
|
});
|
|
window.location.reload();
|
|
}
|
|
|
|
async function createRefund(withWarehouse) {
|
|
const params = {
|
|
ticketsIds: [parseInt(ticketId.value)],
|
|
withWarehouse: withWarehouse,
|
|
negative: true,
|
|
};
|
|
const { data } = await axios.post(`Tickets/cloneAll`, params);
|
|
|
|
if (data) {
|
|
const [refundTicket] = data;
|
|
notify(t('refundTicketCreated', { ticketId: refundTicket.id }), 'positive');
|
|
push({ name: 'TicketSale', params: { id: refundTicket.id } });
|
|
}
|
|
}
|
|
|
|
async function changeShippedHour(time) {
|
|
const params = {
|
|
shipped: time,
|
|
};
|
|
|
|
const { data } = await axios.post(
|
|
`Tickets/${ticketId.value}/updateEditableTicket`,
|
|
params
|
|
);
|
|
|
|
if (data) window.location.reload();
|
|
}
|
|
|
|
function openRecalculateDialog() {
|
|
dialog({
|
|
component: VnConfirm,
|
|
componentProps: {
|
|
title: t('Recalculate components'),
|
|
message: t('Are you sure you want to recalculate components?'),
|
|
promise: recalculateComponents,
|
|
},
|
|
});
|
|
}
|
|
|
|
async function recalculateComponents() {
|
|
await axios.post(`Tickets/${ticketId.value}/recalculateComponents`);
|
|
notify({
|
|
message: t('Data saved'),
|
|
type: 'positive',
|
|
});
|
|
window.location.reload();
|
|
}
|
|
|
|
const handleFetchData = (data) => {
|
|
isEditable.value = data;
|
|
handleInvoiceOutData();
|
|
};
|
|
|
|
async function handleInvoiceOutData() {
|
|
const { data } = await axios.get(`InvoiceOuts`, {
|
|
params: {
|
|
filter: JSON.stringify({ where: { ref: ticket.value.refFk } }),
|
|
},
|
|
});
|
|
hasPdf.value = data[0]?.hasPdf;
|
|
}
|
|
|
|
async function docuwareDownload() {
|
|
await axios.get(`Tickets/${ticketId.value}/docuwareDownload`);
|
|
}
|
|
|
|
async function hasDocuware() {
|
|
const { data } = await axios.post(`Docuwares/${ticketId.value}/checkFile`, {
|
|
fileCabinet: 'deliveryNote',
|
|
signed: true,
|
|
});
|
|
hasDocuwareFile.value = data;
|
|
}
|
|
|
|
async function uploadDocuware(force) {
|
|
if (!force)
|
|
return quasar
|
|
.dialog({
|
|
component: VnConfirm,
|
|
componentProps: {
|
|
title: t('Send PDF to tablet'),
|
|
message: t('Are you sure you want to replace this delivery note?'),
|
|
},
|
|
})
|
|
.onOk(async () => {
|
|
uploadDocuware(true);
|
|
});
|
|
|
|
const { data } = await axios.post(`Docuwares/upload`, {
|
|
fileCabinet: 'deliveryNote',
|
|
ticketIds: [parseInt(ticketId.value)],
|
|
});
|
|
|
|
if (data) notify({ message: t('PDF sent!'), type: 'positive' });
|
|
}
|
|
|
|
const restoreTicket = async () => {
|
|
const filter = {
|
|
fields: ['id', 'originFk', 'creationDate', 'newInstance'],
|
|
where: {
|
|
originFk: ticketId.value,
|
|
newInstance: { like: '%"isDeleted":true%' },
|
|
},
|
|
order: 'creationDate DESC',
|
|
limit: 1,
|
|
};
|
|
const params = { filter: JSON.stringify(filter) };
|
|
|
|
const { data } = await axios.get(`TicketLogs`, { params });
|
|
|
|
if (data && data.length) {
|
|
const now = Date.vnNew();
|
|
const maxDate = new Date(data[0].creationDate);
|
|
maxDate.setHours(maxDate.getHours() + 1);
|
|
if (now <= maxDate) {
|
|
return (canRestoreTicket.value = true);
|
|
}
|
|
return (canRestoreTicket.value = false);
|
|
}
|
|
return (canRestoreTicket.value = false);
|
|
};
|
|
|
|
async function openRestoreConfirmation(force) {
|
|
if (!force)
|
|
return quasar
|
|
.dialog({
|
|
component: VnConfirm,
|
|
componentProps: {
|
|
title: t('Are you sure you want to restore the ticket?'),
|
|
message: t('You are going to restore this ticket'),
|
|
},
|
|
})
|
|
.onOk(async () => {
|
|
ticketToRestore();
|
|
});
|
|
}
|
|
|
|
async function ticketToRestore() {
|
|
const { data } = await axios.post(`Tickets/${ticketId.value}/restore`);
|
|
if (data) {
|
|
notify({ message: t('Ticket restored'), type: 'positive' });
|
|
}
|
|
}
|
|
</script>
|
|
<template>
|
|
<FetchData
|
|
:url="`Tickets/${ticketId}/isEditable`"
|
|
auto-load
|
|
@on-fetch="handleFetchData"
|
|
/>
|
|
<QItem @click="showTransferDialog = !showTransferDialog" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="content_paste" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Transfer client') }}</QItemSection>
|
|
</QItem>
|
|
<QDialog ref="dialogRef" v-model="showTransferDialog">
|
|
<FormPopup
|
|
@on-submit="transferClient(client, address)"
|
|
:title="t('Transfer client')"
|
|
:custom-submit-button-label="t('Transfer client')"
|
|
:default-cancel-button="false"
|
|
>
|
|
<template #form-inputs>
|
|
<VnSelect
|
|
url="Clients"
|
|
:fields="['id', 'name', 'defaultAddressFk']"
|
|
v-model="client"
|
|
:label="t('Client')"
|
|
auto-load
|
|
@update:model-value="() => onClientSelected(client)"
|
|
>
|
|
<template #option="scope">
|
|
<QItem v-bind="scope.itemProps">
|
|
<QItemSection>
|
|
<QItemLabel>
|
|
{{ `#${scope.opt.id} - ` }}
|
|
{{ scope.opt.name }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
<VnSelect
|
|
:disable="!client"
|
|
:options="addressesOptions"
|
|
:fields="['id', 'nickname']"
|
|
option-value="id"
|
|
option-label="nickname"
|
|
v-model="address"
|
|
:label="t('ticketList.addressNickname')"
|
|
auto-load
|
|
:hint="!client ? t('Select a client to enable') : ''"
|
|
>
|
|
<template #option="scope">
|
|
<QItem v-bind="scope.itemProps">
|
|
<QItemSection>
|
|
<QItemLabel>
|
|
{{ `#${scope.opt.id} - ` }}
|
|
{{ scope.opt.nickname }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
</template>
|
|
</FormPopup>
|
|
</QDialog>
|
|
<QItem @click="showTurnDialog = !showTurnDialog" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="vn:calendar" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('addTurn') }}</QItemSection>
|
|
</QItem>
|
|
<QDialog ref="dialogRef" v-model="showTurnDialog">
|
|
<FormPopup
|
|
@on-submit="addTurn"
|
|
:title="t('What is the day of receipt of the ticket?')"
|
|
:default-submit-button="false"
|
|
:default-cancel-button="false"
|
|
style="text-align: center"
|
|
>
|
|
<template #form-inputs>
|
|
<QBtnGroup spread>
|
|
<QBtn
|
|
:label="t('weekdays.mon')"
|
|
color="primary"
|
|
@click="addTurn(0)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
<QBtn
|
|
:label="t('weekdays.tue')"
|
|
color="primary"
|
|
@click="addTurn(1)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
<QBtn
|
|
:label="t('weekdays.wed')"
|
|
color="primary"
|
|
@click="addTurn(2)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
<QBtn
|
|
:label="t('weekdays.thu')"
|
|
color="primary"
|
|
@click="addTurn(3)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
<QBtn
|
|
:label="t('weekdays.fri')"
|
|
color="primary"
|
|
@click="addTurn(4)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
<QBtn
|
|
:label="t('weekdays.sat')"
|
|
color="primary"
|
|
@click="addTurn(5)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
<QBtn
|
|
:label="t('weekdays.sun')"
|
|
color="primary"
|
|
@click="addTurn(6)"
|
|
v-ripple
|
|
class="weekdaysBtn"
|
|
/>
|
|
</QBtnGroup>
|
|
</template>
|
|
</FormPopup>
|
|
</QDialog>
|
|
<QItem v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="picture_as_pdf" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Show Delivery Note...') }}</QItemSection>
|
|
<QItemSection side>
|
|
<QIcon name="keyboard_arrow_right" />
|
|
</QItemSection>
|
|
<QMenu
|
|
anchor="top end"
|
|
self="top start"
|
|
auto-close
|
|
bordered
|
|
@click="hasDocuware()"
|
|
>
|
|
<QList>
|
|
<QItem @click="openDeliveryNote('deliveryNote')" v-ripple clickable>
|
|
<QItemSection>{{ t('as PDF') }}</QItemSection>
|
|
</QItem>
|
|
<QItem @click="openDeliveryNote('withoutPrices')" v-ripple clickable>
|
|
<QItemSection>{{ t('as PDF without prices') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
v-if="hasDocuwareFile"
|
|
@click="docuwareDownload()"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
<QItemSection>{{ t('as PDF signed') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
@click="openDeliveryNote('deliveryNote', 'csv')"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
<QItemSection>{{ t('as CSV') }}</QItemSection>
|
|
</QItem>
|
|
</QList>
|
|
</QMenu>
|
|
</QItem>
|
|
<QItem v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="send" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Send Delivery Note...') }}</QItemSection>
|
|
<QItemSection side>
|
|
<QIcon name="keyboard_arrow_right" />
|
|
</QItemSection>
|
|
<QMenu anchor="top end" self="top start" auto-close @click="hasDocuware()">
|
|
<QList>
|
|
<QItem
|
|
@click="sendDeliveryNoteConfirmation('deliveryNote')"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
<QItemSection>{{ t('Send PDF') }}</QItemSection>
|
|
</QItem>
|
|
<QItem @click="uploadDocuware(!hasDocuwareFile)" v-ripple clickable>
|
|
<QItemSection>{{ t('Send PDF to tablet') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
@click="sendDeliveryNoteConfirmation('deliveryNote', 'csv')"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
<QItemSection>{{ t('Send CSV') }}</QItemSection>
|
|
</QItem>
|
|
</QList>
|
|
</QMenu>
|
|
</QItem>
|
|
<QItem @click="openDeliveryNote('proforma')" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="receipt" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Show Proforma') }}</QItemSection>
|
|
</QItem>
|
|
<QItem v-if="canRestoreTicket" @click="openRestoreConfirmation()" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="restore" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Restore ticket') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
v-if="isEditable"
|
|
@click="showChangeTimeDialog = !showChangeTimeDialog"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
<QItemSection avatar>
|
|
<QIcon name="schedule" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Change shipped hour') }}</QItemSection>
|
|
</QItem>
|
|
<QDialog ref="dialogRef" v-model="showChangeTimeDialog">
|
|
<FormPopup @on-submit="changeShippedHour(time)" :title="t('Change shipped hour')">
|
|
<template #form-inputs>
|
|
<VnInputTime v-model="time" :label="t('Shipped hour')" clearable />
|
|
</template>
|
|
</FormPopup>
|
|
</QDialog>
|
|
<QItem v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="sms" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Send SMS...') }}</QItemSection>
|
|
<QItemSection side>
|
|
<QIcon name="keyboard_arrow_right" />
|
|
</QItemSection>
|
|
<QMenu anchor="top end" self="top start" auto-close>
|
|
<QList>
|
|
<QItem @click="showSmsDialog('pendingPayment')" v-ripple clickable>
|
|
<QItemSection>{{ t('Pending payment') }}</QItemSection>
|
|
</QItem>
|
|
<QItem @click="showSmsDialog('minAmount')" v-ripple clickable>
|
|
<QItemSection>{{ t('Minimum import') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
@click="showSmsDialogWithChanges('orderChanges')"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
<QItemSection>{{ t('Notify changes') }}</QItemSection>
|
|
</QItem>
|
|
</QList>
|
|
</QMenu>
|
|
</QItem>
|
|
<QItem @click="makeInvoiceDialog()" v-ripple clickable v-if="isEditable">
|
|
<QItemSection avatar>
|
|
<QIcon name="picture_as_pdf" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Make invoice') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
@click="generatePdfDialog()"
|
|
v-ripple
|
|
clickable
|
|
v-if="ticket.refFk !== null && (hasInvoicing || hasPdf)"
|
|
>
|
|
<QItemSection avatar>
|
|
<QIcon name="picture_as_pdf" />
|
|
</QItemSection>
|
|
<QItemSection>{{
|
|
hasPdf ? t('Regenerate PDF invoice') : t('Generate PDF invoice')
|
|
}}</QItemSection>
|
|
</QItem>
|
|
<QItem @click="openConfirmDialog('clone')" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="content_copy" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('To clone ticket') }}</QItemSection>
|
|
</QItem>
|
|
<QItem v-if="isEditable" @click="openRecalculateDialog()" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="refresh" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Recalculate components') }}</QItemSection>
|
|
</QItem>
|
|
<QItem v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="monetization_on" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Refund all...') }}</QItemSection>
|
|
<QItemSection side>
|
|
<QIcon name="keyboard_arrow_right" />
|
|
</QItemSection>
|
|
<QMenu anchor="top end" self="top start" auto-close bordered>
|
|
<QList>
|
|
<QItem v-ripple clickable @click="createRefund(true)">
|
|
<QItemSection>
|
|
{{ t('with warehouse') }}
|
|
</QItemSection>
|
|
</QItem>
|
|
<QItem v-ripple clickable @click="createRefund(false)">
|
|
<QItemSection>
|
|
{{ t('without warehouse') }}
|
|
</QItemSection>
|
|
</QItem>
|
|
</QList>
|
|
</QMenu>
|
|
</QItem>
|
|
<QItem @click="$refs.weightDialog.show()" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="weight" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Set weight') }}</QItemSection>
|
|
</QItem>
|
|
<template v-if="!ticket.isDeleted">
|
|
<QSeparator />
|
|
<QItem @click="openConfirmDialog('remove')" v-ripple clickable>
|
|
<QItemSection avatar>
|
|
<QIcon name="delete" />
|
|
</QItemSection>
|
|
<QItemSection>{{ t('Delete ticket') }}</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
<VnConfirm
|
|
ref="weightDialog"
|
|
:title="t('Set weight')"
|
|
:message="false"
|
|
:promise="actions.setWeight"
|
|
>
|
|
<template #customHTML>
|
|
<VnInputNumber
|
|
:label="t('globals.weight')"
|
|
v-model="weight"
|
|
class="full-width"
|
|
/>
|
|
</template>
|
|
</VnConfirm>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.weekdaysBtn {
|
|
margin: 1%;
|
|
}
|
|
</style>
|
|
<i18n>
|
|
en:
|
|
addTurn: Add turn
|
|
invoiceIds: "Invoices have been generated with the following ids: {invoiceIds}"
|
|
|
|
es:
|
|
Show Delivery Note...: Ver albarán...
|
|
Send Delivery Note...: Enviar albarán...
|
|
as PDF: como PDF
|
|
as PDF without prices: como PDF sin precios
|
|
as CSV: Como CSV
|
|
Send PDF: Enviar PDF
|
|
Send PDF to tablet: Enviar PDF a tablet
|
|
Send CSV: Enviar CSV
|
|
Show Proforma: Ver proforma
|
|
Delete ticket: Eliminar ticket
|
|
Send SMS...: Enviar SMS...
|
|
Pending payment: Pago pendiente
|
|
Minimum import: Importe mínimo
|
|
Notify changes: Notificar cambios
|
|
Ticket deleted: Ticket eliminado
|
|
You can undo this action within the first hour: Puedes deshacer esta acción dentro de la primera hora
|
|
To clone ticket: Clonar ticket
|
|
Ticket cloned: Ticked clonado
|
|
It was not able to clone the ticket: No se pudo clonar el ticket
|
|
Generate PDF invoice: Generar PDF factura
|
|
Regenerate PDF invoice: Regenerar PDF factura
|
|
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
|
|
Transfer client: Transferir cliente
|
|
Client: Cliente
|
|
addTurn: Añadir a turno
|
|
What is the day of receipt of the ticket?: ¿Cuál es el día de preparación del pedido?
|
|
Current ticket deleted and added to shift: Ticket actual eliminado y añadido al turno
|
|
Refund all...: Abonar todo...
|
|
with warehouse: con almacén
|
|
without warehouse: sin almacén
|
|
Make invoice: Crear factura
|
|
Change shipped hour: Cambiar hora de envío
|
|
Shipped hour: Hora de envío
|
|
Recalculate components: Recalcular componentes
|
|
Are you sure you want to recalculate components?: ¿Seguro que quieres recalcular los componentes?
|
|
Data saved: Datos guardados
|
|
Are you sure you want to invoice this ticket?: ¿Seguro que quieres facturar este ticket?
|
|
You are going to invoice this ticket: Vas a facturar este ticket
|
|
Ticket invoiced: Ticket facturado
|
|
Set weight: Establecer peso
|
|
Weight set: Peso establecido
|
|
invoiceIds: "Se han generado las facturas con los siguientes ids: {invoiceIds}"
|
|
This ticket will be removed from current route! Continue anyway?: ¡Se eliminará el ticket de la ruta actual! ¿Continuar de todas formas?
|
|
You are going to delete this ticket: Vas a eliminar este ticket
|
|
as PDF signed: como PDF firmado
|
|
Are you sure you want to replace this delivery note?: ¿Seguro que quieres reemplazar este albarán?
|
|
Restore ticket: Restaurar ticket
|
|
Are you sure you want to restore the ticket?: ¿Seguro que quieres restaurar el ticket?
|
|
You are going to restore this ticket: Vas a restaurar este ticket
|
|
Ticket restored: Ticket restaurado
|
|
Select a client to enable: Selecciona un cliente para habilitar
|
|
</i18n>
|