7658-devToTest_2428 #508
|
@ -450,6 +450,7 @@ ticket:
|
||||||
futureTickets: Future tickets
|
futureTickets: Future tickets
|
||||||
purchaseRequest: Purchase request
|
purchaseRequest: Purchase request
|
||||||
weeklyTickets: Weekly tickets
|
weeklyTickets: Weekly tickets
|
||||||
|
services: Service
|
||||||
tracking: Tracking
|
tracking: Tracking
|
||||||
list:
|
list:
|
||||||
nickname: Nickname
|
nickname: Nickname
|
||||||
|
|
|
@ -449,6 +449,7 @@ ticket:
|
||||||
futureTickets: Tickets a futuro
|
futureTickets: Tickets a futuro
|
||||||
purchaseRequest: Petición de compra
|
purchaseRequest: Petición de compra
|
||||||
weeklyTickets: Tickets programados
|
weeklyTickets: Tickets programados
|
||||||
|
services: Servicios
|
||||||
tracking: Estados
|
tracking: Estados
|
||||||
list:
|
list:
|
||||||
nickname: Alias
|
nickname: Alias
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, onMounted, nextTick } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['onDataSaved']);
|
||||||
|
|
||||||
|
const nameInputRef = ref(null);
|
||||||
|
const serviceFormData = reactive({});
|
||||||
|
|
||||||
|
const onDataSaved = (formData, requestResponse) => {
|
||||||
|
emit('onDataSaved', formData, requestResponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await nextTick();
|
||||||
|
nameInputRef.value.focus();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FormModelPopup
|
||||||
|
url-create="TicketServiceTypes"
|
||||||
|
model="TicketServiceType"
|
||||||
|
:title="t('New service type')"
|
||||||
|
:form-initial-data="serviceFormData"
|
||||||
|
@on-data-saved="onDataSaved"
|
||||||
|
>
|
||||||
|
<template #form-inputs="{ data }">
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<VnInput
|
||||||
|
ref="nameInputRef"
|
||||||
|
:label="t('service.description')"
|
||||||
|
v-model="data.name"
|
||||||
|
:required="true"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
</template>
|
||||||
|
</FormModelPopup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
New service type: Nuevo tipo de servicio
|
||||||
|
</i18n>
|
|
@ -0,0 +1,190 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, computed, onMounted } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import CrudModel from 'components/CrudModel.vue';
|
||||||
|
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import TicketCreateServiceType from './TicketCreateServiceType.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const ticketServiceTypeFetchRef = ref(null);
|
||||||
|
const ticketServiceCrudRef = ref(null);
|
||||||
|
const ticketServiceOptions = ref([]);
|
||||||
|
const arrayData = useArrayData('TicketNotes');
|
||||||
|
const { store } = arrayData;
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
const selected = ref([]);
|
||||||
|
const defaultTaxClass = ref(null);
|
||||||
|
|
||||||
|
const crudModelFilter = computed(() => ({
|
||||||
|
where: { ticketFk: route.params.id },
|
||||||
|
}));
|
||||||
|
|
||||||
|
const crudModelRequiredData = computed(() => ({
|
||||||
|
ticketFk: route.params.id,
|
||||||
|
taxClassFk: defaultTaxClass.value?.id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.params.id,
|
||||||
|
async () => {
|
||||||
|
store.filter = crudModelFilter.value;
|
||||||
|
await ticketServiceCrudRef.value.reload();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(async () => await getDefaultTaxClass());
|
||||||
|
|
||||||
|
const createRefund = async () => {
|
||||||
|
try {
|
||||||
|
if (!selected.value.length) return;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
servicesIds: selected.value.map((s) => +s.ticketFk),
|
||||||
|
withWarehouse: false,
|
||||||
|
negative: true,
|
||||||
|
};
|
||||||
|
const { data } = await axios.post('Sales/clone', params);
|
||||||
|
const [refundTicket] = data;
|
||||||
|
notify(
|
||||||
|
t('service.createRefundSuccess', {
|
||||||
|
ticketId: refundTicket.id,
|
||||||
|
}),
|
||||||
|
'positive'
|
||||||
|
);
|
||||||
|
router.push({ name: 'TicketSale', params: { id: refundTicket.id } });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDefaultTaxClass = async () => {
|
||||||
|
try {
|
||||||
|
let filter = {
|
||||||
|
where: { code: 'G' },
|
||||||
|
};
|
||||||
|
const { data } = await axios.get('TaxClasses/findOne', {
|
||||||
|
params: { filter: JSON.stringify(filter) },
|
||||||
|
});
|
||||||
|
defaultTaxClass.value = data;
|
||||||
|
console.log('defaultTaxClass', defaultTaxClass.value);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = computed(() => [
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
label: t('service.description'),
|
||||||
|
field: (row) => row.ticketServiceTypeFk,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'quantity',
|
||||||
|
label: t('service.quantity'),
|
||||||
|
field: (row) => row.quantity,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
label: t('service.price'),
|
||||||
|
field: (row) => row.price,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
ref="ticketServiceTypeFetchRef"
|
||||||
|
@on-fetch="(data) => (ticketServiceOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="TicketServiceTypes"
|
||||||
|
/>
|
||||||
|
<CrudModel
|
||||||
|
ref="ticketServiceCrudRef"
|
||||||
|
data-key="TicketService"
|
||||||
|
url="TicketServices"
|
||||||
|
model="TicketService"
|
||||||
|
:filter="crudModelFilter"
|
||||||
|
:data-required="crudModelRequiredData"
|
||||||
|
auto-load
|
||||||
|
v-model:selected="selected"
|
||||||
|
>
|
||||||
|
<template #moreBeforeActions>
|
||||||
|
<QBtn
|
||||||
|
color="primary"
|
||||||
|
:label="t('service.pay')"
|
||||||
|
:disabled="!selected.length"
|
||||||
|
@click.stop="createRefund()"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #body="{ rows }">
|
||||||
|
<QTable
|
||||||
|
:columns="columns"
|
||||||
|
:rows="rows"
|
||||||
|
row-key="$index"
|
||||||
|
selection="multiple"
|
||||||
|
v-model:selected="selected"
|
||||||
|
table-header-class="text-left"
|
||||||
|
>
|
||||||
|
<template #body-cell-description="{ row, col }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<VnSelectDialog
|
||||||
|
:label="col.label"
|
||||||
|
v-model="row.ticketServiceTypeFk"
|
||||||
|
:options="ticketServiceOptions"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
hide-selected
|
||||||
|
>
|
||||||
|
<template #form>
|
||||||
|
<TicketCreateServiceType
|
||||||
|
@on-data-saved="ticketServiceTypeFetchRef.fetch()"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VnSelectDialog>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-quantity="{ row, col }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<VnInput
|
||||||
|
:label="col.label"
|
||||||
|
v-model.number="row.quantity"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
:info="t('service.quantityInfo')"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-price="{ row, col }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<VnInput
|
||||||
|
:label="col.label"
|
||||||
|
v-model.number="row.price"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</template>
|
||||||
|
</CrudModel>
|
||||||
|
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
||||||
|
<QBtn fab color="primary" icon="add" @click="ticketServiceCrudRef.insert()" />
|
||||||
|
</QPageSticky>
|
||||||
|
</template>
|
|
@ -149,6 +149,16 @@ weeklyTickets:
|
||||||
salesperson: Salesperson
|
salesperson: Salesperson
|
||||||
search: Search weekly tickets
|
search: Search weekly tickets
|
||||||
searchInfo: Search weekly tickets by id or client id
|
searchInfo: Search weekly tickets by id or client id
|
||||||
|
service:
|
||||||
|
pay: Pay
|
||||||
|
description: Description
|
||||||
|
quantity: Quantity
|
||||||
|
price: Price
|
||||||
|
removeService: Remove service
|
||||||
|
newService: New service type
|
||||||
|
addService: Add service
|
||||||
|
quantityInfo: To create services with negative amounts mark the service on the source ticket and press the pay button.
|
||||||
|
createRefundSuccess: 'The following refund ticket have been created: { ticketId }'
|
||||||
tracking:
|
tracking:
|
||||||
state: State
|
state: State
|
||||||
worker: Worker
|
worker: Worker
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
service:
|
||||||
|
pay: Abonar
|
||||||
|
description: Descripción
|
||||||
|
quantity: Cantidad
|
||||||
|
price: Precio
|
||||||
|
removeService: Quitar servicio
|
||||||
|
newService: Nuevo tipo de servicio
|
||||||
|
addService: Añadir servicio
|
||||||
|
quantityInfo: Para crear sevicios con cantidades negativas marcar servicio en el ticket origen y apretar el boton abonar.
|
||||||
|
createRefundSuccess: 'Se ha creado siguiente ticket de abono: { ticketId }'
|
||||||
tracking:
|
tracking:
|
||||||
state: Estado
|
state: Estado
|
||||||
worker: Trabajador
|
worker: Trabajador
|
||||||
|
|
|
@ -19,6 +19,7 @@ export default {
|
||||||
'TicketSale',
|
'TicketSale',
|
||||||
'TicketLog',
|
'TicketLog',
|
||||||
'TicketPurchaseRequest',
|
'TicketPurchaseRequest',
|
||||||
|
'TicketService',
|
||||||
'TicketTracking',
|
'TicketTracking',
|
||||||
'TicketVolume',
|
'TicketVolume',
|
||||||
'TicketNotes',
|
'TicketNotes',
|
||||||
|
@ -159,6 +160,16 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'service',
|
||||||
|
name: 'TicketService',
|
||||||
|
meta: {
|
||||||
|
title: 'services',
|
||||||
|
icon: 'vn:services',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/Card/TicketService.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'volume',
|
path: 'volume',
|
||||||
name: 'TicketVolume',
|
name: 'TicketVolume',
|
||||||
|
|
Loading…
Reference in New Issue