#7553 modified TicketExpedition & changes in ticket section #571
|
@ -234,6 +234,8 @@ async function remove(data) {
|
||||||
newData = newData.filter((form) => !ids.some((id) => id == form[pk]));
|
newData = newData.filter((form) => !ids.some((id) => id == form[pk]));
|
||||||
fetch(newData);
|
fetch(newData);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
emit('update:selected', []);
|
emit('update:selected', []);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ const $props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
bottom: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
cardClass: {
|
cardClass: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'flex-one',
|
default: 'flex-one',
|
||||||
|
@ -102,6 +106,10 @@ const $props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
disabledAttr: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
|
@ -520,6 +528,29 @@ function handleOnDataSaved(_) {
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
<template #bottom v-if="bottom">
|
||||||
|
<slot name="bottom-table">
|
||||||
|
<QBtn
|
||||||
|
@click="
|
||||||
|
() =>
|
||||||
|
createAsDialog
|
||||||
|
? (showForm = !showForm)
|
||||||
|
: handleOnDataSaved(create)
|
||||||
|
"
|
||||||
|
class="cursor-pointer fill-icon"
|
||||||
|
color="primary"
|
||||||
|
icon="add_circle"
|
||||||
|
size="md"
|
||||||
|
round
|
||||||
|
flat
|
||||||
|
shortcut="+"
|
||||||
|
:disabled="!disabledAttr"
|
||||||
|
/>
|
||||||
|
<QTooltip>
|
||||||
|
{{ createForm.title }}
|
||||||
|
</QTooltip>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
<template #item="{ row, colsMap }">
|
<template #item="{ row, colsMap }">
|
||||||
<component
|
<component
|
||||||
:is="$props.redirect ? 'router-link' : 'span'"
|
:is="$props.redirect ? 'router-link' : 'span'"
|
||||||
|
@ -853,4 +884,13 @@ es:
|
||||||
cursor: text;
|
cursor: text;
|
||||||
user-select: all;
|
user-select: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.full-width-slot {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--vn-text-color);
|
||||||
|
margin-bottom: -1%;
|
||||||
|
background-color: var(--vn-header-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -47,6 +47,7 @@ let store;
|
||||||
let entity;
|
let entity;
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
|
const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
|
||||||
|
const menuRef = ref();
|
||||||
defineExpose({ getData });
|
defineExpose({ getData });
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
@ -170,7 +171,7 @@ const toModule = computed(() =>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
{{ t('components.cardDescriptor.moreOptions') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
<QMenu ref="menuRef">
|
<QMenu :ref="menuRef">
|
||||||
<QList>
|
<QList>
|
||||||
<slot name="menu" :entity="entity" :menu-ref="menuRef" />
|
<slot name="menu" :entity="entity" :menu-ref="menuRef" />
|
||||||
</QList>
|
</QList>
|
||||||
|
|
|
@ -495,6 +495,8 @@ ticket:
|
||||||
warehouse: Warehouse
|
warehouse: Warehouse
|
||||||
customerCard: Customer card
|
customerCard: Customer card
|
||||||
alias: Alias
|
alias: Alias
|
||||||
|
ticketList: Ticket List
|
||||||
|
newOrder: New Order
|
||||||
boxing:
|
boxing:
|
||||||
expedition: Expedition
|
expedition: Expedition
|
||||||
item: Item
|
item: Item
|
||||||
|
@ -516,6 +518,7 @@ ticket:
|
||||||
landed: Landed
|
landed: Landed
|
||||||
consigneePhone: Consignee phone
|
consigneePhone: Consignee phone
|
||||||
consigneeMobile: Consignee mobile
|
consigneeMobile: Consignee mobile
|
||||||
|
consigneeAddress: Consignee address
|
||||||
clientPhone: Client phone
|
clientPhone: Client phone
|
||||||
clientMobile: Client mobile
|
clientMobile: Client mobile
|
||||||
consignee: Consignee
|
consignee: Consignee
|
||||||
|
@ -545,6 +548,11 @@ ticket:
|
||||||
weight: Weight
|
weight: Weight
|
||||||
goTo: Go to
|
goTo: Go to
|
||||||
summaryAmount: Summary
|
summaryAmount: Summary
|
||||||
|
purchaseRequest: Purchase request
|
||||||
|
service: Service
|
||||||
|
description: Description
|
||||||
|
attender: Attender
|
||||||
|
ok: Ok
|
||||||
create:
|
create:
|
||||||
client: Client
|
client: Client
|
||||||
address: Address
|
address: Address
|
||||||
|
@ -568,7 +576,6 @@ invoiceOut:
|
||||||
client: Client
|
client: Client
|
||||||
company: Company
|
company: Company
|
||||||
customerCard: Customer card
|
customerCard: Customer card
|
||||||
ticketList: Ticket List
|
|
||||||
summary:
|
summary:
|
||||||
issued: Issued
|
issued: Issued
|
||||||
created: Created
|
created: Created
|
||||||
|
|
|
@ -63,7 +63,7 @@ globals:
|
||||||
shipped: F. envío
|
shipped: F. envío
|
||||||
totalEntries: Ent. totales
|
totalEntries: Ent. totales
|
||||||
amount: Importe
|
amount: Importe
|
||||||
packages: Bultos
|
packages: Embalajes
|
||||||
download: Descargar
|
download: Descargar
|
||||||
downloadPdf: Descargar PDF
|
downloadPdf: Descargar PDF
|
||||||
selectRows: 'Seleccionar las { numberRows } filas(s)'
|
selectRows: 'Seleccionar las { numberRows } filas(s)'
|
||||||
|
@ -267,7 +267,7 @@ globals:
|
||||||
tracking: Estados
|
tracking: Estados
|
||||||
components: Componentes
|
components: Componentes
|
||||||
pictures: Fotos
|
pictures: Fotos
|
||||||
packages: Bultos
|
packages: Embalajes
|
||||||
ldap: LDAP
|
ldap: LDAP
|
||||||
samba: Samba
|
samba: Samba
|
||||||
twoFactor: Doble factor
|
twoFactor: Doble factor
|
||||||
|
@ -486,7 +486,7 @@ ticket:
|
||||||
tracking: Estados
|
tracking: Estados
|
||||||
components: Componentes
|
components: Componentes
|
||||||
pictures: Fotos
|
pictures: Fotos
|
||||||
packages: Bultos
|
packages: Embalajes
|
||||||
list:
|
list:
|
||||||
nickname: Alias
|
nickname: Alias
|
||||||
state: Estado
|
state: Estado
|
||||||
|
@ -504,6 +504,8 @@ ticket:
|
||||||
warehouse: Almacén
|
warehouse: Almacén
|
||||||
customerCard: Ficha del cliente
|
customerCard: Ficha del cliente
|
||||||
alias: Alias
|
alias: Alias
|
||||||
|
ticketList: Listado de tickets
|
||||||
|
newOrder: Nuevo pedido
|
||||||
boxing:
|
boxing:
|
||||||
expedition: Expedición
|
expedition: Expedición
|
||||||
item: Artículo
|
item: Artículo
|
||||||
|
@ -525,6 +527,7 @@ ticket:
|
||||||
landed: Entregado
|
landed: Entregado
|
||||||
consigneePhone: Tel. consignatario
|
consigneePhone: Tel. consignatario
|
||||||
consigneeMobile: Móv. consignatario
|
consigneeMobile: Móv. consignatario
|
||||||
|
consigneeAddress: Dir. consignatario
|
||||||
clientPhone: Tel. cliente
|
clientPhone: Tel. cliente
|
||||||
clientMobile: Móv. cliente
|
clientMobile: Móv. cliente
|
||||||
consignee: Consignatario
|
consignee: Consignatario
|
||||||
|
@ -554,6 +557,10 @@ ticket:
|
||||||
weight: Peso
|
weight: Peso
|
||||||
goTo: Ir a
|
goTo: Ir a
|
||||||
summaryAmount: Resumen
|
summaryAmount: Resumen
|
||||||
|
purchaseRequest: Petición de compra
|
||||||
|
service: Servicio
|
||||||
|
description: Descripción
|
||||||
|
attender: Consignatario
|
||||||
create:
|
create:
|
||||||
client: Cliente
|
client: Cliente
|
||||||
jon marked this conversation as resolved
|
|||||||
address: Dirección
|
address: Dirección
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
<script setup>
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import { QItem } from 'quasar';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import { QItemSection } from 'quasar';
|
||||||
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
defineProps({ dataKey: { type: String, required: true } });
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VnFilterPanel :data-key="dataKey" :search-button="true">
|
||||||
|
<template #tags="{ tag, formatFn }">
|
||||||
|
<div class="q-gutter-x-xs">
|
||||||
|
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
||||||
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #body="{ params }">
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnInput
|
||||||
|
:label="t('params.item')"
|
||||||
|
v-model="params.itemId"
|
||||||
|
is-outlined
|
||||||
|
lazy-rules
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnSelect
|
||||||
|
v-model="params.buyerId"
|
||||||
|
url="TicketRequests/getItemTypeWorker"
|
||||||
|
:fields="['id', 'nickname']"
|
||||||
|
sort-by="nickname ASC"
|
||||||
|
:label="t('params.buyer')"
|
||||||
|
option-value="id"
|
||||||
|
option-label="nickname"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
jon marked this conversation as resolved
jsegarra
commented
este com,entario sobra este com,entario sobra
|
|||||||
|
<VnSelect
|
||||||
|
v-model="params.typeId"
|
||||||
|
url="ItemTypes"
|
||||||
|
:include="['category']"
|
||||||
|
:fields="['id', 'name', 'categoryFk']"
|
||||||
|
sort-by="name ASC"
|
||||||
|
:label="t('params.typeId')"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||||
|
<QItemLabel caption>{{
|
||||||
|
scope.opt?.category?.name
|
||||||
|
}}</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnSelect
|
||||||
|
v-model="params.categoryId"
|
||||||
|
url="ItemCategories"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
sort-by="name ASC"
|
||||||
|
:label="t('params.categoryId')"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnSelect
|
||||||
|
v-model="params.campaignId"
|
||||||
|
url="Campaigns/latest"
|
||||||
|
sort-by="dated DESC"
|
||||||
|
:label="t('params.campaignId')"
|
||||||
|
option-label="code"
|
||||||
|
option-value="id"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
t(`params.${scope.opt?.code}`)
|
||||||
|
}}</QItemLabel>
|
||||||
|
<QItemLabel caption>{{
|
||||||
|
toDate(scope.opt.dated)
|
||||||
|
}}</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnInputDate
|
||||||
|
:label="t('params.from')"
|
||||||
|
v-model="params.from"
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
is-outlined
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnInputDate
|
||||||
|
:label="t('params.to')"
|
||||||
|
v-model="params.to"
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
is-outlined
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnFilterPanel>
|
||||||
|
</template>
|
||||||
|
<i18n>
|
||||||
|
en:
|
||||||
|
params:
|
||||||
|
item: Item id
|
||||||
|
buyer: Buyer
|
||||||
|
type: Type
|
||||||
|
category: Category
|
||||||
|
itemId: Item id
|
||||||
|
buyerId: Buyer
|
||||||
|
typeId: Type
|
||||||
|
categoryId: Category
|
||||||
|
from: From
|
||||||
|
to: To
|
||||||
|
campaignId: Campaña
|
||||||
|
valentinesDay: Valentine's Day
|
||||||
|
mothersDay: Mother's Day
|
||||||
|
allSaints: All Saints' Day
|
||||||
|
es:
|
||||||
|
params:
|
||||||
|
item: Id artículo
|
||||||
|
buyer: Comprador
|
||||||
|
type: Tipo
|
||||||
|
category: Categoría
|
||||||
|
itemId: Id Artículo
|
||||||
|
buyerId: Comprador
|
||||||
|
typeId: Tipo
|
||||||
|
categoryId: Reino
|
||||||
|
from: Desde
|
||||||
|
to: Hasta
|
||||||
|
campaignId: Campaña
|
||||||
|
valentinesDay: Día de San Valentín
|
||||||
|
mothersDay: Día de la Madre
|
||||||
|
allSaints: Día de Todos los Santos
|
||||||
|
</i18n>
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import InvoiceOutDescriptor from './InvoiceOutDescriptor.vue';
|
import InvoiceOutDescriptor from './InvoiceOutDescriptor.vue';
|
||||||
|
import InvoiceOutSummary from './InvoiceOutSummary.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -10,6 +11,10 @@ const $props = defineProps({
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy>
|
<QPopupProxy>
|
||||||
<InvoiceOutDescriptor v-if="$props.id" :id="$props.id" />
|
<InvoiceOutDescriptor
|
||||||
|
v-if="$props.id"
|
||||||
|
:id="$props.id"
|
||||||
|
:summary="InvoiceOutSummary"
|
||||||
|
/>
|
||||||
</QPopupProxy>
|
</QPopupProxy>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -249,7 +249,7 @@ watch(
|
||||||
@on-fetch="(data) => (orderSummary.vat = data)"
|
@on-fetch="(data) => (orderSummary.vat = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<QDrawer side="right" :width="270" v-model="stateStore.rightDrawer">
|
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer">
|
||||||
<QCard
|
<QCard
|
||||||
class="order-lines-summary q-pa-lg"
|
class="order-lines-summary q-pa-lg"
|
||||||
v-if="orderSummary.vat && orderSummary.total"
|
v-if="orderSummary.vat && orderSummary.total"
|
||||||
|
|
|
@ -14,14 +14,15 @@ import OrderFilter from './Card/OrderFilter.vue';
|
||||||
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import { toDateTimeFormat } from 'src/filters/date';
|
import { toDateTimeFormat } from 'src/filters/date';
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const agencyList = ref([]);
|
const agencyList = ref([]);
|
||||||
const addressesList = ref([]);
|
const addressesList = ref([]);
|
||||||
const clientId = ref();
|
const route = useRoute();
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -169,6 +170,13 @@ const getDateColor = (date) => {
|
||||||
if (comparation == 0) return 'bg-warning';
|
if (comparation == 0) return 'bg-warning';
|
||||||
if (comparation < 0) return 'bg-success';
|
if (comparation < 0) return 'bg-success';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!route.query.createForm) return;
|
||||||
|
const clientId = route.query.createForm;
|
||||||
|
const id = JSON.parse(clientId);
|
||||||
|
fetchClientAddress(id.clientFk, id);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<OrderSearchbar />
|
<OrderSearchbar />
|
||||||
|
@ -184,13 +192,14 @@ const getDateColor = (date) => {
|
||||||
:order="['landed DESC', 'clientFk ASC', 'id DESC']"
|
:order="['landed DESC', 'clientFk ASC', 'id DESC']"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'Orders/new',
|
urlCreate: 'Orders/new',
|
||||||
title: 'Create Order',
|
title: t('module.cerateOrder'),
|
||||||
onDataSaved: (url) => {
|
onDataSaved: (url) => {
|
||||||
tableRef.redirect(url);
|
tableRef.redirect(url);
|
||||||
},
|
},
|
||||||
formInitialData: {
|
formInitialData: {
|
||||||
jon marked this conversation as resolved
jsegarra
commented
En la linea 195 el titulo del create no está traducido En la linea 195 el titulo del create no está traducido
|
|||||||
active: true,
|
active: true,
|
||||||
addressId: null,
|
addressId: null,
|
||||||
|
clientFk: null,
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
:user-params="{ showEmpty: false }"
|
:user-params="{ showEmpty: false }"
|
||||||
|
@ -221,7 +230,7 @@ const getDateColor = (date) => {
|
||||||
<VnSelect
|
<VnSelect
|
||||||
url="Clients"
|
url="Clients"
|
||||||
:include="{ relation: 'addresses' }"
|
:include="{ relation: 'addresses' }"
|
||||||
v-model="clientId"
|
v-model="data.clientFk"
|
||||||
:label="t('module.customer')"
|
:label="t('module.customer')"
|
||||||
@update:model-value="(id) => fetchClientAddress(id, data)"
|
@update:model-value="(id) => fetchClientAddress(id, data)"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,6 +10,7 @@ module:
|
||||||
total: Total
|
total: Total
|
||||||
salesPerson: Sales Person
|
salesPerson: Sales Person
|
||||||
address: Address
|
address: Address
|
||||||
|
cerateOrder: Create order
|
||||||
lines:
|
lines:
|
||||||
item: Item
|
item: Item
|
||||||
warehouse: Warehouse
|
warehouse: Warehouse
|
||||||
|
|
|
@ -10,6 +10,7 @@ module:
|
||||||
total: Total
|
total: Total
|
||||||
salesPerson: Comercial
|
salesPerson: Comercial
|
||||||
address: Dirección
|
address: Dirección
|
||||||
|
cerateOrder: Crear cesta
|
||||||
lines:
|
lines:
|
||||||
item: Artículo
|
item: Artículo
|
||||||
warehouse: Almacén
|
warehouse: Almacén
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import FetchedTags from 'components/ui/FetchedTags.vue';
|
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
@ -115,7 +114,7 @@ const totalNewPrice = computed(() => {
|
||||||
const totalDifference = computed(() => {
|
const totalDifference = computed(() => {
|
||||||
return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0);
|
return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0);
|
||||||
});
|
});
|
||||||
const showMovablecolumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
|
const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
|
||||||
const haveDifferences = computed(() => _ticketData.value.sale?.haveDifferences);
|
const haveDifferences = computed(() => _ticketData.value.sale?.haveDifferences);
|
||||||
const ticketHaveNegatives = () => {
|
const ticketHaveNegatives = () => {
|
||||||
let _haveNegatives = false;
|
let _haveNegatives = false;
|
||||||
|
@ -145,85 +144,83 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
@on-fetch="(data) => (ticketUpdateActions = data)"
|
@on-fetch="(data) => (ticketUpdateActions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer">
|
||||||
<template #right-panel>
|
<QCard
|
||||||
<QCard
|
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
bordered
|
||||||
bordered
|
flat
|
||||||
flat
|
style="border-color: black"
|
||||||
style="border-color: black"
|
>
|
||||||
|
<QCardSection horizontal>
|
||||||
|
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||||
|
{{ t('basicData.total') }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection class="column items-left" horizontal>
|
||||||
|
<span>
|
||||||
|
{{ t('basicData.price') }}:
|
||||||
|
{{ toCurrency(totalPrice) }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection class="column items-left" horizontal>
|
||||||
|
<span>
|
||||||
|
{{ t('basicData.newPrice') }}: {{ toCurrency(totalNewPrice) }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection class="column items-left" horizontal>
|
||||||
|
<span>
|
||||||
|
{{ t('basicData.difference') }}: {{ toCurrency(totalDifference) }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
</QCard>
|
||||||
|
<QCard
|
||||||
|
v-if="totalDifference"
|
||||||
|
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||||
|
bordered
|
||||||
|
flat
|
||||||
|
style="border-color: black"
|
||||||
|
>
|
||||||
|
<QCardSection horizontal>
|
||||||
|
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||||
|
{{ t('basicData.chargeDifference') }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection
|
||||||
|
v-for="(action, index) in ticketUpdateActions"
|
||||||
|
:key="index"
|
||||||
|
horizontal
|
||||||
>
|
>
|
||||||
<QCardSection horizontal>
|
<QRadio
|
||||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
v-model="_ticketData.option"
|
||||||
{{ t('basicData.total') }}
|
:val="action.code"
|
||||||
</span>
|
:label="action.description"
|
||||||
</QCardSection>
|
dense
|
||||||
<QCardSection class="column items-center" horizontal>
|
/>
|
||||||
<span>
|
</QCardSection>
|
||||||
{{ t('basicData.price') }}:
|
</QCard>
|
||||||
{{ toCurrency(totalPrice) }}
|
<QCard
|
||||||
</span>
|
v-if="haveNegatives"
|
||||||
</QCardSection>
|
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||||
<QCardSection class="column items-center" horizontal>
|
bordered
|
||||||
<span>
|
flat
|
||||||
{{ t('basicData.newPrice') }}: {{ toCurrency(totalNewPrice) }}
|
style="border-color: black"
|
||||||
</span>
|
>
|
||||||
</QCardSection>
|
<QCardSection horizontal class="flex row items-center">
|
||||||
<QCardSection class="column items-center" horizontal>
|
<QCheckbox
|
||||||
<span>
|
:label="t('basicData.withoutNegatives')"
|
||||||
{{ t('basicData.difference') }}: {{ toCurrency(totalDifference) }}
|
v-model="_ticketData.withoutNegatives"
|
||||||
</span>
|
:toggle-indeterminate="false"
|
||||||
</QCardSection>
|
/>
|
||||||
</QCard>
|
<QIcon name="info" size="xs" class="q-ml-sm">
|
||||||
<QCard
|
<QTooltip max-width="350px">
|
||||||
v-if="totalDifference"
|
{{ t('basicData.withoutNegativesInfo') }}
|
||||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
</QTooltip>
|
||||||
bordered
|
</QIcon>
|
||||||
flat
|
</QCardSection>
|
||||||
style="border-color: black"
|
</QCard>
|
||||||
>
|
</QDrawer>
|
||||||
<QCardSection horizontal>
|
|
||||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
|
||||||
{{ t('basicData.chargeDifference') }}
|
|
||||||
</span>
|
|
||||||
</QCardSection>
|
|
||||||
<QCardSection
|
|
||||||
v-for="(action, index) in ticketUpdateActions"
|
|
||||||
:key="index"
|
|
||||||
horizontal
|
|
||||||
>
|
|
||||||
<QRadio
|
|
||||||
v-model="_ticketData.option"
|
|
||||||
:val="action.code"
|
|
||||||
:label="action.description"
|
|
||||||
dense
|
|
||||||
/>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
<QCard
|
|
||||||
v-if="haveNegatives"
|
|
||||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
|
||||||
bordered
|
|
||||||
flat
|
|
||||||
style="border-color: black"
|
|
||||||
>
|
|
||||||
<QCardSection horizontal class="flex row items-center">
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('basicData.withoutNegatives')"
|
|
||||||
v-model="_ticketData.withoutNegatives"
|
|
||||||
:toggle-indeterminate="false"
|
|
||||||
/>
|
|
||||||
<QIcon name="info" size="xs" class="q-ml-sm">
|
|
||||||
<QTooltip max-width="350px">
|
|
||||||
{{ t('basicData.withoutNegativesInfo') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<QTable
|
<QTable
|
||||||
:visible-columns="showMovablecolumn"
|
:visible-columns="showMovableColumn"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
|
@ -233,15 +230,15 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
flat
|
flat
|
||||||
>
|
>
|
||||||
<template #body-cell-item="{ row }">
|
<template #body-cell-item="{ row }">
|
||||||
<QTd>
|
<QTd @click.stop class="link">
|
||||||
<QBtn flat color="primary">
|
<QBtn flat>
|
||||||
{{ row.itemFk }}
|
{{ row.itemFk }}
|
||||||
<ItemDescriptorProxy :id="row.itemFk" />
|
<ItemDescriptorProxy :id="row.itemFk" />
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-description="{ row }">
|
<template #body-cell-description="{ row }">
|
||||||
<QTd>
|
<QTd style="display: contents">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<span>{{ row.item.name }}</span>
|
<span>{{ row.item.name }}</span>
|
||||||
<span class="color-vn-label">{{ row.item.subName }}</span>
|
<span class="color-vn-label">{{ row.item.subName }}</span>
|
|
@ -12,6 +12,7 @@ import VnInputTime from 'components/common/VnInputTime.vue';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import { useValidator } from 'src/composables/useValidator';
|
||||||
import { toTimeFormat } from 'filters/date.js';
|
import { toTimeFormat } from 'filters/date.js';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
|
@ -23,7 +24,7 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['updateForm']);
|
const emit = defineEmits(['updateForm']);
|
||||||
|
const { validate } = useValidator();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -51,18 +52,18 @@ const agencyByWarehouseFilter = computed(() => ({
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const zonesFilter = computed(() => ({
|
function zoneWhere() {
|
||||||
fields: ['id', 'name'],
|
if (formData?.value?.agencyModeFk) {
|
||||||
order: 'name ASC',
|
return formData.value?.agencyModeFk
|
||||||
where: formData.value?.agencyModeFk
|
? {
|
||||||
? {
|
shipped: formData.value?.shipped,
|
||||||
shipped: formData.value?.shipped,
|
addressFk: formData.value?.addressFk,
|
||||||
addressFk: formData.value?.addressFk,
|
agencyModeFk: formData.value?.agencyModeFk,
|
||||||
agencyModeFk: formData.value?.agencyModeFk,
|
warehouseFk: formData.value?.warehouseFk,
|
||||||
warehouseFk: formData.value?.warehouseFk,
|
}
|
||||||
}
|
: {};
|
||||||
: {},
|
}
|
||||||
}));
|
}
|
||||||
|
|
||||||
const getLanded = async (params) => {
|
const getLanded = async (params) => {
|
||||||
try {
|
try {
|
||||||
|
@ -293,13 +294,6 @@ onMounted(() => onFormModelInit());
|
||||||
@on-fetch="(data) => (agenciesOptions = data)"
|
@on-fetch="(data) => (agenciesOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FetchData
|
|
||||||
ref="zonesFetchRef"
|
|
||||||
url="Zones/includingExpired"
|
|
||||||
:filter="zonesFilter"
|
|
||||||
@on-fetch="(data) => (zonesOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<QForm>
|
<QForm>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
|
@ -313,6 +307,7 @@ onMounted(() => onFormModelInit());
|
||||||
hide-selected
|
hide-selected
|
||||||
map-options
|
map-options
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.client')"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -333,6 +328,7 @@ onMounted(() => onFormModelInit());
|
||||||
hide-selected
|
hide-selected
|
||||||
map-options
|
map-options
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.warehouse')"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
@ -345,6 +341,7 @@ onMounted(() => onFormModelInit());
|
||||||
hide-selected
|
hide-selected
|
||||||
map-options
|
map-options
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.address')"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -392,6 +389,7 @@ onMounted(() => onFormModelInit());
|
||||||
:label="t('basicData.alias')"
|
:label="t('basicData.alias')"
|
||||||
v-model="formData.nickname"
|
v-model="formData.nickname"
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.alias')"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
||||||
|
@ -404,6 +402,7 @@ onMounted(() => onFormModelInit());
|
||||||
hide-selected
|
hide-selected
|
||||||
map-options
|
map-options
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.company')"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('basicData.agency')"
|
:label="t('basicData.agency')"
|
||||||
|
@ -414,17 +413,22 @@ onMounted(() => onFormModelInit());
|
||||||
hide-selected
|
hide-selected
|
||||||
map-options
|
map-options
|
||||||
@focus="agencyFetchRef.fetch()"
|
@focus="agencyFetchRef.fetch()"
|
||||||
|
:rules="validate('basicData.agency')"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('basicData.zone')"
|
:label="t('basicData.zone')"
|
||||||
v-model="zoneId"
|
v-model="zoneId"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
:options="zonesOptions"
|
url="Zones/includingExpired"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
sort-by="id"
|
||||||
|
:where="zoneWhere"
|
||||||
hide-selected
|
hide-selected
|
||||||
map-options
|
map-options
|
||||||
:required="true"
|
:required="true"
|
||||||
@focus="zonesFetchRef.fetch()"
|
@focus="zonesFetchRef.fetch()"
|
||||||
|
:rules="validate('basicData.zone')"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -444,16 +448,19 @@ onMounted(() => onFormModelInit());
|
||||||
:label="t('basicData.shipped')"
|
:label="t('basicData.shipped')"
|
||||||
v-model="formData.shipped"
|
v-model="formData.shipped"
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.shipped')"
|
||||||
/>
|
/>
|
||||||
<VnInputTime
|
<VnInputTime
|
||||||
:label="t('basicData.shippedHour')"
|
:label="t('basicData.shippedHour')"
|
||||||
v-model="formData.shipped"
|
v-model="formData.shipped"
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.shippedHour')"
|
||||||
/>
|
/>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
:label="t('basicData.landed')"
|
:label="t('basicData.landed')"
|
||||||
v-model="formData.landed"
|
v-model="formData.landed"
|
||||||
:required="true"
|
:required="true"
|
||||||
|
:rules="validate('basicData.landed')"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</QForm>
|
</QForm>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ref, onBeforeMount } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import BasicDataTable from './BasicDataTable.vue';
|
import TicketBasicData from './TicketBasicData.vue';
|
||||||
import TicketBasicDataForm from './TicketBasicDataForm.vue';
|
import TicketBasicDataForm from './TicketBasicDataForm.vue';
|
||||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
|
|
||||||
|
@ -158,7 +158,10 @@ onBeforeMount(async () => await getTicketData());
|
||||||
color="primary"
|
color="primary"
|
||||||
animated
|
animated
|
||||||
keep-alive
|
keep-alive
|
||||||
style="max-width: 800px; margin: auto"
|
style="margin: auto"
|
||||||
|
:style="{
|
||||||
|
'max-width': step > 1 ? 'none' : '800px',
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<QStep :name="1" :title="t('globals.pageTitles.basicData')" :done="step > 1">
|
<QStep :name="1" :title="t('globals.pageTitles.basicData')" :done="step > 1">
|
||||||
<TicketBasicDataForm
|
<TicketBasicDataForm
|
||||||
|
@ -168,7 +171,7 @@ onBeforeMount(async () => await getTicketData());
|
||||||
/>
|
/>
|
||||||
</QStep>
|
</QStep>
|
||||||
<QStep :name="2" :title="t('basicData.priceDifference')">
|
<QStep :name="2" :title="t('basicData.priceDifference')">
|
||||||
<BasicDataTable
|
<TicketBasicData
|
||||||
:form-data="formData"
|
:form-data="formData"
|
||||||
v-model:haveNegatives="haveNegatives"
|
v-model:haveNegatives="haveNegatives"
|
||||||
@update-form="($event) => (formData = $event)"
|
@update-form="($event) => (formData = $event)"
|
||||||
|
|
|
@ -31,6 +31,7 @@ const router = useRouter();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
|
||||||
const newTicketFormData = reactive({});
|
const newTicketFormData = reactive({});
|
||||||
|
const date = new Date();
|
||||||
jon marked this conversation as resolved
jon
commented
He puesto esta fecha por defecto, no sé como lo verás He puesto esta fecha por defecto, no sé como lo verás
|
|||||||
|
|
||||||
const createTicket = async () => {
|
const createTicket = async () => {
|
||||||
try {
|
try {
|
||||||
|
@ -64,7 +65,11 @@ const createTicket = async () => {
|
||||||
>
|
>
|
||||||
<template #form-inputs="{ data }">
|
<template #form-inputs="{ data }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInputDate :label="t('expedition.landed')" v-model="data.landed" />
|
<VnInputDate
|
||||||
|
:label="t('expedition.landed')"
|
||||||
|
v-model="data.landed"
|
||||||
|
:model-value="date"
|
||||||
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
|
|
@ -5,15 +5,16 @@ import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import FetchedTags from 'components/ui/FetchedTags.vue';
|
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
||||||
|
import VnImg from 'src/components/ui/VnImg.vue';
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
import { toCurrency } from 'filters/index';
|
import { toCurrency } from 'filters/index';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
|
@ -75,22 +76,39 @@ const columns = computed(() => [
|
||||||
name: 'item',
|
name: 'item',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('lines.image'),
|
||||||
|
name: 'image',
|
||||||
|
columnField: {
|
||||||
|
component: VnImg,
|
||||||
|
attrs: (id) => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
width: '50px',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columnFilter: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t('ticketComponents.description'),
|
label: t('ticketComponents.description'),
|
||||||
name: 'description',
|
name: 'description',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
columnClass: 'expand',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ticketComponents.quantity'),
|
label: t('ticketComponents.quantity'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
field: 'quantity',
|
field: 'quantity',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
format: (val) => dashIfEmpty(val),
|
format: (row) => dashIfEmpty(row.quantity),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ticketComponents.serie'),
|
label: t('ticketComponents.serie'),
|
||||||
name: 'serie',
|
name: 'serie',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
format: (row) => dashIfEmpty(row.serie),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ticketComponents.components'),
|
label: t('ticketComponents.components'),
|
||||||
|
@ -174,181 +192,166 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
@on-fetch="(data) => (components = data)"
|
@on-fetch="(data) => (components = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer">
|
||||||
<template #right-panel>
|
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black">
|
||||||
<QCard
|
<QCardSection horizontal>
|
||||||
class="q-pa-sm color-vn-text"
|
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||||
bordered
|
{{ t('ticketComponents.total') }}
|
||||||
flat
|
</span>
|
||||||
style="border-color: black"
|
</QCardSection>
|
||||||
|
<QCardSection horizontal>
|
||||||
|
<span class="q-mr-xs color-vn-label"
|
||||||
|
>{{ t('ticketComponents.baseToCommission') }}:
|
||||||
|
</span>
|
||||||
|
<span>{{ toCurrency(getBase) }}</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection horizontal>
|
||||||
|
<span class="q-mr-xs color-vn-label"
|
||||||
|
>{{ t('ticketComponents.totalWithoutVat') }}:
|
||||||
|
</span>
|
||||||
|
<span>{{ toCurrency(getTotal) }}</span>
|
||||||
|
</QCardSection>
|
||||||
|
</QCard>
|
||||||
|
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black">
|
||||||
|
<QCardSection horizontal>
|
||||||
|
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||||
|
{{ t('ticketComponents.components') }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection
|
||||||
|
v-for="(component, index) in componentsList"
|
||||||
|
:key="index"
|
||||||
|
horizontal
|
||||||
>
|
>
|
||||||
<QCardSection horizontal>
|
<span v-if="component.name" class="q-mr-xs color-vn-label">
|
||||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
{{ component.name }}:
|
||||||
{{ t('ticketComponents.total') }}
|
</span>
|
||||||
</span>
|
<span v-if="component.value">{{
|
||||||
</QCardSection>
|
toCurrency(component.value, 'EUR', 3)
|
||||||
<QCardSection horizontal>
|
}}</span>
|
||||||
<span class="q-mr-xs color-vn-label"
|
</QCardSection>
|
||||||
>{{ t('ticketComponents.baseToCommission') }}:
|
</QCard>
|
||||||
</span>
|
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black">
|
||||||
<span>{{ toCurrency(getBase) }}</span>
|
<QCardSection horizontal>
|
||||||
</QCardSection>
|
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||||
<QCardSection horizontal>
|
{{ t('ticketComponents.zoneBreakdown') }}
|
||||||
<span class="q-mr-xs color-vn-label"
|
</span>
|
||||||
>{{ t('ticketComponents.totalWithoutVat') }}:
|
</QCardSection>
|
||||||
</span>
|
<QCardSection horizontal>
|
||||||
<span>{{ toCurrency(getTotal) }}</span>
|
<span class="q-mr-xs color-vn-label">
|
||||||
</QCardSection>
|
{{ t('ticketComponents.price') }}:
|
||||||
</QCard>
|
</span>
|
||||||
<QCard
|
<span>{{ toCurrency(ticketData?.zonePrice, 'EUR', 2) }}</span>
|
||||||
class="q-pa-sm color-vn-text"
|
</QCardSection>
|
||||||
bordered
|
<QCardSection horizontal>
|
||||||
flat
|
<span class="q-mr-xs color-vn-label">
|
||||||
style="border-color: black"
|
{{ t('ticketComponents.bonus') }}:
|
||||||
>
|
</span>
|
||||||
<QCardSection horizontal>
|
<span>{{ toCurrency(ticketData?.zoneBonus, 'EUR', 2) }}</span>
|
||||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
</QCardSection>
|
||||||
{{ t('ticketComponents.components') }}
|
<QCardSection horizontal>
|
||||||
</span>
|
<span class="q-mr-xs color-vn-label">
|
||||||
</QCardSection>
|
{{ t('ticketComponents.zone') }}:
|
||||||
<QCardSection
|
</span>
|
||||||
v-for="(component, index) in componentsList"
|
<span class="link">
|
||||||
:key="index"
|
{{ dashIfEmpty(ticketData?.zone?.name) }}
|
||||||
horizontal
|
<ZoneDescriptorProxy :id="ticketData?.zone?.id" />
|
||||||
>
|
</span>
|
||||||
<span v-if="component.name" class="q-mr-xs color-vn-label">
|
</QCardSection>
|
||||||
{{ component.name }}:
|
<QCardSection v-if="ticketData?.zone?.isVolumetric" horizontal>
|
||||||
</span>
|
<span class="q-mr-xs color-vn-label">
|
||||||
<span v-if="component.value">{{
|
{{ t('ticketComponents.volume') }}:
|
||||||
toCurrency(component.value, 'EUR', 3)
|
</span>
|
||||||
}}</span>
|
<span>{{ ticketVolume }}</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
</QCard>
|
<QCardSection horizontal>
|
||||||
<QCard
|
<span class="q-mr-xs color-vn-label">
|
||||||
class="q-pa-sm color-vn-text"
|
{{ t('ticketComponents.packages') }}:
|
||||||
bordered
|
</span>
|
||||||
flat
|
<span>{{ dashIfEmpty(ticketData?.packages) }}</span>
|
||||||
style="border-color: black"
|
</QCardSection>
|
||||||
>
|
</QCard>
|
||||||
<QCardSection horizontal>
|
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black">
|
||||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
<QCardSection horizontal>
|
||||||
{{ t('ticketComponents.zoneBreakdown') }}
|
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
||||||
</span>
|
{{ t('ticketComponents.theoricalCost') }}
|
||||||
</QCardSection>
|
</span>
|
||||||
<QCardSection horizontal>
|
</QCardSection>
|
||||||
<span class="q-mr-xs color-vn-label">
|
<QCardSection horizontal>
|
||||||
{{ t('ticketComponents.price') }}:
|
<span class="q-mr-xs color-vn-label">
|
||||||
</span>
|
{{ t('ticketComponents.totalPrice') }}:
|
||||||
<span>{{ toCurrency(ticketData?.zonePrice, 'EUR', 2) }}</span>
|
</span>
|
||||||
</QCardSection>
|
<span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span>
|
||||||
<QCardSection horizontal>
|
</QCardSection>
|
||||||
<span class="q-mr-xs color-vn-label">
|
</QCard>
|
||||||
{{ t('ticketComponents.bonus') }}:
|
</QDrawer>
|
||||||
</span>
|
<VnTable
|
||||||
<span>{{ toCurrency(ticketData?.zoneBonus, 'EUR', 2) }}</span>
|
ref="tableRef"
|
||||||
</QCardSection>
|
data-key="TicketComponents"
|
||||||
<QCardSection horizontal>
|
url="Sales"
|
||||||
<span class="q-mr-xs color-vn-label">
|
:user-filter="salesFilter"
|
||||||
{{ t('ticketComponents.zone') }}:
|
|
||||||
</span>
|
|
||||||
<span class="link">
|
|
||||||
{{ dashIfEmpty(ticketData?.zone?.name) }}
|
|
||||||
<ZoneDescriptorProxy :id="ticketData?.zone?.id" />
|
|
||||||
</span>
|
|
||||||
</QCardSection>
|
|
||||||
<QCardSection v-if="ticketData?.zone?.isVolumetric" horizontal>
|
|
||||||
<span class="q-mr-xs color-vn-label">
|
|
||||||
{{ t('ticketComponents.volume') }}:
|
|
||||||
</span>
|
|
||||||
<span>{{ ticketVolume }}</span>
|
|
||||||
</QCardSection>
|
|
||||||
<QCardSection horizontal>
|
|
||||||
<span class="q-mr-xs color-vn-label">
|
|
||||||
{{ t('ticketComponents.packages') }}:
|
|
||||||
</span>
|
|
||||||
<span>{{ dashIfEmpty(ticketData?.packages) }}</span>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
<QCard
|
|
||||||
class="q-pa-sm color-vn-text"
|
|
||||||
bordered
|
|
||||||
flat
|
|
||||||
style="border-color: black"
|
|
||||||
>
|
|
||||||
<QCardSection horizontal>
|
|
||||||
<span class="text-weight-bold text-subtitle1 text-center full-width">
|
|
||||||
{{ t('ticketComponents.theoricalCost') }}
|
|
||||||
</span>
|
|
||||||
</QCardSection>
|
|
||||||
<QCardSection horizontal>
|
|
||||||
<span class="q-mr-xs color-vn-label">
|
|
||||||
{{ t('ticketComponents.totalPrice') }}:
|
|
||||||
</span>
|
|
||||||
<span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<QTable
|
|
||||||
:rows="components"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
row-key="id"
|
:right-search="false"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
auto-load
|
||||||
class="full-width q-mt-md"
|
:disable-option="{ card: true }"
|
||||||
:no-data-label="t('globals.noResults')"
|
:column-search="false"
|
||||||
>
|
>
|
||||||
<template #body-cell-item="{ row }">
|
<template #column-item="{ row }">
|
||||||
<QTd>
|
<span @click.stop flat class="link">
|
||||||
<QBtn flat color="primary">
|
{{ row.itemFk }}
|
||||||
<span class="link">{{ row.itemFk }}</span>
|
<ItemDescriptorProxy :id="row.itemFk" />
|
||||||
<ItemDescriptorProxy :id="row.itemFk" />
|
</span>
|
||||||
</QBtn>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-description="{ row }">
|
<template #column-image="{ row }">
|
||||||
<QTd>
|
<div class="image-wrapper">
|
||||||
<div class="column">
|
<VnImg :id="parseInt(row?.item?.id)" class="rounded" />
|
||||||
<span>{{ row.item.name }}</span>
|
</div>
|
||||||
<span class="color-vn-label">{{ row.item.subName }}</span>
|
|
||||||
<FetchedTags :item="row.item" />
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-serie="{ row }">
|
<template #column-description="{ row }">
|
||||||
<QTd>
|
<div class="column">
|
||||||
<div class="column">
|
<span>{{ row.item.name }}</span>
|
||||||
<span v-for="(saleComponent, index) in row.components" :key="index">
|
<span class="color-vn-label">{{ row.item.subName }}</span>
|
||||||
{{ saleComponent.component?.componentType?.name }}
|
<FetchedTags :item="row.item" />
|
||||||
</span>
|
</div>
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-components="{ row }">
|
<template #column-serie="{ row }">
|
||||||
<QTd>
|
<div class="column">
|
||||||
<div class="column">
|
<span v-for="(saleComponent, index) in row.components" :key="index">
|
||||||
<span v-for="(saleComponent, index) in row.components" :key="index">
|
{{ saleComponent.component?.componentType?.name }}
|
||||||
{{ saleComponent.component?.name }}
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-import="{ row }">
|
<template #column-components="{ row }">
|
||||||
<QTd>
|
<div class="column">
|
||||||
<div class="column text-right">
|
<span v-for="(saleComponent, index) in row.components" :key="index">
|
||||||
<span v-for="(saleComponent, index) in row.components" :key="index">
|
{{ saleComponent.component?.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #column-import="{ row }">
|
||||||
|
<div class="column text-left">
|
||||||
|
<span v-for="(saleComponent, index) in row.components" :key="index">
|
||||||
|
{{ toCurrency(saleComponent.value, 'EUR', 3) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #column-total="{ row }">
|
||||||
|
<div class="column">
|
||||||
|
<span v-for="(saleComponent, index) in row.components" :key="index">
|
||||||
|
{{ toCurrency(saleComponent.value * row.quantity, 'EUR', 3) }}
|
||||||
|
<!-- <QTooltip>
|
||||||
|
{{ saleComponent.component?.name }}:
|
||||||
{{ toCurrency(saleComponent.value, 'EUR', 3) }}
|
{{ toCurrency(saleComponent.value, 'EUR', 3) }}
|
||||||
</span>
|
</QTooltip> -->
|
||||||
</div>
|
</span>
|
||||||
</QTd>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-total="{ row }">
|
</VnTable>
|
||||||
<QTd>
|
|
||||||
<div class="column text-right">
|
|
||||||
<span v-for="(saleComponent, index) in row.components" :key="index">
|
|
||||||
{{ toCurrency(saleComponent.value * row.quantity, 'EUR', 3) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.image-wrapper {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { toDate } from 'src/filters';
|
|
||||||
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
|
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import useCardDescription from 'src/composables/useCardDescription';
|
import useCardDescription from 'src/composables/useCardDescription';
|
||||||
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
||||||
|
import { toDateTimeFormat } from 'src/filters/date';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -30,13 +30,24 @@ const filter = {
|
||||||
{
|
{
|
||||||
relation: 'address',
|
relation: 'address',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'name', 'mobile', 'phone'],
|
fields: ['id', 'name', 'mobile', 'phone', 'incotermsFk'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'name', 'salesPersonFk', 'phone', 'mobile', 'email'],
|
fields: [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'salesPersonFk',
|
||||||
|
'phone',
|
||||||
|
'mobile',
|
||||||
|
'email',
|
||||||
|
'isActive',
|
||||||
|
'isFreezed',
|
||||||
|
'isTaxDataChecked',
|
||||||
|
'hasElectronicInvoice',
|
||||||
|
],
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'user',
|
relation: 'user',
|
||||||
|
@ -87,6 +98,10 @@ const filter = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = ref(useCardDescription());
|
const data = ref(useCardDescription());
|
||||||
|
|
||||||
|
function ticketFilter(ticket) {
|
||||||
|
return JSON.stringify({ clientFk: ticket.clientFk });
|
||||||
jsegarra
commented
Creo que no se está ejecutando Creo que no se está ejecutando
|
|||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -128,7 +143,10 @@ const data = ref(useCardDescription());
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :label="t('ticket.card.shipped')" :value="toDate(entity.shipped)" />
|
<VnLv
|
||||||
|
:label="t('ticket.card.shipped')"
|
||||||
|
:value="toDateTimeFormat(entity.shipped)"
|
||||||
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
v-if="entity.agencyMode"
|
v-if="entity.agencyMode"
|
||||||
:label="t('ticket.card.agency')"
|
:label="t('ticket.card.agency')"
|
||||||
|
@ -138,7 +156,39 @@ const data = ref(useCardDescription());
|
||||||
<VnLv :label="t('ticket.card.alias')" :value="entity.nickname" />
|
<VnLv :label="t('ticket.card.alias')" :value="entity.nickname" />
|
||||||
</template>
|
</template>
|
||||||
<template #icons="{ entity }">
|
<template #icons="{ entity }">
|
||||||
<QCardActions>
|
<QCardActions class="q-gutter-x-xs">
|
||||||
|
<QIcon
|
||||||
|
v-if="entity.client.isActive == false"
|
||||||
|
name="vn:disabled"
|
||||||
|
size="xs"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('Client inactive') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="entity.client.isFreezed == true"
|
||||||
|
name="vn:frozen"
|
||||||
|
size="xs"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('Client Frozen') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="entity.problem.includes('hasRisk')"
|
||||||
|
name="vn:risk"
|
||||||
|
size="xs"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('Client has debt') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="entity.client.isTaxDataChecked == false"
|
||||||
|
name="vn:no036"
|
||||||
|
size="xs"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('Client not checked') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="entity.isDeleted == true"
|
v-if="entity.isDeleted == true"
|
||||||
name="vn:deletedTicket"
|
name="vn:deletedTicket"
|
||||||
|
@ -159,6 +209,27 @@ const data = ref(useCardDescription());
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('ticket.card.customerCard') }}</QTooltip>
|
<QTooltip>{{ t('ticket.card.customerCard') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
<QBtn
|
||||||
|
size="md"
|
||||||
|
icon="vn:ticket"
|
||||||
|
color="primary"
|
||||||
|
:to="{ name: 'TicketList', query: { table: ticketFilter(entity) } }"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('ticket.card.ticketList') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
|
<QBtn
|
||||||
|
size="md"
|
||||||
|
icon="vn:basketadd"
|
||||||
|
color="primary"
|
||||||
|
:to="{
|
||||||
|
name: 'OrderList',
|
||||||
|
query: {
|
||||||
|
createForm: JSON.stringify({ clientFk: entity.clientFk }),
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('ticket.card.newOrder') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
</QCardActions>
|
</QCardActions>
|
||||||
</template>
|
</template>
|
||||||
</CardDescriptor>
|
</CardDescriptor>
|
||||||
|
@ -168,4 +239,8 @@ const data = ref(useCardDescription());
|
||||||
es:
|
es:
|
||||||
This ticket is deleted: Este ticket está eliminado
|
This ticket is deleted: Este ticket está eliminado
|
||||||
Go to module index: Ir al índice del modulo
|
Go to module index: Ir al índice del modulo
|
||||||
|
Client inactive: Cliente inactivo
|
||||||
|
Client not checked: Cliente no verificado
|
||||||
|
Client has debt: Cliente con deuda
|
||||||
|
Client Frozen: Cliente congelado
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { ref } from 'vue';
|
import { ref, toRefs } from 'vue';
|
||||||
jon marked this conversation as resolved
jsegarra
commented
Revisate la traduccion "¡Se eliminará el ticket de la ruta actual! ¿Continuar de todas formas?" en salix, porque parece que en Lilium no existe. Fallo mio y de william Revisate la traduccion "¡Se eliminará el ticket de la ruta actual! ¿Continuar de todas formas?" en salix, porque parece que en Lilium no existe. Fallo mio y de william
|
|||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
@ -9,6 +9,11 @@ import SendEmailDialog from 'components/common/SendEmailDialog.vue';
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
import VnSmsDialog from 'components/common/VnSmsDialog.vue';
|
import VnSmsDialog from 'components/common/VnSmsDialog.vue';
|
||||||
import toDate from 'filters/toDate';
|
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 VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
|
||||||
|
@ -24,8 +29,16 @@ const { dialog, notify } = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openReport, sendEmail } = usePrintService();
|
const { openReport, sendEmail } = usePrintService();
|
||||||
const ticketSummary = useArrayData('TicketSummary');
|
const ticketSummary = useArrayData('TicketSummary');
|
||||||
const ticket = ref(props.ticket);
|
const { ticket } = toRefs(props);
|
||||||
const ticketId = currentRoute.value.params.id;
|
const ticketId = currentRoute.value.params.id;
|
||||||
|
const client = 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 weight = ref();
|
||||||
const actions = {
|
const actions = {
|
||||||
clone: async () => {
|
clone: async () => {
|
||||||
|
@ -76,6 +89,7 @@ const actions = {
|
||||||
notify({
|
notify({
|
||||||
message: t('You can undo this action within the first hour'),
|
message: t('You can undo this action within the first hour'),
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
|
type: 'warning',
|
||||||
});
|
});
|
||||||
|
|
||||||
push({ name: 'TicketList' });
|
push({ name: 'TicketList' });
|
||||||
|
@ -87,10 +101,14 @@ const actions = {
|
||||||
|
|
||||||
function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
|
function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
|
||||||
const path = `Tickets/${ticket.value.id}/delivery-note-${documentType}`;
|
const path = `Tickets/${ticket.value.id}/delivery-note-${documentType}`;
|
||||||
openReport(path, {
|
openReport(
|
||||||
recipientId: ticket.value.clientFk,
|
path,
|
||||||
type: type,
|
{
|
||||||
});
|
recipientId: ticket.value.clientFk,
|
||||||
|
type: type,
|
||||||
|
},
|
||||||
|
'_blank'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendDeliveryNoteConfirmation(type = 'deliveryNote', documentType = 'pdf') {
|
function sendDeliveryNoteConfirmation(type = 'deliveryNote', documentType = 'pdf') {
|
||||||
|
@ -173,34 +191,280 @@ function openConfirmDialog(callback) {
|
||||||
dialog({
|
dialog({
|
||||||
component: VnConfirm,
|
component: VnConfirm,
|
||||||
componentProps: {
|
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],
|
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)],
|
||||||
|
};
|
||||||
|
await axios.post(`Tickets/invoiceTicketsAndPdf`, params);
|
||||||
|
|
||||||
|
notify({
|
||||||
|
message: t('Ticket invoiced'),
|
||||||
|
type: 'positive',
|
||||||
|
});
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function transferClient(client) {
|
||||||
|
const params = {
|
||||||
|
clientFk: client,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await axios.patch(`Tickets/${ticketId}/transferClient`, params);
|
||||||
|
|
||||||
|
if (data) window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addTurn(day) {
|
||||||
|
const params = {
|
||||||
|
ticketFk: parseInt(ticketId),
|
||||||
|
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)],
|
||||||
|
withWarehouse: withWarehouse,
|
||||||
|
};
|
||||||
|
const { data } = await axios.post(`Tickets/refund`, params);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const refundTicket = data;
|
||||||
|
|
||||||
|
push({ name: 'TicketSale', params: { id: refundTicket[0].id } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function changeShippedHour(time) {
|
||||||
|
const params = {
|
||||||
|
shipped: time,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await axios.post(`Tickets/${ticketId}/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}/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;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<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)"
|
||||||
|
:title="t('Transfer client')"
|
||||||
|
:custom-submit-button-label="t('Transfer client')"
|
||||||
|
:default-cancel-button="false"
|
||||||
|
>
|
||||||
|
<template #form-inputs>
|
||||||
|
<VnSelect
|
||||||
|
url="Clients"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="client"
|
||||||
|
:label="t('Client')"
|
||||||
|
auto-load
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ `#${scope.opt.id} - ` }}
|
||||||
|
{{ scope.opt.name }}
|
||||||
|
</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>
|
<QItem v-ripple clickable>
|
||||||
<QItemSection avatar>
|
<QItemSection avatar>
|
||||||
<QIcon name="picture_as_pdf" />
|
<QIcon name="picture_as_pdf" />
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>{{ t('Open Delivery Note...') }}</QItemSection>
|
<QItemSection>{{ t('Show Delivery Note...') }}</QItemSection>
|
||||||
<QItemSection side>
|
<QItemSection side>
|
||||||
<QIcon name="keyboard_arrow_right" />
|
<QIcon name="keyboard_arrow_right" />
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QMenu anchor="top end" self="top start" auto-close bordered>
|
<QMenu anchor="top end" self="top start" auto-close bordered>
|
||||||
<QList>
|
<QList>
|
||||||
<QItem @click="openDeliveryNote('deliveryNote')" v-ripple clickable>
|
<QItem @click="openDeliveryNote('deliveryNote')" v-ripple clickable>
|
||||||
<QItemSection>{{ t('With prices') }}</QItemSection>
|
<QItemSection>{{ t('as PDF') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem @click="openDeliveryNote('withoutPrices')" v-ripple clickable>
|
<QItem @click="openDeliveryNote('withoutPrices')" v-ripple clickable>
|
||||||
<QItemSection>{{ t('Without prices') }}</QItemSection>
|
<QItemSection>{{ t('as PDF without prices') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem
|
<QItem
|
||||||
@click="openDeliveryNote('deliveryNote', 'csv')"
|
@click="openDeliveryNote('deliveryNote', 'csv')"
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
>
|
>
|
||||||
<QItemSection>{{ t('As CSV') }}</QItemSection>
|
<QItemSection>{{ t('as CSV') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</QList>
|
</QList>
|
||||||
</QMenu>
|
</QMenu>
|
||||||
|
@ -220,21 +484,21 @@ function openConfirmDialog(callback) {
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
>
|
>
|
||||||
<QItemSection>{{ t('With prices') }}</QItemSection>
|
<QItemSection>{{ t('Send PDF') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem
|
<QItem
|
||||||
@click="sendDeliveryNoteConfirmation('withoutPrices')"
|
@click="sendDeliveryNoteConfirmation('withoutPrices')"
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
>
|
>
|
||||||
<QItemSection>{{ t('Without prices') }}</QItemSection>
|
<QItemSection>{{ t('Send PDF to tablet') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem
|
<QItem
|
||||||
@click="sendDeliveryNoteConfirmation('deliveryNote', 'csv')"
|
@click="sendDeliveryNoteConfirmation('deliveryNote', 'csv')"
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
>
|
>
|
||||||
<QItemSection>{{ t('As CSV') }}</QItemSection>
|
<QItemSection>{{ t('Send CSV') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</QList>
|
</QList>
|
||||||
</QMenu>
|
</QMenu>
|
||||||
|
@ -243,8 +507,26 @@ function openConfirmDialog(callback) {
|
||||||
<QItemSection avatar>
|
<QItemSection avatar>
|
||||||
<QIcon name="receipt" />
|
<QIcon name="receipt" />
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>{{ t('Open Proforma Invoice') }}</QItemSection>
|
<QItemSection>{{ t('Show Proforma') }}</QItemSection>
|
||||||
</QItem>
|
</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>
|
<QItem v-ripple clickable>
|
||||||
<QItemSection avatar>
|
<QItemSection avatar>
|
||||||
<QIcon name="sms" />
|
<QIcon name="sms" />
|
||||||
|
@ -259,24 +541,72 @@ function openConfirmDialog(callback) {
|
||||||
<QItemSection>{{ t('Pending payment') }}</QItemSection>
|
<QItemSection>{{ t('Pending payment') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem @click="showSmsDialog('minAmount')" v-ripple clickable>
|
<QItem @click="showSmsDialog('minAmount')" v-ripple clickable>
|
||||||
<QItemSection>{{ t('Minimum amount') }}</QItemSection>
|
<QItemSection>{{ t('Minimum import') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem
|
<QItem
|
||||||
@click="showSmsDialogWithChanges('orderChanges')"
|
@click="showSmsDialogWithChanges('orderChanges')"
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
>
|
>
|
||||||
<QItemSection>{{ t('Order changes') }}</QItemSection>
|
<QItemSection>{{ t('Notify changes') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</QList>
|
</QList>
|
||||||
</QMenu>
|
</QMenu>
|
||||||
</QItem>
|
</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>
|
<QItem @click="openConfirmDialog('clone')" v-ripple clickable>
|
||||||
<QItemSection avatar>
|
<QItemSection avatar>
|
||||||
<QIcon name="content_copy" />
|
<QIcon name="content_copy" />
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>{{ t('To clone ticket') }}</QItemSection>
|
<QItemSection>{{ t('To clone ticket') }}</QItemSection>
|
||||||
</QItem>
|
</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>
|
<QItem @click="$refs.weightDialog.show()" v-ripple clickable>
|
||||||
<QItemSection avatar>
|
<QItemSection avatar>
|
||||||
<QIcon name="weight" />
|
<QIcon name="weight" />
|
||||||
|
@ -307,29 +637,61 @@ function openConfirmDialog(callback) {
|
||||||
</template>
|
</template>
|
||||||
</VnConfirm>
|
</VnConfirm>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.weekdaysBtn {
|
||||||
|
margin: 1%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
|
addTurn: Add turn
|
||||||
invoiceIds: "Invoices have been generated with the following ids: {invoiceIds}"
|
invoiceIds: "Invoices have been generated with the following ids: {invoiceIds}"
|
||||||
|
|
||||||
es:
|
es:
|
||||||
Open Delivery Note...: Abrir albarán...
|
Show Delivery Note...: Ver albarán...
|
||||||
Send Delivery Note...: Enviar albarán...
|
Send Delivery Note...: Enviar albarán...
|
||||||
With prices: Con precios
|
as PDF: como PDF
|
||||||
Without prices: Sin precios
|
as PDF without prices: como PDF sin precios
|
||||||
As CSV: Como CSV
|
as CSV: Como CSV
|
||||||
Open Proforma Invoice: Abrir factura proforma
|
Send PDF: Enviar PDF
|
||||||
|
Send PDF to tablet: Enviar PDF a tablet
|
||||||
|
Send CSV: Enviar CSV
|
||||||
|
Show Proforma: Ver proforma
|
||||||
Delete ticket: Eliminar ticket
|
Delete ticket: Eliminar ticket
|
||||||
Send SMS...: Enviar SMS
|
Send SMS...: Enviar SMS...
|
||||||
Pending payment: Pago pendiente
|
Pending payment: Pago pendiente
|
||||||
Minimum amount: Importe mínimo
|
Minimum import: Importe mínimo
|
||||||
Order changes: Cambios del pedido
|
Notify changes: Notificar cambios
|
||||||
Ticket deleted: Ticket eliminado
|
Ticket deleted: Ticket eliminado
|
||||||
You can undo this action within the first hour: Puedes deshacer esta acción dentro de la primera hora
|
You can undo this action within the first hour: Puedes deshacer esta acción dentro de la primera hora
|
||||||
To clone ticket: Clonar ticket
|
To clone ticket: Clonar ticket
|
||||||
Ticket cloned: Ticked clonado
|
Ticket cloned: Ticked clonado
|
||||||
It was not able to clone the ticket: No se pudo clonar el ticket
|
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
|
Set weight: Establecer peso
|
||||||
Weight set: Peso establecido
|
Weight set: Peso establecido
|
||||||
This ticket may be invoiced, do you want to continue?: Es posible que se facture este ticket, desea continuar?
|
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}"
|
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
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -1,39 +1,35 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, computed, onUnmounted, reactive, watch } from 'vue';
|
import { onMounted, ref, computed, onUnmounted, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import TicketEditManaProxy from './TicketEditMana.vue';
|
|
||||||
import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import ExpeditionNewTicket from './ExpeditionNewTicket.vue';
|
import ExpeditionNewTicket from './ExpeditionNewTicket.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { toCurrency, toPercentage } from 'src/filters';
|
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import { toDateTimeFormat } from 'src/filters/date';
|
import { toDateTimeFormat } from 'src/filters/date';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
const editPriceProxyRef = ref(null);
|
|
||||||
const newTicketDialogRef = ref(null);
|
const newTicketDialogRef = ref(null);
|
||||||
const logsTableDialogRef = ref(null);
|
const logsTableDialogRef = ref(null);
|
||||||
|
const tableRef = ref();
|
||||||
const expeditionsLogsData = ref([]);
|
const expeditionsLogsData = ref([]);
|
||||||
const selectedExpeditions = ref([]);
|
const selectedExpeditions = ref([]);
|
||||||
const allColumnNames = ref([]);
|
const allColumnNames = ref([]);
|
||||||
const visibleColumns = ref([]);
|
|
||||||
const newTicketWithRoute = ref(false);
|
const newTicketWithRoute = ref(false);
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
const hasSelectedRows = computed(() => selectedRows.value.length > 0);
|
||||||
|
|
||||||
const exprBuilder = (param, value) => {
|
const exprBuilder = (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
|
@ -54,8 +50,6 @@ const expeditionsArrayData = useArrayData('ticketExpeditions', {
|
||||||
filter: expeditionsFilter.value,
|
filter: expeditionsFilter.value,
|
||||||
exprBuilder: exprBuilder,
|
exprBuilder: exprBuilder,
|
||||||
});
|
});
|
||||||
const expeditionsStore = expeditionsArrayData.store;
|
|
||||||
const ticketExpeditions = computed(() => expeditionsStore.data);
|
|
||||||
|
|
||||||
const ticketArrayData = useArrayData('ticketData');
|
const ticketArrayData = useArrayData('ticketData');
|
||||||
const ticketStore = ticketArrayData.store;
|
const ticketStore = ticketArrayData.store;
|
||||||
|
@ -73,129 +67,87 @@ watch(
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const params = reactive({});
|
|
||||||
|
|
||||||
const applyColumnFilter = async (col) => {
|
|
||||||
try {
|
|
||||||
const paramKey = col.columnFilter?.filterParamKey || col.field;
|
|
||||||
params[paramKey] = col.columnFilter.filterValue;
|
|
||||||
await expeditionsArrayData.addFilter({ filter: expeditionsFilter.value, params });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error applying column filter', err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getInputEvents = (col) => {
|
|
||||||
return col.columnFilter.type === 'select'
|
|
||||||
? { 'update:modelValue': () => applyColumnFilter(col) }
|
|
||||||
: {
|
|
||||||
'keyup.enter': () => applyColumnFilter(col),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('expedition.id'),
|
label: t('expedition.id'),
|
||||||
name: 'id',
|
name: 'id',
|
||||||
field: 'id',
|
chip: {
|
||||||
align: 'left',
|
condition: () => true,
|
||||||
sortable: true,
|
},
|
||||||
|
isId: true,
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
component: VnInput,
|
inWhere: true,
|
||||||
type: 'text',
|
|
||||||
filterParamKey: 'expeditionFk',
|
|
||||||
filterValue: null,
|
|
||||||
event: getInputEvents,
|
|
||||||
attrs: {
|
|
||||||
dense: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.item'),
|
label: t('expedition.item'),
|
||||||
name: 'item',
|
name: 'packagingItemFk',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
cardVisible: true,
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
component: VnInput,
|
inWhere: true,
|
||||||
type: 'text',
|
|
||||||
filterParamKey: 'packageItemName',
|
|
||||||
filterValue: null,
|
|
||||||
event: getInputEvents,
|
|
||||||
attrs: {
|
|
||||||
dense: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.name'),
|
label: t('expedition.name'),
|
||||||
name: 'name',
|
name: 'packageItemName',
|
||||||
field: 'packageItemName',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
isTitle: true,
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
component: VnSelect,
|
inWhere: true,
|
||||||
type: 'select',
|
|
||||||
filterValue: null,
|
|
||||||
event: getInputEvents,
|
|
||||||
attrs: {
|
|
||||||
url: 'Items',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
'sort-by': 'name ASC',
|
|
||||||
'option-value': 'id',
|
|
||||||
'option-label': 'name',
|
|
||||||
dense: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.packageType'),
|
label: t('expedition.packageType'),
|
||||||
name: 'packageType',
|
name: 'freightItemName',
|
||||||
field: 'freightItemName',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
component: VnInput,
|
inWhere: true,
|
||||||
type: 'text',
|
|
||||||
// filterParamKey: 'expeditionFk',
|
|
||||||
filterValue: null,
|
|
||||||
event: getInputEvents,
|
|
||||||
attrs: {
|
|
||||||
dense: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.counter'),
|
label: t('expedition.counter'),
|
||||||
name: 'counter',
|
name: 'counter',
|
||||||
field: 'counter',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
columnFilter: null,
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.externalId'),
|
label: t('expedition.externalId'),
|
||||||
name: 'externalId',
|
name: 'externalId',
|
||||||
field: 'externalId',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
columnFilter: null,
|
cardVisible: true,
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.created'),
|
label: t('expedition.created'),
|
||||||
name: 'created',
|
name: 'created',
|
||||||
field: 'created',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
columnFilter: null,
|
cardVisible: true,
|
||||||
format: (value) => toDateTimeFormat(value),
|
format: (row) => toDateTimeFormat(row.created),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.state'),
|
label: t('expedition.state'),
|
||||||
name: 'state',
|
name: 'state',
|
||||||
field: 'state',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
columnFilter: null,
|
cardVisible: true,
|
||||||
|
columnFilter: { inWhere: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '',
|
align: 'right',
|
||||||
name: 'history',
|
name: 'tableActions',
|
||||||
align: 'left',
|
actions: [
|
||||||
columnFilter: null,
|
{
|
||||||
|
title: t('expedition.historyAction'),
|
||||||
|
icon: 'history',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => showLog(row),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -204,23 +156,29 @@ const logTableColumns = computed(() => [
|
||||||
label: t('expedition.state'),
|
label: t('expedition.state'),
|
||||||
name: 'state',
|
name: 'state',
|
||||||
field: 'state',
|
field: 'state',
|
||||||
align: 'left',
|
align: 'center',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.name'),
|
label: t('expedition.name'),
|
||||||
name: 'name',
|
name: 'name',
|
||||||
align: 'name',
|
field: 'name',
|
||||||
|
align: 'center',
|
||||||
columnFilter: null,
|
columnFilter: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('expedition.created'),
|
label: t('expedition.created'),
|
||||||
name: 'created',
|
name: 'created',
|
||||||
field: 'created',
|
field: 'created',
|
||||||
align: 'left',
|
align: 'center',
|
||||||
columnFilter: null,
|
|
||||||
format: (value) => toDateTimeFormat(value),
|
format: (value) => toDateTimeFormat(value),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.isScanned'),
|
||||||
|
name: 'isScanned',
|
||||||
|
field: 'isScanned',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const showNewTicketDialog = (withRoute = false) => {
|
const showNewTicketDialog = (withRoute = false) => {
|
||||||
|
@ -255,10 +213,20 @@ const getExpeditionState = async (expedition) => {
|
||||||
order: ['created DESC'],
|
order: ['created DESC'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data } = await axios.get(`ExpeditionStates/filter`, {
|
const { data: expeditionStates } = await axios.get(`ExpeditionStates/filter`, {
|
||||||
params: { filter: JSON.stringify(filter) },
|
params: { filter: JSON.stringify(filter) },
|
||||||
});
|
});
|
||||||
expeditionsLogsData.value = data;
|
const { data: scannedStates } = await axios.get(`ExpeditionStates`, {
|
||||||
|
params: { filter: JSON.stringify(filter), fields: ['id', 'isScanned'] },
|
||||||
|
});
|
||||||
|
|
||||||
|
expeditionsLogsData.value = expeditionStates.map((state) => {
|
||||||
|
const scannedState = scannedStates.find((s) => s.id === state.id);
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isScanned: scannedState ? scannedState.isScanned : false,
|
||||||
|
};
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
@ -275,21 +243,13 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSubToolbar>
|
<VnSubToolbar>
|
||||||
<template #st-data>
|
|
||||||
<TableVisibleColumns
|
|
||||||
:all-columns="allColumnNames"
|
|
||||||
table-code="expeditionIndex"
|
|
||||||
labels-traductions-path="expedition"
|
|
||||||
@on-config-saved="visibleColumns = [...$event, 'history']"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #st-actions>
|
<template #st-actions>
|
||||||
<QBtnGroup push class="q-gutter-x-sm" flat>
|
<QBtnGroup push class="q-gutter-x-sm" flat>
|
||||||
<QBtnDropdown
|
<QBtnDropdown
|
||||||
ref="btnDropdownRef"
|
ref="btnDropdownRef"
|
||||||
color="primary"
|
color="primary"
|
||||||
:label="t('expedition.move')"
|
:label="t('expedition.move')"
|
||||||
:disable="!selectedExpeditions.length"
|
:disable="!hasSelectedRows"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<QTooltip>{{ t('Select lines to see the options') }}</QTooltip>
|
<QTooltip>{{ t('Select lines to see the options') }}</QTooltip>
|
||||||
|
@ -322,7 +282,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
</QList>
|
</QList>
|
||||||
</QBtnDropdown>
|
</QBtnDropdown>
|
||||||
<QBtn
|
<QBtn
|
||||||
:disable="!selectedExpeditions.length"
|
:disable="!hasSelectedRows"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
color="primary"
|
color="primary"
|
||||||
@click="
|
@click="
|
||||||
|
@ -332,115 +292,34 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
deleteExpedition
|
deleteExpedition
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
/>
|
>
|
||||||
|
<QTooltip>{{ t('expedition.removeExpedition') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
</QBtnGroup>
|
</QBtnGroup>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
|
|
||||||
<QTable
|
<VnTable
|
||||||
:rows="ticketExpeditions"
|
ref="tableRef"
|
||||||
|
data-key="TicketExpedition"
|
||||||
|
url="Expeditions/filter"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
row-key="id"
|
:filter="expeditionsFilter"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
v-model:selected="selectedRows"
|
||||||
class="full-width q-mt-md"
|
:table="{
|
||||||
selection="multiple"
|
'row-key': 'id',
|
||||||
v-model:selected="selectedExpeditions"
|
selection: 'multiple',
|
||||||
:visible-columns="visibleColumns"
|
}"
|
||||||
:no-data-label="t('globals.noResults')"
|
auto-load
|
||||||
|
order="created DESC"
|
||||||
>
|
>
|
||||||
<template #top-row="{ cols }">
|
<template #column-packagingItemFk="{ row }">
|
||||||
<QTr>
|
<span class="link" @click.stop>
|
||||||
<QTd />
|
{{ row.packagingItemFk }}
|
||||||
<QTd v-for="(col, index) in cols" :key="index" style="max-width: 100px">
|
|
||||||
<component
|
|
||||||
:is="col.columnFilter.component"
|
|
||||||
v-if="col.columnFilter"
|
|
||||||
v-model="col.columnFilter.filterValue"
|
|
||||||
v-bind="col.columnFilter.attrs"
|
|
||||||
v-on="col.columnFilter.event(col)"
|
|
||||||
dense
|
|
||||||
/>
|
|
||||||
</QTd>
|
|
||||||
</QTr>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-item="{ row }">
|
|
||||||
<QTd auto-width @click.stop>
|
|
||||||
<QBtn flat color="primary">{{ row.packagingItemFk }}</QBtn>
|
|
||||||
<ItemDescriptorProxy :id="row.packagingItemFk" />
|
<ItemDescriptorProxy :id="row.packagingItemFk" />
|
||||||
</QTd>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-available="{ row }">
|
</VnTable>
|
||||||
<QTd @click.stop>
|
|
||||||
<QBadge :color="row.available < 0 ? 'alert' : 'transparent'" dense>
|
|
||||||
{{ row.available }}
|
|
||||||
</QBadge>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #body-cell-price="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<template v-if="isTicketEditable && row.id">
|
|
||||||
<QBtn flat color="primary" dense @click="onOpenEditPricePopover(row)">
|
|
||||||
{{ toCurrency(row.price) }}
|
|
||||||
</QBtn>
|
|
||||||
<TicketEditManaProxy
|
|
||||||
ref="editPriceProxyRef"
|
|
||||||
:mana="mana"
|
|
||||||
:new-price="getNewPrice"
|
|
||||||
@save="updatePrice(row)"
|
|
||||||
>
|
|
||||||
<VnInput
|
|
||||||
v-model.number="edit.price"
|
|
||||||
:label="t('ticketSale.price')"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
</TicketEditManaProxy>
|
|
||||||
</template>
|
|
||||||
<span v-else>{{ toCurrency(row.price) }}</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-discount="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<template v-if="!isLocked && row.id">
|
|
||||||
<QBtn
|
|
||||||
flat
|
|
||||||
color="primary"
|
|
||||||
dense
|
|
||||||
@click="onOpenEditDiscountPopover(row)"
|
|
||||||
>
|
|
||||||
{{ toPercentage(row.discount / 100) }}
|
|
||||||
</QBtn>
|
|
||||||
<TicketEditManaProxy
|
|
||||||
:mana="mana"
|
|
||||||
:new-price="getNewPrice"
|
|
||||||
@save="changeDiscount(row)"
|
|
||||||
>
|
|
||||||
<VnInput
|
|
||||||
v-model.number="edit.discount"
|
|
||||||
:label="t('ticketSale.discount')"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
</TicketEditManaProxy>
|
|
||||||
</template>
|
|
||||||
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-history="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<QBtn
|
|
||||||
@click.stop="showLog(row)"
|
|
||||||
color="primary"
|
|
||||||
icon="history"
|
|
||||||
size="md"
|
|
||||||
flat
|
|
||||||
>
|
|
||||||
<QTooltip class="text-no-wrap">
|
|
||||||
{{ t('expedition.historyAction') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QBtn>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
<QDialog ref="newTicketDialogRef" transition-show="scale" transition-hide="scale">
|
<QDialog ref="newTicketDialogRef" transition-show="scale" transition-hide="scale">
|
||||||
<ExpeditionNewTicket
|
<ExpeditionNewTicket
|
||||||
:ticket="ticketData"
|
:ticket="ticketData"
|
||||||
|
@ -454,12 +333,23 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
data-key="TicketExpeditionLog"
|
data-key="TicketExpeditionLog"
|
||||||
:rows="expeditionsLogsData"
|
:rows="expeditionsLogsData"
|
||||||
:columns="logTableColumns"
|
:columns="logTableColumns"
|
||||||
class="q-pa-sm"
|
class="q-pa-md full-width"
|
||||||
>
|
>
|
||||||
<template #body-cell-name="{ row }">
|
<template #body-cell-name="{ row }">
|
||||||
<QTd auto-width>
|
<QTd style="text-align: center">
|
||||||
<QBtn flat dense color="primary">{{ row.name }}</QBtn>
|
<span class="link" @click.stop>
|
||||||
<WorkerDescriptorProxy :id="row.workerFk" />
|
<QBtn flat dense>{{ row.name }}</QBtn>
|
||||||
|
<WorkerDescriptorProxy :id="row.workerFk" />
|
||||||
|
</span>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-isScanned="{ row }">
|
||||||
|
<QTd style="text-align: center">
|
||||||
|
<QCheckbox disable v-model="row.isScanned">
|
||||||
|
{{
|
||||||
|
row.isScanned === 1 ? t('expedition.yes') : t('expedition.no')
|
||||||
|
}}
|
||||||
|
</QCheckbox>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
|
|
|
@ -17,6 +17,7 @@ const ticketNotesCrudRef = ref(null);
|
||||||
const observationTypes = ref([]);
|
const observationTypes = ref([]);
|
||||||
const arrayData = useArrayData('TicketNotes');
|
const arrayData = useArrayData('TicketNotes');
|
||||||
const { store } = arrayData;
|
const { store } = arrayData;
|
||||||
|
const isSaving = ref(false);
|
||||||
|
|
||||||
const crudModelFilter = reactive({
|
const crudModelFilter = reactive({
|
||||||
where: { ticketFk: route.params.id },
|
where: { ticketFk: route.params.id },
|
||||||
|
@ -33,6 +34,17 @@ watch(
|
||||||
await ticketNotesCrudRef.value.reload();
|
await ticketNotesCrudRef.value.reload();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
function handleDelete(row) {
|
||||||
|
ticketNotesCrudRef.value.remove([row]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSave() {
|
||||||
|
if (!isSaving.value) {
|
||||||
|
isSaving.value = true;
|
||||||
|
await ticketNotesCrudRef.value?.saveChanges();
|
||||||
|
isSaving.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -73,13 +85,14 @@ watch(
|
||||||
:label="t('ticketNotes.description')"
|
:label="t('ticketNotes.description')"
|
||||||
v-model="row.description"
|
v-model="row.description"
|
||||||
class="col"
|
class="col"
|
||||||
|
@keyup.enter="handleSave"
|
||||||
/>
|
/>
|
||||||
<QIcon
|
<QIcon
|
||||||
name="delete"
|
name="delete"
|
||||||
size="sm"
|
size="sm"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
color="primary"
|
color="primary"
|
||||||
@click="ticketNotesCrudRef.remove([row])"
|
@click="handleDelete(row)"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('ticketNotes.removeNote') }}
|
{{ t('ticketNotes.removeNote') }}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import FetchData from 'components/FetchData.vue';
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
|
@ -1,27 +1,35 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, watch, reactive } from 'vue';
|
import { ref, computed, watch, reactive } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import CrudModel from 'src/components/CrudModel.vue';
|
|
||||||
import TicketCreateRequest from './TicketCreateRequest.vue';
|
|
||||||
|
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import { toDateFormat } from 'src/filters/date.js';
|
import { toDateFormat } from 'src/filters/date.js';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { useStateStore } from 'src/stores/useStateStore';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const createTicketRequestDialogRef = ref(null);
|
const tableRef = ref();
|
||||||
const crudModelRef = ref(null);
|
const attendersOptions = ref([]);
|
||||||
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
async (val) => {
|
async (val) => {
|
||||||
crudModelFilter.where.ticketFk = val;
|
crudModelFilter.where.ticketFk = val;
|
||||||
crudModelRef.value.reload();
|
tableRef.value.reload();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -72,64 +80,81 @@ const crudModelFilter = reactive({
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.id'),
|
label: t('purchaseRequest.id'),
|
||||||
name: 'id',
|
name: 'id',
|
||||||
field: 'id',
|
chip: {
|
||||||
align: 'left',
|
condition: () => true,
|
||||||
columnFilter: null,
|
},
|
||||||
|
isId: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.description'),
|
label: t('purchaseRequest.description'),
|
||||||
name: 'description',
|
name: 'description',
|
||||||
field: 'description',
|
columnClass: 'expand',
|
||||||
align: 'left',
|
|
||||||
format: (val) => dashIfEmpty(val),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.created'),
|
label: t('purchaseRequest.created'),
|
||||||
name: 'created',
|
name: 'created',
|
||||||
field: 'created',
|
format: (row) => toDateFormat(row.created),
|
||||||
align: 'left',
|
cardVisible: true,
|
||||||
format: (val) => toDateFormat(val),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.requester'),
|
label: t('purchaseRequest.requester'),
|
||||||
name: 'requester',
|
name: 'requesterFk',
|
||||||
align: 'left',
|
cardVisible: true,
|
||||||
sortable: true,
|
format: (row) => dashIfEmpty(row.requester?.user?.nickname),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.atender'),
|
label: t('purchaseRequest.atender'),
|
||||||
name: 'atender',
|
name: 'attenderFk',
|
||||||
align: 'left',
|
cardVisible: true,
|
||||||
|
format: (row) => dashIfEmpty(row.atender?.user?.nickname),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.quantity'),
|
label: t('purchaseRequest.quantity'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.price'),
|
label: t('purchaseRequest.price'),
|
||||||
name: 'price',
|
name: 'price',
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.saleFk'),
|
label: t('purchaseRequest.saleFk'),
|
||||||
name: 'saleFk',
|
name: 'saleFk',
|
||||||
align: 'left',
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('purchaseRequest.state'),
|
label: t('purchaseRequest.state'),
|
||||||
name: 'state',
|
name: 'isOk',
|
||||||
field: 'isOk',
|
cardVisible: true,
|
||||||
align: 'left',
|
|
||||||
format: (val) => t(getRequestState(val)),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '',
|
align: 'right',
|
||||||
name: 'actions',
|
name: 'tableActions',
|
||||||
align: 'left',
|
actions: [
|
||||||
columnFilter: null,
|
{
|
||||||
|
title: t('globals.delete'),
|
||||||
|
icon: 'delete',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) =>
|
||||||
|
openConfirmationModal(
|
||||||
|
t('You are going to delete this ticket purchase request'),
|
||||||
|
t(
|
||||||
|
'This ticket will be removed from ticket purchase requests! Continue anyway?'
|
||||||
|
),
|
||||||
|
() => removeLine(row.id)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -140,131 +165,117 @@ const getRequestState = (state) => {
|
||||||
case false:
|
case false:
|
||||||
return 'Denied';
|
return 'Denied';
|
||||||
case true:
|
case true:
|
||||||
return 'Acepted';
|
return 'Accepted';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isEditable = (isOk) => isOk !== null;
|
const isEditable = (isOk) => isOk !== null;
|
||||||
|
|
||||||
const removeLine = async (row) => crudModelRef.value.remove([row]);
|
async function removeLine(id) {
|
||||||
|
try {
|
||||||
|
await axios.delete(`TicketRequests/${id}`);
|
||||||
|
notify(t('globals.dataSaved'), 'positive');
|
||||||
|
location.reload();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error ', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const openCreateModal = () => createTicketRequestDialogRef.value.show();
|
onMounted(() => (stateStore.rightDrawer = false));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPage class="column items-center q-pa-md">
|
<FetchData
|
||||||
<CrudModel
|
url="TicketRequests/getItemTypeWorker"
|
||||||
data-key="PurchaseRequests"
|
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC' }"
|
||||||
url="TicketRequests"
|
auto-load
|
||||||
ref="crudModelRef"
|
@on-fetch="(data) => (attendersOptions = data)"
|
||||||
:filter="crudModelFilter"
|
/>
|
||||||
:order="['created ASC']"
|
<VnTable
|
||||||
:default-remove="false"
|
ref="tableRef"
|
||||||
:default-save="false"
|
data-key="PurchaseRequests"
|
||||||
:default-reset="false"
|
url="TicketRequests"
|
||||||
:limit="0"
|
:create="{
|
||||||
auto-load
|
urlCreate: 'TicketRequests',
|
||||||
>
|
title: t('Create request'),
|
||||||
<template #body="{ rows }">
|
onDataSaved: ({ id }) => tableRef.reload(id),
|
||||||
<QTable
|
formInitialData: {
|
||||||
:rows="rows"
|
ticketFk: route.params.id,
|
||||||
:columns="columns"
|
},
|
||||||
row-key="id"
|
}"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
save-url="TicketRequests/crud"
|
||||||
class="full-width q-mt-md"
|
:filter="crudModelFilter"
|
||||||
:no-data-label="t('globals.noResults')"
|
:columns="columns"
|
||||||
@row-click="(_, row) => redirectToTicketSummary(row.ticketFk)"
|
:is-editable="true"
|
||||||
>
|
:right-search="false"
|
||||||
<template #body-cell-description="{ row }">
|
:column-search="false"
|
||||||
<QTd @click.stop>
|
auto-load
|
||||||
<VnInput
|
>
|
||||||
v-model="row.description"
|
<template #column-description="{ row }">
|
||||||
@blur="crudModelRef.saveChanges()"
|
<VnInput v-model="row.description" :disable="isEditable(row.isOk)" />
|
||||||
:disable="isEditable(row.isOk)"
|
</template>
|
||||||
/>
|
<template #column-requesterFk="{ row }">
|
||||||
</QTd>
|
<span class="link" @click.stop>
|
||||||
</template>
|
{{ row.requester?.user?.nickname }}
|
||||||
<template #body-cell-requester="{ row }">
|
<WorkerDescriptorProxy :id="row.requesterFk" />
|
||||||
<QTd @click.stop>
|
</span>
|
||||||
<QBtn flat color="primary">
|
</template>
|
||||||
{{ row.requester?.user?.nickname }}
|
<template #column-attenderFk="{ row }">
|
||||||
<WorkerDescriptorProxy :id="row.requesterFk" />
|
<span class="link" @click.stop>
|
||||||
</QBtn>
|
{{ row.atender?.user?.nickname }}
|
||||||
</QTd>
|
<WorkerDescriptorProxy :id="row.attenderFk" />
|
||||||
</template>
|
</span>
|
||||||
<template #body-cell-atender="{ row }">
|
</template>
|
||||||
<QTd @click.stop>
|
<template #column-quantity="{ row }">
|
||||||
<QBtn flat color="primary">
|
<VnInput v-model="row.quantity" :disable="isEditable(row.isOk)" />
|
||||||
{{ row.atender?.user?.nickname }}
|
</template>
|
||||||
<WorkerDescriptorProxy :id="row.attenderFk" />
|
<template #column-price="{ row }">
|
||||||
</QBtn>
|
<span @click.stop>
|
||||||
</QTd>
|
<VnInput v-model="row.price" :disable="isEditable(row.isOk)">
|
||||||
</template>
|
{{ row.price }}
|
||||||
<template #body-cell-quantity="{ row }">
|
</VnInput>
|
||||||
<QTd @click.stop>
|
</span>
|
||||||
<VnInput
|
</template>
|
||||||
v-model="row.quantity"
|
<template #column-saleFk="{ row }">
|
||||||
@blur="crudModelRef.saveChanges()"
|
<QTd style="width: 3%">
|
||||||
:disable="isEditable(row.isOk)"
|
<span class="link" @click.stop>
|
||||||
/>
|
{{ dashIfEmpty(row.sale?.itemFk) }}
|
||||||
</QTd>
|
<ItemDescriptorProxy :id="row.sale?.itemFk" /> </span
|
||||||
</template>
|
></QTd>
|
||||||
<template #body-cell-price="{ row }">
|
</template>
|
||||||
<QTd @click.stop>
|
<template #column-isOk="{ row }">
|
||||||
<VnInput
|
{{ t(getRequestState(row.isOk)) }}
|
||||||
v-model="row.price"
|
</template>
|
||||||
@blur="crudModelRef.saveChanges()"
|
|
||||||
:disable="isEditable(row.isOk)"
|
<template #more-create-dialog="{ data }">
|
||||||
/>
|
<VnInput
|
||||||
</QTd>
|
v-model="data.description"
|
||||||
</template>
|
:label="t('purchaseRequest.description')"
|
||||||
<template #body-cell-saleFk="{ row }">
|
|
||||||
<QTd @click.stop>
|
|
||||||
<QBtn v-if="row.saleFk" flat color="primary">
|
|
||||||
{{ row.sale.itemFk }}
|
|
||||||
<ItemDescriptorProxy :id="row.sale.itemFk" />
|
|
||||||
</QBtn>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-actions="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<QIcon
|
|
||||||
@click.stop="removeLine(row)"
|
|
||||||
class="q-ml-sm cursor-pointer"
|
|
||||||
color="primary"
|
|
||||||
name="delete"
|
|
||||||
size="sm"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('globals.delete') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
</template>
|
|
||||||
</CrudModel>
|
|
||||||
<QDialog
|
|
||||||
ref="createTicketRequestDialogRef"
|
|
||||||
transition-show="scale"
|
|
||||||
transition-hide="scale"
|
|
||||||
>
|
|
||||||
<TicketCreateRequest @on-request-created="crudModelRef.reload()" />
|
|
||||||
</QDialog>
|
|
||||||
<QPageSticky :offset="[20, 20]">
|
|
||||||
<QBtn
|
|
||||||
@click="openCreateModal()"
|
|
||||||
color="primary"
|
|
||||||
fab
|
|
||||||
icon="add"
|
|
||||||
shortcut="+"
|
|
||||||
/>
|
/>
|
||||||
<QTooltip class="text-no-wrap">
|
<VnSelect
|
||||||
{{ t('purchaseRequest.newRequest') }}
|
:label="t('purchaseRequest.atender')"
|
||||||
</QTooltip>
|
v-model="data.attenderFk"
|
||||||
</QPageSticky>
|
:options="attendersOptions"
|
||||||
</QPage>
|
hide-selected
|
||||||
|
option-label="nickname"
|
||||||
|
option-value="id"
|
||||||
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-model="data.quantity"
|
||||||
|
:label="t('purchaseRequest.quantity')"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-model="data.price"
|
||||||
|
:label="t('purchaseRequest.price')"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
New: Nueva
|
New: Nueva
|
||||||
|
|
|
@ -16,11 +16,12 @@ import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
|
||||||
import TicketTransfer from './TicketTransfer.vue';
|
import TicketTransfer from './TicketTransfer.vue';
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { toCurrency, toPercentage, dashIfEmpty } from 'src/filters';
|
import { toCurrency, toPercentage } from 'src/filters';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -33,7 +34,8 @@ const stateBtnDropdownRef = ref(null);
|
||||||
|
|
||||||
const arrayData = useArrayData('ticketData');
|
const arrayData = useArrayData('ticketData');
|
||||||
const { store } = arrayData;
|
const { store } = arrayData;
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
const hasSelectedRows = computed(() => selectedRows.value.length > 0);
|
||||||
const ticketConfig = ref(null);
|
const ticketConfig = ref(null);
|
||||||
const isLocked = ref(false);
|
const isLocked = ref(false);
|
||||||
const isTicketEditable = ref(false);
|
const isTicketEditable = ref(false);
|
||||||
|
@ -47,6 +49,7 @@ const transfer = ref({
|
||||||
lastActiveTickets: [],
|
lastActiveTickets: [],
|
||||||
sales: [],
|
sales: [],
|
||||||
});
|
});
|
||||||
|
const tableRef = ref([]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
|
@ -55,86 +58,89 @@ watch(
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
label: '',
|
align: 'left',
|
||||||
name: 'statusIcons',
|
name: 'statusIcons',
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '',
|
align: 'center',
|
||||||
name: 'picture',
|
label: t('lines.image'),
|
||||||
align: 'left',
|
name: 'image',
|
||||||
|
columnField: {
|
||||||
|
component: VnImg,
|
||||||
|
attrs: (id) => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
width: '50px',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.visible'),
|
label: t('ticketSale.visible'),
|
||||||
name: 'visible',
|
name: 'visible',
|
||||||
field: 'visible',
|
format: (row, dashIfEmpty) => dashIfEmpty(row.visible),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.available'),
|
label: t('ticketSale.available'),
|
||||||
name: 'available',
|
name: 'available',
|
||||||
field: 'available',
|
format: (row, dashIfEmpty) => dashIfEmpty(row.available),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.id'),
|
label: t('ticketSale.id'),
|
||||||
name: 'itemFk',
|
name: 'itemFk',
|
||||||
field: 'itemFk',
|
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.quantity'),
|
label: t('ticketSale.quantity'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
field: 'quantity',
|
format: (row) => toCurrency(row.quantity),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.item'),
|
label: t('ticketSale.item'),
|
||||||
name: 'item',
|
name: 'item',
|
||||||
field: 'item',
|
format: (row) => row?.item?.name,
|
||||||
align: 'left',
|
columnClass: 'expand',
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.price'),
|
label: t('ticketSale.price'),
|
||||||
name: 'price',
|
name: 'price',
|
||||||
field: 'price',
|
format: (row) => toCurrency(row.price),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
format: (val) => toCurrency(val),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.discount'),
|
label: t('ticketSale.discount'),
|
||||||
name: 'discount',
|
name: 'discount',
|
||||||
field: 'discount',
|
format: (row) => toPercentage(row.discount),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.amount'),
|
label: t('ticketSale.amount'),
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
field: 'amount',
|
format: (row) => parseInt(row.amount * row.quantity),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
format: (val) => toCurrency(val),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('ticketSale.packaging'),
|
label: t('ticketSale.packaging'),
|
||||||
name: 'itemPackingTypeFk',
|
name: 'itemPackingTypeFk',
|
||||||
field: 'item',
|
format: (row, dashIfEmpty) => dashIfEmpty(row?.item?.itemPackingTypeFk),
|
||||||
align: 'left',
|
|
||||||
sortable: true,
|
|
||||||
format: (val) => dashIfEmpty(val?.itemPackingTypeFk),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '',
|
align: 'right',
|
||||||
name: 'history',
|
name: 'tableActions',
|
||||||
align: 'left',
|
actions: [
|
||||||
columnFilter: null,
|
{
|
||||||
|
title: t('ticketSale.history'),
|
||||||
|
icon: 'history',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => goToLog(row.id),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -210,6 +216,7 @@ const addSale = async (sale) => {
|
||||||
sale.item = newSale.item;
|
sale.item = newSale.item;
|
||||||
|
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
|
window.location.reload();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error adding sale', err);
|
console.error('Error adding sale', err);
|
||||||
}
|
}
|
||||||
|
@ -259,7 +266,7 @@ const getMana = async () => {
|
||||||
|
|
||||||
const selectedValidSales = computed(() => {
|
const selectedValidSales = computed(() => {
|
||||||
if (!sales.value) return;
|
if (!sales.value) return;
|
||||||
return selectedSales.value.filter((sale) => sale.id != undefined);
|
return [...selectedRows.value];
|
||||||
});
|
});
|
||||||
|
|
||||||
const onOpenEditPricePopover = async (sale) => {
|
const onOpenEditPricePopover = async (sale) => {
|
||||||
|
@ -374,7 +381,7 @@ const changeTicketState = async (val) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeSelectedSales = () => {
|
const removeSelectedSales = () => {
|
||||||
selectedSales.value.forEach((sale) => {
|
selectedRows.value.forEach((sale) => {
|
||||||
const index = sales.value.indexOf(sale);
|
const index = sales.value.indexOf(sale);
|
||||||
sales.value.splice(index, 1);
|
sales.value.splice(index, 1);
|
||||||
});
|
});
|
||||||
|
@ -382,19 +389,29 @@ const removeSelectedSales = () => {
|
||||||
|
|
||||||
const removeSales = async () => {
|
const removeSales = async () => {
|
||||||
try {
|
try {
|
||||||
const params = { sales: selectedValidSales.value, ticketId: store.data.id };
|
const params = {
|
||||||
|
sales: selectedRows.value.filter((sale) => sale.id),
|
||||||
|
ticketId: store.data.id,
|
||||||
|
};
|
||||||
|
selectedRows.value
|
||||||
|
.filter((sale) => !sale.id)
|
||||||
|
.forEach((sale) =>
|
||||||
|
tableRef.value.CrudModelRef.formData.splice(sale.$index, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (params.sales.length == 0) return;
|
||||||
await axios.post('Sales/deleteSales', params);
|
await axios.post('Sales/deleteSales', params);
|
||||||
removeSelectedSales();
|
removeSelectedSales();
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
|
window.location.reload();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error deleting sales', err);
|
console.error('Error deleting sales', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertRow = () => sales.value.push({ ...DEFAULT_EDIT });
|
|
||||||
|
|
||||||
const setTransferParams = async () => {
|
const setTransferParams = async () => {
|
||||||
try {
|
try {
|
||||||
|
selectedSales.value = selectedValidSales.value;
|
||||||
const checkedSales = JSON.parse(JSON.stringify(selectedSales.value));
|
const checkedSales = JSON.parse(JSON.stringify(selectedSales.value));
|
||||||
transfer.value = {
|
transfer.value = {
|
||||||
lastActiveTickets: [],
|
lastActiveTickets: [],
|
||||||
|
@ -418,9 +435,70 @@ onMounted(async () => {
|
||||||
stateStore.rightDrawer = true;
|
stateStore.rightDrawer = true;
|
||||||
getConfig();
|
getConfig();
|
||||||
getSales();
|
getSales();
|
||||||
|
getItems();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
|
|
||||||
|
const items = ref([]);
|
||||||
|
const newRow = ref({});
|
||||||
|
|
||||||
|
async function getItems() {
|
||||||
|
const { data } = await axios.get(`Items/withName`);
|
||||||
|
items.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateItem = (row) => {
|
||||||
|
const selectedItem = items.value.find((item) => item.id === row.itemFk);
|
||||||
|
if (selectedItem) {
|
||||||
|
row.item = selectedItem;
|
||||||
|
row.itemFk = selectedItem.id;
|
||||||
|
row.price = selectedItem.price;
|
||||||
|
row.discount = 0;
|
||||||
|
row.quantity = 0;
|
||||||
|
row.amount = row.price * row.quantity;
|
||||||
|
}
|
||||||
|
endNewRow(selectedItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleOnDataSave({ CrudModelRef }) {
|
||||||
|
const { copy } = addRow(CrudModelRef.formData);
|
||||||
|
CrudModelRef.insert(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
const addRow = (original = null) => {
|
||||||
|
let copy = null;
|
||||||
|
if (!original) {
|
||||||
|
copy = { isNew: true };
|
||||||
|
} else {
|
||||||
|
copy = {
|
||||||
|
itemFk: original.itemFk,
|
||||||
|
item: original.item,
|
||||||
|
quantity: original.quantity,
|
||||||
|
price: original.price,
|
||||||
|
discount: original.discount,
|
||||||
|
amount: original.amount,
|
||||||
|
isNew: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
newRow.value = copy;
|
||||||
|
return { original, copy };
|
||||||
|
};
|
||||||
|
|
||||||
|
const endNewRow = (row) => {
|
||||||
|
if (row.itemFk && row.quantity) {
|
||||||
|
row.isNew = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => newRow.value.itemFk,
|
||||||
|
(newItemFk) => {
|
||||||
|
if (newItemFk) {
|
||||||
|
updateItem(newRow.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -471,7 +549,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
:ticket="store.data"
|
:ticket="store.data"
|
||||||
:is-ticket-editable="isTicketEditable"
|
:is-ticket-editable="isTicketEditable"
|
||||||
:sales="selectedValidSales"
|
:sales="selectedValidSales"
|
||||||
:disable="!selectedSales.length"
|
:disable="!hasSelectedRows"
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
:ticket-config="ticketConfig"
|
:ticket-config="ticketConfig"
|
||||||
@get-mana="getMana()"
|
@get-mana="getMana()"
|
||||||
|
@ -480,7 +558,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
<QBtn
|
<QBtn
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
:disable="!isTicketEditable || !selectedSales.length"
|
:disable="!isTicketEditable || !hasSelectedRows"
|
||||||
@click="
|
@click="
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
t('Continue anyway?'),
|
t('Continue anyway?'),
|
||||||
|
@ -494,7 +572,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
<QBtn
|
<QBtn
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="vn:splitline"
|
icon="vn:splitline"
|
||||||
:disable="!isTicketEditable || !selectedSales.length"
|
:disable="!isTicketEditable || !hasSelectedRows"
|
||||||
@click="setTransferParams()"
|
@click="setTransferParams()"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Transfer lines') }}</QTooltip>
|
<QTooltip>{{ t('Transfer lines') }}</QTooltip>
|
||||||
|
@ -507,246 +585,214 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
</QBtnGroup>
|
</QBtnGroup>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
<QDrawer side="right" :width="270" v-model="stateStore.rightDrawer">
|
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer">
|
||||||
<div
|
<div
|
||||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||||
style="border: 2px solid black"
|
style="border: 2px solid black"
|
||||||
>
|
>
|
||||||
<QCardSection class="justify-center text-subtitle1" horizontal>
|
<QCardSection class="justify-end text-subtitle1" horizontal>
|
||||||
<span class="q-mr-xs color-vn-label"
|
<span class="q-mr-xs color-vn-label"
|
||||||
>{{ t('ticketSale.subtotal') }}:
|
>{{ t('ticketSale.subtotal') }}:
|
||||||
</span>
|
</span>
|
||||||
<span>{{ toCurrency(store.data?.totalWithoutVat) }}</span>
|
<span>{{ toCurrency(store.data?.totalWithoutVat) }}</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardSection class="justify-center text-subtitle1" horizontal>
|
<QCardSection class="justify-end text-subtitle1" horizontal>
|
||||||
<span class="q-mr-xs color-vn-label"> {{ t('ticketSale.tax') }}: </span>
|
<span class="q-mr-xs color-vn-label"> {{ t('ticketSale.tax') }}: </span>
|
||||||
<span>{{
|
<span>{{
|
||||||
toCurrency(store.data?.totalWithVat - store.data?.totalWithoutVat)
|
toCurrency(store.data?.totalWithVat - store.data?.totalWithoutVat)
|
||||||
}}</span>
|
}}</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardSection
|
<QCardSection class="justify-end text-weight-bold text-subtitle1" horizontal>
|
||||||
class="justify-center text-weight-bold text-subtitle1"
|
|
||||||
horizontal
|
|
||||||
>
|
|
||||||
<span class="q-mr-xs color-vn-label"> {{ t('ticketSale.total') }}: </span>
|
<span class="q-mr-xs color-vn-label"> {{ t('ticketSale.total') }}: </span>
|
||||||
<span>{{ toCurrency(store.data?.totalWithVat) }}</span>
|
<span>{{ toCurrency(store.data?.totalWithVat) }}</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
</div></QDrawer
|
</div></QDrawer
|
||||||
>
|
>
|
||||||
<QTable
|
<VnTable
|
||||||
:rows="sales"
|
ref="tableRef"
|
||||||
|
data-key="TicketSales"
|
||||||
|
:url="`Tickets/${route.params.id}/getSales`"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
row-key="id"
|
v-model:selected="selectedRows"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
:bottom="true"
|
||||||
class="full-width q-mt-md"
|
:table="{
|
||||||
selection="multiple"
|
'row-key': 'id',
|
||||||
v-model:selected="selectedSales"
|
selection: 'multiple',
|
||||||
:no-data-label="t('globals.noResults')"
|
}"
|
||||||
|
:right-search="false"
|
||||||
|
:column-search="false"
|
||||||
|
:disable-option="{ card: true }"
|
||||||
|
auto-load
|
||||||
|
:create="{
|
||||||
|
onDataSaved: handleOnDataSave,
|
||||||
|
}"
|
||||||
|
:create-as-dialog="false"
|
||||||
|
:crud-model="{
|
||||||
|
paginate: false,
|
||||||
|
}"
|
||||||
|
:default-remove="false"
|
||||||
|
:default-reset="false"
|
||||||
|
:default-save="false"
|
||||||
|
:disabled-attr="isTicketEditable"
|
||||||
>
|
>
|
||||||
<template #body-cell-statusIcons="{ row }">
|
<template #column-statusIcons="{ row }">
|
||||||
<QTd class="q-gutter-x-xs">
|
<router-link
|
||||||
<router-link
|
v-if="row.claim?.claimFk"
|
||||||
v-if="row.claim?.claimFk"
|
:to="{ name: 'ClaimBasicData', params: { id: row.claim?.claimFk } }"
|
||||||
:to="{ name: 'ClaimBasicData', params: { id: row.claim?.claimFk } }"
|
>
|
||||||
>
|
<QIcon color="primary" name="vn:claims" size="xs">
|
||||||
<QIcon color="primary" name="vn:claims" size="xs">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('ticketSale.claim') }}:
|
|
||||||
{{ row.claim?.claimFk }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</router-link>
|
|
||||||
<QIcon v-if="row.visible < 0" color="primary" name="warning" size="xs">
|
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('ticketSale.visible') }}: {{ row.visible || 0 }}
|
{{ t('ticketSale.claim') }}:
|
||||||
|
{{ row.claim?.claimFk }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon v-if="row.reserved" color="primary" name="vn:reserva" size="xs">
|
</router-link>
|
||||||
<QTooltip>
|
<QIcon v-if="row.visible < 0" color="primary" name="warning" size="xs">
|
||||||
{{ t('ticketSale.reserved') }}
|
<QTooltip>
|
||||||
</QTooltip>
|
{{ t('ticketSale.visible') }}: {{ row.visible || 0 }}
|
||||||
</QIcon>
|
</QTooltip>
|
||||||
<QIcon
|
</QIcon>
|
||||||
v-if="row.itemShortage"
|
<QIcon v-if="row.reserved" color="primary" name="vn:reserva" size="xs">
|
||||||
color="primary"
|
<QTooltip>
|
||||||
name="vn:unavailable"
|
{{ t('ticketSale.reserved') }}
|
||||||
size="xs"
|
</QTooltip>
|
||||||
>
|
</QIcon>
|
||||||
<QTooltip>
|
<QIcon
|
||||||
{{ t('ticketSale.noVisible') }}
|
v-if="row.itemShortage"
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasComponentLack"
|
|
||||||
color="primary"
|
|
||||||
name="vn:components"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('ticketSale.hasComponentLack') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-picture="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<div class="image-wrapper">
|
|
||||||
<VnImg :id="row.itemFk" class="rounded" />
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-visible="{ row }">
|
|
||||||
<QTd @click.stop>
|
|
||||||
<QBadge :color="row.visible < 0 ? 'alert' : 'transparent'" dense>
|
|
||||||
{{ row.visible }}
|
|
||||||
</QBadge>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-available="{ row }">
|
|
||||||
<QTd @click.stop>
|
|
||||||
<QBadge :color="row.available < 0 ? 'alert' : 'transparent'" dense>
|
|
||||||
{{ row.available }}
|
|
||||||
</QBadge>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-itemFk="{ row }">
|
|
||||||
<QTd @click.stop>
|
|
||||||
<div v-if="row.id">
|
|
||||||
<QBtn flat color="primary" dense>
|
|
||||||
{{ row.itemFk }}
|
|
||||||
</QBtn>
|
|
||||||
<ItemDescriptorProxy :id="row.itemFk" />
|
|
||||||
</div>
|
|
||||||
<VnSelect
|
|
||||||
v-else
|
|
||||||
hide-selected
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
url="Items/withName"
|
|
||||||
:fields="['id', 'name']"
|
|
||||||
sort-by="id DESC"
|
|
||||||
@update:model-value="changeQuantity(row)"
|
|
||||||
v-model="row.itemFk"
|
|
||||||
>
|
|
||||||
<template #option="scope">
|
|
||||||
<QItem v-bind="scope.itemProps">
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
|
|
||||||
<QItemLabel caption>{{ scope.opt?.name }}</QItemLabel>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-quantity="{ row }">
|
|
||||||
<QTd @click.stop>
|
|
||||||
<VnInput
|
|
||||||
v-if="isTicketEditable"
|
|
||||||
v-model.number="row.quantity"
|
|
||||||
@keyup.enter="changeQuantity(row)"
|
|
||||||
@blur="changeQuantity(row)"
|
|
||||||
@focus="edit.oldQuantity = row.quantity"
|
|
||||||
/>
|
|
||||||
<span v-else>{{ row.quantity }}</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-item="{ row }">
|
|
||||||
<QTd class="col">
|
|
||||||
<div class="column">
|
|
||||||
<span>{{ row.concept }}</span>
|
|
||||||
<span class="color-vn-label">{{ row.item?.subName }}</span>
|
|
||||||
<FetchedTags v-if="row.item" :item="row.item" />
|
|
||||||
<QPopupProxy v-if="row.id && isTicketEditable">
|
|
||||||
<VnInput v-model="row.concept" @change="updateConcept(row)" />
|
|
||||||
</QPopupProxy>
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-price="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<template v-if="isTicketEditable && row.id">
|
|
||||||
<QBtn flat color="primary" dense @click="onOpenEditPricePopover(row)">
|
|
||||||
{{ toCurrency(row.price) }}
|
|
||||||
</QBtn>
|
|
||||||
<TicketEditManaProxy
|
|
||||||
ref="editPriceProxyRef"
|
|
||||||
:mana="mana"
|
|
||||||
:new-price="getNewPrice"
|
|
||||||
@save="updatePrice(row)"
|
|
||||||
>
|
|
||||||
<VnInput
|
|
||||||
v-model.number="edit.price"
|
|
||||||
:label="t('ticketSale.price')"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
</TicketEditManaProxy>
|
|
||||||
</template>
|
|
||||||
<span v-else>{{ toCurrency(row.price) }}</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-discount="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<template v-if="!isLocked && row.id">
|
|
||||||
<QBtn
|
|
||||||
flat
|
|
||||||
color="primary"
|
|
||||||
dense
|
|
||||||
@click="onOpenEditDiscountPopover(row)"
|
|
||||||
>
|
|
||||||
{{ toPercentage(row.discount / 100) }}
|
|
||||||
</QBtn>
|
|
||||||
<TicketEditManaProxy
|
|
||||||
:mana="mana"
|
|
||||||
:new-price="getNewPrice"
|
|
||||||
@save="changeDiscount(row)"
|
|
||||||
>
|
|
||||||
<VnInput
|
|
||||||
v-model.number="edit.discount"
|
|
||||||
:label="t('ticketSale.discount')"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
</TicketEditManaProxy>
|
|
||||||
</template>
|
|
||||||
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-history="{ row }">
|
|
||||||
<QTd>
|
|
||||||
<QBtn
|
|
||||||
v-if="row.$hasLogs"
|
|
||||||
@click.stop="goToLog(row.id)"
|
|
||||||
color="primary"
|
|
||||||
icon="history"
|
|
||||||
size="md"
|
|
||||||
flat
|
|
||||||
>
|
|
||||||
<QTooltip class="text-no-wrap">
|
|
||||||
{{ t('ticketSale.history') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QBtn>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #bottom-row>
|
|
||||||
<QBtn
|
|
||||||
class="cursor-pointer fill-icon q-ml-md q-my-lg"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="add_circle"
|
name="vn:unavailable"
|
||||||
size="md"
|
size="xs"
|
||||||
round
|
|
||||||
flat
|
|
||||||
shortcut="+"
|
|
||||||
:disable="!isTicketEditable"
|
|
||||||
@click="insertRow()"
|
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('Add item') }}
|
{{ t('ticketSale.noVisible') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.hasComponentLack"
|
||||||
|
color="primary"
|
||||||
|
name="vn:components"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('ticketSale.hasComponentLack') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
<template #column-image="{ row }">
|
||||||
|
<div class="image-wrapper">
|
||||||
|
<VnImg :id="parseInt(row?.item?.id)" class="rounded" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #column-visible="{ row }">
|
||||||
|
<QBadge :color="row.visible < 0 ? 'alert' : 'transparent'" dense>
|
||||||
|
{{ row.visible }}
|
||||||
|
</QBadge>
|
||||||
|
</template>
|
||||||
|
<template #column-available="{ row }">
|
||||||
|
<QBadge :color="row.available < 0 ? 'alert' : 'transparent'" dense>
|
||||||
|
{{ row.available }}
|
||||||
|
</QBadge>
|
||||||
|
</template>
|
||||||
|
<template #column-itemFk="{ row }">
|
||||||
|
<VnSelect
|
||||||
|
v-if="row.isNew"
|
||||||
|
url="Items/WithName"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
:sort-by="['id DESC']"
|
||||||
|
:options="items"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="row.itemFk"
|
||||||
|
@update:model-value="updateItem(row)"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.id }} - {{ scope.opt?.name }}</QItemLabel
|
||||||
|
>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
<span v-else class="link" @click.stop>
|
||||||
|
{{ row?.itemFk }}
|
||||||
|
<ItemDescriptorProxy :id="row?.itemFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #column-item="{ row }">
|
||||||
|
<div class="row column full-width justify-between items-start">
|
||||||
|
{{ row?.item?.name }}
|
||||||
|
<div v-if="row?.item?.subName" class="subName">
|
||||||
|
{{ row?.item?.subName.toUpperCase() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FetchedTags :item="row" :max-length="6" />
|
||||||
|
<QPopupProxy v-if="row.id && isTicketEditable">
|
||||||
|
<VnInput v-model="row.concept" @change="updateConcept(row)" />
|
||||||
|
</QPopupProxy>
|
||||||
|
</template>
|
||||||
|
<template #column-quantity="{ row }">
|
||||||
|
<VnInput
|
||||||
|
v-if="row.isNew"
|
||||||
|
v-model.number="row.quantity"
|
||||||
|
type="number"
|
||||||
|
@blur="changeQuantity(row)"
|
||||||
|
@focus="edit.oldQuantity = row.quantity"
|
||||||
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-else-if="isTicketEditable"
|
||||||
|
v-model.number="row.quantity"
|
||||||
|
@blur="changeQuantity(row)"
|
||||||
|
@focus="edit.oldQuantity = row.quantity"
|
||||||
|
/>
|
||||||
|
<span v-else>{{ row.quantity }}</span>
|
||||||
|
</template>
|
||||||
|
<template #column-price="{ row }">
|
||||||
|
<template v-if="isTicketEditable && row.id">
|
||||||
|
<QBtn flat class="link" dense @click="onOpenEditPricePopover(row)">
|
||||||
|
{{ toCurrency(row.price) }}
|
||||||
|
</QBtn>
|
||||||
|
<TicketEditManaProxy
|
||||||
|
ref="editPriceProxyRef"
|
||||||
|
:mana="mana"
|
||||||
|
:new-price="getNewPrice"
|
||||||
|
@save="updatePrice(row)"
|
||||||
|
>
|
||||||
|
<VnInput
|
||||||
|
v-model.number="edit.price"
|
||||||
|
:label="t('ticketSale.price')"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TicketEditManaProxy>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ toCurrency(row.price) }}</span>
|
||||||
|
</template>
|
||||||
|
<template #column-discount="{ row }">
|
||||||
|
<template v-if="!isLocked && row.id">
|
||||||
|
<QBtn flat class="link" dense @click="onOpenEditDiscountPopover(row)">
|
||||||
|
{{ toPercentage(row.discount / 100) }}
|
||||||
|
</QBtn>
|
||||||
|
<TicketEditManaProxy
|
||||||
|
:mana="mana"
|
||||||
|
:new-price="getNewPrice"
|
||||||
|
@save="changeDiscount(row)"
|
||||||
|
>
|
||||||
|
<VnInput
|
||||||
|
v-model.number="edit.discount"
|
||||||
|
:label="t('ticketSale.discount')"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TicketEditManaProxy>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
||||||
|
</template>
|
||||||
|
<template #column-amount="{ row }">
|
||||||
|
{{ toCurrency(row.quantity * row.price) }}
|
||||||
|
</template>
|
||||||
|
</VnTable>
|
||||||
|
|
||||||
<QPageSticky :offset="[20, 20]">
|
<QPageSticky :offset="[20, 20]" style="z-index: 2">
|
||||||
<QBtn @click="newOrderFromTicket()" color="primary" fab icon="add" shortcut="+" />
|
<QBtn @click="newOrderFromTicket()" color="primary" fab icon="add" shortcut="+" />
|
||||||
<QTooltip class="text-no-wrap">
|
<QTooltip class="text-no-wrap">
|
||||||
{{ t('Add item to basket') }}
|
{{ t('Add item to basket') }}
|
||||||
|
@ -754,6 +800,18 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.image-wrapper {
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subName {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--vn-label-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
New item: Nuevo artículo
|
New item: Nuevo artículo
|
||||||
|
|
|
@ -25,7 +25,7 @@ const saleTrackingFetchDataRef = ref(null);
|
||||||
|
|
||||||
const sales = ref([]);
|
const sales = ref([]);
|
||||||
const saleTrackings = ref([]);
|
const saleTrackings = ref([]);
|
||||||
const itemShelvignsSales = ref([]);
|
const itemShelvingsSales = ref([]);
|
||||||
const saleTrackingUrl = computed(() => `SaleTrackings/${route.params.id}/filter`);
|
const saleTrackingUrl = computed(() => `SaleTrackings/${route.params.id}/filter`);
|
||||||
const oldQuantity = ref(null);
|
const oldQuantity = ref(null);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ const logTableColumns = computed(() => [
|
||||||
label: t('ticketSaleTracking.original'),
|
label: t('ticketSaleTracking.original'),
|
||||||
name: 'original',
|
name: 'original',
|
||||||
field: 'originalQuantity',
|
field: 'originalQuantity',
|
||||||
align: 'original',
|
align: 'left',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -177,7 +177,7 @@ const getItemShelvingSales = async (sale) => {
|
||||||
const { data } = await axios.get(`ItemShelvingSales/filter`, {
|
const { data } = await axios.get(`ItemShelvingSales/filter`, {
|
||||||
params: { filter: JSON.stringify(filter) },
|
params: { filter: JSON.stringify(filter) },
|
||||||
});
|
});
|
||||||
itemShelvignsSales.value = data;
|
itemShelvingsSales.value = data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
@ -337,7 +337,7 @@ const qCheckBoxController = (sale, action) => {
|
||||||
:no-data-label="t('globals.noResults')"
|
:no-data-label="t('globals.noResults')"
|
||||||
>
|
>
|
||||||
<template #body-cell-isChecked="{ row }">
|
<template #body-cell-isChecked="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop style="width: 20%">
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
:model-value="!!row.hasSaleGroupDetail"
|
:model-value="!!row.hasSaleGroupDetail"
|
||||||
color="pink"
|
color="pink"
|
||||||
|
@ -396,12 +396,14 @@ const qCheckBoxController = (sale, action) => {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-item="{ row }">
|
<template #body-cell-item="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop style="width: 20%">
|
||||||
<div>
|
<div>
|
||||||
<QBtn flat color="primary">
|
<span class="link">
|
||||||
{{ row.itemFk }}
|
<QBtn flat>
|
||||||
</QBtn>
|
{{ row.itemFk }}
|
||||||
<ItemDescriptorProxy :id="row.itemFk" />
|
</QBtn>
|
||||||
|
<ItemDescriptorProxy :id="row.itemFk" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
@ -416,8 +418,18 @@ const qCheckBoxController = (sale, action) => {
|
||||||
</div>
|
</div>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
<template #body-cell-quantity="{ row }">
|
||||||
|
<QTd style="width: 10%">
|
||||||
|
{{ row.quantity }}
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-parking="{ row }">
|
||||||
|
<QTd style="width: 10%">
|
||||||
|
{{ dashIfEmpty(row.parkingFk) }}
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
<template #body-cell-actions="{ row }">
|
<template #body-cell-actions="{ row }">
|
||||||
<QTd>
|
<QTd style="width: 20%">
|
||||||
<QBtn
|
<QBtn
|
||||||
@click.stop="showLog(row)"
|
@click.stop="showLog(row)"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -452,12 +464,14 @@ const qCheckBoxController = (sale, action) => {
|
||||||
data-key="saleTrackingLog"
|
data-key="saleTrackingLog"
|
||||||
:rows="saleTrackings"
|
:rows="saleTrackings"
|
||||||
:columns="logTableColumns"
|
:columns="logTableColumns"
|
||||||
class="q-pa-sm"
|
class="q-pa-sm full-width"
|
||||||
>
|
>
|
||||||
<template #body-cell-worker="{ row }">
|
<template #body-cell-worker="{ row }">
|
||||||
<QTd auto-width>
|
<QTd>
|
||||||
<QBtn flat dense color="primary">{{ row.name }}</QBtn>
|
<QBtn flat class="link">
|
||||||
<WorkerDescriptorProxy :id="row.workerFk" />
|
{{ row.name }}
|
||||||
|
<WorkerDescriptorProxy :id="row.workerFk" />
|
||||||
|
</QBtn>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
|
@ -469,12 +483,12 @@ const qCheckBoxController = (sale, action) => {
|
||||||
>
|
>
|
||||||
<QTable
|
<QTable
|
||||||
data-key="itemShelvingsSales"
|
data-key="itemShelvingsSales"
|
||||||
:rows="itemShelvignsSales"
|
:rows="itemShelvingsSales"
|
||||||
:columns="shelvingsTableColumns"
|
:columns="shelvingsTableColumns"
|
||||||
class="q-pa-sm"
|
class="q-pa-sm full-width"
|
||||||
>
|
>
|
||||||
<template #body-cell-quantity="{ row }">
|
<template #body-cell-quantity="{ row }">
|
||||||
<QTd auto-width>
|
<QTd>
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model.number="row.quantity"
|
v-model.number="row.quantity"
|
||||||
@keyup.enter="updateQuantity(row)"
|
@keyup.enter="updateQuantity(row)"
|
||||||
|
@ -484,13 +498,15 @@ const qCheckBoxController = (sale, action) => {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-worker="{ row }">
|
<template #body-cell-worker="{ row }">
|
||||||
<QTd auto-width>
|
<QTd>
|
||||||
<QBtn flat dense color="primary">{{ row.name }}</QBtn>
|
<QBtn flat class="link">
|
||||||
<WorkerDescriptorProxy :id="row.userFk" />
|
{{ row.name }}
|
||||||
|
<WorkerDescriptorProxy :id="row.userFk" />
|
||||||
|
</QBtn>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-shelving="{ row }">
|
<template #body-cell-shelving="{ row }">
|
||||||
<QTd auto-width>
|
<QTd>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
url="Shelvings"
|
url="Shelvings"
|
||||||
hide-selected
|
hide-selected
|
||||||
|
@ -503,7 +519,7 @@ const qCheckBoxController = (sale, action) => {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-parking="{ row }">
|
<template #body-cell-parking="{ row }">
|
||||||
<QTd auto-width>
|
<QTd>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
url="Parkings"
|
url="Parkings"
|
||||||
hide-selected
|
hide-selected
|
||||||
|
@ -538,4 +554,10 @@ $estados: (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 560px) {
|
||||||
|
.q-dialog__inner--minimized > div {
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -25,7 +25,7 @@ const { notify } = useNotify();
|
||||||
|
|
||||||
const selected = ref([]);
|
const selected = ref([]);
|
||||||
const defaultTaxClass = ref(null);
|
const defaultTaxClass = ref(null);
|
||||||
|
const isSaving = ref(false);
|
||||||
const crudModelFilter = computed(() => ({
|
const crudModelFilter = computed(() => ({
|
||||||
where: { ticketFk: route.params.id },
|
where: { ticketFk: route.params.id },
|
||||||
}));
|
}));
|
||||||
|
@ -50,7 +50,7 @@ const createRefund = async () => {
|
||||||
if (!selected.value.length) return;
|
if (!selected.value.length) return;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
servicesIds: selected.value.map((s) => +s.ticketFk),
|
servicesIds: selected.value.map((s) => +s.id),
|
||||||
withWarehouse: false,
|
withWarehouse: false,
|
||||||
negative: true,
|
negative: true,
|
||||||
};
|
};
|
||||||
|
@ -104,7 +104,31 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
name: 'actions',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
async function deleteService(row) {
|
||||||
|
const serviceId = row.id;
|
||||||
jon marked this conversation as resolved
jsegarra
commented
Mmm..si le doy al mas, pero luego le doy al delete no tengo id. Mmm..si le doy al mas, pero luego le doy al delete no tengo id.
Salta error porque ejecuta peticion de axios cuando deberia eliminar de la tabla, no?
|
|||||||
|
if (!row.id) ticketServiceCrudRef.value.reset();
|
||||||
|
else {
|
||||||
|
const { data } = await axios.delete(`TicketServices/${serviceId}`);
|
||||||
|
if (data) notify('Service deleted successfully', 'positive');
|
||||||
|
ticketServiceCrudRef.value.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSave() {
|
||||||
|
if (!isSaving.value) {
|
||||||
|
isSaving.value = true;
|
||||||
|
await ticketServiceCrudRef.value?.saveChanges();
|
||||||
|
isSaving.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -123,6 +147,8 @@ const columns = computed(() => [
|
||||||
:data-required="crudModelRequiredData"
|
:data-required="crudModelRequiredData"
|
||||||
auto-load
|
auto-load
|
||||||
v-model:selected="selected"
|
v-model:selected="selected"
|
||||||
|
:order="['description ASC']"
|
||||||
|
:default-remove="false"
|
||||||
>
|
>
|
||||||
<template #moreBeforeActions>
|
<template #moreBeforeActions>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
@ -177,9 +203,25 @@ const columns = computed(() => [
|
||||||
v-model.number="row.price"
|
v-model.number="row.price"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
|
@keyup.enter="handleSave"
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
<template #body-cell-actions="{ row }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<QIcon
|
||||||
|
color="primary"
|
||||||
|
name="delete"
|
||||||
|
class="cursor-pointer"
|
||||||
|
size="sm"
|
||||||
|
@click.stop="deleteService(row)"
|
||||||
|
>
|
||||||
|
<QTooltip class="text-no-wrap">
|
||||||
|
{{ t('globals.delete') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
</template>
|
</template>
|
||||||
</CrudModel>
|
</CrudModel>
|
||||||
|
@ -193,3 +235,4 @@ const columns = computed(() => [
|
||||||
/>
|
/>
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
</template>
|
</template>
|
||||||
|
ñ
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import RouteDescriptorProxy from 'pages/Route/Card/RouteDescriptorProxy.vue';
|
||||||
import { onMounted, ref, computed } from 'vue';
|
import { onMounted, ref, computed } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
@ -14,6 +15,8 @@ import { getUrl } from 'src/composables/getUrl';
|
||||||
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
|
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -71,13 +74,41 @@ async function changeState(value) {
|
||||||
await axios.post(`Tickets/state`, formData);
|
await axios.post(`Tickets/state`, formData);
|
||||||
router.go(route.fullPath);
|
router.go(route.fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNoteValue(description) {
|
||||||
|
switch (description) {
|
||||||
|
case 'ItemPicker':
|
||||||
|
return t('ItemPicker');
|
||||||
|
case 'Packager':
|
||||||
|
return t('Packager');
|
||||||
|
case 'Delivery':
|
||||||
|
return t('Delivery');
|
||||||
|
case 'SalesPerson':
|
||||||
|
return t('SalesPerson');
|
||||||
|
case 'Administrative':
|
||||||
|
return t('Administrative');
|
||||||
|
case 'Weight':
|
||||||
|
return t('Weight');
|
||||||
|
case 'InvoiceOut':
|
||||||
|
return t('InvoiceOut');
|
||||||
|
case 'DropOff':
|
||||||
|
return t('DropOff');
|
||||||
|
case 'Sustitución':
|
||||||
|
return t('Sustitución');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toTicketUrl(section) {
|
||||||
|
return '#/ticket/' + entityId.value + '/' + section;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
url="States/editableStates"
|
url="States/editableStates"
|
||||||
@on-fetch="(data) => (editableStates = data)"
|
:filter="{ fields: ['code', 'name', 'id', 'alertLevel'], order: 'name ASC' }"
|
||||||
auto-load
|
auto-load
|
||||||
|
@on-fetch="(data) => (editableStates = data)"
|
||||||
/>
|
/>
|
||||||
<CardSummary
|
<CardSummary
|
||||||
ref="summaryRef"
|
ref="summaryRef"
|
||||||
|
@ -94,46 +125,36 @@ async function changeState(value) {
|
||||||
</template>
|
</template>
|
||||||
<template #header-right>
|
<template #header-right>
|
||||||
<QBtnDropdown
|
<QBtnDropdown
|
||||||
side
|
|
||||||
top
|
|
||||||
color="black"
|
color="black"
|
||||||
text-color="white"
|
text-color="white"
|
||||||
:label="t('ticket.summary.changeState')"
|
:label="t('ticket.summary.changeState')"
|
||||||
:disable="!isEditable()"
|
:disable="!isEditable()"
|
||||||
>
|
>
|
||||||
<QList>
|
<VnSelect
|
||||||
<QVirtualScroll
|
:options="editableStates"
|
||||||
style="max-height: 300px"
|
hide-selected
|
||||||
:items="editableStates"
|
option-label="name"
|
||||||
separator
|
option-value="code"
|
||||||
v-slot="{ item, index }"
|
hide-dropdown-icon
|
||||||
>
|
focus-on-mount
|
||||||
<QItem
|
@update:model-value="changeState(item.code)"
|
||||||
:key="index"
|
/>
|
||||||
dense
|
|
||||||
clickable
|
|
||||||
v-close-popup
|
|
||||||
@click="changeState(item.code)"
|
|
||||||
>
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel>{{ item.name }}</QItemLabel>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</QVirtualScroll>
|
|
||||||
</QList>
|
|
||||||
</QBtnDropdown>
|
</QBtnDropdown>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="ticketUrl + 'basic-data/step-one'"
|
:url="toTicketUrl('basic-data')"
|
||||||
:text="t('globals.summary.basicData')"
|
:text="t('globals.summary.basicData')"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('ticket.summary.state')">
|
<VnLv v-if="entity.ticketState" :label="t('ticket.summary.state')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<QChip :color="entity.ticketState?.state?.classColor ?? 'dark'">
|
<QBadge
|
||||||
{{ entity.ticketState?.state?.name }}
|
text-color="black"
|
||||||
</QChip>
|
:color="entity.ticketState.state.classColor"
|
||||||
|
>
|
||||||
|
{{ entity.ticketState.state.name }}
|
||||||
|
</QBadge>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :label="t('ticket.summary.salesPerson')">
|
<VnLv :label="t('ticket.summary.salesPerson')">
|
||||||
|
@ -148,7 +169,14 @@ async function changeState(value) {
|
||||||
:label="t('ticket.summary.agency')"
|
:label="t('ticket.summary.agency')"
|
||||||
:value="entity.agencyMode?.name"
|
:value="entity.agencyMode?.name"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('ticket.summary.zone')" :value="entity?.zone?.name" />
|
<VnLv :label="t('ticket.summary.zone')">
|
||||||
|
<template #value>
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ entity?.zone?.name }}
|
||||||
|
<ZoneDescriptorProxy :id="entity.zoneFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</VnLv>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('ticket.summary.warehouse')"
|
:label="t('ticket.summary.warehouse')"
|
||||||
:value="entity.warehouse?.name"
|
:value="entity.warehouse?.name"
|
||||||
|
@ -168,7 +196,14 @@ async function changeState(value) {
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :label="t('ticket.summary.route')" :value="entity.routeFk" />
|
<VnLv :label="t('ticket.summary.route')">
|
||||||
|
<template #value>
|
||||||
|
<span class="link">
|
||||||
|
{{ entity.routeFk }}
|
||||||
|
<RouteDescriptorProxy :id="entity.routeFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</VnLv>
|
||||||
<VnLv :label="t('ticket.summary.invoice')">
|
<VnLv :label="t('ticket.summary.invoice')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<span :class="{ link: entity.refFk }">
|
<span :class="{ link: entity.refFk }">
|
||||||
|
@ -185,9 +220,9 @@ async function changeState(value) {
|
||||||
:value="dashIfEmpty(entity.weight)"
|
:value="dashIfEmpty(entity.weight)"
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one" style="flex: 2 1">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="ticketUrl + 'basic-data/step-one'"
|
:url="toTicketUrl('basic-data')"
|
||||||
:text="t('globals.summary.basicData')"
|
:text="t('globals.summary.basicData')"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
|
@ -230,13 +265,13 @@ async function changeState(value) {
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one" v-if="entity.notes.length">
|
<QCard class="vn-one" v-if="entity.notes.length">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="ticketUrl + 'observation'"
|
:url="toTicketUrl('observation')"
|
||||||
:text="t('ticket.pageTitles.notes')"
|
:text="t('ticket.pageTitles.notes')"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
v-for="note in entity.notes"
|
v-for="note in entity.notes"
|
||||||
:key="note.id"
|
:key="note.id"
|
||||||
:label="note.observationType.description"
|
:label="getNoteValue(note.observationType.description)"
|
||||||
:value="note.description"
|
:value="note.description"
|
||||||
>
|
>
|
||||||
<template #value>
|
<template #value>
|
||||||
|
@ -246,6 +281,7 @@ async function changeState(value) {
|
||||||
type="textarea"
|
type="textarea"
|
||||||
class="notes"
|
class="notes"
|
||||||
readonly
|
readonly
|
||||||
|
autogrow
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
|
@ -263,13 +299,14 @@ async function changeState(value) {
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('ticket.summary.total')"
|
:label="t('ticket.summary.total')"
|
||||||
:value="toCurrency(entity.totalWithVat)"
|
:value="toCurrency(ticket.totalWithVat)"
|
||||||
|
style="font-weight: bold"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-max">
|
<QCard class="vn-max">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="ticketUrl + 'sale'"
|
:url="toTicketUrl('sale')"
|
||||||
:text="t('ticket.summary.saleLines')"
|
:text="t('ticket.summary.saleLines')"
|
||||||
/>
|
/>
|
||||||
<QTable :rows="entity.sales" style="text-align: center">
|
<QTable :rows="entity.sales" style="text-align: center">
|
||||||
|
@ -292,11 +329,10 @@ async function changeState(value) {
|
||||||
</template>
|
</template>
|
||||||
<template #body="props">
|
<template #body="props">
|
||||||
<QTr :props="props">
|
<QTr :props="props">
|
||||||
<QTd>
|
<QTd class="q-gutter-x-xs">
|
||||||
<QBtn
|
<QBtn
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
size="xs"
|
|
||||||
icon="vn:claims"
|
icon="vn:claims"
|
||||||
v-if="props.row.claim"
|
v-if="props.row.claim"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -307,15 +343,14 @@ async function changeState(value) {
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<QTooltip
|
<QTooltip>
|
||||||
>{{ t('ticket.summary.claim') }}:
|
{{ t('ticket.summary.claim') }}:
|
||||||
{{ props.row.claim.claimFk }}</QTooltip
|
{{ props.row.claim.claimFk }}
|
||||||
>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
size="xs"
|
|
||||||
icon="vn:claims"
|
icon="vn:claims"
|
||||||
v-if="props.row.claimBeginning"
|
v-if="props.row.claimBeginning"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -326,27 +361,27 @@ async function changeState(value) {
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<QTooltip
|
<QTooltip>
|
||||||
>{{ t('ticket.summary.claim') }}:
|
{{ t('ticket.summary.claim') }}:
|
||||||
{{ props.row.claimBeginning.claimFk }}</QTooltip
|
{{ props.row.claimBeginning.claimFk }}
|
||||||
>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QIcon
|
<QIcon
|
||||||
name="warning"
|
name="warning"
|
||||||
v-show="props.row.visible < 0"
|
v-show="props.row.visible < 0"
|
||||||
size="xs"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip
|
<QTooltip>
|
||||||
>{{ t('ticket.summary.visible') }}:
|
{{ t('ticket.summary.visible') }}:
|
||||||
{{ props.row.visible }}</QTooltip
|
{{ props.row.visible }}
|
||||||
>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
name="vn:reserva"
|
name="vn:reserved"
|
||||||
v-show="props.row.reserved"
|
v-show="props.row.reserved"
|
||||||
size="xs"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('ticket.summary.reserved') }}
|
{{ t('ticket.summary.reserved') }}
|
||||||
|
@ -355,8 +390,8 @@ async function changeState(value) {
|
||||||
<QIcon
|
<QIcon
|
||||||
name="vn:unavailable"
|
name="vn:unavailable"
|
||||||
v-show="props.row.itemShortage"
|
v-show="props.row.itemShortage"
|
||||||
size="xs"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('ticket.summary.itemShortage') }}
|
{{ t('ticket.summary.itemShortage') }}
|
||||||
|
@ -365,8 +400,8 @@ async function changeState(value) {
|
||||||
<QIcon
|
<QIcon
|
||||||
name="vn:components"
|
name="vn:components"
|
||||||
v-show="props.row.hasComponentLack"
|
v-show="props.row.hasComponentLack"
|
||||||
size="xs"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('ticket.summary.hasComponentLack') }}
|
{{ t('ticket.summary.hasComponentLack') }}
|
||||||
|
@ -383,8 +418,34 @@ async function changeState(value) {
|
||||||
/>
|
/>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QTd>
|
</QTd>
|
||||||
<QTd>{{ props.row.visible }}</QTd>
|
<QTd>
|
||||||
<QTd>{{ props.row.available }}</QTd>
|
<QChip
|
||||||
|
v-if="props.row.visible < 0"
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
:color="'negative'"
|
||||||
|
text-color="white"
|
||||||
|
>
|
||||||
|
{{ props.row.visible }}
|
||||||
|
</QChip>
|
||||||
|
<span v-else>
|
||||||
|
{{ props.row.visible }}
|
||||||
|
</span>
|
||||||
|
</QTd>
|
||||||
|
<QTd>
|
||||||
|
<QChip
|
||||||
|
v-if="props.row.available < 0"
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
:color="'negative'"
|
||||||
|
text-color="white"
|
||||||
|
>
|
||||||
|
{{ props.row.available }}
|
||||||
|
</QChip>
|
||||||
|
<span v-else>
|
||||||
|
{{ props.row.available }}
|
||||||
|
</span>
|
||||||
|
</QTd>
|
||||||
<QTd>{{ props.row.quantity }}</QTd>
|
<QTd>{{ props.row.quantity }}</QTd>
|
||||||
<QTd class="description-cell">
|
<QTd class="description-cell">
|
||||||
<div class="row full-width justify-between">
|
<div class="row full-width justify-between">
|
||||||
|
@ -414,14 +475,11 @@ async function changeState(value) {
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard
|
<QCard class="vn-max" v-if="ticket.packagings.length != 0">
|
||||||
class="vn-max"
|
<VnTitle :url="toTicketUrl('package')" :text="t('globals.packages')" />
|
||||||
v-if="entity.packagings.length || entity.services.length"
|
<QTable :rows="ticket.packagings" flat style="text-align: center">
|
||||||
>
|
|
||||||
<VnTitle :url="ticketUrl + 'package'" :text="t('globals.packages')" />
|
|
||||||
<QTable :rows="entity.packagings" flat>
|
|
||||||
<template #header="props">
|
<template #header="props">
|
||||||
<QTr :props="props">
|
<QTr class="tr-header" :props="props">
|
||||||
<QTh auto-width>{{ t('ticket.summary.created') }}</QTh>
|
<QTh auto-width>{{ t('ticket.summary.created') }}</QTh>
|
||||||
<QTh auto-width>{{ t('ticket.summary.package') }}</QTh>
|
<QTh auto-width>{{ t('ticket.summary.package') }}</QTh>
|
||||||
<QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
|
<QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
|
||||||
|
@ -435,13 +493,15 @@ async function changeState(value) {
|
||||||
</QTr>
|
</QTr>
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
|
</QCard>
|
||||||
|
<QCard class="vn-max" v-if="ticket.services.length != 0">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="ticketUrl + 'service'"
|
:url="toTicketUrl('service')"
|
||||||
:text="t('ticket.summary.service')"
|
:text="t('ticket.summary.service')"
|
||||||
/>
|
/>
|
||||||
<QTable :rows="entity.services" flat>
|
<QTable :rows="ticket.services" flat style="text-align: center">
|
||||||
<template #header="props">
|
<template #header="props">
|
||||||
<QTr :props="props">
|
<QTr class="tr-header" :props="props">
|
||||||
<QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
|
<QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
|
||||||
<QTh auto-width>{{ t('globals.description') }}</QTh>
|
<QTh auto-width>{{ t('globals.description') }}</QTh>
|
||||||
<QTh auto-width>{{ t('ticket.summary.price') }}</QTh>
|
<QTh auto-width>{{ t('ticket.summary.price') }}</QTh>
|
||||||
|
@ -462,12 +522,62 @@ async function changeState(value) {
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
<QCard class="vn-max" v-if="ticket.requests.length != 0">
|
||||||
|
<VnTitle
|
||||||
|
:url="toTicketUrl('request')"
|
||||||
|
:text="t('ticket.summary.purchaseRequest')"
|
||||||
|
/>
|
||||||
|
<QTable :rows="ticket.requests" flat style="text-align: center">
|
||||||
|
<template #header="props">
|
||||||
|
<QTr class="tr-header" :props="props">
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.description') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.created') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.requester') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.attender') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.price') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.item') }}</QTh>
|
||||||
|
<QTh auto-width>{{ t('ticket.summary.ok') }}</QTh>
|
||||||
|
</QTr>
|
||||||
|
</template>
|
||||||
|
<template #body="props">
|
||||||
|
<QTr :props="props">
|
||||||
|
<QTd>{{ props.row.description }}</QTd>
|
||||||
|
<QTd>{{ toDate(props.row.created) }}</QTd>
|
||||||
|
<QTd>{{ props.row.requester?.user?.username }}</QTd>
|
||||||
|
<QTd>{{ props.row.atender?.user?.username }}</QTd>
|
||||||
|
<QTd>{{ props.row.quantity }}</QTd>
|
||||||
|
<QTd>{{ toCurrency(props.row.price) }}</QTd>
|
||||||
|
<QTd>
|
||||||
|
<span class="link" v-if="props.row.isOk">
|
||||||
|
{{ props.row.itemFk }}
|
||||||
|
<ItemDescriptorProxy :id="props.row.itemFk" />
|
||||||
|
</span>
|
||||||
|
</QTd>
|
||||||
|
<QTd>
|
||||||
|
<QCheckbox
|
||||||
|
v-model="props.row.isOk"
|
||||||
|
disable
|
||||||
|
:toggle-indeterminate="false"
|
||||||
|
>
|
||||||
|
<QTooltip v-if="props.row.isOk">
|
||||||
|
{{ t('Accepted') }}
|
||||||
|
</QTooltip>
|
||||||
|
<QTooltip v-else>
|
||||||
|
{{ t('Denied') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QCheckbox>
|
||||||
|
</QTd>
|
||||||
|
</QTr>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</QCard>
|
||||||
</template>
|
</template>
|
||||||
</CardSummary>
|
</CardSummary>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.notes {
|
.notes {
|
||||||
width: max-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-card.q-card--dark.q-dark.vn-one {
|
.q-card.q-card--dark.q-dark.vn-one {
|
||||||
|
@ -503,3 +613,28 @@ async function changeState(value) {
|
||||||
color: $primary-light;
|
color: $primary-light;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
en:
|
||||||
|
ItemPicker: Item Picker
|
||||||
|
Packager: Packager
|
||||||
|
Delivery: Delivery
|
||||||
|
SalesPerson: Sales Person
|
||||||
|
Administrative: Administrative
|
||||||
|
Weight: Weight
|
||||||
|
InvoiceOut: Invoice Out
|
||||||
|
DropOff: Drop Off
|
||||||
|
Sustitución: Sustitution
|
||||||
|
es:
|
||||||
|
ItemPicker: Items
|
||||||
|
Packager: Encajador
|
||||||
|
Delivery: Envío
|
||||||
|
SalesPerson: Comercial
|
||||||
|
Administrative: Administrativa
|
||||||
|
Weight: Peso
|
||||||
|
InvoiceOut: Facturas
|
||||||
|
DropOff: Despacho
|
||||||
|
Sustitución: Sustitución
|
||||||
|
Accepted: Aceptado
|
||||||
|
Denied: Denegado
|
||||||
|
</i18n>
|
||||||
|
|
|
@ -96,8 +96,8 @@ const openCreateModal = () => createTrackingDialogRef.value.show();
|
||||||
:no-data-label="t('globals.noResults')"
|
:no-data-label="t('globals.noResults')"
|
||||||
>
|
>
|
||||||
<template #body-cell-worker="{ row }">
|
<template #body-cell-worker="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd>
|
||||||
jsegarra
commented
Aqui habia un cambio con respecto al orden de los filtros. Seguro que jorge sabe donde se hace porque lo hizo para InvoiceInSummary Aqui habia un cambio con respecto al orden de los filtros. Seguro que jorge sabe donde se hace porque lo hizo para InvoiceInSummary
|
|||||||
<QBtn flat color="primary">
|
<QBtn flat class="link" @click.stop>
|
||||||
{{ row.user?.name }}
|
{{ row.user?.name }}
|
||||||
<WorkerDescriptorProxy :id="row.user?.worker?.id" />
|
<WorkerDescriptorProxy :id="row.user?.worker?.id" />
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import TicketTransferForm from './TicketTransferForm.vue';
|
import TicketTransferForm from './TicketTransferForm.vue';
|
||||||
|
|
||||||
import { toDateFormat } from 'src/filters/date.js';
|
import { toDateFormat } from 'src/filters/date.js';
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
mana: {
|
mana: {
|
||||||
|
@ -28,13 +26,10 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['refreshData']);
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const QPopupProxyRef = ref(null);
|
const QPopupProxyRef = ref(null);
|
||||||
|
const transferFormRef = ref(null);
|
||||||
const _transfer = ref(null);
|
const _transfer = ref();
|
||||||
|
|
||||||
const transferLinesColumns = computed(() => [
|
const transferLinesColumns = computed(() => [
|
||||||
{
|
{
|
||||||
|
@ -85,19 +80,11 @@ const destinationTicketColumns = computed(() => [
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const transferSales = async (ticketId) => {
|
const handleRowClick = (row) => {
|
||||||
const params = {
|
const ticketId = row.id;
|
||||||
ticketId: ticketId,
|
if (transferFormRef.value) {
|
||||||
sales: $props.transfer.sales,
|
transferFormRef.value.transferSales(ticketId);
|
||||||
};
|
}
|
||||||
|
|
||||||
const { data } = await axios.post(
|
|
||||||
`tickets/${$props.ticket.id}/transferSales`,
|
|
||||||
params
|
|
||||||
);
|
|
||||||
|
|
||||||
if (data && data.id === $props.ticket.id) emit('refreshData');
|
|
||||||
else router.push({ name: 'TicketSale', params: { id: data.id } });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => (_transfer.value = $props.transfer));
|
onMounted(() => (_transfer.value = $props.transfer));
|
||||||
|
@ -105,9 +92,8 @@ onMounted(() => (_transfer.value = $props.transfer));
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy ref="QPopupProxyRef">
|
<QPopupProxy ref="QPopupProxyRef">
|
||||||
<QCard class="q-px-md" style="display: flex">
|
<QCard class="q-px-md" style="display: flex; width: 80vw">
|
||||||
<QTable
|
<QTable
|
||||||
v-if="transfer.sales"
|
|
||||||
:rows="transfer.sales"
|
:rows="transfer.sales"
|
||||||
:columns="transferLinesColumns"
|
:columns="transferLinesColumns"
|
||||||
:title="t('Sales to transfer')"
|
:title="t('Sales to transfer')"
|
||||||
|
@ -121,9 +107,6 @@ onMounted(() => (_transfer.value = $props.transfer));
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model.number="row.quantity"
|
v-model.number="row.quantity"
|
||||||
:clearable="false"
|
:clearable="false"
|
||||||
@keyup.enter="changeQuantity(row)"
|
|
||||||
@blur="changeQuantity(row)"
|
|
||||||
@focus="edit.oldQuantity = row.quantity"
|
|
||||||
style="max-width: 60px"
|
style="max-width: 60px"
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
|
@ -137,6 +120,7 @@ onMounted(() => (_transfer.value = $props.transfer));
|
||||||
:title="t('Destination ticket')"
|
:title="t('Destination ticket')"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
class="full-width q-mt-md"
|
class="full-width q-mt-md"
|
||||||
|
@row-click="(_, row) => handleRowClick(row)"
|
||||||
>
|
>
|
||||||
<template #body-cell-address="{ row }">
|
<template #body-cell-address="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop>
|
||||||
|
@ -158,10 +142,10 @@ onMounted(() => (_transfer.value = $props.transfer));
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #no-data>
|
<template #no-data>
|
||||||
<TicketTransferForm v-bind="$props" />
|
<TicketTransferForm ref="transferFormRef" v-bind="$props" />
|
||||||
</template>
|
</template>
|
||||||
<template #bottom>
|
<template #bottom>
|
||||||
<TicketTransferForm v-bind="$props" />
|
<TicketTransferForm ref="transferFormRef" v-bind="$props" />
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ const emit = defineEmits(['refreshData']);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const _transfer = ref(null);
|
const _transfer = ref($props.transfer);
|
||||||
|
|
||||||
const transferSales = async (ticketId) => {
|
const transferSales = async (ticketId) => {
|
||||||
const params = {
|
const params = {
|
||||||
|
@ -48,11 +48,10 @@ const transferSales = async (ticketId) => {
|
||||||
else router.push({ name: 'TicketSale', params: { id: data.id } });
|
else router.push({ name: 'TicketSale', params: { id: data.id } });
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => (_transfer.value = $props.transfer));
|
defineExpose({ transferSales });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
{{ _transfer }}
|
|
||||||
<QForm class="q-mt-lg full-width">
|
<QForm class="q-mt-lg full-width">
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model.number="_transfer.ticketId"
|
v-model.number="_transfer.ticketId"
|
||||||
|
|
|
@ -5,17 +5,18 @@ import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import FetchedTags from 'components/ui/FetchedTags.vue';
|
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const salesRef = ref(null);
|
const salesRef = ref(null);
|
||||||
|
const tableRef = ref();
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
|
@ -34,37 +35,42 @@ const salesFilter = computed(() => ({
|
||||||
|
|
||||||
const sales = ref([]);
|
const sales = ref([]);
|
||||||
const packingTypeVolume = ref([]);
|
const packingTypeVolume = ref([]);
|
||||||
const rows = computed(() => sales.value);
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('volume.item'),
|
label: t('volume.item'),
|
||||||
name: 'item',
|
name: 'itemFk',
|
||||||
align: 'left',
|
chip: {
|
||||||
|
condition: () => true,
|
||||||
|
},
|
||||||
|
isId: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('volume.description'),
|
label: t('volume.description'),
|
||||||
name: 'description',
|
name: 'concept',
|
||||||
align: 'left',
|
columnClass: 'expand',
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('volume.packingType'),
|
label: t('volume.packingType'),
|
||||||
name: 'quantity',
|
name: 'itemPackingTypeFk',
|
||||||
field: (row) => row.item.itemPackingTypeFk,
|
cardVisible: true,
|
||||||
align: 'left',
|
format: (row, dashIfEmpty) => dashIfEmpty(row.item.itemPackingTypeFk),
|
||||||
format: (val) => dashIfEmpty(val),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('volume.quantity'),
|
label: t('volume.quantity'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
field: 'quantity',
|
cardVisible: true,
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('volume.volumeQuantity'),
|
|
||||||
name: 'quantity',
|
|
||||||
field: (row) => row.saleVolume?.volume,
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
label: t('volume.volumeQuantity'),
|
||||||
|
name: 'volume',
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -87,9 +93,7 @@ const applyVolumes = async (salesData) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => (stateStore.rightDrawer = true));
|
||||||
stateStore.rightDrawer = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
</script>
|
</script>
|
||||||
|
@ -102,52 +106,55 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
@on-fetch="(data) => applyVolumes(data)"
|
@on-fetch="(data) => applyVolumes(data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<RightMenu v-if="packingTypeVolume.length">
|
<QDrawer
|
||||||
<template #right-panel>
|
v-if="packingTypeVolume.length"
|
||||||
<QCard
|
side="right"
|
||||||
v-for="(packingType, index) in packingTypeVolume"
|
:width="265"
|
||||||
:key="index"
|
v-model="stateStore.rightDrawer"
|
||||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
|
||||||
bordered
|
|
||||||
flat
|
|
||||||
style="border-color: black"
|
|
||||||
>
|
|
||||||
<QCardSection class="column items-center" horizontal>
|
|
||||||
<span>
|
|
||||||
{{ t('volume.type') }}:
|
|
||||||
{{ dashIfEmpty(packingType.description) }}
|
|
||||||
</span>
|
|
||||||
</QCardSection>
|
|
||||||
<QCardSection class="column items-center" horizontal>
|
|
||||||
<span> {{ t('volume.volume') }}: {{ packingType.volume }} </span>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<QTable
|
|
||||||
:rows="rows"
|
|
||||||
:columns="columns"
|
|
||||||
row-key="id"
|
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
|
||||||
class="full-width q-mt-md"
|
|
||||||
:no-data-label="t('globals.noResults')"
|
|
||||||
>
|
>
|
||||||
<template #body-cell-item="{ row }">
|
<QCard
|
||||||
<QTd>
|
v-for="(packingType, index) in packingTypeVolume"
|
||||||
<QBtn flat color="primary">
|
:key="index"
|
||||||
{{ row.itemFk }}
|
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||||
<ItemDescriptorProxy :id="row.itemFk" />
|
bordered
|
||||||
</QBtn>
|
flat
|
||||||
</QTd>
|
style="border-color: black"
|
||||||
|
>
|
||||||
|
<QCardSection class="column items-center" horizontal>
|
||||||
|
<span>
|
||||||
|
{{ t('volume.type') }}:
|
||||||
|
{{ dashIfEmpty(packingType.description) }}
|
||||||
|
</span>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection class="column items-center" horizontal>
|
||||||
|
<span> {{ t('volume.volume') }}: {{ packingType.volume }} </span>
|
||||||
|
</QCardSection>
|
||||||
|
</QCard>
|
||||||
|
</QDrawer>
|
||||||
|
|
||||||
|
<VnTable
|
||||||
|
ref="tableRef"
|
||||||
|
data-key="TicketVolume"
|
||||||
|
:url="`Tickets/${route.params.id}/getSales`"
|
||||||
|
:columns="columns"
|
||||||
|
:right-search="false"
|
||||||
|
:column-search="false"
|
||||||
|
:order="['itemPackingTypeFk']"
|
||||||
|
auto-load
|
||||||
|
>
|
||||||
|
<template #column-itemFk="{ row }">
|
||||||
|
<span class="link">
|
||||||
|
{{ row.itemFk }}
|
||||||
|
<ItemDescriptorProxy :id="row.itemFk" />
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-description="{ row }">
|
<template #column-concept="{ row }">
|
||||||
<QTd>
|
<span>{{ row.item.name }}</span>
|
||||||
<div class="column">
|
<span class="color-vn-label q-pl-md">{{ row.item.subName }}</span>
|
||||||
<span>{{ row.item.name }}</span>
|
<FetchedTags :item="row.item" />
|
||||||
<span class="color-vn-label">{{ row.item.subName }}</span>
|
|
||||||
<FetchedTags :item="row.item" />
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
<template #column-volume="{ rowIndex }">
|
||||||
|
<span>{{ packingTypeVolume?.[rowIndex]?.volume }}</span>
|
||||||
|
</template>
|
||||||
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -456,11 +456,12 @@ const handleCloseProgressDialog = () => {
|
||||||
const handleCancelProgress = () => (cancelProgress.value = true);
|
const handleCancelProgress = () => (cancelProgress.value = true);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
let today = Date.vnNew().toISOString();
|
let today = Date.vnNew();
|
||||||
const tomorrow = new Date(today);
|
const tomorrow = new Date(today);
|
||||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||||
userParams.dateFuture = tomorrow;
|
userParams.dateFuture = tomorrow;
|
||||||
userParams.dateToAdvance = today;
|
userParams.dateToAdvance = today;
|
||||||
|
userParams.scopeDays = 1;
|
||||||
userParams.warehouseFk = user.value.warehouseFk;
|
userParams.warehouseFk = user.value.warehouseFk;
|
||||||
const filter = { limit: 0 };
|
const filter = { limit: 0 };
|
||||||
await arrayData.addFilter({ filter, userParams });
|
await arrayData.addFilter({ filter, userParams });
|
||||||
|
@ -550,6 +551,7 @@ onMounted(async () => {
|
||||||
style="max-width: 99%"
|
style="max-width: 99%"
|
||||||
>
|
>
|
||||||
<template #header="props">
|
<template #header="props">
|
||||||
|
{{ userParams.scopeDays }}
|
||||||
<QTr :props="props">
|
<QTr :props="props">
|
||||||
<QTh
|
<QTh
|
||||||
class="horizontal-separator text-uppercase color-vn-label"
|
class="horizontal-separator text-uppercase color-vn-label"
|
||||||
|
|
|
@ -9,6 +9,7 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -116,6 +117,15 @@ onMounted(async () => await getItemPackingTypes());
|
||||||
</VnSelect>
|
</VnSelect>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnInputNumber
|
||||||
|
v-model="params.scopeDays"
|
||||||
|
:label="t('Days onward')"
|
||||||
|
is-outlined
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
|
|
|
@ -115,6 +115,15 @@ const warehouses = ref([]);
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnInput
|
||||||
|
v-model="params.scopeDays"
|
||||||
|
:label="t('Days onward')"
|
||||||
|
is-outlined
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
|
@ -278,4 +287,5 @@ es:
|
||||||
Warehouse: Almacén
|
Warehouse: Almacén
|
||||||
Yes: Si
|
Yes: Si
|
||||||
No: No
|
No: No
|
||||||
|
Days onward: Días adelante
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -4,7 +4,9 @@ import { computed, ref, onMounted } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { toDate, toCurrency } from 'src/filters/index';
|
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 TicketSummary from './Card/TicketSummary.vue';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
|
@ -14,11 +16,19 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import VnRow from 'src/components/ui/VnRow.vue';
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
import TicketFilter from './TicketFilter.vue';
|
import TicketFilter from './TicketFilter.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
|
import ZoneDescriptorProxy from '../Zone/Card/ZoneDescriptorProxy.vue';
|
||||||
|
import { toTimeFormat } from 'src/filters/date';
|
||||||
|
import InvoiceOutDescriptorProxy from '../InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
const quasar = useQuasar();
|
||||||
|
const { notify } = useNotify();
|
||||||
const clientsOptions = ref([]);
|
const clientsOptions = ref([]);
|
||||||
const addressesOptions = ref([]);
|
const addressesOptions = ref([]);
|
||||||
const agenciesOptions = ref([]);
|
const agenciesOptions = ref([]);
|
||||||
|
@ -26,6 +36,7 @@ const selectedClient = ref();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const from = Date.vnNew();
|
const from = Date.vnNew();
|
||||||
from.setHours(0, 0, 0, 0);
|
from.setHours(0, 0, 0, 0);
|
||||||
|
from.setDate(from.getDate() - 7);
|
||||||
const to = Date.vnNew();
|
const to = Date.vnNew();
|
||||||
to.setHours(23, 59, 0, 0);
|
to.setHours(23, 59, 0, 0);
|
||||||
to.setDate(to.getDate() + 1);
|
to.setDate(to.getDate() + 1);
|
||||||
|
@ -44,19 +55,21 @@ const initializeFromQuery = () => {
|
||||||
Object.assign(userParams, { from, to });
|
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 columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'stateFk',
|
name: 'statusIcons',
|
||||||
label: t('ticketList.state'),
|
hidden: true,
|
||||||
columnFilter: {
|
format: () => '',
|
||||||
name: 'stateFk',
|
columnClass: 'expand',
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'States',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -67,40 +80,6 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
isId: true,
|
isId: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'nickname',
|
|
||||||
label: t('ticketList.nickname'),
|
|
||||||
isTitle: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'shipped',
|
|
||||||
cardVisible: true,
|
|
||||||
label: t('ticketList.shipped'),
|
|
||||||
columnFilter: {
|
|
||||||
component: 'date',
|
|
||||||
alias: 't',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
format: ({ shipped }) => toDate(shipped),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'zoneFk',
|
|
||||||
label: t('ticketList.zone'),
|
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'Zones',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
},
|
|
||||||
alias: 't',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.zoneName),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('ticketList.salesPerson'),
|
label: t('ticketList.salesPerson'),
|
||||||
|
@ -118,6 +97,89 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'shippedDate',
|
||||||
|
cardVisible: true,
|
||||||
|
label: t('ticketList.shipped'),
|
||||||
|
columnFilter: {
|
||||||
|
component: 'date',
|
||||||
|
alias: 't',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: ({ shippedDate }) => toDate(shippedDate),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'shipped',
|
||||||
|
label: t('ticketList.hour'),
|
||||||
|
format: (row) => toTimeFormat(row.shipped),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'zoneLanding',
|
||||||
|
label: t('ticketList.closure'),
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(toTimeFormat(row.zoneLanding)),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'nickname',
|
||||||
|
label: t('ticketList.nickname'),
|
||||||
|
columnClass: 'expand',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'addressNickname',
|
||||||
|
label: t('ticketList.addressNickname'),
|
||||||
|
columnClass: 'expand',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'province',
|
||||||
|
label: t('ticketList.province'),
|
||||||
|
columnClass: 'expand',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'stateFk',
|
||||||
|
label: t('ticketList.state'),
|
||||||
|
columnFilter: {
|
||||||
|
name: 'stateFk',
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'States',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columnClass: 'expand',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'refFk',
|
||||||
|
label: t('ticketList.ref'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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: 'warehouse',
|
||||||
|
label: t('ticketList.warehouse'),
|
||||||
|
columnClass: 'expand',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'totalWithVat',
|
name: 'totalWithVat',
|
||||||
|
@ -133,15 +195,27 @@ const columns = computed(() => [
|
||||||
align: 'right',
|
align: 'right',
|
||||||
name: 'tableActions',
|
name: 'tableActions',
|
||||||
actions: [
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('ticketList.toLines'),
|
||||||
|
icon: 'list',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => redirectToLines(row.id),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('ticketList.summary'),
|
title: t('ticketList.summary'),
|
||||||
icon: 'preview',
|
icon: 'preview',
|
||||||
|
isPrimary: true,
|
||||||
action: (row) => viewSummary(row.id, TicketSummary),
|
action: (row) => viewSummary(row.id, TicketSummary),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
function redirectToLines(id) {
|
||||||
|
const url = `#/ticket/${id}/sale`;
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
const onClientSelected = async (formData) => {
|
const onClientSelected = async (formData) => {
|
||||||
await fetchClient(formData);
|
await fetchClient(formData);
|
||||||
await fetchAddresses(formData);
|
await fetchAddresses(formData);
|
||||||
|
@ -210,16 +284,174 @@ const fetchAddresses = async (formData) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const getColor = (row) => {
|
const getColor = (row) => {
|
||||||
return row?.classColor ? `bg-${row.classColor}` : 'bg-orange';
|
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';
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initializeFromQuery();
|
initializeFromQuery();
|
||||||
stateStore.rightDrawer = true;
|
stateStore.rightDrawer = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<FetchData
|
||||||
|
url="Companies"
|
||||||
|
@on-fetch="(data) => (companiesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
url="Accountings"
|
||||||
|
@on-fetch="(data) => (accountingOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
<VnSearchbar
|
<VnSearchbar
|
||||||
data-key="Ticket"
|
data-key="Ticket"
|
||||||
:label="t('Search ticket')"
|
:label="t('Search ticket')"
|
||||||
|
@ -246,12 +478,136 @@ onMounted(() => {
|
||||||
:user-params="userParams"
|
:user-params="userParams"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
redirect="ticket"
|
redirect="ticket"
|
||||||
auto-load
|
v-model:selected="selectedRows"
|
||||||
|
:table="{
|
||||||
|
'row-key': 'id',
|
||||||
|
selection: 'multiple',
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
|
<template #column-statusIcons="{ row }">
|
||||||
|
<div class="q-gutter-x-xs">
|
||||||
|
<QIcon
|
||||||
|
v-if="row.isTaxDataChecked === 0"
|
||||||
|
color="primary"
|
||||||
|
name="vn:no036"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('No verified data') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.hasTicketRequest"
|
||||||
|
color="primary"
|
||||||
|
name="vn:buyrequest"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Purchase request') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.itemShortage"
|
||||||
|
color="primary"
|
||||||
|
name="vn:unavailable"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Not visible') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.isFreezed" color="primary" name="vn:frozen" size="xs">
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Client frozen') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
|
||||||
|
<QTooltip> {{ t('Risk') }}: {{ row.risk }} </QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.hasComponentLack"
|
||||||
|
color="primary"
|
||||||
|
name="vn:components"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Component lack') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.hasRounding"
|
||||||
|
color="primary"
|
||||||
|
name="sync_problem"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Rounding') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #column-salesPersonFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ row.salesPerson }}
|
||||||
|
<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="getColor(row)">
|
||||||
|
<QChip :class="getColor(row)" dense square>
|
||||||
|
{{ row.state }}
|
||||||
|
</QChip>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ row.state }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #column-refFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ dashIfEmpty(row.refFk) }}
|
||||||
|
<InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
|
||||||
|
</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 }">
|
<template #more-create-dialog="{ data }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
url="Clients"
|
url="Clients"
|
||||||
|
:fields="['id', 'name']"
|
||||||
jon marked this conversation as resolved
jsegarra
commented
añadir order:id añadir order:id
|
|||||||
:label="t('ticketList.client')"
|
:label="t('ticketList.client')"
|
||||||
v-model="data.clientId"
|
v-model="data.clientId"
|
||||||
:options="clientsOptions"
|
:options="clientsOptions"
|
||||||
|
@ -259,6 +615,7 @@ onMounted(() => {
|
||||||
option-label="name"
|
option-label="name"
|
||||||
hide-selected
|
hide-selected
|
||||||
@update:model-value="(client) => onClientSelected(data)"
|
@update:model-value="(client) => onClientSelected(data)"
|
||||||
|
:sort-by="'id ASC'"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -339,12 +696,136 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</template>
|
</template>
|
||||||
<template #column-stateFk="{ row }">
|
|
||||||
<QChip :class="getColor(row)" dense square>
|
|
||||||
{{ row.state }}
|
|
||||||
</QChip>
|
|
||||||
</template>
|
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
<QPageSticky :offset="[20, 80]" style="z-index: 2">
|
||||||
|
<QBtn
|
||||||
|
v-if="hasSelectedRows"
|
||||||
|
@click="makeInvoice(selectedRows)"
|
||||||
|
color="primary"
|
||||||
|
fab
|
||||||
|
icon="vn:invoice-in"
|
||||||
|
/>
|
||||||
|
<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-value="id"
|
||||||
|
option-label="code"
|
||||||
|
hide-selected
|
||||||
|
>
|
||||||
|
</VnSelect>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
|
<VnSelect
|
||||||
|
:label="t('ticketList.bank')"
|
||||||
|
v-model="dialogData.bankFk"
|
||||||
|
:options="accountingOptions"
|
||||||
|
option-value="id"
|
||||||
|
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>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
@ -353,4 +834,5 @@ es:
|
||||||
You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
||||||
Zone: Zona
|
Zone: Zona
|
||||||
New ticket: Nuevo ticket
|
New ticket: Nuevo ticket
|
||||||
|
Component lack: Faltan componentes
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -67,6 +67,8 @@ advanceTickets:
|
||||||
advanceWithoutNegativeTitle: Advance tickets (without negatives)
|
advanceWithoutNegativeTitle: Advance tickets (without negatives)
|
||||||
advanceWithoutNegativeSubtitle: Advance {selectedTickets} tickets confirmation
|
advanceWithoutNegativeSubtitle: Advance {selectedTickets} tickets confirmation
|
||||||
errorsList: Errors list
|
errorsList: Errors list
|
||||||
|
search: Search advance tickets
|
||||||
|
searchInfo: Search advance tickets by ID or client ID
|
||||||
futureTickets:
|
futureTickets:
|
||||||
problems: Problems
|
problems: Problems
|
||||||
ticketId: ID
|
ticketId: ID
|
||||||
|
@ -105,7 +107,7 @@ expedition:
|
||||||
name: Name
|
name: Name
|
||||||
packageType: Package type
|
packageType: Package type
|
||||||
counter: Counter
|
counter: Counter
|
||||||
externalId: externalId
|
externalId: external Id
|
||||||
created: Created
|
created: Created
|
||||||
state: State
|
state: State
|
||||||
historyAction: Status log
|
historyAction: Status log
|
||||||
|
@ -118,6 +120,10 @@ expedition:
|
||||||
removeExpeditionSubtitle: Are you sure you want to delete this expedition?
|
removeExpeditionSubtitle: Are you sure you want to delete this expedition?
|
||||||
worker: Worker
|
worker: Worker
|
||||||
move: Move
|
move: Move
|
||||||
|
isScanned: Is scanned
|
||||||
|
yes: Yes
|
||||||
|
no: No
|
||||||
|
removeExpedition: Delete expedition
|
||||||
basicData:
|
basicData:
|
||||||
next: Next
|
next: Next
|
||||||
back: Back
|
back: Back
|
||||||
|
@ -233,7 +239,7 @@ package:
|
||||||
removePackage: Remove package
|
removePackage: Remove package
|
||||||
ticketList:
|
ticketList:
|
||||||
id: Id
|
id: Id
|
||||||
nickname: Nickname
|
nickname: Ticket nickname
|
||||||
state: State
|
state: State
|
||||||
shipped: Shipped
|
shipped: Shipped
|
||||||
zone: Zone
|
zone: Zone
|
||||||
|
@ -242,3 +248,27 @@ ticketList:
|
||||||
summary: Summary
|
summary: Summary
|
||||||
client: Customer
|
client: Customer
|
||||||
createTicket: Create ticket
|
createTicket: Create ticket
|
||||||
|
createInvoice: Create invoice
|
||||||
|
accountPayment: Account payment
|
||||||
|
sendDocuware: Set delivered and send delivery note(s) to the tablet
|
||||||
|
addPayment: Add payment
|
||||||
|
date: Date
|
||||||
|
company: Company
|
||||||
|
amount: Amount
|
||||||
|
reference: Reference
|
||||||
|
bank: Bank
|
||||||
|
cash: Cash
|
||||||
|
deliveredAmount: Delivered amount
|
||||||
|
amountToReturn: Amount to return
|
||||||
|
viewReceipt: View receipt
|
||||||
|
sendEmail: Send email
|
||||||
|
compensation: Compensation
|
||||||
|
creditCard: Credit card
|
||||||
|
transfers: Transfers
|
||||||
|
province: Province
|
||||||
|
warehouse: Warehouse
|
||||||
|
hour: Hour
|
||||||
|
closure: Closure
|
||||||
|
toLines: Go to lines
|
||||||
|
addressNickname: Address nickname
|
||||||
|
ref: Reference
|
||||||
|
|
|
@ -114,6 +114,8 @@ advanceTickets:
|
||||||
advanceWithoutNegativeTitle: Adelantar tickets (sin negativos)
|
advanceWithoutNegativeTitle: Adelantar tickets (sin negativos)
|
||||||
advanceWithoutNegativeSubtitle: '¿Desea adelantar {selectedTickets} tickets?'
|
advanceWithoutNegativeSubtitle: '¿Desea adelantar {selectedTickets} tickets?'
|
||||||
errorsList: Lista de errores
|
errorsList: Lista de errores
|
||||||
|
search: Buscar por tickets adelantados
|
||||||
|
searchInfo: Buscar tickets adelantados por el identificador o el identificador del cliente
|
||||||
futureTickets:
|
futureTickets:
|
||||||
problems: Problemas
|
problems: Problemas
|
||||||
ticketId: ID
|
ticketId: ID
|
||||||
|
@ -192,9 +194,9 @@ expedition:
|
||||||
id: Expedición
|
id: Expedición
|
||||||
item: Artículo
|
item: Artículo
|
||||||
name: Nombre
|
name: Nombre
|
||||||
packageType: Package type
|
packageType: Embalaje
|
||||||
counter: Contador
|
counter: Contador
|
||||||
externalId: externalId
|
externalId: ID externo
|
||||||
created: Fecha creación
|
created: Fecha creación
|
||||||
state: Estado
|
state: Estado
|
||||||
historyAction: Historial de estados
|
historyAction: Historial de estados
|
||||||
|
@ -207,6 +209,10 @@ expedition:
|
||||||
removeExpeditionSubtitle: ¿Está seguro de eliminar esta expedición?
|
removeExpeditionSubtitle: ¿Está seguro de eliminar esta expedición?
|
||||||
worker: Trabajador
|
worker: Trabajador
|
||||||
move: Mover
|
move: Mover
|
||||||
|
isScanned: Escaneado
|
||||||
|
yes: Sí
|
||||||
|
no: No
|
||||||
|
removeExpedition: Eliminar expedición
|
||||||
package:
|
package:
|
||||||
package: Embalaje
|
package: Embalaje
|
||||||
quantity: Cantidad
|
quantity: Cantidad
|
||||||
|
@ -236,7 +242,7 @@ You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
||||||
Select lines to see the options: Selecciona líneas para ver las opciones
|
Select lines to see the options: Selecciona líneas para ver las opciones
|
||||||
ticketList:
|
ticketList:
|
||||||
id: Id
|
id: Id
|
||||||
nickname: Alias
|
nickname: Alias ticket
|
||||||
state: Estado
|
state: Estado
|
||||||
shipped: F. Envío
|
shipped: F. Envío
|
||||||
zone: Zona
|
zone: Zona
|
||||||
|
@ -245,3 +251,27 @@ ticketList:
|
||||||
summary: Resumen
|
summary: Resumen
|
||||||
client: Cliente
|
client: Cliente
|
||||||
createTicket: Crear ticket
|
createTicket: Crear ticket
|
||||||
|
createInvoice: Crear factura
|
||||||
|
accountPayment: Pago a cuenta...
|
||||||
|
sendDocuware: Marcar como servido/s y enviar albarán/es a la tablet
|
||||||
|
addPayment: Añadir pago
|
||||||
|
date: Fecha
|
||||||
|
company: Empresa
|
||||||
|
amount: Importe
|
||||||
|
reference: Referencia
|
||||||
|
bank: Caja
|
||||||
|
cash: Efectivo
|
||||||
|
deliveredAmount: Cantidad entregada
|
||||||
|
amountToReturn: Cantidad a devolver
|
||||||
|
viewReceipt: Ver recibido
|
||||||
|
sendEmail: Enviar correo
|
||||||
|
compensation: Compensación
|
||||||
|
creditCard: Tarjeta de crédito
|
||||||
|
transfers: Transferencias
|
||||||
|
province: Provincia
|
||||||
|
warehouse: Almacén
|
||||||
|
hour: Hora
|
||||||
|
closure: Cierre
|
||||||
|
toLines: Ir a lineas
|
||||||
|
addressNickname: Alias consignatario
|
||||||
|
ref: Referencia
|
||||||
|
|
|
@ -198,7 +198,7 @@ export default {
|
||||||
name: 'TicketPackage',
|
name: 'TicketPackage',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'packages',
|
title: 'packages',
|
||||||
icon: 'vn:bin',
|
icon: 'vn:bucket',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Ticket/Card/TicketPackage.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketPackage.vue'),
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Consignatario