0
0
Fork 0

Ticket components

This commit is contained in:
William Buezas 2024-07-02 21:33:19 -03:00
parent 2961c813a5
commit 5c36ad14f4
7 changed files with 421 additions and 0 deletions

View File

@ -452,6 +452,7 @@ ticket:
weeklyTickets: Weekly tickets
services: Service
tracking: Tracking
components: Components
list:
nickname: Nickname
state: State

View File

@ -451,6 +451,7 @@ ticket:
weeklyTickets: Tickets programados
services: Servicios
tracking: Estados
components: Componentes
list:
nickname: Alias
state: Estado

View File

@ -0,0 +1,356 @@
<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import FetchedTags from 'components/ui/FetchedTags.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import FetchData from 'components/FetchData.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import { useStateStore } from 'stores/useStateStore';
import { dashIfEmpty } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
import { toCurrency } from 'filters/index';
import axios from 'axios';
const route = useRoute();
const stateStore = useStateStore();
const { t } = useI18n();
const salesRef = ref(null);
const arrayData = useArrayData('ticketData');
const { store } = arrayData;
const ticketData = computed(() => store.data);
const components = ref([]);
const componentsList = ref([]);
const theoricalCost = ref(0);
const ticketVolume = ref(null);
watch(
() => ticketData.value,
async () => {
await nextTick();
salesRef.value.fetch();
getComponentsSum();
getTheoricalCost();
if (ticketData.value?.zone && ticketData.value?.zone?.isVolumetric)
getTicketVolume();
}
);
const salesFilter = computed(() => ({
order: 'concept ASC',
include: [
{
relation: 'item',
},
{
relation: 'components',
scope: {
fields: ['componentFk', 'value'],
include: {
relation: 'component',
scope: {
fields: ['typeFk', 'name'],
include: {
relation: 'componentType',
scope: {
fields: ['type', 'isBase'],
},
},
},
},
},
},
],
where: { ticketFk: route.params.id },
}));
const columns = computed(() => [
{
label: t('components.item'),
name: 'item',
align: 'left',
},
{
label: t('components.description'),
name: 'description',
align: 'left',
},
{
label: t('components.quantity'),
name: 'quantity',
field: 'quantity',
align: 'left',
format: (val) => dashIfEmpty(val),
},
{
label: t('components.serie'),
name: 'serie',
align: 'left',
},
{
label: t('components.components'),
name: 'components',
align: 'left',
},
{
label: t('components.import'),
name: 'import',
align: 'left',
},
{
label: t('components.total'),
name: 'total',
align: 'left',
},
]);
const getBase = computed(() => {
let sum = 0;
for (let sale of components.value) {
for (let saleComponent of sale.components) {
if (saleComponent.component.componentType.isBase) {
sum += sale.quantity * saleComponent.value;
}
}
}
return sum;
});
const getTotal = computed(() => {
let total = 0;
for (let sale of components.value) {
for (let saleComponent of sale.components) {
total += sale.quantity * saleComponent.value;
}
}
return total;
});
const getComponentsSum = async () => {
try {
const { data } = await axios.get(`Tickets/${route.params.id}/getComponentsSum`);
componentsList.value = data;
console.log('componentsList', componentsList.value);
} catch (error) {
console.error(error);
}
};
const getTheoricalCost = async () => {
try {
const { data } = await axios.get(`Tickets/${route.params.id}/freightCost`);
theoricalCost.value = data;
} catch (error) {
console.error(error);
}
};
const getTicketVolume = async () => {
try {
if (!ticketData.value) return;
const { data } = await axios.get(`Tickets/${ticketData.value.id}/getVolume`);
console.log('data volume: ', data);
ticketVolume.value = data[0].volume;
} catch (error) {
console.error(error);
}
};
onMounted(() => {
stateStore.rightDrawer = true;
});
onUnmounted(() => (stateStore.rightDrawer = false));
</script>
<template>
<FetchData
ref="salesRef"
url="sales"
:filter="salesFilter"
@on-fetch="(data) => (components = data)"
auto-load
/>
<RightMenu>
<template #right-panel>
<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('components.total') }}
</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label"
>{{ t('components.baseToCommission') }}:
</span>
<span>{{ toCurrency(getBase) }}</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label"
>{{ t('components.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('components.components') }}
</span>
</QCardSection>
<QCardSection
v-for="(component, index) in componentsList"
:key="index"
class="justify-center"
horizontal
>
<span class="q-mr-xs color-vn-label"> {{ component.name }}: </span>
<span>{{ toCurrency(component.value, 'EUR', 3) }}</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('components.zoneBreakdown') }}
</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('components.price') }}:
</span>
<span>{{ toCurrency(ticketData?.zonePrice, 'EUR', 2) }}</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('components.bonus') }}:
</span>
<span>{{ toCurrency(ticketData?.zoneBonus, 'EUR', 2) }}</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('components.zone') }}:
</span>
<span class="link">
{{ dashIfEmpty(ticketData?.zone?.name) }}
<ZoneDescriptorProxy :id="ticketData?.zone?.id" />
</span>
</QCardSection>
<QCardSection
v-if="ticketData?.zone?.isVolumetric"
class="justify-center"
horizontal
>
<span class="q-mr-xs color-vn-label">
{{ t('components.volume') }}:
</span>
<span>{{ ticketVolume }}</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('components.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('components.theoricalCost') }}
</span>
</QCardSection>
<QCardSection class="justify-center" horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('components.totalPrice') }}:
</span>
<span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span>
</QCardSection>
</QCard>
</template>
</RightMenu>
<QTable
:rows="components"
: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 }">
<QTd>
<QBtn flat color="primary">
{{ row.itemFk }}
<ItemDescriptorProxy :id="row.itemFk" />
</QBtn>
</QTd>
</template>
<template #body-cell-description="{ row }">
<QTd>
<div class="column">
<span>{{ row.item.name }}</span>
<span class="color-vn-label">{{ row.item.subName }}</span>
<FetchedTags :item="row.item" :max-length="6" />
</div>
</QTd>
</template>
<template #body-cell-serie="{ row }">
<QTd>
<div class="column">
<span v-for="(saleComponent, index) in row.components" :key="index">
{{ saleComponent.component?.componentType?.type }}
</span>
</div>
</QTd>
</template>
<template #body-cell-components="{ row }">
<QTd>
<div class="column">
<span v-for="(saleComponent, index) in row.components" :key="index">
{{ saleComponent.component?.name }}
</span>
</div>
</QTd>
</template>
<template #body-cell-import="{ row }">
<QTd>
<div class="column">
<span v-for="(saleComponent, index) in row.components" :key="index">
{{ toCurrency(saleComponent.value, 'EUR', 3) }}
</span>
</div>
</QTd>
</template>
<template #body-cell-total="{ row }">
<QTd>
<div class="column">
<span v-for="(saleComponent, index) in row.components" :key="index">
{{ toCurrency(saleComponent.value * row.quantity, 'EUR', 3) }}
</span>
</div>
</QTd>
</template>
</QTable>
</template>

View File

@ -66,6 +66,23 @@ const filter = {
fields: ['id', 'name'],
},
},
{
relation: 'zone',
scope: {
fields: [
'agencyModeFk',
'bonus',
'hour',
'id',
'isVolumetric',
'itemMaxSize',
'm3Max',
'name',
'price',
'travelingDays',
],
},
},
],
};

View File

@ -159,6 +159,24 @@ service:
addService: Add service
quantityInfo: To create services with negative amounts mark the service on the source ticket and press the pay button.
createRefundSuccess: 'The following refund ticket have been created: { ticketId }'
components:
item: Item
description: Description
quantity: Quantity
serie: Serie
components: Components
import: Import
total: Total
baseToCommission: Base to commission
totalWithoutVat: Total without VAT
zoneBreakdown: Zone breakdown
price: Price
bonus: Bonus
zone: Zone
volume: Volume
theoricalCost: Theorical cost
totalPrice: Total price
packages: Packages
tracking:
state: State
worker: Worker

View File

@ -164,5 +164,23 @@ ticketSale:
shipped: F. Envío
agency: Agencia
address: Consignatario
components:
item: Artículo
description: Descripción
quantity: Cantidad
serie: Serie
components: Componentes
import: Importe
total: Total
baseToCommission: Base comisionable
totalWithoutVat: Total sin IVA
zoneBreakdown: Desglose zona
price: Precio
bonus: Bonificación
zone: Zona
volume: Volúmen
theoricalCost: Porte teórico
totalPrice: Precio total
packages: Bultos
Search ticket: Buscar tickets
You can search by ticket id or alias: Puedes buscar por id o alias del ticket

View File

@ -23,6 +23,7 @@ export default {
'TicketTracking',
'TicketVolume',
'TicketNotes',
'TicketComponents',
],
},
children: [
@ -179,6 +180,15 @@ export default {
},
component: () => import('src/pages/Ticket/Card/TicketVolume.vue'),
},
{
path: 'components',
name: 'TicketComponents',
meta: {
title: 'components',
icon: 'vn:components',
},
component: () => import('src/pages/Ticket/Card/TicketComponents.vue'),
},
{
path: 'observation',
name: 'TicketNotes',