progress in costChart

This commit is contained in:
Hesabix 2025-03-14 11:21:43 +00:00
parent 41084ea4b1
commit 7d5eb9379e
4 changed files with 186 additions and 2 deletions

View file

@ -2,11 +2,177 @@
namespace App\Controller; namespace App\Controller;
use App\Service\Access;
use App\Service\Jdate;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
class CostController extends AbstractController class CostController extends AbstractController
{ {
#[Route('/api/cost/dashboard/data', name: 'app_cost_dashboard_data', methods: ['GET'])]
public function getCostDashboardData(
Request $request,
Access $access,
Jdate $jdate,
EntityManagerInterface $entityManager
): JsonResponse {
// بررسی دسترسی کاربر
$acc = $access->hasRole('cost');
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);
// کوئری پایه - فقط جمع bd را محاسبه می‌کنیم
$qb = $entityManager->createQueryBuilder()
->select('SUM(COALESCE(r.bd, 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')
->setParameter('bid', $acc['bid'])
->setParameter('money', $acc['money'])
->setParameter('type', 'cost')
->setParameter('year', $acc['year']);
// هزینه امروز
$todayCost = (clone $qb)
->andWhere('d.date = :date')
->setParameter('date', $today)
->getQuery()
->getSingleScalarResult() ?? 0;
// هزینه این هفته
$weekCost = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $weekStart)
->setParameter('end', $today)
->getQuery()
->getSingleScalarResult() ?? 0;
// هزینه این ماه
$monthCost = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $monthStart)
->setParameter('end', $today)
->getQuery()
->getSingleScalarResult() ?? 0;
// هزینه سال مالی
$yearCost = (clone $qb)
->andWhere('d.date BETWEEN :start AND :end')
->setParameter('start', $yearStart)
->setParameter('end', $yearEnd)
->getQuery()
->getSingleScalarResult() ?? 0;
return $this->json([
'today' => (int) $todayCost,
'week' => (int) $weekCost,
'month' => (int) $monthCost,
'year' => (int) $yearCost,
]);
}
#[Route('/api/cost/top-centers', name: 'app_cost_top_centers', methods: ['GET'])]
public function getTopCostCenters(
Request $request,
Access $access,
Jdate $jdate,
EntityManagerInterface $entityManager
): JsonResponse {
// بررسی دسترسی کاربر
$acc = $access->hasRole('cost');
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());
$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 = [
'bid' => $acc['bid'],
'money' => $acc['money'],
'type' => 'cost',
'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()
->select('t.name AS center_name, SUM(COALESCE(r.bd, 0)) AS total_cost')
->from('App\Entity\HesabdariDoc', 'd')
->join('d.hesabdariRows', 'r')
->join('r.ref', 't') // ارتباط با HesabdariTable از طریق ref
->where('d.bid = :bid')
->andWhere('d.money = :money')
->andWhere('d.type = :type')
->andWhere('d.year = :year')
->andWhere('t.type = :tableType') // فقط مراکز هزینه
->andWhere($dateCondition)
->groupBy('t.id, t.name')
->orderBy('total_cost', 'DESC')
->setParameters($parameters + ['tableType' => 'cost_center']); // فرض بر اینکه نوع مرکز هزینه 'cost_center' است
// اگر نوع دیگری در HesabdariTable برای مراکز هزینه استفاده شده، باید جایگزین شود
if ($limit > 0) {
$qb->setMaxResults($limit);
}
$results = $qb->getQuery()->getResult();
// آماده‌سازی داده‌ها برای نمودار
$labels = [];
$series = [];
foreach ($results as $row) {
$labels[] = $row['center_name'];
$series[] = (int) $row['total_cost'];
}
return $this->json([
'labels' => $labels,
'series' => $series,
]);
}
} }

View file

@ -64,6 +64,7 @@ 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']);
$entityManagerInterface->persist($setting); $entityManagerInterface->persist($setting);
$entityManagerInterface->flush(); $entityManagerInterface->flush();

View file

@ -54,6 +54,9 @@ class DashboardSettings
#[ORM\Column(nullable: true)] #[ORM\Column(nullable: true)]
private ?bool $topCommoditiesChart = null; private ?bool $topCommoditiesChart = null;
#[ORM\Column(nullable: true)]
private ?bool $costs = null;
public function getId(): ?int public function getId(): ?int
{ {
return $this->id; return $this->id;
@ -214,4 +217,16 @@ class DashboardSettings
return $this; return $this;
} }
public function isCosts(): ?bool
{
return $this->costs;
}
public function setCosts(?bool $costs): static
{
$this->costs = $costs;
return $this;
}
} }

View file

@ -589,6 +589,7 @@ class Explore
'notif' => $item->isNotif(), 'notif' => $item->isNotif(),
'sellChart' => $item->isSellChart(), 'sellChart' => $item->isSellChart(),
'topCommodities' => $item->isTopCommoditiesChart(), 'topCommodities' => $item->isTopCommoditiesChart(),
'costs' => $item->isCosts(),
]; ];
if ($result['topCommodities'] === null) if ($result['topCommodities'] === null)
$result['topCommodities'] = true; $result['topCommodities'] = true;
@ -612,7 +613,8 @@ class Explore
$result['notif'] = true; $result['notif'] = true;
if ($result['sellChart'] === null) if ($result['sellChart'] === null)
$result['sellChart'] = true; $result['sellChart'] = true;
if ($result['costs'] === null)
$result['costs'] = true;
return $result; return $result;
} }