src/Controller/ProjectManagement/ProjectController.php line 101

Open in your IDE?
  1. <?php
  2. namespace App\Controller\ProjectManagement;
  3. use App\Entity\Client;
  4. use App\Entity\ClientFeedback;
  5. use App\Entity\User;
  6. use App\Entity\Project;
  7. use App\Entity\Department;
  8. use App\Entity\ProjectDeliverable;
  9. use App\Entity\ProjectDeliverableFile;
  10. use App\Entity\ProjectLeadStatus;
  11. use App\Service\LogService;
  12. use App\Service\UploadService;
  13. use App\Service\UtilsService;
  14. use Symfony\Component\Stopwatch\Stopwatch;
  15. use Doctrine\ORM\ORMException;
  16. use App\Service\ProjectService;
  17. use App\Service\WebhookService;
  18. use App\Service\CurrencyService;
  19. use App\Entity\ProjectSalesOrder;
  20. use App\Entity\RevenuePlanning;
  21. use App\Form\ClientFeedbackType;
  22. use App\Form\ProjectClientFeedbackTemplateType;
  23. use App\Form\ProjectClientPersonInChargeType;
  24. use App\Form\ProjectDeliverableType;
  25. use App\Form\ProjectManagement\ClientContactType;
  26. use App\Form\ProjectManagement\ProjectType;
  27. use App\Form\ProjectManagement\SalesOrderType;
  28. use App\Form\ProjectManagement\ProjectNewLeadType;
  29. use App\Form\ProjectManagement\ProjectNewConfirmedType;
  30. use App\Form\ProjectRevenuePlanningType;
  31. use App\Form\MattermostType;
  32. use App\Repository\TaskRepository;
  33. use App\Repository\UserRepository;
  34. use App\Repository\ProjectRepository;
  35. use App\Repository\TimeSpentRepository;
  36. use App\Repository\SalesOrderRepository;
  37. use App\Repository\InvoiceRepository;
  38. use Doctrine\ORM\OptimisticLockException;
  39. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  40. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  41. use App\Repository\VendorInvoiceRepository;
  42. use Psr\Log\LoggerInterface;
  43. use Symfony\Component\HttpFoundation\Request;
  44. use Symfony\Component\HttpFoundation\Response;
  45. use App\Repository\ProjectSalesOrderRepository;
  46. use Symfony\Component\Routing\Annotation\Route;
  47. use Symfony\Component\HttpFoundation\JsonResponse;
  48. use App\Repository\ProjectAllocatedHoursRepository;
  49. use App\Repository\VendorQuotationPlanningRepository;
  50. use Symfony\Component\Serializer\SerializerInterface;
  51. use App\Form\ProjectManagement\ProjectNewClientType;
  52. use App\Form\ProjectManagement\ProjectNewInternalType;
  53. use Symfony\Contracts\Translation\TranslatorInterface;
  54. use App\Repository\ChecklistRepository;
  55. use App\Repository\ClientContactRepository;
  56. use App\Repository\ClientFeedbackRepository;
  57. use App\Repository\ClientFeedbackTemplateRepository;
  58. use App\Repository\IndustryClassificationRepository;
  59. use App\Repository\ProjectClassificationRepository;
  60. use App\Repository\ProjectDeliverableRepository;
  61. use App\Repository\RevenuePlanningRepository;
  62. use App\Repository\VendorContactRepository;
  63. use App\Service\ChecklistService;
  64. use App\Service\MattermostService;
  65. use App\Service\FileService;
  66. use App\Service\GoogleDriveService;
  67. use App\Service\S3Service;
  68. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  69. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  70. use Symfony\Component\HttpFoundation\RedirectResponse;
  71. use Symfony\Component\HttpFoundation\RequestStack;
  72. use Symfony\Component\Security\Core\Security;
  73. class ProjectController extends AbstractController
  74. {
  75.     #[Route(path'/project'name'app_project')]
  76.     public function index(): Response
  77.     {
  78.         return $this->render('private/project-management/project/project-index.html.twig', [
  79.             'controller_name' => 'ProjectController',
  80.         ]);
  81.     }
  82.     /**
  83.      * @param int $_id
  84.      * @param ProjectRepository $projectRepository
  85.      * @param TimeSpentRepository $timeSpentRepository
  86.      * @param VendorInvoiceRepository $vendorInvoiceRepository
  87.      * @param SalesOrderRepository $projectSalesOrderRepository
  88.      * @param VendorQuotationPlanningRepository $vendorQuotationPlanningRepository
  89.      * @param TranslatorInterface $translator
  90.      * @param UserRepository $userRepository
  91.      * @return Response
  92.      * @throws \Exception
  93.      * @throws \GuzzleHttp\Exception\GuzzleException
  94.      */
  95.     #[Route(path'/project-management/project/view/{_id}'defaults: ['_id' => 0], name'view_project')]
  96.     public function viewProject(int $_idCurrencyService $currencyServiceProjectRepository $projectRepositoryTimeSpentRepository $timeSpentRepositoryVendorInvoiceRepository $vendorInvoiceRepositoryProjectSalesOrderRepository $projectSalesOrderRepositoryVendorQuotationPlanningRepository $vendorQuotationPlanningRepositoryTranslatorInterface $translatorUserRepository $userRepositoryRevenuePlanningRepository $revenuePlanningRepositoryProjectService $projectServiceClientFeedbackTemplateRepository $clientFeedbackTemplateRepository): Response
  97.     {
  98.         $user $this->getUser();
  99.         $project $projectRepository->find($_id);
  100.         $formProject $this->createForm(ProjectType::class, $project);
  101.         // $formProject->add('clientContact', ProjectClientPersonInChargeType::class);
  102.         $employeeTimeRecords $timeSpentRepository->getEmployeeTimeRecord($_id);
  103.         $totalTasks $timeSpentRepository->getTotalTasks($_id);
  104.         $totalHours $timeSpentRepository->getTotalHours($_id);
  105.         $totalHoursAll 0;
  106.         $totalCostAll 0;
  107.         $projectStartDate $project && $project->getStartDate() != null $project->getStartDate()->format('Y-m-d') : null;
  108.         $projectEndDate $project && $project->getEndDate() != null $project->getEndDate()->format('Y-m-d') : null;
  109.         $departments $timeSpentRepository->getDepartmentsForProject($_id$projectStartDate$projectEndDate);
  110.         $salesOrdersListForDropDown $projectSalesOrderRepository->findByPage(09999""'ASC'null00);
  111.         $salesOrdersListForProject $projectSalesOrderRepository->findByPage(09999""'ASC'null$_id0);
  112.         $monthlyRevenues $projectService->monthlyRevenues($project);
  113.         $monthlyRevenuesRecognition $projectService->monthlyRevenues($projectfalse);
  114.         
  115.         // dump($project);
  116.         // dd($projectRepository->findInvoices($project));
  117.         //dd($salesOrdersList);
  118.         //$totalManpowerCost = 0;
  119.         for ($i 0$i sizeof($departments); $i++) {
  120.             $employeeSummaryList $userRepository->findTaskSummary($_id$departments[$i]['id'], $projectStartDate$projectEndDate);
  121.             $i2 0;
  122.             foreach ($employeeSummaryList as $employee) {
  123.                 $projectMember $project->getProjectMember($employee['id']);
  124.                 if ($projectMember) {
  125.                     $employeeSummaryList[$i2]['hourly'] = $projectMember->getHourlyRateUsd();
  126.                     $i2++;
  127.                 }
  128.             }
  129.             
  130.             $departments[$i]['employeeSummaryList'] = $employeeSummaryList;
  131.             $tmpHours 0;
  132.             $tmpCost 0;
  133.             for ($j 0$j sizeof($employeeSummaryList); $j++) {
  134.                 $tmpHours $tmpHours $employeeSummaryList[$j]['hours'];
  135.                 $tmpCost $tmpCost $employeeSummaryList[$j]['cost'];
  136.             }
  137.             //$totalManpowerCost += $tmpCost;
  138.             $departments[$i]['totalCost'] = $tmpCost;
  139.             $departments[$i]['totalHours'] = $tmpHours;
  140.         }
  141.         $projectDeliverable null;
  142.         if(!$project->getProjectDeliverable()){
  143.             $projectDeliverable = new ProjectDeliverable();
  144.             $projectDeliverable->setCreatedAt(new \DateTime());
  145.             $project->setProjectDeliverable($projectDeliverable);
  146.             $entityManager $this->getDoctrine()->getManager();
  147.             $entityManager->flush();
  148.         }else{
  149.             $projectDeliverable $project->getProjectDeliverable();
  150.         }
  151.         $generetedRevenuePlanning $projectService->generateRevenuePlanning($project);
  152.         if($generetedRevenuePlanning['status'] == 'OK'){
  153.             $project $generetedRevenuePlanning['data'];
  154.         }
  155.         $formRevenuePlanning $this->createForm(ProjectRevenuePlanningType::class, $project);
  156.         //$manpowerCost = $totalManpowerCost;
  157.         if (!$project) {
  158.             throw new \Exception($translator->trans('messages.security.forbidden'));
  159.         } else {
  160.             if (count($departments) > 0) {
  161.                 foreach ($departments as $department) {
  162.                     $totalHoursAll += $department['totalHours'];
  163.                     $totalCostAll += $department['totalCost'];
  164.                 }
  165.             }
  166.             return $this->render('private/project-management/project/view-project.html.twig', [
  167.                 'project' => $project,
  168.                 'monthlyRevenues' => $monthlyRevenues,
  169.                 'monthlyRevenuesRecognition' => $monthlyRevenuesRecognition,
  170.                 'formProject' => $formProject->createView(),
  171.                 'totalTasks' => $totalTasks,
  172.                 'totalHours' => $totalHours,
  173.                 'totalHoursAll' => $totalHoursAll,
  174.                 'totalCostAll' => $totalCostAll,
  175.                 'timeRecordsByDepartments' => $departments,
  176.                 'soListDd' => $salesOrdersListForDropDown,
  177.                 'soList' => $salesOrdersListForProject,
  178.                 'formRevenuePlanning' => $formRevenuePlanning->createView(),
  179.                 'generateRevenuePlanning' => $generetedRevenuePlanning,
  180.                 'projectDeliverable' => $projectDeliverable
  181.             ]);
  182.         }
  183.     }
  184.     /**
  185.      * @param int $_id
  186.      * @param ProjectRepository $projectRepository
  187.      * @param InvoiceRepository $invoiceRepository
  188.      * @return Response
  189.      * @throws \Exception
  190.      * @throws \GuzzleHttp\Exception\GuzzleException
  191.      */
  192.     #[Route(path'/ajax/project/refresh-overview/{_id}/{_section}'defaults: ['_id' => 0'_section' => ''], name'ajax_project_overview')]
  193.     public function ajaxProjectOverview(int $_idstring $_sectionCurrencyService $currencyServiceProjectRepository $projectRepositoryTimeSpentRepository $timeSpentRepositoryVendorInvoiceRepository $vendorInvoiceRepositorySalesOrderRepository $salesOrderRepositoryVendorQuotationPlanningRepository $vendorQuotationPlanningRepositoryTranslatorInterface $translatorProjectService $projectServiceUserRepository $userRepository): Response
  194.     {
  195.         $project $projectRepository->find($_id);
  196.         $result['status'] = 'OK';
  197.         $result['section'] = [];
  198.         //$totalTasks = $timeSpentRepository->getTotalTasks($_id);
  199.         $totalHours $timeSpentRepository->getTotalHours($_id);
  200.         $totalHoursAll 0;
  201.         $totalCostAll 0;
  202.         $projectStartDate $project && $project->getStartDate() != null $project->getStartDate()->format('Y-m-d') : null;
  203.         $projectEndDate $project && $project->getEndDate() != null $project->getEndDate()->format('Y-m-d') : null;
  204.         $departments $timeSpentRepository->getDepartmentsForProject($_id$projectStartDate$projectEndDate);
  205.         for ($i 0$i sizeof($departments); $i++) {
  206.             $employeeSummaryList $userRepository->findTaskSummary($_id$departments[$i]['id'], $projectStartDate$projectEndDate);
  207.             $departments[$i]['employeeSummaryList'] = $employeeSummaryList;
  208.             $tmpHours 0;
  209.             $tmpCost 0;
  210.             for ($j 0$j sizeof($employeeSummaryList); $j++) {
  211.                 $tmpHours $tmpHours $employeeSummaryList[$j]['hours'];
  212.                 $tmpCost $tmpCost $employeeSummaryList[$j]['cost'];
  213.             }
  214.             $departments[$i]['totalCost'] = $tmpCost;
  215.             $departments[$i]['totalHours'] = $tmpHours;
  216.         }
  217.         if (count($departments) > 0) {
  218.             foreach ($departments as $department) {
  219.                 $totalHoursAll += $department['totalHours'];
  220.                 $totalCostAll += $department['totalCost'];
  221.             }
  222.         }
  223.         // Response
  224.         if ($_section == null || $_section == 'infoPayment') {
  225.             $result['section']['infoPayment'] = $this->renderView('private/project-management/project/components/info-project-payment.html.twig', [
  226.                 'project' => $project,
  227.             ]);
  228.         }
  229.         if ($_section == null || $_section == 'project') {
  230.             $result['section']['project'] = $this->renderView('private/project-management/project/components/overview-detail-project.html.twig', [
  231.                 'project' => $project,
  232.                 'totalHours' => $totalHours
  233.             ]);
  234.         }
  235.         if ($_section == null || $_section == 'salesOrder') {
  236.             $result['section']['salesOrder'] = $this->renderView('private/project-management/sales-order/components/overview-sales-order.html.twig', [
  237.                 'project' => $project
  238.             ]);
  239.         }
  240.         if ($_section == null || $_section == 'employee') {
  241.             $result['section']['employee'] = $this->renderView('private/project-management/employee/components/overview-time-record.html.twig', [
  242.                 'timeRecordsByDepartments' => $departments,
  243.                 'totalHoursAll' => $totalHoursAll,
  244.                 'totalCostAll' => $totalCostAll
  245.             ]);
  246.         }
  247.         if ($_section == null || $_section == 'vendor') {
  248.             $result['section']['vendor'] = $this->renderView('private/project-management/vendor-quotation-planning/components/overview-vendor-quotation-planning.html.twig', [
  249.                 'project' => $project
  250.             ]);
  251.         }
  252.         if ($_section == null || $_section == 'revenue') {
  253.             $monthlyRevenues $projectService->monthlyRevenues($project);
  254.             $monthlyRevenuesRecognition $projectService->monthlyRevenues($projectfalse);
  255.             $result['section']['revenue'] =$this->renderView('private/project-management/project-revenue-planning/components/overview-revenue-planning.html.twig', [
  256.                 'project' => $project,
  257.                 'monthlyRevenues' => $monthlyRevenues,
  258.                 'monthlyRevenuesRecognition' => $monthlyRevenuesRecognition
  259.             ]);
  260.             $result['section']['revenueDetail'] =$this->renderView('private/project-management/project-revenue-planning/components/detail-revenue-planning.html.twig', [
  261.                 'project' => $project,
  262.                 'monthlyRevenues' => $monthlyRevenues,
  263.                 'monthlyRevenuesRecognition' => $monthlyRevenuesRecognition
  264.             ]);
  265.         }
  266.         return new JsonResponse($result);
  267.     }
  268.     /**
  269.      * @param int $_id
  270.      * @param ProjectRepository $projectRepository
  271.      * @return Response
  272.      */
  273.     #[Route(path'/ajax/project-revenue/refresh'name'ajax_project_revenue_refresh')]
  274.     public function ajaxProjectRevenue(ProjectRepository $projectRepositoryProjectService $projectServiceRequest $request): Response
  275.     {
  276.         $_id $request->get("id");
  277.         $project $projectRepository->find($_id);
  278.         $generateRevenuePlanning $projectService->generateRevenuePlanning($project);
  279.         $monthlyRevenues $projectService->monthlyRevenues($project);
  280.         $monthlyRevenuesRecognition $projectService->monthlyRevenues($projectfalse);
  281.         if($generateRevenuePlanning['status'] == 'OK'){
  282.             $project $generateRevenuePlanning['data'];
  283.         }
  284.         
  285.         $result['projectRevenueDetail'] = $this->renderView('private/project-management/project-revenue-planning/components/detail-revenue-planning.html.twig', [
  286.             'project' => $project,
  287.             'monthlyRevenues' => $monthlyRevenues,
  288.             'monthlyRevenuesRecognition' => $monthlyRevenuesRecognition,
  289.             'waitForPage' => false
  290.         ]);
  291.         // $result['projectRevenueOverview'] = $this->renderView('private/project-management/project-revenue-planning/components/overview-revenue-planning.html.twig', [
  292.         //     'project' => $project,
  293.         //     'waitForPage' => false
  294.         // ]);
  295.         $result['status'] = 'OK';
  296.         
  297.         return new JsonResponse($result);
  298.     }
  299.     /**
  300.      * @param ProjectRepository $projectRepository
  301.      * @param Request $request
  302.      * @return Response
  303.      */
  304.     #[Route(path'/ajax/project/list'name'ajax_list_projects')]
  305.     public function ajaxListProjects(ProjectRepository $projectRepositoryRequest $requestLoggerInterface $logger null): Response
  306.     {
  307.         // Example params:
  308.         // page=0&limit=20&keyword=t&orderBy=name&order=asc&waitForPage=true&client=1
  309.         $user $this->getUser();
  310.         $page intval($request->query->get('page') - 1);
  311.         if ($page 0$page 0;
  312.         $limit intval($request->query->get('limit'));
  313.         if ($limit === 0$limit 20;
  314.         $keyword $request->get('keyword');
  315.         $order $request->get('order');
  316.         $orderBy $request->get('orderBy');
  317.         $startDate $request->get('start');
  318.         $endDate $request->get('end');
  319.         $client $request->get('client');
  320.         $status $request->get('status');
  321.         $type $request->get('type');
  322.         $retainer $request->get('retainer');
  323.         $department $request->get('department');
  324.         $project $request->get('project');
  325.         $projectClassification $request->get('projectType');
  326.         $industryClassification $request->get('projectIndustry');
  327.         $assignedUser $request->get('assignedUser');
  328.         $pic $request->get('pic');
  329.         $period $request->get('period');
  330.         $year $request->get('year');
  331.         $picClient $request->get('picClient');
  332.         $vendor $request->get('vendor');
  333.         $picVendor $request->get('picVendor');
  334.         $waitForPage $request->query->get('waitForPage');
  335.         $waitForPage === null $result['waitForPage'] = 'false' $result['waitForPage'] = $waitForPage;
  336.         // $stopwatch = new Stopwatch();
  337.         // $stopwatch->start('query');
  338.         // $logger->error('Start query');
  339.         $projectsList $projectRepository->findByPage($page$limit$keyword$order$orderBy$startDate$endDate$type$client$status$project$department$retainer$assignedUserfalse$pic$period$year$picClient$vendor$picVendor$projectClassification$industryClassification);
  340.         $totalCount $projectRepository->countByPage($keyword$startDate$endDate$type$client$status$project$department$retainer$assignedUserfalse$pic$period$year$picClient$vendor$picVendor$projectClassification$industryClassification);
  341.         // $event = $stopwatch->stop('query');
  342.         // $logger->error($event);
  343.         
  344.         // $stopwatch = new Stopwatch();
  345.         // $stopwatch->start('render');
  346.         // $logger->error('Start render2');
  347.         $body $this->renderView('private/project-management/project/components/list-project.html.twig', [
  348.             'projectsList' => $projectsList,
  349.             'type' => $type
  350.         ]);
  351.         // $event = $stopwatch->stop('render');
  352.         // $logger->error($event);
  353.         $result['content'] = [
  354.             'html' => $body,
  355.             'total' => $totalCount
  356.         ];
  357.         // $result['projectDiagram'] = $this->renderView('private/project-management/project/components/diagram-project.html.twig', [
  358.         //     'projectsList' => $projectsList
  359.         // ]);
  360.         $result['status'] = 'OK';
  361.         //        return new Response($body);
  362.         return new JsonResponse($result);
  363.     }
  364.     /**
  365.      * @param ProjectRepository $projectRepository
  366.      * @param Request $request
  367.      * @param LogService $log
  368.      * @return Response
  369.      */
  370.     #[Route(path'/ajax/project/persist'name'ajax_persist_project')]
  371.     public function ajaxPersistProject(ProjectRepository $projectRepositoryUploadService $uploadServiceParameterBagInterface $paramsRequest $requestProjectService $projectServiceLogService $logWebhookService $webhookMattermostService $mattermostServiceRequestStack $requestStackChecklistService $checklistServiceChecklistRepository $checklistRepository): Response
  372.     {
  373.         // $baseurl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();
  374.         $baseUrl $requestStack->getCurrentRequest()->getSchemeAndHttpHost();
  375.         $currentUrl $requestStack->getCurrentRequest()->getUri();
  376.         $id intval($request->get('id'));
  377.         $type $request->get('type');
  378.         $user $this->getUser();
  379.         $client $request->get('client');
  380.         $project = new Project();
  381.         $result['status'] = 'OK';
  382.         $result['type'] = $type;
  383.         if ($id 0) {
  384.             $project $projectRepository->find($id);
  385.             $oldData = clone $project;
  386.             $oldChecklist $oldData->getChecklists()->toArray();
  387.             $result['id'] = $project->getId();
  388.             $result['update'] = true;
  389.             $type null;
  390.             $result['type'] = $type;
  391.         } else {
  392.             $oldData null;
  393.             $project->setLead(1);
  394.             // if($project->getType() != 'lead') $project->setStatus('In-Planning');
  395.         }
  396.         // $_type = $type;
  397.         // if (is_array($request->request->get('project'))) {
  398.         //     $_type = '';
  399.         // }
  400.         switch ($type) {
  401.             // case 'lead':
  402.             //     $form = $this->createForm(ProjectNewLeadType::class, $project);
  403.             //     break;
  404.             case 'client':
  405.                 $form $this->createForm(ProjectNewClientType::class, $project);
  406.                 break;
  407.             case 'internal':
  408.                 $form $this->createForm(ProjectNewInternalType::class, $project);
  409.                 break;
  410.             // case 'confirmed':
  411.             //     $form = $this->createForm(ProjectNewConfirmedType::class, $project);
  412.             //     break;
  413.             default: 
  414.                 $form $this->createForm(ProjectType::class, $project);
  415.                 break;
  416.         }
  417.         $form->handleRequest($request);
  418.         $formok true;
  419.         if ($form->isSubmitted() && !$form->isValid()) {
  420.             $result['status'] = 'ERROR';
  421.             foreach ($form->getErrors(true) as $key => $error) {
  422.                 $result['message'][$key] = $error->getMessage();
  423.             }
  424.             $formok false;
  425.         }
  426.         /*if(!is_array($request->request->get('project'))){
  427.             $formok=false;
  428.         }*/
  429.         $checklistsForm null;
  430.         if ($form->isSubmitted() && $form->isValid()) {
  431.             $sendHookConfirmedProject false;
  432.             if ($type != 'internal' && $form->get('lead')->getData() == 9) {
  433.                 $project->setStartDate(null);
  434.                 $project->setEndDate(null);
  435.             }
  436.             if ($type === 'internal' || $form->get('lead')->getData() !== 8) {
  437.                 $project->setWinDate(null);
  438.             } elseif ($form->get('winDate')->getData() == null) {
  439.                 $project->setWinDate(new \DateTime());
  440.             }
  441.             if ($id === 0) {
  442.                 // if ($projectRepository->findDuplicate($project->getName()) > 0) {
  443.                 //     $result['status'] = 'ERROR';
  444.                 //     $result['message'] = 'Project with that name already exist!';
  445.                 //     return new JsonResponse($result);
  446.                 // }
  447.                 if ($type == 'internal') {
  448.                     $projectType 'INTERNAL';
  449.                 } else {
  450.                     $projectType $form->get('lead')->getData() == 'CONFIRMED' 'LEAD';
  451.                 }
  452.                 
  453.                 $project->setCurrency($form->get('currency')->getData());
  454.                 
  455.                 $result['projectType'] = $projectType;
  456.                 $project->setCreatedBy($user);
  457.                 $project->setCreatedAt(new \DateTime());
  458.                 $project->setType($projectType);
  459.                 $projectDeliverable = new ProjectDeliverable();
  460.                 $projectDeliverable->setProject($project);
  461.                 $projectDeliverable->setCreatedAt(new \DateTime());
  462.                 if($checklists $form->get('checklists')->getData()){
  463.                     foreach($checklists as $checklist){
  464.                         if($checklist){
  465.                             $checklistService->createChecklistFromTemplate(null$project$checklist);
  466.                         }
  467.                     }
  468.                 }
  469.             } else {
  470.                 // if ($project->getType() == 'LEAD' && $project->getLead() == 8) {
  471.                 //     $project->setType('CONFIRMED');
  472.                 // };
  473.                 // if($project->getStatus() == 'Finished' && empty($project->getClientFeedbackTemplate())){
  474.                 //     $result['status'] = 'ERROR';
  475.                 //     $result['message'] = 'Please select client feedback template';
  476.                 //     $result['code'] = 'feedback_template';
  477.                 //     return new JsonResponse($result);
  478.                 // }
  479.                 if($project->getLead() != 9) {
  480.                     $project->setLeadFailDate(null);
  481.                     $project->setLeadFailNote(null);
  482.                     $project->setLeadFailRemindDate(null);
  483.                 } 
  484.                 if($form->get('checklists')->getData()){$checklistsForm $form->get('checklists')->getData()->toArray();}
  485.                 // else {
  486.                 //     if($request->request->get('project')['leadFailDate']) $project->setLeadFailDate(\DateTimeImmutable::createFromFormat('d/m/Y H:i:s',$request->request->get('project')['leadFailDate'].' 00:00:00'));
  487.                 //     if($request->request->get('project')['leadFailRemindDate']) $project->setLeadFailRemindDate(\DateTimeImmutable::createFromFormat('d/m/Y H:i:s',$request->request->get('project')['leadFailRemindDate'].' 00:00:00'));
  488.                 // }
  489.                 $project->setUpdatedAt(new \DateTime());
  490.                 // get date from form then convert to datetimeimmutable
  491.                 $result['update'] = true;
  492.             }
  493.             if(($oldData != null && ($oldData->getStartDate() != $project->getStartDate())) || ($oldData != null && $oldData->getEndDate() != $project->getEndDate())){
  494.                 $projectService->generateRevenuePlanning($project);
  495.                 $result['updateRevenuePlanning'] = true;
  496.             } else {
  497.                 $result['updateRevenuePlanning'] = false;
  498.             }
  499.             if($oldData != null && $oldData->getStatus() != $project->getStatus()){
  500.                 $result['newProjectStatus'] = $project->getStatus();
  501.             } else {
  502.                 $result['newProjectStatus'] = null;
  503.             }
  504.             $result['lead'] = $project->getLead();
  505.             $result['hasFeedbackTemplate'] =  $project->getClientFeedbackTemplate() ? true false;
  506.             $uploadFolder $params->get('projectPlanFile');
  507.             $planFilepath $form->get('planFilepath')->getData();
  508.             //dd($request->request->get('project'));
  509.             if ($planFilepath !== null) {
  510.                 $uploadResponse $uploadService->uploadFileToS3($uploadFolder'planFilepath'$request$form);
  511.                 if ($uploadResponse['status'] == 'ERROR') {
  512.                     return new JsonResponse($uploadResponse);
  513.                 } else {
  514.                     $project->setPlanFilename($uploadResponse['fileName']);
  515.                     $project->setPlanFilepath($uploadResponse['filePath']);
  516.                     $project->setPlanFiletype($uploadResponse['fileType']);
  517.                 }
  518.             }
  519.             //webhook confirmed project
  520.             if(($oldData != null && $oldData->getType() != 'CONFIRMED' &&  $project->getType() == 'CONFIRMED')){
  521.                 $sendHookConfirmedProject true;
  522.             }
  523.             //$project->setEstimatedVendorCost($request->request->get('project')['estimatedVendorCost']);
  524.             //$project->setPlanURL($request->request->get('project')['planURL']);
  525.             $entityManager $this->getDoctrine()->getManager();
  526.             $entityManager->persist($project);
  527.             $entityManager->flush();
  528.             $entityManager->refresh($project);
  529.             $result['id'] = $project->getId();
  530.             $checklists $project->getChecklists() ? $project->getChecklists()->toArray() : null;
  531.             if($checklistsForm && $checklistsForm != $checklists){
  532.                 if(count($checklistsForm) > count($checklists)){
  533.                     foreach($checklistsForm as $checklist){
  534.                         if(!in_array($checklist$checklists)){
  535.                             if($checklist->isIsTemplate() == true){
  536.                                 $checklistService->createChecklistFromTemplate(null$project$checklist);
  537.                             }else{
  538.                                 $project->addChecklist($checklist);
  539.                             }
  540.                         }
  541.                     }
  542.                 }elseif(count($checklistsForm) < count($checklists)){
  543.                     foreach($checklists as $checklist){
  544.                         if(!in_array($checklist$checklistsForm)){
  545.                             $project->removeChecklist($checklist);
  546.                         }
  547.                     }
  548.                 }
  549.                 $result['updateChecklist'] = true;
  550.                 $result['checklist'] = $this->renderView('private/project-management/project/components/list-checklist.html.twig', [
  551.                     'checklists' => $project->getChecklists()
  552.                 ]);
  553.             }
  554.             if ($project->getGeneratedId() == null && $project->getType() != 'PROSPECT') {
  555.                 $project->setGeneratedId($project->getCreatedAt()->format('ym') . '-' sprintf('%04d'$project->getId()));
  556.                 $entityManager->flush();
  557.                 $entityManager->refresh($project);
  558.             }    
  559.             if($_SERVER['APP_ENV'] == "prod"){
  560.                 $result['webhook'] = $webhook->checkboxWebhook('projects'$id === 'POST' 'PUT'$id === $project->getId() : $id, [
  561.                     'id' => $project->getId(),
  562.                     'name' => $project->getName(),
  563.                     'description' => $project->getDescription(),
  564.                     'type' => $project->getType(),
  565.                     // 'clientURL' => $baseUrl.'/project-management/client/view/'.$project->getClient()->getId(),
  566.                     'client' => $project->getClient()->getName(),
  567.                     'projectURL' => $baseUrl.'/project-management/project/view/'.$project->getId(),
  568.                     // 'projectName' => $project->getName(),
  569.                     'createdBy' => $project->getCreatedBy() ? $project->getCreatedBy()->getPersonalInfo()->getFirstName().' '.$project->getCreatedBy()->getPersonalInfo()->getLastName() : ''
  570.                 ]);
  571.             }
  572.             if( $sendHookConfirmedProject == true){     
  573.                 $baseurl $requestStack->getCurrentRequest()->getSchemeAndHttpHost();    
  574.                 $mattermostMessage "### :star2: Woohoo! Exciting news â€“ we've won a new project!".
  575.                     "\n**Project ID:** ".$project->getGeneratedId().
  576.                     "\n**Project Name:** [".$project->getName().']('.$baseurl.'/project-management/project/view/'.$project->getId(). ")".
  577.                     "\n**Currency:** ".$project->getCurrency()->getName().' ('.$project->getCurrency()->getSymbol().')';
  578.                     
  579.                 if($project->getPlannedRevenue()){
  580.                     $mattermostMessage .= "\n**Est. Project Billing:** ".$project->getCurrency()->getSymbol().number_format($project->getPlannedRevenue(), 2'.'',');
  581.                 };
  582.                 if($project->getEstimatedVendorCost()){
  583.                     $mattermostMessage .= "\n**Est. Vendor Cost:** ".$project->getCurrency()->getSymbol().number_format($project->getEstimatedVendorCost(), 2'.'',');
  584.                 };
  585.                 if($project->getEstimatedProfit()){
  586.                     $mattermostMessage .= "\n**Est. Agency Rev:** ".$project->getCurrency()->getSymbol().number_format($project->getEstimatedProfit(), 2'.'',');
  587.                 };
  588.                 $mattermostService->sendMessage('OPS'$mattermostMessage);
  589.                 // $result['webhook'] = $webhook->checkboxWebhook('projects', $id === 0 ? 'POST' : 'PUT', $id === 0 ? $project->getId() : $id, [
  590.                 //     'id' => $project->getId(),
  591.                 //     'name' => $project->getName(),
  592.                 //     'description' => $project->getDescription(),
  593.                 //     'type' => $project->getType(),
  594.                 //     // 'clientURL' => $baseUrl.'/project-management/client/view/'.$project->getClient()->getId(),
  595.                 //     'client' => $project->getClient()->getName(),
  596.                 //     'projectURL' => $baseUrl.'/project-management/project/view/'.$project->getId(),
  597.                 //     // 'projectName' => $project->getName(),
  598.                 //     'createdBy' => $project->getCreatedBy() ? $project->getCreatedBy()->getPersonalInfo()->getFirstName().' '.$project->getCreatedBy()->getPersonalInfo()->getLastName() : ''
  599.                 // ]);
  600.             }
  601.             $log->save($user, [
  602.                 'owner' => $user,
  603.                 'message' => $id === 'log.project.add' 'log.project.edit',
  604.                 'old_data' => $id === null $oldData,
  605.                 'new_data' => $project
  606.             ]);
  607.             $projectsList $projectRepository->findByPage(01nullnullnullnullnullnullnullnull$project->getId());
  608.             $n 0;
  609.             foreach ($projectsList as $projectDetail) {
  610.                 $projectsList[$n]['cost'] = $projectDetail[0]->getProjectCost();
  611.                 $projectsList[$n]['profit'] = $projectDetail[0]->getProjectProfit1();
  612.                 $projectsList[$n]['leadStatusText'] = $projectDetail[0]->getLeadStatus() ? $projectDetail[0]->getLeadStatus()->getName() : null;
  613.                 $n++;
  614.             };
  615.             if ($client) {
  616.                 $result['content'] = $this->renderView('private/project-management/client/components/row-project-client.html.twig', [
  617.                     'project' => $projectsList[0],
  618.                     'waitForPage' => false
  619.                 ]);
  620.             } else {
  621.                 if ($id) {
  622.                     $result['projectDetail'] = $this->renderView('private/project-management/project/components/detail-project.html.twig', [
  623.                         'project' => $project,
  624.                         'waitForPage' => false
  625.                     ]);
  626.                     $result['projectStatus'] = $this->renderView('private/project-management/project/components/info-project-status.html.twig', [
  627.                         'project' => $project,
  628.                         'waitForPage' => false
  629.                     ]);
  630.                     $result['content'] = $this->renderView('private/project-management/project/components/row-project.html.twig', [
  631.                         'loadCostAndProfit' => true,
  632.                         'project' => $projectsList[0],
  633.                         'waitForPage' => false
  634.                     ]);
  635.                 } else {
  636.                     $result['content'] = $this->renderView('private/project-management/project/components/row-project.html.twig', [
  637.                         'loadCostAndProfit' => true,
  638.                         'project' => $projectsList[0],
  639.                         'waitForPage' => false
  640.                     ]);
  641.                     $result['project'] = [
  642.                         'client' => $project->getClient() ? $project->getClient()->getId() : null,
  643.                         'startDate' => $project->getStartDate() ? $project->getStartDate()->format('d-M-Y') : null,
  644.                         'endDate' => $project->getEndDate() ? $project->getEndDate()->format('d-M-Y') : null,
  645.                         'text' => $project->fullName(),
  646.                         'value' => $project->getId(),
  647.                     ];
  648.                 }
  649.                 $result['prepend'] = $id == null;
  650.             }
  651.             // Email Reminder
  652.             if($oldData != null && $oldData->getProposalDate() != $project->getProposalDate() || $oldData == null && $project->getProposalDate() != null){
  653.                 $projectService->projectDatesEmail($project'proposal_sent_date');
  654.             }
  655.             if($oldData != null && $oldData->getPresentationDate() != $project->getPresentationDate() || $oldData == null && $project->getPresentationDate() != null){
  656.                 $projectService->projectDatesEmail($project'client_present_date');   
  657.             }
  658.             if($oldData != null && $oldData->getProposalFollowUpDate() != $project->getProposalFollowUpDate() || $oldData == null && $project->getProposalFollowUpDate() != null){
  659.                 $projectService->projectDatesEmail($project'proposal_followup_date');   
  660.             }
  661.             
  662.             // hide email reminder for now
  663.             // if($id && $request->request->get('project')['leadFailRemindDate'] != null){
  664.             //     $projectService->projectDatesEmail($project, 'recontact_date');   
  665.             // }
  666.             
  667.             if($oldData != null && $oldData->getStatus() != 'Finished' && $project->getStatus() == 'Finished'){
  668.                 $projectService->projectFinishedEmail($project);
  669.             }
  670.             
  671.             //            return new Response($result['content']);
  672.             return new JsonResponse($result);
  673.         }
  674.         $page intval($request->query->get('page'));
  675.         $limit intval($request->query->get('limit'));
  676.         if ($limit === 0) {
  677.             $limit 20;
  678.         }
  679.         if ($type == null) {
  680.             $result['form'] = $this->renderView('private/project-management/project/components/project-option.html.twig', [
  681.                 'id' => $project->getId()
  682.             ]);
  683.         } else {
  684.             switch ($type) {
  685.                 // case 'lead':
  686.                 //     $formType = 'form-project-new-lead.html.twig';
  687.                 //     break;
  688.                 case 'client':
  689.                     $formType 'form-project-new-client.html.twig';
  690.                     break;
  691.                 case 'internal':
  692.                     $formType 'form-project-new-internal.html.twig';
  693.                     break;
  694.                 // case 'confirmed':
  695.                 //     $formType = 'form-project-new-confirmed.html.twig';
  696.                 //     break;
  697.                 default:
  698.                     $formType 'form-project.html.twig';
  699.                     break;
  700.             }
  701.             $result['form'] = $this->renderView('private/project-management/project/components/' $formType, [
  702.                 'form' => $form->createView(),
  703.                 'projectsList' => $projectRepository->findByPage($page$limit),
  704.                 'id' => $project->getId(),
  705.             ]);
  706.         }
  707.         //return new Response($result['form']);
  708.         return new JsonResponse($result);
  709.     }
  710.     /**
  711.      * @param ProjectRepository $projectRepository
  712.      * @param Request $request
  713.      * @param LogService $log
  714.      * @return Response
  715.      */
  716.     #[Route(path'/ajax/project-revenue/persist'name'ajax_persist_project_revenue')]
  717.     public function ajaxPersistProjectRevenue(ProjectRepository $projectRepositoryUploadService $uploadServiceParameterBagInterface $paramsProjectService $projectServiceRequest $requestLogService $logWebhookService $webhookRequestStack $requestStack): Response
  718.     {
  719.         $baseUrl $requestStack->getCurrentRequest()->getSchemeAndHttpHost();
  720.         $currentUrl $requestStack->getCurrentRequest()->getUri();
  721.         $id intval($request->get('id'));
  722.         // $type = $request->get('type');
  723.         $user $this->getUser();
  724.         $project = new Project();
  725.         $result['status'] = 'OK';
  726.         if ($id 0) {
  727.             $project $projectRepository->find($id);
  728.             $oldData = clone $project;
  729.             $result['id'] = $project->getId();
  730.         } else {
  731.             $oldData null;
  732.         }
  733.         $form $this->createForm(ProjectRevenuePlanningType::class, $project);
  734.         $form->handleRequest($request);
  735.         if ($form->isSubmitted() && !$form->isValid()) {
  736.             $result['status'] = 'ERROR';
  737.             foreach ($form->getErrors(true) as $key => $error) {
  738.                 $result['message'][$key] = $error->getMessage();
  739.             }
  740.         }
  741.         if ($form->isSubmitted() && $form->isValid()) {
  742.             
  743.             if ($id === 0) {
  744.                 
  745.             } else {
  746.                 foreach($project->getRevenuePlannings() as $revenuePlan){
  747.                     $revenuePlan->setAmountUsd($revenuePlan->getAmountToUsd());
  748.                     $revenuePlan->setUpdatedAt(new \DateTimeImmutable());
  749.                 }
  750.                 $result['id'] = $project->getId();
  751.                 $result['update'] = true;
  752.             }
  753.             $entityManager $this->getDoctrine()->getManager();
  754.             $entityManager->persist($project);
  755.             $entityManager->flush();
  756.             $entityManager->refresh($project);
  757.             $log->save($user, [
  758.                 'owner' => $user,
  759.                 'message' => $id === 'log.project-revenue.add' 'log.project-revenue.edit',
  760.                 'old_data' => $id === null $oldData,
  761.                 'new_data' => $project
  762.             ]);
  763.             $monthlyRevenues $projectService->monthlyRevenues($project);
  764.             $monthlyRevenuesRecognition $projectService->monthlyRevenues($projectfalse);
  765.             $result['projectRevenueDetail'] = $this->renderView('private/project-management/project-revenue-planning/components/detail-revenue-planning.html.twig', [
  766.                 'project' => $project,
  767.                 'monthlyRevenues' => $monthlyRevenues,
  768.                 'monthlyRevenuesRecognition' => $monthlyRevenuesRecognition,
  769.                 'waitForPage' => false
  770.             ]);
  771.             $result['projectRevenueOverview'] = $this->renderView('private/project-management/project-revenue-planning/components/overview-revenue-planning.html.twig', [
  772.                 'project' => $project,
  773.                 'monthlyRevenues' => $monthlyRevenues,
  774.                 'monthlyRevenuesRecognition' => $monthlyRevenuesRecognition,
  775.                 'waitForPage' => false
  776.             ]);
  777.             return new JsonResponse($result);
  778.                 
  779.         }
  780.         $result['form'] = $this->renderView('private/project-management/project-revenue-planning/components/form-project-revenue-planning.html.twig', [
  781.             // 'project' => $project,
  782.             'id' => $project->getId(),
  783.             'formProject' => $form->createView(),
  784.         ]);
  785.         return new JsonResponse($result);
  786.     }
  787.     /**
  788.      * @param ProjectRepository $projectRepository
  789.      * @param Request $request
  790.      * @param LogService $log
  791.      * @return Response
  792.      */
  793.     #[Route(path'/ajax/project-deliverable/persist'name'ajax_persist_project_deliverable')]
  794.     public function ajaxPersistProjectDeliverable(ProjectDeliverableRepository $projectDeliverableRepositoryUploadService $uploadServiceParameterBagInterface $paramsProjectService $projectServiceRequest $requestLogService $logRequestStack $requestStackS3Service $s3ServiceFileService $fileService): Response
  795.     {
  796.         $baseUrl $requestStack->getCurrentRequest()->getSchemeAndHttpHost();
  797.         $currentUrl $requestStack->getCurrentRequest()->getUri();
  798.         $id intval($request->get('id'));
  799.         $user $this->getUser();
  800.         
  801.         if($id){
  802.             $projectDeliverable $projectDeliverableRepository->find($id);
  803.         }else{
  804.             $projectDeliverable = new ProjectDeliverable();
  805.             // $projectDeliverableFile = new ProjectDeliverableFile();    
  806.             $oldData null;
  807.         }
  808.         
  809.         $result['status'] = 'OK';
  810.         $form $this->createForm(ProjectDeliverableType::class, $projectDeliverable);
  811.         $form->handleRequest($request);
  812.         if ($form->isSubmitted() && !$form->isValid()) {
  813.             $result['status'] = 'ERROR';
  814.             $result['type'] = 'danger';
  815.             foreach ($form->getErrors(true) as $key => $error) {
  816.                 $fieldName $error->getOrigin()->getName();
  817.                 $result['message'][$key] = ucwords($fieldName).': '$error->getMessage();
  818.                 
  819.                 $view $error->getOrigin()->createView();
  820.                 $id $view->vars['id'];
  821.                 $result['target'][$key] = $id;
  822.             }
  823.         }
  824.         
  825.         if ($form->isSubmitted() && $form->isValid()) {
  826.             for ($i 1$i <= 3$i++) {
  827.                 $key "removeImage$i";
  828.                 if ($request->request->has($key)) {
  829.                     if($request->request->get($key)){
  830.                         $filename explode('/'$projectDeliverable->getThumbnails()[$i]);
  831.                         $s3Result $s3Service->deleteFromS3($filename[2], $this->getParameter('documentFile'));
  832.                         if ($s3Result['@metadata']['statusCode'] == 204) {
  833.                             $thumbnails $projectDeliverable->getThumbnails();
  834.                             unset($thumbnails[$i]);
  835.                             $projectDeliverable->setThumbnails($thumbnails);
  836.                             $entityManager $this->getDoctrine()->getManager();
  837.                             $entityManager->persist($projectDeliverable);
  838.                             $entityManager->flush();
  839.                         } else {
  840.                             $this->addFlash(
  841.                                 'danger',
  842.                                 $s3Result['@metadata']['statusCode']
  843.                             );
  844.                         }
  845.                     }
  846.                 }
  847.             }
  848.             for ($i 1$i <= 3$i++) {
  849.                 $key 'thumbnail'.$i;
  850.                 if ($thumbnails $form->get($key)->getData()) {
  851.                     if ($thumbnails->getError() > 0) {
  852.                         $errorMessage sprintf(
  853.                             'Error uploading thumbnail %d: %s',
  854.                             $i,
  855.                             $thumbnails->getErrorMessage()
  856.                         );
  857.                         $this->addFlash('danger'$errorMessage);
  858.                         // $this->addFlash(
  859.                         //     'danger',
  860.                         //     $thumbnails->getErrorMessage()
  861.                         // );
  862.                         return $this->redirect($request->getUri());
  863.                     }
  864.                     if (!file_exists($this->getParameter('documentFile')))
  865.                         mkdir($this->getParameter('documentFile'), 0755true);
  866.                     $originalName $thumbnails->getClientOriginalName();
  867.                     $extension $thumbnails->guessExtension();
  868.                     $fileName $fileService->generateFilename($originalName$extension);
  869.                     $srcPath $this->getParameter('documentFile') . '/' $fileName;
  870.                     if(is_null($projectDeliverable->getThumbnails())){
  871.                         $thumbnailsData = [
  872.                             $i => $srcPath,
  873.                         ];
  874.                         $projectDeliverable->setThumbnails($thumbnailsData);
  875.                     }else{
  876.                         $thumbnailsData $projectDeliverable->getThumbnails();
  877.                         $thumbnailsData[$i] = $srcPath;
  878.                         $projectDeliverable->setThumbnails($thumbnailsData);
  879.                     }
  880.                     // Local
  881.                     try {
  882.                         $thumbnails->move(
  883.                             $this->getParameter('documentFile'),
  884.                             $fileName
  885.                         );
  886.                     } catch (\FileException $e) {
  887.                         $this->addFlash(
  888.                             'danger',
  889.                             'Upload failed'
  890.                         );
  891.                         return $this->redirect($request->getUri());
  892.                     }
  893.                     // S3
  894.                     $s3Result $s3Service->sendMediaToS3($srcPath$fileName$this->getParameter('documentFile'));
  895.                     if ($s3Result['@metadata']['statusCode'] == 200) {
  896.                         gc_collect_cycles();
  897.                         if (file_exists($srcPath))
  898.                             unlink($srcPath);
  899.                         
  900.                         $entityManager $this->getDoctrine()->getManager();
  901.                         $entityManager->persist($projectDeliverable);
  902.                         $entityManager->flush();
  903.                     } else {
  904.                         $this->addFlash(
  905.                             'danger',
  906.                             $s3Result['@metadata']['statusCode']
  907.                         );
  908.                     }
  909.                 }
  910.             }
  911.             foreach($projectDeliverable->getProjectDeliverableFiles() as $projectDeliverableFile){ 
  912.                     if(!$projectDeliverableFile->getProjectDeliverable()){
  913.                         $projectDeliverableFile->setProjectDeliverable($projectDeliverable);
  914.                     }
  915.                     if($projectDeliverableFile->getId() == null)
  916.                     { 
  917.                         $projectDeliverableFile->setProjectDeliverable($projectDeliverable);
  918.                         if($projectDeliverableFile->getCreatedAt() == null){
  919.                             $projectDeliverableFile->setCreatedAt(new \DateTimeImmutable());
  920.                             $projectDeliverableFile->setCreatedBy($user->getId());
  921.                         }
  922.                     }
  923.             }
  924.             $inputBag $request->request->get('project_deliverable');
  925.             $fileBag $request->files->get('project_deliverable');
  926.             $inputFiles =  is_array($inputBag) ? $inputBag['projectDeliverableFiles'] : null;
  927.             $uploadedFiles is_array($inputBag) ? $fileBag['projectDeliverableFiles'] : null;
  928.             if($uploadedFiles){
  929.                 foreach($uploadedFiles as $key => $fileUpload){
  930.                     if(!$fileUpload['file']) continue;
  931.     
  932.                     $fileUploadUuid $inputFiles[$key]['uuid'];
  933.                     $projectDeliverableFile $projectDeliverable->getProjectDeliverableFileByUuid($fileUploadUuid);
  934.     
  935.                     if($fileUpload['file']){
  936.                         if(!empty($projectDeliverableFile->getFile())){
  937.                             $oldFileName explode('/'$projectDeliverableFile->getFile());
  938.                             $s3Service->deleteFromS3($oldFileName[2], $this->getParameter('documentFile'));
  939.                         }
  940.                         if ($fileUpload['file']->getError() > 0) {
  941.                         $this->addFlash(
  942.                                 'danger',
  943.                                 $fileUpload->getErrorMessage()
  944.                             );
  945.                             return $this->redirect($request->getUri());
  946.                         }
  947.                         if (!file_exists($this->getParameter('documentFile')))
  948.                             mkdir($this->getParameter('documentFile'), 0755true);
  949.         
  950.                         $originalName $fileUpload['file']->getClientOriginalName();
  951.                         $extension $fileUpload['file']->guessExtension();
  952.                         $fileName $fileService->generateFilename($originalName$extension);
  953.                         $srcPath $this->getParameter('documentFile') . '/' $fileName;
  954.                         $projectDeliverableFile->setFile($srcPath);
  955.                         if($projectDeliverableFile->getCreatedAt() == null){
  956.                             $projectDeliverableFile->setCreatedAt(new \DateTimeImmutable());
  957.                             $projectDeliverableFile->setCreatedBy($user->getId());
  958.                         }else{
  959.                             $projectDeliverableFile->setUpdatedAt(new \DateTimeImmutable());
  960.                             $projectDeliverableFile->setUpdatedBy($user->getId());
  961.                         }
  962.     
  963.                         if(!$projectDeliverableFile->getProjectDeliverable()){
  964.                             $projectDeliverableFile->setProjectDeliverable($projectDeliverable);
  965.                         }
  966.         
  967.                         // Local
  968.                         try {
  969.                             $fileUpload['file']->move(
  970.                                 $this->getParameter('documentFile'),
  971.                                 $fileName
  972.                             );
  973.                         } catch (\FileException $e) {
  974.                             $this->addFlash(
  975.                                 'danger',
  976.                                 'Upload failed'
  977.                             );
  978.                             return $this->redirect($request->getUri());
  979.                         }
  980.         
  981.                         // S3
  982.                         $s3Result $s3Service->sendMediaToS3($srcPath$fileName$this->getParameter('documentFile'));
  983.                         if ($s3Result['@metadata']['statusCode'] == 200) {
  984.                             gc_collect_cycles();
  985.                             if (file_exists($srcPath))
  986.                                 unlink($srcPath);
  987.                             
  988.                             $entityManager $this->getDoctrine()->getManager();
  989.                             $entityManager->persist($projectDeliverableFile);
  990.                             $entityManager->flush();
  991.         
  992.                         } else {
  993.                             $this->addFlash(
  994.                                 'danger',
  995.                                 $s3Result['@metadata']['statusCode']
  996.                             );
  997.                         }
  998.                     }
  999.                     
  1000.                 }
  1001.             }
  1002.             
  1003.             $result['id'] = $projectDeliverable->getId();
  1004.             $result['update'] = true;
  1005.             $entityManager $this->getDoctrine()->getManager();
  1006.             $entityManager->persist($projectDeliverable);
  1007.             $entityManager->flush();
  1008.             $entityManager->refresh($projectDeliverable);
  1009.             foreach($projectDeliverable->getProjectDeliverableFiles() as $projectDeliverableFile){  
  1010.                 if($projectDeliverableFile->isIsDeleted() == true){
  1011.                     $projectDeliverableFile->setProjectDeliverable(null);
  1012.                     if(!empty($projectDeliverableFile->getFile())){
  1013.                         $oldFileName explode('/'$projectDeliverableFile->getFile());
  1014.                         $s3Service->deleteFromS3($oldFileName[2], $this->getParameter('documentFile'));
  1015.                     }
  1016.                     $entityManager->remove($projectDeliverableFile);
  1017.                 }
  1018.             }
  1019.             $entityManager->flush();
  1020.             $log->save($user, [
  1021.                 'owner' => $user,
  1022.                 'message' => 'log.project-deliverable.edit',
  1023.                 'old_data' => null,
  1024.                 'new_data' => $projectDeliverable
  1025.             ]);
  1026.             $result['thumbnails'] = $this->renderView('private/project-management/project-deliverable/components/project-deliverable-thumbnails.html.twig', [
  1027.                 'projectDeliverable' => $projectDeliverable,
  1028.             ]);
  1029.             
  1030.             $result['documents'] = $this->renderView('private/project-management/project-deliverable/components/list-project-deliverable.html.twig', [
  1031.                 'projectDeliverable' => $projectDeliverable,
  1032.                 'waitForPage' => false
  1033.             ]);
  1034.             return new JsonResponse($result);
  1035.                 
  1036.         }
  1037.         
  1038.         $result['form'] = $this->renderView('private/project-management/project-deliverable/components/form-project-deliverable.html.twig', [
  1039.             // 'project' => $project,
  1040.             'id' => $projectDeliverable->getId(),
  1041.             'projectDeliverable' => $projectDeliverable,
  1042.             'formProjectDeliverable' => $form->createView(),
  1043.         ]);
  1044.         return new JsonResponse($result);
  1045.     }
  1046.     #[Route(path'/ajax/project-client-feedback-temp/persist'name'ajax_persist_project_client_feedback_temp')]
  1047.     public function ajaxPersistProjectClientFeedbackTemplate(ProjectRepository $projectRepositoryRequest $requestLogService $log): Response
  1048.     {
  1049.         $id intval($request->get('id'));
  1050.         $project $projectRepository->find($id);
  1051.         $oldData = clone $project;
  1052.         $user $this->getUser();
  1053.         
  1054.         $result['status'] = 'OK';
  1055.         $form $this->createForm(ProjectClientFeedbackTemplateType::class, $project);
  1056.         $form->handleRequest($request);
  1057.         if ($form->isSubmitted() && !$form->isValid()) {
  1058.             $result['status'] = 'ERROR';
  1059.             foreach ($form->getErrors(true) as $key => $error) {
  1060.                 $result['message'][$key] = $error->getMessage();
  1061.             }
  1062.         }
  1063.         if ($form->isSubmitted() && $form->isValid()) {
  1064.             
  1065.             $result['id'] = $project->getId();
  1066.             $result['update'] = true;
  1067.             $entityManager $this->getDoctrine()->getManager();
  1068.             if(!empty($project->getClientFeedbackTemplate())){
  1069.                 if($oldData->getClientFeedbackTemplate() && $project->getClientFeedbackTemplate() != $oldData->getClientFeedbackTemplate()){
  1070.                     $feedbacks $oldData->getActiveClientFeedback($oldData->getClientFeedbackTemplate()->getId());
  1071.                     foreach($feedbacks as $feedback){
  1072.                         $project->removeClientFeedback($feedback);
  1073.                     }
  1074.                 }
  1075.                 if(!empty($project->getClientFeedbackTemplate()->getClientFeedbackForms())){
  1076.                     $feedbackForms $project->getClientFeedbackTemplate()->getClientFeedbackForms();
  1077.                     foreach($feedbackForms as $feedbackForm){
  1078.                         $clientFeedback = new ClientFeedback();
  1079.                         $clientFeedback->setFeedbackArea($feedbackForm->getAreaFeedback());
  1080.                         $clientFeedback->setFeedbackAreaDesc($feedbackForm->getDescription());
  1081.                         $clientFeedback->setFeedbackType($feedbackForm->getFeedbackType());
  1082.                         $clientFeedback->setFeedbackTemplate($project->getClientFeedbackTemplate()->getId());
  1083.                         $clientFeedback->setCreatedAt(new \DateTimeImmutable());
  1084.                         $clientFeedback->setCreatedBy($user->getId());
  1085.                         
  1086.                         $project->addClientFeedback($clientFeedback);
  1087.                     }
  1088.                 }
  1089.             }
  1090.             // Old code
  1091.             /*
  1092.             if($project->checkFilledFeedbackTemplate()){
  1093.                 foreach($project->getClientFeedback() as $feedback){
  1094.                     $feedback->setDeletedAt(new \DateTimeImmutable());
  1095.                 }
  1096.             }*/
  1097.             // $project->setScore($project->getFeedbackScore());
  1098.             $entityManager->persist($project);
  1099.             $entityManager->flush();
  1100.             $entityManager->refresh($project);
  1101.             $log->save($user, [
  1102.                 'owner' => $user,
  1103.                 'message' => 'log.project.edit',
  1104.                 'old_data' => null,
  1105.                 'new_data' => $project
  1106.             ]);
  1107.             $result['score'] = $project->getScore();
  1108.             $result['projectStatus'] = $project->getStatus();
  1109.             $result['clientFeedback'] = $this->renderView('private/project-management/client-feedback/client-feedback.html.twig', [
  1110.                 'project' => $project,
  1111.             ]);
  1112.             $result['clientFeedbackList'] = $this->renderView('private/project-management/client-feedback/components/list-client-feedback.html.twig', [
  1113.                 'clientFeedbacks' => $project->getActiveClientFeedback(),
  1114.             ]);
  1115.             return new JsonResponse($result);
  1116.                 
  1117.         }
  1118.         $warning null;
  1119.         if($project->checkFilledFeedbackTemplate()){
  1120.             $warning "Your feedback template has been filled out by the client. Changing the filled feedback template will result in all feedback from the client being lost.";
  1121.         }
  1122.        
  1123.         $result['form'] = $this->renderView('private/project-management/client-feedback/components/form-project-client-feedback-template.html.twig', [
  1124.             'id' => $project->getId(),
  1125.             'project' => $project,
  1126.             'formProject' => $form->createView(),
  1127.             'warning' => $warning
  1128.         ]);
  1129.         return new JsonResponse($result);
  1130.     }
  1131.     #[Route(path'/ajax/crud/project-client-feedback'name'ajax_crud_client_feedback')]
  1132.     public function ajaxCrudClientFeedback(ClientFeedbackRepository $clientFeedbackRepositoryRequest $requestLogService $log): Response
  1133.     {
  1134.         $id intval($request->get('id'));
  1135.         $crud $request->get("crud");
  1136.         $project $request->get('project');
  1137.         $user $this->getUser();
  1138.         
  1139.         $result['status'] = 'OK';
  1140.         if (empty($id)) {
  1141.             $clientFeedback = new ClientFeedback();
  1142.             $id null;
  1143.         } else {
  1144.             $clientFeedback $clientFeedbackRepository->find($id);
  1145.             $oldData = clone $clientFeedback;
  1146.         }
  1147.         $waitForPage $request->query->get('waitForPage');
  1148.         $waitForPage === null $result['waitForPage'] = 'false' $result['waitForPage'] = $waitForPage;
  1149.         $form $this->createForm(ClientFeedbackType::class, $clientFeedback);
  1150.         $form->handleRequest($request);
  1151.         if ($form->isSubmitted() && !$form->isValid()) {
  1152.             $result['status'] = 'ERROR';
  1153.             foreach ($form->getErrors(true) as $key => $error) {
  1154.                 $result['message'][$key] = $error->getMessage();
  1155.             }
  1156.             return new JsonResponse($result);
  1157.         }
  1158.         if ($form->isSubmitted() && $form->isValid()) {
  1159.             if($project !== null){
  1160.                 $project $this->getDoctrine()->getRepository(Project::class)->find($project);
  1161.                 $clientFeedback->setProject($project);
  1162.             }
  1163.             
  1164.             $result['id'] = $clientFeedback->getId();
  1165.             $result['update'] = true;
  1166.             $entityManager $this->getDoctrine()->getManager();
  1167.             
  1168.             if ($id === null) {
  1169.                 $clientFeedback->setCreatedBy($user->getId());
  1170.                 $clientFeedback->setCreatedAt(new \DateTimeImmutable());
  1171.             } else {
  1172.                 $clientFeedback->setUpdatedAt(new \DateTimeImmutable());
  1173.                 $clientFeedback->setUpdatedBy($user->getId());
  1174.             }
  1175.             $entityManager->persist($clientFeedback);
  1176.             $entityManager->flush();
  1177.             $entityManager->refresh($clientFeedback);
  1178.             $log->save($user, [
  1179.                 'owner' => $user,
  1180.                 'message' => 'log.client_feedback.edit',
  1181.                 'old_data' => null,
  1182.                 'new_data' => $clientFeedback
  1183.             ]);
  1184.             $result['id'] = $clientFeedback->getId();
  1185.             $result['content'] = $this->renderView('private/project-management/client-feedback/components/row-client-feedback.html.twig', [
  1186.                 'clientFeedback' => $clientFeedback,
  1187.                 'waitForPage' => $waitForPage,
  1188.                 'hideAction' => false
  1189.             ]);
  1190.             $result['update'] = $id === null false true;
  1191.             return new JsonResponse($result);
  1192.                 
  1193.         }
  1194.         if ($crud === 'delete' && $clientFeedback !== null) {
  1195.             if ($result['status'] == 'OK') {
  1196.                 $clientFeedback->setDeletedAt(new \DateTimeImmutable());
  1197.                 $entityManager $this->getDoctrine()->getManager();
  1198.                 $entityManager->flush();
  1199.                 $log->save($user, [
  1200.                     'owner' => $user,
  1201.                     'message' => 'log.client_feedback.delete',
  1202.                     'old_data' => $oldData,
  1203.                     'new_data' => null
  1204.                 ]);
  1205.             }
  1206.             return new JsonResponse($result);
  1207.         }
  1208.         if ($crud === 'create' || $crud === 'update') {
  1209.             $result['form'] = $this->renderView('private/project-management/client-feedback/components/form-client-feedback.html.twig', [
  1210.                 'id' => $clientFeedback->getId(),
  1211.                 'clientFeedback' => $clientFeedback,
  1212.                 'project' => $project,
  1213.                 'formClientFeedback' => $form->createView(),
  1214.             ]);
  1215.             return new JsonResponse($result);
  1216.         }
  1217.         $order $request->get('order');
  1218.         $orderBy $request->get('orderBy');
  1219.         // $office = $request->get('office');
  1220.         $keyword $request->get('keyword');
  1221.         $page  intval($request->query->get('page'));
  1222.         $limit intval($request->query->get('limit'));
  1223.         if ($limit === 0$limit 20;
  1224.         $clientFeedbacks $clientFeedbackRepository->findByPage($page$limit$order$orderBy$keyword$project);
  1225.         $totalCount =  $clientFeedbackRepository->countByPage($keyword$project);
  1226.         $body $this->renderView('private/project-management/client-feedback/components/list-client-feedback.html.twig', [
  1227.             'clientFeedbacks' => $clientFeedbacks,
  1228.         ]);
  1229.         $result['content'] = [
  1230.             'html' => $body,
  1231.             'total' => $totalCount
  1232.         ];
  1233.         return new JsonResponse($result);
  1234.     }
  1235.     /**
  1236.      * @param ProjectRepository $projectRepository
  1237.      * @param Request $request
  1238.      * @param LogService $log
  1239.      * @return Response
  1240.      */
  1241.     #[Route(path'/ajax/project/sales-order/persist'name'ajax_persist_project_so')]
  1242.     public function ajaxPersistProjectSO(SalesOrderRepository $salesOrderRepositoryProjectSalesOrderRepository $projectSalesOrderRepositoryProjectRepository $projectRepositoryRequest $requestProjectService $projectServiceLogService $log): Response
  1243.     {
  1244.         $soId intval($request->get('so_id'));
  1245.         $projectId intval($request->get('p_id'));
  1246.         $result['status'] = 'OK';
  1247.         $salesOrder $salesOrderRepository->find($soId);
  1248.         $project $projectRepository->find($projectId);
  1249.         $pso $projectSalesOrderRepository->findOneBy(['project' => $project'salesOrder' => $salesOrder]);
  1250.         if (!$salesOrder || !$project) {
  1251.             $result['status'] = 'ERROR';
  1252.             $result['message'] = 'SO no found';
  1253.             return new JsonResponse($result);
  1254.         } else {
  1255.             $oldData = clone $project->getProjectSalesOrders();
  1256.         }
  1257.         
  1258.         $clientId null;
  1259.         $clientId $project->getClient()->getId();
  1260.         $form $this->createForm(SalesOrderType::class, $salesOrder,array('projectId' => $projectId'clientId' => $clientId));
  1261.         $result['form'] = $this->renderView('private/project-management/project/components/form-project-sales-order.html.twig', [
  1262.             'form' => $form->createView(),
  1263.             'salesOrder' => $salesOrder,
  1264.             'so_id' => $soId,
  1265.             'p_id' => $projectId,
  1266.             'pso' => $pso,
  1267.             'project' => $project
  1268.         ]);
  1269.         $form->handleRequest($request);
  1270.         //        dd($form->isSubmitted());
  1271.         if ($form->isSubmitted() && !$form->isValid()) {
  1272.             //            dd('test');
  1273.             //            dd($form->getErrors());
  1274.             $result['status'] = 'ERROR';
  1275.             foreach ($form->getErrors(true) as $key => $error) {
  1276.                 dd($error);
  1277.                 $result['message'][$key] = $error->getMessage();
  1278.             }
  1279.             dd($result['message']);
  1280.         }
  1281.         if ($form->isSubmitted() && $form->isValid()) {
  1282.             $entityManager $this->getDoctrine()->getManager();
  1283.             $pso $projectSalesOrderRepository->findOneBy(['project' => $project'salesOrder' => $salesOrder]);
  1284.             if ($pso) {
  1285.                 foreach ($form->get('salesOrderPurchaseOrders') as $purchaseOrder) {
  1286.                     if ($purchaseOrder->getData()->getProject() === null) {
  1287.                         $purchaseOrder->getData()->setProject($project);
  1288.                     }
  1289.                 }
  1290.                 $pso->setAmount($form->get('amount')->getData());
  1291.                 $entityManager->persist($pso);
  1292.                 $soInvoices $pso->getSalesOrder()->getSalesOrderInvoices();
  1293.                 foreach ($soInvoices as $soInvoice) {
  1294.                     if ($soInvoice->getProject() === null) {
  1295.                         $soInvoice->setProject($project);
  1296.                         $entityManager->persist($soInvoice);
  1297.                         $projectService->projectSalesHasAllocatedEmail($soInvoice->getInvoice(), $project);
  1298.                     }
  1299.                 }
  1300.                 $entityManager->flush();
  1301.             } else {
  1302.                 $projectSalesOrder = new ProjectSalesOrder();
  1303.                 $projectSalesOrder->setProject($project);
  1304.                 $projectSalesOrder->setSalesOrder($salesOrder);
  1305.                 $projectSalesOrder->setAmount($form->get('amount')->getData());
  1306.                 $entityManager->persist($projectSalesOrder);
  1307.                 $soInvoices $projectSalesOrder->getSalesOrder()->getSalesOrderInvoices();
  1308.                 foreach ($soInvoices as $soInvoice) {
  1309.                     if ($soInvoice->getProject() === null) {
  1310.                         $soInvoice->setProject($project);
  1311.                         $entityManager->persist($soInvoice);
  1312.                     }
  1313.                 }
  1314.                 $entityManager->flush();
  1315.             }
  1316.             $entityManager->refresh($salesOrder);
  1317.             
  1318.             $user $this->getUser();
  1319.             $result['content'] = $this->renderView('private/project-management/sales-order/components/row-sales-order.html.twig', [
  1320.                 'salesOrder' => $salesOrder,
  1321.                 'waitForPage' => false,
  1322.                 'project' => $project->getId(),
  1323.                 'projectObj' => $project
  1324.             ]);
  1325.             $result['id'] = $salesOrder->getId();
  1326.             $result['update'] = true;
  1327.             $log->save($user, [
  1328.                 'owner' => $user,
  1329.                 'message' => $soId === 'log.project.addso' 'log.project.updateso',
  1330.                 'old_data' => $oldData,
  1331.                 'new_data' => $project->getProjectSalesOrders()
  1332.             ]);
  1333.         }
  1334.         //        else if (!$form->isSubmitted() && $salesOrder && $request->get('save_so') === 'true') {
  1335.         //            $entityManager = $this->getDoctrine()->getManager();
  1336.         ////            $project->addSalesOrder($salesOrder);
  1337.         //            $entityManager->persist($project);
  1338.         //            $entityManager->flush();
  1339.         //            $user = $this->getUser();
  1340.         //
  1341.         //            $log->save($user, [
  1342.         //                'owner' => $user,
  1343.         //                'message' => $soId === 0 ? 'log.project.addso' : 'log.project.updateso',
  1344.         //                'old_data' => $oldData,
  1345.         //                'new_data' => $project->getSalesOrders()
  1346.         //            ]);
  1347.         //        };
  1348.         foreach ($form->getErrors(true) as $key => $error) {
  1349.             $result['message'][$key] = $error->getMessage();
  1350.         }
  1351.         //        dd($result);
  1352.         //return new Response($result['form']);
  1353.         //        Type::class, $project);
  1354.         return new JsonResponse($result);
  1355.     }
  1356.     /**
  1357.      * @param Request $request
  1358.      * @param ProjectRepository $projectRepository
  1359.      * @param TranslatorInterface $translator
  1360.      * @param LogService $log
  1361.      * @return Response
  1362.      */
  1363.     #[Route(path'/ajax/project/delete'name'ajax_delete_project'methods'POST')]
  1364.     public function ajaxDeleteProject(Request $requestProjectRepository $projectRepositoryTranslatorInterface $translatorLogService $logWebhookService $webhookProjectService $projectService): Response
  1365.     {
  1366.         $project $projectRepository->find(intval($request->get('id')));
  1367.         $oldData = clone $project;
  1368.         if (!$project) {
  1369.             $result['status'] = 'ERROR';
  1370.             $result['message'] = $translator->trans('messages.project.not_found');
  1371.             return new JsonResponse($result);
  1372.         } else {
  1373.             $user $this->getUser();
  1374.             try {
  1375.                 $entityManager $this->getDoctrine()->getManager();
  1376.                 if ($project->getDeletedAt() === null) {
  1377.                     $project->setDeletedAt(new \DateTimeImmutable());
  1378.                     $log->save($user, [
  1379.                         'owner' => $user,
  1380.                         'message' => ' log.project.soft_delete',
  1381.                         'old_data' => $oldData,
  1382.                         'new_data' => null
  1383.                     ]);
  1384.                     
  1385.                     $projectService->projectDeletedEmail($project$user);
  1386.                 } else {
  1387.                     $projectRepository->remove($project);
  1388.                     $log->save($user, [
  1389.                         'owner' => $user,
  1390.                         'message' => ' log.project.delete',
  1391.                         'old_data' => $oldData,
  1392.                         'new_data' => null
  1393.                     ]);
  1394.                 }
  1395.                 $entityManager->flush();
  1396.             } catch (OptimisticLockException ORMException $e) {
  1397.                 $result['status'] = 'ERROR';
  1398.                 $result['message'] = $translator->trans('messages.project.delete.error');
  1399.                 return new JsonResponse($result);
  1400.             }
  1401.             if($_SERVER['APP_ENV'] == "prod"){
  1402.                 $result['webhook'] = $webhook->checkboxWebhook('projects''DELETE'$oldData->getId());
  1403.             }
  1404.         }
  1405.         $result['status'] = 'OK';
  1406.         return new JsonResponse($result);
  1407.     }
  1408.     /**
  1409.      * @param Request $request
  1410.      * @param UploadService $uploadService
  1411.      * @param ParameterBagInterface $params
  1412.      * @return JsonResponse
  1413.      */
  1414.     #[Route(path'/ajax/project/upload'name'upload_project_plan'methods: ['POST'])]
  1415.     public function upload_file(Request $requestUploadService $uploadServiceParameterBagInterface $params)
  1416.     {
  1417.         $uploadFolder $params->get('projectPlanFile');
  1418.         $response $uploadService->uploadFileToS3($uploadFolder'file'$request);
  1419.         return new JsonResponse($response);
  1420.     }
  1421.     /**
  1422.      * @param Request $request
  1423.      * @param MattermostService $mattermostService
  1424.      * @return JsonResponse
  1425.      */
  1426.     #[Route(path'/ajax/mattermost/create-channel'name'ajax_mattermost_create_channel'methods: ['POST'])]
  1427.     public function createMattermostChannel(Request $requestMattermostService $mattermostService): Response
  1428.     {
  1429.         $project $request->get('project');
  1430.         $crud $request->get("crud");
  1431.         $result['status'] = 'OK';
  1432.         // add form
  1433.         $form $this->createForm(MattermostType::class);
  1434.      
  1435.         $form->handleRequest($request);
  1436.         
  1437.         if ($form->isSubmitted() && !$form->isValid()) {
  1438.             $result['status'] = 'ERROR';
  1439.             foreach ($form->getErrors(true) as $key => $error) {
  1440.                 $result['message'][$key] = $error->getMessage();
  1441.             }
  1442.         }
  1443.         if ($form->isSubmitted() && $form->isValid()) {
  1444.             $name $form->get('name')->getData();
  1445.             $response $mattermostService->createChannel($name);
  1446.             if($response['status'] == 'OK'){
  1447.                 $result $response;
  1448.                 $project $this->getDoctrine()->getRepository(Project::class)->find($project);
  1449.                 if($project){
  1450.                     $project->setMattermost($result['url']);
  1451.                     $entityManager $this->getDoctrine()->getManager();
  1452.                     $entityManager->flush();
  1453.                 };
  1454.             } 
  1455.             // $result['url'] = 'https://xxxmattermost.mediatropy.com/mediatropy/channels/test-mm-integration-adhit';
  1456.             // $result['name'] = 'test-mm-integration-adhit';  
  1457.             return new JsonResponse($result);
  1458.         };
  1459.         if($crud === 'create'){
  1460.             $result['form'] = $this->renderView('private/project-management/project/components/form-mattermost.html.twig', [
  1461.             'form' => $form->createView(),
  1462.         ]);
  1463.         return new JsonResponse($result);
  1464.         }
  1465.     }
  1466.     /**
  1467.      * @param int $_id
  1468.      */
  1469.     #[Route(path'/project/export-sales-orders/{_id}'defaults: ['_id' => 0], name'export_project_sales_orders')]
  1470.     public function exportProjectSalesOrders(int $_idSalesOrderRepository $salesOrderRepositoryTranslatorInterface $translatorProjectRepository $projectRepository)
  1471.     {
  1472.         $project $projectRepository->find($_id);
  1473.         if (!$project) {
  1474.             return new Response($translator->trans('messages.project.not_found'));
  1475.         }
  1476.         //        dd($employeeSummaryList);
  1477.         $spreadsheet = new Spreadsheet();
  1478.         $sheet $spreadsheet->getActiveSheet();
  1479.         $sheet->setCellValue('A1''SO Number');
  1480.         $sheet->setCellValue('B1''Currency');
  1481.         $sheet->setCellValue('C1''Amount');
  1482.         $sheet->setCellValue('D1''Reference');
  1483.         $sheet->setCellValue('E1''Invoice');
  1484.         $sheet->setCellValue('F1''Amount');
  1485.         $sheet->setCellValue('G1''Due');
  1486.         $sheet->setCellValue('H1''Status');
  1487.         $soList $salesOrderRepository->findByPage(09999""'ASC'null$_id0);
  1488.         $filename $_id "_" urlencode($project->getName()) . "_" date('Y-m-d') . '.xlsx';
  1489.         foreach ($soList as $salesOrder) {
  1490.             $row $sheet->getHighestRow() + 1;
  1491.             $sheet->insertNewRowBefore($row);
  1492.             $sheet->setCellValue('A' $row$salesOrder->getSalesOrderNo());
  1493.             $sheet->setCellValue('B' $row$salesOrder->getCurrency()->getIso());
  1494.             $sheet->setCellValue('C' $row$salesOrder->getTotal());
  1495.             //Todo this one need to link to the actual PO in HR when we have the page
  1496.             $sheet->setCellValue('D' $row$salesOrder->getPurchaseOrder() ? $salesOrder->getPurchaseOrder()->getPurchaseOrderNo() : "");
  1497.             $invoices $salesOrder->getSalesOrderInvoices($_id);
  1498.             $i 0;
  1499.             foreach ($invoices as $soInvoice) {
  1500.                 if ($i 0) {
  1501.                     $row $sheet->getHighestRow() + 1;
  1502.                     $sheet->insertNewRowBefore($row);
  1503.                 }
  1504.                 $invoice $soInvoice->getInvoice();
  1505.                 $sheet->setCellValue('E' $row$invoice->getInvoiceNo());
  1506.                 $sheet->setCellValue('F' $row$soInvoice->getAmount());
  1507.                 $sheet->setCellValue('G' $row$invoice->getDueDate() ? $invoice->getDueDate()->format('Y-m-d') : "");
  1508.                 $sheet->setCellValue('H' $row$invoice->getXeroStatus());
  1509.                 $i++;
  1510.             }
  1511.         }
  1512.         $writer = new Xlsx($spreadsheet);
  1513.         $writer->save($filename);
  1514.         // Set the content-type:
  1515.         header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  1516.         header('Content-Length: ' filesize($filename));
  1517.         readfile($filename); // send file
  1518.         unlink($filename); // delete file
  1519.         exit;
  1520.     }
  1521.     #[Route(path'/project/export-list/{_target}'defaults: ['_target' => ''], name'export_project_list')]
  1522.     public function exportProjectList(string $_targetRequest $requestProjectService $projectService)
  1523.     {
  1524.         $keyword $request->get('keyword');
  1525.         $startDate $request->get('start');
  1526.         $endDate $request->get('end');
  1527.         $client $request->get('client');
  1528.         $status $request->get('status');
  1529.         $type $request->get('type');
  1530.         $retainer $request->get('retainer');
  1531.         $department $request->get('department');
  1532.         $project $request->get('project');
  1533.         $assignedUser $request->get('assignedUser');
  1534.         $pic $request->get('pic');
  1535.         $showDeleted false;
  1536.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  1537.         $user $this->getUser();
  1538.         $userRoles $user->getRoles();
  1539.         $isAdmin false;
  1540.         if ($this->isGranted('ROLE_MARCOM'$user->getRoles()) or $this->isGranted('ROLE_FINANCE'$user->getRoles())) {
  1541.             $isAdmin true;
  1542.         }
  1543.         if($type == 'LEAD'){
  1544.             return $projectService->exportProjectLead($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$_target);
  1545.             
  1546.         }elseif($type == 'CONFIRMED'){
  1547.             return $projectService->exportProjectConfirmed($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$_target);
  1548.         }else{
  1549.             return $projectService->exportProjectInternal($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$_target);
  1550.         }
  1551.     }
  1552.     #[Route(path'/project/export-list-monthly/{_target}'defaults: ['_target' => ''], name'export_project_list_monthly')]
  1553.     public function exportProjectListMonthly(string $_targetProjectRepository $projectRepositoryProjectAllocatedHoursRepository $allocatedHoursRepositoryRequest $requestGoogleDriveService $googleDriveService)
  1554.     {
  1555.         $user $this->getUser();
  1556.         $userRoles $user->getRoles();
  1557.         // if ((!in_array("ROLE_HR", $userRoles)) && (!in_array("ROLE_FINANCE", $userRoles))) return new Response('You are not allowed to access this page!');
  1558.         if(!$this->isGranted("ROLE_FINANCE")) return new Response('You are not allowed to access this page!');
  1559.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  1560.         $month $request->get('month');
  1561.         $year $request->get('year');
  1562.         $monthlyStartDate = new \DateTimeImmutable($year '-' $month '-01');
  1563.         $monthlyEndDate $monthlyStartDate->modify('last day of this month');
  1564.         // get end of month date from year and month
  1565.         $monthYear date("MY"strtotime($monthlyStartDate->format("Y-m-d")));
  1566.         $keyword $request->get('keyword');
  1567.         $startDate $request->get('start');
  1568.         $endDate $request->get('end');
  1569.         $client $request->get('client');
  1570.         $status $request->get('status');
  1571.         $type $request->get('type');
  1572.         $retainer $request->get('retainer');
  1573.         $department $request->get('department');
  1574.         $project $request->get('project');
  1575.         $assignedUser null;
  1576.         $spreadsheet = new Spreadsheet();
  1577.         // WORKSHEET: Monthy Report
  1578.         //$monthlyReportSheet = $spreadsheet->getActiveSheet()->setTitle('MonthlyReport_'.\DateTime::createFromFormat('!m', $month)->format('M').$year);
  1579.         $monthlyReportSheet $spreadsheet->getActiveSheet()->setTitle('MonthlyReport_' \DateTime::createFromFormat('!m'$month)->format('M') . $year);
  1580.         //$monthlyReportSheet= new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, 'MonthlyReport_'.\DateTime::createFromFormat('!m', $month)->format('M').$year);
  1581.         //$spreadsheet->addSheet($monthlyReportSheet, 0);
  1582.         
  1583.         $monthlyReportSheet->getDefaultColumnDimension()->setWidth(25);
  1584.         $monthlyReportSheet->setCellValue('A1''ID');
  1585.         $monthlyReportSheet->setCellValue('B1''Client Name');
  1586.         $monthlyReportSheet->setCellValue('C1''Project Name');
  1587.         $monthlyReportSheet->setCellValue('D1''Project Status');
  1588.         $monthlyReportSheet->setCellValue('E1''Score');
  1589.         $monthlyReportSheet->setCellValue('F1''Project Type');
  1590.         $monthlyReportSheet->setCellValue('G1''Retainer');
  1591.         $monthlyReportSheet->setCellValue('H1''PIC');
  1592.         $monthlyReportSheet->setCellValue('I1''PIC Client');
  1593.         $monthlyReportSheet->setCellValue('J1''Plan File');
  1594.         $monthlyReportSheet->setCellValue('K1''Plan URL');
  1595.         $monthlyReportSheet->setCellValue('L1''Start Date');
  1596.         $monthlyReportSheet->setCellValue('M1''End Date');
  1597.         $monthlyReportSheet->setCellValue('N1''SO Number(s)');
  1598.         $monthlyReportSheet->setCellValue('O1''Invoice Number(s)');
  1599.         $monthlyReportSheet->setCellValue('P1''Estimated Project Billings USD');
  1600.         $monthlyReportSheet->setCellValue('Q1''Total SO USD');
  1601.         $monthlyReportSheet->setCellValue('R1''Total INV USD');
  1602.         $monthlyReportSheet->setCellValue('S1''Total Invoice Since Start USD');
  1603.         $monthlyReportSheet->setCellValue('T1''Total Invoice ' $monthYear .' USD');
  1604.         $monthlyReportSheet->setCellValue('U1''Est. Hours');
  1605.         $monthlyReportSheet->setCellValue('V1''Est. Hours Cost');
  1606.         $monthlyReportSheet->setCellValue('W1''Planned Vendor Costs USD');
  1607.         $monthlyReportSheet->setCellValue('X1''Total Cost Budget USD');
  1608.         $monthlyReportSheet->setCellValue('Y1''Timesheets Hours Since Start');
  1609.         $monthlyReportSheet->setCellValue('Z1''Timesheets Cost Since Start USD');
  1610.         $monthlyReportSheet->setCellValue('AA1''Timesheets Hours ' $monthYear);
  1611.         $monthlyReportSheet->setCellValue('AB1''Timesheets Cost ' $monthYear ' USD');
  1612.         $monthlyReportSheet->setCellValue('AC1''Vendor Costs Since Start USD');
  1613.         $monthlyReportSheet->setCellValue('AD1''Vendor Costs ' $monthYear ' USD');
  1614.         $monthlyReportSheet->setCellValue('AE1''Total Cost Since Start USD');
  1615.         $monthlyReportSheet->setCellValue('AF1''Total Cost ' $monthYear ' USD');
  1616.         $monthlyReportSheet->getStyle("A1:".$monthlyReportSheet->getHighestColumn()."1")->getFont()->setBold(true);
  1617.         $monthlyReportSheet->getStyle("A1:".$monthlyReportSheet->getHighestColumn()."1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  1618.         $monthlyReportSheet->getStyle("A1:".$monthlyReportSheet->getHighestColumn()."1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  1619.         $monthlyReportSheet->getStyle("A2:".$monthlyReportSheet->getHighestColumn()."2")->getFont()->setBold(false);
  1620.         $monthlyReportSheet->getStyle("A2:".$monthlyReportSheet->getHighestColumn()."2")->getAlignment()->setWrapText(true);
  1621.         $monthlyReportSheet->getStyle("A2:".$monthlyReportSheet->getHighestColumn()."2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  1622.         $monthlyReportSheet->freezePane('A2');
  1623.         $monthlyReportSheet->getColumnDimension('F')->setWidth(10);
  1624.         $departmentName null;
  1625.         if ($department) {
  1626.             $departmentData $this->getDoctrine()->getRepository(Department::class)->find($department);
  1627.             if ($departmentData) {
  1628.                 $departmentName $departmentData->getName();
  1629.             };
  1630.         };
  1631.         $filename "Project_Monthly_Report_";
  1632.         $filename .= $month strtoupper(\DateTime::createFromFormat('!m'$month)->format('F')) : "";
  1633.         $filename .= $year "_" $year "";
  1634.         $filename .= $departmentName "-" urlencode($departmentName) : "";
  1635.         $filename .= $keyword "-" urlencode($keyword) : "";
  1636.         $filename .= $status "-" urlencode($status) : "";
  1637.         $filename .= $type "-" urlencode($type) : "";
  1638.         $filename .= $startDate "_" urlencode($startDate) : "";
  1639.         $filename .= $endDate "-" urlencode($endDate) : "";
  1640.         $filename .= '.xlsx';
  1641.         
  1642.         $projectsList $projectRepository->findByPage(09999$keyword"ASC"null$startDate$endDate$type$client$status$project$department$retainer$assignedUser);
  1643.         $n 0;
  1644.         foreach ($projectsList as $projectDetail) {
  1645.             $projectsList[$n]['cost'] = $projectDetail[0]->getProjectCost();
  1646.             $projectsList[$n]['profit'] = $projectDetail[0]->getProjectProfit1();
  1647.             $projectsList[$n]['leadStatusText'] = $projectDetail[0]->getLeadStatus() ? $projectDetail[0]->getLeadStatus()->getName() : null;
  1648.             $n++;
  1649.         };
  1650.         $row $monthlyReportSheet->getHighestRow();
  1651.         foreach ($projectsList as $project) {
  1652.             $picName $project['picMiddleName'] ? $project['picFirstName'] . ' ' $project['picMiddleName'] . ' ' $project['picLastName'] : $project['picFirstName'] . ' ' $project['picLastName'];
  1653.             $picClientName $project[0]->getClientPersonInCharge() ? $project[0]->getClientPersonInCharge()->getFirstName().' '.$project[0]->getClientPersonInCharge()->getLastName() : '-';
  1654.             //$monthlyReportSheet->insertNewRowBefore($row);
  1655.             $monthlyReportSheet->setCellValue('A' $row$project['generatedId']);
  1656.             $monthlyReportSheet->setCellValue('B' $row$project['clientName']);
  1657.             $monthlyReportSheet->setCellValue('C' $row$project['name']);
  1658.             $monthlyReportSheet->getCell('C' $row)->getHyperlink()->setUrl($baseurl '/project-management/project/view/' $project['id']);
  1659.             $monthlyReportSheet->setCellValue('D' $row$project['type'] == 'LEAD' $project['lead'] . ' - ' $project[0]->getLeadStatus()->getName() : ($project['status'] ? $project['status'] : '-'));
  1660.             $monthlyReportSheet->setCellValue('E' $row$project[0]->getScore());
  1661.             $monthlyReportSheet->setCellValue('F' $row$project['type']);
  1662.             $monthlyReportSheet->setCellValue('G' $row$project['retainer'] ? 'Yes' 'No');
  1663.             $monthlyReportSheet->setCellValue('H' $row$picName);
  1664.             $monthlyReportSheet->setCellValue('I' $row$picClientName);
  1665.             $monthlyReportSheet->setCellValue('J' $row$project['planFilename'] ? $project['planFilename'] : "-");
  1666.             if ($project['planFilename']) {
  1667.                 $monthlyReportSheet->getCell('J' $row)->getHyperlink()->setUrl($project['planFilepath']);
  1668.             }
  1669.             $monthlyReportSheet->setCellValue('K' $row$project['planURL'] ? $project['planURL'] : "-");
  1670.             if ($project['planURL']) {
  1671.                 $monthlyReportSheet->getCell('K' $row)->getHyperlink()->setUrl($project['planURL']);
  1672.             }
  1673.             $monthlyReportSheet->setCellValue('L' $row$project['startDate'] ? $project['startDate']->format('Y-m-d') : '-');
  1674.             $monthlyReportSheet->setCellValue('M' $row$project['endDate'] ? $project['endDate']->format('Y-m-d') : '-');
  1675.             $proSalesOrders $project[0]->getProjectSalesOrders();
  1676.             $proSales = [];
  1677.             $proSalesInvoices = [];
  1678.             foreach ($proSalesOrders as $so) {
  1679.                 array_push($proSales$so->getSalesOrder()->getSalesOrderNo());
  1680.                 $invoices $so->getSalesOrder()->getSalesOrderInvoices($project['id']);
  1681.                 foreach ($invoices as $invoice) {
  1682.                     array_push($proSalesInvoices$invoice->getInvoice()->getInvoiceNo());
  1683.                 }
  1684.             }
  1685.             $monthlyReportSheet->setCellValue('N' $rowimplode(', '$proSales));
  1686.             $monthlyReportSheet->setCellValue('O' $rowimplode(', '$proSalesInvoices));
  1687.             
  1688.             
  1689.             // $multiRow = $row;
  1690.             // $proSalesOrders = $project[0]->getProjectSalesOrders();
  1691.             // foreach ($proSalesOrders as $so){
  1692.             //     $monthlyReportSheet->setCellValue('J' . $multiRow, $so->getSalesOrder()->getSalesOrderNo());
  1693.             //     $invoices = $so->getSalesOrder()->getSalesOrderInvoices();
  1694.             //     $multiMultiRow = $multiRow;
  1695.             //     foreach($invoices as $invoice){
  1696.             //         $monthlyReportSheet->setCellValue('K' . $multiMultiRow, $invoice->getInvoice()->getInvoiceNo());
  1697.             //         $multiMultiRow++;
  1698.             //     }
  1699.             //     $multiRow = $multiMultiRow;
  1700.             // }
  1701.             
  1702.             if ($project['type'] == 'INTERNAL') {
  1703.                 $monthlyReportSheet->setCellValue('P' $row'-');
  1704.             } else {
  1705.                 //$monthlyReportSheet->setCellValue('L' . $row, $project['type'] == 'LEAD' ? $project['estimatedProfit'] : $project['plannedRevenue']);
  1706.                 // $monthlyReportSheet->setCellValue('M' . $row, $project['type'] == 'LEAD' ? $project[0]->getEstimatedProfitUsd() : $project[0]->getPlannedRevenueUsd());
  1707.                 $monthlyReportSheet->setCellValue('P' $row$project[0]->getPlannedRevenueUsd());
  1708.             }
  1709.             $monthlyReportSheet->setCellValue('Q' $row$project[0]->getSoTotalUsd());
  1710.             $monthlyReportSheet->setCellValue('R' $row$project[0]->getInvoicesTotalUsd());
  1711.             $resourceAllocations $allocatedHoursRepository->findByProject(''''$project['id']);
  1712.             $totalEstimatedProjectHours 0;
  1713.             $totalEstProjectHoursCost 0;
  1714.             foreach ($resourceAllocations as $allocation) {
  1715.                 $totalEstimatedProjectHours += intval($allocation->getHours());
  1716.                 $totalEstProjectHoursCost += intval($allocation->getHours() * $allocation->getUserRole()->getCost());
  1717.             }
  1718.             $estimatedProjectHours = !empty($totalEstimatedProjectHours) ? $totalEstimatedProjectHours '0';
  1719.             $estimatedProjectHoursCost = !empty($totalEstProjectHoursCost) ? $totalEstProjectHoursCost '0';
  1720.             $totalCostBudget = (!empty($totalEstProjectHoursCost) ? $totalEstProjectHoursCost 0) + $project[0]->getVendorPlannedTotalUsd();
  1721.             $totalInvoiceSinceStart $project[0]->getInvoicesTotalUsd($monthlyEndDate);
  1722.             $totalInvoiceMonthly $project[0]->getInvoicesTotalUsdByMonth($monthlyStartDate$monthlyEndDate);
  1723.             $recordCost $project[0]->getProjectManhourCost($monthlyEndDate);
  1724.             $recordMonthlyCost $project[0]->getProjectManhourCostByMonth($monthlyStartDate$monthlyEndDate);
  1725.             $totalCostSinceStart $recordCost $project[0]->getVendorInvoicesTotalUsd();
  1726.             $monthlyReportSheet->setCellValue('S' $row$totalInvoiceSinceStart);
  1727.             $monthlyReportSheet->setCellValue('T' $row$totalInvoiceMonthly);
  1728.             $monthlyReportSheet->setCellValue('U' $row$estimatedProjectHours);
  1729.             $monthlyReportSheet->setCellValue('V' $row$estimatedProjectHoursCost);
  1730.             $monthlyReportSheet->setCellValue('W' $row$project[0]->getVendorPlannedTotalUsd());        
  1731.             $monthlyReportSheet->setCellValue('X' $row$totalCostBudget);
  1732.             $monthlyReportSheet->setCellValue('Y' $row$project[0]->getProjectManhour($monthlyEndDate));               
  1733.             $monthlyReportSheet->setCellValue('Z' $row$recordCost);
  1734.             $monthlyReportSheet->setCellValue('AA' $row$project[0]->getProjectManhourByMonth($monthlyStartDate$monthlyEndDate));
  1735.             $monthlyReportSheet->setCellValue('AB' $row$recordMonthlyCost);
  1736.             $monthlyReportSheet->setCellValue('AC' $row$project[0]->getVendorInvoicesTotalUsd($monthlyEndDate));
  1737.             $monthlyReportSheet->setCellValue('AD' $row$project[0]->getVendorInvoicesTotalUsdByMonth($monthlyStartDate$monthlyEndDate));
  1738.             $monthlyReportSheet->setCellValue('AE' $row$totalCostSinceStart);
  1739.             $monthlyReportSheet->setCellValue('AF' $row$recordMonthlyCost $project[0]->getVendorInvoicesTotalUsdByMonth($monthlyStartDate$monthlyEndDate));
  1740.             $row++;
  1741.         }
  1742.         $monthlyReportSheet->setAutoFilter('A1:AE' $monthlyReportSheet->getHighestRow());
  1743.         $monthlyReportSheet->getStyle("C1:C" $monthlyReportSheet->getHighestRow())->getFont()->setUnderline(true);
  1744.         // $monthlyReportSheet->getStyle('O2:S' . $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1745.         // $monthlyReportSheet->getStyle('U2:W' . $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1746.         // $monthlyReportSheet->getStyle('Y2:Y' . $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1747.         // $monthlyReportSheet->getStyle('AA2:AE' . $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1748.         
  1749.         $monthlyReportSheet->getStyle('P2:T' $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1750.         $monthlyReportSheet->getStyle('V2:X' $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1751.         $monthlyReportSheet->getStyle('Z2:Z' $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1752.         $monthlyReportSheet->getStyle('AB2:AD' $monthlyReportSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1753.         /*
  1754.         $monthlyReportSheet->getStyle('L2:M'. $monthlyReportSheet->getHighestRow())->getNumberFormat()
  1755.         ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
  1756.         $monthlyReportSheet->getStyle('O2:V'. $monthlyReportSheet->getHighestRow())->getNumberFormat()
  1757.         ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
  1758.         */
  1759.         // WORKSHEET: Detail Vendor Invoice (id, project name, vendor name, vendor invoice date, vendor invoice number, allocated amount)
  1760.         $detailVendorInvoiceSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet'Detail-VendorInvoices');
  1761.         $spreadsheet->addSheet($detailVendorInvoiceSheet1);
  1762.         $detailVendorInvoiceSheet->getDefaultColumnDimension()->setWidth(35);
  1763.         $detailVendorInvoiceSheet->setCellValue('A1''ID');
  1764.         $detailVendorInvoiceSheet->setCellValue('B1''Project Name');
  1765.         $detailVendorInvoiceSheet->setCellValue('C1''Vendor Name');
  1766.         $detailVendorInvoiceSheet->setCellValue('D1''Vendor Invoice Date');
  1767.         $detailVendorInvoiceSheet->setCellValue('E1''Vendor Invoice Number');
  1768.         $detailVendorInvoiceSheet->setCellValue('F1''Allocated Amount');
  1769.         // $detailVendorInvoiceSheet->setCellValue('G1', 'Paid Amount');
  1770.         // $detailVendorInvoiceSheet->setCellValue('H1', 'Paid Date');
  1771.         //set style of spreadsheet header
  1772.         $detailVendorInvoiceSheet->getStyle("A1:F1")->getFont()->setBold(true);
  1773.         $detailVendorInvoiceSheet->getStyle("A1:F1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  1774.         $detailVendorInvoiceSheet->getStyle("A1:F1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  1775.         $detailVendorInvoiceSheet->getStyle("A2:F2")->getFont()->setBold(false);
  1776.         $detailVendorInvoiceSheet->getStyle("A2:F2")->getAlignment()->setWrapText(true);
  1777.         $detailVendorInvoiceSheet->getStyle("A2:F2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  1778.         $detailVendorInvoiceSheet->freezePane('A2');
  1779.         $row 2;
  1780.         $vendorInvoiceIds = [];
  1781.         foreach ($projectsList as $project) {
  1782.             foreach ($project[0]->getVendorQuotationPlannings() as $vendorQuotationPlanning) {
  1783.                 $vqpInvoices $vendorQuotationPlanning->getVendorQuotationPlanningVendorInvoices();
  1784.                 foreach ($vqpInvoices as $vqpInvoice) {
  1785.                     $vendorInvoice $vqpInvoice->getVendorInvoice();
  1786.                     if ($vendorInvoice->getXeroStatus() === "PAID" && !in_array($vendorInvoice->getId(), $vendorInvoiceIds)) {
  1787.                         array_push($vendorInvoiceIds$vendorInvoice->getId());
  1788.                         $detailVendorInvoiceSheet->setCellValue('A' $row$project['generatedId']);
  1789.                         $detailVendorInvoiceSheet->setCellValue('B' $row$project[0]->getName());
  1790.                         $detailVendorInvoiceSheet->setCellValue('C' $row$vendorQuotationPlanning->getVendor()->getName());
  1791.                         $detailVendorInvoiceSheet->setCellValue('D' $row$vendorInvoice->getInvoiceDate()->format('d/m/Y'));
  1792.                         $detailVendorInvoiceSheet->setCellValue('E' $row$vendorInvoice->getInvoiceNo());
  1793.                         $detailVendorInvoiceSheet->setCellValue('F' $row$vendorInvoice->getSubTotalUsd());
  1794.                         // $detailVendorInvoiceSheet->setCellValue('G' . $row, $vendorInvoice->getPaidAmount());
  1795.                         // $detailVendorInvoiceSheet->setCellValue('H' . $row, $vendorInvoice->getPaidDate() ? $vendorInvoice->getPaidDate()->format('d/m/Y') : '');
  1796.                         $row++;
  1797.                     };
  1798.                 }
  1799.             }
  1800.         }
  1801.         $detailVendorInvoiceSheet->setAutoFilter('A1:F' $detailVendorInvoiceSheet->getHighestRow());
  1802.         // $detailVendorInvoiceSheet->getStyle('F2:F' . $detailVendorInvoiceSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1803.         $detailVendorInvoiceSheet->getStyle('F2:F' $detailVendorInvoiceSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1804.         // WORKSHEET: Detail Timesheet per project (id, project name, date, name, hours, task, hours spent, cost/hour cost)
  1805.         $detailTimesheetSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet'Detail-Timesheets');
  1806.         $spreadsheet->addSheet($detailTimesheetSheet2);
  1807.         $detailTimesheetSheet->getDefaultColumnDimension()->setWidth(25);
  1808.         $detailTimesheetSheet->setCellValue('A1''ID');
  1809.         $detailTimesheetSheet->setCellValue('B1''Project Name');
  1810.         $detailTimesheetSheet->setCellValue('C1''Date');
  1811.         $detailTimesheetSheet->setCellValue('D1''Name');
  1812.         $detailTimesheetSheet->setCellValue('E1''Task');
  1813.         $detailTimesheetSheet->setCellValue('F1''Hours Spent');
  1814.         $detailTimesheetSheet->setCellValue('G1''Hourly Cost');
  1815.         $detailTimesheetSheet->setCellValue('H1''Total Cost');
  1816.         //set style of spreadsheet header
  1817.         $detailTimesheetSheet->getStyle("A1:H1")->getFont()->setBold(true);
  1818.         $detailTimesheetSheet->getStyle("A1:H1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  1819.         $detailTimesheetSheet->getStyle("A1:H1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  1820.         $detailTimesheetSheet->getStyle("A2:H2")->getFont()->setBold(false);
  1821.         $detailTimesheetSheet->getStyle("A2:H2")->getAlignment()->setWrapText(true);
  1822.         $detailTimesheetSheet->getStyle("A2:H2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  1823.         $detailTimesheetSheet->freezePane('A2');
  1824.         $row 2;
  1825.         foreach ($projectsList as $project) {
  1826.             foreach ($project[0]->getTasks() as $task) {
  1827.                 $timeSpents $task->getTimeSpents();
  1828.                 foreach ($timeSpents as $timeSpent) {
  1829.                     $detailTimesheetSheet->setCellValue('A' $row$project['generatedId']);
  1830.                     $detailTimesheetSheet->setCellValue('B' $row$project[0]->getName());
  1831.                     $detailTimesheetSheet->setCellValue('C' $row$timeSpent->getDate()->format('d/m/Y'));
  1832.                     $detailTimesheetSheet->setCellValue('D' $row$task->getUser()->getPersonalInfo()->getFullName());
  1833.                     $detailTimesheetSheet->setCellValue('E' $row$task->getTaskType()->getName());
  1834.                     $detailTimesheetSheet->setCellValue('F' $row$timeSpent->getHours());
  1835.                     $detailTimesheetSheet->setCellValue('G' $row$timeSpent->getUser()->getHourlyRate());
  1836.                     $detailTimesheetSheet->setCellValue('H' $row$timeSpent->getUser()->getHourlyRate() * $timeSpent->getHours());
  1837.                     $row++;
  1838.                 }
  1839.             }
  1840.         }
  1841.         // $detailTimesheetSheet->getStyle('G2:H' . $detailTimesheetSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1842.         $detailTimesheetSheet->getStyle('G2:H' $detailTimesheetSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1843.         
  1844.         $detailTimesheetSheet->setAutoFilter('A1:H' $detailTimesheetSheet->getHighestRow());
  1845.     
  1846.         $spreadsheet->setActiveSheetIndex(0);
  1847.         // Write the file
  1848.         $writer = new Xlsx($spreadsheet);
  1849.         $writer->save($filename);
  1850.         if($_target == 'google'){
  1851.             $gsheetURL $googleDriveService->uploadToGoogleDrive($filename);
  1852.             if($gsheetURL){
  1853.                 unlink($filename);
  1854.                 return new RedirectResponse($gsheetURL302);
  1855.             }
  1856.         }else{
  1857.             $response = new Response();
  1858.             $response->headers->set('Content-type''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  1859.             $response->headers->set('Content-Disposition'sprintf('attachment; filename="%s"'$filename));
  1860.             $response->setContent(file_get_contents($filename));
  1861.             $response->setStatusCode(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
  1862.             $response->headers->set('Content-Transfer-Encoding''binary');
  1863.             $response->headers->set('Pragma''no-cache');
  1864.             $response->headers->set('Expires''0');
  1865.             unlink($filename);
  1866.             return $response;
  1867.             exit;
  1868.         }  
  1869.     }
  1870.     #[Route(path'/project/export-sales-pipeline/{_target}'defaults: ['_target' => ''], name'export_project_sales_pipeline')]
  1871.     public function exportProjectSalesPipeline(string $_targetTranslatorInterface $translatorProjectRepository $projectRepositoryTimeSpentRepository $timeSpentRepositoryUserRepository $userRepositoryProjectAllocatedHoursRepository $allocatedHoursRepositoryRequest $requestGoogleDriveService $googleDriveService)
  1872.     {
  1873.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  1874.     
  1875.         $keyword $request->get('keyword');
  1876.         // $startDate = $request->get('start') ?: date("Y-m-d", strtotime('monday -3 week'));
  1877.         $startDate $request->get('start') ?: date("Y-m-d"strtotime('monday this week'));
  1878.         $endDate $request->get('end') ?: date("Y-m-d"strtotime('sunday this week'));
  1879.         $startDateRange '';
  1880.         $endDateRange '';
  1881.         if (strpos($startDate'/') !== false) {
  1882.             $startDate str_replace('/''-'$startDate);
  1883.             $startDate date("Y-m-d"strtotime($startDate));
  1884.             $startDateRange date("d-M-Y"strtotime($startDate));
  1885.         } 
  1886.         if (strpos($endDate'/') !== false) {
  1887.             $endDate str_replace('/''-'$endDate);
  1888.             $endDate date("Y-m-d"strtotime($endDate));
  1889.             $endDateRange date("d-M-Y"strtotime($endDate));
  1890.         } 
  1891.         
  1892.         $client $request->get('client');
  1893.         $status $request->get('status');
  1894.         $type $request->get('type');
  1895.         $retainer $request->get('retainer');
  1896.         $department $request->get('department');
  1897.         $project $request->get('project');
  1898.         $assignedUser null;
  1899.         $user $this->getUser();
  1900.         $userRoles $user->getRoles();
  1901.         $spreadsheet = new Spreadsheet();
  1902.         // WORKSHEET: PERIOD - OVERVIEW
  1903.         
  1904.         $salesPipelineOverviewSheet $spreadsheet->getActiveSheet()->setTitle('PERIOD-OVERVIEW');
  1905.         $salesPipelineOverviewSheet->getColumnDimension('A')->setWidth(50);
  1906.         $salesPipelineOverviewSheet->setCellValue('A1''OVERVIEW OF THE PERIOD');
  1907.         $salesPipelineOverviewSheet->setCellValue('A2''From');
  1908.         $salesPipelineOverviewSheet->setCellValue('A3''To');
  1909.         $salesPipelineOverviewSheet->getStyle("A1:A3")->getFont()->setBold(true);
  1910.         $salesPipelineOverviewSheet->setCellValue('A5''NEW LEADS');
  1911.         $salesPipelineOverviewSheet->getStyle("A5")->getFont()->setBold(true);
  1912.         $salesPipelineOverviewSheet->setCellValue('A6''# of leads during that Period');
  1913.         
  1914.         $salesPipelineOverviewSheet->setCellValue('A8''PROPOSALS SENT');
  1915.         $salesPipelineOverviewSheet->getStyle("A8")->getFont()->setBold(true);
  1916.         $salesPipelineOverviewSheet->setCellValue('A9''# of proposals sent during that Period');
  1917.         $salesPipelineOverviewSheet->setCellValue('A10''Total revenue of proposals sent during that Period');
  1918.         $salesPipelineOverviewSheet->setCellValue('A11''Total 3rd party cost of proposals sent during that Period');
  1919.         $salesPipelineOverviewSheet->setCellValue('A12''Total profit of proposals sent during that Period');
  1920.         $salesPipelineOverviewSheet->setCellValue('A14''HOT LEADS');
  1921.         $salesPipelineOverviewSheet->getStyle("A14")->getFont()->setBold(true);
  1922.         $salesPipelineOverviewSheet->setCellValue('A15''# of proposals with a win probability % Above 80%');
  1923.         $salesPipelineOverviewSheet->setCellValue('A16''Revenue');
  1924.         $salesPipelineOverviewSheet->setCellValue('A17''3rd party cost');
  1925.         $salesPipelineOverviewSheet->setCellValue('A18''Profit');
  1926.         $salesPipelineOverviewSheet->setCellValue('A20''# of proposals with a win probability  % between 50% to 80%');
  1927.         $salesPipelineOverviewSheet->setCellValue('A21''Revenue');
  1928.         $salesPipelineOverviewSheet->setCellValue('A22''3rd party cost');
  1929.         $salesPipelineOverviewSheet->setCellValue('A23''Profit');
  1930.         $salesPipelineOverviewSheet->setCellValue('A25''# of proposals with a win probability  % below 50%');
  1931.         $salesPipelineOverviewSheet->setCellValue('A26''Revenue');
  1932.         $salesPipelineOverviewSheet->setCellValue('A27''3rd party cost');
  1933.         $salesPipelineOverviewSheet->setCellValue('A28''Profit');
  1934.         $salesPipelineOverviewSheet->setCellValue('A30''PROJECTS WON');
  1935.         $salesPipelineOverviewSheet->getStyle("A30")->getFont()->setBold(true);
  1936.         $salesPipelineOverviewSheet->setCellValue('A31''# of WINS during that Period');
  1937.         $salesPipelineOverviewSheet->setCellValue('A32''Total revenue of WON projects during that Period');
  1938.         $salesPipelineOverviewSheet->setCellValue('A33''Total 3rd party cost of WON project during that Period');
  1939.         $salesPipelineOverviewSheet->setCellValue('A34''Total profit of WON projects during that Period');
  1940.         $salesPipelineOverviewSheet->setCellValue('A36''PROJECTS LOST');
  1941.         $salesPipelineOverviewSheet->getStyle("A36")->getFont()->setBold(true);
  1942.         $salesPipelineOverviewSheet->setCellValue('A37''# of LOST during that Period ');
  1943.         $salesPipelineOverviewSheet->setCellValue('A38''Total revenue of LOST projects during that Period');
  1944.         $salesPipelineOverviewSheet->setCellValue('A39''Total 3rd party cost of LOST project during that Period');
  1945.         $salesPipelineOverviewSheet->setCellValue('A40''Total profit of LOST projects during that Period');
  1946.         $salesPipelineOverviewSheet->getColumnDimension('B')->setWidth(50);
  1947.         $newLead $projectRepository->findNewLeadOverview($startDate$endDate);
  1948.         $proposalSent $projectRepository->findProposalSentOverview($startDate$endDate);
  1949.         $hotLeadAbove80 $projectRepository->findHotLeadOverviewAbove80($startDate$endDate);
  1950.         $hotLeadBetween50to80 $projectRepository->findHotLeadOverviewBetween50to80($startDate$endDate);
  1951.         $hotLeadUnder50 $projectRepository->findHotLeadOverviewUnder50($startDate$endDate);
  1952.         $projectWon $projectRepository->findProjectWonOverview($startDate$endDate);
  1953.         $projectLost $projectRepository->findProjectLostOverview($startDate$endDate);
  1954.         
  1955.         $salesPipelineOverviewSheet->setCellValue('B2'$startDateRange);
  1956.         $salesPipelineOverviewSheet->setCellValue('B3'$endDateRange);
  1957.         $salesPipelineOverviewSheet->getStyle("B2:B3")->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT);
  1958.         $salesPipelineOverviewSheet->setCellValue('B6'$newLead);
  1959.         
  1960.         $salesPipelineOverviewSheet->setCellValue('B9'$proposalSent $proposalSent[0]['projectCount'] : 0);
  1961.         $salesPipelineOverviewSheet->setCellValue('B10'$proposalSent $proposalSent[0]['plannedRevenue'] : 0);
  1962.         $salesPipelineOverviewSheet->setCellValue('B11'$proposalSent $proposalSent[0]['estimatedVendorCost'] : 0);
  1963.         $salesPipelineOverviewSheet->setCellValue('B12'$proposalSent $proposalSent[0]['estimatedMargin'] : 0);
  1964.         // $salesPipelineOverviewSheet->getStyle('B10:B12')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1965.         $salesPipelineOverviewSheet->getStyle('B10:B12')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1966.         
  1967.         $salesPipelineOverviewSheet->setCellValue('B15'$hotLeadAbove80 $hotLeadAbove80[0]['projectCount'] : 0);
  1968.         $salesPipelineOverviewSheet->setCellValue('B16'$hotLeadAbove80 ? ($hotLeadAbove80[0]['plannedRevenue'] ?: 0): 0);
  1969.         $salesPipelineOverviewSheet->setCellValue('B17'$hotLeadAbove80 ? ($hotLeadAbove80[0]['estimatedVendorCost']?: 0): 0);
  1970.         $salesPipelineOverviewSheet->setCellValue('B18'$hotLeadAbove80 ? ($hotLeadAbove80[0]['estimatedMargin']?: 0): 0);
  1971.         // $salesPipelineOverviewSheet->getStyle('B16:B18')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1972.         $salesPipelineOverviewSheet->getStyle('B16:B18')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1973.         $salesPipelineOverviewSheet->setCellValue('B20'$hotLeadBetween50to80 $hotLeadBetween50to80[0]['projectCount']: 0);
  1974.         $salesPipelineOverviewSheet->setCellValue('B21'$hotLeadBetween50to80 ? ($hotLeadBetween50to80[0]['plannedRevenue']?: 0): 0);
  1975.         $salesPipelineOverviewSheet->setCellValue('B22'$hotLeadBetween50to80 ? ($hotLeadBetween50to80[0]['estimatedVendorCost']?: 0): 0);
  1976.         $salesPipelineOverviewSheet->setCellValue('B23'$hotLeadBetween50to80 ? ($hotLeadBetween50to80[0]['estimatedMargin']?: 0): 0);
  1977.         
  1978.         // $salesPipelineOverviewSheet->getStyle('B21:B23')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1979.         $salesPipelineOverviewSheet->getStyle('B21:B23')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1980.         $salesPipelineOverviewSheet->setCellValue('B25'$hotLeadUnder50 $hotLeadUnder50[0]['projectCount']: 0);
  1981.         $salesPipelineOverviewSheet->setCellValue('B26'$hotLeadUnder50 ? ($hotLeadUnder50[0]['plannedRevenue']?: 0): 0);
  1982.         $salesPipelineOverviewSheet->setCellValue('B27'$hotLeadUnder50 ? ($hotLeadUnder50[0]['estimatedVendorCost']?: 0): 0);
  1983.         $salesPipelineOverviewSheet->setCellValue('B28'$hotLeadUnder50 ? ($hotLeadUnder50[0]['estimatedMargin']?: 0): 0);
  1984.         // $salesPipelineOverviewSheet->getStyle('B26:B28')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1985.         $salesPipelineOverviewSheet->getStyle('B26:B28')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1986.         $salesPipelineOverviewSheet->setCellValue('B31'$projectWon $projectWon[0]['projectCount'] : 0);
  1987.         $salesPipelineOverviewSheet->setCellValue('B32'$projectWon $projectWon[0]['plannedRevenue'] : 0);
  1988.         $salesPipelineOverviewSheet->setCellValue('B33'$projectWon $projectWon[0]['estimatedVendorCost'] : 0);
  1989.         $salesPipelineOverviewSheet->setCellValue('B34'$projectWon $projectWon[0]['estimatedMargin'] : 0);
  1990.         // $salesPipelineOverviewSheet->getStyle('B32:B34')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1991.         $salesPipelineOverviewSheet->getStyle('B32:B34')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1992.         $salesPipelineOverviewSheet->setCellValue('B37'$projectLost $projectLost[0]['projectCount'] : 0);
  1993.         $salesPipelineOverviewSheet->setCellValue('B38'$projectLost ? (is_null($projectLost[0]['plannedRevenue'])? 0$projectLost[0]['plannedRevenue']) : 0);
  1994.         $salesPipelineOverviewSheet->setCellValue('B39'$projectLost ? (is_null($projectLost[0]['estimatedVendorCost'])? 0$projectLost[0]['estimatedVendorCost']) : 0);
  1995.         $salesPipelineOverviewSheet->setCellValue('B40'$projectLost ? (is_null($projectLost[0]['estimatedMargin'])? 0$projectLost[0]['estimatedMargin']) : 0);
  1996.         // $salesPipelineOverviewSheet->getStyle('B38:B40')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  1997.         $salesPipelineOverviewSheet->getStyle('B38:B40')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  1998.         if($_SERVER['APP_ENV'] != "prod"){
  1999.             $salesPipelineOverviewSheet->setCellValue('D6''[leadDate in date range]');
  2000.             $salesPipelineOverviewSheet->setCellValue('D9''[sentDate in date range]');
  2001.             $salesPipelineOverviewSheet->setCellValue('D15''[sentDate in date range and % Above 80% where sentDate != winDate and lead != 8]');
  2002.             $salesPipelineOverviewSheet->setCellValue('D20''[sentDate in date range and % between 50% to 80% where sentDate != winDate and lead != 8]');
  2003.             $salesPipelineOverviewSheet->setCellValue('D25''[sentDate in date range and % below 50% where sentDate != winDate and lead != 8]');
  2004.             $salesPipelineOverviewSheet->setCellValue('D31''[winDate in date range and lead = 8 (Won)]');
  2005.             $salesPipelineOverviewSheet->setCellValue('D37''[leadFailDate in date range and lead = 9 (Lost)]');
  2006.         }
  2007.         $filename "Sales_Pipeline_Report";
  2008.         $filename .= $startDate "_" urlencode($startDate) : "";
  2009.         $filename .= $endDate "-" urlencode($endDate) : "";
  2010.         $filename .= $startDate '.xlsx' "_" date('Y-m-d') . '.xlsx';
  2011.         // WORKSHEET: Detail Sales Pipeline
  2012.         $detailSheet = ['allLeadSheet' => 'PERIOD-ALL LEADS''allSentSheet' => 'PERIOD-ALL SENT''allWinSheet' => 'PERIOD-ALL WIN''allLostSheet' => 'PERIOD-ALL LOST'];
  2013.         $sheetIdx 1;
  2014.         foreach($detailSheet as $varSheet => $descSheet){
  2015.             ${$varSheet} = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet$descSheet);
  2016.             $spreadsheet->addSheet(${$varSheet}, $sheetIdx);
  2017.             $sheetIdx++;
  2018.         }
  2019.         foreach($detailSheet as $varSheet => $descSheet){
  2020.             ${$varSheet}->getDefaultColumnDimension()->setWidth(20);
  2021.             ${$varSheet}->getColumnDimension('B')->setWidth(35);
  2022.             ${$varSheet}->getColumnDimension('C')->setWidth(35);
  2023.             ${$varSheet}->getColumnDimension('I')->setWidth(30);
  2024.             ${$varSheet}->getColumnDimension('J')->setWidth(35);
  2025.             ${$varSheet}->getColumnDimension('L')->setWidth(35);
  2026.             ${$varSheet}->setCellValue('A1''ID');
  2027.             ${$varSheet}->setCellValue('B1''Client Name');
  2028.             ${$varSheet}->setCellValue('C1''Project Name');
  2029.             ${$varSheet}->setCellValue('D1''Estimated Project Billings (USD)');
  2030.             ${$varSheet}->setCellValue('E1''Total 3rd Party Cost (USD)');
  2031.             ${$varSheet}->setCellValue('F1''Total Profit (USD)');
  2032.             ${$varSheet}->setCellValue('G1''New Lead Date (DDMMYYYY)');
  2033.             ${$varSheet}->setCellValue('H1''Sent Date (DDMMYYYY)');
  2034.             ${$varSheet}->setCellValue('I1''Win Date (DDMMYYYY)');
  2035.             ${$varSheet}->setCellValue('J1''Lost Date (DDMMYYYY)');
  2036.             ${$varSheet}->setCellValue('K1''Project Status');
  2037.             ${$varSheet}->setCellValue('L1''PIC');
  2038.             ${$varSheet}->setCellValue('M1''Description');
  2039.             ${$varSheet}->setCellValue('N1''% Likely To Win');
  2040.             $lastCol 'N';
  2041.             if($varSheet == 'allLostSheet'){
  2042.                 ${$varSheet}->setCellValue('O1''Lost Reason');
  2043.                 $lastCol 'O';
  2044.             }
  2045.             ${$varSheet}->getStyle("A1:".$lastCol."1")->getFont()->setBold(true);
  2046.             ${$varSheet}->getStyle("A1:".$lastCol."1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2047.             ${$varSheet}->getStyle("A1:".$lastCol."1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2048.             ${$varSheet}->getStyle("A2:".$lastCol."2")->getFont()->setBold(false);
  2049.             ${$varSheet}->getStyle("A2:".$lastCol."2")->getAlignment()->setWrapText(true);
  2050.             ${$varSheet}->getStyle("A2:".$lastCol."2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  2051.             /*
  2052.             if($_SERVER['APP_ENV'] != "prod"){
  2053.             ${$varSheet}->setCellValue('N1', 'Type (temporary)');
  2054.             ${$varSheet}->setCellValue('O1', 'FROM');
  2055.             }
  2056.             //set style of spreadsheet header
  2057.             if($_SERVER['APP_ENV'] != "prod"){
  2058.                 ${$varSheet}->getStyle("A1:O1")->getFont()->setBold(true);
  2059.                 ${$varSheet}->getStyle("A1:O1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2060.                 ${$varSheet}->getStyle("A1:O1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2061.                 ${$varSheet}->getStyle("A2:O2")->getFont()->setBold(false);
  2062.                 ${$varSheet}->getStyle("A2:O2")->getAlignment()->setWrapText(true);
  2063.                 ${$varSheet}->getStyle("A2:O2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  2064.             }else{
  2065.                 ${$varSheet}->getStyle("A1:M1")->getFont()->setBold(true);
  2066.                 ${$varSheet}->getStyle("A1:M1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2067.                 ${$varSheet}->getStyle("A1:M1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2068.                 ${$varSheet}->getStyle("A2:M2")->getFont()->setBold(false);
  2069.                 ${$varSheet}->getStyle("A2:M2")->getAlignment()->setWrapText(true);
  2070.                 ${$varSheet}->getStyle("A2:M2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  2071.             }
  2072.             */
  2073.         }
  2074.         $leadStatus = [
  2075.             => 'Lead',
  2076.             => 'First discussion',
  2077.             => 'Brief received',
  2078.             => 'Work on proposal or quote',
  2079.             => 'Proposal sent -> to follow up',
  2080.             => 'Verbally Accepted',
  2081.             => 'Work on Contract',
  2082.             => 'Won (Contract or Quote signed)',
  2083.             => 'Lost',
  2084.             91 => 'Lost / No answer',
  2085.             92 => 'No go / Closed'
  2086.         ];
  2087.         
  2088.         // $detailSales = [];
  2089.         $newLeads $projectRepository->findNewLead($startDate$endDate);
  2090.         $proposalSents $projectRepository->findProposalSent($startDate$endDate);
  2091.         $projectWons $projectRepository->findProjectWon($startDate$endDate);
  2092.         $projectLosts $projectRepository->findProjectLost($startDate$endDate);
  2093.         $contentSheets = ['allLeadSheet' => 'newLeads''allSentSheet' => 'proposalSents''allWinSheet' => 'projectWons''allLostSheet' => 'projectLosts'];
  2094.         foreach($detailSheet as $varSheet => $descSheet){
  2095.             $row 2;
  2096.             foreach(${$contentSheets[$varSheet]} as $salePipeline){
  2097.                 ${$varSheet}->setCellValue('A'.$row$salePipeline['generatedId']);
  2098.                 ${$varSheet}->setCellValue('B'.$row$salePipeline['clientName']);
  2099.                 ${$varSheet}->setCellValue('C'.$row$salePipeline['name']);
  2100.                 ${$varSheet}->setCellValue('D'.$row$salePipeline[0]->getPlannedRevenueUsd());
  2101.                 ${$varSheet}->setCellValue('E'.$row$salePipeline[0]->getEstimatedVendorCostUsd());
  2102.                 ${$varSheet}->setCellValue('F'.$row$salePipeline[0]->getEstimatedProfitUsd());
  2103.                 ${$varSheet}->setCellValue('G'.$row$salePipeline['leadDate'] ? $salePipeline['leadDate']->format("d-m-Y"): '');
  2104.                 ${$varSheet}->setCellValue('H'.$row$salePipeline[0]->getProposalDate() ? $salePipeline[0]->getProposalDate()->format("d-m-Y") : '');
  2105.                 ${$varSheet}->setCellValue('I'.$row$salePipeline[0]->getWinDate() ? $salePipeline[0]->getWinDate()->format("d-m-Y") : '');
  2106.                 ${$varSheet}->setCellValue('J'.$row$salePipeline[0]->getLeadFailDate() ? $salePipeline[0]->getLeadFailDate()->format("d-m-Y") : '');
  2107.                 ${$varSheet}->setCellValue('K'.$row$salePipeline['lead'].' - '.$leadStatus[$salePipeline['lead']]);
  2108.                 ${$varSheet}->setCellValue('L'.$row$salePipeline['picFirstName'].' '.$salePipeline['picMiddleName'].' '.$salePipeline['picLastName']);
  2109.                 ${$varSheet}->setCellValue('M'.$row$salePipeline[0]->getDescription());
  2110.                 ${$varSheet}->setCellValue('N'.$row$salePipeline[0]->getProbabilityText());
  2111.                 if($varSheet == 'allLostSheet'){
  2112.                     $leadFailText $salePipeline[0]->getLeadFail() ? $salePipeline[0]->getLeadFail()->getTitle() : null;
  2113.                     $leadFailReason $salePipeline[0]->getLeadFailNote() ?: null;
  2114.                     $leadFailShow $leadFailText.($leadFailReason ': '.$leadFailReason '');
  2115.                     // ${$varSheet}->setCellValue('O'.$row, $salePipeline[0]->getLeadFailNote());
  2116.                     ${$varSheet}->setCellValue('O'.$row$salePipeline[0]->getLeadLostReason());
  2117.                 }
  2118.                 // if($_SERVER['APP_ENV'] != "prod"){
  2119.                 // ${$varSheet}->setCellValue('N'.$row, $salePipeline[0]->getType());
  2120.                 // ${$varSheet}->setCellValue('O'.$row, isset($salePipeline['FROM'])? $salePipeline['FROM'] : '');
  2121.                 // }
  2122.                 $row++;
  2123.             }
  2124.             
  2125.             ${$varSheet}->setAutoFilter('A1:'$lastCol . ${$varSheet}->getHighestRow());
  2126.             // ${$varSheet}->getStyle('D2:F' . ${$varSheet}->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  2127.             ${$varSheet}->getStyle('D2:F' . ${$varSheet}->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  2128.             ${$varSheet}->getStyle("M2:M".${$varSheet}->getHighestRow())->getAlignment()->setWrapText(true);
  2129.             ${$varSheet}->getStyle("N2:N".${$varSheet}->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_PERCENTAGE_00);
  2130.             ${$varSheet}->getStyle("A2:N".${$varSheet}->getHighestRow())->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
  2131.         }
  2132.         /*
  2133.         $i = 0;
  2134.         foreach($newLeads as $lead){
  2135.             $newLeads[$i]['FROM'] = 'NEW LEAD';
  2136.             $i++;
  2137.         }
  2138.         $j = 0;
  2139.         foreach($projectWons as $won){
  2140.             $projectWons[$j]['FROM'] = 'PROJECT WON';
  2141.             $j++;
  2142.         }
  2143.         $k = 0;
  2144.         foreach($projectLosts as $lost){
  2145.             $projectLosts[$k]['FROM'] = 'PROJECT LOST';
  2146.             $k++;
  2147.         }
  2148.         $m = 0;
  2149.         foreach($proposalSents as $sent){
  2150.             $proposalSents[$m]['FROM'] = 'PROPOSAL SENT';
  2151.             $m++;
  2152.         }
  2153.         if(!is_null($newLeads)) {
  2154.             $detailSales = array_merge($detailSales, $newLeads);
  2155.         }
  2156.         if(!is_null($proposalSents)) {
  2157.             $detailSales = array_merge($detailSales, $proposalSents);
  2158.         }
  2159.         if(!is_null($projectWons)) {
  2160.             $detailSales = array_merge($detailSales, $projectWons);
  2161.         }
  2162.         if(!is_null($projectLosts)) {
  2163.             $detailSales = array_merge($detailSales, $projectLosts);
  2164.         }
  2165.         $newDetailSales = array();
  2166.         foreach ($detailSales as $detailSale) {
  2167.             $id = $detailSale['id'];
  2168.             if (!isset($newDetailSales[$id])) {
  2169.                 $newDetailSales[$id] = $detailSale;
  2170.             }
  2171.         }
  2172.         $detailSalesUnique = array_values($newDetailSales);
  2173.         */
  2174.         // LOST REASONS
  2175.         $lostReasonSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet'LOST REASONS');
  2176.         $spreadsheet->addSheet($lostReasonSheet5);
  2177.         $lostReasonSheet->getDefaultColumnDimension()->setWidth(20);
  2178.         $lostReasonSheet->getColumnDimension('B')->setWidth(10);
  2179.         $lostReasonSheet->getColumnDimension('C')->setWidth(30);
  2180.         $lostReasonSheet->getColumnDimension('D')->setWidth(30);
  2181.         $lostReasonSheet->setCellValue('A1''OVERVIEW OF THE PERIOD');
  2182.         $lostReasonSheet->setCellValue('A2''From');
  2183.         $lostReasonSheet->setCellValue('A3''To');
  2184.         $lostReasonSheet->getStyle("A1:A3")->getFont()->setBold(true);
  2185.         $lostReasonSheet->setCellValue('B2'$startDateRange);
  2186.         $lostReasonSheet->setCellValue('B3'$endDateRange);
  2187.         $lostReasonSheet->setCellValue('A4''REASON');
  2188.         $lostReasonSheet->setCellValue('B4''% LOST');
  2189.         $lostReasonSheet->setCellValue('C4''REVENUE USD');
  2190.         $lostReasonSheet->setCellValue('D4''GROSS MARGIN USD');
  2191.         
  2192.         $lostReasonSheet->setCellValue('A5''Proposal quality');
  2193.         $lostReasonSheet->setCellValue('A6''Team Ressources');
  2194.         $lostReasonSheet->setCellValue('A7''Price');
  2195.         $lostReasonSheet->setCellValue('A8''Timeline');
  2196.         $lostReasonSheet->setCellValue('A9''Postponed');
  2197.         $lostReasonSheet->setCellValue('A10''Cancelled');
  2198.         $lostReasonSheet->setCellValue('A11''No answer');
  2199.         $lostReasonSheet->setCellValue('A12''No go (MT)');
  2200.         $lostReasonSheet->setCellValue('A13''Other');
  2201.         $lostReasonSheet->setCellValue('A14''TOTAL');
  2202.         $lostReasonSheet->getStyle("A4:D4")->getFont()->setBold(true);
  2203.         $lostReasonSheet->getStyle("A4:D4")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2204.         $lostReasonSheet->getStyle("A4:D4")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2205.         $lostReasonSheet->getStyle("A14:D14")->getFont()->setBold(true);
  2206.         $lostReasonSheet->getStyle("A14:D14")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2207.         $lostReasonSheet->getStyle("A14:D14")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2208.         $projectlostResons = ['Proposal Quality''MT Team Resource''Price''Timeline''Postponed''Cancelled''No Answer''No Go (MT)''Other'];
  2209.         $projectLostGroupByReason = [];
  2210.         foreach ($projectlostResons as $lostReason){
  2211.             if(!isset($projectLostGroupByReason[$lostReason])){
  2212.                 $projectLostGroupByReason[$lostReason] = [
  2213.                     'total' => 0,
  2214.                     'revenueUsd' => 0,
  2215.                     'estVendorCost' => 0,
  2216.                     'estMargin' => 0,
  2217.                     'grossMargin' => 0,
  2218.                     'data' => []
  2219.                 ];
  2220.             }
  2221.         }
  2222.         $projectLostByReasons $projectRepository->findProjectLost($startDate$endDate);
  2223.         
  2224.         foreach($projectLostByReasons as $projectLost){
  2225.             $failNote $projectLost['failNote'];
  2226.             if(!is_null($failNote) && isset($projectLostGroupByReason[$failNote])){
  2227.                 // if($failNote == $projectLostGroupByReason[$failNote]){
  2228.                 array_push($projectLostGroupByReason[$failNote]['data'], $projectLost);
  2229.                 $projectLostGroupByReason[$failNote]['total'] += 1;
  2230.                 $projectLostGroupByReason[$failNote]['revenueUsd'] += $projectLost['plannedRevenueUsd'];
  2231.                 $projectLostGroupByReason[$failNote]['estVendorCost'] += $projectLost[0]->getEstimatedVendorCostUsd();
  2232.                 $projectLostGroupByReason[$failNote]['estMargin'] += $projectLost['plannedRevenueUsd'] - $projectLost[0]->getEstimatedVendorCostUsd();
  2233.                 // }
  2234.             }else{
  2235.                 array_push($projectLostGroupByReason['Other']['data'], $projectLost);
  2236.                 $projectLostGroupByReason['Other']['total'] += 1;
  2237.                 $projectLostGroupByReason['Other']['revenueUsd'] += $projectLost['plannedRevenueUsd'];
  2238.                 $projectLostGroupByReason['Other']['estVendorCost'] += $projectLost[0]->getEstimatedVendorCostUsd();
  2239.                 $projectLostGroupByReason['Other']['estMargin'] += $projectLost['plannedRevenueUsd'] - $projectLost[0]->getEstimatedVendorCostUsd();
  2240.             }  
  2241.         }
  2242.         $totalRevenueUsdLosts 0;
  2243.         $totalEstMarginLosts 0;
  2244.         $totalQtyLost 0;
  2245.         foreach($projectLostGroupByReason as $groupLosts){
  2246.             $totalRevenueUsdLosts += $groupLosts['revenueUsd']; 
  2247.             $totalEstMarginLosts += $groupLosts['estMargin']; 
  2248.             $totalQtyLost += $groupLosts['total']; 
  2249.         }
  2250.         $row 5;
  2251.         foreach($projectLostGroupByReason as $groupLosts){
  2252.             $lostReasonSheet->setCellValue('B'$row$totalQtyLost ? ($groupLosts['total'] / $totalQtyLost) : 0);
  2253.             $lostReasonSheet->setCellValue('C'$row$groupLosts['revenueUsd']);
  2254.             $lostReasonSheet->setCellValue('D'$row$groupLosts['estMargin']);
  2255.             $row++;
  2256.         }
  2257.         // $lostReasonSheet->setCellValue('B'. $row, ($groupLosts['total'] / $totalQtyLost) * 100);
  2258.         $lostReasonSheet->setCellValue('C'$row$totalRevenueUsdLosts);
  2259.         $lostReasonSheet->setCellValue('D'$row$totalEstMarginLosts);
  2260.         // $lostReasonSheet->getStyle('C5:D14')->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  2261.         $lostReasonSheet->getStyle('C5:D14')->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  2262.         $lostReasonSheet->getStyle("B5:B14")->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_PERCENTAGE_00);
  2263.         $spreadsheet->setActiveSheetIndex(0);
  2264.         // Write the file
  2265.         $writer = new Xlsx($spreadsheet);
  2266.         $writer->save($filename);
  2267.         if($_target == 'google'){
  2268.             $gsheetURL $googleDriveService->uploadToGoogleDrive($filename);
  2269.             if($gsheetURL){
  2270.                 unlink($filename);
  2271.                 return new RedirectResponse($gsheetURL302);
  2272.             }
  2273.         }else{
  2274.             $response = new Response();
  2275.             $response->headers->set('Content-type''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  2276.             $response->headers->set('Content-Disposition'sprintf('attachment; filename="%s"'$filename));
  2277.             $response->setContent(file_get_contents($filename));
  2278.             $response->setStatusCode(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
  2279.             $response->headers->set('Content-Transfer-Encoding''binary');
  2280.             $response->headers->set('Pragma''no-cache');
  2281.             $response->headers->set('Expires''0');
  2282.             unlink($filename);
  2283.             return $response;
  2284.             exit;
  2285.         }  
  2286.     }
  2287.     #[Route(path'/project/export-revenue-forecast/{_target}'defaults: ['_target' => ''], name'export_project_revenue_forecast')]
  2288.     public function exportProjectRevenueForecast(string $_targetRequest $requestProjectService $projectService)
  2289.     {
  2290.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  2291.     
  2292.         $keyword $request->get('keyword');
  2293.         $startDate $request->get('start');
  2294.         $endDate $request->get('end');
  2295.         $filterType $request->get('filter_type');
  2296.         if (strpos($startDate'/') !== false) {
  2297.             $startDate str_replace('/''-'$startDate);
  2298.             $startDate date("Y-m-d"strtotime($startDate));
  2299.         } 
  2300.         if (strpos($endDate'/') !== false) {
  2301.             $endDate str_replace('/''-'$endDate);
  2302.             $endDate date("Y-m-d"strtotime($endDate));
  2303.         } 
  2304.         
  2305.         $client $request->get('client');
  2306.         $status $request->get('status');
  2307.         $type 'CONFIRMED;LEAD';
  2308.         $retainer $request->get('retainer');
  2309.         $department $request->get('department');
  2310.         $project $request->get('project');
  2311.         $pic $request->get('pic');
  2312.         $assignedUser null;
  2313.         $showDeleted false;
  2314.         $user $this->getUser();
  2315.         $userRoles $user->getRoles();
  2316.         $isCashflow true;
  2317.         $isAdmin true;
  2318.         if($filterType == 'project_start'){
  2319.             $result $projectService->exportProjectRevenueForecastProjectDate($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$isCashflow$_target);
  2320.         }elseif($filterType == 'invoice_due'){
  2321.             $result $projectService->exportProjectRevenueForecast($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$isCashflow$_target);
  2322.         }
  2323.         
  2324.         return $result;
  2325.     }
  2326.     #[Route(path'/project/export-revenue-recognition/{_target}'defaults: ['_target' => ''], name'export_project_revenue_recognition')]
  2327.     public function exportProjectRevenueRecognition(string $_targetRequest $requestProjectService $projectService)
  2328.     {
  2329.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  2330.     
  2331.         $keyword $request->get('keyword');
  2332.         $startDate $request->get('start');
  2333.         $endDate $request->get('end');
  2334.         $filterType $request->get('filter_type');
  2335.         if (strpos($startDate'/') !== false) {
  2336.             $startDate str_replace('/''-'$startDate);
  2337.             $startDate date("Y-m-d"strtotime($startDate));
  2338.         } 
  2339.         if (strpos($endDate'/') !== false) {
  2340.             $endDate str_replace('/''-'$endDate);
  2341.             $endDate date("Y-m-d"strtotime($endDate));
  2342.         } 
  2343.         
  2344.         $client $request->get('client');
  2345.         $status $request->get('status');
  2346.         $type 'CONFIRMED;LEAD';
  2347.         $retainer $request->get('retainer');
  2348.         $department $request->get('department');
  2349.         $project $request->get('project');
  2350.         $pic $request->get('pic');
  2351.         $assignedUser null;
  2352.         $showDeleted false;
  2353.         $user $this->getUser();
  2354.         $userRoles $user->getRoles();
  2355.         $isCashflow false;
  2356.         $isAdmin true;
  2357.         if($filterType == 'project_start'){
  2358.             $result $projectService->exportProjectRevenueForecastProjectDate($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$isCashflow$_target);
  2359.         }elseif($filterType == 'invoice_issue'){
  2360.             $result $projectService->exportProjectRevenueForecast($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$isCashflow$_target);
  2361.         }
  2362.         return $result;
  2363.     }
  2364.     #[Route(path'/project/project-revenue-vs-cost-report/{_target}'defaults: ['_target' => ''], name'project_revenue_vs_cost_report')]
  2365.     public function reportProjectRevenueCostReport(string $_targetRequest $requestProjectService $projectService)
  2366.     {
  2367.         $result ='';
  2368.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  2369.         $isAdmin true;
  2370.         $financialYear $request->get('financialYear');
  2371.         // $startDate = $request->get('start');
  2372.         // $endDate = $request->get('end');
  2373.         // if (strpos($startDate, '/') !== false) {
  2374.         //     $startDate = str_replace('/', '-', $startDate);
  2375.         //     $startDate = date("Y-m-d", strtotime($startDate));
  2376.         // } 
  2377.         // if (strpos($endDate, '/') !== false) {
  2378.         //     $endDate = str_replace('/', '-', $endDate);
  2379.         //     $endDate = date("Y-m-d", strtotime($endDate));
  2380.         // } 
  2381.         
  2382.         // $client = $request->get('client');
  2383.         // $status = $request->get('status');
  2384.         // $type = 'CONFIRMED;LEAD';
  2385.         // $retainer = $request->get('retainer');
  2386.         // $department = $request->get('department');
  2387.         // $project = $request->get('project');
  2388.         // $pic = $request->get('pic');
  2389.         // $assignedUser = null;
  2390.         // $showDeleted = false;
  2391.         // $user = $this->getUser();
  2392.         // $userRoles = $user->getRoles();
  2393.         // $isAdmin = true;
  2394.         $result $projectService->exportProjectRevenueCost($isAdmin$financialYear$baseurl$_target);
  2395.         return $result;
  2396.     }
  2397.     #[Route(path'/project/project-revenue-vs-cost-report-range/{_target}'defaults: ['_target' => ''], name'project_revenue_vs_cost_report_range')]
  2398.     public function reportProjectRevenueCostReportRange(string $_targetRequest $requestProjectService $projectService)
  2399.     {
  2400.         $result ='';
  2401.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  2402.         $isAdmin true;
  2403.         $startDate $request->get('start');
  2404.         $endDate $request->get('end');
  2405.         if (strpos($startDate'/') !== false) {
  2406.             $startDate str_replace('/''-'$startDate);
  2407.             $startDate date("Y-m-d"strtotime($startDate));
  2408.         } 
  2409.         if (strpos($endDate'/') !== false) {
  2410.             $endDate str_replace('/''-'$endDate);
  2411.             $endDate date("Y-m-d"strtotime($endDate));
  2412.         } 
  2413.         
  2414.         // $client = $request->get('client');
  2415.         // $status = $request->get('status');
  2416.         // $type = 'CONFIRMED;LEAD';
  2417.         // $retainer = $request->get('retainer');
  2418.         // $department = $request->get('department');
  2419.         // $project = $request->get('project');
  2420.         // $pic = $request->get('pic');
  2421.         // $assignedUser = null;
  2422.         // $showDeleted = false;
  2423.         // $user = $this->getUser();
  2424.         // $userRoles = $user->getRoles();
  2425.         // $isAdmin = true;
  2426.         $result $projectService->exportProjectRevenueCostDateRange($isAdmin$startDate$endDate$baseurl$_target);
  2427.         return $result;
  2428.     }
  2429.     #[Route(path'/project/vendor-invoices-report/{_target}'defaults: ['_target' => ''], name'project_vendor_invoices_report')]
  2430.     public function projectVendorInvoicesReport(string $_targetRequest $requestProjectService $projectService)
  2431.     {
  2432.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  2433.     
  2434.         $keyword $request->get('keyword');
  2435.         $startDate $request->get('start');
  2436.         $endDate $request->get('end');
  2437.         if (strpos($startDate'/') !== false) {
  2438.             $startDate str_replace('/''-'$startDate);
  2439.             $startDate date("Y-m-d"strtotime($startDate));
  2440.         } 
  2441.         if (strpos($endDate'/') !== false) {
  2442.             $endDate str_replace('/''-'$endDate);
  2443.             $endDate date("Y-m-d"strtotime($endDate));
  2444.         } 
  2445.         
  2446.         $client $request->get('client');
  2447.         $status $request->get('status');
  2448.         $type 'CONFIRMED;LEAD';
  2449.         $retainer $request->get('retainer');
  2450.         $department $request->get('department');
  2451.         $project $request->get('project');
  2452.         $pic $request->get('pic');
  2453.         $assignedUser null;
  2454.         $showDeleted false;
  2455.         $user $this->getUser();
  2456.         $userRoles $user->getRoles();
  2457.         $isAdmin true;
  2458.         $result $projectService->exportProjectVendorInvoices($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$_target);
  2459.         return $result;
  2460.     }
  2461.     #[Route(path'/project/client-invoices-report/{_target}'defaults: ['_target' => ''], name'project_client_invoices_report')]
  2462.     public function projectClientInvoicesReport(string $_targetRequest $requestProjectService $projectService)
  2463.     {
  2464.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  2465.     
  2466.         $keyword $request->get('keyword');
  2467.         $startDate $request->get('start');
  2468.         $endDate $request->get('end');
  2469.         if (strpos($startDate'/') !== false) {
  2470.             $startDate str_replace('/''-'$startDate);
  2471.             $startDate date("Y-m-d"strtotime($startDate));
  2472.         } 
  2473.         if (strpos($endDate'/') !== false) {
  2474.             $endDate str_replace('/''-'$endDate);
  2475.             $endDate date("Y-m-d"strtotime($endDate));
  2476.         } 
  2477.         
  2478.         $client $request->get('client');
  2479.         $status $request->get('status');
  2480.         $type 'CONFIRMED;LEAD';
  2481.         $retainer $request->get('retainer');
  2482.         $department $request->get('department');
  2483.         $project $request->get('project');
  2484.         $pic $request->get('pic');
  2485.         $assignedUser null;
  2486.         $showDeleted false;
  2487.         $user $this->getUser();
  2488.         $userRoles $user->getRoles();
  2489.         $isAdmin true;
  2490.         $result $projectService->exportProjectClientInvoices($isAdmin$keyword$startDate$endDate$client$status$type$retainer$department$project$assignedUser$pic$showDeleted$baseurl$_target);
  2491.         return $result;
  2492.     }
  2493.     /**
  2494.      * @param int $id
  2495.      */
  2496.     #[Route(path'/project/export-detail/{id}/{_target}'defaults: ['id' => null'_target' => ''], name'export_project_detail')]
  2497.     public function exportProjectDetail($idstring $_targetTranslatorInterface $translatorProjectRepository $projectRepositoryProjectAllocatedHoursRepository $allocatedHoursRepositoryTimeSpentRepository $timeSpentRepositoryUserRepository $userRepositoryTaskRepository $taskRepositoryGoogleDriveService $googleDriveService)
  2498.     {
  2499.         $projectId $id ?: null;
  2500.         $assignedUser null;
  2501.         $user $this->getUser();
  2502.         $userRoles $user->getRoles();
  2503.         if ($this->isGranted("ROLE_TEAM_LEADER") or $this->isGranted("ROLE_MARCOM") or $this->isGranted("ROLE_FINANCE")) {
  2504.             $spreadsheet = new Spreadsheet();
  2505.             $sheet $spreadsheet->getActiveSheet();
  2506.             $sheet->setCellValue('A1''Client Name');
  2507.             $sheet->setCellValue('B1''ID');
  2508.             $sheet->setCellValue('C1''Project Name');
  2509.             $sheet->setCellValue('D1''Project Status');
  2510.             $sheet->setCellValue('E1''PIC');
  2511.             $sheet->setCellValue('F1''Plan File');
  2512.             $sheet->setCellValue('G1''Plan URL');
  2513.             $sheet->setCellValue('H1''Start Date');
  2514.             $sheet->setCellValue('I1''End Date');
  2515.             $sheet->setCellValue('J1''Invoice Number(s)');
  2516.             $sheet->setCellValue('K1''SO Number(s)');
  2517.             $sheet->setCellValue('L1''Estimated Project Billings');
  2518.             $sheet->setCellValue('M1''Estimated Project Billings Based on SO');
  2519.             $sheet->setCellValue('N1''Estimated Project Billings Based on INV');
  2520.             $sheet->setCellValue('O1''Estimated Project Hours');
  2521.             // $sheet->setCellValue('O1', 'Man Hours Cost');
  2522.             $sheet->setCellValue('P1''Employee Time Record Hours');
  2523.             $sheet->setCellValue('Q1''Vendor Costs Based On Plan');
  2524.             $sheet->setCellValue('R1''Vendor Costs Based On INV');
  2525.             $sheet->setCellValue('S1''Project Type');
  2526.             $sheet->setCellValue('T1''Profit (SO amount - 3rd party cost planned - man hours)');
  2527.             $sheet->setCellValue('U1''Profit (INV amount - 3rd party cost planned - man hours)');
  2528.             $sheet->setCellValue('V1''Profit (SO amount - 3rd party invoices - man hours)');
  2529.             $sheet->setCellValue('W1''Profit (INV amount - 3rd party invoices - man hours)');
  2530.             $sheet->getDefaultColumnDimension()->setWidth(25);
  2531.             $sheet->getStyle("A1:W1")->getFont()->setBold(true);
  2532.             $sheet->getStyle("A1:W1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2533.             $sheet->getStyle("A1:W1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2534.             $sheet->getStyle("A2:W2")->getFont()->setBold(false);
  2535.             $sheet->getStyle("A2:W2")->getAlignment()->setWrapText(true);
  2536.             $sheet->getStyle("A2:W2")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  2537.             $filename "ProjectDetail_" $projectId "_" date('Y-m-d') . '.xlsx';
  2538.             $projectsList $projectRepository->findByPage(09999"""ASC"null""""""0null$projectIdnull0$assignedUser);
  2539.             $n 0;
  2540.             foreach ($projectsList as $projectDetail) {
  2541.                 $projectsList[$n]['cost'] = $projectDetail[0]->getProjectCost();
  2542.                 $projectsList[$n]['profit'] = $projectDetail[0]->getProjectProfit1();
  2543.                 $projectsList[$n]['leadStatusText'] = $projectDetail[0]->getLeadStatus() ? $projectDetail[0]->getLeadStatus()->getName() : null;
  2544.                 $n++;
  2545.             };
  2546.             $row $sheet->getHighestRow();
  2547.             foreach ($projectsList as $project) {
  2548.                 $picName $project['picMiddleName'] ? $project['picFirstName'] . ' ' $project['picMiddleName'] . ' ' $project['picLastName'] : $project['picFirstName'] . ' ' $project['picLastName'];
  2549.                 //$sheet->insertNewRowBefore($row);
  2550.                 $sheet->setCellValue('A' $row$project['clientName']);
  2551.                 $sheet->setCellValue('B' $row$project['generatedId']);
  2552.                 $sheet->setCellValue('C' $row$project['name']);
  2553.                 $sheet->setCellValue('D' $row$project['type'] == 'LEAD' $project['lead'] . ' - ' $project[0]->getLeadStatus()->getName() : ($project['status'] ? $project['status'] : '-'));
  2554.                 $sheet->setCellValue('E' $row$picName);
  2555.                 $sheet->setCellValue('F' $row$project['planFilename'] ? $project['planFilename'] : "-");
  2556.                 if ($project['planFilename']) {
  2557.                     $sheet->getCell('F' $row)->getHyperlink()->setUrl($project['planFilepath']);
  2558.                 }
  2559.                 $sheet->setCellValue('G' $row$project['planURL'] ? $project['planURL'] : "-");
  2560.                 if ($project['planURL']) {
  2561.                     $sheet->getCell('G' $row)->getHyperlink()->setUrl($project['planURL']);
  2562.                 }
  2563.                 $sheet->setCellValue('H' $row$project['startDate'] ? $project['startDate']->format('Y-m-d') : '-');
  2564.                 $sheet->setCellValue('I' $row$project['endDate'] ? $project['endDate']->format('Y-m-d') : '-');
  2565.                 $multiRow $row;
  2566.                 $proSalesOrders $project[0]->getProjectSalesOrders();
  2567.                 foreach ($proSalesOrders as $so) {
  2568.                     $sheet->setCellValue('J' $multiRow$so->getSalesOrder()->getSalesOrderNo());
  2569.                     $invoices $so->getSalesOrder()->getSalesOrderInvoices($project['id']);
  2570.                     $multiMultiRow $multiRow;
  2571.                     foreach ($invoices as $invoice) {
  2572.                         $sheet->setCellValue('K' $multiMultiRow$invoice->getInvoice()->getInvoiceNo());
  2573.                         $multiMultiRow++;
  2574.                     }
  2575.                     $multiRow $multiMultiRow;
  2576.                 }
  2577.                 if ($project['type'] == 'INTERNAL') {
  2578.                     $sheet->setCellValue('L' $row'-');
  2579.                 } else {
  2580.                     //$sheet->setCellValue('L' . $row, $project['type'] == 'LEAD' ? $project['estimatedProfit'] : $project['plannedRevenue']);
  2581.                     // $sheet->setCellValue('L' . $row, $project['type'] == 'LEAD' ? $project[0]->getEstimatedProfitUsd() : $project[0]->getPlannedRevenueUsd());
  2582.                     $sheet->setCellValue('L' $row$project[0]->getPlannedRevenueUsd());
  2583.                 }
  2584.                 $sheet->setCellValue('M' $row$project[0]->getSoTotalUsd());
  2585.                 $sheet->setCellValue('N' $row$project[0]->getInvoicesTotalUsd());
  2586.                 // $sheet->setCellValue('O' . $row, $project[0]->getProjectManhourCost());
  2587.                 $resourceAllocations $allocatedHoursRepository->findByProject(''''$project['id']);
  2588.                 $totalEstimatedProjectHours 0;
  2589.                 foreach ($resourceAllocations as $allocation) {
  2590.                     $totalEstimatedProjectHours += intval($allocation->getHours());
  2591.                 }
  2592.                 $estimatedProjectHours = !empty($totalEstimatedProjectHours) ? $totalEstimatedProjectHours '-';
  2593.                 $sheet->setCellValue('O' $row$estimatedProjectHours);
  2594.                 // Calculate employee time record
  2595.                 $_id intval($project['id']);
  2596.                 $departments $timeSpentRepository->getDepartmentsForProject($_id$project[0]->getStartDate(), $project[0]->getEndDate());
  2597.                 $totalHoursAll 0;
  2598.                 $totalCostAll 0;
  2599.                 for ($i 0$i sizeof($departments); $i++) {
  2600.                     $employeeSummaryList $userRepository->findTaskSummary($_id$departments[$i]['id']);
  2601.                     $departments[$i]['employeeSummaryList'] = $employeeSummaryList;
  2602.                     $tmpHours 0;
  2603.                     $tmpCost 0;
  2604.                     for ($j 0$j sizeof($employeeSummaryList); $j++) {
  2605.                         $tmpHours $tmpHours $employeeSummaryList[$j]['hours'];
  2606.                         $tmpCost $tmpCost $employeeSummaryList[$j]['cost'];
  2607.                     }
  2608.                     //$totalManpowerCost += $tmpCost;
  2609.                     $departments[$i]['totalCost'] = $tmpCost;
  2610.                     $departments[$i]['totalHours'] = $tmpHours;
  2611.                 }
  2612.                 if (count($departments) > 0) {
  2613.                     foreach ($departments as $department) {
  2614.                         $totalHoursAll += $department['totalHours'];
  2615.                         $totalCostAll += $department['totalCost'];
  2616.                     }
  2617.                 }
  2618.                 $employeeTimeRecordHours = !empty($totalHoursAll) ? $totalHoursAll '-';
  2619.                 $sheet->setCellValue('P' $row$employeeTimeRecordHours);
  2620.                 $sheet->setCellValue('Q' $row$project[0]->getVendorPlannedTotalUsd());
  2621.                 $sheet->setCellValue('R' $row$project[0]->getVendorInvoicesTotalUsd());
  2622.                 $sheet->setCellValue('S' $row$project['type']);
  2623.                 $sheet->setCellValue('T' $row$project[0]->getProjectProfit3());
  2624.                 $sheet->setCellValue('U' $row$project[0]->getProjectProfit4());
  2625.                 $sheet->setCellValue('V' $row$project[0]->getProjectProfit2());
  2626.                 $sheet->setCellValue('W' $row$project[0]->getProjectProfit1());
  2627.                 $row $multiRow 1;
  2628.             }
  2629.             $sheet->setAutoFilter('A1:W' $sheet->getHighestRow());
  2630.             // $sheet->getStyle('L2:N' . $sheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  2631.             // $sheet->getStyle('Q2:R' . $sheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  2632.             // $sheet->getStyle('T2:W' . $sheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  2633.             $sheet->getStyle('L2:N' $sheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  2634.             $sheet->getStyle('Q2:R' $sheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  2635.             $sheet->getStyle('T2:W' $sheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  2636.             $ManHoursSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet'Man Hours');
  2637.             $spreadsheet->addSheet($ManHoursSheet1);
  2638.             $ManHoursSheet $spreadsheet->getSheet(1);
  2639.             $column = [];
  2640.             for ($i 65$i 91$i++) {
  2641.                 $column[] = chr($i);
  2642.             }
  2643.             $projectMembers $project[0]->getProjectMembers();
  2644.             $allDepartment $user->assignedCompany()->getDepartments();
  2645.             $ManHoursSheet->setCellValue('A1''Departments \ Users');
  2646.             $i 2;
  2647.             foreach ($allDepartment as $department) {
  2648.                 $ManHoursSheet->setCellValue('A' $i$department->getName());
  2649.                 $i++;
  2650.             }
  2651.             $ManHoursSheet->setCellValue('A' $i'Total Hours');
  2652.             $j 1;
  2653.             foreach ($projectMembers as $member) {
  2654.                 if(!isset($column[$j])) continue;
  2655.                 $ManHoursSheet->setCellValue($column[$j] . '1'$member->getUser()->getPersonalInfo()->getFirstName());
  2656.                 $j++;
  2657.             }
  2658.             if(isset($column[$j])) $ManHoursSheet->setCellValue($column[$j] . '1''Total Hours');
  2659.             $hours = [];
  2660.             $row 2;
  2661.             $AllTotalRowHours 0;
  2662.             foreach ($allDepartment as $department) {
  2663.                 $col 1;
  2664.                 $totalRowHours 0;
  2665.                 foreach ($projectMembers as $member) {
  2666.                     $tasks $taskRepository->findTaskbyProjectDepartment($projectId$member->getUser()->getId(), $department->getId());
  2667.                     if ($tasks) {
  2668.                         $taskHours 0;
  2669.                         foreach ($tasks as $task) {
  2670.                             $taskHours += $task->getWeeklyTotalHours();
  2671.                         }
  2672.                         $dataHours $taskHours;
  2673.                         $hours['column'][$member->getUser()->getId()][$department->getId()] = $taskHours;
  2674.                     } else {
  2675.                         $dataHours 0;
  2676.                         $hours['column'][$member->getUser()->getId()][$department->getId()] = 0;
  2677.                     }
  2678.                     if(!isset($column[$col])) continue;
  2679.                     $ManHoursSheet->setCellValue($column[$col] . $row, !empty($dataHours) ? $dataHours '-');
  2680.                     $totalRowHours += $dataHours;
  2681.                     $col++;
  2682.                 }
  2683.                 if(isset($column[$col])) $ManHoursSheet->setCellValue($column[$col] . $row$totalRowHours == '-' $totalRowHours);
  2684.                 $hours['totalRow'][$department->getId()] = $totalRowHours;
  2685.                 $AllTotalRowHours += $totalRowHours;
  2686.                 $row++;
  2687.             }
  2688.             if(isset($column[$col])) $ManHoursSheet->setCellValue($column[$col] . $row$AllTotalRowHours == '-' $AllTotalRowHours);
  2689.             $hours['totalColumn'] = [];
  2690.             if(isset($hours['column'])){
  2691.                 foreach ($hours['column'] as $key => $value) {
  2692.                     $hours['totalColumn'] += [$key => array_sum($value)];
  2693.                 }
  2694.             } else {
  2695.                 $hours['totalColumn'] = ['-'];
  2696.             }
  2697.             
  2698.             $columnLoop 1;
  2699.             foreach ($hours['totalColumn'] as $dataColumn) {
  2700.                 if(!isset($column[$columnLoop])) continue;
  2701.                 $ManHoursSheet->setCellValue($column[$columnLoop] . $row$dataColumn);
  2702.                 $columnLoop++;
  2703.             }
  2704.             $hours['totalAllHours'] = $AllTotalRowHours;
  2705.             $lastColumn $ManHoursSheet->getHighestColumn();
  2706.             $lastRow $ManHoursSheet->getHighestRow();
  2707.             $ManHoursSheet->getColumnDimension('A')->setWidth(25);
  2708.             $lengthColumn array_search($lastColumn$column);
  2709.             for ($i 1$i <= $lengthColumn$i++) {
  2710.                 $ManHoursSheet->getColumnDimension($column[$i])->setWidth(15);
  2711.             }
  2712.             $ManHoursSheet->getStyle("A1:" $lastColumn "1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2713.             $ManHoursSheet->getStyle("A1:" $lastColumn "1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2714.             $ManHoursSheet->getStyle("A1:" $lastColumn "1")->getFont()->setBold(true);
  2715.             $ManHoursSheet->getStyle("A1:A" $lastRow)->getFont()->setBold(true);
  2716.             $ManHoursSheet->getStyle("A" $lastRow ":" $lastColumn $lastRow)->getFont()->setBold(true);
  2717.             $ManHoursSheet->getStyle("A" $lastRow ":" $lastColumn $lastRow)->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2718.             $ManHoursSheet->getStyle("A" $lastRow ":" $lastColumn $lastRow)->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2719.             $ManHoursSheet->getStyle($lastColumn "1:" $lastColumn $lastRow)->getFont()->setBold(true);
  2720.             $VendorSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet'Vendors');
  2721.             $spreadsheet->addSheet($VendorSheet2);
  2722.             $VendorSheet $spreadsheet->getSheet(2);
  2723.             $VendorSheet->setCellValue('A1''Vendors');
  2724.             $VendorSheet->setCellValue('B1''Planned (total)');
  2725.             $VendorSheet->setCellValue('C1''Invoiced (total)');
  2726.             $VendorSheet->setCellValue('D1''Difference Planned & Invoiced');
  2727.             $VendorSheet->getStyle("A1:D1")->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2728.             $VendorSheet->getStyle("A1:D1")->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2729.             $VendorSheet->getDefaultColumnDimension()->setWidth(27);
  2730.             $VendorSheet->getStyle("A1:D1")->getFont()->setBold(true);
  2731.             $vendorsQuotationPlannings $project[0]->getVendorQuotationPlannings();
  2732.             $vqpData = [];
  2733.             $x 2;
  2734.             foreach ($vendorsQuotationPlannings as $vqp) {
  2735.                 $VendorSheet->setCellValue('A' $x$vqp->getVendor()->getName());
  2736.                 $VendorSheet->setCellValue('B' $x$vqp->getAmountPlannedUsd());
  2737.                 $VendorSheet->setCellValue('C' $x$vqp->getTotalInvoiceReceivedUSD());
  2738.                 $VendorSheet->setCellValue('D' $x$vqp->getBudgetRemainingUsd());
  2739.                 $data = [
  2740.                     'vendorName' => $vqp->getVendor()->getName(),
  2741.                     'totalPlanned' => $vqp->getAmountPlannedUsd(),
  2742.                     'totalInvoiced' => $vqp->getTotalInvoiceReceivedUSD(),
  2743.                     'diffPlannedInvoiced' => $vqp->getBudgetRemainingUsd()
  2744.                 ];
  2745.                 array_push($vqpData$data);
  2746.                 $x++;
  2747.             }
  2748.             $totalPlanned array_column($vqpData'totalPlanned');
  2749.             $totalInvoiced array_column($vqpData'totalInvoiced');
  2750.             $diffPlannedInvoiced array_column($vqpData'diffPlannedInvoiced');
  2751.             $vqpData['total']['vendorName'] = 'Total';
  2752.             $vqpData['total']['totalPlanned'] = array_sum($totalPlanned);
  2753.             $vqpData['total']['totalInvoiced'] = array_sum($totalInvoiced);
  2754.             $vqpData['total']['diffPlannedInvoiced'] = array_sum($diffPlannedInvoiced);
  2755.             $vendorLastColumn $VendorSheet->getHighestColumn();
  2756.             $vendorLastRow $VendorSheet->getHighestRow() + 1;
  2757.             $VendorSheet->setCellValue('A' $vendorLastRow$vqpData['total']['vendorName']);
  2758.             $VendorSheet->setCellValue('B' $vendorLastRow$vqpData['total']['totalPlanned']);
  2759.             $VendorSheet->setCellValue('C' $vendorLastRow$vqpData['total']['totalInvoiced']);
  2760.             $VendorSheet->setCellValue('D' $vendorLastRow$vqpData['total']['diffPlannedInvoiced']);
  2761.             $VendorSheet->getStyle("A" $VendorSheet->getHighestRow() . ":D" $VendorSheet->getHighestRow())->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
  2762.             $VendorSheet->getStyle("A" $VendorSheet->getHighestRow() . ":D" $VendorSheet->getHighestRow())->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
  2763.             $VendorSheet->getStyle("A" $VendorSheet->getHighestRow() . ":D" $VendorSheet->getHighestRow())->getFont()->setBold(true);
  2764.             // $VendorSheet->getStyle('B2:D' . $VendorSheet->getHighestRow())->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2);
  2765.             $VendorSheet->getStyle('B2:D' $VendorSheet->getHighestRow())->getNumberFormat()->setFormatCode('#,##0.00;(#,##0.00)');
  2766.             
  2767.             // $VendorSheet->setAutoFilter('A1:D' . $VendorSheet->getHighestRow());
  2768.         }
  2769.         $writer = new Xlsx($spreadsheet);
  2770.         $writer->save($filename);
  2771.         if($_target == 'google'){
  2772.             $gsheetURL $googleDriveService->uploadToGoogleDrive($filename);
  2773.             if($gsheetURL){
  2774.                 unlink($filename);
  2775.                 return new RedirectResponse($gsheetURL302);
  2776.             }
  2777.         }else{
  2778.             $response = new Response();
  2779.             $response->headers->set('Content-type''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  2780.             $response->headers->set('Content-Disposition'sprintf('attachment; filename="%s"'$filename));
  2781.             $response->setContent(file_get_contents($filename));
  2782.             $response->setStatusCode(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
  2783.             $response->headers->set('Content-Transfer-Encoding''binary');
  2784.             $response->headers->set('Pragma''no-cache');
  2785.             $response->headers->set('Expires''0');
  2786.             unlink($filename);
  2787.             return $response;
  2788.             exit;
  2789.         } 
  2790.     }
  2791.     #[Route(path'/api/projects'name'api_projects'methods: ['GET'])]
  2792.     public function apiProjects(SerializerInterface $serializerProjectRepository $projectRepositoryRequest $request): Response
  2793.     {
  2794.         $header $request->headers->get('Authorization') ?: null;
  2795.         if ($header !== $this->getParameter('checkboxAuthToken')) {
  2796.             $responseData = [
  2797.                 'status' => '401 Unauthorized',
  2798.             ];
  2799.             $response = new Response(
  2800.                 $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2801.                 Response::HTTP_UNAUTHORIZED,
  2802.                 ['Content-type' => 'application/json']
  2803.             );
  2804.             return $response;
  2805.         }
  2806.         $projects $projectRepository->findAll();
  2807.         $data = [];
  2808.         if (!empty($projects)) {
  2809.             foreach ($projects as $project) {
  2810.                 $members = [];
  2811.                 foreach ($project->getProjectMembers() as $member) {
  2812.                     $members[] .= $member->getId();
  2813.                 }
  2814.                 $data[] = [
  2815.                     'id' => $project->getId(),
  2816.                     'name' => $project->getName(),
  2817.                     'description' => $project->getDescription(),
  2818.                     'client_id' => $project->getClient()->getId(),
  2819.                     'pic_id' => $project->getPersonInCharge() ? $project->getPersonInCharge()->getId() : "",
  2820.                     'status' => $project->getStatus(),
  2821.                     'project_members' => $members,
  2822.                     'active' => $project->getDeletedAt() ? false true
  2823.                 ];
  2824.             }
  2825.         }
  2826.         $responseData = [
  2827.             'status' => !empty($data) ? 200 404,
  2828.             'data' => $data
  2829.         ];
  2830.         $response = new Response(
  2831.             $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2832.             Response::HTTP_OK,
  2833.             ['Content-type' => 'application/json']
  2834.         );
  2835.         return $response;
  2836.     }
  2837.     #[Route(path'/api/projects/{id}'name'api_project_show'methods: ['GET'])]
  2838.     public function apiProjectShow($idSerializerInterface $serializerProjectRepository $projectRepositoryRequest $request): Response
  2839.     {
  2840.         $header $request->headers->get('Authorization') ?: null;
  2841.         if ($header !== $this->getParameter('checkboxAuthToken')) {
  2842.             $responseData = [
  2843.                 'status' => '401 Unauthorized',
  2844.             ];
  2845.             $response = new Response(
  2846.                 $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2847.                 Response::HTTP_UNAUTHORIZED,
  2848.                 ['Content-type' => 'application/json']
  2849.             );
  2850.             return $response;
  2851.         }
  2852.         $projects $projectRepository->find($id);
  2853.         $data = [];
  2854.         if ($projects) {
  2855.             $members = [];
  2856.             foreach ($projects->getProjectMembers() as $member) {
  2857.                 $members[] .= $member->getId();
  2858.             }
  2859.             $data[] = [
  2860.                 'id' => $projects->getId(),
  2861.                 'name' => $projects->getName(),
  2862.                 'description' => $projects->getDescription(),
  2863.                 'client_id' => $projects->getClient()->getId(),
  2864.                 'pic_id' => $projects->getPersonInCharge()->getId(),
  2865.                 'status' => $projects->getStatus(),
  2866.                 'project_members' => $members,
  2867.                 'active' => $projects->getDeletedAt() ? false true
  2868.             ];
  2869.         }
  2870.         $responseData = [
  2871.             'status' => !empty($data) ? 200 404,
  2872.             'data' => $data
  2873.         ];
  2874.         $response = new Response(
  2875.             $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2876.             Response::HTTP_OK,
  2877.             ['Content-type' => 'application/json']
  2878.         );
  2879.         return $response;
  2880.     }
  2881.     #[Route(path'/api/projects/{id}'name'api_project_delete'methods: ['DELETE'])]
  2882.     public function apiProjectDelete($idSerializerInterface $serializerProjectRepository $projectRepositoryRequest $request): Response
  2883.     {
  2884.         $header $request->headers->get('Authorization') ?: null;
  2885.         if ($header !== $this->getParameter('checkboxAuthToken')) {
  2886.             $responseData = [
  2887.                 'status' => '401 Unauthorized',
  2888.             ];
  2889.             $response = new Response(
  2890.                 $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2891.                 Response::HTTP_UNAUTHORIZED,
  2892.                 ['Content-type' => 'application/json']
  2893.             );
  2894.             return $response;
  2895.         }
  2896.         $em $this->getDoctrine()->getManager();
  2897.         $project $projectRepository->find($id);
  2898.         if (!$project) {
  2899.             $responseData = [
  2900.                 'status' => '404 No Project found for id ' $id,
  2901.             ];
  2902.             $response = new Response(
  2903.                 $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2904.                 Response::HTTP_NOT_FOUND,
  2905.                 ['Content-type' => 'application/json']
  2906.             );
  2907.             return $response;
  2908.         }
  2909.         $em->remove($project);
  2910.         $em->flush();
  2911.         $responseData = [
  2912.             'status' => 200,
  2913.             'data' => 'Deleted a project successfully with id ' $id
  2914.         ];
  2915.         $response = new Response(
  2916.             $serializer->serialize($responseData'json', ['groups' => 'APIProject']),
  2917.             Response::HTTP_OK,
  2918.             ['Content-type' => 'application/json']
  2919.         );
  2920.         return $response;
  2921.     }
  2922.     /**
  2923.      * @param ProjectRepository $projectRepository
  2924.      * @param Request $request
  2925.      * @return Response
  2926.      */
  2927.     #[Route(path'/ajax/project/prospect-summary'name'ajax_prospect_summary')]
  2928.     public function ajaxProjectProspectSummary(ProjectRepository $projectRepositoryRequest $request): Response
  2929.     {
  2930.         // Example params:
  2931.         // http://localhost:8000/ajax/project/prospect-summary?orderBy=projectCount&order=DESC&pic=&client=&startDate=2022-10-01&endDate=2023-12-31
  2932.         //        $user = $this->getUser();
  2933.         $page intval($request->query->get('page') - 1);
  2934.         if ($page 0$page 0;
  2935.         $limit intval($request->query->get('limit'));
  2936.         if ($limit === 0$limit 20;
  2937.         $keyword $request->get('keyword');
  2938.         $order $request->get('order');
  2939.         $orderBy $request->get('orderBy');
  2940.         $startDate $request->get('start');
  2941.         $endDate $request->get('end');
  2942.         $client $request->get('client');
  2943.         $pic $request->get('pic');
  2944.         $period $request->get('period');
  2945.         $year $request->get('year');
  2946.         $retainer $request->get('retainer');
  2947.         $waitForPage $request->query->get('waitForPage');
  2948.         $reportList $projectRepository->findProspectSummaryByPage($keyword$order$orderBy$startDate$endDate$client$pic$period$year$retainer);
  2949.         $leadStatus = [
  2950.             => 'Lead',
  2951.             => 'First discussion',
  2952.             => 'Brief received',
  2953.             => 'Work on proposal or quote',
  2954.             => 'Proposal sent -> to follow up',
  2955.             => 'Verbally Accepted',
  2956.             => 'Work on Contract',
  2957.             => 'Won (Contract or Quote signed)',
  2958.             => 'Lost',
  2959.             91 => 'Lost / No answer',
  2960.             92 => 'No go / Closed'
  2961.         ];
  2962.         $total = [];
  2963.         $total['plannedRevenue'] = 0;
  2964.         $total['estimatedMargin'] = 0;
  2965.         $total['estimatedVendorCost'] = 0;
  2966.         $total['projectCount'] = 0;
  2967.         $total['clients'] = 0;
  2968.         foreach ($reportList as $report) {
  2969.             $total['plannedRevenue'] += $report['plannedRevenue'];
  2970.             $total['estimatedMargin'] += $report['estimatedMargin'];
  2971.             $total['estimatedVendorCost'] += $report['estimatedVendorCost'];
  2972.             $total['projectCount'] += $report['projectCount'];
  2973.             $total['clients'] += $report['clients'];
  2974.         }
  2975.         $body $this->renderView('private/project-management/report/components/list-report.html.twig', [
  2976.             'reportList' => $reportList,
  2977.             'leadStatus' => $leadStatus,
  2978.             'totalReport' => $total
  2979.         ]);
  2980.         $result['waitForPage'] = false;
  2981.         $result['content'] = [
  2982.             'html' => $body,
  2983.             'total' => 1
  2984.         ];
  2985.         $result['status'] = 'OK';
  2986.         return new JsonResponse($result);
  2987.     }
  2988.     /**
  2989.      * @param ProjectRepository $projectRepository
  2990.      * @param Request $request
  2991.      * @return Response
  2992.      */
  2993.     #[Route(path'/ajax/project/confirmed-summary'name'ajax_confirmed_summary')]
  2994.     public function ajaxProjectconfirmedSummary(ProjectRepository $projectRepositoryRequest $request): Response
  2995.     {
  2996.         // Example params:
  2997.         // http://localhost:8000/ajax/project/prospect-summary?orderBy=projectCount&order=DESC&pic=&client=&startDate=2022-10-01&endDate=2023-12-31
  2998.         //        $user = $this->getUser();
  2999.         $page intval($request->query->get('page') - 1);
  3000.         if ($page 0$page 0;
  3001.         $limit intval($request->query->get('limit'));
  3002.         if ($limit === 0$limit 20;
  3003.         $keyword $request->get('keyword');
  3004.         $order $request->get('order');
  3005.         $orderBy $request->get('orderBy');
  3006.         $startDate $request->get('start');
  3007.         $endDate $request->get('end');
  3008.         $client $request->get('client');
  3009.         $pic $request->get('pic');
  3010.         $period $request->get('period');
  3011.         $year $request->get('year');
  3012.         $retainer $request->get('retainer');
  3013.         $waitForPage $request->query->get('waitForPage');
  3014.         $reportList $projectRepository->findConfirmedSummaryByPage($keyword$order$orderBy$startDate$endDate$client$pic$period$year$retainer);
  3015.         $total = [];
  3016.         $total['plannedRevenue'] = 0;
  3017.         $total['estimatedMargin'] = 0;
  3018.         $total['estimatedVendorCost'] = 0;
  3019.         $total['projectCount'] = 0;
  3020.         $total['clients'] = 0;
  3021.         foreach ($reportList as $report) {
  3022.             $total['plannedRevenue'] += $report['plannedRevenue'];
  3023.             $total['estimatedMargin'] += $report['estimatedMargin'];
  3024.             $total['estimatedVendorCost'] += $report['estimatedVendorCost'];
  3025.             $total['projectCount'] += $report['projectCount'];
  3026.             $total['clients'] += $report['clients'];
  3027.         }
  3028.         $body $this->renderView('private/project-management/report/components/list-report-confirmed.html.twig', [
  3029.             'reportList' => $reportList,
  3030.             // 'leadStatus' => $leadStatus,
  3031.             'totalReport' => $total
  3032.         ]);
  3033.         $result['waitForPage'] = false;
  3034.         $result['content'] = [
  3035.             'html' => $body,
  3036.             'total' => 1
  3037.         ];
  3038.         $result['status'] = 'OK';
  3039.         return new JsonResponse($result);
  3040.     }
  3041.     /**
  3042.      * @param Request $request
  3043.      * @param ProjectRepository $projectRepository
  3044.      * @param TranslatorInterface $translator
  3045.      * @param LogService $log
  3046.      * @return Response
  3047.      */
  3048.     #[Route(path'/ajax/project/duplicate'name'ajax_duplicate_project')]
  3049.     public function ajaxDuplicateProject(Request $requestProjectRepository $projectRepositoryTranslatorInterface $translatorLogService $logWebhookService $webhook): Response
  3050.     {
  3051.         $projectId intval($request->get('id'));
  3052.         $project $projectRepository->find(intval($projectId));
  3053.         if (!$project) {
  3054.             $result['status'] = 'error';
  3055.             $result['error'] = 'Project not found';
  3056.             return new JsonResponse($result);
  3057.         }
  3058.         $user $this->getUser();
  3059.         /*
  3060.         $newProject = new Project();
  3061.         $dateForStr = new \DateTime();
  3062.         $newProject->setClient($project->getClient());
  3063.         $newProject->setName($project->getName() . "_" . $dateForStr->format('Y-m-d'));
  3064.         $newProject->setDescription("");
  3065.         $newProject->setCurrency($project->getCurrency());
  3066.         $newProject->setCreatedBy($user);
  3067.         $newProject->setCreatedAt(new \DateTime());
  3068.         $newProject->setUpdatedAt(new \DateTime());
  3069.         //        $newProject->setStartDate($project->getStartDate());
  3070.         //        $newProject->setEndDate($project->getEndDate());
  3071.         $newProject->setPersonInCharge($project->getPersonInCharge());
  3072.         $newProject->setStatus($project->getStatus());
  3073.         $newProject->setRetainer(0);
  3074.         $newProject->setLead($project->getLead());
  3075.         $newProject->setType($project->getType());
  3076.         */
  3077.         
  3078.         $newProject = clone $project;
  3079.         // Update the name with a timestamp
  3080.         $dateForStr = new \DateTime();
  3081.         $newProject->setName($project->getName() . "_" $dateForStr->format('Y-m-d'));
  3082.         // Set other properties as needed
  3083.         $newProject->setDescription("");
  3084.         $newProject->setCreatedBy($user);
  3085.         $newProject->setCreatedAt(new \DateTime());
  3086.         $newProject->setUpdatedAt(new \DateTime());
  3087.         $newProject->setGeneratedId(null);
  3088.         $newProject->setStartDate(null);
  3089.         $newProject->setEndDate(null);
  3090.         $newProject->setLeadDate(new \DateTime());
  3091.         $newProject->setProposalDate(new \DateTime());
  3092.         $newProject->setWinDate(new \DateTime());
  3093.         $newProject->setProposalFollowUpDate(null);
  3094.         $newProject->setPresentationDate(null);
  3095.         $newProject->setNoEstimatedVendorCost(false);
  3096.         $newProject->setEstimatedVendorCost(0);
  3097.         $newProject->setEstimatedProfit(null);
  3098.         $newProject->setPlannedRevenue(null);
  3099.         $newProject->setPlannedRevenueUsd(null);
  3100.         $newProject->setRetainer(0);
  3101.         $newProject->setPlanFilename(null);
  3102.         $newProject->setPlanFilepath(null);
  3103.         $newProject->setPlanFiletype(null);
  3104.         $newProject->setPlanURL(null);
  3105.         $entityManager $this->getDoctrine()->getManager();
  3106.         $entityManager->persist($newProject);
  3107.         $entityManager->flush();
  3108.         
  3109.         if ($newProject->getGeneratedId() == null) {
  3110.             $newProject->setGeneratedId($newProject->getCreatedAt()->format('ym') . '-' sprintf('%04d'$newProject->getId()));
  3111.             $entityManager->flush();
  3112.             $entityManager->refresh($newProject);
  3113.         }
  3114.         $log->save($user, [
  3115.             'owner' => $user,
  3116.             'message' => 'log.project.duplicate',
  3117.             'new_data' => $newProject,
  3118.             'old_data' => "",
  3119.         ]);
  3120.         // $result['status'] = 'OK';
  3121.         // $result['id'] = $newProject->getId();
  3122.         return $this->redirectToRoute('view_project', ['_id' => $newProject->getId()]);
  3123.         // return new JsonResponse($result);
  3124.     }
  3125.     /**
  3126.      * @param UserRepository $userRepository
  3127.      * @param ProjectRepository $projectRepository
  3128.      * @param TranslatorInterface $translator
  3129.      * @return Response
  3130.      * @throws \Exception
  3131.      */
  3132.     #[Route(path'/project-management/project/pic/view/{_id}'defaults: ['_id' => 0], name'view_pic_project')]
  3133.     public function viewPicProject($_idUserRepository $userRepositoryProjectRepository $projectRepositoryTranslatorInterface $translatorIndustryClassificationRepository $industryClassificationRepositoryProjectClassificationRepository $projectClassificationRepository): Response
  3134.     {
  3135.         $user $this->getUser();
  3136.         $pic $userRepository->findByActiveEmail($_id) ?: null;
  3137.         // if (!$this->isGranted('ROLE_FINANCE') && !$this->isGranted('ROLE_TEAM_LEADER')) {
  3138.         //     throw new \Exception($translator->trans('messages.security.forbidden'));
  3139.         // };
  3140.         $totalProject $projectRepository->getTotalProjectByPic($pic);
  3141.         $industryClassification $industryClassificationRepository->findAll();
  3142.         $projectClassification $projectClassificationRepository->findAll();
  3143.         if (!$pic) {
  3144.             throw new \Exception($translator->trans('messages.security.forbidden'));
  3145.         } else {
  3146.             return $this->render('private/project-management/project/components/view-pic.html.twig', [
  3147.                 'pic' => $pic,
  3148.                 'totalProject' => $totalProject,
  3149.                 'industryClassification' => $industryClassification,
  3150.                 'projectClassification' => $projectClassification
  3151.             ]);
  3152.         }
  3153.     }
  3154.     /**
  3155.      * @param UserRepository $userRepository
  3156.      * @param ProjectRepository $projectRepository
  3157.      * @param TranslatorInterface $translator
  3158.      * @return Response
  3159.      * @throws \Exception
  3160.      */
  3161.     #[Route(path'/project-management/project/employee/view/{_id}'defaults: ['_id' => 0], name'view_user_project')]
  3162.     public function viewUserProject($_idUserRepository $userRepositoryProjectRepository $projectRepositoryTranslatorInterface $translatorIndustryClassificationRepository $industryClassificationRepositoryProjectClassificationRepository $projectClassificationRepository): Response
  3163.     {
  3164.         $user $this->getUser();
  3165.         // $targetedUser = $userRepository->findByActiveEmail($_id) ?: null;
  3166.         $targetedUser $userRepository->findByEmail($_id);
  3167.         // if (!$this->isGranted('ROLE_FINANCE') && !$this->isGranted('ROLE_TEAM_LEADER')) {
  3168.         //     throw new \Exception($translator->trans('messages.security.forbidden'));
  3169.         // };
  3170.         
  3171.         $totalProject $projectRepository->getTotalProjectByEmployee($targetedUser);
  3172.         $industryClassification $industryClassificationRepository->findAll();
  3173.         $projectClassification $projectClassificationRepository->findAll();
  3174.         
  3175.         // $totalProject = 0;
  3176.         if (!$targetedUser) {
  3177.             throw new \Exception($translator->trans('messages.security.forbidden'));
  3178.         } else {
  3179.             return $this->render('private/project-management/project/components/view-user-project-list.html.twig', [
  3180.                 'user' => $targetedUser,
  3181.                 'totalProject' => $totalProject,
  3182.                 'industryClassification' => $industryClassification,
  3183.                 'projectClassification' => $projectClassification
  3184.             ]);
  3185.         }
  3186.     }
  3187.     /**
  3188.      * @param UserRepository $userRepository
  3189.      * @param ProjectRepository $projectRepository
  3190.      * @param TranslatorInterface $translator
  3191.      * @return Response
  3192.      * @throws \Exception
  3193.      */
  3194.     #[Route(path'/project-management/project/client-pic/view/{_id}'defaults: ['_id' => 0], name'view_client_pic_project')]
  3195.     public function viewClientPicProject($_idClientContactRepository $clientContactRepositoryProjectRepository $projectRepositoryTranslatorInterface $translatorIndustryClassificationRepository $industryClassificationRepositoryProjectClassificationRepository $projectClassificationRepository): Response
  3196.     {
  3197.         $user $this->getUser();
  3198.         $clientPic $clientContactRepository->find($_id) ?: null;
  3199.         // if (!$this->isGranted('ROLE_FINANCE') && !$this->isGranted('ROLE_TEAM_LEADER')) {
  3200.         //     throw new \Exception($translator->trans('messages.security.forbidden'));
  3201.         // };
  3202.         $totalProject $projectRepository->getTotalProjectByClientPic($clientPic);
  3203.         $industryClassification $industryClassificationRepository->findAll();
  3204.         $projectClassification $projectClassificationRepository->findAll();
  3205.         if (!$clientPic) {
  3206.             throw new \Exception($translator->trans('messages.security.forbidden'));
  3207.         } else {
  3208.             return $this->render('private/project-management/project/components/view-pic-client.html.twig', [
  3209.                 'pic' => $clientPic,
  3210.                 'totalProject' => $totalProject,
  3211.                 'industryClassification' => $industryClassification,
  3212.                 'projectClassification' => $projectClassification
  3213.             ]);
  3214.         }
  3215.     }
  3216.     /**
  3217.      * @param UserRepository $userRepository
  3218.      * @param ProjectRepository $projectRepository
  3219.      * @param TranslatorInterface $translator
  3220.      * @return Response
  3221.      * @throws \Exception
  3222.      */
  3223.     #[Route(path'/project-management/project/vendor-pic/view/{_id}'defaults: ['_id' => 0], name'view_vendor_pic_project')]
  3224.     public function viewVendorPicProject($_idVendorContactRepository $vendorContactRepositoryProjectRepository $projectRepositoryTranslatorInterface $translatorIndustryClassificationRepository $industryClassificationRepositoryProjectClassificationRepository $projectClassificationRepository): Response
  3225.     {
  3226.         $user $this->getUser();
  3227.         $vendorPic $vendorContactRepository->find($_id) ?: null;
  3228.         // if (!$this->isGranted('ROLE_FINANCE') && !$this->isGranted('ROLE_TEAM_LEADER')) {
  3229.         //     throw new \Exception($translator->trans('messages.security.forbidden'));
  3230.         // };
  3231.         $totalProject $projectRepository->getTotalProjectByVendorPic($vendorPic);
  3232.         $industryClassification $industryClassificationRepository->findAll();
  3233.         $projectClassification $projectClassificationRepository->findAll();
  3234.         if (!$vendorPic) {
  3235.             throw new \Exception($translator->trans('messages.security.forbidden'));
  3236.         } else {
  3237.             return $this->render('private/project-management/project/components/view-pic-vendor.html.twig', [
  3238.                 'pic' => $vendorPic,
  3239.                 'totalProject' => $totalProject,
  3240.                 'industryClassification' => $industryClassification,
  3241.                 'projectClassification' => $projectClassification
  3242.             ]);
  3243.         }
  3244.     }
  3245.     #[Route(path'/project/get-project-file'name'get-project-file'methods: ['GET'])]
  3246.     public function getProjectFile(Request $requestUtilsService $utilsServiceParameterBagInterface $params)
  3247.     {
  3248.         $path $request->get('path');
  3249.         $name $request->get('name');
  3250.         if (!$path || strlen($path) == 0) {
  3251.             exit();
  3252.         }
  3253.         $preSignedAwsFileProd $utilsService->createPresignedUrl2($pathtrue);
  3254.         $preSignedAwsFileDev $utilsService->createPresignedUrl2($path);
  3255.         if ($utilsService->UR_exists($preSignedAwsFileProd)) {
  3256.             header('Content-Type: application/octet-stream');
  3257.             header("Content-Transfer-Encoding: Binary");
  3258.             header("Content-disposition: attachment; filename=\"" $name "\"");
  3259.             readfile($preSignedAwsFileProd);
  3260.             exit();
  3261.         } elseif ($utilsService->UR_exists($preSignedAwsFileDev)) {
  3262.             header('Content-Type: application/octet-stream');
  3263.             header("Content-Transfer-Encoding: Binary");
  3264.             header("Content-disposition: attachment; filename=\"" $name "\"");
  3265.             readfile($preSignedAwsFileDev);
  3266.             exit();
  3267.         } else {
  3268.             exit();
  3269.         }
  3270.     }
  3271.     /**
  3272.      * @param Request $request
  3273.      * @param ProjectRepository $projectRepository
  3274.      */
  3275.     #[Route(path'/ajax/project/get-cost-and-profit'name'ajax_get-project-cost-and-profit'methods: ['POST'])]
  3276.     public function getProjectCostAndProfit(Request $requestProjectRepository $projectRepository)
  3277.     {
  3278.         $idList $request->get('projects');
  3279.         $projects $projectRepository->findBy(array('id' => $idList));
  3280.         //        dd($projects);
  3281.         $result['status'] = 'OK';
  3282.         $result['projects'] = [];
  3283.         foreach ($projects as $project) {
  3284.             $data['profit1'] = 0;
  3285.             if ($project->getType() == 'CONFIRMED') {
  3286.                 $data['profit1'] = $project->getProjectProfit1();
  3287.             } else {
  3288.                 $data['profit1'] = $project->getEstimatedProfitUsd();
  3289.             } 
  3290.             //$data['profit1USD'] = $project->getType() == 'CONFIRMED' ? $project->getProjectProfit1() : $project->getEstimatedProfit();
  3291.             $data['cost'] = $project->getType() == 'CONFIRMED' $project->getProjectCost() : $project->getProjectEstimatedCostUsd();
  3292.             $data['id'] = $project->getId();
  3293.             array_push($result['projects'], $data);
  3294.         }
  3295.         return new JsonResponse($result);
  3296.     }
  3297.     /**
  3298.      * @param ProjectRepository $projectRepositor
  3299.      * @param TranslatorInterface $translator
  3300.      * @param LogService $log
  3301.      * @return Response
  3302.      * @throws \Exception
  3303.      */
  3304.     #[Route(path'/project-management/project/log/description/{_id}/{_type}'defaults: ['_id' => 0'_type' => null], name'view_project_log')]
  3305.     public function viewProjectLog($_id$_typeProjectRepository $projectRepositoryLogService $logTranslatorInterface $translator): Response
  3306.     {
  3307.         $project $projectRepository->find($_id) ?: null;
  3308.         
  3309.         if (!$project) {
  3310.             $result['status'] = 'ERROR';
  3311.         } else {
  3312.             $logData $log->data('log.project.edit'$project->getId(), $_type);
  3313.             $projectLeadStatus $this->getDoctrine()->getRepository(ProjectLeadStatus::class)->findAll();
  3314.             $projectLeadStatusArr = [];
  3315.             foreach ($projectLeadStatus as $pls) {
  3316.                 $projectLeadStatusArr[$pls->getLead()] = $pls->getName();
  3317.             }
  3318.             $result['status'] = 'OK';
  3319.             $result['content'] = $this->renderView('private/project-management/project/components/view-log.html.twig', [
  3320.                 'project' => $project,
  3321.                 'logType' => $_type,
  3322.                 'logData' => $logData,
  3323.                 'projectLeadStatus' => $projectLeadStatusArr
  3324.             ]);
  3325.         }
  3326.         return new JsonResponse($result);
  3327.     }
  3328.     #[Route(path'/project-management/project/email/client-feedback/send/{_id}'defaults: ['_id' => 0'_type' => null], name'send_email_client_feedback')]
  3329.     public function sendEmailClientFeedbackk($_idProjectService $projectServiceProjectRepository $projectRepositoryRequestStack $requestStack)
  3330.     {
  3331.         $baseUrl $requestStack->getCurrentRequest()->getSchemeAndHttpHost();
  3332.         $project $projectRepository->find($_id);
  3333.         if(!empty($project)){
  3334.             $projectService->projectClientFeedbackEmail($project$baseUrl);
  3335.         }
  3336.         
  3337.         $result['status'] = 'OK';
  3338.         return new JsonResponse($result);
  3339.     }
  3340.     /**
  3341.      * @param ProjectRepository $projectRepositor
  3342.      * @param TranslatorInterface $translator
  3343.      * @param LogService $log
  3344.      * @return Response
  3345.      * @throws \Exception
  3346.      */
  3347.     #[Route(path'/project-management/project/client-feedback/email/log/{_toAddress}/{_title}'defaults: ['_toAddress' => 0'_title' => null], name'view_client_feedback_email_log'requirements: ['_title' => '.+'])]
  3348.     public function viewClientFeedbackEmailLog($_toAddress$_titleProjectRepository $projectRepositoryProjectService $projectServiceLogService $logTranslatorInterface $translator): Response
  3349.     {   
  3350.         $emailLogs $projectService->getEmailLogFeedback($_toAddress$_title);
  3351.         $result['status'] = 'OK';
  3352.         $result['content'] = $this->renderView('private/project-management/project/components/view-email-log.html.twig', [
  3353.             'emailLogs' => $emailLogs,
  3354.         ]);
  3355.         return new JsonResponse($result);
  3356.     }
  3357. }