Untitled
unknown
plain_text
10 months ago
17 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"
:footer-props="{
itemsPerPageText: 'Itens por página',
pageText: (pageStart, pageStop, totalItems) => `${pageStart}-${pageStop} de ${totalItems}`
}"
>
<template v-slot:column.data-table-select="{ props }">
<v-checkbox
v-model="checkAll"
@click="toggleSelectAll"
label="Selecionar Todos"
></v-checkbox>
</template>
<!-- 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
>
<!-- 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, subTotalStrech, subTotalStretchMinutes, qualificationToShow } = useOrders()
const selectedFilter = ref({
currentDateRange: '',
selectedProgramObj: '',
selectedClientObj: '',
currentDate: new Date(),
})
const response = ref([]);
const selectedItems = ref([])
const selectedItemsFilho = ref([])
const checkAll = ref(false);
const checkAllFilhos = ref(false);
const expandedRows = ref([]);
onMounted(async() => {
await getUpgradeRates();
await getDowngradeRates();
})
const onParentCheckboxChange = (parentItem) => {
const isSelected = selectedItems.value.includes(parentItem.id);
// Atualiza os filhos com o mesmo estado do pai
parentItem.stretchsFull.forEach((child) => {
if(isSelected){
if(!selectedItemsFilho.value.includes(child.id)){
selectedItemsFilho.value.push(child.id);
}
}else{
const index = selectedItemsFilho.value.indexOf(child.id);
if (index > -1) {
selectedItemsFilho.value.splice(index, 1);
}
}
});
};
const onChildCheckboxChange = (item) => {
let filhoFalso = item.stretchsFull.find(i => !selectedItemsFilho.value.includes(i.id))
let isSelected = !filhoFalso;
if(isSelected){
if(!selectedItems.value.includes(item.id)){
selectedItems.value.push(item.id);
}
}else{
const index = selectedItems.value.indexOf(item.id);
if (index > -1) {
selectedItems.value.splice(index, 1);
}
}
};
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);
}
}
function 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 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 extractCotaID = (clientsShareContracts, booking) => {
if (clientsShareContracts != null) {
clientsShareContracts.map((itemClient) => {
if (itemClient == booking.client.id) {
return contractQuota.taxa_variavel.cota_id;
}
});
}
}
const extractDiaVencimento = (clientsShareContracts) => {
for (const shareContract of clientsShareContracts) {
if (shareContract.status === 'ativo') {
for (const contractQuota of Object.values(shareContract.contract_quotas)) {
return contractQuota.taxa_variavel.data_vencimento;
}
}
}
return 0;
};
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;
};
function formatStringToCurrency (value){
value = value.split(' ')[1].replace(/\./g, "").replace(",", ".")
return parseFloat(value);
}
const toggleSelectAll = () => {
selectedItems.value = [];
if(checkAll.value){
response.value.array.forEach(booking => {
selectedItems.value.push(booking.id)
});
}
console.log('chegou aqui', checkAll.value)
}
const formatBodyOrder = async() => {
console.log('response.value', response.value)
if(selectedItemsFilho.value.length === 0){
Toast.fire({
icon: 'info',
title: `Selecione ao menos uma linha.`
})
return;
}
const diasDistintosSelecionados = [
...new Set(response.value.flatMap(r => r.stretchsFull.filter(i => selectedItemsFilho.value.includes(i.id)).map(s => s.dia_vencimento)))
];
diasDistintosSelecionados.forEach( dia => {
response.value.map(booking => enviarDados(booking, dia))
});
}
const enviarDados = (booking, dia) => {
let orderToSend = {};
orderToSend.bookings = [];
orderToSend.status = "Criado";
let totalProvidencias, totalValorTempoVoo = 0;
orderToSend.client_id = booking.client.id;
booking.stretchsFull.map((stretch) => {
if(stretch.dia_vencimento === dia && selectedItemsFilho.value.includes(stretch.id)){
totalProvidencias += formatStringToCurrency(stretch.valor_providencias);
totalValorTempoVoo += formatStringToCurrency(stretch.valor_tempo_voo);
orderToSend.dia_vencimento = stretch.dia_vencimento;
}
})
if(totalProvidencias === 0){
return;
}
orderToSend.valor_providencias = totalProvidencias;
orderToSend.valor = totalValorTempoVoo;
orderToSend.total = orderToSend.valor_providencias + orderToSend.valor;
orderToSend.bookings.push(booking.id);
orderToSend.company_id = 2;
orderToSend.tipo = "taxa_variavel";
console.log('orderToSend', orderToSend)
//storeOrder(orderToSend);
};
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,
formatBodyOrder,
selectedItems,
selectedItemsFilho,
onActionClick,
expandedRows,
upgradeRates,
downgradeRates,
onParentCheckboxChange,
onChildCheckboxChange,
checkAll,
checkAllFilhos,
toggleSelectAll
}
},
components: {
Filters
},
}
</script>
Editor is loading...
Leave a Comment