<?php
namespace App\Controller\Api\Internal;
use App\Controller\Admin\AdminDashbordController;
use App\Controller\Admin\RequestLogCrudController;
use App\Entity\ControllerUser;
use App\Entity\Eg\Admin\UserGroup;
use App\Entity\Eg\Osm\Parking;
use App\Entity\ElectricList;
use App\Entity\Fine;
use App\Entity\Gps;
use App\Entity\LapPair;
use App\Entity\LogExport;
use App\Entity\Logs\RequestLogHistory;
use App\Entity\Operations\FineOperation;
use App\Entity\Operations\OperationType;
use App\Entity\Operations\RequestLogOperation;
use App\Entity\ParkingStatus;
use App\Entity\Photo;
use App\Entity\RequestLog;
use App\Entity\RouteLap;
use App\Entity\VerificationStatus;
use App\ValueObject\LicensePlate;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
final class ApiController extends AdminDashbordController
{
#[Route(path: '/fine-logs/{fineId}', name: 'api_fine_logs', methods: ['GET'])]
public function getFineLogs(EntityManagerInterface $manager, $fineId): JsonResponse
{
$response = [];
/** @var FineOperation[] $data */
$data = $manager->getRepository(FineOperation::class)->findByFine($fineId, ['id' => 'DESC']);
foreach ($data as $operation) {
$response[] = $operation->getHistoryData();
}
return new JsonResponse($response);
}
#[Route(path: '/request-log-operations/{requestLogId}', name: 'api_request_log_operations', methods: ['GET'])]
public function getRequestLogOperations(EntityManagerInterface $manager, $requestLogId): JsonResponse
{
$response = [];
// Tutaj dodajemy jeszcze weryfikacje użytkowników, bo się w trochę złym miejscu to dodawało, a teraz już za późno zmieniać strukturę
// (po to też są te while poniżej)
$verifications = $manager->getRepository(RequestLogHistory::class)->findBy([
'requestLog' => $requestLogId,
'method' => 'verify'
], ['id' => 'DESC']);
$i = 0;
/** @var RequestLogOperation[] $data */
$data = $manager->getRepository(RequestLogOperation::class)->findByRequestLog($requestLogId, ['id' => 'DESC']);
foreach ($data as $operation) {
while ($i < count($verifications) && $verifications[$i]->getCreatedAt() > $operation->getCreatedAt()) {
$response[] = $verifications[$i]->imitateOperationHistoryData();
$i += 1;
}
$response[] = $operation->getHistoryData();
}
// To w teorii nie powinno być potrzebne, no bo jakim cudem ma ręczna weryfikacja byćc przed operacjami powstającymi przy utworzeniu odczytu, ale niech zostanie
while ($i < count($verifications)) {
$response[] = $verifications[$i]->imitateOperationHistoryData();
$i += 1;
}
return new JsonResponse($response);
}
#[Route(path: '/request-log-history/{requestLogId}', name: 'api_request_log_history', methods: ['GET'])]
public function getRequestLogHistory(EntityManagerInterface $manager, $requestLogId): JsonResponse
{
$response = [];
$requestLog = $manager->getRepository(RequestLog::class)->find($requestLogId);
$data = $manager->getRepository(RequestLogHistory::class)->filterOutMethod('verify', $requestLogId);
foreach ($data as $log) {
$logData = $log->getKeyData();
if ($log->getMethod() === RequestLogHistory::ELECTRIC_METHOD) {
$requestArr = \json_decode($log->getRequestExternal(), true);
$licensePlate = $requestArr['license_plate'] ?? null;
$electricCar = null;
if ($licensePlate) {
$electricCar = $manager->getRepository(ElectricList::class)->find($licensePlate);
}
if ($electricCar) {
$logData['formattedResponses'][] = [
'created_at' => $electricCar->getCreatedAt()->format('Y-m-d H:i:s'),
'photo' => $_ENV['PHOTO_ADDRESS'] . $electricCar->getPhotoPath()
];
} else {
$logData['formattedResponses'][] = [
'created_at' => null,
'photo' => null
];
}
}
$logData['licensePlate'] = LicensePlate::fromHttpRequest($logData['request'], $requestLog->getAnonymized()) ?? 'Brak';
$response[] = $logData;
}
return new JsonResponse($response);
}
#[Route(path: '/is-super-admin', name: 'api_is_super_admin', methods: ['GET'])]
public function isSuperAdmin(): JsonResponse
{
return new JsonResponse($this->isGranted('ROLE_SUPER_ADMIN'));
}
#[Route(path: '/is-badanie-granted', name: 'api_is_badanie_granted', methods: ['GET'])]
public function isBadanieGranted(): JsonResponse
{
return new JsonResponse($this->isGranted('ROLE_BADANIE'));
}
/**
* Metoda do wyciągania zdjęć danego obiektu RequestLog
*/
#[Route(path: '/get-photos/{requestLogId}', name: 'api_get_photos')]
public function getPhotos(EntityManagerInterface $manager, $requestLogId): JsonResponse
{
$photos = $manager->getRepository(Photo::class)->findByLogIds([$requestLogId]);
return new JsonResponse($photos);
}
/**
* Metoda do wyciągnięcie gps dla kontrolerów z ograniczeniem do co 5 odczytu lokalizacji
*
* dateFrom - data od (format "yyyy-mm-dd hh:mm:ss", np.: "2022-06-09 00:00:00")
* dateTo - data do (format "yyyy-mm-dd hh:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/get-controllers-routes', name: 'api_get_controllers_routes', methods: ['GET'])]
public function getControllersRoutes(EntityManagerInterface $manager, Request $request)
{
$data = $request->query;
$result = [];
$gpsRepository = $manager->getRepository(Gps::class);
$controllersDevices = $gpsRepository->getControllersAndDevicePairForTimeRange($data->get('dateFrom'), $data->get('dateTo'));
$gpsInterval = 5;
$dateFrom = new \DateTime($data->get('dateFrom'));
$dateTo = new \DateTime($data->get('dateTo'));
$diff = $dateTo->diff($dateFrom);
$hoursNumber = $diff->h;
if ($hoursNumber > 1 && $hoursNumber < 2) {
$gpsInterval = 10;
} elseif ($hoursNumber >= 2 && $hoursNumber < 4) {
$gpsInterval = 15;
} elseif ($hoursNumber >= 4) {
$gpsInterval = 20;
}
foreach ($controllersDevices as $key => $controllerData) {
$gpsList = $gpsRepository->getGpsForIntervalByController($data->get('dateFrom'), $data->get('dateTo'), $gpsInterval, $controllerData['createdBy'], $controllerData['urzadzeniaId']);
$keyControllerDevice = $controllerData['createdBy'] . '_' . $controllerData['urzadzeniaId'];
if (empty($controllerData['controllerLogin'])) {
$controllerId = $manager->getRepository(ControllerUser::class)->findOneBy(['controllerId' => $controllerData['createdBy']]);
if ($controllerId) {
$controllerData['controllerLogin'] = $controllerData['createdBy'];
}
}
if (!array_key_exists($keyControllerDevice, $result)) {
$result[$keyControllerDevice] = [
'points' => [],
'createdBy' => $controllerData['createdBy'],
'deviceId' => $controllerData['urzadzeniaId'],
'controllerLogin' => $controllerData['controllerLogin']
];
}
foreach ($gpsList as $key => $gps) {
if ($gpsList[$key]['createdAt']) {
$gpsList[$key]['createdAt'] = $gps['createdAt']->format('Y-m-d H:i:s.u');
}
if ($gpsList[$key]['gps']) {
$gpsList[$key]['gps'] = json_decode($gps['gps'], true);
}
if ($gpsList[$key]['accuracy']) {
$gpsList[$key]['accuracy'] = $gps['accuracy'];
}
if ($gpsList[$key]['speed']) {
$gpsList[$key]['speed'] = $gps['speed'];
}
if ($gpsList[$key]['direction']) {
$gpsList[$key]['direction'] = $gps['direction'];
}
array_push($result[$keyControllerDevice]['points'], $gpsList[$key]);
}
}
return new JsonResponse($result);
}
/**
* Metoda do wyciągania wszystkich grup requestów między datami
*
* time - data i czas (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
*/
#[Route(path: '/controler-car-position', name: 'get_controller_car_position', methods: ['GET'])]
public function getControllerCarPosition(EntityManagerInterface $manager, Request $request): JsonResponse
{
$timeEnd = new \DateTime($request->query->get('time'));
$timeStart = (new \DateTime($request->query->get('time')))->modify('-5 minutes');
$points = $manager->getRepository(Gps::class)->getControllerCarPositions($timeStart, $timeEnd);
$result = [];
foreach ($points as $point) {
$key = $point['createdBy'] . '_' . $point['urzadzeniaId'];
if (!array_key_exists($key, $result)) {
$result[$key] = [];
$result[$key]['points'] = [];
$result[$key]['controlerId'] = $point['createdBy'];
$result[$key]['deviceId'] = $point['urzadzeniaId'];
$result[$key]['controllerLogin'] = $point['controllerLogin'];
}
$result[$key]['lastPoint'] = [
'lon' => $point['longitude'],
'lat' => $point['latitude']
];
array_push($result[$key]['points'], [floatval($point['longitude']), floatval($point['latitude'])]);
}
return new JsonResponse($result);
}
/**
* Metoda do wyciągania danych przejazdów między konkretnymi datami (z jednego dnia)
*
* start - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* end - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/getstates', name: 'get_states', methods: ['GET'])]
public function getStates(EntityManagerInterface $manager, Request $request): JsonResponse
{
$check = $this->checkDateIntervalQueryParams($request, true);
if ($check) {
return $check;
}
$result = [];
$routeLaps = $manager->getRepository(RouteLap::class)->getStates(new \DateTime($request->query->get('start')), new \DateTime($request->query->get('end')));
$grouppedByParking = \array_reduce($routeLaps, function ($res, $item) {
if (!isset($res[$item['parkingId']])) {
$res[$item['parkingId']] = [];
}
$res[$item['parkingId']][] = $item;
return $res;
}, []);
foreach ($grouppedByParking as $parkingId => $parkingRoutes) {
$parking = $manager->getRepository(Parking::class)->find($parkingId);
$parkingTypes = $parking->getParkingType();
$totalPlaces = $parking->getTotalPlaces();
$avgOccupiedPlaces = $this->floorAvgFromArrayByKey($parkingRoutes, 'occupiedPlaces');
$avgUnpaidPlaces = $this->floorAvgFromArrayByKey($parkingRoutes, 'unpaidPlaces');
$occupancyState = null;
$paymentState = null;
if ($totalPlaces > 0) {
// Occupancy
$occPercent = ($avgOccupiedPlaces / $totalPlaces) * 100;
if ($occPercent > $parkingTypes->getOccupiedMaxPercent()) {
$occupancyState = 2;
} elseif ($occPercent <= $parkingTypes->getOccupiedMaxPercent() && $occPercent > $parkingTypes->getFreeMaxPercent()) {
$occupancyState = 1;
} else {
$occupancyState = 0;
}
// Payment
$percentUnpaid = ($avgUnpaidPlaces / $totalPlaces) * 100;
if ($percentUnpaid > $parkingTypes->getSomeUnpaidMaxPercent()) {
$paymentState = 2;
} elseif ($percentUnpaid <= $parkingTypes->getSomeUnpaidMaxPercent() && $percentUnpaid > $parkingTypes->getFewUnpaidMaxPercent()) {
$paymentState = 1;
} else {
if ($occupancyState == 0) {
$paymentState = 3;
} else {
$paymentState = 0;
}
}
}
$result[$parkingId] = [
'parkingId' => $parkingId,
'occupancyState' => $occupancyState,
'paymentState' => $paymentState,
'totalPlaces' => $totalPlaces,
'occupiedPlaces' => $avgOccupiedPlaces,
'unpaidPlaces' => $avgUnpaidPlaces
];
}
return new JsonResponse($result);
}
/**
* Metoda do wyliczania średniej wartości dla wskazanego klucza w tablicy obiektów. Wartość jest zaokroąglana i sprowadzana to typu int
*
* @param array $arr tablica obiektów
* @param string $key klucz
*
* @return int liczba stanowiącą średnią z wartości pod wskazanym kluczem w obiektach w tablicy
*/
private function floorAvgFromArrayByKey(array $arr, string $key): int
{
$arrOfKey = \array_map(fn ($item) => $item[$key], $arr);
return (int) \round(\array_sum($arrOfKey) / \count($arrOfKey));
}
/**
* Metoda do wyciągania danych przejazdów między konkretnymi datami (z jednego dnia) na jednym parkingu
*
* start - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* end - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/getstate/{parkingId}', name: 'get_state_parking', methods: ['GET'])]
public function getState(EntityManagerInterface $manager, Request $request, $parkingId)
{
$check = $this->checkDateIntervalQueryParams($request, true);
if ($check) {
return $check;
}
$result = $manager->getRepository(RouteLap::class)->getState(new \DateTime($request->query->get('start')), new \DateTime($request->query->get('end')), $parkingId);
return new JsonResponse($result);
}
/**
* Metoda do sprawdzania czy otrzymane parametry zapytania są poprawne dla przedziału dat
*
* @param bool $sameDay Parametr decydujący o tym, czy daty muszą być tego samego dnia
*
* @return JsonResponse|void jeżeli jest bład to zwróci go w postaci JsonResponse, jeżeli nie to nic nie zwróci
*/
private function checkDateIntervalQueryParams(Request $request, $sameDay = false)
{
$timeRange = [];
if (!$request->query->get('start') || !$request->query->get('end')) {
return new JsonResponse(['error' => 'Niepełne parametry zapytania'], 400);
}
$timeRange['start'] = new \DateTime($request->query->get('start'));
$timeRange['end'] = new \DateTime($request->query->get('end'));
if ($timeRange['start'] > $timeRange['end']) {
return new JsonResponse(['error' => 'Data końca jest wcześniejsza niż data początku'], 400);
}
if ($sameDay) {
$midnight = (new \DateTime($request->query->get('end')))->setTime(0, 0, 0);
if ($timeRange['start'] < $midnight) {
return new JsonResponse(['error' => 'Daty początku i końca nie są tego samego dnia'], 400);
}
}
}
/**
* Metoda do wyciągania statystyk wystawionych zawiadomień w danym przedziale czasowym
*
* dateStart - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* dateEnd - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/get-fine-statistics', name: 'get-fine-statistics', methods: ['GET'])]
public function getFineStatistics(Request $request): JsonResponse
{
$dateStart = new \DateTime($request->query->get('dateStart'));
$dateEnd = new \DateTime($request->query->get('dateEnd'));
$verificationStatuses = VerificationStatus::STATUSES;
$isSuperAdmin = $this->getUser()->isSuperAdmin();
if (!$isSuperAdmin) {
unset($verificationStatuses[VerificationStatus::AUTOMATICALLY_ANONYMIZED_DUPLICATE]);
}
foreach ($verificationStatuses as $id => $name) {
$fineStats[$id] = [
'number_of_fines' => 0,
'name' => $name
];
}
foreach (
$this->manager->getRepository(Fine::class)->getGroupedByVerificationStatuses($dateStart, $dateEnd, $isSuperAdmin) as $fineByStatus
) {
$fineStats[$fineByStatus['id']] = [
'number_of_fines' => $fineByStatus['number_of_fines'],
'name' => $fineByStatus['name']
];
}
return new JsonResponse($fineStats);
}
/**
* Metoda do wyciągania statystyk pojedynczych odczytów w danym przedziale czasowym
*
* start - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* end - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/get-request-log-statistics', name: 'get-request-log-statistics', methods: ['GET'])]
public function getRequestLogStatistics(EntityManagerInterface $manager, Request $request)
{
$dateStart = new \DateTime($request->query->get('dateStart'));
$dateEnd = new \DateTime($request->query->get('dateEnd'));
$requestLogStats = [];
$mergedStatuses = [
ParkingStatus::PARKING_ERROR_2 => ParkingStatus::PARKING_ERROR,
ParkingStatus::PARKING_EXCEEDED_2 => ParkingStatus::PARKING_EXCEEDED,
];
foreach (ParkingStatus::ARRAY_PARKING_STATUSES as $key => $value) {
if ($key !== ParkingStatus::OUTSIDE_PARKING && !isset($mergedStatuses[$key])) {
$requestLogStats[$key] = [
'numer_of_request_logs' => 0,
'name' => $value['name']
];
}
}
foreach ($manager->getRepository(RequestLog::class)->getGroupedByPaymentStatuses($dateStart, $dateEnd) as $requestLogByStatus) {
$id = (int) $requestLogByStatus['id'];
$targetId = $mergedStatuses[$id] ?? $id;
$requestLogStats[$targetId]['numer_of_request_logs'] = ($requestLogStats[$targetId]['numer_of_request_logs'] ?? 0) + $requestLogByStatus['numer_of_request_logs'];
}
return new JsonResponse($requestLogStats);
}
/**
* Metoda do wyciągania statystyk niepoprawnych odczytów kazdego dnia w danym przedziale czasowym
*
* start - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* end - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/get-request-log-mistakes', name: 'get-request-log-mistakes', methods: ['GET'])]
public function getRequestLogMistakes(EntityManagerInterface $manager, Request $request)
{
$dateStart = new \DateTime($request->query->get('dateStart'));
$dateEnd = new \DateTime($request->query->get('dateEnd'));
$mistakes = $manager->getRepository(RequestLog::class)->getIncorrectlyRead($dateStart, $dateEnd);
$requestsByDay = [];
foreach ($manager->getRepository(RequestLog::class)->getAllRead($dateStart, $dateEnd) as $dayOfReqeusts) {
$requestsByDay[$dayOfReqeusts['requestDate']] = $dayOfReqeusts['requestCount'];
}
foreach ($mistakes as $index => $key) {
if (array_key_exists($key['requestDate'], $requestsByDay)) {
$mistakes[$index]['percentage'] = round($key['requestCount'] * 100 / $requestsByDay[$key['requestDate']], 2) . '%';
} else {
$mistakes[$index]['percentage'] = 'NaN';
}
}
return new JsonResponse($mistakes);
}
/**
* Metoda do sugerowania niesparowanych odczytów w parach przejazdów
*/
#[Route(path: '/get-suggestions/{lapPairID}', name: 'get-lap-pair-suggestions', methods: ['GET'])]
public function getLapPairSuggestions(EntityManagerInterface $manager, $lapPairID)
{
$lapPair = $manager->getRepository(LapPair::class)->find($lapPairID);
$suggestions = [];
$suggestionPairs = [];
foreach (
$manager->getRepository(RequestLog::class)->findBy([
'routeLap' => $lapPair->getFirstLap(),
'paymentStatus' => [ParkingStatus::PARKING_ERROR, ParkingStatus::PARKING_UNPAID]
]) as $firstLog
) {
foreach (
$manager->getRepository(RequestLog::class)->getToSuggestions(
$lapPair->getSecondLap(),
[ParkingStatus::PARKING_ERROR, ParkingStatus::PARKING_UNPAID],
$firstLog->getLicensePlate()
) as $secondLog
) {
$proximity = $this->getStringProximity($firstLog->getLicensePlate(), $secondLog->getLicensePlate());
if ($proximity <= 2) {
$suggestionPairs[] = [
'first_log' => $firstLog->getBasicLogData(),
'second_log' => $secondLog->getBasicLogData()
];
}
}
}
foreach ($suggestionPairs as $pair) {
$firstLink = $this->container->get(AdminUrlGenerator::class)
->setAction(Crud::PAGE_EDIT)
->setController(RequestLogCrudController::class)
->setEntityId($pair['first_log']['id'])
->generateUrl();
$secondLink = $this->container->get(AdminUrlGenerator::class)
->setAction(Crud::PAGE_EDIT)
->setController(RequestLogCrudController::class)
->setEntityId($pair['second_log']['id'])
->generateUrl();
$suggestions[] = [
'firstLicensePlate' => $pair['first_log']['licensePlate'],
'secondLicensePlate' => $pair['second_log']['licensePlate'],
'firstDate' => $pair['first_log']['date'],
'secondDate' => $pair['second_log']['date'],
'firstLocation' => $pair['first_log']['location'],
'secondLocation' => $pair['second_log']['location'],
'first_photo' => array_key_exists('plate', $pair['first_log']['photos']) ? $pair['first_log']['photos']['plate'] : '',
'second_photo' => array_key_exists('plate', $pair['second_log']['photos']) ? $pair['second_log']['photos']['plate'] : '',
'first_edit_url' => $firstLink,
'second_edit_url' => $secondLink,
];
}
return new JsonResponse($suggestions);
}
/**
* Prywatna metoda do obliczania "bliskości" dwóch stringów
*
* zwraca:
* 0 - jeden string zawiera drugi
* x - stringi róznia sie o conajmniej liter
*/
private function getStringProximity($first, $second)
{
if (strlen($first) > strlen($second)) {
$longer = $first;
$shorter = $second;
} else {
$longer = $second;
$shorter = $first;
}
if (str_contains($longer, (string) $shorter)) {
return 0;
}
// Sprawdzanie odpoczątku
$commonLetters = 0;
foreach (str_split($shorter) as $index => $value) {
if ($value === $longer[$index]) {
$commonLetters += 1;
}
}
if (strlen($shorter) - $commonLetters <= 2) {
return strlen($shorter) - $commonLetters;
}
// Sprawdzanie od końca
$commonLetters = 0;
for ($i = 0; $i < strlen($shorter); $i += 1) {
if ($shorter[strlen($shorter) - $i - 1] === $longer[strlen($longer) - $i - 1]) {
$commonLetters += 1;
}
}
return strlen($shorter) - $commonLetters;
}
#[Route(path: '/fine-payment-requests/{fineId}', name: 'api_fine_payment_requests', methods: ['GET'])]
public function getFinePaymentRequests(EntityManagerInterface $manager, $fineId): JsonResponse
{
$response = [];
$data = $manager->getRepository(RequestLogHistory::class)->findByFineId($fineId);
foreach ($data as $log) {
$logData = $log->getKeyData();
$logData['licensePlate'] = LicensePlate::fromHttpRequest($logData['request'], $log->getRequestLog()->getAnonymized()) ?? 'Brak';
$response[] = $logData;
}
return new JsonResponse($response);
}
#[Route(path: '/fine-payment-requests-admin/{fineId}', name: 'api_fine_payment_requests_admin', methods: ['GET'])]
public function getFinePaymentRequestsAdmin(EntityManagerInterface $manager, $fineId): JsonResponse
{
$response = [];
$reqLogsHistory = $manager->getRepository(RequestLogHistory::class)->getAllFromSpecificFineRequestGroup($fineId);
foreach ($reqLogsHistory as $log) {
$logData = $log->getKeyData();
$logData['licensePlate'] = LicensePlate::fromHttpRequest($logData['request'], $log->getRequestLog()->getAnonymized()) ?? 'Brak';
$response[] = $logData;
}
return new JsonResponse($response);
}
/**
* Metoda do wyciągania statystyk operacji wykonanych przez uzytkownikow w danym przedziale czasowym
*
* dateStart - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* dateEnd - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
* user - ID użytkownika (jeżeli 0 to wszyscy użytkownicy)
*/
#[Route(path: '/get-user-statements', name: 'get-user-statements', methods: ['GET'])]
public function getUserStatements(EntityManagerInterface $manager, Request $request): JsonResponse
{
$dateStart = new \DateTime($request->query->get('dateStart'));
$dateEnd = new \DateTime($request->query->get('dateEnd'));
$user = $request->query->get('user');
$allVerificationOperations = $manager->getRepository(FineOperation::class)->getGroupedByUserActions($dateStart, $dateEnd, [OperationType::MANUAL_REQUEST_VERIFICATION, OperationType::DIRECTORS_CONFIRMATION], $user, UserGroup::WORKERS_GROUP_NAMES);
$positiveVerifications = $manager->getRepository(FineOperation::class)->getGroupedByUserActions($dateStart, $dateEnd, [OperationType::MANUAL_REQUEST_VERIFICATION], $user, UserGroup::WORKERS_GROUP_NAMES, VerificationStatus::AWAITING_POSITIVE_VERIFICATION);
$negativeVerifications = $manager->getRepository(FineOperation::class)->getGroupedByUserActions($dateStart, $dateEnd, [OperationType::MANUAL_REQUEST_VERIFICATION], $user, UserGroup::WORKERS_GROUP_NAMES, VerificationStatus::AWAITING_NEGATIVE_VERIFICATION);
$confirmPositiveVerifications = $manager->getRepository(FineOperation::class)->getGroupedByUserActions($dateStart, $dateEnd, [OperationType::DIRECTORS_CONFIRMATION], $user, UserGroup::WORKERS_GROUP_NAMES, VerificationStatus::POSITIVELY_VERIFIED);
$confirmNegativeVerifications = $manager->getRepository(FineOperation::class)->getGroupedByUserActions($dateStart, $dateEnd, [OperationType::DIRECTORS_CONFIRMATION], $user, UserGroup::WORKERS_GROUP_NAMES, VerificationStatus::NEGATIVELY_VERIFIED);
$groupedResponses = [];
foreach ($allVerificationOperations as $operation) {
$groupedResponses[$operation['authorUsername']][$operation['createdDate']] = [
'date' => $operation['createdDate'],
'allOperations' => $operation['typeCount'],
'positiveOperations' => 0,
'negativeOperations' => 0,
'confirmPositiveOperations' => 0,
'confirmNegativeOperations' => 0
];
}
foreach ($positiveVerifications as $operation) {
$groupedResponses[$operation['authorUsername']][$operation['createdDate']]['positiveOperations'] = $operation['typeCount'];
}
foreach ($negativeVerifications as $operation) {
$groupedResponses[$operation['authorUsername']][$operation['createdDate']]['negativeOperations'] = $operation['typeCount'];
}
foreach ($confirmPositiveVerifications as $operation) {
$groupedResponses[$operation['authorUsername']][$operation['createdDate']]['confirmPositiveOperations'] = $operation['typeCount'];
}
foreach ($confirmNegativeVerifications as $operation) {
$groupedResponses[$operation['authorUsername']][$operation['createdDate']]['confirmNegativeOperations'] = $operation['typeCount'];
}
foreach ($groupedResponses as $userKey => $userResponses) {
foreach ($userResponses as $dateKey => $dateResponse) {
$groupedResponses[$userKey][$dateKey]['otherOperations'] = $dateResponse['allOperations'] - $dateResponse['positiveOperations'] - $dateResponse['negativeOperations'] - $dateResponse['confirmPositiveOperations'] - $dateResponse['confirmNegativeOperations'];
}
}
return new JsonResponse($groupedResponses);
}
/**
* Metoda do wyciągania statystyk operacji wykonanych przez uzytkownikow w danym przedziale czasowym
*
* start - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* end - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
* user - ID użytkownika (jeżeli 0 to wszyscy użytkownicy)
*/
#[Route(path: '/get-request-log-statements', name: 'get-request-log-statements', methods: ['GET'])]
public function getRequestLogStatements(EntityManagerInterface $manager, Request $request)
{
$dateStart = new \DateTime($request->query->get('dateStart'));
$dateEnd = new \DateTime($request->query->get('dateEnd'));
$user = $request->query->get('user');
$unformattedStats = $manager->getRepository(RequestLogHistory::class)->getGroupedByDay($dateStart, $dateEnd, 'verify', $user, UserGroup::WORKERS_GROUP_NAMES);
$groupedResponses = [];
foreach ($unformattedStats as $operation) {
$groupedResponses[$operation['authorUsername']][$operation['createdDate']] = [
'date' => $operation['createdDate'],
'count' => $operation['typeCount']
];
}
return new JsonResponse($groupedResponses);
}
/**
* Metoda do wyciągania statystyk esportów w danym przedziale czasowym
*
* start - data i czas startu (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 00:00:00")
* end - data i czas końca (format "YYYY-MM-DD HH:mm:ss", np.: "2022-06-09 23:59:59")
*/
#[Route(path: '/get-log-exports-statements', name: 'get-log-exports-statements', methods: ['GET'])]
public function getLogExportsStatements(EntityManagerInterface $manager, Request $request)
{
$dateStart = new \DateTime($request->query->get('dateStart'));
$dateEnd = new \DateTime($request->query->get('dateEnd'));
$unformattedStats = $manager->getRepository(LogExport::class)->getGroupedByDay($dateStart, $dateEnd);
$groupedResponses = ['' => []];
foreach ($unformattedStats as $export) {
$groupedResponses[''][$export['createdDate']]['createdDate'] = $export['createdDate'];
$groupedResponses[''][$export['createdDate']]['s' . $export['status']] = $export['typeCount']; // Muszę tutaj dodać jakąś literkę, bo Vue.js przerabia kolejność kolumn, jeżeli zinterpretuje, że część z nich to inty :)
}
foreach ($groupedResponses[''] as $date => $response) {
if (!array_key_exists('s0', $response)) {
$groupedResponses[''][$date]['s0'] = 0;
}
if (!array_key_exists('s200', $response)) {
$groupedResponses[''][$date]['s200'] = 0;
}
if (!array_key_exists('s201', $response)) {
$groupedResponses[''][$date]['s201'] = 0;
}
if (!array_key_exists('s409', $response)) {
$groupedResponses[''][$date]['s409'] = 0;
}
$groupedResponses[''][$date]['count'] = $groupedResponses[''][$date]['s0'] + $groupedResponses[''][$date]['s200'] + $groupedResponses[''][$date]['s201'] + $groupedResponses[''][$date]['s409'];
}
return new JsonResponse($groupedResponses);
}
#[Route(path: '/save-image', name: 'save_image', methods: ['POST'])]
public function saveImage(Request $request): JsonResponse
{
$file = $request->files->get('file');
$mode = $request->request->get('mode');
$requestLogId = $request->request->get('requestLogId');
$errors = [];
if (!$file) {
$errors[] = 'file is missing';
}
if (!$mode) {
$errors[] = 'mode is missing';
}
if (!$requestLogId) {
$errors[] = 'requestLogId is missing';
}
if (!empty($errors)) {
return new JsonResponse(['errors' => $errors], Response::HTTP_BAD_REQUEST);
}
$curl = \curl_init();
\curl_setopt_array($curl, [
CURLOPT_URL => $_ENV['WS_ADDRESS_PHOTO'] . 'upload-file',
CURLOPT_POSTFIELDS => [
'mode' => $mode,
'file' => new \CURLFile($file->getPathname(), $file->getMimeType(), $file->getClientOriginalName()),
'requestLogId' => $requestLogId
],
CURLOPT_HTTPHEADER => [
'Content-Type: multipart/form-data',
'Access-Control-Allow-Origin: *'
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
]);
$result = \curl_exec($curl);
$info = \curl_getinfo($curl);
\curl_close($curl);
return new JsonResponse([
'response' => $result,
'code' => $info['http_code']
]);
}
}