more improve in sell report
This commit is contained in:
parent
fa46e410fc
commit
2e4b0a68f2
|
@ -45,6 +45,15 @@ class SellReportController extends AbstractController
|
||||||
], 403);
|
], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// دریافت اطلاعات کسب و کار
|
||||||
|
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||||
|
if (!$business) {
|
||||||
|
return $this->json([
|
||||||
|
'result' => 0,
|
||||||
|
'message' => 'کسب و کار یافت نشد'
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
// دریافت پارامترها
|
// دریافت پارامترها
|
||||||
$startDate = $request->query->get('startDate');
|
$startDate = $request->query->get('startDate');
|
||||||
$endDate = $request->query->get('endDate');
|
$endDate = $request->query->get('endDate');
|
||||||
|
@ -52,6 +61,11 @@ class SellReportController extends AbstractController
|
||||||
$customerId = $request->query->get('customerId');
|
$customerId = $request->query->get('customerId');
|
||||||
$status = $request->query->get('status');
|
$status = $request->query->get('status');
|
||||||
|
|
||||||
|
// بررسی وضعیت فقط اگر سیستم تایید دو مرحلهای فعال باشد
|
||||||
|
if ($status && !$business->isRequireTwoStepApproval()) {
|
||||||
|
$status = null;
|
||||||
|
}
|
||||||
|
|
||||||
// تنظیم تاریخهای پیشفرض اگر ارسال نشده باشند
|
// تنظیم تاریخهای پیشفرض اگر ارسال نشده باشند
|
||||||
if (!$startDate) {
|
if (!$startDate) {
|
||||||
$startDate = $jdate->jdate('Y/m/01', time()); // ابتدای ماه جاری
|
$startDate = $jdate->jdate('Y/m/01', time()); // ابتدای ماه جاری
|
||||||
|
@ -107,6 +121,15 @@ class SellReportController extends AbstractController
|
||||||
], 403);
|
], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// دریافت اطلاعات کسب و کار
|
||||||
|
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||||
|
if (!$business) {
|
||||||
|
return $this->json([
|
||||||
|
'result' => 0,
|
||||||
|
'message' => 'کسب و کار یافت نشد'
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
// دریافت پارامترها
|
// دریافت پارامترها
|
||||||
$startDate = $request->query->get('startDate');
|
$startDate = $request->query->get('startDate');
|
||||||
$endDate = $request->query->get('endDate');
|
$endDate = $request->query->get('endDate');
|
||||||
|
@ -116,6 +139,11 @@ class SellReportController extends AbstractController
|
||||||
$page = max(1, (int) $request->query->get('page', 1));
|
$page = max(1, (int) $request->query->get('page', 1));
|
||||||
$perPage = max(1, min(100, (int) $request->query->get('perPage', 20)));
|
$perPage = max(1, min(100, (int) $request->query->get('perPage', 20)));
|
||||||
|
|
||||||
|
// بررسی وضعیت فقط اگر سیستم تایید دو مرحلهای فعال باشد
|
||||||
|
if ($status && !$business->isRequireTwoStepApproval()) {
|
||||||
|
$status = null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$invoices = $sellReportService->getSellInvoices(
|
$invoices = $sellReportService->getSellInvoices(
|
||||||
$acc['bid'],
|
$acc['bid'],
|
||||||
|
@ -165,6 +193,15 @@ class SellReportController extends AbstractController
|
||||||
], 403);
|
], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// دریافت اطلاعات کسب و کار
|
||||||
|
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||||
|
if (!$business) {
|
||||||
|
return $this->json([
|
||||||
|
'result' => 0,
|
||||||
|
'message' => 'کسب و کار یافت نشد'
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
// دریافت پارامترها
|
// دریافت پارامترها
|
||||||
$startDate = $request->query->get('startDate');
|
$startDate = $request->query->get('startDate');
|
||||||
$endDate = $request->query->get('endDate');
|
$endDate = $request->query->get('endDate');
|
||||||
|
@ -173,6 +210,11 @@ class SellReportController extends AbstractController
|
||||||
$customerId = $request->query->get('customerId');
|
$customerId = $request->query->get('customerId');
|
||||||
$status = $request->query->get('status');
|
$status = $request->query->get('status');
|
||||||
|
|
||||||
|
// بررسی وضعیت فقط اگر سیستم تایید دو مرحلهای فعال باشد
|
||||||
|
if ($status && !$business->isRequireTwoStepApproval()) {
|
||||||
|
$status = null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$topProducts = $sellReportService->getTopProducts(
|
$topProducts = $sellReportService->getTopProducts(
|
||||||
$acc['bid'],
|
$acc['bid'],
|
||||||
|
@ -221,6 +263,15 @@ class SellReportController extends AbstractController
|
||||||
], 403);
|
], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// دریافت اطلاعات کسب و کار
|
||||||
|
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||||
|
if (!$business) {
|
||||||
|
return $this->json([
|
||||||
|
'result' => 0,
|
||||||
|
'message' => 'کسب و کار یافت نشد'
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
// دریافت پارامترها
|
// دریافت پارامترها
|
||||||
$startDate = $request->query->get('startDate');
|
$startDate = $request->query->get('startDate');
|
||||||
$endDate = $request->query->get('endDate');
|
$endDate = $request->query->get('endDate');
|
||||||
|
@ -228,6 +279,11 @@ class SellReportController extends AbstractController
|
||||||
$customerId = $request->query->get('customerId');
|
$customerId = $request->query->get('customerId');
|
||||||
$status = $request->query->get('status');
|
$status = $request->query->get('status');
|
||||||
|
|
||||||
|
// بررسی وضعیت فقط اگر سیستم تایید دو مرحلهای فعال باشد
|
||||||
|
if ($status && !$business->isRequireTwoStepApproval()) {
|
||||||
|
$status = null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$topCustomers = $sellReportService->getTopCustomers(
|
$topCustomers = $sellReportService->getTopCustomers(
|
||||||
$acc['bid'],
|
$acc['bid'],
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
<v-card :loading="loading ? 'red' : null" :disabled="loading">
|
<v-card :loading="loading ? 'red' : null" :disabled="loading">
|
||||||
<!-- Toolbar -->
|
<!-- Toolbar -->
|
||||||
<v-toolbar color="toolbar" :title="$t('dialog.explore_accounts')" flat>
|
<v-toolbar color="toolbar" :title="$t('dialog.explore_accounts')" flat>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<v-tooltip :text="$t('dialog.back')" location="bottom">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text"
|
||||||
|
icon="mdi-arrow-right" />
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
</template>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn icon @click="loadNode('root', 'calc', true, 1)" :title="$t('button.back_to_root')">
|
<v-btn icon @click="loadNode('root', 'calc', true, 1)" :title="$t('button.back_to_root')">
|
||||||
<v-icon>mdi-home</v-icon>
|
<v-icon>mdi-home</v-icon>
|
||||||
|
|
|
@ -2,132 +2,201 @@
|
||||||
<v-card :loading="loading ? 'red' : null" :disabled="loading">
|
<v-card :loading="loading ? 'red' : null" :disabled="loading">
|
||||||
<!-- Toolbar -->
|
<!-- Toolbar -->
|
||||||
<v-toolbar color="toolbar" title="گزارش فروش" flat>
|
<v-toolbar color="toolbar" title="گزارش فروش" flat>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<v-tooltip :text="$t('dialog.back')" location="bottom">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text"
|
||||||
|
icon="mdi-arrow-right" />
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
</template>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn icon @click="exportReport" :loading="exporting" :disabled="loading" title="دانلود گزارش">
|
|
||||||
<v-icon>mdi-download</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
|
|
||||||
<!-- Date Filter -->
|
<!-- Filters Section -->
|
||||||
<v-card-text class="pt-0">
|
<v-card-text class="pt-2">
|
||||||
<v-card variant="outlined" class="mb-4 date-filter-card">
|
<v-expansion-panels variant="accordion" class="mb-4">
|
||||||
<v-card-title class="text-subtitle-1 font-weight-medium pa-4 pb-2">
|
<v-expansion-panel>
|
||||||
<v-icon icon="mdi-calendar-filter" class="me-2" color="primary"></v-icon>
|
<v-expansion-panel-title class="filters-panel-title">
|
||||||
فیلتر بر اساس تاریخ
|
<div class="d-flex align-center">
|
||||||
<v-chip
|
<v-icon icon="mdi-filter-variant" class="me-2" color="primary"></v-icon>
|
||||||
v-if="isDateFilterActive"
|
<span class="font-weight-medium">فیلترهای گزارش</span>
|
||||||
color="success"
|
<v-chip
|
||||||
size="small"
|
v-if="isAnyFilterActive"
|
||||||
class="ms-2"
|
color="success"
|
||||||
prepend-icon="mdi-check-circle"
|
size="small"
|
||||||
>
|
class="ms-2"
|
||||||
فعال
|
prepend-icon="mdi-check-circle"
|
||||||
</v-chip>
|
>
|
||||||
</v-card-title>
|
فعال
|
||||||
<v-card-text class="pt-0">
|
</v-chip>
|
||||||
<v-row>
|
</div>
|
||||||
<v-col cols="12" sm="6" md="4" class="date-picker-container">
|
</v-expansion-panel-title>
|
||||||
<v-text-field
|
<v-expansion-panel-text>
|
||||||
:model-value="formattedStartDate"
|
<v-card variant="outlined" class="filters-card">
|
||||||
label="تاریخ شروع"
|
<v-card-text class="pt-0">
|
||||||
prepend-inner-icon="mdi-calendar"
|
<v-row>
|
||||||
readonly
|
<!-- Date Filters -->
|
||||||
@click="showStartDatePicker = true"
|
<v-col cols="12">
|
||||||
variant="outlined"
|
<div class="text-caption text-medium-emphasis mb-3">
|
||||||
density="comfortable"
|
<v-icon size="small" class="me-1">mdi-calendar</v-icon>
|
||||||
/>
|
فیلتر بر اساس تاریخ
|
||||||
<v-dialog v-model="showStartDatePicker" max-width="400">
|
</div>
|
||||||
<v-date-picker
|
<v-row>
|
||||||
v-model="gregorianStartDate"
|
<v-col cols="12" sm="6" md="3" class="date-picker-container">
|
||||||
:min="convertJalaliToGregorian(year.start)"
|
<v-text-field
|
||||||
:max="convertJalaliToGregorian(year.end)"
|
:model-value="formattedStartDate"
|
||||||
locale="fa"
|
label="تاریخ شروع"
|
||||||
color="primary"
|
prepend-inner-icon="mdi-calendar-start"
|
||||||
@update:model-value="(value) => {
|
readonly
|
||||||
dateFilter.startDate = convertGregorianToJalali(value);
|
@click="showStartDatePicker = true"
|
||||||
gregorianStartDate = value;
|
variant="outlined"
|
||||||
showStartDatePicker = false;
|
density="comfortable"
|
||||||
}"
|
class="filter-field"
|
||||||
/>
|
/>
|
||||||
</v-dialog>
|
<v-dialog v-model="showStartDatePicker" max-width="400">
|
||||||
</v-col>
|
<v-date-picker
|
||||||
<v-col cols="12" sm="6" md="4" class="date-picker-container">
|
v-model="gregorianStartDate"
|
||||||
<v-text-field
|
:min="convertJalaliToGregorian(year.start)"
|
||||||
:model-value="formattedEndDate"
|
:max="convertJalaliToGregorian(year.end)"
|
||||||
label="تاریخ پایان"
|
locale="fa"
|
||||||
prepend-inner-icon="mdi-calendar"
|
color="primary"
|
||||||
readonly
|
@update:model-value="(value) => {
|
||||||
@click="showEndDatePicker = true"
|
dateFilter.startDate = convertGregorianToJalali(value);
|
||||||
variant="outlined"
|
gregorianStartDate = value;
|
||||||
density="comfortable"
|
showStartDatePicker = false;
|
||||||
/>
|
}"
|
||||||
<v-dialog v-model="showEndDatePicker" max-width="400">
|
/>
|
||||||
<v-date-picker
|
</v-dialog>
|
||||||
v-model="gregorianEndDate"
|
</v-col>
|
||||||
:min="convertJalaliToGregorian(dateFilter.startDate || year.start)"
|
<v-col cols="12" sm="6" md="3" class="date-picker-container">
|
||||||
:max="convertJalaliToGregorian(year.end)"
|
<v-text-field
|
||||||
locale="fa"
|
:model-value="formattedEndDate"
|
||||||
color="primary"
|
label="تاریخ پایان"
|
||||||
@update:model-value="(value) => {
|
prepend-inner-icon="mdi-calendar-end"
|
||||||
dateFilter.endDate = convertGregorianToJalali(value);
|
readonly
|
||||||
gregorianEndDate = value;
|
@click="showEndDatePicker = true"
|
||||||
showEndDatePicker = false;
|
variant="outlined"
|
||||||
}"
|
density="comfortable"
|
||||||
/>
|
class="filter-field"
|
||||||
</v-dialog>
|
/>
|
||||||
</v-col>
|
<v-dialog v-model="showEndDatePicker" max-width="400">
|
||||||
|
<v-date-picker
|
||||||
|
v-model="gregorianEndDate"
|
||||||
|
:min="convertJalaliToGregorian(dateFilter.startDate || year.start)"
|
||||||
|
:max="convertJalaliToGregorian(year.end)"
|
||||||
|
locale="fa"
|
||||||
|
color="primary"
|
||||||
|
@update:model-value="(value) => {
|
||||||
|
dateFilter.endDate = convertGregorianToJalali(value);
|
||||||
|
gregorianEndDate = value;
|
||||||
|
showEndDatePicker = false;
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</v-dialog>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
</v-row>
|
<!-- Other Filters -->
|
||||||
</v-card-text>
|
<v-col cols="12">
|
||||||
</v-card>
|
<v-divider class="mb-3"></v-divider>
|
||||||
</v-card-text>
|
<div class="text-caption text-medium-emphasis mb-3">
|
||||||
|
<v-icon size="small" class="me-1">mdi-tune</v-icon>
|
||||||
|
فیلترهای اضافی
|
||||||
|
</div>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12" sm="6" md="3">
|
||||||
|
<Hpersonsearch
|
||||||
|
v-model="filters.customerId"
|
||||||
|
label="مشتری"
|
||||||
|
:return-object="false"
|
||||||
|
:rules="[]"
|
||||||
|
class="filter-field"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col v-if="business.requireTwoStepApproval" cols="12" sm="6" md="3">
|
||||||
|
<v-select
|
||||||
|
v-model="filters.status"
|
||||||
|
:items="statusOptions"
|
||||||
|
item-title="text"
|
||||||
|
item-value="value"
|
||||||
|
label="وضعیت فاکتور"
|
||||||
|
prepend-inner-icon="mdi-check-circle"
|
||||||
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
|
clearable
|
||||||
|
class="filter-field"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="business.requireTwoStepApproval ? 6 : 3" md="3">
|
||||||
|
<v-select
|
||||||
|
v-model="filters.groupBy"
|
||||||
|
:items="groupByOptions"
|
||||||
|
item-title="text"
|
||||||
|
item-value="value"
|
||||||
|
label="گروهبندی نمودار"
|
||||||
|
prepend-inner-icon="mdi-chart-line"
|
||||||
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
|
class="filter-field"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="business.requireTwoStepApproval ? 6 : 3" md="3">
|
||||||
|
<v-select
|
||||||
|
v-model="chartType"
|
||||||
|
:items="chartTypeOptions"
|
||||||
|
item-title="text"
|
||||||
|
item-value="value"
|
||||||
|
label="نوع نمودار"
|
||||||
|
prepend-inner-icon="mdi-chart-bar"
|
||||||
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
|
class="filter-field"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
<!-- Additional Filters -->
|
<!-- Quick Actions -->
|
||||||
<v-card-text class="pt-0">
|
<v-col cols="12">
|
||||||
<v-row>
|
<v-divider class="mb-3"></v-divider>
|
||||||
<v-col cols="12" md="3">
|
<div class="d-flex justify-space-between align-center">
|
||||||
<Hpersonsearch
|
<div class="text-caption text-medium-emphasis">
|
||||||
v-model="filters.customerId"
|
<v-icon size="small" class="me-1">mdi-lightning-bolt</v-icon>
|
||||||
label="مشتری"
|
عملیات سریع
|
||||||
:return-object="false"
|
</div>
|
||||||
:rules="[]"
|
<div class="d-flex gap-2">
|
||||||
/>
|
<v-btn
|
||||||
</v-col>
|
size="small"
|
||||||
<v-col cols="12" md="3">
|
variant="outlined"
|
||||||
<v-select
|
color="primary"
|
||||||
v-model="filters.status"
|
prepend-icon="mdi-refresh"
|
||||||
:items="statusOptions"
|
@click="loadData"
|
||||||
item-title="text"
|
:loading="loading"
|
||||||
item-value="value"
|
>
|
||||||
label="وضعیت"
|
بهروزرسانی
|
||||||
outlined
|
</v-btn>
|
||||||
dense
|
<v-btn
|
||||||
clearable
|
size="small"
|
||||||
></v-select>
|
variant="outlined"
|
||||||
</v-col>
|
color="success"
|
||||||
<v-col cols="12" md="3">
|
prepend-icon="mdi-download"
|
||||||
<v-select
|
@click="exportReport"
|
||||||
v-model="filters.groupBy"
|
:loading="exporting"
|
||||||
:items="groupByOptions"
|
:disabled="loading"
|
||||||
item-title="text"
|
>
|
||||||
item-value="value"
|
دانلود گزارش
|
||||||
label="گروهبندی نمودار"
|
</v-btn>
|
||||||
outlined
|
</div>
|
||||||
dense
|
</div>
|
||||||
></v-select>
|
</v-col>
|
||||||
</v-col>
|
</v-row>
|
||||||
<v-col cols="12" md="3">
|
</v-card-text>
|
||||||
<v-select
|
</v-card>
|
||||||
v-model="chartType"
|
</v-expansion-panel-text>
|
||||||
:items="chartTypeOptions"
|
</v-expansion-panel>
|
||||||
item-title="text"
|
</v-expansion-panels>
|
||||||
item-value="value"
|
|
||||||
label="نوع نمودار"
|
|
||||||
outlined
|
|
||||||
dense
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
||||||
<!-- Summary Cards -->
|
<!-- Summary Cards -->
|
||||||
|
@ -272,10 +341,10 @@
|
||||||
</template>
|
</template>
|
||||||
<template #item.status="{ item }">
|
<template #item.status="{ item }">
|
||||||
<v-chip
|
<v-chip
|
||||||
:color="item.isApproved ? 'success' : 'warning'"
|
:color="getApprovalStatusColor(item)"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
{{ item.isApproved ? 'تایید شده' : 'پیشنمایش' }}
|
{{ getApprovalStatusText(item) }}
|
||||||
</v-chip>
|
</v-chip>
|
||||||
</template>
|
</template>
|
||||||
<template #item.actions="{ item }">
|
<template #item.actions="{ item }">
|
||||||
|
@ -349,6 +418,9 @@ export default {
|
||||||
errorDialog: false,
|
errorDialog: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
|
|
||||||
|
// Business Info
|
||||||
|
business: { requireTwoStepApproval: false },
|
||||||
|
|
||||||
// Date Filter
|
// Date Filter
|
||||||
dateFilter: {
|
dateFilter: {
|
||||||
startDate: '',
|
startDate: '',
|
||||||
|
@ -464,31 +536,31 @@ export default {
|
||||||
],
|
],
|
||||||
|
|
||||||
productHeaders: [
|
productHeaders: [
|
||||||
{ text: 'نام کالا', value: 'name' },
|
{ title: 'نام کالا', value: 'name', sortable: true, width: 200 },
|
||||||
{ text: 'کد', value: 'code' },
|
{ title: 'کد', value: 'code', sortable: true, width: 120 },
|
||||||
{ text: 'تعداد', value: 'totalCount' },
|
{ title: 'تعداد', value: 'totalCount', sortable: true, width: 100 },
|
||||||
{ text: 'مبلغ کل', value: 'totalAmount' },
|
{ title: 'مبلغ کل', value: 'totalAmount', sortable: true, width: 150 },
|
||||||
{ text: 'سود', value: 'profit' },
|
{ title: 'سود', value: 'profit', sortable: true, width: 150 },
|
||||||
{ text: 'درصد سود', value: 'profitMargin' }
|
{ title: 'درصد سود', value: 'profitMargin', sortable: true, width: 120 }
|
||||||
],
|
],
|
||||||
|
|
||||||
customerHeaders: [
|
customerHeaders: [
|
||||||
{ text: 'نام مشتری', value: 'name' },
|
{ title: 'نام مشتری', value: 'name', sortable: true, width: 200 },
|
||||||
{ text: 'کد', value: 'code' },
|
{ title: 'کد', value: 'code', sortable: true, width: 120 },
|
||||||
{ text: 'تعداد فاکتور', value: 'invoiceCount' },
|
{ title: 'تعداد فاکتور', value: 'invoiceCount', sortable: true, width: 120 },
|
||||||
{ text: 'مبلغ کل', value: 'totalAmount' },
|
{ title: 'مبلغ کل', value: 'totalAmount', sortable: true, width: 150 },
|
||||||
{ text: 'میانگین فاکتور', value: 'averageAmount' }
|
{ title: 'میانگین فاکتور', value: 'averageAmount', sortable: true, width: 150 }
|
||||||
],
|
],
|
||||||
|
|
||||||
invoiceHeaders: [
|
invoiceHeaders: [
|
||||||
{ text: 'شماره فاکتور', value: 'code' },
|
{ title: 'شماره فاکتور', value: 'code', sortable: true, width: 120 },
|
||||||
{ text: 'تاریخ', value: 'date' },
|
{ title: 'تاریخ', value: 'date', sortable: true, width: 120 },
|
||||||
{ text: 'مشتری', value: 'customer.name' },
|
{ title: 'مشتری', value: 'customer.name', sortable: true, width: 150 },
|
||||||
{ text: 'مبلغ', value: 'amount' },
|
{ title: 'مبلغ', value: 'amount', sortable: true, width: 150 },
|
||||||
{ text: 'سود', value: 'profit' },
|
{ title: 'سود', value: 'profit', sortable: true, width: 150 },
|
||||||
{ text: 'درصد سود', value: 'profitMargin' },
|
{ title: 'درصد سود', value: 'profitMargin', sortable: true, width: 120 },
|
||||||
{ text: 'وضعیت', value: 'status' },
|
{ title: 'وضعیت', value: 'status', sortable: true, width: 120 },
|
||||||
{ text: 'عملیات', value: 'actions', sortable: false }
|
{ title: 'عملیات', value: 'actions', sortable: false, width: 100 }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -498,6 +570,13 @@ export default {
|
||||||
return this.dateFilter.startDate && this.dateFilter.endDate &&
|
return this.dateFilter.startDate && this.dateFilter.endDate &&
|
||||||
(this.dateFilter.startDate !== this.year.start || this.dateFilter.endDate !== this.year.end);
|
(this.dateFilter.startDate !== this.year.start || this.dateFilter.endDate !== this.year.end);
|
||||||
},
|
},
|
||||||
|
isAnyFilterActive() {
|
||||||
|
return this.isDateFilterActive ||
|
||||||
|
this.filters.customerId ||
|
||||||
|
this.filters.status ||
|
||||||
|
this.filters.groupBy !== 'day' ||
|
||||||
|
this.chartType !== 'amount';
|
||||||
|
},
|
||||||
formattedStartDate() {
|
formattedStartDate() {
|
||||||
return this.dateFilter.startDate ? this.formatDateForDisplay(this.dateFilter.startDate) : '';
|
return this.dateFilter.startDate ? this.formatDateForDisplay(this.dateFilter.startDate) : '';
|
||||||
},
|
},
|
||||||
|
@ -507,9 +586,10 @@ export default {
|
||||||
totalInvoicePages() {
|
totalInvoicePages() {
|
||||||
return Math.ceil(this.totalInvoices / 20);
|
return Math.ceil(this.totalInvoices / 20);
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|
},
|
||||||
// Watchers for automatic filter updates
|
|
||||||
|
// Watchers for automatic filter updates
|
||||||
watch: {
|
watch: {
|
||||||
'filters.customerId'() {
|
'filters.customerId'() {
|
||||||
this.loadData();
|
this.loadData();
|
||||||
|
@ -567,6 +647,22 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// متدهای مربوط به وضعیت تایید
|
||||||
|
getApprovalStatusText(item) {
|
||||||
|
if (!this.business?.requireTwoStepApproval) return 'تایید دو مرحلهای غیرفعال';
|
||||||
|
|
||||||
|
if (item.isPreview) return 'در انتظار تایید';
|
||||||
|
if (item.isApproved) return 'تایید شده';
|
||||||
|
return 'تایید شده';
|
||||||
|
},
|
||||||
|
getApprovalStatusColor(item) {
|
||||||
|
if (!this.business?.requireTwoStepApproval) return 'default';
|
||||||
|
|
||||||
|
if (item.isPreview) return 'warning';
|
||||||
|
if (item.isApproved) return 'success';
|
||||||
|
return 'success';
|
||||||
|
},
|
||||||
|
|
||||||
async loadInitialData() {
|
async loadInitialData() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
|
@ -574,6 +670,10 @@ export default {
|
||||||
const yearResponse = await axios.get('/api/year/get');
|
const yearResponse = await axios.get('/api/year/get');
|
||||||
this.year = yearResponse.data;
|
this.year = yearResponse.data;
|
||||||
|
|
||||||
|
// دریافت اطلاعات کسب و کار
|
||||||
|
const businessResponse = await axios.get('/api/business/get/info/' + localStorage.getItem('activeBid'));
|
||||||
|
this.business = businessResponse.data || { requireTwoStepApproval: false };
|
||||||
|
|
||||||
// تنظیم تاریخهای پیشفرض
|
// تنظیم تاریخهای پیشفرض
|
||||||
this.dateFilter.startDate = this.year.start;
|
this.dateFilter.startDate = this.year.start;
|
||||||
this.dateFilter.endDate = this.year.end;
|
this.dateFilter.endDate = this.year.end;
|
||||||
|
@ -861,14 +961,30 @@ export default {
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.date-filter-card {
|
.filters-panel-title {
|
||||||
|
background: linear-gradient(135deg, #f8fafc, #f1f5f9);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters-panel-title:hover {
|
||||||
|
background: linear-gradient(135deg, #eff6ff, #f0f7ff);
|
||||||
|
border-color: #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters-card {
|
||||||
border-left: 4px solid #1976d2;
|
border-left: 4px solid #1976d2;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
background: linear-gradient(135deg, #f8fafc, #f1f5f9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-buttons {
|
.filter-field {
|
||||||
gap: 8px;
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-field:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.date-picker-container {
|
.date-picker-container {
|
||||||
|
@ -897,8 +1013,36 @@ export default {
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gap-2 {
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expansion Panel Styles */
|
||||||
|
:deep(.v-expansion-panels) {
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.v-expansion-panel) {
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.v-expansion-panel-title) {
|
||||||
|
min-height: 56px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.v-expansion-panel-text__wrapper) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.v-expansion-panels__item) {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.filter-buttons {
|
.gap-2 {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue