bug fix clock,add cost and income data to dashboard

This commit is contained in:
Hesabix 2025-03-14 15:45:19 +00:00
parent 7d5eb9379e
commit b3de30b3e7
5 changed files with 243 additions and 33 deletions

View file

@ -75,9 +75,6 @@ class CostController extends AbstractController
// هزینه سال مالی // هزینه سال مالی
$yearCost = (clone $qb) $yearCost = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $yearStart)
->setParameter('end', $yearEnd)
->getQuery() ->getQuery()
->getSingleScalarResult() ?? 0; ->getSingleScalarResult() ?? 0;
@ -106,22 +103,11 @@ class CostController extends AbstractController
$period = $request->query->get('period', 'today'); // پیش‌فرض: امروز $period = $request->query->get('period', 'today'); // پیش‌فرض: امروز
$limit = (int) $request->query->get('limit', 10); // پیش‌فرض: 10 $limit = (int) $request->query->get('limit', 10); // پیش‌فرض: 10
// تاریخ‌های شمسی // تاریخ‌های شمسی برای امروز و ماه
$today = $jdate->jdate('Y/m/d', time()); $today = $jdate->jdate('Y/m/d', time());
$monthStart = $jdate->jdate('Y/m/01', time()); $monthStart = $jdate->jdate('Y/m/01', time());
$yearStartUnix = (int) $acc['year']->getStart();
$yearEndUnix = (int) $acc['year']->getEnd();
$yearStart = $jdate->jdate('Y/m/d', $yearStartUnix);
$yearEnd = $jdate->jdate('Y/m/d', $yearEndUnix);
// تنظیم بازه زمانی بر اساس فیلتر
$dateCondition = match ($period) {
'month' => 'd.date BETWEEN :start AND :end',
'year' => 'd.date BETWEEN :start AND :end',
'today' => 'd.date = :date',
default => 'd.date = :date',
};
// پارامترهای پایه
$parameters = [ $parameters = [
'bid' => $acc['bid'], 'bid' => $acc['bid'],
'money' => $acc['money'], 'money' => $acc['money'],
@ -129,32 +115,31 @@ class CostController extends AbstractController
'year' => $acc['year'], 'year' => $acc['year'],
]; ];
if ($period === 'month') { // کوئری پایه
$parameters['start'] = $monthStart;
$parameters['end'] = $today;
} elseif ($period === 'year') {
$parameters['start'] = $yearStart;
$parameters['end'] = $yearEnd;
} else { // today
$parameters['date'] = $today;
}
// کوئری برای محاسبه مراکز هزینه برتر
$qb = $entityManager->createQueryBuilder() $qb = $entityManager->createQueryBuilder()
->select('t.name AS center_name, SUM(COALESCE(r.bd, 0)) AS total_cost') ->select('t.name AS center_name, SUM(COALESCE(r.bd, 0)) AS total_cost')
->from('App\Entity\HesabdariDoc', 'd') ->from('App\Entity\HesabdariDoc', 'd')
->join('d.hesabdariRows', 'r') ->join('d.hesabdariRows', 'r')
->join('r.ref', 't') // ارتباط با HesabdariTable از طریق ref ->join('r.ref', 't') // ارتباط با HesabdariTable
->where('d.bid = :bid') ->where('d.bid = :bid')
->andWhere('d.money = :money') ->andWhere('d.money = :money')
->andWhere('d.type = :type') ->andWhere('d.type = :type')
->andWhere('d.year = :year') ->andWhere('d.year = :year')
->andWhere('t.type = :tableType') // فقط مراکز هزینه ->andWhere('r.bd != 0')
->andWhere($dateCondition)
->groupBy('t.id, t.name') ->groupBy('t.id, t.name')
->orderBy('total_cost', 'DESC') ->orderBy('total_cost', 'DESC')
->setParameters($parameters + ['tableType' => 'cost_center']); // فرض بر اینکه نوع مرکز هزینه 'cost_center' است ->setParameters($parameters);
// اگر نوع دیگری در HesabdariTable برای مراکز هزینه استفاده شده، باید جایگزین شود
// اعمال فیلتر تاریخ فقط برای امروز و ماه
if ($period === 'today') {
$qb->andWhere('d.date = :date')
->setParameter('date', $today);
} elseif ($period === 'month') {
$qb->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $monthStart)
->setParameter('end', $today);
}
// برای 'year' نیازی به شرط تاریخ نیست، چون year و type کافی است
if ($limit > 0) { if ($limit > 0) {
$qb->setMaxResults($limit); $qb->setMaxResults($limit);

View file

@ -64,7 +64,10 @@ class DashboardController extends AbstractController
if(array_key_exists('notif',$params)) $setting->setNotif($params['notif']); if(array_key_exists('notif',$params)) $setting->setNotif($params['notif']);
if(array_key_exists('sellChart',$params)) $setting->setSellChart($params['sellChart']); if(array_key_exists('sellChart',$params)) $setting->setSellChart($params['sellChart']);
if(array_key_exists('topCommodities',$params)) $setting->setTopCommoditiesChart($params['topCommodities']); if(array_key_exists('topCommodities',$params)) $setting->setTopCommoditiesChart($params['topCommodities']);
if(array_key_exists('costs',$params)) $setting->setCasts($params['costs']); if(array_key_exists('costs',$params)) $setting->setCosts($params['costs']);
if(array_key_exists('topCostCenters',$params)) $setting->setTopCostCenters($params['topCostCenters']);
if(array_key_exists('incomes',$params)) $setting->setIncomes($params['incomes']);
if(array_key_exists('topIncomeCenters',$params)) $setting->setTopIncomesChart($params['topIncomeCenters']);
$entityManagerInterface->persist($setting); $entityManagerInterface->persist($setting);
$entityManagerInterface->flush(); $entityManagerInterface->flush();

View file

@ -0,0 +1,167 @@
<?php
namespace App\Controller;
use App\Service\Access;
use App\Service\Jdate;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class IncomeController extends AbstractController
{
#[Route('/api/income/dashboard/data', name: 'app_income_dashboard_data', methods: ['GET'])]
public function getIncomeDashboardData(
Request $request,
Access $access,
Jdate $jdate,
EntityManagerInterface $entityManager
): JsonResponse {
// بررسی دسترسی کاربر
$acc = $access->hasRole('income');
if (!$acc) {
throw $this->createAccessDeniedException();
}
// تاریخ‌های شمسی برای امروز، هفته و ماه
$today = $jdate->jdate('Y/m/d', time());
$weekStart = $jdate->jdate('Y/m/d', strtotime('-6 days'));
$monthStart = $jdate->jdate('Y/m/01', time());
// تاریخ شروع و پایان سال مالی از $acc['year'] و تبدیل به شمسی
$yearStartUnix = (int) $acc['year']->getStart();
$yearEndUnix = (int) $acc['year']->getEnd();
$yearStart = $jdate->jdate('Y/m/d', $yearStartUnix);
$yearEnd = $jdate->jdate('Y/m/d', $yearEndUnix);
// کوئری پایه - جمع bs را محاسبه می‌کنیم
$qb = $entityManager->createQueryBuilder()
->select('SUM(COALESCE(r.bs, 0)) as total')
->from('App\Entity\HesabdariDoc', 'd')
->join('d.hesabdariRows', 'r')
->where('d.bid = :bid')
->andWhere('d.money = :money')
->andWhere('d.type = :type')
->andWhere('d.year = :year')
->andWhere('r.bs != 0') // فقط ردیف‌هایی که bs صفر نیست
->setParameter('bid', $acc['bid'])
->setParameter('money', $acc['money'])
->setParameter('type', 'income')
->setParameter('year', $acc['year']);
// درآمد امروز
$todayIncome = (clone $qb)
->andWhere('d.date = :date')
->setParameter('date', $today)
->getQuery()
->getSingleScalarResult() ?? 0;
// درآمد این هفته
$weekIncome = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $weekStart)
->setParameter('end', $today)
->getQuery()
->getSingleScalarResult() ?? 0;
// درآمد این ماه
$monthIncome = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $monthStart)
->setParameter('end', $today)
->getQuery()
->getSingleScalarResult() ?? 0;
// درآمد سال مالی
$yearIncome = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $yearStart)
->setParameter('end', $yearEnd)
->getQuery()
->getSingleScalarResult() ?? 0;
return $this->json([
'today' => (int) $todayIncome,
'week' => (int) $weekIncome,
'month' => (int) $monthIncome,
'year' => (int) $yearIncome,
]);
}
#[Route('/api/income/top-centers', name: 'app_income_top_centers', methods: ['GET'])]
public function getTopIncomeCenters(
Request $request,
Access $access,
Jdate $jdate,
EntityManagerInterface $entityManager
): JsonResponse {
// بررسی دسترسی کاربر
$acc = $access->hasRole('income');
if (!$acc) {
throw $this->createAccessDeniedException();
}
// پارامترهای درخواست
$period = $request->query->get('period', 'today'); // پیش‌فرض: امروز
$limit = (int) $request->query->get('limit', 10); // پیش‌فرض: 10
// تاریخ‌های شمسی برای امروز و ماه
$today = $jdate->jdate('Y/m/d', time());
$monthStart = $jdate->jdate('Y/m/01', time());
// پارامترهای پایه
$parameters = [
'bid' => $acc['bid'],
'money' => $acc['money'],
'type' => 'income',
'year' => $acc['year'],
];
// کوئری پایه
$qb = $entityManager->createQueryBuilder()
->select('t.name AS center_name, SUM(COALESCE(r.bs, 0)) AS total_income')
->from('App\Entity\HesabdariDoc', 'd')
->join('d.hesabdariRows', 'r')
->join('r.ref', 't') // ارتباط با HesabdariTable
->where('d.bid = :bid')
->andWhere('d.money = :money')
->andWhere('d.type = :type')
->andWhere('d.year = :year')
->andWhere('r.bs != 0') // فقط ردیف‌هایی که bs صفر نیست
->groupBy('t.id, t.name')
->orderBy('total_income', 'DESC')
->setParameters($parameters);
// اعمال فیلتر تاریخ فقط برای امروز و ماه
if ($period === 'today') {
$qb->andWhere('d.date = :date')
->setParameter('date', $today);
} elseif ($period === 'month') {
$qb->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $monthStart)
->setParameter('end', $today);
}
// برای 'year' نیازی به شرط تاریخ نیست، چون year و type کافی است
if ($limit > 0) {
$qb->setMaxResults($limit);
}
$results = $qb->getQuery()->getResult();
// آماده‌سازی داده‌ها برای نمودار
$labels = [];
$series = [];
foreach ($results as $row) {
$labels[] = $row['center_name'];
$series[] = (int) $row['total_income'];
}
return $this->json([
'labels' => $labels,
'series' => $series,
]);
}
}

