Переглянути джерело

refactor: metricas financeiro

Gustavo Mantovani 1 місяць тому
батько
коміт
bd9d0efc38

+ 7 - 9
src/helpers/buildMetricCards.js

@@ -7,6 +7,8 @@ import {
 
 export function buildMetricCards(summary, options = {}) {
   const { isAllPropertiesSelected = false, referenceLabel = "" } = options;
+  const displayedExpenses =
+    Number(summary.expenses_amount ?? 0) + Number(summary.ota_amount ?? 0);
 
   // const totalExpenses = Number(summary.expenses ?? 0);
 
@@ -22,7 +24,7 @@ export function buildMetricCards(summary, options = {}) {
   // const netPayout = Number(summary.final_payout_amount ?? 0);
 
   const occupancyCaption = isAllPropertiesSelected
-    ? "percentual consolidado do período"
+    ? "percentual do período"
     : `${formatInteger(summary.occupied_nights_in_month)} de ${formatInteger(summary.days_in_month)} dias`;
 
   /*
@@ -95,11 +97,7 @@ export function buildMetricCards(summary, options = {}) {
 
     {
       label: "Total de Reservas",
-      value: formatInteger(
-        summary.distinct_reservations_count ??
-        summary.checkout_reservations_count ??
-        summary.reservations_count
-      ),
+      value: formatInteger(summary.reservations_count),
       caption: "no período",
     },
 
@@ -138,7 +136,7 @@ export function buildMetricCards(summary, options = {}) {
     // FINANCEIRO
 
     {
-      label: "Faturamento Bruto",
+      label: "Faturamento",
       value: formatCurrency(summary.gross_revenue),
       caption: referenceLabel || "Mês selecionado",
     },
@@ -169,8 +167,8 @@ export function buildMetricCards(summary, options = {}) {
 
     {
       label: "Despesas",
-      value: formatCurrency(summary.expenses_amount),
-      caption: "manutenção e operação",
+      value: formatCurrency(displayedExpenses),
+      caption: "inclui OTA",
     },
 
     {

+ 5 - 11
src/pages/dashboard/DashboardPage.vue

@@ -101,7 +101,9 @@
 
             <DashboardPayoutTable
               :rows="payoutRows"
-              :total-reservations="Number(summary.checkout_reservations_count ?? 0)"
+              :total-reservations="
+                Number(summary.checkout_reservations_count ?? 0)
+              "
               :total-value="Number(summary.final_payout_amount ?? 0)"
             />
           </q-card>
@@ -259,10 +261,7 @@ const isAllPropertiesSelected = computed(
 );
 
 const canExportReport = computed(
-  () =>
-    hasProperties.value &&
-    dashboard.value !== null &&
-    selectedPropertyId.value !== null,
+  () => hasProperties.value && dashboard.value !== null,
 );
 
 //
@@ -355,12 +354,7 @@ const availabilityTotalLabel = computed(() => {
 });
 
 const channelsTotalLabel = computed(() => {
-  const total = Number(
-    summary.value.distinct_reservations_count ??
-    summary.value.checkout_reservations_count ??
-    summary.value.reservations_count ??
-    0
-  );
+  const total = Number(summary.value.reservations_count ?? 0);
 
   return `Total: ${formatInteger(total)} reservas`;
 });

+ 51 - 169
src/pages/dashboard/components/DashboardPayoutTable.vue

@@ -3,47 +3,20 @@
     <table class="payout-table">
       <thead>
         <tr>
-          <th
-            v-for="(column, index) in columns"
-            :key="column.key"
-          >
+          <th v-for="column in columns" :key="column.key">
             <div class="header-wrapper">
               <div class="header-content">
                 <q-icon
                   class="cursor-pointer sort-icon q-my-md"
-                  :name="
-                    column.direction === 'desc'
-                      ? 'south'
-                      : 'north'
-                  "
+                  :name="column.direction === 'desc' ? 'south' : 'north'"
                   size="15px"
-                  :color="
-                    column.direction
-                      ? 'primary'
-                      : '#b0b0b0'
-                  "
+                  :color="column.direction ? 'primary' : '#b0b0b0'"
                   @click="toggleSort(column)"
                 />
 
-                <q-icon
-                  class="cursor-pointer move-icon"
-                  color="#888"
-                  name="chevron_left"
-                  size="18px"
-                  @click="moveLeft(index)"
-                />
-
                 <span class="header-label">
                   {{ column.label }}
                 </span>
-
-                <q-icon
-                  class="cursor-pointer move-icon"
-                  color="#888"
-                  name="chevron_right"
-                  size="18px"
-                  @click="moveRight(index)"
-                />
               </div>
             </div>
           </th>
@@ -51,38 +24,14 @@
       </thead>
 
       <tbody>
-        <tr
-          v-for="item in sortedRows"
-          :key="item.property_id"
-        >
-          <td
-            v-for="column in columns"
-            :key="column.key"
-          >
-            <template
-              v-if="
-                column.key ===
-                'final_payout_amount'
-              "
-            >
-              {{
-                formatCurrency(
-                  item[column.key]
-                )
-              }}
+        <tr v-for="item in sortedRows" :key="item.property_id">
+          <td v-for="column in columns" :key="column.key">
+            <template v-if="column.key === 'final_payout_amount'">
+              {{ formatCurrency(item[column.key]) }}
             </template>
 
-            <template
-              v-else-if="
-                column.key ===
-                'reservations_count'
-              "
-            >
-              {{
-                formatInteger(
-                  resolveReservationsCount(item)
-                )
-              }}
+            <template v-else-if="column.key === 'reservations_count'">
+              {{ formatInteger(resolveReservationsCount(item)) }}
             </template>
 
             <template v-else>
@@ -95,17 +44,11 @@
           <td>Total</td>
 
           <td>
-            {{
-              formatInteger(
-                totalReservations
-              )
-            }}
+            {{ formatInteger(totalReservations) }}
           </td>
 
           <td>
-            {{
-              formatCurrency(totalValue)
-            }}
+            {{ formatCurrency(totalValue) }}
           </td>
         </tr>
       </tbody>
@@ -114,10 +57,7 @@
 </template>
 
 <script setup>
-import {
-  computed,
-  ref,
-} from "vue";
+import { computed, ref } from "vue";
 
 const props = defineProps({
   rows: {
@@ -156,91 +96,48 @@ const columns = ref([
   },
 ]);
 
-const toggleSort = (
-  column
-) => {
-  column.direction =
-    column.direction === "asc"
-      ? "desc"
-      : "asc";
-};
-
-const moveLeft = (index) => {
-  const lastIndex =
-    columns.value.length - 1;
-
-  const targetIndex =
-    index === 0
-      ? lastIndex
-      : index - 1;
-
-  [
-    columns.value[targetIndex],
-    columns.value[index],
-  ] = [
-    columns.value[index],
-    columns.value[targetIndex],
-  ];
-};
+const toggleSort = (column) => {
+  columns.value.forEach((item) => {
+    if (item !== column) {
+      item.direction = null;
+    }
+  });
 
-const moveRight = (index) => {
-  const lastIndex =
-    columns.value.length - 1;
-
-  const targetIndex =
-    index === lastIndex
-      ? 0
-      : index + 1;
-
-  [
-    columns.value[targetIndex],
-    columns.value[index],
-  ] = [
-    columns.value[index],
-    columns.value[targetIndex],
-  ];
+  column.direction = column.direction === "asc" ? "desc" : "asc";
 };
 
 const sortedRows = computed(() => {
-  const activeSorts =
-    columns.value.filter(
-      (column) => column.direction
-    );
+  const activeSorts = columns.value.filter((column) => column.direction);
 
   if (!activeSorts.length) {
     return [...props.rows];
   }
 
-  return [...props.rows].sort(
-    (a, b) => {
-      for (const sort of activeSorts) {
-        const direction =
-          sort.direction === "asc"
-            ? 1
-            : -1;
-
-        const valueA =
-          sort.key === "reservations_count"
-            ? resolveReservationsCount(a)
-            : a[sort.key];
-
-        const valueB =
-          sort.key === "reservations_count"
-            ? resolveReservationsCount(b)
-            : b[sort.key];
-
-        if (valueA > valueB) {
-          return direction;
-        }
-
-        if (valueA < valueB) {
-          return -direction;
-        }
+  return [...props.rows].sort((a, b) => {
+    for (const sort of activeSorts) {
+      const direction = sort.direction === "asc" ? 1 : -1;
+
+      const valueA =
+        sort.key === "reservations_count"
+          ? resolveReservationsCount(a)
+          : a[sort.key];
+
+      const valueB =
+        sort.key === "reservations_count"
+          ? resolveReservationsCount(b)
+          : b[sort.key];
+
+      if (valueA > valueB) {
+        return direction;
       }
 
-      return 0;
+      if (valueA < valueB) {
+        return -direction;
+      }
     }
-  );
+
+    return 0;
+  });
 });
 
 const resolveReservationsCount = (item) =>
@@ -248,28 +145,19 @@ const resolveReservationsCount = (item) =>
     item.checkout_reservations_count ??
       item.distinct_reservations_count ??
       item.reservations_count ??
-      0
+      0,
   );
 
-const formatCurrency = (
-  value
-) => {
-  return new Intl.NumberFormat(
-    "pt-BR",
-    {
-      style: "currency",
-      currency: "BRL",
-      minimumFractionDigits: 2,
-    }
-  ).format(Number(value ?? 0));
+const formatCurrency = (value) => {
+  return new Intl.NumberFormat("pt-BR", {
+    style: "currency",
+    currency: "BRL",
+    minimumFractionDigits: 2,
+  }).format(Number(value ?? 0));
 };
 
-const formatInteger = (
-  value
-) => {
-  return Number(
-    value ?? 0
-  ).toLocaleString("pt-BR");
+const formatInteger = (value) => {
+  return Number(value ?? 0).toLocaleString("pt-BR");
 };
 </script>
 
@@ -327,12 +215,6 @@ const formatInteger = (
   transition: 0.2s ease;
 }
 
-.move-icon {
-  opacity: 0.7;
-  transition: 0.2s ease;
-}
-
-.move-icon:hover,
 .sort-icon:hover {
   opacity: 1;
   transform: scale(1.08);