<?php
namespace ApplicationBundle\Controller;
use ApplicationBundle\Constants\GeneralConstant;
use ApplicationBundle\Constants\HumanResourceConstant;
use ApplicationBundle\Constants\ProjectConstant;
use ApplicationBundle\Entity\Branch;
use ApplicationBundle\Entity\DocumentData;
use ApplicationBundle\Entity\EmployeeAttendance;
use ApplicationBundle\Entity\PlanningItem;
use ApplicationBundle\Entity\Project;
use ApplicationBundle\Entity\ProjectBoq;
use ApplicationBundle\Entity\ProjectSite;
use ApplicationBundle\Entity\SalesProposal;
use ApplicationBundle\Entity\TaskLog;
use ApplicationBundle\Entity\Warehouse;
use ApplicationBundle\Interfaces\SessionCheckInterface;
use ApplicationBundle\Modules\Accounts\Accounts;
use ApplicationBundle\Modules\Authentication\Constants\UserConstants; use ApplicationBundle\Modules\Api\Constants\ApiConstants;
use ApplicationBundle\Modules\HumanResource\HumanResource;
use ApplicationBundle\Modules\Inventory\Inventory;
use ApplicationBundle\Modules\Project\ProjectM;
use ApplicationBundle\Modules\Project\Service\ProjectTeamResolverService;
use ApplicationBundle\Modules\Project\Service\ProjectTicketSummaryService;
use ApplicationBundle\Modules\Sales\Client;
use ApplicationBundle\Modules\Sales\Constants\SalesConstant;
use ApplicationBundle\Modules\Sales\SalesOrderM;
use ApplicationBundle\Modules\System\DeleteDocument;
use ApplicationBundle\Modules\System\DocValidation;
use ApplicationBundle\Modules\System\MiscActions;
use ApplicationBundle\Modules\System\System;
use ApplicationBundle\Modules\User\Company;
use ApplicationBundle\Modules\User\Users;
use CompanyGroupBundle\Entity\EntityFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
//use ApplicationBundle\Constants\GeneralConstant;
//use ApplicationBundle\Modules\Sales\SalesOrderM;
//use Symfony\Bundle\FrameworkBundle\Controller\Controller;
//use Symfony\Component\HttpFoundation\Request;
class ProjectController extends GenericController implements SessionCheckInterface
{
public function checkLogin(Request $request)
{
return true; //becasue sessioncheck will never let you come here if you are not logged in
}
public function CreateNewAction(Request $request, $projectId = 0)
{
$companyId = $this->getLoggedUserCompanyId($request);
$em_goc = $this->getDoctrine()->getManager('company_group');
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$entity_id = array_flip(GeneralConstant::$Entity_list)['Project']; //change
$dochash = $request->request->get('proj'); //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash(
'error',
'Sorry Could not insert Data.'
);
} else {
$funcname = 'Project';
$doc_id = $projectId;
DeleteDocument::$funcname($em, $doc_id, 0);
$projectId = ProjectM::CreateNew($projectId, $this->getDoctrine()->getManager(), $request->request,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
ProjectM::UpdateWarehouseForPendingSites($em, $companyId, 1, $projectId);
$file_path_list = [];
$deliverable_file_path_list = [];
if ($projectId != 0)
if (!empty($request->files->get('deliverable_images', [])) || !empty($request->files->get('prerequisites_images', []))) {
MiscActions::RemoveFilesForEntityDoc($em_goc, 'Project', $projectId);
$storePath = 'uploads/Voucher/';
$path = "";
$file_path = "";
$session = $request->getSession();
MiscActions::RemoveExpiredFiles($em_goc);
foreach ($request->files->get('deliverable_images', []) as $uploadedFileGG) {
// if($uploadedFile->getImage())
// var_dump($uploadedFile->getFile());
// var_dump($uploadedFile);
$tempD = $uploadedFileGG;
if (!is_array($uploadedFileGG)) {
$uploadedFileGG = array();
$uploadedFileGG[] = $tempD;
}
foreach ($uploadedFileGG as $uploadedFile) {
if ($uploadedFile != null) {
$extension = $uploadedFile->guessExtension();
$size = $uploadedFile->getSize();
$fileName = 'REQ_' . $projectId . '_' . (md5(uniqid())) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/' . $storePath;
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
if (file_exists($upl_dir . '' . $path)) {
chmod($upl_dir . '' . $path, 0755);
unlink($upl_dir . '' . $path);
}
$file = $uploadedFile->move($upl_dir, $path);
$expireNever = 1;
$expireTs = 0;
$EntityFile = new EntityFile();
$EntityFile->setPath($this->container->getParameter('kernel.root_dir') . '/../web/' . $storePath . $path);
$EntityFile->setName($path);
$EntityFile->setMarker('_GEN_');
$EntityFile->setExtension($extension);
$EntityFile->setExpireTs($expireTs);
$EntityFile->setSize($size);
$EntityFile->setRelativePath($storePath . $path);
$EntityFile->setEntityName('Project');
$EntityFile->setEntityBundle('ApplicationBundle');
$EntityFile->setEntityId($projectId);
$EntityFile->setEntityIdField('projectId');
$EntityFile->setModifyFieldSetter('setFiles');
$EntityFile->setDocIdForApplicant(0);
$EntityFile->setUserId($session->get(UserConstants::USER_ID, 0));
$EntityFile->setAppId($session->get(UserConstants::USER_APP_ID, 0));
$EntityFile->setEmployeeId($session->get(UserConstants::USER_EMPLOYEE_ID, 0));
$EntityFile->setUserType($session->get(UserConstants::USER_TYPE, 0));
$em_goc->persist($EntityFile);
$em_goc->flush();
$EntityFileId = $EntityFile->getId();
}
if ($path != "")
$file_path_list[] = ($storePath . $path);
}
}
foreach ($request->files->get('prerequisites_images', []) as $uploadedFileGG) {
// if($uploadedFile->getImage())
// var_dump($uploadedFile->getFile());
// var_dump($uploadedFile);
$tempD = $uploadedFileGG;
if (!is_array($uploadedFileGG)) {
$uploadedFileGG = array();
$uploadedFileGG[] = $tempD;
}
foreach ($uploadedFileGG as $uploadedFile) {
if ($uploadedFile != null) {
$extension = $uploadedFile->guessExtension();
$size = $uploadedFile->getSize();
$fileName = 'REQ_' . $projectId . '_' . (md5(uniqid())) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/' . $storePath;
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
if (file_exists($upl_dir . '' . $path)) {
chmod($upl_dir . '' . $path, 0755);
unlink($upl_dir . '' . $path);
}
$file = $uploadedFile->move($upl_dir, $path);
$expireNever = 1;
$expireTs = 0;
$EntityFile = new EntityFile();
$EntityFile->setPath($this->container->getParameter('kernel.root_dir') . '/../web/' . $storePath . $path);
$EntityFile->setName($path);
$EntityFile->setMarker('_GEN_');
$EntityFile->setExtension($extension);
$EntityFile->setExpireTs($expireTs);
$EntityFile->setSize($size);
$EntityFile->setRelativePath($storePath . $path);
$EntityFile->setEntityName('Project');
$EntityFile->setEntityBundle('ApplicationBundle');
$EntityFile->setEntityId($projectId);
$EntityFile->setEntityIdField('projectId');
$EntityFile->setModifyFieldSetter('setFiles');
$EntityFile->setDocIdForApplicant(0);
$EntityFile->setUserId($session->get(UserConstants::USER_ID, 0));
$EntityFile->setAppId($session->get(UserConstants::USER_APP_ID, 0));
$EntityFile->setEmployeeId($session->get(UserConstants::USER_EMPLOYEE_ID, 0));
$EntityFile->setUserType($session->get(UserConstants::USER_TYPE, 0));
$em_goc->persist($EntityFile);
$em_goc->flush();
$EntityFileId = $EntityFile->getId();
}
if ($path != "")
$deliverable_file_path_list[] = ($storePath . $path);
}
}
$g_path = $this->container->getParameter('kernel.root_dir') . '/../web/' . $storePath . $path;
$v = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(array(
'projectId' => $projectId,
));
if ($v) {
$v->setPreRequisiteFiles(implode(',', $file_path_list));
$v->setDeliverableFiles(implode(',', $deliverable_file_path_list));
$em->flush();
} else {
}
}
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = 1; //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['Project']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['Project'],
$projectId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['Project'],
$projectId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'New Project Created'
);
if ($request->request->get('projectType', 0) == 6) {
$url = $this->generateUrl(
'create_project_wp'
);
} else
$url = $this->generateUrl(
'view_project_details'
);
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),
"A New Project : " . $dochash . " Has Been Created And is Under Processing",
'all',
'',
'information',
$url . "/" . $projectId,
"New Project"
);
//marketing team
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),
"You Have been added to the Marketing team for project : " . $dochash . " ",
'user',
$request->request->get('marketing_team', null),
'information',
$url . "/" . $projectId,
"Project Marketing Assignment"
);
//material team
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),
"You Have been added to the Engineering team for project : " . $dochash . " ",
'user',
$request->request->get('material_team', null),
'information',
$url . "/" . $projectId,
"Project Engineering Assignment"
);
//Design team
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),
"You Have been added to the Financial Designing team for project : " . $dochash . " ",
'user',
$request->request->get('designing_team', null),
'information',
$url . "/" . $projectId,
"Project Designing Assignment"
);
//implementing team
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),
"You Have been added to the implementation team for project : " . $dochash . " ",
'user',
$request->request->get('implementing_team', null),
'information',
$url . "/" . $projectId,
"Project Implemntation Assignment"
);
//technician team
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),
"You Have been added to the implementation team for project : " . $dochash . " ",
'user',
$request->request->get('technician_team', null),
'information',
$url . "/" . $projectId,
"Project Technician Assignment"
);
//Billing team
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),
"You Have been added to the Billing team for project : " . $dochash . " ",
'user',
$request->request->get('billing_team', null),
'information',
$url . "/" . $projectId,
"Project Billing Assignment"
);
return $this->redirect($url . "/" . $projectId);
}
}
$em = $this->getDoctrine()->getManager();
//for edits
$extDocData = [];
$extDocDetailsData = [];
$projectSiteList = [];
$assignedProjectSiteList = [];
if ($projectId == 0) {
$projectSiteList = ProjectM::ProjectSiteList($em, [], $companyId);
} else {
$extTrans = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
$assignedProjectSiteList = ProjectM::ProjectSiteList($em, $projectId, $companyId);
$projectSiteList = ProjectM::ProjectSiteList($em, [], $companyId);
//now if its not editable, redirect to view
if ($extTrans) {
if ($extTrans->getEditFlag() != 1 && $request->query->get('forceEdit', 0) == 0) {
$url = $this->generateUrl(
'view_project'
);
return $this->redirect($url . "/" . $projectId);
} else {
$extDocData = $extTrans;
// $extDocDetailsData=Accounts::GetVoucherDataForEdit($em,$projectId);
}
}
}
return $this->render('@Project/pages/input_forms/new_project.html.twig',
array(
'page_title' => 'New Project',
'projectList' => ProjectM::GetProjectList($em),
'clients' => SalesOrderM::GetClientList($em),
'clients_by_ac_head' => SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'sales_person_list' => Client::SalesPersonList($this->getDoctrine()->getManager()),
'stages' => ProjectConstant::$projectStages,
'extDocData' => $extDocData,
'projectSiteList' => $projectSiteList,
'assignedProjectSiteList' => $assignedProjectSiteList,
'projectTypes' => ProjectM::getProjectTypesFromConfigFile($this->container->getParameter('kernel.root_dir')),
'categories' => $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy(
array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
)
),
)
);
}
public function UpdateProjectAction(Request $request, $projectId)
{
$companyId = $this->getLoggedUserCompanyId($request);
$em = $this->getDoctrine()->getManager();
$em_goc = $this->getDoctrine()->getManager('company_group');
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) {
$this->addFlash('error', 'Project not found.');
return $this->redirectToRoute('view_project');
}
if ($request->isMethod('POST')) {
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
$entity_id = array_flip(GeneralConstant::$Entity_list)['Project'];
$dochash = $request->request->get('proj');
if (!DocValidation::isInsertable($em, $entity_id, $dochash, $loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash('error', 'Update validation failed.');
} else {
// Perform project update logic
$updatedProjectId = ProjectM::UpdateProject($projectId, $em, $request->request, $loginId, $companyId);
// Handle files
if (!empty($request->files->get('deliverable_images', [])) || !empty($request->files->get('prerequisites_images', []))) {
MiscActions::RemoveFilesForEntityDoc($em_goc, 'Project', $projectId);
$storePath = 'uploads/Voucher/';
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/' . $storePath;
$filePaths = ['deliverables' => [], 'prerequisites' => []];
foreach (['deliverable_images' => 'deliverables', 'prerequisites_images' => 'prerequisites'] as $inputKey => $type) {
foreach ((array)$request->files->get($inputKey, []) as $uploadedFileGroup) {
if (!is_array($uploadedFileGroup)) {
$uploadedFileGroup = [$uploadedFileGroup];
}
foreach ($uploadedFileGroup as $file) {
if ($file) {
$filename = 'REQ_' . $projectId . '_' . md5(uniqid()) . '.' . $file->guessExtension();
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
if (file_exists($upl_dir . $filename)) {
unlink($upl_dir . $filename);
}
$file->move($upl_dir, $filename);
$entityFile = new EntityFile();
$entityFile->setPath($upl_dir . $filename);
$entityFile->setName($filename);
$entityFile->setMarker('_GEN_');
$entityFile->setExtension($file->guessExtension());
$entityFile->setExpireTs(0);
$entityFile->setSize($file->getSize());
$entityFile->setRelativePath($storePath . $filename);
$entityFile->setEntityName('Project');
$entityFile->setEntityBundle('ApplicationBundle');
$entityFile->setEntityId($projectId);
$entityFile->setEntityIdField('projectId');
$entityFile->setModifyFieldSetter('setFiles');
$entityFile->setDocIdForApplicant(0);
$entityFile->setUserId($request->getSession()->get(UserConstants::USER_ID));
$entityFile->setAppId($request->getSession()->get(UserConstants::USER_APP_ID));
$entityFile->setEmployeeId($request->getSession()->get(UserConstants::USER_EMPLOYEE_ID));
$entityFile->setUserType($request->getSession()->get(UserConstants::USER_TYPE));
$em_goc->persist($entityFile);
$em_goc->flush();
$filePaths[$type][] = $storePath . $filename;
}
}
}
}
$project->setDeliverableFiles(implode(',', $filePaths['deliverables']));
$project->setPreRequisiteFiles(implode(',', $filePaths['prerequisites']));
$em->flush();
}
// Approval Info Update
$options = [
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[$entity_id]['entity_view_route_path_name']
)
];
System::setApprovalInfo($em, $options, $entity_id, $projectId, $loginId);
System::createEditSignatureHash($em, $entity_id, $projectId, $loginId, $approveRole, $approveHash);
$this->addFlash('success', 'Project updated successfully.');
return $this->redirectToRoute('view_project_details', ['id' => $projectId]);
}
}
return $this->render('@Project/pages/input_forms/new_project.html.twig', [
'page_title' => 'Edit Project',
'projectList' => ProjectM::GetProjectList($em),
'clients' => SalesOrderM::GetClientList($em),
'clients_by_ac_head' => SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'sales_person_list' => Client::SalesPersonList($em),
'stages' => ProjectConstant::$projectStages,
'extDocData' => $project,
'projectSiteList' => ProjectM::ProjectSiteList($em, [], $companyId),
'assignedProjectSiteList' => ProjectM::ProjectSiteList($em, $projectId, $companyId),
'projectTypes' => ProjectM::getProjectTypesFromConfigFile($this->container->getParameter('kernel.root_dir')),
'categories' => $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy([
'status' => GeneralConstant::ACTIVE,
'CompanyId' => $companyId,
]),
]);
}
public function ProjectSiteExcelUploadAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
if ($request->isMethod('POST')) {
$post = $request->request;
$path = "";
$file_path = "";
// var_dump($request->files);
// var_dump($request->getFile());
foreach ($request->files as $uploadedFile) {
// if($uploadedFile->getImage())
// var_dump($uploadedFile->getFile());
// var_dump($uploadedFile);
if ($uploadedFile != null) {
$fileName = md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/FileUploads/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
}
// print_r($file);
if ($path != "")
$file_path = 'uploads/FileUploads/' . $path;
$g_path = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/FileUploads/' . $path;
//
// $img_file = file_get_contents($g_path);
// $r=base64_encode($img_file);
$row = 1;
$csv_data = [];
if (($handle = fopen($g_path, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
$csv_data[$row] = $data;
// echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
// for ($c=0; $c < $num; $c++) {
// echo $data[$c] . "<br />\n";
// }
}
fclose($handle);
}
//now getting the relevant checks
$check_list = [];
foreach ($csv_data as $key => $data_row) {
//skip 1st row
if ($key == 1)
continue;
//zone,sitename,site_Location,client_name,father_name,address,address_region,contact_number,allocation
if ($data_row[1] == '')
continue;
$projectSite = new ProjectSite();
$projectSite->setProjectId(null);
$projectSite->setZone($data_row[0]);
$projectSite->setSiteName($data_row[1]);
$projectSite->setSiteLocation($data_row[2]);
$projectSite->setClientName($data_row[3]);
$projectSite->setFatherName($data_row[4]);
$projectSite->setContactNumber($data_row[7]);
$projectSite->setAddress($data_row[5]);
$projectSite->setAddressRegion($data_row[6]);
$projectSite->setAllocation($data_row[8]);
$projectSite->setLatitude($data_row[9]);
$projectSite->setLongitude($data_row[10]);
$projectSite->setCompanyId($companyId);
$projectSite->setCreatedLoginId($loginId);
$projectSite->setEditedLoginId($loginId);
$em->persist($projectSite);
$em->flush();
}
return new JsonResponse(array(
"success" => true,
"file_path" => $file_path,
"csv_data" => $csv_data,
// "check_data" => $check_list,
// "debug_data"=>System::encryptSignature($r)
));
}
return new JsonResponse(array(
"success" => false,
"file_path" => '',
));
}
public function CreateProjectSiteAction(Request $request, $id)
{
$cc_id = '';
$cc_name = '';
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
if ($request->isMethod('POST')) {
$new_cc = [];
$regionId = 0;
$warehouseId = $request->request->get('warehouseId');
if ($request->request->get('branchId') != '' && $request->request->get('branchId') != 0) {
$em = $this->getDoctrine()->getManager();
$new_cc = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Branch')
->findOneBy(
array(
'branchId' => $request->request->get('branchId'),
)
);
$new_cc->setName($request->request->get('name'));
$new_cc->setAddress($request->request->get('address'));
$new_cc->setDeliveryAddress($request->request->get('deliveryAddress'));
$new_cc->setBillingAddress($request->request->get('billingAddress'));
$new_cc->setWarehouseId($request->request->get('warehouseId'));
$new_cc->setCashHeadIds(json_encode($request->request->get('cashHeadIds')));
$new_cc->setBankHeadIds(json_encode($request->request->get('bankHeadIds')));
$new_cc->setCompanyId($companyId);
$new_cc->setType($request->request->get('type'));
$new_cc->setSalesMethod($request->request->get('salesMethod'));
$new_cc->setDeliveryProcessType($request->request->get('deliveryProcessType'));
$new_cc->setPaymentProcessType($request->request->get('paymentProcessType'));
$em->flush();
$branchId = $new_cc->getBranchId();
$this->addFlash(
'success',
'Branch Information Updated'
);
} else {
$new_cc = new Branch();
$new_cc->setName($request->request->get('name'));
$new_cc->setWarehouseId($request->request->get('warehouseId'));
$new_cc->setCashHeadIds(json_encode($request->request->get('cashHeadIds')));
$new_cc->setBankHeadIds(json_encode($request->request->get('bankHeadIds')));
$new_cc->setCompanyId($companyId);
$new_cc->setType($request->request->get('type'));
$new_cc->setSalesMethod($request->request->get('salesMethod'));
$new_cc->setDeliveryProcessType($request->request->get('deliveryProcessType'));
$new_cc->setPaymentProcessType($request->request->get('paymentProcessType'));
$em->persist($new_cc);
$em->flush();
$branchId = $new_cc->getBranchId();
$this->addFlash(
'success',
'New Branch Added'
);
}
//now update salesperson on any client if available
if ($request->request->has('addWarehouseToSystem')) {
if ($warehouseId == 0 || $warehouseId == '') {
$warehouse = new Warehouse();
$warehouse->setCompanyId($companyId);
$warehouse->setName($request->request->get('name'));
$warehouse->setStatus(GeneralConstant::ACTIVE);
$em->persist($warehouse);
$em->flush();
$new_cc->setWarehouseId($warehouse->getId());
$em->flush();
}
}
if ($request->request->has('addCashHeadToSystem')) {
$id_list = json_decode($new_cc->getCashHeadIds(), true);
if ($id_list == [] || $id_list == null) {
if ($id_list == null)
$id_list = [];
//now get the cash parent for branch head
$par_set = $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
'name' => 'branch_cash_parent'
));
$par_head = '';
if ($par_set)
$par_head = $par_set->getData();
if ($par_head == '') {
$this->addFlash(
'error',
'Could not add cash head. Parent not found in settings'
);
} else {
//create The head
$accHead = Accounts:: CreateNewHead($em, GeneralConstant::OPENING_YEAR, $par_head, 'Cash at ' . $new_cc->getName(), '', 0, 0, 'dr', $request->getSession()->get(UserConstants::USER_LOGIN_ID));
$id_list = Accounts::addNumberToArrayIfNotExists($accHead, $id_list);
$new_cc->setCashHeadIds(json_encode($id_list));
$em->flush();
}
}
}
if ($request->request->has('addBankHeadToSystem')) {
$id_list = json_decode($new_cc->getBankHeadIds(), true);
if ($id_list == [] || $id_list == null) {
if ($id_list == null)
$id_list = [];
//now get the bank parent for branch head
$par_set = $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
'name' => 'branch_bank_parent'
));
$par_head = '';
if ($par_set)
$par_head = $par_set->getData();
if ($par_head == '') {
$this->addFlash(
'error',
'Could not add bank head. Parent not found in settings'
);
} else {
//create The head
$accHead = Accounts:: CreateNewHead($em, GeneralConstant::OPENING_YEAR, $par_head, 'Bank at ' . $new_cc->getName(), '', 0, 0, 'dr', $request->getSession()->get(UserConstants::USER_LOGIN_ID));
$id_list = Accounts::addNumberToArrayIfNotExists($accHead, $id_list);
$new_cc->setBankHeadIds(json_encode($id_list));
$em->flush();
}
}
}
}
$extData = [];
if ($id != 0) {
$extData = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Branch')
->findOneBy(
array(
'branchId' => $id
)
);
// $cc_data_list = [];
// foreach ($cc_data as $value) {
// $cc_data_list[$value->getSupplierCategoryId()]['id'] = $value->getSupplierCategoryId();
// $cc_data_list[$value->getSupplierCategoryId()]['name'] = $value->getName();
//
// if ($value->getSupplierCategoryId() == $id) {
// $cc_id = $value->getSupplierCategoryId();
// $cc_name = $value->getName();
// }
// }
}
return $this->render('@Project/pages/input_forms/ProjectSite.html.twig',
array(
'page_title' => 'Project Site',
'siteList' => $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\ProjectSite')
->findBy(
array(
'CompanyId' => $companyId
)
),
'extData' => $extData,
'headList' => Accounts::getParentLedgerHeads($em),
'branchTypes' => SalesConstant::$branchTypes,
'branchTypeDetails' => SalesConstant::$branchTypeDetails,
'salesMethodList' => SalesConstant::$salesMethod,
'deliveryProcessTypes' => SalesConstant::$deliveryProcessType,
'paymentProcessTypes' => SalesConstant::$paymentProcessType,
'warehouseList' => Inventory::WarehouseList($em),
'sales_person_list' => Client::SalesPersonList($this->getDoctrine()->getManager()),
// 'countryList'=>SalesOrderM::Co
)
);
}
/**
* JSON feed of a project's work-plan tasks for the cp-shell gantt Timeline.
* Normalises the mixed seconds/milliseconds timestamps and strips item_alias
* HTML so the front-end gets clean {id,parentId,name,start,end,status,pct}.
*/
public function ProjectWpTimelineDataAction(Request $request, $projectId = 0)
{
$conn = $this->getDoctrine()->getManager()->getConnection();
$rows = [];
try {
$rows = $conn->fetchAllAssociative(
"SELECT id, parent_id, item_alias AS name,
estimated_start_time_ts s, estimated_completion_time_ts e,
actual_start_time_ts as_s, actual_completion_time_ts as_e,
task_status status, completion_percentage pct, sequence,
dependency_planning_data dpd, dependency_planning_ids dpids, data meta
FROM planning_item
WHERE project_id = :p AND reference_type = 1 AND (delete_flag IS NULL OR delete_flag = 0)
ORDER BY COALESCE(sequence, id) ASC",
['p' => (int) $projectId]
);
} catch (\Throwable $e) { $rows = []; }
$norm = function ($v) {
$v = (float) $v;
if ($v <= 0) { return 0; }
if ($v > 9999999999) { $v = $v / 1000; } // milliseconds → seconds
return (int) $v;
};
$tasks = [];
$nowTs = time();
foreach ($rows as $r) {
$s = $norm($r['s']); $e = $norm($r['e']);
// Fall back to the schedule stored in the data JSON baseline (some tasks
// keep dates there rather than the estimated_* columns).
if (!$s || !$e) {
$meta = json_decode((string) ($r['meta'] ?? ''), true);
$bl = (is_array($meta) && isset($meta['baseline']) && is_array($meta['baseline'])) ? $meta['baseline'] : [];
if (!$s && isset($bl['startTs'])) { $s = $norm($bl['startTs']); }
if (!$e && isset($bl['endTs'])) { $e = $norm($bl['endTs']); }
}
// Unscheduled tasks still appear (anchored to today) so they can be
// dragged onto the calendar — matches the old timeline's behaviour.
$unscheduled = (!$s && !$e);
if ($unscheduled) { $s = $nowTs; $e = $nowTs; }
if (!$e) { $e = $s; }
if (!$s) { $s = $e; }
if ($e < $s) { $e = $s; }
$name = trim(strip_tags((string) $r['name']));
// Predecessor ids: prefer the structured dependency_planning_data JSON,
// fall back to the CSV dependency_planning_ids.
$deps = []; $seen = [];
$dpd = (string) ($r['dpd'] ?? '');
if ($dpd !== '') {
$arr = json_decode($dpd, true);
if (is_array($arr)) {
foreach ($arr as $dep) {
$did = is_array($dep) ? (int) ($dep['id'] ?? 0) : (int) $dep;
$lag = is_array($dep) ? (int) ($dep['lagDays'] ?? 0) : 0;
if ($did > 0 && !isset($seen[$did])) { $seen[$did] = 1; $deps[] = ['id' => $did, 'lag' => $lag]; }
}
}
}
if (empty($deps) && trim((string) ($r['dpids'] ?? '')) !== '') {
foreach (explode(',', (string) $r['dpids']) as $x) { $x = (int) trim($x); if ($x > 0 && !isset($seen[$x])) { $seen[$x] = 1; $deps[] = ['id' => $x, 'lag' => 0]; } }
}
$tasks[] = [
'id' => (int) $r['id'],
'parentId' => (int) $r['parent_id'],
'name' => $name !== '' ? $name : ('Task #' . (int) $r['id']),
'start' => $s, 'end' => $e,
'actualStart' => $norm($r['as_s']), 'actualEnd' => $norm($r['as_e']),
'status' => (string) $r['status'],
'pct' => round((float) $r['pct'], 1),
'deps' => array_values($deps),
'unscheduled' => $unscheduled,
];
}
return new \Symfony\Component\HttpFoundation\JsonResponse(['tasks' => $tasks]);
}
/**
* Persist a drag-reschedule from the gantt: update one planning item's
* estimated start/end (Unix seconds, matching the rest of the app). Direct
* update, tenant-scoped, fail-safe JSON.
*/
public function ProjectWpTimelineUpdateAction(Request $request)
{
$id = (int) $request->request->get('id');
$start = (int) $request->request->get('start');
$end = (int) $request->request->get('end');
if ($id <= 0 || $start <= 0 || $end <= 0 || $end < $start) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Invalid schedule.']);
}
try {
$conn = $this->getDoctrine()->getManager()->getConnection();
$loginId = (int) $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$aff = $conn->executeStatement(
"UPDATE planning_item
SET estimated_start_time_ts = :s, estimated_completion_time_ts = :e, edited_login_id = :l
WHERE id = :id AND (delete_flag IS NULL OR delete_flag = 0)",
['s' => $start, 'e' => $end, 'l' => $loginId, 'id' => $id]
);
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => (bool) $aff, 'id' => $id, 'start' => $start, 'end' => $end]);
} catch (\Throwable $ex) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Could not save.']);
}
}
/**
* Admin-only: set/clear a task's ACTUAL start & end (Unix seconds). Lets an
* admin backfill real dates for projects that ran before the work plan was
* created (and were tracked in Excel). Pass 0 to clear a field.
*/
public function ProjectWpActualUpdateAction(Request $request)
{
if ((int) $request->getSession()->get(UserConstants::USER_TYPE) !== 1) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Only an administrator can set actual dates.'], 403);
}
$id = (int) $request->request->get('id');
$as = (int) $request->request->get('actualStart');
$ae = (int) $request->request->get('actualEnd');
if ($id <= 0) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Invalid task.']);
}
if ($as > 0 && $ae > 0 && $ae < $as) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Actual end is before actual start.']);
}
try {
$conn = $this->getDoctrine()->getManager()->getConnection();
$loginId = (int) $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$conn->executeStatement(
"UPDATE planning_item
SET actual_start_time_ts = :as, actual_completion_time_ts = :ae, edited_login_id = :l
WHERE id = :id AND (delete_flag IS NULL OR delete_flag = 0)",
['as' => $as, 'ae' => $ae, 'l' => $loginId, 'id' => $id]
);
// Note: affected-rows may be 0 when re-saving identical values; the
// statement still succeeded, so report success unless it threw.
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'id' => $id, 'actualStart' => $as, 'actualEnd' => $ae]);
} catch (\Throwable $ex) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Could not save actual dates.']);
}
}
/**
* Toggle a finish→start dependency from the gantt: taskId (successor) depends
* on dependsOnId (predecessor). If the link already exists it is removed,
* otherwise added. Guards self-links and direct 2-cycles. Keeps both
* dependency_planning_data (JSON) and dependency_planning_ids (CSV) in sync.
*/
public function ProjectWpTimelineDependencyAction(Request $request)
{
$taskId = (int) $request->request->get('taskId');
$dependsOnId = (int) $request->request->get('dependsOnId');
if ($taskId <= 0 || $dependsOnId <= 0 || $taskId === $dependsOnId) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Invalid link.']);
}
try {
$conn = $this->getDoctrine()->getManager()->getConnection();
$decode = function ($id) use ($conn) {
$raw = (string) $conn->fetchOne("SELECT dependency_planning_data FROM planning_item WHERE id = :id", ['id' => $id]);
$arr = $raw !== '' ? json_decode($raw, true) : [];
return is_array($arr) ? $arr : [];
};
// Prevent a direct 2-cycle (predecessor already depends on this task).
foreach ($decode($dependsOnId) as $d) {
if ((int) (is_array($d) ? ($d['id'] ?? 0) : $d) === $taskId) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'That would create a circular dependency.']);
}
}
$remove = (int) $request->request->get('remove', 0) === 1;
$lag = (int) $request->request->get('lag', 0);
$arr = $decode($taskId);
$byId = [];
foreach ($arr as $d) { $did = (int) (is_array($d) ? ($d['id'] ?? 0) : $d); if ($did > 0) { $byId[$did] = is_array($d) ? $d : ['id' => $did]; } }
if ($remove) {
unset($byId[$dependsOnId]); $action = 'removed';
} else {
$existing = $byId[$dependsOnId] ?? ['id' => $dependsOnId, 'mode' => 'FS', 'completionRequired' => 0];
$existing['id'] = $dependsOnId; $existing['lagDays'] = $lag;
$action = isset($byId[$dependsOnId]) ? 'updated' : 'added';
$byId[$dependsOnId] = $existing;
}
$list = array_values($byId);
$csv = implode(',', array_map(function ($d) { return (int) $d['id']; }, $list));
$conn->executeStatement(
"UPDATE planning_item SET dependency_planning_data = :j, dependency_planning_ids = :c WHERE id = :id",
['j' => json_encode($list), 'c' => $csv, 'id' => $taskId]
);
$deps = array_map(function ($d) { return ['id' => (int) $d['id'], 'lag' => (int) ($d['lagDays'] ?? 0)]; }, $list);
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'action' => $action, 'taskId' => $taskId, 'deps' => $deps]);
} catch (\Throwable $ex) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Could not save the link.']);
}
}
public function updateDocDataAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
//all product fdm
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\InvProducts')
->findAll();
foreach ($QD as $entry) {
$entry->setProductFdm(
$entry->getIgId() . '_' .
$entry->getCategoryId() . '_' .
$entry->getSubCategoryId() . '_' .
$entry->getBrandCompany() . '_' .
$entry->getId()
);
$em->flush();
}
//stock req
$productListArray = [];
$subCategoryListArray = [];
$categoryListArray = [];
$igListArray = [];
$unitListArray = [];
$productList = Inventory::ProductList($em, $companyId);
$subCategoryList = Inventory::ProductSubCategoryList($em, $companyId);
$categoryList = Inventory::ProductCategoryList($em, $companyId);
$igList = Inventory::ItemGroupList($em, $companyId);
$unitList = Inventory::UnitTypeList($em);
//sales order item
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\SalesOrderItem')
->findAll();
foreach ($QD as $entry) {
if (isset($productList[$entry->getProductId()])) {
// $entry->setIgId($productList[$entry->getProductId()]['igId']);
// $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
// $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
// $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
$entry->setProductFdm(
(1 * $productList[$entry->getProductId()]['igId']) . '_' .
(1 * $productList[$entry->getProductId()]['categoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['subCategoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['brandCompany']) . '_' .
(1 * $entry->getProductId())
);
$entry->setUnitTypeId($productList[$entry->getProductId()]['unit_type']);
} else {
// $entry->setProductFdm(
// (1 * $entry->getIgId()) . '_' .
// (1 * $entry->getCategoryId()) . '_' .
// (1 * $entry->getSubCategoryId()) . '_' .
// (1 * $entry->getBrandCompany()) . '_' .
// (1 * $entry->getProductId())
// );
}
}
$em->flush();
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\DeliveryReceiptItem')
->findAll();
foreach ($QD as $entry) {
if ($entry->getUnitMultiplier() == 0 || $entry->getUnitMultiplier() == null)
$entry->setUnitMultiplier(1);
if ($entry->getUnitTypeId() == 0 || $entry->getUnitTypeId() == null)
$entry->setUnitTypeId(isset($productList[$entry->getProductId()]) ? $productList[$entry->getProductId()]['unit_type'] : 0);
}
$em->flush();
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\SalesInvoiceItem')
->findAll();
foreach ($QD as $entry) {
if ($entry->getUnitMultiplier() == 0 || $entry->getUnitMultiplier() == null)
$entry->setUnitMultiplier(1);
if ($entry->getUnitTypeId() == 0 || $entry->getUnitTypeId() == null)
$entry->setUnitTypeId(isset($productList[$entry->getProductId()]) ? $productList[$entry->getProductId()]['unit_type'] : 0);
}
$em->flush();
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\DeliveryOrderItem')
->findAll();
foreach ($QD as $entry) {
if (isset($productList[$entry->getProductId()])) {
// $entry->setIgId($productList[$entry->getProductId()]['igId']);
// $entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
// $entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
// $entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
$entry->setProductFdm(
(1 * $productList[$entry->getProductId()]['igId']) . '_' .
(1 * $productList[$entry->getProductId()]['categoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['subCategoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['brandCompany']) . '_' .
(1 * $entry->getProductId())
);
$entry->setUnitTypeId($productList[$entry->getProductId()]['unit_type']);
} else {
// $entry->setProductFdm(
// (1 * $entry->getIgId()) . '_' .
// (1 * $entry->getCategoryId()) . '_' .
// (1 * $entry->getSubCategoryId()) . '_' .
// (1 * $entry->getBrandCompany()) . '_' .
// (1 * $entry->getProductId())
// );
}
}
$em->flush();
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\StockRequisitionItem')
->findAll();
foreach ($QD as $entry) {
if (isset($productList[$entry->getProductId()])) {
$entry->setIgId($productList[$entry->getProductId()]['igId']);
$entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
$entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
$entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
$entry->setProductFdm(
(1 * $productList[$entry->getProductId()]['igId']) . '_' .
(1 * $productList[$entry->getProductId()]['categoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['subCategoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['brandCompany']) . '_' .
(1 * $entry->getProductId())
);
} else {
$entry->setProductFdm(
(1 * $entry->getIgId()) . '_' .
(1 * $entry->getCategoryId()) . '_' .
(1 * $entry->getSubCategoryId()) . '_' .
(1 * $entry->getBrandCompany()) . '_' .
(1 * $entry->getProductId())
);
}
}
$em->flush();
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\StoreRequisitionItem')
->findAll();
foreach ($QD as $entry) {
if (isset($productList[$entry->getProductId()])) {
$entry->setIgId($productList[$entry->getProductId()]['igId']);
$entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
$entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
$entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
$entry->setProductFdm(
(1 * $productList[$entry->getProductId()]['igId']) . '_' .
(1 * $productList[$entry->getProductId()]['categoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['subCategoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['brandCompany']) . '_' .
(1 * $entry->getProductId())
);
} else {
$entry->setProductFdm(
(1 * $entry->getIgId()) . '_' .
(1 * $entry->getCategoryId()) . '_' .
(1 * $entry->getSubCategoryId()) . '_' .
(1 * $entry->getBrandCompany()) . '_' .
(1 * $entry->getProductId())
);
}
}
$em->flush();
$QD = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\PurchaseRequisitionItem')
->findAll();
foreach ($QD as $entry) {
if (isset($productList[$entry->getProductId()])) {
$entry->setIgId($productList[$entry->getProductId()]['igId']);
$entry->setCategoryId($productList[$entry->getProductId()]['categoryId']);
$entry->setSubCategoryId($productList[$entry->getProductId()]['subCategoryId']);
$entry->setBrandCompany($productList[$entry->getProductId()]['brandCompany']);
$entry->setProductFdm(
(1 * $productList[$entry->getProductId()]['igId']) . '_' .
(1 * $productList[$entry->getProductId()]['categoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['subCategoryId']) . '_' .
(1 * $productList[$entry->getProductId()]['brandCompany']) . '_' .
(1 * $entry->getProductId())
);
} else {
$entry->setProductFdm(
(1 * $entry->getIgId()) . '_' .
(1 * $entry->getCategoryId()) . '_' .
(1 * $entry->getSubCategoryId()) . '_' .
(1 * $entry->getBrandCompany()) . '_' .
(1 * $entry->getProductId())
);
}
}
$em->flush();
foreach ($productList as $product) {
$productListArray[] = $product;
}
foreach ($categoryList as $product) {
$categoryListArray[] = $product;
}
foreach ($subCategoryList as $product) {
$subCategoryListArray[] = $product;
}
foreach ($igList as $product) {
$igListArray[] = $product;
}
foreach ($unitList as $product) {
$unitListArray[] = $product;
}
$brandList = Inventory::GetBrandList($em, $companyId);
$brandListArray = [];
foreach ($brandList as $product) {
$brandListArray[] = $product;
}
//1st bom
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findBy(
array()
);
foreach ($materialData as $bom) {
$Data = json_decode($bom->getData(), true);
$newData = [];
foreach ($Data as $dt) {
if (isset($dt['Products'])) {
foreach ($dt['Products']['products'] as $key => $value) {
if (!isset($dt['Products']['product_fdm']))
$dt['Products']['product_fdm'] = array();
if (!isset($dt['Products']['product_name']))
$dt['Products']['product_name'] = array();
if (!isset($dt['Products']['product_unit_type']))
$dt['Products']['product_unit_type'] = array();
if (!isset($dt['Products']['product_fdm'][$key])) {
$dt['Products']['product_fdm'][$key] = $productList[$value]['igId'] . '_' . $productList[$value]['categoryId'] . '_' . $productList[$value]['subCategoryId'] . '_' . $productList[$value]['brandCompany'] . '_' . $value;
}
if (!isset($dt['Products']['product_name'][$key])) {
$dt['Products']['product_name'][$key] = $productList[$value]['name'];
}
if (!isset($dt['Products']['product_unit_type'][$key])) {
$dt['Products']['product_unit_type'][$key] = $productList[$value]['unit_type'];
}
}
}
$newData[] = $dt;
}
$bom->setData(json_encode($newData));
$em->flush();
}
//now boq
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findBy(
array()
);
foreach ($materialData as $boq) {
$Data = json_decode($boq->getData(), true);
$newData = [];
foreach ($Data as $dt) {
if (isset($dt['Products'])) {
foreach ($dt['Products']['products'] as $key => $value) {
if (!isset($dt['Products']['product_fdm']))
$dt['Products']['product_fdm'] = array();
if (!isset($dt['Products']['product_name']))
$dt['Products']['product_name'] = array();
if (!isset($dt['Products']['product_unit_type']))
$dt['Products']['product_unit_type'] = array();
if (!isset($dt['Products']['product_fdm'][$key])) {
$dt['Products']['product_fdm'][$key] = $productList[$value]['igId'] . '_' . $productList[$value]['categoryId'] . '_' . $productList[$value]['subCategoryId'] . '_' . $productList[$value]['brandCompany'] . '_' . $value;
}
if (!isset($dt['Products']['product_name'][$key])) {
$dt['Products']['product_name'][$key] = $productList[$value]['name'];
}
if (!isset($dt['Products']['product_unit_type'][$key])) {
$dt['Products']['product_unit_type'][$key] = $productList[$value]['unit_type'];
}
}
}
$newData[] = $dt;
}
$boq->setData(json_encode($newData));
$em->flush();
}
//now offer
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findBy(
array()
);
foreach ($materialData as $offer) {
$Data = json_decode($offer->getData(), true);
$newData = [];
foreach ($Data as $of) {
if (isset($of['boqData'])) {
$dt = $of['boqData'];
if (isset($dt['Products'])) {
foreach ($dt['Products']['products'] as $key => $value) {
if (!isset($dt['Products']['product_fdm']))
$dt['Products']['product_fdm'] = array();
if (!isset($dt['Products']['product_name']))
$dt['Products']['product_name'] = array();
if (!isset($dt['Products']['product_unit_type']))
$dt['Products']['product_unit_type'] = array();
if (!isset($dt['Products']['product_fdm'][$key])) {
$dt['Products']['product_fdm'][$key] = $productList[$value]['igId'] . '_' . $productList[$value]['categoryId'] . '_' . $productList[$value]['subCategoryId'] . '_' . $productList[$value]['brandCompany'] . '_' . $value;
}
if (!isset($dt['Products']['product_name'][$key])) {
$dt['Products']['product_name'][$key] = $productList[$value]['name'];
}
if (!isset($dt['Products']['product_unit_type'][$key])) {
$dt['Products']['product_unit_type'][$key] = $productList[$value]['unit_type'];
}
}
}
$of['boqData'] = $dt;
}
$newData[] = $of;
}
$offer->setData(json_encode($newData));
$em->flush();
}
$url = $this->generateUrl(
'dashboard'
);
return $this->redirect($url);
}
public function overhaulItemDataAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
ProjectM::overhaulItems($em, $companyId);
return 1;
}
public function EditProjectDetailsAction(Request $request, $id)
{
return $this->UpdateProjectAction($request, $id);
}
public function ViewProjectDetailsAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $id, ///material
));
if ($id == 0) {
$url = $this->generateUrl(
'project_list'
);
return $this->redirect($url);
}
$Approval_data = System::checkIfApprovalExists(
$em,
array_flip(GeneralConstant::$Entity_list)['Project'],
$id,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
$stage_list = ProjectConstant::$projectStages;
$status_list = ProjectConstant::$projectStatus;
$steps_list = ProjectConstant::$projectSteps;
$categoryList = [];
$categories = $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy(
array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
)
);
foreach ($categories as $cat) {
$categoryList[$cat->getProjectCategoryId()] = array(
'id' => $cat->getProjectCategoryId(),
'categoryName' => $cat->getCategoryName(),
);
}
$projectSurfaceSplit = $this->isProjectSurfaceSplitEnabled();
$projectTeamGroups = $this->get(ProjectTeamResolverService::class)->resolveProjectTeamGroups($projectData, $this->getLoggedUserCompanyId($request));
return $this->render('@Project/pages/views/view_project_details.html.twig',
array(
'page_title' => 'Project Details',
'projectData' => $projectData,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'proposalData' => ProjectM::GetProposalDetails($em, $id),
'materialData' => ProjectM::GetBomDetails($em, $id),
'boqData' => ProjectM::GetBoqDetails($em, $id),
'wpData' => ProjectM::GetWpDetails($em, $id),
'offerData' => ProjectM::GetOfferDetails($em, $id),
'clientList' => SalesOrderM::GetClientList($em),
'stageList' => $stage_list,
'statusList' => $status_list,
'stepsList' => $steps_list,
'categories' => $categoryList,
'projectTypes' => ProjectM::getProjectTypesFromConfigFile($this->container->getParameter('kernel.root_dir')),
'stepsListRoutes' => ProjectConstant::$projectStepsRoutes,
'approval_status' => $projectData->getApproved(),
'approval_data' => $Approval_data,
'auto_created' => $projectData->getAutocreated(),
'id' => $id,
'milestoneData' => ProjectM::GetProjectMilestones($em, $id, $this->getLoggedUserCompanyId($request)),
'projectCostData' => ProjectM::GetProjectCosts($em, $id, $this->getLoggedUserCompanyId($request)),
'omLinkage' => ProjectM::GetProjectOmLinkage($em, $id),
'publicShareData' => ProjectM::GetProjectPublicShares($em, $id),
'ganttTasks' => ProjectM::GetProjectGanttData($em, $id, false),
'projectIntelligence' => ProjectM::GetProjectIntelligenceData($em, $id, $this->getLoggedUserCompanyId($request), false),
'projectTeamGroups' => $projectTeamGroups,
'projectSurfaceSplit' => $projectSurfaceSplit,
'document_log' => $projectData->getAutocreated() == 0 ? System::getDocumentLog(
$this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['Project'],
$id,
$projectData->getCreatedLoginId(),
$projectData->getEditedLoginId()
) : []
)
);
}
// PLC5 — site-completion / O&M lifecycle transition; the enums existed for years with no writer
public function SetProjectLifecycleStateAction(Request $request, $id = 0)
{
// House auth model (PLC2 lesson): the Symfony firewall sees everyone as anonymous here —
// gate on the session login id; SessionCheckInterface blocks the unauthenticated upstream.
if (!$request->getSession()->get(UserConstants::USER_LOGIN_ID)) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'message' => 'Not authenticated.'], 403);
}
$em = $this->getDoctrine()->getManager();
/** @var \ApplicationBundle\Entity\Project|null $project */
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(['projectId' => $id]);
if (!$project) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'message' => 'Project not found.'], 404);
}
$verdict = \ApplicationBundle\Modules\Project\Support\ProjectCompletionCore::decide(
$request->request->get('target', ''),
$project->getStage(),
$project->getProjectStep()
);
if (!$verdict['ok']) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'message' => $verdict['message']], 400);
}
// Project.status is deliberately untouched: it is the boolean ACTIVE/soft-delete flag
// (Project.orm.yml maps it boolean), not the $projectStatus enum — see ProjectCompletionCore.
$project->setStage($verdict['set']['stage']);
$project->setProjectStep($verdict['set']['projectStep']);
$project->setLastModifiedDate(new \DateTime());
$em->flush();
return new \Symfony\Component\HttpFoundation\JsonResponse([
'success' => true,
'stage' => $verdict['set']['stage'],
'step' => $verdict['set']['projectStep'],
'phase' => \ApplicationBundle\Modules\Project\Support\ProjectCompletionCore::phaseFor($verdict['set']['projectStep']),
]);
}
public function GetRefreshedItemAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$qry = $em->getRepository("ApplicationBundle\\Entity\\InvProducts")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
'type' => 1//trade items
));
$pl = [];
$pl_array = [];
foreach ($qry as $product) {
$pl[$product->getId()] = array(
'text' => $product->getName(),
'name' => $product->getName(),
'id' => $product->getId(),
'value' => $product->getId(),
'purchase_price' => $product->getPurchasePrice(),
'sales_price' => $product->getSalesPrice(),
'supplier_id' => $product->getBrandCompany(),
);
$pl_array[] = array(
'text' => $product->getName(),
'value' => $product->getId(),
'name' => $product->getName(),
'id' => $product->getId(),
'purchase_price' => $product->getPurchasePrice(),
'sales_price' => $product->getSalesPrice(),
'supplier_id' => $product->getBrandCompany(),
);
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$sl = [];
$sl_array = [];
foreach ($qry as $product) {
$sl[$product->getServiceId()] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
$sl_array[] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
}
$hl = Accounts::HeadList($em);
$hl_array = Accounts::getParentLedgerHeads($em, "", "", [], 1, $this->getLoggedUserCompanyId($request));
return new JsonResponse(
array(
// 'page_title'=>'BOM',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
"success" => true,
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'sl' => $sl,
'pl' => $pl,
'hl' => $hl,
'hl_array' => $hl_array,
'pl_array' => $pl_array,
'sl_array' => $sl_array,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function CreateProjectProposalAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$em = $this->getDoctrine()->getManager();
$entity_id = array_flip(GeneralConstant::$Entity_list)['ProjectProposal']; //change
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
), array('projectDate' => 'desc')
);
// $client=$em->getRepository('ApplicationBundle\\Entity\\AccClients')->findOneBy(
// array(
// 'clientId'=>$projectData->getClientId(), ///material
//
// ),array('projectDate'=>'desc')
// );
$dochash = "PP/" . $projectData->getProjectCategoryId() . "/" . $projectData->getClientId() . "/" . $projectId; //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash(
'error',
'Sorry Could not insert Data.'
);
} else {
//construct the files
$file_list = array(
'product_files' => [],
'service_files' => [],
'ar_files' => [],
);
if ($request->request->has('products')) {
foreach ($request->files->get('product_reference_file') as $uploadedFile) {
$path = "";
if ($uploadedFile != null) {
$fileName = 'p' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['product_files'][] = $path;
}
}
if ($request->request->has('services')) {
//construct the ref_files array
$ref_files = [];
$path = "";
$file_path = "";
foreach ($request->files->get('service_reference_file') as $uploadedFile) {
// $uploadedFile = $request->files['service_reference_file_' . $request->request->get('service_uid')[$key]];
$path = "";
if ($uploadedFile != null) {
$fileName = 's' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['service_files'][] = $path;
}
}
if ($request->request->has('heads')) {
//construct the ref_files array
$ref_files = [];
$path = "";
$file_path = "";
foreach ($request->files->get('ar_reference_file') as $uploadedFile) {
// $uploadedFile = $request->files['ar_reference_file_' . $request->request->get('ar_uid')[$key]];
$path = "";
if ($uploadedFile != null) {
$fileName = 'a' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['ar_files'][] = $path;
}
}
$projectWpId = ProjectM::CreateNewProposal($this->getDoctrine()->getManager(), $projectId, $request->request, $dochash, $file_list,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole'); //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectProposal']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$projectWpId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$projectWpId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'Project Offer Created'
);
}
$url = $this->generateUrl(
'view_project_proposal'
);
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
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),
"Offer Letter : " . $dochash . " Has Been Created For The Project:" . $proj_here->getProjectName() . " ",
'user',
array_merge(
json_decode($proj_here->getMarketingUserIds(), true),
json_decode($proj_here->getBillingUserIds(), true),
json_decode($proj_here->getDesigningUserIds(), true)
),
'information',
$url . "/" . $projectId,
"Offer Letter- " . $proj_here->getProjectName()
);
return $this->redirect($url . "/" . $projectId);
}
$projectList = [];
$projectData = [];
$materialData = [];
$boqData = [];
$wpData = [];
$offerData = [];
$proposalData = [];
$message = "";
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
'projectStep' => array_flip(ProjectConstant::$projectSteps)['PROPOSAL'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectId == 0) {
} else {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData) {
$proposalData = $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
//now if its not editable, redirect to view
if ($proposalData) {
if ($proposalData->getEditFlag() != 1) {
$url = $this->generateUrl(
'view_project_proposal'
);
$this->addFlash(
'error',
'Sorry You cant Edit the document Right now.'
);
return $this->redirect($url . "/" . $projectId);
}
}
} else {
$this->addFlash(
'error',
'Sorry! Could not find your desired project data or this action is not allowed for your specific project at the moment..'
);
}
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\InvProducts")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
'type' => 1//trade items
));
$pl = [];
$pl_array = [];
foreach ($qry as $product) {
$pl[$product->getId()] = array(
'text' => $product->getName(),
'name' => $product->getName(),
'id' => $product->getId(),
'value' => $product->getId(),
'purchase_price' => $product->getPurchasePrice(),
'sales_price' => $product->getSalesPrice(),
'supplier_id' => $product->getBrandCompany(),
);
$pl_array[] = array(
'text' => $product->getName(),
'value' => $product->getId(),
'name' => $product->getName(),
'id' => $product->getId(),
'purchase_price' => $product->getPurchasePrice(),
'sales_price' => $product->getSalesPrice(),
'supplier_id' => $product->getBrandCompany(),
);
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$sl = [];
$sl_array = [];
foreach ($qry as $product) {
$sl[$product->getServiceId()] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
$sl_array[] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\ProjectWorkStage")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$workStages = [];
$workStages_array = [];
foreach ($qry as $product) {
$workStages[$product->getProjectWorkStageId()] = array(
'text' => $product->getStageName(),
'value' => $product->getProjectWorkStageId(),
'name' => $product->getStageName(),
'id' => $product->getProjectWorkStageId(),
);
$workStages_array[] = array(
'text' => $product->getStageName(),
'value' => $product->getProjectWorkStageId(),
'name' => $product->getStageName(),
'id' => $product->getProjectWorkStageId(),
);
}
$hl = Accounts::HeadList($em);
$debug_data = $request->files->get('product_reference_file');
$companyId = $this->getLoggedUserCompanyId($request);
$productListArray = [];
$subCategoryListArray = [];
$categoryListArray = [];
$igListArray = [];
$unitListArray = [];
$productList = Inventory::ProductList($em, $companyId);
$subCategoryList = Inventory::ProductSubCategoryList($em, $companyId);
$categoryList = Inventory::ProductCategoryList($em, $companyId);
$igList = Inventory::ItemGroupList($em, $companyId);
$unitList = Inventory::UnitTypeList($em);
foreach ($productList as $product) {
$productListArray[] = $product;
}
foreach ($categoryList as $product) {
$categoryListArray[] = $product;
}
foreach ($subCategoryList as $product) {
$subCategoryListArray[] = $product;
}
foreach ($igList as $product) {
$igListArray[] = $product;
}
foreach ($unitList as $product) {
$unitListArray[] = $product;
}
$brandList = Inventory::GetBrandList($em, $companyId);
$brandListArray = [];
foreach ($brandList as $product) {
$brandListArray[] = $product;
}
return $this->render('@Project/pages/input_forms/create_project_proposal.html.twig',
array(
'page_title' => 'Project Proposal Letter',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'productList' => $productList,
'subCategoryList' => $subCategoryList,
'categoryList' => $categoryList,
'igList' => $igList,
'unitList' => $unitList,
'brandList' => $brandList,
'brandListArray' => $brandListArray,
'productListArray' => $productListArray,
'subCategoryListArray' => $subCategoryListArray,
'categoryListArray' => $categoryListArray,
'igListArray' => $igListArray,
'unitListArray' => $unitListArray,
'sl' => $sl,
'pl' => $pl,
'hl' => $hl,
'workStages' => $workStages,
'projectList' => $projectList,
'projectData' => $projectData,
'materialData' => $materialData,
'boqData' => $boqData,
'wpData' => $wpData,
'offerData' => $offerData,
'proposalData' => $proposalData,
'message' => $message,
'projectId' => $projectId,
'pl_array' => $pl_array,
'sl_array' => $sl_array,
'workStages_array' => $workStages_array,
'debug_data' => $debug_data,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function ViewProjectProposalAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetProposalDetails($em, $id);
///
// $projectData=$em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
// array(
// 'projectId'=>$id, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['NEGOTIATION'], ///material
//// 'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
//// 'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
// ),array('projectDate'=>'desc')
// );
// $offerDataList=$em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findBy(
// array(
// 'approved'=>1, ///material
//
// )
// );
// if(!empty($offerDataList)) {
// foreach ($offerDataList as $offerData) {
// $all_det_data = json_decode($offerData->getData(), true);
// $entry = $all_det_data[0];
// $store_items = $entry['boqData']['Products'];
// ProjectM::addProductsByFdm($em, $store_items['product_fdm'], $offerData->getCompanyId());
//
// }
// }
///////
if (!$dt) {
$url = $this->generateUrl(
'create_project_proposal'
);
$this->addFlash(
'error',
'Please Create Offer for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$stage_list = ProjectConstant::$projectStages;
$status_list = ProjectConstant::$projectStatus;
$steps_list = ProjectConstant::$projectSteps;
$costSheetDoc = $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
->findOneBy(['projectId' => (int) $id, 'dataType' => 'cost_sheet']);
$costSheetData = $costSheetDoc ? (json_decode((string) $costSheetDoc->getData(), true) ?: null) : null;
return $this->render('@Project/pages/views/view_project_proposal.html.twig',
array(
'page_title' => 'Proposal Letter',
'data' => $dt,
'costSheetData' => $costSheetData,
'costSheetProjectId' => (int) $id,
// 'boqData'=>ProjectM::GetBoqDetails($em,$id),
// 'wpData'=>ProjectM::GetWpDetails($em,$id),
'clientList' => SalesOrderM::GetClientList($em),
'stageList' => $stage_list,
'statusList' => $status_list,
'stepsList' => $steps_list,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'auto_created' => $dt['auto_created'],
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => $dt['auto_created'] == 0 ? System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$id,
$dt['created_by'],
$dt['edited_by']) : [],
'users' => Users::getUserListById($em)
)
);
}
public function PrintProjectProposalAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetProposalDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_proposal'
);
$this->addFlash(
'error',
'Please Create Offer for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$company_data = Company::getCompanyData($em, 1);
$document_mark = array(
'original' => '/images/Original-Stamp-PNG-Picture.png',
'copy' => ''
);
if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
$html = $this->renderView('@Project/pages/print/print_project_proposal.html.twig',
array(
//full array here
'pdf' => true,
'page_title' => 'Offer Letter',
'export' => 'pdf,print',
'data' => $dt,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'document_type' => 'Offer Letter',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
$pdf_response = $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
// 'orientation' => 'landscape',
// 'enable-javascript' => true,
// 'javascript-delay' => 1000,
'no-stop-slow-scripts' => false,
'no-background' => false,
'lowquality' => false,
'encoding' => 'utf-8',
// 'images' => true,
// 'cookie' => array(),
'dpi' => 300,
'image-dpi' => 300,
// 'enable-external-links' => true,
// 'enable-internal-links' => true
));
return new Response(
$pdf_response,
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="offer.pdf"'
)
);
}
return $this->render('@Project/pages/print/print_project_proposal.html.twig',
array(
'page_title' => 'Project Offer Letter',
'export' => 'pdf,print',
'data' => $dt,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
}
public function CreateProjectMaterialAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$em = $this->getDoctrine()->getManager();
$entity_id = array_flip(GeneralConstant::$Entity_list)['ProjectMaterial']; //change
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
$dochash = "BM/" . $proj_here->getProjectCategoryId() . "/" . $proj_here->getClientId() . "/" . $projectId; //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash(
'error',
'Sorry Couldnot insert Data.'
);
} else {
$projectBomId = ProjectM::CreateNewBom($this->getDoctrine()->getManager(), $projectId, $request->request, $dochash,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole'); //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectMaterial']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$projectBomId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$projectBomId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'Bill of Materials Created'
);
}
$url = $this->generateUrl(
'view_project_bom'
);
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
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),
"Bill of material : " . $dochash . " Has Been Created For The Project:" . $proj_here->getProjectName() . " ",
'user',
array_merge(
json_decode($proj_here->getMarketingUserIds(), true),
json_decode($proj_here->getMaterialUserIds(), true),
json_decode($proj_here->getDesigningUserIds(), true)
),
'information',
$url . "/" . $projectId,
"Bill of Materials- " . $proj_here->getProjectName()
);
return $this->redirect($url . "/" . $projectId);
}
$projectList = [];
$projectData = [];
$materialData = [];
$message = "";
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
'projectStep' => array_flip(ProjectConstant::$projectSteps)['MATERIAL PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectId == 0) {
} else {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
'projectStep' => array_flip(ProjectConstant::$projectSteps)['MATERIAL PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData) {
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
$proposalData = $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
if (!$proposalData && $projectData->getProposalRequired() == 1) {
$url = $this->generateUrl(
'create_project_proposal'
);
$this->addFlash(
'error',
'Please Create Proposal for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
//now if its not editable, redirect to view
if ($materialData) {
if ($materialData->getEditFlag() != 1) {
$url = $this->generateUrl(
'view_project_bom'
);
return $this->redirect($url . "/" . $projectId);
}
}
} else {
$this->addFlash(
'error',
'Sorry! Could not find your desired project data or this action is not allowed for your specific project at the moment..'
);
}
}
$companyId = $this->getLoggedUserCompanyId($request);
$productListArray = [];
$subCategoryListArray = [];
$categoryListArray = [];
$igListArray = [];
$unitListArray = [];
// $productList=Inventory::ProductList($em,$companyId);
$productList = [];
$subCategoryList = [];
// $subCategoryList=Inventory::ProductSubCategoryList($em,$companyId);
$categoryList = [];
// $categoryList=Inventory::ProductCategoryList($em,$companyId);
$igList = [];
// $igList=Inventory::ItemGroupList($em,$companyId);
// $unitList=[];
$unitList = Inventory::UnitTypeList($em);
// foreach ($productList as $product) {
//
// $productListArray[]=$product;
// }
// foreach ($categoryList as $product) {
//
// $categoryListArray[]=$product;
// }
// foreach ($subCategoryList as $product) {
//
// $subCategoryListArray[]=$product;
// }
// foreach ($igList as $product) {
//
// $igListArray[]=$product;
// }
foreach ($unitList as $product) {
$unitListArray[] = $product;
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$sl = [];
$sl_array = [];
// foreach ($qry as $product) {
// $sl[$product->getServiceId()]=array(
// 'text'=>$product->getServiceName(),
// 'value'=>$product->getServiceId(),
// 'name'=>$product->getServiceName(),
// 'id'=>$product->getServiceId(),
// );
// $sl_array[]=array(
// 'text'=>$product->getServiceName(),
// 'value'=>$product->getServiceId(),
// 'name'=>$product->getServiceName(),
// 'id'=>$product->getServiceId(),
// );
// }
$hl = Accounts::HeadList($em);
$brandList = Inventory::GetBrandList($em, $companyId);
$brandListArray = [];
foreach ($brandList as $product) {
$brandListArray[] = $product;
}
return $this->render('@Project/pages/input_forms/create_project_bom.html.twig',
array(
'page_title' => 'BOM',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'sl' => $sl,
'userRestrictions' => Users::getUserApplicationAccessSettings($em, $request->getSession()->get(UserConstants::USER_ID))['options'],
'productList' => $productList,
'subCategoryList' => $subCategoryList,
'categoryList' => $categoryList,
'igList' => $igList,
'unitList' => $unitList,
'productListArray' => $productListArray,
'subCategoryListArray' => $subCategoryListArray,
'categoryListArray' => $categoryListArray,
'igListArray' => $igListArray,
'unitListArray' => $unitListArray,
'brandList' => $brandList,
'brandListArray' => $brandListArray,
'hl' => $hl,
'projectList' => $projectList,
'projectData' => $projectData,
'materialData' => $materialData,
'message' => $message,
'projectId' => $projectId,
'sl_array' => $sl_array,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function ViewProjectBomAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetBomDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_material'
);
$this->addFlash(
'error',
'Please Create Material Listings for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
return $this->render('@Project/pages/views/view_project_bom.html.twig',
array(
'page_title' => 'View',
'data' => $dt,
'auto_created' => $dt['auto_created'],
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => $dt['auto_created'] == 0 ? System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$id,
$dt['created_by'],
$dt['edited_by']) : [],
'users' => Users::getUserListById($em)
)
);
}
public function PrintProjectBomAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetBomDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_material'
);
$this->addFlash(
'error',
'Please Create Material Listings for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$company_data = Company::getCompanyData($em, 1);
$document_mark = array(
'original' => '/images/Original-Stamp-PNG-Picture.png',
'copy' => ''
);
if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
$html = $this->renderView('@Project/pages/print/print_project_bom.html.twig',
array(
//full array here
'pdf' => true,
'page_title' => 'Project BOM',
'export' => 'pdf,print',
'data' => $dt,
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'document_type' => 'Bill Of materials',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
$pdf_response = $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
// 'orientation' => 'landscape',
// 'enable-javascript' => true,
// 'javascript-delay' => 1000,
'no-stop-slow-scripts' => false,
'no-background' => false,
'lowquality' => false,
'encoding' => 'utf-8',
// 'images' => true,
// 'cookie' => array(),
'dpi' => 300,
'image-dpi' => 300,
// 'enable-external-links' => true,
// 'enable-internal-links' => true
));
return new Response(
$pdf_response,
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="bom.pdf"'
)
);
}
return $this->render('@Project/pages/print/print_project_bom.html.twig',
array(
'page_title' => 'Project BOM',
'export' => 'pdf,print',
'data' => $dt,
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
}
public function ForceEditProjectBoqAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$em = $this->getDoctrine()->getManager();
$entity_id = array_flip(GeneralConstant::$Entity_list)['ProjectBoq']; //change
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
$dochash = "BQ/" . $proj_here->getProjectCategoryId() . "/" . $proj_here->getClientId() . "/" . $projectId; //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
$boqData = $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
$prev_edit_flg = 0;
if ($boqData) {
$prev_edit_flg = $boqData->getEditFlag();//temporarily
$boqData->setEditFlag(1);//temporarily
$boqData->setLockFlag(1);//temporarily
}
$em->flush();
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
if ($boqData) {
$boqData->setEditFlag($prev_edit_flg);//temporarily
$boqData->setLockFlag(1);//temporarily
}
$em->flush();
$this->addFlash(
'error',
'Sorry Couldnot insert Data.'
);
} else {
//construct the files
$file_list = array(
'product_files' => [],
'service_files' => [],
'ar_files' => [],
);
if ($request->request->has('products')) {
foreach ($request->files->get('product_reference_file', []) as $uploadedFile) {
$path = "";
if ($uploadedFile != null) {
$fileName = 'p' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['product_files'][] = $path;
}
}
if ($request->request->has('services')) {
//construct the ref_files array
$ref_files = [];
$path = "";
$file_path = "";
foreach ($request->files->get('service_reference_file', []) as $uploadedFile) {
// $uploadedFile = $request->files['service_reference_file_' . $request->request->get('service_uid')[$key]];
$path = "";
if ($uploadedFile != null) {
$fileName = 's' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['service_files'][] = $path;
}
}
if ($request->request->has('heads')) {
//construct the ref_files array
$ref_files = [];
$path = "";
$file_path = "";
foreach ($request->files->get('ar_reference_file', []) as $uploadedFile) {
// $uploadedFile = $request->files['ar_reference_file_' . $request->request->get('ar_uid')[$key]];
$path = "";
if ($uploadedFile != null) {
$fileName = 'a' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['ar_files'][] = $path;
}
}
$document_data_id = SalesOrderM::UpdateDocumentData($this->getDoctrine()->getManager(), $request->request->get('documentDataId'), $request->request, $file_list);
$projectBoqId = ProjectM::CreateNewBoq($this->getDoctrine()->getManager(), $projectId, $document_data_id, $request->request, $dochash, $file_list,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
$all_seq_list = $em->getRepository('ApplicationBundle\\Entity\\Approval')
->findBy(
array(
'entity' => array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
'entityId' => $projectBoqId,
// 'sequence' => $dt->getSequence()
)
);
foreach ($all_seq_list as $useless_data) {
// if($useless_data->getSequence()>$dt->getSequence())
{
$em->remove($useless_data);
$em->flush();
}
}
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole'); //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectBoq']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$projectBoqId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$projectBoqId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'Bill of Quantity Created'
);
}
$url = $this->generateUrl(
'view_project_boq'
);
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
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),
"Bill of Quantity : " . $dochash . " Has Been Created For The Project:" . $proj_here->getProjectName() . " ",
'user',
array_merge(
json_decode($proj_here->getMarketingUserIds(), true),
json_decode($proj_here->getDesigningUserIds(), true)
),
'information',
$url . "/" . $projectId,
"Bill of Quantity- " . $proj_here->getProjectName()
);
return $this->redirect($url . "/" . $projectId);
}
$projectList = [];
$projectData = [];
$materialData = [];
$boqData = [];
$message = "";
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectId == 0) {
} else {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData) {
$proposalData = $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
if (!$proposalData && $projectData->getProposalRequired() == 1) {
$url = $this->generateUrl(
'create_project_proposal'
);
$this->addFlash(
'error',
'Please Create Proposal for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
$boqData = $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
//now if its not editable, redirect to view
if (!$materialData && ($projectData->getBomRequired() == 1)) {
$url = $this->generateUrl(
'create_project_material'
);
$this->addFlash(
'error',
'Please Create Material Listings for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
} else {
$this->addFlash(
'error',
'Sorry! Could not find your desired project data or this action is not allowed for your specific project at the moment..'
);
}
}
$companyId = $this->getLoggedUserCompanyId($request);
$productListArray = [];
$subCategoryListArray = [];
$categoryListArray = [];
$igListArray = [];
$unitListArray = [];
$currencyList = Inventory::CurrencyList($em);
$currencyListArray = [];
$productList = Inventory::ProductList($em, $companyId);
$subCategoryList = Inventory::ProductSubCategoryList($em, $companyId);
$categoryList = Inventory::ProductCategoryList($em, $companyId);
$igList = Inventory::ItemGroupList($em, $companyId);
$unitList = Inventory::UnitTypeList($em);
foreach ($productList as $product) {
$productListArray[] = $product;
}
foreach ($categoryList as $product) {
$categoryListArray[] = $product;
}
foreach ($subCategoryList as $product) {
$subCategoryListArray[] = $product;
}
foreach ($igList as $product) {
$igListArray[] = $product;
}
foreach ($unitList as $product) {
$unitListArray[] = $product;
}
$brandList = Inventory::GetBrandList($em, $companyId);
$brandListArray = [];
foreach ($brandList as $product) {
$brandListArray[] = $product;
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$sl = [];
$sl_array = [];
foreach ($qry as $product) {
$sl[$product->getServiceId()] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
$sl_array[] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
}
$hl = Accounts::HeadList($em);
$debug_data = $request->files->get('product_reference_file');
return $this->render('@Project/pages/input_forms/create_project_boq.html.twig',
array(
'page_title' => 'BOQ',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'sl' => $sl,
'productList' => $productList,
'subCategoryList' => $subCategoryList,
'categoryList' => $categoryList,
'igList' => $igList,
'userRestrictions' => Users::getUserApplicationAccessSettings($em, $request->getSession()->get(UserConstants::USER_ID))['options'],
'unitList' => $unitList,
'brandList' => $brandList,
'brandListArray' => $brandListArray,
'currencyList' => $currencyList,
'currencyListArray' => $currencyListArray,
'productListArray' => $productListArray,
'subCategoryListArray' => $subCategoryListArray,
'categoryListArray' => $categoryListArray,
'igListArray' => $igListArray,
'unitListArray' => $unitListArray,
'hl' => $hl,
'projectList' => $projectList,
'projectData' => $projectData,
'materialData' => $materialData,
'extDocData' => $boqData,
'message' => $message,
'projectId' => $projectId,
'sl_array' => $sl_array,
'debug_data' => $debug_data,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function ToggleLockProjectAction(Request $request, $id = 0)
{
$em = $this->getDoctrine()->getManager();
$prj = $em->getRepository("ApplicationBundle\\Entity\\Project")->findOneBy(array(
'projectId' => $id
));
if ($prj) {
if ($prj->getLockFlag() != 1)
$prj->setLockFlag(1);
else
$prj->setLockFlag(0);
$em->flush();
return new JsonResponse(array(
"success" => true,
"status" => $prj->getLockFlag(),
"id" => $id
// "file_path"=>$file_path,
// "r"=>$r,
// "debug_data"=>System::encryptSignature($r)
));
}
return new JsonResponse(array(
"success" => false,
"id" => $id
// "status"=>$prj->getLockFlag(),
// "file_path"=>$file_path,
// "r"=>$r,
// "debug_data"=>System::encryptSignature($r)
));
//for edits
$extVoucherData = [];
$extVoucherDetailsData = [];
// if($voucherId==0)
// {
//
// }
// else
// {
//
// $extTrans=$em->getRepository('ApplicationBundle\\Entity\\AccTransactions')->findOneBy(
// array(
// 'transactionId'=>$voucherId, ///material
//
// )
// );
//
//
// //now if its not editable, redirect to view
// if($extTrans) {
// if ($extTrans->getEditFlag() != 1) {
// $url = $this->generateUrl(
// 'view_voucher'
// );
// return $this->redirect($url . "/" . $voucherId);
// }
// else
// {
// $extVoucherData=$extTrans;
// $extVoucherDetailsData=Accounts::GetVoucherDataForEdit($em,$voucherId);
// }
// }
// else
// {
//
// }
//
// }
//
//
// return $this->render('ApplicationBundle:pages/accounts/input_forms:journal_voucher.html.twig',
// array(
// 'page_title'=>'Create Journal Voucher',
// 'transaction'=>[],
// 'extVoucherData'=>$extVoucherData,
// 'extVoucherDetailsData'=>$extVoucherDetailsData
// )
// );
return new JsonResponse(array(
"success" => true,
"status" => $prj->getLockFlag(),
// "file_path"=>$file_path,
// "r"=>$r,
// "debug_data"=>System::encryptSignature($r)
));
// $url = $this->generateUrl(
// 'check_management'
// );
// return $this->redirect($url );
}
public function CreateProjectBoqAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$em = $this->getDoctrine()->getManager();
$entity_id = array_flip(GeneralConstant::$Entity_list)['ProjectBoq']; //change
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
$dochash = "BQ/" . $proj_here->getProjectCategoryId() . "/" . $proj_here->getClientId() . "/" . $projectId; //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash(
'error',
'Sorry Couldnot insert Data.'
);
} else {
//construct the files
$file_list = array(
'product_files' => [],
'service_files' => [],
'ar_files' => [],
);
if ($request->request->has('products')) {
if ($request->files->has('product_reference_file')) {
foreach ($request->files->get('product_reference_file') as $uploadedFile) {
$path = "";
if ($uploadedFile != null) {
$fileName = 'p' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['product_files'][] = $path;
}
}
}
if ($request->request->has('services')) {
//construct the ref_files array
$ref_files = [];
$path = "";
$file_path = "";
if ($request->files->has('service_reference_file')) {
foreach ($request->files->get('service_reference_file') as $uploadedFile) {
// $uploadedFile = $request->files['service_reference_file_' . $request->request->get('service_uid')[$key]];
$path = "";
if ($uploadedFile != null) {
$fileName = 's' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['service_files'][] = $path;
}
}
}
if ($request->request->has('heads')) {
//construct the ref_files array
$ref_files = [];
$path = "";
$file_path = "";
if ($request->files->has('ar_reference_file')) {
foreach ($request->files->get('ar_reference_file') as $uploadedFile) {
// $uploadedFile = $request->files['ar_reference_file_' . $request->request->get('ar_uid')[$key]];
$path = "";
if ($uploadedFile != null) {
$fileName = 'a' . md5(uniqid()) . '.' . $uploadedFile->guessExtension();
$path = $fileName;
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/ProjectDocs/' . $projectId . '/';
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$file = $uploadedFile->move($upl_dir, $path);
}
$file_list['ar_files'][] = $path;
}
}
}
$document_data_id = SalesOrderM::UpdateDocumentData($this->getDoctrine()->getManager(), $request->request->get('documentDataId'), $request->request, $file_list);
$projectBoqId = ProjectM::CreateNewBoq($this->getDoctrine()->getManager(), $projectId, $document_data_id, $request->request, $dochash, $file_list,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
// ── Persist BoQ billing-schedule edits to the project's sales-order
// schedule. The billing_schedule table is the source the milestone-billing
// cron, invoice generation and retention all read; the BoQ form posts the
// same billSchedule* fields as the SO form, so we reuse that exact path.
// Guarded: only runs when the BoQ actually carries schedule rows, so a
// routine BoQ save never wipes the SO's existing (non-invoiced) schedule.
$__boqStruct = (array) $request->request->get('billScheduleStructure', []);
$__hasSchedule = false;
foreach ($__boqStruct as $__s) { if ((int) $__s !== 0) { $__hasSchedule = true; break; } }
if ($__hasSchedule) {
$__projSos = $this->getDoctrine()->getManager()
->getRepository('ApplicationBundle\\Entity\\SalesOrder')
->findBy(['projectId' => $projectId], ['salesOrderId' => 'ASC']);
if (!empty($__projSos)) {
$__primarySo = $__projSos[0]; // EPC project → its (primary) sales order
$__bsMgr = new \ApplicationBundle\Modules\Sales\BillingScheduleManager($this->getDoctrine()->getManager());
$__bsMgr->saveSchedulesFromRequest(
\ApplicationBundle\Entity\BillingSchedule::OWNER_SALES_ORDER,
(int) $__primarySo->getSalesOrderId(),
null,
$request,
(int) $this->getLoggedUserCompanyId($request),
(int) $loginId
);
$__primarySo->setBillScheduleAmountType(
$request->request->get('billScheduleAmountType', $__primarySo->getBillScheduleAmountType())
);
$this->getDoctrine()->getManager()->flush();
}
}
$approveRole = $request->request->get('approvalRole'); //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectBoq']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$projectBoqId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$projectBoqId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'Bill of Quantity Created'
);
}
$url = $this->generateUrl(
'view_project_boq'
);
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
$marketing_user_ids=json_decode($proj_here->getMarketingUserIds(), true);
if($marketing_user_ids== null) {
$marketing_user_ids = [];
}
$design_user_ids=json_decode($proj_here->getMarketingUserIds(), true);
if($design_user_ids== null) {
$design_user_ids = [];
}
$marketing_user_ids[] = $request->getSession()->get(UserConstants::USER_ID);
$proj_here->setMarketingUserIds(json_encode($marketing_user_ids));
$this->getDoctrine()->getManager()->flush();
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),
"Bill of Quantity : " . $dochash . " Has Been Created For The Project:" . $proj_here->getProjectName() . " ",
'user',
array_merge(
$marketing_user_ids,
$design_user_ids
),
'information',
$url . "/" . $projectId,
"Bill of Quantity- " . $proj_here->getProjectName()
);
return $this->redirect($url . "/" . $projectId);
}
$projectList = [];
$projectData = [];
$materialData = [];
$boqData = [];
$message = "";
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
'projectStep' => array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectId == 0) {
} else {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData) {
$proposalData = $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
if (!$proposalData && $projectData->getProposalRequired() == 1) {
$url = $this->generateUrl(
'create_project_proposal'
);
$this->addFlash(
'error',
'Please Create Proposal for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
$boqData = $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
//now if its not editable, redirect to view
if (!$materialData && ($projectData->getBomRequired() == 1)) {
$url = $this->generateUrl(
'create_project_material'
);
$this->addFlash(
'error',
'Please Create Material Listings for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
if ($boqData) {
if ($boqData->getEditFlag() != 1) {
$url = $this->generateUrl(
'view_project_boq'
);
$this->addFlash(
'error',
'Sorry You cant Edit the document Right now.'
);
return $this->redirect($url . "/" . $projectId);
}
}
} else {
$this->addFlash(
'error',
'Sorry! Could not find your desired project data or this action is not allowed for your specific project at the moment..'
);
}
}
$companyId = $this->getLoggedUserCompanyId($request);
$productListArray = [];
$subCategoryListArray = [];
$categoryListArray = [];
$igListArray = [];
$unitListArray = [];
$productList = Inventory::ProductList($em, $companyId);
$subCategoryList = Inventory::ProductSubCategoryList($em, $companyId);
$categoryList = Inventory::ProductCategoryList($em, $companyId);
$igList = Inventory::ItemGroupList($em, $companyId);
$unitList = Inventory::UnitTypeList($em);
$currencyList = Inventory::CurrencyList($em);
$currencyListArray = [];
foreach ($productList as $product) {
$productListArray[] = $product;
}
foreach ($categoryList as $product) {
$categoryListArray[] = $product;
}
foreach ($subCategoryList as $product) {
$subCategoryListArray[] = $product;
}
foreach ($igList as $product) {
$igListArray[] = $product;
}
foreach ($unitList as $product) {
$unitListArray[] = $product;
}
$brandList = Inventory::GetBrandList($em, $companyId);
$brandListArray = [];
foreach ($brandList as $product) {
$brandListArray[] = $product;
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$sl = [];
$sl_array = [];
foreach ($qry as $product) {
$sl[$product->getServiceId()] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
$sl_array[] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
}
$hl = Accounts::HeadList($em);
$debug_data = $request->files->get('product_reference_file');
return $this->render('@Project/pages/input_forms/create_project_boq.html.twig',
array(
'page_title' => 'BOQ',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'userRestrictions' => Users::getUserApplicationAccessSettings($em, $request->getSession()->get(UserConstants::USER_ID))['options'],
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'sl' => $sl,
'productList' => $productList,
'subCategoryList' => $subCategoryList,
'categoryList' => $categoryList,
'currencyList' => $currencyList,
'currencyListArray' => $currencyListArray,
'igList' => $igList,
'unitList' => $unitList,
'brandList' => $brandList,
'brandListArray' => $brandListArray,
'productListArray' => $productListArray,
'subCategoryListArray' => $subCategoryListArray,
'categoryListArray' => $categoryListArray,
'igListArray' => $igListArray,
'unitListArray' => $unitListArray,
'hl' => $hl,
'projectList' => $projectList,
'projectData' => $projectData,
'materialData' => $materialData,
'extDocData' => $boqData,
'message' => $message,
'projectId' => $projectId,
'sl_array' => $sl_array,
'debug_data' => $debug_data,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function ViewProjectBoqAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$themeId = $request->get('themeId', 1);
$defaultColEnabled = array(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
);
$columnsEnabled = $request->get('columnsEnabled', $defaultColEnabled);
$config = $request->get('config', []);
if (is_string($columnsEnabled)) $columnsEnabled = json_decode($columnsEnabled, true);
if (is_string($config)) $config = json_decode($config, true);
if ($config == null) $config = [];
if ($columnsEnabled == null) $columnsEnabled = [];
$dt = ProjectM::GetBoqDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_boq'
);
// $this->addFlash(
// 'error',
// 'Please Create BOQ for the project 1st.'
// );
return $this->redirect($url . "/" . $id);
}
return $this->render('@Project/pages/views/view_project_boq.html.twig',
array(
'page_title' => 'View',
'data' => $dt,
'config' => $config,
'columnsEnabled' => $columnsEnabled,
'theme_id' => $themeId,
'auto_created' => $dt['auto_created'],
'userRestrictions' => Users::getUserApplicationAccessSettings($em, $request->getSession()->get(UserConstants::USER_ID))['options'],
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => $dt['auto_created'] == 0 ? System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$id,
$dt['created_by'],
$dt['edited_by']) : [],
'users' => Users::getUserListById($em)
)
);
}
public function PrintProjectBoqAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$themeId = $request->get('themeId', 1);
$defaultColEnabled = array(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
);
$columnsEnabled = $request->get('columnsEnabled', $defaultColEnabled);
if ($themeId == 2)
$columnsEnabled = array_diff($columnsEnabled, [6, 8, 10, 12, 15, 18]);
if ($request->get('printType', 'technical_proposal') == 'technical_proposal') {
}
$config = $request->get('config', []);
if (is_string($columnsEnabled)) $columnsEnabled = json_decode($columnsEnabled, true);
if (is_string($config)) $config = json_decode($config, true);
if ($config == null) $config = [];
if ($columnsEnabled == null) $columnsEnabled = [];
$dt = ProjectM::GetBoqDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_boq'
);
$this->addFlash(
'error',
'Please Create BOQ for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$company_data = Company::getCompanyData($em, 1);
$document_mark = array(
'original' => '/images/Original-Stamp-PNG-Picture.png',
'copy' => ''
);
if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
$html = $this->renderView('@Project/pages/print/print_project_boq.html.twig',
array(
//full array here
'pdf' => true,
'page_title' => 'Project BOM',
'export' => 'pdf,print',
'config' => $config,
'columnsEnabled' => $columnsEnabled,
'theme_id' => $themeId,
'data' => $dt,
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$id,
$dt['created_by'],
$dt['edited_by']),
'userRestrictions' => Users::getUserApplicationAccessSettings($em, $request->getSession()->get(UserConstants::USER_ID))['options'],
'document_mark_image' => $document_mark['original'],
'document_type' => 'Bill Of Quantity',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
$pdf_response = $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
// 'orientation' => 'landscape',
// 'enable-javascript' => true,
// 'javascript-delay' => 1000,
'no-stop-slow-scripts' => false,
'no-background' => false,
'lowquality' => false,
'encoding' => 'utf-8',
// 'images' => true,
// 'cookie' => array(),
'dpi' => 300,
'image-dpi' => 300,
// 'enable-external-links' => true,
// 'enable-internal-links' => true
));
return new Response(
$pdf_response,
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="boq.pdf"'
)
);
}
return $this->render('@Project/pages/print/print_project_boq.html.twig',
array(
'page_title' => 'Project BOQ',
'export' => 'pdf,print',
'config' => $config,
'columnsEnabled' => $columnsEnabled,
'theme_id' => $themeId,
'data' => $dt,
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
$id,
$dt['created_by'],
$dt['edited_by']),
'userRestrictions' => Users::getUserApplicationAccessSettings($em, $request->getSession()->get(UserConstants::USER_ID))['options'],
'document_mark_image' => $document_mark['original'],
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
}
public function ViewProjectCostingReportAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
if ($id == 0) {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
// 'projectId'=>$projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'projectStep' => [3, 4, 5, 6], ///material
// 'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
// 'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData)
$id = $projectData->getProjectId();
}
$dt = ProjectM::GetProjectCostingDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_boq'
);
$this->addFlash(
'error',
'Please Create BOQ for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
'projectStep' => [3, 4, 5, 6]
), array('projectDate' => 'desc')
);
// dump($dt);
return $this->render('@Project/pages/report/project_costing_report.html.twig',
array(
'page_title' => 'View',
'data' => $dt,
'projectList' => $projectList,
'projectId' => $id,
'auto_created' => $dt['auto_created'],
'users' => Users::getUserListById($em)
)
);
}
public function PrintProjectCostingReportAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
if ($id == 0) {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
// 'projectId'=>$projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'projectStep' => [3, 4, 5, 6], ///material
// 'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
// 'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData)
$id = $projectData->getProjectId();
}
$dt = ProjectM::GetProjectCostingDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_boq'
);
$this->addFlash(
'error',
'Please Create BOQ for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
'projectStep' => [3, 4, 5, 6]
), array('projectDate' => 'desc')
);
$company_data = Company::getCompanyData($em, 1);
$document_mark = array(
'original' => '/images/Original-Stamp-PNG-Picture.png',
'copy' => ''
);
if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
$html = $this->renderView('@Project/pages/report/project_costing_report_print.html.twig',
array(
//full array here
'pdf' => true,
'page_title' => 'Project Costing',
'export' => 'pdf,print',
'data' => $dt,
'projectList' => $projectList,
'projectId' => $id,
'auto_created' => $dt['auto_created'],
'users' => Users::getUserListById($em),
'document_mark_image' => $document_mark['original'],
'document_type' => 'Project Costing',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'general_footer' => $company_data->getGeneralFooter(),
'red' => 0
)
);
$pdf_response = $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
// 'orientation' => 'landscape',
// 'enable-javascript' => true,
// 'javascript-delay' => 1000,
'no-stop-slow-scripts' => false,
'no-background' => false,
'lowquality' => false,
'encoding' => 'utf-8',
// 'images' => true,
// 'cookie' => array(),
'dpi' => 300,
'image-dpi' => 300,
// 'enable-external-links' => true,
// 'enable-internal-links' => true
));
return new Response(
$pdf_response,
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="project_costing.pdf"'
)
);
}
return $this->render('@Project/pages/report/project_costing_report_print.html.twig',
array(
'page_title' => 'Project Costing',
'export' => 'pdf,print',
'data' => $dt,
'projectList' => $projectList,
'projectId' => $id,
'auto_created' => $dt['auto_created'],
'users' => Users::getUserListById($em),
'document_mark_image' => $document_mark['original'],
'document_type' => 'Project Costing',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'general_footer' => $company_data->getGeneralFooter(),
'red' => 0
)
);
}
public function CreateProjectWpAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$em = $this->getDoctrine()->getManager();
$entity_id = array_flip(GeneralConstant::$Entity_list)['ProjectWp']; //change
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
$dochash = "WP/" . $proj_here->getProjectCategoryId() . "/" . $proj_here->getClientId() . "/" . $projectId; //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash(
'error',
'Sorry Could not insert Data.'
);
} else {
//construct the files
$file_list = array(
'product_files' => [],
'service_files' => [],
'ar_files' => [],
);
$projectWpId = ProjectM::CreateNewWp($this->getDoctrine()->getManager(), $projectId, $request->request, $dochash, $file_list,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole'); //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectWp']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$projectWpId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$projectWpId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'Work Plan Created'
);
}
$url = $this->generateUrl(
'view_project_wp'
);
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
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),
"Work Schedule : " . $dochash . " Has Been Created For The Project:" . $proj_here->getProjectName() . " ",
'user',
array_merge(
json_decode($proj_here->getImplementingUserIds(), true),
json_decode($proj_here->getDesigningUserIds(), true)
),
'information',
$url . "/" . $projectId,
"Work Schedule - " . $proj_here->getProjectName()
);
return $this->redirect($url . "/" . $projectId);
}
$projectList = [];
$projectData = [];
$materialData = [];
$boqData = [];
$wpData = [];
$message = "";
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['WORK PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectId == 0) {
} else {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData) {
// $proposalData=$em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
// array(
// 'projectId'=>$projectId, ///material
// 'approved'=>GeneralConstant::APPROVED
//
// )
// );
// if(!$proposalData && $projectData->getProposalRequired()==1) {
// $url = $this->generateUrl(
// 'create_project_proposal'
// );
// $this->addFlash(
// 'error',
// 'Please Create Proposal for the project 1st.'
// );
// return $this->redirect($url . "/" . $projectId);
// }
// $materialData=$em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
// array(
// 'projectId'=>$projectId, ///material
// 'approved'=>GeneralConstant::APPROVED
//
// )
// );
// $boqData=$em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
// array(
// 'projectId'=>$projectId, ///material
// 'approved'=>GeneralConstant::APPROVED
//
// )
// );
// $wpData=$em->getRepository('ApplicationBundle\\Entity\\ProjectWp')->findOneBy(
// array(
// 'projectId'=>$projectId, ///material
//
// )
// );
//
// //now if its not editable, redirect to view
// if(!$materialData &&( $projectData->getBomRequired()==1)) {
// $url = $this->generateUrl(
// 'create_project_material'
// );
// $this->addFlash(
// 'error',
// 'Please Create Material Listings for the project 1st.'
// );
// return $this->redirect($url . "/" . $projectId);
// }
// if(!$boqData &&( $projectData->getBoqRequired()==1)) {
// $url = $this->generateUrl(
// 'create_project_boq'
// );
// $this->addFlash(
// 'error',
// 'Please Create Bill of Quantity for the project 1st.'
// );
// return $this->redirect($url . "/" . $projectId);
// }
// if($wpData) {
// if ($wpData->getEditFlag() != 1) {
// $url = $this->generateUrl(
// 'view_project_wp'
// );
// $this->addFlash(
// 'error',
// 'Sorry You cant Edit the document Right now.'
// );
// return $this->redirect($url . "/" . $projectId);
// }
//
// }
} else {
$this->addFlash(
'error',
'Sorry! Could not find your desired project data or this action is not allowed for your specific project at the moment..'
);
}
}
// Default = the cp-shell Task List (Task Management module). The legacy
// codecovers template is opt-in via ?old_theme=1 (?shell=cp still works
// and is now the implicit default).
$wpTemplate = ($request->query->get('old_theme') == 1)
? '@Project/pages/input_forms/create_project_wp.html.twig'
: '@TaskManagement/pages/task_list.html.twig';
return $this->render($wpTemplate,
array(
'page_title' => 'Work Plan',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'projectList' => $projectList,
'projectData' => $projectData,
'materialData' => $materialData,
'boqData' => $boqData,
'wpData' => $wpData,
'message' => $message,
'projectId' => $projectId,
// Admins (user type 1) may backfill actual start/end dates on tasks
// — e.g. for projects that ran before the work plan was created.
'canEditActual' => ((int) $request->getSession()->get(UserConstants::USER_TYPE) === 1),
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function TaskCalendarAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['WORK PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
return $this->render('@Project/pages/input_forms/task_calendar.html.twig',
array(
'page_title' => 'Work Plan',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'projectList' => $projectList,
'projectId' => $projectId,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function ViewProjectWpAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetWpDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_wp'
);
$this->addFlash(
'error',
'Please Create Work Plan for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
return $this->render('@Project/pages/views/view_project_wp.html.twig',
array(
'page_title' => 'Work Plan',
'data' => $dt,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'auto_created' => $dt['auto_created'],
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => $dt['auto_created'] == 0 ? System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$id,
$dt['created_by'],
$dt['edited_by']) : [],
'users' => Users::getUserListById($em),
'ganttTasks' => ProjectM::GetProjectGanttData($em, $id, false)
)
);
}
public function PrintProjectWpAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetWpDetails($em, $id);
if (!$dt) {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
['projectId' => $id]
);
if (!$projectData) {
$this->addFlash(
'error',
'Sorry! Could not find work plan or project data for printing.'
);
return $this->redirect($this->generateUrl('create_project_wp'));
}
$clientData = [
'clientName' => '',
'addressContact' => '',
'contactNumber' => '',
];
if (method_exists($projectData, 'getClientId') && $projectData->getClientId()) {
$foundClient = $em->getRepository('ApplicationBundle\\Entity\\AccClients')->findOneBy(
['clientId' => $projectData->getClientId()]
);
if ($foundClient) {
$clientData = $foundClient;
}
}
$dt = [
'project_data' => $projectData,
'client_data' => $clientData,
'general_data' => [
'documentHash' => method_exists($projectData, 'getDocumentHash') ? $projectData->getDocumentHash() : '',
'createdAt' => method_exists($projectData, 'getProjectDate') && $projectData->getProjectDate() ? $projectData->getProjectDate() : new \DateTime(),
'lastModifiedDate' => method_exists($projectData, 'getLastModifiedDate') ? $projectData->getLastModifiedDate() : null,
'projectWpDate' => method_exists($projectData, 'getProjectDate') && $projectData->getProjectDate() ? $projectData->getProjectDate() : new \DateTime(),
'approved' => 0,
'data' => json_encode([[
'workStages' => [
'workStage' => [],
'assignType' => [],
'start_date' => [],
'end_date' => [],
'days' => [],
'remarks' => [],
]
]]),
'autoCreated' => 0,
'createdAt' => method_exists($projectData, 'getProjectDate') && $projectData->getProjectDate() ? $projectData->getProjectDate() : new \DateTime(),
],
'authorizations' => [],
'created_by' => 0,
'edited_by' => 0,
'updated_at' => null,
'created_at' => null,
'doc_hash' => method_exists($projectData, 'getDocumentHash') ? $projectData->getDocumentHash() : '',
'projectId' => $id,
'auto_created' => 0
];
$this->addFlash(
'warning',
'No saved work plan was found yet. Printing the project shell with empty timeline and task list.'
);
}
$company_data = Company::getCompanyData($em, 1);
$document_mark = array(
'original' => '/images/Original-Stamp-PNG-Picture.png',
'copy' => ''
);
if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
$html = $this->renderView('@Project/pages/print/print_project_wp.html.twig',
array(
//full array here
'pdf' => true,
'page_title' => 'Project BOM',
'export' => 'pdf,print',
'data' => $dt,
'ganttTasks' => ProjectM::GetProjectGanttData($em, $id, false),
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'document_type' => 'Bill Of Quantity',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
$pdf_response = $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
// 'orientation' => 'landscape',
// 'enable-javascript' => true,
// 'javascript-delay' => 1000,
'no-stop-slow-scripts' => false,
'no-background' => false,
'lowquality' => false,
'encoding' => 'utf-8',
// 'images' => true,
// 'cookie' => array(),
'dpi' => 300,
'image-dpi' => 300,
// 'enable-external-links' => true,
// 'enable-internal-links' => true
));
return new Response(
$pdf_response,
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="wp.pdf"'
)
);
}
return $this->render('@Project/pages/print/print_project_wp.html.twig',
array(
'page_title' => 'Project WP',
'export' => 'pdf,print',
'data' => $dt,
'ganttTasks' => ProjectM::GetProjectGanttData($em, $id, false),
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectWp'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
}
public function GetProjectDataForSoAction(Request $request, $id = 0)
{
$em = $this->getDoctrine()->getManager();
$Content = [];
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $id, ///material
'projectStep' => array_flip(ProjectConstant::$projectSteps)['SALES ORDER'],
), array('projectDate' => 'desc')
);
if ($projectData) {
if ($projectData->getOfferRequired() == 1) {
$docData = $em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findOneBy(
array(
'projectId' => $id, ///material
)
);
$Content = array(
'data' => json_decode($docData->getData(), true)[0]
);
} else if ($projectData->getBoqRequired() == 1) {
$docData = $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
array(
'projectId' => $id, ///material
)
);
$boqData = json_decode($docData->getData(), true)[0];
$Content = array(
'data' => array(
'boqData' => $boqData,
'check_override_markup' => 0,
'boqSalesValue' => isset($boqData['salesValue']) ? $boqData['salesValue'] : 0,
'totalCost' => isset($boqData['totalCost']) ? $boqData['totalCost'] : 0,
'offerSalesValue' => 0
)
);
}
}
if (!$docData)
return new JsonResponse(array("success" => false, "content" => $Content));;
if ($Content) {
// $Content=$engine->render('@Sales/pages/report/selected_client_details_for_so.html.twig', array("cd"=>$CD));
return new JsonResponse(array("success" => true, "content" => $Content));
}
return new JsonResponse(array("success" => false));
}
public function CreateProjectOfferAction(Request $request, $projectId = 0)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$em = $this->getDoctrine()->getManager();
$entity_id = array_flip(GeneralConstant::$Entity_list)['ProjectOffer']; //change
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
), array('projectDate' => 'desc')
);
// $client=$em->getRepository('ApplicationBundle\\Entity\\AccClients')->findOneBy(
// array(
// 'clientId'=>$projectData->getClientId(), ///material
//
// ),array('projectDate'=>'desc')
// );
$dochash = "OL/" . $projectData->getProjectCategoryId() . "/" . $projectData->getClientId() . "/" . $projectId; //change
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole');
$approveHash = $request->request->get('approvalHash');
if (!DocValidation::isInsertable($em, $entity_id, $dochash,
$loginId, $approveRole, $approveHash, $projectId)) {
$this->addFlash(
'error',
'Sorry Couldnot insert Data.'
);
} else {
//construct the files
$file_list = array(
'product_files' => [],
'service_files' => [],
'ar_files' => [],
);
$projectWpId = ProjectM::CreateNewOffer($this->getDoctrine()->getManager(), $projectId, $request->request, $dochash,
$request->getSession()->get(UserConstants::USER_LOGIN_ID),
$this->getLoggedUserCompanyId($request));
//now add Approval info
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$approveRole = $request->request->get('approvalRole'); //created
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'url' => $this->generateUrl(
GeneralConstant::$Entity_list_details[array_flip(GeneralConstant::$Entity_list)['ProjectOffer']]
['entity_view_route_path_name']
)
);
System::setApprovalInfo($this->getDoctrine()->getManager(), $options,
array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$projectWpId,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
System::createEditSignatureHash($this->getDoctrine()->getManager(), array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$projectWpId,
$loginId,
$approveRole,
$request->request->get('approvalHash'));
$this->addFlash(
'success',
'Project Offer Created'
);
}
$url = $this->generateUrl(
'view_project_offer'
);
$proj_here = $this->getDoctrine()
->getRepository('ApplicationBundle\\Entity\\Project')
->findOneBy(
array(
'projectId' => $projectId
)
);
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),
"Offer Letter : " . $dochash . " Has Been Created For The Project:" . $proj_here->getProjectName() . " ",
'user',
array_merge(
json_decode($proj_here->getMarketingUserIds(), true),
json_decode($proj_here->getBillingUserIds(), true),
json_decode($proj_here->getDesigningUserIds(), true)
),
'information',
$url . "/" . $projectId,
"Offer Letter- " . $proj_here->getProjectName()
);
return $this->redirect($url . "/" . $projectId);
}
$projectList = [];
$projectData = [];
$materialData = [];
$boqData = [];
$wpData = [];
$offerData = [];
$message = "";
$projectList = $em->getRepository('ApplicationBundle\\Entity\\Project')->findBy(
array(
'projectStep' => array_flip(ProjectConstant::$projectSteps)['NEGOTIATION'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectId == 0) {
} else {
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array(
'projectId' => $projectId, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['BILL OF QUANTITY PLAN'], ///material
'stage' => array_flip(ProjectConstant::$projectStages)['INITIATED'],
'status' => array_flip(ProjectConstant::$projectStatus)['PROCESSING']
), array('projectDate' => 'desc')
);
if ($projectData) {
$materialData = $em->getRepository('ApplicationBundle\\Entity\\ProjectMaterial')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
$proposalData = $em->getRepository('ApplicationBundle\\Entity\\ProjectProposal')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
if (!$proposalData && $projectData->getProposalRequired() == 1) {
$url = $this->generateUrl(
'create_project_proposal'
);
$this->addFlash(
'error',
'Please Create Proposal for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
$boqData = $em->getRepository('ApplicationBundle\\Entity\\ProjectBoq')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
$wpData = $em->getRepository('ApplicationBundle\\Entity\\ProjectWp')->findOneBy(
array(
'projectId' => $projectId, ///material
'approved' => GeneralConstant::APPROVED
)
);
$offerData = $em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findOneBy(
array(
'projectId' => $projectId, ///material
)
);
//now if its not editable, redirect to view
if (!$materialData && ($projectData->getBomRequired() == 1)) {
$url = $this->generateUrl(
'create_project_material'
);
$this->addFlash(
'error',
'Please Create Material Listings for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
if (!$boqData && ($projectData->getBoqRequired() == 1)) {
$url = $this->generateUrl(
'create_project_boq'
);
$this->addFlash(
'error',
'Please Create Bill of Quantity for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
if (!$wpData && ($projectData->getWpRequired() == 1)) {
$url = $this->generateUrl(
'create_project_wp'
);
$this->addFlash(
'error',
'Please Create Work Plan for the project 1st.'
);
return $this->redirect($url . "/" . $projectId);
}
if ($offerData) {
if ($offerData->getEditFlag() != 1) {
$url = $this->generateUrl(
'view_project_offer'
);
$this->addFlash(
'error',
'Sorry You cant Edit the document Right now.'
);
return $this->redirect($url . "/" . $projectId);
}
}
} else {
$this->addFlash(
'error',
'Sorry! Could not find your desired project data or this action is not allowed for your specific project at the moment..'
);
}
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\InvProducts")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
'type' => 1//trade items
));
$pl = [];
$pl_array = [];
foreach ($qry as $product) {
$pl[$product->getId()] = array(
'text' => $product->getName(),
'name' => $product->getName(),
'id' => $product->getId(),
'value' => $product->getId(),
'purchase_price' => $product->getPurchasePrice(),
'sales_price' => $product->getSalesPrice(),
'supplier_id' => $product->getBrandCompany(),
);
$pl_array[] = array(
'text' => $product->getName(),
'value' => $product->getId(),
'name' => $product->getName(),
'id' => $product->getId(),
'purchase_price' => $product->getPurchasePrice(),
'sales_price' => $product->getSalesPrice(),
'supplier_id' => $product->getBrandCompany(),
);
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\AccService")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$sl = [];
$sl_array = [];
foreach ($qry as $product) {
$sl[$product->getServiceId()] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
$sl_array[] = array(
'text' => $product->getServiceName(),
'value' => $product->getServiceId(),
'name' => $product->getServiceName(),
'id' => $product->getServiceId(),
);
}
$qry = $em->getRepository("ApplicationBundle\\Entity\\ProjectWorkStage")->findBy(array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
// 'type'=>1//trade items
));
$workStages = [];
$workStages_array = [];
foreach ($qry as $product) {
$workStages[$product->getProjectWorkStageId()] = array(
'text' => $product->getStageName(),
'value' => $product->getProjectWorkStageId(),
'name' => $product->getStageName(),
'id' => $product->getProjectWorkStageId(),
);
$workStages_array[] = array(
'text' => $product->getStageName(),
'value' => $product->getProjectWorkStageId(),
'name' => $product->getStageName(),
'id' => $product->getProjectWorkStageId(),
);
}
$hl = Accounts::HeadList($em);
$debug_data = $request->files->get('product_reference_file');
return $this->render('@Project/pages/input_forms/create_project_offer.html.twig',
array(
'page_title' => 'Offer Letter',
// 'clients'=>SalesOrderM::GetClientList($em),
// 'clients_by_ac_head'=>SalesOrderM::GetClientListByAcHead($em),
'users' => Users::getUserListById($em),
'stages' => ProjectConstant::$projectStages,
'sl' => $sl,
'pl' => $pl,
'hl' => $hl,
'workStages' => $workStages,
'projectList' => $projectList,
'projectData' => $projectData,
'materialData' => $materialData,
'boqData' => $boqData,
'wpData' => $wpData,
'offerData' => $offerData,
'message' => $message,
'projectId' => $projectId,
'pl_array' => $pl_array,
'sl_array' => $sl_array,
'workStages_array' => $workStages_array,
'debug_data' => $debug_data,
// 'product_list_obj'=>Inventory::ProductList($this->getDoctrine()->getManager(),$this->getLoggedUserCompanyId($request))
)
);
}
public function ViewProjectOfferAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetOfferDetails($em, $id);
///
// $projectData=$em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
// array(
// 'projectId'=>$id, ///material
// 'projectStep'=>array_flip(ProjectConstant::$projectSteps)['NEGOTIATION'], ///material
//// 'stage'=>array_flip(ProjectConstant::$projectStages)['INITIATED'],
//// 'status'=>array_flip(ProjectConstant::$projectStatus)['PROCESSING']
// ),array('projectDate'=>'desc')
// );
// $offerDataList=$em->getRepository('ApplicationBundle\\Entity\\ProjectOffer')->findBy(
// array(
// 'approved'=>1, ///material
//
// )
// );
// if(!empty($offerDataList)) {
// foreach ($offerDataList as $offerData) {
// $all_det_data = json_decode($offerData->getData(), true);
// $entry = $all_det_data[0];
// $store_items = $entry['boqData']['Products'];
// ProjectM::addProductsByFdm($em, $store_items['product_fdm'], $offerData->getCompanyId());
//
// }
// }
///////
if (!$dt) {
$url = $this->generateUrl(
'create_project_offer'
);
$this->addFlash(
'error',
'Please Create Offer for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$stage_list = ProjectConstant::$projectStages;
$status_list = ProjectConstant::$projectStatus;
$steps_list = ProjectConstant::$projectSteps;
return $this->render('@Project/pages/views/view_project_offer.html.twig',
array(
'page_title' => 'Offer Letter',
'data' => $dt,
// 'boqData'=>ProjectM::GetBoqDetails($em,$id),
// 'wpData'=>ProjectM::GetWpDetails($em,$id),
'clientList' => SalesOrderM::GetClientList($em),
'stageList' => $stage_list,
'statusList' => $status_list,
'stepsList' => $steps_list,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'auto_created' => $dt['auto_created'],
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => $dt['auto_created'] == 0 ? System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$id,
$dt['created_by'],
$dt['edited_by']) : [],
'users' => Users::getUserListById($em)
)
);
}
public function PrintProjectOfferAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$dt = ProjectM::GetOfferDetails($em, $id);
if (!$dt) {
$url = $this->generateUrl(
'create_project_offer'
);
$this->addFlash(
'error',
'Please Create Offer for the project 1st.'
);
return $this->redirect($url . "/" . $id);
}
$company_data = Company::getCompanyData($em, 1);
$document_mark = array(
'original' => '/images/Original-Stamp-PNG-Picture.png',
'copy' => ''
);
if ($request->query->has('pdf') && $this->get('knp_snappy.pdf')) {
$html = $this->renderView('@Project/pages/print/print_project_offer.html.twig',
array(
//full array here
'pdf' => true,
'page_title' => 'Offer Letter',
'export' => 'pdf,print',
'data' => $dt,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'document_type' => 'Offer Letter',
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
$pdf_response = $this->get('knp_snappy.pdf')->getOutputFromHtml($html, array(
// 'orientation' => 'landscape',
// 'enable-javascript' => true,
// 'javascript-delay' => 1000,
'no-stop-slow-scripts' => false,
'no-background' => false,
'lowquality' => false,
'encoding' => 'utf-8',
// 'images' => true,
// 'cookie' => array(),
'dpi' => 300,
'image-dpi' => 300,
// 'enable-external-links' => true,
// 'enable-internal-links' => true
));
return new Response(
$pdf_response,
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="offer.pdf"'
)
);
}
return $this->render('@Project/pages/print/print_project_offer.html.twig',
array(
'page_title' => 'Project Offer Letter',
'export' => 'pdf,print',
'data' => $dt,
'stage_list' => ProjectM::GetWorkStageList($em, $this->getLoggedUserCompanyId($request)),
'approval_data' => System::checkIfApprovalExists($em, array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$id, $request->getSession()->get(UserConstants::USER_LOGIN_ID)),
'document_log' => System::getDocumentLog($this->getDoctrine()->getManager(),
array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
$id,
$dt['created_by'],
$dt['edited_by']),
'document_mark_image' => $document_mark['original'],
'company_name' => $company_data->getName(),
'company_address' => $company_data->getAddress(),
'company_image' => $company_data->getImage(),
'invoice_footer' => $company_data->getInvoiceFooter(),
'red' => 0
)
);
}
public function ProjectListAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$stage_list = ProjectConstant::$projectStages;
$status_list = ProjectConstant::$projectStatus;
$steps_list = ProjectConstant::$projectSteps;
return $this->render('@Project/pages/listing/project_list.html.twig',
array(
'page_title' => 'Project List',
'data' => ProjectM::GetProjectList($em),
'sales_person_list' => Client::SalesPersonList($this->getDoctrine()->getManager()),
'clientList' => SalesOrderM::GetClientList($em),
'stageList' => $stage_list,
'statusList' => $status_list,
'stepsList' => $steps_list,
'stepsListRoutes' => ProjectConstant::$projectStepsRoutes
)
);
}
public function NewProjectCategoryAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
// Check if store already exists.
// if(Service::CheckIfServiceExists($this->getDoctrine()->getManager(), $request->request->get('service_name'))){
// $this->addFlash(
// 'error',
// 'Service already exists'
// );
//
// return $this->redirectToRoute("create_service");
// }
ProjectM::CreateNewCategory(
$this->getDoctrine()->getManager(),
$this->getLoggedUserCompanyId($request),
$request->request,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
$this->addFlash(
'success',
'New Category Have Been Added'
);
return $this->redirectToRoute("create_project_category");
}
return $this->render('@Project/pages/input_forms/create_project_category.html.twig',
array(
'page_title' => 'Project Category',
'categories' => $em->getRepository('ApplicationBundle\\Entity\\ProjectCategory')->findBy(
array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
)
),
)
);
}
public function NewProjectWorkStageAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
// Check if store already exists.
// if(Service::CheckIfServiceExists($this->getDoctrine()->getManager(), $request->request->get('service_name'))){
// $this->addFlash(
// 'error',
// 'Service already exists'
// );
//
// return $this->redirectToRoute("create_service");
// }
ProjectM::CreateNewWorkStage(
$this->getDoctrine()->getManager(),
$this->getLoggedUserCompanyId($request),
$request->request,
$request->getSession()->get(UserConstants::USER_LOGIN_ID)
);
$this->addFlash(
'success',
'New Stage Have Been Added'
);
return $this->redirectToRoute("create_project_work_stage");
}
return $this->render('@Project/pages/input_forms/create_project_work_stage.html.twig',
array(
'page_title' => 'Project Work Stages',
'stages' => $em->getRepository('ApplicationBundle\\Entity\\ProjectWorkStage')->findBy(
array(
"status" => GeneralConstant::ACTIVE,
'CompanyId' => $this->getLoggedUserCompanyId($request),
)
),
)
);
}
public function storeWorkPlanAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
$session = $request->getSession();
$dependenciesArray = [];
$dependencies = array(
'id' => $request->get('dependencyPlanId'),
'enabled' => $request->get('dependencyEnabled', 1),
'dependencyMode' => $request->get('dependencyMode'),
'dependencyLagDays' => $request->get('dependencyLagDays'),
'dependencyCompletionRequired' => $request->get('dependencyCompletionRequired')
);
if ($request->isMethod('POST')) {
if (1) {
$stmt = $em->getConnection()->fetchAllAssociative("select `id` , parent_id, sequence from planning_item where sequence is null
ORDER BY parent_id ASC, id ASC
");
$query_output = $stmt;
foreach ($query_output as $dupe) {
System::updatePlanningItemSequence($em, $dupe["id"]);
}
}
$loginId = $request->getSession()->get(UserConstants::USER_LOGIN_ID);
$plannigItem = new PlanningItem;
$taskContextType = $request->request->get('taskContextType', $request->request->get('projectSelector', 0) ? 'project' : 'general');
$plannigItem->setProjectId($taskContextType === 'general' ? null : $request->request->get('projectSelector', 0));
$plannigItem->setItemAlias($request->request->get('planning_task_title'));
$plannigItem->setParentId($request->request->get('planning_parent_task_selector', 0));
$plannigItem->setEntryType($request->request->get('planning_task_type'));
$plannigItem->setAssignedTo($request->request->get('planning_task_assigned_to', $session->get(UserConstants::USER_EMPLOYEE_ID)));
$plannigItem->setReviewerId($request->request->get('planning_task_reviewer', 0));
$plannigItem->setEstimatedStartTimeTs($request->request->get('planning_task_start'));
$plannigItem->setEstimatedCompletionTimeTs($request->request->get('planning_task_end'));
$plannigItem->setUrgency($request->request->get('planning_task_priority'));
$plannigItem->setProjectedCost($request->request->get('planning_task_projected_cost'));
$plannigItem->setDependencyPlanningData(json_encode($dependencies));
$plannigItem->setReferenceType($request->request->get('referenceType', 1));
$plannigItem->setDescription($request->request->get('planning_task_note'));
$plannigItem->setTaskContextType($taskContextType);
$plannigItem->setExpectedOutput($request->request->get('expectedOutput', ''));
$plannigItem->setTaggedDocType($request->request->get('taggedDocType', array_flip(GeneralConstant::$Entity_list)['Project']));
$plannigItem->setTaggedDocId($request->request->get('taggedDocId', $request->request->get('projectSelector', 0)));
$plannigItem->setCurrentState('created');
$plannigItem->setReviewStatus('draft');
$plannigItem->setKpiCounted(0);
$plannigItem->setBlockerSummary($request->request->get('blockerSummary', ''));
$plannigItem->setNextAction($request->request->get('nextAction', ''));
$plannigItem->setProjectedCost($request->request->get('projected_cost', 0));
$plannigItem->setActualCost($request->request->get('actual_cost', 0));
$plannigItem->setCompanyId($companyId);
$plannigItem->setCreatedLoginId($request->getSession()->get(UserConstants::USER_LOGIN_ID));
$em->persist($plannigItem);
$em->flush();
if (1) {
$stmt = $em->getConnection()->fetchAllAssociative('select distinct parent_id from planning_item where parent_id is not null and parent_id <> 0;');
$get_kids = $stmt;
$p_ids = [];
foreach ($get_kids as $g) {
if (!isset($g['parent_id'])) {
continue;
}
$parentId = (int) $g['parent_id'];
if ($parentId > 0) {
$p_ids[] = $parentId;
}
}
$p_ids = array_values(array_unique($p_ids));
if (empty($p_ids)) {
$em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0');
} else {
$idList = implode(',', $p_ids);
$em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0 WHERE id NOT IN (' . $idList . ')');
$em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 1 WHERE id IN (' . $idList . ')');
}
$updatedData = System::updatePlanningItemSequence($em, $plannigItem->getId());
$theEntity = $updatedData['primaryOne'];
$theEntityUpdated = $theEntity;
if ($theEntityUpdated->getEntryType() == 4)///cashflow
{
MiscActions::AddCashFlowProjection($em, 0, [
'planningItemId' => $theEntityUpdated->getId(),
'fundRequisitionId' => 0,
'concernedPersonId' => 0,
'type' => 1, //exp
'subType' => 1, //1== khoroch hobe 2: ashbe
'cashFlowType' => 1, //2== RCV /in 1: Payment/out
'creationType' => 1, //auto
'amountType' => 1, //fund
'cashFlowAmount' => 0,
'expAstAmount' => 0,
'accumulatedCashFlowAmount' => 0,
'accumulatedCashFlowBalance' => 0,
'accumulatedExpAstAmount' => 0,
'relevantExpAstHeadId' => 0,
'balancingHeadId' => 0,
'cashFlowHeadId' => 0,
'cashFlowHeadType' => 1,
'relevantProductIds' => [],
'reminderDateTs' => 0,
'cashFlowDateTs' => 0,
'expAstRealizationDateTs' => 0,
]);
}
}
}
return new JsonResponse(array(
"success" => 'true',
));
}
public function updateWorkPlanAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$session = $request->getSession();
$planningItem = $em->getRepository("ApplicationBundle\\Entity\\PlanningItem")->find($id);
if (!$planningItem) {
return new JsonResponse(['success' => false, 'message' => 'Work plan not found']);
}
if ($request->isMethod('POST')) {
$dependencies = [
'id' => $request->request->get('dependencyPlanId'),
'enabled' => $request->request->get('dependencyEnabled', 1),
'dependencyMode' => $request->request->get('dependencyMode'),
'dependencyLagDays' => $request->request->get('dependencyLagDays'),
'dependencyCompletionRequired' => $request->request->get('dependencyCompletionRequired'),
];
$taskContextType = $request->request->get('taskContextType', $planningItem->getTaskContextType() ?: ($request->request->get('projectSelector', 0) ? 'project' : 'general'));
$planningItem->setProjectId($taskContextType === 'general' ? null : $request->request->get('projectSelector', 0));
$planningItem->setItemAlias($request->request->get('planning_task_title'));
$planningItem->setParentId($request->request->get('planning_parent_task_selector', 0));
$planningItem->setEntryType($request->request->get('planning_task_type'));
$planningItem->setAssignedTo($request->request->get('planning_task_assigned_to', $session->get(UserConstants::USER_EMPLOYEE_ID)));
$planningItem->setReviewerId($request->request->get('planning_task_reviewer', $planningItem->getReviewerId() ?: 0));
$planningItem->setEstimatedStartTimeTs($request->request->get('planning_task_start'));
$planningItem->setEstimatedCompletionTimeTs($request->request->get('planning_task_end'));
$planningItem->setUrgency($request->request->get('planning_task_priority'));
$planningItem->setProjectedCost($request->request->get('projected_cost', 0));
$planningItem->setActualCost($request->request->get('actual_cost', 0));
$planningItem->setDependencyPlanningData(json_encode($dependencies));
$planningItem->setReferenceType($request->request->get('referenceType', 1));
$planningItem->setDescription($request->request->get('planning_task_note'));
$planningItem->setTaskContextType($taskContextType);
if ($request->request->has('expectedOutput')) {
$planningItem->setExpectedOutput($request->request->get('expectedOutput', ''));
}
$planningItem->setTaggedDocType($request->request->get('taggedDocType', $planningItem->getTaggedDocType() ?: array_flip(GeneralConstant::$Entity_list)['Project']));
$planningItem->setTaggedDocId($request->request->get('taggedDocId', $request->request->get('projectSelector', $planningItem->getProjectId())));
if ($planningItem->getCurrentState() === null) {
$planningItem->setCurrentState('created');
}
if ($planningItem->getReviewStatus() === null) {
$planningItem->setReviewStatus('draft');
}
if ($request->request->has('blockerSummary')) {
$planningItem->setBlockerSummary($request->request->get('blockerSummary', ''));
}
if ($request->request->has('nextAction')) {
$planningItem->setNextAction($request->request->get('nextAction', ''));
}
$em->flush();
if (1) {
$stmt = $em->getConnection()->fetchAllAssociative('select distinct parent_id from planning_item where parent_id is not null and parent_id <> 0;');
$get_kids = $stmt;
$p_ids = [];
foreach ($get_kids as $g) {
if (!isset($g['parent_id'])) {
continue;
}
$parentId = (int) $g['parent_id'];
if ($parentId > 0) {
$p_ids[] = $parentId;
}
}
$p_ids = array_values(array_unique($p_ids));
if (empty($p_ids)) {
$em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0');
} else {
$idList = implode(',', $p_ids);
$em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 0 WHERE id NOT IN (' . $idList . ')');
$em->getConnection()->executeStatement('UPDATE planning_item SET has_child = 1 WHERE id IN (' . $idList . ')');
}
$updatedData = System::updatePlanningItemSequence($em, $planningItem->getId());
$theEntity = $updatedData['primaryOne'];
$theEntityUpdated = $theEntity;
if ($theEntityUpdated->getEntryType() == 4)///cashflow
{
MiscActions::AddCashFlowProjection($em, 0, [
'planningItemId' => $theEntityUpdated->getId(),
'fundRequisitionId' => 0,
'concernedPersonId' => 0,
'type' => 1, //exp
'subType' => 1, //1== khoroch hobe 2: ashbe
'cashFlowType' => 1, //2== RCV /in 1: Payment/out
'creationType' => 1, //auto
'amountType' => 1, //fund
'cashFlowAmount' => 0,
'expAstAmount' => 0,
'accumulatedCashFlowAmount' => 0,
'accumulatedCashFlowBalance' => 0,
'accumulatedExpAstAmount' => 0,
'relevantExpAstHeadId' => 0,
'balancingHeadId' => 0,
'cashFlowHeadId' => 0,
'cashFlowHeadType' => 1,
'relevantProductIds' => [],
'reminderDateTs' => 0,
'cashFlowDateTs' => 0,
'expAstRealizationDateTs' => 0,
]);
}
}
}
return new JsonResponse(array(
"success" => 'true',
));
}
public function activityAction()
{
$activity = GeneralConstant::$activity;
return new JsonResponse(array(
$activity
));
}
public function taskInAction(Request $request)
{
$session = $request->getSession();
$currentTime = new \Datetime();
$currTs = $currentTime->format('U');
$em = $this->getDoctrine()->getManager();
$em_goc = $this->getDoctrine()->getManager('company_group');
$currentTaskId = $session->get(UserConstants::USER_CURRENT_TASK_ID, 0);
$currentPlanningItemId = $session->get(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, 0);
$token = $session->get(UserConstants::USER_TOKEN);
$providedToken = $request->headers->get('auth-token');
if (empty($providedToken) || $providedToken !== $token) {
return new JsonResponse([
'status' => 'error',
'message' => 'Token not match or missing',
], 401);
}
$toSetPlanningItemId = $request->request->get('planningItemId', 0);
$em = $this->getDoctrine()->getManager();
if($toSetPlanningItemId==0)
{
$lastTask = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
'userId' => $session->get(UserConstants::USER_ID),
// 'workingStatus' => 1
],[
'id'=>'desc'
]);
if($lastTask)
$toSetPlanningItemId=$lastTask->getPLanningItemId();
}
$activeTask = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
'userId' => $session->get(UserConstants::USER_ID),
'workingStatus' => 1
]);
// if ($activeTask && $activeTask->getPlanningItemId() != 0)
// {
//
// }
// if ($activeTask && $activeTask->getPlanningItemId() != 0)
if(0)
{
return new JsonResponse([
'success' => false,
'message' => 'A Task is already active. Please end current task!'
], 200);
}
if ($request->isMethod('POST')) {
$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) . ' ;');
$taskLog = new TaskLog;
$taskLog->setPlanningItemId($toSetPlanningItemId);
$taskLog->setUserId($request->request->get('userId', $session->get(UserConstants::USER_ID)));
$taskLog->setLogType('session');
$taskLog->setWorkingStatus($request->request->get('workingStatus', 1));
$taskLog->setActualStartTs($request->request->get('actualStartTs', $currTs));
$em->persist($taskLog);
$em->flush();
$currentTaskId = $taskLog->getId();
$currentPlanningItemId = $toSetPlanningItemId;
if ($request->request->get('swipe') && $toSetPlanningItemId==0) {
$lastLog = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
'userId' => $session->get(UserConstants::USER_ID),
], ['id' => 'DESC']);
$currentPlanningItemId = $lastLog ? $lastLog->getPlanningItemId() : 0;
}
if ($taskLog) {
$empId = $session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$currTime = new \DateTime();
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
);
// $positionsArray = [
//
// array(
// 'employeeId' => $empId,
// 'userId' => $session->get(UserConstants::USER_ID, 0),
// 'sysUserId' => $session->get(UserConstants::USER_ID, 0),
// 'timeStamp' => $currTime->format(DATE_ISO8601),
// 'lat' => 23.8623834,
// 'lng' => 90.3979294,
// 'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_GENERAL_TRACKING,
//// 'userId'=>$session->get(UserConstants::USER_ID, 0),
// )
//
// ];
$positionsArray=$request->request->get('position_array',[]);
if (is_string($positionsArray)) $positionsArray = json_decode($positionsArray, true);
if ($positionsArray == null) $positionsArray = [];
if(empty($positionsArray))
{
$positionsArray = [
array(
'tsMilSec' => 1000*$currTime->format('U'),
'lat' => 23.8623834,
'lng' => 90.3979294,
'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN,
'timeStamp' => $currTime->format(DATE_ISO8601),
)
];
}
else
{
}
$dataByAttId = [];
$workPlaceType = '_UNSET_';
foreach ($positionsArray as $findex => $d) {
$sysUserId = 0;
$userId = 0;
$empId = $session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$dtTs = 0;
$timeZoneStr = '+0000';
if (isset($d['employeeId'])) $empId = $d['employeeId'];
if (isset($d['userId'])) $userId = $d['userId'];
if (isset($d['sysUserId'])) $sysUserId = $d['sysUserId'];
if (isset($d['tsMilSec'])) {
$dtTs = ceil((1 * $d['tsMilSec']) / 1000);
}
$d['employeeId']=$empId;
$positionsArray[$findex] = $d;
if ($dtTs == 0) {
$currTsTime = new \DateTime();
$dtTs = $currTsTime->format('U');
} else {
$currTsTime = new \DateTime('@' . $dtTs);
}
$currTsTime->setTimezone(new \DateTimeZone('UTC'));
$attDate = new \DateTime($currTsTime->format('Y-m-d') . ' 00:00:00' . $timeZoneStr);
$EmployeeAttendance = $this->getDoctrine()
->getRepository(EmployeeAttendance::class)
->findOneBy(array('employeeId' => $empId, 'date' => $attDate));
if (!$EmployeeAttendance) {
$d['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
$positionsArray[$findex]['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
$EmployeeAttendance = new EmployeeAttendance;
} else {
if ($EmployeeAttendance->getCurrentLocation() == 'out') {
$d['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
$positionsArray[$findex]['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN;
} else {
$d['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_GENERAL_TRACKING;
$positionsArray[$findex]['markerId'] = HumanResourceConstant::ATTENDANCE_MARKER_GENERAL_TRACKING;
}
}
$attendanceInfo = HumanResource::StoreAttendance($em, $empId, $sysUserId, $request, $EmployeeAttendance, $attDate, $dtTs, $timeZoneStr, $d['markerId']);
if ($d['markerId'] == HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN) {
$workPlaceType = '_STATIC_';
}
if (!isset($dataByAttId[$attendanceInfo->getId()]))
$dataByAttId[$attendanceInfo->getId()] = array(
'attendanceInfo' => $attendanceInfo,
'empId' => $empId,
'lat' => 0,
'lng' => 0,
'address' => 0,
'sysUserId' => $sysUserId,
'companyId' => $request->getSession()->get(UserConstants::USER_COMPANY_ID),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'positionArray' => []
);
$posData = array(
'ts' => $dtTs,
'lat' => $d['lat'],
'lng' => $d['lng'],
'marker' => $d['markerId'],
'src' => 2,
);
$posDataArray = array(
$dtTs,
$d['lat'],
$d['lng'],
$d['markerId'],
2
);
$dataByAttId[$attendanceInfo->getId()]['markerId'] = $d['markerId'];
//this markerId will be calclulted and modified to check if user is in our out of office/workplace later
$dataByAttId[$attendanceInfo->getId()]['attendanceInfo'] = $attendanceInfo;
$dataByAttId[$attendanceInfo->getId()]['positionArray'][] = $posData;
$dataByAttId[$attendanceInfo->getId()]['lat'] = $d['lat']; //for last lat lng etc
$dataByAttId[$attendanceInfo->getId()]['lng'] = $d['lng']; //for last lat lng etc
if (isset($d['address']))
$dataByAttId[$attendanceInfo->getId()]['address'] = $d['address']; //for last lat lng etc
// $dataByAttId[$attendanceInfo->getId()]['positionArray'][]=$posDataArray;
}
$response = array(
'success' => true,
);
foreach ($dataByAttId as $attInfoId => $d) {
$response = HumanResource::setAttendanceLogFlutterApp($em,
$d['empId'],
$d['sysUserId'],
$d['companyId'],
$d['appId'],
$request,
$d['attendanceInfo'],
$options,
$d['positionArray'],
$d['lat'],
$d['lng'],
$d['address'],
$d['markerId']
);
}
$session->set(UserConstants::USER_CURRENT_TASK_ID, $taskLog->getId());
$session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, $taskLog->getPlanningItemId());
} else {
$session->set(UserConstants::USER_CURRENT_TASK_ID, 0);
$session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, 0);
$empId = $session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$currTime = new \DateTime();
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
);
// $positionsArray = [
//
// array(
// 'employeeId' => $empId,
// 'userId' => $session->get(UserConstants::USER_ID, 0),
// 'sysUserId' => $session->get(UserConstants::USER_ID, 0),
// 'timeStamp' => $currTime->format(DATE_ISO8601),
// 'lat' => 23.8623834,
// 'lng' => 90.3979294,
// 'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT,
//// 'userId'=>$session->get(UserConstants::USER_ID, 0),
// )
//
// ];
$positionsArray=$request->request->get('position_array',[]);
if (is_string($positionsArray)) $positionsArray = json_decode($positionsArray, true);
if ($positionsArray == null) $positionsArray = [];
if(empty($positionsArray))
{
$positionsArray = [
array(
'tsMilSec' => 1000*$currTime->format('U'),
'lat' => 23.8623834,
'lng' => 90.3979294,
'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_IN,
)
];
}
else
{
}
$dataByAttId = [];
$workPlaceType = '_UNSET_';
foreach ($positionsArray as $findex => $d) {
$sysUserId = 0;
$userId = 0;
$empId = $session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$dtTs = 0;
$timeZoneStr = '+0000';
if (isset($d['employeeId'])) $empId = $d['employeeId'];
if (isset($d['userId'])) $userId = $d['userId'];
if (isset($d['sysUserId'])) $sysUserId = $d['sysUserId'];
if (isset($d['tsMilSec'])) {
$dtTs = ceil((1 * $d['tsMilSec']) / 1000);
}
$d['employeeId']=$empId;
$positionsArray[$findex] = $d;
if ($dtTs == 0) {
$currTsTime = new \DateTime();
$dtTs = $currTsTime->format('U');
} else {
$currTsTime = new \DateTime('@' . $dtTs);
}
$currTsTime->setTimezone(new \DateTimeZone('UTC'));
$attDate = new \DateTime($currTsTime->format('Y-m-d') . ' 00:00:00' . $timeZoneStr);
$EmployeeAttendance = $this->getDoctrine()
->getRepository(EmployeeAttendance::class)
->findOneBy(array('employeeId' => $empId, 'date' => $attDate));
if (!$EmployeeAttendance) {
continue;
} else {
}
$attendanceInfo = HumanResource::StoreAttendance($em, $empId, $sysUserId, $request, $EmployeeAttendance, $attDate, $dtTs, $timeZoneStr, $d['markerId']);
if ($d['markerId'] == HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT) {
$workPlaceType = '_STATIC_';
}
if (!isset($dataByAttId[$attendanceInfo->getId()]))
$dataByAttId[$attendanceInfo->getId()] = array(
'attendanceInfo' => $attendanceInfo,
'empId' => $empId,
'lat' => 0,
'lng' => 0,
'address' => 0,
'sysUserId' => $sysUserId,
'companyId' => $request->getSession()->get(UserConstants::USER_COMPANY_ID),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'positionArray' => []
);
$posData = array(
'ts' => $dtTs,
'lat' => $d['lat'],
'lng' => $d['lng'],
'marker' => $d['markerId'],
'src' => 2,
);
$posDataArray = array(
$dtTs,
$d['lat'],
$d['lng'],
$d['markerId'],
2
);
$dataByAttId[$attendanceInfo->getId()]['markerId'] = $d['markerId'];
//this markerId will be calclulted and modified to check if user is in our out of office/workplace later
$dataByAttId[$attendanceInfo->getId()]['attendanceInfo'] = $attendanceInfo;
$dataByAttId[$attendanceInfo->getId()]['positionArray'][] = $posData;
$dataByAttId[$attendanceInfo->getId()]['lat'] = $d['lat']; //for last lat lng etc
$dataByAttId[$attendanceInfo->getId()]['lng'] = $d['lng']; //for last lat lng etc
if (isset($d['address']))
$dataByAttId[$attendanceInfo->getId()]['address'] = $d['address']; //for last lat lng etc
// $dataByAttId[$attendanceInfo->getId()]['positionArray'][]=$posDataArray;
}
$response = array(
'success' => true,
);
foreach ($dataByAttId as $attInfoId => $d) {
$response = HumanResource::setAttendanceLogFlutterApp($em,
$d['empId'],
$d['sysUserId'],
$d['companyId'],
$d['appId'],
$request,
$d['attendanceInfo'],
$options,
$d['positionArray'],
$d['lat'],
$d['lng'],
$d['address'],
$d['markerId']
);
}
}
$theEntityUpdated = $taskLog;
}
$session->set(UserConstants::USER_CURRENT_TASK_ID, $currentTaskId);
$session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, $currentPlanningItemId);
$to_set_session_data = MiscActions::GetSessionDataFromToken($em_goc, $session->get(UserConstants::USER_TOKEN, ''))['sessionData'];
// $to_set_session_data = MiscActions::GetSessionDataFromToken($em_goc, $request->query->get('token'));
$to_set_session_data[UserConstants::USER_CURRENT_TASK_ID] = $currentTaskId;
$to_set_session_data[UserConstants::USER_CURRENT_PLANNING_ITEM_ID] = $currentPlanningItemId;
// MiscActions::CreateTokenFromSessionData($em_goc, $to_set_session_data);
$updatedToken = MiscActions::CreateTokenFromSessionData($em_goc,
$to_set_session_data,
1,
1,
1, 1
);
return new JsonResponse(array(
"success" => 'true',
"message" => 'Task added successfully!',
"token" => $updatedToken, // Return this
"currentTaskId" => $currentTaskId,
"currentPlanningItemId" => $currentPlanningItemId
));
}
public function taskOutAction(Request $request)
{
{
$session = $request->getSession();
$em_goc = $this->getDoctrine()->getManager('company_group');
$session = $request->getSession();
$currentTime = new \Datetime();
$currTs = $currentTime->format('U');
$token = $session->get(UserConstants::USER_TOKEN);
$providedToken = $request->headers->get('auth-token');
if (empty($providedToken) || $providedToken !== $token) {
return new JsonResponse([
'status' => 'error',
'message' => 'Token mismatched or missing',
], 401);
}
$em = $this->getDoctrine()->getManager();
$activeTask = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy([
'userId' => $session->get(UserConstants::USER_ID),
'workingStatus' => 1
]);
if (!$activeTask) {
return new JsonResponse([
'success' => false,
'message' => 'No active task is found!'
], 200);
}
// $currentTaskId = $session->get(UserConstants::USER_CURRENT_TASK_ID, 0);
$currentTaskId = $activeTask->getId();
$planningItemId = (int)$activeTask->getPlanningItemId();
$planningItem = $planningItemId ? $em->getRepository('ApplicationBundle\\Entity\\PlanningItem')->find($planningItemId) : null;
$hasCompletionPercentage = $request->request->has('completionPercentage');
$taskStatus = strtolower(trim((string)$request->request->get('taskStatus', 'pending')));
$completionPercentage = (float)$request->request->get(
'completionPercentage',
$planningItem && $planningItem->getCompletionPercentage() !== null ? $planningItem->getCompletionPercentage() : 0
);
$markDone = in_array($taskStatus, ['completed', 'done', 'submitted'], true)
|| ($hasCompletionPercentage && $completionPercentage >= 100)
|| (int)$request->request->get('markDone', 0) === 1;
$workCompleted = trim((string)$request->request->get('workCompleted', ''));
$evidenceNote = trim((string)$request->request->get('evidenceNote', ''));
$evidenceFiles = $request->request->get('evidenceFiles', '');
$blockerDetail = trim((string)$request->request->get('blockerDetail', ''));
$nextAction = trim((string)$request->request->get('nextAction', ''));
if (is_string($evidenceFiles) && $evidenceFiles !== '') {
$decodedEvidence = json_decode($evidenceFiles, true);
if (json_last_error() === JSON_ERROR_NONE) {
$evidenceFiles = $decodedEvidence;
}
}
if ($markDone) {
$evidenceCount = 0;
if (is_array($evidenceFiles)) {
$evidenceCount = count(array_filter($evidenceFiles, function ($item) {
return trim((string)$item) !== '';
}));
} elseif (is_string($evidenceFiles)) {
$evidenceCount = strlen(trim($evidenceFiles)) > 0 ? 1 : 0;
}
if ($workCompleted === '' || $evidenceCount === 0) {
return new JsonResponse([
'success' => false,
'message' => 'Work completed summary and evidence are required before submitting a completed task.'
], 422);
}
// if (!$planningItem || (int)$planningItem->getReviewerId() === 0) {
//
// return new JsonResponse([
// 'success' => false,
// 'message' => 'Reviewer must be assigned before a completed task can be submitted for review.'
// ], 422);
// }
if ($planningItem && (int)$planningItem->getReviewerId() === 0) {
$decision='approve';
$now=new \DateTime();
if ($decision === 'approve') {
$planningItem->setCurrentState('approved');
$planningItem->setReviewStatus('approved');
$planningItem->setKpiCounted(1);
$planningItem->setApprovedAt($now);
$planningItem->setActualCompletionTimeTs($now->getTimestamp());
} else {
$planningItem->setCurrentState('rejected');
$planningItem->setReviewStatus('rejected');
$planningItem->setKpiCounted(0);
$planningItem->setRejectedAt($now);
}
}
}
// $currentPlanningItemId = $session->get(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, 0);
if (
($currentTaskId != 0 && $currentTaskId != null && $currentTaskId != '') &&
($session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_GENERAL ||
$session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_SYSTEM)
) {
$em = $this->getDoctrine()->getManager();
$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) . ' ;');
if ($planningItem && !$markDone) {
$activeTask->setFeedback(trim((string)$request->request->get('feedback', '')));
$activeTask->setNote(trim((string)$request->request->get('feedback', '')));
$planningItem->setCompletionPercentage($completionPercentage);
if ($planningItem->getCurrentState() !== 'submitted' && $planningItem->getCurrentState() !== 'approved') {
$planningItem->setCurrentState('in_progress');
}
if (!$planningItem->getReviewStatus()) {
$planningItem->setReviewStatus('draft');
}
}
$em->flush();
if ($markDone && $planningItem && !((int)$planningItem->getReviewerId() === 0)) {
$submissionLog = new TaskLog();
$submissionLog->setPlanningItemId($planningItemId);
$submissionLog->setUserId($session->get(UserConstants::USER_ID));
$submissionLog->setEmployeeId($session->get(UserConstants::USER_EMPLOYEE_ID, 0));
$submissionLog->setAppId($session->get(UserConstants::USER_APP_ID, 0));
$submissionLog->setTitle($planningItem->getItemAlias());
$submissionLog->setWorkingStatus(3);
$submissionLog->setStatus(0);
$submissionLog->setCompleted(1);
$submissionLog->setLogType('submission');
$submissionLog->setWorkCompleted($workCompleted);
$submissionLog->setEvidenceFiles(is_array($evidenceFiles) ? json_encode($evidenceFiles) : (string)$evidenceFiles);
$submissionLog->setEvidenceNote($evidenceNote);
$submissionLog->setBlockerDetail($blockerDetail);
$submissionLog->setNextAction($nextAction);
$submissionLog->setNote($workCompleted);
$submissionLog->setFeedback($evidenceNote);
$submissionLog->setActualStartTs($activeTask->getActualStartTs());
$submissionLog->setActualEndTs($currTs);
$submissionLog->setCreatedLoginId($session->get(UserConstants::USER_LOGIN_ID));
$em->persist($submissionLog);
$planningItem->setCompletionPercentage(100);
$planningItem->setCurrentState('submitted');
$planningItem->setReviewStatus('pending');
$planningItem->setSubmittedAt(new \DateTime());
$planningItem->setKpiCounted(0);
$planningItem->setBlockerSummary($blockerDetail);
$planningItem->setNextAction($nextAction);
if (!$planningItem->getActualStartTimeTs()) {
$planningItem->setActualStartTimeTs($activeTask->getActualStartTs());
}
$em->flush();
}
if (1) {
$session->set(UserConstants::USER_CURRENT_TASK_ID, 0);
$session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, 0);
$empId = $session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$currTime = new \DateTime();
$options = array(
'notification_enabled' => $this->container->getParameter('notification_enabled'),
'notification_server' => $this->container->getParameter('notification_server'),
);
// $positionsArray = [
// array(
// 'employeeId' => $empId,
// 'userId' => $session->get(UserConstants::USER_ID, 0),
// 'sysUserId' => $session->get(UserConstants::USER_ID, 0),
// 'timeStamp' => $currTime->format(DATE_ISO8601),
// 'lat' => 23.8623834,
// 'lng' => 90.3979294,
// 'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT,
// // 'userId'=>$session->get(UserConstants::USER_ID, 0),
// )
//
// ];
$positionsArray=$request->request->get('position_array',[]);
if (is_string($positionsArray)) $positionsArray = json_decode($positionsArray, true);
if ($positionsArray == null) $positionsArray = [];
if(empty($positionsArray))
{
$positionsArray = [
array(
'tsMilSec' => 1000*$currTime->format('U'),
'lat' => 23.8623834,
'lng' => 90.3979294,
'markerId' => HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT,
'timeStamp' => $currTime->format(DATE_ISO8601),
)
];
}
else
{
}
$dataByAttId = [];
$workPlaceType = '_UNSET_';
foreach ($positionsArray as $findex => $d) {
$sysUserId = 0;
$userId = 0;
$empId = $session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$dtTs = 0;
$timeZoneStr = '+0000';
if (isset($d['employeeId'])) $empId = $d['employeeId'];
if (isset($d['userId'])) $userId = $d['userId'];
if (isset($d['sysUserId'])) $sysUserId = $d['sysUserId'];
if (isset($d['tsMilSec'])) {
$dtTs = ceil((1 * $d['tsMilSec']) / 1000);
}
$d['employeeId']=$empId;
$positionsArray[$findex] = $d;
if ($dtTs == 0) {
$currTsTime = new \DateTime();
$dtTs = $currTsTime->format('U');
} else {
$currTsTime = new \DateTime('@' . $dtTs);
}
$currTsTime->setTimezone(new \DateTimeZone('UTC'));
$attDate = new \DateTime($currTsTime->format('Y-m-d') . ' 00:00:00' . $timeZoneStr);
$EmployeeAttendance = $this->getDoctrine()
->getRepository(EmployeeAttendance::class)
->findOneBy(array('employeeId' => $empId, 'date' => $attDate));
if (!$EmployeeAttendance) {
continue;
} else {
}
$attendanceInfo = HumanResource::StoreAttendance($em, $empId, $sysUserId, $request, $EmployeeAttendance, $attDate, $dtTs, $timeZoneStr, $d['markerId']);
if ($d['markerId'] == HumanResourceConstant::ATTENDANCE_MARKER_CLOCK_OUT) {
$workPlaceType = '_STATIC_';
}
if (!isset($dataByAttId[$attendanceInfo->getId()]))
$dataByAttId[$attendanceInfo->getId()] = array(
'attendanceInfo' => $attendanceInfo,
'empId' => $empId,
'lat' => 0,
'lng' => 0,
'address' => 0,
'sysUserId' => $sysUserId,
'companyId' => $request->getSession()->get(UserConstants::USER_COMPANY_ID),
'appId' => $request->getSession()->get(UserConstants::USER_APP_ID),
'positionArray' => []
);
$posData = array(
'ts' => $dtTs,
'lat' => $d['lat'],
'lng' => $d['lng'],
'marker' => $d['markerId'],
'src' => 2,
);
$posDataArray = array(
$dtTs,
$d['lat'],
$d['lng'],
$d['markerId'],
2
);
$dataByAttId[$attendanceInfo->getId()]['markerId'] = $d['markerId'];
//this markerId will be calclulted and modified to check if user is in our out of office/workplace later
$dataByAttId[$attendanceInfo->getId()]['attendanceInfo'] = $attendanceInfo;
$dataByAttId[$attendanceInfo->getId()]['positionArray'][] = $posData;
$dataByAttId[$attendanceInfo->getId()]['lat'] = $d['lat']; //for last lat lng etc
$dataByAttId[$attendanceInfo->getId()]['lng'] = $d['lng']; //for last lat lng etc
if (isset($d['address']))
$dataByAttId[$attendanceInfo->getId()]['address'] = $d['address']; //for last lat lng etc
// $dataByAttId[$attendanceInfo->getId()]['positionArray'][]=$posDataArray;
}
$response = array(
'success' => true,
);
foreach ($dataByAttId as $attInfoId => $d) {
$response = HumanResource::setAttendanceLogFlutterApp($em,
$d['empId'],
$d['sysUserId'],
$d['companyId'],
$d['appId'],
$request,
$d['attendanceInfo'],
$options,
$d['positionArray'],
$d['lat'],
$d['lng'],
$d['address'],
$d['markerId']
);
}
}
}
$currentTaskId = 0;
$currentPlanningItemId = 0;
$session->set(UserConstants::USER_CURRENT_TASK_ID, $currentTaskId);
$session->set(UserConstants::USER_CURRENT_PLANNING_ITEM_ID, $currentPlanningItemId);
$to_set_session_data = MiscActions::GetSessionDataFromToken($em_goc, $token)['sessionData'];
$to_set_session_data[UserConstants::USER_CURRENT_TASK_ID] = $currentTaskId;
$to_set_session_data[UserConstants::USER_CURRENT_PLANNING_ITEM_ID] = $currentPlanningItemId;
// MiscActions::CreateTokenFromSessionData($em_goc, $to_set_session_data);
$updatedToken = MiscActions::CreateTokenFromSessionData($em_goc, $to_set_session_data,
1,
1,
1, 1);
return new JsonResponse(array(
"success" => 'true',
"message" => 'Successfully stop task!',
"token" => $updatedToken
));
}
}
public function taskReviewAction(Request $request)
{
$session = $request->getSession();
$token = $session->get(UserConstants::USER_TOKEN);
$providedToken = $request->headers->get('auth-token');
if (empty($providedToken) || $providedToken !== $token) {
return new JsonResponse([
'status' => 'error',
'message' => 'Token not match or missing',
], 401);
}
if (!$request->isMethod('POST')) {
return new JsonResponse([
'success' => false,
'message' => 'Invalid request method'
], 405);
}
$em = $this->getDoctrine()->getManager();
$planningItemId = (int)$request->request->get('planningItemId', 0);
$decision = strtolower(trim((string)$request->request->get('decision', '')));
$reviewComment = trim((string)$request->request->get('reviewComment', ''));
if ($planningItemId === 0 || !in_array($decision, ['approve', 'reject'], true)) {
return new JsonResponse([
'success' => false,
'message' => 'Invalid review payload'
], 422);
}
$planningItem = $em->getRepository('ApplicationBundle\\Entity\\PlanningItem')->find($planningItemId);
if (!$planningItem) {
return new JsonResponse([
'success' => false,
'message' => 'Task not found'
], 404);
}
$latestSubmission = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->findOneBy(
[
'planningItemId' => $planningItemId,
'logType' => 'submission'
],
[
'id' => 'DESC'
]
);
if (!$latestSubmission) {
return new JsonResponse([
'success' => false,
'message' => 'No submitted task is available for review'
], 422);
}
$reviewerId = (int)$planningItem->getReviewerId();
$currentEmployeeId = (int)$session->get(UserConstants::USER_EMPLOYEE_ID, 0);
$isAuthorizedOverride = (
(int)$session->get(UserConstants::USER_TYPE) === UserConstants::USER_TYPE_SYSTEM
|| (int)$session->get(UserConstants::IS_BUDDYBEE_ADMIN, 0) === 1
);
if ($reviewerId === 0) {
return new JsonResponse([
'success' => false,
'message' => 'Reviewer must be assigned before review can be completed'
], 422);
}
if ($reviewerId !== $currentEmployeeId && !$isAuthorizedOverride) {
return new JsonResponse([
'success' => false,
'message' => 'You are not assigned as the reviewer for this task'
], 403);
}
if ($planningItem->getCurrentState() !== 'submitted' || $planningItem->getReviewStatus() !== 'pending') {
return new JsonResponse([
'success' => false,
'message' => 'Only submitted tasks waiting for review can be reviewed'
], 422);
}
$now = new \DateTime();
$reviewLog = new TaskLog();
$reviewLog->setPlanningItemId($planningItemId);
$reviewLog->setUserId($session->get(UserConstants::USER_ID));
$reviewLog->setEmployeeId($currentEmployeeId);
$reviewLog->setTitle($planningItem->getItemAlias());
$reviewLog->setLogType('review');
$reviewLog->setReviewDecision($decision);
$reviewLog->setReviewComment($reviewComment);
$reviewLog->setReviewedBy($session->get(UserConstants::USER_ID));
$reviewLog->setReviewedAt($now);
$reviewLog->setStatus($decision === 'approve' ? 1 : 0);
$reviewLog->setCompleted($decision === 'approve' ? 1 : 0);
$reviewLog->setWorkingStatus(4);
$reviewLog->setCreatedLoginId($session->get(UserConstants::USER_LOGIN_ID));
$em->persist($reviewLog);
if ($latestSubmission) {
$latestSubmission->setReviewDecision($decision);
$latestSubmission->setReviewComment($reviewComment);
$latestSubmission->setReviewedBy($session->get(UserConstants::USER_ID));
$latestSubmission->setReviewedAt($now);
$latestSubmission->setApproved($decision === 'approve' ? 1 : 0);
}
if ($decision === 'approve') {
$planningItem->setCurrentState('approved');
$planningItem->setReviewStatus('approved');
$planningItem->setKpiCounted(1);
$planningItem->setApprovedAt($now);
$planningItem->setActualCompletionTimeTs($now->getTimestamp());
} else {
$planningItem->setCurrentState('rejected');
$planningItem->setReviewStatus('rejected');
$planningItem->setKpiCounted(0);
$planningItem->setRejectedAt($now);
}
$em->flush();
return new JsonResponse([
'success' => true,
'message' => $decision === 'approve' ? 'Task approved successfully' : 'Task rejected successfully',
'planningItemId' => $planningItemId,
'decision' => $decision
]);
}
public function getTaskByProjectIdAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$taskByProjectId = $request->query->get('projectId');
$taskListByProject = $em->getRepository(PlanningItem::class)->createQueryBuilder('A')
->where('A.projectId = :projectId')
->setParameter('projectId', $taskByProjectId)
->getQuery()
->getResult();
$taskList = [];
foreach ($taskListByProject as $data) {
$list = array(
'id' => $data->getId(),
'taskName' => $data->getItemAlias()
);
$taskList[] = $list;
}
return new JsonResponse($taskList);
}
public function TaskLogViewAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$session = $request->getSession();
$allTask =
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select(
't.planningItemId',
't.actualStartTs',
't.actualEndTs',
't.workingStatus',
't.feedback',
't.status',
't.logType',
't.workCompleted',
't.evidenceFiles',
't.evidenceNote',
't.blockerDetail',
't.nextAction',
't.reviewDecision',
't.reviewComment',
't.reviewedBy',
't.reviewedAt',
'p.itemAlias',
'p.assignedTo',
'p.assignedToType',
'p.estimatedStartTimeTs',
'p.estimatedCompletionTimeTs',
'p.currentState',
'p.reviewStatus',
'p.reviewerId',
'p.taskContextType',
'p.expectedOutput',
'p.kpiCounted',
'p.submittedAt',
'p.approvedAt',
'p.rejectedAt'
)
->from('ApplicationBundle\\Entity\\TaskLog', 't')
->leftJoin('ApplicationBundle\\Entity\\PlanningItem', 'p', 'WITH', 't.planningItemId = p.id');
$taskLogData = $queryBuilder->getQuery()->getResult();
foreach ($taskLogData as &$task) {
$assignedToId = $task['assignedTo'] ?? null;
$assignedToType = $task['assignedToType'] ?? null;
$entity = null;
if ($assignedToId !== null) {
if ($assignedToType === 1 || $assignedToType === null || $assignedToType === 0) {
$entity = $em->getRepository('ApplicationBundle\\Entity\\Employee')->find($assignedToId);
} elseif ($assignedToType === 2) {
$entity = $em->getRepository('ApplicationBundle\\Entity\\SysUser')->find($assignedToId);
}
}
$task['assignedToName'] = ($entity && method_exists($entity, 'getName')) ? $entity->getName() : 'Unassigned';
}
return $this->render(
'@Project/pages/report/task_log_views.html.twig',
[
'page_title' => 'Task Log',
'task_log_data' => $taskLogData,
'currentEmployeeId' => $session->get(UserConstants::USER_EMPLOYEE_ID, 0),
]
);
}
public function taskHistoryAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$session = $request->getSession();
$currentTime = new \DateTime();
$currDate = $currentTime->format('Y-m-d');
$userId = $session->get(UserConstants::USER_ID);
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select(
't.id',
't.planningItemId',
't.actualStartTs',
't.actualEndTs',
't.userId',
'p.itemAlias'
)
->from('ApplicationBundle\\Entity\\TaskLog', 't')
->leftJoin('ApplicationBundle\\Entity\\PlanningItem', 'p', 'WITH', 't.planningItemId = p.id')
->where('t.userId = :userId')
->andWhere('t.createdAt >= :date')
->andWhere('t.createdAt <= :date_end')
->setParameter('userId', $userId)
->setParameter('date', $currDate)
->setParameter('date_end', $currDate . ' 23:59:59')
->orderBy('t.createdAt', 'DESC');
$taskLogData = $queryBuilder->getQuery()->getArrayResult();
if (empty($taskLogData)) {
return new JsonResponse([
'success' => false,
'message' => 'No task history found',
'data' => []
]);
}
return new JsonResponse([
'success' => true,
'message' => 'Task history fetched successfully',
'data' => $taskLogData,
]);
}
public function taskDetailsAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$taskId = $request->query->get('taskId');
// Fetch task details
$taskDetails = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->createQueryBuilder('t')
->select(
't.id',
't.planningItemId',
't.actualStartTs',
't.actualEndTs',
'p.itemAlias',
'p.estimatedStartTimeTs',
'p.projectedCost',
'p.actualCost',
'p.estimatedCompletionTimeTs',
'p.completionPercentage',
'p.description'
)
->leftJoin('ApplicationBundle\\Entity\\PlanningItem', 'p', 'WITH', 't.planningItemId = p.id')
->where('t.id = :taskId')
->setParameter('taskId', $taskId)
->getQuery()
->getResult();
if (!$taskDetails) {
return new JsonResponse(['error' => 'Task not found'], 404);
}
$taskDetail = $taskDetails[0];
$planningItemId = $taskDetail['planningItemId'];
// Add validation for actualCost and projectedCost
$taskDetail['actualCost'] = isset($taskDetail['actualCost']) ? $taskDetail['actualCost'] : '';
$taskDetail['projectedCost'] = isset($taskDetail['projectedCost']) ? $taskDetail['projectedCost'] : '';
// Fetch planning details for history
$planningDetails = $em->getRepository('ApplicationBundle\\Entity\\TaskLog')->createQueryBuilder('t')
->select('t.planningItemId', 't.actualStartTs', 't.actualEndTs', 'p.itemAlias')
->leftJoin('ApplicationBundle\\Entity\\PlanningItem', 'p', 'WITH', 't.planningItemId = p.id')
->where('t.planningItemId = :planningItemId')
->setParameter('planningItemId', $planningItemId)
->getQuery()
->getResult();
// Calculate total work time
$totalWorkSeconds = 0;
foreach ($planningDetails as $task) {
if (isset($task['actualStartTs']) && isset($task['actualEndTs'])) {
$totalWorkSeconds += ($task['actualEndTs'] - $task['actualStartTs']);
}
}
$totalHours = floor($totalWorkSeconds / 3600);
$totalMinutes = floor(($totalWorkSeconds % 3600) / 60);
$totalSeconds = $totalWorkSeconds % 60;
$totalWorkHour = sprintf('%02d:%02d:%02d', $totalHours, $totalMinutes, $totalSeconds);
return new JsonResponse([
'totalWorkHour' => $totalWorkHour,
'taskDetails' => $taskDetail,
'taskHistory' => $planningDetails,
]);
}
public function taskHistoryByPlanningItemIdAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$taskId = $request->query->get('id');
$queryBuilder = $em->createQueryBuilder();
$queryBuilder
->select('t.planningItemId', 't.actualStartTs', 't.actualEndTs',
'p.itemAlias', 'p.estimatedStartTimeTs', 'p.estimatedCompletionTimeTs',
'p.completionPercentage', 'p.description', 'p.projectedCost', 'p.actualCost')
->from('ApplicationBundle\\Entity\\TaskLog', 't')
->leftJoin('ApplicationBundle\\Entity\\PlanningItem', 'p', 'WITH', 't.planningItemId = p.id')
->where('t.planningItemId = :id')
->setParameter('id', $taskId);
$rawData = $queryBuilder->getQuery()->getArrayResult();
// Sanitize cost fields
$taskDetails = array_map(function ($item) {
$item['projectedCost'] = $item['projectedCost'] ?? '';
$item['actualCost'] = $item['actualCost'] ?? '';
return $item;
}, $rawData);
return new JsonResponse($taskDetails);
}
public function DeleteTaskLogAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$session = $request->getSession();
$userId = $session->get(UserConstants::USER_ID);
$query = $em->createQuery(
'DELETE FROM ApplicationBundle\\Entity\\TaskLog t
WHERE t.userId = :userId AND (t.actualEndTs IS NULL OR t.actualEndTs = 0)'
);
$query->setParameter('userId', $userId);
$deletedCount = $query->executeStatement();
return new Response("Deleted $deletedCount task logs.");
}
public function taskListAction(Request $request)
{
if (!$request->isMethod('GET')) {
return new JsonResponse([
'success' => false,
'message' => 'Invalid request method'
], 405);
}
$em = $this->getDoctrine()->getManager();
$session = $request->getSession();
$employeeId = $session->get(UserConstants::USER_EMPLOYEE_ID);
if (!$employeeId) {
return new JsonResponse([
'success' => false,
'message' => 'Unauthorized access'
], 401);
}
$page = max((int) $request->query->get('page', 1), 1);
$limit = max((int) $request->query->get('limit', 10), 1);
$offset = ($page - 1) * $limit;
$total = (int) $em->getRepository(PlanningItem::class)
->createQueryBuilder('P')
->select('COUNT(P.id)')
->where('P.assignedTo = :employeeId')
->setParameter('employeeId', $employeeId)
->getQuery()
->getSingleScalarResult();
$taskRecords = $em->getRepository(PlanningItem::class)
->createQueryBuilder('P')
->select(
'P.id',
'P.itemAlias',
'P.estimatedStartTimeTs',
'P.estimatedCompletionTimeTs',
'P.actualStartTimeTs',
'P.actualCompletionTimeTs'
)
->where('P.assignedTo = :employeeId')
->setParameter('employeeId', $employeeId)
->setFirstResult($offset)
->setMaxResults($limit)
->orderBy('P.id', 'DESC')
->getQuery()
->getResult();
$formattedData = [];
foreach ($taskRecords as $task) {
$formattedData[] = [
'taskId' => $task['id'],
'itemAlias' => $task['itemAlias'],
'estimatedStartTimeTs' => $task['estimatedStartTimeTs'],
'estimatedCompletionTimeTs' => $task['estimatedCompletionTimeTs'],
'actualStartTimeTs' => $task['actualStartTimeTs'],
'actualCompletionTimeTs' => $task['actualCompletionTimeTs'],
];
}
return new JsonResponse([
'success' => true,
'message' => 'Task list fetched successfully',
'data' => $formattedData,
'currentPage' => $page,
'limit' => $limit,
'total' => $total,
'totalPages' => ceil($total / $limit),
]);
}
public function ViewProjectWorkspaceAction(Request $request, $id = 0)
{
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
if ($id == 0) {
return $this->redirect($this->generateUrl('project_list'));
}
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
array('projectId' => $id)
);
if (!$projectData) {
return $this->redirect($this->generateUrl('project_list'));
}
$clientList = SalesOrderM::GetClientList($em);
$clientName = isset($clientList[$projectData->getClientId()]) ? $clientList[$projectData->getClientId()]['client_name'] : '';
$salesPersonList = Client::SalesPersonList($em);
$salesPersonName = isset($salesPersonList[$projectData->getSalesPersonId()]) ? $salesPersonList[$projectData->getSalesPersonId()]['name'] : '';
$pos = $em->getRepository('ApplicationBundle\\Entity\\PurchaseOrder')->findBy(
array('projectId' => $id)
);
$invoices = $em->getRepository('ApplicationBundle\\Entity\\SalesInvoice')->findBy(
array('projectId' => $id)
);
$invoicedAmount = 0;
foreach ($invoices as $inv) {
$invoicedAmount += method_exists($inv, 'getInvoiceAmount') ? (float)$inv->getInvoiceAmount() : 0;
}
$proposals = $em->getRepository('ApplicationBundle\\Entity\\SalesProposal')->findBy(
array('projectId' => $id)
);
$wps = $em->getRepository('ApplicationBundle\\Entity\\ProjectWp')->findBy(
array('projectId' => $id)
);
$stageList = ProjectConstant::$projectStages;
$statusList = ProjectConstant::$projectStatus;
// S4.6 — SI Delivery sub-lists and snapshot
$requirements = ProjectM::getRequirementList($em, $id, $companyId);
$interfaces = ProjectM::getInterfaceList($em, $id, $companyId);
$devices = ProjectM::getDeviceList($em, $id, $companyId);
$baselines = ProjectM::getConfigBaselineList($em, $id, $companyId);
$testCases = ProjectM::getTestCaseList($em, $id, $companyId);
$siSnapshot = ProjectM::GetSiDeliverySnapshot($em, $id, $companyId);
$projectTicketsSummary = $this->get(ProjectTicketSummaryService::class)->summarizeProjectTickets($id, $companyId);
$projectTickets = $projectTicketsSummary['rows'];
$projectTicketsCount = $projectTicketsSummary['count'];
$projectSurfaceSplit = $this->isProjectSurfaceSplitEnabled();
// Co-pilot shell variant (?shell=cp) renders the same body inside the
// cp-shell so the co-pilot sidebar persists; default = codecovers chrome.
$workspaceTemplate = ($request->query->get('shell') === 'cp')
? '@Project/pages/views/view_project_workspace_cp.html.twig'
: '@Project/pages/views/view_project_workspace.html.twig';
return $this->render($workspaceTemplate, array(
'page_title' => 'Project Workspace — ' . $projectData->getProjectName(),
'projectData' => $projectData,
'clientName' => $clientName,
'salesPersonName' => $salesPersonName,
'prCount' => 0,
'poCount' => count($pos),
'invoicedAmount' => $invoicedAmount,
'outstandingAmount' => 0,
'wps' => $wps,
'proposals' => $proposals,
'pos' => $pos,
'invoices' => $invoices,
'stageList' => $stageList,
'statusList' => $statusList,
'id' => $id,
// S4.6
'requirements' => $requirements,
'interfaces' => $interfaces,
'devices' => $devices,
'baselines' => $baselines,
'testCases' => $testCases,
'siSnapshot' => $siSnapshot,
'projectTickets' => $projectTickets,
'projectTicketsCount' => $projectTicketsCount,
'projectIntelligence' => ProjectM::GetProjectIntelligenceData($em, $id, $companyId, false),
'projectSurfaceSplit' => $projectSurfaceSplit,
));
}
public function ConvertToProjectAction(Request $request, $id = 0)
{
$em = $this->getDoctrine()->getManager();
$retData = array(
'success' => false,
'projectId' => 0,
'redirectUrl' => '',
'message' => ''
);
if ($request->isMethod('POST')) {
$docType = $request->get('docType', '_project_');
$docId = $request->get('docId', 0);
if ($docType == '_project_') {
$salesProposal = $em->getRepository('ApplicationBundle\\Entity\\SalesProposal')->findOneBy(
array('salesProposalId' => $docId)
);
if (!$salesProposal) {
$retData['message'] = 'Proposal not found';
return new JsonResponse($retData);
}
// Idempotency: refuse if project already created
if ($salesProposal->getProjectCreated() == 1) {
$existingProjectId = $salesProposal->getProjectId();
$retData['message'] = 'Project already created';
$retData['projectId'] = $existingProjectId;
$retData['redirectUrl'] = $this->generateUrl('view_project_details') . '/' . $existingProjectId;
return new JsonResponse($retData);
}
$companyId = $this->getLoggedUserCompanyId($request);
$loginId = $this->getLoggedUserLoginId($request);
$currentDate = new \DateTime();
$project = new Project();
$project->setProjectName($salesProposal->getProposalTitle());
$project->setProjectDate($currentDate);
$project->setDocumentHash($salesProposal->getProposalTitle());
$project->setClientId($salesProposal->getClientId());
$project->setSalesPersonId($salesProposal->getSalesPersonId());
$project->setCurrency($salesProposal->getCurrency());
$project->setCurrencyMultiply($salesProposal->getCurrencyMultiply());
$project->setCurrencyMultiplyRate($salesProposal->getCurrencyMultiplyRate());
$project->setCompanyId($companyId);
$project->setBoqRequired(1);
$project->setProposalRequired(0);
$project->setOfferRequired(0);
$project->setBomRequired(0);
$project->setStatus(GeneralConstant::ACTIVE);
$project->setStage(array_flip(ProjectConstant::$projectStages)['INITIATED']);
$project->setProjectStep(array_flip(ProjectConstant::$projectSteps)['N/A']);
$project->setApproved(GeneralConstant::APPROVED);
$project->setAutoCreated(1);
$project->setAutoSoEnabled(0);
$project->setMarketingUserIds(json_encode([]));
$project->setMaterialUserIds(json_encode([]));
$project->setDesigningUserIds(json_encode([]));
$project->setImplementingUserIds(json_encode([]));
$project->setBillingUserIds(json_encode([]));
$project->setAccountsHeadId('');
$project->setAdvanceHeadId('');
$project->setPreRequisiteText('');
$project->setDeliverableText('');
$project->setDescription('');
$project->setRefPoNumber('');
$project->setCreatedLoginId($loginId);
$project->setEditedLoginId($loginId);
$em->persist($project);
$em->flush();
$projectId = $project->getProjectId();
// Create linked BoQ referencing the proposal's document data
if ($salesProposal->getDocumentDataId()) {
$boq = new ProjectBoq();
$boq->setProjectId($projectId);
$boq->setProjectBoqDate($currentDate);
$boq->setDocumentDataId($salesProposal->getDocumentDataId());
$boq->setDocumentHash($salesProposal->getDocumentHash() . '');
$boq->setCompanyId($companyId);
$boq->setData(json_encode([]));
$boq->setStatus(GeneralConstant::ACTIVE);
$boq->setApproved(GeneralConstant::APPROVED);
$boq->setAutoCreated(1);
$boq->setEditFlag(0);
$boq->setDeleteFlag(0);
$boq->setLockFlag(0);
$boq->setDisabledFlag(0);
$boq->setCreatedLoginId($loginId);
$boq->setEditedLoginId($loginId);
$em->persist($boq);
$documentData = $em->getRepository('ApplicationBundle\\Entity\\DocumentData')->findOneBy(
array('id' => $salesProposal->getDocumentDataId())
);
if ($documentData) {
$documentData->setProjectId($projectId);
// Seed ProjectMilestone rows from the proposal's work-plan milestones so the
// converted project shows its milestones without manual re-entry (req #13).
$wpRaw = json_decode($documentData->getData(), true);
$wpRaw0 = isset($wpRaw[0]) ? $wpRaw[0] : [];
$wpMsList = !empty($wpRaw0['workPlanMilestonesJson'])
? (json_decode($wpRaw0['workPlanMilestonesJson'], true) ?: [])
: [];
// Dedupe against any milestones already on this project.
$existingNames = [];
$existingMilestones = $em->getRepository('ApplicationBundle\\Entity\\ProjectMilestone')
->findBy(['projectId' => $projectId, 'deleteFlag' => 0]);
foreach ($existingMilestones as $exMs) {
$existingNames[mb_strtolower(trim((string)$exMs->getMilestoneName()))] = true;
}
foreach ($wpMsList as $ord => $ms) {
if (empty($ms['name'])) continue;
if (isset($existingNames[mb_strtolower(trim((string)$ms['name']))])) continue;
$milestone = new \ApplicationBundle\Entity\ProjectMilestone();
$milestone->setMilestoneName($ms['name']);
$milestone->setMilestoneDescription($ms['description'] ?? '');
$milestone->setMilestoneOrder($ord + 1);
$milestone->setMilestoneStatus('planned');
$milestone->setProjectId($projectId);
$milestone->setSalesOrderId(0);
if (!empty($ms['targetDate'])) {
try { $milestone->setPlannedDate(new \DateTime($ms['targetDate'])); } catch (\Exception $e) {}
}
$milestone->setCompanyId($companyId);
$milestone->setDeleteFlag(0);
$milestone->setEditFlag(0);
$milestone->setLockFlag(0);
$milestone->setStatus(1);
$em->persist($milestone);
}
}
}
$salesProposal->setProjectCreated(1);
$salesProposal->setProjectId($projectId);
$em->flush();
$retData['success'] = true;
$retData['projectId'] = $projectId;
$retData['redirectUrl'] = $this->generateUrl('view_project_details') . '/' . $projectId;
}
}
return new JsonResponse($retData);
}
// S3.1 — Material Readiness Dashboard
public function MaterialReadinessDashboardAction(Request $request, $id = 0)
{
$em = $this->getDoctrine()->getManager();
$companyId = $this->getLoggedUserCompanyId($request);
if ($id == 0) {
return $this->redirect($this->generateUrl('project_list'));
}
$projectData = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(
['projectId' => $id]
);
if (!$projectData) {
return $this->redirect($this->generateUrl('project_list'));
}
$readiness = ProjectM::getMaterialReadiness($em, $id, $companyId);
return $this->render('@Project/pages/views/material_readiness_dashboard.html.twig', [
'page_title' => 'Material Readiness — ' . $projectData->getProjectName(),
'projectData' => $projectData,
'items' => $readiness['items'],
'kpi' => $readiness['kpi'],
'projectId' => $id,
]);
}
// =========================================================================
// S4.1 — Project Requirement Register
// =========================================================================
public function CreateRequirementAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$loginId = $session->get('loginId');
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$error = '';
$success = '';
if ($request->isMethod('POST')) {
$result = ProjectM::saveRequirement($em, $request->request->all(), $projectId, $companyId, $loginId);
if ($result['success']) {
return $this->redirect($this->generateUrl('project_requirement_view', ['id' => $result['requirementId']]));
}
$error = $result['msg'];
}
return $this->render('@Project/pages/input_forms/create_requirement.html.twig', [
'page_title' => 'New Requirement — ' . $project->getProjectName(),
'project' => $project,
'projectId' => $projectId,
'error' => $error,
]);
}
public function ViewRequirementAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getRequirementById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/views/view_requirement.html.twig', [
'page_title' => 'Requirement — ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
public function ListRequirementsAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$list = ProjectM::getRequirementList($em, $projectId, $companyId);
return $this->render('@Project/pages/listing/list_requirements.html.twig', [
'page_title' => 'Requirements — ' . $project->getProjectName(),
'project' => $project,
'list' => $list,
'projectId' => $projectId,
]);
}
public function PrintRequirementAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getRequirementById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/print/print_requirement.html.twig', [
'page_title' => 'Requirement ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
// =========================================================================
// S4.2 — Interface Matrix
// =========================================================================
public function CreateInterfaceAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$loginId = $session->get('loginId');
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$error = '';
if ($request->isMethod('POST')) {
$result = ProjectM::saveInterface($em, $request->request->all(), $projectId, $companyId, $loginId);
if ($result['success']) {
return $this->redirect($this->generateUrl('project_interface_view', ['id' => $result['interfaceId']]));
}
$error = $result['msg'];
}
return $this->render('@Project/pages/input_forms/create_interface.html.twig', [
'page_title' => 'New Interface — ' . $project->getProjectName(),
'project' => $project,
'projectId' => $projectId,
'error' => $error,
]);
}
public function ViewInterfaceAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getInterfaceById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/views/view_interface.html.twig', [
'page_title' => 'Interface — ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
public function ListInterfacesAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$list = ProjectM::getInterfaceList($em, $projectId, $companyId);
return $this->render('@Project/pages/listing/list_interfaces.html.twig', [
'page_title' => 'Interface Matrix — ' . $project->getProjectName(),
'project' => $project,
'list' => $list,
'projectId' => $projectId,
]);
}
public function PrintInterfaceAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getInterfaceById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/print/print_interface.html.twig', [
'page_title' => 'Interface ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
// =========================================================================
// S4.3 — Project Device & Protocol Library
// =========================================================================
public function CreateDeviceAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$loginId = $session->get('loginId');
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$error = '';
if ($request->isMethod('POST')) {
$result = ProjectM::saveDevice($em, $request->request->all(), $projectId, $companyId, $loginId);
if ($result['success']) {
return $this->redirect($this->generateUrl('project_device_view', ['id' => $result['deviceId']]));
}
$error = $result['msg'];
}
return $this->render('@Project/pages/input_forms/create_device.html.twig', [
'page_title' => 'New Device — ' . $project->getProjectName(),
'project' => $project,
'projectId' => $projectId,
'error' => $error,
]);
}
public function ViewDeviceAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getDeviceById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/views/view_device.html.twig', [
'page_title' => 'Device — ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
public function ListDevicesAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$list = ProjectM::getDeviceList($em, $projectId, $companyId);
return $this->render('@Project/pages/listing/list_devices.html.twig', [
'page_title' => 'Device Library — ' . $project->getProjectName(),
'project' => $project,
'list' => $list,
'projectId' => $projectId,
]);
}
public function PrintDeviceAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getDeviceById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/print/print_device.html.twig', [
'page_title' => 'Device ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
// =========================================================================
// S4.4 — Configuration Baseline
// =========================================================================
public function CreateConfigBaselineAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$loginId = $session->get('loginId');
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$error = '';
if ($request->isMethod('POST')) {
$result = ProjectM::saveConfigBaseline($em, $request->request->all(), $projectId, $companyId, $loginId);
if ($result['success']) {
return $this->redirect($this->generateUrl('project_config_baseline_view', ['id' => $result['baselineId']]));
}
$error = $result['msg'];
}
return $this->render('@Project/pages/input_forms/create_config_baseline.html.twig', [
'page_title' => 'New Configuration Baseline — ' . $project->getProjectName(),
'project' => $project,
'projectId' => $projectId,
'error' => $error,
]);
}
public function ViewConfigBaselineAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getConfigBaselineById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/views/view_config_baseline.html.twig', [
'page_title' => 'Baseline — ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
public function ListConfigBaselinesAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$list = ProjectM::getConfigBaselineList($em, $projectId, $companyId);
return $this->render('@Project/pages/listing/list_config_baselines.html.twig', [
'page_title' => 'Configuration Baselines — ' . $project->getProjectName(),
'project' => $project,
'list' => $list,
'projectId' => $projectId,
]);
}
public function PrintConfigBaselineAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getConfigBaselineById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/print/print_config_baseline.html.twig', [
'page_title' => 'Baseline ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
// =========================================================================
// S4.5 — FAT/SAT/UAT/SIT Test Cases
// =========================================================================
public function CreateTestCaseAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$loginId = $session->get('loginId');
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$error = '';
if ($request->isMethod('POST')) {
$result = ProjectM::saveTestCase($em, $request->request->all(), $projectId, $companyId, $loginId);
if ($result['success']) {
return $this->redirect($this->generateUrl('project_test_case_view', ['id' => $result['testCaseId']]));
}
$error = $result['msg'];
}
$requirements = ProjectM::getRequirementList($em, $projectId, $companyId);
return $this->render('@Project/pages/input_forms/create_test_case.html.twig', [
'page_title' => 'New Test Case — ' . $project->getProjectName(),
'project' => $project,
'projectId' => $projectId,
'requirements' => $requirements,
'error' => $error,
]);
}
public function ViewTestCaseAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getTestCaseById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/views/view_test_case.html.twig', [
'page_title' => 'Test Case — ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
public function ListTestCasesAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($projectId);
if (!$project) return $this->redirect($this->generateUrl('project_list'));
$phase = $request->query->get('phase', null);
$list = ProjectM::getTestCaseList($em, $projectId, $companyId, $phase);
return $this->render('@Project/pages/listing/list_test_cases.html.twig', [
'page_title' => 'Test Cases — ' . $project->getProjectName(),
'project' => $project,
'list' => $list,
'projectId' => $projectId,
'phase' => $phase,
]);
}
public function PrintTestCaseAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$em = $this->getDoctrine()->getManager();
$entity = ProjectM::getTestCaseById($em, $id);
if (!$entity) return $this->redirect($this->generateUrl('project_list'));
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->find($entity->getProjectId());
return $this->render('@Project/pages/print/print_test_case.html.twig', [
'page_title' => 'Test Case ' . $entity->getDocumentHash(),
'entity' => $entity,
'project' => $project,
]);
}
public function ExecuteTestCaseAction(Request $request, $id)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) return $this->redirectToLogin($request);
$loginId = $session->get('loginId');
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
ProjectM::executeTestCase($em, $request->request->all(), $id, $loginId);
}
return $this->redirect($this->generateUrl('project_test_case_view', ['id' => $id]));
}
// =========================================================================
// S4.5 — Invoice Milestone Warning (JSON endpoint)
// Called before issuing a project-linked invoice to check for unmet milestones
// =========================================================================
public function CheckInvoiceMilestonesAction(Request $request, $projectId)
{
$session = $request->getSession();
if (!$this->checkLogin($request)) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'Not authenticated']);
}
$companyId = $session->get('loginCompanyId');
$em = $this->getDoctrine()->getManager();
// Find test cases that are invoice-milestone-triggering but NOT yet passed
$allTc = ProjectM::getTestCaseList($em, $projectId, $companyId);
$blocking = [];
foreach ($allTc as $tc) {
if ($tc->getInvoiceMilestoneTrigger() && !in_array($tc->getTestStatus(), ['pass', 'approved'])) {
$blocking[] = [
'testCaseId' => $tc->getTestCaseId(),
'testCode' => $tc->getTestCode(),
'title' => $tc->getTitle(),
'testPhase' => $tc->getTestPhase(),
'testStatus' => $tc->getTestStatus(),
];
}
}
return new \Symfony\Component\HttpFoundation\JsonResponse([
'success' => true,
'canInvoice' => count($blocking) === 0,
'blockingCount' => count($blocking),
'blocking' => $blocking,
'warning' => count($blocking) > 0
? count($blocking) . ' invoice-milestone test case(s) have not yet passed. Consider completing them before issuing this invoice.'
: '',
]);
}
// S7 — Milestone actions. Auth handled by SessionCheckInterface listener.
public function ProjectMilestoneSaveAction(Request $request, $projectId)
{
$session = $request->getSession();
$companyId = $session->get('loginCompanyId');
$loginId = $session->get(UserConstants::USER_LOGIN_ID);
$userId = $session->get(UserConstants::USER_ID);
$em = $this->getDoctrine()->getManager();
$data = $request->request->all();
$newId = ProjectM::SaveProjectMilestone($em, $data, $projectId, $companyId, $loginId, $userId);
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'id' => $newId]);
}
public function ProjectMilestoneDeleteAction(Request $request, $projectId, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ApplicationBundle\\Entity\\ProjectMilestone')->findOneBy(['projectMilestoneId' => $id]);
if ($entity) {
$entity->setDeleteFlag(1);
$em->flush();
}
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
}
public function ProjectMilestoneCompleteAction(Request $request, $projectId, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ApplicationBundle\\Entity\\ProjectMilestone')->findOneBy(['projectMilestoneId' => $id]);
if ($entity) {
$entity->setActualDate(new \DateTime());
$entity->setMilestoneStatus('completed');
$entity->setCompletionPercentage(100);
$em->flush();
}
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
}
// ── Time & Materials (work-hour) billing ─────────────────────────────────
// Config + preview + bill-now for service/BPO projects billed by the hour.
public function ProjectTmBillingAction(Request $request, $projectId)
{
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('ApplicationBundle\\Entity\\Project')->findOneBy(['projectId' => (int) $projectId]);
if (!$project) {
return new \Symfony\Component\HttpFoundation\Response('Project not found', 404);
}
$mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
$config = $mgr->getConfig($projectId);
$preview = $mgr->getPreview($projectId);
$salesOrders = $em->getRepository('ApplicationBundle\\Entity\\SalesOrder')
->findBy(['projectId' => (int) $projectId], ['salesOrderId' => 'ASC']);
$soList = [];
foreach ($salesOrders as $so) {
$soList[] = ['id' => $so->getSalesOrderId(), 'hash' => $so->getDocumentHash()];
}
return $this->render('@Project/pages/views/tm_billing.html.twig', [
'projectId' => (int) $projectId,
'projectName' => $project->getProjectName(),
'config' => $config,
'preview' => $preview,
'salesOrders' => $soList,
'currencyList' => \ApplicationBundle\Modules\Inventory\Inventory::CurrencyList($em),
]);
}
public function ProjectTmBillingSaveAction(Request $request, $projectId)
{
$session = $request->getSession();
$loginId = $session->get(UserConstants::USER_LOGIN_ID);
$em = $this->getDoctrine()->getManager();
$mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
$data = [
'enabled' => $request->request->get('enabled', 0),
'hourlyRate' => $request->request->get('hourlyRate', 0),
'currencyId' => $request->request->get('currencyId', ''),
'primarySalesOrderId' => $request->request->get('primarySalesOrderId', ''),
'billingIntervalDays' => $request->request->get('billingIntervalDays', 30),
'requireApprovedHours' => $request->request->get('requireApprovedHours', 1),
'note' => $request->request->get('note', ''),
];
$mgr->saveConfig($projectId, $data, $loginId);
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'preview' => $mgr->getPreview($projectId)]);
}
public function ProjectTmBillingPreviewAction(Request $request, $projectId)
{
$em = $this->getDoctrine()->getManager();
$mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'preview' => $mgr->getPreview($projectId)]);
}
public function ProjectTmBillingBillNowAction(Request $request, $projectId)
{
$session = $request->getSession();
$loginId = $session->get(UserConstants::USER_LOGIN_ID);
$em = $this->getDoctrine()->getManager();
$mgr = new \ApplicationBundle\Modules\Sales\TimeAndMaterialBillingManager($em);
$result = $mgr->runBilling($projectId, $loginId, $request->request->get('until', null));
return new \Symfony\Component\HttpFoundation\JsonResponse($result);
}
// ── Proposal Cost Sheet (budgeted margin) ────────────────────────────────
// Live recompute (no save) — for the editable panel's instant feedback.
public function ProposalCostSheetComputeAction(Request $request)
{
$inputs = json_decode($request->request->get('costSheet', '{}'), true) ?: [];
return new \Symfony\Component\HttpFoundation\JsonResponse([
'success' => true,
'computed' => \ApplicationBundle\Modules\Project\Service\CostSheetCalculator::compute($inputs),
]);
}
// Find-or-create the project's dedicated cost-sheet DocumentData row.
private function resolveCostSheetDoc($em, $projectId, $companyId = 1)
{
$dd = $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
->findOneBy(['projectId' => (int) $projectId, 'dataType' => 'cost_sheet']);
if (!$dd) {
$dd = new \ApplicationBundle\Entity\DocumentData();
$dd->setProjectId((int) $projectId);
$dd->setDataType('cost_sheet');
$dd->setEntity('cost_sheet');
$dd->setCompanyId($companyId);
$dd->setData('{}');
$dd->setCreatedAt(new \DateTime('now'));
$em->persist($dd);
}
return $dd;
}
// A dedicated cost_sheet DocumentData keyed by the PROPOSAL's documentDataId
// (distinct dataType so it never collides with the legacy projectId-keyed one,
// and — critically — it NEVER pollutes the proposal's own DocumentData/entries).
private function resolveCostSheetDocByDd($em, $proposalDdId, $companyId = 1)
{
$dd = $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
->findOneBy(['projectId' => (int) $proposalDdId, 'dataType' => 'cost_sheet_dd']);
if (!$dd) {
$dd = new \ApplicationBundle\Entity\DocumentData();
$dd->setProjectId((int) $proposalDdId);
$dd->setDataType('cost_sheet_dd');
$dd->setEntity('cost_sheet');
$dd->setCompanyId($companyId);
$dd->setData('{}');
$dd->setCreatedAt(new \DateTime('now'));
$em->persist($dd);
}
return $dd;
}
// Persist the cost-sheet inputs + computed result into a SEPARATE cost_sheet doc
// (keyed by the proposal's documentDataId, or by projectId for the legacy view).
// It is never stored inside the proposal's own DocumentData (that would corrupt
// the proposal entry list → 500 on view + data reset on re-save).
public function ProposalCostSheetSaveAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$ddId = (int) $request->request->get('documentDataId', 0);
$projectId = (int) $request->request->get('projectId', 0);
$inputs = json_decode($request->request->get('costSheet', '{}'), true) ?: [];
$computed = \ApplicationBundle\Modules\Project\Service\CostSheetCalculator::compute($inputs);
if ($ddId > 0) {
$dd = $this->resolveCostSheetDocByDd($em, $ddId, (int) $this->getLoggedUserCompanyId($request));
} elseif ($projectId > 0) {
$dd = $this->resolveCostSheetDoc($em, $projectId, (int) $this->getLoggedUserCompanyId($request));
} else {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'message' => 'documentDataId or projectId is required.']);
}
$dd->setData(json_encode(['inputs' => $inputs, 'computed' => $computed]));
$em->flush();
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'computed' => $computed]);
}
// GET the saved cost sheet for a proposal documentDataId (panel loads on init).
public function ProposalCostSheetGetAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$ddId = (int) $request->query->get('documentDataId', 0);
$data = null;
if ($ddId > 0) {
$dd = $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
->findOneBy(['projectId' => $ddId, 'dataType' => 'cost_sheet_dd']);
$data = $dd ? (json_decode((string) $dd->getData(), true) ?: null) : null;
}
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'costSheet' => $data]);
}
// S7 — Project Cost actions. Auth handled by SessionCheckInterface listener.
public function ProjectCostSaveAction(Request $request, $projectId)
{
$session = $request->getSession();
$companyId = $session->get('loginCompanyId');
$loginId = $session->get(UserConstants::USER_LOGIN_ID);
$userId = $session->get(UserConstants::USER_ID);
$em = $this->getDoctrine()->getManager();
$data = $request->request->all();
$newId = ProjectM::SaveProjectCost($em, $data, $projectId, $companyId, $loginId, $userId);
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true, 'id' => $newId]);
}
public function ProjectCostDeleteAction(Request $request, $projectId, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ApplicationBundle\\Entity\\ProjectCost')->findOneBy(['projectCostId' => $id]);
if ($entity) {
$entity->setDeleteFlag(1);
$em->flush();
}
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
}
// S8 — Project Public Share admin actions. Auth handled by SessionCheckInterface.
// The PUBLIC view (no-auth, /p/project/{id}) lives in PublicPagesController, not here,
// so this controller can stay session-only (DB connection, login, app context).
public function ProjectPublicShareCreateAction(Request $request, $projectId)
{
$session = $request->getSession();
$companyId = $session->get('loginCompanyId');
$loginId = $session->get(UserConstants::USER_LOGIN_ID);
$userId = $session->get(UserConstants::USER_ID);
$appId = $session->get(UserConstants::USER_APP_ID);
$em = $this->getDoctrine()->getManager();
$share = new \ApplicationBundle\Entity\ProjectPublicShare();
$share->setProjectId($projectId);
$share->setCompanyId($companyId);
$share->setShareToken(ProjectM::GenerateShareToken());
$share->setShareTitle($request->request->get('shareTitle', 'Project Progress'));
$expiry = $request->request->get('expiryDate', '');
if ($expiry) $share->setExpiryDate(new \DateTime($expiry));
$share->setIsActive(1);
$share->setViewCount(0);
$share->setSettingsData($request->request->get('settingsData', '{}'));
$share->setDeleteFlag(0);
$share->setEditFlag(1);
$share->setStatus(1);
$share->setStage(0);
$share->setApproved(0);
$share->setCreatedUserId($userId);
$share->setCreatedLoginId($loginId);
$em->persist($share);
$em->flush();
// Build encrypted URL payload — same pattern as PaymentVoucherPublicView.
// Token is embedded so regeneration invalidates old links.
$payload = json_encode([
'id' => $share->getProjectPublicShareId(),
'appId' => $appId,
't' => $share->getShareToken(),
'dt' => date('Y-m-d'),
]);
$encrypted = $this->get('url_encryptor')->encrypt($payload);
$publicUrl = $request->getSchemeAndHttpHost() . $this->generateUrl('public_project_view', ['id' => $encrypted]);
return new \Symfony\Component\HttpFoundation\JsonResponse([
'success' => true,
'id' => $share->getProjectPublicShareId(),
'url' => $publicUrl,
]);
}
public function ProjectPublicShareUpdateAction(Request $request, $projectId, $id)
{
$em = $this->getDoctrine()->getManager();
$share = $em->getRepository('ApplicationBundle\\Entity\\ProjectPublicShare')->findOneBy(
['projectPublicShareId' => $id, 'projectId' => $projectId]
);
if (!$share) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false, 'msg' => 'not found']);
}
if ($request->request->has('shareTitle')) $share->setShareTitle($request->request->get('shareTitle'));
if ($request->request->has('expiryDate')) {
$exp = $request->request->get('expiryDate');
$share->setExpiryDate($exp ? new \DateTime($exp) : null);
}
if ($request->request->has('isActive')) $share->setIsActive((int)$request->request->get('isActive'));
if ($request->request->has('settingsData')) $share->setSettingsData($request->request->get('settingsData'));
$em->flush();
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
}
public function ProjectPublicShareRevokeAction(Request $request, $projectId, $id)
{
$em = $this->getDoctrine()->getManager();
$share = $em->getRepository('ApplicationBundle\\Entity\\ProjectPublicShare')->findOneBy(
['projectPublicShareId' => $id, 'projectId' => $projectId]
);
if ($share) {
$share->setIsActive(0);
$share->setDeleteFlag(1);
$em->flush();
}
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => true]);
}
public function ProjectPublicShareRegenerateAction(Request $request, $projectId, $id)
{
$session = $request->getSession();
$appId = $session->get(UserConstants::USER_APP_ID);
$em = $this->getDoctrine()->getManager();
$share = $em->getRepository('ApplicationBundle\\Entity\\ProjectPublicShare')->findOneBy(
['projectPublicShareId' => $id, 'projectId' => $projectId]
);
if (!$share) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['success' => false]);
}
$share->setShareToken(ProjectM::GenerateShareToken());
$share->setViewCount(0);
$em->flush();
$payload = json_encode([
'id' => $share->getProjectPublicShareId(),
'appId' => $appId,
't' => $share->getShareToken(),
'dt' => date('Y-m-d'),
]);
$encrypted = $this->get('url_encryptor')->encrypt($payload);
$publicUrl = $request->getSchemeAndHttpHost() . $this->generateUrl('public_project_view', ['id' => $encrypted]);
return new \Symfony\Component\HttpFoundation\JsonResponse([
'success' => true,
'url' => $publicUrl,
]);
}
private function isProjectSurfaceSplitEnabled()
{
if (!isset($this->container)) {
return false;
}
foreach (['project.surface_split', 'project_surface_split'] as $paramName) {
if ($this->container->hasParameter($paramName)) {
return (bool)$this->container->getParameter($paramName);
}
}
return false;
}
}