<?php
namespace App\Controller\Admin;
use App\Entity\Clinic\Appointment;
use App\Entity\Clinic\Appointment\GoogleEvent;
use App\Entity\Clinic\Clinic;
use App\Entity\Clinic\Person\ClinicUser;
use App\Entity\Clinic\Stock\PriceList;
use App\Entity\Clinic\Stock\Product;
use App\Entity\Clinic\Stock\ProductBalanceHistory;
use App\Entity\Clinic\Stock\TreatmentClinic;
use App\Entity\Clinic\TaskBoard;
use App\Entity\Clinic\TaskBoard\TaskItem;
use App\Entity\LeadCapture\LeadCapture;
use App\Entity\Patient\BaseInvoice;
use App\Entity\Patient\CreditNote;
use App\Entity\Patient\GiftVoucher;
use App\Entity\Patient\Invoice;
use App\Entity\Patient\Invoice\Refund;
use App\Entity\Patient\Payment;
use App\Entity\Patient\Payment\Kind;
use App\Entity\Patient\Prepay;
use App\Entity\Person\Patient;
use App\Entity\Person\Setting;
use App\Entity\Person\SuperClinicAdmin;
use App\Form\Model\DashboardFilter;
use App\Form\Model\SearchFilter;
use App\Form\Type\Dashboard\DashboardFilterType;
use App\Form\Type\Model\BoardSearchClinicFilterType;
use App\Form\Type\Person\SettingType;
use App\HighCharts\TransformData;
use App\Services\CreateDefaultTaskBoard;
use App\Services\DashboardService;
use App\Services\Twilio;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Persistence\ManagerRegistry;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Twilio\Rest\Api\V2010\Account\MessageInstance;
use WhiteOctober\BreadcrumbsBundle\Model\Breadcrumbs;
use App\Entity\Person\User;
use App\Entity\SmsSetting;
/**
* Class DashboardController.
*
* @Route("/admin")
* @Security("is_granted('ROLE_SUB_DASHBOARD')")
*/
class DashboardController extends AbstractController
{
/**
* @var Breadcrumbs
*/
private $breadcrumbs;
/**
* @var CreateDefaultTaskBoard
*/
private $createDefaultTaskBoard;
/**
* @var DashboardService
*/
private $dashboardService;
public function __construct(
Breadcrumbs $breadcrumbs,
CreateDefaultTaskBoard $createDefaultTaskBoard,
DashboardService $dashboardService
) {
$this->breadcrumbs = $breadcrumbs;
$this->createDefaultTaskBoard = $createDefaultTaskBoard;
$this->dashboardService = $dashboardService;
}
/**
* @var ManagerRegistry
*/
private static $entityManager;
public static function setEntityManager(ManagerRegistry $entityManager)
{
self::$entityManager = $entityManager;
}
/**
* @Route("", name="dashboard_index")
* @Template()
*/
public function index(Request $request)
{
$user = $this->getUser();
// $connection = $this->getDoctrine()->getManager()->getConnection();
// $sql = "SELECT * FROM user WHERE id = :userId";
// $statement = $connection->prepare($sql);
// $statement->bindValue('userId', $user->getId());
// $statement->execute();
// $usr = $statement->fetch();
// $clinic = $this->getDoctrine()->getRepository(User::Class)->find($usr['clinic_id']);
$filter = new DashboardFilter();
$filter->addClinic($this->getClinic());
$filter->setDashboard(true);
$form = $this->createForm(DashboardFilterType::class, $filter, [
'timezone' => $this->getParameter('google_calendar_default_timezone'),
'user' => $this->getUser()
]);
$form->handleRequest($request);
if (0 == $filter->getClinics()->count() && ($user instanceof SuperClinicAdmin || $user->getRole() == User::ROLE_SUPER_CLINIC_ADMIN)) {
$user->getOrganisation()->getClinics()->map(function (Clinic $clinic) use (&$filter) {
$filter->addClinic($clinic);
});
}
if ($user instanceof ClinicUser && $user->getRole() != User::ROLE_SUPER_CLINIC_ADMIN) {
$filter->addClinic($user->getClinic());
}
$filter->getDateEnd()->setTime(23, 59, 59);
if ($filter->getDateEndSecond()) {
$filter->getDateEndSecond()->setTime(23, 59, 59);
}
$filter->getDateStart()->setTimezone(new \DateTimeZone('UTC'));
$filter->getDateEnd()->setTimezone(new \DateTimeZone('UTC'));
$filter->getDateStartSecond()->setTimezone(new \DateTimeZone('UTC'));
$filter->getDateEndSecond()->setTimezone(new \DateTimeZone('UTC'));
$setting = $this->getDoctrine()->getRepository(Setting::class)->findOneBy(['user' => $user]);
if (!$setting) {
$setting = new Setting();
$setting->setUser($user);
}
$settingsForm = $this->createForm(SettingType::class, $setting, [
'action' => $this->generateUrl('setting', ['redirect' => 1]),
'clinic' => $filter->getClinics()->count() ? $filter->getClinics()->first() : null,
]);
$breadcrumbs = $this->breadcrumbs;
$breadcrumbs->addItem('Dashboard');
$settingsList = $this->getDoctrine()->getRepository(Setting::class)->findOneBy(['user' => $this->getUser()]);
if ((!$settingsList || !$settingsList->getValue()) && $this->isGranted('ROLE_SUB_REPORTING')) {
$this->addFlash('warning', 'Please select Charts from the Dashboard Settings panel below');
}
$searchClinicFilter = new SearchFilter();
$searchClinicFilter->setCurrentUser($user);
$searchClinicFilter->setForMe((bool) $request->get('forMe'));
$formSearchClinic = $this->createForm(BoardSearchClinicFilterType::class, $searchClinicFilter, ['user' => $user]);
$formSearchClinic->handleRequest($request);
if ($user instanceof ClinicUser && $user->getRole() != User::ROLE_SUPER_CLINIC_ADMIN) {
$this->createDefaultTaskBoard->create($user->getClinic());
$searchClinicFilter->setClinic($user->getClinic());
} else {
if ($searchClinicFilter->getClinic()) {
$this->createDefaultTaskBoard->create($searchClinicFilter->getClinic());
}
}
if ($user->getRole() == User::ROLE_CONSENTZ_ADMIN) {
$clinic = '';
}else{
$clinic = $user->getClinic();
}
return [
'form' => $form->createView(),
'clinic' => $clinic,
'filter' => $filter,
'settingsForm' => $settingsForm->createView(),
'settingsList' => $settingsList ? $settingsList->getValue() : null,
'formTaskBoard' => ($user instanceof SuperClinicAdmin || $user->getRole() == User::ROLE_SUPER_CLINIC_ADMIN) ? $formSearchClinic->createView() : null,
'boardList' => $this->getDoctrine()->getRepository(TaskBoard::class)
->findBy(['clinic' => $searchClinicFilter->getClinic()], ['position' => Criteria::ASC]),
'taskList' => $this->getDoctrine()->getRepository(TaskItem::class)
->findTaskByFilter($searchClinicFilter),
'searchClinicFilter' => $searchClinicFilter,
];
}
/**
* @return Clinic|null
*/
private function getClinic()
{
return $this->getUser() instanceof ClinicUser ? $this->getUser()->getClinic() : null;
}
/**
* @return JsonResponse
*
* @Route("/dashboard/transaction", name="dashboard_transaction", options={"expose" = "true"}, methods={"POST"})
*/
public function transactions(Request $request)
{
$filter = $this->getFilter($request);
$filter->setNameReport(Setting::TRANSACTIONS);
$baseInvoice = $this->getDoctrine()->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$originalPaymentType = $this->getDoctrine()->getRepository(Kind::class)->findBy(['clinic' => $filter->getClinics()->getValues()]);
$arrOriginalType = [];
$criteriaDb = Criteria::create()->andWhere(
Criteria::expr()->andX(
Criteria::expr()->gte('createdAt', $filter->getDateStart()),
Criteria::expr()->lt('createdAt', $filter->getDateEnd())
)
);
/** @var Kind $type */
foreach ($originalPaymentType as $type) {
$arrOriginalType = array_merge($arrOriginalType, array_filter([$type->getType() => $type->getColor()]));
}
$data = [];
$resultData = [];
$result = [];
$categories = [];
$format = $this->dashboardService->createFormat($filter);
$datePayment = $this->dashboardService->createDefaultData($filter);
/* @var BaseInvoice $payment */
foreach ($baseInvoice as $item) {
if ($item instanceof Prepay && $item->getKind()) {
$dataType[] = $item->getKind()->getType();
}
if ($item instanceof Invoice) {
/** @var Payment $payment */
foreach ($item->getPayments()->matching($criteriaDb) as $payment) {
if (!$payment->isPrepay()) {
$dataType[] = $payment->getType()->getType();
}
}
}
}
if (isset($dataType)) {
$dataType = array_unique($dataType);
} else {
$dataType = array_column($this->getDoctrine()->getRepository(Kind::class)->findNamePaymentType($filter->getClinics()->getValues()), 'type');
}
/**
* @var string
* @var \DateTime $dateValue
*/
foreach ($datePayment as $dateItem => $dateValue) {
$date = $dateValue;
$name = null;
$arrSomeDate = [];
$defaultKeyValue = array_fill_keys($dataType, 0);
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $dateValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/* @var BaseInvoice $payment */
foreach ($baseInvoice as $item) {
if ($item instanceof Prepay && $item->getKind()) {
$type = $item->getKind()->getType();
if ($dateItem == $item->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $item->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$date = $item->getCreatedAt();
if (array_key_exists($type, $arrSomeDate)) {
$value = $arrSomeDate[$type];
$value += (float) $item->getAmount();
$arrSomeDate[$type] = $value;
} else {
$arrSomeDate[$type] = (float) $item->getAmount();
}
}
}
if ($item instanceof Invoice) {
/** @var Payment $payment */
foreach ($item->getPayments() as $payment) {
if (!$payment->isPrepay()) {
$type = $payment->getType()->getType();
if ($dateItem == $payment->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $payment->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$date = $payment->getCreatedAt();
if (array_key_exists($type, $arrSomeDate)) {
$value = $arrSomeDate[$type];
$value += (float) $payment->getAmount();
$arrSomeDate[$type] = $value;
} else {
$arrSomeDate[$type] = (float) $payment->getAmount();
}
}
}
}
}
}
$arrSomeDate = array_merge($defaultKeyValue, $arrSomeDate);
if ($arrSomeDate) {
$data[] = [
'data' => $arrSomeDate,
'categories' => $name ? $name : $dateItem,
'date' => $date
];
}
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
$ars = [];
foreach ($data as $item) {
foreach ($item['data'] as $key => $value) {
if (array_key_exists($key, $ars)) {
$ars[$key][] = $value;
} else {
$ars[$key] = [$value];
}
}
$resultData['data'] = $ars;
}
foreach ($resultData['data'] as $key => $value) {
$arr['name'] = $key;
$arr['data'] = $value;
$arr['color'] = isset($arrOriginalType[$key]) ? $arrOriginalType[$key] : null;
$result['data'][] = $arr;
}
foreach ($data as $item) {
$categories[] = $item['categories'];
}
$result['categories'] = $categories;
}
return $this->json($result);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/net-transaction", name="dashboard_net_transaction", options={"expose" = "true"}, methods={"POST"})
*/
public function netTransactions(Request $request)
{
$filter = $this->getFilter($request);
$filter->setNameReport(Setting::TRANSACTIONS);
$baseInvoice = $this->getDoctrine()->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$originalPaymentType = $this->getDoctrine()->getRepository(Kind::class)->findBy(['clinic' => $filter->getClinics()->getValues()]);
$arrOriginalType = [];
$criteriaDb = Criteria::create()->andWhere(
Criteria::expr()->andX(
Criteria::expr()->gte('createdAt', $filter->getDateStart()),
Criteria::expr()->lt('createdAt', $filter->getDateEnd())
)
);
/** @var Kind $type */
foreach ($originalPaymentType as $type) {
$arrOriginalType = array_merge($arrOriginalType, array_filter([$type->getType() => $type->getColor()]));
// $arrOriginalType[$type->getType()] = $type->getColor();
}
$data = [];
$resultData = [];
$result = [];
$categories = [];
$format = $this->dashboardService->createFormat($filter);
$datePayment = $this->dashboardService->createDefaultData($filter);
/* @var BaseInvoice $payment */
foreach ($baseInvoice as $item) {
if ($item instanceof Prepay && $item->getKind()) {
$dataType[] = $item->getKind()->getType();
}
if ($item instanceof Invoice) {
/** @var Payment $payment */
foreach ($item->getPayments()->matching($criteriaDb) as $payment) {
if (!$payment->isPrepay()) {
$dataType[] = $payment->getType()->getType();
}
}
/** @var Refund $refund */
foreach ($item->getItems()->matching($criteriaDb) as $refund) {
if ($refund instanceof Refund && !$refund->isPrepay()) {
$dataType[] = $refund->getKind()->getType();
}
}
}
}
if (isset($dataType)) {
$dataType = array_unique($dataType);
} else {
$dataType = array_column($this->getDoctrine()->getRepository(Kind::class)->findNamePaymentType($filter->getClinics()->getValues()), 'type');
}
/**
* @var string
* @var \DateTime $dateValue
*/
foreach ($datePayment as $dateItem => $dateValue) {
$date = $dateValue;
$name = null;
$arrSomeDate = [];
$defaultKeyValue = array_fill_keys($dataType, 0);
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $dateValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/* @var BaseInvoice $payment */
foreach ($baseInvoice as $item) {
if ($item instanceof Prepay && $item->getKind()) {
$type = $item->getKind()->getType();
if ($dateItem == $item->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $item->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$date = $item->getCreatedAt();
if (array_key_exists($type, $arrSomeDate)) {
$value = $arrSomeDate[$type];
$value += (float) $item->getAmount();
$arrSomeDate[$type] = $value;
} else {
$arrSomeDate[$type] = (float) $item->getAmount();
}
}
}
if ($item instanceof Invoice) {
/** @var Payment $payment */
foreach ($item->getPayments() as $payment) {
if (!$payment->isPrepay()) {
$type = $payment->getType()->getType();
if ($dateItem == $payment->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $payment->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$date = $payment->getCreatedAt();
if (array_key_exists($type, $arrSomeDate)) {
$value = $arrSomeDate[$type];
$value += (float) $payment->getAmount();
$arrSomeDate[$type] = $value;
} else {
$arrSomeDate[$type] = (float) $payment->getAmount();
}
}
}
}
/** @var Refund $itemInv */
foreach ($item->getItems() as $itemInv) {
if ($itemInv instanceof Refund && !$itemInv->isPrepay()) {
$type = $itemInv->getKind()->getType();
if ($dateItem == $itemInv->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemInv->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$date = $itemInv->getCreatedAt();
if (array_key_exists($type, $arrSomeDate)) {
$value = $arrSomeDate[$type];
$value += (float) $itemInv->getTotal();
$arrSomeDate[$type] = $value;
} else {
$arrSomeDate[$type] = (float) $itemInv->getTotal();
}
}
}
}
}
}
$arrSomeDate = array_merge($defaultKeyValue, $arrSomeDate);
if ($arrSomeDate) {
$data[] = [
'data' => $arrSomeDate,
'categories' => $name ? $name : $dateItem,
'date' => $date
];
}
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
$ars = [];
foreach ($data as $item) {
foreach ($item['data'] as $key => $value) {
if (array_key_exists($key, $ars)) {
$ars[$key][] = $value;
} else {
$ars[$key] = [$value];
}
}
$resultData['data'] = $ars;
}
foreach ($resultData['data'] as $key => $value) {
$arr['name'] = $key;
$arr['data'] = $value;
$arr['color'] = isset($arrOriginalType[$key]) ? $arrOriginalType[$key] : null;
$result['data'][] = $arr;
}
foreach ($data as $item) {
$categories[] = $item['categories'];
}
$result['categories'] = $categories;
}
return $this->json($result);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/cash-transaction", name="dashboard_cash_transaction", options={"expose" = "true"}, methods={"POST"})
*/
public function cashTrans(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(Payment::class)->findPaymentCashByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/dashboard_card_transaction", name="dashboard_card_transaction", options={"expose" = "true"}, methods={"POST"})
*/
public function cardTransactionBySuplier(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository('App:Patient\Payment')->findPaymentCardByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/stock-levels", name="stock-levels", options={"expose" = "true"}, methods={"POST"})
*/
public function stockLevels(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(Product::class)->findStockLevelsByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/stock-values", name="stock-values", options={"expose" = "true"}, methods={"POST"})
*/
public function stockValues(Request $request)
{
$filter = $this->getFilter($request);
$currentBalance = 0;
$data = [];
$dataProduct = [];
$originalProducts = [];
$products = $this->getDoctrine()->getRepository(Product::class)->selectProductByFilter($filter)->getQuery()->getResult();
/** @var Product $product */
foreach ($products as $product) {
$currentBalance += $product->getTotal();
$originalProducts['id_' . $product->getId()] = $product->getTotal();
}
$productsHistory = $this->getDoctrine()->getRepository(ProductBalanceHistory::class)->selectProductByFilter($filter)->getQuery()->getResult();
/** @var ProductBalanceHistory $item */
foreach ($productsHistory as $item) {
$itemProduct = $item->getProduct();
if (isset($dataProduct['id_' . $itemProduct->getId()])) {
$dataProduct['id_' . $itemProduct->getId()] = (($item->getBalance() * $itemProduct->getUnitPrice()) > $dataProduct['id_' . $itemProduct->getId()]) ? ($item->getBalance() * $itemProduct->getUnitPrice()) : $dataProduct['id_' . $itemProduct->getId()];
} else {
$dataProduct['id_' . $itemProduct->getId()] = $item->getBalance() * $itemProduct->getUnitPrice();
}
}
$dataProduct = array_merge($originalProducts, $dataProduct);
$maxBalance = array_sum(array_values($dataProduct));
$data[] = [
'name' => '',
'y' => $currentBalance,
'maxBalance' => $maxBalance
];
return $this->json($data);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/stock-sales", name="stock-sales", options={"expose" = "true"}, methods={"POST"})
*/
public function stockSales(Request $request)
{
$filter = $this->getFilter($request);
$sales = $this->getDoctrine()->getRepository(PriceList::class)->findSaleProducts($filter);
$stock = $this->getDoctrine()->getRepository(Product::class)->findStockSalesByFilter($filter);
return $this->json(
TransformData::diffArray($sales, $stock)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/sale-product-per-practitioner", name="sale-product-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function saleProductsPerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(Invoice::class)->findSaleProductsPerPractitioner($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/sale-service-per-practitioner", name="sale-service-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function saleServicePerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(Invoice::class)->findSaleServicesPerPractitioner($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/revenue-per-practitioner", name="revenue-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function revenuePerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
$data = $this->getDoctrine()->getRepository(Invoice::class)->findRevenuePerPractitioner($filter);
$defaultData = $this->dashboardService->createDefaultDataPerPractitioner($filter);
$result = [];
foreach ($defaultData as $item) {
$sumInv = 0;
/** @var Invoice $baseInvoice */
foreach ($data as $baseInvoice) {
if ($item['id'] === $baseInvoice->getPractitioner()->getId()) {
$sumInv += $baseInvoice->getTotalList() + $baseInvoice->getAmountRefund();
}
}
$result[] = [
'y' => $sumInv,
'name' => $item['name'],
'color' => $item['color'],
];
}
return $this->json(
TransformData::transform($result)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/revenue-per-period", name="revenue-per-period", options={"expose" = "true"}, methods={"POST"})
*/
public function revenuePerPeriod(Request $request)
{
$filter = $this->getFilter($request);
$invoices = $this->getDoctrine()->getRepository(Invoice::class)->findRevenuePerPractitioner($filter);
$data = [];
$invoicesDate = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($invoicesDate as $item => $itemValue) {
$sumInvoices = 0;
$date = $itemValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var Invoice $invoice */
foreach ($invoices as $invoice) {
if ($item == $invoice->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $invoice->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$sumInvoices += $invoice->getTotalList() + $invoice->getAmountRefund();
$date = $invoice->getCreatedAt();
}
}
$data[] = [
'name' => $name ? $name : $item,
'y' => $sumInvoices,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/appointments-per-practitioner", name="appointments-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function appointmentsPerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(GoogleEvent::class)->findAppoitmentsPerPractitionerByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/average-per-practitioner", name="average-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function averagePerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository('App:Clinic\Appointment')->findAverageAppoitmentsPerPractitionerByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/commission-per-practitioner", name="commission-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function commissionPerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository('App:Patient\Invoice')->findRevenuePerPractitioner($filter, 0.05)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/appointments-by-new-patient", name="appointments-by-new-patient", options={"expose" = "true"}, methods={"POST"})
*/
public function appointmentsByNewPatient(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(GoogleEvent::class)->findAppoitmentsPatientsByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/appointments-by-existing-patient", name="appointments-by-existing-patient", options={"expose" = "true"}, methods={"POST"})
*/
public function appointmentsByExistingPatient(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(GoogleEvent::class)->findAppoitmentsPatientsByFilter($filter, false)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/spend-by-new-patient", name="spend-by-new-patient", options={"expose" = "true"}, methods={"POST"})
*/
public function spendByNewPatient(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository('App:Clinic\Appointment')->findSpendPatientsByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/spend-by-existing-patient", name="spend-by-existing-patient", options={"expose" = "true"}, methods={"POST"})
*/
public function spendByExistingPatient(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository('App:Clinic\Appointment')->findSpendPatientsByFilter($filter, false)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/demand-clinic", name="demand-clinic", options={"expose" = "true"}, methods={"POST"})
*/
public function demandClinic(Request $request)
{
$filter = $this->getFilter($request);
$appointments = count($this->getDoctrine()->getRepository('App:Clinic\Appointment')->findBy(['clinic' => $filter->getClinic()]));
$waitings = count($this->getDoctrine()->getRepository('App:Waiting\Item')->findBy(['clinic' => $filter->getClinic()]));
$leadCaptures = count($this->getDoctrine()->getRepository('App:LeadCapture\LeadCapture')->findBy(['clinic' => $filter->getClinic()]));
return $this->json(
[
[
'name' => $filter->getClinic()->getName(),
'y' => (float) ($appointments + $waitings + $leadCaptures),
],
]
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/average-spend-patients", name="average-spend-patients", options={"expose" = "true"}, methods={"POST"})
*/
public function averageSpendPatients(Request $request)
{
$filter = $this->getFilter($request);
$start = $filter->getDateStart();
$end = $filter->getDateEnd();
$filter->setNameReport(Setting::AVERAGE_SPEND_PER_PATIENT);
// $invoices = $this->getDoctrine()->getRepository(Invoice::class)->findInvoicesAverageSpendPatients($filter);
$invoices = $this->getDoctrine()->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$data = [];
$format = $this->dashboardService->createFormat($filter);
$dateInvoices = $this->dashboardService->createDefaultData($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($dateInvoices as $item => $itemValue) {
$sumInvoices = 0;
$date = $itemValue;
$startFilter = $start;
$endFilter = $end;
$name = null;
$patients = [];
$countPatientsAppointment = 0;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
if ($invoices) {
/** @var BaseInvoice $invoice */
foreach ($invoices as $invoice) {
if ($invoice instanceof Prepay) {
if ($item == $invoice->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $invoice->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$sumInvoices += $invoice->getAmount();
$date = $invoice->getCreatedAt();
$patients[] = $invoice->getPatient()->getId();
}
}
if ($invoice instanceof Invoice) {
if ($item == $invoice->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $invoice->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$sumInvoices += $invoice->getTotalList();
$date = $invoice->getCreatedAt();
$patients[] = $invoice->getPatient()->getId();
}
}
}
$countPatientsAppointment = count(array_unique($patients));
}
$data[] = [
'name' => $name ? $name : $item,
'y' => (isset($countPatientsAppointment) && $countPatientsAppointment) ? $sumInvoices / $countPatientsAppointment : 0,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @param Request $request
* @return JsonResponse
*
* @throws \Exception
* @Route("/dashboard/birthday-patient", name="birthday-patient", options={"expose" = "true"}, methods={"POST"})
*/
public function birthdayPatient(Request $request)
{
$filter = $this->getFilter($request);
$filter->setDateStart(new \DateTime('first day of this month'));
$filter->setDateEnd(new \DateTime('last day of this month'));
return $this->json(
$this->getDoctrine()->getRepository('App:Person\Patient')->findBirthdayCurrentMonth($filter)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/last-appointment", name="last_appointment", options={"expose" = "true"}, methods={"POST"})
*/
public function lastAppointment(Request $request)
{
$filter = $this->getFilter($request);
$events = $this->getDoctrine()->getRepository(GoogleEvent::class)->selectLastAppointments($filter);
return $this->json(TransformData::transformLastAppointmentData($events->getQuery()->getResult()));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/top-patient-revenue", name="top-patient-revenue", options={"expose" = "true"}, methods={"POST"})
*/
public function topPatientsRevenue(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
$this->getDoctrine()->getRepository('App:Patient\Payment')->findTopPatientsByFilter($filter)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/number-appointments", name="number-appointments", options={"expose" = "true"}, methods={"POST"})
*/
public function numberAppointments(Request $request)
{
$filter = $this->getFilter($request);
$events = $this->getDoctrine()->getRepository(GoogleEvent::class)->findNumberAppointments($filter);
$data = [];
$format = $this->dashboardService->createFormat($filter);
$dataPeriod = $this->dashboardService->createDefaultData($filter);
/**
* @var string
* @var \DateTime $dateValue
*/
foreach ($dataPeriod as $dateItem => $dateValue) {
$count = 0;
$date = $dateValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $dateValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var GoogleEvent $event */
foreach ($events as $event) {
if ($dateItem == $event->getStart()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $event->getStart();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
++$count;
$date = $event->getStart();
}
}
$data[] = [
'y' => $count,
'name' => $name ? $name : $dateItem,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/number-paying-appointments", name="number-paying-appointments", options={"expose" = "true"}, methods={"POST"})
*/
public function numberPayingAppointments(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(GoogleEvent::class)->findNumberAppointments($filter, Appointment::STATUS_CONFIRMED)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/number-rebooked-appointments", name="number-rebooked-appointments", options={"expose" = "true"}, methods={"POST"})
*/
public function numberRebookedAppointments(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transform(
$this->getDoctrine()->getRepository(GoogleEvent::class)->findRebookedAppointmentsByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/number-cancellations-appointments", name="number-cancellations-appointments", options={"expose" = "true"}, methods={"POST"})
*/
public function numberCancellationsAppointments(Request $request)
{
$filter = $this->getFilter($request);
$events = $this->getDoctrine()->getRepository(GoogleEvent::class)->findCancelledAppointments($filter);
$data = [];
$format = $this->dashboardService->createFormat($filter);
$dataPeriod = $this->dashboardService->createDefaultData($filter);
/**
* @var string
* @var \DateTime $dateValue
*/
foreach ($dataPeriod as $dateItem => $dateValue) {
$count = 0;
$date = $dateValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $dateValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var GoogleEvent $event */
foreach ($events as $event) {
if ($dateItem == $event->getStart()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $event->getStart();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
++$count;
$date = $event->getStart();
}
}
$data[] = [
'y' => $count,
'name' => $name ? $name : $dateItem,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/conversion-appointments", name="conversion-appointments", options={"expose" = "true"}, methods={"POST"})
*/
public function conversionAppointments(Request $request)
{
$filter = $this->getFilter($request);
$filter->setNameReport(Setting::CONVERSION_APPOINTMENTS_NEW_PATIENT);
$events = $this->getDoctrine()->getRepository(GoogleEvent::class)->selectEventsDetailPage($filter)->getResult();
$data = [];
$format = $this->dashboardService->createFormat($filter);
$dataPeriod = $this->dashboardService->createDefaultData($filter);
/**
* @var string
* @var \DateTime $value
*/
foreach ($dataPeriod as $item => $value) {
$count = 0;
$countInv = 0;
$date = $value;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $value;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var GoogleEvent $event */
foreach ($events as $event) {
if ($item == $event->getStart()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format) && $event->getAppointment()->getPatient()) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $event->getStart();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$invoices = $this->getDoctrine()->getRepository(Invoice::class)->findInvoicesByEvent($event);
$countInv += count($invoices) >= 1 ? 1 : 0;
++$count;
$date = $event->getStart();
}
}
$data[] = [
'y' => $count > 0 ? ($countInv / $count) * 100 : 0,
'name' => $name ? $name : $value,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/refunds-clinic", name="refunds-clinic", options={"expose" = "true"}, methods={"POST"})
*/
public function refundsClinic(Request $request)
{
$filter = $this->getFilter($request);
$refunds = $this->getDoctrine()->getRepository(Refund::class)->findRefundsClinicByFilter($filter);
$data = [];
$result = [];
$resultData = [];
$categories = [];
$format = $this->dashboardService->createFormat($filter);
$dataPeriod = $this->dashboardService->createDefaultData($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($dataPeriod as $item => $itemValue) {
$date = null;
$name = null;
$arrSomeDate = [];
$i = 1;
if (!$refunds) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$arrSomeDate[$item . '_Number'] = 0;
$arrSomeDate[$item . '_Value'] = 0;
$date = $itemValue;
}
/** @var Refund $refund */
foreach ($refunds as $refund) {
if ($item == $refund->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $refund->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
if (array_key_exists($item . '_Value', $arrSomeDate)) {
$value = $arrSomeDate[$item . '_Value'];
$value += (float) $refund->getTotal() * (-1);
$arrSomeDate[$item . '_Value'] = $value;
} else {
$arrSomeDate[$item . '_Value'] = (float) $refund->getTotal() * (-1);
}
if (array_key_exists($item . '_Number', $arrSomeDate)) {
$arrSomeDate[$item . '_Number'] = $i++;
} else {
$arrSomeDate[$item . '_Number'] = $i++;
}
$date = $refund->getCreatedAt();
} else {
if (!array_key_exists($item . '_Number', $arrSomeDate) && !array_key_exists($item . '_Value', $arrSomeDate)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$arrSomeDate[$item . '_Number'] = 0;
$arrSomeDate[$item . '_Value'] = 0;
$date = $itemValue;
}
}
}
$data[] = [
'categories' => $name ? $name : $item,
'data' => $arrSomeDate,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
$ars = [];
foreach ($data as $item) {
foreach ($item['data'] as $key => $value) {
if (array_key_exists($key = substr(stristr($key, '_'), 1), $ars)) {
$ars[$key][] = $value;
} else {
$ars[$key] = [$value];
}
}
$resultData['data'] = $ars;
}
foreach ($resultData['data'] as $key => $value) {
$arr = [];
$arr['name'] = $key;
$arr['data'] = $value;
if ('Value' == $key) {
$arr['type'] = 'column';
$arr['yAxis'] = 1;
} else {
$arr['type'] = 'spline';
}
$result['data'][] = $arr;
}
foreach ($data as $item) {
$categories[] = $item['categories'];
}
$result['categories'] = $categories;
}
return $this->json($result);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/retention-clinic", name="retention-clinic", options={"expose" = "true"}, methods={"POST"})
*/
public function retentionClinic(Request $request)
{
$filter = $this->getFilter($request);
$allPatients = $this->getDoctrine()->getRepository(Patient::class)->findAllPatientsByFilter($filter);
$allPatientsAppointments = $this->getDoctrine()->getRepository(Patient::class)->findAllPatientsAppointmentsByFilter($filter);
$allPatients = $allPatients ? (float) $allPatients : 0;
$allPatientsAppointments = $allPatientsAppointments ? (float) $allPatientsAppointments : 0;
$allPatientsWithoutAppointments = $allPatients - $allPatientsAppointments;
$data = [
["Customers whom existed 12m before period not visiting in selected period - $allPatientsWithoutAppointments patient(s)", $allPatientsWithoutAppointments],
["Customers whom existed 12m before period visiting during selected period - $allPatientsAppointments patient(s)", $allPatientsAppointments]
];
return $this->json($data);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/frequency-of-visit", name="frequency-of-visit", options={"expose" = "true"}, methods={"POST"})
*/
public function frequencyOfVisit(Request $request)
{
$filter = $this->getFilter($request);
// $filter->setViewType(DashboardFilter::VIEW_TYPE_MONTH);
$events = $this->getDoctrine()->getRepository(GoogleEvent::class)->findFrequencyOfVisitByFilter($filter);
$data = [];
$dateAppointments = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
/**
* @var string
* @var \DateTime $dateValue
*/
foreach ($dateAppointments as $dateItem => $dateValue) {
$patients = [];
$sumPatients = 0;
$countPatients = 1;
$date = $dateValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $dateValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var GoogleEvent $event */
foreach ($events as $event) {
if ($dateItem == $event->getStart()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $event->getStart();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$patients[] = $event->getAppointment()->getPatient()->getId();
$date = $event->getStart();
}
}
if ($patients) {
$countValuesPatients = array_count_values($patients);
$sumPatients = array_sum($countValuesPatients);
$countPatients = count($countValuesPatients);
}
$data[] = [
'y' => $sumPatients / $countPatients,
'name' => $name ? $name : $dateItem,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/base-of-visit", name="base-of-visit", options={"expose" = "true"}, methods={"POST"})
*/
public function baseOfVisit(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transformBasePeriodData(
$this->getDoctrine()->getRepository(Patient::class)->findBaseOfVisitByFilter($filter)
)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/list-patient-treatment-date", name="list-patient-treatment-date", options={"expose" = "true"}, methods={"POST"})
*/
public function listPatientTreatmentDate(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
$this->getDoctrine()->getRepository(GoogleEvent::class)->findPatientTreatmentDate($filter)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/list-patient-practitioner-bouncing", name="list-patient-practitioner-bouncing", options={"expose" = "true"}, methods={"POST"})
*/
public function listPatientPractitionerBouncing(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
$this->getDoctrine()->getRepository('App:Clinic\Appointment')->findPatientPractitionerBouncing($filter)
);
}
/**
* @return JsonResponse
*
* @Route("/dashboard/recency-of-visit", name="recency-of-visit", options={"expose" = "true"}, methods={"POST"})
*/
public function recency(Request $request)
{
$filter = $this->getFilter($request);
$events = $this->getDoctrine()->getRepository(GoogleEvent::class)->findEventsByFilter($filter);
$data = [];
$resultData = [];
$patients = [];
$arrMonth = [];
$defaultDataPeriod = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
/** @var GoogleEvent $event */
foreach ($events as $event) {
$nameWeek = null;
if (!in_array([$event->getStart()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format) => $event->getAppointment()->getPatient()->getId()], $patients)) {
$patients[] = [$event->getStart()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format) => $event->getAppointment()->getPatient()->getId()];
/** @var GoogleEvent $prevEvent */
$prevEvent = $this->getDoctrine()->getRepository(GoogleEvent::class)->findPrevLastVisitByFilter($event);
if ($prevEvent) {
$startLastVisit = $event->getStart();
$startPrevVisit = $prevEvent->getStart();
$interval = $startLastVisit->diff($startPrevVisit)->format('%a');
if (0 == $interval) {
$dayLast = $startLastVisit->format('d');
$dayPrev = $startPrevVisit->format('d');
$interval = $dayLast - $dayPrev;
}
if (!in_array($startLastVisit->format($format), $arrMonth)) {
$arrMonth[] = $startLastVisit->format($format);
}
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
/** @var \DateTime $cloneDate */
$cloneDate = clone $startLastVisit;
$cloneDate = $cloneDate->modify('monday this week');
$nameWeek = $cloneDate->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$data[] = [
'y' => $interval,
'name' => $startLastVisit->format($format),
'date' => $startLastVisit,
'nameWeek' => $nameWeek
];
}
}
}
/**
* @var string
* @var \DateTime $monthDate
*/
foreach ($defaultDataPeriod as $month => $monthDate) {
$y = 0;
$count = 0;
$name = '';
$date = null;
$nameWeek = null;
if (!$data) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $monthDate;
$cloneDate = $cloneDate->modify('monday this week');
$nameWeek = $cloneDate->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$y = 0;
$count = 1;
$name = $nameWeek ? $nameWeek : $month;
$date = $monthDate;
}
foreach ($data as $item) {
if ($item['name'] == $month) {
$y += $item['y'];
++$count;
$name = $item['nameWeek'] ? $item['nameWeek'] : $item['name'];
$date = $item['date'];
} else {
if (!in_array($month, $arrMonth)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $monthDate;
$cloneDate = $cloneDate->modify('monday this week');
$nameWeek = $cloneDate->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$y = 0;
$count = 1;
$name = $nameWeek ? $nameWeek : $month;
$date = $monthDate;
}
}
}
$resultData[] = [
'y' => $y / $count,
'name' => $name,
'date' => $date
];
}
if ($resultData) {
usort($resultData, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(
TransformData::transform($resultData)
);
}
/**
* @Route("/dashboard/treatments-per-practitioner", name="treatments-per-practitioner", options={"expose" = "true"}, methods={"POST"})
*/
public function treatmentsPerPractitioner(Request $request)
{
$filter = $this->getFilter($request);
$data = $this->getDoctrine()->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$defaultData = $this->dashboardService->createDefaultDataPerPractitioner($filter);
$result = [];
foreach ($defaultData as $item) {
$sumInv = 0;
/** @var BaseInvoice $baseInvoice */
foreach ($data as $baseInvoice) {
if ($item['id'] === $baseInvoice->getPractitioner()->getId()) {
if ($baseInvoice instanceof Invoice) {
$sumInv += $baseInvoice->getTotalList() - $baseInvoice->getAmountPrepay() + $baseInvoice->getAmountRefund();
}
if ($baseInvoice instanceof Prepay) {
$sumInv += $baseInvoice->getAmount();
}
}
}
$result[] = [
'y' => $sumInv,
'name' => $item['name'],
'color' => $item['color'],
];
}
return $this->json(
TransformData::transform($result)
);
}
/**
* @Route("/dashboard/treatments-per-period", name="treatments-per-period", options={"expose" = "true"}, methods={"POST"})
*/
public function treatmentsPerPeriod(Request $request)
{
$filter = $this->getFilter($request);
$invoices = $this->getDoctrine()->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$data = [];
$invoicesDate = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($invoicesDate as $item => $itemValue) {
$sumInvoices = 0;
$date = $itemValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var BaseInvoice $invoice */
foreach ($invoices as $invoice) {
if ($item == $invoice->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $invoice->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
if ($invoice instanceof Invoice) {
$sumInvoices += $invoice->getTotalList() - $invoice->getAmountPrepay();
}
if ($invoice instanceof Prepay) {
$sumInvoices += $invoice->getAmount();
}
$date = $invoice->getCreatedAt();
}
}
$data[] = [
'name' => $name ? $name : $item,
'y' => $sumInvoices,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @Route("/dashboard/billings-per-coordinator", name="billings-per-coordinator", options={"expose" = "true"}, methods={"POST"})
*/
public function billingsPerCoordinator(Request $request)
{
$filter = $this->getFilter($request);
$filter->setNameReport(Setting::BILLINGS_PER_COORDINATOR);
$data = $this->getDoctrine()->getRepository(Invoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$defaultData = $this->dashboardService->createDefaultDataPerPractitioner($filter);
$result = [];
foreach ($defaultData as $item) {
$sumInv = 0;
/** @var Invoice $baseInvoice */
foreach ($data as $baseInvoice) {
if ($baseInvoice->getConsultationPractitioner() && $item['id'] === $baseInvoice->getConsultationPractitioner()->getId()) {
$sumInv += $baseInvoice->getTotalList() - $baseInvoice->getAmountPrepay() + $baseInvoice->getAmountRefund();
}
}
$result[] = [
'y' => $sumInv,
'name' => $item['name'],
'color' => $item['color'],
];
}
return $this->json(
TransformData::transform($result)
);
}
/**
* @Route("/dashboard/vouchers", name="vouchers", options={"expose" = "true"}, methods={"POST"})
*/
public function vouchers(Request $request)
{
$filter = $this->getFilter($request);
$vouchers = $this->getDoctrine()->getRepository(GiftVoucher::class)->selectVouchersDetailPage($filter)->getResult();
$data = [];
$vouchersDate = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($vouchersDate as $item => $itemValue) {
$sumVouchers = 0;
$date = $itemValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var GiftVoucher $voucher */
foreach ($vouchers as $voucher) {
if ($item == $voucher->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $voucher->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$sumVouchers += $voucher->getAmount();
$date = $voucher->getCreatedAt();
}
}
$data[] = [
'name' => $name ? $name : $item,
'y' => $sumVouchers,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @Route("/dashboard/treatments-interested-in", name="treatments-interested-in", options={"expose" = "true"}, methods={"POST"})
*/
public function treatmentsInterestedIn(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transformTreatmentsInterestedIn(
$this->getDoctrine()->getRepository(TreatmentClinic::class)->findPatientsTreatmentsInterestedIn($filter)
)
);
}
/**
* @Route("/dashboard/conversion-prospects", name="conversion-prospects", options={"expose" = "true"}, methods={"POST"})
*/
public function conversionProspects(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transformConvertProspectData(
$this->getDoctrine()->getRepository(LeadCapture::class)->findCoversionProspects($filter)
)
);
}
/**
* @Route("/dashboard/mailing-list", name="mailing-list", options={"expose" = "true"}, methods={"POST"})
*/
public function mailingList(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
$this->getDoctrine()->getRepository(Patient::class)->findMailingListByFilter($filter)
);
}
/**
* @Route("/dashboard/prepayments-balance", name="prepayments-balance", options={"expose" = "true"}, methods={"POST"})
*/
public function prepaymentsBalance(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
$this->getDoctrine()->getRepository(Prepay::class)->findPrepayDashboard($filter)
);
}
/**
* @Route("/dashboard/reconciliation", name="reconciliation", options={"expose" = "true"}, methods={"POST"})
*/
public function reconciliation(Request $request)
{
$filter = $this->getFilter($request);
self::setEntityManager($this->getDoctrine());
return $this->json(
self::getReconciliationData($filter)
);
}
/**
* @Route("/dashboard/unpaid-report", name="unpaid-report", options={"expose" = "true"}, methods={"POST"})
*/
public function unpaidReport(Request $request)
{
$filter = $this->getFilter($request);
$filter->setNameReport(Setting::UNPAID_REPORT);
$invoices = $this->getDoctrine()->getRepository(Invoice::class)->selectInvoices($filter)->getQuery()->getResult();
$data = [];
$invoicesDate = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($invoicesDate as $item => $itemValue) {
$sumInvoices = 0;
$date = $itemValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
/** @var Invoice $invoice */
foreach ($invoices as $invoice) {
if ($item == $invoice->getCreatedAt()->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $invoice->getCreatedAt();
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
$sumInvoices += $invoice->getDue();
$date = $invoice->getCreatedAt();
}
}
$data[] = [
'name' => $name ? $name : $item,
'y' => $sumInvoices,
'date' => $date
];
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @Route("/dashboard/sms-messages", name="sms-messages", options={"expose" = "true"}, methods={"POST"})
*/
public function smsMessages(Request $request, Twilio $twilio)
{
$filter = $this->getFilter($request);
$mesDate = $this->dashboardService->createDefaultData($filter);
$format = $this->dashboardService->createFormat($filter);
$data = [];
$messages = $twilio->getStatusesByFilter($filter);
/**
* @var string
* @var \DateTime $itemValue
*/
foreach ($mesDate as $item => $itemValue) {
$sumMes = 0;
$sumTotal = 0;
$date = $itemValue;
$name = null;
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $itemValue;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
foreach ($messages as $itemMes) {
/** @var MessageInstance $message */
foreach ($itemMes as $message) {
if ($item == $message->dateSent->setTimezone(new \DateTimeZone($this->getParameter('google_calendar_default_timezone')))->format($format)) {
if (DashboardFilter::VIEW_TYPE_WEEK == $filter->getViewType()) {
$cloneDate = clone $message->dateSent;
$name = $cloneDate->modify('monday this week')->format(DashboardFilter::FORMAT_WEEK_FOR_NAME);
}
if ('delivered' === $message->status) {
++$sumMes;
}
++$sumTotal;
$date = $message->dateSent;
}
}
$data[] = [
'name' => $name ? $name : $item,
'y' => $sumTotal ? (float) (($sumMes * 100) / $sumTotal) : 0,
'date' => $date,
'sumMes' => $sumMes,
'sumTotal' => $sumTotal
];
}
}
if ($data) {
usort($data, function ($a, $b) {
return ($a['date'] < $b['date']) ? -1 : 1;
});
}
return $this->json(TransformData::transform($data));
}
/**
* @return JsonResponse
*
* @Route("/dashboard/referred-patients", name="referred-patients", options={"expose" = "true"}, methods={"POST"})
*/
public function referredPatients(Request $request)
{
$filter = $this->getFilter($request);
return $this->json(
TransformData::transformReferredPatientsData(
$this->getDoctrine()->getRepository(Patient::class)->findReferredPatients($filter)
)
);
}
/**
* @return DashboardFilter
*/
private function getFilter(Request $request)
{
$user = $this->getUser();
$filter = new DashboardFilter();
$filter->addClinic($this->getClinic());
$filter->setDashboard(true);
$form = $this->createForm(DashboardFilterType::class, $filter, ['timezone' => $this->getParameter('google_calendar_default_timezone'), 'user' => $this->getUser()]);
$form->handleRequest($request);
if (0 == $filter->getClinics()->count() && ($user instanceof SuperClinicAdmin || $user->getRole() == User::ROLE_SUPER_CLINIC_ADMIN)) {
$user->getOrganisation()->getClinics()->map(function (Clinic $clinic) use (&$filter) {
$filter->addClinic($clinic);
});
}
if ($user instanceof ClinicUser && $user->getRole() != User::ROLE_SUPER_CLINIC_ADMIN) {
$filter->addClinic($user->getClinic());
}
if($filter->getDateEnd()) {
$filter->getDateEnd()->setTime(23, 59, 59);
}
if ($filter->getDateEndSecond()) {
$filter->getDateEndSecond()->setTime(23, 59, 59);
$filter->getDateEndSecond()->setTimezone(new \DateTimeZone('UTC'));
}
if ($filter->getDateStartSecond()) {
$filter->getDateStartSecond()->setTimezone(new \DateTimeZone('UTC'));
}
$filter->getDateStart()->setTimezone(new \DateTimeZone('UTC'));
$filter->getDateEnd()->setTimezone(new \DateTimeZone('UTC'));
return $filter;
}
public static function getReconciliationData(DashboardFilter $filter)
{
$filter->setNameReport(Setting::RECONCILIATION);
$totals = self::$entityManager->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$sum_amt = 0;
foreach ($totals as $total) {
if ($total instanceof Invoice) {
$sum_amt += $total->getTotalList();
}
if ($total instanceof Prepay) {
$sum_amt += $total->getAmount();
}
// if ($total->getType() == '')
// $sum_amt += $total->getTotalList();
}
$filter->setNameReport(Setting::BILLINGS_PER_PERIOD);
$totalBillings = self::$entityManager->getRepository(BaseInvoice::class)->selectInvoicesDeatilPage($filter)->getResult();
$sumBillings = 0;
$refundTotal = 0;
$totalNet = 0;
$dueAmt = 0;
/** @var Invoice|Prepay|CreditNote $billing */
foreach ($totalBillings as $billing) {
if ($billing instanceof Invoice) {
$dueAmt += $billing->getDue();
//echo $sumInvoices;
foreach ($billing->getPayments() as $list) {
$totalNet += $list->getAmount();
}
foreach ($billing->getItems() as $itemInv) {
if ($itemInv instanceof Refund) {
$refundTotal += $itemInv->getTotal();
}
}
$sumBillings += $billing->getTotalList();
}
if ($billing instanceof Prepay) {
$sumBillings += $billing->getAmount();
}
}
$refundValue = ($dueAmt) - ($refundTotal);
//echo "<br>";
//echo $refundTotal;
$sumBillings = $sum_amt;
//echo $sum_amt - $totalNet;
$filter->setNameReport(Setting::RECONCILIATION);
$receiptsPrevPeriod = self::$entityManager->getRepository(Payment::class)->findTransactionsPrevPeriodByFilter($filter);
$sumReceiptsPrevPeriod = 0;
$neus = 0;
/** @var Payment $receipt */
foreach ($receiptsPrevPeriod as $receipt) {
//echo $neus;
if (!$receipt->isPrepay()) {
$testBIlling = $receipt->getInvoice();
foreach ($testBIlling->getItems() as $itemInv) {
if ($itemInv instanceof Refund) {
$neus += $itemInv->getTotal();
}
}
$sumReceiptsPrevPeriod += $receipt->getAmount();
}
}
$totalBillingsNotPayment = self::$entityManager->getRepository(Invoice::class)->findBillingsNotPayment($filter);
$sumBillingsNotPayment = 0;
/** @var Invoice $item */
foreach ($totalBillingsNotPayment as $item) {
$sumBillingsNotPayment += $item->getTotalList();
}
$sumBillingsNotPayment = $refundValue;
$sumPrepayments = 0;
/** @var Invoice|Prepay|CreditNote $billing */
foreach ($totalBillings as $billing) {
if ($billing instanceof Prepay) {
$sumPrepayments += $billing->getAmount();
}
}
$filter->setNameReport(Setting::TRANSACTIONS);
$sumReceipts = $sumBillings + $sumReceiptsPrevPeriod - $sumBillingsNotPayment;
$totalPrepaidInvoice = self::$entityManager->getRepository(Invoice::class)->findRevenuePerPractitioner($filter, true);
$sumPrepaidInvoice = 0;
/** @var Invoice $item */
foreach ($totalPrepaidInvoice as $item) {
$sumPrepaidInvoice += $item->getTotalList();
}
$sumRevenue = $sumReceipts - $sumPrepayments - $sumReceiptsPrevPeriod + $sumPrepaidInvoice + $sumBillingsNotPayment + $refundTotal;
$sumBillingsNotPayment = $sumBillingsNotPayment;
$newValue = $sumBillingsNotPayment + ($refundTotal);
return
[
[
'th1' => 'Total Billings',
'th2' => $sum_amt,
],
[
'th1' => 'Plus: Net Receipts from Previous Period',
'th2' => $sumReceiptsPrevPeriod + ($neus),
],
[
'th1' => 'Less: Billings Payment Not Received',
'th2' => $sumBillingsNotPayment * (-1),
],
[
'th1' => 'Total Net Receipts',
'th2' => $sumReceipts,
],
[
'th1' => 'Less: Prepayments',
'th2' => $sumPrepayments * (-1),
],
[
'th1' => 'Less: Net Receipts for Previous Period',
'th2' => $sumReceiptsPrevPeriod * (-1),
],
[
'th1' => 'Plus: Prepaid Invoices',
'th2' => $sumPrepaidInvoice,
],
[
'th1' => 'Plus: Invoices Payment Not Received',
'th2' => $newValue,
],
[
'th1' => 'Total Revenue',
'th2' => $sumRevenue,
]
];
}
}