src/ApplicationBundle/Controller/DashboardController.php line 2126

Open in your IDE?
  1. <?php
  2. namespace ApplicationBundle\Controller;
  3. use ApplicationBundle\Constants\GeneralConstant;
  4. use ApplicationBundle\Constants\HumanResourceConstant;
  5. use ApplicationBundle\Entity\DashboardWidget;
  6. use ApplicationBundle\Entity\Employee;
  7. use ApplicationBundle\Entity\EmployeeDetails;
  8. use ApplicationBundle\Entity\SysUser;
  9. use ApplicationBundle\Interfaces\SessionCheckInterface;
  10. use ApplicationBundle\Modules\Accounts\Accounts;
  11. use ApplicationBundle\Modules\Authentication\Constants\UserConstants; use ApplicationBundle\Modules\Api\Constants\ApiConstants;
  12. use ApplicationBundle\Modules\HumanResource\HumanResource;
  13. use ApplicationBundle\Modules\Inventory\Inventory;
  14. use ApplicationBundle\Modules\Purchase\Supplier;
  15. use ApplicationBundle\Modules\Sales\Client;
  16. use ApplicationBundle\Modules\System\Support\PeriodFilterCore;
  17. use ApplicationBundle\Modules\System\MiscActions;
  18. use ApplicationBundle\Modules\System\System;
  19. use ApplicationBundle\Modules\User\Company;
  20. use ApplicationBundle\Modules\User\Position;
  21. use ApplicationBundle\Modules\User\Users;
  22. use CompanyGroupBundle\Entity\CompanyGroup;
  23. use CompanyGroupBundle\Entity\EntityApplicantApplicationList;
  24. use CompanyGroupBundle\Entity\EntityApplicantDetails;
  25. use CompanyGroupBundle\Entity\EntityTicket;
  26. use Symfony\Component\BrowserKit\Client as BrowserClientKit;
  27. use Symfony\Component\Debug\Exception\FlattenException;
  28. use Symfony\Component\HttpFoundation\JsonResponse;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpFoundation\Response;
  31. use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
  32. use Symfony\Component\Routing\Generator\UrlGenerator;
  33. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  34. class DashboardController extends GenericController implements SessionCheckInterface
  35. {
  36.     private function getPublicDocumentEntityManager($appId)
  37.     {
  38.         $emGoc $this->getDoctrine()->getManager('company_group');
  39.         $emGoc->getConnection()->connect();
  40.         $goc $emGoc
  41.             ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  42.             ->findOneBy(
  43.                 array(
  44.                     'appId' => $appId
  45.                 )
  46.             );
  47.         if (!$goc) {
  48.             return array(nullnull);
  49.         }
  50.         $connector $this->container->get('application_connector');
  51.         $connector->resetConnection(
  52.             'default',
  53.             $goc->getDbName(),
  54.             $goc->getDbUser(),
  55.             $goc->getDbPass(),
  56.             $goc->getDbHost(),
  57.             $reset true
  58.         );
  59.         return array($this->getDoctrine()->getManager(), $goc);
  60.     }
  61.     private function buildAllocationAwareTransactionSourceSql(array $filters = [])
  62.     {
  63.         $conn $this->getDoctrine()->getManager()->getConnection();
  64.         $conditions = [];
  65.         if (!empty($filters['document_type'])) {
  66.             $conditions[] = 't.document_type = ' . (int) $filters['document_type'];
  67.         }
  68.         if (!empty($filters['company_id'])) {
  69.             $conditions[] = 't.company_id = ' . (int) $filters['company_id'];
  70.         }
  71.         if (!empty($filters['start_date'])) {
  72.             $conditions[] = "t.ledger_hit_date >= " $conn->quote(date('Y-m-d'strtotime((string) $filters['start_date'])) . ' 00:00:00');
  73.         }
  74.         if (!empty($filters['end_date'])) {
  75.             $conditions[] = "t.ledger_hit_date <= " $conn->quote(date('Y-m-d'strtotime((string) $filters['end_date'])) . ' 23:59:59.999');
  76.         }
  77.         if (!empty($filters['client_head_ids'])) {
  78.             $conditions[] = 'td.accounts_head_id IN (' implode(','array_map('intval', (array) $filters['client_head_ids'])) . ')';
  79.         }
  80.         if (isset($filters['approved'])) {
  81.             $conditions[] = 't.approved = ' . (int) $filters['approved'];
  82.         } else {
  83.             $conditions[] = 't.approved = 1';
  84.         }
  85.         if (isset($filters['ledger_hit'])) {
  86.             $conditions[] = 't.ledger_hit = ' . (int) $filters['ledger_hit'];
  87.         } else {
  88.             $conditions[] = 't.ledger_hit = 1';
  89.         }
  90.         $whereSql = empty($conditions) ? '1=1' implode(' AND '$conditions);
  91.         return "(
  92.             SELECT td.transaction_details_id AS transaction_details_id,
  93.                    td.transaction_id,
  94.                    td.accounts_head_id,
  95.                    td.position,
  96.                    td.amount AS allocation_amount,
  97.                    td.ledger_hit_date,
  98.                    t.document_hash,
  99.                    t.company_id,
  100.                    t.document_type,
  101.                    1 AS has_allocation
  102.             FROM acc_transaction_details td
  103.             JOIN acc_transactions t ON t.transaction_id = td.transaction_id
  104.             JOIN transaction_detail_allocations tda ON tda.transaction_detail_id = td.transaction_details_id
  105.             WHERE " $whereSql "
  106.             UNION ALL
  107.             SELECT td.transaction_details_id AS transaction_details_id,
  108.                    td.transaction_id,
  109.                    td.accounts_head_id,
  110.                    td.position,
  111.                    td.amount AS allocation_amount,
  112.                    td.ledger_hit_date,
  113.                    t.document_hash,
  114.                    t.company_id,
  115.                    t.document_type,
  116.                    0 AS has_allocation
  117.             FROM acc_transaction_details td
  118.             JOIN acc_transactions t ON t.transaction_id = td.transaction_id
  119.             WHERE " $whereSql "
  120.               AND NOT EXISTS (
  121.                   SELECT 1
  122.                   FROM transaction_detail_allocations tda
  123.                   WHERE tda.transaction_detail_id = td.transaction_details_id
  124.               )
  125.         )";
  126.     }
  127.     public function doLoginAsAction(Request $request)
  128.     {
  129.         $session $request->getSession();
  130.         if ($request->isMethod('POST')) {
  131.             $session->set(UserConstants::USER_CURRENT_POSITION$request->request->get('position'));
  132.             $curr_position_id $request->request->get('position');
  133.             if ($session->get(UserConstants::USER_LOGIN_ID) != 0) {
  134.                 $loginID $this->get('user_module')->addUserLoginLog(
  135.                     $session->get(UserConstants::USER_ID),
  136.                     $request->server->get("REMOTE_ADDR"),
  137.                     $request->request->get('position'),
  138.                     '',
  139.                     '',
  140.                     '',
  141.                     $session->get(UserConstants::USER_LOGIN_ID)
  142.                 );
  143.             } else $loginID $this->get('user_module')->addUserLoginLog(
  144.                 $session->get(UserConstants::USER_ID),
  145.                 $request->server->get("REMOTE_ADDR"),
  146.                 $request->request->get('position'),
  147.                 '',
  148.                 '',
  149.                 '',
  150.                 0
  151.             );
  152.             if ($session->get(UserConstants::ALL_MODULE_ACCESS_FLAG) == 1)
  153.                 $prohibit_list_array = [];
  154.             else if ($curr_position_id != 0)
  155.                 $prohibit_list_array Position::getUserProhibitRouteArray($this->getDoctrine()->getManager(), $curr_position_id$session->get(UserConstants::USER_ID));
  156.             $session->set(UserConstants::USER_LOGIN_ID$loginID);
  157.             $session->set(UserConstants::USER_PROHIBIT_LISTjson_encode($prohibit_list_array));
  158.             $session->set(UserConstants::USER_ROUTE_LISTjson_encode(Position::getUserRouteArray($this->getDoctrine()->getManager(), $request->request->get('position'), $session->get(UserConstants::USER_ID))));
  159.             return $this->redirectToRoute("dashboard");
  160.         }
  161.         $message "";
  162.         $PositionList = array();
  163.         $PL json_decode($session->get(UserConstants::USER_POSITION_LIST), true);
  164.         foreach ($PL as &$positionID) {
  165.             $PositionList[$positionID] = Position::getPositionName($this->getDoctrine()->getManager(), $positionID);
  166.         }
  167.         return $this->render(
  168.             '@Authentication/pages/views/login_position.html.twig',
  169.             array(
  170.                 "message" => $message,
  171.                 'page_title' => 'Users',
  172.                 'position_list' => $PositionList
  173.             )
  174.         );
  175.     }
  176.     //    protected $twig;
  177.     //    protected $debug;
  178.     //
  179.     //    /**
  180.     //     * @param bool $debug Show error (false) or exception (true) pages by default
  181.     //     */
  182.     //    public function __construct(Environment $twig, $debug)
  183.     //    {
  184.     //        $this->twig = $twig;
  185.     //        $this->debug = $debug;
  186.     //    }
  187.     public function TestSmsAction(Request $request)
  188.     {
  189.         $em $this->getDoctrine()->getManager();
  190.         $session $request->getSession();
  191.         $em $this->getDoctrine()->getManager();
  192.         $userAppId $session->get('userAppId');
  193.         $companyId $session->get('userCompanyId');
  194.         if (GeneralConstant::SMS_ENABLED == 1) {
  195.             $company $em->getRepository('ApplicationBundle\\Entity\\Company')->findOneBy(
  196.                 array(
  197.                     'id' => $companyId///material
  198.                 )
  199.             );
  200.             if ($company->getSmsNotificationEnabled() == 1) {
  201.                 $smsData = [];
  202.                 $smsSettings json_decode($company->getSmsSettings(), true);
  203.                 if ($smsSettings != null && !empty($smsSettings)) {
  204.                     $method = isset($smsSettings['method']) ? $smsSettings['method'] : 'GET';
  205.                     $destination_url = isset($smsSettings['destination_url']) ? $smsSettings['destination_url'] : 'http://172.105.70.96:1234';
  206.                     $user_name = isset($smsSettings['user_name']) ? $smsSettings['user_name'] : 'test';
  207.                     $user_name_var = isset($smsSettings['user_name_var']) ? $smsSettings['user_name_var'] : 'Username';
  208.                     $password_var = isset($smsSettings['password_var']) ? $smsSettings['password_var'] : 'Password';
  209.                     $password = isset($smsSettings['password']) ? $smsSettings['password'] : '';
  210.                     $from_number_var = isset($smsSettings['from_number_var']) ? $smsSettings['from_number_var'] : 'From';
  211.                     $from_number = isset($smsSettings['from_number']) ? $smsSettings['from_number'] : '';
  212.                     $to_number_var = isset($smsSettings['to_number_var']) ? $smsSettings['to_number_var'] : 'To';
  213.                     $to_number $request->query->has('To') ? $request->query->get('To') : '01911706483';
  214.                     $text_var = isset($smsSettings['text_var']) ? $smsSettings['text_var'] : 'Message';
  215.                     $text $request->query->has('Message') ? $request->query->get('Message') : 'Test message';
  216.                     return new JsonResponse(System::sendSms(
  217.                         1,
  218.                         $method,
  219.                         $destination_url,
  220.                         $user_name_var,
  221.                         $user_name,
  222.                         $password_var,
  223.                         $password,
  224.                         $from_number_var,
  225.                         $from_number,
  226.                         $to_number_var,
  227.                         $to_number,
  228.                         $text_var,
  229.                         $text,
  230.                         $viewlink ""
  231.                     ));
  232.                 }
  233.             }
  234.             return new JsonResponse(
  235.                 [
  236.                     'companyId' => $companyId,
  237.                     'companyName' => $company->getName(),
  238.                     'enabled' => $company->getSmsNotificationEnabled(),
  239.                     //                    'smsSettings'=>$smsSettings
  240.                 ]
  241.             );
  242.         }
  243.         return new JsonResponse(
  244.             [
  245.                 'success' => false
  246.             ]
  247.         );
  248.     }
  249.     public function SyncCompanyProductToEntityProductAction(Request $request)
  250.     {
  251.         $gocId $request->query->has('gocId') ? $request->query->get('gocId') : 0;
  252.         $companyId $request->query->has('companyId') ? $request->query->get('companyId') : 1;
  253.         $genQueryArray = [];
  254.         $em_goc $this->getDoctrine()->getManager('company_group');
  255.         $em_goc->getConnection()->connect();
  256.         $em $this->getDoctrine()->getManager();
  257.         if ($request->query->has('forceRefresh')) {
  258.             $genQueryArray = [];
  259.             $query "
  260.             TRUNCATE `entity_brand_company`;
  261.             TRUNCATE `entity_item_group`;
  262.             TRUNCATE `entity_products`;
  263.             TRUNCATE `entity_product_categories`;
  264.             TRUNCATE `entity_product_specifications`;
  265.             TRUNCATE `entity_product_sub_categories`;
  266.             TRUNCATE `entity_specification_types`;
  267.             TRUNCATE `entity_unit_type`;
  268.             SELECT * from `entity_unit_type`;";
  269.             $stmt $em_goc->getConnection()->executeStatement($query);
  270.             
  271.             //            $Transactions = $stmt;
  272.             $get_kids_sql 'select * from acc_accounts_head where accounts_head_id not in (select distinct parent_id from acc_accounts_head) ;';
  273.             //UPDATE company SET sales=0, expense=0, payable=0 ,net_worth=0, monthly_growth=0 WHERE 1;';
  274.             $stmt $em->getConnection()->executeStatement($get_kids_sql);
  275.             
  276.             $query $stmt;
  277.         } else
  278.             $genQueryArray = ['globalId' => [0null]];
  279.         //1st step get all company item ids and then check for global id null if its null then the
  280.         // item group is not present in entity so add it
  281.         $company_wise_entities = [
  282.             'Currencies',
  283.             'UnitType',
  284.             'SpecType',
  285.             'BrandCompany',
  286.             'InvItemGroup',
  287.             'InvProductCategories',
  288.             'InvProductSubCategories',
  289.             'InvProductSpecifications',
  290.             'InvSpecificationTypes',
  291.             'InvProducts'
  292.         ];
  293.         $entity_wise_entities = [
  294.             'EntityCurrencies',
  295.             'EntityUnitType',
  296.             'EntitySpecType',
  297.             'EntityBrandCompany',
  298.             'EntityItemGroup',
  299.             'EntityProductCategories',
  300.             'EntityProductSubCategories',
  301.             'EntityProductSpecifications',
  302.             'EntitySpecificationTypes',
  303.             'EntityProducts'
  304.         ];
  305.         ////ITEMGROUPS
  306.         foreach ($company_wise_entities as $k => $cwa) {
  307.             $dataOnCompany $em
  308.                 ->getRepository("ApplicationBundle\\Entity\\" $cwa)
  309.                 ->findBy(
  310.                     $genQueryArray
  311.                 );
  312.             $match_cid_gid_itemgroup = [];  //[cid=>gid]
  313.             $match_cid_gid_itemgroup = [];  //[cid=>gid]
  314.             foreach ($dataOnCompany as $data) {
  315.                 $newClass "\\CompanyGroupBundle\\Entity\\" $entity_wise_entities[$k];
  316.                 $new = new $newClass();
  317.                 //                $new = new \CompanyGroupBundle\Entity\EntityItemGroup();
  318.                 $getters array_filter(get_class_methods($data), function ($method) {
  319.                     return 'get' === substr($method03);
  320.                 });
  321.                 foreach ($getters as $getter) {
  322.                     if ($getter == 'getGlobalId')
  323.                         continue;
  324.                     //                    if ($getter == 'getId')
  325.                     //                        continue;
  326.                     $setMethod str_replace('get''set'$getter);
  327.                     if (method_exists($new$setMethod))
  328.                         $new->{$setMethod}($data->{$getter}()); // `foo!`
  329.                 }
  330.                 $em_goc->persist($new);
  331.                 $em_goc->flush();
  332.                 if ($cwa == 'Currencies') {
  333.                     $data->setGlobalId($new->getCurrencyId());
  334.                     $new->setGlobalId($new->getCurrencyId());
  335.                 } else {
  336.                     $data->setGlobalId($new->getId());
  337.                     $new->setGlobalId($new->getId());
  338.                 }
  339.                 $em->flush();
  340.                 $em_goc->flush();
  341.                 //                $match_cid_gid_itemgroup[$data->getId()] = $new->getId();
  342.             }
  343.         }
  344.         return new JsonResponse(
  345.             array(
  346.                 'data' => $entity_wise_entities
  347.             )
  348.         );
  349.     }
  350.     public function SyncEntityProductToCompanyProductAction(Request $request)
  351.     {
  352.         $gocId $request->query->has('gocId') ? $request->query->get('gocId') : 0;
  353.         $companyId $request->query->has('companyId') ? $request->query->get('companyId') : 1;
  354.         $genQueryArray = [];
  355.         $em_goc $this->getDoctrine()->getManager('company_group');
  356.         $em_goc->getConnection()->connect();
  357.         $em $this->getDoctrine()->getManager();
  358.         if ($request->query->has('forceRefresh')) {
  359.             $genQueryArray = [];
  360.             $query "
  361.             TRUNCATE `brand_company`;
  362.             TRUNCATE `inv_item_group`;
  363.             TRUNCATE `inv_products`;
  364.             TRUNCATE `inv_product_categories`;
  365.             TRUNCATE `inv_product_specifications`;
  366.             TRUNCATE `inv_product_sub_categories`;
  367.             TRUNCATE `inv_specification_types`;
  368.             TRUNCATE `unit_type`;
  369.             SELECT * from `unit_type`;";
  370.             $stmt $em->getConnection()->executeStatement($query);
  371.             
  372.             //            $Transactions = $stmt;
  373.             $get_kids_sql 'select * from acc_accounts_head where accounts_head_id not in (select distinct parent_id from acc_accounts_head) ;';
  374.             //UPDATE company SET sales=0, expense=0, payable=0 ,net_worth=0, monthly_growth=0 WHERE 1;';
  375.             $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql);
  376.             
  377.             $query $stmt;
  378.         } else {
  379.             //            $genQueryArray = ['globalId' => [0, null]];
  380.         }
  381.         //1st step get all company item ids and then check for global id null if its null then the
  382.         // item group is not present in entity so add it
  383.         $company_wise_entities = [
  384.             'Currencies',
  385.             'UnitType',
  386.             'SpecType',
  387.             'BrandCompany',
  388.             'InvItemGroup',
  389.             'InvProductCategories',
  390.             'InvProductSubCategories',
  391.             'InvProductSpecifications',
  392.             'InvSpecificationTypes',
  393.             'InvProducts'
  394.         ];
  395.         $entity_wise_entities = [
  396.             'EntityCurrencies',
  397.             'EntityUnitType',
  398.             'EntitySpecType',
  399.             'EntityBrandCompany',
  400.             'EntityItemGroup',
  401.             'EntityProductCategories',
  402.             'EntityProductSubCategories',
  403.             'EntityProductSpecifications',
  404.             'EntitySpecificationTypes',
  405.             'EntityProducts'
  406.         ];
  407.         foreach ($entity_wise_entities as $k => $ewa) {
  408.             $dataOnEntity $em_goc
  409.                 ->getRepository("CompanyGroupBundle\\Entity\\" $ewa)
  410.                 ->findBy(
  411.                     $genQueryArray
  412.                 );
  413.             $match_cid_gid_itemgroup = [];  //[cid=>gid]
  414.             $match_cid_gid_itemgroup = [];  //[cid=>gid]
  415.             foreach ($dataOnEntity as $data) {
  416.                 $newClass "\\ApplicationBundle\\Entity\\" $company_wise_entities[$k];
  417.                 $rec_exists 0;
  418.                 $new $em
  419.                     ->getRepository("ApplicationBundle\\Entity\\" $company_wise_entities[$k])
  420.                     ->findOneBy(
  421.                         array(
  422.                             'globalId' => $data->getGlobalId()
  423.                         )
  424.                     );
  425.                 if ($new) {
  426.                     $rec_exists 1;
  427.                 } else
  428.                     $new = new $newClass();
  429.                 //                $new = new \CompanyGroupBundle\Entity\EntityItemGroup();
  430.                 $getters array_filter(get_class_methods($data), function ($method) {
  431.                     return 'get' === substr($method03);
  432.                 });
  433.                 foreach ($getters as $getter) {
  434.                     if ($getter == 'getId')
  435.                         continue;
  436.                     $setMethod str_replace('get''set'$getter);
  437.                     if (method_exists($new$setMethod)) {
  438.                         if ($ewa == 'EntityProducts') {
  439.                             if ($rec_exists == 1) {
  440.                                 if (in_array($setMethod, [
  441.                                     'setPurchasePrice',
  442.                                     'setPurchasePriceWoExpense',
  443.                                     'setQty',
  444.                                     'setReorderLevel',
  445.                                     'setBookingQty',
  446.                                     'setNonSalesInvoicedQty',
  447.                                     'setNonSalesReturnReceivedQty',
  448.                                     'setBookingQty',
  449.                                     'setPhysicalQty',
  450.                                 ])) {
  451.                                     continue;
  452.                                 }
  453.                             }
  454.                         }
  455.                         $new->{$setMethod}($data->{$getter}()); // `foo!`
  456.                     }
  457.                 }
  458.                 if ($rec_exists == 0)
  459.                     $em->persist($new);
  460.                 $em->flush();
  461.                 if ($ewa == 'EntityCurrencies') {
  462.                     $new->setGlobalId($data->getCurrencyId());
  463.                 } else {
  464.                     $new->setGlobalId($data->getId());
  465.                 }
  466.                 $em->flush();
  467.                 //                $match_cid_gid_itemgroup[$data->getId()] = $new->getId();
  468.             }
  469.         }
  470.         return new JsonResponse(
  471.             array(
  472.                 'data' => $company_wise_entities
  473.             )
  474.         );
  475.     }
  476.     public function getAppGeneralDashboardDataAction(Request $request)
  477.     {
  478.         $dataFor 'client';
  479.         $personId 0;
  480.         if ($request->query->has('dataFor'))
  481.             $dataFor $request->query->get('dataFor');
  482.         if ($request->request->has('dataFor'))
  483.             $dataFor $request->request->get('dataFor');
  484.         if ($request->query->has('personId'))
  485.             $personId $request->query->get('personId');
  486.         if ($request->request->has('personId'))
  487.             $personId $request->request->get('personId');
  488.         if ($personId == 0)
  489.             return new JsonResponse(
  490.                 array(
  491.                     'success' => false,
  492.                     'data' => [],
  493.                 )
  494.             );
  495.         $session $request->getSession();
  496.         $em $this->getDoctrine()->getManager();
  497.         $userAppId $session->get('userAppId');
  498.         $companyId $session->get('userCompanyId');
  499.         $dataToConnectList = [];
  500.         $appIdList $session->get('appIdList');
  501.         $companyIdListByAppId $session->get('companyIdListByAppId');
  502.         $companyNameListByAppId $session->get('companyNameListByAppId');
  503.         $companyImageListByAppId $session->get('companyImageListByAppId');
  504.         $gocEnabled 0;
  505.         if ($this->container->hasParameter('entity_group_enabled'))
  506.             $gocEnabled $this->container->getParameter('entity_group_enabled');
  507.         $connector $this->container->get('application_connector');
  508.         $connector->resetConnection(
  509.             'default',
  510.             $session->get('gocDbName'),
  511.             $session->get('gocDbUser'),
  512.             $session->get('gocDbPass'),
  513.             $session->get('gocDbHost'),
  514.             $reset true
  515.         );
  516.         $em $this->getDoctrine()->getManager();
  517.         $data = [];
  518.         if ($dataFor == 'client') {
  519.             //get order_count, order_amount,bill_count, bill_amount, collection_amount, due_amount
  520.             $data = [
  521.                 'order_count' => 0,
  522.                 'order_amount' => 0,
  523.                 'invoice_count' => 0,
  524.                 'invoice_amount' => 0,
  525.                 'collection_amount' => 0,
  526.                 'due_amount' => 0,
  527.                 'client_count' => 1,
  528.             ];
  529.             $clientIds = [$personId];
  530.             //order count and amount
  531.             $get_sql "SELECT count(sales_order_id) order_count, sum(so_amount) order_amount
  532. FROM sales_order WHERE approved=1 and sales_order.company_id=" $companyId "  and sales_order.client_id in (" implode(','$clientIds) . ");";
  533.             $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  534.             
  535.             $entries $stmt;
  536.             if (!empty($entries)) {
  537.                 $data['order_count'] = $entries[0]['order_count'];
  538.                 $data['order_amount'] = $entries[0]['order_amount'];
  539.             }
  540.             //invoice
  541.             $get_sql "SELECT count(sales_invoice_id) invoice_count, sum(invoice_amount) invoice_amount
  542. FROM sales_invoice WHERE approved=1 and sales_invoice.company_id=" $companyId "  and sales_invoice.client_id in (" implode(','$clientIds) . ");";
  543.             $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  544.             
  545.             $entries $stmt;
  546.             if (!empty($entries)) {
  547.                 $data['invoice_count'] = $entries[0]['invoice_count'];
  548.                 $data['invoice_amount'] = $entries[0]['invoice_amount'];
  549.             }
  550.             //now collection
  551.             $allocationSourceSql $this->buildAllocationAwareTransactionSourceSql(array(
  552.                 'document_type' => 6,
  553.                 'company_id' => $companyId,
  554.                 'start_date' => null,
  555.                 'end_date' => null,
  556.                 'approved' => 1,
  557.                 'ledger_hit' => 1,
  558.             ));
  559.             $get_sql "SELECT SUM(CASE WHEN alloc_rows.position = 'cr' THEN alloc_rows.allocation_amount ELSE 0 END) positive_amount,
  560. SUM(CASE WHEN alloc_rows.position = 'dr' THEN alloc_rows.allocation_amount ELSE 0 END) negative_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type, acc_clients.client_due, acc_clients.client_id
  561.  FROM " $allocationSourceSql " alloc_rows
  562.    join acc_clients on acc_clients.accounts_head_id=alloc_rows.accounts_head_id or acc_clients.advance_head_id=alloc_rows.accounts_head_id
  563.   join client_type on acc_clients.type=client_type.client_type_id
  564.   WHERE acc_clients.company_id=" $companyId " and acc_clients.client_id in (" implode(','$clientIds) . ") ";
  565.             $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  566.             
  567.             $entries $stmt;
  568.             $clientTypes = [];
  569.             $clientTypeNames = [];
  570.             $alreadyCids = [];
  571.             foreach ($entries as $entry) {
  572.                 $data['collection_amount'] += (* ($entry['positive_amount'] - $entry['negative_amount']));
  573.                 if (!in_array($entry['client_id'], $alreadyCids)) {
  574.                     $data['due_amount'] += ($entry['client_due']);
  575.                     $alreadyCids[] = $entry['client_id'];
  576.                 }
  577.             }
  578.         }
  579.         if ($dataFor == 'sales_user') {
  580.             //get order_count, order_amount,bill_count, bill_amount, collection_amount, due_amount
  581.             $data = [
  582.                 'order_count' => 0,
  583.                 'order_amount' => 0,
  584.                 'invoice_count' => 0,
  585.                 'invoice_amount' => 0,
  586.                 'collection_amount' => 0,
  587.                 'due_amount' => 0,
  588.                 'client_count' => 0,
  589.             ];
  590.             $clientIds = [];
  591.             $salesPersonIds = [];
  592.             $allSalespersonFlag 1//temp
  593.             if ($allSalespersonFlag != 1) {
  594.                 $query $em->getRepository('ApplicationBundle\\Entity\\Employee')->findOneBy(
  595.                     array(
  596.                         'userId' => $personId
  597.                     )
  598.                 );
  599.                 if ($query)
  600.                     $salesPersonIds[] = $query->getEmployeeId();
  601.             }
  602.             //Client count
  603.             $get_sql "SELECT  client_id
  604. FROM acc_clients WHERE  acc_clients.company_id=" $companyId " ";
  605.             if ($allSalespersonFlag != 1)
  606.                 $get_sql .= " and acc_clients.sales_person_id in (" implode(','$salesPersonIds) . ");";
  607.             else
  608.                 $get_sql .= " ;";
  609.             $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  610.             
  611.             $entries $stmt;
  612.             if (!empty($entries)) {
  613.                 foreach ($entries as $entry) {
  614.                     $data['client_count'] += 1;
  615.                     $clientIds[] = $entry['client_id'];
  616.                 }
  617.             }
  618.             //order count and amount
  619.             if (!empty($clientIds)) {
  620.                 $get_sql "SELECT count(sales_order_id) order_count, sum(so_amount) order_amount
  621. FROM sales_order WHERE approved=1 and sales_order.company_id=" $companyId "  and sales_order.client_id in (" implode(','$clientIds) . ");";
  622.                 $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  623.                 
  624.                 $entries $stmt;
  625.                 if (!empty($entries)) {
  626.                     $data['order_count'] = $entries[0]['order_count'];
  627.                     $data['order_amount'] = $entries[0]['order_amount'];
  628.                 }
  629.                 //invoice
  630.                 $get_sql "SELECT count(sales_invoice_id) invoice_count, sum(invoice_amount) invoice_amount
  631. FROM sales_invoice WHERE approved=1 and sales_invoice.company_id=" $companyId "  and sales_invoice.client_id in (" implode(','$clientIds) . ");";
  632.                 $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  633.                 
  634.                 $entries $stmt;
  635.                 if (!empty($entries)) {
  636.                     $data['invoice_count'] = $entries[0]['invoice_count'];
  637.                     $data['invoice_amount'] = $entries[0]['invoice_amount'];
  638.                 }
  639.                 //now collection
  640.                 $allocationSourceSql $this->buildAllocationAwareTransactionSourceSql(array(
  641.                     'document_type' => 6,
  642.                     'approved' => 1,
  643.                     'ledger_hit' => 1,
  644.                 ));
  645.                 $get_sql "SELECT SUM(CASE WHEN alloc_rows.position = 'cr' THEN alloc_rows.allocation_amount ELSE 0 END) positive_amount,
  646. SUM(CASE WHEN alloc_rows.position = 'dr' THEN alloc_rows.allocation_amount ELSE 0 END) negative_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type, acc_clients.client_due, acc_clients.client_id
  647.  FROM " $allocationSourceSql " alloc_rows
  648.    join acc_clients on acc_clients.accounts_head_id=alloc_rows.accounts_head_id or acc_clients.advance_head_id=alloc_rows.accounts_head_id
  649.   join client_type on acc_clients.type=client_type.client_type_id
  650.   WHERE acc_clients.company_id=" $companyId " and acc_clients.client_id in (" implode(','$clientIds) . ") ";
  651.                 $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  652.                 
  653.                 $entries $stmt;
  654.                 $clientTypes = [];
  655.                 $clientTypeNames = [];
  656.                 $alreadyCids = [];
  657.                 foreach ($entries as $entry) {
  658.                     $data['collection_amount'] += (* ($entry['positive_amount'] - $entry['negative_amount']));
  659.                     if (!in_array($entry['client_id'], $alreadyCids)) {
  660.                         $data['due_amount'] += ($entry['client_due']);
  661.                         $alreadyCids[] = $entry['client_id'];
  662.                     }
  663.                 }
  664.             }
  665.         }
  666.         if ($dataFor == 'user') {
  667.             //get order_count, payment_amount,
  668.         }
  669.         return new JsonResponse(
  670.             array(
  671.                 'success' => true,
  672.                 'data' => $data,
  673.                 'dataFor' => $dataFor,
  674.                 'personId' => $personId,
  675.             )
  676.         );
  677.     }
  678.     public function getManagementDashboardDataAction(Request $request)
  679.     {
  680.         $session $request->getSession();
  681.         $data = array(
  682.             'cash_and_bank_position' => [],
  683.             'order_and_client_count' => [],
  684.             'expense_vs_revenue' => [],
  685.             'receivable_position' => [],
  686.             'payable_position' => [],
  687.             'expense_position' => [],
  688.             'inventory_position' => [],
  689.             'production_position' => [],
  690.             'sales_position' => [],
  691.             'collection_position' => [],
  692.             'market_return_position' => [],
  693.             'top_selling_item_position' => [],
  694.             'top_selling_client_position' => [],
  695.         );
  696.         $em $this->getDoctrine()->getManager();
  697.         $reportsToGet = [
  698.             'cash_and_bank_position',
  699.             'order_and_client_count',
  700.             'expense_vs_revenue',
  701.             'receivable_position',
  702.             'payable_position',
  703.             'expense_position',
  704.             'inventory_position',
  705.             'production_position',
  706.             'sales_position',
  707.             'collection_position',
  708.             'market_return_position',
  709.             'top_selling_item_position',
  710.             'top_selling_client_position',
  711.         ];
  712.         //        $periodType='day'; //day,month,week,year,quarter etc
  713.         $periodType 'month'//day,month,week,year,quarter etc
  714.         if ($request->request->has('reportsToGet')) {
  715.             if ($request->request->get('reportsToGet') != 'all' && !in_array('all'$request->request->get('reportsToGet'))) {
  716.                 $reportsToGet $request->request->get('reportsToGet');
  717.             }
  718.         }
  719.         if ($request->request->has('periodType')) {
  720.             $periodType $request->request->get('periodType');
  721.         }
  722.         $userAppId $session->get('userAppId');
  723.         $dataToConnectList = [];
  724.         $appIdList $session->get('appIdList');
  725.         $companyIdListByAppId $session->get('companyIdListByAppId');
  726.         $companyNameListByAppId $session->get('companyNameListByAppId');
  727.         $companyImageListByAppId $session->get('companyImageListByAppId');
  728.         $gocEnabled 0;
  729.         if ($this->container->hasParameter('entity_group_enabled'))
  730.             $gocEnabled $this->container->getParameter('entity_group_enabled');
  731.         $thisPeriodStartDate '';
  732.         $lastPeriodStartDate '';
  733.         $thisPeriodEndDate '';
  734.         $lastPeriodEndDate '';
  735.         $today = new \DateTime();
  736.         if ($periodType == 'month') {
  737.             $thisPeriodEndDate $today->format('Y-m-d');
  738.             $thisPeriodStartDate $today->format('Y-m-') . '01';
  739.             $currDate = new \DateTime($thisPeriodStartDate);
  740.             $currDate->modify('-1 day');
  741.             $lastPeriodEndDate $currDate->format('Y-m-d');
  742.             $lastPeriodStartDate $currDate->format('Y-m-') . '01';
  743.         } else if ($periodType == 'week') {
  744.             $thisPeriodEndDate $today->format('Y-m-d');
  745.             $thisWeekStartDate date("Y-m-d"strtotime("previous saturday"));
  746.             $thisPeriodStartDate date("Y-m-d"strtotime("previous saturday"));
  747.             $currDate = new \DateTime($thisPeriodStartDate);
  748.             $currDate->modify('-1 day');
  749.             $lastPeriodEndDate $currDate->format('Y-m-d');
  750.             $currDate->modify('-6 day');
  751.             $lastPeriodStartDate $currDate->format('Y-m-d');
  752.         } else if ($periodType == 'quarter') {
  753.             $thisPeriodEndDate $today->format('Y-m-d');
  754.             $thisWeekStartDate date("Y-m-d"strtotime("previous saturday"));
  755.             $thisPeriodStartDate date("Y-m-d"strtotime("previous saturday"));
  756.             $currDate = new \DateTime($thisPeriodStartDate);
  757.             $currDate->modify('-1 day');
  758.             $lastPeriodEndDate $currDate->format('Y-m-d');
  759.             $currDate->modify('-6 day');
  760.             $lastPeriodStartDate $currDate->format('Y-m-d');
  761.         } else if ($periodType == 'year') {
  762.             $thisPeriodEndDate $today->format('Y-m-d');
  763.             //            $thisWeekStartDate = date("Y-m-d", strtotime("previous saturday"));
  764.             $thisPeriodStartDate = ($today->format('Y')) . '-01-01';
  765.             $currDate = new \DateTime($thisPeriodStartDate);
  766.             $currDate->modify('-1 day');
  767.             $lastPeriodEndDate $currDate->format('Y-m-d');
  768.             $lastPeriodStartDate = ($currDate->format('Y')) . '-01-01';;
  769.         }
  770.         $companyListData = [];
  771.         foreach ($appIdList as $appId) {
  772.             //queryonly if mor ethan one app id
  773.             $skip 0;
  774.             if ($appId == $userAppId) {
  775.                 $connector $this->container->get('application_connector');
  776.                 $connector->resetConnection(
  777.                     'default',
  778.                     $session->get('gocDbName'),
  779.                     $session->get('gocDbUser'),
  780.                     $session->get('gocDbPass'),
  781.                     $session->get('gocDbHost'),
  782.                     $reset true
  783.                 );
  784.                 $em $this->getDoctrine()->getManager();
  785.             } else {
  786.                 $dataToConnect System::changeDoctrineManagerByAppId($this->getDoctrine()->getManager('company_group'), $gocEnabled$appId);
  787.                 $dataToConnectList[] = $dataToConnect;
  788.                 if (!empty($dataToConnect)) {
  789.                     $connector $this->container->get('application_connector');
  790.                     $connector->resetConnection(
  791.                         'default',
  792.                         $dataToConnect['dbName'],
  793.                         $dataToConnect['dbUser'],
  794.                         $dataToConnect['dbPass'],
  795.                         $dataToConnect['dbHost'],
  796.                         $reset true
  797.                     );
  798.                     $em $this->getDoctrine()->getManager();
  799.                 } else {
  800.                     $skip 1;
  801.                 }
  802.             }
  803.             if ($skip == 1)
  804.                 continue;
  805.             //                $companyListData[] = Company::getCompanyListWithImage($em);
  806.             //                $get_sql = "SELECT * FROM company ";
  807.             //                $stmt = $em->getConnection()->executeStatement($get_sql);
  808.             //                
  809.             //                $entries = $stmt;
  810.             //                $companyListData[] = $entries;
  811.             //                foreach ($companyIdListByAppId as $app_company_index)
  812.             if (isset($companyIdListByAppId[$appId])) {
  813.                 foreach ($companyIdListByAppId[$appId] as $app_company_index) {
  814.                     //exp vs rev
  815.                     if (in_array('expense_vs_revenue'$reportsToGet)) {
  816.                         $acHeadList = [];
  817.                         $companyId explode('_'$app_company_index)[1];
  818.                         $acHeadDataById = [];
  819.                         $thisBalanceDataByAcHead = [];
  820.                         $lastBalanceDataByAcHead = [];
  821.                         $mon_names = ["""January""February""March""April""May""June""July""August""September""October""November""December"];
  822.                         $limit 12;
  823.                         $get_kids_sql "SELECT expense, revenue, `date` summ_date
  824.                           FROM monthly_summary
  825.                             where monthly_summary.company_id=$companyId
  826.                             AND ( monthly_summary.branch_id=0 or monthly_summary.branch_id is null) ";
  827.                         //                               GROUP BY monthly_summary.`date`
  828.                         $get_kids_sql .= " ORDER BY monthly_summary.`date` DESC  limit " $limit;
  829.                         $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql);
  830.                         
  831.                         $pl $stmt;
  832.                         $curr_date = new \DateTime();
  833.                         $curr_mon = ($curr_date->format('m'));
  834.                         $curr_year = ($curr_date->format('Y'));
  835.                         $object_list = [];
  836.                         $debug_list = [];
  837.                         $list = [];
  838.                         $timeStampList = [];
  839.                         //        $first
  840.                         foreach ($pl as $key => $entry) {
  841.                             $qryDate = new \DateTime($entry['summ_date']);
  842.                             $qrMon $qryDate->format('m');;
  843.                             $qrYr $qryDate->format('Y');;
  844.                             $object_list[$qrYr '_' $qrMon] = $entry;
  845.                         }
  846.                         for ($k 0$k 11$k++) {
  847.                             $debug_list[$k] = $curr_year '_' $curr_mon;
  848.                             $currTimeStamp strtotime($curr_year "-" $curr_mon '-1');
  849.                             $currTimeStampMili $currTimeStamp 1000;
  850.                             $cashAddition 0;
  851.                             $bankAddition 0;
  852.                             if (isset($object_list[$curr_year '_' $curr_mon])) {
  853.                                 $entry $object_list[$curr_year '_' $curr_mon];
  854.                                 $list['monthList'][] = $mon_names[$curr_mon];
  855.                                 $list['revenue'][] = round($entry['revenue']);
  856.                                 $list['tsCommaRevenue'][] = [$currTimeStampMiliround($entry['revenue'])];
  857.                                 $list['expense'][] = round($entry['expense']);
  858.                                 $list['tsCommaExpense'][] = [$currTimeStampMiliround($entry['expense'])];
  859.                             } else {
  860.                                 $list['monthList'][] = $mon_names[($curr_mon)];
  861.                                 $list['revenue'][] = 0;
  862.                                 $list['expense'][] = 0;
  863.                                 $list['tsCommaRevenue'][] = [$currTimeStampMili0];
  864.                                 $list['tsCommaExpense'][] = [$currTimeStampMili0];
  865.                             }
  866.                             $curr_mon--;
  867.                             if ($curr_mon <= 0) {
  868.                                 $curr_mon 12;
  869.                                 $curr_year--;
  870.                             }
  871.                             //new end
  872.                         }
  873.                         $data['expense_vs_revenue'][$app_company_index] = $list;
  874.                     }
  875.                     //cash and bank position
  876.                     if (in_array('cash_and_bank_position'$reportsToGet)) {
  877.                         $acHeadList = [];
  878.                         $companyId explode('_'$app_company_index)[1];
  879.                         $acHeadDataById = [];
  880.                         $thisBalanceDataByAcHead = [];
  881.                         $lastBalanceDataByAcHead = [];
  882.                         $bank_settings $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
  883.                             'name' => 'bank_parents',
  884.                             //                        'CompanyId'=>$companyId
  885.                         ));
  886.                         $bank_id_list = [];
  887.                         if ($bank_settings)
  888.                             $bank_id_list json_decode($bank_settings->getData());
  889.                         $bank_child_id_list = [];
  890.                         $likeQuery '';
  891.                         foreach ($bank_id_list as $p) {
  892.                             $likeQuery .= "OR path_tree like '%/" $p "%/' ";
  893.                         }
  894.                         $get_sql "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" $companyId " AND  accounts_head_id not in (select distinct parent_id from acc_accounts_head)and (1=0 " $likeQuery ") ";
  895.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  896.                         
  897.                         $entries $stmt;
  898.                         foreach ($entries as $entry) {
  899.                             $has_payments 1;
  900.                             $bank_child_id_list[] = $entry['accounts_head_id'];
  901.                             $acHeadList[] = $entry['accounts_head_id'];
  902.                             $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  903.                         }
  904.                         $cash_settings $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
  905.                             'name' => 'cash_parents'
  906.                             //                        'CompanyId'=>$companyId
  907.                         ));
  908.                         $cash_id_list = [];
  909.                         if ($cash_settings)
  910.                             $cash_id_list json_decode($cash_settings->getData());
  911.                         $cash_child_id_list = [];
  912.                         $likeQuery '';
  913.                         foreach ($cash_id_list as $p) {
  914.                             $likeQuery .= "OR path_tree like '%/" $p "%/' ";
  915.                         }
  916.                         $get_sql "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" $companyId " AND accounts_head_id not in (select distinct parent_id from acc_accounts_head)and (1=0 " $likeQuery ") ";
  917.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  918.                         
  919.                         $entries $stmt;
  920.                         foreach ($entries as $entry) {
  921.                             $has_payments 1;
  922.                             $cash_child_id_list[] = $entry['accounts_head_id'];
  923.                             $acHeadList[] = $entry['accounts_head_id'];
  924.                             $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  925.                         }
  926.                         $thisBalance_data Accounts::GetBalanceOnDate($em$thisPeriodEndDate, []);
  927.                         $lastBalance_data Accounts::GetBalanceOnDate($em$lastPeriodEndDate, []);
  928.                         foreach ($acHeadList as $acHead) {
  929.                             $thisBalanceDataByAcHead[$acHead]['balance'] = $thisBalance_data[$acHead]['end_balance']['balance'];
  930.                             $lastBalanceDataByAcHead[$acHead]['balance'] = $lastBalance_data[$acHead]['end_balance']['balance'];
  931.                         }
  932.                         $thisReportData = array(
  933.                             'accountsHeadList' => $acHeadList,
  934.                             'acHeadDataById' => $acHeadDataById,
  935.                             'cash_child_id_list' => $cash_child_id_list,
  936.                             'bank_child_id_list' => $bank_child_id_list,
  937.                             'thisBalanceDataByAcHead' => $thisBalanceDataByAcHead,
  938.                             'lastBalanceDataByAcHead' => $lastBalanceDataByAcHead,
  939.                         );
  940.                         $data['cash_and_bank_position'][$app_company_index] = $thisReportData;
  941.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  942.                     }
  943.                     //Expense Position
  944.                     if (in_array('expense_position'$reportsToGet)) {
  945.                         $acHeadList = [];
  946.                         $companyId explode('_'$app_company_index)[1];
  947.                         $acHeadDataById = [];
  948.                         $thisBalanceDataByAcHead = [];
  949.                         $lastBalanceDataByAcHead = [];
  950.                         $get_sql "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" $companyId "
  951.                         AND acc_accounts_head.head_level= 2 ";
  952.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  953.                         
  954.                         $entries $stmt;
  955.                         foreach ($entries as $entry) {
  956.                             $has_payments 1;
  957.                             $cash_child_id_list[] = $entry['accounts_head_id'];
  958.                             $acHeadList[] = $entry['accounts_head_id'];
  959.                             $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  960.                         }
  961.                         $thisBalance_data Accounts::GetPeriodicDataByType($em$type 'exp'$level_to_group_by 1$parent_id_list = [], $expand_level 1$thisPeriodStartDate$thisPeriodEndDate'_during_', [], [], [], false);
  962.                         $lastBalance_data Accounts::GetPeriodicDataByType($em$type 'exp'$level_to_group_by 1$parent_id_list = [], $expand_level 1$lastPeriodStartDate$lastPeriodEndDate'_during_', [], [], [], false);
  963.                         $skipHeadIds = [];
  964.                         foreach ($thisBalance_data as $parentHead => $balanceData) {
  965.                             foreach ($balanceData['data'] as $acHead => $headData) {
  966.                                 if (!in_array($acHead$acHeadList))
  967.                                     continue;
  968.                                 $thisBalanceDataByAcHead[$acHead]['balance'] = $headData['head_balance'];
  969.                                 if (isset($lastBalance_data[$parentHead])) {
  970.                                     if (isset($lastBalance_data[$parentHead]['data'][$acHead]))
  971.                                         $lastBalanceDataByAcHead[$acHead]['balance'] = $lastBalance_data[$parentHead]['data'][$acHead]['head_balance'];
  972.                                     else
  973.                                         $lastBalanceDataByAcHead[$acHead]['balance'] = 0;
  974.                                 } else
  975.                                     $lastBalanceDataByAcHead[$acHead]['balance'] = 0;
  976.                                 $skipHeadIds[] = $acHead;
  977.                             }
  978.                         }
  979.                         foreach ($lastBalance_data as $parentHead => $balanceData) {
  980.                             foreach ($balanceData['data'] as $acHead => $headData) {
  981.                                 if (in_array($acHead$skipHeadIds))
  982.                                     continue;
  983.                                 if (!in_array($acHead$acHeadList))
  984.                                     continue;
  985.                                 $lastBalanceDataByAcHead[$acHead]['balance'] = $headData['head_balance'];
  986.                                 if (isset($thisBalance_data[$parentHead])) {
  987.                                     if (isset($thisBalance_data[$parentHead]['data'][$acHead]))
  988.                                         $thisBalanceDataByAcHead[$acHead]['balance'] = $thisBalance_data[$parentHead]['data'][$acHead]['head_balance'];
  989.                                     else
  990.                                         $thisBalanceDataByAcHead[$acHead]['balance'] = 0;
  991.                                 } else
  992.                                     $thisBalanceDataByAcHead[$acHead]['balance'] = 0;
  993.                                 $skipHeadIds[] = $acHead;
  994.                             }
  995.                         }
  996.                         $thisReportData = array(
  997.                             'accountsHeadList' => $acHeadList,
  998.                             //                            'thisBalance_data' => $thisBalance_data,
  999.                             'confirmedHeadList' => $skipHeadIds,
  1000.                             'acHeadDataById' => $acHeadDataById,
  1001.                             'thisBalanceDataByAcHead' => $thisBalanceDataByAcHead,
  1002.                             'lastBalanceDataByAcHead' => $lastBalanceDataByAcHead,
  1003.                         );
  1004.                         $data['expense_position'][$app_company_index] = $thisReportData;
  1005.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1006.                     }
  1007.                     //Payable Position
  1008.                     if (in_array('payable_position'$reportsToGet)) {
  1009.                         $acHeadList = [];
  1010.                         $companyId explode('_'$app_company_index)[1];
  1011.                         $acHeadDataById = [];
  1012.                         $thisBalanceDataByAcHead = [];
  1013.                         $lastBalanceDataByAcHead = [];
  1014.                         $filter_settings $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
  1015.                             'name' => 'payable_parents',
  1016.                             //                        'CompanyId'=>$companyId
  1017.                         ));
  1018.                         $filter_head_parents_id_list = [];
  1019.                         if ($filter_settings)
  1020.                             $filter_head_parents_id_list json_decode($filter_settings->getData());
  1021.                         $likeQuery '';
  1022.                         foreach ($filter_head_parents_id_list as $p) {
  1023.                             $likeQuery .= "OR path_tree like '%/" $p "%/' ";
  1024.                         }
  1025.                         $get_sql "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" $companyId "
  1026.                          and (1=0 " $likeQuery ") ";
  1027.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1028.                         
  1029.                         $entries $stmt;
  1030.                         foreach ($entries as $entry) {
  1031.                             $has_payments 1;
  1032.                             $acHeadList[] = $entry['accounts_head_id'];
  1033.                             $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  1034.                         }
  1035.                         //                        $get_sql = "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" . $companyId . "
  1036.                         //                        AND acc_accounts_head.head_level= 2 and acc_accounts_head.type='lib'";
  1037.                         //
  1038.                         //                        $stmt = $em->getConnection()->executeStatement($get_sql);
  1039.                         //                        
  1040.                         //                        $entries = $stmt;
  1041.                         //
  1042.                         //                        foreach ($entries as $entry) {
  1043.                         //                            $has_payments = 1;
  1044.                         //                            $cash_child_id_list[] = $entry['accounts_head_id'];
  1045.                         //                            $acHeadList[] = $entry['accounts_head_id'];
  1046.                         //                            $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  1047.                         //                        }
  1048.                         $thisBalance_data Accounts::GetPeriodicDataByType($em$type 'lib'$level_to_group_by 2$parent_id_list = [], $expand_level 1$thisPeriodStartDate$thisPeriodEndDate'_during_', [], [], [], false);
  1049.                         $lastBalance_data Accounts::GetPeriodicDataByType($em$type 'lib'$level_to_group_by 2$parent_id_list = [], $expand_level 1$lastPeriodStartDate$lastPeriodEndDate'_during_', [], [], [], false);
  1050.                         $skipHeadIds = [];
  1051.                         foreach ($thisBalance_data as $parentHead => $balanceData) {
  1052.                             foreach ($balanceData['data'] as $acHead => $headData) {
  1053.                                 if (!(in_array($acHead$acHeadList)))
  1054.                                     continue;
  1055.                                 if ($headData['head_level'] > 4)
  1056.                                     continue;
  1057.                                 //                                $thisBalanceDataByAcHead[$acHead]['balance'] = $headData['head_balance'];
  1058.                                 $thisBalanceDataByAcHead[$acHead]['balance'] = $headData['end_balance']['balance'];
  1059.                                 if (isset($lastBalance_data[$parentHead])) {
  1060.                                     if (isset($lastBalance_data[$parentHead]['data'][$acHead]))
  1061.                                         //                                        $lastBalanceDataByAcHead[$acHead]['balance'] = $lastBalance_data[$parentHead]['data'][$acHead]['head_balance'];
  1062.                                         $lastBalanceDataByAcHead[$acHead]['balance'] = $lastBalance_data[$parentHead]['data'][$acHead]['end_balance']['balance'];
  1063.                                     else
  1064.                                         $lastBalanceDataByAcHead[$acHead]['balance'] = 0;
  1065.                                 } else
  1066.                                     $lastBalanceDataByAcHead[$acHead]['balance'] = 0;
  1067.                                 $skipHeadIds[] = $acHead;
  1068.                             }
  1069.                         }
  1070.                         foreach ($lastBalance_data as $parentHead => $balanceData) {
  1071.                             foreach ($balanceData['data'] as $acHead => $headData) {
  1072.                                 if (in_array($acHead$skipHeadIds))
  1073.                                     continue;
  1074.                                 if (!in_array($acHead$acHeadList))
  1075.                                     continue;
  1076.                                 if ($headData['head_level'] > 4)
  1077.                                     continue;
  1078.                                 $lastBalanceDataByAcHead[$acHead]['balance'] = $headData['end_balance']['balance'];
  1079.                                 if (isset($thisBalance_data[$parentHead])) {
  1080.                                     if (isset($thisBalance_data[$parentHead]['data'][$acHead]))
  1081.                                         $thisBalanceDataByAcHead[$acHead]['balance'] = $thisBalance_data[$parentHead]['data'][$acHead]['end_balance']['balance'];
  1082.                                     else
  1083.                                         $thisBalanceDataByAcHead[$acHead]['balance'] = 0;
  1084.                                 } else
  1085.                                     $thisBalanceDataByAcHead[$acHead]['balance'] = 0;
  1086.                                 $skipHeadIds[] = $acHead;
  1087.                             }
  1088.                         }
  1089.                         $thisReportData = array(
  1090.                             'accountsHeadList' => $acHeadList,
  1091.                             //                            'thisBalance_data' => $thisBalance_data,
  1092.                             'confirmedHeadList' => $skipHeadIds,
  1093.                             'acHeadDataById' => $acHeadDataById,
  1094.                             'thisBalanceDataByAcHead' => $thisBalanceDataByAcHead,
  1095.                             'lastBalanceDataByAcHead' => $lastBalanceDataByAcHead,
  1096.                         );
  1097.                         $data['payable_position'][$app_company_index] = $thisReportData;
  1098.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1099.                     }
  1100.                     //Receivable Position
  1101.                     if (in_array('receivable_position'$reportsToGet)) {
  1102.                         $acHeadList = [];
  1103.                         $companyId explode('_'$app_company_index)[1];
  1104.                         $acHeadDataById = [];
  1105.                         $thisBalanceDataByAcHead = [];
  1106.                         $lastBalanceDataByAcHead = [];
  1107.                         //                        $filter_settings = $em->getRepository('ApplicationBundle\\Entity\\AccSettings')->findOneBy(array(
  1108.                         //                            'name' => 'receivable_parents',
  1109.                         ////                        'CompanyId'=>$companyId
  1110.                         //                        ));
  1111.                         //                        $filter_head_parents_id_list = [];
  1112.                         //                        if ($filter_settings)
  1113.                         //                            $filter_head_parents_id_list = json_decode($filter_settings->getData());
  1114.                         //                        $likeQuery = '';
  1115.                         //                        foreach ($filter_head_parents_id_list as $p) {
  1116.                         //                            $likeQuery .= "OR path_tree like '%/" . $p . "%/' ";
  1117.                         //                        }
  1118.                         //                        $get_sql = "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" . $companyId . "
  1119.                         //                         and (1=0 " . $likeQuery . ") ";
  1120.                         $get_sql "SELECT acc_accounts_head.*  FROM acc_accounts_head
  1121.  WHERE acc_accounts_head.company_id=" $companyId "
  1122.                          and  ( acc_accounts_head.accounts_head_id in (select distinct accounts_head_id from acc_clients)
  1123.                           OR acc_accounts_head.accounts_head_id in (select distinct advance_head_id from acc_clients)
  1124.                          ) ";
  1125.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1126.                         
  1127.                         $entries $stmt;
  1128.                         $account_head_ids_by_client_type = [];
  1129.                         foreach ($entries as $entry) {
  1130.                             $has_payments 1;
  1131.                             $acHeadList[] = $entry['accounts_head_id'];
  1132.                             $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  1133.                         }
  1134.                         $get_sql "SELECT acc_clients.*  FROM acc_clients
  1135.  WHERE acc_clients.company_id=" $companyId;
  1136.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1137.                         
  1138.                         $entries $stmt;
  1139.                         $clientTypeListArray Client::ClientTypeList($em, [$companyId], true);
  1140.                         $clientTypesOfHeads = [];
  1141.                         foreach ($entries as $entry) {
  1142.                             if (!isset($account_head_ids_by_client_type[$entry['type']]))
  1143.                                 $account_head_ids_by_client_type[$entry['type']] = [];
  1144.                             $account_head_ids_by_client_type[$entry['type']][] = $entry['accounts_head_id'];
  1145.                             $clientTypesOfHeads[$entry['accounts_head_id']] = $entry['type'];
  1146.                             if ($entry['accounts_head_id'] != $entry['advance_head_id']) {
  1147.                                 $account_head_ids_by_client_type[$entry['type']][] = $entry['advance_head_id'];
  1148.                                 $clientTypesOfHeads[$entry['advance_head_id']] = $entry['type'];
  1149.                             }
  1150.                         }
  1151.                         //                        $get_sql = "SELECT * FROM acc_accounts_head WHERE acc_accounts_head.company_id=" . $companyId . "
  1152.                         //                        AND acc_accounts_head.head_level= 2 and acc_accounts_head.type='lib'";
  1153.                         //
  1154.                         //                        $stmt = $em->getConnection()->executeStatement($get_sql);
  1155.                         //                        
  1156.                         //                        $entries = $stmt;
  1157.                         //
  1158.                         //                        foreach ($entries as $entry) {
  1159.                         //                            $has_payments = 1;
  1160.                         //                            $cash_child_id_list[] = $entry['accounts_head_id'];
  1161.                         //                            $acHeadList[] = $entry['accounts_head_id'];
  1162.                         //                            $acHeadDataById[$entry['accounts_head_id']]['name'] = $entry['name'];
  1163.                         //                        }
  1164.                         $thisBalance_data Accounts::GetPeriodicDataByType($em$type 'ast'$level_to_group_by 2$parent_id_list = [], $expand_level 1$thisPeriodStartDate$thisPeriodEndDate'_during_', [], [], [], true);
  1165.                         $lastBalance_data Accounts::GetPeriodicDataByType($em$type 'ast'$level_to_group_by 2$parent_id_list = [], $expand_level 1$lastPeriodStartDate$lastPeriodEndDate'_during_', [], [], [], true);
  1166.                         $skipHeadIds = [];
  1167.                         $thisBalanceDataByClientType = [];
  1168.                         $lastBalanceDataByClientType = [];
  1169.                         foreach ($clientTypeListArray as $ct) {
  1170.                             $thisBalanceDataByClientType[$ct['id']] = 0;
  1171.                             $lastBalanceDataByClientType[$ct['id']] = 0;
  1172.                         }
  1173.                         foreach ($thisBalance_data as $parentHead => $balanceData) {
  1174.                             foreach ($balanceData['data'] as $acHead => $headData) {
  1175.                                 if (!(in_array($acHead$acHeadList)))
  1176.                                     continue;
  1177.                                 //                                if ($headData['head_level'] > 4)
  1178.                                 //                                    continue;
  1179.                                 $thisBalanceDataByAcHead[$acHead]['balance'] = $headData['end_balance']['balance'];
  1180.                                 if (isset($lastBalance_data[$parentHead])) {
  1181.                                     if (isset($lastBalance_data[$parentHead]['data'][$acHead]))
  1182.                                         $lastBalanceDataByAcHead[$acHead]['balance'] = $lastBalance_data[$parentHead]['data'][$acHead]['end_balance']['balance'];
  1183.                                     else
  1184.                                         $lastBalanceDataByAcHead[$acHead]['balance'] = 0;
  1185.                                 } else
  1186.                                     $lastBalanceDataByAcHead[$acHead]['balance'] = 0;
  1187.                                 if (!isset($thisBalanceDataByClientType[$clientTypesOfHeads[$acHead]]))
  1188.                                     $thisBalanceDataByClientType[$clientTypesOfHeads[$acHead]] = $headData['end_balance']['balance'];
  1189.                                 else
  1190.                                     $thisBalanceDataByClientType[$clientTypesOfHeads[$acHead]] += $headData['end_balance']['balance'];
  1191.                                 if (!isset($lastBalanceDataByClientType[$clientTypesOfHeads[$acHead]]))
  1192.                                     $lastBalanceDataByClientType[$clientTypesOfHeads[$acHead]] = 0;
  1193.                                 else
  1194.                                     $lastBalanceDataByClientType[$clientTypesOfHeads[$acHead]] += $lastBalance_data[$parentHead]['data'][$acHead]['end_balance']['balance'];
  1195.                                 $skipHeadIds[] = $acHead;
  1196.                             }
  1197.                         }
  1198.                         foreach ($lastBalance_data as $parentHead => $balanceData) {
  1199.                             foreach ($balanceData['data'] as $acHead => $headData) {
  1200.                                 if (in_array($acHead$skipHeadIds))
  1201.                                     continue;
  1202.                                 if (!in_array($acHead$acHeadList))
  1203.                                     continue;
  1204.                                 //                                if ($headData['head_level'] > 4)
  1205.                                 //                                    continue;
  1206.                                 $lastBalanceDataByAcHead[$acHead]['balance'] = $headData['end_balance']['balance'];
  1207.                                 if (isset($thisBalance_data[$parentHead])) {
  1208.                                     if (isset($thisBalance_data[$parentHead]['data'][$acHead]))
  1209.                                         $thisBalanceDataByAcHead[$acHead]['balance'] = $thisBalance_data[$parentHead]['data'][$acHead]['end_balance']['balance'];
  1210.                                     else
  1211.                                         $thisBalanceDataByAcHead[$acHead]['balance'] = 0;
  1212.                                 } else
  1213.                                     $thisBalanceDataByAcHead[$acHead]['balance'] = 0;
  1214.                                 if (!isset($lastBalanceDataByClientType[$clientTypesOfHeads[$acHead]]))
  1215.                                     $lastBalanceDataByClientType[$clientTypesOfHeads[$acHead]] = $headData['end_balance']['balance'];
  1216.                                 else
  1217.                                     $lastBalanceDataByClientType[$clientTypesOfHeads[$acHead]] += $headData['end_balance']['balance'];
  1218.                                 if (!isset($thisBalanceDataByClientType[$clientTypesOfHeads[$acHead]]))
  1219.                                     $thisBalanceDataByClientType[$clientTypesOfHeads[$acHead]] = 0;
  1220.                                 $skipHeadIds[] = $acHead;
  1221.                             }
  1222.                         }
  1223.                         $thisReportData = array(
  1224.                             //                            'accountsHeadList' => $acHeadList,
  1225.                             //                            'thisBalance_data' => $thisBalance_data,
  1226.                             //                            'confirmedHeadList' => $skipHeadIds,
  1227.                             //                            'acHeadDataById' => $acHeadDataById,
  1228.                             'thisBalance_data' => $thisBalance_data,
  1229.                             'lastBalance_data' => $lastBalance_data,
  1230.                             'thisBalanceDataByAcHead' => $thisBalanceDataByAcHead,
  1231.                             'lastBalanceDataByAcHead' => $lastBalanceDataByAcHead,
  1232.                             'clientTypeListArray' => $clientTypeListArray,
  1233.                             'thisBalanceDataByClientType' => $thisBalanceDataByClientType,
  1234.                             'lastBalanceDataByClientType' => $lastBalanceDataByClientType,
  1235.                         );
  1236.                         $data['receivable_position'][$app_company_index] = $thisReportData;
  1237.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1238.                     }
  1239.                     //Sales Position
  1240.                     if (in_array('sales_position'$reportsToGet)) {
  1241.                         $acHeadList = [];
  1242.                         $companyId explode('_'$app_company_index)[1];
  1243.                         $acHeadDataById = [];
  1244.                         $thisBalanceDataByClientType = [];
  1245.                         $lastBalanceDataByClientType = [];
  1246.                         $get_sql "SELECT sum(sales_invoice.invoice_amount) sales_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type
  1247.   FROM sales_invoice
  1248.   join acc_clients on acc_clients.client_id=sales_invoice.client_id
  1249.   join client_type on acc_clients.type=client_type.client_type_id
  1250.    WHERE sales_invoice.company_id=" $companyId " AND sales_invoice.approved=1
  1251.                           AND sales_invoice_date between '" $thisPeriodStartDate " 00:00:00' and '" $thisPeriodEndDate " 23:59:59.999'
  1252.                           GROUP BY client_type.client_type_id
  1253.                           ";
  1254.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1255.                         
  1256.                         $entries $stmt;
  1257.                         $clientTypes = [];
  1258.                         $clientTypeNames = [];
  1259.                         $get_sql_1 $get_sql;
  1260.                         foreach ($entries as $entry) {
  1261.                             $has_payments 1;
  1262.                             $thisBalanceDataByClientType[$entry['client_type_id']] = $entry;
  1263.                             $lastBalanceDataByClientType[$entry['client_type_id']]['sales_amount'] = 0//just for the lulz
  1264.                             if (!in_array($entry['client_type_id'], $clientTypes)) {
  1265.                                 $clientTypes[] = $entry['client_type_id'];
  1266.                                 $clientTypeNames[$entry['client_type_id']] = $entry['name'];
  1267.                             }
  1268.                         }
  1269.                         $get_sql "SELECT sum(sales_invoice.invoice_amount) sales_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type
  1270.   FROM sales_invoice
  1271.   join acc_clients on acc_clients.client_id=sales_invoice.client_id
  1272.   join client_type on acc_clients.type=client_type.client_type_id
  1273.    WHERE sales_invoice.company_id=" $companyId " AND sales_invoice.approved=1
  1274.                           AND sales_invoice_date between '" $lastPeriodStartDate " 00:00:00' and '" $lastPeriodEndDate " 23:59:59.999'
  1275.                           GROUP BY client_type.client_type_id
  1276.                           ";
  1277.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1278.                         
  1279.                         $entries $stmt;
  1280.                         foreach ($entries as $entry) {
  1281.                             $has_payments 1;
  1282.                             $lastBalanceDataByClientType[$entry['client_type_id']] = $entry;
  1283.                             if (!isset($thisBalanceDataByClientType[$entry['client_type_id']]))
  1284.                                 $thisBalanceDataByClientType[$entry['client_type_id']]['sales_amount'] = 0//just for the lulz
  1285.                             if (!in_array($entry['client_type_id'], $clientTypes)) {
  1286.                                 $clientTypes[] = $entry['client_type_id'];
  1287.                                 $clientTypeNames[$entry['client_type_id']] = $entry['name'];
  1288.                             }
  1289.                         }
  1290.                         $skipHeadIds = [];
  1291.                         $thisReportData = array(
  1292.                             'clientTypes' => $clientTypes,
  1293.                             //                            'get_sql_1' => $get_sql_1,
  1294.                             //                            'get_sql' => $get_sql,
  1295.                             'clientTypeNames' => $clientTypeNames,
  1296.                             'thisBalanceDataByClientType' => $thisBalanceDataByClientType,
  1297.                             'lastBalanceDataByClientType' => $lastBalanceDataByClientType,
  1298.                         );
  1299.                         $data['sales_position'][$app_company_index] = $thisReportData;
  1300.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1301.                     }
  1302.                     //Collection Position
  1303.                     if (in_array('collection_position'$reportsToGet)) {
  1304.                         $acHeadList = [];
  1305.                         $companyId explode('_'$app_company_index)[1];
  1306.                         $acHeadDataById = [];
  1307.                         $thisBalanceDataByClientType = [];
  1308.                         $lastBalanceDataByClientType = [];
  1309.                         $allocationSourceSql $this->buildAllocationAwareTransactionSourceSql(array(
  1310.                             'document_type' => 6,
  1311.                             'start_date' => $thisPeriodStartDate,
  1312.                             'end_date' => $thisPeriodEndDate,
  1313.                             'approved' => 1,
  1314.                             'ledger_hit' => 1,
  1315.                         ));
  1316.                         $get_sql "SELECT SUM(CASE WHEN alloc_rows.position = 'cr' THEN alloc_rows.allocation_amount ELSE 0 END) positive_amount,
  1317. SUM(CASE WHEN alloc_rows.position = 'dr' THEN alloc_rows.allocation_amount ELSE 0 END) negative_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type
  1318.  FROM " $allocationSourceSql " alloc_rows
  1319.    join acc_clients on acc_clients.accounts_head_id=alloc_rows.accounts_head_id or acc_clients.advance_head_id=alloc_rows.accounts_head_id
  1320.   join client_type on acc_clients.type=client_type.client_type_id
  1321.   WHERE acc_clients.company_id=" $companyId "
  1322.                               GROUP BY client_type.client_type_id";
  1323.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1324.                         
  1325.                         $entries $stmt;
  1326.                         $clientTypes = [];
  1327.                         $clientTypeNames = [];
  1328.                         foreach ($entries as $entry) {
  1329.                             $has_payments 1;
  1330.                             $thisBalanceDataByClientType[$entry['client_type_id']] = $entry;
  1331.                             $lastBalanceDataByClientType[$entry['client_type_id']]['collection_amount'] = 0//just for the lulz
  1332.                             $thisBalanceDataByClientType[$entry['client_type_id']]['collection_amount'] = $entry['positive_amount'] - $entry['negative_amount'];
  1333.                             if (!in_array($entry['client_type_id'], $clientTypes)) {
  1334.                                 $clientTypes[] = $entry['client_type_id'];
  1335.                                 $clientTypeNames[$entry['client_type_id']] = $entry['name'];
  1336.                             }
  1337.                         }
  1338.                         $allocationSourceSql $this->buildAllocationAwareTransactionSourceSql(array(
  1339.                             'document_type' => 6,
  1340.                             'start_date' => $lastPeriodStartDate,
  1341.                             'end_date' => $lastPeriodEndDate,
  1342.                             'approved' => 1,
  1343.                             'ledger_hit' => 1,
  1344.                         ));
  1345.                         $get_sql "SELECT SUM(CASE WHEN alloc_rows.position = 'cr' THEN alloc_rows.allocation_amount ELSE 0 END) positive_amount,
  1346. SUM(CASE WHEN alloc_rows.position = 'dr' THEN alloc_rows.allocation_amount ELSE 0 END) negative_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type
  1347.  FROM " $allocationSourceSql " alloc_rows
  1348.    join acc_clients on acc_clients.accounts_head_id=alloc_rows.accounts_head_id or acc_clients.advance_head_id=alloc_rows.accounts_head_id
  1349.   join client_type on acc_clients.type=client_type.client_type_id
  1350.   WHERE acc_clients.company_id=" $companyId "
  1351.                               GROUP BY client_type.client_type_id";
  1352.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1353.                         
  1354.                         $entries $stmt;
  1355.                         foreach ($entries as $entry) {
  1356.                             $has_payments 1;
  1357.                             $lastBalanceDataByClientType[$entry['client_type_id']] = $entry;
  1358.                             $lastBalanceDataByClientType[$entry['client_type_id']]['collection_amount'] = $entry['positive_amount'] - $entry['negative_amount'];
  1359.                             if (!isset($thisBalanceDataByClientType[$entry['client_type_id']]))
  1360.                                 $thisBalanceDataByClientType[$entry['client_type_id']]['collection_amount'] = 0//just for the lulz
  1361.                             if (!in_array($entry['client_type_id'], $clientTypes)) {
  1362.                                 $clientTypes[] = $entry['client_type_id'];
  1363.                                 $clientTypeNames[$entry['client_type_id']] = $entry['name'];
  1364.                             }
  1365.                         }
  1366.                         $skipHeadIds = [];
  1367.                         $thisReportData = array(
  1368.                             'clientTypes' => $clientTypes,
  1369.                             'clientTypeNames' => $clientTypeNames,
  1370.                             'thisBalanceDataByClientType' => $thisBalanceDataByClientType,
  1371.                             'lastBalanceDataByClientType' => $lastBalanceDataByClientType,
  1372.                         );
  1373.                         $data['collection_position'][$app_company_index] = $thisReportData;
  1374.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1375.                     }
  1376.                     //Return Position
  1377.                     if (in_array('market_return_position'$reportsToGet)) {
  1378.                         $acHeadList = [];
  1379.                         $companyId explode('_'$app_company_index)[1];
  1380.                         $acHeadDataById = [];
  1381.                         $thisBalanceDataByClientType = [];
  1382.                         $lastBalanceDataByClientType = [];
  1383.                         $get_sql "SELECT sum(irr_item.received_total_sales_price) return_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type
  1384.   FROM irr_item
  1385.   join item_received_replacement on item_received_replacement.irr_id=irr_item.irr_id
  1386.   join acc_clients on acc_clients.client_id=item_received_replacement.client_id
  1387.   join client_type on acc_clients.type=client_type.client_type_id
  1388.    WHERE item_received_replacement.company_id=" $companyId " AND item_received_replacement.approved=1
  1389.                           AND item_received_replacement.irr_date between '" $thisPeriodStartDate " 00:00:00' and '" $thisPeriodEndDate " 23:59:59.999'
  1390.                           GROUP BY client_type.client_type_id
  1391.                           ";
  1392.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1393.                         
  1394.                         $entries $stmt;
  1395.                         $clientTypes = [];
  1396.                         $clientTypeNames = [];
  1397.                         $get_sql_1 $get_sql;
  1398.                         foreach ($entries as $entry) {
  1399.                             $has_payments 1;
  1400.                             $thisBalanceDataByClientType[$entry['client_type_id']] = $entry;
  1401.                             $lastBalanceDataByClientType[$entry['client_type_id']]['return_amount'] = 0//just for the lulz
  1402.                             if (!in_array($entry['client_type_id'], $clientTypes)) {
  1403.                                 $clientTypes[] = $entry['client_type_id'];
  1404.                                 $clientTypeNames[$entry['client_type_id']] = $entry['name'];
  1405.                             }
  1406.                         }
  1407.                         $get_sql "SELECT sum(irr_item.received_total_sales_price) return_amount,client_type.client_type_id, client_type.name, acc_clients.client_id, acc_clients.type
  1408.   FROM irr_item
  1409.   join item_received_replacement on item_received_replacement.irr_id=irr_item.irr_id
  1410.   join acc_clients on acc_clients.client_id=item_received_replacement.client_id
  1411.   join client_type on acc_clients.type=client_type.client_type_id
  1412.    WHERE item_received_replacement.company_id=" $companyId " AND item_received_replacement.approved=1
  1413.                           AND item_received_replacement.irr_date between '" $lastPeriodStartDate " 00:00:00' and '" $lastPeriodEndDate " 23:59:59.999'
  1414.                           GROUP BY client_type.client_type_id
  1415.                           ";
  1416.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1417.                         
  1418.                         $entries $stmt;
  1419.                         foreach ($entries as $entry) {
  1420.                             $has_payments 1;
  1421.                             $lastBalanceDataByClientType[$entry['client_type_id']] = $entry;
  1422.                             if (!isset($thisBalanceDataByClientType[$entry['client_type_id']]))
  1423.                                 $thisBalanceDataByClientType[$entry['client_type_id']]['return_amount'] = 0//just for the lulz
  1424.                             if (!in_array($entry['client_type_id'], $clientTypes)) {
  1425.                                 $clientTypes[] = $entry['client_type_id'];
  1426.                                 $clientTypeNames[$entry['client_type_id']] = $entry['name'];
  1427.                             }
  1428.                         }
  1429.                         $skipHeadIds = [];
  1430.                         $thisReportData = array(
  1431.                             'clientTypes' => $clientTypes,
  1432.                             //                            'get_sql_1' => $get_sql_1,
  1433.                             //                            'get_sql' => $get_sql,
  1434.                             'clientTypeNames' => $clientTypeNames,
  1435.                             'thisBalanceDataByClientType' => $thisBalanceDataByClientType,
  1436.                             'lastBalanceDataByClientType' => $lastBalanceDataByClientType,
  1437.                         );
  1438.                         $data['market_return_position'][$app_company_index] = $thisReportData;
  1439.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1440.                     }
  1441.                     //order and client count
  1442.                     if (in_array('order_and_client_count'$reportsToGet)) {
  1443.                         $acHeadList = [];
  1444.                         $companyId explode('_'$app_company_index)[1];
  1445.                         $acHeadDataById = [];
  1446.                         $thisBalanceDataByAcHead = [];
  1447.                         $lastBalanceDataByAcHead = [];
  1448.                         $today = new \DateTime();
  1449.                         $get_sql "SELECT count(sales_order_id) total_so_count, sum(so_amount) total_so_amount, sum(invoice_amount) total_invoice_amount FROM sales_order WHERE sales_order.company_id=" $companyId " and  sales_order.sales_order_date between '" $thisPeriodStartDate " 00:00:00' and '" $thisPeriodEndDate " 23:59:59.999' ";
  1450.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1451.                         
  1452.                         $entries1 $stmt;
  1453.                         $get_sql "SELECT count(client_id) total_clients FROM acc_clients WHERE acc_clients.company_id=" $companyId;
  1454.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1455.                         
  1456.                         $entries2 $stmt;
  1457.                         $currCompanyData Company::getCompanyData($em$session->get(UserConstants::USER_COMPANY_ID$companyId));
  1458.                         $allocationSourceSql $this->buildAllocationAwareTransactionSourceSql(array(
  1459.                             'document_type' => 6,
  1460.                             'company_id' => $companyId,
  1461.                             'start_date' => $thisPeriodStartDate,
  1462.                             'end_date' => $thisPeriodEndDate,
  1463.                             'approved' => 1,
  1464.                             'ledger_hit' => 1,
  1465.                         ));
  1466.                         $get_sql "SELECT SUM(CASE WHEN alloc_rows.position = 'cr' THEN alloc_rows.allocation_amount ELSE ((-1)*alloc_rows.allocation_amount) END) total_collection_amount, alloc_rows.document_hash FROM " $allocationSourceSql " alloc_rows
  1467.                         join acc_clients on acc_clients.accounts_head_id=alloc_rows.accounts_head_id or acc_clients.advance_head_id=alloc_rows.accounts_head_id
  1468.                         WHERE acc_clients.company_id=" $companyId " ";
  1469.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1470.                         
  1471.                         $entries3 $stmt;
  1472.                         //
  1473.                         //                        $get_sql = "SELECT (select  c.balance last_balance from inv_closing_balance c
  1474.                         //where c.product_id=a.product_id and c.warehouse_id=a.warehouse_id and c.action_tag_id=a.action_tag_id order by date desc limit 1) stock_amount
  1475.                         //from inv_closing_balance a
  1476.                         //                        where a.warehouse_id in (select distinct id from warehouse
  1477.                         //                        WHERE  warehouse.company_id=" . $companyId . ") and  a.date between '" . $thisPeriodStartDate . " 00:00:00' and '" . $thisPeriodEndDate . " 23:59:59.999' ";
  1478.                         $get_sql "SELECT a.* , (select  c.balance last_balance from inv_closing_balance c
  1479. where date <='" $thisPeriodEndDate " 00:00:00' and c.product_id=a.product_id and c.warehouse_id=a.warehouse_id and c.action_tag_id=a.action_tag_id order by date desc limit 1) last_balance
  1480. from inv_closing_balance a
  1481. where a.warehouse_id in (select distinct id from warehouse
  1482.                       WHERE  warehouse.company_id=" $companyId ") ";
  1483.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1484.                         
  1485.                         $entries4 $stmt;
  1486.                         $currCompanyData Company::getCompanyData($em$session->get(UserConstants::USER_COMPANY_ID$companyId));
  1487.                         $total_stock_amount 0;
  1488.                         foreach ($entries4 as $ent) {
  1489.                             $total_stock_amount += $ent['last_balance'];
  1490.                         }
  1491.                         $thisReportData = array(
  1492.                             //                            'total_stock_amount' => empty($entries3) ? 0 : $entries4[0]['total_stock_amount'],
  1493.                             'total_stock_amount' => $total_stock_amount,
  1494.                             'total_collection_amount' => empty($entries3) ? $entries3[0]['total_collection_amount'],
  1495.                             'total_so_count' => empty($entries1) ? $entries1[0]['total_so_count'],
  1496.                             'total_so_amount' => empty($entries1) ? $entries1[0]['total_so_amount'],
  1497.                             'total_invoice_amount' => empty($entries1) ? $entries1[0]['total_invoice_amount'],
  1498.                             'total_receivable' => $currCompanyData->getReceivable(),
  1499.                             'total_payable' => $currCompanyData->getPayable(),
  1500.                             'total_clients' => empty($entries2) ? $entries2[0]['total_clients'],
  1501.                         );
  1502.                         $data['order_and_client_count'][$app_company_index] = $thisReportData;
  1503.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1504.                     }
  1505.                     //Inventory Position
  1506.                     if (in_array('inventory_position'$reportsToGet)) {
  1507.                         $acHeadList = [];
  1508.                         $companyId explode('_'$app_company_index)[1];
  1509.                         $acHeadDataById = [];
  1510.                         $thisBalanceDataByActionTag = [];
  1511.                         $lastBalanceDataByActionTag = [];
  1512.                         $warehouseList Inventory::warehouse_action_list($em$companyId$method 'object');
  1513.                         $get_sql "SELECT a.* , (select  c.balance last_balance from inv_closing_balance c
  1514. where date <='" $thisPeriodEndDate " 00:00:00' and c.product_id=a.product_id and c.warehouse_id=a.warehouse_id and c.action_tag_id=a.action_tag_id order by date desc limit 1) last_balance
  1515. from inv_closing_balance a
  1516. where a.warehouse_id in (select distinct id from warehouse
  1517.                        WHERE  warehouse.company_id=" $companyId ") ";
  1518.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1519.                         
  1520.                         $entries $stmt;
  1521.                         $confirmed_action_ids = [];
  1522.                         $confirmed_action_names = [];
  1523.                         $get_sql_1 $get_sql;
  1524.                         foreach ($entries as $entry) {
  1525.                             $has_payments 1;
  1526.                             if (isset($thisBalanceDataByActionTag[$entry['action_tag_id']]))
  1527.                                 $thisBalanceDataByActionTag[$entry['action_tag_id']]['inventory_amount'] += $entry['last_balance'];
  1528.                             else
  1529.                                 $thisBalanceDataByActionTag[$entry['action_tag_id']]['inventory_amount'] = $entry['last_balance'];
  1530.                             if (!isset($lastBalanceDataByActionTag[$entry['action_tag_id']]))
  1531.                                 $lastBalanceDataByActionTag[$entry['action_tag_id']]['inventory_amount'] = 0;
  1532.                             if (!in_array($entry['action_tag_id'], $confirmed_action_ids)) {
  1533.                                 $confirmed_action_ids[] = $entry['action_tag_id'];
  1534.                                 $confirmed_action_names[$entry['action_tag_id']] = $warehouseList[$entry['action_tag_id']]['name'];
  1535.                             }
  1536.                         }
  1537.                         $get_sql "SELECT a.* , (select  c.balance last_balance from inv_closing_balance c
  1538. where date <='" $lastPeriodEndDate " 00:00:00' and c.product_id=a.product_id and c.warehouse_id=a.warehouse_id and c.action_tag_id=a.action_tag_id order by date desc limit 1) last_balance
  1539. from inv_closing_balance a
  1540. where a.warehouse_id in (select distinct id from warehouse
  1541.                        WHERE  warehouse.company_id=" $companyId ") ";
  1542.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1543.                         
  1544.                         $entries $stmt;
  1545.                         foreach ($entries as $entry) {
  1546.                             $has_payments 1;
  1547.                             if (isset($lastBalanceDataByActionTag[$entry['action_tag_id']]))
  1548.                                 $lastBalanceDataByActionTag[$entry['action_tag_id']]['inventory_amount'] += $entry['last_balance'];
  1549.                             else
  1550.                                 $lastBalanceDataByActionTag[$entry['action_tag_id']]['inventory_amount'] = $entry['last_balance'];
  1551.                             if (!isset($thisBalanceDataByActionTag[$entry['action_tag_id']]))
  1552.                                 $thisBalanceDataByActionTag[$entry['action_tag_id']]['inventory_amount'] = 0;
  1553.                             if (!in_array($entry['action_tag_id'], $confirmed_action_ids)) {
  1554.                                 $confirmed_action_ids[] = $entry['action_tag_id'];
  1555.                                 $confirmed_action_names[$entry['action_tag_id']] = $warehouseList[$entry['action_tag_id']]['name'];
  1556.                             }
  1557.                         }
  1558.                         $skipHeadIds = [];
  1559.                         $thisReportData = array(
  1560.                             //                            'clientTypes' => $clientTypes,
  1561.                             //                            'get_sql_1' => $get_sql_1,
  1562.                             //                            'get_sql' => $get_sql,
  1563.                             'confirmed_action_ids' => $confirmed_action_ids,
  1564.                             'confirmed_action_names' => $confirmed_action_names,
  1565.                             'thisBalanceDataByActionTag' => $thisBalanceDataByActionTag,
  1566.                             'lastBalanceDataByActionTag' => $lastBalanceDataByActionTag,
  1567.                         );
  1568.                         $data['inventory_position'][$app_company_index] = $thisReportData;
  1569.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1570.                     }
  1571.                     //Production Position
  1572.                     if (in_array('production_position'$reportsToGet)) {
  1573.                         $acHeadList = [];
  1574.                         $companyId explode('_'$app_company_index)[1];
  1575.                         $acHeadDataById = [];
  1576.                         $thisBalanceDataByIgId = [];
  1577.                         $lastBalanceDataByIgId = [];
  1578.                         $itemGroups = [];
  1579.                         $itemGroupNames = [];
  1580.                         $get_sql "SELECT sum((case WHEN inv_products.curr_sales_price!=0 then inv_products.curr_sales_price else inv_products.curr_purchase_price END )*production_entry_item.produced_qty) production_amount,inv_item_group.id item_group_id ,inv_item_group.name item_group_name ,inv_products.id product_id
  1581.   FROM production_entry_item
  1582.   join production on production_entry_item.production_id=production.production_id
  1583.   join inv_products on production_entry_item.product_id=inv_products.id
  1584.   join inv_item_group on inv_item_group.id=inv_products.ig_id
  1585.    WHERE production.company_id=" $companyId " AND production.approved=1
  1586.                           AND production.production_date between '" $thisPeriodStartDate " 00:00:00' and '" $thisPeriodEndDate " 23:59:59.999'
  1587.                           GROUP BY inv_item_group.id
  1588.                           ";
  1589.                         //                        $get_sql = "SELECT sum(product_mrp.average_price*production_entry_item.produced_qty) production_amount,inv_item_group.id item_group_id ,inv_item_group.name item_group_name ,inv_products.id product_id
  1590.                         //  FROM production_entry_item
  1591.                         //  join production on production_entry_item.production_id=production.production_id
  1592.                         //  join inv_products on production_entry_item.product_id=inv_products.id
  1593.                         //  join product_mrp on production_entry_item.product_id=product_mrp.product_id
  1594.                         //  join inv_item_group on inv_item_group.id=inv_products.ig_id
  1595.                         //   WHERE production.company_id=" . $companyId . " AND production.approved=1
  1596.                         //                          AND production.production_date between '" . $thisPeriodStartDate . " 00:00:00' and '" . $thisPeriodEndDate . " 23:59:59.999'
  1597.                         //                          GROUP BY inv_item_group.id
  1598.                         //                          ";
  1599.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1600.                         
  1601.                         $entries $stmt;
  1602.                         $get_sql_1 $get_sql;
  1603.                         foreach ($entries as $entry) {
  1604.                             $has_payments 1;
  1605.                             $thisBalanceDataByIgId[$entry['item_group_id']] = $entry;
  1606.                             $lastBalanceDataByIgId[$entry['item_group_id']]['production_amount'] = 0//just for the lulz
  1607.                             if (!in_array($entry['item_group_id'], $clientTypes)) {
  1608.                                 $itemGroups[] = $entry['item_group_id'];
  1609.                                 $itemGroupNames[$entry['item_group_id']] = $entry['item_group_name'];
  1610.                             }
  1611.                         }
  1612.                         $get_sql "SELECT sum(production_entry_item.price*production_entry_item.produced_qty) production_amount,inv_item_group.id item_group_id ,inv_item_group.name item_group_name ,inv_products.id product_id
  1613.   FROM production_entry_item
  1614.   join production on production_entry_item.production_id=production.production_id
  1615.   join inv_products on production_entry_item.product_id=inv_products.id
  1616.   join inv_item_group on inv_item_group.id=inv_products.ig_id
  1617.    WHERE production.company_id=" $companyId " AND production.approved=1
  1618.                           AND production.production_date between '" $lastPeriodStartDate " 00:00:00' and '" $lastPeriodEndDate " 23:59:59.999'
  1619.                           GROUP BY inv_item_group.id
  1620.                           ";
  1621.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1622.                         
  1623.                         $entries $stmt;
  1624.                         foreach ($entries as $entry) {
  1625.                             $has_payments 1;
  1626.                             $lastBalanceDataByIgId[$entry['item_group_id']] = $entry;
  1627.                             if (!isset($thisBalanceDataByIgId[$entry['item_group_id']]))
  1628.                                 $thisBalanceDataByIgId[$entry['item_group_id']]['production_amount'] = 0//just for the lulz
  1629.                             if (!in_array($entry['item_group_id'], $clientTypes)) {
  1630.                                 $itemGroups[] = $entry['item_group_id'];
  1631.                                 $itemGroupNames[$entry['item_group_id']] = $entry['item_group_name'];
  1632.                             }
  1633.                         }
  1634.                         $skipHeadIds = [];
  1635.                         $thisReportData = array(
  1636.                             'itemGroups' => $itemGroups,
  1637.                             //                            'get_sql_1' => $get_sql_1,
  1638.                             //                            'get_sql' => $get_sql,
  1639.                             'itemGroupNames' => $itemGroupNames,
  1640.                             'thisBalanceDataByIgId' => $thisBalanceDataByIgId,
  1641.                             'lastBalanceDataByIgId' => $lastBalanceDataByIgId,
  1642.                         );
  1643.                         $data['production_position'][$app_company_index] = $thisReportData;
  1644.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1645.                     }
  1646.                     //Top Products
  1647.                     if (in_array('top_selling_item_position'$reportsToGet)) {
  1648.                         $acHeadList = [];
  1649.                         $companyId explode('_'$app_company_index)[1];
  1650.                         $acHeadDataById = [];
  1651.                         $thisBalanceDataByRelId = [];
  1652.                         $lastBalanceDataByRelId = [];
  1653.                         $clientIds = [];
  1654.                         $clientNames = [];
  1655.                         $productIds = [];
  1656.                         $productNames = [];
  1657.                         $get_sql "SELECT sum(sales_invoice_item.qty*sales_invoice_item.current_purchase_price) sales_amount, inv_products.id product_id, inv_products.name product_name, acc_clients.client_id, acc_clients.type
  1658.   FROM sales_invoice_item
  1659.   join sales_invoice on sales_invoice_item.sales_invoice_id=sales_invoice.sales_invoice_id
  1660.   join inv_products on sales_invoice_item.product_id=inv_products.id
  1661.   join acc_clients on acc_clients.client_id=sales_invoice.client_id
  1662.    WHERE sales_invoice.company_id=" $companyId " AND sales_invoice.approved=1
  1663.                           AND sales_invoice_date between '" $thisPeriodStartDate " 00:00:00' and '" $thisPeriodEndDate " 23:59:59.999'
  1664.                           GROUP BY sales_invoice_item.product_id
  1665.                           ORDER BY sales_amount DESC
  1666.                           LIMIT 10
  1667.                           ";
  1668.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1669.                         
  1670.                         $entries $stmt;
  1671.                         $get_sql_1 $get_sql;
  1672.                         for ($k 0$k 10$k++) {
  1673.                             $has_payments 1;
  1674.                             if (!isset($entries[$k]))
  1675.                                 $entries[$k] = array(
  1676.                                     'sales_amount' => '',
  1677.                                     'product_name' => '',
  1678.                                     'client_name' => '',
  1679.                                 );
  1680.                             $has_payments 1;
  1681.                             $thisBalanceDataByRelId[$k] = $entries[$k];
  1682.                         }
  1683.                         $get_sql "SELECT sum(sales_invoice_item.qty*sales_invoice_item.current_purchase_price) sales_amount, inv_products.id product_id, inv_products.name product_name, acc_clients.client_id, acc_clients.type
  1684.   FROM sales_invoice_item
  1685.   join sales_invoice on sales_invoice_item.sales_invoice_id=sales_invoice.sales_invoice_id
  1686.   join inv_products on sales_invoice_item.product_id=inv_products.id
  1687.   join acc_clients on acc_clients.client_id=sales_invoice.client_id
  1688.    WHERE sales_invoice.company_id=" $companyId " AND sales_invoice.approved=1
  1689.                           AND sales_invoice_date between '" $lastPeriodStartDate " 00:00:00' and '" $lastPeriodEndDate " 23:59:59.999'
  1690.                           GROUP BY sales_invoice_item.product_id
  1691.                           ORDER BY sales_amount DESC
  1692.                           LIMIT 10
  1693.                           ";
  1694.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1695.                         
  1696.                         $entries $stmt;
  1697.                         for ($k 0$k 10$k++) {
  1698.                             $has_payments 1;
  1699.                             if (!isset($entries[$k]))
  1700.                                 $entries[$k] = array(
  1701.                                     'sales_amount' => '',
  1702.                                     'product_name' => '',
  1703.                                     'client_name' => '',
  1704.                                 );
  1705.                             $lastBalanceDataByRelId[$k] = $entries[$k];
  1706.                         }
  1707.                         $skipHeadIds = [];
  1708.                         $thisReportData = array(
  1709.                             //                            'clientTypes' => $clientTypes,
  1710.                             ////                            'get_sql_1' => $get_sql_1,
  1711.                             ////                            'get_sql' => $get_sql,
  1712.                             //                            'clientTypeNames' => $clientTypeNames,
  1713.                             'thisBalanceDataByRelId' => $thisBalanceDataByRelId,
  1714.                             'lastBalanceDataByRelId' => $lastBalanceDataByRelId,
  1715.                         );
  1716.                         $data['top_selling_item_position'][$app_company_index] = $thisReportData;
  1717.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1718.                     }
  1719.                     //Top Products
  1720.                     if (in_array('top_selling_client_position'$reportsToGet)) {
  1721.                         $acHeadList = [];
  1722.                         $companyId explode('_'$app_company_index)[1];
  1723.                         $acHeadDataById = [];
  1724.                         $thisBalanceDataByRelId = [];
  1725.                         $lastBalanceDataByRelId = [];
  1726.                         $clientIds = [];
  1727.                         $clientNames = [];
  1728.                         $productIds = [];
  1729.                         $productNames = [];
  1730.                         $get_sql "SELECT sum(sales_invoice.invoice_amount) sales_amount,  acc_clients.client_id, acc_clients.client_name client_name
  1731.   FROM sales_invoice
  1732.   join acc_clients on acc_clients.client_id=sales_invoice.client_id
  1733.    WHERE sales_invoice.company_id=" $companyId " AND sales_invoice.approved=1
  1734.                           AND sales_invoice_date between '" $thisPeriodStartDate " 00:00:00' and '" $thisPeriodEndDate " 23:59:59.999'
  1735.                           GROUP BY sales_invoice.client_id
  1736.                           ORDER BY sales_amount DESC
  1737.                           LIMIT 10
  1738.                           ";
  1739.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1740.                         
  1741.                         $entries $stmt;
  1742.                         $get_sql_1 $get_sql;
  1743.                         for ($k 0$k 10$k++) {
  1744.                             $has_payments 1;
  1745.                             if (!isset($entries[$k]))
  1746.                                 $entries[$k] = array(
  1747.                                     'sales_amount' => '',
  1748.                                     'product_name' => '',
  1749.                                     'client_name' => '',
  1750.                                 );
  1751.                             $has_payments 1;
  1752.                             $thisBalanceDataByRelId[$k] = $entries[$k];
  1753.                         }
  1754.                         $get_sql "SELECT sum(sales_invoice.invoice_amount) sales_amount,  acc_clients.client_id, acc_clients.client_name client_name
  1755.   FROM sales_invoice
  1756.   join acc_clients on acc_clients.client_id=sales_invoice.client_id
  1757.    WHERE sales_invoice.company_id=" $companyId " AND sales_invoice.approved=1
  1758.                           AND sales_invoice_date between '" $lastPeriodStartDate " 00:00:00' and '" $lastPeriodEndDate " 23:59:59.999'
  1759.                           GROUP BY sales_invoice.client_id
  1760.                           ORDER BY sales_amount DESC
  1761.                           LIMIT 10
  1762.                           ";
  1763.                         $stmt $em->getConnection()->fetchAllAssociative($get_sql);
  1764.                         
  1765.                         $entries $stmt;
  1766.                         for ($k 0$k 10$k++) {
  1767.                             $has_payments 1;
  1768.                             if (!isset($entries[$k]))
  1769.                                 $entries[$k] = array(
  1770.                                     'sales_amount' => '',
  1771.                                     'product_name' => '',
  1772.                                     'client_name' => '',
  1773.                                 );
  1774.                             $lastBalanceDataByRelId[$k] = $entries[$k];
  1775.                         }
  1776.                         $skipHeadIds = [];
  1777.                         $thisReportData = array(
  1778.                             //                            'clientTypes' => $clientTypes,
  1779.                             ////                            'get_sql_1' => $get_sql_1,
  1780.                             ////                            'get_sql' => $get_sql,
  1781.                             //                            'clientTypeNames' => $clientTypeNames,
  1782.                             'thisBalanceDataByRelId' => $thisBalanceDataByRelId,
  1783.                             'lastBalanceDataByRelId' => $lastBalanceDataByRelId,
  1784.                         );
  1785.                         $data['top_selling_client_position'][$app_company_index] = $thisReportData;
  1786.                         //                    $companyListData[] = Company::getCompanyListWithImage($em);
  1787.                     }
  1788.                 }
  1789.             }
  1790.         }
  1791.         return new JsonResponse(
  1792.             array(
  1793.                 'success' => true,
  1794.                 'data' => $data,
  1795.                 'companyListData' => $companyListData,
  1796.                 'dataToConnectList' => $dataToConnectList,
  1797.                 'periodType' => $periodType,
  1798.                 'queriedReportsToGet' => $request->request->get('reportsToGet'),
  1799.                 'reportsToGet' => $reportsToGet,
  1800.                 'thisPeriodStartDate' => $thisPeriodStartDate,
  1801.                 'thisPeriodEndDate' => $thisPeriodEndDate,
  1802.                 'lastPeriodStartDate' => $lastPeriodStartDate,
  1803.                 'lastPeriodEndDate' => $lastPeriodEndDate,
  1804.                 'companyIdListByAppId' => $companyIdListByAppId,
  1805.                 'companyNameListByAppId' => $companyNameListByAppId,
  1806.                 'companyImageListByAppId' => $companyImageListByAppId,
  1807.                 'appIdList' => $appIdList,
  1808.             )
  1809.         );
  1810.     }
  1811.     public function indexAction(Request $request$cgHash '')
  1812.     {
  1813.         $session $request->getSession();
  1814.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  1815.         if ($systemType == '_ERP_') {
  1816.             //do nothing its default to dashboard index
  1817.         } else if ($systemType == '_BUDDYBEE_') {
  1818.             if ($cgHash != '')
  1819.                 $session->set('codeHash'$cgHash);
  1820.         }
  1821.         // Generic::debugMessage($session);
  1822.         $ROUTE_LIST json_decode($session->get(UserConstants::USER_ROUTE_LIST), true);
  1823.         if ($ROUTE_LIST == null)
  1824.             $ROUTE_LIST = [];
  1825.         $CurrentRoute $request->attributes->get('_route');
  1826.         if ($session->get(UserConstants::USER_ROUTE_LIST) == || in_array('management_dashboard'$ROUTE_LIST)) {
  1827.             // User is not authorized. send him to dashboard
  1828.             //                    $controller->addFlash(
  1829.             //                        'error',
  1830.             //                        'Sorry Couldnot insert Data.'
  1831.             //                    );
  1832.             //                    return $this->render('ApplicationBundle:pages/dashboard:advanced_management_dashboard.html.twig',
  1833.             if ($session->has('isMobile'))
  1834.                 if ($session->get('isMobile') == true) {
  1835.                     return $this->render(
  1836.                         '@Application/pages/dashboard/index_finance_mobile.html.twig',
  1837.                         array(
  1838.                             'page_title' => 'Finance Dashboard',
  1839.                             'dashboardDataForUser' => []
  1840.                         )
  1841.                     );
  1842.                 }
  1843.             return $this->render(
  1844.                 '@Application/pages/dashboard/advanced_management_dashboard.html.twig',
  1845.                 array(
  1846.                     'page_title' => 'Dashboard'
  1847.                 )
  1848.             );
  1849.         }
  1850.         if ($session->has('isMobile'))
  1851.             if ($session->get('isMobile') == true) {
  1852.                 if ($systemType == '_CENTRAL_') {
  1853.                     $defaultRoute 'central_landing';
  1854.                     return $this->redirectToRoute($defaultRoute);
  1855.                 }
  1856.                 elseif ($systemType == '_SOPHIA_') {
  1857.                     $defaultRoute 'sofia_dashboard_admin';
  1858.                     return $this->redirectToRoute($defaultRoute);
  1859.                 }else
  1860.                     return $this->render(
  1861.                         '@Application/pages/dashboard/index_finance_mobile.html.twig',
  1862.                         array(
  1863.                             'page_title' => 'Finance Dashboard',
  1864.                             'dashboardDataForUser' => []
  1865.                         )
  1866.                     );
  1867.             }
  1868.         else {
  1869.                 //check if user has a default route if yes redirect to it
  1870.                 if ($session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_SUPPLIER)
  1871.                     $defaultRoute 'supplier_dashboard';
  1872.                 else if ($session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_CLIENT)
  1873.                     $defaultRoute 'client_dashboard';
  1874.                 else if ($session->get(UserConstants::USER_TYPE) == UserConstants::USER_TYPE_APPLICANT) {
  1875.                     if ($systemType == '_CENTRAL_') {
  1876.                         $defaultRoute 'central_landing';
  1877.                     }
  1878.                     elseif ($systemType == '_SOPHIA_') {
  1879.                         $defaultRoute 'sofia_dashboard_admin';
  1880.                     } else
  1881.                         $defaultRoute 'applicant_dashboard';
  1882.                 } else
  1883.                     $defaultRoute $session->get(UserConstants::USER_DEFAULT_ROUTE);
  1884.                 //            if(in_array($defaultRoute, $ROUTE_LIST))
  1885.                 if ($defaultRoute != '' && $defaultRoute != null)
  1886.                     return $this->redirectToRoute($defaultRoute);
  1887.                 else
  1888.                     return $this->redirectToRoute('sales_dashboard');
  1889. //                return $this->render(
  1890. //                    'ApplicationBundle:pages/dashboard:index.html.twig',
  1891. //                    array(
  1892. //                        'page_title' => 'Dashboard',
  1893. //                        'allocation_filters' => [],
  1894. //                        'allocationFilters' => [],
  1895. //                        'allocation_tag_types' => [],
  1896. //                        'allocation_tag_values_by_type' => [],
  1897. //                        'project_list' => [],
  1898. //                        'branch_list' => [],
  1899. //                        'cost_centers' => []
  1900. //                    )
  1901. //                );
  1902.             }
  1903.     }
  1904.     public function indexSupplierAction(Request $request)
  1905.     {
  1906.         $session $request->getSession();
  1907.         $supplierId 3;
  1908.         if ($request->query->has('supplierId')) //for debug now
  1909.         {
  1910.             $session->set('supplierId'$request->query->get('supplierId'));
  1911.         }
  1912.         $supplierId $session->get('supplierId');  //////////////////////LATER
  1913.         $em $this->getDoctrine()->getManager();
  1914.         $companyId $this->getLoggedUserCompanyId($request);
  1915.         $userId $request->getSession()->get(UserConstants::USER_ID);
  1916.         $SD Supplier::GetSupplierProfileDetails($em$supplierId'SI');
  1917.         $dashboardDataForUser = [];
  1918.         return $this->render(
  1919.             '@Application/pages/dashboard/index_supplier.html.twig',
  1920.             array(
  1921.                 'page_title' => 'Supplier Dashboard',
  1922.                 'dashboardDataForUser' => $dashboardDataForUser,
  1923.                 'data' => $SD,
  1924.                 'igList' => Inventory::ItemGroupList($em$companyId)
  1925.             )
  1926.         );
  1927.     }
  1928.     public function indexClientAction(Request $request)
  1929.     {
  1930.         $session $request->getSession();
  1931.         $clientId 3;
  1932.         if ($request->query->has('clientId')) //for debug now
  1933.         {
  1934.             $session->set('clientId'$request->query->get('clientId'));
  1935.         }
  1936.         $clientId $session->get('clientId');  //////////////////////LATER
  1937.         $em $this->getDoctrine()->getManager();
  1938.         $companyId $this->getLoggedUserCompanyId($request);
  1939.         $userId $request->getSession()->get(UserConstants::USER_ID);
  1940.         $SD Client::GetClientProfileDetails($em$clientId'CI');
  1941.         $dashboardDataForUser = [];
  1942.         return $this->render(
  1943.             '@Application/pages/dashboard/index_client.html.twig',
  1944.             array(
  1945.                 'page_title' => 'Client Dashboard',
  1946.                 'dashboardDataForUser' => $dashboardDataForUser,
  1947.                 'data' => $SD,
  1948.                 'igList' => Inventory::ItemGroupList($em$companyId)
  1949.             )
  1950.         );
  1951.     }
  1952.     public function indexFinanceAction(Request $request)
  1953.     {
  1954.         $session $request->getSession();
  1955.         $dashboardDataForUser = [];
  1956.         $em $this->getDoctrine()->getManager();
  1957.         $companyId $this->getLoggedUserCompanyId($request);
  1958.         $userId $request->getSession()->get(UserConstants::USER_ID);
  1959.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  1960.             array(
  1961.                 'CompanyId' => $companyId,
  1962.                 'userId' => $userId,
  1963.                 'status' => GeneralConstant::ACTIVE
  1964.             ),
  1965.             array(
  1966.                 'sequence' => 'ASC'
  1967.             )
  1968.         );
  1969.         if (empty($dbQuery))   ///now get the defaults
  1970.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  1971.                 array(
  1972.                     'CompanyId' => $companyId,
  1973.                     //                    'userId'=>$userId,
  1974.                     'defaultBoxFlag' => 1,
  1975.                     'status' => GeneralConstant::ACTIVE
  1976.                 ),
  1977.                 array(
  1978.                     'sequence' => 'ASC'
  1979.                 )
  1980.             );
  1981.         foreach ($dbQuery as $entry) {
  1982.             $dashboardDataForUser[] = array(
  1983.                 'id' => $entry->getId(),
  1984.                 'widgetId' => $entry->getId(),
  1985.                 'widgetSequence' => $entry->getSequence(),
  1986.                 'widgetStatus' => $entry->getStatus(),
  1987.                 'widgetData' => json_decode($entry->getData(), true),
  1988.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  1989.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  1990.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  1991.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  1992.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  1993.                 'refreshInterval' => $entry->getRefreshInterval(),
  1994.             );
  1995.         }
  1996.         if ($session->has('isMobile')) {
  1997.             if ($session->get('isMobile') == true) {
  1998.                 return $this->render(
  1999.                     '@Application/pages/dashboard/index_finance_mobile.html.twig',
  2000.                     array(
  2001.                         'page_title' => 'Finance Dashboard',
  2002.                         'dashboardDataForUser' => $dashboardDataForUser
  2003.                     )
  2004.                 );
  2005.             } else {
  2006.             }
  2007.         }
  2008.         return $this->render(
  2009.             '@Accounts/pages/finance_dashboard.html.twig',
  2010.             array(
  2011.                 'page_title' => 'Finance Dashboard',
  2012.                 'dashboardDataForUser' => $dashboardDataForUser,
  2013.                 'dashboardAnalytics' => $this->buildFinanceDashboardAnalytics($em)
  2014.             )
  2015.         );
  2016.     }
  2017.     /**
  2018.      * Lean, fail-safe analytics for the Finance cp-shell dashboard. Guarded scalar DQL â€”
  2019.      * a schema/tenant quirk degrades to 0 rather than 500-ing the dashboard.
  2020.      */
  2021.     private function buildFinanceDashboardAnalytics($em)
  2022.     {
  2023.         $scalar = function ($dql$params = []) use ($em) {
  2024.             try {
  2025.                 $v $em->createQuery($dql)->setParameters($params)->getSingleScalarResult();
  2026.                 return $v === null $v;
  2027.             } catch (\Throwable $e) {
  2028.                 return 0;
  2029.             }
  2030.         };
  2031.         $salesInv     = (int) $scalar("SELECT COUNT(i) FROM ApplicationBundle:SalesInvoice i WHERE (i.deleteFlag = 0 OR i.deleteFlag IS NULL)");
  2032.         $expenseInv   = (int) $scalar("SELECT COUNT(e) FROM ApplicationBundle:ExpenseInvoice e WHERE (e.deleteFlag = 0 OR e.deleteFlag IS NULL)");
  2033.         $banks        = (int) $scalar("SELECT COUNT(b) FROM ApplicationBundle:BankAccounts b");
  2034.         $salesPending = (int) $scalar("SELECT COUNT(i) FROM ApplicationBundle:SalesInvoice i WHERE i.approved <> :a AND (i.deleteFlag = 0 OR i.deleteFlag IS NULL)", ['a' => GeneralConstant::APPROVED]);
  2035.         $expPending   = (int) $scalar("SELECT COUNT(e) FROM ApplicationBundle:ExpenseInvoice e WHERE e.approved <> :a AND (e.deleteFlag = 0 OR e.deleteFlag IS NULL)", ['a' => GeneralConstant::APPROVED]);
  2036.         // â”€â”€ Money figures (outstanding + this-month), fail-safe â”€â”€
  2037.         // Receivable/Payable come from the GL (transactions Ã— each leg's FX rate to base), NOT the
  2038.         // invoice sub-ledger (i.dueAmount) nor the stored current_balance. Both of those drift when a
  2039.         // payment is booked as a journal/contra voucher instead of an invoice-linked receipt â€” verified
  2040.         // on a live tenant where the sub-ledger read 38,519 but the GL truth was 2,927. Receivable
  2041.         // (client) heads are debit-nature (dr−cr); payable (supplier) heads credit-nature (cr−dr).
  2042.         // NULLIF(rate,0)→1 keeps base-currency legs (no rate) unconverted.
  2043.         $rawScalar = function ($sql) use ($em) {
  2044.             try { $v $em->getConnection()->fetchOne($sql); return ($v === null || $v === false) ? 0.0 : (float) $v; }
  2045.             catch (\Throwable $e) { return 0.0; }
  2046.         };
  2047.         $arOutstanding $rawScalar(
  2048.             "SELECT COALESCE(SUM(td.amount * COALESCE(NULLIF(td.currency_multiply_rate,0),1) * (CASE WHEN td.position='dr' THEN 1 ELSE -1 END)),0)
  2049.                FROM acc_transaction_details td
  2050.               WHERE td.accounts_head_id IN (SELECT accounts_head_id FROM acc_clients WHERE accounts_head_id IS NOT NULL)");
  2051.         $apOutstanding $rawScalar(
  2052.             "SELECT COALESCE(SUM(td.amount * COALESCE(NULLIF(td.currency_multiply_rate,0),1) * (CASE WHEN td.position='cr' THEN 1 ELSE -1 END)),0)
  2053.                FROM acc_transaction_details td
  2054.               WHERE td.accounts_head_id IN (SELECT accounts_head_id FROM acc_suppliers WHERE accounts_head_id IS NOT NULL)");
  2055.         $monthStart = (new \DateTime('first day of this month 00:00:00'))->format('Y-m-d H:i:s');
  2056.         $salesThisMonth   = (float) $scalar("SELECT COALESCE(SUM(i.invoiceAmount),0) FROM ApplicationBundle:SalesInvoice i WHERE i.createdAt >= :d AND (i.deleteFlag = 0 OR i.deleteFlag IS NULL)", ['d' => $monthStart]);
  2057.         $expenseThisMonth = (float) $scalar("SELECT COALESCE(SUM(e.invoiceAmount),0) FROM ApplicationBundle:ExpenseInvoice e WHERE e.createdAt >= :d AND (e.deleteFlag = 0 OR e.deleteFlag IS NULL)", ['d' => $monthStart]);
  2058.         // â”€â”€ Reuse the company cash-flow builder for the mini trend + current cash â”€â”€
  2059.         $cashFlow = ['hasData' => false];
  2060.         try { $cashFlow $this->buildCompanyCashFlow($em12); } catch (\Throwable $e) { $cashFlow = ['hasData' => false]; }
  2061.         // Base (functional) currency so the money tiles are labelled, not bare numbers.
  2062.         $baseCurrency '';
  2063.         try { $baseCurrency = (string) \ApplicationBundle\Modules\Accounts\Service\CompanyCurrencyResolver::getFunctionalCurrencyCode($em1); } catch (\Throwable $e) { $baseCurrency ''; }
  2064.         return [
  2065.             'base_currency' => $baseCurrency,
  2066.             'kpis' => [
  2067.                 ['label' => 'Sales Invoices',   'value' => $salesInv,   'note' => 'Receivables'],
  2068.                 ['label' => 'Expense Invoices''value' => $expenseInv'note' => 'Payables'],
  2069.                 ['label' => 'Bank Accounts',    'value' => $banks,      'note' => 'Cash & bank'],
  2070.                 ['label' => 'Pending AR',       'value' => $salesPending'note' => 'Sales invoices to approve'],
  2071.                 ['label' => 'Pending AP',       'value' => $expPending,   'note' => 'Expense invoices to approve'],
  2072.             ],
  2073.             'money' => [
  2074.                 ['label' => 'Current Cash',       'value' => isset($cashFlow['closingBalance']) ? $cashFlow['closingBalance'] : 0'note' => 'Cash & bank balance',   'accent' => 'a'],
  2075.                 ['label' => 'Receivable Due',     'value' => round($arOutstanding2),  'note' => 'Outstanding from customers''accent' => 'b'],
  2076.                 ['label' => 'Payable Due',        'value' => round($apOutstanding2),  'note' => 'Outstanding to suppliers',   'accent' => 'c'],
  2077.                 ['label' => 'Invoiced (mo)',      'value' => round($salesThisMonth2), 'note' => 'Sales billed this month',     'accent' => 'b'],
  2078.                 ['label' => 'Expensed (mo)',      'value' => round($expenseThisMonth2), 'note' => 'Expenses this month',       'accent' => 'c'],
  2079.             ],
  2080.             'cashFlow' => $cashFlow,
  2081.             'pending_items' => [
  2082.                 ['label' => 'Sales Invoices',   'value' => $salesPending'note' => 'Receivable approvals'],
  2083.                 ['label' => 'Expense Invoices''value' => $expPending,   'note' => 'Payable approvals'],
  2084.             ],
  2085.         ];
  2086.     }
  2087.     public function indexSalesAction(Request $request)
  2088.     {
  2089.         $session $request->getSession();
  2090.         $dashboardDataForUser = [];
  2091.         $em $this->getDoctrine()->getManager();
  2092.         $companyId $this->getLoggedUserCompanyId($request);
  2093.         $userId $request->getSession()->get(UserConstants::USER_ID);
  2094.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2095.             array(
  2096.                 'CompanyId' => $companyId,
  2097.                 'userId' => $userId,
  2098.                 'status' => GeneralConstant::ACTIVE
  2099.             ),
  2100.             array(
  2101.                 'sequence' => 'ASC'
  2102.             )
  2103.         );
  2104.         if (empty($dbQuery))   ///now get the defaults
  2105.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2106.                 array(
  2107.                     'CompanyId' => $companyId,
  2108.                     //                    'userId'=>$userId,
  2109.                     'defaultBoxFlag' => 1,
  2110.                     'status' => GeneralConstant::ACTIVE
  2111.                 ),
  2112.                 array(
  2113.                     'sequence' => 'ASC'
  2114.                 )
  2115.             );
  2116.         foreach ($dbQuery as $entry) {
  2117.             $dashboardDataForUser[] = array(
  2118.                 'id' => $entry->getId(),
  2119.                 'widgetId' => $entry->getId(),
  2120.                 'widgetSequence' => $entry->getSequence(),
  2121.                 'widgetStatus' => $entry->getStatus(),
  2122.                 'widgetData' => json_decode($entry->getData(), true),
  2123.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  2124.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  2125.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  2126.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  2127.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  2128.                 'refreshInterval' => $entry->getRefreshInterval(),
  2129.             );
  2130.         }
  2131.         if ($session->has('isMobile')) {
  2132.             if ($session->get('isMobile') == true) {
  2133.                 return $this->render(
  2134.                     '@Application/pages/dashboard/index_finance_mobile.html.twig',
  2135.                     array(
  2136.                         'page_title' => 'Finance Dashboard',
  2137.                         'dashboardDataForUser' => $dashboardDataForUser
  2138.                     )
  2139.                 );
  2140.             } else {
  2141.             }
  2142.         }
  2143.         return $this->render(
  2144.             '@Sales/pages/sales_dashboard.html.twig',
  2145.             array(
  2146.                 'page_title' => 'Sales Dashboard',
  2147.                 'dashboardDataForUser' => $dashboardDataForUser,
  2148.                 'dashboardAnalytics' => $this->buildSalesDashboardAnalytics($em)
  2149.             )
  2150.         );
  2151.     }
  2152.     /**
  2153.      * Fail-safe analytics for the Sales cp-shell dashboard â€” KPIs + 6-month order-value trend +
  2154.      * a health snapshot. Every metric/query is guarded so a schema/tenant quirk degrades to
  2155.      * empty rather than 500-ing the dashboard.
  2156.      */
  2157.     private function buildSalesDashboardAnalytics($em)
  2158.     {
  2159.         $scalar = function ($dql$params = []) use ($em) {
  2160.             try {
  2161.                 $v $em->createQuery($dql)->setParameters($params)->getSingleScalarResult();
  2162.                 return $v === null $v;
  2163.             } catch (\Throwable $e) {
  2164.                 return 0;
  2165.             }
  2166.         };
  2167.         $soTotal    = (int) $scalar("SELECT COUNT(s) FROM ApplicationBundle:SalesOrder s WHERE (s.deleteFlag = 0 OR s.deleteFlag IS NULL)");
  2168.         $soApproved = (int) $scalar("SELECT COUNT(s) FROM ApplicationBundle:SalesOrder s WHERE s.approved = :a AND (s.deleteFlag = 0 OR s.deleteFlag IS NULL)", ['a' => GeneralConstant::APPROVED]);
  2169.         $soValue    = (float) $scalar("SELECT SUM(s.soAmount) FROM ApplicationBundle:SalesOrder s WHERE s.approved = :a AND (s.deleteFlag = 0 OR s.deleteFlag IS NULL)", ['a' => GeneralConstant::APPROVED]);
  2170.         $soPending  max($soTotal $soApproved0);
  2171.         $opps       = (int) $scalar("SELECT COUNT(o) FROM ApplicationBundle:Opportunity o WHERE (o.deleteFlag = 0 OR o.deleteFlag IS NULL)");
  2172.         $clients    = (int) $scalar("SELECT COUNT(c) FROM ApplicationBundle:AccClients c");
  2173.         // â”€â”€ 6-month order-value trend (guarded raw SQL â€” flat/empty on any quirk) â”€â”€
  2174.         $monthKeys = [];
  2175.         $monthLabels = [];
  2176.         for ($i 5$i >= 0$i--) {
  2177.             $m = new \DateTime('first day of this month');
  2178.             if ($i 0) {
  2179.                 $m->modify('-' $i ' month');
  2180.             }
  2181.             $monthKeys[] = $m->format('Y-m');
  2182.             $monthLabels[] = $m->format('M');
  2183.         }
  2184.         $trend = function ($sql) use ($em) {
  2185.             try {
  2186.                 return $em->getConnection()->fetchAllAssociative($sql);
  2187.             } catch (\Throwable $e) {
  2188.                 return [];
  2189.             }
  2190.         };
  2191.         $seriesFromRows = function (array $rows, array $keys) {
  2192.             $map = [];
  2193.             foreach ($rows as $r) {
  2194.                 $map[$r['month']] = (float) $r['total'];
  2195.             }
  2196.             $out = [];
  2197.             foreach ($keys as $k) {
  2198.                 $out[] = isset($map[$k]) ? round($map[$k], 2) : 0;
  2199.             }
  2200.             return $out;
  2201.         };
  2202.         $orderRows $trend("
  2203.             SELECT DATE_FORMAT(sales_order_date, '%Y-%m') AS month,
  2204.                    COALESCE(SUM(CAST(COALESCE(NULLIF(so_amount,''),0) AS DECIMAL(15,2))),0) AS total
  2205.             FROM sales_order
  2206.             WHERE status = 1 AND (delete_flag = 0 OR delete_flag IS NULL)
  2207.               AND sales_order_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2208.             GROUP BY DATE_FORMAT(sales_order_date, '%Y-%m') ORDER BY month ASC");
  2209.         $approvedRows $trend("
  2210.             SELECT DATE_FORMAT(sales_order_date, '%Y-%m') AS month,
  2211.                    COALESCE(SUM(CAST(COALESCE(NULLIF(so_amount,''),0) AS DECIMAL(15,2))),0) AS total
  2212.             FROM sales_order
  2213.             WHERE status = 1 AND approved = 1 AND (delete_flag = 0 OR delete_flag IS NULL)
  2214.               AND sales_order_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2215.             GROUP BY DATE_FORMAT(sales_order_date, '%Y-%m') ORDER BY month ASC");
  2216.         $coverage $soTotal round(($soApproved $soTotal) * 1001) : 0;
  2217.         // â”€â”€ Intelligent helper â€” surface the most useful next action â”€â”€
  2218.         if ($soPending 0) {
  2219.             $salesHelper = ['type' => 'warn''text' => $soPending ' sales order' . ($soPending == '' 's') . ' awaiting approval â€” sign off to release delivery.'];
  2220.         } elseif ($opps 0) {
  2221.             $salesHelper = ['type' => 'ok''text' => $opps ' opportunit' . ($opps == 'y' 'ies') . ' in the pipeline and nothing stuck in approval â€” keep them moving.'];
  2222.         } else {
  2223.             $salesHelper null;
  2224.         }
  2225.         return [
  2226.             'helper' => $salesHelper,
  2227.             'kpis' => [
  2228.                 ['label' => 'Sales Orders',     'value' => $soTotal,        'note' => 'Active orders'],
  2229.                 ['label' => 'Approved Value',   'value' => round($soValue), 'note' => 'Approved SO value'],
  2230.                 ['label' => 'Opportunities',    'value' => $opps,           'note' => 'In the pipeline'],
  2231.                 ['label' => 'Clients',          'value' => $clients,        'note' => 'Customer base'],
  2232.                 ['label' => 'Pending Approval''value' => $soPending,      'note' => 'Awaiting sign-off'],
  2233.             ],
  2234.             'pending_items' => [
  2235.                 ['label' => 'Sales Orders''value' => $soPending'note' => 'Waiting for approval'],
  2236.             ],
  2237.             'hero' => [
  2238.                 'labels' => $monthLabels,
  2239.                 'series' => [
  2240.                     ['label' => 'Order Value''values' => $seriesFromRows($orderRows$monthKeys),    'color' => '#2b5fb8''fill' => 'rgba(43,95,184,0.14)'],
  2241.                     ['label' => 'Approved',    'values' => $seriesFromRows($approvedRows$monthKeys), 'color' => '#4BAA6B''fill' => 'rgba(75,170,107,0.14)'],
  2242.                 ],
  2243.             ],
  2244.             'hero_summary' => [
  2245.                 'subhead' => 'Order value over the last 6 months',
  2246.             ],
  2247.             'snapshot' => [
  2248.                 'label' => 'Sales Health',
  2249.                 'ring_value' => $coverage,
  2250.                 'ring_note' => 'Approved of all orders',
  2251.                 'metrics' => [
  2252.                     ['label' => 'Approved Value''value' => number_format(round($soValue)), 'note' => 'Signed-off SO value'],
  2253.                     ['label' => 'Pending Orders''value' => $soPending'note' => 'Awaiting approval'],
  2254.                     ['label' => 'Opportunities',  'value' => $opps,      'note' => 'Open pipeline'],
  2255.                 ],
  2256.             ],
  2257.         ];
  2258.     }
  2259.     public function indexPurchaseAction(Request $request)
  2260.     {
  2261.         $em $this->getDoctrine()->getManager();
  2262.         $companyId $this->getLoggedUserCompanyId($request);
  2263.         $dashboardDataForUser $this->loadDashboardWidgetsForUser($request);
  2264.         $dashboardAnalytics $this->buildPurchaseDashboardAnalytics($em$companyId);
  2265.         return $this->render(
  2266.             '@Purchase/pages/supply_chain_dashboard.html.twig',
  2267.             array(
  2268.                 'page_title' => 'Purchasing Dashboard',
  2269.                 'dashboardMode' => 'purchase',
  2270.                 'dashboardDataForUser' => $dashboardDataForUser,
  2271.                 'dashboardAnalytics' => $dashboardAnalytics
  2272.             )
  2273.         );
  2274.     }
  2275.     public function indexDistributionAction(Request $request)
  2276.     {
  2277.         $session $request->getSession();
  2278.         $dashboardDataForUser = [];
  2279.         $em $this->getDoctrine()->getManager();
  2280.         $companyId $this->getLoggedUserCompanyId($request);
  2281.         $userId $request->getSession()->get(UserConstants::USER_ID);
  2282.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2283.             array(
  2284.                 'CompanyId' => $companyId,
  2285.                 'userId' => $userId,
  2286.                 'status' => GeneralConstant::ACTIVE
  2287.             ),
  2288.             array(
  2289.                 'sequence' => 'ASC'
  2290.             )
  2291.         );
  2292.         if (empty($dbQuery))   ///now get the defaults
  2293.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2294.                 array(
  2295.                     'CompanyId' => $companyId,
  2296.                     //                    'userId'=>$userId,
  2297.                     'defaultBoxFlag' => 1,
  2298.                     'status' => GeneralConstant::ACTIVE
  2299.                 ),
  2300.                 array(
  2301.                     'sequence' => 'ASC'
  2302.                 )
  2303.             );
  2304.         foreach ($dbQuery as $entry) {
  2305.             $dashboardDataForUser[] = array(
  2306.                 'id' => $entry->getId(),
  2307.                 'widgetId' => $entry->getId(),
  2308.                 'widgetSequence' => $entry->getSequence(),
  2309.                 'widgetStatus' => $entry->getStatus(),
  2310.                 'widgetData' => json_decode($entry->getData(), true),
  2311.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  2312.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  2313.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  2314.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  2315.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  2316.                 'refreshInterval' => $entry->getRefreshInterval(),
  2317.             );
  2318.         }
  2319.         return $this->render(
  2320.             '@Distribution/pages/distribution_dashboard.html.twig',
  2321.             array(
  2322.                 'page_title' => 'Distribution Dashboard',
  2323.                 'dashboardDataForUser' => $dashboardDataForUser,
  2324.                 'dashboardAnalytics' => $this->buildDistributionDashboardAnalytics($em)
  2325.             )
  2326.         );
  2327.     }
  2328.     /**
  2329.      * Lean, fail-safe analytics for the Distribution cp-shell dashboard. Guarded scalar DQL â€”
  2330.      * a schema/tenant quirk degrades to 0 rather than 500-ing the dashboard.
  2331.      */
  2332.     private function buildDistributionDashboardAnalytics($em)
  2333.     {
  2334.         $scalar = function ($dql$params = []) use ($em) {
  2335.             try {
  2336.                 $v $em->createQuery($dql)->setParameters($params)->getSingleScalarResult();
  2337.                 return $v === null $v;
  2338.             } catch (\Throwable $e) {
  2339.                 return 0;
  2340.             }
  2341.         };
  2342.         $doTotal    = (int) $scalar("SELECT COUNT(d) FROM ApplicationBundle:DeliveryOrder d WHERE (d.deleteFlag = 0 OR d.deleteFlag IS NULL)");
  2343.         $doApproved = (int) $scalar("SELECT COUNT(d) FROM ApplicationBundle:DeliveryOrder d WHERE d.approved = :a AND (d.deleteFlag = 0 OR d.deleteFlag IS NULL)", ['a' => GeneralConstant::APPROVED]);
  2344.         $doPending  max($doTotal $doApproved0);
  2345.         $confirms   = (int) $scalar("SELECT COUNT(c) FROM ApplicationBundle:DeliveryConfirmation c");
  2346.         $receipts   = (int) $scalar("SELECT COUNT(r) FROM ApplicationBundle:DeliveryReceipt r");
  2347.         $challans   = (int) $scalar("SELECT COUNT(s) FROM ApplicationBundle:ServiceChallan s");
  2348.         return [
  2349.             'kpis' => [
  2350.                 ['label' => 'Delivery Orders',   'value' => $doTotal,   'note' => 'All dispatch orders'],
  2351.                 ['label' => 'Confirmations',     'value' => $confirms,  'note' => 'Delivery confirmed'],
  2352.                 ['label' => 'Delivery Receipts''value' => $receipts,  'note' => 'Received by customer'],
  2353.                 ['label' => 'Service Challans',  'value' => $challans,  'note' => 'Dispatch challans'],
  2354.                 ['label' => 'Pending Dispatch',  'value' => $doPending'note' => 'Awaiting sign-off'],
  2355.             ],
  2356.             'pending_items' => [
  2357.                 ['label' => 'Delivery Orders''value' => $doPending'note' => 'Waiting for approval'],
  2358.             ],
  2359.         ];
  2360.     }
  2361.     public function indexProjectsAction(Request $request)
  2362.     {
  2363.         $em $this->getDoctrine()->getManager();
  2364.         return $this->render(
  2365.             '@Project/pages/projects_dashboard.html.twig',
  2366.             array(
  2367.                 'page_title' => 'Projects Dashboard',
  2368.                 'dashboardAnalytics' => $this->buildProjectsDashboardAnalytics($em),
  2369.             )
  2370.         );
  2371.     }
  2372.     /**
  2373.      * Lean, fail-safe analytics for the Projects cp-shell home. Guarded scalar DQL â€” a
  2374.      * schema/tenant quirk degrades each metric to 0 rather than 500-ing the landing page.
  2375.      * Project.deleteFlag is nullable-with-no-default, so every count uses (=0 OR IS NULL).
  2376.      */
  2377.     private function buildProjectsDashboardAnalytics($em)
  2378.     {
  2379.         $scalar = function ($dql$params = []) use ($em) {
  2380.             try {
  2381.                 $v $em->createQuery($dql)->setParameters($params)->getSingleScalarResult();
  2382.                 return $v === null $v;
  2383.             } catch (\Throwable $e) {
  2384.                 return 0;
  2385.             }
  2386.         };
  2387.         $list = function ($dql$params = [], $max 6) use ($em) {
  2388.             try {
  2389.                 $q $em->createQuery($dql)->setParameters($params)->setMaxResults($max);
  2390.                 return $q->getArrayResult();
  2391.             } catch (\Throwable $e) { return []; }
  2392.         };
  2393.         $today date('Y-m-d');
  2394.         $total     = (int) $scalar("SELECT COUNT(p) FROM ApplicationBundle:Project p WHERE (p.deleteFlag = 0 OR p.deleteFlag IS NULL)");
  2395.         $active    = (int) $scalar("SELECT COUNT(p) FROM ApplicationBundle:Project p WHERE p.status = :s AND (p.deleteFlag = 0 OR p.deleteFlag IS NULL)", ['s' => GeneralConstant::ACTIVE]);
  2396.         $baselines = (int) $scalar("SELECT COUNT(b) FROM ApplicationBundle:ProjectConfigBaseline b");
  2397.         // â”€â”€ Project confirmation status mix (0/null budgeting, 2 confirmed-not-impacted, 1 impacted) â”€â”€
  2398.         $budgeting = (int) $scalar("SELECT COUNT(p) FROM ApplicationBundle:Project p WHERE (p.projectConfirmationStatus = 0 OR p.projectConfirmationStatus IS NULL) AND (p.deleteFlag = 0 OR p.deleteFlag IS NULL)");
  2399.         $confirmed = (int) $scalar("SELECT COUNT(p) FROM ApplicationBundle:Project p WHERE p.projectConfirmationStatus = 2 AND (p.deleteFlag = 0 OR p.deleteFlag IS NULL)");
  2400.         $impacted  = (int) $scalar("SELECT COUNT(p) FROM ApplicationBundle:Project p WHERE p.projectConfirmationStatus = 1 AND (p.deleteFlag = 0 OR p.deleteFlag IS NULL)");
  2401.         // â”€â”€ Milestone health â”€â”€
  2402.         $msTotal     = (int) $scalar("SELECT COUNT(m) FROM ApplicationBundle:ProjectMilestone m");
  2403.         $msDone       = (int) $scalar("SELECT COUNT(m) FROM ApplicationBundle:ProjectMilestone m WHERE m.actualDate IS NOT NULL");
  2404.         $msOverdue   = (int) $scalar("SELECT COUNT(m) FROM ApplicationBundle:ProjectMilestone m WHERE m.actualDate IS NULL AND m.plannedDate IS NOT NULL AND m.plannedDate < :t", ['t' => $today]);
  2405.         $msUpcoming  = (int) $scalar("SELECT COUNT(m) FROM ApplicationBundle:ProjectMilestone m WHERE m.actualDate IS NULL AND m.plannedDate >= :t", ['t' => $today]);
  2406.         $msBilling   = (float) $scalar("SELECT COALESCE(SUM(m.billingAmount),0) FROM ApplicationBundle:ProjectMilestone m");
  2407.         $msInvoiced  = (float) $scalar("SELECT COALESCE(SUM(m.billingAmount),0) FROM ApplicationBundle:ProjectMilestone m WHERE m.invoicedDate IS NOT NULL");
  2408.         $pctComplete $msTotal round($msDone $msTotal 100) : 0;
  2409.         // â”€â”€ Upcoming milestones (not yet done, soonest first) â”€â”€
  2410.         $upRows $list("SELECT m.milestoneName AS name, m.plannedDate AS planned, m.billingAmount AS amount
  2411.                             FROM ApplicationBundle:ProjectMilestone m
  2412.                            WHERE m.actualDate IS NULL AND m.plannedDate >= :t
  2413.                            ORDER BY m.plannedDate ASC", ['t' => $today], 5);
  2414.         $upcoming = [];
  2415.         foreach ($upRows as $r) {
  2416.             $upcoming[] = [
  2417.                 'name'    => $r['name'] ?: 'Milestone',
  2418.                 'date'    => $r['planned'] instanceof \DateTimeInterface $r['planned']->format('Y-m-d') : (is_string($r['planned']) ? substr($r['planned'], 010) : ''),
  2419.                 'amount'  => number_format((float) ($r['amount'] ?? 0), 2'.'','),
  2420.             ];
  2421.         }
  2422.         // â”€â”€ CoPilot surface counts â”€â”€
  2423.         $surfaces = [
  2424.             ['label' => 'Requirements',    'value' => (int) $scalar("SELECT COUNT(r) FROM ApplicationBundle:ProjectRequirement r"), 'icon' => 'checklist',    'route' => 'project_requirement_list'],
  2425.             ['label' => 'Devices',         'value' => (int) $scalar("SELECT COUNT(d) FROM ApplicationBundle:ProjectDevice d"),      'icon' => 'memory',       'route' => 'project_device_list'],
  2426.             ['label' => 'Interfaces',      'value' => (int) $scalar("SELECT COUNT(i) FROM ApplicationBundle:ProjectInterface i"),   'icon' => 'cable',        'route' => 'project_interface_list'],
  2427.             ['label' => 'Config Baselines','value' => $baselines,                                                                    'icon' => 'layers',       'route' => 'project_config_baseline_list'],
  2428.         ];
  2429.         // â”€â”€ Sales target vs achievement (current year) â€” fail-safe â”€â”€
  2430.         $tva null;
  2431.         try {
  2432.             $sts = new \ApplicationBundle\Modules\ProjectSalesReport\Service\SalesTargetService($em);
  2433.             $year date('Y');
  2434.             $perf $sts->fprPerformance(\ApplicationBundle\Modules\ProjectSalesReport\Support\SalesTargetCore::YEARLY$year);
  2435.             $tgt = (float) $perf['totals']['target'];
  2436.             $ach = (float) $perf['totals']['achieved'];
  2437.             $tva = [
  2438.                 'period'   => $year,
  2439.                 'target'   => number_format($tgt0'.'','),
  2440.                 'achieved' => number_format($ach0'.'','),
  2441.                 'pct'      => $perf['totals']['achievement_pct'],       // null when no target set
  2442.                 'bar'      => $tgt min(100round($ach $tgt 100)) : 0,
  2443.                 'has_target' => $tgt 0,
  2444.             ];
  2445.         } catch (\Throwable $e) { $tva null; }
  2446.         // â”€â”€ Smart helper â”€â”€
  2447.         if ($msOverdue 0) {
  2448.             $helper = ['type' => 'warn''text' => $msOverdue ' milestone' . ($msOverdue == '' 's') . ' overdue â€” the planned date has passed with no completion recorded. Review delivery on these first.'];
  2449.         } elseif ($msUpcoming 0) {
  2450.             $helper = ['type' => 'ok''text' => $msUpcoming ' milestone' . ($msUpcoming == '' 's') . ' coming up and nothing overdue â€” delivery is on track.'];
  2451.         } else {
  2452.             $helper null;
  2453.         }
  2454.         return [
  2455.             'kpis' => [
  2456.                 ['label' => 'Total Projects''value' => $total,      'note' => 'All non-deleted projects'],
  2457.                 ['label' => 'Active',          'value' => $active,     'note' => 'Currently active'],
  2458.                 ['label' => 'Milestones Due',  'value' => $msUpcoming'note' => 'Upcoming, not yet done'],
  2459.                 ['label' => 'Overdue',         'value' => $msOverdue,  'note' => 'Past planned date'],
  2460.             ],
  2461.             'status_mix' => [
  2462.                 ['label' => 'Budgeting''value' => $budgeting'color' => '#c98a00'],
  2463.                 ['label' => 'Confirmed''value' => $confirmed'color' => '#1976d2'],
  2464.                 ['label' => 'Impacted',  'value' => $impacted,  'color' => '#2e7d32'],
  2465.             ],
  2466.             'status_total' => $budgeting $confirmed $impacted,
  2467.             'milestones' => [
  2468.                 'total' => $msTotal'done' => $msDone'overdue' => $msOverdue'upcoming' => $msUpcoming,
  2469.                 'pct_complete' => $pctComplete,
  2470.                 'billing_total' => number_format($msBilling2'.'','),
  2471.                 'invoiced_total' => number_format($msInvoiced2'.'','),
  2472.                 'outstanding_total' => number_format(max(0$msBilling $msInvoiced), 2'.'','),
  2473.             ],
  2474.             'surfaces' => $surfaces,
  2475.             'upcoming' => $upcoming,
  2476.             'target_vs_achievement' => $tva,
  2477.             'helper' => $helper,
  2478.             'pending_items' => [
  2479.                 ['label' => 'Open Projects',      'value' => $active,    'note' => 'Active delivery'],
  2480.                 ['label' => 'Overdue Milestones''value' => $msOverdue'note' => 'Past planned date'],
  2481.                 ['label' => 'Due Soon',           'value' => $msUpcoming,'note' => 'Upcoming milestones'],
  2482.             ],
  2483.         ];
  2484.     }
  2485.     public function indexProductionAction(Request $request)
  2486.     {
  2487.         $session $request->getSession();
  2488.         $dashboardDataForUser = [];
  2489.         $em $this->getDoctrine()->getManager();
  2490.         $companyId $this->getLoggedUserCompanyId($request);
  2491.         $userId $request->getSession()->get(UserConstants::USER_ID);
  2492.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2493.             array(
  2494.                 'CompanyId' => $companyId,
  2495.                 'userId' => $userId,
  2496.                 'status' => GeneralConstant::ACTIVE
  2497.             ),
  2498.             array(
  2499.                 'sequence' => 'ASC'
  2500.             )
  2501.         );
  2502.         if (empty($dbQuery))   ///now get the defaults
  2503.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2504.                 array(
  2505.                     'CompanyId' => $companyId,
  2506.                     //                    'userId'=>$userId,
  2507.                     'defaultBoxFlag' => 1,
  2508.                     'status' => GeneralConstant::ACTIVE
  2509.                 ),
  2510.                 array(
  2511.                     'sequence' => 'ASC'
  2512.                 )
  2513.             );
  2514.         foreach ($dbQuery as $entry) {
  2515.             $dashboardDataForUser[] = array(
  2516.                 'id' => $entry->getId(),
  2517.                 'widgetId' => $entry->getId(),
  2518.                 'widgetSequence' => $entry->getSequence(),
  2519.                 'widgetStatus' => $entry->getStatus(),
  2520.                 'widgetData' => json_decode($entry->getData(), true),
  2521.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  2522.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  2523.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  2524.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  2525.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  2526.                 'refreshInterval' => $entry->getRefreshInterval(),
  2527.             );
  2528.         }
  2529.         return $this->render(
  2530.             '@Production/pages/production_dashboard.html.twig',
  2531.             array(
  2532.                 'page_title' => 'Production Dashboard',
  2533.                 'dashboardDataForUser' => $dashboardDataForUser,
  2534.                 'dashboardAnalytics' => $this->buildProductionDashboardAnalytics($em),
  2535.             )
  2536.         );
  2537.     }
  2538.     /**
  2539.      * Lean, fail-safe analytics for the Production cp-shell dashboard. Guarded scalar DQL â€”
  2540.      * a missing entity/column degrades to 0 rather than 500-ing the page.
  2541.      */
  2542.     private function buildProductionDashboardAnalytics($em)
  2543.     {
  2544.         $scalar = function ($dql) use ($em) {
  2545.             try {
  2546.                 $v $em->createQuery($dql)->getSingleScalarResult();
  2547.                 return $v === null $v;
  2548.             } catch (\Throwable $e) {
  2549.                 return 0;
  2550.             }
  2551.         };
  2552.         $entries   = (int) $scalar("SELECT COUNT(p) FROM ApplicationBundle:Production p");
  2553.         $boms      = (int) $scalar("SELECT COUNT(b) FROM ApplicationBundle:ProductionBom b");
  2554.         $schedules = (int) $scalar("SELECT COUNT(s) FROM ApplicationBundle:ProductionSchedule s");
  2555.         $lines     = (int) $scalar("SELECT COUNT(l) FROM ApplicationBundle:ProductionLine l");
  2556.         return [
  2557.             'kpis' => [
  2558.                 ['label' => 'Production Entries''value' => $entries,   'note' => 'All production runs'],
  2559.                 ['label' => 'Bills of Material',  'value' => $boms,      'note' => 'Defined BOMs'],
  2560.                 ['label' => 'Schedules',          'value' => $schedules'note' => 'Planned runs'],
  2561.                 ['label' => 'Production Lines',   'value' => $lines,     'note' => 'Configured lines'],
  2562.             ],
  2563.             'pending_items' => [],
  2564.         ];
  2565.     }
  2566.     public function indexInventoryAction(Request $request)
  2567.     {
  2568.         $em $this->getDoctrine()->getManager();
  2569.         $companyId $this->getLoggedUserCompanyId($request);
  2570.         $dashboardDataForUser $this->loadDashboardWidgetsForUser($request);
  2571.         $dashboardAnalytics $this->buildInventoryDashboardAnalytics($em$companyId);
  2572.         return $this->render(
  2573.             '@Inventory/pages/inventory_dashboard.html.twig',
  2574.             array(
  2575.                 'page_title' => 'Inventory Dashboard',
  2576.                 'dashboardMode' => 'inventory',
  2577.                 'dashboardDataForUser' => $dashboardDataForUser,
  2578.                 'dashboardAnalytics' => $dashboardAnalytics
  2579.             )
  2580.         );
  2581.     }
  2582.     private function loadDashboardWidgetsForUser(Request $request)
  2583.     {
  2584.         $dashboardDataForUser = [];
  2585.         $em $this->getDoctrine()->getManager();
  2586.         $companyId $this->getLoggedUserCompanyId($request);
  2587.         $userId $request->getSession()->get(UserConstants::USER_ID);
  2588.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2589.             array(
  2590.                 'CompanyId' => $companyId,
  2591.                 'userId' => $userId,
  2592.                 'status' => GeneralConstant::ACTIVE
  2593.             ),
  2594.             array(
  2595.                 'sequence' => 'ASC'
  2596.             )
  2597.         );
  2598.         if (empty($dbQuery)) {
  2599.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  2600.                 array(
  2601.                     'CompanyId' => $companyId,
  2602.                     'defaultBoxFlag' => 1,
  2603.                     'status' => GeneralConstant::ACTIVE
  2604.                 ),
  2605.                 array(
  2606.                     'sequence' => 'ASC'
  2607.                 )
  2608.             );
  2609.         }
  2610.         foreach ($dbQuery as $entry) {
  2611.             $dashboardDataForUser[] = array(
  2612.                 'id' => $entry->getId(),
  2613.                 'widgetId' => $entry->getId(),
  2614.                 'widgetSequence' => $entry->getSequence(),
  2615.                 'widgetStatus' => $entry->getStatus(),
  2616.                 'widgetData' => json_decode($entry->getData(), true),
  2617.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  2618.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  2619.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  2620.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  2621.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  2622.                 'refreshInterval' => $entry->getRefreshInterval(),
  2623.             );
  2624.         }
  2625.         return $dashboardDataForUser;
  2626.     }
  2627.     private function buildPurchaseDashboardAnalytics($em$companyId)
  2628.     {
  2629.         $conn $em->getConnection();
  2630.         $monthKeys = [];
  2631.         $monthLabels = [];
  2632.         for ($i 5$i >= 0$i--) {
  2633.             $month = new \DateTime('first day of this month');
  2634.             if ($i 0) {
  2635.                 $month->modify('-' $i ' month');
  2636.             }
  2637.             $monthKeys[] = $month->format('Y-m');
  2638.             $monthLabels[] = $month->format('M');
  2639.         }
  2640.         $poTrendRows $conn->fetchAllAssociative("
  2641.             SELECT DATE_FORMAT(purchase_order_date, '%Y-%m') AS month, COALESCE(SUM(CAST(COALESCE(NULLIF(po_amount, ''), 0) AS DECIMAL(15,2))), 0) AS total
  2642.             FROM purchase_order
  2643.             WHERE company_id = :companyId
  2644.               AND status = 1
  2645.               AND approved = 1
  2646.               AND purchase_order_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2647.             GROUP BY DATE_FORMAT(purchase_order_date, '%Y-%m')
  2648.             ORDER BY month ASC
  2649.         ", ['companyId' => $companyId]);
  2650.         $invoiceTrendRows $conn->fetchAllAssociative("
  2651.             SELECT DATE_FORMAT(purchase_invoice_date, '%Y-%m') AS month, COALESCE(SUM(CAST(COALESCE(NULLIF(invoice_amount, ''), 0) AS DECIMAL(15,2))), 0) AS total
  2652.             FROM purchase_invoice
  2653.             WHERE company_id = :companyId
  2654.               AND status = 1
  2655.               AND approved = 1
  2656.               AND purchase_invoice_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2657.             GROUP BY DATE_FORMAT(purchase_invoice_date, '%Y-%m')
  2658.             ORDER BY month ASC
  2659.         ", ['companyId' => $companyId]);
  2660.         $paidTrendRows $conn->fetchAllAssociative("
  2661.             SELECT DATE_FORMAT(purchase_invoice_date, '%Y-%m') AS month, COALESCE(SUM(CAST(COALESCE(NULLIF(paid_amount, ''), invoice_amount, 0) AS DECIMAL(15,2))), 0) AS total
  2662.             FROM purchase_invoice
  2663.             WHERE company_id = :companyId
  2664.               AND status = 1
  2665.               AND approved = 1
  2666.               AND purchase_invoice_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2667.             GROUP BY DATE_FORMAT(purchase_invoice_date, '%Y-%m')
  2668.             ORDER BY month ASC
  2669.         ", ['companyId' => $companyId]);
  2670.         $requisitionTrendRows $conn->fetchAllAssociative("
  2671.             SELECT DATE_FORMAT(purchase_requisition_date, '%Y-%m') AS month, COUNT(*) AS total
  2672.             FROM purchase_requisition
  2673.             WHERE company_id = :companyId
  2674.               AND status = 1
  2675.               AND purchase_requisition_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2676.             GROUP BY DATE_FORMAT(purchase_requisition_date, '%Y-%m')
  2677.             ORDER BY month ASC
  2678.         ", ['companyId' => $companyId]);
  2679.         $seriesFromRows = function (array $rows, array $monthKeys) {
  2680.             $series array_fill_keys($monthKeys0);
  2681.             foreach ($rows as $row) {
  2682.                 $month $row['month'] ?? null;
  2683.                 if ($month !== null && array_key_exists($month$series)) {
  2684.                     $series[$month] = (float) $row['total'];
  2685.                 }
  2686.             }
  2687.             return array_values($series);
  2688.         };
  2689.         $purchaseOrderTotal = (float) $conn->fetchOne("
  2690.             SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(po_amount, ''), 0) AS DECIMAL(15,2))), 0)
  2691.             FROM purchase_order
  2692.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2693.         ", ['companyId' => $companyId]);
  2694.         $purchaseInvoiceTotal = (float) $conn->fetchOne("
  2695.             SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(invoice_amount, ''), 0) AS DECIMAL(15,2))), 0)
  2696.             FROM purchase_invoice
  2697.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2698.         ", ['companyId' => $companyId]);
  2699.         $purchasePaidTotal = (float) $conn->fetchOne("
  2700.             SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(paid_amount, ''), invoice_amount, 0) AS DECIMAL(15,2))), 0)
  2701.             FROM purchase_invoice
  2702.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2703.         ", ['companyId' => $companyId]);
  2704.         $purchaseRequisitionCount = (int) $conn->fetchOne("
  2705.             SELECT COUNT(*)
  2706.             FROM purchase_requisition
  2707.             WHERE company_id = :companyId AND status = 1
  2708.         ", ['companyId' => $companyId]);
  2709.         $purchaseOrderCount = (int) $conn->fetchOne("
  2710.             SELECT COUNT(*)
  2711.             FROM purchase_order
  2712.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2713.         ", ['companyId' => $companyId]);
  2714.         $purchaseInvoiceCount = (int) $conn->fetchOne("
  2715.             SELECT COUNT(*)
  2716.             FROM purchase_invoice
  2717.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2718.         ", ['companyId' => $companyId]);
  2719.         $pendingPurchaseRequisitionCount = (int) $conn->fetchOne("
  2720.             SELECT COUNT(*)
  2721.             FROM purchase_requisition
  2722.             WHERE company_id = :companyId AND status = 1 AND COALESCE(approved, 0) = 0
  2723.         ", ['companyId' => $companyId]);
  2724.         $pendingPurchaseOrderCount = (int) $conn->fetchOne("
  2725.             SELECT COUNT(*)
  2726.             FROM purchase_order
  2727.             WHERE company_id = :companyId AND status = 1 AND COALESCE(approved, 0) = 0
  2728.         ", ['companyId' => $companyId]);
  2729.         $pendingPurchaseInvoiceCount = (int) $conn->fetchOne("
  2730.             SELECT COUNT(*)
  2731.             FROM purchase_invoice
  2732.             WHERE company_id = :companyId AND status = 1 AND COALESCE(approved, 0) = 0
  2733.         ", ['companyId' => $companyId]);
  2734.         $supplierCount = (int) $conn->fetchOne("
  2735.             SELECT COUNT(DISTINCT supplier_id)
  2736.             FROM purchase_order
  2737.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2738.         ", ['companyId' => $companyId]);
  2739.         $topSuppliers $conn->fetchAllAssociative("
  2740.             SELECT po.supplier_id, s.supplier_name, COALESCE(SUM(CAST(COALESCE(NULLIF(po.po_amount, ''), 0) AS DECIMAL(15,2))), 0) AS total
  2741.             FROM purchase_order po
  2742.             LEFT JOIN acc_suppliers s ON s.supplier_id = po.supplier_id
  2743.             WHERE po.company_id = :companyId AND po.status = 1 AND po.approved = 1
  2744.             GROUP BY po.supplier_id, s.supplier_name
  2745.             ORDER BY total DESC
  2746.             LIMIT 5
  2747.         ", ['companyId' => $companyId]);
  2748.         $topSupplierTotal 0;
  2749.         foreach ($topSuppliers as $row) {
  2750.             $topSupplierTotal += (float) $row['total'];
  2751.         }
  2752.         $funnelBase max($purchaseRequisitionCount$purchaseOrderCount$purchaseInvoiceCount1);
  2753.         $paidCoverage $purchaseInvoiceTotal ? ($purchasePaidTotal $purchaseInvoiceTotal) * 100 0;
  2754.         return array(
  2755.             'kpis' => array(
  2756.                 array('label' => 'Purchase Orders''value' => $purchaseOrderCount'note' => 'Approved and active''icon' => 'shopping-cart''color' => 'blue'),
  2757.                 array('label' => 'Invoice Value''value' => $purchaseInvoiceTotal'note' => 'Billed through the period''icon' => 'file-text''color' => 'green'),
  2758.                 array('label' => 'Paid Value''value' => $purchasePaidTotal'note' => 'Settled to suppliers''icon' => 'check-circle''color' => 'teal'),
  2759.                 array('label' => 'Outstanding Due''value' => max($purchaseInvoiceTotal $purchasePaidTotal0), 'note' => 'Open supplier liability''icon' => 'hourglass-half''color' => 'red'),
  2760.                 array('label' => 'Suppliers''value' => $supplierCount'note' => 'Active vendor base''icon' => 'building''color' => 'amber'),
  2761.                 array('label' => 'Open Requisitions''value' => $pendingPurchaseRequisitionCount'note' => 'Waiting for movement''icon' => 'tasks''color' => 'slate'),
  2762.             ),
  2763.             'pending_total' => $pendingPurchaseRequisitionCount $pendingPurchaseOrderCount $pendingPurchaseInvoiceCount,
  2764.             'pending_items' => array(
  2765.                 array('label' => 'Requisitions''value' => $pendingPurchaseRequisitionCount'note' => 'Needs buy-side review'),
  2766.                 array('label' => 'Purchase Orders''value' => $pendingPurchaseOrderCount'note' => 'Waiting for approval'),
  2767.                 array('label' => 'Purchase Invoices''value' => $pendingPurchaseInvoiceCount'note' => 'Pending matching'),
  2768.             ),
  2769.             'hero' => array(
  2770.                 'labels' => $monthLabels,
  2771.                 'series' => array(
  2772.                     array('label' => 'PO Value''values' => $seriesFromRows($poTrendRows$monthKeys), 'color' => '#3D7DB8''fill' => 'rgba(61,125,184,0.14)'),
  2773.                     array('label' => 'Invoice Value''values' => $seriesFromRows($invoiceTrendRows$monthKeys), 'color' => '#4BAA6B''fill' => 'rgba(75,170,107,0.14)'),
  2774.                     array('label' => 'Paid Value''values' => $seriesFromRows($paidTrendRows$monthKeys), 'color' => '#2F9E91''fill' => 'rgba(47,158,145,0.14)'),
  2775.                 ),
  2776.             ),
  2777.             'hero_summary' => array(
  2778.                 'headline' => $purchaseInvoiceTotal round($paidCoverage1) . '%' '0%',
  2779.                 'headline_label' => 'Payment coverage',
  2780.                 'subhead' => 'Paid ' round($paidCoverage1) . '% of billed value',
  2781.             ),
  2782.             'snapshot' => array(
  2783.                 'label' => 'Procurement Health',
  2784.                 'ring_value' => round($paidCoverage1),
  2785.                 'ring_note' => 'Invoice coverage',
  2786.                 'metrics' => array(
  2787.                     array('label' => 'Requisition to PO''value' => $purchaseRequisitionCount round(($purchaseOrderCount $purchaseRequisitionCount) * 1001) . '%' '0%''note' => 'Flow conversion'),
  2788.                     array('label' => 'Average PO Size''value' => $purchaseOrderCount number_format($purchaseOrderTotal $purchaseOrderCount0'.'',') : '0''note' => 'Approved order value'),
  2789.                     array('label' => 'Due Ratio''value' => $purchaseInvoiceTotal round((max($purchaseInvoiceTotal $purchasePaidTotal0) / $purchaseInvoiceTotal) * 1001) . '%' '0%''note' => 'Open liability share'),
  2790.                     array('label' => 'Supplier Concentration''value' => $purchaseOrderTotal round(($topSupplierTotal $purchaseOrderTotal) * 1001) . '%' '0%''note' => 'Top-5 spend share'),
  2791.                 ),
  2792.             ),
  2793.             'lower_cards' => array(
  2794.                 array(
  2795.                     'title' => 'Pipeline Atlas',
  2796.                     'subtitle' => 'Requisition to payment flow',
  2797.                     'type' => 'pipeline',
  2798.                     'items' => array(
  2799.                         array('label' => 'Requisitions''value' => $purchaseRequisitionCount'note' => 'Planning demand'),
  2800.                         array('label' => 'Purchase Orders''value' => $purchaseOrderCount'note' => 'Committed spend'),
  2801.                         array('label' => 'Purchase Invoices''value' => $purchaseInvoiceCount'note' => 'Vendor billing'),
  2802.                         array('label' => 'Settled''value' => (int) $conn->fetchOne("SELECT COUNT(*) FROM purchase_invoice WHERE company_id = :companyId AND status = 1 AND approved = 1 AND CAST(COALESCE(NULLIF(paid_amount, ''), 0) AS DECIMAL(15,2)) > 0", ['companyId' => $companyId]), 'note' => 'Cash released'),
  2803.                     ),
  2804.                     'base' => $funnelBase,
  2805.                 ),
  2806.                 array(
  2807.                     'title' => 'Supplier Mix',
  2808.                     'subtitle' => 'Concentration by approved spend',
  2809.                     'type' => 'bars',
  2810.                     'items' => array_map(function ($row) use ($topSupplierTotal) {
  2811.                         $total = (float) $row['total'];
  2812.                         return array(
  2813.                             'label' => $row['supplier_name'] ?: ('Supplier #' $row['supplier_id']),
  2814.                             'value' => $total,
  2815.                             'bar' => $topSupplierTotal round(($total $topSupplierTotal) * 1001) : 0,
  2816.                             'note' => 'Approved spend share',
  2817.                         );
  2818.                     }, $topSuppliers),
  2819.                 ),
  2820.                 array(
  2821.                     'title' => 'Spend Lens',
  2822.                     'subtitle' => 'Analytical ratios that matter',
  2823.                     'type' => 'ratios',
  2824.                     'items' => array(
  2825.                         array('label' => 'Payment Coverage''value' => round($paidCoverage1) . '%''bar' => $paidCoverage'note' => 'Cash settled vs billed'),
  2826.                         array('label' => 'Requisition Coverage''value' => $purchaseRequisitionCount round(($purchaseOrderCount $purchaseRequisitionCount) * 1001) . '%' '0%''bar' => $purchaseRequisitionCount ? (($purchaseOrderCount $purchaseRequisitionCount) * 100) : 0'note' => 'POs created from requests'),
  2827.                         array('label' => 'Open Due''value' => number_format(max($purchaseInvoiceTotal $purchasePaidTotal0), 0'.'','), 'bar' => $purchaseInvoiceTotal ? ((max($purchaseInvoiceTotal $purchasePaidTotal0) / $purchaseInvoiceTotal) * 100) : 0'note' => 'Balance still outstanding'),
  2828.                     ),
  2829.                 ),
  2830.             ),
  2831.             'months' => $monthLabels
  2832.         );
  2833.     }
  2834.     private function buildInventoryDashboardAnalytics($em$companyId)
  2835.     {
  2836.         $conn $em->getConnection();
  2837.         $monthKeys = [];
  2838.         $monthLabels = [];
  2839.         for ($i 5$i >= 0$i--) {
  2840.             $month = new \DateTime('first day of this month');
  2841.             if ($i 0) {
  2842.                 $month->modify('-' $i ' month');
  2843.             }
  2844.             $monthKeys[] = $month->format('Y-m');
  2845.             $monthLabels[] = $month->format('M');
  2846.         }
  2847.         $receivedRows $conn->fetchAllAssociative("
  2848.             SELECT DATE_FORMAT(stock_received_note_date, '%Y-%m') AS month, COUNT(*) AS total
  2849.             FROM stock_received_note
  2850.             WHERE company_id = :companyId
  2851.               AND status = 1
  2852.               AND approved = 1
  2853.               AND stock_received_note_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2854.             GROUP BY DATE_FORMAT(stock_received_note_date, '%Y-%m')
  2855.             ORDER BY month ASC
  2856.         ", ['companyId' => $companyId]);
  2857.         $transferRows $conn->fetchAllAssociative("
  2858.             SELECT DATE_FORMAT(stock_transfer_date, '%Y-%m') AS month, COUNT(*) AS total
  2859.             FROM stock_transfer
  2860.             WHERE company_id = :companyId
  2861.               AND status = 1
  2862.               AND approved = 1
  2863.               AND stock_transfer_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2864.             GROUP BY DATE_FORMAT(stock_transfer_date, '%Y-%m')
  2865.             ORDER BY month ASC
  2866.         ", ['companyId' => $companyId]);
  2867.         $consumptionRows $conn->fetchAllAssociative("
  2868.             SELECT DATE_FORMAT(stock_consumption_note_date, '%Y-%m') AS month, COUNT(*) AS total
  2869.             FROM stock_consumption_note
  2870.             WHERE company_id = :companyId
  2871.               AND status = 1
  2872.               AND approved = 1
  2873.               AND stock_consumption_note_date >= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
  2874.             GROUP BY DATE_FORMAT(stock_consumption_note_date, '%Y-%m')
  2875.             ORDER BY month ASC
  2876.         ", ['companyId' => $companyId]);
  2877.         $seriesFromRows = function (array $rows, array $monthKeys) {
  2878.             $series array_fill_keys($monthKeys0);
  2879.             foreach ($rows as $row) {
  2880.                 $month $row['month'] ?? null;
  2881.                 if ($month !== null && array_key_exists($month$series)) {
  2882.                     $series[$month] = (float) $row['total'];
  2883.                 }
  2884.             }
  2885.             return array_values($series);
  2886.         };
  2887.         $skuCount = (int) $conn->fetchOne("
  2888.             SELECT COUNT(*)
  2889.             FROM inv_products
  2890.             WHERE company_id = :companyId AND status = 1
  2891.         ", ['companyId' => $companyId]);
  2892.         $totalUnits = (float) $conn->fetchOne("
  2893.             SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2))), 0)
  2894.             FROM inv_products
  2895.             WHERE company_id = :companyId AND status = 1
  2896.         ", ['companyId' => $companyId]);
  2897.         $stockValue = (float) $conn->fetchOne("
  2898.             SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2)) * CAST(COALESCE(NULLIF(curr_purchase_price, ''), 0) AS DECIMAL(15,2))), 0)
  2899.             FROM inv_products
  2900.             WHERE company_id = :companyId AND status = 1
  2901.         ", ['companyId' => $companyId]);
  2902.         $lowStockCount = (int) $conn->fetchOne("
  2903.             SELECT COUNT(*)
  2904.             FROM inv_products
  2905.             WHERE company_id = :companyId
  2906.               AND status = 1
  2907.               AND CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2)) <= CAST(COALESCE(NULLIF(reorder_level, ''), 0) AS DECIMAL(15,2))
  2908.               AND CAST(COALESCE(NULLIF(reorder_level, ''), 0) AS DECIMAL(15,2)) > 0
  2909.         ", ['companyId' => $companyId]);
  2910.         $zeroStockCount = (int) $conn->fetchOne("
  2911.             SELECT COUNT(*)
  2912.             FROM inv_products
  2913.             WHERE company_id = :companyId AND status = 1 AND CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2)) <= 0
  2914.         ", ['companyId' => $companyId]);
  2915.         $overstockCount = (int) $conn->fetchOne("
  2916.             SELECT COUNT(*)
  2917.             FROM inv_products
  2918.             WHERE company_id = :companyId
  2919.               AND status = 1
  2920.               AND CAST(COALESCE(NULLIF(reorder_level, ''), 0) AS DECIMAL(15,2)) > 0
  2921.               AND CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2)) > (CAST(COALESCE(NULLIF(reorder_level, ''), 0) AS DECIMAL(15,2)) * 3)
  2922.         ", ['companyId' => $companyId]);
  2923.         $warehouseCount = (int) $conn->fetchOne("
  2924.             SELECT COUNT(*)
  2925.             FROM warehouse
  2926.             WHERE company_id = :companyId AND status = 1
  2927.         ", ['companyId' => $companyId]);
  2928.         $receivedPending = (int) $conn->fetchOne("
  2929.             SELECT COUNT(*)
  2930.             FROM stock_received_note
  2931.             WHERE company_id = :companyId AND status = 1 AND COALESCE(approved, 0) = 0
  2932.         ", ['companyId' => $companyId]);
  2933.         $transferPending = (int) $conn->fetchOne("
  2934.             SELECT COUNT(*)
  2935.             FROM stock_transfer
  2936.             WHERE company_id = :companyId AND status = 1 AND COALESCE(approved, 0) = 0
  2937.         ", ['companyId' => $companyId]);
  2938.         $consumptionPending = (int) $conn->fetchOne("
  2939.             SELECT COUNT(*)
  2940.             FROM stock_consumption_note
  2941.             WHERE company_id = :companyId AND status = 1 AND COALESCE(approved, 0) = 0
  2942.         ", ['companyId' => $companyId]);
  2943.         $receivedCount = (int) $conn->fetchOne("
  2944.             SELECT COUNT(*)
  2945.             FROM stock_received_note
  2946.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2947.         ", ['companyId' => $companyId]);
  2948.         $transferCount = (int) $conn->fetchOne("
  2949.             SELECT COUNT(*)
  2950.             FROM stock_transfer
  2951.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2952.         ", ['companyId' => $companyId]);
  2953.         $consumptionCount = (int) $conn->fetchOne("
  2954.             SELECT COUNT(*)
  2955.             FROM stock_consumption_note
  2956.             WHERE company_id = :companyId AND status = 1 AND approved = 1
  2957.         ", ['companyId' => $companyId]);
  2958.         $warehouseMap = \ApplicationBundle\Modules\Inventory\Inventory::WarehouseList($em$companyId);
  2959.         $warehouseRows $conn->fetchAllAssociative("
  2960.             SELECT warehouse_id, COALESCE(SUM(CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2))), 0) AS total_qty,
  2961.                    COALESCE(SUM(CAST(COALESCE(NULLIF(qty, ''), 0) AS DECIMAL(15,2)) * CAST(COALESCE(NULLIF(curr_purchase_price, ''), 0) AS DECIMAL(15,2))), 0) AS total_value
  2962.             FROM inventory_storage
  2963.             WHERE company_id = :companyId
  2964.             GROUP BY warehouse_id
  2965.             ORDER BY total_value DESC
  2966.             LIMIT 5
  2967.         ", ['companyId' => $companyId]);
  2968.         $productRows $conn->fetchAllAssociative("
  2969.             SELECT s.product_id, p.name, p.reorder_level,
  2970.                    COALESCE(SUM(CAST(COALESCE(NULLIF(s.qty, ''), 0) AS DECIMAL(15,2))), 0) AS total_qty,
  2971.                    COALESCE(SUM(CAST(COALESCE(NULLIF(s.qty, ''), 0) AS DECIMAL(15,2)) * CAST(COALESCE(NULLIF(s.curr_purchase_price, ''), 0) AS DECIMAL(15,2))), 0) AS total_value
  2972.             FROM inventory_storage s
  2973.             LEFT JOIN inv_products p ON p.id = s.product_id
  2974.             WHERE s.company_id = :companyId
  2975.             GROUP BY s.product_id, p.name, p.reorder_level
  2976.             ORDER BY total_value DESC
  2977.             LIMIT 5
  2978.         ", ['companyId' => $companyId]);
  2979.         $movementBalance $receivedCount $consumptionCount;
  2980.         $healthIndex $skuCount max(0100 round(($lowStockCount $skuCount) * 100)) : 0;
  2981.         $reorderPressure $skuCount round(($lowStockCount $skuCount) * 1001) : 0;
  2982.         $stockCoverage $warehouseCount round($totalUnits $warehouseCount1) : 0;
  2983.         $topWarehouseTotal 0;
  2984.         foreach ($warehouseRows as $row) {
  2985.             $topWarehouseTotal += (float) $row['total_value'];
  2986.         }
  2987.         $topProductTotal 0;
  2988.         foreach ($productRows as $row) {
  2989.             $topProductTotal += (float) $row['total_value'];
  2990.         }
  2991.         return array(
  2992.             'kpis' => array(
  2993.                 array('label' => 'SKUs''value' => $skuCount'note' => 'Active item master''icon' => 'cube''color' => 'blue'),
  2994.                 array('label' => 'On-hand Units''value' => $totalUnits'note' => 'Current quantity snapshot''icon' => 'cubes''color' => 'green'),
  2995.                 array('label' => 'Stock Value''value' => $stockValue'note' => 'Book value at purchase cost''icon' => 'database''color' => 'teal'),
  2996.                 array('label' => 'Low Stock SKUs''value' => $lowStockCount'note' => 'At or below reorder point''icon' => 'exclamation-triangle''color' => 'red'),
  2997.                 array('label' => 'Warehouses''value' => $warehouseCount'note' => 'Active storage nodes''icon' => 'warehouse''color' => 'amber'),
  2998.                 array('label' => 'Pending Docs''value' => $receivedPending $transferPending $consumptionPending'note' => 'Awaiting approval''icon' => 'hourglass-half''color' => 'slate'),
  2999.             ),
  3000.             'pending_total' => $receivedPending $transferPending $consumptionPending,
  3001.             'pending_items' => array(
  3002.                 array('label' => 'Stock Received''value' => $receivedPending'note' => 'Incoming goods'),
  3003.                 array('label' => 'Stock Transfer''value' => $transferPending'note' => 'Warehouse movement'),
  3004.                 array('label' => 'Consumption Notes''value' => $consumptionPending'note' => 'Consumption posting'),
  3005.             ),
  3006.             'hero' => array(
  3007.                 'labels' => $monthLabels,
  3008.                 'series' => array(
  3009.                     array('label' => 'Received''values' => $seriesFromRows($receivedRows$monthKeys), 'color' => '#3D7DB8''fill' => 'rgba(61,125,184,0.14)'),
  3010.                     array('label' => 'Transfers''values' => $seriesFromRows($transferRows$monthKeys), 'color' => '#D4A843''fill' => 'rgba(212,168,67,0.14)'),
  3011.                     array('label' => 'Consumed''values' => $seriesFromRows($consumptionRows$monthKeys), 'color' => '#C05350''fill' => 'rgba(192,83,80,0.14)'),
  3012.                 ),
  3013.             ),
  3014.             'hero_summary' => array(
  3015.                 'headline' => $healthIndex '%',
  3016.                 'headline_label' => 'Health index',
  3017.                 'subhead' => 'Low stock pressure at ' $reorderPressure '%',
  3018.             ),
  3019.             'snapshot' => array(
  3020.                 'label' => 'Stock Health',
  3021.                 'ring_value' => $healthIndex,
  3022.                 'ring_note' => 'Health index',
  3023.                 'metrics' => array(
  3024.                     array('label' => 'Low Stock Pressure''value' => $reorderPressure '%''note' => 'At or under reorder'),
  3025.                     array('label' => 'Movement Balance''value' => $movementBalance'note' => 'Received minus consumed'),
  3026.                     array('label' => 'Avg Units / Warehouse''value' => $stockCoverage'note' => 'Distribution breadth'),
  3027.                     array('label' => 'Zero Stock SKUs''value' => $zeroStockCount'note' => 'Immediate attention'),
  3028.                 ),
  3029.             ),
  3030.             'lower_cards' => array(
  3031.                 array(
  3032.                     'title' => 'Reorder Radar',
  3033.                     'subtitle' => 'What needs intervention now',
  3034.                     'type' => 'radar',
  3035.                     'items' => array(
  3036.                         array('label' => 'Low Stock''value' => $lowStockCount'bar' => $skuCount ? (($lowStockCount $skuCount) * 100) : 0'note' => 'At reorder threshold'),
  3037.                         array('label' => 'Zero Stock''value' => $zeroStockCount'bar' => $skuCount ? (($zeroStockCount $skuCount) * 100) : 0'note' => 'Unavailable items'),
  3038.                         array('label' => 'Overstock''value' => $overstockCount'bar' => $skuCount ? (($overstockCount $skuCount) * 100) : 0'note' => 'Potential capital lock-up'),
  3039.                         array('label' => 'Movement Balance''value' => $movementBalance'bar' => max(0min(10050 + ($movementBalance 5))), 'note' => 'Inbound vs consumption'),
  3040.                     ),
  3041.                 ),
  3042.                 array(
  3043.                     'title' => 'Warehouse Atlas',
  3044.                     'subtitle' => 'Value concentration by store',
  3045.                     'type' => 'bars',
  3046.                     'items' => array_map(function ($row) use ($warehouseMap$topWarehouseTotal) {
  3047.                         $warehouseId = (int) $row['warehouse_id'];
  3048.                         $warehouseName = isset($warehouseMap[$warehouseId]['name']) ? $warehouseMap[$warehouseId]['name'] : ('Warehouse #' $warehouseId);
  3049.                         $total = (float) $row['total_value'];
  3050.                         return array(
  3051.                             'label' => $warehouseName,
  3052.                             'value' => $total,
  3053.                             'bar' => $topWarehouseTotal round(($total $topWarehouseTotal) * 1001) : 0,
  3054.                             'note' => 'Stock value share',
  3055.                         );
  3056.                     }, $warehouseRows),
  3057.                 ),
  3058.                 array(
  3059.                     'title' => 'Value Lens',
  3060.                     'subtitle' => 'Highest value stock pockets',
  3061.                     'type' => 'products',
  3062.                     'items' => array_map(function ($row) use ($topProductTotal) {
  3063.                         $total = (float) $row['total_value'];
  3064.                         $reorderLevel = isset($row['reorder_level']) ? (float) $row['reorder_level'] : 0;
  3065.                         return array(
  3066.                             'label' => $row['name'] ?: ('SKU #' $row['product_id']),
  3067.                             'value' => $total,
  3068.                             'bar' => $topProductTotal round(($total $topProductTotal) * 1001) : 0,
  3069.                             'note' => 'Reorder level ' number_format($reorderLevel0'.'','),
  3070.                         );
  3071.                     }, $productRows),
  3072.                 ),
  3073.             ),
  3074.             'months' => $monthLabels
  3075.         );
  3076.     }
  3077.     public function indexServiceAction(Request $request)
  3078.     {
  3079.         $session $request->getSession();
  3080.         $dashboardDataForUser = [];
  3081.         $em $this->getDoctrine()->getManager();
  3082.         $companyId $this->getLoggedUserCompanyId($request);
  3083.         $userId $request->getSession()->get(UserConstants::USER_ID);
  3084.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  3085.             array(
  3086.                 'CompanyId' => $companyId,
  3087.                 'userId' => $userId,
  3088.                 'status' => GeneralConstant::ACTIVE
  3089.             ),
  3090.             array(
  3091.                 'sequence' => 'ASC'
  3092.             )
  3093.         );
  3094.         if (empty($dbQuery))   ///now get the defaults
  3095.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  3096.                 array(
  3097.                     'CompanyId' => $companyId,
  3098.                     //                    'userId'=>$userId,
  3099.                     'defaultBoxFlag' => 1,
  3100.                     'status' => GeneralConstant::ACTIVE
  3101.                 ),
  3102.                 array(
  3103.                     'sequence' => 'ASC'
  3104.                 )
  3105.             );
  3106.         foreach ($dbQuery as $entry) {
  3107.             $dashboardDataForUser[] = array(
  3108.                 'id' => $entry->getId(),
  3109.                 'widgetId' => $entry->getId(),
  3110.                 'widgetSequence' => $entry->getSequence(),
  3111.                 'widgetStatus' => $entry->getStatus(),
  3112.                 'widgetData' => json_decode($entry->getData(), true),
  3113.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  3114.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  3115.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  3116.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  3117.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  3118.                 'refreshInterval' => $entry->getRefreshInterval(),
  3119.             );
  3120.         }
  3121.         return $this->render(
  3122.             '@Application/pages/dashboard/index_sales.html.twig',
  3123.             array(
  3124.                 'page_title' => 'Sales Dashboard',
  3125.                 'dashboardDataForUser' => $dashboardDataForUser
  3126.             )
  3127.         );
  3128.     }
  3129.     public function modifyDashboardAction(Request $request)
  3130.     {
  3131.         $session $request->getSession();
  3132.         $em $this->getDoctrine()->getManager();
  3133.         $companyId $this->getLoggedUserCompanyId($request);
  3134.         $userId $request->getSession()->get(UserConstants::USER_ID);
  3135.         if ($request->isMethod('post')) {
  3136.             //update dashboard data
  3137.             if ($request->request->has('widgetId')) {
  3138.                 foreach ($request->request->get('widgetId') as $k => $v) {
  3139.                     if ($v != 0) {
  3140.                         //exists sso edit
  3141.                         $widget $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findOneBy(
  3142.                             array(
  3143.                                 'id' => $v,
  3144.                             )
  3145.                         );
  3146.                     } else
  3147.                         $widget = new DashboardWidget();
  3148.                     $widget->setData($request->request->get('widgetData')[$k]);
  3149.                     $widget->setSequence($request->request->get('widgetSequence')[$k]);
  3150.                     $widget->setStatus($request->request->has('widgetStatus') ? $request->request->get('widgetStatus')[$k] : GeneralConstant::ACTIVE);
  3151.                     $widget->setUserId($userId);
  3152.                     $widget->setCompanyId($companyId);
  3153.                     $widget->setDefaultBoxFlag($request->request->has('defaultBoxFlag') ? $request->request->get('defaultBoxFlag')[$k] : 0);
  3154.                     if ($v == 0)
  3155.                         $em->persist($widget);
  3156.                     $em->flush();
  3157.                 }
  3158.             }
  3159.         }
  3160.         $dashboardDataForUser = [];
  3161.         $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  3162.             array(
  3163.                 'CompanyId' => $companyId,
  3164.                 'userId' => $userId,
  3165.                 'status' => GeneralConstant::ACTIVE
  3166.             )
  3167.         );
  3168.         if (empty($dbQuery))   ///now get the defaults
  3169.             $dbQuery $em->getRepository("ApplicationBundle\\Entity\\DashboardWidget")->findBy(
  3170.                 array(
  3171.                     'CompanyId' => $companyId,
  3172.                     //                    'userId'=>$userId,
  3173.                     'defaultBoxFlag' => 1,
  3174.                     'status' => GeneralConstant::ACTIVE
  3175.                 )
  3176.             );
  3177.         foreach ($dbQuery as $entry) {
  3178.             $dashboardDataForUser[] = array(
  3179.                 'id' => $entry->getId(),
  3180.                 'widgetId' => $entry->getId(),
  3181.                 'widgetSequence' => $entry->getSequence(),
  3182.                 'widgetStatus' => $entry->getStatus(),
  3183.                 'widgetData' => $entry->getData(),
  3184.                 'defaultBoxFlag' => $entry->getDefaultBoxFlag(),
  3185.                 'widgetSizeTiny' => $entry->getSizeTiny(),
  3186.                 'widgetSizeSmall' => $entry->getSizeSmall(),
  3187.                 'widgetSizeMedium' => $entry->getSizeMedium(),
  3188.                 'widgetSizeLarge' => $entry->getSizeLarge(),
  3189.                 'refreshInterval' => $entry->getRefreshInterval(),
  3190.             );
  3191.         }
  3192.         //1st try to see if any exists
  3193.         return $this->render(
  3194.             '@Application/pages/dashboard/index_sales.html.twig',
  3195.             array(
  3196.                 'page_title' => 'Modify Dashboard'
  3197.             )
  3198.         );
  3199.     }
  3200.     public function ChangeCompanyDashboardAction(Request $request$id 1)
  3201.     {
  3202.         $session $request->getSession();
  3203.         if ($request->query->has('sys_admin_panel'))
  3204.             return $this->redirectToRoute('system_admin_dashboard');
  3205.         else {
  3206.             $session->set(UserConstants::USER_COMPANY_ID$id);
  3207.             return $this->redirectToRoute('dashboard');
  3208.         }
  3209.     }
  3210.     public function ChangeLeftPanelDisplayStatusAction(Request $request)
  3211.     {
  3212.         $session $request->getSession();
  3213.         $curr_status 1;
  3214.         if ($session->has('HIDE_LEFT_PANEL'))
  3215.             $curr_status $session->get('HIDE_LEFT_PANEL');
  3216.         if ($curr_status == 1)
  3217.             $curr_status 0;
  3218.         else
  3219.             $curr_status 1;
  3220.         $session->set('HIDE_LEFT_PANEL'$curr_status);
  3221.         //            return $this->redirectToRoute('dashboard');
  3222.         return new Response($curr_status);
  3223.     }
  3224.     public function PermissionDeniedAction(Request $request)
  3225.     {
  3226.         $session $request->getSession();
  3227.         // Generic::debugMessage($session);
  3228.         return $this->render(
  3229.             '@System/pages/permission_denied.html.twig',
  3230.             array(
  3231.                 'page_title' => 'Permission Denied'
  3232.             )
  3233.         );
  3234.     }
  3235.     public function MyDocumentsAction(Request $request)
  3236.     {
  3237.         $session $request->getSession();
  3238.         $em $this->getDoctrine()->getManager();
  3239.         /* DATE FILTER â€” issue register #14. A month token wins over a hand-typed range
  3240.            (register #27: "i need another filter field where i can select only Month option"),
  3241.            and an INVALID range is reported rather than silently ignored â€” a filter that
  3242.            quietly drops your input is worse than one that says no. */
  3243.         $period PeriodFilterCore::resolve(
  3244.             $request->query->get('month'''),
  3245.             $request->query->get('start_date'''),
  3246.             $request->query->get('end_date''')
  3247.         );
  3248.         $periodError $period['ok'] ? '' $period['reason'];
  3249.         $data MiscActions::getDocumentsByUserId(
  3250.             $em,
  3251.             $session->get(UserConstants::USER_ID),
  3252.             $period['ok'] ? $period['start'] : '',
  3253.             $period['ok'] ? $period['end'] : ''
  3254.         );
  3255.         // DOC-001: the view calls path(item.documentViewPathName); if an entity's
  3256.         // registered view-route name is stale/unregistered, path() throws and the
  3257.         // whole page 500s the moment a user owns a document of that type. Validate
  3258.         // each route against the router and fall back to a safe one.
  3259.         $routes $this->container->get('router')->getRouteCollection();
  3260.         if (is_array($data)) {
  3261.             foreach ($data as $k => $item) {
  3262.                 $rn = isset($item['documentViewPathName']) ? $item['documentViewPathName'] : '';
  3263.                 if ($rn === '' || $routes->get($rn) === null) {
  3264.                     $data[$k]['documentViewPathName'] = 'dashboard';
  3265.                 }
  3266.             }
  3267.         }
  3268.         return $this->render(
  3269.             '@Application/pages/dashboard/my_documents.html.twig',
  3270.             array(
  3271.                 'page_title' => 'My Documents',
  3272.                 'data' => $data,
  3273.                 'filter_month' => $request->query->get('month'''),
  3274.                 'filter_start' => $request->query->get('start_date'''),
  3275.                 'filter_end' => $request->query->get('end_date'''),
  3276.                 'filter_label' => $period['ok'] ? $period['label'] : '',
  3277.                 'filter_error' => $periodError,
  3278.                 'month_options' => PeriodFilterCore::recentMonths(date('Y-m-d'), 18),
  3279.             )
  3280.         );
  3281.     }
  3282.     //     public function MyDocumentsListForAppAction(Request $request)
  3283.     //     {
  3284.     //         $session = $request->getSession();
  3285.     //         $em = $this->getDoctrine()->getManager();
  3286.     //         $absoluteUrlList = [];
  3287.     //         foreach (GeneralConstant::$Entity_list_details as $e => $d) {
  3288.     //             if (isset($d['entity_print_route_path_name']))
  3289.     //                 $absoluteUrlList[$e] = $this->generateUrl($d['entity_print_route_path_name'], [], UrlGenerator::ABSOLUTE_URL);
  3290.     //         }
  3291.     //         $data = MiscActions::getDocumentsByUserIdForApp($em, $session->get(UserConstants::USER_ID), 1, $absoluteUrlList);
  3292.     //         // Generic::debugMessage($session);
  3293.     //         return new JsonResponse(array(
  3294.     //             'data' => $data
  3295.     //         ));
  3296.     // //        return $this->render('ApplicationBundle:pages/dashboard:my_documents.html.twig',
  3297.     // //            array(
  3298.     // //                'page_title' => 'My Documents',
  3299.     // //                'data' => $data
  3300.     // //            )
  3301.     // //        );
  3302.     //     }
  3303.     public function MyDocumentsListForAppAction(Request $request)
  3304.     {
  3305.         $session $request->getSession();
  3306.         $em $this->getDoctrine()->getManager();
  3307.         // Build absolute URL list
  3308.         $absoluteUrlList = [];
  3309.         foreach (GeneralConstant::$Entity_list_details as $e => $d) {
  3310.             if (isset($d['entity_print_route_path_name'])) {
  3311.                 $absoluteUrlList[$e] = $this->generateUrl($d['entity_print_route_path_name'], [], UrlGenerator::ABSOLUTE_URL);
  3312.             }
  3313.         }
  3314.         // Extract pagination parameters from the request
  3315.         $page $request->query->get('page''_UNSET_');
  3316.         $offset $request->query->get('offset'0);
  3317.         $limit $request->query->get('limit'10); // default limit is 10
  3318.         // Call the document list method with pagination
  3319.         return new JsonResponse(
  3320.             MiscActions::getDocumentsByUserIdForApp(
  3321.                 $em,
  3322.                 $session->get(UserConstants::USER_ID),
  3323.                 1,
  3324.                 $absoluteUrlList,
  3325.                 $page,
  3326.                 $offset,
  3327.                 $limit
  3328.             )
  3329.         );
  3330.     }
  3331.     public function ShowExceptionAction(Request $requestFlattenException $exceptionDebugLoggerInterface $logger null)
  3332.     {
  3333.         $session $request->getSession();
  3334.         $em $this->getDoctrine()->getManager();
  3335.         // Generic::debugMessage($session);
  3336.         //        $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
  3337.         //        $showException = $request->attributes->get('showException', $this->debug); // As opposed to an additional parameter, this maintains BC
  3338.         $code $exception->getStatusCode();
  3339.         //        $data = MiscActions::getDocumentsByUserId($em, $session->get(UserConstants::USER_ID));
  3340.         return $this->render(
  3341.             '@Application/pages/error/error_' $code '.html.twig',
  3342.             array(
  3343.                 'page_title' => 'Sorry',
  3344.                 //                'data' => $data
  3345.             )
  3346.         );
  3347.     }
  3348.     public function NotificationAction(Request $request)
  3349.     {
  3350.         $session $request->getSession();
  3351.         //'error', 'success', 'alert', 'information', 'warning', 'confirm'
  3352.         $themes = array(
  3353.             'error' => 'bg-red',
  3354.             'success' => 'bg-green',
  3355.             'alert' => 'bg-purple',
  3356.             'information' => 'bg-grey',
  3357.             'warning' => 'bg-orange',
  3358.             'confirm' => 'bg-blue',
  3359.         );
  3360.         $fa = array(
  3361.             'error' => 'fa fa-ban',
  3362.             'success' => 'fa fa-check',
  3363.             'alert' => 'fa fa-envelope',
  3364.             'information' => 'fa fa-comments',
  3365.             'warning' => 'fa fa-warning',
  3366.             'confirm' => 'fa fa-crosshairs',
  3367.         );
  3368.         // Generic::debugMessage($session);
  3369.         // â”€â”€ DB-first notification list â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
  3370.         // History is sourced from entity_notification (persistent DB), not the
  3371.         // socket server's in-memory cache which is lost on restart / missing the
  3372.         // /get_all_notification endpoint entirely.
  3373.         $cgEm   $this->getDoctrine()->getManager('company_group');
  3374.         $userId = (int) $request->getSession()->get(UserConstants::USER_ID0);
  3375.         $companyId = (int) $request->getSession()->get(UserConstants::USER_COMPANY_ID0);
  3376.         $filterUnread $request->query->get('filter') === 'unread';
  3377.         $qb $cgEm->getRepository('CompanyGroupBundle\\Entity\\EntityNotification')
  3378.             ->createQueryBuilder('n')
  3379.             ->where('n.userId = :uid')
  3380.             ->setParameter('uid'$userId);
  3381.         if ($filterUnread) {
  3382.             $qb->andWhere('n.seenFlag = 0');
  3383.         }
  3384.         $notifications $qb
  3385.             ->orderBy('n.notificationTs''DESC')
  3386.             ->setMaxResults(100)
  3387.             ->getQuery()
  3388.             ->getResult();
  3389.         $unreadCount = (int) $cgEm->getConnection()->fetchOne(
  3390.             'SELECT COUNT(*) FROM entity_notification WHERE user_id = :uid AND seen_flag = 0',
  3391.             ['uid' => $userId]
  3392.         );
  3393.         return $this->render(
  3394.             '@Application/pages/dashboard/notification.html.twig',
  3395.             array(
  3396.                 'page_title'    => 'Notifications',
  3397.                 'dt'            => $notifications,
  3398.                 'unreadCount'   => $unreadCount,
  3399.                 'filterUnread'  => $filterUnread,
  3400.                 'themes'        => $themes,
  3401.                 'fa'            => $fa,
  3402.             )
  3403.         );
  3404.     }
  3405.     public function NotificationDetailAction(Request $request$id 0)
  3406.     {
  3407.         $em $this->getDoctrine()->getManager('company_group');
  3408.         $notification $em->getRepository('CompanyGroupBundle\\Entity\\EntityNotification')->find($id);
  3409.         if (!$notification) {
  3410.             return $this->render(
  3411.                 '@Application/pages/dashboard/notification_detail.html.twig',
  3412.                 array(
  3413.                     'page_title' => 'Notification Detail',
  3414.                     'notification' => null,
  3415.                     'detailError' => 'Notification not found.',
  3416.                 )
  3417.             );
  3418.         }
  3419.         if ((int) $notification->getSeenFlag() !== 1) {
  3420.             $notification->setSeenFlag(1);
  3421.         }
  3422.         if ((int) $notification->getReadFlag() !== 1) {
  3423.             $notification->setReadFlag(1);
  3424.         }
  3425.         $em->flush();
  3426.         return $this->render(
  3427.             '@Application/pages/dashboard/notification_detail.html.twig',
  3428.             array(
  3429.                 'page_title' => 'Notification Detail',
  3430.                 'notification' => $notification,
  3431.                 'detailError' => '',
  3432.             )
  3433.         );
  3434.     }
  3435.     public function EditAccountAction(Request $request)
  3436.     {
  3437.         $session $request->getSession();
  3438.         //'error', 'success', 'alert', 'information', 'warning', 'confirm'
  3439.         $themes = array(
  3440.             'error' => 'bg-red',
  3441.             'success' => 'bg-green',
  3442.             'alert' => 'bg-purple',
  3443.             'information' => 'bg-aqua',
  3444.             'warning' => 'bg-orange',
  3445.             'confirm' => 'bg-blue',
  3446.         );
  3447.         $fa = array(
  3448.             'error' => 'fa fa-ban',
  3449.             'success' => 'fa fa-check',
  3450.             'alert' => 'fa fa-envelope',
  3451.             'information' => 'fa fa-comments',
  3452.             'warning' => 'fa fa-warning',
  3453.             'confirm' => 'fa fa-crosshairs',
  3454.         );
  3455.         $em $this->getDoctrine()->getManager();
  3456.         $g_path '';
  3457.         if ($request->isMethod('POST')) {
  3458.             $post $request->request;
  3459.             $path "";
  3460.             foreach ($request->files as $uploadedFile) {
  3461.                 if ($uploadedFile != null) {
  3462.                     $fileName md5(uniqid()) . '.' $uploadedFile->guessExtension();
  3463.                     $path $fileName;
  3464.                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/FileUploads/' $request->request->get('userId') . '/';
  3465.                     if (!file_exists($upl_dir)) {
  3466.                         mkdir($upl_dir0777true);
  3467.                     }
  3468.                     $file $uploadedFile->move($upl_dir$path);
  3469.                 }
  3470.             }
  3471.             if ($path != "")
  3472.                 $file_path 'uploads/FileUploads/' $request->request->get('userId') . '/' $path;
  3473.             $g_path $this->container->getParameter('kernel.root_dir') . '/../web/uploads/FileUploads/' $request->request->get('userId') . '/' $path;
  3474.             //            $img_file = file_get_contents($g_path);
  3475.             //            $image_data=base64_encode($img_file);
  3476.             //            $encoded_data=System::encryptSignature($image_data,$request->request->get('approvalHash'));
  3477.             $query_here $this->getDoctrine()
  3478.                 ->getRepository('ApplicationBundle\\Entity\\SysUser')
  3479.                 ->findOneBy(
  3480.                     array('userId' => $request->request->get('userId'))
  3481.                 );
  3482.             if ($query_here) {
  3483.                 $new $query_here;
  3484.                 if ($path != "") {
  3485.                     if ($request->request->has('check_pp')) {
  3486.                         $new->setImage($file_path);
  3487.                         $session->set(UserConstants::USER_IMAGE$new->getImage());
  3488.                     } else
  3489.                         $new->setImage('');
  3490.                 }
  3491.                 $new->setName($request->request->get('name'));
  3492.                 $session->set(UserConstants::USER_NAME$request->request->get('name'));
  3493.                 //now password
  3494.                 if ($request->request->get('oldPass') != '') {
  3495.                     //1st check if old pass valid
  3496.                     if (!$this->container->get('app.legacy_password_service')->verifyWithSalt($new->getPassword(), $request->request->get('oldPass'), $new->getSalt())) {
  3497.                         $this->addFlash(
  3498.                             'error',
  3499.                             'Your Old Password Was Wrong'
  3500.                         );
  3501.                     } else {
  3502.                         //old pass valid so now check if neww passes matches
  3503.                         if ($request->request->get('newPass') == $request->request->get('newPassAgain')) {
  3504.                             $new->setSalt(uniqid(mt_rand()));
  3505.                             $password $this->container->get('app.legacy_password_service')->hashWithSalt($request->request->get('newPass'), $new->getSalt());
  3506.                             $new->setPassword($password);
  3507.                             $em->flush();
  3508.                         } else {
  3509.                             $this->addFlash(
  3510.                                 'error',
  3511.                                 'Passwords Did not Match'
  3512.                             );
  3513.                         }
  3514.                     }
  3515.                 }
  3516.             } else {
  3517.                 //                    $new=new EncryptedSignature();
  3518.                 //                    $new->setData($encoded_data);
  3519.                 //                    $new->setUserId($request->request->get('userId'));
  3520.                 //                    $em->persist($new);
  3521.             }
  3522.             $em->flush();
  3523.             //            now deleting the file
  3524.         }
  3525.         $user_data Users::getUserInfoByLoginId($em$this->getLoggedUserLoginId($request));
  3526.         // Generic::debugMessage($session);
  3527.         return $this->render(
  3528.             '@System/pages/settings/edit_account.html.twig',
  3529.             array(
  3530.                 'page_title' => 'Edit Account',
  3531.                 'user_data' => $user_data,
  3532.                 //                'dt'=>json_decode(System::GetAllNotification($request->getSession()->get(UserConstants::USER_ID)),true),
  3533.                 'themes' => $themes,
  3534.                 'fa' => $fa,
  3535.             )
  3536.         );
  3537.     }
  3538.     public function indexApplicantAction(Request $request)
  3539.     {
  3540.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  3541.         $twig_file '@Application/pages/login/applicant_login.html.twig';
  3542.         $session $request->getSession();
  3543.         if ($systemType == '_BUDDYBEE_') {
  3544.             if ($session->get('buddybeeAdminLevel'0) > 1)
  3545.                 return $this->redirectToRoute("buddybee_admin_dashboard", []);
  3546.             elseif ($session->get('isConsultant') == 1)
  3547.                 return $this->redirectToRoute("consultant_dashboard", []);
  3548.             else
  3549.                 return $this->redirectToRoute("student_dashboard", []);
  3550.         } elseif ($systemType == '_CENTRAL_') {
  3551.             return $this->render(
  3552.                 '@Application/pages/dashboard/index_applicant.html.twig',
  3553.                 array(
  3554.                     'page_title' => 'Applicant Dashboard'
  3555.                 )
  3556.             );
  3557.         } else
  3558.             return $this->render(
  3559.                 '@Application/pages/dashboard/consultant_dashboard.html.twig',
  3560.                 array(
  3561.                     'page_title' => 'Applicant Dashboard'
  3562.                 )
  3563.             );
  3564.     }
  3565.     public function indexCentralLandingAction(Request $request)
  3566.     {
  3567.         $session $request->getSession();
  3568.         $userAccessList $session->get('userAccessList', []);
  3569.         $companyNames array_map(function ($company) {
  3570.             return $company['companyName'];
  3571.         }, $userAccessList);
  3572.         if ($request->isMethod('POST')) {
  3573.             $employeeId $request->request->get('employee_id');
  3574.             $companyName $request->request->get('company_name');
  3575.             if ($employeeId && $companyName) {
  3576.                 return new JsonResponse([
  3577.                     'status' => 'success',
  3578.                     'message' => 'Data received successfully',
  3579.                     'employee_id' => $employeeId,
  3580.                     'company_name' => $companyName,
  3581.                 ]);
  3582.             } else {
  3583.                 return new JsonResponse([
  3584.                     'status' => 'error',
  3585.                     'message' => 'Employee ID or Company Name is missing',
  3586.                 ]);
  3587.             }
  3588.         }
  3589.         // If the request is not a POST request, render the normal page
  3590.         return $this->render(
  3591.             '@Application/pages/dashboard/index_central_landing.html.twig',
  3592.             [
  3593.                 'page_title' => 'Central Landing',
  3594.                 'companyNames' => $companyNames
  3595.             ]
  3596.         );
  3597.     }
  3598.     public function HummanResourceAction()
  3599.     {
  3600.         $em $this->getDoctrine()->getManager();
  3601.         $currentTime = new \Datetime();
  3602.         $currDate $currentTime->format('Y-m-d');
  3603.         $queryBuilder $em->createQueryBuilder();
  3604.         $queryBuilder->select('A.employeeId''A.entry''A.lastIn''A.lastOut''A.currentLocation','A.createdAt''E.name','E.image','D.positionName')
  3605.             ->from('ApplicationBundle\\Entity\\EmployeeAttendance''A')
  3606.             ->where('A.createdAt >=  :date')
  3607.             ->andWhere('A.createdAt <=  :date_end')
  3608.             ->leftJoin('ApplicationBundle\\Entity\\Employee''E''WITH''A.employeeId = E.employeeId')
  3609.             ->leftJoin('ApplicationBundle\\Entity\\SysDepartmentPosition''D''WITH''E.positionId = D.positionId')
  3610.             ->setParameter('date'$currDate)
  3611.             ->setParameter('date_end'$currDate ' 23:59:59')
  3612.             ->orderBy('A.createdAt''DESC'// latest records first
  3613.             ->setMaxResults(5); // limit to 5 records
  3614.         $data $queryBuilder->getQuery()->getResult();
  3615.         $formattedData array_map(function($item) {
  3616.             return [
  3617.                 'employeeId' => $item['employeeId'],
  3618.                 'entry' => $item['entry'] ? $item['entry']->format('Y-m-d H:i:s') : null,
  3619.                 'lastIn' => $item['lastIn'] ? $item['lastIn']->format('Y-m-d H:i:s') : null,
  3620.                 'lastOut' => $item['lastOut'] ? $item['lastOut']->format('Y-m-d H:i:s') : null,
  3621.                 'currentLocation' => $item['currentLocation'],
  3622.                 'createdAt' => $item['createdAt'] ? $item['createdAt']->format('Y-m-d H:i:s') : null,
  3623.                 'name' => $item['name'],
  3624.                 'image' => $item['image'],
  3625.                 'positionName' => $item['positionName'],
  3626.             ];
  3627.         }, $data);
  3628.         $totalEmployees $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3629.             ->createQueryBuilder('E')
  3630.             ->select('COUNT(E.emp_status)')
  3631.             ->where('E.emp_status = 1')
  3632.             ->getQuery()
  3633.             ->getSingleScalarResult();
  3634.         $maleCount $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3635.             ->createQueryBuilder('E')
  3636.             ->select('COUNT(E.id)')
  3637.             ->where('E.sex = 1')
  3638.             ->getQuery()
  3639.             ->getSingleScalarResult();
  3640.         $femaleCount $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3641.             ->createQueryBuilder('E')
  3642.             ->select('COUNT(E.id)')
  3643.             ->where('E.sex = 2')
  3644.             ->getQuery()
  3645.             ->getSingleScalarResult();
  3646.         $fullTime $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3647.             ->createQueryBuilder('E')
  3648.             ->select('COUNT(E.id)')
  3649.             ->where('E.empType = 1')
  3650.             ->getQuery()
  3651.             ->getSingleScalarResult();
  3652.         $partTime $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3653.             ->createQueryBuilder('E')
  3654.             ->select('COUNT(E.id)')
  3655.             ->where('E.empType = 2')
  3656.             ->getQuery()
  3657.             ->getSingleScalarResult();
  3658.         $intern $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3659.             ->createQueryBuilder('E')
  3660.             ->select('COUNT(E.id)')
  3661.             ->where('E.empType = 3')
  3662.             ->getQuery()
  3663.             ->getSingleScalarResult();
  3664.         $temporary $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3665.             ->createQueryBuilder('E')
  3666.             ->select('COUNT(E.id)')
  3667.             ->where('E.empType = 4')
  3668.             ->getQuery()
  3669.             ->getSingleScalarResult();
  3670.         $contractual $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  3671.             ->createQueryBuilder('E')
  3672.             ->select('COUNT(E.id)')
  3673.             ->where('E.empType = 5')
  3674.             ->getQuery()
  3675.             ->getSingleScalarResult();
  3676.         return $this->render(
  3677.             '@Application/pages/dashboard/humanResource.html.twig',
  3678.             [
  3679.                 'page_title' => 'Human Resource Dashboard',
  3680.                 'attendanceDetails' => $formattedData,
  3681.                 'totalEmployee' => $totalEmployees,
  3682.                 'maleCount' => $maleCount,
  3683.                 'femaleCount' => $femaleCount,
  3684.                 'fullTime' => $fullTime,
  3685.                 'partTime' => $partTime,
  3686.                 'temporary' => $temporary,
  3687.                 'contractual' => $contractual,
  3688.                 'intern' => $intern,
  3689.             ]
  3690.         );
  3691.     }
  3692.     public function projectCashFlowReportAction(Request $request)
  3693.     {
  3694.         $em $this->getDoctrine()->getManager();
  3695.         $context $request->query->get('context''finance'); // 'finance' | 'projects' â€” only tweaks the active nav item
  3696.         $cashFlow = ['hasData' => false];
  3697.         try {
  3698.             $cashFlow $this->buildCompanyCashFlow($em12);
  3699.         } catch (\Throwable $e) {
  3700.             $cashFlow = ['hasData' => false'error' => $e->getMessage()];
  3701.         }
  3702.         return $this->render(
  3703.             '@Application/pages/dashboard/cash_flow_report.html.twig',
  3704.             array(
  3705.                 'page_title' => 'Cash Flow Report',
  3706.                 'cashFlow'   => $cashFlow,
  3707.                 'context'    => $context,
  3708.             )
  3709.         );
  3710.     }
  3711.     /**
  3712.      * Company cash-flow: real monthly cash inflow / outflow / net + running balance over the
  3713.      * last N months, derived from posted GL movements on the Cash &amp; Cash Equivalents head
  3714.      * subtree (marker _CACEP_ + path_tree descendants) â€” the same definition the financial
  3715.      * statements use. Base-currency amounts (amount x currency_multiply_rate). Fail-safe.
  3716.      */
  3717.     private function buildCompanyCashFlow($em$monthsBack 12)
  3718.     {
  3719.         $conn $em->getConnection();
  3720.         $cashMarker = \ApplicationBundle\Constants\AccountsConstant::CASH_AND_CASH_EQUIVALENT_PARENT;
  3721.         $result = [
  3722.             'hasData' => false,
  3723.             'labels' => [], 'inflow' => [], 'outflow' => [], 'net' => [], 'balance' => [],
  3724.             'totalInflow' => 0'totalOutflow' => 0'totalNet' => 0,
  3725.             'openingBalance' => 0'closingBalance' => 0'rows' => [],
  3726.         ];
  3727.         // 1. Resolve cash &amp; bank head ids: heads marked _CACEP_ plus their path_tree descendants.
  3728.         $marked $conn->fetchAllAssociative(
  3729.             'SELECT accounts_head_id FROM acc_accounts_head WHERE marker_hash LIKE ?',
  3730.             ['%' $cashMarker '%']
  3731.         );
  3732.         $ids = [];
  3733.         $likeParts = [];
  3734.         $params = [];
  3735.         foreach ($marked as $m) {
  3736.             $hid = (int) $m['accounts_head_id'];
  3737.             $ids[$hid] = $hid;
  3738.             $likeParts[] = 'path_tree LIKE ?';
  3739.             $params[] = '%/' $hid '/%';
  3740.         }
  3741.         if (!empty($likeParts)) {
  3742.             foreach ($conn->fetchAllAssociative('SELECT accounts_head_id FROM acc_accounts_head WHERE ' implode(' OR '$likeParts), $params) as $d) {
  3743.                 $ids[(int) $d['accounts_head_id']] = (int) $d['accounts_head_id'];
  3744.             }
  3745.         }
  3746.         $cashHeadIds array_values($ids);
  3747.         if (empty($cashHeadIds)) {
  3748.             return $result// hasData=false â†’ the page shows a friendly "no cash heads marked" notice
  3749.         }
  3750.         $inClause  implode(','array_map('intval'$cashHeadIds));
  3751.         $baseExpr  "td.amount * COALESCE(NULLIF(td.currency_multiply_rate, ''), 1)";
  3752.         $drCond    "(LOWER(td.position) LIKE 'dr%' OR LOWER(td.position) = 'debit')";
  3753.         $start = new \DateTime('first day of this month 00:00:00');
  3754.         $start->modify('-' . ($monthsBack 1) . ' months');
  3755.         $startStr $start->format('Y-m-d 00:00:00');
  3756.         // Opening cash balance (Dr - Cr) before the window.
  3757.         $openRow $conn->fetchAssociative(
  3758.             "SELECT SUM(CASE WHEN $drCond THEN $baseExpr ELSE -($baseExpr) END) bal
  3759.              FROM acc_transaction_details td
  3760.              JOIN acc_transactions t ON t.transaction_id = td.transaction_id
  3761.              WHERE td.accounts_head_id IN ($inClause) AND td.ledger_hit = 1 AND t.transaction_date < ?",
  3762.             [$startStr]
  3763.         );
  3764.         $opening = (float) ($openRow['bal'] ?? 0);
  3765.         // Monthly movements inside the window.
  3766.         $rows $conn->fetchAllAssociative(
  3767.             "SELECT DATE_FORMAT(t.transaction_date, '%Y-%m') ym,
  3768.                     SUM(CASE WHEN $drCond THEN $baseExpr ELSE 0 END) inflow,
  3769.                     SUM(CASE WHEN NOT $drCond THEN $baseExpr ELSE 0 END) outflow
  3770.              FROM acc_transaction_details td
  3771.              JOIN acc_transactions t ON t.transaction_id = td.transaction_id
  3772.              WHERE td.accounts_head_id IN ($inClause) AND td.ledger_hit = 1 AND t.transaction_date >= ?
  3773.              GROUP BY ym",
  3774.             [$startStr]
  3775.         );
  3776.         $byMonth = [];
  3777.         foreach ($rows as $r) {
  3778.             $byMonth[$r['ym']] = ['in' => (float) $r['inflow'], 'out' => (float) $r['outflow']];
  3779.         }
  3780.         $running $opening;
  3781.         $cursor = clone $start;
  3782.         for ($i 0$i $monthsBack$i++) {
  3783.             $ym $cursor->format('Y-m');
  3784.             $in  = isset($byMonth[$ym]) ? $byMonth[$ym]['in']  : 0.0;
  3785.             $out = isset($byMonth[$ym]) ? $byMonth[$ym]['out'] : 0.0;
  3786.             $net $in $out;
  3787.             $running += $net;
  3788.             $result['labels'][]  = $cursor->format('M Y');
  3789.             $result['inflow'][]  = round($in2);
  3790.             $result['outflow'][] = round($out2);
  3791.             $result['net'][]     = round($net2);
  3792.             $result['balance'][] = round($running2);
  3793.             $result['rows'][]    = ['label' => $cursor->format('M Y'), 'inflow' => round($in2), 'outflow' => round($out2), 'net' => round($net2), 'balance' => round($running2)];
  3794.             $result['totalInflow']  += $in;
  3795.             $result['totalOutflow'] += $out;
  3796.             $cursor->modify('+1 month');
  3797.         }
  3798.         $result['hasData']        = true;
  3799.         $result['openingBalance'] = round($opening2);
  3800.         $result['closingBalance'] = round($running2);
  3801.         $result['totalNet']       = round($result['totalInflow'] - $result['totalOutflow'], 2);
  3802.         $result['totalInflow']    = round($result['totalInflow'], 2);
  3803.         $result['totalOutflow']   = round($result['totalOutflow'], 2);
  3804.         return $result;
  3805.     }
  3806.     public function PerformanceReviewDashboardAction()
  3807.     {
  3808.         return $this->render(
  3809.             '@Application/pages/dashboard/performance_review_dashboard.html.twig',
  3810.             array(
  3811.                 'page_title' => 'Performance Review Dashboard'
  3812.             )
  3813.         );
  3814.     }
  3815.     public function RecruitmentDashboardAction(Request $request)
  3816.     {
  3817.         $em $this->getDoctrine()->getManager();
  3818.         $em_goc $this->getDoctrine()->getManager('company_group');
  3819.         $companyId $this->getLoggedUserCompanyId($request);
  3820.         $company_data Company::getCompanyData($em$companyId);
  3821.         // 1. Total Job Posts
  3822.         $totalJobPosts $em->getRepository('ApplicationBundle\\Entity\\JobRecruitment')
  3823.             ->createQueryBuilder('j')
  3824.             ->select('COUNT(j.jobRecruitmentId)')
  3825.             ->where('j.approved = 1')
  3826.             ->getQuery()
  3827.             ->getSingleScalarResult();
  3828.         // 2. Active Job Posts
  3829.         $activeJobPosts $em->getRepository('ApplicationBundle\\Entity\\JobRecruitment')
  3830.             ->createQueryBuilder('j')
  3831.             ->select('COUNT(j.jobRecruitmentId)')
  3832.             ->where('j.approved = 1')
  3833.             ->andWhere('j.jobOpeningStatus = 2'// Assuming 2 is Active
  3834.             ->getQuery()
  3835.             ->getSingleScalarResult();
  3836.         // 3. Total Applicants
  3837.         $totalApplicants $em_goc->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantApplicationList")
  3838.             ->createQueryBuilder('a')
  3839.             ->select('COUNT(a.id)')
  3840.             ->where('a.CompanyId = :companyId')
  3841.             ->andWhere('a.appId = :appId')
  3842.             ->setParameter('companyId'$companyId)
  3843.             ->setParameter('appId'$company_data->getAppId())
  3844.             ->getQuery()
  3845.             ->getSingleScalarResult();
  3846.         // 4. Simple recent activity for dashboard
  3847.         $recentJobs $em->getRepository('ApplicationBundle\\Entity\\JobRecruitment')
  3848.             ->findBy(['approved' => 1], ['createdAt' => 'DESC'], 5);
  3849.         // 5. Jobs with applicant counts
  3850.         $jobsWithApplicantCount $em->getRepository('ApplicationBundle\\Entity\\JobRecruitment')
  3851.             ->createQueryBuilder('j')
  3852.             ->select('j.jobRecruitmentId''j.title''j.applicationClosingDate''j.jobOpeningStatus')
  3853.             ->where('j.approved = 1')
  3854.             ->orderBy('j.createdAt''DESC')
  3855.             ->setMaxResults(8)
  3856.             ->getQuery()
  3857.             ->getResult();
  3858.         foreach ($jobsWithApplicantCount as &$job) {
  3859.             $count $em_goc->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantApplicationList")
  3860.                 ->createQueryBuilder('a')
  3861.                 ->select('COUNT(a.id)')
  3862.                 ->where('a.jobPostId = :jobId')
  3863.                 ->setParameter('jobId'$job['jobRecruitmentId'])
  3864.                 ->getQuery()
  3865.                 ->getSingleScalarResult();
  3866.             $job['applicantCount'] = $count;
  3867.         }
  3868.         return $this->render(
  3869.             '@Application/pages/dashboard/recruitment_dashboard.html.twig',
  3870.             array(
  3871.                 'page_title' => 'Recruitment Dashboard',
  3872.                 'totalJobPosts' => $totalJobPosts,
  3873.                 'activeJobPosts' => $activeJobPosts,
  3874.                 'totalApplicants' => $totalApplicants,
  3875.                 'recentJobs' => $recentJobs,
  3876.                 'jobsWithApplicantCount' => $jobsWithApplicantCount,
  3877.                 'jobOpeningStatusArr' => HumanResourceConstant::$jobOpeningStatus
  3878.             )
  3879.         );
  3880.     }
  3881.     public function TalentManagementDashboardAction()
  3882.     {
  3883.         return $this->render(
  3884.             '@Application/pages/dashboard/talent_management_dashboard.html.twig',
  3885.             array(
  3886.                 'page_title' => 'Talent Management Dashboard'
  3887.             )
  3888.         );
  3889.     }
  3890.     public function CreateCompanyAction(Request $request)
  3891.     {
  3892.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  3893.         $appId $request->get('app_id'0);
  3894.         $post $request;
  3895.         $session $request->getSession();
  3896.         if ($request->isMethod('POST')) {
  3897.             if ($systemType == '_CENTRAL_') {
  3898.                 $em_goc $this->getDoctrine()->getManager('company_group');
  3899.                 $em_goc->getConnection()->connect();
  3900.                 $connected $em_goc->getConnection()->isConnected();
  3901.                 $gocDataList = [];
  3902.                 if ($connected) {
  3903.                     $goc null;
  3904.                     $serverList MiscActions::getServerListById(                     $this->container->getParameter('database_user'),                     $this->container->getParameter('database_password'),                     $this->container->hasParameter('server_access_list') ?$this->container->getParameter('server_access_list') :[]                 );
  3905.                     $companyGroupHash $post->get('company_short_code''');
  3906.                     $defaultUsageDate = new \DateTime();
  3907.                     $defaultUsageDate->modify('+1 year');
  3908.                     $usageValidUpto = new \DateTime($post->get('usage_valid_upto_dt_str'$defaultUsageDate->format('Y-m-d')));
  3909.                     $companyGroupServerId $post->get('server_id'1);
  3910.                     $companyGroupServerAddress $serverList[$companyGroupServerId]['absoluteUrl'];
  3911.                     $companyGroupServerPort $serverList[$companyGroupServerId]['port'];
  3912.                     $companyGroupServerHash $serverList[$companyGroupServerId]['serverMarker'];
  3913.                     //                $dbUser=
  3914.                     if ($appId != 0)
  3915.                         $goc $this->getDoctrine()->getManager('company_group')
  3916.                             ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3917.                             ->findOneBy(array(
  3918.                                 'appId' => $appId
  3919.                             ));
  3920.                     if (!$goc)
  3921.                         $goc = new CompanyGroup();
  3922.                     if ($appId == 0) {
  3923.                         $biggestAppIdCg $this->getDoctrine()->getManager('company_group')
  3924.                             ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3925.                             ->findOneBy(array( //                            'appId' => $appId
  3926.                             ), array(
  3927.                                 'appId' => 'desc'
  3928.                             ));
  3929.                         if ($biggestAppIdCg)
  3930.                             $appId $biggestAppIdCg->getAppId();
  3931.                     }
  3932.                     $goc->setName($post->get('company_name'));
  3933.                     $goc->setCompanyGroupHash($companyGroupHash);
  3934.                     $goc->setAppId($appId);
  3935.                     $goc->setActive(1);
  3936.                     $goc->setAddress($post->get('address'));
  3937.                     $goc->setShippingAddress($post->get('s_address'));
  3938.                     $goc->setBillingAddress($post->get('b_address'));
  3939.                     $goc->setMotto($post->get('motto'));
  3940.                     $goc->setInitiateFlag($post->get('initiate_flag'3));
  3941.                     $goc->setInvoiceFooter($post->get('i_footer'));
  3942.                     $goc->setGeneralFooter($post->get('g_footer'));
  3943.                     $goc->setCompanyReg($post->get('company_reg'''));
  3944.                     $goc->setCompanyTin($post->get('company_tin'''));
  3945.                     $goc->setCompanyBin($post->get('company_bin'''));
  3946.                     $goc->setCompanyTl($post->get('company_tl'''));
  3947.                     $goc->setCompanyType($post->get('company_type'''));
  3948.                     $goc->setCurrentSubscriptionPackageId($post->get('package'1));
  3949.                     $goc->setUsageValidUptoDate($usageValidUpto);
  3950.                     $goc->setUsageValidUptoDateTs($usageValidUpto->format('U'));
  3951.                     //                $goc->setCu($post->get('package', ''));
  3952.                     $goc->setAdminUserAllowed($post->get('number_of_admin_user'1));
  3953.                     $goc->setUserAllowed($post->get('number_of_user'2));
  3954.                     $goc->setSubscriptionMonth($post->get('subscription_month'1));
  3955.                     $goc->setCompanyDescription($post->get('company_description'''));
  3956.                     $goc->setDbUser($post->get('db_user'));
  3957.                     $goc->setDbPass($post->get('db_pass'));
  3958.                     $goc->setDbHost($post->get('db_host'));
  3959.                     $goc->setOwnerId($session->get(UserConstants::USER_ID));
  3960.                     $goc->setCompanyGroupServerId($companyGroupServerId);
  3961.                     $goc->setCompanyGroupServerAddress($companyGroupServerAddress);
  3962.                     $goc->setCompanyGroupServerPort($companyGroupServerPort);
  3963.                     $goc->setCompanyGroupServerHash($companyGroupServerHash);
  3964.                     foreach ($request->files as $uploadedFile) {
  3965.                         if ($uploadedFile != null) {
  3966.                             $fileName 'company_image' $appId '.' $uploadedFile->guessExtension();
  3967.                             $path $fileName;
  3968.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/';
  3969.                             if ($goc->getImage() != null && $goc->getImage() != '' && file_exists($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage())) {
  3970.                                 unlink($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage());
  3971.                             }
  3972.                             if (!file_exists($upl_dir)) {
  3973.                                 mkdir($upl_dir0777true);
  3974.                             }
  3975.                             $file $uploadedFile->move($upl_dir$path);
  3976.                             if ($path != "")
  3977.                                 $goc->setImage('/uploads/CompanyImage/' $path);
  3978.                         }
  3979.                     }
  3980.                     $em_goc->persist($goc);
  3981.                     $em_goc->flush();
  3982.                     $goc->setDbName('cg_' $appId '_' $companyGroupHash);
  3983.                     $goc->setDbUser($serverList[$companyGroupServerId]['dbUser']);
  3984.                     $goc->setDbPass($serverList[$companyGroupServerId]['dbPass']);
  3985.                     $goc->setDbHost('localhost');
  3986.                     $em_goc->flush();
  3987.                     $centralUser $this->getDoctrine()->getManager('company_group')
  3988.                         ->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantDetails")
  3989.                         ->findOneBy(array(
  3990.                             'applicantId' => $session->get(UserConstants::USER_ID0)
  3991.                         ));
  3992.                     if ($centralUser) {
  3993.                         $userAppIds json_decode($centralUser->getUserAppIds(), true);
  3994.                         $userTypesByAppIds json_decode($centralUser->getUserTypesByAppIds(), true);
  3995.                         if ($userAppIds == null$userAppIds = [];
  3996.                         if ($userTypesByAppIds == null$userTypesByAppIds = [];
  3997.                         $userAppIds array_merge($userAppIdsarray_diff([$appId], $userAppIds));
  3998.                         if (!isset($userTypesByAppIds[$appId])) {
  3999.                             $userTypesByAppIds[$appId] = [];
  4000.                         }
  4001.                         $userTypesByAppIds[$appId] = array_merge($userTypesByAppIds[$appId], array_diff([UserConstants::USER_TYPE_SYSTEM], $userTypesByAppIds[$appId]));
  4002.                         $centralUser->setUserAppIds(json_encode($userAppIds));
  4003.                         $centralUser->setUserTypesByAppIds(json_encode($userTypesByAppIds));
  4004.                         $em_goc->flush();
  4005.                     }
  4006.                     $accessList $session->get('userAccessList', []);
  4007.                     $d = array(
  4008.                         'userType' => UserConstants::USER_TYPE_SYSTEM,
  4009.                         'globalId' => $session->get(UserConstants::USER_ID0),
  4010.                         'serverId' => $companyGroupServerId,
  4011.                         'serverUrl' => $companyGroupServerAddress,
  4012.                         'serverPort' => $companyGroupServerPort,
  4013.                         'systemType' => '_ERP_',
  4014.                         'companyId' => 1,
  4015.                         'appId' => $appId,
  4016.                         'companyLogoUrl' => $goc->getImage(),
  4017.                         'companyName' => $goc->getName(),
  4018.                         'authenticationStr' => $this->get('url_encryptor')->encrypt(
  4019.                             json_encode(
  4020.                                 array(
  4021.                                     'globalId' => $session->get(UserConstants::USER_ID0),
  4022.                                     'appId' => $appId,
  4023.                                     'authenticate' => 1,
  4024.                                     'userType' => UserConstants::USER_TYPE_SYSTEM
  4025.                                 )
  4026.                             )
  4027.                         ),
  4028.                         'userCompanyList' => []
  4029.                     );
  4030.                     $accessList[] = $d;
  4031. //                    MiscActions::UpdateCompanyListInSession($em_goc, $centralUser->getApplicantId(), 1, 1, 1, $d);
  4032.                     //temporary solution
  4033.                     MiscActions::UpdateCompanyListInSession($em_goc$session->get(UserConstants::USER_ID), 111$d);
  4034.                     $session->set('userAccessList'$accessList);
  4035.                 }
  4036.                 return new JsonResponse(array(
  4037.                     'success' => true,
  4038.                     "message" => "Company Created Successfully",
  4039.                     'user_access_data' => $d,
  4040.                     'app_id' => $appId
  4041.                 ));
  4042.             }
  4043.         }
  4044.         return $this->render('@HoneybeeWeb/pages/create_company.html.twig', array(
  4045.             'page_title' => 'Company',
  4046.             'serverList' => GeneralConstant::$serverListById
  4047.         ));
  4048.     }
  4049.     public function checkBinTinAction(Request $request)
  4050.     {
  4051.         $em_goc $this->getDoctrine()->getManager('company_group');
  4052.         $type  $request->request->get('type');
  4053.         $value trim($request->request->get('value'));
  4054.         $repo $em_goc->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup");
  4055.         if ($type === 'tin') {
  4056.             $company $repo->findOneBy(array(
  4057.                 'company_tin' => $value
  4058.             ));
  4059.         } elseif ($type === 'bin') {
  4060.             $company $repo->findOneBy(array(
  4061.                 'company_bin' => $value
  4062.             ));
  4063.         } elseif ($type === 'reg') {
  4064.             $company $repo->findOneBy(array(
  4065.                 'company_reg' => $value
  4066.             ));
  4067.         } else {
  4068.             return new JsonResponse(['exists' => false]);
  4069.         }
  4070.         return new JsonResponse([
  4071.             'exists' => $company true false
  4072.         ]);
  4073.     }
  4074.     public function createTicketAction(Request $request)
  4075.     {
  4076.         $em_goc $this->getDoctrine()->getManager('company_group');
  4077.         if ($request->isMethod('POST')) {
  4078.             $ticket = new EntityTicket();
  4079.             $ticket->setTitle($request->request->get('title'0));
  4080.             $ticket->setEmail($request->request->get('email'));
  4081.             $ticket->setTicketBody($request->request->get('ticketBody'));
  4082.             $em_goc->persist($ticket);
  4083.             $em_goc->flush();
  4084.         }
  4085.         return new JsonResponse(array(
  4086.             "success" => 'true',
  4087.             "message" => "Ticket Created Successfully",
  4088.         ));
  4089.     }
  4090.     public function GetSessionDataForAppAction(
  4091.         Request $request,
  4092.                 $remoteVerify 0,
  4093.                 $version 'latest',
  4094.                 $identifier '_default_',
  4095.                 $refRoute '',
  4096.                 $apiKey '_ignore_'
  4097.     )
  4098.     {
  4099.         $message "";
  4100.         $gocList = [];
  4101.         $session $request->getSession();
  4102.         if ($request->request->has('token')) {
  4103.             $em_goc $this->getDoctrine()->getManager('company_group');
  4104.             $to_set_session_data MiscActions::GetSessionDataFromToken($em_goc$request->request->get('token'))['sessionData'];
  4105.             if ($to_set_session_data != null) {
  4106.                 foreach ($to_set_session_data as $k => $d) {
  4107.                     //check if mobile
  4108.                     $session->set($k$d);
  4109.                 }
  4110.             }
  4111.         }
  4112.         if ($request->request->has('sessionData')) {
  4113.             $to_set_session_data $request->request->get('sessionData');
  4114.             foreach ($to_set_session_data as $k => $d) {
  4115.                 //check if mobile
  4116.                 $session->set($k$d);
  4117.             }
  4118.         }
  4119.         if ($version !== 'latest') {
  4120.             $session_data = array(
  4121.                 'oAuthToken' => $session->get('oAuthToken'),
  4122.                 'locale' => $session->get('locale'),
  4123.                 'firebaseToken' => $session->get('firebaseToken'),
  4124.                 'token' => $session->get('token'),
  4125.                 UserConstants::USER_EMPLOYEE_ID => $session->get(UserConstants::USER_EMPLOYEE_ID),
  4126.                 UserConstants::USER_ID => $session->get(UserConstants::USER_ID),
  4127.                 UserConstants::LAST_SETTINGS_UPDATED_TS => $session->get(UserConstants::LAST_SETTINGS_UPDATED_TS),
  4128.                 UserConstants::USER_LOGIN_ID => $session->get(UserConstants::USER_LOGIN_ID),
  4129.                 UserConstants::USER_EMAIL => $session->get(UserConstants::USER_EMAIL),
  4130.                 UserConstants::USER_TYPE => $session->get(UserConstants::USER_TYPE),
  4131.                 UserConstants::USER_IMAGE => $session->get(UserConstants::USER_IMAGE),
  4132.                 UserConstants::USER_DEFAULT_ROUTE => $session->get(UserConstants::USER_DEFAULT_ROUTE),
  4133.                 UserConstants::USER_NAME => $session->get(UserConstants::USER_NAME),
  4134.                 UserConstants::USER_COMPANY_ID => $session->get(UserConstants::USER_COMPANY_ID),
  4135.                 UserConstants::USER_COMPANY_ID_LIST => $session->get(UserConstants::USER_COMPANY_ID_LIST),
  4136.                 UserConstants::USER_COMPANY_NAME_LIST => $session->get(UserConstants::USER_COMPANY_NAME_LIST),
  4137.                 UserConstants::USER_COMPANY_IMAGE_LIST => $session->get(UserConstants::USER_COMPANY_IMAGE_LIST),
  4138.                 UserConstants::USER_APP_ID => $session->get(UserConstants::USER_APP_ID),
  4139.                 UserConstants::USER_POSITION_LIST => $session->get(UserConstants::USER_POSITION_LIST),
  4140.                 UserConstants::USER_CURRENT_POSITION => $session->get(UserConstants::USER_CURRENT_POSITION),
  4141.                 UserConstants::ALL_MODULE_ACCESS_FLAG => $session->get(UserConstants::ALL_MODULE_ACCESS_FLAG),
  4142.                 UserConstants::USER_GOC_ID => $session->get(UserConstants::USER_GOC_ID),
  4143.                 UserConstants::USER_NOTIFICATION_ENABLED => GeneralConstant::NOTIFICATION_ENABLED == ? ($this->getParameter('notification_enabled') == 0) : 0,
  4144.                 UserConstants::USER_NOTIFICATION_SERVER => $this->getParameter('notification_server'),
  4145.                 UserConstants::PRODUCT_NAME_DISPLAY_TYPE => $session->get(UserConstants::PRODUCT_NAME_DISPLAY_TYPE),
  4146.                 UserConstants::APPLICATION_SECRET => $session->get(UserConstants::APPLICATION_SECRET),
  4147.                 //new addition
  4148.                 'appIdList' => $session->get('appIdList'),
  4149.                 'branchIdList' => $session->get('branchIdList'null),
  4150.                 'branchId' => $session->get('branchId'null),
  4151.                 'companyIdListByAppId' => $session->get('companyIdListByAppId'),
  4152.                 'companyNameListByAppId' => $session->get('companyNameListByAppId'),
  4153.                 'companyImageListByAppId' => $session->get('companyImageListByAppId'),
  4154.                 'userAccessList' => $session->get('userAccessList'),
  4155.                 'csToken' => $session->get('csToken'),
  4156.             );
  4157.         } else {
  4158.             $session_data = array(
  4159.                 'oAuthToken' => $session->get('oAuthToken'),
  4160.                 'locale' => $session->get('locale'),
  4161.                 'firebaseToken' => $session->get('firebaseToken'),
  4162.                 'token' => $session->get('token'),
  4163.                 UserConstants::USER_EMPLOYEE_ID => $session->get(UserConstants::USER_EMPLOYEE_ID),
  4164.                 UserConstants::USER_ID => $session->get(UserConstants::USER_ID),
  4165.                 UserConstants::LAST_SETTINGS_UPDATED_TS => $session->get(UserConstants::LAST_SETTINGS_UPDATED_TS),
  4166.                 UserConstants::USER_LOGIN_ID => $session->get(UserConstants::USER_LOGIN_ID),
  4167.                 UserConstants::USER_EMAIL => $session->get(UserConstants::USER_EMAIL),
  4168.                 UserConstants::USER_TYPE => $session->get(UserConstants::USER_TYPE),
  4169.                 UserConstants::USER_IMAGE => $session->get(UserConstants::USER_IMAGE),
  4170.                 UserConstants::USER_DEFAULT_ROUTE => $session->get(UserConstants::USER_DEFAULT_ROUTE),
  4171.                 UserConstants::USER_NAME => $session->get(UserConstants::USER_NAME),
  4172.                 UserConstants::USER_COMPANY_ID => $session->get(UserConstants::USER_COMPANY_ID),
  4173.                 UserConstants::USER_COMPANY_ID_LIST => $session->get(UserConstants::USER_COMPANY_ID_LIST),
  4174.                 UserConstants::USER_COMPANY_NAME_LIST => $session->get(UserConstants::USER_COMPANY_NAME_LIST),
  4175.                 UserConstants::USER_COMPANY_IMAGE_LIST => $session->get(UserConstants::USER_COMPANY_IMAGE_LIST),
  4176.                 UserConstants::USER_APP_ID => $session->get(UserConstants::USER_APP_ID),
  4177.                 UserConstants::USER_POSITION_LIST => $session->get(UserConstants::USER_POSITION_LIST),
  4178.                 UserConstants::USER_CURRENT_POSITION => $session->get(UserConstants::USER_CURRENT_POSITION),
  4179.                 UserConstants::ALL_MODULE_ACCESS_FLAG => $session->get(UserConstants::ALL_MODULE_ACCESS_FLAG),
  4180.                 UserConstants::USER_GOC_ID => $session->get(UserConstants::USER_GOC_ID),
  4181.                 UserConstants::USER_NOTIFICATION_ENABLED => GeneralConstant::NOTIFICATION_ENABLED == ? ($this->getParameter('notification_enabled') == 0) : 0,
  4182.                 UserConstants::USER_NOTIFICATION_SERVER => $this->getParameter('notification_server'),
  4183.                 UserConstants::PRODUCT_NAME_DISPLAY_TYPE => $session->get(UserConstants::PRODUCT_NAME_DISPLAY_TYPE),
  4184.                 UserConstants::APPLICATION_SECRET => $session->get(UserConstants::APPLICATION_SECRET),
  4185.                 //new addition
  4186.                 'appIdList' => $session->get('appIdList'),
  4187.                 'branchIdList' => $session->get('branchIdList'null),
  4188.                 'branchId' => $session->get('branchId'null),
  4189.                 'companyIdListByAppId' => $session->get('companyIdListByAppId'),
  4190.                 'companyNameListByAppId' => $session->get('companyNameListByAppId'),
  4191.                 'companyImageListByAppId' => $session->get('companyImageListByAppId'),
  4192.                 'userAccessList' => $session->get('userAccessList'),
  4193.                 'csToken' => $session->get('csToken'),
  4194.             );
  4195.         }
  4196.         $response = new JsonResponse(array(
  4197.             "success" => empty($session->get(UserConstants::USER_ID)) ? false true,
  4198.             //            'session'=>$request->getSession(),
  4199.             'session_data' => $session_data,
  4200.             //            'session2'=>$_SESSION,
  4201.         ));
  4202.         $response->headers->set('Access-Control-Allow-Origin''*, null');
  4203.         $response->headers->set('Access-Control-Allow-Methods''POST');
  4204.         //        $response->setCallback('FUNCTION_CALLBACK_NAME');
  4205.         return $response;
  4206.     }
  4207.     public function EmployeeAddUsingQrCodeCentralAction(Request $request)
  4208.     {
  4209.         $session $request->getSession();
  4210.         if ($request->isMethod('post')) {
  4211.             $em_goc $this->getDoctrine()->getManager('company_group');
  4212.             $entityApplicant $em_goc->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantDetails")
  4213.                 ->findOneBy(
  4214.                     array(
  4215.                         'applicantId' => $request->request->get('userId'),
  4216.                     )
  4217.                 );
  4218.             $app $em_goc->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  4219.                 ->findOneBy(
  4220.                     array(
  4221.                         'appId' => $request->request->get('appId'),
  4222.                     )
  4223.                 );
  4224.             $userType $request->request->get('userType');
  4225.             $currAccessData json_decode($entityApplicant->getUserTypesByAppIds(), true);
  4226.             if ($currAccessData == null$currAccessData = [];
  4227.             if (!isset($currAccessData[$request->request->get('appId')]))
  4228.                 $currAccessData[$request->request->get('appId')] = [];
  4229.             $currAccessData[$request->request->get('appId')] = array_merge($currAccessData[$request->request->get('appId')], array_diff([$request->request->get('userType'$userType)], $currAccessData[$request->request->get('appId')]));
  4230.             $entityApplicant->setUserTypesByAppIds(json_encode($currAccessData));
  4231.             $em_goc->flush();
  4232.             $postData = [];
  4233.             $postData['globalId'] = $entityApplicant->getApplicantId();
  4234.             $postData['username'] = $entityApplicant->getUsername();
  4235.             $postData['email'] = $entityApplicant->getEmail();
  4236.             $postData['firstname'] = $entityApplicant->getFirstname();
  4237.             $postData['lastname'] = $entityApplicant->getLastname();
  4238.             $postData['appId'] = $request->request->get('appId');
  4239.             $postData['companyId'] = $request->request->get('companyId');
  4240.             $postData['userType'] = $userType;
  4241.             $urlToCall $app->getCompanyGroupServerAddress() . '/add_employee_by_qr_erp';
  4242.             $userFiles $postData;
  4243.             $curl curl_init();
  4244.             curl_setopt_array($curl, array(
  4245.                 CURLOPT_RETURNTRANSFER => 1,
  4246.                 CURLOPT_POST => 1,
  4247.                 CURLOPT_URL => $urlToCall,
  4248.                 CURLOPT_CONNECTTIMEOUT => 10,
  4249.                 CURLOPT_SSL_VERIFYPEER => false,
  4250.                 CURLOPT_SSL_VERIFYHOST => false,
  4251.                 CURLOPT_HTTPHEADER => array( //              "Accept: multipart/form-data",
  4252.                 ),
  4253.                 //                            ),
  4254.                 CURLOPT_POSTFIELDS => $userFiles
  4255.             ));
  4256.             $retData curl_exec($curl);
  4257.             $errData curl_error($curl);
  4258.             curl_close($curl);
  4259.             if ($errData) {
  4260. //                $returnData['message']='';
  4261.             } else {
  4262.                 $retDataObj json_decode($retDatatrue);
  4263.                 if ($retDataObj['status'] == 'success') {
  4264.                     $newAccess = [
  4265.                         'userType' => 1,
  4266.                         'userTypeName' => 'Admin',
  4267.                         'globalId' => $entityApplicant->getApplicantId(),
  4268.                         'serverId' => $app->getCompanyGroupServerId(),
  4269.                         'serverUrl' => $app->getCompanyGroupServerAddress(),
  4270.                         'serverPort' => $app->getCompanyGroupServerPort(),
  4271.                         'systemType' => '_ERP_',
  4272.                         'companyId' => 1,
  4273.                         'appId' => $app->getAppId(),
  4274.                         'companyLogoUrl' => '/uploads/CompanyImage/company_image' $request->request->get('appId') . '.png',
  4275.                         'companyName' => $app->getName(),
  4276.                         'authenticationStr' => $this->get('url_encryptor')->encrypt(json_encode(
  4277.                                 array(
  4278.                                     'globalId' => $entityApplicant->getApplicantId(),
  4279.                                     'appId' => $app->getAppId(),
  4280.                                     'authenticate' => 1,
  4281.                                     'userType' => $userType,
  4282.                                     'userTypeName' => UserConstants::$userTypeName[$userType]
  4283.                                 )
  4284.                             )
  4285.                         ),
  4286.                         'userCompanyList' => [],
  4287.                     ];
  4288. //            $token = $session->get('token');
  4289. //            $em_goc = $this->getDoctrine()->getManager('company_group');
  4290.                     $to_set_session_data MiscActions::GetSessionDataFromToken($em_goc$session->get(UserConstants::USER_TOKEN''))['sessionData'];
  4291.                     $currentUserAccessListInSession $to_set_session_data['userAccessList'];
  4292.                     $isAlreadyJoined false;
  4293.                     foreach ($currentUserAccessListInSession as $acc) {
  4294.                         if (isset($acc['appId']) && $acc['appId'] == $request->request->get('appId')) {
  4295.                             $isAlreadyJoined true;
  4296.                             break;
  4297.                         }
  4298.                     }
  4299. //                    if(isset($currentUserAccessListInSession[$request->request->get('appId')]))
  4300. //                        $isAlreadyJoined=true;
  4301.                     if ($isAlreadyJoined) {
  4302.                         return new JsonResponse([
  4303.                             'status' => 'false',
  4304.                             'message' => 'Already joined.',
  4305.                             'currentUserAccessListInSession'  => $currentUserAccessListInSession
  4306.                         ]);
  4307.                     }else{
  4308.                         $currentUserAccessListInSession[] = $newAccess;
  4309.                         $session->set('userAccessList'$currentUserAccessListInSession);
  4310.                         $to_set_session_data['userAccessList'] = $currentUserAccessListInSession;
  4311.                         $updatedToken MiscActions::CreateTokenFromSessionData($em_goc,
  4312.                             $to_set_session_data,
  4313.                             1,
  4314.                             1,
  4315.                             11
  4316.                         );
  4317.                         return new JsonResponse([
  4318.                             'status' => 'success',
  4319.                             'message' => 'User successfully added to company.',
  4320.                             'currentUserAccessListInSession'  => $currentUserAccessListInSession
  4321.                         ]);
  4322.                     }
  4323.                 }
  4324.             }
  4325. //            MiscActions::UpdateCompanyListInSession($em_goc, $entityApplicant->getApplicantId(), 1, 1, 1, $newAccess);
  4326.         } else {
  4327.             $company $request->get('company');
  4328.             return new JsonResponse(array(
  4329.                 'status' => 'error',
  4330.                 'message' => 'Something went wrong while onboarding.'
  4331.             ));
  4332.         }
  4333.         return new JsonResponse(array(
  4334.             'status' => 'error',
  4335.             'message' => 'Something went wrong while onboarding.'
  4336.         ));
  4337.     }
  4338.     public function EmployeeAddUsingQrCodeAction(Request $request)
  4339.     {
  4340.         $post $request;
  4341.         $em $this->getDoctrine()->getManager('company_group');
  4342.         $appid $request->query->get('appid'$request->request->get('appid'null));
  4343.         $session $request->getSession();
  4344.         $CurrentRoute $request->attributes->get('_route');
  4345.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  4346.         if ($request->isMethod('POST')) {
  4347.             $userId $request->request->get('userId'null);
  4348.             if ($userId === null) {
  4349.                 $companyId $request->request->get('company',1);
  4350.                 $email $request->request->get('email');
  4351.                 $qrImage $request->files->get('qr_image');
  4352.                 if (!$email) {
  4353.                     return new JsonResponse(['status' => 'error''message' => 'Invalid request'], 400);
  4354.                 }
  4355.                 if ($qrImage) {
  4356.                     $uploadsDir $this->getParameter('kernel.project_dir') . '/public/uploads/';
  4357.                     $fileName 'qr_' $companyId '_' time() . '.png';
  4358.                     $qrImage->move($uploadsDir$fileName);
  4359.                     $qrImagePath $uploadsDir $fileName;
  4360.                     $bodyTemplate '@Application/email/user/applicant_confirm.html.twig';
  4361.                     $bodyData = [
  4362.                         'name' => $email,
  4363.                         'companyData' => $companyId,
  4364.                         'companyName' => $request->request->get('company'),
  4365.                         'userType' => 2,
  4366.                         'appId' => $appid,
  4367.                         //                        'qr_code_url' => '/uploads/' . $fileName
  4368.                     ];
  4369.                     $userAccessList $session->get('userAccessList', []);
  4370.                     $companyName array_map(function ($company) {
  4371.                         return $company['companyName'];
  4372.                     }, $userAccessList);
  4373.                     $new_mail $this->get('mail_module');
  4374.                     $new_mail->sendMyMail([
  4375.                         'senderHash' => '_CUSTOM_',
  4376.                         'forwardToMailAddress' => $email,
  4377.                         'fromAddress' => 'accounts@ourhoneybee.eu',
  4378.                         'userName' => 'accounts@ourhoneybee.eu',
  4379.                         'password' => \ApplicationBundle\Helper\MailerConfig::buddybeePassword(),
  4380.                         'smtpServer' => \ApplicationBundle\Helper\MailerConfig::host(),
  4381.                         'smtpPort' => \ApplicationBundle\Helper\MailerConfig::port(),
  4382.                         'subject' => 'User Registration on HoneyBee Ecosystem under Entity ',
  4383.                         'toAddress' => $email,
  4384.                         'mailTemplate' => $bodyTemplate,
  4385.                         'templateData' => $bodyData,
  4386.                         'companyId' => $companyId,
  4387.                     ]);
  4388.                     return $this->render(
  4389.                         '@Application/pages/dashboard/index_central_landing.html.twig',
  4390.                         [
  4391.                             'page_title' => 'Central Landing',
  4392.                             'companyNames' => $companyName
  4393.                         ]
  4394.                     );
  4395.                 } else {
  4396.                     $userAccessList $session->get('userAccessList', []);
  4397.                     $companyName array_map(function ($company) {
  4398.                         return $company['companyName'];
  4399.                     }, $userAccessList);
  4400.                     return $this->render(
  4401.                         '@Application/pages/dashboard/index_central_landing.html.twig',
  4402.                         [
  4403.                             'page_title' => 'Central Landing',
  4404.                             'companyNames' => $companyName
  4405.                         ]
  4406.                     );
  4407.                 }
  4408.             } else {
  4409.                 if ($systemType == '_CENTRAL_') {
  4410.                     $userAccessList $session->get('userAccessList', []);
  4411.                     $companyName array_map(function ($company) {
  4412.                         return $company['companyName'];
  4413.                     }, $userAccessList);
  4414.                     $modifiedRequest $request->duplicate(
  4415.                         null,
  4416.                         array_merge($request->request->all(), ['appId' => $request->request->get('appid')])
  4417.                     );
  4418.                     $response $this->EmployeeAddUsingQrCodeCentralAction($modifiedRequest);
  4419. //                    if ($CurrentRoute == 'employee_add_by_qr_api')
  4420.                     {
  4421.                         return $response;
  4422.                     }
  4423. //                    return $this->render(
  4424. //                        'ApplicationBundle:pages/dashboard:index_central_landing.html.twig',
  4425. //                        [
  4426. //                            'page_title' => 'Central Landing',
  4427. //                            'companyNames' => $companyName
  4428. //                        ]
  4429. //                    );
  4430.                 }
  4431.             }
  4432.         } else {
  4433.             $company $request->get('company');
  4434.             $em_goc $this->getDoctrine()->getManager('company_group');
  4435.             $company $em_goc->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")->findOneBy(['appId' => $request->get('appid')]);
  4436.             return $this->render(
  4437.                 '@Application/pages/dashboard/employee_add_by_qr.html.twig',
  4438.                 [
  4439.                     'page_title' => 'Company Invitation',
  4440.                     'company' => $company
  4441.                 ]
  4442.             );
  4443.         }
  4444.     }
  4445.     public function EmployeeOnboardUsingQrAction(Request $request): JsonResponse
  4446.     {
  4447.         $email $request->get('email');
  4448.         $isAjax $request->isXmlHttpRequest();
  4449.         $currentRoute $request->attributes->get('_route');
  4450.         if (!$email) {
  4451.             if ($isAjax) {
  4452.                 return new JsonResponse(['status' => 'error''message' => 'Email is required.']);
  4453.             } else {
  4454.                 throw $this->createNotFoundException("Email is missing.");
  4455.             }
  4456.         }
  4457.         $em_goc $this->getDoctrine()->getManager('company_group');
  4458.         $user $em_goc->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantDetails")->findOneBy(['email' => $email]);
  4459.         if (!$user) {
  4460.             if ($isAjax) {
  4461.                 return new JsonResponse(['status' => 'error''message' => 'Applicant not found.']);
  4462.             } else {
  4463.                 throw $this->createNotFoundException("Applicant not found.");
  4464.             }
  4465.         }
  4466.         $payloadUrl $this->generateUrl('employee_onboard_by_qr_api', [
  4467.             'email' => $user->getEmail(),
  4468.             'applicantId' => $user->getApplicantId(),
  4469.             'employeeQr' => 1
  4470.         ], UrlGeneratorInterface::ABSOLUTE_URL);
  4471.         if ($currentRoute === 'employee_onboard') {
  4472.             return new JsonResponse([
  4473.                 'status' => 'success',
  4474.                 'data' => [
  4475.                     'applicantId' => $user->getApplicantId(),
  4476.                     'username' => $user->getUsername(),
  4477.                     'email' => $user->getEmail(),
  4478.                     'firstName' => $user->getFirstname(),
  4479.                     'lastName' => $user->getLastname(),
  4480.                     'link' => $payloadUrl
  4481.                 ]
  4482.             ]);
  4483.         }
  4484.         if ($isAjax) {
  4485.             return new JsonResponse([
  4486.                 'status' => 'success',
  4487.                 'data' => [
  4488.                     'id' => $user->getApplicantId(),
  4489.                     'email' => $user->getEmail(),
  4490.                     'name' => $user->getFirstname() . ' ' $user->getLastname(),
  4491.                     'dob' => $user->getDob() ? $user->getDob()->format('Y-m-d') : null,
  4492.                 ]
  4493.             ]);
  4494.         }
  4495.         $companies $request->getSession()->get('userAccessList', []);
  4496.         return $this->render('@Application/pages/dashboard/qr_onboard_result.html.twig', [
  4497.             'page_title' => 'Onboarding',
  4498.             'applicant' => $user,
  4499.             'companies' => $companies
  4500.         ]);
  4501.     }
  4502.     public function OnboardUserToCompanyAction(Request $request)
  4503.     {
  4504.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  4505.         $currentRoute $request->attributes->get('_route');
  4506.         if ($systemType !== '_CENTRAL_') {
  4507.             throw new \Exception("This action must be called from CENTRAL system.");
  4508.         }
  4509.         $email $request->request->get('email');
  4510.         $applicantId $request->request->get('applicant_id');
  4511.         $appId $request->request->get('company_id');
  4512.         $userType $request->request->get('user_type');
  4513.         if (!$email || !$appId || !$userType) {
  4514.             $this->addFlash('error''Missing required fields.');
  4515.             return new JsonResponse(['status' => 'error''message' => 'Missing required fields.']);
  4516.         }
  4517.         $em $this->getDoctrine()->getManager('company_group');
  4518.         $applicant $em->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantDetails")->findOneBy(['email' => $email]);
  4519.         if (!$applicant) {
  4520.             $this->addFlash('error''Applicant not found.');
  4521.             return $this->redirectToRoute('central_landing');
  4522.         }
  4523.         $userAppIds json_decode($applicant->getUserAppIds(), true);
  4524.         if (!is_array($userAppIds)) {
  4525.             $userAppIds = [];
  4526.         }
  4527.         if (!in_array($appId$userAppIds)) {
  4528.             $userAppIds[] = $appId;
  4529.             $applicant->setUserAppIds(json_encode($userAppIds));
  4530.         }
  4531.         $userTypesByAppIds json_decode($applicant->getUserTypesByAppIds(), true) ?: [];
  4532.         $userTypesByAppIds[$appId] = array((int)$userType);
  4533.         $applicant->setUserTypesByAppIds(json_encode($userTypesByAppIds));
  4534.         $em->persist($applicant);
  4535.         $em->flush();
  4536.         $companyRepo $this->getDoctrine()->getManager('company_group')->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup");
  4537.         $targetCompany $companyRepo->findOneBy(['appId' => $appId]);
  4538.         if (!$targetCompany) {
  4539.             $this->addFlash('error''Target company not found.');
  4540.             return $this->redirectToRoute('central_landing');
  4541.         }
  4542.         $serverList MiscActions::getServerListById(                     $this->container->getParameter('database_user'),                     $this->container->getParameter('database_password'),                     $this->container->hasParameter('server_access_list') ?$this->container->getParameter('server_access_list') :[]                 );
  4543.         $serverId $targetCompany->getCompanyGroupServerId();
  4544.         $appId $targetCompany->getAppId();
  4545.         if (!isset($serverList[$serverId])) {
  4546.             $this->addFlash('error''Server configuration not found.');
  4547.             return $this->redirectToRoute('central_landing');
  4548.         }
  4549.         // Find correct companyId from session userAccessList using appId
  4550.         $session $request->getSession();
  4551.         $userAccessList $session->get('userAccessList', []);
  4552.         $resolvedCompanyId null;
  4553.         foreach ($userAccessList as $access) {
  4554.             if (isset($access['appId']) && $access['appId'] == $appId) {
  4555.                 $resolvedCompanyId $access['companyId'];
  4556.                 break;
  4557.             }
  4558.         }
  4559.         if (!$resolvedCompanyId) {
  4560.             $this->addFlash('error''Could not resolve companyId from session for the given appId.');
  4561.             return $this->redirectToRoute('central_landing');
  4562.         }
  4563.         $imagePath $this->container->getParameter('kernel.root_dir') . '/../web/' $applicant->getImage();
  4564.         $imageFile null;
  4565.         if ($applicant->getImage() && file_exists($imagePath)) {
  4566.             $mime mime_content_type($imagePath);
  4567.             $name pathinfo($imagePathPATHINFO_BASENAME);
  4568.             $imageFile = new \CURLFile($imagePath$mime$name);
  4569.         }
  4570.         // Prepare userData
  4571.         $userData = [];
  4572.         $getters array_filter(get_class_methods($applicant), function ($method) {
  4573.             return strpos($method'get') === 0;
  4574.         });
  4575.         foreach ($getters as $getter) {
  4576.             if (in_array($getter, ['getCreatedAt''getUpdatedAt''getImage'])) continue;
  4577.             $value $applicant->$getter();
  4578.             $userData[$getter] = $value instanceof \DateTime $value->format('Y-m-d') : $value;
  4579.         }
  4580.         $userData['getUserAppIds'] = json_encode($userAppIds);
  4581.         $userData['getUserTypesByAppIds'] = json_encode($userTypesByAppIds);
  4582.         $postFields = [
  4583.             'userData' => json_encode([$userData]),
  4584.             'appIds' => $appId,
  4585.             'userIds' => $applicantId,
  4586.             'companyId' => $resolvedCompanyId,
  4587.             'userType' => $userType,
  4588.             'imageFile' => $imageFile
  4589.         ];
  4590.         if ($imageFile) {
  4591.             $postFields['file_' $applicant->getApplicantId()] = $imageFile;
  4592.         }
  4593.         $url $serverList[$serverId]['absoluteUrl'] . '/OnBoardCentralUserToErp';
  4594.         $curl curl_init();
  4595.         curl_setopt_array($curl, [
  4596.             CURLOPT_RETURNTRANSFER => 1,
  4597.             CURLOPT_POST => 1,
  4598.             CURLOPT_URL => $url,
  4599.             CURLOPT_POSTFIELDS => $postFields,
  4600.             CURLOPT_CONNECTTIMEOUT => 10,
  4601.             CURLOPT_SSL_VERIFYPEER => false,
  4602.             CURLOPT_SSL_VERIFYHOST => false,
  4603.         ]);
  4604.         $response curl_exec($curl);
  4605.         $curlError curl_error($curl);
  4606.         curl_close($curl);
  4607.         $responseObj json_decode($responsetrue);
  4608.         if ($currentRoute === 'employee_onboard_api') {
  4609.             return new JsonResponse(
  4610.                 $responseObj
  4611.             );
  4612.         }
  4613.         if (!empty($responseObj['success'])) {
  4614.             $this->addFlash('success''Applicant onboarded and synced to ERP.');
  4615.         } else {
  4616.             $this->addFlash('warning''Onboarded, but ERP sync may have failed. Check logs.');
  4617.         }
  4618.         return $this->redirectToRoute('central_landing');
  4619.     }
  4620.     public function OnBoardCentralUserToErpAction(Request $request)
  4621.     {
  4622.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  4623.         if ($systemType === '_CENTRAL_') {
  4624.             return new JsonResponse(['success' => false'message' => 'Invalid system type.']);
  4625.         }
  4626.         $userDataJson $request->get('userData');
  4627.         $userDataList json_decode($userDataJsontrue);
  4628.         if (!$userDataList || !is_array($userDataList)) {
  4629.             return new JsonResponse(['success' => false'message' => 'Invalid or missing userData.']);
  4630.         }
  4631.         $userData $userDataList[0] ?? null;
  4632.         if (!$userData || empty($userData['getApplicantId'])) {
  4633.             return new JsonResponse(['success' => false'message' => 'Missing applicant ID.']);
  4634.         }
  4635.         $em_goc $this->getDoctrine()->getManager('company_group');
  4636.         $globalId $userData['getApplicantId'];
  4637.         $appIds $request->get('appIds');
  4638.         $userIds $request->get('userIds');
  4639.         $companyId $request->get('companyId');
  4640.         $company $em_goc->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")->findOneBy(['appId' => $appIds]);
  4641.         if (!$company) {
  4642.             return new JsonResponse(['success' => false'message' => 'Target company not found.']);
  4643.         }
  4644.         $connector $this->container->get('application_connector');
  4645.         $connector->resetConnection(
  4646.             'default',
  4647.             $company->getDbName(),
  4648.             $company->getDbUser(),
  4649.             $company->getDbPass(),
  4650.             $company->getDbHost(),
  4651.             true
  4652.         );
  4653.         $em $this->getDoctrine()->getManager();
  4654.         $user $em->getRepository('ApplicationBundle\\Entity\\SysUser')->findOneBy([
  4655.             'globalId' => $globalId
  4656.         ]);
  4657.         if (!$user) {
  4658.             $user = new \ApplicationBundle\Entity\SysUser();
  4659.             $user->setGlobalId($globalId);
  4660.         } else {
  4661.             return new JsonResponse([
  4662.                 'status' => 'info',
  4663.                 'message' => 'User is already onboarded',
  4664.                 'userId' => $user->getUserId(),
  4665.                 'redirectUrl' => 'dashboard'
  4666.             ]);
  4667.         }
  4668.         $setterMap = [
  4669.             'getUsername' => 'setUserName',
  4670.             'getEmail' => 'setEmail',
  4671.             'getPassword' => 'setPassword',
  4672.             'getDeviceId' => 'setDeviceId',
  4673.             'getDeviceIdLockedFlag' => 'setDeviceIdLockedFlag',
  4674.             'getLockDeviceIdOnNextLoginFlag' => 'setLockDeviceIdOnNextLoginFlag',
  4675.             'getOAuthUniqueId' => 'setOAuthUniqueId',
  4676.             'getOAuthEmail' => 'setOAuthEmail',
  4677.             'getSyncFlag' => 'setSyncFlag',
  4678.             'getFirstname' => 'setName',
  4679.         ];
  4680.         $user->setUserAppId($appIds);
  4681.         $user->setUserAppIdList(json_encode([$appIds]));
  4682.         $user->setStatus(1);
  4683.         foreach ($setterMap as $getter => $setter) {
  4684.             if (isset($userData[$getter]) && method_exists($user$setter)) {
  4685.                 $user->$setter($userData[$getter]);
  4686.             }
  4687.         }
  4688.         $fullName trim(($userData['getFirstname'] ?? '') . ' ' . ($userData['getLastname'] ?? ''));
  4689.         if (!empty($fullName)) {
  4690.             $user->setName($fullName);
  4691.         }
  4692.         $imagePathToSet '';
  4693.         $uploadedFile $request->files->get('file_' $globalId);
  4694.         if ($uploadedFile) {
  4695.             $uploadDir $this->getParameter('kernel.project_dir') . '/web/uploads/UserImage/';
  4696.             if (!file_exists($uploadDir)) {
  4697.                 mkdir($uploadDir0777true);
  4698.             }
  4699.             $filename 'user_' $globalId '.' $uploadedFile->guessExtension();
  4700.             $uploadedFile->move($uploadDir$filename);
  4701.             $imagePathToSet 'uploads/UserImage/' $filename;
  4702.             $user->setImage($imagePathToSet);
  4703.         }
  4704.         $user->setUserType(1);
  4705.         $em->persist($user);
  4706.         $em->flush();
  4707.         $employee $em->getRepository('ApplicationBundle\\Entity\\Employee')->findOneBy([
  4708.             'userId' => $user->getUserId()
  4709.         ]);
  4710.         if (!$employee) {
  4711.             $employee = new \ApplicationBundle\Entity\Employee();
  4712.             $employee->setUserId($user->getUserId());
  4713.             $employee->setDateOfAddition(new \DateTime());
  4714.         }
  4715.         $employee->setFirstName($userData['getFirstname'] ?? null);
  4716.         $employee->setLastName($userData['getLastname'] ?? null);
  4717.         $employee->setName(trim(($userData['getFirstname'] ?? '') . ' ' . ($userData['getLastname'] ?? '')));
  4718.         $employee->setEmail($userData['getEmail'] ?? null);
  4719.         $employee->setEmmContact($userData['getEmmContact'] ?? null);
  4720.         $employee->setCurrentAddress($userData['getCurrAddr'] ?? null);
  4721.         $employee->setPermanentAddress($userData['getPermAddr'] ?? null);
  4722.         $employee->setCompanyId((int)$companyId);
  4723.         $employee->setDepartmentId($userData['getDept'] ?? null);
  4724.         $employee->setBranchId($userData['getBranch'] ?? null);
  4725.         $employee->setPositionId($userData['getDesg'] ?? null);
  4726.         $employee->setSupervisorId($userData['getSupervisor'] ?? null);
  4727.         if (!empty($imagePathToSet)) {
  4728.             $employee->setImage($imagePathToSet);
  4729.         }
  4730.         $employee->setStatus("1");
  4731.         $employee->setLastModifiedDate(new \DateTime());
  4732.         $em->persist($employee);
  4733.         $em->flush();
  4734.         $employeeDetails $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  4735.             ->findOneBy(['userId' => $user->getUserId()]);
  4736.         if (!$employeeDetails) {
  4737.             $employeeDetails = new \ApplicationBundle\Entity\EmployeeDetails();
  4738.             $employeeDetails->setUserId($user->getUserId());
  4739.         }
  4740.         $employeeDetails->setId($employee->getEmployeeId());
  4741.         $employeeDetails->setFirstname($userData['getFirstname'] ?? null);
  4742.         $employeeDetails->setLastname($userData['getLastname'] ?? null);
  4743.         $employeeDetails->setUsername($userData['getUsername'] ?? null);
  4744.         $employeeDetails->setEmail($userData['getEmail'] ?? null);
  4745.         $employeeDetails->setPassword($userData['getPassword'] ?? null);
  4746.         $employeeDetails->setNid($userData['getNid'] ?? null);
  4747.         $employeeDetails->setSex($userData['getSex'] ?? null);
  4748.         $employeeDetails->setFather($userData['getFather'] ?? null);
  4749.         $employeeDetails->setMother($userData['getMother'] ?? null);
  4750.         $employeeDetails->setSpouse($userData['getSpouse'] ?? null);
  4751.         $employeeDetails->setChild1($userData['getChild1'] ?? null);
  4752.         $employeeDetails->setChild2($userData['getChild2'] ?? null);
  4753.         $employeeDetails->setPhone($userData['getPhone'] ?? null);
  4754.         $employeeDetails->setOfficialPhone($userData['getOfficailPhone'] ?? null);
  4755.         $employeeDetails->setCurrAddr($userData['getCurrAddr'] ?? null);
  4756.         $employeeDetails->setPermAddr($userData['getPermAddr'] ?? null);
  4757.         $employeeDetails->setEmmContact($userData['getEmmContact'] ?? null);
  4758.         if (!empty($userData['getDob'])) {
  4759.             $employeeDetails->setDob(new \DateTime($userData['getDob']));
  4760.         }
  4761.         if (!empty($userData['getJoiningDate'])) {
  4762.             $employeeDetails->setJoiningDate(new \DateTime($userData['getJoiningDate']));
  4763.         }
  4764.         if (!empty($userData['getEmpValidTill'])) {
  4765.             $employeeDetails->setEmpValidTill(new \DateTime($userData['getEmpValidTill']));
  4766.         }
  4767.         if (!empty($userData['getTinValidTill'])) {
  4768.             $employeeDetails->setTinValidTill(new \DateTime($userData['getTinValidTill']));
  4769.         }
  4770.         if (!empty($userData['getMedInsValidTill'])) {
  4771.             $employeeDetails->setMedInsValidTill(new \DateTime($userData['getMedInsValidTill']));
  4772.         }
  4773.         $employeeDetails->setEmpType($userData['getEmpType'] ?? null);
  4774.         $employeeDetails->setEmpCode($userData['getEmpCode'] ?? null);
  4775.         $employeeDetails->setEmployeeLevel($userData['getEmployeeLevel'] ?? null);
  4776.         $employeeDetails->setTin($userData['getTin'] ?? null);
  4777.         $employeeDetails->setSkill($userData['getSkill'] ?? null);
  4778.         $employeeDetails->setEducationData($userData['getEducationData'] ?? null);
  4779.         $employeeDetails->setWorkExperienceData($userData['getWorkExperienceData'] ?? null);
  4780.         $employeeDetails->setApplicationText($userData['getApplicationText'] ?? null);
  4781.         $employeeDetails->setCurrentEmployment($userData['getCurrentEmployment'] ?? null);
  4782.         $employeeDetails->setEmergencyContactNumber($userData['getEmergencyContactNumber'] ?? null);
  4783.         $employeeDetails->setPostalCode($userData['getPostalCode'] ?? null);
  4784.         $employeeDetails->setCountry($userData['getCountry'] ?? null);
  4785.         if (!empty($imagePathToSet)) {
  4786.             $employeeDetails->setImage($imagePathToSet);
  4787.         }
  4788.         $em->persist($employeeDetails);
  4789.         $em->flush();
  4790.         $uploadedFile $request->files->get('file_' $globalId);
  4791.         return new JsonResponse([
  4792.             'success' => true,
  4793.             'globalId' => $globalId,
  4794.             'appIds' => $appIds,
  4795.             'userIds' => $userIds,
  4796.             'hasFile' => $uploadedFile !== null,
  4797.         ]);
  4798.     }
  4799.     public function getIndustryListForAppAction()
  4800.     {
  4801.         $industryList GeneralConstant::$industryList;
  4802.         return new JsonResponse($industryList);
  4803.     }
  4804.     public function getFeatureListAction()
  4805.     {
  4806.         $featureList GeneralConstant::$featureList;
  4807.         return new JsonResponse($featureList);
  4808.     }
  4809.     public function chooseYourPlanAction()
  4810.     {
  4811.         $plan GeneralConstant::$chooseYourPlan;
  4812.         return new JsonResponse($plan);
  4813.     }
  4814. //    public function getLogindataFromTokenAction(Request $request)
  4815. //    {
  4816. //        $em_goc = $this->getDoctrine()->getManager('company_group');
  4817. //        $sessionData = MiscActions::GetSessionDataFromToken($em_goc, $request->query->get('hbeeSessionToken'))['sessionData'];
  4818. //        return new JsonResponse($sessionData);
  4819. //        $sessionDataa = MiscActions::GetSessionDataFromToken($em_goc, $request->query->get('hbeeSessionToken'))['sessionData'];
  4820. //        return new JsonResponse($sessionDataa);
  4821. //    }
  4822.     public function getLogindataFromTokenAction(Request $request)
  4823.     {
  4824.         $em_goc $this->getDoctrine()->getManager('company_group');
  4825.         $token $request->query->get('hbeeSessionToken');
  4826.         if (!$token) {
  4827.             return new JsonResponse(['error' => 'Missing session token'], 400);
  4828.         }
  4829.         $sessionResult MiscActions::GetSessionDataFromToken($em_goc$token);
  4830.         if (!$sessionResult || !isset($sessionResult['sessionData'])) {
  4831.             return new JsonResponse(['error' => 'Invalid session token or session not found'], 401);
  4832.         }
  4833.         $sessionData $sessionResult['sessionData'];
  4834.         return new JsonResponse($sessionData);
  4835.     }
  4836.    public function packageDetailsAction()
  4837. {
  4838.     $packageDetails GeneralConstant::$packageDetails;
  4839.     return new JsonResponse([
  4840.         'success' => true,
  4841.         'message' => 'Data fetched successfully.',
  4842.         'data' => $packageDetails
  4843.     ]);
  4844. }
  4845.     public function employeeRangeAction()
  4846.     {
  4847.         $employeeRangeForApp GeneralConstant::$employeeRange;
  4848.         return new JsonResponse($employeeRangeForApp);
  4849.     }
  4850.     public function paymentMethodAction()
  4851.     {
  4852.         $paymentMethod GeneralConstant::$paymentMethod;
  4853.         return new JsonResponse($paymentMethod);
  4854.     }
  4855.     public function companyTypeAction()
  4856.     {
  4857.         $companyType GeneralConstant::$companyType;
  4858.         return new JsonResponse(
  4859.             [
  4860.                 'status' => 'success',
  4861.                 'message' => 'Company types retrieved successfully.',
  4862.                 'data' => $companyType,
  4863.             ]
  4864.          );
  4865.     }
  4866.     public function getCountryListAction()
  4867.     {
  4868.         $em_goc $this->getDoctrine()->getManager('company_group');
  4869.         $countryList $em_goc->getRepository('CompanyGroupBundle\\Entity\\EntityCountries')
  4870.             ->createQueryBuilder('C')
  4871.             ->select('C.CountryId''C.code''C.nameEn')
  4872.             ->getQuery()
  4873.             ->getArrayResult();
  4874.         // $formattedList = array_map(function ($country) {
  4875.         //     return [
  4876.         //         'countryId' => $country['countryId'],
  4877.         //         'countryName' => $country['nameEn'],
  4878.         //         'countryCode' => $country['code'],
  4879.         //     ];
  4880.         // }, $countryList);
  4881.         return new JsonResponse([
  4882.             'status' => true,
  4883.             'message' => 'Country list fetched successfully',
  4884.             'data' => $countryList,
  4885.         ]);
  4886.     }
  4887. public function spotLightSearchAction(Request $request,$queryStr ''){
  4888.     
  4889.     $em $this->getDoctrine()->getManager();
  4890.     $data = [];
  4891.     $data_by_id = [];
  4892.     $session $request->getSession();
  4893.     $entityDetails GeneralConstant::$Entity_list_details
  4894.     if ($queryStr == '_DEFAULT_')
  4895.         $queryStr '';
  4896.     if ($request->request->has('query') && $queryStr == '')
  4897.         $queryStr $request->request->get('query');
  4898.     if ($queryStr == '_DEFAULT_')
  4899.         $queryStr '';
  4900.     $queryStr str_ireplace('_FSLASH_''/'$queryStr);
  4901.     //module
  4902.     $filterQryForCriteria "select * from sys_module where 1=1 and module_name  like '%" $queryStr "%'  limit 10";
  4903.     $get_kids_sql $filterQryForCriteria;
  4904.     $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql);
  4905.     
  4906.     $get_kids $stmt;
  4907.     $productId 0;
  4908.     $absoluteUrl $this->generateUrl('dashboard', [], UrlGenerator::ABSOLUTE_URL);
  4909.     if (!empty($get_kids)) {
  4910.         foreach ($get_kids as $product) {
  4911.             $router $this->container->get('router');
  4912.             $routeName $product['module_route'];
  4913.             if ($router->getRouteCollection()->get($routeName)) {
  4914.                 $pa            = array();
  4915.                 $pa['id']      = $product['module_id'];
  4916.                 $pa['name']    = $product['module_name'];
  4917.                 $pa['type']    = 'module';
  4918. //            $pa['url']     = $absoluteUrl . '/' . $product['module_route'];
  4919.                 $pa['url']     = $this->generateUrl($product['module_route'], [], UrlGenerator::ABSOLUTE_URL);
  4920.                 $data[] = $pa;
  4921.             } else {
  4922.                 // treat as non-route
  4923. //                $pa['url'] = $routeName; // or custom fallback
  4924.             }
  4925.         }
  4926.     }
  4927.     // supplier
  4928.     $get_kids $em->getConnection()->fetchAllAssociative(
  4929.         "select * from acc_suppliers where supplier_name like '%" $queryStr "%' limit 10"
  4930.     );
  4931.     $url $this->generateUrl('supplier_profile');
  4932.     if (!empty($get_kids)) {
  4933.         foreach ($get_kids as $product) {
  4934.             $pa           = array();
  4935.             $pa['id']     = $product['supplier_id'];
  4936.             $pa['name']   = $product['supplier_name'];
  4937.             $pa['type']   = 'supplier';
  4938.             $pa['url']    = rtrim($absoluteUrl'/') . '/' ltrim($url'/') . '?ex_s_id=' $product['supplier_id'];
  4939.             $data[] = $pa;
  4940.         }
  4941.     }
  4942.     // client
  4943.     $get_kids $em->getConnection()->fetchAllAssociative(
  4944.         "select * from acc_clients where client_name like '%" $queryStr "%' limit 10"
  4945.     );
  4946.     $url $this->generateUrl('client_profile');
  4947.     if (!empty($get_kids)) {
  4948.         foreach ($get_kids as $product) {
  4949.             $pa           = array();
  4950.             $pa['id']     = $product['client_id'];
  4951.             $pa['name']   = $product['client_name'];
  4952.             $pa['type']   = 'client';
  4953.             $pa['url']    = rtrim($absoluteUrl'/') . '/' trim($url'/') . '/' $product['client_id'];
  4954.             $data[] = $pa;
  4955.         }
  4956.     }
  4957.     // document (approval)
  4958.     $get_kids $em->getConnection()->fetchAllAssociative(
  4959.         "select * from approval where document_hash like '%" $queryStr "%' limit 10"
  4960.     );
  4961.     if (!empty($get_kids)) {
  4962.         foreach ($get_kids as $product) {
  4963.             try {
  4964.                 $viewUrl $this->generateUrl(
  4965.                     $entityDetails[$product['entity']]['entity_view_route_path_name']
  4966.                 );
  4967.                 $pa           = array();
  4968.                 $pa['id']     = $product['id'];
  4969.                 $pa['name']   = $product['document_hash'];
  4970.                 $pa['type']   = 'document';
  4971.                 $pa['url']    = rtrim($absoluteUrl'/') . '/' trim($viewUrl'/') . '/' $product['entity_id'];
  4972.                 $data[] = $pa;
  4973.             } catch (\Exception $e) { /* skip if route undefined */ }
  4974.         }
  4975.     }
  4976.     return new JsonResponse(array(
  4977.         'success' => true,
  4978.         'data'    => $data,
  4979.     ));
  4980. }
  4981.     public function getMlDataAction()
  4982.     {
  4983.         $data GeneralConstant::$dataFromMl;
  4984.         return new JsonResponse($data);
  4985.     }
  4986.     public function UploadDocumentsAction(Request $request)
  4987.     {
  4988.         $session $request->getSession();
  4989.         $em $this->getDoctrine()->getManager();
  4990.         return $this->render(
  4991.             '@Application/pages/dashboard/upload_documents.html.twig',
  4992.             array(
  4993.                 'page_title' => 'Upload Documents',
  4994.             )
  4995.         );
  4996.     }
  4997. }