src/ApplicationBundle/Controller/ProjectController.php line 54

Open in your IDE?
  1. <?php
  2. namespace ApplicationBundle\Controller;
  3. use ApplicationBundle\Constants\GeneralConstant;
  4. use ApplicationBundle\Constants\HumanResourceConstant;
  5. use ApplicationBundle\Constants\ProjectConstant;
  6. use ApplicationBundle\Entity\Branch;
  7. use ApplicationBundle\Entity\DocumentData;
  8. use ApplicationBundle\Entity\EmployeeAttendance;
  9. use ApplicationBundle\Entity\PlanningItem;
  10. use ApplicationBundle\Entity\Project;
  11. use ApplicationBundle\Entity\ProjectBoq;
  12. use ApplicationBundle\Entity\ProjectSite;
  13. use ApplicationBundle\Entity\SalesProposal;
  14. use ApplicationBundle\Entity\TaskLog;
  15. use ApplicationBundle\Entity\Warehouse;
  16. use ApplicationBundle\Interfaces\SessionCheckInterface;
  17. use ApplicationBundle\Modules\Accounts\Accounts;
  18. use ApplicationBundle\Modules\Authentication\Constants\UserConstants; use ApplicationBundle\Modules\Api\Constants\ApiConstants;
  19. use ApplicationBundle\Modules\HumanResource\HumanResource;
  20. use ApplicationBundle\Modules\Inventory\Inventory;
  21. use ApplicationBundle\Modules\Project\ProjectM;
  22. use ApplicationBundle\Modules\Project\Service\ProjectTeamResolverService;
  23. use ApplicationBundle\Modules\Project\Service\ProjectTicketSummaryService;
  24. use ApplicationBundle\Modules\Sales\Client;
  25. use ApplicationBundle\Modules\Sales\Constants\SalesConstant;
  26. use ApplicationBundle\Modules\Sales\SalesOrderM;
  27. use ApplicationBundle\Modules\System\DeleteDocument;
  28. use ApplicationBundle\Modules\System\DocValidation;
  29. use ApplicationBundle\Modules\System\MiscActions;
  30. use ApplicationBundle\Modules\System\System;
  31. use ApplicationBundle\Modules\User\Company;
  32. use ApplicationBundle\Modules\User\Users;
  33. use CompanyGroupBundle\Entity\EntityFile;
  34. use Symfony\Component\HttpFoundation\JsonResponse;
  35. use Symfony\Component\HttpFoundation\Request;
  36. use Symfony\Component\HttpFoundation\Response;
  37. //use ApplicationBundle\Constants\GeneralConstant;
  38. //use ApplicationBundle\Modules\Sales\SalesOrderM;
  39. //use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  40. //use Symfony\Component\HttpFoundation\Request;
  41. class ProjectController extends GenericController implements SessionCheckInterface
  42. {
  43.     public function checkLogin(Request $request)
  44.     {
  45.         return true//becasue sessioncheck will never let you come here if you are not logged in
  46.     }
  47.     public function CreateNewAction(Request $request$projectId 0)
  48.     {
  49.         $companyId $this->getLoggedUserCompanyId($request);
  50.         $em_goc $this->getDoctrine()->getManager('company_group');
  51.         $em $this->getDoctrine()->getManager();
  52.         if ($request->isMethod('POST')) {
  53.             $entity_id array_flip(GeneralConstant::$Entity_list)['Project']; //change
  54.             $dochash $request->request->get('proj'); //change
  55.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  56.             $approveRole $request->request->get('approvalRole');
  57.             $approveHash $request->request->get('approvalHash');
  58.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  59.                 $loginId$approveRole$approveHash$projectId)) {
  60.                 $this->addFlash(
  61.                     'error',
  62.                     'Sorry Could not insert Data.'
  63.                 );
  64.             } else {
  65.                 $funcname 'Project';
  66.                 $doc_id $projectId;
  67.                 DeleteDocument::$funcname($em$doc_id0);
  68.                 $projectId ProjectM::CreateNew($projectId$this->getDoctrine()->getManager(), $request->request,
  69.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  70.                     $this->getLoggedUserCompanyId($request));
  71.                 ProjectM::UpdateWarehouseForPendingSites($em$companyId1$projectId);
  72.                 $file_path_list = [];
  73.                 $deliverable_file_path_list = [];
  74.                 if ($projectId != 0)
  75.                     if (!empty($request->files->get('deliverable_images', [])) || !empty($request->files->get('prerequisites_images', []))) {
  76.                         MiscActions::RemoveFilesForEntityDoc($em_goc'Project'$projectId);
  77.                         $storePath 'uploads/Voucher/';
  78.                         $path "";
  79.                         $file_path "";
  80.                         $session $request->getSession();
  81.                         MiscActions::RemoveExpiredFiles($em_goc);
  82.                         foreach ($request->files->get('deliverable_images', []) as $uploadedFileGG) {
  83.                             //            if($uploadedFile->getImage())
  84.                             //                var_dump($uploadedFile->getFile());
  85.                             //                var_dump($uploadedFile);
  86.                             $tempD $uploadedFileGG;
  87.                             if (!is_array($uploadedFileGG)) {
  88.                                 $uploadedFileGG = array();
  89.                                 $uploadedFileGG[] = $tempD;
  90.                             }
  91.                             foreach ($uploadedFileGG as $uploadedFile) {
  92.                                 if ($uploadedFile != null) {
  93.                                     $extension $uploadedFile->guessExtension();
  94.                                     $size $uploadedFile->getSize();
  95.                                     $fileName 'REQ_' $projectId '_' . (md5(uniqid())) . '.' $uploadedFile->guessExtension();
  96.                                     $path $fileName;
  97.                                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/' $storePath;
  98.                                     if (!file_exists($upl_dir)) {
  99.                                         mkdir($upl_dir0777true);
  100.                                     }
  101.                                     if (file_exists($upl_dir '' $path)) {
  102.                                         chmod($upl_dir '' $path0755);
  103.                                         unlink($upl_dir '' $path);
  104.                                     }
  105.                                     $file $uploadedFile->move($upl_dir$path);
  106.                                     $expireNever 1;
  107.                                     $expireTs 0;
  108.                                     $EntityFile = new EntityFile();
  109.                                     $EntityFile->setPath($this->container->getParameter('kernel.root_dir') . '/../web/' $storePath $path);
  110.                                     $EntityFile->setName($path);
  111.                                     $EntityFile->setMarker('_GEN_');
  112.                                     $EntityFile->setExtension($extension);
  113.                                     $EntityFile->setExpireTs($expireTs);
  114.                                     $EntityFile->setSize($size);
  115.                                     $EntityFile->setRelativePath($storePath $path);
  116.                                     $EntityFile->setEntityName('Project');
  117.                                     $EntityFile->setEntityBundle('ApplicationBundle');
  118.                                     $EntityFile->setEntityId($projectId);
  119.                                     $EntityFile->setEntityIdField('projectId');
  120.                                     $EntityFile->setModifyFieldSetter('setFiles');
  121.                                     $EntityFile->setDocIdForApplicant(0);
  122.                                     $EntityFile->setUserId($session->get(UserConstants::USER_ID0));
  123.                                     $EntityFile->setAppId($session->get(UserConstants::USER_APP_ID0));
  124.                                     $EntityFile->setEmployeeId($session->get(UserConstants::USER_EMPLOYEE_ID0));
  125.                                     $EntityFile->setUserType($session->get(UserConstants::USER_TYPE0));
  126.                                     $em_goc->persist($EntityFile);
  127.                                     $em_goc->flush();
  128.                                     $EntityFileId $EntityFile->getId();
  129.                                 }
  130.                                 if ($path != "")
  131.                                     $file_path_list[] = ($storePath $path);
  132.                             }
  133.                         }
  134.                         foreach ($request->files->get('prerequisites_images', []) as $uploadedFileGG) {
  135.                             //            if($uploadedFile->getImage())
  136.                             //                var_dump($uploadedFile->getFile());
  137.                             //                var_dump($uploadedFile);
  138.                             $tempD $uploadedFileGG;
  139.                             if (!is_array($uploadedFileGG)) {
  140.                                 $uploadedFileGG = array();
  141.                                 $uploadedFileGG[] = $tempD;
  142.                             }
  143.                             foreach ($uploadedFileGG as $uploadedFile) {
  144.                                 if ($uploadedFile != null) {
  145.                                     $extension $uploadedFile->guessExtension();
  146.                                     $size $uploadedFile->getSize();
  147.                                     $fileName 'REQ_' $projectId '_' . (md5(uniqid())) . '.' $uploadedFile->guessExtension();
  148.                                     $path $fileName;
  149.                                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/' $storePath;
  150.                                     if (!file_exists($upl_dir)) {
  151.                                         mkdir($upl_dir0777true);
  152.                                     }
  153.                                     if (file_exists($upl_dir '' $path)) {
  154.                                         chmod($upl_dir '' $path0755);
  155.                                         unlink($upl_dir '' $path);
  156.                                     }
  157.                                     $file $uploadedFile->move($upl_dir$path);
  158.                                     $expireNever 1;
  159.                                     $expireTs 0;
  160.                                     $EntityFile = new EntityFile();
  161.                                     $EntityFile->setPath($this->container->getParameter('kernel.root_dir') . '/../web/' $storePath $path);
  162.                                     $EntityFile->setName($path);
  163.                                     $EntityFile->setMarker('_GEN_');
  164.                                     $EntityFile->setExtension($extension);
  165.                                     $EntityFile->setExpireTs($expireTs);
  166.                                     $EntityFile->setSize($size);
  167.                                     $EntityFile->setRelativePath($storePath $path);
  168.                                     $EntityFile->setEntityName('Project');
  169.                                     $EntityFile->setEntityBundle('ApplicationBundle');
  170.                                     $EntityFile->setEntityId($projectId);
  171.                                     $EntityFile->setEntityIdField('projectId');
  172.                                     $EntityFile->setModifyFieldSetter('setFiles');
  173.                                     $EntityFile->setDocIdForApplicant(0);
  174.                                     $EntityFile->setUserId($session->get(UserConstants::USER_ID0));
  175.                                     $EntityFile->setAppId($session->get(UserConstants::USER_APP_ID0));
  176.                                     $EntityFile->setEmployeeId($session->get(UserConstants::USER_EMPLOYEE_ID0));
  177.                                     $EntityFile->setUserType($session->get(UserConstants::USER_TYPE0));
  178.                                     $em_goc->persist($EntityFile);
  179.                                     $em_goc->flush();
  180.                                     $EntityFileId $EntityFile->getId();
  181.                                 }
  182.                                 if ($path != "")
  183.                                     $deliverable_file_path_list[] = ($storePath $path);
  184.                             }
  185.                         }
  186.                         $g_path $this->container->getParameter('kernel.root_dir') . '/../web/' $storePath $path;
  187.                         $v $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(array(
  188.                             'projectId' => $projectId,
  189.                         ));
  190.                         if ($v) {
  191.                             $v->setPreRequisiteFiles(implode(','$file_path_list));
  192.                             $v->setDeliverableFiles(implode(','$deliverable_file_path_list));
  193.                             $em->flush();
  194.                         } else {
  195.                         }
  196.                     }
  197.                 //now add Approval info
  198.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  199.                 $approveRole 1;  //created
  200.                 $options = array(
  201.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  202.                     'notification_server' => $this->container->getParameter('notification_server'),
  203.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  204.                     'url' => $this->generateUrl(
  205.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['Project']]
  206.                         ['entity_view_route_path_name']
  207.                     )
  208.                 );
  209.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  210.                     array_flip(GeneralConstant::$Entity_list)['Project'],
  211.                     $projectId,
  212.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  213.                 );
  214.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['Project'],
  215.                     $projectId,
  216.                     $loginId,
  217.                     $approveRole,
  218.                     $request->request->get('approvalHash'));
  219.                 $this->addFlash(
  220.                     'success',
  221.                     'New Project Created'
  222.                 );
  223.                 if ($request->request->get('projectType'0) == 6) {
  224.                     $url $this->generateUrl(
  225.                         'create_project_wp'
  226.                     );
  227.                 } else
  228.                     $url $this->generateUrl(
  229.                         'view_project_details'
  230.                     );
  231.                 System::AddNewNotification(
  232.                     $this->container->getParameter('notification_enabled'),
  233.                     $this->container->getParameter('notification_server'),
  234.                     $request->getSession()->get(UserConstants::USER_APP_ID),
  235.                     $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  236.                     "A New Project : " $dochash " Has Been Created And is Under Processing",
  237.                     'all',
  238.                     '',
  239.                     'information',
  240.                     $url "/" $projectId,
  241.                     "New Project"
  242.                 );
  243.                 //marketing team
  244.                 System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  245.                     "You Have been added to the Marketing team for project : " $dochash "  ",
  246.                     'user',
  247.                     $request->request->get('marketing_team'null),
  248.                     'information',
  249.                     $url "/" $projectId,
  250.                     "Project Marketing Assignment"
  251.                 );
  252.                 //material team
  253.                 System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  254.                     "You Have been added to the Engineering team for project : " $dochash "  ",
  255.                     'user',
  256.                     $request->request->get('material_team'null),
  257.                     'information',
  258.                     $url "/" $projectId,
  259.                     "Project Engineering Assignment"
  260.                 );
  261.                 //Design team
  262.                 System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  263.                     "You Have been added to the Financial Designing team for project : " $dochash "  ",
  264.                     'user',
  265.                     $request->request->get('designing_team'null),
  266.                     'information',
  267.                     $url "/" $projectId,
  268.                     "Project Designing Assignment"
  269.                 );
  270.                 //implementing team
  271.                 System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  272.                     "You Have been added to the implementation team for project : " $dochash "  ",
  273.                     'user',
  274.                     $request->request->get('implementing_team'null),
  275.                     'information',
  276.                     $url "/" $projectId,
  277.                     "Project Implemntation Assignment"
  278.                 );
  279.                 //technician team
  280.                 System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  281.                     "You Have been added to the implementation team for project : " $dochash "  ",
  282.                     'user',
  283.                     $request->request->get('technician_team'null),
  284.                     'information',
  285.                     $url "/" $projectId,
  286.                     "Project Technician Assignment"
  287.                 );
  288.                 //Billing team
  289.                 System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  290.                     "You Have been added to the Billing team for project : " $dochash "  ",
  291.                     'user',
  292.                     $request->request->get('billing_team'null),
  293.                     'information',
  294.                     $url "/" $projectId,
  295.                     "Project Billing Assignment"
  296.                 );
  297.                 return $this->redirect($url "/" $projectId);
  298.             }
  299.         }
  300.         $em $this->getDoctrine()->getManager();
  301.         //for edits
  302.         $extDocData = [];
  303.         $extDocDetailsData = [];
  304.         $projectSiteList = [];
  305.         $assignedProjectSiteList = [];
  306.         if ($projectId == 0) {
  307.             $projectSiteList ProjectM::ProjectSiteList($em, [], $companyId);
  308.         } else {
  309.             $extTrans $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  310.                 array(
  311.                     'projectId' => $projectId///material
  312.                 )
  313.             );
  314.             $assignedProjectSiteList ProjectM::ProjectSiteList($em$projectId$companyId);
  315.             $projectSiteList ProjectM::ProjectSiteList($em, [], $companyId);
  316.             //now if its not editable, redirect to view
  317.             if ($extTrans) {
  318.                 if ($extTrans->getEditFlag() != && $request->query->get('forceEdit'0) == 0) {
  319.                     $url $this->generateUrl(
  320.                         'view_project'
  321.                     );
  322.                     return $this->redirect($url "/" $projectId);
  323.                 } else {
  324.                     $extDocData $extTrans;
  325. //                    $extDocDetailsData=Accounts::GetVoucherDataForEdit($em,$projectId);
  326.                 }
  327.             }
  328.         }
  329.         return $this->render('@Project/pages/input_forms/new_project.html.twig',
  330.             array(
  331.                 'page_title' => 'New Project',
  332.                 'projectList' => ProjectM::GetProjectList($em),
  333.                 'clients' => SalesOrderM::GetClientList($em),
  334.                 'clients_by_ac_head' => SalesOrderM::GetClientListByAcHead($em),
  335.                 'users' => Users::getUserListById($em),
  336.                 'sales_person_list' => Client::SalesPersonList($this->getDoctrine()->getManager()),
  337.                 'stages' => ProjectConstant::$projectStages,
  338.                 'extDocData' => $extDocData,
  339.                 'projectSiteList' => $projectSiteList,
  340.                 'assignedProjectSiteList' => $assignedProjectSiteList,
  341.                 'projectTypes' => ProjectM::getProjectTypesFromConfigFile($this->container->getParameter('kernel.root_dir')),
  342.                 'categories' => $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy(
  343.                     array(
  344.                         "status" => GeneralConstant::ACTIVE,
  345.                         'CompanyId' => $this->getLoggedUserCompanyId($request),
  346.                     )
  347.                 ),
  348.             )
  349.         );
  350.     }
  351.     public function UpdateProjectAction(Request $request$projectId)
  352.     {
  353.         $companyId $this->getLoggedUserCompanyId($request);
  354.         $em $this->getDoctrine()->getManager();
  355.         $em_goc $this->getDoctrine()->getManager('company_group');
  356.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  357.         if (!$project) {
  358.             $this->addFlash('error''Project not found.');
  359.             return $this->redirectToRoute('view_project');
  360.         }
  361.         if ($request->isMethod('POST')) {
  362.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  363.             $approveRole $request->request->get('approvalRole');
  364.             $approveHash $request->request->get('approvalHash');
  365.             $entity_id array_flip(GeneralConstant::$Entity_list)['Project'];
  366.             $dochash $request->request->get('proj');
  367.             if (!DocValidation::isInsertable($em$entity_id$dochash$loginId$approveRole$approveHash$projectId)) {
  368.                 $this->addFlash('error''Update validation failed.');
  369.             } else {
  370.                 // Perform project update logic
  371.                 $updatedProjectId ProjectM::UpdateProject($projectId$em$request->request$loginId$companyId);
  372.                 // Handle files
  373.                 if (!empty($request->files->get('deliverable_images', [])) || !empty($request->files->get('prerequisites_images', []))) {
  374.                     MiscActions::RemoveFilesForEntityDoc($em_goc'Project'$projectId);
  375.                     $storePath 'uploads/Voucher/';
  376.                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/' $storePath;
  377.                     $filePaths = ['deliverables' => [], 'prerequisites' => []];
  378.                     foreach (['deliverable_images' => 'deliverables''prerequisites_images' => 'prerequisites'] as $inputKey => $type) {
  379.                         foreach ((array)$request->files->get($inputKey, []) as $uploadedFileGroup) {
  380.                             if (!is_array($uploadedFileGroup)) {
  381.                                 $uploadedFileGroup = [$uploadedFileGroup];
  382.                             }
  383.                             foreach ($uploadedFileGroup as $file) {
  384.                                 if ($file) {
  385.                                     $filename 'REQ_' $projectId '_' md5(uniqid()) . '.' $file->guessExtension();
  386.                                     if (!file_exists($upl_dir)) {
  387.                                         mkdir($upl_dir0777true);
  388.                                     }
  389.                                     if (file_exists($upl_dir $filename)) {
  390.                                         unlink($upl_dir $filename);
  391.                                     }
  392.                                     $file->move($upl_dir$filename);
  393.                                     $entityFile = new EntityFile();
  394.                                     $entityFile->setPath($upl_dir $filename);
  395.                                     $entityFile->setName($filename);
  396.                                     $entityFile->setMarker('_GEN_');
  397.                                     $entityFile->setExtension($file->guessExtension());
  398.                                     $entityFile->setExpireTs(0);
  399.                                     $entityFile->setSize($file->getSize());
  400.                                     $entityFile->setRelativePath($storePath $filename);
  401.                                     $entityFile->setEntityName('Project');
  402.                                     $entityFile->setEntityBundle('ApplicationBundle');
  403.                                     $entityFile->setEntityId($projectId);
  404.                                     $entityFile->setEntityIdField('projectId');
  405.                                     $entityFile->setModifyFieldSetter('setFiles');
  406.                                     $entityFile->setDocIdForApplicant(0);
  407.                                     $entityFile->setUserId($request->getSession()->get(UserConstants::USER_ID));
  408.                                     $entityFile->setAppId($request->getSession()->get(UserConstants::USER_APP_ID));
  409.                                     $entityFile->setEmployeeId($request->getSession()->get(UserConstants::USER_EMPLOYEE_ID));
  410.                                     $entityFile->setUserType($request->getSession()->get(UserConstants::USER_TYPE));
  411.                                     $em_goc->persist($entityFile);
  412.                                     $em_goc->flush();
  413.                                     $filePaths[$type][] = $storePath $filename;
  414.                                 }
  415.                             }
  416.                         }
  417.                     }
  418.                     $project->setDeliverableFiles(implode(','$filePaths['deliverables']));
  419.                     $project->setPreRequisiteFiles(implode(','$filePaths['prerequisites']));
  420.                     $em->flush();
  421.                 }
  422.                 // Approval Info Update
  423.                 $options = [
  424.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  425.                     'notification_server' => $this->container->getParameter('notification_server'),
  426.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  427.                     'url' => $this->generateUrl(
  428.                         GeneralConstant::$Entity_list_details[$entity_id]['entity_view_route_path_name']
  429.                     )
  430.                 ];
  431.                 System::setApprovalInfo($em$options$entity_id$projectId$loginId);
  432.                 System::createEditSignatureHash($em$entity_id$projectId$loginId$approveRole$approveHash);
  433.                 $this->addFlash('success''Project updated successfully.');
  434.                 return $this->redirectToRoute('view_project_details', ['id' => $projectId]);
  435.             }
  436.         }
  437.         return $this->render('@Project/pages/input_forms/new_project.html.twig', [
  438.             'page_title' => 'Edit Project',
  439.             'projectList' => ProjectM::GetProjectList($em),
  440.             'clients' => SalesOrderM::GetClientList($em),
  441.             'clients_by_ac_head' => SalesOrderM::GetClientListByAcHead($em),
  442.             'users' => Users::getUserListById($em),
  443.             'sales_person_list' => Client::SalesPersonList($em),
  444.             'stages' => ProjectConstant::$projectStages,
  445.             'extDocData' => $project,
  446.             'projectSiteList' => ProjectM::ProjectSiteList($em, [], $companyId),
  447.             'assignedProjectSiteList' => ProjectM::ProjectSiteList($em$projectId$companyId),
  448.             'projectTypes' => ProjectM::getProjectTypesFromConfigFile($this->container->getParameter('kernel.root_dir')),
  449.             'categories' => $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy([
  450.                 'status' => GeneralConstant::ACTIVE,
  451.                 'CompanyId' => $companyId,
  452.             ]),
  453.         ]);
  454.     }
  455.     public function ProjectSiteExcelUploadAction(Request $request)
  456.     {
  457.         $em $this->getDoctrine()->getManager();
  458.         $companyId $this->getLoggedUserCompanyId($request);
  459.         $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  460.         if ($request->isMethod('POST')) {
  461.             $post $request->request;
  462.             $path "";
  463.             $file_path "";
  464.             //            var_dump($request->files);
  465.             //        var_dump($request->getFile());
  466.             foreach ($request->files as $uploadedFile) {
  467.                 //            if($uploadedFile->getImage())
  468.                 //                var_dump($uploadedFile->getFile());
  469.                 //                var_dump($uploadedFile);
  470.                 if ($uploadedFile != null) {
  471.                     $fileName md5(uniqid()) . '.' $uploadedFile->guessExtension();
  472.                     $path $fileName;
  473.                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/FileUploads/';
  474.                     if (!file_exists($upl_dir)) {
  475.                         mkdir($upl_dir0777true);
  476.                     }
  477.                     $file $uploadedFile->move($upl_dir$path);
  478.                 }
  479.             }
  480.             //        print_r($file);
  481.             if ($path != "")
  482.                 $file_path 'uploads/FileUploads/' $path;
  483.             $g_path $this->container->getParameter('kernel.root_dir') . '/../web/uploads/FileUploads/' $path;
  484.             //
  485.             //            $img_file = file_get_contents($g_path);
  486.             //            $r=base64_encode($img_file);
  487.             $row 1;
  488.             $csv_data = [];
  489.             if (($handle fopen($g_path"r")) !== FALSE) {
  490.                 while (($data fgetcsv($handle1000",")) !== FALSE) {
  491.                     $num count($data);
  492.                     $csv_data[$row] = $data;
  493.                     //                    echo "<p> $num fields in line $row: <br /></p>\n";
  494.                     $row++;
  495.                     //                    for ($c=0; $c < $num; $c++) {
  496.                     //                        echo $data[$c] . "<br />\n";
  497.                     //                    }
  498.                 }
  499.                 fclose($handle);
  500.             }
  501.             //now getting the relevant checks
  502.             $check_list = [];
  503.             foreach ($csv_data as $key => $data_row) {
  504.                 //skip 1st row
  505.                 if ($key == 1)
  506.                     continue;
  507.                 //zone,sitename,site_Location,client_name,father_name,address,address_region,contact_number,allocation
  508.                 if ($data_row[1] == '')
  509.                     continue;
  510.                 $projectSite = new ProjectSite();
  511.                 $projectSite->setProjectId(null);
  512.                 $projectSite->setZone($data_row[0]);
  513.                 $projectSite->setSiteName($data_row[1]);
  514.                 $projectSite->setSiteLocation($data_row[2]);
  515.                 $projectSite->setClientName($data_row[3]);
  516.                 $projectSite->setFatherName($data_row[4]);
  517.                 $projectSite->setContactNumber($data_row[7]);
  518.                 $projectSite->setAddress($data_row[5]);
  519.                 $projectSite->setAddressRegion($data_row[6]);
  520.                 $projectSite->setAllocation($data_row[8]);
  521.                 $projectSite->setLatitude($data_row[9]);
  522.                 $projectSite->setLongitude($data_row[10]);
  523.                 $projectSite->setCompanyId($companyId);
  524.                 $projectSite->setCreatedLoginId($loginId);
  525.                 $projectSite->setEditedLoginId($loginId);
  526.                 $em->persist($projectSite);
  527.                 $em->flush();
  528.             }
  529.             return new JsonResponse(array(
  530.                 "success" => true,
  531.                 "file_path" => $file_path,
  532.                 "csv_data" => $csv_data,
  533. //                "check_data" => $check_list,
  534.                 //                "debug_data"=>System::encryptSignature($r)
  535.             ));
  536.         }
  537.         return new JsonResponse(array(
  538.             "success" => false,
  539.             "file_path" => '',
  540.         ));
  541.     }
  542.     public function CreateProjectSiteAction(Request $request$id)
  543.     {
  544.         $cc_id '';
  545.         $cc_name '';
  546.         $em $this->getDoctrine()->getManager();
  547.         $companyId $this->getLoggedUserCompanyId($request);
  548.         if ($request->isMethod('POST')) {
  549.             $new_cc = [];
  550.             $regionId 0;
  551.             $warehouseId $request->request->get('warehouseId');
  552.             if ($request->request->get('branchId') != '' && $request->request->get('branchId') != 0) {
  553.                 $em $this->getDoctrine()->getManager();
  554.                 $new_cc $this->getDoctrine()
  555.                     ->getRepository('ApplicationBundle\\Entity\\Branch')
  556.                     ->findOneBy(
  557.                         array(
  558.                             'branchId' => $request->request->get('branchId'),
  559.                         )
  560.                     );
  561.                 $new_cc->setName($request->request->get('name'));
  562.                 $new_cc->setAddress($request->request->get('address'));
  563.                 $new_cc->setDeliveryAddress($request->request->get('deliveryAddress'));
  564.                 $new_cc->setBillingAddress($request->request->get('billingAddress'));
  565.                 $new_cc->setWarehouseId($request->request->get('warehouseId'));
  566.                 $new_cc->setCashHeadIds(json_encode($request->request->get('cashHeadIds')));
  567.                 $new_cc->setBankHeadIds(json_encode($request->request->get('bankHeadIds')));
  568.                 $new_cc->setCompanyId($companyId);
  569.                 $new_cc->setType($request->request->get('type'));
  570.                 $new_cc->setSalesMethod($request->request->get('salesMethod'));
  571.                 $new_cc->setDeliveryProcessType($request->request->get('deliveryProcessType'));
  572.                 $new_cc->setPaymentProcessType($request->request->get('paymentProcessType'));
  573.                 $em->flush();
  574.                 $branchId $new_cc->getBranchId();
  575.                 $this->addFlash(
  576.                     'success',
  577.                     'Branch Information Updated'
  578.                 );
  579.             } else {
  580.                 $new_cc = new Branch();
  581.                 $new_cc->setName($request->request->get('name'));
  582.                 $new_cc->setWarehouseId($request->request->get('warehouseId'));
  583.                 $new_cc->setCashHeadIds(json_encode($request->request->get('cashHeadIds')));
  584.                 $new_cc->setBankHeadIds(json_encode($request->request->get('bankHeadIds')));
  585.                 $new_cc->setCompanyId($companyId);
  586.                 $new_cc->setType($request->request->get('type'));
  587.                 $new_cc->setSalesMethod($request->request->get('salesMethod'));
  588.                 $new_cc->setDeliveryProcessType($request->request->get('deliveryProcessType'));
  589.                 $new_cc->setPaymentProcessType($request->request->get('paymentProcessType'));
  590.                 $em->persist($new_cc);
  591.                 $em->flush();
  592.                 $branchId $new_cc->getBranchId();
  593.                 $this->addFlash(
  594.                     'success',
  595.                     'New Branch Added'
  596.                 );
  597.             }
  598.             //now update salesperson on any client if available
  599.             if ($request->request->has('addWarehouseToSystem')) {
  600.                 if ($warehouseId == || $warehouseId == '') {
  601.                     $warehouse = new Warehouse();
  602.                     $warehouse->setCompanyId($companyId);
  603.                     $warehouse->setName($request->request->get('name'));
  604.                     $warehouse->setStatus(GeneralConstant::ACTIVE);
  605.                     $em->persist($warehouse);
  606.                     $em->flush();
  607.                     $new_cc->setWarehouseId($warehouse->getId());
  608.                     $em->flush();
  609.                 }
  610.             }
  611.             if ($request->request->has('addCashHeadToSystem')) {
  612.                 $id_list json_decode($new_cc->getCashHeadIds(), true);
  613.                 if ($id_list == [] || $id_list == null) {
  614.                     if ($id_list == null)
  615.                         $id_list = [];
  616.                     //now get the cash parent for branch head
  617.                     $par_set $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
  618.                         'name' => 'branch_cash_parent'
  619.                     ));
  620.                     $par_head '';
  621.                     if ($par_set)
  622.                         $par_head $par_set->getData();
  623.                     if ($par_head == '') {
  624.                         $this->addFlash(
  625.                             'error',
  626.                             'Could not add cash head. Parent not found in settings'
  627.                         );
  628.                     } else {
  629.                         //create The head
  630.                         $accHead Accounts:: CreateNewHead($emGeneralConstant::OPENING_YEAR$par_head'Cash at ' $new_cc->getName(), ''00'dr'$request->getSession()->get(UserConstants::USER_LOGIN_ID));
  631.                         $id_list Accounts::addNumberToArrayIfNotExists($accHead$id_list);
  632.                         $new_cc->setCashHeadIds(json_encode($id_list));
  633.                         $em->flush();
  634.                     }
  635.                 }
  636.             }
  637.             if ($request->request->has('addBankHeadToSystem')) {
  638.                 $id_list json_decode($new_cc->getBankHeadIds(), true);
  639.                 if ($id_list == [] || $id_list == null) {
  640.                     if ($id_list == null)
  641.                         $id_list = [];
  642.                     //now get the bank parent for branch head
  643.                     $par_set $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
  644.                         'name' => 'branch_bank_parent'
  645.                     ));
  646.                     $par_head '';
  647.                     if ($par_set)
  648.                         $par_head $par_set->getData();
  649.                     if ($par_head == '') {
  650.                         $this->addFlash(
  651.                             'error',
  652.                             'Could not add bank head. Parent not found in settings'
  653.                         );
  654.                     } else {
  655.                         //create The head
  656.                         $accHead Accounts:: CreateNewHead($emGeneralConstant::OPENING_YEAR$par_head'Bank at ' $new_cc->getName(), ''00'dr'$request->getSession()->get(UserConstants::USER_LOGIN_ID));
  657.                         $id_list Accounts::addNumberToArrayIfNotExists($accHead$id_list);
  658.                         $new_cc->setBankHeadIds(json_encode($id_list));
  659.                         $em->flush();
  660.                     }
  661.                 }
  662.             }
  663.         }
  664.         $extData = [];
  665.         if ($id != 0) {
  666.             $extData $this->getDoctrine()
  667.                 ->getRepository('ApplicationBundle\\Entity\\Branch')
  668.                 ->findOneBy(
  669.                     array(
  670.                         'branchId' => $id
  671.                     )
  672.                 );
  673. //            $cc_data_list = [];
  674. //            foreach ($cc_data as $value) {
  675. //                $cc_data_list[$value->getSupplierCategoryId()]['id'] = $value->getSupplierCategoryId();
  676. //                $cc_data_list[$value->getSupplierCategoryId()]['name'] = $value->getName();
  677. //
  678. //                if ($value->getSupplierCategoryId() == $id) {
  679. //                    $cc_id = $value->getSupplierCategoryId();
  680. //                    $cc_name = $value->getName();
  681. //                }
  682. //            }
  683.         }
  684.         return $this->render('@Project/pages/input_forms/ProjectSite.html.twig',
  685.             array(
  686.                 'page_title' => 'Project Site',
  687.                 'siteList' => $this->getDoctrine()
  688.                     ->getRepository('ApplicationBundle\\Entity\\ProjectSite')
  689.                     ->findBy(
  690.                         array(
  691.                             'CompanyId' => $companyId
  692.                         )
  693.                     ),
  694.                 'extData' => $extData,
  695.                 'headList' => Accounts::getParentLedgerHeads($em),
  696.                 'branchTypes' => SalesConstant::$branchTypes,
  697.                 'branchTypeDetails' => SalesConstant::$branchTypeDetails,
  698.                 'salesMethodList' => SalesConstant::$salesMethod,
  699.                 'deliveryProcessTypes' => SalesConstant::$deliveryProcessType,
  700.                 'paymentProcessTypes' => SalesConstant::$paymentProcessType,
  701.                 'warehouseList' => Inventory::WarehouseList($em),
  702.                 'sales_person_list' => Client::SalesPersonList($this->getDoctrine()->getManager()),
  703. //                'countryList'=>SalesOrderM::Co
  704.             )
  705.         );
  706.     }
  707.     /**
  708.      * JSON feed of a project's work-plan tasks for the cp-shell gantt Timeline.
  709.      * Normalises the mixed seconds/milliseconds timestamps and strips item_alias
  710.      * HTML so the front-end gets clean {id,parentId,name,start,end,status,pct}.
  711.      */
  712.     public function ProjectWpTimelineDataAction(Request $request$projectId 0)
  713.     {
  714.         $conn $this->getDoctrine()->getManager()->getConnection();
  715.         $rows = [];
  716.         try {
  717.             $rows $conn->fetchAllAssociative(
  718.                 "SELECT id, parent_id, item_alias AS name,
  719.                         estimated_start_time_ts s, estimated_completion_time_ts e,
  720.                         actual_start_time_ts as_s, actual_completion_time_ts as_e,
  721.                         task_status status, completion_percentage pct, sequence,
  722.                         dependency_planning_data dpd, dependency_planning_ids dpids, data meta
  723.                    FROM planning_item
  724.                   WHERE project_id = :p AND reference_type = 1 AND (delete_flag IS NULL OR delete_flag = 0)
  725.                   ORDER BY COALESCE(sequence, id) ASC",
  726.                 ['p' => (int) $projectId]
  727.             );
  728.         } catch (\Throwable $e) { $rows = []; }
  729.         $norm = function ($v) {
  730.             $v = (float) $v;
  731.             if ($v <= 0) { return 0; }
  732.             if ($v 9999999999) { $v $v 1000; } // milliseconds → seconds
  733.             return (int) $v;
  734.         };
  735.         $tasks = [];
  736.         $nowTs time();
  737.         foreach ($rows as $r) {
  738.             $s $norm($r['s']); $e $norm($r['e']);
  739.             // Fall back to the schedule stored in the data JSON baseline (some tasks
  740.             // keep dates there rather than the estimated_* columns).
  741.             if (!$s || !$e) {
  742.                 $meta json_decode((string) ($r['meta'] ?? ''), true);
  743.                 $bl = (is_array($meta) && isset($meta['baseline']) && is_array($meta['baseline'])) ? $meta['baseline'] : [];
  744.                 if (!$s && isset($bl['startTs'])) { $s $norm($bl['startTs']); }
  745.                 if (!$e && isset($bl['endTs'])) { $e $norm($bl['endTs']); }
  746.             }
  747.             // Unscheduled tasks still appear (anchored to today) so they can be
  748.             // dragged onto the calendar — matches the old timeline's behaviour.
  749.             $unscheduled = (!$s && !$e);
  750.             if ($unscheduled) { $s $nowTs$e $nowTs; }
  751.             if (!$e) { $e $s; }
  752.             if (!$s) { $s $e; }
  753.             if ($e $s) { $e $s; }
  754.             $name trim(strip_tags((string) $r['name']));
  755.             // Predecessor ids: prefer the structured dependency_planning_data JSON,
  756.             // fall back to the CSV dependency_planning_ids.
  757.             $deps = []; $seen = [];
  758.             $dpd = (string) ($r['dpd'] ?? '');
  759.             if ($dpd !== '') {
  760.                 $arr json_decode($dpdtrue);
  761.                 if (is_array($arr)) {
  762.                     foreach ($arr as $dep) {
  763.                         $did is_array($dep) ? (int) ($dep['id'] ?? 0) : (int) $dep;
  764.                         $lag is_array($dep) ? (int) ($dep['lagDays'] ?? 0) : 0;
  765.                         if ($did && !isset($seen[$did])) { $seen[$did] = 1$deps[] = ['id' => $did'lag' => $lag]; }
  766.                     }
  767.                 }
  768.             }
  769.             if (empty($deps) && trim((string) ($r['dpids'] ?? '')) !== '') {
  770.                 foreach (explode(',', (string) $r['dpids']) as $x) { $x = (int) trim($x); if ($x && !isset($seen[$x])) { $seen[$x] = 1$deps[] = ['id' => $x'lag' => 0]; } }
  771.             }
  772.             $tasks[] = [
  773.                 'id' => (int) $r['id'],
  774.                 'parentId' => (int) $r['parent_id'],
  775.                 'name' => $name !== '' $name : ('Task #' . (int) $r['id']),
  776.                 'start' => $s'end' => $e,
  777.                 'actualStart' => $norm($r['as_s']), 'actualEnd' => $norm($r['as_e']),
  778.                 'status' => (string) $r['status'],
  779.                 'pct' => round((float) $r['pct'], 1),
  780.                 'deps' => array_values($deps),
  781.                 'unscheduled' => $unscheduled,
  782.             ];
  783.         }
  784.         return new \Symfony\Component\HttpFoundation\JsonResponse(['tasks' => $tasks]);
  785.     }
  786.     /**
  787.      * Persist a drag-reschedule from the gantt: update one planning item's
  788.      * estimated start/end (Unix seconds, matching the rest of the app). Direct
  789.      * update, tenant-scoped, fail-safe JSON.
  790.      */
  791.     public function ProjectWpTimelineUpdateAction(Request $request)
  792.     {
  793.         $id = (int) $request->request->get('id');
  794.         $start = (int) $request->request->get('start');
  795.         $end = (int) $request->request->get('end');
  796.         if ($id <= || $start <= || $end <= || $end $start) {
  797.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Invalid schedule.']);
  798.         }
  799.         try {
  800.             $conn $this->getDoctrine()->getManager()->getConnection();
  801.             $loginId = (int) $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  802.             $aff $conn->executeStatement(
  803.                 "UPDATE planning_item
  804.                     SET estimated_start_time_ts = :s, estimated_completion_time_ts = :e, edited_login_id = :l
  805.                   WHERE id = :id AND (delete_flag IS NULL OR delete_flag = 0)",
  806.                 ['s' => $start'e' => $end'l' => $loginId'id' => $id]
  807.             );
  808.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => (bool) $aff'id' => $id'start' => $start'end' => $end]);
  809.         } catch (\Throwable $ex) {
  810.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Could not save.']);
  811.         }
  812.     }
  813.     /**
  814.      * Admin-only: set/clear a task's ACTUAL start & end (Unix seconds). Lets an
  815.      * admin backfill real dates for projects that ran before the work plan was
  816.      * created (and were tracked in Excel). Pass 0 to clear a field.
  817.      */
  818.     public function ProjectWpActualUpdateAction(Request $request)
  819.     {
  820.         if ((int) $request->getSession()->get(UserConstants::USER_TYPE) !== 1) {
  821.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Only an administrator can set actual dates.'], 403);
  822.         }
  823.         $id = (int) $request->request->get('id');
  824.         $as = (int) $request->request->get('actualStart');
  825.         $ae = (int) $request->request->get('actualEnd');
  826.         if ($id <= 0) {
  827.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Invalid task.']);
  828.         }
  829.         if ($as && $ae && $ae $as) {
  830.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Actual end is before actual start.']);
  831.         }
  832.         try {
  833.             $conn $this->getDoctrine()->getManager()->getConnection();
  834.             $loginId = (int) $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  835.             $conn->executeStatement(
  836.                 "UPDATE planning_item
  837.                     SET actual_start_time_ts = :as, actual_completion_time_ts = :ae, edited_login_id = :l
  838.                   WHERE id = :id AND (delete_flag IS NULL OR delete_flag = 0)",
  839.                 ['as' => $as'ae' => $ae'l' => $loginId'id' => $id]
  840.             );
  841.             // Note: affected-rows may be 0 when re-saving identical values; the
  842.             // statement still succeeded, so report success unless it threw.
  843.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'id' => $id'actualStart' => $as'actualEnd' => $ae]);
  844.         } catch (\Throwable $ex) {
  845.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Could not save actual dates.']);
  846.         }
  847.     }
  848.     /**
  849.      * Toggle a finish→start dependency from the gantt: taskId (successor) depends
  850.      * on dependsOnId (predecessor). If the link already exists it is removed,
  851.      * otherwise added. Guards self-links and direct 2-cycles. Keeps both
  852.      * dependency_planning_data (JSON) and dependency_planning_ids (CSV) in sync.
  853.      */
  854.     public function ProjectWpTimelineDependencyAction(Request $request)
  855.     {
  856.         $taskId = (int) $request->request->get('taskId');
  857.         $dependsOnId = (int) $request->request->get('dependsOnId');
  858.         if ($taskId <= || $dependsOnId <= || $taskId === $dependsOnId) {
  859.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Invalid link.']);
  860.         }
  861.         try {
  862.             $conn $this->getDoctrine()->getManager()->getConnection();
  863.             $decode = function ($id) use ($conn) {
  864.                 $raw = (string) $conn->fetchOne("SELECT dependency_planning_data FROM planning_item WHERE id = :id", ['id' => $id]);
  865.                 $arr $raw !== '' json_decode($rawtrue) : [];
  866.                 return is_array($arr) ? $arr : [];
  867.             };
  868.             // Prevent a direct 2-cycle (predecessor already depends on this task).
  869.             foreach ($decode($dependsOnId) as $d) {
  870.                 if ((int) (is_array($d) ? ($d['id'] ?? 0) : $d) === $taskId) {
  871.                     return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'That would create a circular dependency.']);
  872.                 }
  873.             }
  874.             $remove = (int) $request->request->get('remove'0) === 1;
  875.             $lag = (int) $request->request->get('lag'0);
  876.             $arr $decode($taskId);
  877.             $byId = [];
  878.             foreach ($arr as $d) { $did = (int) (is_array($d) ? ($d['id'] ?? 0) : $d); if ($did 0) { $byId[$did] = is_array($d) ? $d : ['id' => $did]; } }
  879.             if ($remove) {
  880.                 unset($byId[$dependsOnId]); $action 'removed';
  881.             } else {
  882.                 $existing $byId[$dependsOnId] ?? ['id' => $dependsOnId'mode' => 'FS''completionRequired' => 0];
  883.                 $existing['id'] = $dependsOnId$existing['lagDays'] = $lag;
  884.                 $action = isset($byId[$dependsOnId]) ? 'updated' 'added';
  885.                 $byId[$dependsOnId] = $existing;
  886.             }
  887.             $list array_values($byId);
  888.             $csv implode(','array_map(function ($d) { return (int) $d['id']; }, $list));
  889.             $conn->executeStatement(
  890.                 "UPDATE planning_item SET dependency_planning_data = :j, dependency_planning_ids = :c WHERE id = :id",
  891.                 ['j' => json_encode($list), 'c' => $csv'id' => $taskId]
  892.             );
  893.             $deps array_map(function ($d) { return ['id' => (int) $d['id'], 'lag' => (int) ($d['lagDays'] ?? 0)]; }, $list);
  894.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'action' => $action'taskId' => $taskId'deps' => $deps]);
  895.         } catch (\Throwable $ex) {
  896.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Could not save the link.']);
  897.         }
  898.     }
  899.     public function updateDocDataAction(Request $request)
  900.     {
  901.         $em $this->getDoctrine()->getManager();
  902.         $companyId $this->getLoggedUserCompanyId($request);
  903.         //all product fdm
  904.         $QD $this->getDoctrine()
  905.             ->getRepository('ApplicationBundle\\Entity\\InvProducts')
  906.             ->findAll();
  907.         foreach ($QD as $entry) {
  908.             $entry->setProductFdm(
  909.                 $entry->getIgId() . '_' .
  910.                 $entry->getCategoryId() . '_' .
  911.                 $entry->getSubCategoryId() . '_' .
  912.                 $entry->getBrandCompany() . '_' .
  913.                 $entry->getId()
  914.             );
  915.             $em->flush();
  916.         }
  917.         //stock req
  918.         $productListArray = [];
  919.         $subCategoryListArray = [];
  920.         $categoryListArray = [];
  921.         $igListArray = [];
  922.         $unitListArray = [];
  923.         $productList Inventory::ProductList($em$companyId);
  924.         $subCategoryList Inventory::ProductSubCategoryList($em$companyId);
  925.         $categoryList Inventory::ProductCategoryList($em$companyId);
  926.         $igList Inventory::ItemGroupList($em$companyId);
  927.         $unitList Inventory::UnitTypeList($em);
  928.         //sales order item
  929.         $QD $this->getDoctrine()
  930.             ->getRepository('ApplicationBundle\\Entity\\SalesOrderItem')
  931.             ->findAll();
  932.         foreach ($QD as $entry) {
  933.             if (isset($productList[$entry->getProductId()])) {
  934. //                $entry->setIgId($productList[$entry->getProductId()]['igId']);
  935. //                $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
  936. //                $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
  937. //                $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
  938.                 $entry->setProductFdm(
  939.                     ($productList[$entry->getProductId()]['igId']) . '_' .
  940.                     ($productList[$entry->getProductId()]['categoryId']) . '_' .
  941.                     ($productList[$entry->getProductId()]['subCategoryId']) . '_' .
  942.                     ($productList[$entry->getProductId()]['brandCompany']) . '_' .
  943.                     ($entry->getProductId())
  944.                 );
  945.                 $entry->setUnitTypeId($productList[$entry->getProductId()]['unit_type']);
  946.             } else {
  947. //                $entry->setProductFdm(
  948. //                    (1 * $entry->getIgId()) . '_' .
  949. //                    (1 * $entry->getCategoryId()) . '_' .
  950. //                    (1 * $entry->getSubCategoryId()) . '_' .
  951. //                    (1 * $entry->getBrandCompany()) . '_' .
  952. //                    (1 * $entry->getProductId())
  953. //                );
  954.             }
  955.         }
  956.         $em->flush();
  957.         $QD $this->getDoctrine()
  958.             ->getRepository('ApplicationBundle\\Entity\\DeliveryReceiptItem')
  959.             ->findAll();
  960.         foreach ($QD as $entry) {
  961.             if ($entry->getUnitMultiplier() == || $entry->getUnitMultiplier() == null)
  962.                 $entry->setUnitMultiplier(1);
  963.             if ($entry->getUnitTypeId() == || $entry->getUnitTypeId() == null)
  964.                 $entry->setUnitTypeId(isset($productList[$entry->getProductId()]) ? $productList[$entry->getProductId()]['unit_type'] : 0);
  965.         }
  966.         $em->flush();
  967.         $QD $this->getDoctrine()
  968.             ->getRepository('ApplicationBundle\\Entity\\SalesInvoiceItem')
  969.             ->findAll();
  970.         foreach ($QD as $entry) {
  971.             if ($entry->getUnitMultiplier() == || $entry->getUnitMultiplier() == null)
  972.                 $entry->setUnitMultiplier(1);
  973.             if ($entry->getUnitTypeId() == || $entry->getUnitTypeId() == null)
  974.                 $entry->setUnitTypeId(isset($productList[$entry->getProductId()]) ? $productList[$entry->getProductId()]['unit_type'] : 0);
  975.         }
  976.         $em->flush();
  977.         $QD $this->getDoctrine()
  978.             ->getRepository('ApplicationBundle\\Entity\\DeliveryOrderItem')
  979.             ->findAll();
  980.         foreach ($QD as $entry) {
  981.             if (isset($productList[$entry->getProductId()])) {
  982. //                $entry->setIgId($productList[$entry->getProductId()]['igId']);
  983. //                $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
  984. //                $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
  985. //                $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
  986.                 $entry->setProductFdm(
  987.                     ($productList[$entry->getProductId()]['igId']) . '_' .
  988.                     ($productList[$entry->getProductId()]['categoryId']) . '_' .
  989.                     ($productList[$entry->getProductId()]['subCategoryId']) . '_' .
  990.                     ($productList[$entry->getProductId()]['brandCompany']) . '_' .
  991.                     ($entry->getProductId())
  992.                 );
  993.                 $entry->setUnitTypeId($productList[$entry->getProductId()]['unit_type']);
  994.             } else {
  995. //                $entry->setProductFdm(
  996. //                    (1 * $entry->getIgId()) . '_' .
  997. //                    (1 * $entry->getCategoryId()) . '_' .
  998. //                    (1 * $entry->getSubCategoryId()) . '_' .
  999. //                    (1 * $entry->getBrandCompany()) . '_' .
  1000. //                    (1 * $entry->getProductId())
  1001. //                );
  1002.             }
  1003.         }
  1004.         $em->flush();
  1005.         $QD $this->getDoctrine()
  1006.             ->getRepository('ApplicationBundle\\Entity\\StockRequisitionItem')
  1007.             ->findAll();
  1008.         foreach ($QD as $entry) {
  1009.             if (isset($productList[$entry->getProductId()])) {
  1010.                 $entry->setIgId($productList[$entry->getProductId()]['igId']);
  1011.                 $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
  1012.                 $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
  1013.                 $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
  1014.                 $entry->setProductFdm(
  1015.                     ($productList[$entry->getProductId()]['igId']) . '_' .
  1016.                     ($productList[$entry->getProductId()]['categoryId']) . '_' .
  1017.                     ($productList[$entry->getProductId()]['subCategoryId']) . '_' .
  1018.                     ($productList[$entry->getProductId()]['brandCompany']) . '_' .
  1019.                     ($entry->getProductId())
  1020.                 );
  1021.             } else {
  1022.                 $entry->setProductFdm(
  1023.                     ($entry->getIgId()) . '_' .
  1024.                     ($entry->getCategoryId()) . '_' .
  1025.                     ($entry->getSubCategoryId()) . '_' .
  1026.                     ($entry->getBrandCompany()) . '_' .
  1027.                     ($entry->getProductId())
  1028.                 );
  1029.             }
  1030.         }
  1031.         $em->flush();
  1032.         $QD $this->getDoctrine()
  1033.             ->getRepository('ApplicationBundle\\Entity\\StoreRequisitionItem')
  1034.             ->findAll();
  1035.         foreach ($QD as $entry) {
  1036.             if (isset($productList[$entry->getProductId()])) {
  1037.                 $entry->setIgId($productList[$entry->getProductId()]['igId']);
  1038.                 $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
  1039.                 $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
  1040.                 $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
  1041.                 $entry->setProductFdm(
  1042.                     ($productList[$entry->getProductId()]['igId']) . '_' .
  1043.                     ($productList[$entry->getProductId()]['categoryId']) . '_' .
  1044.                     ($productList[$entry->getProductId()]['subCategoryId']) . '_' .
  1045.                     ($productList[$entry->getProductId()]['brandCompany']) . '_' .
  1046.                     ($entry->getProductId())
  1047.                 );
  1048.             } else {
  1049.                 $entry->setProductFdm(
  1050.                     ($entry->getIgId()) . '_' .
  1051.                     ($entry->getCategoryId()) . '_' .
  1052.                     ($entry->getSubCategoryId()) . '_' .
  1053.                     ($entry->getBrandCompany()) . '_' .
  1054.                     ($entry->getProductId())
  1055.                 );
  1056.             }
  1057.         }
  1058.         $em->flush();
  1059.         $QD $this->getDoctrine()
  1060.             ->getRepository('ApplicationBundle\\Entity\\PurchaseRequisitionItem')
  1061.             ->findAll();
  1062.         foreach ($QD as $entry) {
  1063.             if (isset($productList[$entry->getProductId()])) {
  1064.                 $entry->setIgId($productList[$entry->getProductId()]['igId']);
  1065.                 $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
  1066.                 $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
  1067.                 $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
  1068.                 $entry->setProductFdm(
  1069.                     ($productList[$entry->getProductId()]['igId']) . '_' .
  1070.                     ($productList[$entry->getProductId()]['categoryId']) . '_' .
  1071.                     ($productList[$entry->getProductId()]['subCategoryId']) . '_' .
  1072.                     ($productList[$entry->getProductId()]['brandCompany']) . '_' .
  1073.                     ($entry->getProductId())
  1074.                 );
  1075.             } else {
  1076.                 $entry->setProductFdm(
  1077.                     ($entry->getIgId()) . '_' .
  1078.                     ($entry->getCategoryId()) . '_' .
  1079.                     ($entry->getSubCategoryId()) . '_' .
  1080.                     ($entry->getBrandCompany()) . '_' .
  1081.                     ($entry->getProductId())
  1082.                 );
  1083.             }
  1084.         }
  1085.         $em->flush();
  1086.         foreach ($productList as $product) {
  1087.             $productListArray[] = $product;
  1088.         }
  1089.         foreach ($categoryList as $product) {
  1090.             $categoryListArray[] = $product;
  1091.         }
  1092.         foreach ($subCategoryList as $product) {
  1093.             $subCategoryListArray[] = $product;
  1094.         }
  1095.         foreach ($igList as $product) {
  1096.             $igListArray[] = $product;
  1097.         }
  1098.         foreach ($unitList as $product) {
  1099.             $unitListArray[] = $product;
  1100.         }
  1101.         $brandList Inventory::GetBrandList($em$companyId);
  1102.         $brandListArray = [];
  1103.         foreach ($brandList as $product) {
  1104.             $brandListArray[] = $product;
  1105.         }
  1106.         //1st bom
  1107.         $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findBy(
  1108.             array()
  1109.         );
  1110.         foreach ($materialData as $bom) {
  1111.             $Data json_decode($bom->getData(), true);
  1112.             $newData = [];
  1113.             foreach ($Data as $dt) {
  1114.                 if (isset($dt['Products'])) {
  1115.                     foreach ($dt['Products']['products'] as $key => $value) {
  1116.                         if (!isset($dt['Products']['product_fdm']))
  1117.                             $dt['Products']['product_fdm'] = array();
  1118.                         if (!isset($dt['Products']['product_name']))
  1119.                             $dt['Products']['product_name'] = array();
  1120.                         if (!isset($dt['Products']['product_unit_type']))
  1121.                             $dt['Products']['product_unit_type'] = array();
  1122.                         if (!isset($dt['Products']['product_fdm'][$key])) {
  1123.                             $dt['Products']['product_fdm'][$key] = $productList[$value]['igId'] . '_' $productList[$value]['categoryId'] . '_' $productList[$value]['subCategoryId'] . '_' $productList[$value]['brandCompany'] . '_' $value;
  1124.                         }
  1125.                         if (!isset($dt['Products']['product_name'][$key])) {
  1126.                             $dt['Products']['product_name'][$key] = $productList[$value]['name'];
  1127.                         }
  1128.                         if (!isset($dt['Products']['product_unit_type'][$key])) {
  1129.                             $dt['Products']['product_unit_type'][$key] = $productList[$value]['unit_type'];
  1130.                         }
  1131.                     }
  1132.                 }
  1133.                 $newData[] = $dt;
  1134.             }
  1135.             $bom->setData(json_encode($newData));
  1136.             $em->flush();
  1137.         }
  1138.         //now boq
  1139.         $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findBy(
  1140.             array()
  1141.         );
  1142.         foreach ($materialData as $boq) {
  1143.             $Data json_decode($boq->getData(), true);
  1144.             $newData = [];
  1145.             foreach ($Data as $dt) {
  1146.                 if (isset($dt['Products'])) {
  1147.                     foreach ($dt['Products']['products'] as $key => $value) {
  1148.                         if (!isset($dt['Products']['product_fdm']))
  1149.                             $dt['Products']['product_fdm'] = array();
  1150.                         if (!isset($dt['Products']['product_name']))
  1151.                             $dt['Products']['product_name'] = array();
  1152.                         if (!isset($dt['Products']['product_unit_type']))
  1153.                             $dt['Products']['product_unit_type'] = array();
  1154.                         if (!isset($dt['Products']['product_fdm'][$key])) {
  1155.                             $dt['Products']['product_fdm'][$key] = $productList[$value]['igId'] . '_' $productList[$value]['categoryId'] . '_' $productList[$value]['subCategoryId'] . '_' $productList[$value]['brandCompany'] . '_' $value;
  1156.                         }
  1157.                         if (!isset($dt['Products']['product_name'][$key])) {
  1158.                             $dt['Products']['product_name'][$key] = $productList[$value]['name'];
  1159.                         }
  1160.                         if (!isset($dt['Products']['product_unit_type'][$key])) {
  1161.                             $dt['Products']['product_unit_type'][$key] = $productList[$value]['unit_type'];
  1162.                         }
  1163.                     }
  1164.                 }
  1165.                 $newData[] = $dt;
  1166.             }
  1167.             $boq->setData(json_encode($newData));
  1168.             $em->flush();
  1169.         }
  1170.         //now offer
  1171.         $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findBy(
  1172.             array()
  1173.         );
  1174.         foreach ($materialData as $offer) {
  1175.             $Data json_decode($offer->getData(), true);
  1176.             $newData = [];
  1177.             foreach ($Data as $of) {
  1178.                 if (isset($of['boqData'])) {
  1179.                     $dt $of['boqData'];
  1180.                     if (isset($dt['Products'])) {
  1181.                         foreach ($dt['Products']['products'] as $key => $value) {
  1182.                             if (!isset($dt['Products']['product_fdm']))
  1183.                                 $dt['Products']['product_fdm'] = array();
  1184.                             if (!isset($dt['Products']['product_name']))
  1185.                                 $dt['Products']['product_name'] = array();
  1186.                             if (!isset($dt['Products']['product_unit_type']))
  1187.                                 $dt['Products']['product_unit_type'] = array();
  1188.                             if (!isset($dt['Products']['product_fdm'][$key])) {
  1189.                                 $dt['Products']['product_fdm'][$key] = $productList[$value]['igId'] . '_' $productList[$value]['categoryId'] . '_' $productList[$value]['subCategoryId'] . '_' $productList[$value]['brandCompany'] . '_' $value;
  1190.                             }
  1191.                             if (!isset($dt['Products']['product_name'][$key])) {
  1192.                                 $dt['Products']['product_name'][$key] = $productList[$value]['name'];
  1193.                             }
  1194.                             if (!isset($dt['Products']['product_unit_type'][$key])) {
  1195.                                 $dt['Products']['product_unit_type'][$key] = $productList[$value]['unit_type'];
  1196.                             }
  1197.                         }
  1198.                     }
  1199.                     $of['boqData'] = $dt;
  1200.                 }
  1201.                 $newData[] = $of;
  1202.             }
  1203.             $offer->setData(json_encode($newData));
  1204.             $em->flush();
  1205.         }
  1206.         $url $this->generateUrl(
  1207.             'dashboard'
  1208.         );
  1209.         return $this->redirect($url);
  1210.     }
  1211.     public function overhaulItemDataAction(Request $request)
  1212.     {
  1213.         $em $this->getDoctrine()->getManager();
  1214.         $companyId $this->getLoggedUserCompanyId($request);
  1215.         ProjectM::overhaulItems($em$companyId);
  1216.         return 1;
  1217.     }
  1218.     public function EditProjectDetailsAction(Request $request$id)
  1219.     {
  1220.         return $this->UpdateProjectAction($request$id);
  1221.     }
  1222.     public function ViewProjectDetailsAction(Request $request$id)
  1223.     {
  1224.         $em $this->getDoctrine()->getManager();
  1225.         $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  1226.             array(
  1227.                 'projectId' => $id///material
  1228.             ));
  1229.         if ($id == 0) {
  1230.             $url $this->generateUrl(
  1231.                 'project_list'
  1232.             );
  1233.             return $this->redirect($url);
  1234.         }
  1235.         $Approval_data System::checkIfApprovalExists(
  1236.             $em,
  1237.             array_flip(GeneralConstant::$Entity_list)['Project'],
  1238.             $id,
  1239.             $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  1240.         );
  1241.         $stage_list ProjectConstant::$projectStages;
  1242.         $status_list ProjectConstant::$projectStatus;
  1243.         $steps_list ProjectConstant::$projectSteps;
  1244.         $categoryList = [];
  1245.         $categories $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy(
  1246.             array(
  1247.                 "status" => GeneralConstant::ACTIVE,
  1248.                 'CompanyId' => $this->getLoggedUserCompanyId($request),
  1249.             )
  1250.         );
  1251.         foreach ($categories as $cat) {
  1252.             $categoryList[$cat->getProjectCategoryId()] = array(
  1253.                 'id' => $cat->getProjectCategoryId(),
  1254.                 'categoryName' => $cat->getCategoryName(),
  1255.             );
  1256.         }
  1257.         $projectSurfaceSplit $this->isProjectSurfaceSplitEnabled();
  1258.         $projectTeamGroups $this->get(ProjectTeamResolverService::class)->resolveProjectTeamGroups($projectData$this->getLoggedUserCompanyId($request));
  1259.         return $this->render('@Project/pages/views/view_project_details.html.twig',
  1260.             array(
  1261.                 'page_title' => 'Project Details',
  1262.                 'projectData' => $projectData,
  1263.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  1264.                 'proposalData' => ProjectM::GetProposalDetails($em$id),
  1265.                 'materialData' => ProjectM::GetBomDetails($em$id),
  1266.                 'boqData' => ProjectM::GetBoqDetails($em$id),
  1267.                 'wpData' => ProjectM::GetWpDetails($em$id),
  1268.                 'offerData' => ProjectM::GetOfferDetails($em$id),
  1269.                 'clientList' => SalesOrderM::GetClientList($em),
  1270.                 'stageList' => $stage_list,
  1271.                 'statusList' => $status_list,
  1272.                 'stepsList' => $steps_list,
  1273.                 'categories' => $categoryList,
  1274.                 'projectTypes' => ProjectM::getProjectTypesFromConfigFile($this->container->getParameter('kernel.root_dir')),
  1275.                 'stepsListRoutes' => ProjectConstant::$projectStepsRoutes,
  1276.                  'approval_status' => $projectData->getApproved(),
  1277.                 'approval_data' => $Approval_data,
  1278.                 'auto_created' => $projectData->getAutocreated(),
  1279.                 'id' => $id,
  1280.                 'milestoneData'   => ProjectM::GetProjectMilestones($em$id$this->getLoggedUserCompanyId($request)),
  1281.                 'projectCostData' => ProjectM::GetProjectCosts($em$id$this->getLoggedUserCompanyId($request)),
  1282.                 'omLinkage'       => ProjectM::GetProjectOmLinkage($em$id),
  1283.                 'publicShareData' => ProjectM::GetProjectPublicShares($em$id),
  1284.                 'ganttTasks'      => ProjectM::GetProjectGanttData($em$idfalse),
  1285.                 'projectIntelligence' => ProjectM::GetProjectIntelligenceData($em$id$this->getLoggedUserCompanyId($request), false),
  1286.                 'projectTeamGroups' => $projectTeamGroups,
  1287.                 'projectSurfaceSplit' => $projectSurfaceSplit,
  1288.                 'document_log' => $projectData->getAutocreated() == System::getDocumentLog(
  1289.                 $this->getDoctrine()->getManager(),
  1290.                 array_flip(GeneralConstant::$Entity_list)['Project'],
  1291.                 $id,
  1292.                     $projectData->getCreatedLoginId(),
  1293.                     $projectData->getEditedLoginId()
  1294.             ) : []
  1295.             )
  1296.         );
  1297.     }
  1298.     // PLC5 — site-completion / O&M lifecycle transition; the enums existed for years with no writer
  1299.     public function SetProjectLifecycleStateAction(Request $request$id 0)
  1300.     {
  1301.         // House auth model (PLC2 lesson): the Symfony firewall sees everyone as anonymous here —
  1302.         // gate on the session login id; SessionCheckInterface blocks the unauthenticated upstream.
  1303.         if (!$request->getSession()->get(UserConstants::USER_LOGIN_ID)) {
  1304.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'message' => 'Not authenticated.'], 403);
  1305.         }
  1306.         $em $this->getDoctrine()->getManager();
  1307.         /** @var \ApplicationBundle\Entity\Project|null $project */
  1308.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(['projectId' => $id]);
  1309.         if (!$project) {
  1310.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'message' => 'Project not found.'], 404);
  1311.         }
  1312.         $verdict = \ApplicationBundle\Modules\Project\Support\ProjectCompletionCore::decide(
  1313.             $request->request->get('target'''),
  1314.             $project->getStage(),
  1315.             $project->getProjectStep()
  1316.         );
  1317.         if (!$verdict['ok']) {
  1318.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'message' => $verdict['message']], 400);
  1319.         }
  1320.         // Project.status is deliberately untouched: it is the boolean ACTIVE/soft-delete flag
  1321.         // (Project.orm.yml maps it boolean), not the $projectStatus enum — see ProjectCompletionCore.
  1322.         $project->setStage($verdict['set']['stage']);
  1323.         $project->setProjectStep($verdict['set']['projectStep']);
  1324.         $project->setLastModifiedDate(new \DateTime());
  1325.         $em->flush();
  1326.         return new \Symfony\Component\HttpFoundation\JsonResponse([
  1327.             'success' => true,
  1328.             'stage'   => $verdict['set']['stage'],
  1329.             'step'    => $verdict['set']['projectStep'],
  1330.             'phase'   => \ApplicationBundle\Modules\Project\Support\ProjectCompletionCore::phaseFor($verdict['set']['projectStep']),
  1331.         ]);
  1332.     }
  1333.     public function GetRefreshedItemAction(Request $request)
  1334.     {
  1335.         $em $this->getDoctrine()->getManager();
  1336.         $qry $em->getRepository("ApplicationBundle\\Entity\\InvProducts")->findBy(array(
  1337.             "status" => GeneralConstant::ACTIVE,
  1338.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  1339.             'type' => 1//trade items
  1340.         ));
  1341.         $pl = [];
  1342.         $pl_array = [];
  1343.         foreach ($qry as $product) {
  1344.             $pl[$product->getId()] = array(
  1345.                 'text' => $product->getName(),
  1346.                 'name' => $product->getName(),
  1347.                 'id' => $product->getId(),
  1348.                 'value' => $product->getId(),
  1349.                 'purchase_price' => $product->getPurchasePrice(),
  1350.                 'sales_price' => $product->getSalesPrice(),
  1351.                 'supplier_id' => $product->getBrandCompany(),
  1352.             );
  1353.             $pl_array[] = array(
  1354.                 'text' => $product->getName(),
  1355.                 'value' => $product->getId(),
  1356.                 'name' => $product->getName(),
  1357.                 'id' => $product->getId(),
  1358.                 'purchase_price' => $product->getPurchasePrice(),
  1359.                 'sales_price' => $product->getSalesPrice(),
  1360.                 'supplier_id' => $product->getBrandCompany(),
  1361.             );
  1362.         }
  1363.         $qry $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
  1364.             "status" => GeneralConstant::ACTIVE,
  1365.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  1366. //            'type'=>1//trade items
  1367.         ));
  1368.         $sl = [];
  1369.         $sl_array = [];
  1370.         foreach ($qry as $product) {
  1371.             $sl[$product->getServiceId()] = array(
  1372.                 'text' => $product->getServiceName(),
  1373.                 'value' => $product->getServiceId(),
  1374.                 'name' => $product->getServiceName(),
  1375.                 'id' => $product->getServiceId(),
  1376.             );
  1377.             $sl_array[] = array(
  1378.                 'text' => $product->getServiceName(),
  1379.                 'value' => $product->getServiceId(),
  1380.                 'name' => $product->getServiceName(),
  1381.                 'id' => $product->getServiceId(),
  1382.             );
  1383.         }
  1384.         $hl Accounts::HeadList($em);
  1385.         $hl_array Accounts::getParentLedgerHeads($em"""", [], 1$this->getLoggedUserCompanyId($request));
  1386.         return new JsonResponse(
  1387.             array(
  1388. //                'page_title'=>'BOM',
  1389. //                'clients'=>SalesOrderM::GetClientList($em),
  1390. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  1391.                 "success" => true,
  1392.                 'users' => Users::getUserListById($em),
  1393.                 'stages' => ProjectConstant::$projectStages,
  1394.                 'sl' => $sl,
  1395.                 'pl' => $pl,
  1396.                 'hl' => $hl,
  1397.                 'hl_array' => $hl_array,
  1398.                 'pl_array' => $pl_array,
  1399.                 'sl_array' => $sl_array,
  1400. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  1401.             )
  1402.         );
  1403.     }
  1404.     public function CreateProjectProposalAction(Request $request$projectId 0)
  1405.     {
  1406.         $em $this->getDoctrine()->getManager();
  1407.         if ($request->isMethod('POST')) {
  1408.             $em $this->getDoctrine()->getManager();
  1409.             $entity_id array_flip(GeneralConstant::$Entity_list)['ProjectProposal']; //change
  1410.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  1411.                 array(
  1412.                     'projectId' => $projectId///material
  1413.                 ), array('projectDate' => 'desc')
  1414.             );
  1415. //            $client=$em->getRepository('ApplicationBundle\\Entity\\AccClients')->findOneBy(
  1416. //                array(
  1417. //                    'clientId'=>$projectData->getClientId(), ///material
  1418. //
  1419. //                ),array('projectDate'=>'desc')
  1420. //            );
  1421.             $dochash "PP/" $projectData->getProjectCategoryId() . "/" $projectData->getClientId() . "/" $projectId//change
  1422.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  1423.             $approveRole $request->request->get('approvalRole');
  1424.             $approveHash $request->request->get('approvalHash');
  1425.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  1426.                 $loginId$approveRole$approveHash$projectId)) {
  1427.                 $this->addFlash(
  1428.                     'error',
  1429.                     'Sorry Could not insert Data.'
  1430.                 );
  1431.             } else {
  1432.                 //construct the files
  1433.                 $file_list = array(
  1434.                     'product_files' => [],
  1435.                     'service_files' => [],
  1436.                     'ar_files' => [],
  1437.                 );
  1438.                 if ($request->request->has('products')) {
  1439.                     foreach ($request->files->get('product_reference_file') as $uploadedFile) {
  1440.                         $path "";
  1441.                         if ($uploadedFile != null) {
  1442.                             $fileName 'p' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  1443.                             $path $fileName;
  1444.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  1445.                             if (!file_exists($upl_dir)) {
  1446.                                 mkdir($upl_dir0777true);
  1447.                             }
  1448.                             $file $uploadedFile->move($upl_dir$path);
  1449.                         }
  1450.                         $file_list['product_files'][] = $path;
  1451.                     }
  1452.                 }
  1453.                 if ($request->request->has('services')) {
  1454.                     //construct the ref_files array
  1455.                     $ref_files = [];
  1456.                     $path "";
  1457.                     $file_path "";
  1458.                     foreach ($request->files->get('service_reference_file') as $uploadedFile) {
  1459. //                        $uploadedFile = $request->files['service_reference_file_' . $request->request->get('service_uid')[$key]];
  1460.                         $path "";
  1461.                         if ($uploadedFile != null) {
  1462.                             $fileName 's' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  1463.                             $path $fileName;
  1464.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  1465.                             if (!file_exists($upl_dir)) {
  1466.                                 mkdir($upl_dir0777true);
  1467.                             }
  1468.                             $file $uploadedFile->move($upl_dir$path);
  1469.                         }
  1470.                         $file_list['service_files'][] = $path;
  1471.                     }
  1472.                 }
  1473.                 if ($request->request->has('heads')) {
  1474.                     //construct the ref_files array
  1475.                     $ref_files = [];
  1476.                     $path "";
  1477.                     $file_path "";
  1478.                     foreach ($request->files->get('ar_reference_file') as $uploadedFile) {
  1479. //                        $uploadedFile = $request->files['ar_reference_file_' . $request->request->get('ar_uid')[$key]];
  1480.                         $path "";
  1481.                         if ($uploadedFile != null) {
  1482.                             $fileName 'a' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  1483.                             $path $fileName;
  1484.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  1485.                             if (!file_exists($upl_dir)) {
  1486.                                 mkdir($upl_dir0777true);
  1487.                             }
  1488.                             $file $uploadedFile->move($upl_dir$path);
  1489.                         }
  1490.                         $file_list['ar_files'][] = $path;
  1491.                     }
  1492.                 }
  1493.                 $projectWpId ProjectM::CreateNewProposal($this->getDoctrine()->getManager(), $projectId$request->request$dochash$file_list,
  1494.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  1495.                     $this->getLoggedUserCompanyId($request));
  1496.                 //now add Approval info
  1497.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  1498.                 $approveRole $request->request->get('approvalRole');  //created
  1499.                 $options = array(
  1500.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  1501.                     'notification_server' => $this->container->getParameter('notification_server'),
  1502.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  1503.                     'url' => $this->generateUrl(
  1504.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectProposal']]
  1505.                         ['entity_view_route_path_name']
  1506.                     )
  1507.                 );
  1508.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  1509.                     array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1510.                     $projectWpId,
  1511.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  1512.                 );
  1513.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1514.                     $projectWpId,
  1515.                     $loginId,
  1516.                     $approveRole,
  1517.                     $request->request->get('approvalHash'));
  1518.                 $this->addFlash(
  1519.                     'success',
  1520.                     'Project Offer Created'
  1521.                 );
  1522.             }
  1523.             $url $this->generateUrl(
  1524.                 'view_project_proposal'
  1525.             );
  1526.             $proj_here $this->getDoctrine()
  1527.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  1528.                 ->findOneBy(
  1529.                     array(
  1530.                         'projectId' => $projectId
  1531.                     )
  1532.                 );
  1533.             System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  1534.                 "Offer Letter  : " $dochash " Has Been Created For The Project:" $proj_here->getProjectName() . " ",
  1535.                 'user',
  1536.                 array_merge(
  1537.                     json_decode($proj_here->getMarketingUserIds(), true),
  1538.                     json_decode($proj_here->getBillingUserIds(), true),
  1539.                     json_decode($proj_here->getDesigningUserIds(), true)
  1540.                 ),
  1541.                 'information',
  1542.                 $url "/" $projectId,
  1543.                 "Offer Letter- " $proj_here->getProjectName()
  1544.             );
  1545.             return $this->redirect($url "/" $projectId);
  1546.         }
  1547.         $projectList = [];
  1548.         $projectData = [];
  1549.         $materialData = [];
  1550.         $boqData = [];
  1551.         $wpData = [];
  1552.         $offerData = [];
  1553.         $proposalData = [];
  1554.         $message "";
  1555.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  1556.             array(
  1557.                 'projectStep' => array_flip(ProjectConstant::$projectSteps)['PROPOSAL'], ///material
  1558.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  1559.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  1560.             ), array('projectDate' => 'desc')
  1561.         );
  1562.         if ($projectId == 0) {
  1563.         } else {
  1564.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  1565.                 array(
  1566.                     'projectId' => $projectId///material
  1567. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  1568.                     'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  1569.                     'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  1570.                 ), array('projectDate' => 'desc')
  1571.             );
  1572.             if ($projectData) {
  1573.                 $proposalData $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
  1574.                     array(
  1575.                         'projectId' => $projectId///material
  1576.                     )
  1577.                 );
  1578.                 //now if its not editable, redirect to view
  1579.                 if ($proposalData) {
  1580.                     if ($proposalData->getEditFlag() != 1) {
  1581.                         $url $this->generateUrl(
  1582.                             'view_project_proposal'
  1583.                         );
  1584.                         $this->addFlash(
  1585.                             'error',
  1586.                             'Sorry You cant Edit the document Right now.'
  1587.                         );
  1588.                         return $this->redirect($url "/" $projectId);
  1589.                     }
  1590.                 }
  1591.             } else {
  1592.                 $this->addFlash(
  1593.                     'error',
  1594.                     'Sorry!  Could not find your desired project data or this action is not allowed for your specific project at the moment..'
  1595.                 );
  1596.             }
  1597.         }
  1598.         $qry $em->getRepository("ApplicationBundle\\Entity\\InvProducts")->findBy(array(
  1599.             "status" => GeneralConstant::ACTIVE,
  1600.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  1601.             'type' => 1//trade items
  1602.         ));
  1603.         $pl = [];
  1604.         $pl_array = [];
  1605.         foreach ($qry as $product) {
  1606.             $pl[$product->getId()] = array(
  1607.                 'text' => $product->getName(),
  1608.                 'name' => $product->getName(),
  1609.                 'id' => $product->getId(),
  1610.                 'value' => $product->getId(),
  1611.                 'purchase_price' => $product->getPurchasePrice(),
  1612.                 'sales_price' => $product->getSalesPrice(),
  1613.                 'supplier_id' => $product->getBrandCompany(),
  1614.             );
  1615.             $pl_array[] = array(
  1616.                 'text' => $product->getName(),
  1617.                 'value' => $product->getId(),
  1618.                 'name' => $product->getName(),
  1619.                 'id' => $product->getId(),
  1620.                 'purchase_price' => $product->getPurchasePrice(),
  1621.                 'sales_price' => $product->getSalesPrice(),
  1622.                 'supplier_id' => $product->getBrandCompany(),
  1623.             );
  1624.         }
  1625.         $qry $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
  1626.             "status" => GeneralConstant::ACTIVE,
  1627.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  1628. //            'type'=>1//trade items
  1629.         ));
  1630.         $sl = [];
  1631.         $sl_array = [];
  1632.         foreach ($qry as $product) {
  1633.             $sl[$product->getServiceId()] = array(
  1634.                 'text' => $product->getServiceName(),
  1635.                 'value' => $product->getServiceId(),
  1636.                 'name' => $product->getServiceName(),
  1637.                 'id' => $product->getServiceId(),
  1638.             );
  1639.             $sl_array[] = array(
  1640.                 'text' => $product->getServiceName(),
  1641.                 'value' => $product->getServiceId(),
  1642.                 'name' => $product->getServiceName(),
  1643.                 'id' => $product->getServiceId(),
  1644.             );
  1645.         }
  1646.         $qry $em->getRepository("ApplicationBundle\\Entity\\ProjectWorkStage")->findBy(array(
  1647.             "status" => GeneralConstant::ACTIVE,
  1648.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  1649. //            'type'=>1//trade items
  1650.         ));
  1651.         $workStages = [];
  1652.         $workStages_array = [];
  1653.         foreach ($qry as $product) {
  1654.             $workStages[$product->getProjectWorkStageId()] = array(
  1655.                 'text' => $product->getStageName(),
  1656.                 'value' => $product->getProjectWorkStageId(),
  1657.                 'name' => $product->getStageName(),
  1658.                 'id' => $product->getProjectWorkStageId(),
  1659.             );
  1660.             $workStages_array[] = array(
  1661.                 'text' => $product->getStageName(),
  1662.                 'value' => $product->getProjectWorkStageId(),
  1663.                 'name' => $product->getStageName(),
  1664.                 'id' => $product->getProjectWorkStageId(),
  1665.             );
  1666.         }
  1667.         $hl Accounts::HeadList($em);
  1668.         $debug_data $request->files->get('product_reference_file');
  1669.         $companyId $this->getLoggedUserCompanyId($request);
  1670.         $productListArray = [];
  1671.         $subCategoryListArray = [];
  1672.         $categoryListArray = [];
  1673.         $igListArray = [];
  1674.         $unitListArray = [];
  1675.         $productList Inventory::ProductList($em$companyId);
  1676.         $subCategoryList Inventory::ProductSubCategoryList($em$companyId);
  1677.         $categoryList Inventory::ProductCategoryList($em$companyId);
  1678.         $igList Inventory::ItemGroupList($em$companyId);
  1679.         $unitList Inventory::UnitTypeList($em);
  1680.         foreach ($productList as $product) {
  1681.             $productListArray[] = $product;
  1682.         }
  1683.         foreach ($categoryList as $product) {
  1684.             $categoryListArray[] = $product;
  1685.         }
  1686.         foreach ($subCategoryList as $product) {
  1687.             $subCategoryListArray[] = $product;
  1688.         }
  1689.         foreach ($igList as $product) {
  1690.             $igListArray[] = $product;
  1691.         }
  1692.         foreach ($unitList as $product) {
  1693.             $unitListArray[] = $product;
  1694.         }
  1695.         $brandList Inventory::GetBrandList($em$companyId);
  1696.         $brandListArray = [];
  1697.         foreach ($brandList as $product) {
  1698.             $brandListArray[] = $product;
  1699.         }
  1700.         return $this->render('@Project/pages/input_forms/create_project_proposal.html.twig',
  1701.             array(
  1702.                 'page_title' => 'Project Proposal Letter',
  1703. //                'clients'=>SalesOrderM::GetClientList($em),
  1704. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  1705.                 'users' => Users::getUserListById($em),
  1706.                 'stages' => ProjectConstant::$projectStages,
  1707.                 'productList' => $productList,
  1708.                 'subCategoryList' => $subCategoryList,
  1709.                 'categoryList' => $categoryList,
  1710.                 'igList' => $igList,
  1711.                 'unitList' => $unitList,
  1712.                 'brandList' => $brandList,
  1713.                 'brandListArray' => $brandListArray,
  1714.                 'productListArray' => $productListArray,
  1715.                 'subCategoryListArray' => $subCategoryListArray,
  1716.                 'categoryListArray' => $categoryListArray,
  1717.                 'igListArray' => $igListArray,
  1718.                 'unitListArray' => $unitListArray,
  1719.                 'sl' => $sl,
  1720.                 'pl' => $pl,
  1721.                 'hl' => $hl,
  1722.                 'workStages' => $workStages,
  1723.                 'projectList' => $projectList,
  1724.                 'projectData' => $projectData,
  1725.                 'materialData' => $materialData,
  1726.                 'boqData' => $boqData,
  1727.                 'wpData' => $wpData,
  1728.                 'offerData' => $offerData,
  1729.                 'proposalData' => $proposalData,
  1730.                 'message' => $message,
  1731.                 'projectId' => $projectId,
  1732.                 'pl_array' => $pl_array,
  1733.                 'sl_array' => $sl_array,
  1734.                 'workStages_array' => $workStages_array,
  1735.                 'debug_data' => $debug_data,
  1736. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  1737.             )
  1738.         );
  1739.     }
  1740.     public function ViewProjectProposalAction(Request $request$id)
  1741.     {
  1742.         $em $this->getDoctrine()->getManager();
  1743.         $dt ProjectM::GetProposalDetails($em$id);
  1744.         ///
  1745. //        $projectData=$em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  1746. //            array(
  1747. //                'projectId'=>$id, ///material
  1748. //                'projectStep'=>array_flip(ProjectConstant::$projectSteps)['NEGOTIATION'], ///material
  1749. ////                'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
  1750. ////                'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  1751. //            ),array('projectDate'=>'desc')
  1752. //        );
  1753. //        $offerDataList=$em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findBy(
  1754. //            array(
  1755. //                'approved'=>1, ///material
  1756. //
  1757. //            )
  1758. //        );
  1759. //        if(!empty($offerDataList)) {
  1760. //            foreach ($offerDataList as $offerData) {
  1761. //                $all_det_data = json_decode($offerData->getData(), true);
  1762. //                $entry = $all_det_data[0];
  1763. //                $store_items = $entry['boqData']['Products'];
  1764. //                ProjectM::addProductsByFdm($em, $store_items['product_fdm'], $offerData->getCompanyId());
  1765. //
  1766. //            }
  1767. //        }
  1768.         ///////
  1769.         if (!$dt) {
  1770.             $url $this->generateUrl(
  1771.                 'create_project_proposal'
  1772.             );
  1773.             $this->addFlash(
  1774.                 'error',
  1775.                 'Please Create Offer for the project 1st.'
  1776.             );
  1777.             return $this->redirect($url "/" $id);
  1778.         }
  1779.         $stage_list ProjectConstant::$projectStages;
  1780.         $status_list ProjectConstant::$projectStatus;
  1781.         $steps_list ProjectConstant::$projectSteps;
  1782.         $costSheetDoc $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  1783.             ->findOneBy(['projectId' => (int) $id'dataType' => 'cost_sheet']);
  1784.         $costSheetData $costSheetDoc ? (json_decode((string) $costSheetDoc->getData(), true) ?: null) : null;
  1785.         return $this->render('@Project/pages/views/view_project_proposal.html.twig',
  1786.             array(
  1787.                 'page_title' => 'Proposal Letter',
  1788.                 'data' => $dt,
  1789.                 'costSheetData' => $costSheetData,
  1790.                 'costSheetProjectId' => (int) $id,
  1791. //                'boqData'=>ProjectM::GetBoqDetails($em,$id),
  1792. //                'wpData'=>ProjectM::GetWpDetails($em,$id),
  1793.                 'clientList' => SalesOrderM::GetClientList($em),
  1794.                 'stageList' => $stage_list,
  1795.                 'statusList' => $status_list,
  1796.                 'stepsList' => $steps_list,
  1797.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  1798.                 'auto_created' => $dt['auto_created'],
  1799.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1800.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  1801.                 'document_log' => $dt['auto_created'] == System::getDocumentLog($this->getDoctrine()->getManager(),
  1802.                     array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1803.                     $id,
  1804.                     $dt['created_by'],
  1805.                     $dt['edited_by']) : [],
  1806.                 'users' => Users::getUserListById($em)
  1807.             )
  1808.         );
  1809.     }
  1810.     public function PrintProjectProposalAction(Request $request$id)
  1811.     {
  1812.         $em $this->getDoctrine()->getManager();
  1813.         $dt ProjectM::GetProposalDetails($em$id);
  1814.         if (!$dt) {
  1815.             $url $this->generateUrl(
  1816.                 'create_project_proposal'
  1817.             );
  1818.             $this->addFlash(
  1819.                 'error',
  1820.                 'Please Create Offer for the project 1st.'
  1821.             );
  1822.             return $this->redirect($url "/" $id);
  1823.         }
  1824.         $company_data Company::getCompanyData($em1);
  1825.         $document_mark = array(
  1826.             'original' => '/images/Original-Stamp-PNG-Picture.png',
  1827.             'copy' => ''
  1828.         );
  1829.         if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
  1830.             $html $this->renderView('@Project/pages/print/print_project_proposal.html.twig',
  1831.                 array(
  1832.                     //full array here
  1833.                     'pdf' => true,
  1834.                     'page_title' => 'Offer Letter',
  1835.                     'export' => 'pdf,print',
  1836.                     'data' => $dt,
  1837.                     'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  1838.                     'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1839.                         $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  1840.                     'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  1841.                         array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1842.                         $id,
  1843.                         $dt['created_by'],
  1844.                         $dt['edited_by']),
  1845.                     'document_mark_image' => $document_mark['original'],
  1846.                     'document_type' => 'Offer Letter',
  1847.                     'company_name' => $company_data->getName(),
  1848.                     'company_address' => $company_data->getAddress(),
  1849.                     'company_image' => $company_data->getImage(),
  1850.                     'invoice_footer' => $company_data->getInvoiceFooter(),
  1851.                     'red' => 0
  1852.                 )
  1853.             );
  1854.             $pdf_response $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
  1855. //                'orientation' => 'landscape',
  1856. //                'enable-javascript' => true,
  1857. //                'javascript-delay' => 1000,
  1858.                 'no-stop-slow-scripts' => false,
  1859.                 'no-background' => false,
  1860.                 'lowquality' => false,
  1861.                 'encoding' => 'utf-8',
  1862. //            'images' => true,
  1863. //            'cookie' => array(),
  1864.                 'dpi' => 300,
  1865.                 'image-dpi' => 300,
  1866. //                'enable-external-links' => true,
  1867. //                'enable-internal-links' => true
  1868.             ));
  1869.             return new Response(
  1870.                 $pdf_response,
  1871.                 200,
  1872.                 array(
  1873.                     'Content-Type' => 'application/pdf',
  1874.                     'Content-Disposition' => 'attachment; filename="offer.pdf"'
  1875.                 )
  1876.             );
  1877.         }
  1878.         return $this->render('@Project/pages/print/print_project_proposal.html.twig',
  1879.             array(
  1880.                 'page_title' => 'Project Offer Letter',
  1881.                 'export' => 'pdf,print',
  1882.                 'data' => $dt,
  1883.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  1884.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1885.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  1886.                 'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  1887.                     array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  1888.                     $id,
  1889.                     $dt['created_by'],
  1890.                     $dt['edited_by']),
  1891.                 'document_mark_image' => $document_mark['original'],
  1892.                 'company_name' => $company_data->getName(),
  1893.                 'company_address' => $company_data->getAddress(),
  1894.                 'company_image' => $company_data->getImage(),
  1895.                 'invoice_footer' => $company_data->getInvoiceFooter(),
  1896.                 'red' => 0
  1897.             )
  1898.         );
  1899.     }
  1900.     public function CreateProjectMaterialAction(Request $request$projectId 0)
  1901.     {
  1902.         $em $this->getDoctrine()->getManager();
  1903.         if ($request->isMethod('POST')) {
  1904.             $em $this->getDoctrine()->getManager();
  1905.             $entity_id array_flip(GeneralConstant::$Entity_list)['ProjectMaterial']; //change
  1906.             $proj_here $this->getDoctrine()
  1907.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  1908.                 ->findOneBy(
  1909.                     array(
  1910.                         'projectId' => $projectId
  1911.                     )
  1912.                 );
  1913.             $dochash "BM/" $proj_here->getProjectCategoryId() . "/" $proj_here->getClientId() . "/" $projectId//change
  1914.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  1915.             $approveRole $request->request->get('approvalRole');
  1916.             $approveHash $request->request->get('approvalHash');
  1917.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  1918.                 $loginId$approveRole$approveHash$projectId)) {
  1919.                 $this->addFlash(
  1920.                     'error',
  1921.                     'Sorry Couldnot insert Data.'
  1922.                 );
  1923.             } else {
  1924.                 $projectBomId ProjectM::CreateNewBom($this->getDoctrine()->getManager(), $projectId$request->request$dochash,
  1925.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  1926.                     $this->getLoggedUserCompanyId($request));
  1927.                 //now add Approval info
  1928.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  1929.                 $approveRole $request->request->get('approvalRole');  //created
  1930.                 $options = array(
  1931.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  1932.                     'notification_server' => $this->container->getParameter('notification_server'),
  1933.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  1934.                     'url' => $this->generateUrl(
  1935.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectMaterial']]
  1936.                         ['entity_view_route_path_name']
  1937.                     )
  1938.                 );
  1939.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  1940.                     array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  1941.                     $projectBomId,
  1942.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  1943.                 );
  1944.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  1945.                     $projectBomId,
  1946.                     $loginId,
  1947.                     $approveRole,
  1948.                     $request->request->get('approvalHash'));
  1949.                 $this->addFlash(
  1950.                     'success',
  1951.                     'Bill of Materials Created'
  1952.                 );
  1953.             }
  1954.             $url $this->generateUrl(
  1955.                 'view_project_bom'
  1956.             );
  1957.             $proj_here $this->getDoctrine()
  1958.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  1959.                 ->findOneBy(
  1960.                     array(
  1961.                         'projectId' => $projectId
  1962.                     )
  1963.                 );
  1964.             System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  1965.                 "Bill of material  : " $dochash " Has Been Created For The Project:" $proj_here->getProjectName() . " ",
  1966.                 'user',
  1967.                 array_merge(
  1968.                     json_decode($proj_here->getMarketingUserIds(), true),
  1969.                     json_decode($proj_here->getMaterialUserIds(), true),
  1970.                     json_decode($proj_here->getDesigningUserIds(), true)
  1971.                 ),
  1972.                 'information',
  1973.                 $url "/" $projectId,
  1974.                 "Bill of Materials- " $proj_here->getProjectName()
  1975.             );
  1976.             return $this->redirect($url "/" $projectId);
  1977.         }
  1978.         $projectList = [];
  1979.         $projectData = [];
  1980.         $materialData = [];
  1981.         $message "";
  1982.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  1983.             array(
  1984.                 'projectStep' => array_flip(ProjectConstant::$projectSteps)['MATERIAL PLAN'], ///material
  1985.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  1986.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  1987.             ), array('projectDate' => 'desc')
  1988.         );
  1989.         if ($projectId == 0) {
  1990.         } else {
  1991.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  1992.                 array(
  1993.                     'projectId' => $projectId///material
  1994.                     'projectStep' => array_flip(ProjectConstant::$projectSteps)['MATERIAL PLAN'], ///material
  1995.                     'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  1996.                     'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  1997.                 ), array('projectDate' => 'desc')
  1998.             );
  1999.             if ($projectData) {
  2000.                 $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
  2001.                     array(
  2002.                         'projectId' => $projectId///material
  2003.                     )
  2004.                 );
  2005.                 $proposalData $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
  2006.                     array(
  2007.                         'projectId' => $projectId///material
  2008.                         'approved' => GeneralConstant::APPROVED
  2009.                     )
  2010.                 );
  2011.                 if (!$proposalData && $projectData->getProposalRequired() == 1) {
  2012.                     $url $this->generateUrl(
  2013.                         'create_project_proposal'
  2014.                     );
  2015.                     $this->addFlash(
  2016.                         'error',
  2017.                         'Please Create Proposal for the project 1st.'
  2018.                     );
  2019.                     return $this->redirect($url "/" $projectId);
  2020.                 }
  2021.                 //now if its not editable, redirect to view
  2022.                 if ($materialData) {
  2023.                     if ($materialData->getEditFlag() != 1) {
  2024.                         $url $this->generateUrl(
  2025.                             'view_project_bom'
  2026.                         );
  2027.                         return $this->redirect($url "/" $projectId);
  2028.                     }
  2029.                 }
  2030.             } else {
  2031.                 $this->addFlash(
  2032.                     'error',
  2033.                     'Sorry!  Could not find your desired project data or this action is not allowed for your specific project at the moment..'
  2034.                 );
  2035.             }
  2036.         }
  2037.         $companyId $this->getLoggedUserCompanyId($request);
  2038.         $productListArray = [];
  2039.         $subCategoryListArray = [];
  2040.         $categoryListArray = [];
  2041.         $igListArray = [];
  2042.         $unitListArray = [];
  2043. //        $productList=Inventory::ProductList($em,$companyId);
  2044.         $productList = [];
  2045.         $subCategoryList = [];
  2046. //        $subCategoryList=Inventory::ProductSubCategoryList($em,$companyId);
  2047.         $categoryList = [];
  2048. //        $categoryList=Inventory::ProductCategoryList($em,$companyId);
  2049.         $igList = [];
  2050. //        $igList=Inventory::ItemGroupList($em,$companyId);
  2051. //        $unitList=[];
  2052.         $unitList Inventory::UnitTypeList($em);
  2053. //        foreach ($productList as $product) {
  2054. //
  2055. //            $productListArray[]=$product;
  2056. //        }
  2057. //        foreach ($categoryList as $product) {
  2058. //
  2059. //            $categoryListArray[]=$product;
  2060. //        }
  2061. //        foreach ($subCategoryList as $product) {
  2062. //
  2063. //            $subCategoryListArray[]=$product;
  2064. //        }
  2065. //        foreach ($igList as $product) {
  2066. //
  2067. //            $igListArray[]=$product;
  2068. //        }
  2069.         foreach ($unitList as $product) {
  2070.             $unitListArray[] = $product;
  2071.         }
  2072.         $qry $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
  2073.             "status" => GeneralConstant::ACTIVE,
  2074.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  2075. //            'type'=>1//trade items
  2076.         ));
  2077.         $sl = [];
  2078.         $sl_array = [];
  2079. //        foreach ($qry as $product) {
  2080. //            $sl[$product->getServiceId()]=array(
  2081. //                'text'=>$product->getServiceName(),
  2082. //                'value'=>$product->getServiceId(),
  2083. //                'name'=>$product->getServiceName(),
  2084. //                'id'=>$product->getServiceId(),
  2085. //            );
  2086. //            $sl_array[]=array(
  2087. //                'text'=>$product->getServiceName(),
  2088. //                'value'=>$product->getServiceId(),
  2089. //                'name'=>$product->getServiceName(),
  2090. //                'id'=>$product->getServiceId(),
  2091. //            );
  2092. //        }
  2093.         $hl Accounts::HeadList($em);
  2094.         $brandList Inventory::GetBrandList($em$companyId);
  2095.         $brandListArray = [];
  2096.         foreach ($brandList as $product) {
  2097.             $brandListArray[] = $product;
  2098.         }
  2099.         return $this->render('@Project/pages/input_forms/create_project_bom.html.twig',
  2100.             array(
  2101.                 'page_title' => 'BOM',
  2102. //                'clients'=>SalesOrderM::GetClientList($em),
  2103. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  2104.                 'users' => Users::getUserListById($em),
  2105.                 'stages' => ProjectConstant::$projectStages,
  2106.                 'sl' => $sl,
  2107.                 'userRestrictions' => Users::getUserApplicationAccessSettings($em$request->getSession()->get(UserConstants::USER_ID))['options'],
  2108.                 'productList' => $productList,
  2109.                 'subCategoryList' => $subCategoryList,
  2110.                 'categoryList' => $categoryList,
  2111.                 'igList' => $igList,
  2112.                 'unitList' => $unitList,
  2113.                 'productListArray' => $productListArray,
  2114.                 'subCategoryListArray' => $subCategoryListArray,
  2115.                 'categoryListArray' => $categoryListArray,
  2116.                 'igListArray' => $igListArray,
  2117.                 'unitListArray' => $unitListArray,
  2118.                 'brandList' => $brandList,
  2119.                 'brandListArray' => $brandListArray,
  2120.                 'hl' => $hl,
  2121.                 'projectList' => $projectList,
  2122.                 'projectData' => $projectData,
  2123.                 'materialData' => $materialData,
  2124.                 'message' => $message,
  2125.                 'projectId' => $projectId,
  2126.                 'sl_array' => $sl_array,
  2127. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  2128.             )
  2129.         );
  2130.     }
  2131.     public function ViewProjectBomAction(Request $request$id)
  2132.     {
  2133.         $em $this->getDoctrine()->getManager();
  2134.         $dt ProjectM::GetBomDetails($em$id);
  2135.         if (!$dt) {
  2136.             $url $this->generateUrl(
  2137.                 'create_project_material'
  2138.             );
  2139.             $this->addFlash(
  2140.                 'error',
  2141.                 'Please Create Material Listings for the project 1st.'
  2142.             );
  2143.             return $this->redirect($url "/" $id);
  2144.         }
  2145.         return $this->render('@Project/pages/views/view_project_bom.html.twig',
  2146.             array(
  2147.                 'page_title' => 'View',
  2148.                 'data' => $dt,
  2149.                 'auto_created' => $dt['auto_created'],
  2150.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2151.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  2152.                 'document_log' => $dt['auto_created'] == System::getDocumentLog($this->getDoctrine()->getManager(),
  2153.                     array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2154.                     $id,
  2155.                     $dt['created_by'],
  2156.                     $dt['edited_by']) : [],
  2157.                 'users' => Users::getUserListById($em)
  2158.             )
  2159.         );
  2160.     }
  2161.     public function PrintProjectBomAction(Request $request$id)
  2162.     {
  2163.         $em $this->getDoctrine()->getManager();
  2164.         $dt ProjectM::GetBomDetails($em$id);
  2165.         if (!$dt) {
  2166.             $url $this->generateUrl(
  2167.                 'create_project_material'
  2168.             );
  2169.             $this->addFlash(
  2170.                 'error',
  2171.                 'Please Create Material Listings for the project 1st.'
  2172.             );
  2173.             return $this->redirect($url "/" $id);
  2174.         }
  2175.         $company_data Company::getCompanyData($em1);
  2176.         $document_mark = array(
  2177.             'original' => '/images/Original-Stamp-PNG-Picture.png',
  2178.             'copy' => ''
  2179.         );
  2180.         if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
  2181.             $html $this->renderView('@Project/pages/print/print_project_bom.html.twig',
  2182.                 array(
  2183.                     //full array here
  2184.                     'pdf' => true,
  2185.                     'page_title' => 'Project BOM',
  2186.                     'export' => 'pdf,print',
  2187.                     'data' => $dt,
  2188.                     'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2189.                         $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  2190.                     'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  2191.                         array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2192.                         $id,
  2193.                         $dt['created_by'],
  2194.                         $dt['edited_by']),
  2195.                     'document_mark_image' => $document_mark['original'],
  2196.                     'document_type' => 'Bill Of materials',
  2197.                     'company_name' => $company_data->getName(),
  2198.                     'company_address' => $company_data->getAddress(),
  2199.                     'company_image' => $company_data->getImage(),
  2200.                     'invoice_footer' => $company_data->getInvoiceFooter(),
  2201.                     'red' => 0
  2202.                 )
  2203.             );
  2204.             $pdf_response $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
  2205. //                'orientation' => 'landscape',
  2206. //                'enable-javascript' => true,
  2207. //                'javascript-delay' => 1000,
  2208.                 'no-stop-slow-scripts' => false,
  2209.                 'no-background' => false,
  2210.                 'lowquality' => false,
  2211.                 'encoding' => 'utf-8',
  2212. //            'images' => true,
  2213. //            'cookie' => array(),
  2214.                 'dpi' => 300,
  2215.                 'image-dpi' => 300,
  2216. //                'enable-external-links' => true,
  2217. //                'enable-internal-links' => true
  2218.             ));
  2219.             return new Response(
  2220.                 $pdf_response,
  2221.                 200,
  2222.                 array(
  2223.                     'Content-Type' => 'application/pdf',
  2224.                     'Content-Disposition' => 'attachment; filename="bom.pdf"'
  2225.                 )
  2226.             );
  2227.         }
  2228.         return $this->render('@Project/pages/print/print_project_bom.html.twig',
  2229.             array(
  2230.                 'page_title' => 'Project BOM',
  2231.                 'export' => 'pdf,print',
  2232.                 'data' => $dt,
  2233.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2234.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  2235.                 'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  2236.                     array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2237.                     $id,
  2238.                     $dt['created_by'],
  2239.                     $dt['edited_by']),
  2240.                 'document_mark_image' => $document_mark['original'],
  2241.                 'company_name' => $company_data->getName(),
  2242.                 'company_address' => $company_data->getAddress(),
  2243.                 'company_image' => $company_data->getImage(),
  2244.                 'invoice_footer' => $company_data->getInvoiceFooter(),
  2245.                 'red' => 0
  2246.             )
  2247.         );
  2248.     }
  2249.     public function ForceEditProjectBoqAction(Request $request$projectId 0)
  2250.     {
  2251.         $em $this->getDoctrine()->getManager();
  2252.         if ($request->isMethod('POST')) {
  2253.             $em $this->getDoctrine()->getManager();
  2254.             $entity_id array_flip(GeneralConstant::$Entity_list)['ProjectBoq']; //change
  2255.             $proj_here $this->getDoctrine()
  2256.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  2257.                 ->findOneBy(
  2258.                     array(
  2259.                         'projectId' => $projectId
  2260.                     )
  2261.                 );
  2262.             $dochash "BQ/" $proj_here->getProjectCategoryId() . "/" $proj_here->getClientId() . "/" $projectId//change
  2263.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  2264.             $approveRole $request->request->get('approvalRole');
  2265.             $approveHash $request->request->get('approvalHash');
  2266.             $boqData $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
  2267.                 array(
  2268.                     'projectId' => $projectId///material
  2269.                 )
  2270.             );
  2271.             $prev_edit_flg 0;
  2272.             if ($boqData) {
  2273.                 $prev_edit_flg $boqData->getEditFlag();//temporarily
  2274.                 $boqData->setEditFlag(1);//temporarily
  2275.                 $boqData->setLockFlag(1);//temporarily
  2276.             }
  2277.             $em->flush();
  2278.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  2279.                 $loginId$approveRole$approveHash$projectId)) {
  2280.                 if ($boqData) {
  2281.                     $boqData->setEditFlag($prev_edit_flg);//temporarily
  2282.                     $boqData->setLockFlag(1);//temporarily
  2283.                 }
  2284.                 $em->flush();
  2285.                 $this->addFlash(
  2286.                     'error',
  2287.                     'Sorry Couldnot insert Data.'
  2288.                 );
  2289.             } else {
  2290.                 //construct the files
  2291.                 $file_list = array(
  2292.                     'product_files' => [],
  2293.                     'service_files' => [],
  2294.                     'ar_files' => [],
  2295.                 );
  2296.                 if ($request->request->has('products')) {
  2297.                     foreach ($request->files->get('product_reference_file', []) as $uploadedFile) {
  2298.                         $path "";
  2299.                         if ($uploadedFile != null) {
  2300.                             $fileName 'p' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  2301.                             $path $fileName;
  2302.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  2303.                             if (!file_exists($upl_dir)) {
  2304.                                 mkdir($upl_dir0777true);
  2305.                             }
  2306.                             $file $uploadedFile->move($upl_dir$path);
  2307.                         }
  2308.                         $file_list['product_files'][] = $path;
  2309.                     }
  2310.                 }
  2311.                 if ($request->request->has('services')) {
  2312.                     //construct the ref_files array
  2313.                     $ref_files = [];
  2314.                     $path "";
  2315.                     $file_path "";
  2316.                     foreach ($request->files->get('service_reference_file', []) as $uploadedFile) {
  2317. //                        $uploadedFile = $request->files['service_reference_file_' . $request->request->get('service_uid')[$key]];
  2318.                         $path "";
  2319.                         if ($uploadedFile != null) {
  2320.                             $fileName 's' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  2321.                             $path $fileName;
  2322.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  2323.                             if (!file_exists($upl_dir)) {
  2324.                                 mkdir($upl_dir0777true);
  2325.                             }
  2326.                             $file $uploadedFile->move($upl_dir$path);
  2327.                         }
  2328.                         $file_list['service_files'][] = $path;
  2329.                     }
  2330.                 }
  2331.                 if ($request->request->has('heads')) {
  2332.                     //construct the ref_files array
  2333.                     $ref_files = [];
  2334.                     $path "";
  2335.                     $file_path "";
  2336.                     foreach ($request->files->get('ar_reference_file', []) as $uploadedFile) {
  2337. //                        $uploadedFile = $request->files['ar_reference_file_' . $request->request->get('ar_uid')[$key]];
  2338.                         $path "";
  2339.                         if ($uploadedFile != null) {
  2340.                             $fileName 'a' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  2341.                             $path $fileName;
  2342.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  2343.                             if (!file_exists($upl_dir)) {
  2344.                                 mkdir($upl_dir0777true);
  2345.                             }
  2346.                             $file $uploadedFile->move($upl_dir$path);
  2347.                         }
  2348.                         $file_list['ar_files'][] = $path;
  2349.                     }
  2350.                 }
  2351.                 $document_data_id SalesOrderM::UpdateDocumentData($this->getDoctrine()->getManager(), $request->request->get('documentDataId'), $request->request$file_list);
  2352.                 $projectBoqId ProjectM::CreateNewBoq($this->getDoctrine()->getManager(), $projectId$document_data_id$request->request$dochash$file_list,
  2353.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  2354.                     $this->getLoggedUserCompanyId($request));
  2355.                 $all_seq_list $em->getRepository('ApplicationBundle\\Entity\\Approval')
  2356.                     ->findBy(
  2357.                         array(
  2358.                             'entity' => array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  2359.                             'entityId' => $projectBoqId,
  2360. //                        'sequence' => $dt->getSequence()
  2361.                         )
  2362.                     );
  2363.                 foreach ($all_seq_list as $useless_data) {
  2364. //                    if($useless_data->getSequence()>$dt->getSequence())
  2365.                     {
  2366.                         $em->remove($useless_data);
  2367.                         $em->flush();
  2368.                     }
  2369.                 }
  2370.                 //now add Approval info
  2371.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  2372.                 $approveRole $request->request->get('approvalRole');  //created
  2373.                 $options = array(
  2374.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  2375.                     'notification_server' => $this->container->getParameter('notification_server'),
  2376.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  2377.                     'url' => $this->generateUrl(
  2378.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectBoq']]
  2379.                         ['entity_view_route_path_name']
  2380.                     )
  2381.                 );
  2382.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  2383.                     array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  2384.                     $projectBoqId,
  2385.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  2386.                 );
  2387.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  2388.                     $projectBoqId,
  2389.                     $loginId,
  2390.                     $approveRole,
  2391.                     $request->request->get('approvalHash'));
  2392.                 $this->addFlash(
  2393.                     'success',
  2394.                     'Bill of Quantity Created'
  2395.                 );
  2396.             }
  2397.             $url $this->generateUrl(
  2398.                 'view_project_boq'
  2399.             );
  2400.             $proj_here $this->getDoctrine()
  2401.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  2402.                 ->findOneBy(
  2403.                     array(
  2404.                         'projectId' => $projectId
  2405.                     )
  2406.                 );
  2407.             System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  2408.                 "Bill of Quantity  : " $dochash " Has Been Created For The Project:" $proj_here->getProjectName() . " ",
  2409.                 'user',
  2410.                 array_merge(
  2411.                     json_decode($proj_here->getMarketingUserIds(), true),
  2412.                     json_decode($proj_here->getDesigningUserIds(), true)
  2413.                 ),
  2414.                 'information',
  2415.                 $url "/" $projectId,
  2416.                 "Bill of Quantity- " $proj_here->getProjectName()
  2417.             );
  2418.             return $this->redirect($url "/" $projectId);
  2419.         }
  2420.         $projectList = [];
  2421.         $projectData = [];
  2422.         $materialData = [];
  2423.         $boqData = [];
  2424.         $message "";
  2425.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  2426.             array(
  2427. //                'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  2428.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  2429.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  2430.             ), array('projectDate' => 'desc')
  2431.         );
  2432.         if ($projectId == 0) {
  2433.         } else {
  2434.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  2435.                 array(
  2436.                     'projectId' => $projectId///material
  2437. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  2438.                     'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  2439.                     'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  2440.                 ), array('projectDate' => 'desc')
  2441.             );
  2442.             if ($projectData) {
  2443.                 $proposalData $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
  2444.                     array(
  2445.                         'projectId' => $projectId///material
  2446.                         'approved' => GeneralConstant::APPROVED
  2447.                     )
  2448.                 );
  2449.                 if (!$proposalData && $projectData->getProposalRequired() == 1) {
  2450.                     $url $this->generateUrl(
  2451.                         'create_project_proposal'
  2452.                     );
  2453.                     $this->addFlash(
  2454.                         'error',
  2455.                         'Please Create Proposal for the project 1st.'
  2456.                     );
  2457.                     return $this->redirect($url "/" $projectId);
  2458.                 }
  2459.                 $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
  2460.                     array(
  2461.                         'projectId' => $projectId///material
  2462.                         'approved' => GeneralConstant::APPROVED
  2463.                     )
  2464.                 );
  2465.                 $boqData $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
  2466.                     array(
  2467.                         'projectId' => $projectId///material
  2468.                     )
  2469.                 );
  2470.                 //now if its not editable, redirect to view
  2471.                 if (!$materialData && ($projectData->getBomRequired() == 1)) {
  2472.                     $url $this->generateUrl(
  2473.                         'create_project_material'
  2474.                     );
  2475.                     $this->addFlash(
  2476.                         'error',
  2477.                         'Please Create Material Listings for the project 1st.'
  2478.                     );
  2479.                     return $this->redirect($url "/" $projectId);
  2480.                 }
  2481.             } else {
  2482.                 $this->addFlash(
  2483.                     'error',
  2484.                     'Sorry!  Could not find your desired project data or this action is not allowed for your specific project at the moment..'
  2485.                 );
  2486.             }
  2487.         }
  2488.         $companyId $this->getLoggedUserCompanyId($request);
  2489.         $productListArray = [];
  2490.         $subCategoryListArray = [];
  2491.         $categoryListArray = [];
  2492.         $igListArray = [];
  2493.         $unitListArray = [];
  2494.         $currencyList Inventory::CurrencyList($em);
  2495.         $currencyListArray = [];
  2496.         $productList Inventory::ProductList($em$companyId);
  2497.         $subCategoryList Inventory::ProductSubCategoryList($em$companyId);
  2498.         $categoryList Inventory::ProductCategoryList($em$companyId);
  2499.         $igList Inventory::ItemGroupList($em$companyId);
  2500.         $unitList Inventory::UnitTypeList($em);
  2501.         foreach ($productList as $product) {
  2502.             $productListArray[] = $product;
  2503.         }
  2504.         foreach ($categoryList as $product) {
  2505.             $categoryListArray[] = $product;
  2506.         }
  2507.         foreach ($subCategoryList as $product) {
  2508.             $subCategoryListArray[] = $product;
  2509.         }
  2510.         foreach ($igList as $product) {
  2511.             $igListArray[] = $product;
  2512.         }
  2513.         foreach ($unitList as $product) {
  2514.             $unitListArray[] = $product;
  2515.         }
  2516.         $brandList Inventory::GetBrandList($em$companyId);
  2517.         $brandListArray = [];
  2518.         foreach ($brandList as $product) {
  2519.             $brandListArray[] = $product;
  2520.         }
  2521.         $qry $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
  2522.             "status" => GeneralConstant::ACTIVE,
  2523.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  2524. //            'type'=>1//trade items
  2525.         ));
  2526.         $sl = [];
  2527.         $sl_array = [];
  2528.         foreach ($qry as $product) {
  2529.             $sl[$product->getServiceId()] = array(
  2530.                 'text' => $product->getServiceName(),
  2531.                 'value' => $product->getServiceId(),
  2532.                 'name' => $product->getServiceName(),
  2533.                 'id' => $product->getServiceId(),
  2534.             );
  2535.             $sl_array[] = array(
  2536.                 'text' => $product->getServiceName(),
  2537.                 'value' => $product->getServiceId(),
  2538.                 'name' => $product->getServiceName(),
  2539.                 'id' => $product->getServiceId(),
  2540.             );
  2541.         }
  2542.         $hl Accounts::HeadList($em);
  2543.         $debug_data $request->files->get('product_reference_file');
  2544.         return $this->render('@Project/pages/input_forms/create_project_boq.html.twig',
  2545.             array(
  2546.                 'page_title' => 'BOQ',
  2547. //                'clients'=>SalesOrderM::GetClientList($em),
  2548. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  2549.                 'users' => Users::getUserListById($em),
  2550.                 'stages' => ProjectConstant::$projectStages,
  2551.                 'sl' => $sl,
  2552.                 'productList' => $productList,
  2553.                 'subCategoryList' => $subCategoryList,
  2554.                 'categoryList' => $categoryList,
  2555.                 'igList' => $igList,
  2556.                 'userRestrictions' => Users::getUserApplicationAccessSettings($em$request->getSession()->get(UserConstants::USER_ID))['options'],
  2557.                 'unitList' => $unitList,
  2558.                 'brandList' => $brandList,
  2559.                 'brandListArray' => $brandListArray,
  2560.                 'currencyList' => $currencyList,
  2561.                 'currencyListArray' => $currencyListArray,
  2562.                 'productListArray' => $productListArray,
  2563.                 'subCategoryListArray' => $subCategoryListArray,
  2564.                 'categoryListArray' => $categoryListArray,
  2565.                 'igListArray' => $igListArray,
  2566.                 'unitListArray' => $unitListArray,
  2567.                 'hl' => $hl,
  2568.                 'projectList' => $projectList,
  2569.                 'projectData' => $projectData,
  2570.                 'materialData' => $materialData,
  2571.                 'extDocData' => $boqData,
  2572.                 'message' => $message,
  2573.                 'projectId' => $projectId,
  2574.                 'sl_array' => $sl_array,
  2575.                 'debug_data' => $debug_data,
  2576. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  2577.             )
  2578.         );
  2579.     }
  2580.     public function ToggleLockProjectAction(Request $request$id 0)
  2581.     {
  2582.         $em $this->getDoctrine()->getManager();
  2583.         $prj $em->getRepository("ApplicationBundle\\Entity\\Project")->findOneBy(array(
  2584.             'projectId' => $id
  2585.         ));
  2586.         if ($prj) {
  2587.             if ($prj->getLockFlag() != 1)
  2588.                 $prj->setLockFlag(1);
  2589.             else
  2590.                 $prj->setLockFlag(0);
  2591.             $em->flush();
  2592.             return new JsonResponse(array(
  2593.                 "success" => true,
  2594.                 "status" => $prj->getLockFlag(),
  2595.                 "id" => $id
  2596. //            "file_path"=>$file_path,
  2597. //                "r"=>$r,
  2598. //                "debug_data"=>System::encryptSignature($r)
  2599.             ));
  2600.         }
  2601.         return new JsonResponse(array(
  2602.             "success" => false,
  2603.             "id" => $id
  2604. //            "status"=>$prj->getLockFlag(),
  2605. //            "file_path"=>$file_path,
  2606. //                "r"=>$r,
  2607. //                "debug_data"=>System::encryptSignature($r)
  2608.         ));
  2609.         //for edits
  2610.         $extVoucherData = [];
  2611.         $extVoucherDetailsData = [];
  2612. //        if($voucherId==0)
  2613. //        {
  2614. //
  2615. //        }
  2616. //        else
  2617. //        {
  2618. //
  2619. //            $extTrans=$em->getRepository('ApplicationBundle\\Entity\\AccTransactions')->findOneBy(
  2620. //                array(
  2621. //                    'transactionId'=>$voucherId, ///material
  2622. //
  2623. //                )
  2624. //            );
  2625. //
  2626. //
  2627. //            //now if its not editable, redirect to view
  2628. //            if($extTrans) {
  2629. //                if ($extTrans->getEditFlag() != 1) {
  2630. //                    $url = $this->generateUrl(
  2631. //                        'view_voucher'
  2632. //                    );
  2633. //                    return $this->redirect($url . "/" . $voucherId);
  2634. //                }
  2635. //                else
  2636. //                {
  2637. //                    $extVoucherData=$extTrans;
  2638. //                    $extVoucherDetailsData=Accounts::GetVoucherDataForEdit($em,$voucherId);
  2639. //                }
  2640. //            }
  2641. //            else
  2642. //            {
  2643. //
  2644. //            }
  2645. //
  2646. //        }
  2647. //
  2648. //
  2649. //        return $this->render('ApplicationBundle:pages/accounts/input_forms:journal_voucher.html.twig',
  2650. //            array(
  2651. //                'page_title'=>'Create Journal Voucher',
  2652. //                'transaction'=>[],
  2653. //                'extVoucherData'=>$extVoucherData,
  2654. //                'extVoucherDetailsData'=>$extVoucherDetailsData
  2655. //            )
  2656. //        );
  2657.         return new JsonResponse(array(
  2658.             "success" => true,
  2659.             "status" => $prj->getLockFlag(),
  2660. //            "file_path"=>$file_path,
  2661. //                "r"=>$r,
  2662. //                "debug_data"=>System::encryptSignature($r)
  2663.         ));
  2664. //        $url = $this->generateUrl(
  2665. //            'check_management'
  2666. //        );
  2667. //        return $this->redirect($url );
  2668.     }
  2669.     public function CreateProjectBoqAction(Request $request$projectId 0)
  2670.     {
  2671.         $em $this->getDoctrine()->getManager();
  2672.         if ($request->isMethod('POST')) {
  2673.             $em $this->getDoctrine()->getManager();
  2674.             $entity_id array_flip(GeneralConstant::$Entity_list)['ProjectBoq']; //change
  2675.             $proj_here $this->getDoctrine()
  2676.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  2677.                 ->findOneBy(
  2678.                     array(
  2679.                         'projectId' => $projectId
  2680.                     )
  2681.                 );
  2682.             $dochash "BQ/" $proj_here->getProjectCategoryId() . "/" $proj_here->getClientId() . "/" $projectId//change
  2683.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  2684.             $approveRole $request->request->get('approvalRole');
  2685.             $approveHash $request->request->get('approvalHash');
  2686.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  2687.                 $loginId$approveRole$approveHash$projectId)) {
  2688.                 $this->addFlash(
  2689.                     'error',
  2690.                     'Sorry Couldnot insert Data.'
  2691.                 );
  2692.             } else {
  2693.                 //construct the files
  2694.                 $file_list = array(
  2695.                     'product_files' => [],
  2696.                     'service_files' => [],
  2697.                     'ar_files' => [],
  2698.                 );
  2699.                 if ($request->request->has('products')) {
  2700.                     if ($request->files->has('product_reference_file')) {
  2701.                         foreach ($request->files->get('product_reference_file') as $uploadedFile) {
  2702.                             $path "";
  2703.                             if ($uploadedFile != null) {
  2704.                                 $fileName 'p' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  2705.                                 $path $fileName;
  2706.                                 $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  2707.                                 if (!file_exists($upl_dir)) {
  2708.                                     mkdir($upl_dir0777true);
  2709.                                 }
  2710.                                 $file $uploadedFile->move($upl_dir$path);
  2711.                             }
  2712.                             $file_list['product_files'][] = $path;
  2713.                         }
  2714.                     }
  2715.                 }
  2716.                 if ($request->request->has('services')) {
  2717.                     //construct the ref_files array
  2718.                     $ref_files = [];
  2719.                     $path "";
  2720.                     $file_path "";
  2721.                     if ($request->files->has('service_reference_file')) {
  2722.                         foreach ($request->files->get('service_reference_file') as $uploadedFile) {
  2723. //                        $uploadedFile = $request->files['service_reference_file_' . $request->request->get('service_uid')[$key]];
  2724.                             $path "";
  2725.                             if ($uploadedFile != null) {
  2726.                                 $fileName 's' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  2727.                                 $path $fileName;
  2728.                                 $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  2729.                                 if (!file_exists($upl_dir)) {
  2730.                                     mkdir($upl_dir0777true);
  2731.                                 }
  2732.                                 $file $uploadedFile->move($upl_dir$path);
  2733.                             }
  2734.                             $file_list['service_files'][] = $path;
  2735.                         }
  2736.                     }
  2737.                 }
  2738.                 if ($request->request->has('heads')) {
  2739.                     //construct the ref_files array
  2740.                     $ref_files = [];
  2741.                     $path "";
  2742.                     $file_path "";
  2743.                     if ($request->files->has('ar_reference_file')) {
  2744.                         foreach ($request->files->get('ar_reference_file') as $uploadedFile) {
  2745. //                        $uploadedFile = $request->files['ar_reference_file_' . $request->request->get('ar_uid')[$key]];
  2746.                             $path "";
  2747.                             if ($uploadedFile != null) {
  2748.                                 $fileName 'a' md5(uniqid()) . '.' $uploadedFile->guessExtension();
  2749.                                 $path $fileName;
  2750.                                 $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' $projectId '/';
  2751.                                 if (!file_exists($upl_dir)) {
  2752.                                     mkdir($upl_dir0777true);
  2753.                                 }
  2754.                                 $file $uploadedFile->move($upl_dir$path);
  2755.                             }
  2756.                             $file_list['ar_files'][] = $path;
  2757.                         }
  2758.                     }
  2759.                 }
  2760.                 $document_data_id SalesOrderM::UpdateDocumentData($this->getDoctrine()->getManager(), $request->request->get('documentDataId'), $request->request$file_list);
  2761.                 $projectBoqId ProjectM::CreateNewBoq($this->getDoctrine()->getManager(), $projectId$document_data_id$request->request$dochash$file_list,
  2762.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  2763.                     $this->getLoggedUserCompanyId($request));
  2764.                 //now add Approval info
  2765.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  2766.                 // ── Persist BoQ billing-schedule edits to the project's sales-order
  2767.                 // schedule. The billing_schedule table is the source the milestone-billing
  2768.                 // cron, invoice generation and retention all read; the BoQ form posts the
  2769.                 // same billSchedule* fields as the SO form, so we reuse that exact path.
  2770.                 // Guarded: only runs when the BoQ actually carries schedule rows, so a
  2771.                 // routine BoQ save never wipes the SO's existing (non-invoiced) schedule.
  2772.                 $__boqStruct = (array) $request->request->get('billScheduleStructure', []);
  2773.                 $__hasSchedule false;
  2774.                 foreach ($__boqStruct as $__s) { if ((int) $__s !== 0) { $__hasSchedule true; break; } }
  2775.                 if ($__hasSchedule) {
  2776.                     $__projSos $this->getDoctrine()->getManager()
  2777.                         ->getRepository('ApplicationBundle\\Entity\\SalesOrder')
  2778.                         ->findBy(['projectId' => $projectId], ['salesOrderId' => 'ASC']);
  2779.                     if (!empty($__projSos)) {
  2780.                         $__primarySo $__projSos[0];   // EPC project → its (primary) sales order
  2781.                         $__bsMgr = new \ApplicationBundle\Modules\Sales\BillingScheduleManager($this->getDoctrine()->getManager());
  2782.                         $__bsMgr->saveSchedulesFromRequest(
  2783.                             \ApplicationBundle\Entity\BillingSchedule::OWNER_SALES_ORDER,
  2784.                             (int) $__primarySo->getSalesOrderId(),
  2785.                             null,
  2786.                             $request,
  2787.                             (int) $this->getLoggedUserCompanyId($request),
  2788.                             (int) $loginId
  2789.                         );
  2790.                         $__primarySo->setBillScheduleAmountType(
  2791.                             $request->request->get('billScheduleAmountType'$__primarySo->getBillScheduleAmountType())
  2792.                         );
  2793.                         $this->getDoctrine()->getManager()->flush();
  2794.                     }
  2795.                 }
  2796.                 $approveRole $request->request->get('approvalRole');  //created
  2797.                 $options = array(
  2798.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  2799.                     'notification_server' => $this->container->getParameter('notification_server'),
  2800.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  2801.                     'url' => $this->generateUrl(
  2802.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectBoq']]
  2803.                         ['entity_view_route_path_name']
  2804.                     )
  2805.                 );
  2806.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  2807.                     array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  2808.                     $projectBoqId,
  2809.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  2810.                 );
  2811.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  2812.                     $projectBoqId,
  2813.                     $loginId,
  2814.                     $approveRole,
  2815.                     $request->request->get('approvalHash'));
  2816.                 $this->addFlash(
  2817.                     'success',
  2818.                     'Bill of Quantity Created'
  2819.                 );
  2820.             }
  2821.             $url $this->generateUrl(
  2822.                 'view_project_boq'
  2823.             );
  2824.             $proj_here $this->getDoctrine()
  2825.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  2826.                 ->findOneBy(
  2827.                     array(
  2828.                         'projectId' => $projectId
  2829.                     )
  2830.                 );
  2831.             $marketing_user_ids=json_decode($proj_here->getMarketingUserIds(), true);
  2832.             if($marketing_user_ids== null) {
  2833.                 $marketing_user_ids = [];
  2834.             }
  2835.             $design_user_ids=json_decode($proj_here->getMarketingUserIds(), true);
  2836.             if($design_user_ids== null) {
  2837.                 $design_user_ids = [];
  2838.             }
  2839.             $marketing_user_ids[] = $request->getSession()->get(UserConstants::USER_ID);
  2840.             $proj_here->setMarketingUserIds(json_encode($marketing_user_ids));
  2841.             $this->getDoctrine()->getManager()->flush();
  2842.             System::AddNewNotification(
  2843.                 $this->container->getParameter('notification_enabled'),
  2844.                 $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID),
  2845.                 $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  2846.                 "Bill of Quantity  : " $dochash " Has Been Created For The Project:" $proj_here->getProjectName() . " ",
  2847.                 'user',
  2848.                 array_merge(
  2849.                     $marketing_user_ids,
  2850.                     $design_user_ids
  2851.                 ),
  2852.                 'information',
  2853.                 $url "/" $projectId,
  2854.                 "Bill of Quantity- " $proj_here->getProjectName()
  2855.             );
  2856.             return $this->redirect($url "/" $projectId);
  2857.         }
  2858.         $projectList = [];
  2859.         $projectData = [];
  2860.         $materialData = [];
  2861.         $boqData = [];
  2862.         $message "";
  2863.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  2864.             array(
  2865.                 'projectStep' => array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  2866.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  2867.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  2868.             ), array('projectDate' => 'desc')
  2869.         );
  2870.         if ($projectId == 0) {
  2871.         } else {
  2872.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  2873.                 array(
  2874.                     'projectId' => $projectId///material
  2875. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  2876.                     'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  2877.                     'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  2878.                 ), array('projectDate' => 'desc')
  2879.             );
  2880.             if ($projectData) {
  2881.                 $proposalData $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
  2882.                     array(
  2883.                         'projectId' => $projectId///material
  2884.                         'approved' => GeneralConstant::APPROVED
  2885.                     )
  2886.                 );
  2887.                 if (!$proposalData && $projectData->getProposalRequired() == 1) {
  2888.                     $url $this->generateUrl(
  2889.                         'create_project_proposal'
  2890.                     );
  2891.                     $this->addFlash(
  2892.                         'error',
  2893.                         'Please Create Proposal for the project 1st.'
  2894.                     );
  2895.                     return $this->redirect($url "/" $projectId);
  2896.                 }
  2897.                 $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
  2898.                     array(
  2899.                         'projectId' => $projectId///material
  2900.                         'approved' => GeneralConstant::APPROVED
  2901.                     )
  2902.                 );
  2903.                 $boqData $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
  2904.                     array(
  2905.                         'projectId' => $projectId///material
  2906.                     )
  2907.                 );
  2908.                 //now if its not editable, redirect to view
  2909.                 if (!$materialData && ($projectData->getBomRequired() == 1)) {
  2910.                     $url $this->generateUrl(
  2911.                         'create_project_material'
  2912.                     );
  2913.                     $this->addFlash(
  2914.                         'error',
  2915.                         'Please Create Material Listings for the project 1st.'
  2916.                     );
  2917.                     return $this->redirect($url "/" $projectId);
  2918.                 }
  2919.                 if ($boqData) {
  2920.                     if ($boqData->getEditFlag() != 1) {
  2921.                         $url $this->generateUrl(
  2922.                             'view_project_boq'
  2923.                         );
  2924.                         $this->addFlash(
  2925.                             'error',
  2926.                             'Sorry You cant Edit the document Right now.'
  2927.                         );
  2928.                         return $this->redirect($url "/" $projectId);
  2929.                     }
  2930.                 }
  2931.             } else {
  2932.                 $this->addFlash(
  2933.                     'error',
  2934.                     'Sorry!  Could not find your desired project data or this action is not allowed for your specific project at the moment..'
  2935.                 );
  2936.             }
  2937.         }
  2938.         $companyId $this->getLoggedUserCompanyId($request);
  2939.         $productListArray = [];
  2940.         $subCategoryListArray = [];
  2941.         $categoryListArray = [];
  2942.         $igListArray = [];
  2943.         $unitListArray = [];
  2944.         $productList Inventory::ProductList($em$companyId);
  2945.         $subCategoryList Inventory::ProductSubCategoryList($em$companyId);
  2946.         $categoryList Inventory::ProductCategoryList($em$companyId);
  2947.         $igList Inventory::ItemGroupList($em$companyId);
  2948.         $unitList Inventory::UnitTypeList($em);
  2949.         $currencyList Inventory::CurrencyList($em);
  2950.         $currencyListArray = [];
  2951.         foreach ($productList as $product) {
  2952.             $productListArray[] = $product;
  2953.         }
  2954.         foreach ($categoryList as $product) {
  2955.             $categoryListArray[] = $product;
  2956.         }
  2957.         foreach ($subCategoryList as $product) {
  2958.             $subCategoryListArray[] = $product;
  2959.         }
  2960.         foreach ($igList as $product) {
  2961.             $igListArray[] = $product;
  2962.         }
  2963.         foreach ($unitList as $product) {
  2964.             $unitListArray[] = $product;
  2965.         }
  2966.         $brandList Inventory::GetBrandList($em$companyId);
  2967.         $brandListArray = [];
  2968.         foreach ($brandList as $product) {
  2969.             $brandListArray[] = $product;
  2970.         }
  2971.         $qry $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
  2972.             "status" => GeneralConstant::ACTIVE,
  2973.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  2974. //            'type'=>1//trade items
  2975.         ));
  2976.         $sl = [];
  2977.         $sl_array = [];
  2978.         foreach ($qry as $product) {
  2979.             $sl[$product->getServiceId()] = array(
  2980.                 'text' => $product->getServiceName(),
  2981.                 'value' => $product->getServiceId(),
  2982.                 'name' => $product->getServiceName(),
  2983.                 'id' => $product->getServiceId(),
  2984.             );
  2985.             $sl_array[] = array(
  2986.                 'text' => $product->getServiceName(),
  2987.                 'value' => $product->getServiceId(),
  2988.                 'name' => $product->getServiceName(),
  2989.                 'id' => $product->getServiceId(),
  2990.             );
  2991.         }
  2992.         $hl Accounts::HeadList($em);
  2993.         $debug_data $request->files->get('product_reference_file');
  2994.         return $this->render('@Project/pages/input_forms/create_project_boq.html.twig',
  2995.             array(
  2996.                 'page_title' => 'BOQ',
  2997. //                'clients'=>SalesOrderM::GetClientList($em),
  2998. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  2999.                 'userRestrictions' => Users::getUserApplicationAccessSettings($em$request->getSession()->get(UserConstants::USER_ID))['options'],
  3000.                 'users' => Users::getUserListById($em),
  3001.                 'stages' => ProjectConstant::$projectStages,
  3002.                 'sl' => $sl,
  3003.                 'productList' => $productList,
  3004.                 'subCategoryList' => $subCategoryList,
  3005.                 'categoryList' => $categoryList,
  3006.                 'currencyList' => $currencyList,
  3007.                 'currencyListArray' => $currencyListArray,
  3008.                 'igList' => $igList,
  3009.                 'unitList' => $unitList,
  3010.                 'brandList' => $brandList,
  3011.                 'brandListArray' => $brandListArray,
  3012.                 'productListArray' => $productListArray,
  3013.                 'subCategoryListArray' => $subCategoryListArray,
  3014.                 'categoryListArray' => $categoryListArray,
  3015.                 'igListArray' => $igListArray,
  3016.                 'unitListArray' => $unitListArray,
  3017.                 'hl' => $hl,
  3018.                 'projectList' => $projectList,
  3019.                 'projectData' => $projectData,
  3020.                 'materialData' => $materialData,
  3021.                 'extDocData' => $boqData,
  3022.                 'message' => $message,
  3023.                 'projectId' => $projectId,
  3024.                 'sl_array' => $sl_array,
  3025.                 'debug_data' => $debug_data,
  3026. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  3027.             )
  3028.         );
  3029.     }
  3030.     public function ViewProjectBoqAction(Request $request$id)
  3031.     {
  3032.         $em $this->getDoctrine()->getManager();
  3033.         $themeId $request->get('themeId'1);
  3034.         $defaultColEnabled = array(
  3035.             12345678910111213141516171819202122232425262728293031
  3036.         );
  3037.         $columnsEnabled $request->get('columnsEnabled'$defaultColEnabled);
  3038.         $config $request->get('config', []);
  3039.         if (is_string($columnsEnabled)) $columnsEnabled json_decode($columnsEnabledtrue);
  3040.         if (is_string($config)) $config json_decode($configtrue);
  3041.         if ($config == null$config = [];
  3042.         if ($columnsEnabled == null$columnsEnabled = [];
  3043.         $dt ProjectM::GetBoqDetails($em$id);
  3044.         if (!$dt) {
  3045.             $url $this->generateUrl(
  3046.                 'create_project_boq'
  3047.             );
  3048. //            $this->addFlash(
  3049. //                'error',
  3050. //                'Please Create BOQ for the project 1st.'
  3051. //            );
  3052.             return $this->redirect($url "/" $id);
  3053.         }
  3054.         return $this->render('@Project/pages/views/view_project_boq.html.twig',
  3055.             array(
  3056.                 'page_title' => 'View',
  3057.                 'data' => $dt,
  3058.                 'config' => $config,
  3059.                 'columnsEnabled' => $columnsEnabled,
  3060.                 'theme_id' => $themeId,
  3061.                 'auto_created' => $dt['auto_created'],
  3062.                 'userRestrictions' => Users::getUserApplicationAccessSettings($em$request->getSession()->get(UserConstants::USER_ID))['options'],
  3063.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  3064.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  3065.                 'document_log' => $dt['auto_created'] == System::getDocumentLog($this->getDoctrine()->getManager(),
  3066.                     array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  3067.                     $id,
  3068.                     $dt['created_by'],
  3069.                     $dt['edited_by']) : [],
  3070.                 'users' => Users::getUserListById($em)
  3071.             )
  3072.         );
  3073.     }
  3074.     public function PrintProjectBoqAction(Request $request$id)
  3075.     {
  3076.         $em $this->getDoctrine()->getManager();
  3077.         $themeId $request->get('themeId'1);
  3078.         $defaultColEnabled = array(
  3079.             12345678910111213141516171819202122232425262728293031
  3080.         );
  3081.         $columnsEnabled $request->get('columnsEnabled'$defaultColEnabled);
  3082.         if ($themeId == 2)
  3083.             $columnsEnabled array_diff($columnsEnabled, [6810121518]);
  3084.         if ($request->get('printType''technical_proposal') == 'technical_proposal') {
  3085.         }
  3086.         $config $request->get('config', []);
  3087.         if (is_string($columnsEnabled)) $columnsEnabled json_decode($columnsEnabledtrue);
  3088.         if (is_string($config)) $config json_decode($configtrue);
  3089.         if ($config == null$config = [];
  3090.         if ($columnsEnabled == null$columnsEnabled = [];
  3091.         $dt ProjectM::GetBoqDetails($em$id);
  3092.         if (!$dt) {
  3093.             $url $this->generateUrl(
  3094.                 'create_project_boq'
  3095.             );
  3096.             $this->addFlash(
  3097.                 'error',
  3098.                 'Please Create BOQ for the project 1st.'
  3099.             );
  3100.             return $this->redirect($url "/" $id);
  3101.         }
  3102.         $company_data Company::getCompanyData($em1);
  3103.         $document_mark = array(
  3104.             'original' => '/images/Original-Stamp-PNG-Picture.png',
  3105.             'copy' => ''
  3106.         );
  3107.         if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
  3108.             $html $this->renderView('@Project/pages/print/print_project_boq.html.twig',
  3109.                 array(
  3110.                     //full array here
  3111.                     'pdf' => true,
  3112.                     'page_title' => 'Project BOM',
  3113.                     'export' => 'pdf,print',
  3114.                     'config' => $config,
  3115.                     'columnsEnabled' => $columnsEnabled,
  3116.                     'theme_id' => $themeId,
  3117.                     'data' => $dt,
  3118.                     'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  3119.                         $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  3120.                     'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  3121.                         array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  3122.                         $id,
  3123.                         $dt['created_by'],
  3124.                         $dt['edited_by']),
  3125.                     'userRestrictions' => Users::getUserApplicationAccessSettings($em$request->getSession()->get(UserConstants::USER_ID))['options'],
  3126.                     'document_mark_image' => $document_mark['original'],
  3127.                     'document_type' => 'Bill Of Quantity',
  3128.                     'company_name' => $company_data->getName(),
  3129.                     'company_address' => $company_data->getAddress(),
  3130.                     'company_image' => $company_data->getImage(),
  3131.                     'invoice_footer' => $company_data->getInvoiceFooter(),
  3132.                     'red' => 0
  3133.                 )
  3134.             );
  3135.             $pdf_response $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
  3136. //                'orientation' => 'landscape',
  3137. //                'enable-javascript' => true,
  3138. //                'javascript-delay' => 1000,
  3139.                 'no-stop-slow-scripts' => false,
  3140.                 'no-background' => false,
  3141.                 'lowquality' => false,
  3142.                 'encoding' => 'utf-8',
  3143. //            'images' => true,
  3144. //            'cookie' => array(),
  3145.                 'dpi' => 300,
  3146.                 'image-dpi' => 300,
  3147. //                'enable-external-links' => true,
  3148. //                'enable-internal-links' => true
  3149.             ));
  3150.             return new Response(
  3151.                 $pdf_response,
  3152.                 200,
  3153.                 array(
  3154.                     'Content-Type' => 'application/pdf',
  3155.                     'Content-Disposition' => 'attachment; filename="boq.pdf"'
  3156.                 )
  3157.             );
  3158.         }
  3159.         return $this->render('@Project/pages/print/print_project_boq.html.twig',
  3160.             array(
  3161.                 'page_title' => 'Project BOQ',
  3162.                 'export' => 'pdf,print',
  3163.                 'config' => $config,
  3164.                 'columnsEnabled' => $columnsEnabled,
  3165.                 'theme_id' => $themeId,
  3166.                 'data' => $dt,
  3167.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  3168.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  3169.                 'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  3170.                     array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  3171.                     $id,
  3172.                     $dt['created_by'],
  3173.                     $dt['edited_by']),
  3174.                 'userRestrictions' => Users::getUserApplicationAccessSettings($em$request->getSession()->get(UserConstants::USER_ID))['options'],
  3175.                 'document_mark_image' => $document_mark['original'],
  3176.                 'company_name' => $company_data->getName(),
  3177.                 'company_address' => $company_data->getAddress(),
  3178.                 'company_image' => $company_data->getImage(),
  3179.                 'invoice_footer' => $company_data->getInvoiceFooter(),
  3180.                 'red' => 0
  3181.             )
  3182.         );
  3183.     }
  3184.     public function ViewProjectCostingReportAction(Request $request$id)
  3185.     {
  3186.         $em $this->getDoctrine()->getManager();
  3187.         if ($id == 0) {
  3188.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3189.                 array(
  3190. //                    'projectId'=>$projectId, ///material
  3191. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  3192.                     'projectStep' => [3456], ///material
  3193. //                    'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3194. //                    'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3195.                 ), array('projectDate' => 'desc')
  3196.             );
  3197.             if ($projectData)
  3198.                 $id $projectData->getProjectId();
  3199.         }
  3200.         $dt ProjectM::GetProjectCostingDetails($em$id);
  3201.         if (!$dt) {
  3202.             $url $this->generateUrl(
  3203.                 'create_project_boq'
  3204.             );
  3205.             $this->addFlash(
  3206.                 'error',
  3207.                 'Please Create BOQ for the project 1st.'
  3208.             );
  3209.             return $this->redirect($url "/" $id);
  3210.         }
  3211.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  3212.             array(
  3213.                 'projectStep' => [3456]
  3214.             ), array('projectDate' => 'desc')
  3215.         );
  3216. //        dump($dt);
  3217.         return $this->render('@Project/pages/report/project_costing_report.html.twig',
  3218.             array(
  3219.                 'page_title' => 'View',
  3220.                 'data' => $dt,
  3221.                 'projectList' => $projectList,
  3222.                 'projectId' => $id,
  3223.                 'auto_created' => $dt['auto_created'],
  3224.                 'users' => Users::getUserListById($em)
  3225.             )
  3226.         );
  3227.     }
  3228.     public function PrintProjectCostingReportAction(Request $request$id)
  3229.     {
  3230.         $em $this->getDoctrine()->getManager();
  3231.         if ($id == 0) {
  3232.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3233.                 array(
  3234. //                    'projectId'=>$projectId, ///material
  3235. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  3236.                     'projectStep' => [3456], ///material
  3237. //                    'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3238. //                    'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3239.                 ), array('projectDate' => 'desc')
  3240.             );
  3241.             if ($projectData)
  3242.                 $id $projectData->getProjectId();
  3243.         }
  3244.         $dt ProjectM::GetProjectCostingDetails($em$id);
  3245.         if (!$dt) {
  3246.             $url $this->generateUrl(
  3247.                 'create_project_boq'
  3248.             );
  3249.             $this->addFlash(
  3250.                 'error',
  3251.                 'Please Create BOQ for the project 1st.'
  3252.             );
  3253.             return $this->redirect($url "/" $id);
  3254.         }
  3255.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  3256.             array(
  3257.                 'projectStep' => [3456]
  3258.             ), array('projectDate' => 'desc')
  3259.         );
  3260.         $company_data Company::getCompanyData($em1);
  3261.         $document_mark = array(
  3262.             'original' => '/images/Original-Stamp-PNG-Picture.png',
  3263.             'copy' => ''
  3264.         );
  3265.         if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
  3266.             $html $this->renderView('@Project/pages/report/project_costing_report_print.html.twig',
  3267.                 array(
  3268.                     //full array here
  3269.                     'pdf' => true,
  3270.                     'page_title' => 'Project Costing',
  3271.                     'export' => 'pdf,print',
  3272.                     'data' => $dt,
  3273.                     'projectList' => $projectList,
  3274.                     'projectId' => $id,
  3275.                     'auto_created' => $dt['auto_created'],
  3276.                     'users' => Users::getUserListById($em),
  3277.                     'document_mark_image' => $document_mark['original'],
  3278.                     'document_type' => 'Project Costing',
  3279.                     'company_name' => $company_data->getName(),
  3280.                     'company_address' => $company_data->getAddress(),
  3281.                     'company_image' => $company_data->getImage(),
  3282.                     'general_footer' => $company_data->getGeneralFooter(),
  3283.                     'red' => 0
  3284.                 )
  3285.             );
  3286.             $pdf_response $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
  3287. //                'orientation' => 'landscape',
  3288. //                'enable-javascript' => true,
  3289. //                'javascript-delay' => 1000,
  3290.                 'no-stop-slow-scripts' => false,
  3291.                 'no-background' => false,
  3292.                 'lowquality' => false,
  3293.                 'encoding' => 'utf-8',
  3294. //            'images' => true,
  3295. //            'cookie' => array(),
  3296.                 'dpi' => 300,
  3297.                 'image-dpi' => 300,
  3298. //                'enable-external-links' => true,
  3299. //                'enable-internal-links' => true
  3300.             ));
  3301.             return new Response(
  3302.                 $pdf_response,
  3303.                 200,
  3304.                 array(
  3305.                     'Content-Type' => 'application/pdf',
  3306.                     'Content-Disposition' => 'attachment; filename="project_costing.pdf"'
  3307.                 )
  3308.             );
  3309.         }
  3310.         return $this->render('@Project/pages/report/project_costing_report_print.html.twig',
  3311.             array(
  3312.                 'page_title' => 'Project Costing',
  3313.                 'export' => 'pdf,print',
  3314.                 'data' => $dt,
  3315.                 'projectList' => $projectList,
  3316.                 'projectId' => $id,
  3317.                 'auto_created' => $dt['auto_created'],
  3318.                 'users' => Users::getUserListById($em),
  3319.                 'document_mark_image' => $document_mark['original'],
  3320.                 'document_type' => 'Project Costing',
  3321.                 'company_name' => $company_data->getName(),
  3322.                 'company_address' => $company_data->getAddress(),
  3323.                 'company_image' => $company_data->getImage(),
  3324.                 'general_footer' => $company_data->getGeneralFooter(),
  3325.                 'red' => 0
  3326.             )
  3327.         );
  3328.     }
  3329.     public function CreateProjectWpAction(Request $request$projectId 0)
  3330.     {
  3331.         $em $this->getDoctrine()->getManager();
  3332.         if ($request->isMethod('POST')) {
  3333.             $em $this->getDoctrine()->getManager();
  3334.             $entity_id array_flip(GeneralConstant::$Entity_list)['ProjectWp']; //change
  3335.             $proj_here $this->getDoctrine()
  3336.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  3337.                 ->findOneBy(
  3338.                     array(
  3339.                         'projectId' => $projectId
  3340.                     )
  3341.                 );
  3342.             $dochash "WP/" $proj_here->getProjectCategoryId() . "/" $proj_here->getClientId() . "/" $projectId//change
  3343.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  3344.             $approveRole $request->request->get('approvalRole');
  3345.             $approveHash $request->request->get('approvalHash');
  3346.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  3347.                 $loginId$approveRole$approveHash$projectId)) {
  3348.                 $this->addFlash(
  3349.                     'error',
  3350.                     'Sorry Could not insert Data.'
  3351.                 );
  3352.             } else {
  3353.                 //construct the files
  3354.                 $file_list = array(
  3355.                     'product_files' => [],
  3356.                     'service_files' => [],
  3357.                     'ar_files' => [],
  3358.                 );
  3359.                 $projectWpId ProjectM::CreateNewWp($this->getDoctrine()->getManager(), $projectId$request->request$dochash$file_list,
  3360.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  3361.                     $this->getLoggedUserCompanyId($request));
  3362.                 //now add Approval info
  3363.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  3364.                 $approveRole $request->request->get('approvalRole');  //created
  3365.                 $options = array(
  3366.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  3367.                     'notification_server' => $this->container->getParameter('notification_server'),
  3368.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  3369.                     'url' => $this->generateUrl(
  3370.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectWp']]
  3371.                         ['entity_view_route_path_name']
  3372.                     )
  3373.                 );
  3374.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  3375.                     array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3376.                     $projectWpId,
  3377.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  3378.                 );
  3379.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3380.                     $projectWpId,
  3381.                     $loginId,
  3382.                     $approveRole,
  3383.                     $request->request->get('approvalHash'));
  3384.                 $this->addFlash(
  3385.                     'success',
  3386.                     'Work Plan Created'
  3387.                 );
  3388.             }
  3389.             $url $this->generateUrl(
  3390.                 'view_project_wp'
  3391.             );
  3392.             $proj_here $this->getDoctrine()
  3393.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  3394.                 ->findOneBy(
  3395.                     array(
  3396.                         'projectId' => $projectId
  3397.                     )
  3398.                 );
  3399.             System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  3400.                 "Work Schedule  : " $dochash " Has Been Created For The Project:" $proj_here->getProjectName() . " ",
  3401.                 'user',
  3402.                 array_merge(
  3403.                     json_decode($proj_here->getImplementingUserIds(), true),
  3404.                     json_decode($proj_here->getDesigningUserIds(), true)
  3405.                 ),
  3406.                 'information',
  3407.                 $url "/" $projectId,
  3408.                 "Work Schedule - " $proj_here->getProjectName()
  3409.             );
  3410.             return $this->redirect($url "/" $projectId);
  3411.         }
  3412.         $projectList = [];
  3413.         $projectData = [];
  3414.         $materialData = [];
  3415.         $boqData = [];
  3416.         $wpData = [];
  3417.         $message "";
  3418.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  3419.             array(
  3420. //                'projectStep'=>array_flip(ProjectConstant::$projectSteps)['WORK PLAN'], ///material
  3421.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3422.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3423.             ), array('projectDate' => 'desc')
  3424.         );
  3425.         if ($projectId == 0) {
  3426.         } else {
  3427.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3428.                 array(
  3429.                     'projectId' => $projectId///material
  3430. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  3431.                     'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3432.                     'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3433.                 ), array('projectDate' => 'desc')
  3434.             );
  3435.             if ($projectData) {
  3436. //                $proposalData=$em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
  3437. //                    array(
  3438. //                        'projectId'=>$projectId, ///material
  3439. //                        'approved'=>GeneralConstant::APPROVED
  3440. //
  3441. //                    )
  3442. //                );
  3443. //                if(!$proposalData && $projectData->getProposalRequired()==1) {
  3444. //                    $url = $this->generateUrl(
  3445. //                        'create_project_proposal'
  3446. //                    );
  3447. //                    $this->addFlash(
  3448. //                        'error',
  3449. //                        'Please Create Proposal for the project 1st.'
  3450. //                    );
  3451. //                    return $this->redirect($url . "/" . $projectId);
  3452. //                }
  3453. //                $materialData=$em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
  3454. //                    array(
  3455. //                        'projectId'=>$projectId, ///material
  3456. //                        'approved'=>GeneralConstant::APPROVED
  3457. //
  3458. //                    )
  3459. //                );
  3460. //                $boqData=$em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
  3461. //                    array(
  3462. //                        'projectId'=>$projectId, ///material
  3463. //                        'approved'=>GeneralConstant::APPROVED
  3464. //
  3465. //                    )
  3466. //                );
  3467. //                $wpData=$em->getRepository('ApplicationBundle\\Entity\\ProjectWp')->findOneBy(
  3468. //                    array(
  3469. //                        'projectId'=>$projectId, ///material
  3470. //
  3471. //                    )
  3472. //                );
  3473. //
  3474. //                //now if its not editable, redirect to view
  3475. //                if(!$materialData &&( $projectData->getBomRequired()==1)) {
  3476. //                    $url = $this->generateUrl(
  3477. //                        'create_project_material'
  3478. //                    );
  3479. //                    $this->addFlash(
  3480. //                        'error',
  3481. //                        'Please Create Material Listings for the project 1st.'
  3482. //                    );
  3483. //                    return $this->redirect($url . "/" . $projectId);
  3484. //                }
  3485. //                if(!$boqData &&( $projectData->getBoqRequired()==1)) {
  3486. //                    $url = $this->generateUrl(
  3487. //                        'create_project_boq'
  3488. //                    );
  3489. //                    $this->addFlash(
  3490. //                        'error',
  3491. //                        'Please Create Bill of Quantity for the project 1st.'
  3492. //                    );
  3493. //                    return $this->redirect($url . "/" . $projectId);
  3494. //                }
  3495. //                if($wpData) {
  3496. //                    if ($wpData->getEditFlag() != 1) {
  3497. //                        $url = $this->generateUrl(
  3498. //                            'view_project_wp'
  3499. //                        );
  3500. //                        $this->addFlash(
  3501. //                            'error',
  3502. //                            'Sorry You cant Edit the document Right now.'
  3503. //                        );
  3504. //                        return $this->redirect($url . "/" . $projectId);
  3505. //                    }
  3506. //
  3507. //                }
  3508.             } else {
  3509.                 $this->addFlash(
  3510.                     'error',
  3511.                     'Sorry!  Could not find your desired project data or this action is not allowed for your specific project at the moment..'
  3512.                 );
  3513.             }
  3514.         }
  3515.         // Default = the cp-shell Task List (Task Management module). The legacy
  3516.         // codecovers template is opt-in via ?old_theme=1 (?shell=cp still works
  3517.         // and is now the implicit default).
  3518.         $wpTemplate = ($request->query->get('old_theme') == 1)
  3519.             ? '@Project/pages/input_forms/create_project_wp.html.twig'
  3520.             '@TaskManagement/pages/task_list.html.twig';
  3521.         return $this->render($wpTemplate,
  3522.             array(
  3523.                 'page_title' => 'Work Plan',
  3524. //                'clients'=>SalesOrderM::GetClientList($em),
  3525. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  3526.                 'users' => Users::getUserListById($em),
  3527.                 'stages' => ProjectConstant::$projectStages,
  3528.                 'projectList' => $projectList,
  3529.                 'projectData' => $projectData,
  3530.                 'materialData' => $materialData,
  3531.                 'boqData' => $boqData,
  3532.                 'wpData' => $wpData,
  3533.                 'message' => $message,
  3534.                 'projectId' => $projectId,
  3535.                 // Admins (user type 1) may backfill actual start/end dates on tasks
  3536.                 // — e.g. for projects that ran before the work plan was created.
  3537.                 'canEditActual' => ((int) $request->getSession()->get(UserConstants::USER_TYPE) === 1),
  3538. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  3539.             )
  3540.         );
  3541.     }
  3542.     public function TaskCalendarAction(Request $request$projectId 0)
  3543.     {
  3544.         $em $this->getDoctrine()->getManager();
  3545.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  3546.             array(
  3547. //                'projectStep'=>array_flip(ProjectConstant::$projectSteps)['WORK PLAN'], ///material
  3548.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3549.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3550.             ), array('projectDate' => 'desc')
  3551.         );
  3552.         return $this->render('@Project/pages/input_forms/task_calendar.html.twig',
  3553.             array(
  3554.                 'page_title' => 'Work Plan',
  3555. //                'clients'=>SalesOrderM::GetClientList($em),
  3556. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  3557.                 'users' => Users::getUserListById($em),
  3558.                 'stages' => ProjectConstant::$projectStages,
  3559.                 'projectList' => $projectList,
  3560.                 'projectId' => $projectId,
  3561. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  3562.             )
  3563.         );
  3564.     }
  3565.     public function ViewProjectWpAction(Request $request$id)
  3566.     {
  3567.         $em $this->getDoctrine()->getManager();
  3568.         $dt ProjectM::GetWpDetails($em$id);
  3569.         if (!$dt) {
  3570.             $url $this->generateUrl(
  3571.                 'create_project_wp'
  3572.             );
  3573.             $this->addFlash(
  3574.                 'error',
  3575.                 'Please Create Work Plan for the project 1st.'
  3576.             );
  3577.             return $this->redirect($url "/" $id);
  3578.         }
  3579.         return $this->render('@Project/pages/views/view_project_wp.html.twig',
  3580.             array(
  3581.                 'page_title' => 'Work Plan',
  3582.                 'data' => $dt,
  3583.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  3584.                 'auto_created' => $dt['auto_created'],
  3585.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3586.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  3587.                 'document_log' => $dt['auto_created'] == System::getDocumentLog($this->getDoctrine()->getManager(),
  3588.                     array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3589.                     $id,
  3590.                     $dt['created_by'],
  3591.                     $dt['edited_by']) : [],
  3592.                 'users' => Users::getUserListById($em),
  3593.                 'ganttTasks' => ProjectM::GetProjectGanttData($em$idfalse)
  3594.             )
  3595.         );
  3596.     }
  3597.     public function PrintProjectWpAction(Request $request$id)
  3598.     {
  3599.         $em $this->getDoctrine()->getManager();
  3600.         $dt ProjectM::GetWpDetails($em$id);
  3601.         if (!$dt) {
  3602.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3603.                 ['projectId' => $id]
  3604.             );
  3605.             if (!$projectData) {
  3606.                 $this->addFlash(
  3607.                     'error',
  3608.                     'Sorry! Could not find work plan or project data for printing.'
  3609.                 );
  3610.                 return $this->redirect($this->generateUrl('create_project_wp'));
  3611.             }
  3612.             $clientData = [
  3613.                 'clientName' => '',
  3614.                 'addressContact' => '',
  3615.                 'contactNumber' => '',
  3616.             ];
  3617.             if (method_exists($projectData'getClientId') && $projectData->getClientId()) {
  3618.                 $foundClient $em->getRepository('ApplicationBundle\\Entity\\AccClients')->findOneBy(
  3619.                     ['clientId' => $projectData->getClientId()]
  3620.                 );
  3621.                 if ($foundClient) {
  3622.                     $clientData $foundClient;
  3623.                 }
  3624.             }
  3625.             $dt = [
  3626.                 'project_data' => $projectData,
  3627.                 'client_data' => $clientData,
  3628.                 'general_data' => [
  3629.                     'documentHash' => method_exists($projectData'getDocumentHash') ? $projectData->getDocumentHash() : '',
  3630.                     'createdAt' => method_exists($projectData'getProjectDate') && $projectData->getProjectDate() ? $projectData->getProjectDate() : new \DateTime(),
  3631.                     'lastModifiedDate' => method_exists($projectData'getLastModifiedDate') ? $projectData->getLastModifiedDate() : null,
  3632.                     'projectWpDate' => method_exists($projectData'getProjectDate') && $projectData->getProjectDate() ? $projectData->getProjectDate() : new \DateTime(),
  3633.                     'approved' => 0,
  3634.                     'data' => json_encode([[
  3635.                         'workStages' => [
  3636.                             'workStage' => [],
  3637.                             'assignType' => [],
  3638.                             'start_date' => [],
  3639.                             'end_date' => [],
  3640.                             'days' => [],
  3641.                             'remarks' => [],
  3642.                         ]
  3643.                     ]]),
  3644.                     'autoCreated' => 0,
  3645.                     'createdAt' => method_exists($projectData'getProjectDate') && $projectData->getProjectDate() ? $projectData->getProjectDate() : new \DateTime(),
  3646.                 ],
  3647.                 'authorizations' => [],
  3648.                 'created_by' => 0,
  3649.                 'edited_by' => 0,
  3650.                 'updated_at' => null,
  3651.                 'created_at' => null,
  3652.                 'doc_hash' => method_exists($projectData'getDocumentHash') ? $projectData->getDocumentHash() : '',
  3653.                 'projectId' => $id,
  3654.                 'auto_created' => 0
  3655.             ];
  3656.             $this->addFlash(
  3657.                 'warning',
  3658.                 'No saved work plan was found yet. Printing the project shell with empty timeline and task list.'
  3659.             );
  3660.         }
  3661.         $company_data Company::getCompanyData($em1);
  3662.         $document_mark = array(
  3663.             'original' => '/images/Original-Stamp-PNG-Picture.png',
  3664.             'copy' => ''
  3665.         );
  3666.         if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
  3667.             $html $this->renderView('@Project/pages/print/print_project_wp.html.twig',
  3668.                 array(
  3669.                     //full array here
  3670.                     'pdf' => true,
  3671.                     'page_title' => 'Project BOM',
  3672.                     'export' => 'pdf,print',
  3673.                     'data' => $dt,
  3674.                     'ganttTasks' => ProjectM::GetProjectGanttData($em$idfalse),
  3675.                     'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  3676.                     'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3677.                         $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  3678.                     'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  3679.                         array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3680.                         $id,
  3681.                         $dt['created_by'],
  3682.                         $dt['edited_by']),
  3683.                     'document_mark_image' => $document_mark['original'],
  3684.                     'document_type' => 'Bill Of Quantity',
  3685.                     'company_name' => $company_data->getName(),
  3686.                     'company_address' => $company_data->getAddress(),
  3687.                     'company_image' => $company_data->getImage(),
  3688.                     'invoice_footer' => $company_data->getInvoiceFooter(),
  3689.                     'red' => 0
  3690.                 )
  3691.             );
  3692.             $pdf_response $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
  3693. //                'orientation' => 'landscape',
  3694. //                'enable-javascript' => true,
  3695. //                'javascript-delay' => 1000,
  3696.                 'no-stop-slow-scripts' => false,
  3697.                 'no-background' => false,
  3698.                 'lowquality' => false,
  3699.                 'encoding' => 'utf-8',
  3700. //            'images' => true,
  3701. //            'cookie' => array(),
  3702.                 'dpi' => 300,
  3703.                 'image-dpi' => 300,
  3704. //                'enable-external-links' => true,
  3705. //                'enable-internal-links' => true
  3706.             ));
  3707.             return new Response(
  3708.                 $pdf_response,
  3709.                 200,
  3710.                 array(
  3711.                     'Content-Type' => 'application/pdf',
  3712.                     'Content-Disposition' => 'attachment; filename="wp.pdf"'
  3713.                 )
  3714.             );
  3715.         }
  3716.         return $this->render('@Project/pages/print/print_project_wp.html.twig',
  3717.             array(
  3718.                 'page_title' => 'Project WP',
  3719.                 'export' => 'pdf,print',
  3720.                 'data' => $dt,
  3721.                 'ganttTasks' => ProjectM::GetProjectGanttData($em$idfalse),
  3722.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  3723.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3724.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  3725.                 'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  3726.                     array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
  3727.                     $id,
  3728.                     $dt['created_by'],
  3729.                     $dt['edited_by']),
  3730.                 'document_mark_image' => $document_mark['original'],
  3731.                 'company_name' => $company_data->getName(),
  3732.                 'company_address' => $company_data->getAddress(),
  3733.                 'company_image' => $company_data->getImage(),
  3734.                 'invoice_footer' => $company_data->getInvoiceFooter(),
  3735.                 'red' => 0
  3736.             )
  3737.         );
  3738.     }
  3739.     public function GetProjectDataForSoAction(Request $request$id 0)
  3740.     {
  3741.         $em $this->getDoctrine()->getManager();
  3742.         $Content = [];
  3743.         $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3744.             array(
  3745.                 'projectId' => $id///material
  3746.                 'projectStep' => array_flip(ProjectConstant::$projectSteps)['SALES ORDER'],
  3747.             ), array('projectDate' => 'desc')
  3748.         );
  3749.         if ($projectData) {
  3750.             if ($projectData->getOfferRequired() == 1) {
  3751.                 $docData $em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findOneBy(
  3752.                     array(
  3753.                         'projectId' => $id///material
  3754.                     )
  3755.                 );
  3756.                 $Content = array(
  3757.                     'data' => json_decode($docData->getData(), true)[0]
  3758.                 );
  3759.             } else if ($projectData->getBoqRequired() == 1) {
  3760.                 $docData $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
  3761.                     array(
  3762.                         'projectId' => $id///material
  3763.                     )
  3764.                 );
  3765.                 $boqData json_decode($docData->getData(), true)[0];
  3766.                 $Content = array(
  3767.                     'data' => array(
  3768.                         'boqData' => $boqData,
  3769.                         'check_override_markup' => 0,
  3770.                         'boqSalesValue' => isset($boqData['salesValue']) ? $boqData['salesValue'] : 0,
  3771.                         'totalCost' => isset($boqData['totalCost']) ? $boqData['totalCost'] : 0,
  3772.                         'offerSalesValue' => 0
  3773.                     )
  3774.                 );
  3775.             }
  3776.         }
  3777.         if (!$docData)
  3778.             return new JsonResponse(array("success" => false"content" => $Content));;
  3779.         if ($Content) {
  3780. //            $Content=$engine->render('@Sales/pages/report/selected_client_details_for_so.html.twig', array("cd"=>$CD));
  3781.             return new JsonResponse(array("success" => true"content" => $Content));
  3782.         }
  3783.         return new JsonResponse(array("success" => false));
  3784.     }
  3785.     public function CreateProjectOfferAction(Request $request$projectId 0)
  3786.     {
  3787.         $em $this->getDoctrine()->getManager();
  3788.         if ($request->isMethod('POST')) {
  3789.             $em $this->getDoctrine()->getManager();
  3790.             $entity_id array_flip(GeneralConstant::$Entity_list)['ProjectOffer']; //change
  3791.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3792.                 array(
  3793.                     'projectId' => $projectId///material
  3794.                 ), array('projectDate' => 'desc')
  3795.             );
  3796. //            $client=$em->getRepository('ApplicationBundle\\Entity\\AccClients')->findOneBy(
  3797. //                array(
  3798. //                    'clientId'=>$projectData->getClientId(), ///material
  3799. //
  3800. //                ),array('projectDate'=>'desc')
  3801. //            );
  3802.             $dochash "OL/" $projectData->getProjectCategoryId() . "/" $projectData->getClientId() . "/" $projectId//change
  3803.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  3804.             $approveRole $request->request->get('approvalRole');
  3805.             $approveHash $request->request->get('approvalHash');
  3806.             if (!DocValidation::isInsertable($em$entity_id$dochash,
  3807.                 $loginId$approveRole$approveHash$projectId)) {
  3808.                 $this->addFlash(
  3809.                     'error',
  3810.                     'Sorry Couldnot insert Data.'
  3811.                 );
  3812.             } else {
  3813.                 //construct the files
  3814.                 $file_list = array(
  3815.                     'product_files' => [],
  3816.                     'service_files' => [],
  3817.                     'ar_files' => [],
  3818.                 );
  3819.                 $projectWpId ProjectM::CreateNewOffer($this->getDoctrine()->getManager(), $projectId$request->request$dochash,
  3820.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID),
  3821.                     $this->getLoggedUserCompanyId($request));
  3822.                 //now add Approval info
  3823.                 $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  3824.                 $approveRole $request->request->get('approvalRole');  //created
  3825.                 $options = array(
  3826.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  3827.                     'notification_server' => $this->container->getParameter('notification_server'),
  3828.                     'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  3829.                     'url' => $this->generateUrl(
  3830.                         GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectOffer']]
  3831.                         ['entity_view_route_path_name']
  3832.                     )
  3833.                 );
  3834.                 System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
  3835.                     array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  3836.                     $projectWpId,
  3837.                     $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  3838.                 );
  3839.                 System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  3840.                     $projectWpId,
  3841.                     $loginId,
  3842.                     $approveRole,
  3843.                     $request->request->get('approvalHash'));
  3844.                 $this->addFlash(
  3845.                     'success',
  3846.                     'Project Offer Created'
  3847.                 );
  3848.             }
  3849.             $url $this->generateUrl(
  3850.                 'view_project_offer'
  3851.             );
  3852.             $proj_here $this->getDoctrine()
  3853.                 ->getRepository('ApplicationBundle\\Entity\\Project')
  3854.                 ->findOneBy(
  3855.                     array(
  3856.                         'projectId' => $projectId
  3857.                     )
  3858.                 );
  3859.             System::AddNewNotification($this->container->getParameter('notification_enabled'), $this->container->getParameter('notification_server'), $request->getSession()->get(UserConstants::USER_APP_ID), $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  3860.                 "Offer Letter  : " $dochash " Has Been Created For The Project:" $proj_here->getProjectName() . " ",
  3861.                 'user',
  3862.                 array_merge(
  3863.                     json_decode($proj_here->getMarketingUserIds(), true),
  3864.                     json_decode($proj_here->getBillingUserIds(), true),
  3865.                     json_decode($proj_here->getDesigningUserIds(), true)
  3866.                 ),
  3867.                 'information',
  3868.                 $url "/" $projectId,
  3869.                 "Offer Letter- " $proj_here->getProjectName()
  3870.             );
  3871.             return $this->redirect($url "/" $projectId);
  3872.         }
  3873.         $projectList = [];
  3874.         $projectData = [];
  3875.         $materialData = [];
  3876.         $boqData = [];
  3877.         $wpData = [];
  3878.         $offerData = [];
  3879.         $message "";
  3880.         $projectList $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
  3881.             array(
  3882.                 'projectStep' => array_flip(ProjectConstant::$projectSteps)['NEGOTIATION'], ///material
  3883.                 'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3884.                 'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3885.             ), array('projectDate' => 'desc')
  3886.         );
  3887.         if ($projectId == 0) {
  3888.         } else {
  3889.             $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  3890.                 array(
  3891.                     'projectId' => $projectId///material
  3892. //                    'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
  3893.                     'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
  3894.                     'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  3895.                 ), array('projectDate' => 'desc')
  3896.             );
  3897.             if ($projectData) {
  3898.                 $materialData $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
  3899.                     array(
  3900.                         'projectId' => $projectId///material
  3901.                         'approved' => GeneralConstant::APPROVED
  3902.                     )
  3903.                 );
  3904.                 $proposalData $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
  3905.                     array(
  3906.                         'projectId' => $projectId///material
  3907.                         'approved' => GeneralConstant::APPROVED
  3908.                     )
  3909.                 );
  3910.                 if (!$proposalData && $projectData->getProposalRequired() == 1) {
  3911.                     $url $this->generateUrl(
  3912.                         'create_project_proposal'
  3913.                     );
  3914.                     $this->addFlash(
  3915.                         'error',
  3916.                         'Please Create Proposal for the project 1st.'
  3917.                     );
  3918.                     return $this->redirect($url "/" $projectId);
  3919.                 }
  3920.                 $boqData $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
  3921.                     array(
  3922.                         'projectId' => $projectId///material
  3923.                         'approved' => GeneralConstant::APPROVED
  3924.                     )
  3925.                 );
  3926.                 $wpData $em->getRepository('ApplicationBundle\\Entity\\ProjectWp')->findOneBy(
  3927.                     array(
  3928.                         'projectId' => $projectId///material
  3929.                         'approved' => GeneralConstant::APPROVED
  3930.                     )
  3931.                 );
  3932.                 $offerData $em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findOneBy(
  3933.                     array(
  3934.                         'projectId' => $projectId///material
  3935.                     )
  3936.                 );
  3937.                 //now if its not editable, redirect to view
  3938.                 if (!$materialData && ($projectData->getBomRequired() == 1)) {
  3939.                     $url $this->generateUrl(
  3940.                         'create_project_material'
  3941.                     );
  3942.                     $this->addFlash(
  3943.                         'error',
  3944.                         'Please Create Material Listings for the project 1st.'
  3945.                     );
  3946.                     return $this->redirect($url "/" $projectId);
  3947.                 }
  3948.                 if (!$boqData && ($projectData->getBoqRequired() == 1)) {
  3949.                     $url $this->generateUrl(
  3950.                         'create_project_boq'
  3951.                     );
  3952.                     $this->addFlash(
  3953.                         'error',
  3954.                         'Please Create Bill of Quantity for the project 1st.'
  3955.                     );
  3956.                     return $this->redirect($url "/" $projectId);
  3957.                 }
  3958.                 if (!$wpData && ($projectData->getWpRequired() == 1)) {
  3959.                     $url $this->generateUrl(
  3960.                         'create_project_wp'
  3961.                     );
  3962.                     $this->addFlash(
  3963.                         'error',
  3964.                         'Please Create Work Plan for the project 1st.'
  3965.                     );
  3966.                     return $this->redirect($url "/" $projectId);
  3967.                 }
  3968.                 if ($offerData) {
  3969.                     if ($offerData->getEditFlag() != 1) {
  3970.                         $url $this->generateUrl(
  3971.                             'view_project_offer'
  3972.                         );
  3973.                         $this->addFlash(
  3974.                             'error',
  3975.                             'Sorry You cant Edit the document Right now.'
  3976.                         );
  3977.                         return $this->redirect($url "/" $projectId);
  3978.                     }
  3979.                 }
  3980.             } else {
  3981.                 $this->addFlash(
  3982.                     'error',
  3983.                     'Sorry!  Could not find your desired project data or this action is not allowed for your specific project at the moment..'
  3984.                 );
  3985.             }
  3986.         }
  3987.         $qry $em->getRepository("ApplicationBundle\\Entity\\InvProducts")->findBy(array(
  3988.             "status" => GeneralConstant::ACTIVE,
  3989.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  3990.             'type' => 1//trade items
  3991.         ));
  3992.         $pl = [];
  3993.         $pl_array = [];
  3994.         foreach ($qry as $product) {
  3995.             $pl[$product->getId()] = array(
  3996.                 'text' => $product->getName(),
  3997.                 'name' => $product->getName(),
  3998.                 'id' => $product->getId(),
  3999.                 'value' => $product->getId(),
  4000.                 'purchase_price' => $product->getPurchasePrice(),
  4001.                 'sales_price' => $product->getSalesPrice(),
  4002.                 'supplier_id' => $product->getBrandCompany(),
  4003.             );
  4004.             $pl_array[] = array(
  4005.                 'text' => $product->getName(),
  4006.                 'value' => $product->getId(),
  4007.                 'name' => $product->getName(),
  4008.                 'id' => $product->getId(),
  4009.                 'purchase_price' => $product->getPurchasePrice(),
  4010.                 'sales_price' => $product->getSalesPrice(),
  4011.                 'supplier_id' => $product->getBrandCompany(),
  4012.             );
  4013.         }
  4014.         $qry $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
  4015.             "status" => GeneralConstant::ACTIVE,
  4016.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  4017. //            'type'=>1//trade items
  4018.         ));
  4019.         $sl = [];
  4020.         $sl_array = [];
  4021.         foreach ($qry as $product) {
  4022.             $sl[$product->getServiceId()] = array(
  4023.                 'text' => $product->getServiceName(),
  4024.                 'value' => $product->getServiceId(),
  4025.                 'name' => $product->getServiceName(),
  4026.                 'id' => $product->getServiceId(),
  4027.             );
  4028.             $sl_array[] = array(
  4029.                 'text' => $product->getServiceName(),
  4030.                 'value' => $product->getServiceId(),
  4031.                 'name' => $product->getServiceName(),
  4032.                 'id' => $product->getServiceId(),
  4033.             );
  4034.         }
  4035.         $qry $em->getRepository("ApplicationBundle\\Entity\\ProjectWorkStage")->findBy(array(
  4036.             "status" => GeneralConstant::ACTIVE,
  4037.             'CompanyId' => $this->getLoggedUserCompanyId($request),
  4038. //            'type'=>1//trade items
  4039.         ));
  4040.         $workStages = [];
  4041.         $workStages_array = [];
  4042.         foreach ($qry as $product) {
  4043.             $workStages[$product->getProjectWorkStageId()] = array(
  4044.                 'text' => $product->getStageName(),
  4045.                 'value' => $product->getProjectWorkStageId(),
  4046.                 'name' => $product->getStageName(),
  4047.                 'id' => $product->getProjectWorkStageId(),
  4048.             );
  4049.             $workStages_array[] = array(
  4050.                 'text' => $product->getStageName(),
  4051.                 'value' => $product->getProjectWorkStageId(),
  4052.                 'name' => $product->getStageName(),
  4053.                 'id' => $product->getProjectWorkStageId(),
  4054.             );
  4055.         }
  4056.         $hl Accounts::HeadList($em);
  4057.         $debug_data $request->files->get('product_reference_file');
  4058.         return $this->render('@Project/pages/input_forms/create_project_offer.html.twig',
  4059.             array(
  4060.                 'page_title' => 'Offer Letter',
  4061. //                'clients'=>SalesOrderM::GetClientList($em),
  4062. //                'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
  4063.                 'users' => Users::getUserListById($em),
  4064.                 'stages' => ProjectConstant::$projectStages,
  4065.                 'sl' => $sl,
  4066.                 'pl' => $pl,
  4067.                 'hl' => $hl,
  4068.                 'workStages' => $workStages,
  4069.                 'projectList' => $projectList,
  4070.                 'projectData' => $projectData,
  4071.                 'materialData' => $materialData,
  4072.                 'boqData' => $boqData,
  4073.                 'wpData' => $wpData,
  4074.                 'offerData' => $offerData,
  4075.                 'message' => $message,
  4076.                 'projectId' => $projectId,
  4077.                 'pl_array' => $pl_array,
  4078.                 'sl_array' => $sl_array,
  4079.                 'workStages_array' => $workStages_array,
  4080.                 'debug_data' => $debug_data,
  4081. //                'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
  4082.             )
  4083.         );
  4084.     }
  4085.     public function ViewProjectOfferAction(Request $request$id)
  4086.     {
  4087.         $em $this->getDoctrine()->getManager();
  4088.         $dt ProjectM::GetOfferDetails($em$id);
  4089.         ///
  4090. //        $projectData=$em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  4091. //            array(
  4092. //                'projectId'=>$id, ///material
  4093. //                'projectStep'=>array_flip(ProjectConstant::$projectSteps)['NEGOTIATION'], ///material
  4094. ////                'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
  4095. ////                'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
  4096. //            ),array('projectDate'=>'desc')
  4097. //        );
  4098. //        $offerDataList=$em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findBy(
  4099. //            array(
  4100. //                'approved'=>1, ///material
  4101. //
  4102. //            )
  4103. //        );
  4104. //        if(!empty($offerDataList)) {
  4105. //            foreach ($offerDataList as $offerData) {
  4106. //                $all_det_data = json_decode($offerData->getData(), true);
  4107. //                $entry = $all_det_data[0];
  4108. //                $store_items = $entry['boqData']['Products'];
  4109. //                ProjectM::addProductsByFdm($em, $store_items['product_fdm'], $offerData->getCompanyId());
  4110. //
  4111. //            }
  4112. //        }
  4113.         ///////
  4114.         if (!$dt) {
  4115.             $url $this->generateUrl(
  4116.                 'create_project_offer'
  4117.             );
  4118.             $this->addFlash(
  4119.                 'error',
  4120.                 'Please Create Offer for the project 1st.'
  4121.             );
  4122.             return $this->redirect($url "/" $id);
  4123.         }
  4124.         $stage_list ProjectConstant::$projectStages;
  4125.         $status_list ProjectConstant::$projectStatus;
  4126.         $steps_list ProjectConstant::$projectSteps;
  4127.         return $this->render('@Project/pages/views/view_project_offer.html.twig',
  4128.             array(
  4129.                 'page_title' => 'Offer Letter',
  4130.                 'data' => $dt,
  4131. //                'boqData'=>ProjectM::GetBoqDetails($em,$id),
  4132. //                'wpData'=>ProjectM::GetWpDetails($em,$id),
  4133.                 'clientList' => SalesOrderM::GetClientList($em),
  4134.                 'stageList' => $stage_list,
  4135.                 'statusList' => $status_list,
  4136.                 'stepsList' => $steps_list,
  4137.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  4138.                 'auto_created' => $dt['auto_created'],
  4139.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  4140.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  4141.                 'document_log' => $dt['auto_created'] == System::getDocumentLog($this->getDoctrine()->getManager(),
  4142.                     array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  4143.                     $id,
  4144.                     $dt['created_by'],
  4145.                     $dt['edited_by']) : [],
  4146.                 'users' => Users::getUserListById($em)
  4147.             )
  4148.         );
  4149.     }
  4150.     public function PrintProjectOfferAction(Request $request$id)
  4151.     {
  4152.         $em $this->getDoctrine()->getManager();
  4153.         $dt ProjectM::GetOfferDetails($em$id);
  4154.         if (!$dt) {
  4155.             $url $this->generateUrl(
  4156.                 'create_project_offer'
  4157.             );
  4158.             $this->addFlash(
  4159.                 'error',
  4160.                 'Please Create Offer for the project 1st.'
  4161.             );
  4162.             return $this->redirect($url "/" $id);
  4163.         }
  4164.         $company_data Company::getCompanyData($em1);
  4165.         $document_mark = array(
  4166.             'original' => '/images/Original-Stamp-PNG-Picture.png',
  4167.             'copy' => ''
  4168.         );
  4169.         if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
  4170.             $html $this->renderView('@Project/pages/print/print_project_offer.html.twig',
  4171.                 array(
  4172.                     //full array here
  4173.                     'pdf' => true,
  4174.                     'page_title' => 'Offer Letter',
  4175.                     'export' => 'pdf,print',
  4176.                     'data' => $dt,
  4177.                     'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  4178.                     'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  4179.                         $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  4180.                     'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  4181.                         array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  4182.                         $id,
  4183.                         $dt['created_by'],
  4184.                         $dt['edited_by']),
  4185.                     'document_mark_image' => $document_mark['original'],
  4186.                     'document_type' => 'Offer Letter',
  4187.                     'company_name' => $company_data->getName(),
  4188.                     'company_address' => $company_data->getAddress(),
  4189.                     'company_image' => $company_data->getImage(),
  4190.                     'invoice_footer' => $company_data->getInvoiceFooter(),
  4191.                     'red' => 0
  4192.                 )
  4193.             );
  4194.             $pdf_response $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
  4195. //                'orientation' => 'landscape',
  4196. //                'enable-javascript' => true,
  4197. //                'javascript-delay' => 1000,
  4198.                 'no-stop-slow-scripts' => false,
  4199.                 'no-background' => false,
  4200.                 'lowquality' => false,
  4201.                 'encoding' => 'utf-8',
  4202. //            'images' => true,
  4203. //            'cookie' => array(),
  4204.                 'dpi' => 300,
  4205.                 'image-dpi' => 300,
  4206. //                'enable-external-links' => true,
  4207. //                'enable-internal-links' => true
  4208.             ));
  4209.             return new Response(
  4210.                 $pdf_response,
  4211.                 200,
  4212.                 array(
  4213.                     'Content-Type' => 'application/pdf',
  4214.                     'Content-Disposition' => 'attachment; filename="offer.pdf"'
  4215.                 )
  4216.             );
  4217.         }
  4218.         return $this->render('@Project/pages/print/print_project_offer.html.twig',
  4219.             array(
  4220.                 'page_title' => 'Project Offer Letter',
  4221.                 'export' => 'pdf,print',
  4222.                 'data' => $dt,
  4223.                 'stage_list' => ProjectM::GetWorkStageList($em$this->getLoggedUserCompanyId($request)),
  4224.                 'approval_data' => System::checkIfApprovalExists($emarray_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  4225.                     $id$request->getSession()->get(UserConstants::USER_LOGIN_ID)),
  4226.                 'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
  4227.                     array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  4228.                     $id,
  4229.                     $dt['created_by'],
  4230.                     $dt['edited_by']),
  4231.                 'document_mark_image' => $document_mark['original'],
  4232.                 'company_name' => $company_data->getName(),
  4233.                 'company_address' => $company_data->getAddress(),
  4234.                 'company_image' => $company_data->getImage(),
  4235.                 'invoice_footer' => $company_data->getInvoiceFooter(),
  4236.                 'red' => 0
  4237.             )
  4238.         );
  4239.     }
  4240.     public function ProjectListAction(Request $request)
  4241.     {
  4242.         $em $this->getDoctrine()->getManager();
  4243.         $stage_list ProjectConstant::$projectStages;
  4244.         $status_list ProjectConstant::$projectStatus;
  4245.         $steps_list ProjectConstant::$projectSteps;
  4246.         return $this->render('@Project/pages/listing/project_list.html.twig',
  4247.             array(
  4248.                 'page_title' => 'Project List',
  4249.                 'data' => ProjectM::GetProjectList($em),
  4250.                 'sales_person_list' => Client::SalesPersonList($this->getDoctrine()->getManager()),
  4251.                 'clientList' => SalesOrderM::GetClientList($em),
  4252.                 'stageList' => $stage_list,
  4253.                 'statusList' => $status_list,
  4254.                 'stepsList' => $steps_list,
  4255.                 'stepsListRoutes' => ProjectConstant::$projectStepsRoutes
  4256.             )
  4257.         );
  4258.     }
  4259.     public function NewProjectCategoryAction(Request $request)
  4260.     {
  4261.         $em $this->getDoctrine()->getManager();
  4262.         if ($request->isMethod('POST')) {
  4263.             // Check if store already exists.
  4264. //            if(Service::CheckIfServiceExists($this->getDoctrine()->getManager(), $request->request->get('service_name'))){
  4265. //                $this->addFlash(
  4266. //                    'error',
  4267. //                    'Service already exists'
  4268. //                );
  4269. //
  4270. //                return $this->redirectToRoute("create_service");
  4271. //            }
  4272.             ProjectM::CreateNewCategory(
  4273.                 $this->getDoctrine()->getManager(),
  4274.                 $this->getLoggedUserCompanyId($request),
  4275.                 $request->request,
  4276.                 $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  4277.             );
  4278.             $this->addFlash(
  4279.                 'success',
  4280.                 'New Category Have Been Added'
  4281.             );
  4282.             return $this->redirectToRoute("create_project_category");
  4283.         }
  4284.         return $this->render('@Project/pages/input_forms/create_project_category.html.twig',
  4285.             array(
  4286.                 'page_title' => 'Project Category',
  4287.                 'categories' => $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy(
  4288.                     array(
  4289.                         "status" => GeneralConstant::ACTIVE,
  4290.                         'CompanyId' => $this->getLoggedUserCompanyId($request),
  4291.                     )
  4292.                 ),
  4293.             )
  4294.         );
  4295.     }
  4296.     public function NewProjectWorkStageAction(Request $request)
  4297.     {
  4298.         $em $this->getDoctrine()->getManager();
  4299.         if ($request->isMethod('POST')) {
  4300.             // Check if store already exists.
  4301. //            if(Service::CheckIfServiceExists($this->getDoctrine()->getManager(), $request->request->get('service_name'))){
  4302. //                $this->addFlash(
  4303. //                    'error',
  4304. //                    'Service already exists'
  4305. //                );
  4306. //
  4307. //                return $this->redirectToRoute("create_service");
  4308. //            }
  4309.             ProjectM::CreateNewWorkStage(
  4310.                 $this->getDoctrine()->getManager(),
  4311.                 $this->getLoggedUserCompanyId($request),
  4312.                 $request->request,
  4313.                 $request->getSession()->get(UserConstants::USER_LOGIN_ID)
  4314.             );
  4315.             $this->addFlash(
  4316.                 'success',
  4317.                 'New Stage Have Been Added'
  4318.             );
  4319.             return $this->redirectToRoute("create_project_work_stage");
  4320.         }
  4321.         return $this->render('@Project/pages/input_forms/create_project_work_stage.html.twig',
  4322.             array(
  4323.                 'page_title' => 'Project Work Stages',
  4324.                 'stages' => $em->getRepository('ApplicationBundle\\Entity\\ProjectWorkStage')->findBy(
  4325.                     array(
  4326.                         "status" => GeneralConstant::ACTIVE,
  4327.                         'CompanyId' => $this->getLoggedUserCompanyId($request),
  4328.                     )
  4329.                 ),
  4330.             )
  4331.         );
  4332.     }
  4333.     public function storeWorkPlanAction(Request $request)
  4334.     {
  4335.         $em $this->getDoctrine()->getManager();
  4336.         $companyId $this->getLoggedUserCompanyId($request);
  4337.         $session $request->getSession();
  4338.         $dependenciesArray = [];
  4339.         $dependencies = array(
  4340.             'id' => $request->get('dependencyPlanId'),
  4341.             'enabled' => $request->get('dependencyEnabled'1),
  4342.             'dependencyMode' => $request->get('dependencyMode'),
  4343.             'dependencyLagDays' => $request->get('dependencyLagDays'),
  4344.             'dependencyCompletionRequired' => $request->get('dependencyCompletionRequired')
  4345.         );
  4346.         if ($request->isMethod('POST')) {
  4347.             if (1) {
  4348.                 $stmt $em->getConnection()->fetchAllAssociative("select  `id` , parent_id, sequence from planning_item where sequence is null
  4349.             ORDER BY parent_id ASC, id ASC
  4350.                         ");
  4351.                 $query_output $stmt;
  4352.                 foreach ($query_output as $dupe) {
  4353.                     System::updatePlanningItemSequence($em$dupe["id"]);
  4354.                 }
  4355.             }
  4356.             $loginId $request->getSession()->get(UserConstants::USER_LOGIN_ID);
  4357.             $plannigItem = new PlanningItem;
  4358.             $taskContextType $request->request->get('taskContextType'$request->request->get('projectSelector'0) ? 'project' 'general');
  4359.             $plannigItem->setProjectId($taskContextType === 'general' null $request->request->get('projectSelector'0));
  4360.             $plannigItem->setItemAlias($request->request->get('planning_task_title'));
  4361.             $plannigItem->setParentId($request->request->get('planning_parent_task_selector'0));
  4362.             $plannigItem->setEntryType($request->request->get('planning_task_type'));
  4363.             $plannigItem->setAssignedTo($request->request->get('planning_task_assigned_to'$session->get(UserConstants::USER_EMPLOYEE_ID)));
  4364.             $plannigItem->setReviewerId($request->request->get('planning_task_reviewer'0));
  4365.             $plannigItem->setEstimatedStartTimeTs($request->request->get('planning_task_start'));
  4366.             $plannigItem->setEstimatedCompletionTimeTs($request->request->get('planning_task_end'));
  4367.             $plannigItem->setUrgency($request->request->get('planning_task_priority'));
  4368.             $plannigItem->setProjectedCost($request->request->get('planning_task_projected_cost'));
  4369.             $plannigItem->setDependencyPlanningData(json_encode($dependencies));
  4370.             $plannigItem->setReferenceType($request->request->get('referenceType'1));
  4371.             $plannigItem->setDescription($request->request->get('planning_task_note'));
  4372.             $plannigItem->setTaskContextType($taskContextType);
  4373.             $plannigItem->setExpectedOutput($request->request->get('expectedOutput'''));
  4374.             $plannigItem->setTaggedDocType($request->request->get('taggedDocType'array_flip(GeneralConstant::$Entity_list)['Project']));
  4375.             $plannigItem->setTaggedDocId($request->request->get('taggedDocId'$request->request->get('projectSelector'0)));
  4376.             $plannigItem->setCurrentState('created');
  4377.             $plannigItem->setReviewStatus('draft');
  4378.             $plannigItem->setKpiCounted(0);
  4379.             $plannigItem->setBlockerSummary($request->request->get('blockerSummary'''));
  4380.             $plannigItem->setNextAction($request->request->get('nextAction'''));
  4381.             $plannigItem->setProjectedCost($request->request->get('projected_cost'0));
  4382.             $plannigItem->setActualCost($request->request->get('actual_cost'0));
  4383.             $plannigItem->setCompanyId($companyId);
  4384.             $plannigItem->setCreatedLoginId($request->getSession()->get(UserConstants::USER_LOGIN_ID));
  4385.             $em->persist($plannigItem);
  4386.             $em->flush();
  4387.             if (1) {
  4388.                 $stmt $em->getConnection()->fetchAllAssociative('select distinct parent_id from planning_item where parent_id is not null and parent_id <> 0;');
  4389.                 $get_kids $stmt;
  4390.                 $p_ids = [];
  4391.                 foreach ($get_kids as $g) {
  4392.                     if (!isset($g['parent_id'])) {
  4393.                         continue;
  4394.                     }
  4395.                     $parentId = (int) $g['parent_id'];
  4396.                     if ($parentId 0) {
  4397.                         $p_ids[] = $parentId;
  4398.                     }
  4399.                 }
  4400.                 $p_ids array_values(array_unique($p_ids));
  4401.                 if (empty($p_ids)) {
  4402.                     $em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0');
  4403.                 } else {
  4404.                     $idList implode(','$p_ids);
  4405.                     $em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0 WHERE id NOT IN (' $idList ')');
  4406.                     $em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 1 WHERE id IN (' $idList ')');
  4407.                 }
  4408.                 $updatedData System::updatePlanningItemSequence($em$plannigItem->getId());
  4409.                 $theEntity $updatedData['primaryOne'];
  4410.                 $theEntityUpdated $theEntity;
  4411.                 if ($theEntityUpdated->getEntryType() == 4)///cashflow
  4412.                 {
  4413.                     MiscActions::AddCashFlowProjection($em0, [
  4414.                         'planningItemId' => $theEntityUpdated->getId(),
  4415.                         'fundRequisitionId' => 0,
  4416.                         'concernedPersonId' => 0,
  4417.                         'type' => 1//exp
  4418.                         'subType' => 1//1== khoroch hobe 2: ashbe
  4419.                         'cashFlowType' => 1//2== RCV /in  1: Payment/out
  4420.                         'creationType' => 1//auto
  4421.                         'amountType' => 1//fund
  4422.                         'cashFlowAmount' => 0,
  4423.                         'expAstAmount' => 0,
  4424.                         'accumulatedCashFlowAmount' => 0,
  4425.                         'accumulatedCashFlowBalance' => 0,
  4426.                         'accumulatedExpAstAmount' => 0,
  4427.                         'relevantExpAstHeadId' => 0,
  4428.                         'balancingHeadId' => 0,
  4429.                         'cashFlowHeadId' => 0,
  4430.                         'cashFlowHeadType' => 1,
  4431.                         'relevantProductIds' => [],
  4432.                         'reminderDateTs' => 0,
  4433.                         'cashFlowDateTs' => 0,
  4434.                         'expAstRealizationDateTs' => 0,
  4435.                     ]);
  4436.                 }
  4437.             }
  4438.         }
  4439.         return new JsonResponse(array(
  4440.             "success" => 'true',
  4441.         ));
  4442.     }
  4443.     public function updateWorkPlanAction(Request $request$id)
  4444.     {
  4445.         $em $this->getDoctrine()->getManager();
  4446.         $session $request->getSession();
  4447.         $planningItem $em->getRepository("ApplicationBundle\\Entity\\PlanningItem")->find($id);
  4448.         if (!$planningItem) {
  4449.             return new JsonResponse(['success' => false'message' => 'Work plan not found']);
  4450.         }
  4451.         if ($request->isMethod('POST')) {
  4452.             $dependencies = [
  4453.                 'id' => $request->request->get('dependencyPlanId'),
  4454.                 'enabled' => $request->request->get('dependencyEnabled'1),
  4455.                 'dependencyMode' => $request->request->get('dependencyMode'),
  4456.                 'dependencyLagDays' => $request->request->get('dependencyLagDays'),
  4457.                 'dependencyCompletionRequired' => $request->request->get('dependencyCompletionRequired'),
  4458.             ];
  4459.             $taskContextType $request->request->get('taskContextType'$planningItem->getTaskContextType() ?: ($request->request->get('projectSelector'0) ? 'project' 'general'));
  4460.             $planningItem->setProjectId($taskContextType === 'general' null $request->request->get('projectSelector'0));
  4461.             $planningItem->setItemAlias($request->request->get('planning_task_title'));
  4462.             $planningItem->setParentId($request->request->get('planning_parent_task_selector'0));
  4463.             $planningItem->setEntryType($request->request->get('planning_task_type'));
  4464.             $planningItem->setAssignedTo($request->request->get('planning_task_assigned_to'$session->get(UserConstants::USER_EMPLOYEE_ID)));
  4465.             $planningItem->setReviewerId($request->request->get('planning_task_reviewer'$planningItem->getReviewerId() ?: 0));
  4466.             $planningItem->setEstimatedStartTimeTs($request->request->get('planning_task_start'));
  4467.             $planningItem->setEstimatedCompletionTimeTs($request->request->get('planning_task_end'));
  4468.             $planningItem->setUrgency($request->request->get('planning_task_priority'));
  4469.             $planningItem->setProjectedCost($request->request->get('projected_cost'0));
  4470.             $planningItem->setActualCost($request->request->get('actual_cost'0));
  4471.             $planningItem->setDependencyPlanningData(json_encode($dependencies));
  4472.             $planningItem->setReferenceType($request->request->get('referenceType'1));
  4473.             $planningItem->setDescription($request->request->get('planning_task_note'));
  4474.             $planningItem->setTaskContextType($taskContextType);
  4475.             if ($request->request->has('expectedOutput')) {
  4476.                 $planningItem->setExpectedOutput($request->request->get('expectedOutput'''));
  4477.             }
  4478.             $planningItem->setTaggedDocType($request->request->get('taggedDocType'$planningItem->getTaggedDocType() ?: array_flip(GeneralConstant::$Entity_list)['Project']));
  4479.             $planningItem->setTaggedDocId($request->request->get('taggedDocId'$request->request->get('projectSelector'$planningItem->getProjectId())));
  4480.             if ($planningItem->getCurrentState() === null) {
  4481.                 $planningItem->setCurrentState('created');
  4482.             }
  4483.             if ($planningItem->getReviewStatus() === null) {
  4484.                 $planningItem->setReviewStatus('draft');
  4485.             }
  4486.             if ($request->request->has('blockerSummary')) {
  4487.                 $planningItem->setBlockerSummary($request->request->get('blockerSummary'''));
  4488.             }
  4489.             if ($request->request->has('nextAction')) {
  4490.                 $planningItem->setNextAction($request->request->get('nextAction'''));
  4491.             }
  4492.             $em->flush();
  4493.             if (1) {
  4494.                 $stmt $em->getConnection()->fetchAllAssociative('select distinct parent_id from planning_item where parent_id is not null and parent_id <> 0;');
  4495.                 $get_kids $stmt;
  4496.                 $p_ids = [];
  4497.                 foreach ($get_kids as $g) {
  4498.                     if (!isset($g['parent_id'])) {
  4499.                         continue;
  4500.                     }
  4501.                     $parentId = (int) $g['parent_id'];
  4502.                     if ($parentId 0) {
  4503.                         $p_ids[] = $parentId;
  4504.                     }
  4505.                 }
  4506.                 $p_ids array_values(array_unique($p_ids));
  4507.                 if (empty($p_ids)) {
  4508.                     $em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0');
  4509.                 } else {
  4510.                     $idList implode(','$p_ids);
  4511.                     $em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0 WHERE id NOT IN (' $idList ')');
  4512.                     $em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 1 WHERE id IN (' $idList ')');
  4513.                 }
  4514.                 
  4515.                 
  4516.                 $updatedData System::updatePlanningItemSequence($em$planningItem->getId());
  4517.                 $theEntity $updatedData['primaryOne'];
  4518.                 $theEntityUpdated $theEntity;
  4519.                 if ($theEntityUpdated->getEntryType() == 4)///cashflow
  4520.                 {
  4521.                     MiscActions::AddCashFlowProjection($em0, [
  4522.                         'planningItemId' => $theEntityUpdated->getId(),
  4523.                         'fundRequisitionId' => 0,
  4524.                         'concernedPersonId' => 0,
  4525.                         'type' => 1//exp
  4526.                         'subType' => 1//1== khoroch hobe 2: ashbe
  4527.                         'cashFlowType' => 1//2== RCV /in  1: Payment/out
  4528.                         'creationType' => 1//auto
  4529.                         'amountType' => 1//fund
  4530.                         'cashFlowAmount' => 0,
  4531.                         'expAstAmount' => 0,
  4532.                         'accumulatedCashFlowAmount' => 0,
  4533.                         'accumulatedCashFlowBalance' => 0,
  4534.                         'accumulatedExpAstAmount' => 0,
  4535.                         'relevantExpAstHeadId' => 0,
  4536.                         'balancingHeadId' => 0,
  4537.                         'cashFlowHeadId' => 0,
  4538.                         'cashFlowHeadType' => 1,
  4539.                         'relevantProductIds' => [],
  4540.                         'reminderDateTs' => 0,
  4541.                         'cashFlowDateTs' => 0,
  4542.                         'expAstRealizationDateTs' => 0,
  4543.                     ]);
  4544.                 }
  4545.             }
  4546.         }
  4547.         return new JsonResponse(array(
  4548.             "success" => 'true',
  4549.         ));
  4550.     }
  4551.     public function activityAction()
  4552.     {
  4553.         $activity GeneralConstant::$activity;
  4554.         return new JsonResponse(array(
  4555.             $activity
  4556.         ));
  4557.     }
  4558.     public function taskInAction(Request $request)
  4559.     {
  4560.         $session $request->getSession();
  4561.         $currentTime = new \Datetime();
  4562.         $currTs $currentTime->format('U');
  4563.         $em $this->getDoctrine()->getManager();
  4564.         $em_goc $this->getDoctrine()->getManager('company_group');
  4565.         $currentTaskId $session->get(UserConstants::USER_CURRENT_TASK_ID0);
  4566.         $currentPlanningItemId $session->get(UserConstants::USER_CURRENT_PLANNING_ITEM_ID0);
  4567.         $token $session->get(UserConstants::USER_TOKEN);
  4568.         $providedToken $request->headers->get('auth-token');
  4569.         if (empty($providedToken) || $providedToken !== $token) {
  4570.             return new JsonResponse([
  4571.                 'status' => 'error',
  4572.                 'message' => 'Token not match or missing',
  4573.             ], 401);
  4574.         }
  4575.         $toSetPlanningItemId $request->request->get('planningItemId'0);
  4576.         $em $this->getDoctrine()->getManager();
  4577.         if($toSetPlanningItemId==0)
  4578.         {
  4579.             $lastTask $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
  4580.                 'userId' => $session->get(UserConstants::USER_ID),
  4581. //                'workingStatus' => 1
  4582.             ],[
  4583.                 'id'=>'desc'
  4584.             ]);
  4585.             if($lastTask)
  4586.                 $toSetPlanningItemId=$lastTask->getPLanningItemId();
  4587.         }
  4588.         $activeTask $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
  4589.             'userId' => $session->get(UserConstants::USER_ID),
  4590.             'workingStatus' => 1
  4591.         ]);
  4592. //        if ($activeTask && $activeTask->getPlanningItemId() != 0)
  4593. //        {
  4594. //
  4595. //        }
  4596. //        if ($activeTask && $activeTask->getPlanningItemId() != 0)
  4597.         if(0)
  4598.         {
  4599.             return new JsonResponse([
  4600.                 'success' => false,
  4601.                 'message' => 'A Task is already active. Please end current task!'
  4602.             ], 200);
  4603.         }
  4604.         if ($request->isMethod('POST')) {
  4605.             $stmt $em->getConnection()->executeStatement('UPDATE task_log set working_status=2, actual_end_ts=' $currTs ' where working_status=1 and user_id= ' $session->get(UserConstants::USER_ID) . ' ;');
  4606.             
  4607.             
  4608.             $taskLog = new TaskLog;
  4609.             $taskLog->setPlanningItemId($toSetPlanningItemId);
  4610.             $taskLog->setUserId($request->request->get('userId'$session->get(UserConstants::USER_ID)));
  4611.             $taskLog->setLogType('session');
  4612.             $taskLog->setWorkingStatus($request->request->get('workingStatus'1));
  4613.             $taskLog->setActualStartTs($request->request->get('actualStartTs'$currTs));
  4614.             $em->persist($taskLog);
  4615.             $em->flush();
  4616.             $currentTaskId $taskLog->getId();
  4617.             $currentPlanningItemId $toSetPlanningItemId;
  4618.             if ($request->request->get('swipe') && $toSetPlanningItemId==0) {
  4619.                 $lastLog $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
  4620.                     'userId' => $session->get(UserConstants::USER_ID),
  4621.                 ], ['id' => 'DESC']);
  4622.                 $currentPlanningItemId $lastLog $lastLog->getPlanningItemId() : 0;
  4623.             }
  4624.             if ($taskLog) {
  4625.                 $empId $session->get(UserConstants::USER_EMPLOYEE_ID0);
  4626.                 $currTime = new \DateTime();
  4627.                 $options = array(
  4628.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  4629.                     'notification_server' => $this->container->getParameter('notification_server'),
  4630.                 );
  4631. //                $positionsArray = [
  4632. //
  4633. //                    array(
  4634. //                        'employeeId' => $empId,
  4635. //                        'userId' => $session->get(UserConstants::USER_ID, 0),
  4636. //                        'sysUserId' => $session->get(UserConstants::USER_ID, 0),
  4637. //                        'timeStamp' => $currTime->format(DATE_ISO8601),
  4638. //                        'lat' => 23.8623834,
  4639. //                        'lng' => 90.3979294,
  4640. //                        'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_GENERAL_TRACKING,
  4641. ////                            'userId'=>$session->get(UserConstants::USER_ID, 0),
  4642. //                    )
  4643. //
  4644. //                ];
  4645.                 $positionsArray=$request->request->get('position_array',[]);
  4646.                 if (is_string($positionsArray)) $positionsArray json_decode($positionsArraytrue);
  4647.                 if ($positionsArray == null$positionsArray = [];
  4648.                 if(empty($positionsArray))
  4649.                 {
  4650.                     $positionsArray = [
  4651.                         array(
  4652.                             'tsMilSec' => 1000*$currTime->format('U'),
  4653.                             'lat' => 23.8623834,
  4654.                             'lng' => 90.3979294,
  4655.                             'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN,
  4656.                             'timeStamp' => $currTime->format(DATE_ISO8601),
  4657.                         )
  4658.                     ];
  4659.                 }
  4660.                 else
  4661.                 {
  4662.                 }
  4663.                 $dataByAttId = [];
  4664.                 $workPlaceType '_UNSET_';
  4665.                 foreach ($positionsArray as $findex => $d) {
  4666.                     $sysUserId 0;
  4667.                     $userId 0;
  4668.                     $empId $session->get(UserConstants::USER_EMPLOYEE_ID0);
  4669.                     $dtTs 0;
  4670.                     $timeZoneStr '+0000';
  4671.                     if (isset($d['employeeId'])) $empId $d['employeeId'];
  4672.                     if (isset($d['userId'])) $userId $d['userId'];
  4673.                     if (isset($d['sysUserId'])) $sysUserId $d['sysUserId'];
  4674.                     if (isset($d['tsMilSec'])) {
  4675.                         $dtTs ceil(($d['tsMilSec']) / 1000);
  4676.                     }
  4677.                     $d['employeeId']=$empId;
  4678.                     $positionsArray[$findex] = $d;
  4679.                     if ($dtTs == 0) {
  4680.                         $currTsTime = new \DateTime();
  4681.                         $dtTs $currTsTime->format('U');
  4682.                     } else {
  4683.                         $currTsTime = new \DateTime('@' $dtTs);
  4684.                     }
  4685.                     $currTsTime->setTimezone(new \DateTimeZone('UTC'));
  4686.                     $attDate = new \DateTime($currTsTime->format('Y-m-d') . ' 00:00:00' $timeZoneStr);
  4687.                     $EmployeeAttendance $this->getDoctrine()
  4688.                         ->getRepository(EmployeeAttendance::class)
  4689.                         ->findOneBy(array('employeeId' => $empId'date' => $attDate));
  4690.                     if (!$EmployeeAttendance) {
  4691.                         $d['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
  4692.                         $positionsArray[$findex]['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
  4693.                         $EmployeeAttendance = new EmployeeAttendance;
  4694.                     } else {
  4695.                         if ($EmployeeAttendance->getCurrentLocation() == 'out') {
  4696.                             $d['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
  4697.                             $positionsArray[$findex]['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
  4698.                         } else {
  4699.                             $d['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_GENERAL_TRACKING;
  4700.                             $positionsArray[$findex]['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_GENERAL_TRACKING;
  4701.                         }
  4702.                     }
  4703.                     $attendanceInfo HumanResource::StoreAttendance($em$empId$sysUserId$request$EmployeeAttendance$attDate$dtTs$timeZoneStr$d['markerId']);
  4704.                     if ($d['markerId'] == HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN) {
  4705.                         $workPlaceType '_STATIC_';
  4706.                     }
  4707.                     if (!isset($dataByAttId[$attendanceInfo->getId()]))
  4708.                         $dataByAttId[$attendanceInfo->getId()] = array(
  4709.                             'attendanceInfo' => $attendanceInfo,
  4710.                             'empId' => $empId,
  4711.                             'lat' => 0,
  4712.                             'lng' => 0,
  4713.                             'address' => 0,
  4714.                             'sysUserId' => $sysUserId,
  4715.                             'companyId' => $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  4716.                             'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  4717.                             'positionArray' => []
  4718.                         );
  4719.                     $posData = array(
  4720.                         'ts' => $dtTs,
  4721.                         'lat' => $d['lat'],
  4722.                         'lng' => $d['lng'],
  4723.                         'marker' => $d['markerId'],
  4724.                         'src' => 2,
  4725.                     );
  4726.                     $posDataArray = array(
  4727.                         $dtTs,
  4728.                         $d['lat'],
  4729.                         $d['lng'],
  4730.                         $d['markerId'],
  4731.                         2
  4732.                     );
  4733.                     $dataByAttId[$attendanceInfo->getId()]['markerId'] = $d['markerId'];
  4734.                     //this markerId will be calclulted and modified to check if user is in our out of office/workplace later
  4735.                     $dataByAttId[$attendanceInfo->getId()]['attendanceInfo'] = $attendanceInfo;
  4736.                     $dataByAttId[$attendanceInfo->getId()]['positionArray'][] = $posData;
  4737.                     $dataByAttId[$attendanceInfo->getId()]['lat'] = $d['lat'];  //for last lat lng etc
  4738.                     $dataByAttId[$attendanceInfo->getId()]['lng'] = $d['lng'];  //for last lat lng etc
  4739.                     if (isset($d['address']))
  4740.                         $dataByAttId[$attendanceInfo->getId()]['address'] = $d['address'];  //for last lat lng etc
  4741. //                $dataByAttId[$attendanceInfo->getId()]['positionArray'][]=$posDataArray;
  4742.                 }
  4743.                 $response = array(
  4744.                     'success' => true,
  4745.                 );
  4746.                 foreach ($dataByAttId as $attInfoId => $d) {
  4747.                     $response HumanResource::setAttendanceLogFlutterApp($em,
  4748.                         $d['empId'],
  4749.                         $d['sysUserId'],
  4750.                         $d['companyId'],
  4751.                         $d['appId'],
  4752.                         $request,
  4753.                         $d['attendanceInfo'],
  4754.                         $options,
  4755.                         $d['positionArray'],
  4756.                         $d['lat'],
  4757.                         $d['lng'],
  4758.                         $d['address'],
  4759.                         $d['markerId']
  4760.                     );
  4761.                 }
  4762.                 $session->set(UserConstants::USER_CURRENT_TASK_ID$taskLog->getId());
  4763.                 $session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID$taskLog->getPlanningItemId());
  4764.             } else {
  4765.                 $session->set(UserConstants::USER_CURRENT_TASK_ID0);
  4766.                 $session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID0);
  4767.                 $empId $session->get(UserConstants::USER_EMPLOYEE_ID0);
  4768.                 $currTime = new \DateTime();
  4769.                 $options = array(
  4770.                     'notification_enabled' => $this->container->getParameter('notification_enabled'),
  4771.                     'notification_server' => $this->container->getParameter('notification_server'),
  4772.                 );
  4773. //                $positionsArray = [
  4774. //
  4775. //                    array(
  4776. //                        'employeeId' => $empId,
  4777. //                        'userId' => $session->get(UserConstants::USER_ID, 0),
  4778. //                        'sysUserId' => $session->get(UserConstants::USER_ID, 0),
  4779. //                        'timeStamp' => $currTime->format(DATE_ISO8601),
  4780. //                        'lat' => 23.8623834,
  4781. //                        'lng' => 90.3979294,
  4782. //                        'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT,
  4783. ////                            'userId'=>$session->get(UserConstants::USER_ID, 0),
  4784. //                    )
  4785. //
  4786. //                ];
  4787.                 $positionsArray=$request->request->get('position_array',[]);
  4788.                 if (is_string($positionsArray)) $positionsArray json_decode($positionsArraytrue);
  4789.                 if ($positionsArray == null$positionsArray = [];
  4790.                 if(empty($positionsArray))
  4791.                 {
  4792.                     $positionsArray = [
  4793.                         array(
  4794.                             'tsMilSec' => 1000*$currTime->format('U'),
  4795.                             'lat' => 23.8623834,
  4796.                             'lng' => 90.3979294,
  4797.                             'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN,
  4798.                         )
  4799.                     ];
  4800.                 }
  4801.                 else
  4802.                 {
  4803.                 }
  4804.                 $dataByAttId = [];
  4805.                 $workPlaceType '_UNSET_';
  4806.                 foreach ($positionsArray as $findex => $d) {
  4807.                     $sysUserId 0;
  4808.                     $userId 0;
  4809.                     $empId $session->get(UserConstants::USER_EMPLOYEE_ID0);
  4810.                     $dtTs 0;
  4811.                     $timeZoneStr '+0000';
  4812.                     if (isset($d['employeeId'])) $empId $d['employeeId'];
  4813.                     if (isset($d['userId'])) $userId $d['userId'];
  4814.                     if (isset($d['sysUserId'])) $sysUserId $d['sysUserId'];
  4815.                     if (isset($d['tsMilSec'])) {
  4816.                         $dtTs ceil(($d['tsMilSec']) / 1000);
  4817.                     }
  4818.                     $d['employeeId']=$empId;
  4819.                     $positionsArray[$findex] = $d;
  4820.                     if ($dtTs == 0) {
  4821.                         $currTsTime = new \DateTime();
  4822.                         $dtTs $currTsTime->format('U');
  4823.                     } else {
  4824.                         $currTsTime = new \DateTime('@' $dtTs);
  4825.                     }
  4826.                     $currTsTime->setTimezone(new \DateTimeZone('UTC'));
  4827.                     $attDate = new \DateTime($currTsTime->format('Y-m-d') . ' 00:00:00' $timeZoneStr);
  4828.                     $EmployeeAttendance $this->getDoctrine()
  4829.                         ->getRepository(EmployeeAttendance::class)
  4830.                         ->findOneBy(array('employeeId' => $empId'date' => $attDate));
  4831.                     if (!$EmployeeAttendance) {
  4832.                         continue;
  4833.                     } else {
  4834.                     }
  4835.                     $attendanceInfo HumanResource::StoreAttendance($em$empId$sysUserId$request$EmployeeAttendance$attDate$dtTs$timeZoneStr$d['markerId']);
  4836.                     if ($d['markerId'] == HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT) {
  4837.                         $workPlaceType '_STATIC_';
  4838.                     }
  4839.                     if (!isset($dataByAttId[$attendanceInfo->getId()]))
  4840.                         $dataByAttId[$attendanceInfo->getId()] = array(
  4841.                             'attendanceInfo' => $attendanceInfo,
  4842.                             'empId' => $empId,
  4843.                             'lat' => 0,
  4844.                             'lng' => 0,
  4845.                             'address' => 0,
  4846.                             'sysUserId' => $sysUserId,
  4847.                             'companyId' => $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  4848.                             'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  4849.                             'positionArray' => []
  4850.                         );
  4851.                     $posData = array(
  4852.                         'ts' => $dtTs,
  4853.                         'lat' => $d['lat'],
  4854.                         'lng' => $d['lng'],
  4855.                         'marker' => $d['markerId'],
  4856.                         'src' => 2,
  4857.                     );
  4858.                     $posDataArray = array(
  4859.                         $dtTs,
  4860.                         $d['lat'],
  4861.                         $d['lng'],
  4862.                         $d['markerId'],
  4863.                         2
  4864.                     );
  4865.                     $dataByAttId[$attendanceInfo->getId()]['markerId'] = $d['markerId'];
  4866.                     //this markerId will be calclulted and modified to check if user is in our out of office/workplace later
  4867.                     $dataByAttId[$attendanceInfo->getId()]['attendanceInfo'] = $attendanceInfo;
  4868.                     $dataByAttId[$attendanceInfo->getId()]['positionArray'][] = $posData;
  4869.                     $dataByAttId[$attendanceInfo->getId()]['lat'] = $d['lat'];  //for last lat lng etc
  4870.                     $dataByAttId[$attendanceInfo->getId()]['lng'] = $d['lng'];  //for last lat lng etc
  4871.                     if (isset($d['address']))
  4872.                         $dataByAttId[$attendanceInfo->getId()]['address'] = $d['address'];  //for last lat lng etc
  4873. //                $dataByAttId[$attendanceInfo->getId()]['positionArray'][]=$posDataArray;
  4874.                 }
  4875.                 $response = array(
  4876.                     'success' => true,
  4877.                 );
  4878.                 foreach ($dataByAttId as $attInfoId => $d) {
  4879.                     $response HumanResource::setAttendanceLogFlutterApp($em,
  4880.                         $d['empId'],
  4881.                         $d['sysUserId'],
  4882.                         $d['companyId'],
  4883.                         $d['appId'],
  4884.                         $request,
  4885.                         $d['attendanceInfo'],
  4886.                         $options,
  4887.                         $d['positionArray'],
  4888.                         $d['lat'],
  4889.                         $d['lng'],
  4890.                         $d['address'],
  4891.                         $d['markerId']
  4892.                     );
  4893.                 }
  4894.             }
  4895.             $theEntityUpdated $taskLog;
  4896.         }
  4897.         $session->set(UserConstants::USER_CURRENT_TASK_ID$currentTaskId);
  4898.         $session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID$currentPlanningItemId);
  4899.         $to_set_session_data MiscActions::GetSessionDataFromToken($em_goc$session->get(UserConstants::USER_TOKEN''))['sessionData'];
  4900. //        $to_set_session_data = MiscActions::GetSessionDataFromToken($em_goc, $request->query->get('token'));
  4901.         $to_set_session_data[UserConstants::USER_CURRENT_TASK_ID] = $currentTaskId;
  4902.         $to_set_session_data[UserConstants::USER_CURRENT_PLANNING_ITEM_ID] = $currentPlanningItemId;
  4903. //        MiscActions::CreateTokenFromSessionData($em_goc, $to_set_session_data);
  4904.         $updatedToken MiscActions::CreateTokenFromSessionData($em_goc,
  4905.             $to_set_session_data,
  4906.             1,
  4907.             1,
  4908.             11
  4909.         );
  4910.         return new JsonResponse(array(
  4911.             "success" => 'true',
  4912.             "message" => 'Task added successfully!',
  4913.             "token" => $updatedToken// Return this
  4914.             "currentTaskId" => $currentTaskId,
  4915.             "currentPlanningItemId" => $currentPlanningItemId
  4916.         ));
  4917.     }
  4918.     public function taskOutAction(Request $request)
  4919.     {
  4920.         {
  4921.             $session $request->getSession();
  4922.             $em_goc $this->getDoctrine()->getManager('company_group');
  4923.             $session $request->getSession();
  4924.             $currentTime = new \Datetime();
  4925.             $currTs $currentTime->format('U');
  4926.             $token $session->get(UserConstants::USER_TOKEN);
  4927.             $providedToken $request->headers->get('auth-token');
  4928.             if (empty($providedToken) || $providedToken !== $token) {
  4929.                 return new JsonResponse([
  4930.                     'status' => 'error',
  4931.                     'message' => 'Token mismatched or missing',
  4932.                 ], 401);
  4933.             }
  4934.             $em $this->getDoctrine()->getManager();
  4935.             $activeTask $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
  4936.                 'userId' => $session->get(UserConstants::USER_ID),
  4937.                 'workingStatus' => 1
  4938.             ]);
  4939.             if (!$activeTask) {
  4940.                 return new JsonResponse([
  4941.                     'success' => false,
  4942.                     'message' => 'No active task is found!'
  4943.                 ], 200);
  4944.             }
  4945. //            $currentTaskId = $session->get(UserConstants::USER_CURRENT_TASK_ID, 0);
  4946.             $currentTaskId $activeTask->getId();
  4947.             $planningItemId = (int)$activeTask->getPlanningItemId();
  4948.             $planningItem $planningItemId $em->getRepository('ApplicationBundle\\Entity\\PlanningItem')->find($planningItemId) : null;
  4949.             $hasCompletionPercentage $request->request->has('completionPercentage');
  4950.             $taskStatus strtolower(trim((string)$request->request->get('taskStatus''pending')));
  4951.             $completionPercentage = (float)$request->request->get(
  4952.                 'completionPercentage',
  4953.                 $planningItem && $planningItem->getCompletionPercentage() !== null $planningItem->getCompletionPercentage() : 0
  4954.             );
  4955.             $markDone in_array($taskStatus, ['completed''done''submitted'], true)
  4956.                 || ($hasCompletionPercentage && $completionPercentage >= 100)
  4957.                 || (int)$request->request->get('markDone'0) === 1;
  4958.             $workCompleted trim((string)$request->request->get('workCompleted'''));
  4959.             $evidenceNote trim((string)$request->request->get('evidenceNote'''));
  4960.             $evidenceFiles $request->request->get('evidenceFiles''');
  4961.             $blockerDetail trim((string)$request->request->get('blockerDetail'''));
  4962.             $nextAction trim((string)$request->request->get('nextAction'''));
  4963.             if (is_string($evidenceFiles) && $evidenceFiles !== '') {
  4964.                 $decodedEvidence json_decode($evidenceFilestrue);
  4965.                 if (json_last_error() === JSON_ERROR_NONE) {
  4966.                     $evidenceFiles $decodedEvidence;
  4967.                 }
  4968.             }
  4969.             if ($markDone) {
  4970.                 $evidenceCount 0;
  4971.                 if (is_array($evidenceFiles)) {
  4972.                     $evidenceCount count(array_filter($evidenceFiles, function ($item) {
  4973.                         return trim((string)$item) !== '';
  4974.                     }));
  4975.                 } elseif (is_string($evidenceFiles)) {
  4976.                     $evidenceCount strlen(trim($evidenceFiles)) > 0;
  4977.                 }
  4978.                 if ($workCompleted === '' || $evidenceCount === 0) {
  4979.                     return new JsonResponse([
  4980.                         'success' => false,
  4981.                         'message' => 'Work completed summary and evidence are required before submitting a completed task.'
  4982.                     ], 422);
  4983.                 }
  4984. //                if (!$planningItem || (int)$planningItem->getReviewerId() === 0) {
  4985. //
  4986. //                    return new JsonResponse([
  4987. //                        'success' => false,
  4988. //                        'message' => 'Reviewer must be assigned before a completed task can be submitted for review.'
  4989. //                    ], 422);
  4990. //                }
  4991.                 if ($planningItem && (int)$planningItem->getReviewerId() === 0) {
  4992.                     $decision='approve';
  4993.                     $now=new \DateTime();
  4994.                     if ($decision === 'approve') {
  4995.                         $planningItem->setCurrentState('approved');
  4996.                         $planningItem->setReviewStatus('approved');
  4997.                         $planningItem->setKpiCounted(1);
  4998.                         $planningItem->setApprovedAt($now);
  4999.                         $planningItem->setActualCompletionTimeTs($now->getTimestamp());
  5000.                     } else {
  5001.                         $planningItem->setCurrentState('rejected');
  5002.                         $planningItem->setReviewStatus('rejected');
  5003.                         $planningItem->setKpiCounted(0);
  5004.                         $planningItem->setRejectedAt($now);
  5005.                     }
  5006.                 }
  5007.             }
  5008. //            $currentPlanningItemId = $session->get(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, 0);
  5009.             if (
  5010.                 ($currentTaskId != && $currentTaskId != null && $currentTaskId != '') &&
  5011.                 ($session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_GENERAL ||
  5012.                     $session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_SYSTEM)
  5013.             ) {
  5014.                 $em $this->getDoctrine()->getManager();
  5015.                 $stmt $em->getConnection()->executeStatement('UPDATE task_log set working_status=2, actual_end_ts=' $currTs ' where working_status=1 and user_id= ' $session->get(UserConstants::USER_ID) . ' ;');
  5016.                 if ($planningItem && !$markDone) {
  5017.                     $activeTask->setFeedback(trim((string)$request->request->get('feedback''')));
  5018.                     $activeTask->setNote(trim((string)$request->request->get('feedback''')));
  5019.                     $planningItem->setCompletionPercentage($completionPercentage);
  5020.                     if ($planningItem->getCurrentState() !== 'submitted' && $planningItem->getCurrentState() !== 'approved') {
  5021.                         $planningItem->setCurrentState('in_progress');
  5022.                     }
  5023.                     if (!$planningItem->getReviewStatus()) {
  5024.                         $planningItem->setReviewStatus('draft');
  5025.                     }
  5026.                 }
  5027.                 $em->flush();
  5028.                 if ($markDone && $planningItem && !((int)$planningItem->getReviewerId() === 0)) {
  5029.                     $submissionLog = new TaskLog();
  5030.                     $submissionLog->setPlanningItemId($planningItemId);
  5031.                     $submissionLog->setUserId($session->get(UserConstants::USER_ID));
  5032.                     $submissionLog->setEmployeeId($session->get(UserConstants::USER_EMPLOYEE_ID0));
  5033.                     $submissionLog->setAppId($session->get(UserConstants::USER_APP_ID0));
  5034.                     $submissionLog->setTitle($planningItem->getItemAlias());
  5035.                     $submissionLog->setWorkingStatus(3);
  5036.                     $submissionLog->setStatus(0);
  5037.                     $submissionLog->setCompleted(1);
  5038.                     $submissionLog->setLogType('submission');
  5039.                     $submissionLog->setWorkCompleted($workCompleted);
  5040.                     $submissionLog->setEvidenceFiles(is_array($evidenceFiles) ? json_encode($evidenceFiles) : (string)$evidenceFiles);
  5041.                     $submissionLog->setEvidenceNote($evidenceNote);
  5042.                     $submissionLog->setBlockerDetail($blockerDetail);
  5043.                     $submissionLog->setNextAction($nextAction);
  5044.                     $submissionLog->setNote($workCompleted);
  5045.                     $submissionLog->setFeedback($evidenceNote);
  5046.                     $submissionLog->setActualStartTs($activeTask->getActualStartTs());
  5047.                     $submissionLog->setActualEndTs($currTs);
  5048.                     $submissionLog->setCreatedLoginId($session->get(UserConstants::USER_LOGIN_ID));
  5049.                     $em->persist($submissionLog);
  5050.                     $planningItem->setCompletionPercentage(100);
  5051.                     $planningItem->setCurrentState('submitted');
  5052.                     $planningItem->setReviewStatus('pending');
  5053.                     $planningItem->setSubmittedAt(new \DateTime());
  5054.                     $planningItem->setKpiCounted(0);
  5055.                     $planningItem->setBlockerSummary($blockerDetail);
  5056.                     $planningItem->setNextAction($nextAction);
  5057.                     if (!$planningItem->getActualStartTimeTs()) {
  5058.                         $planningItem->setActualStartTimeTs($activeTask->getActualStartTs());
  5059.                     }
  5060.                     $em->flush();
  5061.                 }
  5062.                 if (1) {
  5063.                     $session->set(UserConstants::USER_CURRENT_TASK_ID0);
  5064.                     $session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID0);
  5065.                     $empId $session->get(UserConstants::USER_EMPLOYEE_ID0);
  5066.                     $currTime = new \DateTime();
  5067.                     $options = array(
  5068.                         'notification_enabled' => $this->container->getParameter('notification_enabled'),
  5069.                         'notification_server' => $this->container->getParameter('notification_server'),
  5070.                     );
  5071. //                    $positionsArray = [
  5072. //                        array(
  5073. //                            'employeeId' => $empId,
  5074. //                            'userId' => $session->get(UserConstants::USER_ID, 0),
  5075. //                            'sysUserId' => $session->get(UserConstants::USER_ID, 0),
  5076. //                            'timeStamp' => $currTime->format(DATE_ISO8601),
  5077. //                            'lat' => 23.8623834,
  5078. //                            'lng' => 90.3979294,
  5079. //                            'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT,
  5080. //                            //                            'userId'=>$session->get(UserConstants::USER_ID, 0),
  5081. //                        )
  5082. //
  5083. //                    ];
  5084.                     $positionsArray=$request->request->get('position_array',[]);
  5085.                     if (is_string($positionsArray)) $positionsArray json_decode($positionsArraytrue);
  5086.                     if ($positionsArray == null$positionsArray = [];
  5087.                     if(empty($positionsArray))
  5088.                     {
  5089.                         $positionsArray = [
  5090.                             array(
  5091.                                 'tsMilSec' => 1000*$currTime->format('U'),
  5092.                                 'lat' => 23.8623834,
  5093.                                 'lng' => 90.3979294,
  5094.                                 'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT,
  5095.                                 'timeStamp' => $currTime->format(DATE_ISO8601),
  5096.                             )
  5097.                         ];
  5098.                     }
  5099.                     else
  5100.                     {
  5101.                     }
  5102.                     $dataByAttId = [];
  5103.                     $workPlaceType '_UNSET_';
  5104.                     foreach ($positionsArray as $findex => $d) {
  5105.                         $sysUserId 0;
  5106.                         $userId 0;
  5107.                         $empId $session->get(UserConstants::USER_EMPLOYEE_ID0);
  5108.                         $dtTs 0;
  5109.                         $timeZoneStr '+0000';
  5110.                         if (isset($d['employeeId'])) $empId $d['employeeId'];
  5111.                         if (isset($d['userId'])) $userId $d['userId'];
  5112.                         if (isset($d['sysUserId'])) $sysUserId $d['sysUserId'];
  5113.                         if (isset($d['tsMilSec'])) {
  5114.                             $dtTs ceil(($d['tsMilSec']) / 1000);
  5115.                         }
  5116.                         $d['employeeId']=$empId;
  5117.                         $positionsArray[$findex] = $d;
  5118.                         if ($dtTs == 0) {
  5119.                             $currTsTime = new \DateTime();
  5120.                             $dtTs $currTsTime->format('U');
  5121.                         } else {
  5122.                             $currTsTime = new \DateTime('@' $dtTs);
  5123.                         }
  5124.                         $currTsTime->setTimezone(new \DateTimeZone('UTC'));
  5125.                         $attDate = new \DateTime($currTsTime->format('Y-m-d') . ' 00:00:00' $timeZoneStr);
  5126.                         $EmployeeAttendance $this->getDoctrine()
  5127.                             ->getRepository(EmployeeAttendance::class)
  5128.                             ->findOneBy(array('employeeId' => $empId'date' => $attDate));
  5129.                         if (!$EmployeeAttendance) {
  5130.                             continue;
  5131.                         } else {
  5132.                         }
  5133.                         $attendanceInfo HumanResource::StoreAttendance($em$empId$sysUserId$request$EmployeeAttendance$attDate$dtTs$timeZoneStr$d['markerId']);
  5134.                         if ($d['markerId'] == HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT) {
  5135.                             $workPlaceType '_STATIC_';
  5136.                         }
  5137.                         if (!isset($dataByAttId[$attendanceInfo->getId()]))
  5138.                             $dataByAttId[$attendanceInfo->getId()] = array(
  5139.                                 'attendanceInfo' => $attendanceInfo,
  5140.                                 'empId' => $empId,
  5141.                                 'lat' => 0,
  5142.                                 'lng' => 0,
  5143.                                 'address' => 0,
  5144.                                 'sysUserId' => $sysUserId,
  5145.                                 'companyId' => $request->getSession()->get(UserConstants::USER_COMPANY_ID),
  5146.                                 'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
  5147.                                 'positionArray' => []
  5148.                             );
  5149.                         $posData = array(
  5150.                             'ts' => $dtTs,
  5151.                             'lat' => $d['lat'],
  5152.                             'lng' => $d['lng'],
  5153.                             'marker' => $d['markerId'],
  5154.                             'src' => 2,
  5155.                         );
  5156.                         $posDataArray = array(
  5157.                             $dtTs,
  5158.                             $d['lat'],
  5159.                             $d['lng'],
  5160.                             $d['markerId'],
  5161.                             2
  5162.                         );
  5163.                         $dataByAttId[$attendanceInfo->getId()]['markerId'] = $d['markerId'];
  5164.                         //this markerId will be calclulted and modified to check if user is in our out of office/workplace later
  5165.                         $dataByAttId[$attendanceInfo->getId()]['attendanceInfo'] = $attendanceInfo;
  5166.                         $dataByAttId[$attendanceInfo->getId()]['positionArray'][] = $posData;
  5167.                         $dataByAttId[$attendanceInfo->getId()]['lat'] = $d['lat'];  //for last lat lng etc
  5168.                         $dataByAttId[$attendanceInfo->getId()]['lng'] = $d['lng'];  //for last lat lng etc
  5169.                         if (isset($d['address']))
  5170.                             $dataByAttId[$attendanceInfo->getId()]['address'] = $d['address'];  //for last lat lng etc
  5171.                         //                $dataByAttId[$attendanceInfo->getId()]['positionArray'][]=$posDataArray;
  5172.                     }
  5173.                     $response = array(
  5174.                         'success' => true,
  5175.                     );
  5176.                     foreach ($dataByAttId as $attInfoId => $d) {
  5177.                         $response HumanResource::setAttendanceLogFlutterApp($em,
  5178.                             $d['empId'],
  5179.                             $d['sysUserId'],
  5180.                             $d['companyId'],
  5181.                             $d['appId'],
  5182.                             $request,
  5183.                             $d['attendanceInfo'],
  5184.                             $options,
  5185.                             $d['positionArray'],
  5186.                             $d['lat'],
  5187.                             $d['lng'],
  5188.                             $d['address'],
  5189.                             $d['markerId']
  5190.                         );
  5191.                     }
  5192.                 }
  5193.             }
  5194.             $currentTaskId 0;
  5195.             $currentPlanningItemId 0;
  5196.             $session->set(UserConstants::USER_CURRENT_TASK_ID$currentTaskId);
  5197.             $session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID$currentPlanningItemId);
  5198.             $to_set_session_data MiscActions::GetSessionDataFromToken($em_goc$token)['sessionData'];
  5199.             $to_set_session_data[UserConstants::USER_CURRENT_TASK_ID] = $currentTaskId;
  5200.             $to_set_session_data[UserConstants::USER_CURRENT_PLANNING_ITEM_ID] = $currentPlanningItemId;
  5201. //                MiscActions::CreateTokenFromSessionData($em_goc, $to_set_session_data);
  5202.             $updatedToken MiscActions::CreateTokenFromSessionData($em_goc$to_set_session_data,
  5203.                 1,
  5204.                 1,
  5205.                 11);
  5206.             return new JsonResponse(array(
  5207.                 "success" => 'true',
  5208.                 "message" => 'Successfully stop task!',
  5209.                 "token" => $updatedToken
  5210.             ));
  5211.         }
  5212.     }
  5213.     public function taskReviewAction(Request $request)
  5214.     {
  5215.         $session $request->getSession();
  5216.         $token $session->get(UserConstants::USER_TOKEN);
  5217.         $providedToken $request->headers->get('auth-token');
  5218.         if (empty($providedToken) || $providedToken !== $token) {
  5219.             return new JsonResponse([
  5220.                 'status' => 'error',
  5221.                 'message' => 'Token not match or missing',
  5222.             ], 401);
  5223.         }
  5224.         if (!$request->isMethod('POST')) {
  5225.             return new JsonResponse([
  5226.                 'success' => false,
  5227.                 'message' => 'Invalid request method'
  5228.             ], 405);
  5229.         }
  5230.         $em $this->getDoctrine()->getManager();
  5231.         $planningItemId = (int)$request->request->get('planningItemId'0);
  5232.         $decision strtolower(trim((string)$request->request->get('decision''')));
  5233.         $reviewComment trim((string)$request->request->get('reviewComment'''));
  5234.         if ($planningItemId === || !in_array($decision, ['approve''reject'], true)) {
  5235.             return new JsonResponse([
  5236.                 'success' => false,
  5237.                 'message' => 'Invalid review payload'
  5238.             ], 422);
  5239.         }
  5240.         $planningItem $em->getRepository('ApplicationBundle\\Entity\\PlanningItem')->find($planningItemId);
  5241.         if (!$planningItem) {
  5242.             return new JsonResponse([
  5243.                 'success' => false,
  5244.                 'message' => 'Task not found'
  5245.             ], 404);
  5246.         }
  5247.         $latestSubmission $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy(
  5248.             [
  5249.                 'planningItemId' => $planningItemId,
  5250.                 'logType' => 'submission'
  5251.             ],
  5252.             [
  5253.                 'id' => 'DESC'
  5254.             ]
  5255.         );
  5256.         if (!$latestSubmission) {
  5257.             return new JsonResponse([
  5258.                 'success' => false,
  5259.                 'message' => 'No submitted task is available for review'
  5260.             ], 422);
  5261.         }
  5262.         $reviewerId = (int)$planningItem->getReviewerId();
  5263.         $currentEmployeeId = (int)$session->get(UserConstants::USER_EMPLOYEE_ID0);
  5264.         $isAuthorizedOverride = (
  5265.             (int)$session->get(UserConstants::USER_TYPE) === UserConstants::USER_TYPE_SYSTEM
  5266.             || (int)$session->get(UserConstants::IS_BUDDYBEE_ADMIN0) === 1
  5267.         );
  5268.         if ($reviewerId === 0) {
  5269.             return new JsonResponse([
  5270.                 'success' => false,
  5271.                 'message' => 'Reviewer must be assigned before review can be completed'
  5272.             ], 422);
  5273.         }
  5274.         if ($reviewerId !== $currentEmployeeId && !$isAuthorizedOverride) {
  5275.             return new JsonResponse([
  5276.                 'success' => false,
  5277.                 'message' => 'You are not assigned as the reviewer for this task'
  5278.             ], 403);
  5279.         }
  5280.         if ($planningItem->getCurrentState() !== 'submitted' || $planningItem->getReviewStatus() !== 'pending') {
  5281.             return new JsonResponse([
  5282.                 'success' => false,
  5283.                 'message' => 'Only submitted tasks waiting for review can be reviewed'
  5284.             ], 422);
  5285.         }
  5286.         $now = new \DateTime();
  5287.         $reviewLog = new TaskLog();
  5288.         $reviewLog->setPlanningItemId($planningItemId);
  5289.         $reviewLog->setUserId($session->get(UserConstants::USER_ID));
  5290.         $reviewLog->setEmployeeId($currentEmployeeId);
  5291.         $reviewLog->setTitle($planningItem->getItemAlias());
  5292.         $reviewLog->setLogType('review');
  5293.         $reviewLog->setReviewDecision($decision);
  5294.         $reviewLog->setReviewComment($reviewComment);
  5295.         $reviewLog->setReviewedBy($session->get(UserConstants::USER_ID));
  5296.         $reviewLog->setReviewedAt($now);
  5297.         $reviewLog->setStatus($decision === 'approve' 0);
  5298.         $reviewLog->setCompleted($decision === 'approve' 0);
  5299.         $reviewLog->setWorkingStatus(4);
  5300.         $reviewLog->setCreatedLoginId($session->get(UserConstants::USER_LOGIN_ID));
  5301.         $em->persist($reviewLog);
  5302.         if ($latestSubmission) {
  5303.             $latestSubmission->setReviewDecision($decision);
  5304.             $latestSubmission->setReviewComment($reviewComment);
  5305.             $latestSubmission->setReviewedBy($session->get(UserConstants::USER_ID));
  5306.             $latestSubmission->setReviewedAt($now);
  5307.             $latestSubmission->setApproved($decision === 'approve' 0);
  5308.         }
  5309.         if ($decision === 'approve') {
  5310.             $planningItem->setCurrentState('approved');
  5311.             $planningItem->setReviewStatus('approved');
  5312.             $planningItem->setKpiCounted(1);
  5313.             $planningItem->setApprovedAt($now);
  5314.             $planningItem->setActualCompletionTimeTs($now->getTimestamp());
  5315.         } else {
  5316.             $planningItem->setCurrentState('rejected');
  5317.             $planningItem->setReviewStatus('rejected');
  5318.             $planningItem->setKpiCounted(0);
  5319.             $planningItem->setRejectedAt($now);
  5320.         }
  5321.         $em->flush();
  5322.         return new JsonResponse([
  5323.             'success' => true,
  5324.             'message' => $decision === 'approve' 'Task approved successfully' 'Task rejected successfully',
  5325.             'planningItemId' => $planningItemId,
  5326.             'decision' => $decision
  5327.         ]);
  5328.     }
  5329.     public function getTaskByProjectIdAction(Request $request)
  5330.     {
  5331.         $em $this->getDoctrine()->getManager();
  5332.         $taskByProjectId $request->query->get('projectId');
  5333.         $taskListByProject $em->getRepository(PlanningItem::class)->createQueryBuilder('A')
  5334.             ->where('A.projectId = :projectId')
  5335.             ->setParameter('projectId'$taskByProjectId)
  5336.             ->getQuery()
  5337.             ->getResult();
  5338.         $taskList = [];
  5339.         foreach ($taskListByProject as $data) {
  5340.             $list = array(
  5341.                 'id' => $data->getId(),
  5342.                 'taskName' => $data->getItemAlias()
  5343.             );
  5344.             $taskList[] = $list;
  5345.         }
  5346.         return new JsonResponse($taskList);
  5347.     }
  5348.     public function TaskLogViewAction(Request $request)
  5349.     {
  5350.         $em $this->getDoctrine()->getManager();
  5351.         $session $request->getSession();
  5352.         $allTask =
  5353.         $queryBuilder $em->createQueryBuilder();
  5354.         $queryBuilder->select(
  5355.             't.planningItemId',
  5356.             't.actualStartTs',
  5357.             't.actualEndTs',
  5358.             't.workingStatus',
  5359.             't.feedback',
  5360.             't.status',
  5361.             't.logType',
  5362.             't.workCompleted',
  5363.             't.evidenceFiles',
  5364.             't.evidenceNote',
  5365.             't.blockerDetail',
  5366.             't.nextAction',
  5367.             't.reviewDecision',
  5368.             't.reviewComment',
  5369.             't.reviewedBy',
  5370.             't.reviewedAt',
  5371.             'p.itemAlias',
  5372.             'p.assignedTo',
  5373.             'p.assignedToType',
  5374.             'p.estimatedStartTimeTs',
  5375.             'p.estimatedCompletionTimeTs',
  5376.             'p.currentState',
  5377.             'p.reviewStatus',
  5378.             'p.reviewerId',
  5379.             'p.taskContextType',
  5380.             'p.expectedOutput',
  5381.             'p.kpiCounted',
  5382.             'p.submittedAt',
  5383.             'p.approvedAt',
  5384.             'p.rejectedAt'
  5385.         )
  5386.             ->from('ApplicationBundle\\Entity\\TaskLog''t')
  5387.             ->leftJoin('ApplicationBundle\\Entity\\PlanningItem''p''WITH''t.planningItemId = p.id');
  5388.         $taskLogData $queryBuilder->getQuery()->getResult();
  5389.         foreach ($taskLogData as &$task) {
  5390.             $assignedToId $task['assignedTo'] ?? null;
  5391.             $assignedToType $task['assignedToType'] ?? null;
  5392.             $entity null;
  5393.             if ($assignedToId !== null) {
  5394.                 if ($assignedToType === || $assignedToType === null || $assignedToType === 0) {
  5395.                     $entity $em->getRepository('ApplicationBundle\\Entity\\Employee')->find($assignedToId);
  5396.                 } elseif ($assignedToType === 2) {
  5397.                     $entity $em->getRepository('ApplicationBundle\\Entity\\SysUser')->find($assignedToId);
  5398.                 }
  5399.             }
  5400.             $task['assignedToName'] = ($entity && method_exists($entity'getName')) ? $entity->getName() : 'Unassigned';
  5401.         }
  5402.         return $this->render(
  5403.             '@Project/pages/report/task_log_views.html.twig',
  5404.             [
  5405.                 'page_title' => 'Task Log',
  5406.                 'task_log_data' => $taskLogData,
  5407.                 'currentEmployeeId' => $session->get(UserConstants::USER_EMPLOYEE_ID0),
  5408.             ]
  5409.         );
  5410.     }
  5411.     public function taskHistoryAction(Request $request)
  5412.     {
  5413.         $em $this->getDoctrine()->getManager();
  5414.         $session $request->getSession();
  5415.         $currentTime = new \DateTime();
  5416.         $currDate $currentTime->format('Y-m-d');
  5417.         $userId $session->get(UserConstants::USER_ID);
  5418.         $queryBuilder $em->createQueryBuilder();
  5419.         $queryBuilder->select(
  5420.             't.id',
  5421.             't.planningItemId',
  5422.             't.actualStartTs',
  5423.             't.actualEndTs',
  5424.             't.userId',
  5425.             'p.itemAlias'
  5426.         )
  5427.             ->from('ApplicationBundle\\Entity\\TaskLog''t')
  5428.             ->leftJoin('ApplicationBundle\\Entity\\PlanningItem''p''WITH''t.planningItemId = p.id')
  5429.             ->where('t.userId = :userId')
  5430.             ->andWhere('t.createdAt >= :date')
  5431.             ->andWhere('t.createdAt <= :date_end')
  5432.             ->setParameter('userId'$userId)
  5433.             ->setParameter('date'$currDate)
  5434.             ->setParameter('date_end'$currDate ' 23:59:59')
  5435.             ->orderBy('t.createdAt''DESC');
  5436.         $taskLogData $queryBuilder->getQuery()->getArrayResult();
  5437.         if (empty($taskLogData)) {
  5438.             return new JsonResponse([
  5439.                 'success' => false,
  5440.                 'message' => 'No task history found',
  5441.                 'data'    => []
  5442.             ]);
  5443.         }
  5444.         return new JsonResponse([
  5445.             'success' => true,
  5446.             'message' => 'Task history fetched successfully',
  5447.             'data'    => $taskLogData,
  5448.         ]);
  5449.     }
  5450.     public function taskDetailsAction(Request $request)
  5451.     {
  5452.         $em $this->getDoctrine()->getManager();
  5453.         $taskId $request->query->get('taskId');
  5454.         // Fetch task details
  5455.         $taskDetails $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->createQueryBuilder('t')
  5456.             ->select(
  5457.                 't.id',
  5458.                 't.planningItemId',
  5459.                 't.actualStartTs',
  5460.                 't.actualEndTs',
  5461.                 'p.itemAlias',
  5462.                 'p.estimatedStartTimeTs',
  5463.                 'p.projectedCost',
  5464.                 'p.actualCost',
  5465.                 'p.estimatedCompletionTimeTs',
  5466.                 'p.completionPercentage',
  5467.                 'p.description'
  5468.             )
  5469.             ->leftJoin('ApplicationBundle\\Entity\\PlanningItem''p''WITH''t.planningItemId = p.id')
  5470.             ->where('t.id = :taskId')
  5471.             ->setParameter('taskId'$taskId)
  5472.             ->getQuery()
  5473.             ->getResult();
  5474.         if (!$taskDetails) {
  5475.             return new JsonResponse(['error' => 'Task not found'], 404);
  5476.         }
  5477.         $taskDetail $taskDetails[0];
  5478.         $planningItemId $taskDetail['planningItemId'];
  5479.         // Add validation for actualCost and projectedCost
  5480.         $taskDetail['actualCost'] = isset($taskDetail['actualCost']) ? $taskDetail['actualCost'] : '';
  5481.         $taskDetail['projectedCost'] = isset($taskDetail['projectedCost']) ? $taskDetail['projectedCost'] : '';
  5482.         // Fetch planning details for history
  5483.         $planningDetails $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->createQueryBuilder('t')
  5484.             ->select('t.planningItemId''t.actualStartTs''t.actualEndTs''p.itemAlias')
  5485.             ->leftJoin('ApplicationBundle\\Entity\\PlanningItem''p''WITH''t.planningItemId = p.id')
  5486.             ->where('t.planningItemId = :planningItemId')
  5487.             ->setParameter('planningItemId'$planningItemId)
  5488.             ->getQuery()
  5489.             ->getResult();
  5490.         // Calculate total work time
  5491.         $totalWorkSeconds 0;
  5492.         foreach ($planningDetails as $task) {
  5493.             if (isset($task['actualStartTs']) && isset($task['actualEndTs'])) {
  5494.                 $totalWorkSeconds += ($task['actualEndTs'] - $task['actualStartTs']);
  5495.             }
  5496.         }
  5497.         $totalHours floor($totalWorkSeconds 3600);
  5498.         $totalMinutes floor(($totalWorkSeconds 3600) / 60);
  5499.         $totalSeconds $totalWorkSeconds 60;
  5500.         $totalWorkHour sprintf('%02d:%02d:%02d'$totalHours$totalMinutes$totalSeconds);
  5501.         return new JsonResponse([
  5502.             'totalWorkHour' => $totalWorkHour,
  5503.             'taskDetails' => $taskDetail,
  5504.             'taskHistory' => $planningDetails,
  5505.         ]);
  5506.     }
  5507.     public function taskHistoryByPlanningItemIdAction(Request $request)
  5508.     {
  5509.         $em $this->getDoctrine()->getManager();
  5510.         $taskId $request->query->get('id');
  5511.         $queryBuilder $em->createQueryBuilder();
  5512.         $queryBuilder
  5513.             ->select('t.planningItemId''t.actualStartTs''t.actualEndTs',
  5514.                 'p.itemAlias''p.estimatedStartTimeTs''p.estimatedCompletionTimeTs',
  5515.                 'p.completionPercentage''p.description''p.projectedCost''p.actualCost')
  5516.             ->from('ApplicationBundle\\Entity\\TaskLog''t')
  5517.             ->leftJoin('ApplicationBundle\\Entity\\PlanningItem''p''WITH''t.planningItemId = p.id')
  5518.             ->where('t.planningItemId = :id')
  5519.             ->setParameter('id'$taskId);
  5520.         $rawData $queryBuilder->getQuery()->getArrayResult();
  5521.         // Sanitize cost fields
  5522.         $taskDetails array_map(function ($item) {
  5523.             $item['projectedCost'] = $item['projectedCost'] ?? '';
  5524.             $item['actualCost'] = $item['actualCost'] ?? '';
  5525.             return $item;
  5526.         }, $rawData);
  5527.         return new JsonResponse($taskDetails);
  5528.     }
  5529.     public function DeleteTaskLogAction(Request $request)
  5530.     {
  5531.         $em $this->getDoctrine()->getManager();
  5532.         $session $request->getSession();
  5533.         $userId $session->get(UserConstants::USER_ID);
  5534.         $query $em->createQuery(
  5535.             'DELETE FROM ApplicationBundle\\Entity\\TaskLog t
  5536.          WHERE t.userId = :userId AND (t.actualEndTs IS NULL OR t.actualEndTs = 0)'
  5537.         );
  5538.         $query->setParameter('userId'$userId);
  5539.         $deletedCount $query->executeStatement();
  5540.         return new Response("Deleted $deletedCount task logs.");
  5541.     }
  5542.     public function taskListAction(Request $request)
  5543.     {
  5544.         if (!$request->isMethod('GET')) {
  5545.             return new JsonResponse([
  5546.                 'success' => false,
  5547.                 'message' => 'Invalid request method'
  5548.             ], 405);
  5549.         }
  5550.         $em $this->getDoctrine()->getManager();
  5551.         $session $request->getSession();
  5552.         $employeeId $session->get(UserConstants::USER_EMPLOYEE_ID);
  5553.         if (!$employeeId) {
  5554.             return new JsonResponse([
  5555.                 'success' => false,
  5556.                 'message' => 'Unauthorized access'
  5557.             ], 401);
  5558.         }
  5559.         $page max((int) $request->query->get('page'1), 1);
  5560.         $limit max((int) $request->query->get('limit'10), 1);
  5561.         $offset = ($page 1) * $limit;
  5562.         $total = (int) $em->getRepository(PlanningItem::class)
  5563.             ->createQueryBuilder('P')
  5564.             ->select('COUNT(P.id)')
  5565.             ->where('P.assignedTo = :employeeId')
  5566.             ->setParameter('employeeId'$employeeId)
  5567.             ->getQuery()
  5568.             ->getSingleScalarResult();
  5569.         $taskRecords $em->getRepository(PlanningItem::class)
  5570.             ->createQueryBuilder('P')
  5571.             ->select(
  5572.                 'P.id',
  5573.                 'P.itemAlias',
  5574.                 'P.estimatedStartTimeTs',
  5575.                 'P.estimatedCompletionTimeTs',
  5576.                 'P.actualStartTimeTs',
  5577.                 'P.actualCompletionTimeTs'
  5578.             )
  5579.             ->where('P.assignedTo = :employeeId')
  5580.             ->setParameter('employeeId'$employeeId)
  5581.             ->setFirstResult($offset)
  5582.             ->setMaxResults($limit)
  5583.             ->orderBy('P.id''DESC')
  5584.             ->getQuery()
  5585.             ->getResult();
  5586.         $formattedData = [];
  5587.         foreach ($taskRecords as $task) {
  5588.             $formattedData[] = [
  5589.                 'taskId' => $task['id'],
  5590.                 'itemAlias' => $task['itemAlias'],
  5591.                 'estimatedStartTimeTs' => $task['estimatedStartTimeTs'],
  5592.                 'estimatedCompletionTimeTs' => $task['estimatedCompletionTimeTs'],
  5593.                 'actualStartTimeTs' => $task['actualStartTimeTs'],
  5594.                 'actualCompletionTimeTs' => $task['actualCompletionTimeTs'],
  5595.             ];
  5596.         }
  5597.         return new JsonResponse([
  5598.             'success' => true,
  5599.             'message' => 'Task list fetched successfully',
  5600.             'data' => $formattedData,
  5601.             'currentPage' => $page,
  5602.             'limit' => $limit,
  5603.             'total' => $total,
  5604.             'totalPages' => ceil($total $limit),
  5605.         ]);
  5606.     }
  5607.     public function ViewProjectWorkspaceAction(Request $request$id 0)
  5608.     {
  5609.         $em $this->getDoctrine()->getManager();
  5610.         $companyId $this->getLoggedUserCompanyId($request);
  5611.         if ($id == 0) {
  5612.             return $this->redirect($this->generateUrl('project_list'));
  5613.         }
  5614.         $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  5615.             array('projectId' => $id)
  5616.         );
  5617.         if (!$projectData) {
  5618.             return $this->redirect($this->generateUrl('project_list'));
  5619.         }
  5620.         $clientList SalesOrderM::GetClientList($em);
  5621.         $clientName = isset($clientList[$projectData->getClientId()]) ? $clientList[$projectData->getClientId()]['client_name'] : '';
  5622.         $salesPersonList Client::SalesPersonList($em);
  5623.         $salesPersonName = isset($salesPersonList[$projectData->getSalesPersonId()]) ? $salesPersonList[$projectData->getSalesPersonId()]['name'] : '';
  5624.         $pos $em->getRepository('ApplicationBundle\\Entity\\PurchaseOrder')->findBy(
  5625.             array('projectId' => $id)
  5626.         );
  5627.         $invoices $em->getRepository('ApplicationBundle\\Entity\\SalesInvoice')->findBy(
  5628.             array('projectId' => $id)
  5629.         );
  5630.         $invoicedAmount 0;
  5631.         foreach ($invoices as $inv) {
  5632.             $invoicedAmount += method_exists($inv'getInvoiceAmount') ? (float)$inv->getInvoiceAmount() : 0;
  5633.         }
  5634.         $proposals $em->getRepository('ApplicationBundle\\Entity\\SalesProposal')->findBy(
  5635.             array('projectId' => $id)
  5636.         );
  5637.         $wps $em->getRepository('ApplicationBundle\\Entity\\ProjectWp')->findBy(
  5638.             array('projectId' => $id)
  5639.         );
  5640.         $stageList ProjectConstant::$projectStages;
  5641.         $statusList ProjectConstant::$projectStatus;
  5642.         // S4.6 — SI Delivery sub-lists and snapshot
  5643.         $requirements ProjectM::getRequirementList($em$id$companyId);
  5644.         $interfaces   ProjectM::getInterfaceList($em$id$companyId);
  5645.         $devices      ProjectM::getDeviceList($em$id$companyId);
  5646.         $baselines    ProjectM::getConfigBaselineList($em$id$companyId);
  5647.         $testCases    ProjectM::getTestCaseList($em$id$companyId);
  5648.         $siSnapshot   ProjectM::GetSiDeliverySnapshot($em$id$companyId);
  5649.         $projectTicketsSummary $this->get(ProjectTicketSummaryService::class)->summarizeProjectTickets($id$companyId);
  5650.         $projectTickets $projectTicketsSummary['rows'];
  5651.         $projectTicketsCount $projectTicketsSummary['count'];
  5652.         $projectSurfaceSplit $this->isProjectSurfaceSplitEnabled();
  5653.         // Co-pilot shell variant (?shell=cp) renders the same body inside the
  5654.         // cp-shell so the co-pilot sidebar persists; default = codecovers chrome.
  5655.         $workspaceTemplate = ($request->query->get('shell') === 'cp')
  5656.             ? '@Project/pages/views/view_project_workspace_cp.html.twig'
  5657.             '@Project/pages/views/view_project_workspace.html.twig';
  5658.         return $this->render($workspaceTemplate, array(
  5659.             'page_title' => 'Project Workspace — ' $projectData->getProjectName(),
  5660.             'projectData' => $projectData,
  5661.             'clientName' => $clientName,
  5662.             'salesPersonName' => $salesPersonName,
  5663.             'prCount' => 0,
  5664.             'poCount' => count($pos),
  5665.             'invoicedAmount' => $invoicedAmount,
  5666.             'outstandingAmount' => 0,
  5667.             'wps' => $wps,
  5668.             'proposals' => $proposals,
  5669.             'pos' => $pos,
  5670.             'invoices' => $invoices,
  5671.             'stageList' => $stageList,
  5672.             'statusList' => $statusList,
  5673.             'id' => $id,
  5674.             // S4.6
  5675.             'requirements' => $requirements,
  5676.             'interfaces'   => $interfaces,
  5677.             'devices'      => $devices,
  5678.             'baselines'    => $baselines,
  5679.             'testCases'    => $testCases,
  5680.             'siSnapshot'   => $siSnapshot,
  5681.             'projectTickets' => $projectTickets,
  5682.             'projectTicketsCount' => $projectTicketsCount,
  5683.             'projectIntelligence' => ProjectM::GetProjectIntelligenceData($em$id$companyIdfalse),
  5684.             'projectSurfaceSplit' => $projectSurfaceSplit,
  5685.         ));
  5686.     }
  5687.     public function ConvertToProjectAction(Request $request$id 0)
  5688.     {
  5689.         $em $this->getDoctrine()->getManager();
  5690.         $retData = array(
  5691.             'success' => false,
  5692.             'projectId' => 0,
  5693.             'redirectUrl' => '',
  5694.             'message' => ''
  5695.         );
  5696.         if ($request->isMethod('POST')) {
  5697.             $docType $request->get('docType''_project_');
  5698.             $docId $request->get('docId'0);
  5699.             if ($docType == '_project_') {
  5700.                 $salesProposal $em->getRepository('ApplicationBundle\\Entity\\SalesProposal')->findOneBy(
  5701.                     array('salesProposalId' => $docId)
  5702.                 );
  5703.                 if (!$salesProposal) {
  5704.                     $retData['message'] = 'Proposal not found';
  5705.                     return new JsonResponse($retData);
  5706.                 }
  5707.                 // Idempotency: refuse if project already created
  5708.                 if ($salesProposal->getProjectCreated() == 1) {
  5709.                     $existingProjectId $salesProposal->getProjectId();
  5710.                     $retData['message'] = 'Project already created';
  5711.                     $retData['projectId'] = $existingProjectId;
  5712.                     $retData['redirectUrl'] = $this->generateUrl('view_project_details') . '/' $existingProjectId;
  5713.                     return new JsonResponse($retData);
  5714.                 }
  5715.                 $companyId $this->getLoggedUserCompanyId($request);
  5716.                 $loginId $this->getLoggedUserLoginId($request);
  5717.                 $currentDate = new \DateTime();
  5718.                 $project = new Project();
  5719.                 $project->setProjectName($salesProposal->getProposalTitle());
  5720.                 $project->setProjectDate($currentDate);
  5721.                 $project->setDocumentHash($salesProposal->getProposalTitle());
  5722.                 $project->setClientId($salesProposal->getClientId());
  5723.                 $project->setSalesPersonId($salesProposal->getSalesPersonId());
  5724.                 $project->setCurrency($salesProposal->getCurrency());
  5725.                 $project->setCurrencyMultiply($salesProposal->getCurrencyMultiply());
  5726.                 $project->setCurrencyMultiplyRate($salesProposal->getCurrencyMultiplyRate());
  5727.                 $project->setCompanyId($companyId);
  5728.                 $project->setBoqRequired(1);
  5729.                 $project->setProposalRequired(0);
  5730.                 $project->setOfferRequired(0);
  5731.                 $project->setBomRequired(0);
  5732.                 $project->setStatus(GeneralConstant::ACTIVE);
  5733.                 $project->setStage(array_flip(ProjectConstant::$projectStages)['INITIATED']);
  5734.                 $project->setProjectStep(array_flip(ProjectConstant::$projectSteps)['N/A']);
  5735.                 $project->setApproved(GeneralConstant::APPROVED);
  5736.                 $project->setAutoCreated(1);
  5737.                 $project->setAutoSoEnabled(0);
  5738.                 $project->setMarketingUserIds(json_encode([]));
  5739.                 $project->setMaterialUserIds(json_encode([]));
  5740.                 $project->setDesigningUserIds(json_encode([]));
  5741.                 $project->setImplementingUserIds(json_encode([]));
  5742.                 $project->setBillingUserIds(json_encode([]));
  5743.                 $project->setAccountsHeadId('');
  5744.                 $project->setAdvanceHeadId('');
  5745.                 $project->setPreRequisiteText('');
  5746.                 $project->setDeliverableText('');
  5747.                 $project->setDescription('');
  5748.                 $project->setRefPoNumber('');
  5749.                 $project->setCreatedLoginId($loginId);
  5750.                 $project->setEditedLoginId($loginId);
  5751.                 $em->persist($project);
  5752.                 $em->flush();
  5753.                 $projectId $project->getProjectId();
  5754.                 // Create linked BoQ referencing the proposal's document data
  5755.                 if ($salesProposal->getDocumentDataId()) {
  5756.                     $boq = new ProjectBoq();
  5757.                     $boq->setProjectId($projectId);
  5758.                     $boq->setProjectBoqDate($currentDate);
  5759.                     $boq->setDocumentDataId($salesProposal->getDocumentDataId());
  5760.                     $boq->setDocumentHash($salesProposal->getDocumentHash() . '');
  5761.                     $boq->setCompanyId($companyId);
  5762.                     $boq->setData(json_encode([]));
  5763.                     $boq->setStatus(GeneralConstant::ACTIVE);
  5764.                     $boq->setApproved(GeneralConstant::APPROVED);
  5765.                     $boq->setAutoCreated(1);
  5766.                     $boq->setEditFlag(0);
  5767.                     $boq->setDeleteFlag(0);
  5768.                     $boq->setLockFlag(0);
  5769.                     $boq->setDisabledFlag(0);
  5770.                     $boq->setCreatedLoginId($loginId);
  5771.                     $boq->setEditedLoginId($loginId);
  5772.                     $em->persist($boq);
  5773.                     $documentData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')->findOneBy(
  5774.                         array('id' => $salesProposal->getDocumentDataId())
  5775.                     );
  5776.                     if ($documentData) {
  5777.                         $documentData->setProjectId($projectId);
  5778.                         // Seed ProjectMilestone rows from the proposal's work-plan milestones so the
  5779.                         // converted project shows its milestones without manual re-entry (req #13).
  5780.                         $wpRaw    json_decode($documentData->getData(), true);
  5781.                         $wpRaw0   = isset($wpRaw[0]) ? $wpRaw[0] : [];
  5782.                         $wpMsList = !empty($wpRaw0['workPlanMilestonesJson'])
  5783.                             ? (json_decode($wpRaw0['workPlanMilestonesJson'], true) ?: [])
  5784.                             : [];
  5785.                         // Dedupe against any milestones already on this project.
  5786.                         $existingNames = [];
  5787.                         $existingMilestones $em->getRepository('ApplicationBundle\\Entity\\ProjectMilestone')
  5788.                             ->findBy(['projectId' => $projectId'deleteFlag' => 0]);
  5789.                         foreach ($existingMilestones as $exMs) {
  5790.                             $existingNames[mb_strtolower(trim((string)$exMs->getMilestoneName()))] = true;
  5791.                         }
  5792.                         foreach ($wpMsList as $ord => $ms) {
  5793.                             if (empty($ms['name'])) continue;
  5794.                             if (isset($existingNames[mb_strtolower(trim((string)$ms['name']))])) continue;
  5795.                             $milestone = new \ApplicationBundle\Entity\ProjectMilestone();
  5796.                             $milestone->setMilestoneName($ms['name']);
  5797.                             $milestone->setMilestoneDescription($ms['description'] ?? '');
  5798.                             $milestone->setMilestoneOrder($ord 1);
  5799.                             $milestone->setMilestoneStatus('planned');
  5800.                             $milestone->setProjectId($projectId);
  5801.                             $milestone->setSalesOrderId(0);
  5802.                             if (!empty($ms['targetDate'])) {
  5803.                                 try { $milestone->setPlannedDate(new \DateTime($ms['targetDate'])); } catch (\Exception $e) {}
  5804.                             }
  5805.                             $milestone->setCompanyId($companyId);
  5806.                             $milestone->setDeleteFlag(0);
  5807.                             $milestone->setEditFlag(0);
  5808.                             $milestone->setLockFlag(0);
  5809.                             $milestone->setStatus(1);
  5810.                             $em->persist($milestone);
  5811.                         }
  5812.                     }
  5813.                 }
  5814.                 $salesProposal->setProjectCreated(1);
  5815.                 $salesProposal->setProjectId($projectId);
  5816.                 $em->flush();
  5817.                 $retData['success'] = true;
  5818.                 $retData['projectId'] = $projectId;
  5819.                 $retData['redirectUrl'] = $this->generateUrl('view_project_details') . '/' $projectId;
  5820.             }
  5821.         }
  5822.         return new JsonResponse($retData);
  5823.     }
  5824.     // S3.1 — Material Readiness Dashboard
  5825.     public function MaterialReadinessDashboardAction(Request $request$id 0)
  5826.     {
  5827.         $em        $this->getDoctrine()->getManager();
  5828.         $companyId $this->getLoggedUserCompanyId($request);
  5829.         if ($id == 0) {
  5830.             return $this->redirect($this->generateUrl('project_list'));
  5831.         }
  5832.         $projectData $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
  5833.             ['projectId' => $id]
  5834.         );
  5835.         if (!$projectData) {
  5836.             return $this->redirect($this->generateUrl('project_list'));
  5837.         }
  5838.         $readiness ProjectM::getMaterialReadiness($em$id$companyId);
  5839.         return $this->render('@Project/pages/views/material_readiness_dashboard.html.twig', [
  5840.             'page_title'  => 'Material Readiness — ' $projectData->getProjectName(),
  5841.             'projectData' => $projectData,
  5842.             'items'       => $readiness['items'],
  5843.             'kpi'         => $readiness['kpi'],
  5844.             'projectId'   => $id,
  5845.         ]);
  5846.     }
  5847.     // =========================================================================
  5848.     // S4.1 — Project Requirement Register
  5849.     // =========================================================================
  5850.     public function CreateRequirementAction(Request $request$projectId)
  5851.     {
  5852.         $session   $request->getSession();
  5853.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5854.         $loginId   $session->get('loginId');
  5855.         $companyId $session->get('loginCompanyId');
  5856.         $em        $this->getDoctrine()->getManager();
  5857.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  5858.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  5859.         $error   '';
  5860.         $success '';
  5861.         if ($request->isMethod('POST')) {
  5862.             $result ProjectM::saveRequirement($em$request->request->all(), $projectId$companyId$loginId);
  5863.             if ($result['success']) {
  5864.                 return $this->redirect($this->generateUrl('project_requirement_view', ['id' => $result['requirementId']]));
  5865.             }
  5866.             $error $result['msg'];
  5867.         }
  5868.         return $this->render('@Project/pages/input_forms/create_requirement.html.twig', [
  5869.             'page_title' => 'New Requirement — ' $project->getProjectName(),
  5870.             'project'    => $project,
  5871.             'projectId'  => $projectId,
  5872.             'error'      => $error,
  5873.         ]);
  5874.     }
  5875.     public function ViewRequirementAction(Request $request$id)
  5876.     {
  5877.         $session   $request->getSession();
  5878.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5879.         $companyId $session->get('loginCompanyId');
  5880.         $em        $this->getDoctrine()->getManager();
  5881.         $entity ProjectM::getRequirementById($em$id);
  5882.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  5883.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  5884.         return $this->render('@Project/pages/views/view_requirement.html.twig', [
  5885.             'page_title' => 'Requirement — ' $entity->getDocumentHash(),
  5886.             'entity'     => $entity,
  5887.             'project'    => $project,
  5888.         ]);
  5889.     }
  5890.     public function ListRequirementsAction(Request $request$projectId)
  5891.     {
  5892.         $session   $request->getSession();
  5893.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5894.         $companyId $session->get('loginCompanyId');
  5895.         $em        $this->getDoctrine()->getManager();
  5896.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  5897.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  5898.         $list ProjectM::getRequirementList($em$projectId$companyId);
  5899.         return $this->render('@Project/pages/listing/list_requirements.html.twig', [
  5900.             'page_title' => 'Requirements — ' $project->getProjectName(),
  5901.             'project'    => $project,
  5902.             'list'       => $list,
  5903.             'projectId'  => $projectId,
  5904.         ]);
  5905.     }
  5906.     public function PrintRequirementAction(Request $request$id)
  5907.     {
  5908.         $session   $request->getSession();
  5909.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5910.         $em        $this->getDoctrine()->getManager();
  5911.         $entity  ProjectM::getRequirementById($em$id);
  5912.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  5913.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  5914.         return $this->render('@Project/pages/print/print_requirement.html.twig', [
  5915.             'page_title' => 'Requirement ' $entity->getDocumentHash(),
  5916.             'entity'     => $entity,
  5917.             'project'    => $project,
  5918.         ]);
  5919.     }
  5920.     // =========================================================================
  5921.     // S4.2 — Interface Matrix
  5922.     // =========================================================================
  5923.     public function CreateInterfaceAction(Request $request$projectId)
  5924.     {
  5925.         $session   $request->getSession();
  5926.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5927.         $loginId   $session->get('loginId');
  5928.         $companyId $session->get('loginCompanyId');
  5929.         $em        $this->getDoctrine()->getManager();
  5930.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  5931.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  5932.         $error '';
  5933.         if ($request->isMethod('POST')) {
  5934.             $result ProjectM::saveInterface($em$request->request->all(), $projectId$companyId$loginId);
  5935.             if ($result['success']) {
  5936.                 return $this->redirect($this->generateUrl('project_interface_view', ['id' => $result['interfaceId']]));
  5937.             }
  5938.             $error $result['msg'];
  5939.         }
  5940.         return $this->render('@Project/pages/input_forms/create_interface.html.twig', [
  5941.             'page_title' => 'New Interface — ' $project->getProjectName(),
  5942.             'project'    => $project,
  5943.             'projectId'  => $projectId,
  5944.             'error'      => $error,
  5945.         ]);
  5946.     }
  5947.     public function ViewInterfaceAction(Request $request$id)
  5948.     {
  5949.         $session   $request->getSession();
  5950.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5951.         $em        $this->getDoctrine()->getManager();
  5952.         $entity  ProjectM::getInterfaceById($em$id);
  5953.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  5954.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  5955.         return $this->render('@Project/pages/views/view_interface.html.twig', [
  5956.             'page_title' => 'Interface — ' $entity->getDocumentHash(),
  5957.             'entity'     => $entity,
  5958.             'project'    => $project,
  5959.         ]);
  5960.     }
  5961.     public function ListInterfacesAction(Request $request$projectId)
  5962.     {
  5963.         $session   $request->getSession();
  5964.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5965.         $companyId $session->get('loginCompanyId');
  5966.         $em        $this->getDoctrine()->getManager();
  5967.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  5968.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  5969.         $list ProjectM::getInterfaceList($em$projectId$companyId);
  5970.         return $this->render('@Project/pages/listing/list_interfaces.html.twig', [
  5971.             'page_title' => 'Interface Matrix — ' $project->getProjectName(),
  5972.             'project'    => $project,
  5973.             'list'       => $list,
  5974.             'projectId'  => $projectId,
  5975.         ]);
  5976.     }
  5977.     public function PrintInterfaceAction(Request $request$id)
  5978.     {
  5979.         $session   $request->getSession();
  5980.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5981.         $em        $this->getDoctrine()->getManager();
  5982.         $entity  ProjectM::getInterfaceById($em$id);
  5983.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  5984.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  5985.         return $this->render('@Project/pages/print/print_interface.html.twig', [
  5986.             'page_title' => 'Interface ' $entity->getDocumentHash(),
  5987.             'entity'     => $entity,
  5988.             'project'    => $project,
  5989.         ]);
  5990.     }
  5991.     // =========================================================================
  5992.     // S4.3 — Project Device & Protocol Library
  5993.     // =========================================================================
  5994.     public function CreateDeviceAction(Request $request$projectId)
  5995.     {
  5996.         $session   $request->getSession();
  5997.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  5998.         $loginId   $session->get('loginId');
  5999.         $companyId $session->get('loginCompanyId');
  6000.         $em        $this->getDoctrine()->getManager();
  6001.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  6002.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  6003.         $error '';
  6004.         if ($request->isMethod('POST')) {
  6005.             $result ProjectM::saveDevice($em$request->request->all(), $projectId$companyId$loginId);
  6006.             if ($result['success']) {
  6007.                 return $this->redirect($this->generateUrl('project_device_view', ['id' => $result['deviceId']]));
  6008.             }
  6009.             $error $result['msg'];
  6010.         }
  6011.         return $this->render('@Project/pages/input_forms/create_device.html.twig', [
  6012.             'page_title' => 'New Device — ' $project->getProjectName(),
  6013.             'project'    => $project,
  6014.             'projectId'  => $projectId,
  6015.             'error'      => $error,
  6016.         ]);
  6017.     }
  6018.     public function ViewDeviceAction(Request $request$id)
  6019.     {
  6020.         $session   $request->getSession();
  6021.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6022.         $em        $this->getDoctrine()->getManager();
  6023.         $entity  ProjectM::getDeviceById($em$id);
  6024.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  6025.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  6026.         return $this->render('@Project/pages/views/view_device.html.twig', [
  6027.             'page_title' => 'Device — ' $entity->getDocumentHash(),
  6028.             'entity'     => $entity,
  6029.             'project'    => $project,
  6030.         ]);
  6031.     }
  6032.     public function ListDevicesAction(Request $request$projectId)
  6033.     {
  6034.         $session   $request->getSession();
  6035.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6036.         $companyId $session->get('loginCompanyId');
  6037.         $em        $this->getDoctrine()->getManager();
  6038.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  6039.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  6040.         $list ProjectM::getDeviceList($em$projectId$companyId);
  6041.         return $this->render('@Project/pages/listing/list_devices.html.twig', [
  6042.             'page_title' => 'Device Library — ' $project->getProjectName(),
  6043.             'project'    => $project,
  6044.             'list'       => $list,
  6045.             'projectId'  => $projectId,
  6046.         ]);
  6047.     }
  6048.     public function PrintDeviceAction(Request $request$id)
  6049.     {
  6050.         $session   $request->getSession();
  6051.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6052.         $em        $this->getDoctrine()->getManager();
  6053.         $entity  ProjectM::getDeviceById($em$id);
  6054.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  6055.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  6056.         return $this->render('@Project/pages/print/print_device.html.twig', [
  6057.             'page_title' => 'Device ' $entity->getDocumentHash(),
  6058.             'entity'     => $entity,
  6059.             'project'    => $project,
  6060.         ]);
  6061.     }
  6062.     // =========================================================================
  6063.     // S4.4 — Configuration Baseline
  6064.     // =========================================================================
  6065.     public function CreateConfigBaselineAction(Request $request$projectId)
  6066.     {
  6067.         $session   $request->getSession();
  6068.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6069.         $loginId   $session->get('loginId');
  6070.         $companyId $session->get('loginCompanyId');
  6071.         $em        $this->getDoctrine()->getManager();
  6072.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  6073.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  6074.         $error '';
  6075.         if ($request->isMethod('POST')) {
  6076.             $result ProjectM::saveConfigBaseline($em$request->request->all(), $projectId$companyId$loginId);
  6077.             if ($result['success']) {
  6078.                 return $this->redirect($this->generateUrl('project_config_baseline_view', ['id' => $result['baselineId']]));
  6079.             }
  6080.             $error $result['msg'];
  6081.         }
  6082.         return $this->render('@Project/pages/input_forms/create_config_baseline.html.twig', [
  6083.             'page_title' => 'New Configuration Baseline — ' $project->getProjectName(),
  6084.             'project'    => $project,
  6085.             'projectId'  => $projectId,
  6086.             'error'      => $error,
  6087.         ]);
  6088.     }
  6089.     public function ViewConfigBaselineAction(Request $request$id)
  6090.     {
  6091.         $session   $request->getSession();
  6092.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6093.         $em        $this->getDoctrine()->getManager();
  6094.         $entity  ProjectM::getConfigBaselineById($em$id);
  6095.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  6096.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  6097.         return $this->render('@Project/pages/views/view_config_baseline.html.twig', [
  6098.             'page_title' => 'Baseline — ' $entity->getDocumentHash(),
  6099.             'entity'     => $entity,
  6100.             'project'    => $project,
  6101.         ]);
  6102.     }
  6103.     public function ListConfigBaselinesAction(Request $request$projectId)
  6104.     {
  6105.         $session   $request->getSession();
  6106.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6107.         $companyId $session->get('loginCompanyId');
  6108.         $em        $this->getDoctrine()->getManager();
  6109.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  6110.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  6111.         $list ProjectM::getConfigBaselineList($em$projectId$companyId);
  6112.         return $this->render('@Project/pages/listing/list_config_baselines.html.twig', [
  6113.             'page_title' => 'Configuration Baselines — ' $project->getProjectName(),
  6114.             'project'    => $project,
  6115.             'list'       => $list,
  6116.             'projectId'  => $projectId,
  6117.         ]);
  6118.     }
  6119.     public function PrintConfigBaselineAction(Request $request$id)
  6120.     {
  6121.         $session   $request->getSession();
  6122.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6123.         $em        $this->getDoctrine()->getManager();
  6124.         $entity  ProjectM::getConfigBaselineById($em$id);
  6125.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  6126.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  6127.         return $this->render('@Project/pages/print/print_config_baseline.html.twig', [
  6128.             'page_title' => 'Baseline ' $entity->getDocumentHash(),
  6129.             'entity'     => $entity,
  6130.             'project'    => $project,
  6131.         ]);
  6132.     }
  6133.     // =========================================================================
  6134.     // S4.5 — FAT/SAT/UAT/SIT Test Cases
  6135.     // =========================================================================
  6136.     public function CreateTestCaseAction(Request $request$projectId)
  6137.     {
  6138.         $session   $request->getSession();
  6139.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6140.         $loginId   $session->get('loginId');
  6141.         $companyId $session->get('loginCompanyId');
  6142.         $em        $this->getDoctrine()->getManager();
  6143.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  6144.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  6145.         $error '';
  6146.         if ($request->isMethod('POST')) {
  6147.             $result ProjectM::saveTestCase($em$request->request->all(), $projectId$companyId$loginId);
  6148.             if ($result['success']) {
  6149.                 return $this->redirect($this->generateUrl('project_test_case_view', ['id' => $result['testCaseId']]));
  6150.             }
  6151.             $error $result['msg'];
  6152.         }
  6153.         $requirements ProjectM::getRequirementList($em$projectId$companyId);
  6154.         return $this->render('@Project/pages/input_forms/create_test_case.html.twig', [
  6155.             'page_title'   => 'New Test Case — ' $project->getProjectName(),
  6156.             'project'      => $project,
  6157.             'projectId'    => $projectId,
  6158.             'requirements' => $requirements,
  6159.             'error'        => $error,
  6160.         ]);
  6161.     }
  6162.     public function ViewTestCaseAction(Request $request$id)
  6163.     {
  6164.         $session   $request->getSession();
  6165.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6166.         $em        $this->getDoctrine()->getManager();
  6167.         $entity  ProjectM::getTestCaseById($em$id);
  6168.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  6169.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  6170.         return $this->render('@Project/pages/views/view_test_case.html.twig', [
  6171.             'page_title' => 'Test Case — ' $entity->getDocumentHash(),
  6172.             'entity'     => $entity,
  6173.             'project'    => $project,
  6174.         ]);
  6175.     }
  6176.     public function ListTestCasesAction(Request $request$projectId)
  6177.     {
  6178.         $session   $request->getSession();
  6179.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6180.         $companyId $session->get('loginCompanyId');
  6181.         $em        $this->getDoctrine()->getManager();
  6182.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
  6183.         if (!$project) return $this->redirect($this->generateUrl('project_list'));
  6184.         $phase $request->query->get('phase'null);
  6185.         $list  ProjectM::getTestCaseList($em$projectId$companyId$phase);
  6186.         return $this->render('@Project/pages/listing/list_test_cases.html.twig', [
  6187.             'page_title' => 'Test Cases — ' $project->getProjectName(),
  6188.             'project'    => $project,
  6189.             'list'       => $list,
  6190.             'projectId'  => $projectId,
  6191.             'phase'      => $phase,
  6192.         ]);
  6193.     }
  6194.     public function PrintTestCaseAction(Request $request$id)
  6195.     {
  6196.         $session   $request->getSession();
  6197.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6198.         $em        $this->getDoctrine()->getManager();
  6199.         $entity  ProjectM::getTestCaseById($em$id);
  6200.         if (!$entity) return $this->redirect($this->generateUrl('project_list'));
  6201.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
  6202.         return $this->render('@Project/pages/print/print_test_case.html.twig', [
  6203.             'page_title' => 'Test Case ' $entity->getDocumentHash(),
  6204.             'entity'     => $entity,
  6205.             'project'    => $project,
  6206.         ]);
  6207.     }
  6208.     public function ExecuteTestCaseAction(Request $request$id)
  6209.     {
  6210.         $session   $request->getSession();
  6211.         if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
  6212.         $loginId   $session->get('loginId');
  6213.         $em        $this->getDoctrine()->getManager();
  6214.         if ($request->isMethod('POST')) {
  6215.             ProjectM::executeTestCase($em$request->request->all(), $id$loginId);
  6216.         }
  6217.         return $this->redirect($this->generateUrl('project_test_case_view', ['id' => $id]));
  6218.     }
  6219.     // =========================================================================
  6220.     // S4.5 — Invoice Milestone Warning (JSON endpoint)
  6221.     // Called before issuing a project-linked invoice to check for unmet milestones
  6222.     // =========================================================================
  6223.     public function CheckInvoiceMilestonesAction(Request $request$projectId)
  6224.     {
  6225.         $session   $request->getSession();
  6226.         if (!$this->checkLogin($request)) {
  6227.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'Not authenticated']);
  6228.         }
  6229.         $companyId $session->get('loginCompanyId');
  6230.         $em        $this->getDoctrine()->getManager();
  6231.         // Find test cases that are invoice-milestone-triggering but NOT yet passed
  6232.         $allTc ProjectM::getTestCaseList($em$projectId$companyId);
  6233.         $blocking = [];
  6234.         foreach ($allTc as $tc) {
  6235.             if ($tc->getInvoiceMilestoneTrigger() && !in_array($tc->getTestStatus(), ['pass''approved'])) {
  6236.                 $blocking[] = [
  6237.                     'testCaseId'  => $tc->getTestCaseId(),
  6238.                     'testCode'    => $tc->getTestCode(),
  6239.                     'title'       => $tc->getTitle(),
  6240.                     'testPhase'   => $tc->getTestPhase(),
  6241.                     'testStatus'  => $tc->getTestStatus(),
  6242.                 ];
  6243.             }
  6244.         }
  6245.         return new \Symfony\Component\HttpFoundation\JsonResponse([
  6246.             'success'      => true,
  6247.             'canInvoice'   => count($blocking) === 0,
  6248.             'blockingCount' => count($blocking),
  6249.             'blocking'     => $blocking,
  6250.             'warning'      => count($blocking) > 0
  6251.                 count($blocking) . ' invoice-milestone test case(s) have not yet passed. Consider completing them before issuing this invoice.'
  6252.                 '',
  6253.         ]);
  6254.     }
  6255.     // S7 — Milestone actions. Auth handled by SessionCheckInterface listener.
  6256.     public function ProjectMilestoneSaveAction(Request $request$projectId)
  6257.     {
  6258.         $session $request->getSession();
  6259.         $companyId $session->get('loginCompanyId');
  6260.         $loginId   $session->get(UserConstants::USER_LOGIN_ID);
  6261.         $userId    $session->get(UserConstants::USER_ID);
  6262.         $em $this->getDoctrine()->getManager();
  6263.         $data $request->request->all();
  6264.         $newId ProjectM::SaveProjectMilestone($em$data$projectId$companyId$loginId$userId);
  6265.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'id' => $newId]);
  6266.     }
  6267.     public function ProjectMilestoneDeleteAction(Request $request$projectId$id)
  6268.     {
  6269.         $em $this->getDoctrine()->getManager();
  6270.         $entity $em->getRepository('ApplicationBundle\\Entity\\ProjectMilestone')->findOneBy(['projectMilestoneId' => $id]);
  6271.         if ($entity) {
  6272.             $entity->setDeleteFlag(1);
  6273.             $em->flush();
  6274.         }
  6275.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
  6276.     }
  6277.     public function ProjectMilestoneCompleteAction(Request $request$projectId$id)
  6278.     {
  6279.         $em $this->getDoctrine()->getManager();
  6280.         $entity $em->getRepository('ApplicationBundle\\Entity\\ProjectMilestone')->findOneBy(['projectMilestoneId' => $id]);
  6281.         if ($entity) {
  6282.             $entity->setActualDate(new \DateTime());
  6283.             $entity->setMilestoneStatus('completed');
  6284.             $entity->setCompletionPercentage(100);
  6285.             $em->flush();
  6286.         }
  6287.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
  6288.     }
  6289.     // ── Time & Materials (work-hour) billing ─────────────────────────────────
  6290.     // Config + preview + bill-now for service/BPO projects billed by the hour.
  6291.     public function ProjectTmBillingAction(Request $request$projectId)
  6292.     {
  6293.         $em $this->getDoctrine()->getManager();
  6294.         $project $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(['projectId' => (int) $projectId]);
  6295.         if (!$project) {
  6296.             return new \Symfony\Component\HttpFoundation\Response('Project not found'404);
  6297.         }
  6298.         $mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
  6299.         $config  $mgr->getConfig($projectId);
  6300.         $preview $mgr->getPreview($projectId);
  6301.         $salesOrders $em->getRepository('ApplicationBundle\\Entity\\SalesOrder')
  6302.             ->findBy(['projectId' => (int) $projectId], ['salesOrderId' => 'ASC']);
  6303.         $soList = [];
  6304.         foreach ($salesOrders as $so) {
  6305.             $soList[] = ['id' => $so->getSalesOrderId(), 'hash' => $so->getDocumentHash()];
  6306.         }
  6307.         return $this->render('@Project/pages/views/tm_billing.html.twig', [
  6308.             'projectId'   => (int) $projectId,
  6309.             'projectName' => $project->getProjectName(),
  6310.             'config'      => $config,
  6311.             'preview'     => $preview,
  6312.             'salesOrders' => $soList,
  6313.             'currencyList' => \ApplicationBundle\Modules\Inventory\Inventory::CurrencyList($em),
  6314.         ]);
  6315.     }
  6316.     public function ProjectTmBillingSaveAction(Request $request$projectId)
  6317.     {
  6318.         $session $request->getSession();
  6319.         $loginId $session->get(UserConstants::USER_LOGIN_ID);
  6320.         $em  $this->getDoctrine()->getManager();
  6321.         $mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
  6322.         $data = [
  6323.             'enabled'              => $request->request->get('enabled'0),
  6324.             'hourlyRate'           => $request->request->get('hourlyRate'0),
  6325.             'currencyId'           => $request->request->get('currencyId'''),
  6326.             'primarySalesOrderId'  => $request->request->get('primarySalesOrderId'''),
  6327.             'billingIntervalDays'  => $request->request->get('billingIntervalDays'30),
  6328.             'requireApprovedHours' => $request->request->get('requireApprovedHours'1),
  6329.             'note'                 => $request->request->get('note'''),
  6330.         ];
  6331.         $mgr->saveConfig($projectId$data$loginId);
  6332.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'preview' => $mgr->getPreview($projectId)]);
  6333.     }
  6334.     public function ProjectTmBillingPreviewAction(Request $request$projectId)
  6335.     {
  6336.         $em  $this->getDoctrine()->getManager();
  6337.         $mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
  6338.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'preview' => $mgr->getPreview($projectId)]);
  6339.     }
  6340.     public function ProjectTmBillingBillNowAction(Request $request$projectId)
  6341.     {
  6342.         $session $request->getSession();
  6343.         $loginId $session->get(UserConstants::USER_LOGIN_ID);
  6344.         $em  $this->getDoctrine()->getManager();
  6345.         $mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
  6346.         $result $mgr->runBilling($projectId$loginId$request->request->get('until'null));
  6347.         return new \Symfony\Component\HttpFoundation\JsonResponse($result);
  6348.     }
  6349.     // ── Proposal Cost Sheet (budgeted margin) ────────────────────────────────
  6350.     // Live recompute (no save) — for the editable panel's instant feedback.
  6351.     public function ProposalCostSheetComputeAction(Request $request)
  6352.     {
  6353.         $inputs json_decode($request->request->get('costSheet''{}'), true) ?: [];
  6354.         return new \Symfony\Component\HttpFoundation\JsonResponse([
  6355.             'success'  => true,
  6356.             'computed' => \ApplicationBundle\Modules\Project\Service\CostSheetCalculator::compute($inputs),
  6357.         ]);
  6358.     }
  6359.     // Find-or-create the project's dedicated cost-sheet DocumentData row.
  6360.     private function resolveCostSheetDoc($em$projectId$companyId 1)
  6361.     {
  6362.         $dd $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  6363.             ->findOneBy(['projectId' => (int) $projectId'dataType' => 'cost_sheet']);
  6364.         if (!$dd) {
  6365.             $dd = new \ApplicationBundle\Entity\DocumentData();
  6366.             $dd->setProjectId((int) $projectId);
  6367.             $dd->setDataType('cost_sheet');
  6368.             $dd->setEntity('cost_sheet');
  6369.             $dd->setCompanyId($companyId);
  6370.             $dd->setData('{}');
  6371.             $dd->setCreatedAt(new \DateTime('now'));
  6372.             $em->persist($dd);
  6373.         }
  6374.         return $dd;
  6375.     }
  6376.     // A dedicated cost_sheet DocumentData keyed by the PROPOSAL's documentDataId
  6377.     // (distinct dataType so it never collides with the legacy projectId-keyed one,
  6378.     // and — critically — it NEVER pollutes the proposal's own DocumentData/entries).
  6379.     private function resolveCostSheetDocByDd($em$proposalDdId$companyId 1)
  6380.     {
  6381.         $dd $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  6382.             ->findOneBy(['projectId' => (int) $proposalDdId'dataType' => 'cost_sheet_dd']);
  6383.         if (!$dd) {
  6384.             $dd = new \ApplicationBundle\Entity\DocumentData();
  6385.             $dd->setProjectId((int) $proposalDdId);
  6386.             $dd->setDataType('cost_sheet_dd');
  6387.             $dd->setEntity('cost_sheet');
  6388.             $dd->setCompanyId($companyId);
  6389.             $dd->setData('{}');
  6390.             $dd->setCreatedAt(new \DateTime('now'));
  6391.             $em->persist($dd);
  6392.         }
  6393.         return $dd;
  6394.     }
  6395.     // Persist the cost-sheet inputs + computed result into a SEPARATE cost_sheet doc
  6396.     // (keyed by the proposal's documentDataId, or by projectId for the legacy view).
  6397.     // It is never stored inside the proposal's own DocumentData (that would corrupt
  6398.     // the proposal entry list → 500 on view + data reset on re-save).
  6399.     public function ProposalCostSheetSaveAction(Request $request)
  6400.     {
  6401.         $em     $this->getDoctrine()->getManager();
  6402.         $ddId   = (int) $request->request->get('documentDataId'0);
  6403.         $projectId = (int) $request->request->get('projectId'0);
  6404.         $inputs json_decode($request->request->get('costSheet''{}'), true) ?: [];
  6405.         $computed = \ApplicationBundle\Modules\Project\Service\CostSheetCalculator::compute($inputs);
  6406.         if ($ddId 0) {
  6407.             $dd $this->resolveCostSheetDocByDd($em$ddId, (int) $this->getLoggedUserCompanyId($request));
  6408.         } elseif ($projectId 0) {
  6409.             $dd $this->resolveCostSheetDoc($em$projectId, (int) $this->getLoggedUserCompanyId($request));
  6410.         } else {
  6411.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'message' => 'documentDataId or projectId is required.']);
  6412.         }
  6413.         $dd->setData(json_encode(['inputs' => $inputs'computed' => $computed]));
  6414.         $em->flush();
  6415.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'computed' => $computed]);
  6416.     }
  6417.     // GET the saved cost sheet for a proposal documentDataId (panel loads on init).
  6418.     public function ProposalCostSheetGetAction(Request $request)
  6419.     {
  6420.         $em   $this->getDoctrine()->getManager();
  6421.         $ddId = (int) $request->query->get('documentDataId'0);
  6422.         $data null;
  6423.         if ($ddId 0) {
  6424.             $dd $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  6425.                 ->findOneBy(['projectId' => $ddId'dataType' => 'cost_sheet_dd']);
  6426.             $data $dd ? (json_decode((string) $dd->getData(), true) ?: null) : null;
  6427.         }
  6428.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'costSheet' => $data]);
  6429.     }
  6430.     // S7 — Project Cost actions. Auth handled by SessionCheckInterface listener.
  6431.     public function ProjectCostSaveAction(Request $request$projectId)
  6432.     {
  6433.         $session $request->getSession();
  6434.         $companyId $session->get('loginCompanyId');
  6435.         $loginId   $session->get(UserConstants::USER_LOGIN_ID);
  6436.         $userId    $session->get(UserConstants::USER_ID);
  6437.         $em $this->getDoctrine()->getManager();
  6438.         $data $request->request->all();
  6439.         $newId ProjectM::SaveProjectCost($em$data$projectId$companyId$loginId$userId);
  6440.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true'id' => $newId]);
  6441.     }
  6442.     public function ProjectCostDeleteAction(Request $request$projectId$id)
  6443.     {
  6444.         $em $this->getDoctrine()->getManager();
  6445.         $entity $em->getRepository('ApplicationBundle\\Entity\\ProjectCost')->findOneBy(['projectCostId' => $id]);
  6446.         if ($entity) {
  6447.             $entity->setDeleteFlag(1);
  6448.             $em->flush();
  6449.         }
  6450.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
  6451.     }
  6452.     // S8 — Project Public Share admin actions. Auth handled by SessionCheckInterface.
  6453.     // The PUBLIC view (no-auth, /p/project/{id}) lives in PublicPagesController, not here,
  6454.     // so this controller can stay session-only (DB connection, login, app context).
  6455.     public function ProjectPublicShareCreateAction(Request $request$projectId)
  6456.     {
  6457.         $session $request->getSession();
  6458.         $companyId $session->get('loginCompanyId');
  6459.         $loginId   $session->get(UserConstants::USER_LOGIN_ID);
  6460.         $userId    $session->get(UserConstants::USER_ID);
  6461.         $appId     $session->get(UserConstants::USER_APP_ID);
  6462.         $em $this->getDoctrine()->getManager();
  6463.         $share = new \ApplicationBundle\Entity\ProjectPublicShare();
  6464.         $share->setProjectId($projectId);
  6465.         $share->setCompanyId($companyId);
  6466.         $share->setShareToken(ProjectM::GenerateShareToken());
  6467.         $share->setShareTitle($request->request->get('shareTitle''Project Progress'));
  6468.         $expiry $request->request->get('expiryDate''');
  6469.         if ($expiry$share->setExpiryDate(new \DateTime($expiry));
  6470.         $share->setIsActive(1);
  6471.         $share->setViewCount(0);
  6472.         $share->setSettingsData($request->request->get('settingsData''{}'));
  6473.         $share->setDeleteFlag(0);
  6474.         $share->setEditFlag(1);
  6475.         $share->setStatus(1);
  6476.         $share->setStage(0);
  6477.         $share->setApproved(0);
  6478.         $share->setCreatedUserId($userId);
  6479.         $share->setCreatedLoginId($loginId);
  6480.         $em->persist($share);
  6481.         $em->flush();
  6482.         // Build encrypted URL payload — same pattern as PaymentVoucherPublicView.
  6483.         // Token is embedded so regeneration invalidates old links.
  6484.         $payload   json_encode([
  6485.             'id'    => $share->getProjectPublicShareId(),
  6486.             'appId' => $appId,
  6487.             't'     => $share->getShareToken(),
  6488.             'dt'    => date('Y-m-d'),
  6489.         ]);
  6490.         $encrypted $this->get('url_encryptor')->encrypt($payload);
  6491.         $publicUrl $request->getSchemeAndHttpHost() . $this->generateUrl('public_project_view', ['id' => $encrypted]);
  6492.         return new \Symfony\Component\HttpFoundation\JsonResponse([
  6493.             'success' => true,
  6494.             'id'      => $share->getProjectPublicShareId(),
  6495.             'url'     => $publicUrl,
  6496.         ]);
  6497.     }
  6498.     public function ProjectPublicShareUpdateAction(Request $request$projectId$id)
  6499.     {
  6500.         $em $this->getDoctrine()->getManager();
  6501.         $share $em->getRepository('ApplicationBundle\\Entity\\ProjectPublicShare')->findOneBy(
  6502.             ['projectPublicShareId' => $id'projectId' => $projectId]
  6503.         );
  6504.         if (!$share) {
  6505.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false'msg' => 'not found']);
  6506.         }
  6507.         if ($request->request->has('shareTitle')) $share->setShareTitle($request->request->get('shareTitle'));
  6508.         if ($request->request->has('expiryDate')) {
  6509.             $exp $request->request->get('expiryDate');
  6510.             $share->setExpiryDate($exp ? new \DateTime($exp) : null);
  6511.         }
  6512.         if ($request->request->has('isActive'))   $share->setIsActive((int)$request->request->get('isActive'));
  6513.         if ($request->request->has('settingsData')) $share->setSettingsData($request->request->get('settingsData'));
  6514.         $em->flush();
  6515.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
  6516.     }
  6517.     public function ProjectPublicShareRevokeAction(Request $request$projectId$id)
  6518.     {
  6519.         $em $this->getDoctrine()->getManager();
  6520.         $share $em->getRepository('ApplicationBundle\\Entity\\ProjectPublicShare')->findOneBy(
  6521.             ['projectPublicShareId' => $id'projectId' => $projectId]
  6522.         );
  6523.         if ($share) {
  6524.             $share->setIsActive(0);
  6525.             $share->setDeleteFlag(1);
  6526.             $em->flush();
  6527.         }
  6528.         return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
  6529.     }
  6530.     public function ProjectPublicShareRegenerateAction(Request $request$projectId$id)
  6531.     {
  6532.         $session $request->getSession();
  6533.         $appId $session->get(UserConstants::USER_APP_ID);
  6534.         $em $this->getDoctrine()->getManager();
  6535.         $share $em->getRepository('ApplicationBundle\\Entity\\ProjectPublicShare')->findOneBy(
  6536.             ['projectPublicShareId' => $id'projectId' => $projectId]
  6537.         );
  6538.         if (!$share) {
  6539.             return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false]);
  6540.         }
  6541.         $share->setShareToken(ProjectM::GenerateShareToken());
  6542.         $share->setViewCount(0);
  6543.         $em->flush();
  6544.         $payload   json_encode([
  6545.             'id'    => $share->getProjectPublicShareId(),
  6546.             'appId' => $appId,
  6547.             't'     => $share->getShareToken(),
  6548.             'dt'    => date('Y-m-d'),
  6549.         ]);
  6550.         $encrypted $this->get('url_encryptor')->encrypt($payload);
  6551.         $publicUrl $request->getSchemeAndHttpHost() . $this->generateUrl('public_project_view', ['id' => $encrypted]);
  6552.         return new \Symfony\Component\HttpFoundation\JsonResponse([
  6553.             'success' => true,
  6554.             'url'     => $publicUrl,
  6555.         ]);
  6556.     }
  6557.     private function isProjectSurfaceSplitEnabled()
  6558.     {
  6559.         if (!isset($this->container)) {
  6560.             return false;
  6561.         }
  6562.         foreach (['project.surface_split''project_surface_split'] as $paramName) {
  6563.             if ($this->container->hasParameter($paramName)) {
  6564.                 return (bool)$this->container->getParameter($paramName);
  6565.             }
  6566.         }
  6567.         return false;
  6568.     }
  6569. }