diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index fd4860107..4fa374b62 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -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"> diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index ef5e02b12..4e1c4f406 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -96,6 +96,7 @@ globals: to: To notes: Notes refresh: Refresh + weight: Weight pageTitles: logIn: Login summary: Summary diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 7143bf96f..6415a2930 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -98,6 +98,7 @@ globals: to: Hasta notes: Notas refresh: Actualizar + weight: Peso pageTitles: logIn: Inicio de sesión summary: Resumen diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue index 441b547ed..9491579f8 100644 --- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue +++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue @@ -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,7 +49,25 @@ const actions = { push({ name: 'TicketSummary', params: { id: clonedTicketId } }); } }, - setWeight: async () => {}, + 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`); @@ -261,7 +282,7 @@ function openConfirmDialog(callback) { </QItemSection> <QItemSection>{{ t('To clone ticket') }}</QItemSection> </QItem> - <QItem @click="openConfirmDialog('setWeight')" v-ripple clickable> + <QItem @click="$refs.weightDialog.show()" v-ripple clickable> <QItemSection avatar> <QIcon name="weight" /> </QItemSection> @@ -276,9 +297,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... @@ -297,5 +334,7 @@ es: 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> diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index 177384663..a7a541e6d 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -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> @@ -420,10 +412,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> @@ -443,7 +435,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>