src/Controller/Api/TimesheetController.php line 635

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Api;
  3. use App\Entity\AccessRoles;
  4. use App\Entity\Branches;
  5. use App\Entity\ProjectBranches;
  6. use App\Entity\ProjectOrders;
  7. use App\Entity\Projects;
  8. use App\Entity\ProjectStakeholders;
  9. use App\Entity\TimesheetStatus;
  10. use App\Entity\WorkerActivities;
  11. use App\Entity\WorkerInProject;
  12. use App\Entity\WorkerTimesheet;
  13. use App\Entity\WorkerTimesheetHistories;
  14. use App\Service\PdfOutputTimesheet;
  15. use App\Service\RgbToHex;
  16. use App\Service\TimesheetInterface\TimesheetHistoryInterface;
  17. use App\Service\TimesheetInterface\TimesheetReaderInterface;
  18. use App\Service\TimesheetInterface\TimesheetWriterInterface;
  19. use App\Service\TimesheetSpecificMonthDays;
  20. use Doctrine\Common\Collections\ArrayCollection;
  21. use Doctrine\ORM\EntityManagerInterface;
  22. use Doctrine\ORM\Mapping\Entity;
  23. use IntlCalendar;
  24. use Matrix\Exception;
  25. use Monolog\DateTimeImmutable;
  26. use phpDocumentor\Reflection\Project;
  27. use phpDocumentor\Reflection\Types\This;
  28. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  29. use Symfony\Component\HttpFoundation\InputBag;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use Symfony\Component\Routing\Annotation\Route;
  32. use Symfony\Component\HttpFoundation\Response;
  33. use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
  34. use Symfony\Component\Serializer\SerializerInterface;
  35. use Symfony\Component\Validator\Constraints\DateTime;
  36. use Symfony\Contracts\Translation\TranslatorInterface;
  37. use function PHPUnit\Framework\returnArgument;
  38. use function Symfony\Component\DependencyInjection\Loader\Configurator\param;
  39. /**
  40.  * @Route("/api/timesheet")
  41. */
  42. class TimesheetController extends AISAbstractController {
  43.     /**
  44.      * @Route("/test", name="app_api_timesheet_test", methods={"POST"})
  45.     */
  46.     public function test(): Response {
  47.         return $this->json([
  48.             'message' => 'Successfully'
  49.         ]);
  50.     }
  51.     /**
  52.      * @Route("/status", name="app_api_timesheet_status", methods={"POST"})
  53.      */
  54.     public function status(EntityManagerInterface $managerSerializerInterface $serializer): Response {
  55.         $status $manager->getRepository(TimesheetStatus::class)->findAll();
  56.         $status json_decode($serializer->serialize($status'json', [
  57.             'groups' => [
  58.             ]
  59.         ]), true );
  60.         return $this->json([
  61.             'message' => 'Successfully',
  62.             'status' => $status
  63.         ]);
  64.     }
  65.     /**
  66.      * @Route("/employee-list/{project_id}/{order_id}/{branch_id}", name="employee_list", methods={"POST"}, defaults={"project_id": null, "order_id": null, "branch_id": null})
  67.      * @ParamConverter("project", options={"mapping":{"project_id":"id"}})
  68.      * @ParamConverter("order", options={"mapping":{"order_id":"id"}})
  69.      * @ParamConverter("branch", options={"mapping":{"branch_id":"id"}})
  70.      */
  71.     // public function employeeListOfJoinedProject(Projects $project, ProjectOrders $order, ProjectBranches $projectBranch, SerializerInterface $serializer, TranslatorInterface $translator, EntityManagerInterface $manager, Request $request, ?int $project_branch_id = null ): Response {
  72.     public function employeeList( ?Projects $project, ?ProjectOrders $order, ?Branches $branchSerializerInterface $serializerTimesheetSpecificMonthDays $timesheetSpecificMonthDaysTranslatorInterface $translatorEntityManagerInterface $managerRequest $requestint $project_id null,  int $order_id null,  int $branch_id null ): Response {
  73.         $year $request->request->get('year');
  74.         $month $request->request->get('month');
  75.         $workers = [];
  76.         # dd($year, $month);
  77.         // dd($branch);
  78.         if( $project ){
  79.             $timesheetSpecificMonthDays->initWithDomain$project$order$branch );
  80.             $project->getStakeholders()->map(function(/**@var $projectStakeholder ProjectStakeholders*/$projectStakeholder) use ($project$branch, &$workers$month$year$timesheetSpecificMonthDays ){
  81.                 $sys 1;
  82.                 $dym 'Branched';
  83.                 if($sys === 1){
  84.                     if($branch){
  85.                         $workersInProjects $projectStakeholder->getWorkerInProjects()->filter(function (/**@var WorkerInProject $workerInProject*/ $workerInProject) use ($branch) {
  86.                             return $workerInProject->getAssignedProjectBranches()->exists(function ( $key/**@var ProjectBranches $projectBranch*/ $projectBranch) use ($branch) {
  87.                                 return $projectBranch->getBranch()->getId() === $branch->getId();
  88.                             });
  89.                         });
  90.                     }
  91.                     else {
  92.                         $workersInProjects $projectStakeholder->getWorkerInProjects()->filter(function(/**@var WorkerInProject $workerInProject*/ $workerInProject ) use ($project){
  93.                             return $workerInProject->getProject()->getProject()->getId() === $project->getId();
  94.                         });
  95.                         $dym 'No-Branched';
  96.                     }
  97.                     # dump($projectStakeholder->getCustomer()->getCompany(), $workersInProjects->count(), $dym);
  98.                     $workersInProjects->map(function(/**@var WorkerInProject $workerInProject*/ $workerInProject ) use (&$workers$year$month$timesheetSpecificMonthDays){
  99.                         $workerActivity $workerInProject->getWorkerActivity();
  100.                         /** @var $foundedTimeSheet WorkerTimesheet */
  101.                         $foundedTimeSheet $workerActivity->getWorkerTimesheets()->filter(function (/** @var $workerTimesheet WorkerTimesheet */ $workerTimesheet) use (&$workers$year$month$timesheetSpecificMonthDays ) {
  102.                             return $workerTimesheet->getYear() === intval($year);
  103.                         })->first();
  104.                         $specifiedTimesheet = [];
  105.                         if($foundedTimeSheet){
  106.                             /** @var $specifiedTimesheet WorkerTimesheet */
  107.                             // $specifiedTimesheet = $foundedTimeSheet->getSpecificMonths($year, $month, $timesheetReader ); // Tüm kolonları bir dizi olarak al
  108.                             $specifiedTimesheet $timesheetSpecificMonthDays->getSpecificMonths$year$month$foundedTimeSheet ); // Tüm kolonları bir dizi olarak al
  109.                         }
  110.                         $hasExit $workerActivity->getExitAt() && $workerActivity->getExitAt() <  new \DateTimeImmutable('now');
  111.                         $workers[] = [
  112.                             "id" => $workerActivity->getId(),
  113.                             "is_kpi_responsible" => $workerActivity->isIsKpiResponsible(),
  114.                             "status" => !$hasExit,
  115.                             "exit_at" => $workerActivity->getExitAt(),
  116.                             "entry_at" => $workerActivity->getEntryAt(),
  117.                             "worker" => [
  118.                                 "name" => $workerActivity->getWorker()->getName(),
  119.                                 "surname" => $workerActivity->getWorker()->getSurname(),
  120.                             ],
  121.                             "customer" => $workerActivity->getCustomer(),
  122.                             "timesheet" => $specifiedTimesheet,
  123.                             "timesheet_revisions" => $foundedTimeSheet $foundedTimeSheet->getWorkerTimesheetHistories(): [],
  124.                         ];
  125.                     });
  126.                 }
  127.                 else {
  128.                     $projectStakeholder->getWorkerInProjects()->map(function(/**@var $workerInProject WorkerInProject*/$workerInProject) use ($branch, &$workers$month$year$timesheetSpecificMonthDays ){
  129.                         if($branch){
  130.                             $assigned $workerInProject->getAssignedProjectBranches()->filter(function (/**@var $workerAssignedProjectBranches ProjectBranches*/ $workerAssignedProjectBranches) use ($branch, &$workers$month$year$timesheetSpecificMonthDays ){
  131.                                 return $workerAssignedProjectBranches->getBranch()->getId() === $branch->getId();
  132.                             })->first();
  133.                             if( $assigned ){
  134.                                 $workerActivity $workerInProject->getWorkerActivity();
  135.                                 /** @var $foundedTimeSheet WorkerTimesheet */
  136.                                 $foundedTimeSheet $workerActivity->getWorkerTimesheets()->filter(function (/** @var $workerTimesheet WorkerTimesheet */ $workerTimesheet) use (&$workers$year$month$timesheetSpecificMonthDays ) {
  137.                                     return $workerTimesheet->getYear() === intval($year);
  138.                                 })->first();
  139.                                 $specifiedTimesheet = [];
  140.                                 if($foundedTimeSheet){
  141.                                     /** @var $specifiedTimesheet WorkerTimesheet */
  142.                                     // $specifiedTimesheet = $foundedTimeSheet->getSpecificMonths($year, $month, $timesheetReader ); // Tüm kolonları bir dizi olarak al
  143.                                     $specifiedTimesheet $timesheetSpecificMonthDays->getSpecificMonths$year$month$foundedTimeSheet ); // Tüm kolonları bir dizi olarak al
  144.                                 }
  145.                                 $hasExit $workerActivity->getExitAt() && $workerActivity->getExitAt() <  new \DateTimeImmutable('now');
  146.                                 $workers[] = [
  147.                                     "id" => $workerActivity->getId(),
  148.                                     "is_kpi_responsible" => $workerActivity->isIsKpiResponsible(),
  149.                                     "status" => !$hasExit,
  150.                                     "exit_at" => $workerActivity->getExitAt(),
  151.                                     "entry_at" => $workerActivity->getEntryAt(),
  152.                                     "worker" => [
  153.                                         "id" => $workerActivity->getWorker()->getId(),
  154.                                         "name" => $workerActivity->getWorker()->getName(),
  155.                                         "surname" => $workerActivity->getWorker()->getSurname(),
  156.                                     ],
  157.                                     "customer" => $workerActivity->getCustomer(),
  158.                                     "timesheet" => $specifiedTimesheet,
  159.                                     "timesheet_revisions" => $foundedTimeSheet $foundedTimeSheet->getWorkerTimesheetHistories(): [],
  160.                                 ];
  161.                             }
  162.                         } else {
  163.                             $workerActivity $workerInProject->getWorkerActivity();
  164.                             /** @var $foundedTimeSheet WorkerTimesheet */
  165.                             $foundedTimeSheet $workerActivity->getWorkerTimesheets()->filter(function (/** @var $workerTimesheet WorkerTimesheet */ $workerTimesheet) use (&$workers$year$month$timesheetSpecificMonthDays ) {
  166.                                 return $workerTimesheet->getYear() === intval($year);
  167.                             })->first();
  168.                             $specifiedTimesheet = [];
  169.                             if($foundedTimeSheet){
  170.                                 /** @var $specifiedTimesheet WorkerTimesheet */
  171.                                 // $specifiedTimesheet = $foundedTimeSheet->getSpecificMonths($year, $month, $timesheetReader ); // Tüm kolonları bir dizi olarak al
  172.                                 $specifiedTimesheet $timesheetSpecificMonthDays->getSpecificMonths$year$month$foundedTimeSheet ); // Tüm kolonları bir dizi olarak al
  173.                             }
  174.                             $hasExit $workerActivity->getExitAt() && $workerActivity->getExitAt() <  new \DateTimeImmutable('now');
  175.                             $workers[] = [
  176.                                 "id" => $workerActivity->getId(),
  177.                                 "is_kpi_responsible" => $workerActivity->isIsKpiResponsible(),
  178.                                 "status" => !$hasExit,
  179.                                 "exit_at" => $workerActivity->getExitAt(),
  180.                                 "entry_at" => $workerActivity->getEntryAt(),
  181.                                 "worker" => [
  182.                                     "id" => $workerActivity->getWorker()->getId(),
  183.                                     "name" => $workerActivity->getWorker()->getName(),
  184.                                     "surname" => $workerActivity->getWorker()->getSurname(),
  185.                                 ],
  186.                                 "customer" => $workerActivity->getCustomer(),
  187.                                 "timesheet" => $specifiedTimesheet,
  188.                                 "timesheet_revisions" => $foundedTimeSheet $foundedTimeSheet->getWorkerTimesheetHistories(): [],
  189.                             ];
  190.                         }
  191.                     });
  192.                 }
  193.             });
  194.         }
  195.         else {
  196.             $timesheetSpecificMonthDays->initWithDomain$project$order$branch );
  197.             // All employees in Timesheet
  198.             $workerActivities = new ArrayCollection($manager->getRepository(WorkerActivities::class)->findAll());
  199.             $workers $workerActivities->map(function(/**@var $workerActivity WorkerActivities*/ $workerActivity) use (&$workers$year$month$timesheetSpecificMonthDays$serializer ){
  200.                 /** @var $foundedTimeSheet WorkerTimesheet */
  201.                 $foundedTimeSheet $workerActivity->getWorkerTimesheets()->filter(function (/** @var $workerTimesheet WorkerTimesheet */ $workerTimesheet) use (&$workers$year$month$timesheetSpecificMonthDays ) {
  202.                     return $workerTimesheet->getYear() === intval($year);
  203.                 })->first();
  204.                 $specifiedTimesheet = [];
  205.                 if($foundedTimeSheet){
  206.                     /** @var $specifiedTimesheet WorkerTimesheet */
  207.                     # $specifiedTimesheet = $foundedTimeSheet->getSpecificMonths($year, $month); // Tüm kolonları bir dizi olarak al
  208.                     $specifiedTimesheet $timesheetSpecificMonthDays->getSpecificMonths$year$month$foundedTimeSheet ); // Tüm kolonları bir dizi olarak al
  209.                 }
  210.                 $hasExit $workerActivity->getExitAt() && $workerActivity->getExitAt() <  new \DateTimeImmutable('now');
  211.                 return [
  212.                     "id" => $workerActivity->getId(),
  213.                     "is_kpi_responsible" => $workerActivity->isIsKpiResponsible(),
  214.                     "status" => !$hasExit,
  215.                     "exit_at" => $workerActivity->getExitAt(),
  216.                     "entry_at" => $workerActivity->getEntryAt(),
  217.                     "worker" => [
  218.                         "id" => $workerActivity->getWorker()->getId(),
  219.                         "name" => $workerActivity->getWorker()->getName(),
  220.                         "surname" => $workerActivity->getWorker()->getSurname(),
  221.                     ],
  222.                     "customer" => $workerActivity->getCustomer(),
  223.                     "timesheet" => $specifiedTimesheet,
  224.                     "timesheet_revisions" => $foundedTimeSheet $foundedTimeSheet->getWorkerTimesheetHistories(): [],
  225.                 ];
  226.             });
  227.         }
  228.         #dd(count($workers));
  229.         $serializedWorkers json_decode($serializer->serialize($workers'json', [
  230.             'groups' => [
  231.                 "worker.in.project.worker.activity",
  232.                 "worker.in.project.worker.activity.base",
  233.                 "worker.in.project.worker.activity.worker",
  234.                 "worker.base",
  235.                 "worker.in.project.worker.activity.customer",
  236.                 "customer.base",
  237.                 "timesheet.history",
  238.                 "timesheet.history.base",
  239.             ]
  240.         ]));
  241.         return $this->json([
  242.             "message" => "Successfully",
  243.             "severity"=>"success",
  244.             "serializedWorkers"=>$serializedWorkers
  245.         ], Response::HTTP_OK, []);
  246.     }
  247.     /**
  248.      * @Route("/pdf-output/{worker_activity_id}/{project_id}/{project_order_id}/{branch_id}", name="app_api_timesheet_pdf_output", methods={"POST"}, defaults={ "project_id"=null, "branch_id"=null, "project_order_id"=null })
  249.      * @ParamConverter("workerActivity", options={"mapping":{"worker_activity_id":"id"}})
  250.      * @ParamConverter("project", options={"mapping":{"project_id":"id"}})
  251.      * @ParamConverter("branch", options={"mapping":{"branch_id":"id"}})
  252.      * @ParamConverter("projectOrder", options={"mapping":{"project_order_id":"id"}})
  253.      * @param TimesheetReaderInterface $timesheetReader
  254.      * @param WorkerActivities $workerActivity
  255.      * @param PdfOutputTimesheet $pdfOutputTimesheet
  256.      * @param Projects|null $project
  257.      * @param Branches|null $branch
  258.      * @param ProjectOrders|null $projectOrder
  259.      * @param SerializerInterface $serializer
  260.      * @param TranslatorInterface $translator
  261.      * @param RgbToHex $rgbToHex
  262.      * @param Request $request
  263.      * @param EntityManagerInterface $manager
  264.      * @param int|null $project_order
  265.      * @return Response
  266.      */
  267.     public function workerTimesheetPDF(TimesheetReaderInterface $timesheetReaderWorkerActivities $workerActivityPdfOutputTimesheet $pdfOutputTimesheet, ?Projects $project, ?Branches $branch, ?ProjectOrders $projectOrder SerializerInterface $serializerTranslatorInterface $translatorRgbToHex $rgbToHexRequest $requestEntityManagerInterface $managerint $project_order null): Response
  268.     {
  269.         $params $request->request;
  270.         $month  intval($params->get('month'));
  271.         $year   intval($params->get('year'));
  272.         /// TODO Should remove
  273.         $read_mode $params->get('read_mode');
  274.         $absolutePdfInfoPathText = [];
  275.         if( $project ){
  276.             $absolutePdfInfoPathText[] = $project->getName();
  277.         }
  278.         if( $branch ){
  279.             $absolutePdfInfoPathText[] = $branch->getName();
  280.         }
  281.         if($projectOrder){
  282.             $absolutePdfInfoPathText[] = $projectOrder->getOrderNr();
  283.         }
  284.         if (!$year && !$month) {
  285.             return $this->json([
  286.                 'message' => $translator->trans('Please select year & month first!'),
  287.                 "severity" => "warning",
  288.             ], Response::HTTP_UNAUTHORIZED ) ;
  289.         }
  290.         $foundedYear $workerActivity->getWorkerTimesheets()->filter( function (/**@var WorkerTimesheet $workerTimesheet*/ $workerTimesheet ) use ( $year ){
  291.             return $year === $workerTimesheet->getYear();
  292.         })->first();
  293.         if( !$foundedYear ){
  294.             return $this->json([
  295.                 'message' => 'B' $translator->trans('Timesheet not found!!'),
  296.                 "severity" => "warning",
  297.             ], Response::HTTP_NO_CONTENT ) ;
  298.         }
  299.         $timesheetStatus = (new ArrayCollection($manager->getRepository(TimesheetStatus::class)->findAll() ?? []))->map( function(/**@var $item TimesheetStatus*/ $item ) use ($rgbToHex){
  300.             $item->setAbsenceColorHex($rgbToHex->convertWithArray($item->getAbsenceBrColor()));
  301.             return $item;
  302.         });
  303.         try{
  304.             /**
  305.              * Found day's of month
  306.              */
  307.             $intlCalendar IntlCalendar::createInstance(null"@calendar=gregorian");
  308.             $intlCalendar->set(IntlCalendar::FIELD_MONTH$month 1); // Months in IntlCalendar are 0-based (0 to 11)
  309.             $intlCalendar->set(IntlCalendar::FIELD_YEAR$year);
  310.             $numberOfDays $intlCalendar->getActualMaximum(IntlCalendar::FIELD_DAY_OF_MONTH);
  311.         }
  312.         catch (\Exception $exception ){
  313.             return $this->json([
  314.                 'message' => 'A' $exception->getMessage(),
  315.                 "severity" => "error"
  316.             ], Response::HTTP_CONFLICT );
  317.         }
  318.         try{
  319.             $serializedTimesheet json_decode($serializer->serialize($foundedYear'json', [
  320.                 'groups' => [
  321.                     'worker.manage.base.timesheet'
  322.                 ],
  323.                 AbstractNormalizer::IGNORED_ATTRIBUTES => [
  324.                     // 'worker_activity'
  325.                 ]
  326.             ]), true );
  327.         } catch (\Exception $exception ){
  328.             return $this->json([
  329.                 'message' => 'C' $exception->getMessage(),
  330.                 "severity" => "error"
  331.             ], Response::HTTP_CONFLICT );
  332.         }
  333.         try{
  334.             // Dinamik olarak belirlenen "m" harfi sonrasındaki rakamı içeren bir filtre fonksiyonu
  335.             $pattern '/^m' $month '\_d\d+?$/';
  336.             $activeColumns array_filterarray_keys($serializedTimesheet), function($item) use ($pattern) {
  337.                 return preg_match($pattern$item);
  338.             });
  339.             $activeColumns array_values($activeColumns);
  340.             foreach ($serializedTimesheet as $key => $item ) {
  341.                 if( !in_array($key$activeColumns) ){
  342.                     unset($serializedTimesheet[$key]);
  343.                 }
  344.             }
  345.         }
  346.         catch (\Exception $exception ){
  347.             return $this->json([
  348.                 'message' => 'D' $exception->getMessage(),
  349.                 "severity" => "error"
  350.             ], Response::HTTP_CONFLICT );
  351.         }
  352.         // Initial Values
  353.         $timesheetReader
  354.             ->setTimesheetStatusCollection($timesheetStatus)
  355.             ->setMonth($month);
  356.         try{
  357.             $finalDayTotalWithAllProjects = [];
  358.             $timesCollection $workerActivity->getWorkerInProjects()->filter(function( /**@var $workerInProject WorkerInProject*/ $workerInProject) use ( $project$branch$projectOrder ){
  359.                 if( !is_null($branch) ){
  360.                     return $workerInProject->getProject()->getProject()->getId() === $project->getId()
  361.                         && $workerInProject->getAssignedProjectBranches()->filter(function(/**@var $assignedProjectBranches ProjectBranches*/ $assignedProjectBranches ) use ( $branch ){
  362.                             return $assignedProjectBranches->getBranch()->getId() === $branch->getId();
  363.                         })->first() && $workerInProject->getProject()->getProject()->getProjectOrders()->filter(function(/**@var $_projectOrder ProjectOrders*/ $_projectOrder ) use ( $projectOrder ){
  364.                             return $_projectOrder->getId() === $projectOrder->getId();
  365.                         })->first();
  366.                 }
  367.                 // TODO Eger Branch Secilmesse bile gösteriyor
  368.                 if( !is_null($projectOrder)) {
  369.                     return $workerInProject->getProject()->getProject()->getId() === $project->getId()
  370.                         && $workerInProject->getProject()->getProject()->getProjectOrders()->filter(function(/**@var $order ProjectOrders*/ $order) use ($projectOrder){
  371.                             return $order->getId() === $projectOrder->getId();
  372.                         })->first();
  373.                 }
  374. //                if( !is_null($projectOrder) ){
  375. //                    return $workerInProject->getProject()->getProject()->getId() === $project->getId()
  376. //                        && $workerInProject->getAssignedProjectBranches()->filter(function(/**@var $assignedProjectBranches ProjectBranches*/ $assignedProjectBranches ) use ( $branch ){
  377. //                            return $assignedProjectBranches->getBranch()->getId() === $branch->getId();
  378. //                        })->first() && $workerInProject->getProject()->getProject()->getProjectOrders()->filter(function(/**@var $_projectOrder ProjectOrders*/ $_projectOrder ) use ( $projectOrder ){
  379. //                            return $_projectOrder->getId() === $projectOrder->getId();
  380. //                        })->first();
  381. //                }
  382. //                if( !is_null($branch)) {
  383. //                    return $workerInProject->getProject()->getProject()->getId() === $project->getId()
  384. //                        && $workerInProject->getAssignedProjectBranches()->filter(function(/**@var $assignedProjectBranches ProjectBranches*/ $assignedProjectBranches ) use ( $branch ){
  385. //                            return $assignedProjectBranches->getBranch()->getId() === $branch->getId();
  386. //                        })->first();
  387. //                }
  388.                 if( !is_null($project) ){
  389.                     return $workerInProject->getProject()->getProject()->getId() === $project->getId() ? $workerInProject null;
  390.                 }
  391.                 return $workerInProject;
  392.             })
  393.                 ->map( function( /**@var $workerInProject WorkerInProject*/ $workerInProject) use ( $timesheetReader, &$finalDayTotalWithAllProjects$serializedTimesheet$workerActivity$month$timesheetStatus$project$branch$projectOrder ){
  394.                     // Update Stakeholder
  395.                     if( $project ){
  396.                         $timesheetReader->readerPathManager$project$branch$projectOrder );
  397.                     }
  398.                     else {
  399.                         $timesheetReader->readerPathManager$workerInProject->getProject()->getProject(), $branch$projectOrder );
  400.                     }
  401.                     $days = [];
  402.                     foreach ($serializedTimesheet as $dayKey => $object) {
  403.                         $timesheetReader
  404.                             ->setDayKey($dayKey)
  405.                             ->setData($object);
  406.                         $days[$dayKey] = $timesheetReader->readTimeExtendRolesBasic();
  407.                         // From All project same day add worked time
  408.                         if( array_key_exists($timesheetReader::KEY_TIME_PROP$days[$dayKey])){
  409.                             if( $days[$dayKey][$timesheetReader::KEY_ABSENCE_SHORT_KEY_PROP] === ABSENCE_PRESENT ){
  410.                                 $finalDayTotalWithAllProjects[$dayKey][] = $days[$dayKey][$timesheetReader::KEY_TIME_PROP];
  411.                             }
  412.                             else {
  413.                                 // Absence Not Present Should Time add just one time
  414.                                 if( !array_key_exists$dayKey$finalDayTotalWithAllProjects ) ){
  415.                                     $finalDayTotalWithAllProjects[$dayKey][] = $days[$dayKey][$timesheetReader::KEY_TIME_PROP];
  416.                                 }
  417.                             }
  418.                         }
  419.                         else {
  420.                             if( !array_key_exists$dayKey$finalDayTotalWithAllProjects ) ){
  421.                                 $finalDayTotalWithAllProjects[$dayKey] = [];
  422.                             }
  423.                         }
  424.                     }
  425.                     $projectTime = [];
  426.                     $projectCost = [];
  427.                     $projectActiveCost = [];
  428.                     $projectInactiveCost = [];
  429.                     array_map( function($item) use ($timesheetReader, &$projectTime, &$projectCost, &$projectActiveCost, &$projectInactiveCost ){
  430.                         if( array_key_exists$timesheetReader::KEY_COST_TYPE $item ) ){
  431.                             if( $item[$timesheetReader::KEY_COST_TYPE] === $timesheetReader::KEY_COST_TYPE_ACTIVE ){
  432.                                 $projectActiveCost[] = $item[$timesheetReader::KEY_COST ];
  433.                                 $projectTime[] = $item[$timesheetReader::KEY_TIME_PROP ];
  434.                             }
  435.                             if( $item[$timesheetReader::KEY_COST_TYPE] === $timesheetReader::KEY_COST_TYPE_INACTIVE ){
  436.                                 $projectInactiveCost[] = $item[$timesheetReader::KEY_COST ];
  437.                             }
  438.                             $projectCost[] = $item[$timesheetReader::KEY_COST ];
  439.                         }
  440.                     }, array_values($days) );
  441.                     return [
  442.                         "name" => $workerInProject->getProject()->getProject()->getName(),
  443.                         "days" => $days,
  444.                         "projectTime" => array_sum($projectTime),
  445.                         "projectCost" => array_sum($projectCost),
  446.                         "projectActiveCost" => array_sum($projectActiveCost),
  447.                         "projectInactiveCost" => array_sum($projectInactiveCost),
  448.                     ];
  449.                 });
  450.             #dd();
  451.             #dd($timesCollection);
  452.             $costCollection = [];
  453.             $activeCostCollection = [];
  454.             $inActiveCostCollection = [];
  455.             $timesCollection->map(function ($project) use( &$costCollection, &$activeCostCollection, &$inActiveCostCollection ){
  456.                 $costCollection[] = $project['projectCost'];
  457.                 $activeCostCollection[] = $project['projectActiveCost'];
  458.                 $inActiveCostCollection[] = $project['projectInactiveCost'];
  459.             });
  460.             $costs = [
  461.                 // "costs" => array_sum($costCollection),
  462.                 // For Inactive Costs need just one part
  463.                 // Inactive Cost show only if not Project ( Stakeholder selected )
  464.                 "inActiveCost" => $project "-" $inActiveCostCollection[0], // array_sum($inActiveCostCollection),
  465.                 "activeCost" => array_sum($activeCostCollection),
  466.                 // Inactive Cost show only if not Project ( Stakeholder selected )
  467.                 "costs" => array_sum(array_merge($activeCostCollection, [$project $inActiveCostCollection[0]])),
  468.             ];
  469.         }
  470.         catch (\Exception $exception ){
  471.             return $this->json([
  472.                 'message' => 'E' $exception->getTraceAsString(),
  473.                 "severity" => "error"
  474.             ], Response::HTTP_CONFLICT );
  475.         }
  476.         $printedBy $translator->trans('Anonymous');
  477.         try{
  478.             if(!is_null($this->getUser())){
  479.                 $printedBy $this->getUser()->getEmail();
  480.             }
  481.         } catch (\Exception $exception){}
  482.         #dd($timesCollection);
  483.         try{
  484.             // Reindex Collection
  485.             // Safe Mode As selected Project
  486.             $timesCollection array_values($timesCollection->toArray());
  487.             #dd($timesCollection);
  488.             #dd($absolutePdfInfoPathText);
  489.             #if(true){
  490.             $output null;
  491.             $pdfOutputTimesheet->setPrintedBy$printedBy );
  492.             $output $pdfOutputTimesheet->workerTimesheet(
  493.                 $translator->trans('Timesheet') . ' ' $workerActivity->getWorker()->getName() . ' ' $workerActivity->getWorker()->getSurname(),
  494.                 implode(" / "$absolutePdfInfoPathText ),
  495.                 $month,
  496.                 $year,
  497.                 $timesCollection,
  498.                 $costs,
  499.                 $timesheetStatus,
  500.                 array_map(function ($item) {
  501.                     return array_sum($item);
  502.                 }, $finalDayTotalWithAllProjects),
  503.                 'F'
  504.             );
  505.             #}
  506.             #dd(32);
  507.         }
  508.         catch (\Exception $exception ){
  509.             return $this->json([
  510.                 'message' => 'F:' $exception->getMessage(),
  511.                 "severity" => "error"
  512.             ], Response::HTTP_NOT_FOUND );
  513.         }
  514.         return $this->json([
  515.             'message' => $translator->trans('Timesheet created successfully!'),
  516.             "severity" => "success",
  517.             "output" => $output
  518.         ]);
  519.     }
  520.     /**
  521.      * @Route("/add-time-v2/{project_id}/{project_order_id}/{branch_id}", name="worker_timesheet_add_time_v2", methods={"POST"}, defaults={"project_id": null, "branch_id": null, "project_order_id": null } )
  522.      * @ParamConverter("project", options={"mapping":{"project_id":"id"}})
  523.      * @ParamConverter("branch", options={"mapping":{"branch_id":"id"}})
  524.      * @ParamConverter("projectOrder", options={"mapping": {"project_order_id": "id"}})
  525.      * @throws \Exception
  526.      */
  527.     public function timesheetAddTime_v2 ( ?Projects $project, ?Branches $branch, ?ProjectOrders $projectOrderTimesheetReaderInterface $timesheetReaderTimesheetWriterInterface $timesheetWriterTimesheetHistoryInterface $timesheetHistorySerializerInterface $serializerTranslatorInterface $translatorRequest $requestEntityManagerInterface $managerTimesheetSpecificMonthDays $timesheetSpecificMonthDays ): Response
  528.     {
  529. //        return $this->json([
  530. //            'message' => $translator->trans('Out of service, Coming soon!'),
  531. //            "severity" => "info",
  532. //            "variant"=>"snackbar"
  533. //        ], Response::HTTP_NOT_ACCEPTABLE );
  534.         $params     $request->request;
  535.         #dd($params);
  536.        /* dump($params);
  537.         dump($project->getName());
  538.         dump($projectOrder->getOrderNr());
  539.         dump($branch->getName());*/
  540.         // CheckUp start...
  541.         if( $params->get('calendar_day_selected_action') === "P" ){
  542.             if( !$project->getProjectId() ){
  543.                 return $this->json([
  544.                     'message' => $translator->trans('ProjectID required!'),
  545.                     "severity" => "error",
  546.                     "variant"=>"snackbar"
  547.                 ], Response::HTTP_NOT_ACCEPTABLE );
  548.             }
  549.             if(!$projectOrder->getId()){
  550.                 return $this->json([
  551.                     'message' => $translator->trans('Project order required!'),
  552.                     "severity" => "error",
  553.                     "variant"=>"snackbar"
  554.                 ], Response::HTTP_NOT_ACCEPTABLE );
  555.             }
  556.             if(!$branch->getId()){
  557.                 return $this->json([
  558.                     'message' => $translator->trans('Project branch required!'),
  559.                     "severity" => "error",
  560.                     "variant"=>"snackbar"
  561.                 ], Response::HTTP_NOT_ACCEPTABLE );
  562.             }
  563.         }
  564.         if( !$this->getUser() ){
  565.             return $this->json([
  566.                 'message' => $translator->trans('The operation must be performed by a user requiring authentication.!'),
  567.                 "severity" => "error",
  568.                 "variant"=>"snackbar"
  569.             ], Response::HTTP_NOT_ACCEPTABLE );
  570.         }
  571.         if( !$this->getUser()->getName() && !$this->getUser()->getSurname() ){
  572.             return $this->json([
  573.                 'message' => $translator->trans('You cannot proceed with the transaction as your name or surname is not specified in your account.!'),
  574.                 "severity" => "error",
  575.                 "variant"=>"snackbar"
  576.             ], Response::HTTP_NOT_ACCEPTABLE );
  577.         }
  578.         /**@var $userRole AccessRoles */
  579.         $userRole =$this->getUser()->getUserAccessedRoles()->filter(function(/**@var $item AccessRoles*/$item){
  580.             return $item->getAccessType()->getName() === 'Timesheet';
  581.         })->first();
  582.         if( !$userRole ){
  583.             return $this->json([
  584.                 'message' => $translator->trans('Access role required for this operation.'),
  585.                 "severity" => "error",
  586.                 "variant"=>"snackbar"
  587.             ], Response::HTTP_NOT_ACCEPTABLE );
  588.         }
  589.         $timesheetStatusCollection $manager->getRepository(TimesheetStatus::class)->findAll();
  590.         if( !count($timesheetStatusCollection) ){
  591.             return $this->json([
  592.                 'message' => $translator->trans('This process cannot continue as no status has been found in the collection. Please manage the time tracking status before proceeding.'),
  593.                 "severity" => "error",
  594.                 "variant"=>"snackbar"
  595.             ], Response::HTTP_NOT_ACCEPTABLE );
  596.         }
  597.         // Start Here...
  598.         $period     json_decode($params->get('period'), true);
  599.         $year       intval($period['year']['displayId']);
  600.         $month      intval($period['month']['displayId']);
  601.         $adder      =  $this->getUser() ? substr($this->getUser()->getName(), ,1) . '. ' $this->getUser()->getSurname() : "Anonymus";
  602.         // $writeMode  = $params->get('write_mode');
  603.         $time       $params->get('time');
  604.         $route      $params->get('route');
  605.         $employees      json_decode($params->get('employee_days'), true);
  606.         $employeeIds    array_keys($employees);
  607.         $writeMode      $timesheetWriter::TIMESHEET_WRITE_TYPE_DAILY;
  608.         $response       = [];
  609.         $workers        = [];
  610.         $absenceChangeReason json_decode($params->get('absenceChangeReason'), true);
  611.         $employeeCachedHistoryEntities = [];
  612.         /**@var $timesheetStatus TimesheetStatus */
  613.         $timesheetStatus = (new ArrayCollection($timesheetStatusCollection))->filter(function (/**@var $timesheetStatus TimesheetStatus */ $timesheetStatus) use ($time) {
  614.             // $time should be numeric(P) | S | H | HNP
  615.             return $timesheetStatus->getAbsenceShortKey() === (is_numeric($time) ? 'P' $time);
  616.         })->first();
  617.         // Table for Update Costs
  618.         $projectOrderCosts = new OrderCostController$timesheetReader$manager );
  619.         // Loop Employees
  620.         $nestedEmployees = new ArrayCollection($manager->getRepository(WorkerActivities::class)->findBy(['id' => $employeeIds]));
  621.         # dd($nestedEmployees->count());
  622.         #dd($project->getId());
  623.         $timesheetSpecificMonthDays->initWithDomain$project$projectOrder$branch );
  624.         $errors = [];
  625.         #dd($nestedEmployees);
  626.         $nestedEmployees->map(function( /**@var WorkerActivities $workerActivity*/ $workerActivity ) use (
  627.                 $timesheetStatus,
  628.                 $timesheetWriter,
  629.                 $serializer,
  630.                 $timesheetSpecificMonthDays,
  631.                 $project,
  632.                 $projectOrder,
  633.                 $branch,
  634.                 $userRole,
  635.                 $writeMode,
  636.                 $translator,
  637.                 $employees,
  638.                 $month,
  639.                 $year,
  640.                 $time,
  641.                 $route,
  642.                 $manager,
  643.                 &$response,
  644.                 &$workers,
  645.                 // After added time orders table should be update for actually costs
  646.                 $projectOrderCosts,
  647.                 $params,
  648.                 $timesheetHistory,
  649.                 $absenceChangeReason,
  650.                 &$employeeCachedHistoryEntities,
  651.                 &$errors
  652.             ) {
  653.                     # dd($workerActivity);
  654.                     if( !$workerActivity->getWorker()->getDailyWorkTime() ){
  655.                         $response[] = [
  656.                             'message' => $translator->trans('Please define Worker daily work time and price per hour!') . ' ' $workerActivity->getWorker()->getFullName(),
  657.                             "severity" => "info"
  658.                         ];
  659.                     }
  660.                     else {
  661.                         /**
  662.                          * Filter as year timesheet's
  663.                          *@var $proceedYear WorkerTimesheet
  664.                          */
  665.                         $proceedYear $workerActivity->getWorkerTimesheets()->filter( function (/**@var $workerTimesheet WorkerTimesheet */ $workerTimesheet )  use( $year) {
  666.                             return $workerTimesheet->getYear() === intval($year);
  667.                         })->first();
  668.                         // Create New
  669.                         if( !$proceedYear ) {
  670.                             $proceedYear = new WorkerTimesheet();
  671.                             $proceedYear
  672.                                 // ->setWorker( $worker )
  673.                                 ->setWorkerActivity$workerActivity )
  674.                                 ->setYear$year );
  675.                         }
  676.                         // Update others
  677.                         /**
  678.                          * Example ...
  679.                          * array:2 [
  680.                          *      124 => array:2 [
  681.                          *          0 => "m2_d4"
  682.                          *          1 => "m2_d5"
  683.                          *      ]
  684.                          *      138 => array:3 [
  685.                          *          0 => "m2_d4"
  686.                          *          1 => "m2_d6"
  687.                          *          2 => "m2_d21"
  688.                          *      ]
  689.                          * ]
  690.                          */
  691.                         $pushedEmployeeDays $employees[$workerActivity->getId()];
  692.                         // Add This worker to Order as assign if already not assigned
  693.                         if( $route === ABSENCE_PRESENT ){
  694.                             $alreadyAssigned $workerActivity->getAssignedOrders()->filter( fn(/**@var ProjectOrders $item*/ $item ) => $item->getId()
  695.                                 === $projectOrder->getId());
  696.                             if(!$alreadyAssigned->first()){
  697.                                 $workerActivity->addAssignedOrder($projectOrder);
  698.                             }
  699.                         }
  700.                         #dd($alreadyAssigned->first());
  701.                         foreach ($pushedEmployeeDays as $monthDay ) {
  702.                             if( !$workerActivity->getWorker()->getDailyWorkTime() )
  703.                             {
  704.                                 $response[] = [
  705.                                     'message' => $translator->trans('Please define Worker daily work time and price per hour!'),
  706.                                     "severity" => "info"
  707.                                 ];
  708.                             }
  709.                             else {
  710.                                 // Get method name from prop name -> m2_d6 should be getM2D6 || setM2D6
  711.                                 $property $monthDay;
  712.                                 $property preg_replace('/_/'''$property);
  713.                                 $getterMethod 'get' strtoupper($property);
  714.                                 $setterMethod 'set' strtoupper($property);
  715.                                 // Take Day
  716.                                 $dayData $proceedYear->{$getterMethod}() ?? [];
  717.                                 $workerInProject null;
  718.                                 if( $project ){
  719.                                     $workerInProject $workerActivity->getWorkerInProjects()->filter(function (/**@var WorkerInProject $workerInProject*/ $workerInProject ) use ($project){
  720.                                         return $workerInProject->getProject()->getProject()->getId()
  721.                                             === $project->getId();
  722.                                     })->first();
  723.                                 }
  724.                                 $manager->beginTransaction();
  725.                                 try{
  726.                                     $timesheetWriter
  727.                                         ->setWorker($workerActivity->getWorker())
  728.                                         ->setMonth($month)
  729.                                         ->setUser$this->getUser() )
  730.                                         ->setManagerRole($userRole)
  731.                                         ->setTimesheetStatus$timesheetStatus )
  732.                                         // TODO ProjectStakeholder should replace with workerInProject project access over workerInProject
  733.                                         ->writerPathManager$workerInProject$branch$projectOrder )
  734.                                         ->setData$dayData );
  735.                                     if (is_numeric($time) )
  736.                                     {
  737.                                         // Time can addable if validate time
  738.                                         $upsertDayData $timesheetWriter->addTime($time)->extendResultRolesBasic();
  739.                                         // $projectOrderCosts = new OrderCostController($timesheetReader, $manager );
  740.                                         // $projectOrder = $projectOrderCosts->updateProjectOrderSpentTimes($projectOrder, $manager);
  741.                                         // $manager->persist($projectOrder);
  742.                                         // // // 1. Persist Timesheets
  743.                                         // $manager->persist( $workerTimesheetForYear );
  744.                                         // // // 2. Summary Times and Costs
  745.                                         // // // Persist can run, while order ist defined here not like R,H...
  746.                                         // $projectOrder = $projectOrderCosts->updateProjectOrderSpentTimes($manager, $projectOrder, null);
  747.                                         // $manager->persist($projectOrder);
  748.                                     }
  749.                                     else {
  750.                                         #dd($projectOrder->getId(), $branch->getId());
  751.                                         // 1. Persist Order (Remove Times and Costs)
  752.                                         // Persist should run insider function for every order
  753.                                         // if($projectOrder){
  754.                                         //     $manager->persist($projectOrder);
  755.                                         // }
  756.                                         if( $timesheetStatus->getAbsenceShortKey() === 'R' ){
  757.                                             // Other Status Will be change Automatically from null or Present
  758.                                             $upsertDayData $timesheetWriter->reset()->extendResultRolesBasic();
  759.                                         }
  760.                                         else {
  761.                                             $upsertDayData $timesheetWriter->updateStatus()->extendResultRolesBasic();
  762.                                         }
  763.                                     }
  764.                                     $proceedYear->{$setterMethod}( $upsertDayData );
  765.                                     $manager->persist$proceedYear );
  766.                                     $manager->flush();
  767.                                     // ☝️ Burda yada employee loop disinda !!!
  768.                                     // Update Order Table for Cost of Project & Order
  769.                                     // 2. Persist Order (Remove Times and Costs)
  770.                                     if (is_numeric($time) ){
  771.                                         // Saat girilmis gerekli kontrolleri yapiyoruz
  772.                                         // Last Control
  773.                                         if( !$workerInProject->getProject()->getProject()->getProjectId() ){
  774.                                             return $this->json([
  775.                                                 'message' => $translator->trans('ProjectID required!'),
  776.                                                 "severity" => "error",
  777.                                                 "variant"=>"snackbar"
  778.                                             ], Response::HTTP_NOT_ACCEPTABLE );
  779.                                         }
  780.                                         if(!$projectOrder){
  781.                                             return $this->json([
  782.                                                 'message' => $translator->trans('Project order required!'),
  783.                                                 "severity" => "error",
  784.                                                 "variant"=>"snackbar"
  785.                                             ], Response::HTTP_NOT_ACCEPTABLE );
  786.                                         }
  787.                                         if(!$branch){
  788.                                             return $this->json([
  789.                                                 'message' => $translator->trans('Project branch required!'),
  790.                                                 "severity" => "error",
  791.                                                 "variant"=>"snackbar"
  792.                                             ], Response::HTTP_NOT_ACCEPTABLE );
  793.                                         }
  794.                                         // Sonra secilen Auftrag in butun saatlerini toplayip Auftragin ilgili kolonunu updateliyoruz
  795.                                         $projectOrder $projectOrderCosts->updateProjectOrderSpentTimes$manager$projectOrdernull);
  796.                                         $manager->persist($projectOrder);
  797.                                     }
  798.                                     else {
  799.                                         // Saat yok bu bir R|H|HNP ... olabilir
  800.                                         // Kolon icindeki degeri alip O Gun icerisinde ki Auftrag lari alip,
  801.                                         // O auftraglari terar update ediyoruz yani o Auftragdaki saatler silinmis olacak sekilde son halini updateliyoruz...
  802.                                         $projectOrderCosts->updateProjectOrderSpentTimes$managernull$dayData);
  803.                                     }
  804.                                     #dd($absenceChangeReason);
  805.                                     // History Manager // Ignore if is new
  806.                                     if($dayData){
  807.                                         if( $absenceChangeReason ){
  808.                                             $workerActivityLogs $absenceChangeReason[$workerActivity->getId()];
  809.                                             $newDayLog $workerActivityLogs[$monthDay];
  810.                                             /**
  811.                                              * 🛑 Sorunun Kaynağı:
  812.                                              * - Loop içinde employee’ye ait bir kayıt yoksa, `new WorkerTimesheetHistories()` çağırılıyor.
  813.                                              * - Ancak bu entity henüz persist edildiği için veritabanında görünmüyor.
  814.                                              * - Aynı employee için tekrar kontrol yapıldığında, veritabanında kayıt olmadığı için tekrar new ile yeni bir entity oluşturuluyor.
  815.                                              * - Bu da aynı kaydı iki kez persist etmeye ve duplicate hatasına yol açıyor.
  816.                                              *
  817.                                              * ✅ Çözüm: Geçici Bir Bellek Referansı Kullan
  818.                                              * - Persist edilmemiş entity’leri loop içinde saklamak için geçici bir bellek yapısı (örneğin bir dizi) kullanmalısın.
  819.                                              * - 👉 `$employeeCachedHistoryEntities[$workerActivity->getId()]`
  820.                                              */
  821.                                             if( !array_key_exists($workerActivity->getId(), $employeeCachedHistoryEntities) ){
  822.                                                 $historyInstance $proceedYear->getWorkerTimesheetHistories();
  823.                                                 if(is_null($historyInstance)){
  824.                                                     $historyInstance = new WorkerTimesheetHistories();
  825.                                                     $historyInstance
  826.                                                         ->setWorkerTimesheet($proceedYear)
  827.                                                         ->setCreatedAt(new \DateTimeImmutable('now'));
  828.                                                 }
  829.                                                 $employeeCachedHistoryEntities[$workerActivity->getId()] = $historyInstance;
  830.                                             }
  831.                                             #dd($employeeCachedHistoryEntities);
  832.                                             $timesheetHistory->setCachedEmployeeHistoryEntity($employeeCachedHistoryEntities[$workerActivity->getId()]);
  833.                                             $timesheetHistory->init$proceedYear$newDayLog$monthDay$route$project$projectOrder$branch);
  834.                                             $timesheetHistory->upsert();
  835.                                         }
  836.                                     }
  837.                                     $manager->getConnection()->commit();
  838.                                 } catch (\Exception $exception){
  839.                                     $manager->getConnection()->rollBack();
  840.                                     $errors[] = [
  841.                                         $translator->trans('Please reset this day before adding time for it.')
  842.                                     ];
  843.                                     // Orijinal hatayı tekrar fırlatırken, asıl hata mesajı ve stack trace'i koruyalım
  844. //                                    throw new \Exception(
  845. //                                        $exception->getMessage() . ' ' . $translator->trans('Please reset this day before adding time for it.') .
  846. //                                        "Hata Mesajı: " . ' ' . $exception->getMessage() . PHP_EOL .
  847. //                                        "Dosya: " . $exception->getFile() . PHP_EOL .
  848. //                                        "Satır: " . $exception->getLine() . PHP_EOL .
  849. //                                        "Stack Trace: " . $exception->getTraceAsString()
  850. //                                    );
  851.                                 }
  852.                             }
  853.                         }
  854.                         if(!count($errors)){
  855.                             $manager->flush();
  856.                             $manager->refresh$proceedYear );
  857.                             // Simulate Fetched Timesheet from WorkerActivity
  858.                             $specifiedTimesheet $timesheetSpecificMonthDays->getSpecificMonths$year$month$proceedYear ); // Tüm kolonları bir dizi olarak al
  859.                             $workers[] = [
  860.                                 "id" => $workerActivity->getId(),
  861.                                 "worker" => [
  862.                                     "name" => $workerActivity->getWorker()->getName(),
  863.                                     "surname" => $workerActivity->getWorker()->getSurname(),
  864.                                 ],
  865.                                 "customer" => $workerActivity->getCustomer(),
  866.                                 "timesheet" => $specifiedTimesheet,
  867.                                 "timesheet_revisions" => $proceedYear->getWorkerTimesheetHistories(),
  868.                             ];
  869.                         }
  870.                     }
  871.         });
  872.         #dd();
  873.         if(count($errors)){
  874.             return $this->json([
  875.                 'message' => $translator->trans('Please reset this day before adding time for it.'),
  876.                 "severity" => "error",
  877.             ], Response::HTTP_NOT_ACCEPTABLE );
  878.         }
  879.         $serializedWorkers json_decode($serializer->serialize($workers'json', [
  880.             'groups' => [
  881.                 "worker.in.project.worker.activity",
  882.                 "worker.in.project.worker.activity.base",
  883.                 "worker.in.project.worker.activity.worker",
  884.                 "worker.base",
  885.                 "worker.in.project.worker.activity.customer",
  886.                 "customer.base",
  887.                 "timesheet.history",
  888.                 "timesheet.history.base",
  889.             ]
  890.         ]));
  891.         return $this->json([
  892.             "message" => "Successfully",
  893.             "severity"=>"success",
  894.             "serializedWorkers"=>$serializedWorkers,
  895.             "response" => $response
  896.         ], Response::HTTP_OK, []);
  897.     }
  898.     /**
  899.      * @Route("/employee-yearly-statistics/{worker_activity_id}", name="employee_yearly_statistics", methods={"POST"} )
  900.      * @ParamConverter("workerActivities", options={"mapping":{"worker_activity_id":"id"}})
  901.      * @throws \Exception
  902.      */
  903.     public function employeeYearlyStatisticsWorkerActivities  $workerActivitiesRequest $requestTranslatorInterface $translator): Response {
  904.         $params $request->request;
  905.         $year $params->get('year');
  906.         // this year until current month
  907.         $maxMonthIndex 12;
  908.         $now = new \DateTimeImmutable('now');
  909.         if( intval($year) === intval($now->format('Y')) ){
  910.             $maxMonthIndex intval($now->format('n'));
  911.         }
  912.         /**@var WorkerTimesheet $timesheet*/
  913.         $timesheet $workerActivities->getWorkerTimesheets()->filter(function (/**@var WorkerTimesheet $workerTimesheet*/ $workerTimesheet) use ($year$maxMonthIndex){
  914.             return $workerTimesheet->getYear() === intval($year);
  915.         })->first();
  916.         if($timesheet){
  917.             $timesheetClass = new \ReflectionClass(WorkerTimesheet::class);
  918.             $properties $timesheetClass->getProperties(\ReflectionProperty::IS_PRIVATE);
  919.             $methods $timesheetClass->getMethods(\ReflectionMethod::IS_PUBLIC);
  920.             //        $filteredMethods = array_filter($methods, function ($method) {
  921.             //            return preg_match('/^getM[1-12]\dD[1-31]\d$/', $method->getName());
  922.             //        });
  923.             // Every Month
  924.             $filteredMethods array_reduce($methods, function ($carry$method) use ($maxMonthIndex) {
  925.                 if (sscanf($method->getName(), "getM%dD%d"$month$day) === 2) {
  926.                     // if ($month >= 1 && $month <= 12 && $day >= 1 && $day <= 31) {
  927.                     if ($month >= && $month <= $maxMonthIndex && $day >= && $day <= 31) {
  928.                         $carry[$month][] = $method->getName();
  929.                         // $carry[] = $method->getName();
  930.                     }
  931.                 }
  932.                 return $carry;
  933.             }, []);
  934.             $P $S $H $HNP $chartDataset = [];
  935.             foreach ($filteredMethods as $monthIndex => $monthDays) {
  936.                 $_P $_S $_H $_HNP = [];
  937.                 array_map( function($method) use ($timesheet, &$_P, &$_S, &$_H, &$_HNP, &$chartDataset){
  938.                     $ts $timesheet->{$method}();
  939.                     if(!is_null($ts)){
  940.                         if( array_key_exists('absenceShortKey'$ts)){
  941.                             switch ($ts['absenceShortKey']){
  942.                                 case 'P':
  943.                                     $_P[] = array_sum(array_map(fn($prj) => array_sum(array_values($prj['orders_total'])), $ts['projects']));
  944.                                     break;
  945.                                 case 'S':
  946.                                 case 'H':
  947.                                     if($ts['absenceShortKey'] === 'S'){
  948.                                         $_S[] = $ts['info']['time'];
  949.                                     } else {
  950.                                         $_H[] = $ts['info']['time'];
  951.                                     }
  952.                                     break;
  953.                                 case 'HNP':
  954.                                     $_HNP[] = 0;
  955.                                     break;
  956.                             }
  957.                         }
  958.                     }
  959.                 }, $monthDays );
  960.                 #dump($partActive);
  961.                 $P[$monthIndex]['daily'] = $_P// Presents Total
  962.                 $P[$monthIndex]['total'] = array_sum($_P); // Presents Total
  963.                 // $P[$monthIndex] = $_P; // Presents Total
  964.                 $S[$monthIndex]['daily'] = $_S// Sick Total
  965.                 $S[$monthIndex]['total'] = array_sum($_S); // Sick Total
  966.                 $H[$monthIndex]['daily'] = $_H// Holiday Total
  967.                 $H[$monthIndex]['total'] = array_sum($_H); // Holiday Total
  968.                 $HNP[$monthIndex]['daily'] = $_HNP// Holiday Not Payable Total
  969.                 $HNP[$monthIndex]['total'] = array_sum($_HNP); // Holiday Not Payable Total
  970.                 $chartDataset[] = [
  971.                     'P' => array_sum($_P),
  972.                     'S' => array_sum($_S),
  973.                     'H' => array_sum($_H),
  974.                     'HNP' => array_sum($_HNP),
  975.                     'month' => $monthIndex,
  976.                     'year' => $year
  977.                 ];
  978.             }
  979.             return $this->json([
  980.                 "message" => "Successfully",
  981.                 "severity" => "success",
  982.                 "data" => [
  983.                     "P" => $P,
  984.                     "S" => $S,
  985.                     "H" => $H,
  986.                     "HNP" => $HNP,
  987.                 ],
  988.                 "chartDataSet" => $chartDataset,
  989.                 "founded" => true
  990.             ], Response::HTTP_OK );
  991.         }
  992.         return $this->json([
  993.             "message" => $translator->trans('No timesheet found'),
  994.             "severity" => "warning",
  995.             "chartDataSet" => [],
  996.             "founded" => false
  997.         ], Response::HTTP_OK );
  998.     }
  999. }