chet novoe

This commit is contained in:
Vladimir Voronin
2024-10-30 12:49:10 +03:00
parent eede3430b0
commit 5e49e223ee
2 changed files with 91 additions and 63 deletions

View File

@@ -17,7 +17,7 @@
<div :class="!updateLoading ? '' : 'h-fit bg-white opacity-50 z-0 '" class=" flex flex-col gap-3">
<div class="flex flex-col ">
<!-- {{ budget }}-->
<h2 class="text-4xl font-bold">Budget for {{ budget.name }} </h2>
<h2 class="text-4xl font-bold">Бюджет {{ budget.name }} </h2>
<!-- <div class="flex flex-row gap-2 text-xl">{{ formatDate(budget.dateFrom) }} - -->
<!-- {{ formatDate(budget.dateTo) }}-->
<!-- </div> -->
@@ -31,20 +31,24 @@
class="bg-white p-4 shadow-lg rounded-lg flex flex-col gap-4 items-start ">
<h3 class="text-xl font-bold">Аналитика</h3>
<SelectButton v-model="selectedChart" :options="modes" optionLabel="label" optionIcon="icon"> <template #option="slotProps">
<i :class="slotProps.option.icon"></i>
</template></SelectButton>
<Chart v-if="selectedChart.value=='bar'" type="bar" :data="incomeExpenseChartData" :options="incomeExpenseChartOptions" class="!w-full"
<SelectButton v-model="selectedChart" :options="modes" optionLabel="label" optionIcon="icon">
<template #option="slotProps">
<i :class="slotProps.option.icon"></i>
</template>
</SelectButton>
<Chart v-if="selectedChart.value=='bar'" type="bar" :data="incomeExpenseChartData"
:options="incomeExpenseChartOptions" class="!w-full"
style="width: 100%"/>
<Chart v-if="selectedChart.value=='pie'" type="pie" :data="pieChartData" :options="pieChartOptions" class="chart "/>
<Chart v-if="selectedChart.value=='pie'" type="pie" :data="pieChartData" :options="pieChartOptions"
class="chart "/>
<div class="flex gap-5 items-center justify-items-center ">
<div class="w-full">
<button class="grid grid-cols-2 gap-5 items-center w-full" @click="detailedShowed = !detailedShowed">
<div class="flex flex-col items-center font-bold ">
<h4 class="text-xl font-bold text-green-500">Сумма поступлений</h4>
<h4 class="text-lg font-bold">Поступления</h4>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
+{{ formatAmount(totalIncomes) }}
@@ -52,7 +56,7 @@
<!-- <p>Total Incomes</p>-->
</div>
<div class="flex flex-col items-center ">
<h4 class="text-xl font-bold text-red-500">Сумма трат</h4>
<h4 class="text-lg font-bold ">Расходы</h4>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
-{{ formatAmount(totalExpenses) }}
@@ -61,27 +65,27 @@
</button>
<div class="grid grid-cols-2 !gap-1 mt-4" :class="detailedShowed ? 'block' : 'hidden'">
<div class="flex flex-col items-center font-bold ">
<p class="font-bold ">Поступление в первый период</p>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
<p class="font-light ">в первый период</p>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
+{{ formatAmount(incomesByPeriod[0]) }}
</div>
</div>
<div class="flex flex-col items-center">
<p class="font-bold ">Траты в первый период</p>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
<p class="font-light ">в первый период</p>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
-{{ formatAmount(expensesByPeriod[0]) }}
</div>
</div>
<div class="flex flex-col items-center">
<p class="font-bold ">Поступления во второй период</p>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
<p class="font-light ">во второй период</p>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
+{{ formatAmount(incomesByPeriod[1]) }}
</div>
</div>
<div class="flex flex-col items-center">
<p class="font-bold ">Траты во второй период</p>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
<p class="font-light ">во второй период</p>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
-{{ formatAmount(expensesByPeriod[1]) }}
</div>
</div>
@@ -95,30 +99,30 @@
<button class="grid grid-cols-3 justify-between gap-5 items-center w-full"
@click="detailedShowed = !detailedShowed">
<div class="flex flex-col items-center">
<h4 class="text-lg">Долги</h4>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
<h4 class="text-lg">💳 Долги</h4>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
{{ loansRatio.toFixed(0) }} %
</div>
<!-- <p>Total Incomes</p>-->
</div>
<div class="flex flex-col items-center ">
<h4 class="text-lg ">Сбережения</h4>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
<span class="text-base">💰Сбережения</span>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
{{ savingRatio.toFixed(0) }} %
</div>
</div>
<div class="flex flex-col items-center ">
<h4 class="text-lg ">Ежедневные</h4>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
<h4 class="text-sm">🍎 Ежедневные</h4>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
{{ dailyRatio.toFixed(0) }} %
</div>
</div>
</button>
<div class="grid grid-cols-2 !gap-1 mt-4" :class="detailedShowed ? 'block' : 'hidden'">
<div v-for="transaction in transactionCategoriesSums" class="flex flex-col items-center font-bold ">
<p class="font-bold ">{{ transaction.category.name }}</p>
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
{{ formatAmount(transaction.sum) }}
<div v-for="categorySum in transactionCategoriesSums" class="flex flex-col items-center font-bold ">
<p class="font-light ">{{ categorySum.category.icon }} {{ categorySum.category.name }}</p>
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center w-full ">
{{ formatAmount(categorySum.sum) }}
</div>
</div>
</div>
@@ -130,13 +134,14 @@
</div>
<div class=" h-full overflow-y-auto gap-4 flex-col row-span-6 hidden lg:flex">
<div class="flex flex-row ">
<h3 class="text-2xl font-bold mb-4 ">Transactions List</h3>
<h3 class="text-2xl font-bold">Транзакции</h3>
</div>
<div class=" flex gap-2">
<button v-for="categorySum in transactionCategoriesSums" :key="categorySum.category.id"
class="rounded-full border p-1 bg-white border-gray-300 mb-2 px-2">
<strong>{{ categorySum.category.name }}</strong>:
{{ categorySum.sum }}
<div class=" flex gap-2 overflow-x-auto ">
<button v-for="categorySum in transactionCategoriesSums"
class="rounded-xl border p-1 bg-white border-gray-300 mb-2 min-w-fit px-2">
<p> <span class="text-sm font-bold">{{ categorySum.category.name }}</span>: {{ categorySum.sum }} </p>
</button>
</div>
<div class="grid grid-cols-1 gap-4 max-h-tlist overflow-y-auto pe-2">
@@ -154,8 +159,8 @@
<!-- Планируемые доходы -->
<div>
<div class="flex flex-row gap-4 items-center">
<h3 class="text-xl font-bold text-green-500 mb-4 ">Planned Incomes</h3>
<Button icon="pi pi-plus" rounded outlined size="small"/>
<h3 class="text-xl font-bold text-green-500 mb-4 ">Плановые поступления</h3>
<!-- <Button icon="pi pi-plus" rounded outlined size="small"/>-->
</div>
<div class="grid grid-cols-2 mb-2">
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
@@ -180,7 +185,7 @@
<div class="card p-4 shadow-lg rounded-lg col-span-1 h-fit">
<!-- Планируемые расходы -->
<div class>
<h3 class="text-xl font-bold text-red-500 mb-4">Planned Expenses</h3>
<h3 class="text-xl font-bold text-red-500 mb-4">Плановые расходы</h3>
<div class="grid grid-cols-2 mb-2">
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
{{ formatAmount(totalPlannedExpenses) }}
@@ -202,25 +207,25 @@
</div>
<div class="row-span-1 h-fit">
<h3 class="text-2xl font-bold mb-4">Категории</h3>
<h3 class="text-2xl font-bold ">Категории</h3>
<div class="grid grid-cols-1 gap-4">
<UnplannedCategoryView v-for="category in categories" :key="category.id"
:category="category" :budget-id="budget.id"
@category-updated="updateBudgetCategory"
class="p-4 shadow-lg rounded-lg bg-white flex justify-between items-center"/>
<!-- {{categories.filter(cat => cat.category.id==35)}}-->
<BudgetCategoryView v-for="category in categories" :key="category.id"
:category="category" :budget-id="budget.id"
@category-updated="updateBudgetCategory"
class="p-4 shadow-lg rounded-lg bg-white flex justify-between items-center"/>
</div>
</div>
<div class=" h-full overflow-y-auto gap-4 flex-col row-span-6 lg:hidden ">
<div class="flex flex-row ">
<h3 class="text-2xl font-bold mb-4 ">Transactions List</h3>
<h3 class="text-2xl font-bold">Транзакций</h3>
</div>
<div class=" flex gap-2">
<button v-for="categorySum in transactionCategoriesSums" :key="categorySum.category.id"
<button v-for="categorySum in transactionCategoriesSums"
class="rounded-full border p-1 bg-white border-gray-300 mb-2 px-2">
<strong>{{ categorySum.category.name }}</strong>:
{{ categorySum.sum }}
<p class="text-sm">{{ categorySum.category.name }}</p>:
{{ categorySum }}
</button>
</div>
<div class="grid grid-cols-1 gap-4 max-h-tlist overflow-y-auto pe-2">
@@ -240,11 +245,11 @@
<script setup lang="ts">
import { computed, onMounted, ref} from 'vue';
import {computed, onMounted, ref} from 'vue';
import Chart from 'primevue/chart';
import BudgetTransactionView from "@/components/budgets/BudgetTransactionView.vue";
import {
getBudgetCategories, getBudgetCategoriesSums,
getBudgetCategories,
getBudgetInfo,
getBudgetTransactions,
updateBudgetCategoryRequest
@@ -254,7 +259,7 @@ import {useRoute} from "vue-router";
import {formatAmount} from "@/utils/utils";
import ProgressBar from "primevue/progressbar";
import ProgressSpinner from "primevue/progressspinner";
import UnplannedCategoryView from "@/components/budgets/BudgetCategoryView.vue";
import BudgetCategoryView from "@/components/budgets/BudgetCategoryView.vue";
import {Transaction} from "@/models/Transaction";
import Toast from "primevue/toast";
import Button from "primevue/button";
@@ -271,7 +276,7 @@ const loading = ref(true);
const updateLoading = ref(false);
const route = useRoute()
const detailedShowed = ref(false);
const selectedChart = ref({ "label": "bar", "icon": "pi pi-chart-bar", "value": "bar" });
const selectedChart = ref({"label": "bar", "icon": "pi pi-chart-bar", "value": "bar"});
const modes = [
{label: 'bar', icon: 'pi pi-chart-bar', value: 'bar'},
{label: 'pie', icon: 'pi pi-chart-pie', value: 'pie'}
@@ -381,29 +386,53 @@ const transactions = ref<Transaction[]>([])
const fetchBudgetTransactions = async () => {
transactions.value = await getBudgetTransactions(route.params.id)
transactions.value = await getBudgetTransactions(route.params.id, 'INSTANT')
updateLoading.value = false
}
const updateTransactions = async () => {
await Promise.all([fetchPlannedIncomes(), fetchPlannedExpenses()])
await Promise.all([fetchPlannedIncomes(), fetchPlannedExpenses(), fetchBudgetCategories(),])
}
const categories = ref<BudgetCategory[]>([])
const fetchBudgetCategories = async () => {
categories.value = await getBudgetCategories(route.params.id)
console.log(categories.value)
categories.value = [...categories.value];
updateLoading.value = false
}
const transactionCategoriesSums = ref()
const fetchBudgetTransactionCategoriesSums = async () => {
const transactionCategoriesSums = computed(() => {
// Используем reduce для создания массива сумм по категориям
const categorySums = transactions.value.reduce((acc, transaction) => {
console.log(transaction.category.name)
const category = transaction.category;
// Проверяем, существует ли категория в аккумуляторе
const existingCategory = acc.find(item => item.category.id === category.id);
if (existingCategory) {
// Если категория существует, добавляем сумму к текущей
existingCategory.sum += transaction.amount;
} else {
// Если категории еще нет в аккумуляторе, добавляем ее
acc.push({ category: category, sum: transaction.amount });
}
return acc;
}, []);
console.log(categorySums)
return categorySums;
});
transactionCategoriesSums.value = await getBudgetCategoriesSums(route.params.id)
updateLoading.value = false
}
// const fetchBudgetTransactionCategoriesSums = async () => {
//
// transactionCategoriesSums.value = await getBudgetCategoriesSums(route.params.id)
// updateLoading.value = false
// }
const budgetInfo = ref<BudgetInfo>();
@@ -411,7 +440,7 @@ const fetchBudgetInfo = async () => {
budget.value = await getBudgetInfo(route.params.id);
updateLoading.value = false
updateLoading.value = false
}
const updateBudgetCategory = async (category) => {
@@ -638,7 +667,6 @@ onMounted(async () => {
fetchPlannedExpenses(),
fetchBudgetCategories(),
fetchBudgetTransactions(),
fetchBudgetTransactionCategoriesSums()
]);
} catch (error) {
console.error('Error during fetching data:', error);

View File

@@ -27,11 +27,11 @@ export const getBudgetInfos = async () => {
export const getBudgetTransactions = async (budgetId, transactionType, categoryType) => {
let url = `/budgets/${budgetId}/transactions`
if (transactionType) {
url += '/' + transactionType
if (transactionType && !categoryType) {
url += '/?type=' + transactionType
}
if (transactionType && categoryType) {
url += '/'+categoryType
url += '/'+transactionType+'/'+categoryType
}
// if (!categoryType) {
// throw new Error('No CategoryType');