View file

@ -57,6 +57,15 @@ class DashboardSettings
#[ORM\Column(nullable: true)] #[ORM\Column(nullable: true)]
private ?bool $costs = null; private ?bool $costs = null;
#[ORM\Column(nullable: true)]
private ?bool $topCostCenters = null;
#[ORM\Column(nullable: true)]
private ?bool $incomes = null;
#[ORM\Column(nullable: true)]
private ?bool $topIncomesChart = null;
public function getId(): ?int public function getId(): ?int
{ {
return $this->id; return $this->id;
@ -229,4 +238,40 @@ class DashboardSettings
return $this; return $this;
} }
public function isTopCostCenters(): ?bool
{
return $this->topCostCenters;
}
public function setTopCostCenters(?bool $topCostCenters): static
{
$this->topCostCenters = $topCostCenters;
return $this;
}
public function isIncomes(): ?bool
{
return $this->incomes;
}
public function setIncomes(?bool $incomes): static
{
$this->incomes = $incomes;
return $this;
}
public function isTopIncomesChart(): ?bool
{
return $this->topIncomesChart;
}
public function setTopIncomesChart(?bool $topIncomesChart): static
{
$this->topIncomesChart = $topIncomesChart;
return $this;
}
} }

View file

@ -590,6 +590,9 @@ class Explore
'sellChart' => $item->isSellChart(), 'sellChart' => $item->isSellChart(),
'topCommodities' => $item->isTopCommoditiesChart(), 'topCommodities' => $item->isTopCommoditiesChart(),
'costs' => $item->isCosts(), 'costs' => $item->isCosts(),
'topCostCenters' => $item->isTopCostCenters(),
'incomes' => $item->isIncomes(),
'topIncomeCenters' => $item->isTopIncomesChart(),
]; ];
if ($result['topCommodities'] === null) if ($result['topCommodities'] === null)
$result['topCommodities'] = true; $result['topCommodities'] = true;
@ -615,6 +618,13 @@ class Explore
$result['sellChart'] = true; $result['sellChart'] = true;
if ($result['costs'] === null) if ($result['costs'] === null)
$result['costs'] = true; $result['costs'] = true;
if ($result['topCostCenters'] === null)
$result['topCostCenters'] = true;
if ($result['incomes'] === null)
$result['incomes'] = true;
if ($result['topIncomeCenters'] === null)
$result['topIncomeCenters'] = true;
return $result; return $result;
} }