forked from verdnatura/salix-front
Reviewed-on: verdnatura/salix-front#612 Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
commit
aa5ef76dcf
|
@ -31,6 +31,7 @@ const props = defineProps({
|
|||
});
|
||||
|
||||
defineEmits(['confirm', ...useDialogPluginComponent.emits]);
|
||||
defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() });
|
||||
|
||||
const { dialogRef, onDialogOK } = useDialogPluginComponent();
|
||||
|
||||
|
@ -68,8 +69,10 @@ async function confirm() {
|
|||
<QSpace />
|
||||
<QBtn icon="close" :disable="isLoading" flat round dense v-close-popup />
|
||||
</QCardSection>
|
||||
<QCardSection class="row items-center">
|
||||
<QCardSection class="q-pb-none">
|
||||
<span v-if="message !== false" v-html="message" />
|
||||
</QCardSection>
|
||||
<QCardSection class="row items-center q-pt-none">
|
||||
<slot name="customHTML"></slot>
|
||||
</QCardSection>
|
||||
<QCardActions align="right">
|
||||
|
|
|
@ -98,6 +98,7 @@ globals:
|
|||
to: To
|
||||
notes: Notes
|
||||
refresh: Refresh
|
||||
weight: Weight
|
||||
pageTitles:
|
||||
logIn: Login
|
||||
summary: Summary
|
||||
|
|
|
@ -100,6 +100,7 @@ globals:
|
|||
to: Hasta
|
||||
notes: Notas
|
||||
refresh: Actualizar
|
||||
weight: Peso
|
||||
pageTitles:
|
||||
logIn: Inicio de sesión
|
||||
summary: Resumen
|
||||
|
|
|
@ -9,6 +9,8 @@ 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 VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
|
||||
const props = defineProps({
|
||||
ticket: {
|
||||
|
@ -21,9 +23,10 @@ const { push, currentRoute } = useRouter();
|
|||
const { dialog, notify } = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const { openReport, sendEmail } = usePrintService();
|
||||
|
||||
const ticketSummary = useArrayData('TicketSummary');
|
||||
const ticket = ref(props.ticket);
|
||||
const ticketId = currentRoute.value.params.id;
|
||||
const weight = ref();
|
||||
const actions = {
|
||||
clone: async () => {
|
||||
const opts = { message: t('Ticket cloned'), type: 'positive' };
|
||||
|
@ -46,6 +49,25 @@ const actions = {
|
|||
push({ name: 'TicketSummary', params: { id: clonedTicketId } });
|
||||
}
|
||||
},
|
||||
setWeight: async () => {
|
||||
try {
|
||||
const invoiceIds = (
|
||||
await axios.post(`Tickets/${ticketId}/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}/setDeleted`);
|
||||
|
@ -255,6 +277,12 @@ function openConfirmDialog(callback) {
|
|||
</QItemSection>
|
||||
<QItemSection>{{ t('To clone ticket') }}</QItemSection>
|
||||
</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>
|
||||
|
@ -264,9 +292,25 @@ function openConfirmDialog(callback) {
|
|||
<QItemSection>{{ t('Delete ticket') }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
<VnConfirm
|
||||
ref="weightDialog"
|
||||
:title="t('Set weight')"
|
||||
:message="t('This ticket may be invoiced, do you want to continue?')"
|
||||
:promise="actions.setWeight"
|
||||
>
|
||||
<template #customHTML>
|
||||
<VnInputNumber
|
||||
:label="t('globals.weight')"
|
||||
v-model="weight"
|
||||
class="full-width"
|
||||
/>
|
||||
</template>
|
||||
</VnConfirm>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
en:
|
||||
invoiceIds: "Invoices have been generated with the following ids: {invoiceIds}"
|
||||
|
||||
es:
|
||||
Open Delivery Note...: Abrir albarán...
|
||||
Send Delivery Note...: Enviar albarán...
|
||||
|
@ -284,4 +328,8 @@ es:
|
|||
To clone ticket: Clonar ticket
|
||||
Ticket cloned: Ticked clonado
|
||||
It was not able to clone the ticket: No se pudo clonar el ticket
|
||||
Set weight: Establecer peso
|
||||
Weight set: Peso establecido
|
||||
This ticket may be invoiced, do you want to continue?: Es posible que se facture este ticket, desea continuar?
|
||||
invoiceIds: "Se han generado las facturas con los siguientes ids: {invoiceIds}"
|
||||
</i18n>
|
||||
|
|
|
@ -31,8 +31,7 @@ const $props = defineProps({
|
|||
const entityId = computed(() => $props.id || route.params.id);
|
||||
|
||||
const summaryRef = ref();
|
||||
const ticket = ref();
|
||||
const salesLines = ref(null);
|
||||
const ticket = computed(() => summaryRef.value?.entity);
|
||||
const editableStates = ref([]);
|
||||
const ticketUrl = ref();
|
||||
const grafanaUrl = 'https://grafana.verdnatura.es';
|
||||
|
@ -40,12 +39,6 @@ const grafanaUrl = 'https://grafana.verdnatura.es';
|
|||
onMounted(async () => {
|
||||
ticketUrl.value = (await getUrl('ticket/')) + entityId.value + '/';
|
||||
});
|
||||
async function setData(data) {
|
||||
if (data) {
|
||||
ticket.value = data;
|
||||
salesLines.value = data.sales;
|
||||
}
|
||||
}
|
||||
|
||||
function formattedAddress() {
|
||||
if (!ticket.value) return '';
|
||||
|
@ -89,7 +82,6 @@ async function changeState(value) {
|
|||
<CardSummary
|
||||
ref="summaryRef"
|
||||
:url="`Tickets/${entityId}/summary`"
|
||||
@on-fetch="(data) => setData(data)"
|
||||
data-key="TicketSummary"
|
||||
>
|
||||
<template #header="{ entity }">
|
||||
|
@ -131,7 +123,7 @@ async function changeState(value) {
|
|||
</QList>
|
||||
</QBtnDropdown>
|
||||
</template>
|
||||
<template #body>
|
||||
<template #body="{ entity }">
|
||||
<QCard class="vn-one">
|
||||
<VnTitle
|
||||
:url="ticketUrl + 'basic-data/step-one'"
|
||||
|
@ -139,57 +131,57 @@ async function changeState(value) {
|
|||
/>
|
||||
<VnLv :label="t('ticket.summary.state')">
|
||||
<template #value>
|
||||
<QChip :color="ticket.ticketState?.state?.classColor ?? 'dark'">
|
||||
{{ ticket.ticketState?.state?.name }}
|
||||
<QChip :color="entity.ticketState?.state?.classColor ?? 'dark'">
|
||||
{{ entity.ticketState?.state?.name }}
|
||||
</QChip>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('ticket.summary.salesPerson')">
|
||||
<template #value>
|
||||
<VnUserLink
|
||||
:name="ticket.client?.salesPersonUser?.name"
|
||||
:worker-id="ticket.client?.salesPersonFk"
|
||||
:name="entity.client?.salesPersonUser?.name"
|
||||
:worker-id="entity.client?.salesPersonFk"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.agency')"
|
||||
:value="ticket.agencyMode?.name"
|
||||
:value="entity.agencyMode?.name"
|
||||
/>
|
||||
<VnLv :label="t('ticket.summary.zone')" :value="ticket?.zone?.name" />
|
||||
<VnLv :label="t('ticket.summary.zone')" :value="entity?.zone?.name" />
|
||||
<VnLv
|
||||
:label="t('ticket.summary.warehouse')"
|
||||
:value="ticket.warehouse?.name"
|
||||
:value="entity.warehouse?.name"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.collection')"
|
||||
:value="ticket.ticketCollections[0]?.collectionFk"
|
||||
:value="entity.ticketCollections[0]?.collectionFk"
|
||||
>
|
||||
<template #value>
|
||||
<a
|
||||
:href="`${grafanaUrl}/d/d552ab74-85b4-4e7f-a279-fab7cd9c6124/control-de-expediciones?orgId=1&var-collectionFk=${ticket.ticketCollections[0]?.collectionFk}`"
|
||||
:href="`${grafanaUrl}/d/d552ab74-85b4-4e7f-a279-fab7cd9c6124/control-de-expediciones?orgId=1&var-collectionFk=${entity.ticketCollections[0]?.collectionFk}`"
|
||||
target="_blank"
|
||||
class="grafana"
|
||||
>
|
||||
{{ ticket.ticketCollections[0]?.collectionFk }}
|
||||
{{ entity.ticketCollections[0]?.collectionFk }}
|
||||
</a>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('ticket.summary.route')" :value="ticket.routeFk" />
|
||||
<VnLv :label="t('ticket.summary.route')" :value="entity.routeFk" />
|
||||
<VnLv :label="t('ticket.summary.invoice')">
|
||||
<template #value>
|
||||
<span :class="{ link: ticket.refFk }">
|
||||
{{ dashIfEmpty(ticket.refFk) }}
|
||||
<span :class="{ link: entity.refFk }">
|
||||
{{ dashIfEmpty(entity.refFk) }}
|
||||
<InvoiceOutDescriptorProxy
|
||||
:id="ticket.invoiceOut.id"
|
||||
v-if="ticket.refFk"
|
||||
:id="entity.invoiceOut.id"
|
||||
v-if="entity.refFk"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.weight')"
|
||||
:value="dashIfEmpty(ticket.weight)"
|
||||
:value="dashIfEmpty(entity.weight)"
|
||||
/>
|
||||
</QCard>
|
||||
<QCard class="vn-one">
|
||||
|
@ -199,35 +191,35 @@ async function changeState(value) {
|
|||
/>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.shipped')"
|
||||
:value="toDate(ticket.shipped)"
|
||||
:value="toDate(entity.shipped)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.landed')"
|
||||
:value="toDate(ticket.landed)"
|
||||
:value="toDate(entity.landed)"
|
||||
/>
|
||||
<VnLv :label="t('globals.packages')" :value="ticket.packages" />
|
||||
<VnLv :value="ticket.address.phone">
|
||||
<VnLv :label="t('globals.packages')" :value="entity.packages" />
|
||||
<VnLv :value="entity.address.phone">
|
||||
<template #label>
|
||||
{{ t('ticket.summary.consigneePhone') }}
|
||||
<VnLinkPhone :phone-number="ticket.address.phone" />
|
||||
<VnLinkPhone :phone-number="entity.address.phone" />
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :value="ticket.address.mobile">
|
||||
<VnLv :value="entity.address.mobile">
|
||||
<template #label>
|
||||
{{ t('ticket.summary.consigneeMobile') }}
|
||||
<VnLinkPhone :phone-number="ticket.address.mobile" />
|
||||
<VnLinkPhone :phone-number="entity.address.mobile" />
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :value="ticket.client.phone">
|
||||
<VnLv :value="entity.client.phone">
|
||||
<template #label>
|
||||
{{ t('ticket.summary.clientPhone') }}
|
||||
<VnLinkPhone :phone-number="ticket.client.phone" />
|
||||
<VnLinkPhone :phone-number="entity.client.phone" />
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :value="ticket.client.mobile">
|
||||
<VnLv :value="entity.client.mobile">
|
||||
<template #label>
|
||||
{{ t('ticket.summary.clientMobile') }}
|
||||
<VnLinkPhone :phone-number="ticket.client.mobile" />
|
||||
<VnLinkPhone :phone-number="entity.client.mobile" />
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
|
@ -235,13 +227,13 @@ async function changeState(value) {
|
|||
:value="formattedAddress()"
|
||||
/>
|
||||
</QCard>
|
||||
<QCard class="vn-one" v-if="ticket.notes.length">
|
||||
<QCard class="vn-one" v-if="entity.notes.length">
|
||||
<VnTitle
|
||||
:url="ticketUrl + 'observation'"
|
||||
:text="t('ticket.pageTitles.notes')"
|
||||
/>
|
||||
<VnLv
|
||||
v-for="note in ticket.notes"
|
||||
v-for="note in entity.notes"
|
||||
:key="note.id"
|
||||
:label="note.observationType.description"
|
||||
:value="note.description"
|
||||
|
@ -262,15 +254,15 @@ async function changeState(value) {
|
|||
<div class="bodyCard">
|
||||
<VnLv
|
||||
:label="t('ticket.summary.subtotal')"
|
||||
:value="toCurrency(ticket.totalWithoutVat)"
|
||||
:value="toCurrency(entity.totalWithoutVat)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.vat')"
|
||||
:value="toCurrency(ticket.totalWithVat - ticket.totalWithoutVat)"
|
||||
:value="toCurrency(entity.totalWithVat - entity.totalWithoutVat)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.total')"
|
||||
:value="toCurrency(ticket.totalWithVat)"
|
||||
:value="toCurrency(entity.totalWithVat)"
|
||||
/>
|
||||
</div>
|
||||
</QCard>
|
||||
|
@ -279,7 +271,7 @@ async function changeState(value) {
|
|||
:url="ticketUrl + 'sale'"
|
||||
:text="t('ticket.summary.saleLines')"
|
||||
/>
|
||||
<QTable :rows="ticket.sales" style="text-align: center">
|
||||
<QTable :rows="entity.sales" style="text-align: center">
|
||||
<template #body-cell="{ value }">
|
||||
<QTd>{{ value }}</QTd>
|
||||
</template>
|
||||
|
@ -423,10 +415,10 @@ async function changeState(value) {
|
|||
</QCard>
|
||||
<QCard
|
||||
class="vn-max"
|
||||
v-if="ticket.packagings.length > 0 || ticket.services.length > 0"
|
||||
v-if="entity.packagings.length || entity.services.length"
|
||||
>
|
||||
<VnTitle :url="ticketUrl + 'package'" :text="t('globals.packages')" />
|
||||
<QTable :rows="ticket.packagings" flat>
|
||||
<QTable :rows="entity.packagings" flat>
|
||||
<template #header="props">
|
||||
<QTr :props="props">
|
||||
<QTh auto-width>{{ t('ticket.summary.created') }}</QTh>
|
||||
|
@ -446,7 +438,7 @@ async function changeState(value) {
|
|||
:url="ticketUrl + 'service'"
|
||||
:text="t('ticket.summary.service')"
|
||||
/>
|
||||
<QTable :rows="ticket.services" flat>
|
||||
<QTable :rows="entity.services" flat>
|
||||
<template #header="props">
|
||||
<QTr :props="props">
|
||||
<QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('Ticket descriptor', () => {
|
||||
const toCloneOpt = '[role="menu"] .q-list > :nth-child(5)';
|
||||
const setWeightOpt = '[role="menu"] .q-list > :nth-child(6)';
|
||||
const warehouseValue = ':nth-child(1) > :nth-child(6) > .value > span';
|
||||
const summaryHeader = '.summaryHeader > div';
|
||||
|
||||
const weight = 25;
|
||||
const weightValue = ':nth-child(10) > .value > span';
|
||||
beforeEach(() => {
|
||||
const ticketId = 1;
|
||||
|
||||
cy.login('developer');
|
||||
cy.visit(`/#/ticket/${ticketId}/summary`);
|
||||
cy.waitForElement('.q-page', 7000);
|
||||
cy.viewport(1920, 1080);
|
||||
});
|
||||
|
||||
it('should clone the ticket without warehouse', () => {
|
||||
cy.openLeftMenu();
|
||||
cy.visit('/#/ticket/1/summary');
|
||||
cy.openActionsDescriptor();
|
||||
cy.get(toCloneOpt).click();
|
||||
cy.clickConfirm();
|
||||
|
@ -25,4 +24,15 @@ describe('Ticket descriptor', () => {
|
|||
cy.wrap(owner.trim()).should('eq', 'Bruce Wayne (1101)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should set the weight of the ticket', () => {
|
||||
cy.visit('/#/ticket/10/summary');
|
||||
cy.openActionsDescriptor();
|
||||
cy.get(setWeightOpt).click();
|
||||
cy.intercept('POST', /\/api\/Tickets\/\d+\/setWeight/).as('weight');
|
||||
cy.get('.q-dialog input').type(weight);
|
||||
cy.clickConfirm();
|
||||
cy.wait('@weight');
|
||||
cy.get(weightValue).contains(weight);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue