Untitled
unknown
plain_text
a year ago
9.7 kB
7
Indexable
<template>
<Filters
v-model="selectedFilter"
@buttonClicked="applyFilters"
@sendOrder="formatBodyOrder"
/>
<v-data-table
:headers="headers"
:items="response"
item-value="id"
item-selected="isSelected"
class="elevation-1"
:model-value="selectedItems"
show-select
:footer-props="{
itemsPerPageText: 'Itens por página',
pageText: (pageStart, pageStop, totalItems) => `${pageStart}-${pageStop} de ${totalItems}`
}"
>
<!-- Corpo da tabela -->
<template v-slot:body="{ items }">
<template v-for="(item, index) in items" :key="item.id">
<!-- Linha principal -->
<tr>
<td>
<v-btn icon small @click="onActionClick(index)">
<v-icon>
{{
expandedRows.includes(index)
? "mdi-chevron-up"
: "mdi-chevron-down"
}}
</v-icon>
</v-btn>
</td>
<td>
<v-checkbox
:value="item.id"
color="primary"
hide-details
v-model="selectedItems"
@change="onParentCheckboxChange(item)"
></v-checkbox>
</td>
<td v-for="header in headers.slice(2)" :key="header.value">
{{ item[header.value] }}
</td>
</tr>
<!-- Linha expandida -->
<tr v-if="expandedRows.includes(index)" class="details-row">
<td :colspan="headers.length + 1">
<v-data-table
:headers="detailHeaders"
:items="item.stretchsFull"
dense
hide-default-footer
:model-value="selectedItemsFilho"
show-select
>
<!-- Corpo da tabela detalhada -->
<template v-slot:body="{ items: detailItems }">
<tr v-for="stretchFull in detailItems" :key="stretchFull.id">
<td>
<v-checkbox
:value="stretchFull.id"
color="primary"
hide-details
v-model="selectedItemsFilho"
@change="onChildCheckboxChange(item)"
></v-checkbox>
</td>
<td v-for="header in detailHeaders" :key="header.value">
<template v-if="header.value === 'dia_vencimento'">
<v-text-field
v-model="stretchFull[header.value]"
solo dense hide-details
></v-text-field>
</template>
<template v-else>
{{ stretchFull[header.value] }}
</template>
</td>
</tr>
</template>
</v-data-table>
</td>
</tr>
</template>
</template>
<!-- Nenhum dado -->
<template v-slot:no-data>
<v-alert type="info">Nenhum registro encontrado.</v-alert>
</template>
</v-data-table>
</template>
<script>
import Filters from './Filters.vue';
import { ref, inject, onMounted } from "vue";
import useOrders from "../../../../composables/orders";
import useRates from "../../../../composables/rates";
export default {
setup() {
const swal = inject('$swal');
const Toast = swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', swal.stopTimer);
toast.addEventListener('mouseleave', swal.resumeTimer);
}
});
const { upgradeRates, downgradeRates, getUpgradeRates, getDowngradeRates } = useRates();
const { getClientsContractsRefactor, subTotalStretchProvidences, subTotalStreches, subTotalStretchesMinutes, qualificationToShow } = useOrders();
const selectedFilter = ref({
currentDateRange: '',
selectedProgramObj: '',
selectedClientObj: '',
currentDate: new Date(),
});
const response = ref([]);
const selectedItems = ref([]); // Modelo de seleção para a tabela principal
const selectedItemsFilho = ref([]); // Modelo de seleção para a tabela detalhada
const expandedRows = ref([]);
onMounted(async() => {
await getUpgradeRates();
await getDowngradeRates();
});
const onActionClick = (item) => {
if (expandedRows.value.includes(item)) {
const index = expandedRows.value.indexOf(item);
if (index > -1) {
expandedRows.value.splice(index, 1);
}
} else {
expandedRows.value.push(item);
}
};
const applyFilters = async () => {
if (validarFiltros()) {
const dates = [selectedFilter.value.currentDateRange.start, selectedFilter.value.currentDateRange.end].map(date => moment(date).format('YYYY-MM-DD'));
response.value = await getClientsContractsRefactor('variavel', selectedFilter.value.selectedClientObj, dates, selectedFilter.value.selectedProgramObj);
response.value.forEach((booking, index) => {
treatMainTable(booking);
treatDetailTable(booking);
});
}
};
const formatCurrency = (value) => {
return parseFloat(value).toLocaleString('pt-BR', {
style: 'currency',
currency: 'BRL',
minimumFractionDigits: 2
});
};
const validarFiltros = () => {
for (let key of Object.keys(selectedFilter.value)) {
const value = selectedFilter.value[key];
if (value === null || value === '') {
Toast.fire({
icon: 'info',
title: `Preencha todos os campos obrigatórios.`
});
return false;
}
}
return true;
};
const treatStretch = (booking, stretch, upgradeRates, downgradeRates, diaVencimento, quotaID, clientFullName, stretchIndex) => {
const valorProvidencias = parseFloat(subTotalStretchProvidences(booking, stretch));
const valorTempoVoo = parseFloat(subTotalStrech(booking, stretch, upgradeRates.value, downgradeRates.value));
return {
...stretch,
valor_providencias: formatCurrency(valorProvidencias),
valor_tempo_voo: `${formatCurrency(valorTempoVoo)} / ${subTotalStretchMinutes(stretch)}`,
dia_vencimento: diaVencimento,
cota_id: quotaID,
clientFullname: clientFullName,
stretchIndex: stretchIndex + 1,
qualification: qualificationToShow(stretch.qualification),
selected: false
};
};
const treatDetailTable = (booking) => {
const diaVencimento = extractDiaVencimento(booking.client.clients_share_contracts);
const quotaID = extractCotaID(booking.client.clients_share_contracts, booking);
const clientFullName = booking.clientFullname;
booking.stretchsFull = booking.stretchsFull.map((stretch, stretchIndex) =>
treatStretch(booking, stretch, upgradeRates, downgradeRates, diaVencimento, quotaID, clientFullName, stretchIndex)
);
};
const treatMainTable = (booking) => {
const valorProvidencias = booking.stretchsFull.reduce(
(total, stretch) => total + parseFloat(subTotalStretchProvidences(booking, stretch)),
0
);
const valorTempoVoo = parseFloat(subTotalStreches(booking, upgradeRates.value, downgradeRates.value));
booking.stretchFirstDate = moment(booking.stretchsFull[0].originFull.date, 'YYYY-MM-DD').format('DD/MM/YYYY');
booking.stretchFirstHour = moment(booking.stretchsFull[0].originFull.hour, 'HH:mm:ss').format('HH:mm');
booking.valor_providencias = formatCurrency(valorProvidencias);
booking.valor_tempo_voo = `${formatCurrency(valorTempoVoo)} / ${subTotalStretchesMinutes(booking)}`;
booking.selected = false;
};
const headers = [
{ title: '', align: 'center', value: 'expand' },
{ title: '', align: 'center', value: 'data-table-select' },
{ title: 'Nº da Reserva', align: 'start', value: 'id' },
{ title: 'Status', align: 'start', value: 'status' },
{ title: 'Cliente', align: 'start', value: 'clientFullname' },
{ title: 'Data', align: 'start', value: 'stretchFirstDate' },
{ title: 'Hora', align: 'start', value: 'stretchFirstHour' },
{ title: 'Valor/Tempo de Voo (min)', align: 'start', value: 'valor_tempo_voo' },
{ title: 'Valor Providências', align: 'start', value: 'valor_providencias' },
];
const detailHeaders = [
{ title: '', align: 'center', value: 'data-table-select' },
{ title: 'Trecho', align: 'start', value: 'stretchIndex' },
{ title: 'Qualificação', align: 'start', value: 'qualification' },
{ title: 'Cliente', align: 'start', value: 'clientFullname' },
{ title: 'Dia de Vencimento', align: 'start', value: 'dia_vencimento' },
{ title: 'Valor/Tempo de Voo (min)', align: 'start', value: 'valor_tempo_voo' },
{ title: 'Valor Providências', align: 'start', value: 'valor_providencias' },
];
return {
selectedFilter,
applyFilters,
response,
headers,
detailHeaders,
selectedItems,
selectedItemsFilho,
expandedRows,
upgradeRates,
downgradeRates
};
},
components: {
Filters
}
};
</script>
Editor is loading...
Leave a Comment