src/ApplicationBundle/Controller/ApplicationManagementController.php line 1996

Open in your IDE?
  1. <?php
  2. namespace ApplicationBundle\Controller;
  3. use ApplicationBundle\ApplicationBundle;
  4. use ApplicationBundle\Constants\GeneralConstant;
  5. use ApplicationBundle\Constants\ModuleConstant;
  6. use ApplicationBundle\Entity\Approval;
  7. use ApplicationBundle\Entity\Company;
  8. use ApplicationBundle\Entity\DocumentData;
  9. use ApplicationBundle\Entity\Employee;
  10. use ApplicationBundle\Entity\EmployeeDetails;
  11. use ApplicationBundle\Entity\SysModule;
  12. use ApplicationBundle\Entity\SysUser;
  13. use ApplicationBundle\Interfaces\LoginInterface;
  14. use ApplicationBundle\Modules\Authentication\Constants\UserConstants;
  15. use ApplicationBundle\Modules\Api\Constants\ApiConstants;
  16. use ApplicationBundle\Modules\Inventory\Inventory;
  17. use ApplicationBundle\Modules\System\MiscActions;
  18. use ApplicationBundle\Modules\System\System;
  19. use ApplicationBundle\Modules\User\Users;
  20. use CompanyGroupBundle\Entity\CompanyGroup;
  21. use CompanyGroupBundle\Entity\EmsSite;
  22. use CompanyGroupBundle\Entity\DeviceSensorData;
  23. use CompanyGroupBundle\Entity\DeviceSensorDataDay;
  24. use CompanyGroupBundle\Entity\DeviceSensorDataHour;
  25. use CompanyGroupBundle\Entity\DeviceSensorDataMonth;
  26. use CompanyGroupBundle\Entity\DeviceSensorDataWeek;
  27. use CompanyGroupBundle\Entity\EntityApplicantDetails;
  28. use Doctrine\ORM\Tools\SchemaTool;
  29. use Symfony\Component\HttpFoundation\JsonResponse;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use Symfony\Component\HttpFoundation\Response;
  32. use Symfony\Component\Routing\Generator\UrlGenerator;
  33. class ApplicationManagementController extends GenericController implements LoginInterface
  34. {
  35.     private function getCloudApiKey()
  36.     {
  37.         $configured '';
  38.         if ($this->container->hasParameter('cloud_api_key')) {
  39.             $configured trim((string)$this->container->getParameter('cloud_api_key'));
  40.         }
  41.         if ($configured === '') {
  42.             $configured trim((string)getenv('HONEYBEE_CLOUD_API_KEY'));
  43.         }
  44.         if ($configured === '') {
  45.             $configured 'dev-cloud-key';
  46.         }
  47.         return $configured;
  48.     }
  49.     private function jsonErrorResponse($statusCode$code$message, array $details = array())
  50.     {
  51.         return new JsonResponse(array(
  52.             'status' => 'error',
  53.             'error' => array(
  54.                 'code' => $code,
  55.                 'message' => $message,
  56.                 'details' => $details,
  57.             ),
  58.             'meta' => array(
  59.                 'schema_version' => '1.0',
  60.                 'correlation_id' => uniqid('corr_'true),
  61.             ),
  62.         ), $statusCode);
  63.     }
  64.     private function parseModuleIdList($moduleIdList)
  65.     {
  66.         if (is_array($moduleIdList)) {
  67.             $rawList $moduleIdList;
  68.         } else {
  69.             $moduleIdList trim((string)$moduleIdList);
  70.             if ($moduleIdList === '') {
  71.                 return array();
  72.             }
  73.             $decoded json_decode($moduleIdListtrue);
  74.             $rawList is_array($decoded) ? $decoded explode(','$moduleIdList);
  75.         }
  76.         $cleanList = array();
  77.         foreach ($rawList as $moduleId) {
  78.             $moduleId = (int)$moduleId;
  79.             if ($moduleId 0) {
  80.                 $cleanList[$moduleId] = $moduleId;
  81.             }
  82.         }
  83.         return array_values($cleanList);
  84.     }
  85.     private function normalizeEmsNumericValue($value)
  86.     {
  87.         if (is_bool($value) || is_array($value) || is_object($value) || $value === null) {
  88.             return null;
  89.         }
  90.         if (is_string($value)) {
  91.             $value trim($value);
  92.             if ($value === '') {
  93.                 return null;
  94.             }
  95.         }
  96.         if (!is_numeric($value)) {
  97.             return null;
  98.         }
  99.         $number = (float)$value;
  100.         return is_finite($number) ? $number null;
  101.     }
  102.     private function updateEmsAggregateValues(array $currentValues$numericValue)
  103.     {
  104.         $numericValue = (float)$numericValue;
  105.         $count = isset($currentValues[3]) && is_numeric($currentValues[3]) ? (int)$currentValues[3] : 0;
  106.         if ($count <= 0) {
  107.             return array($numericValue$numericValue$numericValue1);
  108.         }
  109.         $min = isset($currentValues[0]) && is_numeric($currentValues[0]) ? (float)$currentValues[0] : $numericValue;
  110.         $max = isset($currentValues[1]) && is_numeric($currentValues[1]) ? (float)$currentValues[1] : $numericValue;
  111.         $avg = isset($currentValues[2]) && is_numeric($currentValues[2]) ? (float)$currentValues[2] : $numericValue;
  112.         if ($numericValue $max) {
  113.             $max $numericValue;
  114.         }
  115.         if ($numericValue $min) {
  116.             $min $numericValue;
  117.         }
  118.         $avg = (($count $avg) + $numericValue) / ($count 1);
  119.         return array($min$max$avg$count 1);
  120.     }
  121.     private function mergeEmsAggregateValues(array $existingValues, array $newValues)
  122.     {
  123.         $newCount = isset($newValues[3]) && is_numeric($newValues[3]) ? (int)$newValues[3] : 0;
  124.         if ($newCount <= 0) {
  125.             return $existingValues;
  126.         }
  127.         $newMin $this->normalizeEmsNumericValue(isset($newValues[0]) ? $newValues[0] : null);
  128.         $newMax $this->normalizeEmsNumericValue(isset($newValues[1]) ? $newValues[1] : null);
  129.         $newAvg $this->normalizeEmsNumericValue(isset($newValues[2]) ? $newValues[2] : null);
  130.         if ($newMin === null || $newMax === null || $newAvg === null) {
  131.             return $existingValues;
  132.         }
  133.         $existingCount = isset($existingValues[3]) && is_numeric($existingValues[3]) ? (int)$existingValues[3] : 0;
  134.         if ($existingCount <= 0) {
  135.             return array($newMin$newMax$newAvg$newCount);
  136.         }
  137.         $existingMin $this->normalizeEmsNumericValue(isset($existingValues[0]) ? $existingValues[0] : null);
  138.         $existingMax $this->normalizeEmsNumericValue(isset($existingValues[1]) ? $existingValues[1] : null);
  139.         $existingAvg $this->normalizeEmsNumericValue(isset($existingValues[2]) ? $existingValues[2] : null);
  140.         if ($existingMin === null || $existingMax === null || $existingAvg === null) {
  141.             return array($newMin$newMax$newAvg$newCount);
  142.         }
  143.         $min min($existingMin$newMin);
  144.         $max max($existingMax$newMax);
  145.         $avg = (($existingCount $existingAvg) + ($newCount $newAvg)) / ($existingCount $newCount);
  146.         return array($min$max$avg$existingCount $newCount);
  147.     }
  148.     private function getDefaultEnabledCompanyModuleIds()
  149.     {
  150.         $moduleIds = array();
  151.         foreach (ModuleConstant::$moduleList as $module) {
  152.             if ((int)(isset($module['defaultEnabledForCompany']) ? $module['defaultEnabledForCompany'] : 0) === 1) {
  153.                 $moduleIds[] = (int)$module['id'];
  154.             }
  155.         }
  156.         return $moduleIds;
  157.     }
  158.     private function getCentralEnabledModuleIdsForApp($appId)
  159.     {
  160.         $appId = (int)$appId;
  161.         if ($appId <= 0) {
  162.             return array();
  163.         }
  164.         $urlToCall rtrim(GeneralConstant::HONEYBEE_CENTRAL_SERVER'/') . '/GetAppListFromCentralServer';
  165.         $curl curl_init();
  166.         curl_setopt_array($curl, array(
  167.             CURLOPT_RETURNTRANSFER => 1,
  168.             CURLOPT_URL => $urlToCall,
  169.             CURLOPT_CONNECTTIMEOUT => 10,
  170.             CURLOPT_SSL_VERIFYPEER => false,
  171.             CURLOPT_SSL_VERIFYHOST => false,
  172.             CURLOPT_HTTPHEADER => array(
  173.                 'Accept: application/json',
  174.             ),
  175.             CURLOPT_POSTFIELDS => http_build_query(array(
  176.                 'appId' => $appId,
  177.             )),
  178.         ));
  179.         $retData curl_exec($curl);
  180.         $errData curl_error($curl);
  181.         curl_close($curl);
  182.         if ($errData || !$retData) {
  183.             return array();
  184.         }
  185.         $response json_decode($retDatatrue);
  186.         if (!is_array($response)) {
  187.             return array();
  188.         }
  189.         foreach ($response as $entry) {
  190.             if (isset($entry['appId']) && (int)$entry['appId'] === $appId) {
  191.                 return $this->parseModuleIdList(isset($entry['enabledModuleIdList']) ? $entry['enabledModuleIdList'] : '');
  192.             }
  193.         }
  194.         return array();
  195.     }
  196.     private function getEnabledModuleIdsForCompanyRouteSync(array $companyData$systemType)
  197.     {
  198.         $enabledModuleIds = array();
  199.         if ($systemType !== '_CENTRAL_') {
  200.             $enabledModuleIds $this->getCentralEnabledModuleIdsForApp(isset($companyData['appId']) ? $companyData['appId'] : 0);
  201.         } elseif (isset($companyData['enabledModuleIdList'])) {
  202.             $enabledModuleIds $this->parseModuleIdList($companyData['enabledModuleIdList']);
  203.         }
  204.         if (empty($enabledModuleIds)) {
  205.             $enabledModuleIds $this->getDefaultEnabledCompanyModuleIds();
  206.         }
  207.         return $enabledModuleIds;
  208.     }
  209.     private function filterModuleRoutesForCompany(array $enabledModuleIds)
  210.     {
  211.         $enabledLookup array_fill_keys(array_map('intval'$enabledModuleIds), true);
  212.         $routeList = array();
  213.         foreach (ModuleConstant::$moduleList as $module) {
  214.             $moduleId = (int)$module['id'];
  215.             if (isset($enabledLookup[$moduleId])) {
  216.                 $routeList[] = $module;
  217.             }
  218.         }
  219.         return $routeList;
  220.     }
  221.     private function ensureCloudImportTables($em_goc)
  222.     {
  223.         $conn $em_goc->getConnection();
  224.         if (strtolower($conn->getDatabasePlatform()->getName()) !== 'mysql') {
  225.             return;
  226.         }
  227.         $conn->executeStatement('CREATE TABLE IF NOT EXISTS cloud_site_bundle_import_ledger (
  228.             id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  229.             idempotency_key VARCHAR(255) NOT NULL,
  230.             bundle_hash VARCHAR(64) NOT NULL,
  231.             site_uid VARCHAR(255) NOT NULL,
  232.             source_system VARCHAR(64) NOT NULL,
  233.             correlation_id VARCHAR(255) NULL,
  234.             status VARCHAR(32) NOT NULL DEFAULT \'processing\',
  235.             request_json LONGTEXT NOT NULL,
  236.             response_json LONGTEXT NULL,
  237.             created_at DATETIME NOT NULL,
  238.             updated_at DATETIME NOT NULL,
  239.             PRIMARY KEY(id),
  240.             UNIQUE KEY uniq_cloud_site_bundle_import_key (idempotency_key)
  241.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci');
  242.         $conn->executeStatement('CREATE TABLE IF NOT EXISTS cloud_site_bundle_entity (
  243.             id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  244.             site_uid VARCHAR(255) NOT NULL,
  245.             entity_type VARCHAR(64) NOT NULL,
  246.             entity_uid VARCHAR(255) NOT NULL,
  247.             bundle_hash VARCHAR(64) NOT NULL,
  248.             correlation_id VARCHAR(255) NULL,
  249.             payload_json LONGTEXT NOT NULL,
  250.             created_at DATETIME NOT NULL,
  251.             updated_at DATETIME NOT NULL,
  252.             PRIMARY KEY(id),
  253.             UNIQUE KEY uniq_cloud_site_bundle_entity (site_uid, entity_type, entity_uid)
  254.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci');
  255.     }
  256.     private function ensureCloudHeartbeatTable($em_goc)
  257.     {
  258.         $conn $em_goc->getConnection();
  259.         if (strtolower($conn->getDatabasePlatform()->getName()) !== 'mysql') {
  260.             return;
  261.         }
  262.         $conn->executeStatement('CREATE TABLE IF NOT EXISTS cloud_site_heartbeat (
  263.             id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  264.             site_uid VARCHAR(255) NOT NULL,
  265.             source_system VARCHAR(64) NOT NULL DEFAULT \'honeycore\',
  266.             controller_serial VARCHAR(255) NULL,
  267.             payload_json LONGTEXT NULL,
  268.             created_at DATETIME NOT NULL,
  269.             last_seen_at DATETIME NOT NULL,
  270.             PRIMARY KEY(id),
  271.             UNIQUE KEY uniq_cloud_site_heartbeat_site (site_uid)
  272.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci');
  273.     }
  274.     private function recordCloudSiteHeartbeat($em_goc$siteUid$sourceSystem 'honeycore'$controllerSerial '', array $payload = array())
  275.     {
  276.         $siteUid trim((string)$siteUid);
  277.         if ($siteUid === '') {
  278.             return false;
  279.         }
  280.         $now = (new \DateTime('now', new \DateTimeZone('UTC')))->format('Y-m-d H:i:s');
  281.         $this->ensureCloudHeartbeatTable($em_goc);
  282.         $em_goc->getConnection()->executeStatement(
  283.             'INSERT INTO cloud_site_heartbeat
  284.                 (site_uid, source_system, controller_serial, payload_json, created_at, last_seen_at)
  285.              VALUES
  286.                 (:site_uid, :source_system, :controller_serial, :payload_json, :created_at, :last_seen_at)
  287.              ON DUPLICATE KEY UPDATE
  288.                 source_system = VALUES(source_system),
  289.                 controller_serial = VALUES(controller_serial),
  290.                 payload_json = VALUES(payload_json),
  291.                 last_seen_at = VALUES(last_seen_at)',
  292.             array(
  293.                 'site_uid' => $siteUid,
  294.                 'source_system' => (string)$sourceSystem,
  295.                 'controller_serial' => (string)$controllerSerial,
  296.                 'payload_json' => json_encode($payloadJSON_UNESCAPED_SLASHES JSON_UNESCAPED_UNICODE),
  297.                 'created_at' => $now,
  298.                 'last_seen_at' => $now,
  299.             )
  300.         );
  301.         return $now;
  302.     }
  303.     private function upsertCloudBundleEntity($em_goc$siteUid$entityType$entityUid, array $payload$bundleHash$correlationId)
  304.     {
  305.         $conn $em_goc->getConnection();
  306.         $now = (new \DateTime('now', new \DateTimeZone('UTC')))->format('Y-m-d H:i:s');
  307.         $conn->executeStatement(
  308.             'INSERT INTO cloud_site_bundle_entity
  309.                 (site_uid, entity_type, entity_uid, bundle_hash, correlation_id, payload_json, created_at, updated_at)
  310.              VALUES
  311.                 (:site_uid, :entity_type, :entity_uid, :bundle_hash, :correlation_id, :payload_json, :created_at, :updated_at)
  312.              ON DUPLICATE KEY UPDATE
  313.                 bundle_hash = VALUES(bundle_hash),
  314.                 correlation_id = VALUES(correlation_id),
  315.                 payload_json = VALUES(payload_json),
  316.                 updated_at = VALUES(updated_at)',
  317.             array(
  318.                 'site_uid' => (string)$siteUid,
  319.                 'entity_type' => (string)$entityType,
  320.                 'entity_uid' => (string)$entityUid,
  321.                 'bundle_hash' => (string)$bundleHash,
  322.                 'correlation_id' => (string)$correlationId,
  323.                 'payload_json' => json_encode($payloadJSON_UNESCAPED_SLASHES JSON_UNESCAPED_UNICODE),
  324.                 'created_at' => $now,
  325.                 'updated_at' => $now,
  326.             )
  327.         );
  328.     }
  329.     private function getInfluxSettings()
  330.     {
  331.         $getEnv = function ($key) {
  332.             $value getenv($key);
  333.             return $value === false '' trim((string)$value);
  334.         };
  335.         return array(
  336.             'enabled' => $getEnv('HONEYBEE_INFLUX_WRITE_URL') !== '' && $getEnv('HONEYBEE_INFLUX_BUCKET') !== '',
  337.             'write_url' => $getEnv('HONEYBEE_INFLUX_WRITE_URL'),
  338.             'bucket' => $getEnv('HONEYBEE_INFLUX_BUCKET'),
  339.             'org' => $getEnv('HONEYBEE_INFLUX_ORG'),
  340.             'token' => $getEnv('HONEYBEE_INFLUX_TOKEN'),
  341.             'measurement' => $getEnv('HONEYBEE_INFLUX_MEASUREMENT') ?: 'telemetry',
  342.             'query_url' => $getEnv('HONEYBEE_INFLUX_QUERY_URL'),
  343.             'timeout' => (int)($getEnv('HONEYBEE_INFLUX_TIMEOUT') ?: 5),
  344.         );
  345.     }
  346.     private function escapeInfluxTag($value)
  347.     {
  348.         return str_replace(array('\\'' '','), array('\\\\''\ ''\,'), (string)$value);
  349.     }
  350.     private function escapeInfluxFieldString($value)
  351.     {
  352.         return '"' str_replace(array('\\''"'), array('\\\\''\"'), (string)$value) . '"';
  353.     }
  354.     private function httpRequest($url$method, array $headers$body$timeout 5)
  355.     {
  356.         if (function_exists('curl_init')) {
  357.             $ch curl_init($url);
  358.             curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  359.             curl_setopt($chCURLOPT_CUSTOMREQUEST$method);
  360.             curl_setopt($chCURLOPT_TIMEOUT$timeout);
  361.             curl_setopt($chCURLOPT_HTTPHEADER$headers);
  362.             if ($body !== null) {
  363.                 curl_setopt($chCURLOPT_POSTFIELDS$body);
  364.             }
  365.             $responseBody curl_exec($ch);
  366.             $status = (int)curl_getinfo($chCURLINFO_HTTP_CODE);
  367.             $error curl_error($ch);
  368.             curl_close($ch);
  369.             return array(
  370.                 'ok' => $status >= 200 && $status 300,
  371.                 'status' => $status,
  372.                 'body' => $responseBody,
  373.                 'error' => $error,
  374.             );
  375.         }
  376.         $context stream_context_create(array(
  377.             'http' => array(
  378.                 'method' => $method,
  379.                 'header' => implode("\r\n"$headers),
  380.                 'content' => $body,
  381.                 'timeout' => $timeout,
  382.             ),
  383.         ));
  384.         $responseBody = @file_get_contents($urlfalse$context);
  385.         $status 0;
  386.         if (isset($http_response_header) && is_array($http_response_header)) {
  387.             foreach ($http_response_header as $headerLine) {
  388.                 if (preg_match('/^HTTP\/\S+\s+(\d+)/'$headerLine$matches)) {
  389.                     $status = (int)$matches[1];
  390.                     break;
  391.                 }
  392.             }
  393.         }
  394.         return array(
  395.             'ok' => $status >= 200 && $status 300,
  396.             'status' => $status,
  397.             'body' => $responseBody,
  398.             'error' => $responseBody === false 'stream_request_failed' '',
  399.         );
  400.     }
  401.     private function toInfluxFieldValue($value)
  402.     {
  403.         if (is_bool($value)) {
  404.             return $value 'true' 'false';
  405.         }
  406.         if (is_int($value)) {
  407.             return $value 'i';
  408.         }
  409.         if (is_float($value) || is_numeric($value)) {
  410.             return (string)($value);
  411.         }
  412.         if (is_null($value)) {
  413.             return '""';
  414.         }
  415.         return $this->escapeInfluxFieldString($value);
  416.     }
  417.     private function writeInstantTelemetryToInflux(array $record$siteUid, array $dashboardContext$bundleHash$correlationId)
  418.     {
  419.         $settings $this->getInfluxSettings();
  420.         if (empty($settings['enabled'])) {
  421.             return false;
  422.         }
  423.         $timestamp = new \DateTime(isset($record['timestamp']) ? $record['timestamp'] : 'now');
  424.         $timestamp->setTimezone(new \DateTimeZone('+0000'));
  425.         $timestampNs = (string)((int)$timestamp->format('U') * 1000000000);
  426.         $tags = array(
  427.             'site_uid' => $siteUid,
  428.             'device_uid' => (string)($record['device_uid'] ?? $record['device_id'] ?? ''),
  429.             'point_uid' => (string)($record['point_uid'] ?? ''),
  430.             'point_code' => (string)($record['point_code'] ?? $record['identifier'] ?? ''),
  431.             'source' => (string)($record['source'] ?? 'honeycore'),
  432.         );
  433.         if (!empty($dashboardContext['site_type'])) {
  434.             $tags['site_type'] = (string)$dashboardContext['site_type'];
  435.         }
  436.         if (!empty($record['unit'])) {
  437.             $tags['unit'] = (string)$record['unit'];
  438.         }
  439.         $tagParts = array();
  440.         foreach ($tags as $tagKey => $tagValue) {
  441.             if ($tagValue === '') {
  442.                 continue;
  443.             }
  444.             $tagParts[] = $this->escapeInfluxTag($tagKey) . '=' $this->escapeInfluxTag($tagValue);
  445.         }
  446.         $fields = array(
  447.             'value' => $this->toInfluxFieldValue($record['value'] ?? null),
  448.             'record_id' => $this->escapeInfluxFieldString($record['record_id'] ?? ''),
  449.             'alias' => $this->escapeInfluxFieldString($record['alias'] ?? ''),
  450.             'schema_version' => $this->escapeInfluxFieldString($record['schema_version'] ?? '1.0'),
  451.             'bundle_hash' => $this->escapeInfluxFieldString($bundleHash),
  452.             'correlation_id' => $this->escapeInfluxFieldString($record['correlation_id'] ?? $correlationId),
  453.         );
  454.         if (isset($record['quality'])) {
  455.             $fields['quality'] = $this->escapeInfluxFieldString((string)$record['quality']);
  456.         }
  457.         if (isset($record['raw_value']) && is_scalar($record['raw_value'])) {
  458.             $fields['raw_value'] = $this->escapeInfluxFieldString((string)$record['raw_value']);
  459.         }
  460.         $line $settings['measurement'];
  461.         if (!empty($tagParts)) {
  462.             $line .= ',' implode(','$tagParts);
  463.         }
  464.         $line .= ' ';
  465.         $fieldParts = array();
  466.         foreach ($fields as $fieldKey => $fieldValue) {
  467.             $fieldParts[] = $fieldKey '=' $fieldValue;
  468.         }
  469.         $line .= implode(','$fieldParts) . ' ' $timestampNs;
  470.         $writeUrl $settings['write_url'];
  471.         $separator strpos($writeUrl'?') === false '?' '&';
  472.         $writeUrl .= $separator http_build_query(array(
  473.                 'bucket' => $settings['bucket'],
  474.                 'org' => $settings['org'],
  475.                 'precision' => 'ns',
  476.             ));
  477.         $headers = array(
  478.             'Content-Type: text/plain; charset=utf-8',
  479.         );
  480.         if ($settings['token'] !== '') {
  481.             $headers[] = 'Authorization: Token ' $settings['token'];
  482.         }
  483.         $response $this->httpRequest($writeUrl'POST'$headers$line$settings['timeout']);
  484.         if (!$response['ok']) {
  485.             return false;
  486.         }
  487.         return true;
  488.     }
  489.     private function upsertCloudTelemetry($em_goc, array $record$siteUid, array $dashboardContext$bundleHash$correlationId)
  490.     {
  491.         if ($this->writeInstantTelemetryToInflux($record$siteUid$dashboardContext$bundleHash$correlationId)) {
  492.             return;
  493.         }
  494.         $siteIdInt = (int)$siteUid;
  495.         if ($siteIdInt <= 0) {
  496.             return;
  497.         }
  498.         $recordId = (string)($record['record_id'] ?? '');
  499.         if ($recordId === '') {
  500.             return;
  501.         }
  502.         $timestamp = new \DateTime(isset($record['timestamp']) ? $record['timestamp'] : 'now');
  503.         $timestamp->setTimezone(new \DateTimeZone('+0000'));
  504.         $entry $em_goc->getRepository(DeviceSensorData::class)->findOneBy(array(
  505.             'recordId' => $recordId,
  506.         ));
  507.         if (!$entry) {
  508.             $entry = new DeviceSensorData();
  509.             $entry->setRecordId($recordId);
  510.             $entry->setSiteId($siteIdInt);
  511.         }
  512.         $entry->setDeviceId((string)($record['device_uid'] ?? $record['device_id'] ?? ''));
  513.         $entry->setIdentifier((string)($record['point_code'] ?? $record['identifier'] ?? ''));
  514.         $entry->setAlias((string)($record['alias'] ?? ''));
  515.         $entry->setValue(is_scalar($record['value'] ?? null) ? (string)$record['value'] : json_encode($record['value'] ?? null));
  516.         $entry->setTimeStamp($timestamp);
  517.         $entry->setTimeStampTs((int)$timestamp->format('U'));
  518.         $em_goc->persist($entry);
  519.         $em_goc->flush();
  520.     }
  521.     private function normalizeCloudSiteText($value)
  522.     {
  523.         return preg_replace('/[^a-z0-9]+/'''strtolower((string)$value));
  524.     }
  525.     private function bundlePayloadMatchesSite(array $payload, array $dashboardContext$site)
  526.     {
  527.         if (!$site) {
  528.             return false;
  529.         }
  530.         $siteName method_exists($site'getSiteName') ? $this->normalizeCloudSiteText($site->getSiteName()) : '';
  531.         $siteLocation '';
  532.         if (method_exists($site'getSiteLocation')) {
  533.             $siteLocation $site->getSiteLocation();
  534.         }
  535.         if ($siteLocation === '' && method_exists($site'getAddress')) {
  536.             $siteLocation $site->getAddress();
  537.         }
  538.         $siteLocation $this->normalizeCloudSiteText($siteLocation);
  539.         $payloadNames = array(
  540.             $payload['site_name'] ?? null,
  541.             $payload['name'] ?? null,
  542.             $payload['site'] ?? null,
  543.             $dashboardContext['site_name'] ?? null,
  544.             $dashboardContext['name'] ?? null,
  545.         );
  546.         foreach ($payloadNames as $payloadName) {
  547.             $normalized $this->normalizeCloudSiteText($payloadName);
  548.             if ($normalized !== '' && $siteName !== '' && $normalized === $siteName) {
  549.                 return true;
  550.             }
  551.         }
  552.         $payloadLocation $this->normalizeCloudSiteText(
  553.             $payload['location'] ?? $payload['address'] ?? $dashboardContext['location'] ?? $dashboardContext['address'] ?? ''
  554.         );
  555.         return $payloadLocation !== '' && $siteLocation !== '' && $payloadLocation === $siteLocation;
  556.     }
  557.     private function resolveCloudBundleSiteEntity($em_goc, array $sitePayload, array $dashboardContext, array $source$routeSiteId 0)
  558.     {
  559.         $repo $em_goc->getRepository(EmsSite::class);
  560.         if ((int)$routeSiteId 0) {
  561.             $site $repo->find((int)$routeSiteId);
  562.             if ($site) {
  563.                 return $site;
  564.             }
  565.         }
  566.         $explicitCloudSiteId $source['cloud_site_id'] ?? $source['cloudSiteId'] ?? $sitePayload['cloud_site_id'] ?? $dashboardContext['cloud_site_id'] ?? null;
  567.         if ($explicitCloudSiteId !== null && ctype_digit((string)$explicitCloudSiteId)) {
  568.             $site $repo->find((int)$explicitCloudSiteId);
  569.             if ($site) {
  570.                 return $site;
  571.             }
  572.         }
  573.         $sites $repo->createQueryBuilder('s')
  574.             ->orderBy('s.id''ASC')
  575.             ->getQuery()
  576.             ->getResult();
  577.         foreach ($sites as $site) {
  578.             if ($this->bundlePayloadMatchesSite($sitePayload$dashboardContext$site)) {
  579.                 return $site;
  580.             }
  581.         }
  582.         return null;
  583.     }
  584.     public function CloudSiteBundleImportAction(Request $request$id 0)
  585.     {
  586.         $em_goc $this->getDoctrine()->getManager('company_group');
  587.         $this->ensureCloudImportTables($em_goc);
  588.         $expectedApiKey $this->getCloudApiKey();
  589.         $providedApiKey trim((string)$request->headers->get('X-API-Key'''));
  590.         if ($providedApiKey === '' || !hash_equals($expectedApiKey$providedApiKey)) {
  591.             return $this->jsonErrorResponse(401'invalid_api_key''Invalid or missing cloud API key.');
  592.         }
  593.         $idempotencyKey trim((string)$request->headers->get('Idempotency-Key'''));
  594.         if ($idempotencyKey === '') {
  595.             return $this->jsonErrorResponse(400'missing_idempotency_key''Idempotency-Key header is required.');
  596.         }
  597.         $bundle json_decode($request->getContent(), true);
  598.         if (!is_array($bundle)) {
  599.             return $this->jsonErrorResponse(400'invalid_json''Request body must be valid JSON.');
  600.         }
  601.         if (($bundle['schema_version'] ?? '') !== '1.0') {
  602.             return $this->jsonErrorResponse(400'invalid_schema_version''schema_version must be 1.0.');
  603.         }
  604.         if (($bundle['package_type'] ?? '') !== 'site_bundle') {
  605.             return $this->jsonErrorResponse(400'invalid_package_type''package_type must be site_bundle.');
  606.         }
  607.         $source = isset($bundle['source']) && is_array($bundle['source']) ? $bundle['source'] : array();
  608.         if (($source['system'] ?? '') !== 'honeycore') {
  609.             return $this->jsonErrorResponse(400'invalid_source_system''source.system must be honeycore.');
  610.         }
  611.         $siteUid = (string)($source['site_uid'] ?? '');
  612.         if ($siteUid === '') {
  613.             return $this->jsonErrorResponse(400'missing_site_uid''source.site_uid is required.');
  614.         }
  615.         $this->recordCloudSiteHeartbeat(
  616.             $em_goc,
  617.             $siteUid,
  618.             (string)($source['system'] ?? 'honeycore'),
  619.             (string)($source['controller_serial'] ?? $source['controllerSerial'] ?? ''),
  620.             array('source' => $source'package_type' => $bundle['package_type'] ?? '''schema_version' => $bundle['schema_version'] ?? '')
  621.         );
  622.         $bundleHash hash('sha256'json_encode($bundleJSON_UNESCAPED_SLASHES JSON_UNESCAPED_UNICODE));
  623.         $correlationId = (string)($source['correlation_id'] ?? uniqid('corr_'true));
  624.         $conn $em_goc->getConnection();
  625.         $existingLedger $conn->fetchAssociative(
  626.             'SELECT response_json FROM cloud_site_bundle_import_ledger WHERE idempotency_key = :idempotency_key',
  627.             array('idempotency_key' => $idempotencyKey)
  628.         );
  629.         if ($existingLedger && !empty($existingLedger['response_json'])) {
  630.             return new JsonResponse(json_decode($existingLedger['response_json'], true), 200);
  631.         }
  632.         $now = (new \DateTime('now', new \DateTimeZone('UTC')))->format('Y-m-d H:i:s');
  633.         $conn->executeStatement(
  634.             'INSERT INTO cloud_site_bundle_import_ledger
  635.                 (idempotency_key, bundle_hash, site_uid, source_system, correlation_id, status, request_json, created_at, updated_at)
  636.              VALUES
  637.                 (:idempotency_key, :bundle_hash, :site_uid, :source_system, :correlation_id, :status, :request_json, :created_at, :updated_at)
  638.              ON DUPLICATE KEY UPDATE
  639.                 bundle_hash = VALUES(bundle_hash),
  640.                 site_uid = VALUES(site_uid),
  641.                 source_system = VALUES(source_system),
  642.                 correlation_id = VALUES(correlation_id),
  643.                 status = VALUES(status),
  644.                 request_json = VALUES(request_json),
  645.                 updated_at = VALUES(updated_at)',
  646.             array(
  647.                 'idempotency_key' => $idempotencyKey,
  648.                 'bundle_hash' => $bundleHash,
  649.                 'site_uid' => $siteUid,
  650.                 'source_system' => 'honeycore',
  651.                 'correlation_id' => $correlationId,
  652.                 'status' => 'processing',
  653.                 'request_json' => json_encode($bundleJSON_UNESCAPED_SLASHES JSON_UNESCAPED_UNICODE),
  654.                 'created_at' => $now,
  655.                 'updated_at' => $now,
  656.             )
  657.         );
  658.         $sitePayload = isset($bundle['site']) && is_array($bundle['site']) ? $bundle['site'] : array();
  659.         $dashboardContext = isset($bundle['dashboard_context']) && is_array($bundle['dashboard_context']) ? $bundle['dashboard_context'] : array();
  660.         $siteEntity $this->resolveCloudBundleSiteEntity($em_goc$sitePayload$dashboardContext$source$id);
  661.         $linkedSiteId $siteEntity $siteEntity->getId() : null;
  662.         if ($siteEntity) {
  663.             if (method_exists($siteEntity'setSiteType')) {
  664.                 $siteEntity->setSiteType((string)($sitePayload['site_type'] ?? $dashboardContext['site_type'] ?? $bundle['site_type'] ?? 'SOPHIA'));
  665.             }
  666.             if (method_exists($siteEntity'setSiteName') && isset($sitePayload['site_name'])) {
  667.                 $siteEntity->setSiteName((string)$sitePayload['site_name']);
  668.             }
  669.             if (method_exists($siteEntity'setSiteLocation') && isset($sitePayload['address'])) {
  670.                 $siteEntity->setSiteLocation((string)$sitePayload['address']);
  671.             }
  672.             if (method_exists($siteEntity'setSiteNote') && isset($sitePayload['description'])) {
  673.                 $siteEntity->setSiteNote((string)$sitePayload['description']);
  674.             }
  675.             if (method_exists($siteEntity'setContactPerson') && isset($sitePayload['operator'])) {
  676.                 $siteEntity->setContactPerson((string)$sitePayload['operator']);
  677.             }
  678.             if (method_exists($siteEntity'setSiteIcon') && isset($sitePayload['image_url'])) {
  679.                 $siteEntity->setSiteIcon((string)$sitePayload['image_url']);
  680.             }
  681.             $em_goc->persist($siteEntity);
  682.             $em_goc->flush();
  683.         }
  684.         $this->upsertCloudBundleEntity($em_goc$siteUid'site'$siteUid$sitePayload$bundleHash$correlationId);
  685.         foreach (array('system_mode''dashboard_context') as $entityType) {
  686.             if (isset($bundle[$entityType]) && is_array($bundle[$entityType])) {
  687.                 $this->upsertCloudBundleEntity($em_goc$siteUid$entityType$siteUid$bundle[$entityType], $bundleHash$correlationId);
  688.             }
  689.         }
  690.         foreach (array('devices''points''constraints''control_actions') as $entityType) {
  691.             if (empty($bundle[$entityType]) || !is_array($bundle[$entityType])) {
  692.                 continue;
  693.             }
  694.             foreach ($bundle[$entityType] as $row) {
  695.                 if (!is_array($row)) {
  696.                     continue;
  697.                 }
  698.                 $entityUid '';
  699.                 if ($entityType === 'devices') {
  700.                     $entityUid = (string)($row['device_uid'] ?? '');
  701.                 } elseif ($entityType === 'points') {
  702.                     $entityUid = (string)($row['point_uid'] ?? '');
  703.                 } elseif ($entityType === 'constraints') {
  704.                     $entityUid = (string)($row['constraint_uid'] ?? '');
  705.                 } elseif ($entityType === 'control_actions') {
  706.                     $entityUid = (string)($row['action_id'] ?? '');
  707.                 }
  708.                 if ($entityUid === '') {
  709.                     $entityUid md5(json_encode($row));
  710.                 }
  711.                 $this->upsertCloudBundleEntity($em_goc$siteUid$entityType$entityUid$row$bundleHash$correlationId);
  712.             }
  713.         }
  714.         $telemetryCount 0;
  715.         if (!empty($bundle['telemetry']) && is_array($bundle['telemetry'])) {
  716.             foreach ($bundle['telemetry'] as $record) {
  717.                 if (!is_array($record)) {
  718.                     continue;
  719.                 }
  720.                 $this->upsertCloudTelemetry($em_goc$record$siteUid$dashboardContext$bundleHash$correlationId);
  721.                 $telemetryCount++;
  722.             }
  723.         }
  724.         $responseEnvelope = array(
  725.             'status' => 'ok',
  726.             'data' => array(
  727.                 'site_uid' => $siteUid,
  728.                 'site_id' => $linkedSiteId,
  729.                 'linked_site_id' => $linkedSiteId,
  730.                 'site_link_status' => $linkedSiteId 'linked_existing_site' 'unlinked_bundle_only',
  731.                 'telemetry_count' => $telemetryCount,
  732.                 'entity_count' => isset($bundle['devices']) && is_array($bundle['devices']) ? count($bundle['devices']) : 0,
  733.             ),
  734.             'meta' => array(
  735.                 'schema_version' => '1.0',
  736.                 'correlation_id' => $correlationId,
  737.                 'idempotency_key' => $idempotencyKey,
  738.                 'bundle_hash' => $bundleHash,
  739.             ),
  740.             'error' => null,
  741.         );
  742.         $conn->executeStatement(
  743.             'UPDATE cloud_site_bundle_import_ledger
  744.              SET status = :status, response_json = :response_json, updated_at = :updated_at
  745.              WHERE idempotency_key = :idempotency_key',
  746.             array(
  747.                 'status' => 'ok',
  748.                 'response_json' => json_encode($responseEnvelopeJSON_UNESCAPED_SLASHES JSON_UNESCAPED_UNICODE),
  749.                 'updated_at' => (new \DateTime('now', new \DateTimeZone('UTC')))->format('Y-m-d H:i:s'),
  750.                 'idempotency_key' => $idempotencyKey,
  751.             )
  752.         );
  753.         return new JsonResponse($responseEnvelope200);
  754.     }
  755.     public function DeviceDataHeartBeatAction(Request $request$id 0)
  756.     {
  757.         $em_goc $this->getDoctrine()->getManager('company_group');
  758.         $content $request->getContent(); // raw body string
  759.         $data json_decode($contenttrue); // decode JSON if needed
  760.         // Example: access fields
  761.         if ($data == null$data = [];
  762.         $emsDataSegregation GeneralConstant::$emsDataSegregation;
  763.         $segregatedData = [];
  764.         $segregatedDataByDeviceId = [];
  765.         $source = isset($data['source']) && is_array($data['source']) ? $data['source'] : array();
  766.         $siteId = (string)($data['siteId'] ?? $data['site_id'] ?? $data['site_uid'] ?? $source['site_uid'] ?? '');
  767.         $siteId trim($siteId);
  768.         if ($siteId === '') {
  769.             return new JsonResponse(array(
  770.                 'success' => false,
  771.                 'error' => 'missing_site_id',
  772.                 'message' => 'Heartbeat payload must include siteId, site_id, site_uid, or source.site_uid.',
  773.             ), 400);
  774.         }
  775.         $controllerSerial = (string)($data['controllerSerial'] ?? $data['controller_serial'] ?? $source['controller_serial'] ?? '');
  776.         $heartbeatAt $this->recordCloudSiteHeartbeat(
  777.             $em_goc,
  778.             $siteId,
  779.             (string)($source['system'] ?? $data['source_system'] ?? 'honeycore'),
  780.             $controllerSerial,
  781.             $data
  782.         );
  783.         //first create a new array or records which will then be modified and or created
  784.         return new JsonResponse(array(
  785.             'success' => true,
  786.             'site_uid' => $siteId,
  787.             'heartbeat_at' => $heartbeatAt,
  788.         ));
  789.     }
  790.     public function DeviceDataEmsIngestAction(Request $request$id 0)
  791.     {
  792.         $em_goc $this->getDoctrine()->getManager('company_group');
  793.         $content $request->getContent(); // raw body string
  794.         $data json_decode($contenttrue); // decode JSON if needed
  795.         // Example: access fields
  796.         if ($data == null$data = [];
  797.         $emsDataSegregation GeneralConstant::$emsDataSegregation;
  798.         $segregatedData = [];
  799.         $segregatedDataByDeviceId = [];
  800.         $siteId = (isset($data['siteId'])) ? $data['siteId'] : 0;
  801.         if ((int)$siteId 0) {
  802.             $this->recordCloudSiteHeartbeat(
  803.                 $em_goc,
  804.                 $siteId,
  805.                 (string)($data['source_system'] ?? 'honeycore_ingest'),
  806.                 (string)($data['controllerSerial'] ?? $data['controller_serial'] ?? ''),
  807.                 array('source' => 'ems_ingest''records_count' => count($data['records'] ?? array()))
  808.             );
  809.         }
  810.         //first create a new array or records which will then be modified and or created
  811.         $modifiedData = array();
  812.         $firstTs 0;
  813.         $lastTs 0;
  814.         $siteIds = [$siteId];
  815. //        $defaultData = [
  816. //            'marker' => '',
  817. //            'ts' => '',
  818. //            'data' => []
  819. //        ];
  820.         $defaultValues = [0000];
  821.         $skippedNonNumeric 0;
  822.         $skippedInvalidRecords 0;
  823.         if (isset($data['records']))
  824.             foreach ($data['records'] as $key => $value) {
  825.                 if (!is_array($value) || !isset($value['timestamp'], $value['device_id'], $value['identifier'])) {
  826.                     $skippedInvalidRecords++;
  827.                     continue;
  828.                 }
  829.                 $identifier trim((string)$value['identifier']);
  830.                 $deviceId trim((string)$value['device_id']);
  831.                 if ($identifier === '' || $deviceId === '') {
  832.                     $skippedInvalidRecords++;
  833.                     continue;
  834.                 }
  835.                 $numericValue $this->normalizeEmsNumericValue(isset($value['value']) ? $value['value'] : null);
  836.                 if ($numericValue === null) {
  837.                     $skippedNonNumeric++;
  838.                     continue;
  839.                 }
  840.                 $timeStampDt = new \DateTime($value['timestamp']);
  841.                 $timeStampDt->setTimezone(new \DateTimeZone('+0000'));
  842.                 $timeStampTs $timeStampDt->format('U');
  843.                 if ($timeStampTs $lastTs$lastTs $timeStampTs;
  844.                 if ($timeStampTs $firstTs || $firstTs == 0$firstTs $timeStampTs;
  845.                 if (!in_array($siteId$siteIds)) $siteIds[] = $siteId;
  846.                 foreach ($emsDataSegregation as $key2 => $dataSegregation) {
  847.                     if (!isset($segregatedDataByDeviceId[$deviceId]))
  848.                         $segregatedDataByDeviceId[$deviceId] = [];
  849.                     if (!isset($segregatedDataByDeviceId[$deviceId][$key2]))
  850.                         $segregatedDataByDeviceId[$deviceId][$key2] = [];
  851.                     $segregatedData $segregatedDataByDeviceId[$deviceId];
  852. //                    $segregatedData[$key2] = [
  853. ////                             '20250406':   [
  854. ////                                    'marker' => '',
  855. ////                                    'ts' => '',
  856. ////                                    'data' => ['Battery_power' => [0, 2, 1, 4]]
  857. ////                                ]
  858. //                        ];
  859. //                    [{'_identifier_':{min,max,avg,count}}]
  860.                     $markerForThis $timeStampDt->format($dataSegregation['markerStr']);
  861.                     if (isset($dataSegregation['isWeek'])) {
  862.                         $startDtForThis = new \DateTime();
  863.                         $startDtForThis->setISODate($timeStampDt->format('Y'), $timeStampDt->format('W'));
  864.                     } else {
  865.                         $startDtForThis = new \DateTime($timeStampDt->format($dataSegregation['startTsFormat']));
  866.                     }
  867.                     $startDtForThis->setTimezone(new \DateTimeZone('+0000'));
  868.                     $startTsForThis $startDtForThis->format('U');
  869.                     if (!isset($segregatedData[$key2][$markerForThis]))
  870.                         $segregatedData[$key2][$markerForThis] = [
  871.                             'marker' => $markerForThis,
  872.                             'ts' => $startTsForThis,
  873.                             'data' => []
  874.                         ];
  875.                     if (!isset($segregatedData[$key2][$markerForThis]['data'][$identifier]))
  876.                         $segregatedData[$key2][$markerForThis]['data'][$identifier] = $defaultValues;
  877.                     $newValues $segregatedData[$key2][$markerForThis]['data'][$identifier];
  878.                     $segregatedData[$key2][$markerForThis]['data'][$identifier] = $this->updateEmsAggregateValues($newValues$numericValue);
  879.                     $segregatedDataByDeviceId[$deviceId] = $segregatedData;
  880.                 }
  881.             }
  882.         //nnow data are segregated now add them
  883.         foreach ($emsDataSegregation as $key2 => $dataSegregation) {
  884.             foreach ($segregatedDataByDeviceId as $deviceId => $segregatedData) {
  885.                 if (!isset($segregatedData[$key2]))
  886.                     $segregatedData[$key2] = [];
  887.                 foreach ($segregatedData[$key2] as $key3 => $dt) {
  888.                     $timeStampDt = new \DateTime('@' $dt['ts']);
  889.                     $timeStampDt->setTimezone(new \DateTimeZone('+0000'));
  890.                     $markerForThis $dt['marker'];
  891.                     $entry $this->getDoctrine()->getManager('company_group')
  892.                         ->getRepository('CompanyGroupBundle\\Entity\\' $dataSegregation['repository'])
  893.                         ->findOneBy(array(
  894.                             'marker' => $markerForThis,
  895.                             'siteId' => $siteId,
  896.                             'deviceId' => $deviceId
  897.                         ));
  898.                     $repoClassName "CompanyGroupBundle\\Entity\\" $dataSegregation['repository'];
  899.                     $hasEntry 1;
  900.                     if (!$entry) {
  901.                         $hasEntry 0;
  902.                         $entry = new $repoClassName();
  903.                         $entry->setTimeStamp($timeStampDt);
  904.                         $entry->setTimeStampTs($dt['ts']);
  905.                         $entry->setSiteId($siteId);
  906.                         $entry->setMarker($markerForThis);
  907.                         $entry->setDeviceId($deviceId);
  908.                     }
  909.                     $existingData json_decode($entry->getData(), true);
  910.                     if ($existingData == null$existingData = [];
  911. //                    $existingData=$segregatedDataByDeviceId; //temp
  912.                     foreach ($dt['data'] as $identifier => $newValues) {
  913.                         if (!is_array($newValues) || !isset($newValues[3]) || (int)$newValues[3] <= 0) {
  914.                             continue;
  915.                         }
  916.                         if (!isset($existingData[$identifier]) || !is_array($existingData[$identifier]))
  917.                             $existingData[$identifier] = $newValues;
  918.                         else {
  919.                             $existingData[$identifier] = $this->mergeEmsAggregateValues($existingData[$identifier], $newValues);
  920.                         }
  921.                     }
  922.                     $entry->setData(json_encode($existingData));
  923.                     if ($hasEntry == 0)
  924.                         $em_goc->persist($entry);
  925.                     $em_goc->flush();
  926.                 }
  927.             }
  928.         }
  929.         return new JsonResponse(array(
  930.             'success' => true,
  931.             'skipped_non_numeric_rollup' => $skippedNonNumeric,
  932.             'skipped_invalid_records' => $skippedInvalidRecords,
  933.         ));
  934.     }
  935.     public function DeviceDataEmsIngestActionLater(Request $request$id 0)
  936.     {
  937.         $em_goc $this->getDoctrine()->getManager('company_group');
  938.         $content $request->getContent(); // raw body string
  939.         $data json_decode($contenttrue); // decode JSON if needed
  940.         // Example: access fields
  941.         if ($data == null$data = [];
  942.         $siteId = (isset($data['siteId'])) ? $data['siteId'] : 0;
  943.         if (isset($data['records']))
  944.             foreach ($data['records'] as $key => $value) {
  945. //                $entry = $this->getDoctrine()->getManager('company_group')
  946. //                    ->getRepository("CompanyGroupBundle\\Entity\\DeviceSensorData")
  947. //                    ->findOneBy(array(
  948. //                        'recordId' => $value['record_id']
  949. //                    ));
  950.                 $entry null;
  951.                 $hasEntry 1;
  952.                 if (!$entry) {
  953.                     $hasEntry 0;
  954.                     $entry = new DeviceSensorData();
  955.                 }
  956.                 $timeStampDt = new \DateTime($value['timestamp']);
  957.                 $entry->setDeviceId($value['device_id']);
  958.                 $entry->setRecordId($value['record_id']);
  959.                 $entry->setSiteId($siteId);
  960.                 $entry->setAlias($value['alias']);
  961.                 $entry->setValue($value['value']);
  962.                 $entry->setIdentifier($value['identifier']);
  963.                 $entry->setTimeStamp($timeStampDt);
  964.                 $entry->setTimeStampTs($timeStampDt->format('U'));
  965.                 if ($hasEntry == 0)
  966.                     $em_goc->persist($entry);
  967.                 $em_goc->flush();
  968.             }
  969.         return new JsonResponse(array(
  970.             'success' => true,
  971.         ));
  972.     }
  973.     public function DeviceDataEmsGetAction(Request $request$id 0)
  974.     {
  975.         $em_goc $this->getDoctrine()->getManager('company_group');
  976.         $returnData = array(
  977.             'success' => false,
  978.             'dataList' => []
  979.         );
  980.         $getDatakeys = ['_BY_DAY_''_BY_HOUR_'];
  981.         $emsDataSegregation GeneralConstant::$emsDataSegregation;
  982.         foreach ($getDatakeys as $key2) {
  983.             $dataSegregation $emsDataSegregation[$key2];
  984.             if (!isset($returnData['dataList'][$key2]))
  985.                 $returnData['dataList'][$key2] = [];
  986.             $repoClassName $dataSegregation['repository'];
  987.             $dataQry $this->getDoctrine()->getManager('company_group')
  988.                 ->getRepository('CompanyGroupBundle\\Entity\\' $dataSegregation['repository'])
  989.                 ->createQueryBuilder('a')
  990.                 ->where('1=1');
  991.             if ($request->get('start_ts'0) != 0$dataQry->andWhere('a.timeStampTs >= ' $request->get('start_ts'0));
  992.             if ($request->get('end_ts'0) != 0$dataQry->andWhere('a.timeStampTs <= ' $request->get('end_ts'0));
  993.             if (!empty($request->get('device_ids', [])))
  994.                 $dataQry->andWhere('a.deviceId  in ( ' implode(','$request->get('device_ids', [])) . ' ) ');
  995.             if (!empty($request->get('identifiers', [])))
  996.                 $dataQry->andWhere('a.identifier  in ( ' implode(','$request->get('identifiers', [])) . ' ) ');
  997.             if (!empty($request->get('site_ids', [])))
  998.                 $dataQry->andWhere('a.siteId  in ( ' implode(','$request->get('site_ids', [])) . ' ) ');
  999.             $data $dataQry
  1000.                 ->setMaxResults(1000)
  1001.                 ->getQuery()
  1002.                 ->getResult();
  1003.             if (!empty($data))
  1004.                 $returnData['success'] = true;
  1005.             foreach ($data as $key => $entry) {
  1006.                 $value = array();
  1007.                 $timeStampDt $entry->getTimeStamp();
  1008.                 $timeStampDt->setTimezone(new \DateTimeZone('+0000'));
  1009.                 $existingData json_decode($entry->getData(), true);
  1010.                 if ($existingData == null$existingData = [];
  1011.                 foreach ($existingData as $identifier => $newValues) {
  1012.                     $value['device_id'] = $entry->getDeviceId();
  1013.                     $value['value'] = $newValues[2];
  1014.                     $value['identifier'] = $identifier;
  1015.                     $value['timestamp'] = $timeStampDt;
  1016.                     $value['timestamp_ts'] = $entry->getTimeStampTs();;
  1017.                     $returnData['dataList'][$key2][] = $value;
  1018.                 }
  1019.             }
  1020.         }
  1021.         return new JsonResponse($returnData);
  1022.     }
  1023.     public function UpdateCompanyGroupAction(Request $request$id 0)
  1024.     {
  1025.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  1026.         $appId $request->get('app_id'0);
  1027.         $post $request;
  1028.         $session $request->getSession();
  1029.         $d = array();
  1030.         if ($systemType == '_CENTRAL_') {
  1031.             $em_goc $this->getDoctrine()->getManager('company_group');
  1032.             $em_goc->getConnection()->connect();
  1033.             $connected $em_goc->getConnection()->isConnected();
  1034.             $gocDataList = [];
  1035.             if ($connected) {
  1036.                 $goc null;
  1037.                 $serverList MiscActions::getServerListById(
  1038.                     $this->container->getParameter('database_user'),
  1039.                     $this->container->getParameter('database_password'),
  1040.                     $this->container->hasParameter('server_access_list') ? $this->container->getParameter('server_access_list') : []
  1041.                 );
  1042.                 $companyGroupHash $post->get('company_short_code''');
  1043.                 $defaultUsageDate = new \DateTime();
  1044.                 $defaultUsageDate->modify('+1 year');
  1045.                 $usageValidUpto = new \DateTime($post->get('usage_valid_upto_dt_str'$defaultUsageDate->format('Y-m-d')));
  1046.                 $companyGroupServerId $post->get('server_id'1);
  1047.                 $companyGroupServerAddress $serverList[$companyGroupServerId]['absoluteUrl'];
  1048.                 $companyGroupServerPort $serverList[$companyGroupServerId]['port'];
  1049.                 $companyGroupServerHash $serverList[$companyGroupServerId]['serverMarker'];
  1050. //                $dbUser=
  1051.                 if ($appId != 0)
  1052.                     $goc $this->getDoctrine()->getManager('company_group')
  1053.                         ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1054.                         ->findOneBy(array(
  1055.                             'appId' => $appId
  1056.                         ));
  1057.                 if (!$goc)
  1058.                     $goc = new CompanyGroup();
  1059.                 if ($appId == 0) {
  1060.                     $biggestAppIdCg $this->getDoctrine()->getManager('company_group')
  1061.                         ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1062.                         ->findOneBy(array(//                            'appId' => $appId
  1063.                         ), array(
  1064.                             'appId' => 'desc'
  1065.                         ));
  1066.                     if ($biggestAppIdCg)
  1067.                         $appId $biggestAppIdCg->getAppId();
  1068.                 }
  1069.                 if ($post->get('company_name''') != '') {
  1070.                     $goc->setName($post->get('company_name'));
  1071.                     $goc->setCompanyGroupHash($companyGroupHash);
  1072.                     $goc->setAppId($appId);
  1073.                     $goc->setActive(1);
  1074.                     $goc->setAddress($post->get('address'));
  1075.                     $goc->setShippingAddress($post->get('s_address'));
  1076.                     $goc->setBillingAddress($post->get('b_address'));
  1077.                     $goc->setMotto($post->get('motto'));
  1078.                     $goc->setInitiateFlag($post->get('initiate_flag'2));
  1079.                     $goc->setInvoiceFooter($post->get('i_footer'));
  1080.                     $goc->setGeneralFooter($post->get('g_footer'));
  1081.                     $goc->setCompanyReg($post->get('company_reg'''));
  1082.                     $goc->setCompanyTin($post->get('company_tin'''));
  1083.                     $goc->setCompanyBin($post->get('company_bin'''));
  1084.                     $goc->setCompanyTl($post->get('company_tl'''));
  1085.                     $goc->setCompanyType($post->get('company_type'''));
  1086.                     $goc->setCurrentSubscriptionPackageId($post->get('package'1));
  1087.                     $goc->setUsageValidUptoDate($usageValidUpto);
  1088.                     $goc->setUsageValidUptoDateTs($usageValidUpto->format('U'));
  1089. //                $goc->setCu($post->get('package', ''));
  1090.                     $goc->setAdminUserAllowed($post->get('number_of_admin_user'''));
  1091.                     $goc->setUserAllowed($post->get('number_of_user'''));
  1092.                     $goc->setSubscriptionMonth($post->get('subscription_month'''));
  1093.                     $goc->setCompanyDescription($post->get('company_description'''));
  1094.                     $goc->setDbUser($post->get('db_user'));
  1095.                     $goc->setDbPass($post->get('db_pass'));
  1096.                     $goc->setDbHost($post->get('db_host'));
  1097.                     $goc->setOwnerId($session->get(UserConstants::USER_ID));
  1098.                     $goc->setCompanyGroupServerId($companyGroupServerId);
  1099.                     $goc->setCompanyGroupServerAddress($companyGroupServerAddress);
  1100.                     $goc->setCompanyGroupServerPort($companyGroupServerPort);
  1101.                     $goc->setCompanyGroupServerHash($companyGroupServerHash);
  1102.                     foreach ($request->files as $uploadedFile) {
  1103.                         if ($uploadedFile != null) {
  1104.                             $fileName 'company_image' $appId '.' $uploadedFile->guessExtension();
  1105.                             $path $fileName;
  1106.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/';
  1107.                             if ($goc->getImage() != null && $goc->getImage() != '' && file_exists($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage())) {
  1108.                                 unlink($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage());
  1109.                             }
  1110.                             if (!file_exists($upl_dir)) {
  1111.                                 mkdir($upl_dir0777true);
  1112.                             }
  1113.                             $file $uploadedFile->move($upl_dir$path);
  1114.                             if ($path != "")
  1115.                                 $goc->setImage('/uploads/CompanyImage/' $path);
  1116.                         }
  1117.                     }
  1118.                     $em_goc->persist($goc);
  1119.                     $em_goc->flush();
  1120.                     $goc->setDbName('cg_' $appId '_' $companyGroupHash);
  1121.                     $goc->setDbUser($serverList[$companyGroupServerId]['dbUser']);
  1122.                     $goc->setDbPass($serverList[$companyGroupServerId]['dbPass']);
  1123.                     $goc->setDbHost('localhost');
  1124.                     if ($post->get('enabled_module_id_list'null) !== null) {
  1125.                         $goc->setEnabledModuleIdList($post->get('enabled_module_id_list'''));
  1126.                     }
  1127.                     $em_goc->flush();
  1128.                     $centralUser $this->getDoctrine()->getManager('company_group')
  1129.                         ->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantDetails")
  1130.                         ->findOneBy(array(
  1131.                             'applicantId' => $session->get(UserConstants::USER_ID0)
  1132.                         ));
  1133.                     if ($centralUser) {
  1134.                         $userAppIds json_decode($centralUser->getUserAppIds(), true);
  1135.                         $userTypesByAppIds json_decode($centralUser->getUserTypesByAppIds(), true);
  1136.                         if ($userAppIds == null$userAppIds = [];
  1137.                         if ($userTypesByAppIds == null$userTypesByAppIds = [];
  1138.                         $userAppIds array_merge($userAppIdsarray_diff([$appId], $userAppIds));
  1139.                         if (!isset($userTypesByAppIds[$appId])) {
  1140.                             $userTypesByAppIds[$appId] = [];
  1141.                         }
  1142.                         $userTypesByAppIds[$appId] = array_merge($userTypesByAppIds[$appId], array_diff([UserConstants::USER_TYPE_SYSTEM], $userTypesByAppIds[$appId]));
  1143.                         $centralUser->setUserAppIds(json_encode($userAppIds));
  1144.                         $centralUser->setUserTypesByAppIds(json_encode($userTypesByAppIds));
  1145.                         $em_goc->flush();
  1146.                     }
  1147.                     $accessList $session->get('userAccessList', []);
  1148.                     $d = array(
  1149.                         'userType' => UserConstants::USER_TYPE_SYSTEM,
  1150.                         'globalId' => $session->get(UserConstants::USER_ID0),
  1151.                         'serverId' => $companyGroupServerId,
  1152.                         'serverUrl' => $companyGroupServerAddress,
  1153.                         'serverPort' => $companyGroupServerPort,
  1154.                         'systemType' => '_ERP_',
  1155.                         'companyId' => 1,
  1156.                         'appId' => $appId,
  1157.                         'companyLogoUrl' => $goc->getImage(),
  1158.                         'companyName' => $goc->getName(),
  1159.                         'authenticationStr' => $this->get('url_encryptor')->encrypt(json_encode(
  1160.                                 array(
  1161.                                     'globalId' => $session->get(UserConstants::USER_ID0),
  1162.                                     'appId' => $appId,
  1163.                                     'authenticate' => 1,
  1164.                                     'userType' => UserConstants::USER_TYPE_SYSTEM
  1165.                                 )
  1166.                             )
  1167.                         ),
  1168.                         'userCompanyList' => [
  1169.                         ]
  1170.                     );
  1171.                     $accessList[] = $d;
  1172.                     $session->set('userAccessList'$accessList);
  1173. //                    MiscActions::UpdateCompanyListInSession($em_goc, $centralUser->getApplicantId(), 1, 1, 1, $d);
  1174.                     //temporary solution
  1175.                     MiscActions::UpdateCompanyListInSession($em_goc$session->get(UserConstants::USER_ID), 111$d);
  1176.                 }
  1177.                 ///now update Server
  1178.                 ///
  1179.                 ///
  1180.                 if ($post->get('skipUpdateCompanyToErpServer''0') == 0) {
  1181.                     $response MiscActions::updateCompanyToErpServer($em_goc$goc->getAppId(), $this->container->getParameter('kernel.root_dir'));
  1182.                     if (isset($response['success']) && $response['success'] === true) {
  1183.                         return new JsonResponse(array(
  1184.                             'success' => true,
  1185.                             'message' => "Successfully Initialized The Company",
  1186.                             'data' => [],
  1187.                             'user_access_data' => $d,
  1188.                             'initiated' => 1,
  1189.                         ));
  1190.                     }
  1191.                 } else {
  1192.                     return new JsonResponse(array(
  1193.                         'success' => true,
  1194.                         'message' => "Successfully Initialized The Company",
  1195.                         'data' => [],
  1196.                         'user_access_data' => $d,
  1197.                         'initiated' => 1,
  1198.                     ));
  1199.                 }
  1200.             }
  1201.             return new JsonResponse(array(
  1202.                 'success' => false,
  1203.                 'message' => "Company Could not be Initialized or Updated",
  1204.                 'data' => [],
  1205.                 'user_access_data' => $d,
  1206.                 'initiated' => 0,
  1207.             ));
  1208.         } else {
  1209.             $em_goc $this->getDoctrine()->getManager('company_group');
  1210.             $findByQuery = array(
  1211. //                'active' => 1
  1212.                 'appId' => $post->get('app_id')
  1213.             );
  1214.             $goc $em_goc->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1215.                 ->findOneBy($findByQuery);
  1216.             if (!$goc)
  1217.                 $goc = new CompanyGroup();
  1218.             $goc->setName($post->get('company_name'));
  1219.             $goc->setCompanyGroupHash($post->get('companyGroupHash'));
  1220.             $goc->setAppId($post->get('app_id'));
  1221. //            $goc->setCompanyType($post->get('company_type'));
  1222.             $goc->setAddress($post->get('address'));
  1223. //            $goc->setDarkVibrant($post->get('dark_vibrant'));
  1224. //            $goc->setLightVibrant($post->get('light_vibrant'));
  1225. //            $goc->setVibrant($post->get('vibrant'));
  1226.             $goc->setDbName($post->get('db_name'));
  1227.             $goc->setDbUser($post->get('db_user'));
  1228.             $goc->setDbPass($post->get('db_pass'));
  1229.             $goc->setDbHost($post->get('db_host'));
  1230.             if ($post->get('enabled_module_id_list'null) !== null) {
  1231.                 $goc->setEnabledModuleIdList($post->get('enabled_module_id_list'''));
  1232.             }
  1233.             $goc->setActive(1);
  1234.             $goc->setShippingAddress($post->get('s_address'));
  1235.             $goc->setBillingAddress($post->get('b_address'));
  1236.             $goc->setMotto($post->get('motto'));
  1237.             $goc->setInvoiceFooter($post->get('i_footer'));
  1238.             $goc->setGeneralFooter($post->get('g_footer'));
  1239.             $goc->setCompanyReg($post->get('company_reg'''));
  1240.             $goc->setCompanyTin($post->get('company_tin'''));
  1241.             $goc->setCompanyBin($post->get('company_bin'''));
  1242.             $goc->setCompanyTl($post->get('company_tl'''));
  1243.             $goc->setCompanyType($post->get('company_type'''));
  1244.             $goc->setActive((int)$post->get('active'1));
  1245.             $goc->setReadOnlyMode((int)$post->get('read_only_mode'0));
  1246.             $goc->setCompanyStatus($post->get('company_status''active'));
  1247.             $goc->setPackageType($post->get('package_type'''));
  1248.             $goc->setCurrentSubscriptionPackageId($post->get('current_subscription_package_id'$post->get('package''')));
  1249. //                $goc->setCu($post->get('package', ''));
  1250.             $goc->setAdminUserAllowed($post->get('number_of_admin_user'''));
  1251.             $goc->setUserAllowed($post->get('number_of_user'''));
  1252.             $goc->setSubscriptionMonth($post->get('subscription_month'''));
  1253.             $goc->setBillingAmount($post->get('billing_amount'''));
  1254.             $goc->setCompanyDescription($post->get('company_description'''));
  1255.             if ($post->get('subscription_expiry_dt_str''') !== '') {
  1256.                 $goc->setSubscriptionExpiry(new \DateTime($post->get('subscription_expiry_dt_str')));
  1257.             }
  1258.             $goc->setCompanyGroupServerId($post->get('companyGroupServerId'''));
  1259.             $goc->setCompanyGroupServerAddress($post->get('companyGroupServerAddress'''));
  1260.             $goc->setCompanyGroupServerPort($post->get('companyGroupServerPort'''));
  1261.             $goc->setCompanyGroupServerHash($post->get('companyGroupServerHash'''));
  1262.             if ($post->get('enabled_module_id_list'null) !== null) {
  1263.                 $goc->setEnabledModuleIdList($post->get('enabled_module_id_list'''));
  1264.             }
  1265. //            $goc->setSmsNotificationEnabled($post->get('sms_enabled'));
  1266. //            $goc->setSmsSettings($post->get('sms_settings'));
  1267.             foreach ($request->files as $uploadedFile) {
  1268. //            if($uploadedFile->getImage())
  1269. //                var_dump($uploadedFile->getFile());
  1270. //                var_dump($uploadedFile);
  1271.                 if ($uploadedFile != null) {
  1272.                     $fileName 'company_image' $post->get('app_id') . '.' $uploadedFile->guessExtension();
  1273.                     $path $fileName;
  1274.                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/';
  1275.                     if ($goc->getImage() != null && $goc->getImage() != '' && file_exists($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage())) {
  1276.                         unlink($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage());
  1277.                     }
  1278.                     if (!file_exists($upl_dir)) {
  1279.                         mkdir($upl_dir0777true);
  1280.                     }
  1281.                     $file $uploadedFile->move($upl_dir$path);
  1282.                     if ($path != "")
  1283.                         $goc->setImage('/uploads/CompanyImage/' $path);
  1284.                 }
  1285.             }
  1286.             $em_goc->persist($goc);
  1287.             $em_goc->flush();
  1288.             $connector $this->container->get('application_connector');
  1289.             $connector->resetConnection(
  1290.                 'default',
  1291.                 $goc->getDbName(),
  1292.                 $goc->getDbUser(),
  1293.                 $goc->getDbPass(),
  1294.                 $goc->getDbHost(),
  1295.                 $reset true);
  1296.             $em $this->getDoctrine()->getManager();
  1297.             $prePopulateFlag 0;
  1298.             if ($em->getConnection()->isConnected()) {
  1299.             } else {
  1300.                 $servername $goc->getDbHost();
  1301.                 $username $goc->getDbUser();
  1302.                 $password $goc->getDbPass();
  1303.                 // Create connection
  1304.                 $conn = new \mysqli($servername$username$password);
  1305.                 // Check connection
  1306.                 if ($conn->connect_error) {
  1307.                     die("Connection failed: " $conn->connect_error);
  1308.                 }
  1309.                 // Create database
  1310.                 $sql "CREATE DATABASE " $goc->getDbName();
  1311.                 if ($conn->query($sql) === TRUE) {
  1312.                     $prePopulateFlag 1;
  1313.                     //                                echo "Database created successfully";
  1314.                 } else {
  1315.                     //                                echo "Error creating database: " . $conn->error;
  1316.                 }
  1317.                 $conn->close();
  1318.             }
  1319.             $connector->resetConnection(
  1320.                 'default',
  1321.                 $goc->getDbName(),
  1322.                 $goc->getDbUser(),
  1323.                 $goc->getDbPass(),
  1324.                 $goc->getDbHost(),
  1325.                 $reset true);
  1326.             $em $this->getDoctrine()->getManager();
  1327.             $tool = new SchemaTool($em);
  1328.             $classes $em->getMetadataFactory()->getAllMetadata();
  1329. //                    $tool->createSchema($classes);
  1330.             $tool->updateSchema($classes);
  1331.             if ($prePopulateFlag == 1) {
  1332.                 System::prePopulateDatabase($em);
  1333.             }
  1334.             //now modify the company
  1335.             $company $em
  1336.                 ->getRepository('ApplicationBundle\\Entity\\Company')
  1337.                 ->findOneBy(
  1338.                     array()
  1339.                 );
  1340.             if (!$company)
  1341.                 $company = new Company();
  1342.             $company->setImage($goc->getImage());
  1343.             $company->setName($post->get('company_name'));
  1344.             $company->setCompanyHash($post->get('company_short_code'));
  1345.             $company->setAppId($post->get('app_id'));
  1346.             $company->setActive((int)$post->get('active'1));
  1347.             $company->setAddress($post->get('address'));
  1348. //            $company->setAddress("xyz");
  1349.             $company->setShippingAddress($post->get('s_address'));
  1350. //            $company->setShippingAddress("abc");
  1351.             $company->setBillingAddress($post->get('b_address'));
  1352.             $company->setMotto($post->get('motto'));
  1353.             $company->setInvoiceFooter($post->get('i_footer'));
  1354.             $company->setGeneralFooter($post->get('g_footer'));
  1355.             $company->setCompanyReg($post->get('company_reg'''));
  1356.             $company->setCompanyTin($post->get('company_tin'''));
  1357.             $company->setCompanyBin($post->get('company_bin'''));
  1358.             $company->setCompanyTl($post->get('company_tl'''));
  1359.             $company->setCompanyType($post->get('company_type'''));
  1360.             $company->setAdminUserAllowed($post->get('number_of_admin_user'''));
  1361.             $company->setUserAllowed($post->get('number_of_user'''));
  1362.             $company->setCompanyHash($post->get('companyGroupHash'''));
  1363.             //new fields
  1364.             if ($post->get('usage_valid_upto_dt_str'null) != null) {
  1365.                 $usageValidUpto = new \DateTime($post->get('usage_valid_upto_dt_str'null));
  1366.                 $company->setUsageValidUptoDate($usageValidUpto);
  1367.                 $company->setUsageValidUptoDateTs($usageValidUpto->format('U'));
  1368.             } else {
  1369.                 $company->setUsageValidUptoDate(null);
  1370.                 $company->setUsageValidUptoDateTs(0);
  1371.             }
  1372.             $em->persist($company);
  1373.             $em->flush();
  1374.             //initiate Admin
  1375. //            $userName = $request->request->get('username', $request->query->get('username', 'admin'));
  1376. //            $name = $request->request->get('name', $request->query->get('name', 'System Admin'));
  1377. //            $password = $request->request->get('password', $request->query->get('password', 'admin'));
  1378. //            $email = $request->request->get('email', $request->query->get('email', 'admin'));
  1379. //            $encodedPassword = $this->container->get('sha256salted_encoder')->encodePassword($password, $userName);
  1380. //            $companyIds = $request->request->get('companyIds', $request->query->get('companyIds', [1]));
  1381. //            $branchIds = $request->request->get('branchIds', $request->query->get('branchIds', []));
  1382. //            $appIds = $request->request->get('appIds', $request->query->get('appIds', [$post->get('app_id', 0)]));
  1383. //            $freshFlag = $request->request->get('fresh', $request->query->get('fresh', 0));
  1384. //
  1385. //
  1386. //            $message = $this->get('user_module')->addNewUser(
  1387. //                $name,
  1388. //                $email,
  1389. //                $userName,
  1390. //                $password,
  1391. //                '',
  1392. //                0,
  1393. //                1,
  1394. //                UserConstants::USER_TYPE_SYSTEM,
  1395. //                $companyIds,
  1396. //                $branchIds,
  1397. //                '',
  1398. //                "",
  1399. //                1
  1400. //
  1401. //            );
  1402.             if ($company->getAppId()) {
  1403. //                $returnData['message']='';
  1404.                 return new JsonResponse(array(
  1405.                     'success' => true,
  1406.                     'message' => "Successfully Initialized The Company",
  1407.                     'data' => [],
  1408.                     'user_access_data' => $d,
  1409.                     'initiated' => 1,
  1410.                     'app_id' => $company->getAppId(),
  1411.                 ));
  1412.             }
  1413. //            return new JsonResponse($post_fields);
  1414.         }
  1415.         return new JsonResponse(array(
  1416.             'success' => false,
  1417.             'message' => "Company Could not be Initialized or Updated",
  1418.             'data' => [],
  1419.             'user_access_data' => $d,
  1420.             'initiated' => 0,
  1421.             'app_id' => 0
  1422.         ));
  1423.     }
  1424.     public function GenerateErpSubscriptionAction(Request $request$id 0)
  1425.     {
  1426.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  1427.         $appId $request->get('app_id'0);
  1428.         $userNo $request->get('user_no'0);
  1429.         $adminNo $request->get('admin_no'0);
  1430.         $post $request;
  1431.         $session $request->getSession();
  1432.         $d = array();
  1433.         $returnData = array(
  1434.             "invoiceAmount" => 0,
  1435.             "dueAmount" => 0,
  1436.             "invoiceId" => 0,
  1437.             "isPaid" => 1,
  1438.         );
  1439.         if ($systemType == '_CENTRAL_') {
  1440.             $em_goc $this->getDoctrine()->getManager('company_group');
  1441.             $em_goc->getConnection()->connect();
  1442.             $connected $em_goc->getConnection()->isConnected();
  1443.             $gocDataList = [];
  1444.             if ($connected) {
  1445.                 $goc null;
  1446.                 $serverList MiscActions::getServerListById(
  1447.                     $this->container->getParameter('database_user'),
  1448.                     $this->container->getParameter('database_password'),
  1449.                     $this->container->hasParameter('server_access_list') ? $this->container->getParameter('server_access_list') : []
  1450.                 );
  1451.                 $companyGroupHash $post->get('company_short_code''');
  1452.                 $defaultUsageDate = new \DateTime();
  1453.                 $defaultUsageDate->modify('+1 year');
  1454.                 $usageValidUpto = new \DateTime($post->get('usage_valid_upto_dt_str'$defaultUsageDate->format('Y-m-d')));
  1455.                 $companyGroupServerId $post->get('server_id'1);
  1456.                 $companyGroupServerAddress $serverList[$companyGroupServerId]['absoluteUrl'];
  1457.                 $companyGroupServerPort $serverList[$companyGroupServerId]['port'];
  1458.                 $companyGroupServerHash $serverList[$companyGroupServerId]['serverMarker'];
  1459. //                $dbUser=
  1460.                 if ($appId != 0)
  1461.                     $goc $this->getDoctrine()->getManager('company_group')
  1462.                         ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1463.                         ->findOneBy(array(
  1464.                             'appId' => $appId
  1465.                         ));
  1466.                 if (!$goc)
  1467.                     $goc = new CompanyGroup();
  1468.                 $userNo $goc->getUserAllowed();
  1469.                 $adminNo $goc->getAdminUserAllowed();
  1470.                 //calculate usage here
  1471.                 $returnData MiscActions::getInvoiceableAmountErpSubscription(GeneralConstant::$packageDetails$userNo$adminNo$goc->getCompanyGroupBillingFrequency() == 'yearly' 'monthly');
  1472.                 $goc->setUserAllowed($returnData['noOfUser']);
  1473.                 $goc->setAdminUserAllowed($returnData['noOfAdmin']);
  1474.                 if ($returnData['dueAmount'] <= 0) {
  1475.                     if ($goc->getInitiateFlag() != 1) {
  1476.                         $goc->setInitiateFlag(2);
  1477.                     }
  1478.                 }
  1479.                 $em_goc->flush();
  1480.                 //if not covered by packages , temprarily grand free access if available . meanwhile alert sales
  1481.             }
  1482.         }
  1483.         return new JsonResponse($returnData);
  1484.     }
  1485.     public function SyncCompanyGroupToErpServerAction(Request $request$id 0)
  1486.     {
  1487.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  1488.         $appId $request->get('app_id'0);
  1489.         $post $request;
  1490.         $session $request->getSession();
  1491.         $d = array();
  1492.         if ($systemType == '_CENTRAL_') {
  1493.             $em_goc $this->getDoctrine()->getManager('company_group');
  1494.             $em_goc->getConnection()->connect();
  1495.             $connected $em_goc->getConnection()->isConnected();
  1496.             $gocDataList = [];
  1497.             if ($connected) {
  1498.                 $goc null;
  1499.                 $serverList MiscActions::getServerListById(
  1500.                     $this->container->getParameter('database_user'),
  1501.                     $this->container->getParameter('database_password'),
  1502.                     $this->container->hasParameter('server_access_list') ? $this->container->getParameter('server_access_list') : []
  1503.                 );
  1504.                 $companyGroupHash $post->get('company_short_code''');
  1505.                 $defaultUsageDate = new \DateTime();
  1506.                 $defaultUsageDate->modify('+1 year');
  1507.                 $usageValidUpto = new \DateTime($post->get('usage_valid_upto_dt_str'$defaultUsageDate->format('Y-m-d')));
  1508.                 $companyGroupServerId $post->get('server_id'1);
  1509.                 $companyGroupServerAddress $serverList[$companyGroupServerId]['absoluteUrl'];
  1510.                 $companyGroupServerPort $serverList[$companyGroupServerId]['port'];
  1511.                 $companyGroupServerHash $serverList[$companyGroupServerId]['serverMarker'];
  1512. //                $dbUser=
  1513.                 if ($appId != 0)
  1514.                     $goc $this->getDoctrine()->getManager('company_group')
  1515.                         ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1516.                         ->findOneBy(array(
  1517.                             'appId' => $appId
  1518.                         ));
  1519.                 if (!$goc)
  1520.                     $goc = new CompanyGroup();
  1521.                 if ($appId == 0) {
  1522.                     $biggestAppIdCg $this->getDoctrine()->getManager('company_group')
  1523.                         ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1524.                         ->findOneBy(array(//                            'appId' => $appId
  1525.                         ), array(
  1526.                             'appId' => 'desc'
  1527.                         ));
  1528.                     if ($biggestAppIdCg)
  1529.                         $appId $biggestAppIdCg->getAppId();
  1530.                 }
  1531.                 if ($goc->getInitiateFlag() == || $goc->getInitiateFlag() == 2) {
  1532.                     $response MiscActions::updateCompanyToErpServer($em_goc$goc->getAppId(), $this->container->getParameter('kernel.root_dir'));
  1533.                     if (isset($response['success']) && $response['success'] === true) {
  1534.                         $goc->setInitiateFlag(1);
  1535.                         $em_goc->persist($goc);
  1536.                         $em_goc->flush();
  1537.                         return new JsonResponse(array(
  1538.                             'success' => true,
  1539.                             'message' => "Successfully Initialized The Company On Erp Server",
  1540.                             'data' => [],
  1541.                             'user_access_data' => $d,
  1542.                             'initiated' => 1,
  1543.                         ));
  1544.                     }
  1545.                 }
  1546.             }
  1547.             return new JsonResponse(array(
  1548.                 'success' => false,
  1549.                 'message' => "Company Could not be Initialized or Updated",
  1550.                 'data' => [],
  1551.                 'user_access_data' => $d,
  1552.                 'initiated' => 0,
  1553.             ));
  1554.         }
  1555.         return new JsonResponse(array(
  1556.             'success' => false,
  1557.             'message' => "Company Could not be Initialized or Updated",
  1558.             'data' => [],
  1559.             'user_access_data' => $d,
  1560.             'initiated' => 0,
  1561.             'app_id' => 0
  1562.         ));
  1563.     }
  1564.     //update database schema
  1565.     public function RunScheduledNotificationAction(Request $request)
  1566.     {
  1567.         $message "";
  1568.         $gocList = [];
  1569.         $outputList = [];
  1570.         $scheduler $this->get('scheduler_service');
  1571.         $connector $this->get('application_connector');
  1572.         $mail_module $this->get('mail_module');
  1573.         $gocEnabled 1;
  1574. //        if($this->getContainer()->hasParameter('entity_group_enabled'))
  1575. //            $gocEnabled= $this->getContainer()->getParameter('entity_group_enabled');
  1576. //        $to_print=$app_data->UpdatePostDatedTransaction();
  1577. //        $output->writeln($to_print);
  1578.         $to_print $scheduler->checkAndSendScheduledNotification($connector$gocEnabled0$mail_module);
  1579.         return new JsonResponse(array(
  1580.             'to_print' => $to_print
  1581.         ));
  1582.     }
  1583.     /**
  1584.      * HTTP-cron trigger for the billing schedule engine - same pattern as
  1585.      * run_scheduled_notification. Hit /run_billing_schedule_check periodically
  1586.      * (e.g. hourly) so milestone/day-based billing schedules generate invoices.
  1587.      * Pass ?dry_run=1 to evaluate without creating invoices.
  1588.      */
  1589.     public function RunBillingScheduleCheckAction(Request $request)
  1590.     {
  1591.         $kernel $this->get('kernel');
  1592.         $application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
  1593.         $application->setAutoExit(false);
  1594.         $inputArgs = ['command' => 'inno:billing-schedule-check'];
  1595.         if ($request->query->get('dry_run'0)) {
  1596.             $inputArgs['--dry-run'] = true;
  1597.         }
  1598.         $input = new \Symfony\Component\Console\Input\ArrayInput($inputArgs);
  1599.         $output = new \Symfony\Component\Console\Output\BufferedOutput();
  1600.         $exitCode $application->run($input$output);
  1601.         return new JsonResponse(array(
  1602.             'success' => $exitCode === 0,
  1603.             'exit_code' => $exitCode,
  1604.             'output' => $output->fetch(),
  1605.         ));
  1606.     }
  1607.     public function UpdateDatabaseSchemaAction(Request $request)
  1608.     {
  1609.         // L3 (S-2) — the CLI orchestrator `inno:fleet-migrate` is now the safe path (lock, canary,
  1610.         // staged rollout, per-tenant version tracking). Refuse this legacy web loop while the
  1611.         // orchestrator holds the fleet lock so the two can NEVER migrate the fleet concurrently.
  1612.         try {
  1613.             $fleetConn $this->getDoctrine()->getManager('company_group')->getConnection();
  1614.             if (\ApplicationBundle\TimeService\SchedulerLockService::isHeld($fleetConn'fleet-migrate')) {
  1615.                 $msg 'A CLI fleet migration (inno:fleet-migrate) is currently running. The web schema updater is disabled until it finishes.';
  1616.                 if ($request->query->get('returnJson'0) == 1) {
  1617.                     return new \Symfony\Component\HttpFoundation\JsonResponse(array('success' => false'message' => $msg), 423);
  1618.                 }
  1619.                 return new \Symfony\Component\HttpFoundation\Response($msg423);
  1620.             }
  1621.         } catch (\Throwable $e) {
  1622.             // central registry unreachable — fall through to the legacy behaviour unchanged
  1623.         }
  1624.         $dtHere = array(
  1625.             'autoStartUpdateHit' => $request->query->get('autoStartUpdateHit'0),
  1626.             'page_title' => 'Server Actions',
  1627.         );
  1628.         if ($request->query->get('returnJson'0) == 1) {
  1629.             $message "";
  1630.             $gocList = [];
  1631.             $outputList = [];
  1632.             $configJson = array();
  1633.             $configJson['appVersion'] = GeneralConstant::ENTITY_APP_VERSION;
  1634.             $configJson['success'] = false;
  1635.             $configJson['debugData'] = [];
  1636.             $configJson['pending_doc_count'] = 0;
  1637.             $configJson['initiateDataBaseFlagByGoc'] = array();
  1638.             $configJson['motherLode'] = "http://erp.ourhoneybee.eu";
  1639.             $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  1640.             $thisMomentNow = new \DateTime();
  1641.             $currTimeTs $thisMomentNow->format('U');
  1642.             $em $this->getDoctrine()->getManager('company_group');
  1643.             $em_local_default $this->getDoctrine()->getManager();
  1644.             $em_goc $this->getDoctrine()->getManager('company_group');
  1645.             $em->getConnection()->connect();
  1646.             $connected $em->getConnection()->isConnected();
  1647.             $serverId $this->container->hasParameter('server_id') ? $this->container->getParameter('server_id') : '_ALL_';
  1648.             if ($connected) {
  1649.                 if ($request->query->get('prepareEntityGroup'0) == 1) {
  1650.                     $tool = new SchemaTool($em);
  1651.                     $classes $em->getMetadataFactory()->getAllMetadata();
  1652. //                    $tool->createSchema($classes);
  1653.                     $tool->updateSchema($classes);
  1654.                     $em_local_default->getConnection()->connect();
  1655.                     $em_local_default_connected $em_local_default->getConnection()->isConnected();
  1656.                     if ($em_local_default_connected) {
  1657.                         $tool = new SchemaTool($em_local_default);
  1658.                         $classes $em_local_default->getMetadataFactory()->getAllMetadata();
  1659. //                    $tool->createSchema($classes);
  1660.                         $tool->updateSchema($classes);
  1661.                     }
  1662.                     if ($request->query->get('fixEmptyPassword'0) == 1) {
  1663.                         $query "SELECT * from  entity_applicant_details   where password not like '##UNLOCKED##'";
  1664.                         $stmt $em_goc->getConnection()->fetchAllAssociative($query);
  1665.                         $results $stmt;
  1666.                         foreach ($results as $qpo) {
  1667.                             if ($this->container->get('app.legacy_password_service')->verifyWithSalt($qpo['password'], ''$qpo['salt'])
  1668.                                 || $this->container->get('app.legacy_password_service')->verifyWithSalt($qpo['password'], null$qpo['salt'])
  1669.                             ) {
  1670.                                 $queryGG "update entity_applicant_details set password ='##UNLOCKED##' and trigger_reset_password=1 where applicant_id=" $qpo['applicant_id'];
  1671.                                 $stmt $em_goc->getConnection()->executeStatement($queryGG);
  1672.                             }
  1673.                         }
  1674.                     }
  1675.                     if ($request->query->get('triggerReferScore'0) == 1) {
  1676.                         $query "SELECT * from  entity_meeting_session   where booked_by_id !=0 and booked_by_id is not NULL and booked_by_id !=student_id";
  1677.                         $stmt $em_goc->getConnection()->fetchAllAssociative($query);
  1678.                         $results $stmt;
  1679.                         foreach ($results as $qpo) {
  1680.                             MiscActions::updateEntityPerformanceIndex($em_goc, [
  1681.                                 'targetId' => $qpo['booked_by_id'],
  1682.                                 'conversionData' => [
  1683.                                     'count' => 1,
  1684.                                     'score' => 10,
  1685.                                 ]
  1686.                             ],
  1687.                                 new \DateTime($qpo['created_at']));
  1688.                         }
  1689.                         $query "SELECT * from  entity_meeting_session   where booking_referer_id !=0 and booking_referer_id is not NULL and booking_referer_id !=student_id";
  1690.                         $stmt $em_goc->getConnection()->fetchAllAssociative($query);
  1691.                         $results $stmt;
  1692.                         foreach ($results as $qpo) {
  1693.                             MiscActions::updateEntityPerformanceIndex($em_goc, [
  1694.                                 'targetId' => $qpo['booking_referer_id'],
  1695.                                 'referData' => [
  1696.                                     'count' => 1,
  1697.                                     'score' => 10,
  1698.                                 ]
  1699.                             ],
  1700.                                 new \DateTime($qpo['created_at'])
  1701.                             );
  1702.                         }
  1703.                     }
  1704.                     if ($request->query->get('refreshBuddyBeeSalt'0) == 1) {
  1705.                         $query "
  1706.                         UPDATE entity_applicant_details set temp_password=''  where 1;
  1707.                         UPDATE entity_applicant_details set salt=username  where username != '' and username is not NULL and (salt ='' or salt is  NULL);
  1708.                         UPDATE entity_applicant_details set salt='beesalt'  where (salt ='' or salt is  NULL) and (username ='' or username is  NULL);
  1709.                       ";
  1710.                         $stmt $em_goc->getConnection()->executeStatement($query);
  1711.                     }
  1712.                     if ($request->query->get('refreshLastSettingsUpdatedTs'0) == 1) {
  1713.                         $query "
  1714.               
  1715.                         UPDATE entity_user set last_settings_updated_ts=$currTimeTs  where 1;
  1716.                         UPDATE entity_applicant_details set last_settings_updated_ts=$currTimeTs  where 1;
  1717.                      
  1718.                       ";
  1719.                         $stmt $em_goc->getConnection()->executeStatement($query);
  1720.                     }
  1721.                     // Only queue rows that actually have a DB to migrate. A "null tenant"
  1722.                     // (registry row with no db_name/db_user) can never be schema-updated, and if
  1723.                     // it were flagged pending the front-end poll would re-pick it forever (its
  1724.                     // flag is only cleared after a successful connection) — infinite reload.
  1725.                     $get_kids_sql "update `company_group` set `schema_update_pending_flag` =1 "
  1726.                         "where `active`=1 and `db_name` is not null and `db_name` <> '' "
  1727.                         "and `db_user` is not null and `db_user` <> '';";
  1728.                     $stmt $em_goc->getConnection()->executeStatement($get_kids_sql);
  1729.                     // Belt-and-suspenders: clear any stale flag left on DB-less rows so a
  1730.                     // previously-stuck null tenant can't keep the poller looping.
  1731.                     $em_goc->getConnection()->executeStatement(
  1732.                         "update `company_group` set `schema_update_pending_flag` =0 "
  1733.                         "where `db_name` is null or `db_name` = '' or `db_user` is null or `db_user` = '';"
  1734.                     );
  1735.                     $stmt $em_goc->getConnection()->fetchAllAssociative("select count(id) id_count from company_group where active=1 and schema_update_pending_flag=1;");
  1736. //                    
  1737.                     $check_here $stmt;
  1738.                     $pending_id_count 0;
  1739.                     if (isset($check_here[0]))
  1740.                         $pending_id_count $check_here[0]['id_count'];
  1741.                     return new JsonResponse(array(
  1742.                         'pending_doc_count' => $pending_id_count,
  1743.                         'success' => true
  1744.                     ));
  1745.                 } else
  1746.                     if ($systemType != '_CENTRAL_') {
  1747.                         $stmt $em_goc->getConnection()->fetchAllAssociative("select count(id) id_count from company_group where active=1 and schema_update_pending_flag=1;");
  1748. //                        
  1749.                         $check_here $stmt;
  1750.                         if (isset($check_here[0]))
  1751.                             $configJson['pending_doc_count'] = $check_here[0]['id_count'];
  1752. //                        if($serverId!='_ALL_')
  1753.                         $gocList $this->getDoctrine()->getManager('company_group')
  1754.                             ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  1755.                             ->findBy(
  1756.                                 array(
  1757.                                     'active' => 1,
  1758. //                                    'serverId' => 1,
  1759.                                     'schemaUpdatePendingFlag' => 1
  1760.                                 ), array(), 1
  1761.                             );
  1762.                     }
  1763.             }
  1764.             $gocDataList = [];
  1765.             $gocEntryObjectList = [];
  1766.             foreach ($gocList as $entry) {
  1767.                 $d = array(
  1768.                     'name' => $entry->getName(),
  1769.                     'image' => $entry->getImage(),
  1770.                     'shippingAddress' => $entry->getShippingAddress(),
  1771.                     'billingAddress' => $entry->getBillingAddress(),
  1772.                     'id' => $entry->getId(),
  1773.                     'dbName' => $entry->getDbName(),
  1774.                     'dbUser' => $entry->getDbUser(),
  1775.                     'dbPass' => $entry->getDbPass(),
  1776.                     'dbHost' => $entry->getDbHost(),
  1777.                     'appId' => $entry->getAppId(),
  1778.                     'companyRemaining' => $entry->getCompanyRemaining(),
  1779.                     'companyAllowed' => $entry->getCompanyAllowed(),
  1780.                 );
  1781.                 $gocDataList[$entry->getId()] = $d;
  1782.                 $gocEntryObjectList[$entry->getId()] = $entry;
  1783.             }
  1784.             $gocDbName '';
  1785.             $gocDbUser '';
  1786.             $gocDbPass '';
  1787.             $gocDbHost '';
  1788.             $gocId 0;
  1789.             foreach ($gocDataList as $gocId => $entry) {
  1790.                 // Guard against "null tenants" (registry rows with no DB config). resetConnection
  1791.                 // throws on an empty db_name, and even if it didn't the row could never connect —
  1792.                 // either way its pending flag would never clear and the poller would loop. Clear
  1793.                 // the flag and skip so the update run can move on / finish.
  1794.                 if (empty($entry['dbName']) || empty($entry['dbUser'])) {
  1795.                     try {
  1796.                         $em_goc->getConnection()->executeStatement(
  1797.                             "update `company_group` set `schema_update_pending_flag` =0 where `id`=" . (int) $gocId
  1798.                         );
  1799.                     } catch (\Throwable $e) {
  1800.                         // never let flag-clearing failure abort the whole run
  1801.                     }
  1802.                     continue;
  1803.                 }
  1804.                 $connector $this->container->get('application_connector');
  1805.                 $connector->resetConnection(
  1806.                     'default',
  1807.                     $gocDataList[$gocId]['dbName'],
  1808.                     $gocDataList[$gocId]['dbUser'],
  1809.                     $gocDataList[$gocId]['dbPass'],
  1810.                     $gocDataList[$gocId]['dbHost'],
  1811.                     $reset true);
  1812.                 $em $this->getDoctrine()->getManager();
  1813.                 $em->getConnection()->connect();
  1814.                 $indConnected $em->getConnection()->isConnected();
  1815.                 if ($indConnected) {
  1816.                     $configJson['name'] = $entry['name'];
  1817.                     $configJson['image'] = $entry['image'];
  1818.                     $configJson['appId'] = $entry['appId'];
  1819.                     if ($request->query->get('delTable''') != '') {
  1820.                         $get_kids_sql "DROP TABLE " $request->query->get('delTable') . "  ;";
  1821.                         $stmt $em->getConnection()->executeStatement($get_kids_sql);
  1822.                     }
  1823.                     $tool = new SchemaTool($em);
  1824.                     $classes $em->getMetadataFactory()->getAllMetadata();
  1825. //                    $tool->createSchema($classes);
  1826.                     $tool->updateSchema($classes);
  1827.                     //temp
  1828.                     //temp end
  1829.                     if ($request->query->get('refreshLastSettingsUpdatedTs'0) == 1) {
  1830.                         $query "
  1831.                                     UPDATE sys_user set last_settings_updated_ts=$currTimeTs  where 1;
  1832.                                     UPDATE acc_clients set last_settings_updated_ts=$currTimeTs  where 1;
  1833.                                     UPDATE acc_suppliers set last_settings_updated_ts=$currTimeTs  where 1;
  1834.                      
  1835.                       ";
  1836.                         $stmt $em->getConnection()->executeStatement($query);
  1837.                     }
  1838.                     if ($request->query->get('optimizeJunkAttendanceTable'0) == 1) {
  1839.                         $query "
  1840.                                     OPTIMIZE TABLE employee_attendance_log;
  1841.                      
  1842.                       ";
  1843.                         $stmt $em->getConnection()->executeStatement($query);
  1844.                     }
  1845.                     if ($request->query->get('encryptTrans'0) == 1) {
  1846.                         MiscActions::encryptTrans($em'_ALL_'0);
  1847.                     }
  1848.                     if ($request->query->get('decryptTrans'0) == 1) {
  1849.                         MiscActions::decryptTrans($em'_ALL_'0);
  1850.                     }
  1851.                     if ($request->query->get('createdByRefresh'0) == 1) {
  1852.                         foreach (GeneralConstant::$Entity_list as $entity => $entityName) {
  1853.                             if (in_array($entity, [54]))
  1854.                                 continue;
  1855.                             if (!$em->getMetadataFactory()->isTransient('ApplicationBundle\\Entity\\' $entityName)) {
  1856. //                                $className = ('\\ApplicationBundle\\Entity\\') . $entityName;
  1857. //                                $theEntity = new $className();
  1858. //                                $test_now=$theEntity->getCreatedUserId();
  1859.                                 //if its approval decode signature and add it to dbase and pass the id
  1860.                                 $sigId null;
  1861.                                 $doc null;
  1862.                                 $docList $em->getRepository('ApplicationBundle\\Entity\\' $entityName)
  1863.                                     ->findBy(
  1864.                                         array(//                                        GeneralConstant::$Entity_id_field_list[$entity] => $entity_id,
  1865.                                         )
  1866.                                     );
  1867.                                 foreach ($docList as $doc) {
  1868.                                     $notYetAdded 1;
  1869.                                     foreach ([12] as $approveRole) {
  1870.                                         $getIdfunc GeneralConstant::$Entity_id_get_method_list[$entity];
  1871.                                         $entity_id $doc->$getIdfunc();
  1872.                                         $loginId null;
  1873.                                         $sigId null;
  1874.                                         $user_data = [];
  1875.                                         if ($approveRole == 1//created
  1876.                                         {
  1877.                                             $loginId $doc->getCreatedLoginId();
  1878.                                             $notYetAdded $doc->getCreatedUserId() == null 0;
  1879.                                             $sigId $doc->getCreatedSigId();
  1880.                                             $user_data Users::getUserInfoByLoginId($em$loginId);
  1881.                                             if (isset($user_data['id'])) {
  1882.                                                 $doc->setCreatedUserId($user_data['id']);
  1883.                                                 $doc->setCreatedSigId(null);
  1884.                                             }
  1885.                                             $em->flush();
  1886.                                         }
  1887.                                         if ($approveRole == 2//edited
  1888.                                         {
  1889.                                             $loginId $doc->getEditedLoginId();
  1890.                                             $sigId $doc->getEditedSigId();
  1891.                                             $notYetAdded $doc->getEditedUserId() == null 0;
  1892.                                             $user_data Users::getUserInfoByLoginId($em$loginId);
  1893.                                             $doc->setEditedSigId($sigId);
  1894.                                             if (isset($user_data['id'])) {
  1895.                                                 $doc->setEditedUserId($user_data['id']);
  1896.                                                 $doc->setEditedSigId(null);
  1897.                                                 $doc->setLastModifiedDate(new \DateTime());
  1898.                                             }
  1899.                                             $em->flush();
  1900.                                         }
  1901.                                         if (isset($user_data['id']) && $notYetAdded == 1) {
  1902.                                             $new = new Approval();
  1903.                                             $new->setEntity($entity);
  1904.                                             $new->setEntityId($entity_id);
  1905.                                             $new->setPositionId(null);
  1906.                                             $new->setSequence(0);
  1907.                                             $new->setSkipPrintFlag(0);
  1908.                                             $new->setUserAssignType(1);
  1909.                                             $new->setDocumentHash($doc->getDocumentHash());
  1910.                                             //            $new->setUserIds($value->getUserId()); //<-----
  1911.                                             $new->setRoleType($approveRole);
  1912.                                             $new->setRequired(0);
  1913.                                             $new->setSuccession(0);
  1914.                                             $new->setAction(1); //pending status
  1915.                                             $new->setLoginId($loginId); //pending status
  1916.                                             $new->setCurrent(GeneralConstant::CURRENTLY_NON_PENDING_APPROVAL);
  1917.                                             $new->setSuccessionTimeout(0);
  1918.                                             $new->setSigId($sigId);
  1919.                                             $new->setNote('');
  1920.                                             $new->setUserIds(json_encode([$user_data['id']])); //<-----
  1921.                                             $em->persist($new);
  1922.                                             $em->flush();
  1923.                                         }
  1924.                                     }
  1925.                                 }
  1926.                             }
  1927.                         }
  1928.                     }
  1929.                     if ($request->query->get('rectifyOldBoq'0) == 1) {
  1930.                         $boqs $em
  1931.                             ->getRepository('ApplicationBundle\\Entity\\ProjectBoq')
  1932.                             ->findby(array(//                                    'projectId'=>$projectId
  1933.                             ));
  1934.                         foreach ($boqs as $boq) {
  1935. //
  1936. //                            //now the data
  1937. //                            $data = [];
  1938. //                            $newData = [];
  1939. //                            if ($boq)
  1940. //                                $data = json_decode($boq->getData(), true);
  1941. //                            if ($data == null)
  1942. //                                $data = [];
  1943. //                            $defValuesProduct = array(
  1944. //                                'product_note' => '',
  1945. //                                'product_alias' => '',
  1946. //                                'is_foreign_item' => 0,
  1947. //                                'product_segmentIndex' => 0,
  1948. //                                'product_currency_id' => 0,
  1949. //                                'product_currency_text' => '',
  1950. //                                'product_currency_multiply_rate' => 1,
  1951. //                                'product_scope' => 1,
  1952. //                                'product_scopeHolderId' => 0,
  1953. //                                'product_scopeHolderName' => '',
  1954. //                                'product_scopeDescription' => '',
  1955. //                            );
  1956. //                            $defValuesService = array(
  1957. //                                'service_note' => '',
  1958. //                                'service_alias' => '',
  1959. //                                'is_foreign_service' => 0,
  1960. //                                'service_segmentIndex' => 0,
  1961. //                                'service_currency_id' => 0,
  1962. //                                'service_currency_text' => '',
  1963. //                                'service_currency_multiply_rate' => 1,
  1964. //                                'service_scope' => 1,
  1965. //                                'service_scopeHolderId' => 0,
  1966. //                                'service_scopeHolderName' => '',
  1967. //                                'service_scopeDescription' => '',
  1968. //                            );
  1969. //
  1970. //
  1971. //                            if (!empty($data)) {
  1972. //                                $last_key = array_key_last($data);
  1973. ////                                if (isset($data[$last_key]['Products']['product_scope']))
  1974. ////                                    continue;
  1975. ////                                    if (count($data[$last_key]['Products']['products'])==count($data[$last_key]['Products']['is_foreign_item']) )
  1976. //
  1977. //
  1978. //                                $kho = 0;
  1979. //                                $dt_poka = $data[0];
  1980. //                                foreach ($data as $kho => $dt_poka) {
  1981. //
  1982. //
  1983. //                                    if (isset($dt_poka['Products']['products']))
  1984. //                                        foreach ($defValuesProduct as $gopaa => $boka) {
  1985. //                                            if (!isset($dt_poka['Products'][$gopaa]))
  1986. //                                                $dt_poka['Products'][$gopaa] = array_fill(0, count($dt_poka['Products']['products']), $boka);
  1987. //                                            else if ($dt_poka['Products'][$gopaa] == null)
  1988. //                                                $dt_poka['Products'][$gopaa] = array_fill(0, count($dt_poka['Products']['products']), $boka);
  1989. //
  1990. //
  1991. //                                        }
  1992. //                                    if (isset($dt_poka['Services']['services']))
  1993. //                                        foreach ($defValuesService as $gopaa => $boka) {
  1994. //                                            if (!isset($dt_poka['Services'][$gopaa]))
  1995. //                                                $dt_poka['Services'][$gopaa] = array_fill(0, count($dt_poka['Services']['services']), $boka);
  1996. //                                            else if ($dt_poka['Services'][$gopaa] == null)
  1997. //                                                $dt_poka['Services'][$gopaa] = array_fill(0, count($dt_poka['Services']['services']), $boka);
  1998. //
  1999. //                                        }
  2000. //
  2001. //                                    if (!isset($dt_poka['serviceSegmentData']))
  2002. //                                        $dt_poka['serviceSegmentData'] = [
  2003. //                                            array(
  2004. //                                                "title" => "General Services",
  2005. //                                                "index" => 0,
  2006. //                                            )
  2007. //                                        ];
  2008. //                                    else if ($dt_poka['serviceSegmentData'] == null || empty($dt_poka['serviceSegmentData']))
  2009. //                                        $dt_poka['serviceSegmentData'] = [
  2010. //                                            array(
  2011. //                                                "title" => "General Services",
  2012. //                                                "index" => 0,
  2013. //                                            )
  2014. //                                        ];
  2015. //
  2016. //                                    if (!isset($dt_poka['productSegmentData']))
  2017. //                                        $dt_poka['productSegmentData'] = [
  2018. //                                            array(
  2019. //                                                "title" => "General Items",
  2020. //                                                "index" => 0,
  2021. //                                            )
  2022. //                                        ];
  2023. //                                    else if ($dt_poka['productSegmentData'] == null || empty($dt_poka['productSegmentData']))
  2024. //                                        $dt_poka['productSegmentData'] = [
  2025. //                                            array(
  2026. //                                                "title" => "General Items",
  2027. //                                                "index" => 0,
  2028. //                                            )
  2029. //                                        ];
  2030. //
  2031. //
  2032. //                                    $newData[$kho] = $dt_poka;
  2033. //                                }
  2034. //
  2035. //
  2036. //                                $boq->setData(json_encode($newData));
  2037. //                                $em->flush();
  2038. //
  2039. //
  2040. //                            }
  2041.                             $theProj $em->getRepository('ApplicationBundle\\Entity\\Project')
  2042.                                 ->findOneBy(
  2043.                                     array(
  2044.                                         'projectId' => $boq->getProjectId()
  2045.                                     )
  2046.                                 );
  2047.                             if ($theProj)
  2048.                                 $theProj->setDocumentDataId($boq->getDocumentDataId());
  2049.                             $em->flush();
  2050.                         }
  2051.                     }
  2052.                     if ($request->query->get('oldBoqToNewSystem'0) == 1) {
  2053.                         $entitiesGG = [
  2054.                             array_flip(GeneralConstant::$Entity_list)['ProjectBoq'],
  2055.                             array_flip(GeneralConstant::$Entity_list)['ProjectMaterial'],
  2056.                             array_flip(GeneralConstant::$Entity_list)['SalesProposal'],
  2057.                             array_flip(GeneralConstant::$Entity_list)['Opportunity'],
  2058.                             array_flip(GeneralConstant::$Entity_list)['ProjectOffer'],
  2059.                             array_flip(GeneralConstant::$Entity_list)['ProjectProposal'],
  2060.                         ];
  2061.                         foreach ($entitiesGG as $ent) {
  2062.                             $entityNameHere GeneralConstant::$Entity_list[$ent];
  2063.                             $the_actual_docs $em->getRepository('ApplicationBundle\\Entity\\' GeneralConstant::$Entity_list[$ent])
  2064.                                 ->findBy(
  2065.                                     array(//                                        GeneralConstant::$Entity_id_field_list[$ent] => $entity_id,
  2066.                                     )
  2067.                                 );
  2068.                             foreach ($the_actual_docs as $the_actual_doc) {
  2069.                                 //now the data
  2070.                                 //first find the docData if available
  2071.                                 $theDocData null;
  2072.                                 if ($entityNameHere == 'SalesProposal' || $entityNameHere == 'Opportunity') {
  2073.                                     $theDocData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2074.                                         ->findOneBy(
  2075.                                             array(
  2076.                                                 'id' => $the_actual_doc->getDocumentDataId()
  2077.                                             )
  2078.                                         );
  2079.                                     if (!$theDocData)
  2080.                                         if ($the_actual_doc->getSalesProposalId() != null && $the_actual_doc->getSalesProposalId() != 0)
  2081.                                             $theDocData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2082.                                                 ->findOneBy(
  2083.                                                     array(
  2084.                                                         'proposalId' => $the_actual_doc->getSalesProposalId()
  2085.                                                     )
  2086.                                                 );
  2087.                                     if (!$theDocData)
  2088.                                         if ($the_actual_doc->getOpportunityId() != null && $the_actual_doc->getOpportunityId() != 0)
  2089.                                             $theDocData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2090.                                                 ->findOneBy(
  2091.                                                     array(
  2092.                                                         'opportunityId' => $the_actual_doc->getOpportunityId()
  2093.                                                     )
  2094.                                                 );
  2095.                                     if (!$theDocData)
  2096.                                         if ($the_actual_doc->getProjectId() != null && $the_actual_doc->getProjectId() != 0)
  2097.                                             $theDocData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2098.                                                 ->findOneBy(
  2099.                                                     array(
  2100.                                                         'projectId' => $the_actual_doc->getProjectId()
  2101.                                                     )
  2102.                                                 );
  2103.                                     if (!$theDocData) {
  2104.                                         $theDocData = new DocumentData();
  2105.                                         if ($entityNameHere == 'SalesProposal')
  2106.                                             $theDocData->setProposalId($the_actual_doc->getSalesProposalId());
  2107.                                         if ($entityNameHere == 'Opportunity')
  2108.                                             $theDocData->setOpportunityId($the_actual_doc->getOpportunityId());
  2109.                                     }
  2110.                                 } else {
  2111.                                     $theDocData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2112.                                         ->findOneBy(
  2113.                                             array(
  2114.                                                 'id' => $the_actual_doc->getDocumentDataId()
  2115.                                             )
  2116.                                         );
  2117.                                     if (!$theDocData)
  2118.                                         $theDocData $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2119.                                             ->findOneBy(
  2120.                                                 array(
  2121.                                                     'projectId' => $the_actual_doc->getProjectId()
  2122.                                                 )
  2123.                                             );
  2124.                                     if (!$theDocData) {
  2125.                                         $theDocData = new DocumentData();
  2126.                                         $theDocData->setProjectId($the_actual_doc->getProjectId());
  2127.                                     }
  2128.                                 }
  2129.                                 if ($entityNameHere == 'ProjectBoq' || $entityNameHere == 'Opportunity' || $entityNameHere == 'SalesProposal') {
  2130.                                     $data = [];
  2131.                                     $newData = [];
  2132.                                     $data json_decode($the_actual_doc->getData(), true);
  2133.                                     if ($data == null)
  2134.                                         $data = [];
  2135.                                     if (!empty($data)) {
  2136.                                         $last_key array_key_last($data);
  2137.                                         $lastIndex 0;
  2138.                                         foreach ($data as $kho => $dt_poka) {
  2139.                                             $cur_date = new \DateTime();
  2140.                                             $lead_date = new \DateTime(isset($dt_poka['lead_date']) ? $dt_poka['lead_date'] : '');
  2141.                                             $newSingleSet = array(
  2142.                                                 'refPoNumber' => isset($dt_poka['refPoNumber']) ? $dt_poka['refPoNumber'] : '',
  2143.                                                 'segmentData' => isset($dt_poka['segmentData']) ? $dt_poka['segmentData'] : [],
  2144.                                                 'proposal_title' => isset($dt_poka['proposal_title']) ? $dt_poka['proposal_title'] : '',
  2145.                                                 'to_position' => isset($dt_poka['to_position']) ? $dt_poka['to_position'] : '',
  2146.                                                 'system_subCategory' => isset($dt_poka['system_subCategory']) ? $dt_poka['system_subCategory'] : '',
  2147.                                                 'system_size' => isset($dt_poka['system_size']) ? $dt_poka['system_size'] : '',
  2148.                                                 'system_unit' => isset($dt_poka['system_unit']) ? $dt_poka['system_unit'] : '',
  2149.                                                 'system_price' => isset($dt_poka['system_price']) ? $dt_poka['system_price'] : '',
  2150.                                                 'msaTotal' => isset($dt_poka['msaTotal']) ? $dt_poka['msaTotal'] : 0,
  2151.                                                 'totalProjectValue' => isset($dt_poka['totalProjectValue']) ? $dt_poka['totalProjectValue'] : 0,
  2152.                                                 'cl_subject' => isset($dt_poka['cl_subject']) ? $dt_poka['cl_subject'] : '',
  2153.                                                 'cl_body' => isset($dt_poka['cl_body']) ? $dt_poka['cl_body'] : '',
  2154.                                                 'vatPercentage' => isset($dt_poka['vatPercentage']) ? $dt_poka['vatPercentage'] : '',
  2155.                                                 'aitPercentage' => isset($dt_poka['aitPercentage']) ? $dt_poka['aitPercentage'] : '',
  2156.                                                 'proposalSalesValue' => isset($dt_poka['proposalSalesValue']) ? $dt_poka['proposalSalesValue'] : '',
  2157.                                                 'combined_proposal_item_name' => isset($dt_poka['combined_proposal_item_name']) ? $dt_poka['combined_proposal_item_name'] : '',
  2158.                                                 'combined_proposal_details_price' => isset($dt_poka['combined_proposal_details_price']) ? $dt_poka['combined_proposal_details_price'] : '',
  2159.                                                 'check_boq' => isset($dt_poka['check_boq']) ? $dt_poka['check_boq'] : 0,
  2160.                                                 'check_boq_individual_price' => isset($dt_poka['check_boq_individual_price']) ? $dt_poka['check_boq_individual_price'] : 0,
  2161.                                                 'check_show_combined_only' => isset($dt_poka['check_show_combined_only']) ? $dt_poka['check_show_combined_only'] : 0,
  2162.                                                 // Same copy-paste as SalesOrderM's whitelist (see the note there): this
  2163.                                                 // read check_show_combined_only, making the flag a mirror of a different
  2164.                                                 // checkbox. This block is the opt-in ?rectifyOldBoq=1 rebuild and it
  2165.                                                 // touches ProjectBoq / Opportunity / SalesProposal blobs only — never the
  2166.                                                 // ProjectOffer / ProjectProposal blobs the flag is actually read from — so
  2167.                                                 // correcting it changes no rendered figure. Left uncorrected it would have
  2168.                                                 // stamped the wrong value across every rebuilt document the next time the
  2169.                                                 // owner ran the rectify pass.
  2170.                                                 'check_override_markup' => isset($dt_poka['check_override_markup']) ? $dt_poka['check_override_markup'] : 0,
  2171.                                                 'clientId' => isset($dt_poka['client_id']) ? $dt_poka['client_id'] : 0,
  2172.                                                 'salesPersonId' => isset($dt_poka['salesPersonID']) ? $dt_poka['salesPersonID'] : 0,
  2173.                                                 'clientName' => isset($dt_poka['clientName']) ? $dt_poka['clientName'] : '',
  2174.                                                 'ClientContactPerson' => isset($dt_poka['ClientContactPerson']) ? $dt_poka['ClientContactPerson'] : '',
  2175.                                                 'ClientContactNumber' => isset($dt_poka['ClientContactNumber']) ? $dt_poka['ClientContactNumber'] : '',
  2176.                                                 'ClientDeliveryAddress' => isset($dt_poka['ClientDeliveryAddress']) ? $dt_poka['ClientDeliveryAddress'] : '',
  2177.                                                 'ClientBillingAddress' => isset($dt_poka['ClientBillingAddress']) ? $dt_poka['ClientBillingAddress'] : '',
  2178.                                                 'leadDate' => $lead_date->format('Y-m-d'),
  2179.                                                 'date' => $cur_date->format('Y-m-d'),
  2180.                                             );
  2181.                                             $newSegmentData = array();
  2182.                                             $oldSegmentSystem 0;
  2183.                                             if (isset($dt_poka['productSegmentData']) || isset($dt_poka['serviceSegmentData']))
  2184.                                                 $oldSegmentSystem 1;
  2185.                                             if ($oldSegmentSystem == 1) {
  2186.                                                 //unify the ids of segmnent. services will start from 1000+service segmentId for unification
  2187.                                                 if (isset($dt_poka['productSegmentData']))
  2188.                                                     foreach ($dt_poka['productSegmentData'] as $supu => $gupu) {
  2189.                                                         $newModSeg $gupu;
  2190.                                                         $newModSeg['index'] = $gupu['index'];
  2191.                                                         $newModSeg['title'] = isset($gupu['title']) ? $gupu['title'] : 'Items';
  2192.                                                         $newModSeg['scfc'] = isset($gupu['scfc']) ? $gupu['scfc'] : 0;
  2193.                                                         $newModSeg['uomCust'] = isset($gupu['uomCust']) ? $gupu['uomCust'] : '';
  2194.                                                         $newModSeg['unitCust'] = isset($gupu['unitCust']) ? $gupu['unitCust'] : '';
  2195.                                                         $newModSeg['priceCust'] = isset($gupu['priceCust']) ? $gupu['priceCust'] : '';
  2196.                                                         $newModSeg['currCust'] = isset($gupu['currCust']) ? $gupu['currCust'] : '';
  2197.                                                         $newModSeg['descCust'] = isset($gupu['descCust']) ? $gupu['descCust'] : '';
  2198.                                                         $newModSeg['scope'] = isset($gupu['scope']) ? $gupu['scope'] : 0;
  2199.                                                         $newModSeg['scopeId'] = isset($gupu['scopeId']) ? $gupu['scopeId'] : 0;
  2200.                                                         $newModSeg['scopeName'] = isset($gupu['scopeName']) ? $gupu['scopeName'] : '';
  2201.                                                         $newModSeg['scopeDescription'] = isset($gupu['scopeDescription']) ? $gupu['scopeDescription'] : '';
  2202.                                                         $newSegmentData[] = $newModSeg;
  2203.                                                     }
  2204.                                                 if (isset($dt_poka['serviceSegmentData']))
  2205.                                                     if ($dt_poka['serviceSegmentData'] == null || empty($dt_poka['serviceSegmentData']))
  2206.                                                         foreach ($dt_poka['serviceSegmentData'] as $supu => $gupu) {
  2207.                                                             if ($gupu['index'] == 'undefined'$gupu['index'] = 0;
  2208.                                                             if (!is_numeric($gupu['index'])) $gupu['index'] = 0;
  2209.                                                             $newModSeg $gupu;
  2210.                                                             $newModSeg['index'] = 1000 $gupu['index'];
  2211.                                                             $newModSeg['title'] = isset($gupu['title']) ? $gupu['title'] : 'Services';
  2212.                                                             $newModSeg['scfc'] = isset($gupu['scfc']) ? $gupu['scfc'] : 0;
  2213.                                                             $newModSeg['uomCust'] = isset($gupu['uomCust']) ? $gupu['uomCust'] : '';
  2214.                                                             $newModSeg['unitCust'] = isset($gupu['unitCust']) ? $gupu['unitCust'] : '';
  2215.                                                             $newModSeg['priceCust'] = isset($gupu['priceCust']) ? $gupu['priceCust'] : '';
  2216.                                                             $newModSeg['currCust'] = isset($gupu['currCust']) ? $gupu['currCust'] : '';
  2217.                                                             $newModSeg['descCust'] = isset($gupu['descCust']) ? $gupu['descCust'] : '';
  2218.                                                             $newModSeg['scope'] = isset($gupu['scope']) ? $gupu['scope'] : 0;
  2219.                                                             $newModSeg['scopeId'] = isset($gupu['scopeId']) ? $gupu['scopeId'] : 0;
  2220.                                                             $newModSeg['scopeName'] = isset($gupu['scopeName']) ? $gupu['scopeName'] : '';
  2221.                                                             $newModSeg['scopeDescription'] = isset($gupu['scopeDescription']) ? $gupu['scopeDescription'] : '';
  2222.                                                             $newSegmentData[] = $newModSeg;
  2223.                                                         }
  2224.                                                 $newSingleSet['itemSegmentData'] = $newSegmentData;
  2225.                                             }
  2226.                                             $lastSequenceBySegment = array();
  2227.                                             //now modify Services or products
  2228.                                             $oldProductSystem 0;
  2229.                                             if (!isset($dt_poka['rowData']))
  2230.                                                 $dt_poka['rowData'] = array();
  2231.                                             if (isset($dt_poka['Products']) || isset($dt_poka['Services']) || isset($dt_poka['ArCosts'])) {
  2232.                                                 $oldProductSystem 1;
  2233.                                             }
  2234.                                             if ($oldProductSystem == 1) {
  2235.                                                 $theDt = array(
  2236.                                                     'products' => [],
  2237.                                                     'services' => [],
  2238.                                                     'ar_heads' => [],
  2239.                                                 );
  2240.                                                 if (isset($dt_poka['Products']))
  2241.                                                     $theDt $dt_poka['Products'];
  2242.                                                 if (isset($theDt['products']))
  2243.                                                     foreach ($theDt['products'] as $f => $pid) {
  2244.                                                         $unit = isset($theDt['product_units'][$f]) ? $theDt['product_units'][$f] : 0;
  2245.                                                         $indexForThis = isset($theDt['index'][$f]) ? $theDt['index'][$f] : -1;
  2246.                                                         if ($indexForThis == -1) {
  2247.                                                             $indexForThis $lastIndex;
  2248.                                                             $lastIndex++;
  2249.                                                         }
  2250.                                                         $unitPrice = isset($theDt['product_unit_price'][$f]) ? $theDt['product_unit_price'][$f] : 0;
  2251.                                                         if ($unit == ''$unit 0;
  2252.                                                         if ($unitPrice == ''$unitPrice 0;
  2253.                                                         $totalPrice $unit $unitPrice;
  2254.                                                         $segmentIndex = isset($theDt['product_segmentIndex'][$f]) ? $theDt['product_segmentIndex'][$f] : 0;
  2255.                                                         $sequence = isset($theDt['product_segmentIndex'][$f]) ? $theDt['product_segmentIndex'][$f] : '_UNSET_';
  2256.                                                         if (!isset($lastSequenceBySegment[$segmentIndex]))
  2257.                                                             $lastSequenceBySegment[$segmentIndex] = -1;
  2258.                                                         if ($sequence == '_UNSET_')
  2259.                                                             $sequence $lastSequenceBySegment[$segmentIndex] + 1;
  2260.                                                         else if ($sequence == $lastSequenceBySegment[$segmentIndex])
  2261.                                                             $sequence $lastSequenceBySegment[$segmentIndex] + 1;
  2262.                                                         $lastSequenceBySegment[$segmentIndex] = $sequence;
  2263.                                                         $unitSalesPrice = isset($theDt['product_unit_sales_price'][$f]) ? $theDt['product_unit_sales_price'][$f] : $unitPrice;
  2264.                                                         if ($unitSalesPrice == ''$unitSalesPrice 0;
  2265.                                                         $totalSalesPrice $unit $unitSalesPrice;
  2266.                                                         $marginAmount = isset($theDt['product_ma'][$f]) ? $theDt['product_ma'][$f] : ($unitSalesPrice $unitPrice);
  2267.                                                         $marginRate = isset($theDt['product_ma'][$f]) ? $theDt['product_ma'][$f] : ($unitPrice == : (100 $marginAmount $unitPrice));
  2268.                                                         $discountAmount = isset($theDt['product_dr'][$f]) ? $theDt['product_dr'][$f] : 0;
  2269.                                                         $discountRate = isset($theDt['product_da'][$f]) ? $theDt['product_da'][$f] : ($totalSalesPrice == : (100 $discountAmount $totalSalesPrice));
  2270.                                                         $discountedAmount $totalSalesPrice $discountAmount;
  2271.                                                         $taxRate = isset($theDt['product_tax_percentage'][$f]) ? $theDt['product_tax_percentage'][$f] : ($unitPrice == : (100 $discountAmount $unitPrice));
  2272.                                                         $taxAmount = isset($theDt['product_tax_amount'][$f]) ? $theDt['product_tax_amount'][$f] : 0;
  2273.                                                         $finalAmount $discountedAmount $taxAmount;
  2274.                                                         $row = array(
  2275.                                                             'type' => 1,//1:product 2=service 4=tools 5:text 6: expense against head
  2276.                                                             'id' => $pid,
  2277.                                                             'index' => $indexForThis,
  2278.                                                             'isForeign' => isset($theDt['is_foreign_item'][$f]) ? $theDt['is_foreign_item'][$f] : 0,
  2279.                                                             'sequence' => $sequence,
  2280.                                                             'segmentIndex' => $segmentIndex,
  2281.                                                             'soItemId' => isset($theDt['product_soItemId'][$f]) ? $theDt['product_soItemId'][$f] : 0,
  2282.                                                             'soItemDelivered' => isset($theDt['product_soItemDelivered'][$f]) ? $theDt['product_soItemDelivered'][$f] : 0,
  2283.                                                             'soItemFound' => isset($theDt['product_soItemFound'][$f]) ? $theDt['product_soItemFound'][$f] : 0,
  2284.                                                             'alias' => isset($theDt['product_alias'][$f]) ? $theDt['product_alias'][$f] : '',
  2285.                                                             'name' => isset($theDt['product_name'][$f]) ? $theDt['product_name'][$f] : '',
  2286.                                                             'note' => isset($theDt['product_note'][$f]) ? $theDt['product_note'][$f] : '',
  2287.                                                             'fdm' => isset($theDt['product_fdm'][$f]) ? $theDt['product_fdm'][$f] : null,
  2288.                                                             'unit' => isset($theDt['product_units'][$f]) ? $theDt['product_units'][$f] : 0,
  2289.                                                             'unitTypeId' => isset($theDt['product_unit_type'][$f]) ? $theDt['product_unit_type'][$f] : 0,
  2290.                                                             'unitPrice' => $unitPrice,
  2291.                                                             'totalPrice' => $totalPrice,
  2292.                                                             'unitSalesPrice' => $unitSalesPrice,
  2293.                                                             'totalSalesPrice' => $totalSalesPrice,
  2294.                                                             'marginRate' => $marginRate,
  2295.                                                             'marginAmount' => $marginAmount,
  2296.                                                             'discountRate' => $discountRate,
  2297.                                                             'discountAmount' => $discountAmount,
  2298.                                                             'discountedAmount' => $discountedAmount,
  2299.                                                             'taxRate' => $taxRate,
  2300.                                                             'taxAmount' => $taxAmount,
  2301.                                                             'finalAmount' => $finalAmount,
  2302.                                                             'recurring' => isset($theDt['product_recurring'][$f]) ? $theDt['product_recurring'][$f] : 0,
  2303.                                                             'currency' => isset($theDt['product_currency_id'][$f]) ? $theDt['product_currency_id'][$f] : 0,
  2304.                                                             'currencyText' => isset($theDt['product_currency_text'][$f]) ? $theDt['product_currency_text'][$f] : '',
  2305.                                                             'currencyMultiplyRate' => isset($theDt['product_currency_multiply_rate'][$f]) ? $theDt['product_currency_multiply_rate'][$f] : 1,
  2306.                                                             'incoterm' => isset($theDt['incoterm'][$f]) ? $theDt['incoterm'][$f] : '',
  2307.                                                             'taxId' => isset($theDt['product_tax_config_id'][$f]) ? $theDt['product_tax_config_id'][$f] : 0,
  2308.                                                             'taxName' => isset($theDt['product_tax_config_text'][$f]) ? $theDt['product_tax_config_text'][$f] : '',
  2309.                                                             'dependencyOnIndex' => isset($theDt['product_dependency_of_index'][$f]) ? $theDt['product_dependency_of_index'][$f] : 0,
  2310.                                                             'dependencyOnPid' => isset($theDt['product_dependency_of_product_id'][$f]) ? $theDt['product_dependency_of_product_id'][$f] : 0,
  2311.                                                             'dependencyOnSid' => isset($theDt['product_dependency_of_service_id'][$f]) ? $theDt['product_dependency_of_service_id'][$f] : 0,
  2312.                                                             'dependencyOnSegment' => isset($theDt['product_dependency_of_product_index'][$f]) ? $theDt['product_dependency_of_product_index'][$f] : 0,
  2313.                                                             'warranty' => isset($theDt['product_delivery_schedule'][$f]) ? $theDt['product_delivery_schedule'][$f] : 0,
  2314.                                                             'origin' => isset($theDt['product_origin'][$f]) ? $theDt['product_origin'][$f] : 0,
  2315.                                                             'origins' => isset($theDt['product_origin'][$f]) ? [$theDt['product_origin'][$f]] : [],
  2316.                                                             'scope' => isset($theDt['product_scope'][$f]) ? $theDt['product_scope'][$f] : 0,
  2317.                                                             'scopeId' => isset($theDt['product_scopeHolderId'][$f]) ? [$theDt['product_scopeHolderId'][$f]] : 0,
  2318.                                                             'scopeName' => isset($theDt['product_scopeHolderName'][$f]) ? [$theDt['product_scopeHolderName'][$f]] : '',
  2319.                                                             'scopeDescription' => isset($theDt['product_scopeDescription'][$f]) ? [$theDt['product_scopeDescription'][$f]] : '',
  2320.                                                             'deliverySchedule' => isset($theDt['product_delivery_schedule'][$f]) ? $theDt['product_delivery_schedule'][$f] : [],
  2321.                                                             'deliveryPorts' => isset($theDt['product_delivery_ports'][$f]) ? $theDt['product_delivery_ports'][$f] : [],
  2322.                                                             'billingSchedule' => isset($theDt['product_billing_schedule'][$f]) ? $theDt['product_billing_schedule'][$f] : [],
  2323.                                                             'referenceNo' => isset($theDt['product_reference_price'][$f]) ? $theDt['product_reference_price'][$f] : '',
  2324.                                                             'referenceFiles' => isset($theDt['product_reference_price_file'][$f]) ? $theDt['product_reference_price_file'][$f] : '',
  2325.                                                         );
  2326.                                                         $dt_poka['rowData'][] = $row;
  2327.                                                     }
  2328.                                                 //now the services
  2329.                                                 $theDt = array(
  2330.                                                     'products' => [],
  2331.                                                     'services' => [],
  2332.                                                     'ar_heads' => [],
  2333.                                                 );
  2334.                                                 if (isset($dt_poka['Services']))
  2335.                                                     $theDt $dt_poka['Services'];
  2336.                                                 if (isset($theDt['services']))
  2337.                                                     foreach ($theDt['services'] as $f => $pid) {
  2338.                                                         $unit = isset($theDt['service_units'][$f]) ? $theDt['service_units'][$f] : 0;
  2339.                                                         $indexForThis = isset($theDt['index'][$f]) ? $theDt['index'][$f] : -1;
  2340.                                                         if ($indexForThis == -1) {
  2341.                                                             $indexForThis $lastIndex;
  2342.                                                             $lastIndex++;
  2343.                                                         }
  2344.                                                         $unitPrice = isset($theDt['service_unit_price'][$f]) ? $theDt['service_unit_price'][$f] : 0;
  2345.                                                         $totalPrice $unit $unitPrice;
  2346.                                                         $segmentIndex = isset($theDt['service_segmentIndex'][$f]) ? $theDt['service_segmentIndex'][$f] : 0;
  2347.                                                         if ($segmentIndex == 'undefined'$segmentIndex 0;
  2348.                                                         if (!is_numeric($segmentIndex)) $segmentIndex 0;
  2349.                                                         if ($oldSegmentSystem == 1)
  2350.                                                             $segmentIndex 1000 $segmentIndex;
  2351.                                                         $sequence = isset($theDt['service_segmentIndex'][$f]) ? $theDt['service_segmentIndex'][$f] : '_UNSET_';
  2352.                                                         if (!isset($lastSequenceBySegment[$segmentIndex]))
  2353.                                                             $lastSequenceBySegment[$segmentIndex] = -1;
  2354.                                                         if ($sequence == '_UNSET_')
  2355.                                                             $sequence $lastSequenceBySegment[$segmentIndex] + 1;
  2356.                                                         else if ($sequence == $lastSequenceBySegment[$segmentIndex])
  2357.                                                             $sequence $lastSequenceBySegment[$segmentIndex] + 1;
  2358.                                                         $lastSequenceBySegment[$segmentIndex] = $sequence;
  2359.                                                         $unitSalesPrice = isset($theDt['service_unit_sales_price'][$f]) ? $theDt['service_unit_sales_price'][$f] : $unitPrice;
  2360.                                                         $totalSalesPrice $unit $unitSalesPrice;
  2361.                                                         $marginAmount = isset($theDt['service_ma'][$f]) ? $theDt['service_ma'][$f] : ($unitSalesPrice $unitPrice);
  2362.                                                         $marginRate = isset($theDt['service_ma'][$f]) ? $theDt['service_ma'][$f] : ($unitPrice == : (100 $marginAmount $unitPrice));
  2363.                                                         $discountAmount = isset($theDt['service_dr'][$f]) ? $theDt['service_dr'][$f] : 0;
  2364.                                                         $discountRate = isset($theDt['service_da'][$f]) ? $theDt['service_da'][$f] : ($totalSalesPrice == : (100 $discountAmount $totalSalesPrice));
  2365.                                                         $discountedAmount $totalSalesPrice $discountAmount;
  2366.                                                         $taxRate = isset($theDt['service_tax_percentage'][$f]) ? $theDt['service_tax_percentage'][$f] : ($unitPrice == : (100 $discountAmount $unitPrice));
  2367.                                                         $taxAmount = isset($theDt['service_tax_amount'][$f]) ? $theDt['service_tax_amount'][$f] : 0;
  2368.                                                         $finalAmount $discountedAmount $taxAmount;
  2369.                                                         $row = array(
  2370.                                                             'type' => 2,//1:product 2=service 4=tools 5:text 6: expense against head
  2371.                                                             'id' => $pid,
  2372.                                                             'index' => $indexForThis,
  2373.                                                             'isForeign' => isset($theDt['is_foreign_service'][$f]) ? $theDt['is_foreign_service'][$f] : 0,
  2374.                                                             'sequence' => $sequence,
  2375.                                                             'segmentIndex' => $segmentIndex,
  2376.                                                             'soItemId' => isset($theDt['service_soItemId'][$f]) ? $theDt['service_soItemId'][$f] : 0,
  2377.                                                             'soItemDelivered' => isset($theDt['service_soItemDelivered'][$f]) ? $theDt['service_soItemDelivered'][$f] : 0,
  2378.                                                             'soItemFound' => isset($theDt['service_soItemFound'][$f]) ? $theDt['service_soItemFound'][$f] : 0,
  2379.                                                             'alias' => isset($theDt['service_alias'][$f]) ? $theDt['service_alias'][$f] : '',
  2380.                                                             'name' => isset($theDt['service_name'][$f]) ? $theDt['service_name'][$f] : '',
  2381.                                                             'note' => isset($theDt['service_note'][$f]) ? $theDt['service_note'][$f] : '',
  2382.                                                             'fdm' => isset($theDt['service_fdm'][$f]) ? $theDt['service_fdm'][$f] : null,
  2383.                                                             'unit' => isset($theDt['service_units'][$f]) ? $theDt['service_units'][$f] : 0,
  2384.                                                             'unitTypeId' => isset($theDt['service_unit_type'][$f]) ? $theDt['service_unit_type'][$f] : 0,
  2385.                                                             'unitPrice' => $unitPrice,
  2386.                                                             'totalPrice' => $totalPrice,
  2387.                                                             'unitSalesPrice' => $unitSalesPrice,
  2388.                                                             'totalSalesPrice' => $totalSalesPrice,
  2389.                                                             'marginRate' => $marginRate,
  2390.                                                             'marginAmount' => $marginAmount,
  2391.                                                             'discountRate' => $discountRate,
  2392.                                                             'discountAmount' => $discountAmount,
  2393.                                                             'discountedAmount' => $discountedAmount,
  2394.                                                             'taxRate' => $taxRate,
  2395.                                                             'taxAmount' => $taxAmount,
  2396.                                                             'finalAmount' => $finalAmount,
  2397.                                                             'recurring' => isset($theDt['service_recurring'][$f]) ? $theDt['service_recurring'][$f] : 0,
  2398.                                                             'currency' => isset($theDt['service_currency_id'][$f]) ? $theDt['service_currency_id'][$f] : 0,
  2399.                                                             'currencyText' => isset($theDt['service_currency_text'][$f]) ? $theDt['service_currency_text'][$f] : '',
  2400.                                                             'currencyMultiplyRate' => isset($theDt['service_currency_multiply_rate'][$f]) ? $theDt['service_currency_multiply_rate'][$f] : 1,
  2401.                                                             'incoterm' => isset($theDt['incoterm'][$f]) ? $theDt['incoterm'][$f] : '',
  2402.                                                             'taxId' => isset($theDt['service_tax_config_id'][$f]) ? $theDt['service_tax_config_id'][$f] : 0,
  2403.                                                             'taxName' => isset($theDt['service_tax_config_text'][$f]) ? $theDt['service_tax_config_text'][$f] : '',
  2404.                                                             'dependencyOnIndex' => isset($theDt['service_dependency_of_index'][$f]) ? $theDt['service_dependency_of_index'][$f] : 0,
  2405.                                                             'dependencyOnPid' => isset($theDt['service_dependency_of_service_id'][$f]) ? $theDt['service_dependency_of_service_id'][$f] : 0,
  2406.                                                             'dependencyOnSid' => isset($theDt['service_dependency_of_service_id'][$f]) ? $theDt['service_dependency_of_service_id'][$f] : 0,
  2407.                                                             'dependencyOnSegment' => isset($theDt['service_dependency_of_service_index'][$f]) ? $theDt['service_dependency_of_service_index'][$f] : 0,
  2408.                                                             'warranty' => isset($theDt['service_delivery_schedule'][$f]) ? $theDt['service_delivery_schedule'][$f] : 0,
  2409.                                                             'origin' => isset($theDt['service_origin'][$f]) ? $theDt['service_origin'][$f] : 0,
  2410.                                                             'origins' => isset($theDt['service_origin'][$f]) ? [$theDt['service_origin'][$f]] : [],
  2411.                                                             'scope' => isset($theDt['service_scope'][$f]) ? $theDt['service_scope'][$f] : 0,
  2412.                                                             'scopeId' => isset($theDt['service_scopeHolderId'][$f]) ? [$theDt['service_scopeHolderId'][$f]] : 0,
  2413.                                                             'scopeName' => isset($theDt['service_scopeHolderName'][$f]) ? [$theDt['service_scopeHolderName'][$f]] : '',
  2414.                                                             'scopeDescription' => isset($theDt['service_scopeDescription'][$f]) ? [$theDt['service_scopeDescription'][$f]] : '',
  2415.                                                             'deliverySchedule' => isset($theDt['service_delivery_schedule'][$f]) ? $theDt['service_delivery_schedule'][$f] : [],
  2416.                                                             'deliveryPorts' => isset($theDt['service_delivery_ports'][$f]) ? $theDt['service_delivery_ports'][$f] : [],
  2417.                                                             'billingSchedule' => isset($theDt['service_billing_schedule'][$f]) ? $theDt['service_billing_schedule'][$f] : [],
  2418.                                                             'referenceNo' => isset($theDt['service_reference_price'][$f]) ? $theDt['service_reference_price'][$f] : '',
  2419.                                                             'referenceFiles' => isset($theDt['service_reference_price_file'][$f]) ? $theDt['service_reference_price_file'][$f] : '',
  2420.                                                         );
  2421.                                                         $dt_poka['rowData'][] = $row;
  2422.                                                     }
  2423.                                                 //now accounts /Cost
  2424.                                                 $theDt = array(
  2425.                                                     'products' => [],
  2426.                                                     'services' => [],
  2427.                                                     'ar_heads' => [],
  2428.                                                 );
  2429.                                                 if (isset($dt_poka['ArCosts']))
  2430.                                                     $theDt $dt_poka['ArCosts'];
  2431.                                                 if (isset($theDt['ar_heads']))
  2432.                                                     foreach ($theDt['ar_heads'] as $f => $pid) {
  2433.                                                         $unit = isset($theDt['ar_units'][$f]) ? $theDt['ar_units'][$f] : 0;
  2434.                                                         if (!is_numeric($unit)) $unit 0;
  2435.                                                         $indexForThis = isset($theDt['index'][$f]) ? $theDt['index'][$f] : -1;
  2436.                                                         if ($indexForThis == -1) {
  2437.                                                             $indexForThis $lastIndex;
  2438.                                                             $lastIndex++;
  2439.                                                         }
  2440.                                                         $unitPrice = isset($theDt['ar_unit_price'][$f]) ? $theDt['ar_unit_price'][$f] : 0;
  2441.                                                         if (!is_numeric($unitPrice)) $unitPrice 0;
  2442.                                                         $totalPrice $unit $unitPrice;
  2443.                                                         $segmentIndex = isset($theDt['ar_segmentIndex'][$f]) ? $theDt['ar_segmentIndex'][$f] : 0;
  2444.                                                         if ($oldSegmentSystem == 1)
  2445.                                                             $segmentIndex 1000 $segmentIndex;
  2446.                                                         $sequence = isset($theDt['ar_segmentIndex'][$f]) ? $theDt['ar_segmentIndex'][$f] : '_UNSET_';
  2447.                                                         if (!isset($lastSequenceBySegment[$segmentIndex]))
  2448.                                                             $lastSequenceBySegment[$segmentIndex] = -1;
  2449.                                                         if ($sequence == '_UNSET_')
  2450.                                                             $sequence $lastSequenceBySegment[$segmentIndex] + 1;
  2451.                                                         else if ($sequence == $lastSequenceBySegment[$segmentIndex])
  2452.                                                             $sequence $lastSequenceBySegment[$segmentIndex] + 1;
  2453.                                                         $lastSequenceBySegment[$segmentIndex] = $sequence;
  2454.                                                         $unitSalesPrice = isset($theDt['ar_unit_sales_price'][$f]) ? $theDt['ar_unit_sales_price'][$f] : $unitPrice;
  2455.                                                         $totalSalesPrice $unit $unitSalesPrice;
  2456.                                                         $marginAmount = isset($theDt['ar_ma'][$f]) ? $theDt['ar_ma'][$f] : ($unitSalesPrice $unitPrice);
  2457.                                                         $marginRate = isset($theDt['ar_ma'][$f]) ? $theDt['ar_ma'][$f] : ($unitPrice == : (100 $marginAmount $unitPrice));
  2458.                                                         $discountAmount = isset($theDt['ar_dr'][$f]) ? $theDt['ar_dr'][$f] : 0;
  2459.                                                         $discountRate = isset($theDt['ar_da'][$f]) ? $theDt['ar_da'][$f] : ($totalSalesPrice == : (100 $discountAmount $totalSalesPrice));
  2460.                                                         $discountedAmount $totalSalesPrice $discountAmount;
  2461.                                                         $taxRate = isset($theDt['ar_tax_percentage'][$f]) ? $theDt['ar_tax_percentage'][$f] : ($unitPrice == : (100 $discountAmount $unitPrice));
  2462.                                                         $taxAmount = isset($theDt['ar_tax_amount'][$f]) ? $theDt['ar_tax_amount'][$f] : 0;
  2463.                                                         $finalAmount $discountedAmount $taxAmount;
  2464.                                                         $row = array(
  2465.                                                             'type' => 6,//1:product 2=service 4=tools 5:text 6: expense against head
  2466.                                                             'id' => $pid,
  2467.                                                             'index' => $indexForThis,
  2468.                                                             'isForeign' => isset($theDt['is_foreign_cost'][$f]) ? $theDt['is_foreign_cost'][$f] : 0,
  2469.                                                             'sequence' => $sequence,
  2470.                                                             'segmentIndex' => $segmentIndex,
  2471.                                                             'soItemId' => isset($theDt['ar_soItemId'][$f]) ? $theDt['ar_soItemId'][$f] : 0,
  2472.                                                             'soItemDelivered' => isset($theDt['ar_soItemDelivered'][$f]) ? $theDt['ar_soItemDelivered'][$f] : 0,
  2473.                                                             'soItemFound' => isset($theDt['ar_soItemFound'][$f]) ? $theDt['ar_soItemFound'][$f] : 0,
  2474.                                                             'alias' => isset($theDt['ar_alias'][$f]) ? $theDt['ar_alias'][$f] : '',
  2475.                                                             'name' => isset($theDt['ar_name'][$f]) ? $theDt['ar_name'][$f] : '',
  2476.                                                             'note' => isset($theDt['ar_note'][$f]) ? $theDt['ar_note'][$f] : '',
  2477.                                                             'fdm' => isset($theDt['ar_fdm'][$f]) ? $theDt['ar_fdm'][$f] : null,
  2478.                                                             'unit' => isset($theDt['ar_units'][$f]) ? $theDt['ar_units'][$f] : 0,
  2479.                                                             'unitTypeId' => isset($theDt['ar_unit_type'][$f]) ? $theDt['ar_unit_type'][$f] : 0,
  2480.                                                             'unitPrice' => $unitPrice,
  2481.                                                             'totalPrice' => $totalPrice,
  2482.                                                             'unitSalesPrice' => $unitSalesPrice,
  2483.                                                             'totalSalesPrice' => $totalSalesPrice,
  2484.                                                             'marginRate' => $marginRate,
  2485.                                                             'marginAmount' => $marginAmount,
  2486.                                                             'discountRate' => $discountRate,
  2487.                                                             'discountAmount' => $discountAmount,
  2488.                                                             'discountedAmount' => $discountedAmount,
  2489.                                                             'taxRate' => $taxRate,
  2490.                                                             'taxAmount' => $taxAmount,
  2491.                                                             'finalAmount' => $finalAmount,
  2492.                                                             'recurring' => isset($theDt['ar_recurring'][$f]) ? $theDt['ar_recurring'][$f] : 0,
  2493.                                                             'currency' => isset($theDt['ar_currency_id'][$f]) ? $theDt['ar_currency_id'][$f] : 0,
  2494.                                                             'currencyText' => isset($theDt['ar_currency_text'][$f]) ? $theDt['ar_currency_text'][$f] : '',
  2495.                                                             'currencyMultiplyRate' => isset($theDt['ar_currency_multiply_rate'][$f]) ? $theDt['ar_currency_multiply_rate'][$f] : 1,
  2496.                                                             'incoterm' => isset($theDt['incoterm'][$f]) ? $theDt['incoterm'][$f] : '',
  2497.                                                             'taxId' => isset($theDt['ar_tax_config_id'][$f]) ? $theDt['ar_tax_config_id'][$f] : 0,
  2498.                                                             'taxName' => isset($theDt['ar_tax_config_text'][$f]) ? $theDt['ar_tax_config_text'][$f] : '',
  2499.                                                             'dependencyOnIndex' => isset($theDt['ar_dependency_of_index'][$f]) ? $theDt['ar_dependency_of_index'][$f] : 0,
  2500.                                                             'dependencyOnPid' => isset($theDt['ar_dependency_of_ar_id'][$f]) ? $theDt['ar_dependency_of_ar_id'][$f] : 0,
  2501.                                                             'dependencyOnSid' => isset($theDt['ar_dependency_of_ar_id'][$f]) ? $theDt['ar_dependency_of_ar_id'][$f] : 0,
  2502.                                                             'dependencyOnSegment' => isset($theDt['ar_dependency_of_ar_index'][$f]) ? $theDt['ar_dependency_of_ar_index'][$f] : 0,
  2503.                                                             'warranty' => isset($theDt['ar_delivery_schedule'][$f]) ? $theDt['ar_delivery_schedule'][$f] : 0,
  2504.                                                             'origin' => isset($theDt['ar_origin'][$f]) ? $theDt['ar_origin'][$f] : 0,
  2505.                                                             'origins' => isset($theDt['ar_origin'][$f]) ? [$theDt['ar_origin'][$f]] : [],
  2506.                                                             'scope' => isset($theDt['ar_scope'][$f]) ? $theDt['ar_scope'][$f] : 0,
  2507.                                                             'scopeId' => isset($theDt['ar_scopeHolderId'][$f]) ? [$theDt['ar_scopeHolderId'][$f]] : 0,
  2508.                                                             'scopeName' => isset($theDt['ar_scopeHolderName'][$f]) ? [$theDt['ar_scopeHolderName'][$f]] : '',
  2509.                                                             'scopeDescription' => isset($theDt['ar_scopeDescription'][$f]) ? [$theDt['ar_scopeDescription'][$f]] : '',
  2510.                                                             'deliverySchedule' => isset($theDt['ar_delivery_schedule'][$f]) ? $theDt['ar_delivery_schedule'][$f] : [],
  2511.                                                             'deliveryPorts' => isset($theDt['ar_delivery_ports'][$f]) ? $theDt['ar_delivery_ports'][$f] : [],
  2512.                                                             'billingSchedule' => isset($theDt['ar_billing_schedule'][$f]) ? $theDt['ar_billing_schedule'][$f] : [],
  2513.                                                             'referenceNo' => isset($theDt['ar_reference_price'][$f]) ? $theDt['ar_reference_price'][$f] : '',
  2514.                                                             'referenceFiles' => isset($theDt['ar_reference_price_file'][$f]) ? $theDt['ar_reference_price_file'][$f] : '',
  2515.                                                         );
  2516.                                                         $dt_poka['rowData'][] = $row;
  2517.                                                     }
  2518. //                                                $configJson['debugData'][]=$dt_poka;
  2519.                                             }
  2520.                                             $newSingleSet['rowData'] = $dt_poka['rowData'];
  2521.                                             unset($dt_poka['productSegmentData']);
  2522.                                             unset($dt_poka['serviceSegmentData']);
  2523.                                             unset($dt_poka['Products']);
  2524.                                             unset($dt_poka['Services']);
  2525.                                             $newData[$kho] = $newSingleSet;
  2526.                                         }
  2527.                                         $theDocData->setData(json_encode($newData));
  2528.                                         $em->persist($theDocData);
  2529.                                         $em->flush();
  2530.                                     }
  2531.                                     $tempId 0;
  2532.                                     if ($entityNameHere == 'SalesProposal'$tempId $the_actual_doc->getSalesProposalId();
  2533.                                     if ($entityNameHere == 'ProjectBoq'$tempId $the_actual_doc->getProjectId();
  2534.                                     if ($entityNameHere == 'Opportunity'$tempId $the_actual_doc->getOpportunityId();
  2535.                                     $configJson['debugData'][] = array(
  2536.                                         'entityNameHere' => $entityNameHere,
  2537.                                         'entityId' => $tempId,
  2538.                                         'dt' => $newData,
  2539.                                     );
  2540.                                 }
  2541.                                 $the_actual_doc->setData(null);
  2542.                                 $the_actual_doc->setDocumentDataId($theDocData->getId());
  2543.                                 $em->flush();
  2544.                                 if ($entityNameHere == 'ProjectBoq') {
  2545.                                     $theProj $em->getRepository('ApplicationBundle\\Entity\\Project')
  2546.                                         ->findOneBy(
  2547.                                             array(
  2548.                                                 'projectId' => $the_actual_doc->getProjectId()
  2549.                                             )
  2550.                                         );
  2551.                                     if ($theProj)
  2552.                                         $theProj->setDocumentDataId($the_actual_doc->getDocumentDataId());
  2553.                                     $em->flush();
  2554.                                 }
  2555.                             }
  2556.                         }
  2557.                     }
  2558.                     if ($request->query->get('newDocDataItemSegmentFix'0) == 1) {
  2559.                         $the_actual_docs $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2560.                             ->findBy(
  2561.                                 array(//                                        GeneralConstant::$Entity_id_field_list[$ent] => $entity_id,
  2562.                                 )
  2563.                             );
  2564.                         foreach ($the_actual_docs as $the_actual_doc) {
  2565.                             //now the data
  2566.                             //first find the docData if available
  2567.                             $theDocData $the_actual_doc;
  2568.                                 $data = [];
  2569.                                 $newData = [];
  2570.                                 $data json_decode($the_actual_doc->getData(), true);
  2571.                                 if ($data == null)
  2572.                                     $data = [];
  2573.                                 if (!empty($data)) {
  2574.                                     $last_key array_key_last($data);
  2575.                                     $lastIndex 0;
  2576.                                     foreach ($data as $kho => $dt_poka) {
  2577.                                         $newSingleSet $dt_poka;
  2578.                                         $newSegmentData = array();
  2579.                                         //unify the ids of segmnent. services will start from 1000+service segmentId for unification
  2580.                                         if (!isset($newSingleSet['itemSegmentData'])) {
  2581.                                             $newSingleSet['itemSegmentData'] = [];
  2582.                                         }
  2583.                                         if ($newSingleSet['itemSegmentData'] == null) {
  2584.                                             $newSingleSet['itemSegmentData'] = [];
  2585.                                         }
  2586.                                         if (empty($newSingleSet['itemSegmentData'])) {
  2587.                                             $gupu = [];
  2588.                                             $newModSeg $gupu;
  2589.                                             $newModSeg['index'] = 0;
  2590.                                             $newModSeg['title'] = 'Items & Services';
  2591.                                             $newModSeg['scfc'] = 0;
  2592.                                             $newModSeg['uomCust'] = '';
  2593.                                             $newModSeg['unitCust'] = isset($gupu['unitCust']) ? $gupu['unitCust'] : '';
  2594.                                             $newModSeg['priceCust'] = isset($gupu['priceCust']) ? $gupu['priceCust'] : '';
  2595.                                             $newModSeg['currCust'] = isset($gupu['currCust']) ? $gupu['currCust'] : '';
  2596.                                             $newModSeg['descCust'] = isset($gupu['descCust']) ? $gupu['descCust'] : '';
  2597.                                             $newModSeg['scope'] = isset($gupu['scope']) ? $gupu['scope'] : 0;
  2598.                                             $newModSeg['scopeId'] = isset($gupu['scopeId']) ? $gupu['scopeId'] : 0;
  2599.                                             $newModSeg['scopeName'] = isset($gupu['scopeName']) ? $gupu['scopeName'] : '';
  2600.                                             $newModSeg['scopeDescription'] = isset($gupu['scopeDescription']) ? $gupu['scopeDescription'] : '';
  2601.                                             $newSegmentData[] = $newModSeg;
  2602.                                             $newSingleSet['itemSegmentData'] = $newSegmentData;
  2603.                                         }
  2604.                                         $newData[$kho] = $newSingleSet;
  2605.                                     }
  2606.                                     $theDocData->setData(json_encode($newData));
  2607.                                     $em->persist($theDocData);
  2608.                                     $em->flush();
  2609.                                 }
  2610.                             $em->flush();
  2611.                         }
  2612.                     }
  2613.                     if ($request->query->get('convertMarginToMarkupOldDocumentData'0) == 1) {
  2614.                         $the_actual_docs $em->getRepository('ApplicationBundle\\Entity\\DocumentData')
  2615.                             ->findBy(
  2616.                                 array(//                                        GeneralConstant::$Entity_id_field_list[$ent] => $entity_id,
  2617.                                 )
  2618.                             );
  2619.                         foreach ($the_actual_docs as $the_actual_doc) {
  2620.                             //now the data
  2621.                             //first find the docData if available
  2622.                             $theDocData = [];
  2623.                             $theDocData json_decode($the_actual_doc->getData(), true);
  2624.                             if ($theDocData == null)
  2625.                                 $theDocData = [];
  2626.                             $entries $theDocData;
  2627.                             foreach ($entries as $jojo => $mod) {
  2628.                                 if (isset($mod['rowData'])) {
  2629.                                     $rows $mod['rowData'];
  2630.                                     if (is_string($rows))
  2631.                                         $rows json_decode($rowstrue);
  2632.                                     if ($rows == null)
  2633.                                         $rows = [];
  2634.                                     foreach ($rows as $indu => $row) {
  2635.                                         if (!is_numeric($row['unitSalesPrice'])) $row['unitSalesPrice'] = 0;
  2636.                                         if (!is_numeric($row['unitPrice'])) $row['unitPrice'] = 0;
  2637.                                         if (!is_numeric($row['marginAmount'])) $row['marginAmount'] = 0;
  2638.                                         if (!isset($row['markupRate'])) {
  2639.                                             $rows[$indu]['markupRate'] = $row['marginRate'];
  2640.                                         }
  2641.                                         $rows[$indu]['marginRate'] = $row['unitSalesPrice'] != 100 $row['marginAmount'] / $row['unitSalesPrice'] : 0;
  2642.                                     }
  2643.                                     $entries[$jojo]['rowData'] = $rows;
  2644.                                 }
  2645.                             }
  2646.                             $the_actual_doc->setData(json_encode($entries));
  2647. //                                $the_actual_doc->setDocumentDataId($theDocData->getId());
  2648.                             $em->flush();
  2649.                         }
  2650.                     }
  2651.                     if ($request->query->get('rectifyTransCurr'0) == 1) {
  2652.                         $query "
  2653.                                     UPDATE `acc_transaction_details` SET currency_multiply_rate=1 WHERE currency_multiply_rate is NULL or currency_multiply_rate=0 ;
  2654.                                     UPDATE `acc_transaction_details` SET currency_multiply=1 WHERE currency_multiply is NULL or currency_multiply=0 ;
  2655.                                     UPDATE `acc_transactions` SET currency_multiply_rate=1 WHERE currency_multiply_rate is NULL or currency_multiply_rate=0 ;
  2656.                                     UPDATE `acc_transactions` SET currency_multiply=1 WHERE currency_multiply is NULL or currency_multiply=0 ;
  2657.                                     UPDATE `expense_invoice` SET currency_multiply_rate=1 WHERE currency_multiply_rate is NULL or currency_multiply_rate=0 ;
  2658.                                     UPDATE `expense_invoice` SET currency_multiply=1 WHERE currency_multiply is NULL or currency_multiply=0 ;
  2659.   
  2660.                      
  2661.                       ";
  2662.                         $stmt $em->getConnection()->executeStatement($query);
  2663.                     }
  2664.                     if ($request->query->get('deepRefresh'0) == 1) {
  2665.                         //new for updating app id
  2666.                         $get_kids_sql "UPDATE `company` set app_id=" $entry['appId'] . " ;
  2667.                         UPDATE `sys_user` set app_id=" $entry['appId'] . " ;";
  2668.                         $get_kids_sql .= "
  2669.                                       UPDATE `inv_products` set default_color_id=0  where default_color_id ='' or default_color_id is null ;
  2670.                                       UPDATE `inv_products` set default_size=0  where default_size ='' or default_size is null ;
  2671.                                         UPDATE `inventory_storage` set color= (select default_color_id from inv_products where inv_products.id=inventory_storage.product_id)
  2672.                                          where inventory_storage.color =0 or inventory_storage.color is null or inventory_storage.color ='' ;
  2673.                                          UPDATE `inventory_storage` set owner_type= 0 where inventory_storage.owner_type is null or inventory_storage.owner_type ='' ;
  2674.                                          UPDATE `inventory_storage` set owner_id= 0 where inventory_storage.owner_id is null or inventory_storage.owner_id ='' ;
  2675.                                          UPDATE `acc_clients` set client_level= 1 where client_level is null or client_level ='' or client_level=0 ;
  2676.                                          UPDATE `acc_clients` set parent_id= 0 where parent_id is null or parent_id ='' ;
  2677.                                          UPDATE `sales_order` set sales_level= 0 where sales_level is null or sales_level ='' ;
  2678.                                          ";
  2679.                         $get_kids_sql .= "                UPDATE `inventory_storage` set color=0 where color='' or color is null;
  2680.                                         UPDATE `inventory_storage` set `size`=0 where `size`='' or size is null;
  2681.                                         UPDATE `inv_item_transaction` set color=0 where color='' or color is null;
  2682.                                         UPDATE `inv_item_transaction` set `size`=0 where `size`='' or size is null;
  2683.                                         UPDATE `inv_closing_balance` set color=0 where color='' or color is null;
  2684.                                         UPDATE `inv_closing_balance` set `size`=0 where `size`='' or size is null;
  2685.                                         UPDATE `sales_order_item` set `size_id`=(select default_size from inv_products where inv_products.id=sales_order_item.product_id ) where sales_order_item.product_id!=0 and (`size_id`='' or size_id is null);
  2686.                                         UPDATE `sales_order_item` set `color_id`=(select default_color_id from inv_products where inv_products.id=sales_order_item.product_id ) where sales_order_item.product_id!=0 and (`color_id`='' or color_id is null);
  2687.                                         UPDATE `delivery_receipt_item` set `size_id`=(select default_size from inv_products where inv_products.id=delivery_receipt_item.product_id ) where delivery_receipt_item.product_id!=0 and (`size_id`='' or size_id is null);
  2688.                                         UPDATE `delivery_receipt_item` set `color_id`=(select default_color_id from inv_products where inv_products.id=delivery_receipt_item.product_id ) where delivery_receipt_item.product_id!=0 and (`color_id`='' or color_id is null);
  2689.                                         UPDATE `delivery_order_item` set `size_id`=(select default_size from inv_products where inv_products.id=delivery_order_item.product_id ) where delivery_order_item.product_id!=0 and (`size_id`='' or size_id is null);
  2690.                                         UPDATE `delivery_order_item` set `color_id`=(select default_color_id from inv_products where inv_products.id=delivery_order_item.product_id ) where delivery_order_item.product_id!=0 and (`color_id`='' or color_id is null);
  2691.                                         UPDATE `sales_invoice_item` set `size_id`=(select default_size from inv_products where inv_products.id=sales_invoice_item.product_id ) where sales_invoice_item.product_id!=0 and (`size_id`='' or size_id is null);
  2692.                                         UPDATE `sales_invoice_item` set `color_id`=(select default_color_id from inv_products where inv_products.id=sales_invoice_item.product_id ) where sales_invoice_item.product_id!=0 and (`color_id`='' or color_id is null);
  2693.                                         UPDATE `inventory_storage` set curr_purchase_price= (select curr_purchase_price from inv_products where inv_products.id=inventory_storage.product_id)
  2694.                                          where inventory_storage.curr_purchase_price=0 or inventory_storage.curr_purchase_price is null;
  2695.                                        delete TABLE service_opearation;
  2696.                                        delete TABLE assesment_and_confirmation;
  2697.                                        ";
  2698.                         $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2699.                         $query "SELECT * from  company   where 1";
  2700.                         $stmt $em->getConnection()->fetchAllAssociative($query);
  2701. //                        
  2702.                         $results $stmt;
  2703.                         if (empty($results)) {
  2704.                             //insert client level query here
  2705.                             $createdDate = new \DateTime();
  2706.                             $cgEntry $gocEntryObjectList[$gocId];
  2707.                             $get_kids_sql "INSERT INTO `company` (`id`, `name`, `image`, `app_id`,  `created_at`,   `company_hash`, `company_unique_code`, `enabled_module_id_list`, `usage_valid_upto_date`,`active`) VALUES
  2708. (1, '" $cgEntry->getName() . "', '" $cgEntry->getImage() . "'," $cgEntry->getAppId() . ",'" $createdDate->format('Y-m-d H:i:s') . "', '" $cgEntry->getCompanyGroupHash() . "','" $cgEntry->getCompanyGroupUniqueCode() . "',NULL, NULL,1);";
  2709.                             $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2710.                         }
  2711.                         $query "SELECT * from  client_level   where 1";
  2712.                         $stmt $em->getConnection()->fetchAllAssociative($query);
  2713. //                        
  2714.                         $results $stmt;
  2715.                         if (empty($results)) {
  2716.                             //insert client level query here
  2717.                             $get_kids_sql "INSERT INTO `client_level` (`id`, `name`, `level_value`,`company_id`, `parent_level_id`, `status`, `created_at`, `updated_at`, `doc_booked_flag`, `time_stamp_of_form`) VALUES
  2718. (1, 'Primary',1, 1, 0, 1, '2022-02-22 20:58:51', NULL, NULL, NULL),
  2719. (2, 'Secondary',2, 1, 1, 1, '2022-02-22 20:58:51', NULL, NULL, NULL),
  2720. (3, 'Tertiary',3, 1, 2, 1, '2022-02-22 20:58:51', NULL, NULL, NULL)
  2721. ;";
  2722.                             $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2723. //                            
  2724.                         }
  2725.                         $query "SELECT * from  sales_level   where 1";
  2726.                         $stmt $em->getConnection()->fetchAllAssociative($query);
  2727.                         $results $stmt;
  2728.                         if (empty($results)) {
  2729.                             //insert client level query here
  2730.                             $get_kids_sql "INSERT INTO `sales_level` (`id`, `name`, `level_value`,`company_id`, `parent_level_id`, `status`, `created_at`, `updated_at`, `doc_booked_flag`, `time_stamp_of_form`) VALUES
  2731. (1, 'Primary',0, 1, 0, 1, '2022-02-22 20:58:51', NULL, NULL, NULL),
  2732. (2, 'Secondary',1, 1, 1, 1, '2022-02-22 20:58:51', NULL, NULL, NULL),
  2733. (3, 'Tertiary',2, 1, 2, 1, '2022-02-22 20:58:51', NULL, NULL, NULL);";
  2734.                             $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2735.                         }
  2736.                         $services $em->getRepository('ApplicationBundle\\Entity\\AccService')->findBy(array(
  2737. //                            'serviceId' => $ex_id//for now for stock of goods
  2738. //                    'opening_locked'=>0
  2739.                         ));
  2740.                         foreach ($services as $service) {
  2741.                             $productFdm $service->getProductFdm();
  2742.                             if (strpos($productFdm'P_') !== false)
  2743.                                 $productFdm str_replace('P_''P' $service->getServiceId() . '_'$productFdm);
  2744.                             $service->setProductFdm($productFdm);
  2745.                             $em->flush();
  2746.                         }
  2747.                         $query "SELECT * from  warehouse_action   where 1";
  2748.                         $stmt $em->getConnection()->fetchAllAssociative($query);
  2749.                         $results $stmt;
  2750.                         if (!empty($results)) {
  2751.                             //insert client level query here
  2752.                             foreach ($results as $qryResult) {
  2753.                                 $get_kids_sql "update `warehouse_action` set `accounts_head_id` =(select `data` from acc_setting where acc_setting.`name` like 'warehouse_action_" $qryResult['id'] . "') where id=" $qryResult['id'];
  2754.                                 $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2755.                             }
  2756.                         } else {
  2757.                             foreach (GeneralConstant::$warehouse_action_list as $dt_pika) {
  2758.                                 $get_kids_sql "INSERT INTO `warehouse_action` (`id`, `name`,`company_id`,  `status`, `created_at`, `updated_at`, `doc_booked_flag`, `time_stamp_of_form`)
  2759. VALUES(" $dt_pika['id'] . ", '" $dt_pika['name'] . "', 1, 1, '2022-02-22 20:58:51', NULL, NULL, NULL)";
  2760.                                 $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2761.                             }
  2762. //
  2763.                             $query "SELECT * from  warehouse_action   where 1";
  2764.                             $stmt $em->getConnection()->fetchAllAssociative($query);
  2765.                             $newresults $stmt;
  2766.                             foreach ($newresults as $qryResult) {
  2767.                                 $get_kids_sql "update `warehouse_action` set `accounts_head_id` =(select `data` from acc_setting where acc_setting.`name` like 'warehouse_action_" $qryResult['id'] . "') where id=" $qryResult['id'];
  2768.                                 $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2769.                             }
  2770.                         }
  2771.                         $modify_product_by_code_ids_table_list = [
  2772.                             'stock_transfer_item',
  2773.                         ];
  2774.                         $modify_product_by_code_ids_field_list = [
  2775.                             'product_by_code_ids'
  2776.                         ];
  2777.                         $modify_product_by_code_sales_code_field_list = [
  2778.                             'sales_code_range'
  2779.                         ];
  2780.                         $modify_product_by_code_item_id_field_list = [
  2781.                             'id'
  2782.                         ];
  2783.                         foreach ($modify_product_by_code_ids_table_list as $mindex => $dt_table_name) {
  2784.                             $get_kids_sql "select * from " $dt_table_name " where " .
  2785.                                 $modify_product_by_code_ids_field_list[$mindex] . " is null  or " .
  2786.                                 $modify_product_by_code_ids_field_list[$mindex] . " =''  or " .
  2787.                                 $modify_product_by_code_ids_field_list[$mindex] . " ='[]' ;";
  2788.                             $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql);
  2789.                             $dataList $stmt;
  2790.                             foreach ($dataList as $mdt) {
  2791.                                 $sales_code_range_str $mdt[$modify_product_by_code_sales_code_field_list[$mindex]];
  2792.                                 $sales_code_range = [];
  2793.                                 if (version_compare(PHP_VERSION'5.4.0''>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE 4)) {
  2794.                                     $sales_code_range json_decode($sales_code_range_strtrue512JSON_BIGINT_AS_STRING);
  2795.                                 } else {
  2796.                                     $max_int_length strlen((string)PHP_INT_MAX) - 1;
  2797.                                     $json_without_bigints preg_replace('/:\s*(-?\d{' $max_int_length ',})/'': "$1"'$sales_code_range_str);
  2798.                                     $sales_code_range json_decode($json_without_bigintstrue);
  2799.                                 }
  2800. //                    $sales_code_range= json_decode($entry->getSalesCodeRange(),true,512,JSON_BIGINT_AS_STRING);
  2801.                                 $pbcIds = [];
  2802.                                 if ($sales_code_range == null)
  2803.                                     $sales_code_range = [];
  2804.                                 if (empty($sales_code_range)) {
  2805.                                 } else {
  2806.                                     $get_kids_sql_2 "select * from  product_by_code  where sales_code in ('" implode("','"$sales_code_range) . "');";
  2807.                                     $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql_2);
  2808.                                     $dataList $stmt;
  2809.                                     foreach ($dataList as $pbc) {
  2810.                                         $pbcIds[] = $pbc['product_by_code_id'];
  2811.                                     }
  2812.                                 }
  2813.                                 $get_kids_sql_3 "update " $dt_table_name .
  2814.                                     " set  " $modify_product_by_code_ids_field_list[$mindex] . "='" json_encode($pbcIds) . "'" .
  2815.                                     " where " $modify_product_by_code_item_id_field_list[$mindex] . "=" $mdt[$modify_product_by_code_item_id_field_list[$mindex]] . ";";
  2816.                                 $stmt $em->getConnection()->executeStatement($get_kids_sql_3);
  2817.                             }
  2818.                         }
  2819.                         $modify_voucher_date_table_list = [
  2820. //                            'stock_received_note',
  2821. //                            'stock_transfer',
  2822. //                            'stock_consumption_note',
  2823. //                            'fixed_asset_conversion_note',
  2824. //                            'fixed_asset_product'
  2825.                         ];
  2826.                         $modify_date_field_list = [
  2827. //                            'stock_received_note_date',
  2828. //                            'stock_transfer_date',
  2829. //                            'stock_consumption_note_date',
  2830. //                            'fixed_asset_conversion_note_date',
  2831. //                            'fixed_asset_product'
  2832.                         ];
  2833.                         foreach ($modify_voucher_date_table_list as $mindex => $dt_table_name) {
  2834.                             $get_kids_sql "select * from " $dt_table_name " where 1;";
  2835.                             $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql);
  2836.                             $dataList $stmt;
  2837.                             foreach ($dataList as $mdt) {
  2838.                                 $curr_v_ids json_decode($mdt['voucher_ids'], true);
  2839.                                 if ($curr_v_ids == null)
  2840.                                     $curr_v_ids = [];
  2841.                                 $date_for_this $mdt[$modify_date_field_list[$mindex]];
  2842.                                 foreach ($curr_v_ids as $vid) {
  2843.                                     //new for updating app id
  2844.                                     $get_kids_sql "UPDATE `acc_transactions`
  2845.                                                           set transaction_date='" $date_for_this "',
  2846.                                                               ledger_hit_date='" $date_for_this "'
  2847.                                                           where transaction_id=" $vid ";
  2848.                                         UPDATE `acc_transactions_details`
  2849.                                                           set transaction_date='" $date_for_this "',
  2850.                                                               ledger_hit_date='" $date_for_this "'
  2851.                                                           where transaction_id=" $vid ";";
  2852.                                     $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2853.                                 }
  2854.                             }
  2855.                         }
  2856.                         $modify_voucher_narration_table_list = [
  2857. //                            'expense_invoice',
  2858. //                            'stock_transfer',
  2859. //                            'stock_consumption_note',
  2860. //                            'fixed_asset_conversion_note',
  2861. //                            'fixed_asset_product'
  2862.                         ];
  2863.                         $modify_narr_field_list = [
  2864. //                            'description',
  2865. //                            'stock_transfer_date',
  2866. //                            'stock_consumption_note_date',
  2867. //                            'fixed_asset_conversion_note_date',
  2868. //                            'fixed_asset_product'
  2869.                         ];
  2870.                         foreach ($modify_voucher_narration_table_list as $mindex => $dt_table_name) {
  2871.                             $get_kids_sql "select * from " $dt_table_name " where 1;";
  2872.                             $stmt $em->getConnection()->fetchAllAssociative($get_kids_sql);
  2873.                             $dataList $stmt;
  2874.                             foreach ($dataList as $mdt) {
  2875.                                 $curr_v_ids json_decode($mdt['voucher_ids'], true);
  2876.                                 if ($curr_v_ids == null)
  2877.                                     $curr_v_ids = [];
  2878.                                 $narr_for_this $mdt[$modify_narr_field_list[$mindex]];
  2879.                                 foreach ($curr_v_ids as $vid) {
  2880.                                     //new for updating app id
  2881.                                     $get_kids_sql "UPDATE `acc_transactions`
  2882.                                                           set description='" $narr_for_this "'
  2883.                                                           where transaction_id=" $vid "; ";
  2884.                                     $stmt $em->getConnection()->executeStatement($get_kids_sql);
  2885.                                 }
  2886.                             }
  2887.                         }
  2888.                     }
  2889.                     if ($request->query->get('employeeDetailsToProfile'0) == 1) {
  2890.                         $migrationStats $this->migrateEmployeeDetailsToProfile($em);
  2891.                         $configJson['employeeDetailsToProfile'] = $migrationStats;
  2892.                     }
  2893.                     $get_kids_sql "update `company_group` set `schema_update_pending_flag` =0 where `id`=$gocId;";
  2894.                     $stmt $em_goc->getConnection()->executeStatement($get_kids_sql);
  2895.                     $configJson['success'] = true;
  2896.                     //this is for large amount of goc we will see  later
  2897. //                        file_put_contents($path, json_encode($configJson));//overwrite
  2898. //                        return $this->redirectToRoute('update_database_schema');
  2899.                 }
  2900.             }
  2901.             return new JsonResponse($configJson);
  2902.         } else {
  2903.             return $this->render(
  2904.                 '@System/pages/server_actions.html.twig',
  2905.                 $dtHere
  2906.             );
  2907.         }
  2908.     }
  2909.     public function UpdateRoutesAction(Request $request)
  2910.     {
  2911.         $message "";
  2912.         $gocList = [];
  2913.         $outputList = [];
  2914.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  2915.         $appIdFilter = (int)$request->get('appId'$request->get('app_id'0));
  2916.         $em $this->getDoctrine()->getManager('company_group');
  2917.         $em->getConnection()->connect();
  2918.         $connected $em->getConnection()->isConnected();
  2919.         if ($connected)
  2920.             if ($systemType != '_CENTRAL_') {
  2921.                 $findByQuery = array(
  2922.                     'active' => 1
  2923.                 );
  2924.                 if ($appIdFilter 0) {
  2925.                     $findByQuery['appId'] = $appIdFilter;
  2926.                 }
  2927.                 $gocList $this->getDoctrine()->getManager('company_group')
  2928.                     ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  2929.                     ->findBy($findByQuery);
  2930.             }
  2931.         $gocDataList = [];
  2932.         foreach ($gocList as $entry) {
  2933.             $d = array(
  2934.                 'name' => $entry->getName(),
  2935.                 'id' => $entry->getId(),
  2936.                 'dbName' => $entry->getDbName(),
  2937.                 'dbUser' => $entry->getDbUser(),
  2938.                 'dbPass' => $entry->getDbPass(),
  2939.                 'dbHost' => $entry->getDbHost(),
  2940.                 'appId' => $entry->getAppId(),
  2941.                 'companyRemaining' => $entry->getCompanyRemaining(),
  2942.                 'companyAllowed' => $entry->getCompanyAllowed(),
  2943.                 'enabledModuleIdList' => $entry->getEnabledModuleIdList(),
  2944.             );
  2945.             $gocDataList[$entry->getId()] = $d;
  2946.         }
  2947.         $gocDbName '';
  2948.         $gocDbUser '';
  2949.         $gocDbPass '';
  2950.         $gocDbHost '';
  2951.         $gocId 0;
  2952. //        $path = $this->container->get('templating.helper.assets')->getUrl('bundles/tlfront/js/channels.json');
  2953.         $config_dir $this->container->getParameter('kernel.root_dir') . '/gifnoc/';
  2954.         if (!file_exists($config_dir)) {
  2955.             mkdir($config_dir0777true);
  2956.         }
  2957. //        $path = $this->container->getParameter('kernel.root_dir') . '/gifnoc/givnocppa.json';
  2958. //        $content = file_exists($path) ? file_get_contents($path) : null;
  2959.         $content = [];
  2960.         $configJson = array();
  2961.         if ($content)
  2962.             $configJson json_decode($contenttrue);
  2963.         $configJsonOld $configJson;
  2964. //        if($configJson)
  2965. //        {
  2966. //
  2967. //        }
  2968. //        else
  2969.         {
  2970.             $configJson['appVersion'] = GeneralConstant::ENTITY_APP_VERSION;
  2971.             $configJson['dataBaseSchemaUpdateFlag'] = GeneralConstant::ENTITY_APP_FLAG_TRUE;
  2972.             $configJson['initiateDataBaseFlag'] = GeneralConstant::ENTITY_APP_FLAG_FALSE;
  2973.             $configJson['initiateDataBaseFlagByGoc'] = array();
  2974.             $configJson['motherLode'] = "http://innobd.com";
  2975.             foreach ($gocDataList as $gocId => $entry) {
  2976.                 $configJson['initiateDataBaseFlagByGoc'][$gocId "_" $entry['appId']] = GeneralConstant::ENTITY_APP_FLAG_TRUE;
  2977.             }
  2978.         }
  2979.         //now check if database shcema update is true
  2980. //        if($configJson['dataBaseSchemaUpdateFlag']==GeneralConstant::ENTITY_APP_FLAG_TRUE)
  2981.         if (1//temporary overwrite all
  2982.         {
  2983.             //if goclist is not empty switch to each company dbase and schema update
  2984. //            if(!empty($gocDataList))
  2985.             if (1) {
  2986.                 foreach ($gocDataList as $gocId => $entry) {
  2987.                     if ($configJson['initiateDataBaseFlagByGoc'][$gocId "_" $entry['appId']] == GeneralConstant::ENTITY_APP_FLAG_TRUE) {
  2988.                         // OWNER-HIT (2026-07-31, dev): ONE husk registry row (app_id NULL,
  2989.                         // db_name NULL) 500'd this whole action — and because this loop fans out
  2990.                         // to EVERY tenant, a husk anywhere would kill the route sync for every
  2991.                         // tenant after it. Skip-and-log an unconnectable row; never die on it.
  2992.                         if (empty($gocDataList[$gocId]['dbName']) || empty($gocDataList[$gocId]['dbUser'])) {
  2993.                             error_log('[update_routes] skipping registry row goc=' $gocId
  2994.                                 ' — no db_name/db_user (husk row; clean the registry).');
  2995.                             continue;
  2996.                         }
  2997.                         $connector $this->container->get('application_connector');
  2998.                         $connector->resetConnection(
  2999.                             'default',
  3000.                             $gocDataList[$gocId]['dbName'],
  3001.                             $gocDataList[$gocId]['dbUser'],
  3002.                             $gocDataList[$gocId]['dbPass'],
  3003.                             $gocDataList[$gocId]['dbHost'],
  3004.                             $reset true);
  3005.                         $em $this->getDoctrine()->getManager();
  3006. //                        $iv = '1234567812345678';
  3007. //                        $pass = $hash;
  3008. //
  3009. //                        $str = $str . 'YmLRocksLikeABoss';
  3010. //                        $data = openssl_encrypt($str, "AES-128-CBC", $pass, OPENSSL_RAW_DATA, $iv);
  3011. //
  3012. //                        $decrypted = openssl_decrypt(base64_decode(base64_encode($data)), "AES-128-CBC", $hash, OPENSSL_RAW_DATA, $iv);
  3013. //
  3014.                         //now 1st of all lets get the Existing routes
  3015.                         $extRoutesById = [];
  3016.                         $extRoutesByRoute = [];
  3017.                         $modules $em->getRepository("ApplicationBundle\\Entity\\SysModule")
  3018.                             ->findBy(
  3019.                                 array()
  3020.                             );
  3021.                         $module_data = [];
  3022.                         foreach ($modules as $mod) {
  3023.                             $dt = array(
  3024.                                 'id' => $mod->getModuleId(),
  3025.                                 'route' => $mod->getModuleRoute(),
  3026.                                 'name' => $mod->getModuleName(),
  3027.                                 'parentId' => $mod->getParentId(),
  3028.                                 'level' => $mod->getLevel(),
  3029.                                 'eFA' => $mod->getEnabledForAll(),
  3030.                             );
  3031.                             $extRoutesById[$mod->getModuleId()] = $dt;
  3032.                             $extRoutesByRoute[$mod->getModuleRoute()] = $dt;
  3033.                         }
  3034.                         //now clear the module table
  3035.                         $get_kids_sql "truncate `sys_module` ; ";
  3036.                         $stmt $em->getConnection()->executeStatement($get_kids_sql);
  3037.                         $enabledModuleIds $this->getEnabledModuleIdsForCompanyRouteSync($entry$systemType);
  3038.                         $newRoutes $this->filterModuleRoutesForCompany($enabledModuleIds);
  3039.                         $newRoutesByRoute = [];
  3040.                         foreach ($newRoutes as $mod) {
  3041.                             $new = new SysModule();
  3042.                             $new->setModuleId($mod['id']);
  3043.                             $new->setModuleRoute($mod['route']);
  3044.                             $new->setModuleName($mod['name']);
  3045.                             $new->setParentId($mod['parentId']);
  3046.                             $new->setlevel($mod['level']);
  3047.                             $new->setEnabledForAll($mod['eFA']);
  3048.                             $new->setStatus(isset($mod['status']) ? $mod['status'] : GeneralConstant::ACTIVE);
  3049. //                $new->set(GeneralConstant::ACTIVE);
  3050.                             $em->persist($new);
  3051.                             $newRoutesByRoute[$mod['route']] = $mod;
  3052.                         }
  3053.                         $em->flush();
  3054.                         //now lets get the ext modules for positions
  3055.                         $depPosDefModules $em->getRepository("ApplicationBundle\\Entity\\SysDeptPositionDefaultModule")
  3056.                             ->findBy(
  3057.                                 array()
  3058.                             );
  3059.                         foreach ($depPosDefModules as $defmod) {
  3060.                             $moduleList json_decode($defmod->getModuleIds());
  3061.                             $newModuleList = [];
  3062.                             foreach ($moduleList as $oldId) {
  3063.                                 $newId 0;
  3064.                                 if (isset($extRoutesById[$oldId])) {
  3065.                                     if (isset($newRoutesByRoute[$extRoutesById[$oldId]['route']])) {
  3066.                                         $newModuleList[] = $newRoutesByRoute[$extRoutesById[$oldId]['route']]['id'];
  3067.                                     }
  3068.                                 }
  3069.                             }
  3070.                             $defmod->setModuleIds(json_encode($newModuleList));
  3071.                             $em->flush();
  3072.                         }
  3073.                         //now users
  3074.                         $users $em->getRepository("ApplicationBundle\\Entity\\SysUser")
  3075.                             ->findBy(
  3076.                                 array()
  3077.                             );
  3078.                         foreach ($users as $defmod) {
  3079.                             $moduleList json_decode($defmod->getModuleIds());
  3080.                             if ($moduleList == null)
  3081.                                 continue;
  3082.                             $newModuleList = [];
  3083.                             foreach ($moduleList as $oldId) {
  3084.                                 $newId 0;
  3085.                                 if (isset($extRoutesById[$oldId])) {
  3086.                                     if (isset($newRoutesByRoute[$extRoutesById[$oldId]['route']])) {
  3087.                                         $newModuleList[] = $newRoutesByRoute[$extRoutesById[$oldId]['route']]['id'];
  3088.                                     }
  3089.                                 }
  3090.                             }
  3091.                             $defmod->setModuleIds(json_encode($newModuleList));
  3092.                             $em->flush();
  3093.                         }
  3094.                         $module_data = [];
  3095. //                        $tool = new SchemaTool($em);
  3096. //
  3097. //                        $classes = $em->getMetadataFactory()->getAllMetadata();
  3098. ////                    $tool->createSchema($classes);
  3099. //                        $tool->updateSchema($classes);
  3100. //
  3101. //                        //new for updating app id
  3102. //                        $get_kids_sql = "UPDATE `company` set app_id=".$entry['appId']." ;
  3103. //                                        UPDATE `sys_user` set app_id=".$entry['appId']." ;";
  3104. //                        $stmt = $em->getConnection()->executeStatement($get_kids_sql);
  3105. //                        
  3106. //                        
  3107. //
  3108. //                        $configJson['initiateDataBaseFlagByGoc'][$gocId."_".$entry['appId']]=GeneralConstant::ENTITY_APP_FLAG_FALSE;
  3109.                         //this is for large amount of goc we will see  later
  3110. //                        file_put_contents($path, json_encode($configJson));//overwrite
  3111. //                        return $this->redirectToRoute('update_database_schema');
  3112.                     }
  3113.                 }
  3114.             } else {
  3115.                 $em $this->getDoctrine()->getManager();
  3116.                 $tool = new SchemaTool($em);
  3117. //                    $classes = array(
  3118. //                        $em->getClassMetadata('Entities\User'),
  3119. //                        $em->getClassMetadata('Entities\Profile')
  3120. //                    );
  3121.                 $classes $em->getMetadataFactory()->getAllMetadata();
  3122. //                    $tool->createSchema($classes);
  3123.                 $tool->updateSchema($classes);
  3124.             }
  3125.         }
  3126.         $allSchemaUpdateDone 1;
  3127.         foreach ($configJson['initiateDataBaseFlagByGoc'] as $flag) {
  3128.             if ($flag == GeneralConstant::ENTITY_APP_FLAG_TRUE)
  3129.                 $allSchemaUpdateDone 0;
  3130.         }
  3131.         if ($allSchemaUpdateDone == 1)
  3132.             $configJson['dataBaseSchemaUpdateFlag'] = GeneralConstant::ENTITY_APP_FLAG_FALSE;
  3133.         ///last
  3134. //        file_put_contents($path, json_encode($configJson));//overwrite
  3135.         return new Response(json_encode($configJsonOld));
  3136.     }
  3137.     public function CheckTimeStampAction(Request $request)
  3138.     {
  3139.         $message "";
  3140.         $gocList = [];
  3141.         $outputList = [];
  3142.         $toConvertDateStrFromQry $request->query->get('convDate''');
  3143.         $currentRegionalDateStrFromQry $request->query->get('currDate''');
  3144.         $convertedTime MiscActions::ConvertRegionalTimeToServerTime($currentRegionalDateStrFromQry$toConvertDateStrFromQry);
  3145.         $currentServerTime = new \DateTime();
  3146.         $em $this->getDoctrine()->getManager('company_group');
  3147.         $em->getConnection()->connect();
  3148.         ///last
  3149. //        file_put_contents($path, json_encode($configJson));//overwrite
  3150.         return new Response(json_encode(array(
  3151.             'convertedTime' => $convertedTime->format('Y-m-d h:i:s'),
  3152.             'convertedTimeUnix' => $convertedTime->format('U'),
  3153.             'convertedTimeRFC' => $convertedTime->format(DATE_RFC822),
  3154.             'currentServerTime' => $currentServerTime->format('Y-m-d h:i:s'),
  3155.             'currentServerTimeRFC' => $currentServerTime->format(DATE_RFC822),
  3156.             'currentServerTimeUnix' => $currentServerTime->format('U'),
  3157.         )));
  3158.     }
  3159.     public function GetUsersFromCentralServerAction(Request $request$id 0)
  3160.     {
  3161.     }
  3162.     public function UpdateCompanyDataToCentralServerAction(Request $request$id 0)
  3163.     {
  3164.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  3165.         $post $request;
  3166.         $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') : []);
  3167.         if ($systemType == '_CENTRAL_') {
  3168.             $em_goc $this->getDoctrine()->getManager('company_group');
  3169.             //            'company_id' => $company->getId(),
  3170.             //                            'app_id' => $entry['appId'],
  3171.             //                            'dark_vibrant' => $company->getDarkVibrant(),
  3172.             //                            'light_vibrant' => $company->getLightVibrant(),
  3173.             //                            'vibrant' => $company->getVibrant(),
  3174.             //                            'company_type' => $company->getCompanyType(),
  3175.             //                            'company_name' => $company->getName(),
  3176.             //                            'company_address' => $company->getAddress(),
  3177.             //                            'company_s_address' => $company->getShippingAddress(),
  3178.             //                            'company_b_address' => $company->getBillingAddress(),
  3179.             //                            'company_image' => $company->getImage(),
  3180.             //                            'company_motto' => $company->getMotto(),
  3181.             //                            'company_i_footer' => $company->getInvoiceFooter(),
  3182.             //                            'company_g_footer' => $company->getGeneralFooter(),
  3183.             //                            'company_tin' => $company->getCompanyTin(),
  3184.             //                            'company_bin' => $company->getCompanyBin(),
  3185.             //                            'company_reg' => $company->getCompanyReg(),
  3186.             //                            'company_tl' => $company->getCompanyTl(),
  3187.             //                            'sms_enabled' => $company->getSmsNotificationEnabled(),
  3188.             //                            'sms_settings' => $company->getSmsSettings(),
  3189.             //                            'file'=>$output
  3190.             $findByQuery = array(
  3191. //                'active' => 1
  3192.                 'appId' => $post->get('app_id')
  3193.             );
  3194.             $goc $em_goc->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3195.                 ->findOneBy($findByQuery);
  3196.             if (!$goc)
  3197.                 $goc = new CompanyGroup();
  3198.             $goc->setName($post->get('company_name'));
  3199.             $goc->setAppId($post->get('app_id'));
  3200. //            $goc->setCompanyType($post->get('company_type'));
  3201.             $goc->setAddress($post->get('address'));
  3202. //            $goc->setDarkVibrant($post->get('dark_vibrant'));
  3203. //            $goc->setLightVibrant($post->get('light_vibrant'));
  3204. //            $goc->setVibrant($post->get('vibrant'));
  3205.             $goc->setShippingAddress($post->get('s_address'));
  3206.             $goc->setBillingAddress($post->get('b_address'));
  3207.             $goc->setMotto($post->get('motto'));
  3208.             $goc->setInvoiceFooter($post->get('i_footer'));
  3209.             $goc->setGeneralFooter($post->get('g_footer'));
  3210.             $goc->setCompanyReg($post->get('company_reg'''));
  3211.             $goc->setCompanyTin($post->get('company_tin'''));
  3212.             $goc->setCompanyBin($post->get('company_bin'''));
  3213.             $goc->setCompanyTl($post->get('company_tl'''));
  3214.             $goc->setCompanyGroupServerId($post->get('companyGroupServerId'''));
  3215.             $goc->setCompanyGroupServerAddress($post->get('companyGroupServerAddress'''));
  3216.             $goc->setCompanyGroupServerPort($post->get('companyGroupServerPort'''));
  3217.             $goc->setCompanyGroupServerHash($post->get('companyGroupServerHash'''));
  3218. //            $goc->setSmsNotificationEnabled($post->get('sms_enabled'));
  3219. //            $goc->setSmsSettings($post->get('sms_settings'));
  3220.             foreach ($request->files as $uploadedFile) {
  3221. //            if($uploadedFile->getImage())
  3222. //                var_dump($uploadedFile->getFile());
  3223. //                var_dump($uploadedFile);
  3224.                 if ($uploadedFile != null) {
  3225.                     $fileName 'company_image' $post->get('app_id') . '.' $uploadedFile->guessExtension();
  3226.                     $path $fileName;
  3227.                     $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/';
  3228.                     if ($goc->getImage() != null && $goc->getImage() != '' && file_exists($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage())) {
  3229.                         unlink($this->container->getParameter('kernel.root_dir') . '/../web' $goc->getImage());
  3230.                     }
  3231.                     if (!file_exists($upl_dir)) {
  3232.                         mkdir($upl_dir0777true);
  3233.                     }
  3234.                     $file $uploadedFile->move($upl_dir$path);
  3235.                     if ($path != "")
  3236.                         $goc->setImage('/uploads/CompanyImage/' $path);
  3237.                 }
  3238.             }
  3239.             $em_goc->persist($goc);
  3240.             $em_goc->flush();
  3241.             return new JsonResponse([]);
  3242.         } else {
  3243.             $em $this->getDoctrine()->getManager('company_group');
  3244.             $em->getConnection()->connect();
  3245.             $connected $em->getConnection()->isConnected();
  3246.             $gocDataList = [];
  3247.             if ($connected) {
  3248.                 $findByQuery = array(
  3249.                     'active' => 1
  3250.                 );
  3251.                 $gocList $this->getDoctrine()->getManager('company_group')
  3252.                     ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3253.                     ->findBy($findByQuery);
  3254.                 foreach ($gocList as $entry) {
  3255.                     $d = array(
  3256.                         'name' => $entry->getName(),
  3257.                         'id' => $entry->getId(),
  3258.                         'image' => $entry->getImage(),
  3259.                         'companyGroupHash' => $entry->getCompanyGroupHash(),
  3260.                         'companyGroupServerId' => $entry->getCompanyGroupServerId(),
  3261.                         'dbName' => $entry->getDbName(),
  3262.                         'dbUser' => $entry->getDbUser(),
  3263.                         'dbPass' => $entry->getDbPass(),
  3264.                         'dbHost' => $entry->getDbHost(),
  3265.                         'appId' => $entry->getAppId(),
  3266.                         'companyRemaining' => $entry->getCompanyRemaining(),
  3267.                         'companyAllowed' => $entry->getCompanyAllowed(),
  3268.                         'enabledModuleIdList' => $entry->getEnabledModuleIdList(),
  3269.                     );
  3270.                     $gocDataList[$entry->getId()] = $d;
  3271.                 }
  3272.                 foreach ($gocDataList as $gocId => $entry) {
  3273.                     $connector $this->container->get('application_connector');
  3274.                     $connector->resetConnection(
  3275.                         'default',
  3276.                         $gocDataList[$gocId]['dbName'],
  3277.                         $gocDataList[$gocId]['dbUser'],
  3278.                         $gocDataList[$gocId]['dbPass'],
  3279.                         $gocDataList[$gocId]['dbHost'],
  3280.                         $reset true);
  3281.                     $em $this->getDoctrine()->getManager();
  3282.                     $company $this->getDoctrine()
  3283.                         ->getRepository('ApplicationBundle\\Entity\\Company')
  3284.                         ->findOneBy(
  3285.                             array()
  3286.                         );
  3287.                     $output '';
  3288.                     $file $this->container->getParameter('kernel.root_dir') . '/../web' $company->getImage(); //<-- Path could be relative
  3289.                     if (file_exists($file)) {
  3290. //                        $file = new \CURLFile($this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/' . $company->getImage()); //<-- Path could be relative
  3291.                         $mime mime_content_type($file);
  3292.                         $info pathinfo($file);
  3293.                         $name $info['basename'];
  3294.                         if (strpos($mime'image') !== false) {
  3295.                             $output = new \CURLFile($file$mime$name);
  3296.                         }
  3297.                     }
  3298.                     $post_fields = array(
  3299.                         'company_id' => $company->getId(),
  3300.                         'app_id' => $entry['appId'],
  3301.                         'dark_vibrant' => $company->getDarkVibrant(),
  3302.                         'light_vibrant' => $company->getLightVibrant(),
  3303.                         'vibrant' => $company->getVibrant(),
  3304.                         'company_type' => $company->getCompanyType(),
  3305.                         'company_name' => $company->getName(),
  3306.                         'address' => $company->getAddress(),
  3307.                         's_address' => $company->getShippingAddress(),
  3308.                         'b_address' => $company->getBillingAddress(),
  3309.                         'company_image' => $company->getImage(),
  3310.                         'motto' => $company->getMotto(),
  3311.                         'i_footer' => $company->getInvoiceFooter(),
  3312.                         'g_footer' => $company->getGeneralFooter(),
  3313.                         'company_tin' => $company->getCompanyTin(),
  3314.                         'company_bin' => $company->getCompanyBin(),
  3315.                         'company_reg' => $company->getCompanyReg(),
  3316.                         'company_tl' => $company->getCompanyTl(),
  3317.                         'sms_enabled' => $company->getSmsNotificationEnabled(),
  3318.                         'sms_settings' => $company->getSmsSettings(),
  3319.                         'companyGroupHash' => $company->getCompanyHash(),
  3320.                         'currentSubscriptionPackageId' => $company->getCurrentSubscriptionPackageId(),
  3321.                         'companyGroupServerId' => $entry['companyGroupServerId'],
  3322.                         'companyGroupServerAddress' => $serverList[$entry['companyGroupServerId']]['absoluteUrl'],
  3323.                         'companyGroupServerHash' => $serverList[$entry['companyGroupServerId']]['serverMarker'],
  3324.                         'companyGroupServerPort' => $request->server->get("SERVER_PORT"),
  3325.                         'file' => $output
  3326.                     );
  3327.                     $urlToCall GeneralConstant::HONEYBEE_CENTRAL_SERVER '/UpdateCompanyDataToCentralServer';
  3328.                     $curl curl_init();
  3329.                     curl_setopt_array($curl, array(
  3330.                         CURLOPT_RETURNTRANSFER => 1,
  3331.                         CURLOPT_POST => 1,
  3332.                         CURLOPT_URL => $urlToCall,
  3333.                         CURLOPT_CONNECTTIMEOUT => 10,
  3334.                         CURLOPT_SSL_VERIFYPEER => false,
  3335.                         CURLOPT_SSL_VERIFYHOST => false,
  3336.                         CURLOPT_HTTPHEADER => array(),
  3337.                         CURLOPT_POSTFIELDS => $post_fields
  3338.                     ));
  3339.                     $retData curl_exec($curl);
  3340.                     $errData curl_error($curl);
  3341.                     curl_close($curl);
  3342.                 }
  3343.             }
  3344.             return new JsonResponse([]);
  3345.         }
  3346.     }
  3347.     public function GetAppListFromCentralServerAction(Request $request$id 0)
  3348.     {
  3349.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  3350.         $appIds $request->get('appIds', []);
  3351.         $appId $request->get('appId'0);
  3352.         if (is_string($appIds)) $appIds json_decode($appIdstrue);
  3353.         if ($appIds == null$appIds = [];
  3354.         if ($appId != 0)
  3355.             $appIds[] = $appId;
  3356.         if ($systemType == '_CENTRAL_') {
  3357.             $em $this->getDoctrine()->getManager('company_group');
  3358.             $em->getConnection()->connect();
  3359.             $connected $em->getConnection()->isConnected();
  3360.             $gocDataList = [];
  3361.             if ($connected) {
  3362.                 $findByQuery = array(
  3363.                     'active' => 1
  3364.                 );
  3365.                 if ($appIds != '_ALL_' && $appIds != [])
  3366.                     $findByQuery['appId'] = $appIds;
  3367.                 $gocList $this->getDoctrine()->getManager('company_group')
  3368.                     ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3369.                     ->findBy($findByQuery);
  3370.                 foreach ($gocList as $entry) {
  3371.                     $d = array(
  3372.                         'name' => $entry->getName(),
  3373.                         'id' => $entry->getId(),
  3374.                         'image' => $entry->getImage(),
  3375.                         'companyGroupHash' => $entry->getCompanyGroupHash(),
  3376.                         'dbName' => $entry->getDbName(),
  3377.                         'dbUser' => $entry->getDbUser(),
  3378.                         'dbPass' => $entry->getDbPass(),
  3379.                         'dbHost' => $entry->getDbHost(),
  3380.                         'appId' => $entry->getAppId(),
  3381.                         'companyRemaining' => $entry->getCompanyRemaining(),
  3382.                         'companyAllowed' => $entry->getCompanyAllowed(),
  3383.                     );
  3384.                     $gocDataList[$entry->getId()] = $d;
  3385.                 }
  3386.             }
  3387.             return new JsonResponse($gocDataList);
  3388.         } else {
  3389.             $urlToCall GeneralConstant::HONEYBEE_CENTRAL_SERVER '/GetAppListFromCentralServer';
  3390.             $curl curl_init();
  3391.             curl_setopt_array($curl, array(
  3392.                 CURLOPT_RETURNTRANSFER => 1,
  3393.                 CURLOPT_URL => $urlToCall,
  3394.                 CURLOPT_CONNECTTIMEOUT => 10,
  3395.                 CURLOPT_SSL_VERIFYPEER => false,
  3396.                 CURLOPT_SSL_VERIFYHOST => false,
  3397.                 CURLOPT_HTTPHEADER => array(
  3398.                     "Accept: application/json",
  3399.                 ),
  3400.                 //                        CURLOPT_USERAGENT => 'InnoPM',
  3401.                 CURLOPT_POSTFIELDS => http_build_query([
  3402.                     'appIds' => $appIds
  3403.                 ])
  3404.             ));
  3405. //        $headers = array(
  3406. //            "Accept: application/json",
  3407. //        );
  3408. //        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  3409. ////for debug only!
  3410. //        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  3411. //        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  3412.             $retData curl_exec($curl);
  3413.             $errData curl_error($curl);
  3414.             curl_close($curl);
  3415.             return new JsonResponse(json_decode($retDatatrue));
  3416.         }
  3417.     }
  3418.     public function GetTaskListForMenuAction(Request $request$id 0)
  3419.     {
  3420.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  3421.         $session $request->getSession();
  3422.         $appIds $request->get('appIds', []);
  3423.         $appId $request->get('appId'0);
  3424.         if (is_string($appIds)) $appIds json_decode($appIdstrue);
  3425.         if ($appIds == null$appIds = [];
  3426.         if ($appId != 0)
  3427.             $appIds[] = $appId;
  3428.         if ($systemType == '_CENTRAL_') {
  3429.             $em $this->getDoctrine()->getManager('company_group');
  3430.             $em->getConnection()->connect();
  3431.             $connected $em->getConnection()->isConnected();
  3432.             $gocDataList = [];
  3433.             if ($connected) {
  3434.                 $findByQuery = array(
  3435.                     'active' => 1
  3436.                 );
  3437.                 if ($appIds != '_ALL_' && $appIds != [])
  3438.                     $findByQuery['appId'] = $appIds;
  3439.                 $gocList $this->getDoctrine()->getManager('company_group')
  3440.                     ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3441.                     ->findBy($findByQuery);
  3442.                 foreach ($gocList as $entry) {
  3443.                     $d = array(
  3444.                         'name' => $entry->getName(),
  3445.                         'id' => $entry->getId(),
  3446.                         'image' => $entry->getImage(),
  3447.                         'companyGroupHash' => $entry->getCompanyGroupHash(),
  3448.                         'dbName' => $entry->getDbName(),
  3449.                         'dbUser' => $entry->getDbUser(),
  3450.                         'dbPass' => $entry->getDbPass(),
  3451.                         'dbHost' => $entry->getDbHost(),
  3452.                         'appId' => $entry->getAppId(),
  3453.                         'companyRemaining' => $entry->getCompanyRemaining(),
  3454.                         'companyAllowed' => $entry->getCompanyAllowed(),
  3455.                     );
  3456.                     $gocDataList[$entry->getId()] = $d;
  3457.                 }
  3458.             }
  3459.             return new JsonResponse($gocDataList);
  3460.         } else {
  3461.             $findByQuery = array(
  3462.                 'userId' => $session->get(UserConstants::USER_ID0)
  3463.             );
  3464.             $employee $this->getDoctrine()->getManager()
  3465.                 ->getRepository("ApplicationBundle\\Entity\\Employee")
  3466.                 ->findOneBy($findByQuery);
  3467.             $assignedTaskList = array();
  3468.             $currentlyWorkingTaskList = array();
  3469.             if ($employee) {
  3470.                 $findByQuery = array(
  3471.                     'assignedTo' => $employee->getEmployeeId(),
  3472.                     'hasChild' => [0null]
  3473.                 );
  3474.                 $assignedTaskListData $this->getDoctrine()->getManager()
  3475.                     ->getRepository("ApplicationBundle\\Entity\\PlanningItem")
  3476.                     ->findBy($findByQuery);
  3477.                 $findByQuery = array(
  3478.                     'employeeId' => $employee->getEmployeeId(),
  3479.                 );
  3480.                 $currentlyWorkingTaskListData $this->getDoctrine()->getManager()
  3481.                     ->getRepository("ApplicationBundle\\Entity\\TaskLog")
  3482.                     ->findBy($findByQuery);
  3483.                 foreach ($assignedTaskListData as $entry) {
  3484.                     $dt = array(
  3485.                         'description' => $entry->getDescription(),
  3486.                         'urgency' => $entry->getUrgency()
  3487.                     );
  3488.                     $assignedTaskList[] = $dt;
  3489.                 }
  3490.                 foreach ($currentlyWorkingTaskListData as $entry) {
  3491.                     $dt = array();
  3492.                     $currentlyWorkingTaskList[] = $dt;
  3493.                 }
  3494.             }
  3495.             return new JsonResponse(array(
  3496.                 'assignedTaskList' => $assignedTaskList,
  3497.                 'currentlyWorkingTaskList' => $currentlyWorkingTaskList,
  3498.             ));
  3499.         }
  3500.     }
  3501.     public function SyncUserToCentralUserAction(Request $request)
  3502.     {
  3503.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  3504.         $post $request;
  3505.         $globalIdsByAppIdAndUser = [];
  3506.         if ($systemType == '_CENTRAL_') {
  3507.             $userDataList $request->get('userData', []);
  3508.             if (is_string($userDataList)) $userDataList json_decode($userDataListtrue);
  3509.             if ($userDataList == null$userDataList = [];
  3510.             $em_goc $this->getDoctrine()->getManager('company_group');
  3511.             //1st step get all company item ids and then check for global id null if its null then the
  3512. //            return new JsonResponse(
  3513. //                array(
  3514. //                    'userDataList' => $userDataList
  3515. //                )
  3516. //            );
  3517.             ////ITEMGROUPS
  3518.             foreach ($userDataList as $k => $cwa) {
  3519.                 $centralUser $em_goc
  3520.                     ->getRepository("CompanyGroupBundle\\Entity\\EntityApplicantDetails")
  3521.                     ->findOneBy(
  3522.                         array(
  3523.                             'applicantId' => $cwa['getGlobalId']
  3524.                         )
  3525.                     );
  3526.                 if ($centralUser) {
  3527.                     $centralUser->setFirstname($cwa['getFirstname'] ?? null);
  3528.                     $centralUser->setLastname($cwa['getLastname'] ?? null);
  3529.                     $centralUser->setEmail($cwa['getEmail'] ?? null);
  3530.                     $centralUser->setOAuthEmail($cwa['getOAuthEmail'] ?? null);
  3531.                     $centralUser->setPhone($cwa['getPhone'] ?? null);
  3532.                     $centralUser->setNid($cwa['getNid'] ?? null);
  3533.                     $centralUser->setSex($cwa['getSex'] ?? null);
  3534.                     $centralUser->setBlood($cwa['getBlood'] ?? null);
  3535.                     $centralUser->setFather($cwa['getFather'] ?? null);
  3536.                     $centralUser->setMother($cwa['getMother'] ?? null);
  3537.                     $centralUser->setSpouse($cwa['getSpouse'] ?? null);
  3538.                     $centralUser->setCurrAddr($cwa['getCurrAddr'] ?? null);
  3539.                     $centralUser->setPermAddr($cwa['getPermAddr'] ?? null);
  3540.                     $centralUser->setPhoneCountryCode($cwa['getPhoneCountryCode'] ?? null);
  3541.                     $centralUser->setEmpType($cwa['getEmpType'] ?? null);
  3542.                     $centralUser->setTin($cwa['getTin'] ?? null);
  3543.                     $centralUser->setDept($cwa['getDept'] ?? null);
  3544.                     $centralUser->setDesg($cwa['getDesg'] ?? null);
  3545.                     $centralUser->setBranch($cwa['getBranch'] ?? null);
  3546.                     $centralUser->setWeeklyHoliday($cwa['getWeeklyHoliday'] ?? null);
  3547.                     $centralUser->setSupervisor($cwa['getSupervisor'] ?? null);
  3548.                     $centralUser->setDob(!empty($cwa['getDob']) ? new \DateTime($cwa['getDob']) : null);
  3549.                     $centralUser->setJoiningDate(!empty($cwa['getJoiningDate']) ? new \DateTime($cwa['getJoiningDate']) : null);
  3550.                     $centralUser->setEmpValidTill(!empty($cwa['getEmpValidTill']) ? new \DateTime($cwa['getEmpValidTill']) : null);
  3551.                     $centralUser->setTinValidTill(!empty($cwa['getTinValidTill']) ? new \DateTime($cwa['getTinValidTill']) : null);
  3552.                     $centralUser->setMedInsValidTill(!empty($cwa['getMedInsValidTill']) ? new \DateTime($cwa['getMedInsValidTill']) : null);
  3553.                 } else {
  3554.                     $qry $em_goc->getRepository('CompanyGroupBundle\\Entity\\EntityApplicantDetails')
  3555.                         ->createQueryBuilder('m')
  3556.                         ->where("m.email like '" $cwa['getEmail'] . "'");
  3557.                     if ($cwa['getOAuthEmail'] != '' && $cwa['getOAuthEmail'] != null)
  3558.                         $qry->orWhere("m.oAuthEmail like '" $cwa['getOAuthEmail'] . "'");
  3559.                     if ($cwa['getPhoneNumber'] != '' && $cwa['getPhoneNumber'] != null)
  3560.                         $qry->orWhere("m.phone like '" $cwa['getPhoneNumber'] . "'");
  3561.                     $targets $qry->getQuery()
  3562.                         ->setMaxResults(1)
  3563.                         ->getResult();
  3564.                     if (!empty($targets))
  3565.                         $centralUser $targets[0];
  3566.                 }
  3567.                 if ($centralUser) {
  3568.                     $centralUser->setFirstname($cwa['getFirstname'] ?? null);
  3569.                     $centralUser->setLastname($cwa['getLastname'] ?? null);
  3570.                     $centralUser->setEmail($cwa['getEmail'] ?? null);
  3571.                     $centralUser->setOAuthEmail($cwa['getOAuthEmail'] ?? null);
  3572.                     $centralUser->setPhone($cwa['getPhone'] ?? null);
  3573.                     $centralUser->setNid($cwa['getNid'] ?? null);
  3574.                     $centralUser->setSex($cwa['getSex'] ?? null);
  3575.                     $centralUser->setBlood($cwa['getBlood'] ?? null);
  3576.                     $centralUser->setFather($cwa['getFather'] ?? null);
  3577.                     $centralUser->setMother($cwa['getMother'] ?? null);
  3578.                     $centralUser->setSpouse($cwa['getSpouse'] ?? null);
  3579.                     $centralUser->setCurrAddr($cwa['getCurrAddr'] ?? null);
  3580.                     $centralUser->setPermAddr($cwa['getPermAddr'] ?? null);
  3581.                     $centralUser->setPhoneCountryCode($cwa['getPhoneCountryCode'] ?? null);
  3582.                     $centralUser->setEmpType($cwa['getEmpType'] ?? null);
  3583.                     $centralUser->setTin($cwa['getTin'] ?? null);
  3584.                     $centralUser->setDept($cwa['getDept'] ?? null);
  3585.                     $centralUser->setDesg($cwa['getDesg'] ?? null);
  3586.                     $centralUser->setBranch($cwa['getBranch'] ?? null);
  3587.                     $centralUser->setWeeklyHoliday($cwa['getWeeklyHoliday'] ?? null);
  3588.                     $centralUser->setSupervisor($cwa['getSupervisor'] ?? null);
  3589.                     $centralUser->setDob(!empty($cwa['getDob']) ? new \DateTime($cwa['getDob']) : null);
  3590.                     $centralUser->setJoiningDate(!empty($cwa['getJoiningDate']) ? new \DateTime($cwa['getJoiningDate']) : null);
  3591.                     $centralUser->setEmpValidTill(!empty($cwa['getEmpValidTill']) ? new \DateTime($cwa['getEmpValidTill']) : null);
  3592.                     $centralUser->setTinValidTill(!empty($cwa['getTinValidTill']) ? new \DateTime($cwa['getTinValidTill']) : null);
  3593.                     $centralUser->setMedInsValidTill(!empty($cwa['getMedInsValidTill']) ? new \DateTime($cwa['getMedInsValidTill']) : null);
  3594.                 } else
  3595.                     $centralUser = new EntityApplicantDetails();
  3596. //
  3597. //                $getters = array_filter(get_class_methods($data), function ($method) {
  3598. //                    return 'get' === substr($method, 0, 3);
  3599. //                });
  3600.                 // Manual mapping starts here
  3601.                 $centralUser->setFirstname($cwa['getFirstname'] ?? null);
  3602.                 $centralUser->setLastname($cwa['getLastname'] ?? null);
  3603.                 $centralUser->setEmail($cwa['getEmail'] ?? null);
  3604.                 $centralUser->setOAuthEmail($cwa['getOAuthEmail'] ?? null);
  3605.                 $centralUser->setPhone($cwa['getPhone'] ?? null);
  3606.                 $centralUser->setNid($cwa['getNid'] ?? null);
  3607.                 $centralUser->setSex($cwa['getSex'] ?? null);
  3608.                 $centralUser->setBlood($cwa['getBlood'] ?? null);
  3609.                 $centralUser->setFather($cwa['getFather'] ?? null);
  3610.                 $centralUser->setMother($cwa['getMother'] ?? null);
  3611.                 $centralUser->setSpouse($cwa['getSpouse'] ?? null);
  3612.                 $centralUser->setCurrAddr($cwa['getCurrAddr'] ?? null);
  3613.                 $centralUser->setPermAddr($cwa['getPermAddr'] ?? null);
  3614.                 $centralUser->setPhoneCountryCode($cwa['getPhoneCountryCode'] ?? null);
  3615.                 $centralUser->setEmpType($cwa['getEmpType'] ?? null);
  3616.                 $centralUser->setTin($cwa['getTin'] ?? null);
  3617.                 $centralUser->setDept($cwa['getDept'] ?? null);
  3618.                 $centralUser->setDesg($cwa['getDesg'] ?? null);
  3619.                 $centralUser->setBranch($cwa['getBranch'] ?? null);
  3620.                 $centralUser->setWeeklyHoliday($cwa['getWeeklyHoliday'] ?? null);
  3621.                 $centralUser->setSupervisor($cwa['getSupervisor'] ?? null);
  3622. // Date fields
  3623.                 $centralUser->setDob(!empty($cwa['getDob']) ? new \DateTime($cwa['getDob']) : null);
  3624.                 $centralUser->setJoiningDate(!empty($cwa['getJoiningDate']) ? new \DateTime($cwa['getJoiningDate']) : null);
  3625.                 $centralUser->setEmpValidTill(!empty($cwa['getEmpValidTill']) ? new \DateTime($cwa['getEmpValidTill']) : null);
  3626.                 $centralUser->setTinValidTill(!empty($cwa['getTinValidTill']) ? new \DateTime($cwa['getTinValidTill']) : null);
  3627.                 $centralUser->setMedInsValidTill(!empty($cwa['getMedInsValidTill']) ? new \DateTime($cwa['getMedInsValidTill']) : null);
  3628. // Continue mapping more fields as needed...
  3629.                 $userAppIds json_decode($centralUser->getUserAppIds(), true);
  3630.                 $userTypesByAppIds json_decode($centralUser->getUserTypesByAppIds(), true);
  3631.                 if ($userAppIds == null$userAppIds = [];
  3632.                 if ($userTypesByAppIds == null$userTypesByAppIds = [];
  3633.                 $userAppIds array_merge($userAppIdsarray_diff([$cwa['getUserAppId']], $userAppIds));
  3634.                 if (!isset($userTypesByAppIds[$cwa['getUserAppId']])) {
  3635.                     $userTypesByAppIds[$cwa['getUserAppId']] = [];
  3636.                 }
  3637.                 if (in_array(1$userTypesByAppIds[$cwa['getUserAppId']]) && $cwa['getUserType'] == 2) {
  3638.                     $userTypesByAppIds[$cwa['getUserAppId']] = array_diff($userTypesByAppIds[$cwa['getUserAppId']], [1]);
  3639.                 }
  3640.                 if (in_array(2$userTypesByAppIds[$cwa['getUserAppId']]) && $cwa['getUserType'] == 1) {
  3641.                     $userTypesByAppIds[$cwa['getUserAppId']] = array_diff($userTypesByAppIds[$cwa['getUserAppId']], [2]);
  3642.                 }
  3643.                 $userTypesByAppIds[$cwa['getUserAppId']] = array_merge($userTypesByAppIds[$cwa['getUserAppId']], array_diff([$cwa['getUserType']], $userTypesByAppIds[$cwa['getUserAppId']]));
  3644. //                $userTypesByAppIds[$cwa['getUserAppId']] = [$cwa['getUserType']];
  3645.                 $userFullName $cwa['getName'];
  3646.                 $userFullNameArr explode(' '$cwa['getName']);
  3647.                 $userFirstName = isset($userFullNameArr[0]) ? $userFullNameArr[0] : '';
  3648.                 $userLastName '';
  3649.                 if (isset($userFullNameArr[1])) {
  3650.                     foreach ($userFullNameArr as $kunky => $chunky) {
  3651.                         if ($kunky != 0) {
  3652.                             $userLastName .= $chunky;
  3653.                         }
  3654.                         if ($kunky count($userFullNameArr) - 1) {
  3655.                             $userLastName .= ' ';
  3656.                         }
  3657.                     }
  3658.                 }
  3659.                 $centralUser->setUserAppIds(json_encode($userAppIds));
  3660.                 $centralUser->setFirstname($userFirstName);
  3661.                 $centralUser->setLastname($userLastName);
  3662.                 $centralUser->setUserTypesByAppIds(json_encode($userTypesByAppIds));
  3663.                 $em_goc->persist($centralUser);
  3664.                 $em_goc->flush();
  3665.                 $uploadedFile $request->files->get('file_' $cwa['getUserAppId'] . '_' $cwa['getUserId'], null);
  3666.                 {
  3667.                     //            if($uploadedFile->getImage())
  3668.                     //                var_dump($uploadedFile->getFile());
  3669.                     //                var_dump($uploadedFile);
  3670.                     if ($uploadedFile != null) {
  3671.                         $fileName 'user_image' $centralUser->getApplicantId() . '.' $uploadedFile->guessExtension();
  3672.                         $path $fileName;
  3673.                         $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/UserImage/';
  3674.                         if ($centralUser->getImage() != '' && $centralUser->getImage() != null && file_exists($this->container->getParameter('kernel.root_dir') . '/../web/' $centralUser->getImage())) {
  3675.                             unlink($this->container->getParameter('kernel.root_dir') . '/../web/' $centralUser->getImage());
  3676.                         }
  3677.                         if (!file_exists($upl_dir)) {
  3678.                             mkdir($upl_dir0777true);
  3679.                         }
  3680.                         $file $uploadedFile->move($upl_dir$path);
  3681.                         if ($path != "")
  3682.                             $centralUser->setImage('uploads/UserImage/' $path);
  3683.                     }
  3684.                 }
  3685.                 $em_goc->flush();
  3686.                 if (!isset($globalIdsByAppIdAndUser[$cwa['getUserAppId']]))
  3687.                     $globalIdsByAppIdAndUser[$cwa['getUserAppId']] = array();
  3688.                 $globalIdsByAppIdAndUser[$cwa['getUserAppId']][$cwa['getUserId']] =
  3689.                     array(
  3690.                         'gid' => $centralUser->getApplicantId()
  3691.                     );
  3692.                 $companies $em_goc->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findBy([
  3693.                     'appId' => $userAppIds
  3694.                 ]);
  3695.                 $globalId $cwa['getGlobalId'];
  3696.                 $userData $userDataList;
  3697.                 $dataByServerId = [];
  3698.                 $gocDataListByAppId = [];
  3699.                 foreach ($companies as $entry) {
  3700.                     $gocDataListByAppId[$entry->getAppId()] = [
  3701.                         'dbName' => $entry->getDbName(),
  3702.                         'dbUser' => $entry->getDbUser(),
  3703.                         'dbPass' => $entry->getDbPass(),
  3704.                         'dbHost' => $entry->getDbHost(),
  3705.                         'serverAddress' => $entry->getCompanyGroupServerAddress(),
  3706.                         'port' => $entry->getCompanyGroupServerPort() ?: 80,
  3707.                         'appId' => $entry->getAppId(),
  3708.                         'serverId' => $entry->getCompanyGroupServerId(),
  3709.                     ];
  3710.                     if (!isset($dataByServerId[$entry->getCompanyGroupServerId()]))
  3711.                         $dataByServerId[$entry->getCompanyGroupServerId()] = array(
  3712.                             'serverId' => $entry->getCompanyGroupServerId(),
  3713.                             'serverAddress' => $entry->getCompanyGroupServerAddress(),
  3714.                             'port' => $entry->getCompanyGroupServerPort() ?: 80,
  3715.                             'appId' => $userAppIds,
  3716.                             'payload' => array(
  3717.                                 'globalId' => $globalId,
  3718.                                 'appId' => $userAppIds,
  3719.                                 'userData' => $userData,
  3720. //                                      'approvalHash' => $approvalHash
  3721.                             )
  3722.                         );
  3723.                 }
  3724.                 $urls = [];
  3725.                 foreach ($dataByServerId as $entry) {
  3726.                     $serverAddress $entry['serverAddress'];
  3727.                     if (!$serverAddress) continue;
  3728.                     $syncUrl $serverAddress '/ReceiveUserFromCentral';
  3729.                     $payload $entry['payload'];
  3730.                     $curl curl_init();
  3731.                     curl_setopt_array($curl, [
  3732.                         CURLOPT_RETURNTRANSFER => true,
  3733.                         CURLOPT_POST => true,
  3734.                         CURLOPT_URL => $syncUrl,
  3735.                         CURLOPT_CONNECTTIMEOUT => 10,
  3736.                         CURLOPT_SSL_VERIFYPEER => false,
  3737.                         CURLOPT_SSL_VERIFYHOST => false,
  3738.                         CURLOPT_HTTPHEADER => [
  3739.                             'Accept: application/json',
  3740.                             'Content-Type: application/json'
  3741.                         ],
  3742.                         CURLOPT_POSTFIELDS => json_encode($payload)
  3743.                     ]);
  3744.                     $response curl_exec($curl);
  3745.                     $err curl_error($curl);
  3746.                     $httpCode curl_getinfo($curlCURLINFO_HTTP_CODE);
  3747.                     curl_close($curl);
  3748.                     if ($err) {
  3749.                         error_log("ERP Sync Error [Server: {$entry['serverAddress']}]: $err");
  3750.                     } else {
  3751.                         error_log("ERP Sync Success [HTTP $httpCode]: $response");
  3752.                     }
  3753.                 }
  3754.             }
  3755.             return new JsonResponse(
  3756.                 array(
  3757.                     'globalIdsData' => $globalIdsByAppIdAndUser
  3758.                 )
  3759.             );
  3760.         } else {
  3761.             $em $this->getDoctrine()->getManager('company_group');
  3762.             $em->getConnection()->connect();
  3763.             $connected $em->getConnection()->isConnected();
  3764.             $gocDataList = [];
  3765.             $gocDataListByAppId = [];
  3766.             $retDataDebug = array();
  3767.             $appIds $request->get('appIds''_UNSET_');
  3768.             $userIds $request->get('userIds''_UNSET_');
  3769.             if ($connected) {
  3770.                 $findByQuery = array(
  3771.                     'active' => 1
  3772.                 );
  3773.                 if ($appIds !== '_UNSET_')
  3774.                     $findByQuery['appId'] = $appIds;
  3775.                 $gocList $this->getDoctrine()->getManager('company_group')
  3776.                     ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  3777.                     ->findBy($findByQuery);
  3778.                 foreach ($gocList as $entry) {
  3779.                     $d = array(
  3780.                         'name' => $entry->getName(),
  3781.                         'id' => $entry->getId(),
  3782.                         'image' => $entry->getImage(),
  3783.                         'companyGroupHash' => $entry->getCompanyGroupHash(),
  3784.                         'dbName' => $entry->getDbName(),
  3785.                         'dbUser' => $entry->getDbUser(),
  3786.                         'dbPass' => $entry->getDbPass(),
  3787.                         'dbHost' => $entry->getDbHost(),
  3788.                         'appId' => $entry->getAppId(),
  3789.                         'companyRemaining' => $entry->getCompanyRemaining(),
  3790.                         'companyAllowed' => $entry->getCompanyAllowed(),
  3791.                     );
  3792.                     $gocDataList[$entry->getId()] = $d;
  3793.                     $gocDataListByAppId[$entry->getAppId()] = $d;
  3794.                 }
  3795.                 $debugCount 0;
  3796.                 foreach ($gocDataList as $gocId => $entry) {
  3797. //                    if($debugCount>0)
  3798. //                        continue;
  3799.                     $skipSend 1;
  3800.                     $connector $this->container->get('application_connector');
  3801.                     $connector->resetConnection(
  3802.                         'default',
  3803.                         $gocDataList[$gocId]['dbName'],
  3804.                         $gocDataList[$gocId]['dbUser'],
  3805.                         $gocDataList[$gocId]['dbPass'],
  3806.                         $gocDataList[$gocId]['dbHost'],
  3807.                         $reset true);
  3808.                     $em $this->getDoctrine()->getManager();
  3809.                     if ($userIds !== '_UNSET_')
  3810.                         $users $this->getDoctrine()
  3811.                             ->getRepository('ApplicationBundle\\Entity\\SysUser')
  3812.                             ->findBy(
  3813.                                 array(
  3814.                                     'userId' => $userIds
  3815.                                 )
  3816.                             );
  3817.                     else
  3818.                         $users $this->getDoctrine()
  3819.                             ->getRepository('ApplicationBundle\\Entity\\SysUser')
  3820.                             ->findBy(
  3821.                                 array()
  3822.                             );
  3823.                     $output '';
  3824.                     $userData = array();
  3825.                     $userFiles = array();
  3826.                     foreach ($users as $user) {
  3827.                         $file $this->container->getParameter('kernel.root_dir') . '/../web/' $user->getImage(); //<-- Path could be relative
  3828. //                            $output=$file;
  3829.                         if ($user->getImage() != '' && $user->getImage() != null && file_exists($file)) {
  3830. //                        $file = new \CURLFile($this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/' . $company->getImage()); //<-- Path could be relative
  3831.                             $mime mime_content_type($file);
  3832.                             $info pathinfo($file);
  3833.                             $name $info['basename'];
  3834.                             if (strpos($mime'image') !== false) {
  3835.                                 $output = new \CURLFile($file$mime$name);
  3836.                             }
  3837.                             $skipSend 0;
  3838.                             $userFiles['file_' $user->getUserAppId() . '_' $user->getUserId()] = $output;
  3839.                         } else {
  3840. //                                    unlink($this->container->getParameter('kernel.root_dir') . '/../web'. $centralUser->getImage());
  3841.                             $user->setImage(null);
  3842.                             $userFiles['file_' $user->getUserAppId() . '_' $user->getUserId()] = 'pika';
  3843.                             $em->flush();
  3844.                         }
  3845.                         $getters array_filter(get_class_methods($user), function ($method) {
  3846.                             return 'get' === substr($method03);
  3847.                         });
  3848.                         $userDataSingle = array(//                                'file'=>$output
  3849.                         );
  3850.                         foreach ($getters as $getter) {
  3851.                             if ($getter == 'getCreatedAt' || $getter == 'getUpdatedAt' || $getter == 'getImage')
  3852.                                 continue;
  3853. //                                if(is_string($user->{$getter}())|| is_numeric($user->{$getter}()))
  3854. //                                {
  3855. //                                    $userDataSingle[$getter]= $user->{$getter}();
  3856. //                                }
  3857.                             if ($user->{$getter}() instanceof \DateTime) {
  3858.                                 $ggtd $user->{$getter}();
  3859.                                 $userDataSingle[$getter] = $ggtd->format('Y-m-d');
  3860.                             } else
  3861.                                 $userDataSingle[$getter] = $user->{$getter}();
  3862.                         }
  3863.                         $userData[] = $userDataSingle;
  3864.                     }
  3865.                     $retDataDebug[$debugCount] = array(
  3866.                         'skipSend' => $skipSend
  3867.                     );
  3868.                     //now customers
  3869.                     $emailFieldName 'email';
  3870.                     $phoneFieldName 'contact_number';
  3871.                     $query "SELECT * from  acc_clients   where 1=1 ";
  3872.                     $stmt $em->getConnection()->fetchAllAssociative($query);
  3873.                     $results $stmt;
  3874.                     if (!empty($results)) {
  3875.                         foreach ($results as $dt) {
  3876.                             $dt['company_id'] = "1";
  3877.                             $companyData = isset($companyList[$dt['company_id']]) ? $companyList[$dt['company_id']] : [];
  3878.                             $userDataSingle = array(
  3879.                                 'getUserAppId' => strval(UserConstants::USER_TYPE_CLIENT),
  3880.                                 'getUserName' => 'CID-' str_pad($dt['client_id'], 8'0'STR_PAD_LEFT),
  3881.                                 'getUserId' => $dt['client_id']
  3882.                             );
  3883. //                            $userData[] = $userDataSingle;
  3884.                         }
  3885.                     }
  3886.                     //now suppliers
  3887.                     $emailFieldName 'email';
  3888.                     $phoneFieldName 'contact_number';
  3889.                     $query "SELECT * from  acc_suppliers   where 1=1 ";
  3890.                     $stmt $em->getConnection()->fetchAllAssociative($query);
  3891.                     $results $stmt;
  3892.                     if (!empty($results)) {
  3893.                         foreach ($results as $dt) {
  3894.                             $dt['company_id'] = "1";
  3895.                             $companyData = isset($companyList[$dt['company_id']]) ? $companyList[$dt['company_id']] : [];
  3896.                             $userDataSingle = array(
  3897.                                 'userType' => strval(UserConstants::USER_TYPE_SUPPLIER),
  3898.                                 'userName' => 'SID-' str_pad($dt['supplier_id'], 8'0'STR_PAD_LEFT),
  3899.                                 'userId' => $dt['supplier_id'],
  3900.                             );
  3901. //                            $userData[] = $userDataSingle;
  3902.                         }
  3903.                     }
  3904. //                    if ($skipSend == 0)
  3905.                     {
  3906.                         $urlToCall GeneralConstant::HONEYBEE_CENTRAL_SERVER '/SyncUserToCentralUser';
  3907.                         $userFiles['userData'] = json_encode($userData);
  3908.                         $curl curl_init();
  3909.                         curl_setopt_array($curl, array(
  3910.                             CURLOPT_RETURNTRANSFER => 1,
  3911.                             CURLOPT_POST => 1,
  3912.                             CURLOPT_URL => $urlToCall,
  3913.                             CURLOPT_CONNECTTIMEOUT => 10,
  3914.                             CURLOPT_SSL_VERIFYPEER => false,
  3915.                             CURLOPT_SSL_VERIFYHOST => false,
  3916. //                            CURLOPT_SAFE_UPLOAD => false,
  3917.                             CURLOPT_HTTPHEADER => array(//                                "Accept: multipart/form-data",
  3918.                             ),
  3919.                             //                        CURLOPT_USERAGENT => 'InnoPM',
  3920. //                            CURLOPT_POSTFIELDS => array(
  3921. //                                'userData'=>json_encode($userData),
  3922. //                                'userFiles'=>$userFiles
  3923. //                            ),
  3924.                             CURLOPT_POSTFIELDS => $userFiles
  3925.                         ));
  3926.                         $retData curl_exec($curl);
  3927.                         $errData curl_error($curl);
  3928.                         curl_close($curl);
  3929.                         $retDataObj json_decode($retDatatrue);
  3930.                         $retDataDebug[$debugCount] = $retDataObj;
  3931.                         if (isset($retDataObj['globalIdsData']))
  3932.                             foreach ($retDataObj['globalIdsData'] as $app_id => $usrList) {
  3933.                                 $connector $this->container->get('application_connector');
  3934.                                 $connector->resetConnection(
  3935.                                     'default',
  3936.                                     $gocDataListByAppId[$app_id]['dbName'],
  3937.                                     $gocDataListByAppId[$app_id]['dbUser'],
  3938.                                     $gocDataListByAppId[$app_id]['dbPass'],
  3939.                                     $gocDataListByAppId[$app_id]['dbHost'],
  3940.                                     $reset true);
  3941.                                 $em $this->getDoctrine()->getManager();
  3942.                                 foreach ($usrList as $sys_id => $globaldata) {
  3943.                                     $user $this->getDoctrine()
  3944.                                         ->getRepository('ApplicationBundle\\Entity\\SysUser')
  3945.                                         ->findOneBy(
  3946.                                             array(
  3947.                                                 'userId' => $sys_id
  3948.                                             )
  3949.                                         );
  3950.                                     if ($user) {
  3951.                                         $user->setGlobalId($globaldata['gid']);
  3952.                                         $em->flush();
  3953.                                     }
  3954.                                 }
  3955.                             }
  3956.                     }
  3957.                     $debugCount++;
  3958.                 }
  3959.             }
  3960.             return new JsonResponse($retDataDebug);
  3961.         }
  3962.     }
  3963.     public function ReceiveUserFromCentralAction(Request $request)
  3964.     {
  3965.         $data json_decode($request->getContent(), true);
  3966.         if (
  3967.             !$data ||
  3968.             !isset($data['globalId']) ||
  3969.             !isset($data['appId']) ||
  3970.             !isset($data['userData'])
  3971.         ) {
  3972.             return new JsonResponse(['success' => false'message' => 'Missing required fields'], 400);
  3973.         }
  3974.         $globalId $data['globalId'];
  3975.         $userDataRaw $data['userData'];
  3976.         if (is_string($userDataRaw)) {
  3977.             $userDataRaw json_decode($userDataRawtrue);
  3978.         }
  3979.         if (!is_array($userDataRaw)) {
  3980.             return new JsonResponse(['success' => false'message' => 'Invalid userData format'], 400);
  3981.         }
  3982.         $userData is_array($userDataRaw[0] ?? null) ? $userDataRaw[0] : $userDataRaw;
  3983.         if (is_string($userData)) {
  3984.             $userData json_decode($userDatatrue);
  3985.         }
  3986.         if (!is_array($userData)) {
  3987.             return new JsonResponse(['success' => false'message' => 'Invalid userData format'], 400);
  3988.         }
  3989.         $companyIds is_array($data['appId']) ? $data['appId'] : [$data['appId']];
  3990.         $em_goc $this->getDoctrine()->getManager('company_group');
  3991.         $companies $em_goc->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findBy([
  3992.             'appId' => $companyIds
  3993.         ]);
  3994.         foreach ($companies as $entry) {
  3995.             $goc = [
  3996.                 'dbName' => $entry->getDbName(),
  3997.                 'dbUser' => $entry->getDbUser(),
  3998.                 'dbPass' => $entry->getDbPass(),
  3999.                 'dbHost' => $entry->getDbHost(),
  4000.                 'serverAddress' => $entry->getCompanyGroupServerAddress(),
  4001.                 'port' => $entry->getCompanyGroupServerPort() ?: 80,
  4002.                 'appId' => $entry->getAppId(),
  4003. //                                 'serverId' => $entry->getServerId(),
  4004.             ];
  4005.             $connector $this->container->get('application_connector');
  4006.             $connector->resetConnection(
  4007.                 'default',
  4008.                 $goc['dbName'],
  4009.                 $goc['dbUser'],
  4010.                 $goc['dbPass'],
  4011.                 $goc['dbHost'],
  4012.                 $reset true
  4013.             );
  4014.             $em $this->getDoctrine()->getManager();
  4015.             $user $em->getRepository('ApplicationBundle\\Entity\\SysUser')->findOneBy(['globalId' => $globalId]);
  4016.             if (!$user) {
  4017.                 return new JsonResponse(['success' => false'message' => 'User not found'], 404);
  4018.             }
  4019. //            $user = $em->getRepository('ApplicationBundle\\Entity\\SysUser')->findOneBy(['userId' => $user->getUserId()]);
  4020. //            if (!$user) {
  4021. //                $user = new \ApplicationBundle\Entity\EncryptedSignature();
  4022. //                $user->setUserId($user->getUserId());
  4023. //                $user->setCreatedAt(new \DateTime());
  4024. //            }
  4025.             if (!isset($userData['getFirstname']) && !isset($userData['getFirstName'])) {
  4026.                 if (isset($userData['getName'])) {
  4027.                     $nameStrArr explode(" "$userData['getName']);
  4028.                     $userData['getFirstname'] = isset($nameStrArr[0]) ? $nameStrArr[0] : '';
  4029.                     $userData['getLastname'] = isset($nameStrArr[1]) ? $nameStrArr[1] : '';
  4030.                 }
  4031.                 $userData['getFirstName'] = $userData['getFirstname'];
  4032.                 $userData['getLastName'] = $userData['getLastname'];
  4033.             } else if (!isset($userData['getFirstName'])) {
  4034.                 $userData['getFirstName'] = $userData['getFirstname'];
  4035.                 $userData['getLastName'] = $userData['getLastname'];
  4036.             } else if (!isset($userData['getFirstname'])) {
  4037.                 $userData['getFirstname'] = $userData['getFirstName'];
  4038.                 $userData['getLastname'] = $userData['getLastName'];
  4039.             }
  4040.             $user->setUserName($userData['getFirstname'] . ' ' $userData['getLastname']);
  4041.             $user->setUserCompanyId(1);
  4042.             $user->setGlobalId($globalId);
  4043.             $user->setUserName($userData['getName'] ?? null);
  4044.             $user->setUpdatedAt(new \DateTime());
  4045.             $em->persist($user);
  4046.             $em->flush();
  4047.             $employee $em->getRepository('ApplicationBundle\\Entity\\Employee')->findOneBy(['userId' => $user->getUserId()]);
  4048.             if ($employee) {
  4049.                 $employee->setFirstName($userData['getFirstname']);
  4050.                 $employee->setLastName($userData['getLastname']);
  4051.                 $employee->setName($userData['getFirstname'] . ' ' $userData['getLastname']);
  4052.                 $em->persist($employee);
  4053.             }
  4054.             if ($employee)
  4055.                 $employeeDetails $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  4056.                     ->findOneBy(['id' => $employee->getEmployeeId()]);
  4057.             else
  4058.                 $employeeDetails $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  4059.                     ->findOneBy(['userId' => $user->getUserId()]);
  4060.             if ($employeeDetails) {
  4061.                 $employeeDetails->setFirstname($userData['getFirstname']);
  4062.                 $employeeDetails->setLastname($userData['getLastname']);
  4063.                 $employeeDetails->setEmail($userData['getEmail']);
  4064.                 $employeeDetails->setPhone($userData['getPhone'] ?? null);
  4065.                 $employeeDetails->setNid($userData['getNid'] ?? null);
  4066.                 $employeeDetails->setSex($userData['getSex'] ?? null);
  4067.                 $employeeDetails->setBlood($userData['getBlood'] ?? null);
  4068.                 $employeeDetails->setFather($userData['getFather'] ?? null);
  4069.                 $employeeDetails->setMother($userData['getMother'] ?? null);
  4070.                 $employeeDetails->setSpouse($userData['getSpouse'] ?? null);
  4071.                 $employeeDetails->setCurrAddr($userData['getCurrAddr'] ?? null);
  4072.                 $employeeDetails->setPermAddr($userData['getPermAddr'] ?? null);
  4073.                 $em->persist($employeeDetails);
  4074.             }
  4075.             $em->flush();
  4076.         }
  4077.         return new JsonResponse(['success' => true'message' => 'User, Employee, and EmployeeDetails updated in all ERP servers']);
  4078.     }
  4079.     public function MergeApplicantGlobalIdOnServerAction(Request $request)
  4080.     {
  4081.         $payload json_decode($request->getContent(), true);
  4082.         if (!is_array($payload)) {
  4083.             $payload $request->request->all();
  4084.         }
  4085.         $oldGlobalId = isset($payload['oldGlobalId']) ? (int)$payload['oldGlobalId'] : 0;
  4086.         $newGlobalId = isset($payload['newGlobalId']) ? (int)$payload['newGlobalId'] : 0;
  4087.         $appIds = isset($payload['appIds']) ? $payload['appIds'] : [];
  4088.         if (is_string($appIds)) {
  4089.             $decoded json_decode($appIdstrue);
  4090.             $appIds is_array($decoded) ? $decoded explode(','$appIds);
  4091.         }
  4092.         if (!is_array($appIds)) {
  4093.             $appIds = [];
  4094.         }
  4095.         $appIds array_values(array_unique(array_filter(array_map('intval'$appIds))));
  4096.         if ($oldGlobalId <= || $newGlobalId <= || empty($appIds)) {
  4097.             return new JsonResponse(['success' => false'message' => 'oldGlobalId, newGlobalId and appIds are required.'], 400);
  4098.         }
  4099.         $emGoc $this->getDoctrine()->getManager('company_group');
  4100.         $companies $emGoc->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findBy(['appId' => $appIds]);
  4101.         $results = [];
  4102.         foreach ($companies as $entry) {
  4103.             $connector $this->container->get('application_connector');
  4104.             $connector->resetConnection(
  4105.                 'default',
  4106.                 $entry->getDbName(),
  4107.                 $entry->getDbUser(),
  4108.                 $entry->getDbPass(),
  4109.                 $entry->getDbHost(),
  4110.                 $reset true
  4111.             );
  4112.             $em $this->getDoctrine()->getManager();
  4113.             $oldUser $em->getRepository('ApplicationBundle\\Entity\\SysUser')->findOneBy(['globalId' => $oldGlobalId]);
  4114.             $newUser $em->getRepository('ApplicationBundle\\Entity\\SysUser')->findOneBy(['globalId' => $newGlobalId]);
  4115.             $appResult = [
  4116.                 'appId' => (int)$entry->getAppId(),
  4117.                 'oldFound' => $oldUser true false,
  4118.                 'newFound' => $newUser true false,
  4119.                 'mergedIntoExistingUser' => false,
  4120.                 'retaggedOldUser' => false,
  4121.             ];
  4122.             if ($oldUser && $newUser && (int)$oldUser->getUserId() !== (int)$newUser->getUserId()) {
  4123.                 if (!$newUser->getEmail() && $oldUser->getEmail()) {
  4124.                     $newUser->setEmail($oldUser->getEmail());
  4125.                 }
  4126.                 if (!$newUser->getImage() && $oldUser->getImage()) {
  4127.                     $newUser->setImage($oldUser->getImage());
  4128.                 }
  4129.                 if (!$newUser->getName() && $oldUser->getName()) {
  4130.                     $newUser->setName($oldUser->getName());
  4131.                 }
  4132.                 $conn $em->getConnection();
  4133.                 $conn->executeStatement('UPDATE employee SET user_id = :newUserId WHERE user_id = :oldUserId', [
  4134.                     'newUserId' => (int)$newUser->getUserId(),
  4135.                     'oldUserId' => (int)$oldUser->getUserId(),
  4136.                 ]);
  4137.                 $conn->executeStatement('UPDATE employee_details SET user_id = :newUserId WHERE user_id = :oldUserId', [
  4138.                     'newUserId' => (int)$newUser->getUserId(),
  4139.                     'oldUserId' => (int)$oldUser->getUserId(),
  4140.                 ]);
  4141.                 $oldUser->setGlobalId(null);
  4142.                 $oldUser->setStatus(0);
  4143.                 $oldUser->setUserName(($oldUser->getUserName() ?: 'merged_user') . '_merged_' $oldGlobalId);
  4144.                 if ($oldUser->getEmail()) {
  4145.                     $oldUser->setEmail('merged_' $oldGlobalId '_' time() . '@invalid.local');
  4146.                 }
  4147.                 $em->persist($newUser);
  4148.                 $em->persist($oldUser);
  4149.                 $em->flush();
  4150.                 $appResult['mergedIntoExistingUser'] = true;
  4151.             } elseif ($oldUser) {
  4152.                 $oldUser->setGlobalId($newGlobalId);
  4153.                 $em->persist($oldUser);
  4154.                 $em->flush();
  4155.                 $appResult['retaggedOldUser'] = true;
  4156.             }
  4157.             $results[] = $appResult;
  4158.         }
  4159.         return new JsonResponse([
  4160.             'success' => true,
  4161.             'results' => $results,
  4162.         ]);
  4163.     }
  4164.     public function SyncCentralUserToServerAction(Request $request)
  4165.     {
  4166.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  4167.         $post $request;
  4168.         $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') : []);
  4169.         $globalIdsByAppIdAndUser = [];
  4170.         if ($systemType == '_CENTRAL_') {
  4171.             $userDataList = [];
  4172.             $retAppIds = [];
  4173.             $appIdList = [];
  4174.             $userIdList = [];
  4175.             $retDataDebug = [];
  4176.             $appIds $request->get('appIds''_UNSET_');
  4177.             if ($appIds != '_UNSET_') {
  4178.                 $appIdList $userIdList explode(','$appIds);;
  4179.                 if ($appIdList == null$appIdList = [];
  4180.             }
  4181.             $userIds $request->get('userIds''_UNSET_');
  4182.             if ($userIds != '_UNSET_') {
  4183.                 $userIdList explode(','$userIds);
  4184.                 if ($userIdList == null$userIdList = [];
  4185.             }
  4186.             if (is_string($userDataList)) $userDataList json_decode($userDataListtrue);
  4187.             if ($userDataList == null$userDataList = [];
  4188.             $em_goc $this->getDoctrine()->getManager('company_group');
  4189.             $centralUserQry $em_goc->getRepository('CompanyGroupBundle\\Entity\\EntityApplicantDetails')
  4190.                 ->createQueryBuilder('m')
  4191.                 ->where("1=1");
  4192.             if (!empty($userIdList))
  4193.                 $centralUserQry->andWhere("m.applicantId in (" implode(','$userIdList) . " )");
  4194.             $centralUsers $centralUserQry->getQuery()
  4195.                 ->setMaxResults(1)
  4196.                 ->getResult();
  4197.             ////ITEMGROUPS
  4198.             foreach ($centralUsers as $centralUser) {
  4199.                 if ($centralUser) {
  4200.                 } else {
  4201.                 }
  4202.                 $toSetUserData = [];
  4203.                 $userData = array();
  4204.                 $userFiles = array();
  4205.                 $file $this->container->getParameter('kernel.root_dir') . '/../web/' $centralUser->getImage(); //<-- Path could be relative
  4206. //                            $output=$file;
  4207.                 if ($centralUser->getImage() != '' && $centralUser->getImage() != null && file_exists($file)) {
  4208. //                        $file = new \CURLFile($this->container->getParameter('kernel.root_dir') . '/../web/uploads/CompanyImage/' . $company->getImage()); //<-- Path could be relative
  4209.                     $mime mime_content_type($file);
  4210.                     $info pathinfo($file);
  4211.                     $name $info['basename'];
  4212.                     if (strpos($mime'image') !== false) {
  4213.                         $output = new \CURLFile($file$mime$name);
  4214.                     }
  4215.                     $skipSend 0;
  4216.                     $userFiles['file_' $centralUser->getApplicantId()] = $output;
  4217.                 } else {
  4218.                     $centralUser->setImage(null);
  4219.                     $userFiles['file_' $centralUser->getApplicantId()] = 'pika';
  4220.                     $em_goc->flush();
  4221.                 }
  4222. //
  4223.                 $getters array_filter(get_class_methods($centralUser), function ($method) {
  4224.                     return 'get' === substr($method03);
  4225.                 });
  4226.                 $userDataSingle = array();
  4227.                 foreach ($getters as $getter) {
  4228.                     if ($getter == 'getCreatedAt' || $getter == 'getUpdatedAt' || $getter == 'getImage')
  4229.                         continue;
  4230. //                                if(is_string($user->{$getter}())|| is_numeric($user->{$getter}()))
  4231. //                                {
  4232. //                                    $userDataSingle[$getter]= $user->{$getter}();
  4233. //                                }
  4234.                     if ($centralUser->{$getter}() instanceof \DateTime) {
  4235.                         $ggtd $centralUser->{$getter}();
  4236.                         $userDataSingle[$getter] = $ggtd->format('Y-m-d');
  4237.                     } else
  4238.                         $userDataSingle[$getter] = $centralUser->{$getter}();
  4239.                 }
  4240.                 $userAppIds json_decode($centralUser->getUserAppIds(), true);
  4241.                 if ($userAppIds == null$userAppIds = [];
  4242.                 $appIdList array_merge($appIdListarray_diff($userAppIds$appIdList));
  4243.                 $userTypesByAppIds json_decode($centralUser->getUserTypesByAppIds(), true);
  4244.                 if ($userTypesByAppIds == null$userTypesByAppIds = [];
  4245.                 $userDataSingle['userTypesByAppIds'] = $userTypesByAppIds;
  4246.                 $userDataList[] = $userDataSingle;
  4247.                 $em_goc->persist($centralUser);
  4248.                 $em_goc->flush();
  4249.             }
  4250.             $em_goc->flush();
  4251.             $serverIdsCalledAlready = [];
  4252.             $appList $this->getDoctrine()->getManager('company_group')
  4253.                 ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  4254.                 ->findBy(array(
  4255.                         'appId' => $appIdList
  4256.                     )
  4257.                 );
  4258.             $userFiles['userData'] = json_encode($userDataList);
  4259.             foreach ($appList as $app) {
  4260.                 if (!in_array($app->getCompanyGroupServerId(), $serverIdsCalledAlready)) {
  4261.                     if (isset($serverList[$app->getCompanyGroupServerId()])) {
  4262.                         //                    if ($skipSend == 0)
  4263.                         {
  4264.                             $urlToCall $serverList[$app->getCompanyGroupServerId()]['absoluteUrl'] . '/SyncCentralUserToServer';
  4265.                             $curl curl_init();
  4266.                             curl_setopt_array($curl, array(
  4267.                                 CURLOPT_RETURNTRANSFER => 1,
  4268.                                 CURLOPT_POST => 1,
  4269.                                 CURLOPT_URL => $urlToCall,
  4270.                                 CURLOPT_CONNECTTIMEOUT => 10,
  4271.                                 CURLOPT_SSL_VERIFYPEER => false,
  4272.                                 CURLOPT_SSL_VERIFYHOST => false,
  4273.                                 CURLOPT_HTTPHEADER => array(),
  4274.                                 CURLOPT_POSTFIELDS => $userFiles
  4275.                             ));
  4276.                             $retData curl_exec($curl);
  4277.                             $errData curl_error($curl);
  4278.                             curl_close($curl);
  4279.                             $retDataObj json_decode($retDatatrue);
  4280.                             $retDataDebug[] = $retDataObj;
  4281.                         }
  4282.                     }
  4283.                     $serverIdsCalledAlready[] = $app->getCompanyGroupServerId();
  4284.                 }
  4285.             }
  4286. //                if (!isset($globalIdsByAppIdAndUser[$cwa['getUserAppId']]))
  4287. //                    $globalIdsByAppIdAndUser[$cwa['getUserAppId']] = array();
  4288. //
  4289. //                $globalIdsByAppIdAndUser[$cwa['getUserAppId']][$cwa['getUserId']] =
  4290. //                    array(
  4291. //                        'gid' => $centralUser->getApplicantId()
  4292. //                    );
  4293.             return new JsonResponse(
  4294.                 array(
  4295.                     "success" => true,
  4296.                     "retDataDebug" => $retDataDebug,
  4297.                     "serverIdsCalledAlready" => $serverIdsCalledAlready,
  4298.                     "appIdList" => $appIdList,
  4299.                     "userFiles" => $userFiles,
  4300.                     "retAppIds" => $retAppIds,
  4301.                 )
  4302.             );
  4303.         } else {
  4304.             $userDataList $request->get('userData', []);
  4305.             if (is_string($userDataList)) $userDataList json_decode($userDataListtrue);
  4306.             if ($userDataList == null$userDataList = [];
  4307.             foreach ($userDataList as $userData) {
  4308.                 $em_goc $this->getDoctrine()->getManager('company_group');
  4309.                 $em $this->getDoctrine()->getManager('company_group');
  4310.                 $em->getConnection()->connect();
  4311.                 $connected $em->getConnection()->isConnected();
  4312.                 $gocDataList = [];
  4313.                 $gocDataListByAppId = [];
  4314.                 $retDataDebug = array();
  4315.                 $appIds json_decode($userData['getUserAppIds'], true);
  4316.                 if ($appIds == null$appIds = [];
  4317.                 $userTypesByAppIds json_decode($userData['getUserTypesByAppIds'], true);
  4318.                 if ($userTypesByAppIds == null$userTypesByAppIds = [];
  4319.                 $userIds $request->get('userIds''_UNSET_');
  4320.                 if ($connected && !empty($appIds)) {
  4321.                     $findByQuery = array(
  4322.                         'active' => 1
  4323.                     );
  4324.                     $findByQuery['appId'] = $appIds;
  4325.                     $gocList $this->getDoctrine()->getManager('company_group')
  4326.                         ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  4327.                         ->findBy($findByQuery);
  4328.                     $imagePathToSet '';
  4329.                     $uploadedFile $request->files->get('file_' $userData['getApplicantId'], null);
  4330.                     {
  4331.                         if ($uploadedFile != null) {
  4332.                             $fileName 'user_image' $userData['getApplicantId'] . '.' $uploadedFile->guessExtension();
  4333.                             $path $fileName;
  4334.                             $upl_dir $this->container->getParameter('kernel.root_dir') . '/../web/uploads/UserImage/';
  4335.                             if (!file_exists($upl_dir)) {
  4336.                                 mkdir($upl_dir0777true);
  4337.                             }
  4338.                             $file $uploadedFile->move($upl_dir$path);
  4339.                             $imagePathToSet 'uploads/UserImage/' $path;
  4340.                         }
  4341.                     }
  4342.                     foreach ($gocList as $entry) {
  4343.                         $d = array(
  4344.                             'name' => $entry->getName(),
  4345.                             'id' => $entry->getId(),
  4346.                             'image' => $entry->getImage(),
  4347.                             'companyGroupHash' => $entry->getCompanyGroupHash(),
  4348.                             'dbName' => $entry->getDbName(),
  4349.                             'dbUser' => $entry->getDbUser(),
  4350.                             'dbPass' => $entry->getDbPass(),
  4351.                             'dbHost' => $entry->getDbHost(),
  4352.                             'appId' => $entry->getAppId(),
  4353.                             'companyRemaining' => $entry->getCompanyRemaining(),
  4354.                             'companyAllowed' => $entry->getCompanyAllowed(),
  4355.                         );
  4356.                         $gocDataList[$entry->getId()] = $d;
  4357.                         $gocDataListByAppId[$entry->getAppId()] = $d;
  4358.                     }
  4359.                     $debugCount 0;
  4360.                     foreach ($gocDataList as $gocId => $entry) {
  4361. //                    if($debugCount>0)
  4362. //                        continue;
  4363.                         $skipSend 1;
  4364.                         $connector $this->container->get('application_connector');
  4365.                         $connector->resetConnection(
  4366.                             'default',
  4367.                             $gocDataList[$gocId]['dbName'],
  4368.                             $gocDataList[$gocId]['dbUser'],
  4369.                             $gocDataList[$gocId]['dbPass'],
  4370.                             $gocDataList[$gocId]['dbHost'],
  4371.                             $reset true);
  4372.                         $em $this->getDoctrine()->getManager();
  4373.                         $user $this->getDoctrine()
  4374.                             ->getRepository('ApplicationBundle\\Entity\\SysUser')
  4375.                             ->findOneBy(
  4376.                                 array(
  4377.                                     'globalId' => $userData['getApplicantId']
  4378.                                 )
  4379.                             );
  4380.                         $output '';
  4381.                         if (!$user)
  4382.                             $user = new SysUser();
  4383.                         $user->setGlobalId($userData['getApplicantId']);
  4384.                         $user->setUserAppId($entry['appId']);
  4385.                         $user_type 1;
  4386.                         if (isset($userData['userTypesByAppIds'][$entry['appId']])) {
  4387.                             $user_type $userData['userTypesByAppIds'][$entry['appId']];
  4388.                         }
  4389.                         $user->setUserType($user_type);
  4390.                         $user->setUserAppIdList(json_encode($appIds));
  4391.                         $user->setName($userData['getFirstname'] . ' ' $userData['getLastname']);
  4392.                         $user->setStatus(UserConstants::ACTIVE_USER);
  4393.                         if (!isset($userData['getFirstname']) && !isset($userData['getFirstName'])) {
  4394.                             if (isset($userData['getName'])) {
  4395.                                 $nameStrArr explode(" "$userData['getName']);
  4396.                                 $userData['getFirstname'] = isset($nameStrArr[0]) ? $nameStrArr[0] : '';
  4397.                                 $userData['getLastname'] = isset($nameStrArr[1]) ? $nameStrArr[1] : '';
  4398.                             }
  4399.                             $userData['getFirstName'] = $userData['getFirstname'];
  4400.                             $userData['getLastName'] = $userData['getLastname'];
  4401.                         } else if (!isset($userData['getFirstName'])) {
  4402.                             $userData['getFirstName'] = $userData['getFirstname'];
  4403.                             $userData['getLastName'] = $userData['getLastname'];
  4404.                         } else if (!isset($userData['getFirstname'])) {
  4405.                             $userData['getFirstname'] = $userData['getFirstName'];
  4406.                             $userData['getLastname'] = $userData['getLastName'];
  4407.                         }
  4408.                         if (!isset($userData['getName'])) {
  4409.                             $userData['getName'] = $userData['getFirstname'] . ' ' $userData['getLastName'];
  4410.                         }
  4411.                         foreach ($userData as $getter => $value) {
  4412.                             if ($getter == 'getApplicantId')
  4413.                                 continue;
  4414.                             $setMethod str_replace('get''set'$getter);
  4415.                             if (method_exists($user$setMethod)) {
  4416.                                 if ($user->{$getter}() instanceof \DateTime)
  4417.                                     $user->{$setMethod}(new \DateTime($value)); // `foo!`
  4418.                                 else if ($setMethod == 'setUserAppIds') {
  4419.                                 } else
  4420.                                     $user->{$setMethod}($value); // `foo!`
  4421.                             }
  4422.                         }
  4423.                         if ($imagePathToSet != "") {
  4424.                             if ($user->getImage() != $imagePathToSet && $user->getImage() != '' && $user->getImage() != null && file_exists($this->container->getParameter('kernel.root_dir') . '/../web/' $user->getImage())) {
  4425.                                 unlink($this->container->getParameter('kernel.root_dir') . '/../web/' $user->getImage());
  4426.                             }
  4427.                             $user->setImage($imagePathToSet);
  4428.                         }
  4429.                         $em->persist($user);
  4430.                         $em->flush();
  4431.                         ///new test add employee
  4432.                         ///
  4433.                         $employee $em->getRepository('ApplicationBundle\\Entity\\Employee')->findOneBy(['userId' => $user->getUserId()]);
  4434.                         if (!$employee)
  4435.                             $employee = new Employee();
  4436.                         if ($employee) {
  4437.                             $employee->setFirstName($userData['getFirstname']);
  4438.                             $employee->setLastName($userData['getLastname']);
  4439.                             $employee->setName($userData['getFirstname'] . ' ' $userData['getLastname']);
  4440.                             $employee->setUserId($user->getUserId());
  4441.                             $em->persist($employee);
  4442.                         }
  4443.                         $em->flush();
  4444.                         if ($employee)
  4445.                             $employeeDetails $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  4446.                                 ->findOneBy(['id' => $employee->getEmployeeId()]);
  4447.                         else
  4448.                             $employeeDetails $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')
  4449.                                 ->findOneBy(['userId' => $user->getUserId()]);
  4450.                         if (!$employeeDetails) {
  4451.                             $employeeDetails = new EmployeeDetails();
  4452.                             $employeeDetails->setEmpType(1);
  4453.                             $employeeDetails->setEmpStatus(1);
  4454.                         }
  4455.                         if ($employeeDetails) {
  4456.                             $employeeDetails->setFirstname($userData['getFirstname']);
  4457.                             $employeeDetails->setLastname($userData['getLastname']);
  4458.                             $employeeDetails->setUsername($userData['getUsername']);
  4459.                             $employeeDetails->setEmail($userData['getEmail']);
  4460.                             $employeeDetails->setPhone($userData['getPhone'] ?? null);
  4461.                             $employeeDetails->setNid($userData['getNid'] ?? null);
  4462.                             $employeeDetails->setSex($userData['getSex'] ?? null);
  4463.                             $employeeDetails->setBlood($userData['getBlood'] ?? null);
  4464.                             $employeeDetails->setFather($userData['getFather'] ?? null);
  4465.                             $employeeDetails->setMother($userData['getMother'] ?? null);
  4466.                             $employeeDetails->setSpouse($userData['getSpouse'] ?? null);
  4467.                             $employeeDetails->setCurrAddr($userData['getCurrAddr'] ?? null);
  4468.                             $employeeDetails->setPermAddr($userData['getPermAddr'] ?? null);
  4469.                             $employeeDetails->setUserId($user->getUserId());
  4470.                             $employeeDetails->setId($employee->getEmployeeId());
  4471.                             $em->persist($employeeDetails);
  4472.                         }
  4473.                         $em->flush();
  4474.                         /// new test end
  4475.                         $debugCount++;
  4476.                         $retDataDebug[$debugCount] = array(
  4477.                             'skipSend' => $skipSend,
  4478.                             'userId' => $user->getUserId(),
  4479.                             'appId' => $user->getUserAppId(),
  4480.                         );
  4481.                     }
  4482.                 }
  4483.             }
  4484.             return new JsonResponse($retDataDebug);
  4485.         }
  4486.     }
  4487.     public function GetUsersByQueryAction(Request $request$id 0)
  4488.     {
  4489.         $message "";
  4490.         $gocList = [];
  4491.         $outputList = [];
  4492.         $queryType '_ANY_';
  4493. //        if ($request->has('queryType'))
  4494.         $queryType $request->get('queryType''_ANY_');
  4495.         $returnData = [];
  4496.         $debugData = [];
  4497.         $returnDataArray = [];
  4498.         $returnDataByServerId = [];
  4499.         $serverId $request->get('serverId'4);
  4500.         $serverUrl $request->get('serverUrl''http://194.195.244.141');
  4501.         $serverPort $request->get('serverPort''');
  4502.         $queryStr $request->get('queryStr''');
  4503.         $queryStrEmail $request->get('quryStrEmail''');
  4504.         $queryStrPhone $request->get('quryStrPhone''');
  4505.         if ($queryStrEmail == '' && $queryStrPhone == '') {
  4506.             $queryStrEmail $queryStr;
  4507.         }
  4508. //        sample
  4509. //        data will be by company id
  4510.         $d = array(
  4511.             'userType' => 2,
  4512.             'userId' => 4,
  4513.             'userName' => 'abc',
  4514.             'loginUserName' => 'CID-abc',
  4515.             'serverId' => $serverId,
  4516.             'serverUrl' => $serverUrl,
  4517.             'systemType' => $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_',
  4518.             'gocId' => 2,
  4519.             'companyId' => 1,
  4520.             'appId' => 45,
  4521.             'companyLogoUrl' => '/uploads/CompanyImage/4c48d9d0f26918c8bd866a197e50e15e.png',
  4522.             'companyName' => 'HoneyBee Iot Ltd.',
  4523.             'userCompanyIds' => [14],
  4524.             'userAppIds' => [140],
  4525.             'userCompanyList' => [
  4526.                 => [
  4527.                     'companyLogoUrl' => '/uploads/CompanyImage/4c48d9d0f26918c8bd866a197e50e15e.png',
  4528.                     'companyName' => 'HoneyBee IoT Ltd.',
  4529.                 ],
  4530.                 => [
  4531.                     'companyLogoUrl' => '/uploads/CompanyImage/4c48d9d0f26918c8bd866a197e50e15e.png',
  4532.                     'companyName' => 'Nastec Srl',
  4533.                 ]
  4534.             ]
  4535.         );
  4536. //        return new JsonResponse(array(
  4537. //            $d, $d
  4538. //        ));
  4539.         $em $this->getDoctrine()->getManager('company_group');
  4540.         $em->getConnection()->connect();
  4541.         $connected $em->getConnection()->isConnected();
  4542.         if ($connected)
  4543.             $gocList $this->getDoctrine()->getManager('company_group')
  4544.                 ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  4545.                 ->findBy(
  4546.                     array(
  4547.                         'active' => 1
  4548.                     )
  4549.                 );
  4550.         $gocDataList = [];
  4551.         foreach ($gocList as $entry) {
  4552.             $d = array(
  4553.                 'name' => $entry->getName(),
  4554.                 'id' => $entry->getId(),
  4555.                 'dbName' => $entry->getDbName(),
  4556.                 'dbUser' => $entry->getDbUser(),
  4557.                 'dbPass' => $entry->getDbPass(),
  4558.                 'dbHost' => $entry->getDbHost(),
  4559.                 'appId' => $entry->getAppId(),
  4560.                 'companyRemaining' => $entry->getCompanyRemaining(),
  4561.                 'companyAllowed' => $entry->getCompanyAllowed(),
  4562.             );
  4563.             $gocDataList[$entry->getId()] = $d;
  4564.         }
  4565.         $gocDbName '';
  4566.         $gocDbUser '';
  4567.         $gocDbPass '';
  4568.         $gocDbHost '';
  4569.         $gocId 0;
  4570. //        $web_root_dir = $this->container->getParameter('kernel.root_dir'). '/../web' ;
  4571.         $web_root_dir $url $this->generateUrl('dashboard', [], UrlGenerator::ABSOLUTE_URL);
  4572. //        $root_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/temp/' . 'ledger' . '.pdf';
  4573.         foreach ($gocDataList as $gocId => $entry) {
  4574.             $connector $this->container->get('application_connector');
  4575.             $connector->resetConnection(
  4576.                 'default',
  4577.                 $gocDataList[$gocId]['dbName'],
  4578.                 $gocDataList[$gocId]['dbUser'],
  4579.                 $gocDataList[$gocId]['dbPass'],
  4580.                 $gocDataList[$gocId]['dbHost'],
  4581.                 $reset true);
  4582.             $em $this->getDoctrine()->getManager();
  4583.             $companyList = [];
  4584.             $query "SELECT * from  company   where 1";
  4585.             $stmt $em->getConnection()->fetchAllAssociative($query);
  4586.             $results $stmt;
  4587.             if (!empty($results))
  4588.                 foreach ($results as $dt) {
  4589.                     $companyList[$dt['id']] = $dt;
  4590.                 }
  4591.             else
  4592.                 $companyList = array(
  4593.                     => [
  4594.                         'image' => '',
  4595.                         'name' => 'Company',
  4596.                     ]
  4597.                 );
  4598.             ///SysUSER
  4599.             $fieldName = ($queryType == '_EMAIL_' || $queryType == '_ANY_') ? 'email' 'phone_number';
  4600.             if ($queryStrEmail == '' && $queryStrPhone == '') {
  4601.             } else {
  4602.                 $emailFieldName 'email';
  4603.                 $phoneFieldName 'phone_number';
  4604.                 $userNameFieldName 'user_name';
  4605.                 $query "SELECT * from  sys_user   where 1=1 ";
  4606.                 $query .= ($queryStrEmail != '') ? "and $emailFieldName like '$queryStrEmail' " '';
  4607.                 $query .= ($queryStrPhone != '') ? "and $phoneFieldName like '%$queryStrPhone%' " '';
  4608.                 $query .= ($queryStr != '') ? " or $userNameFieldName like '$queryStr' " '';
  4609.                 $stmt $em->getConnection()->fetchAllAssociative($query);
  4610.                 $results $stmt;
  4611.                 if (!empty($results)) {
  4612.                     foreach ($results as $dt) {
  4613. //                        if($dt['company_id']==0 || $dt['company_id'] ==null)
  4614.                         $dt['company_id'] = "1";
  4615.                         $user_app_ids json_decode($dt['user_app_id_list'], true);
  4616.                         if ($user_app_ids == null$user_app_ids = [$dt['app_id']];
  4617.                         $user_company_ids json_decode($dt['user_company_id_list'], true);
  4618.                         if ($user_company_ids == null$user_company_ids = [$dt['company_id']];
  4619.                         $companyData = isset($companyList[$dt['company_id']]) ? $companyList[$dt['company_id']] : [];
  4620.                         $d = array(
  4621.                             'userType' => $dt['user_type'],
  4622.                             'userName' => $dt['user_name'],
  4623.                             'userId' => $dt['user_id'],
  4624.                             'loginUserName' => $dt['user_name'],
  4625.                             'email' => $dt['email'],
  4626.                             'phone' => $dt['phone_number'],
  4627.                             'serverId' => $serverId,
  4628.                             'serverUrl' => $serverUrl,
  4629.                             'systemType' => $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_',
  4630.                             'gocId' => $gocId,
  4631.                             'companyId' => $dt['company_id'],
  4632.                             'appId' => $dt['app_id'],
  4633.                             'companyLogoUrl' => $web_root_dir $companyData['image'],
  4634.                             'companyName' => $companyData['name'],
  4635.                             'userCompanyIds' => $user_company_ids,
  4636.                             'userAppIds' => $user_app_ids,
  4637.                             'userCompanyList' => [
  4638.                             ]
  4639.                         );
  4640.                         foreach ($user_company_ids as $cid) {
  4641.                             $d['userCompanyList'][$cid] = [
  4642.                                 'companyLogoUrl' => $web_root_dir $companyList[$cid]['image'],
  4643.                                 'companyName' => $companyList[$cid]['name'],
  4644.                             ];
  4645.                         }
  4646.                         $returnData[] = $d;
  4647.                         $returnDataByServerId[$serverId][] = $d;
  4648.                     }
  4649.                 }
  4650.                 //now customers
  4651.                 $emailFieldName 'email';
  4652.                 $phoneFieldName 'contact_number';
  4653.                 $query "SELECT * from  acc_clients   where 1=1 ";
  4654.                 $query .= ($queryStrEmail != '') ? "and $emailFieldName like '$queryStrEmail'" '';
  4655.                 $query .= ($queryStrPhone != '') ? "and $phoneFieldName like '%$queryStrPhone%'" '';
  4656.                 $stmt $em->getConnection()->fetchAllAssociative($query);
  4657.                 $results $stmt;
  4658.                 if (!empty($results)) {
  4659.                     foreach ($results as $dt) {
  4660.                         $dt['company_id'] = "1";
  4661.                         $companyData = isset($companyList[$dt['company_id']]) ? $companyList[$dt['company_id']] : [];
  4662.                         $d = array(
  4663.                             'userType' => strval(UserConstants::USER_TYPE_CLIENT),
  4664.                             'userName' => 'CID-' str_pad($dt['client_id'], 8'0'STR_PAD_LEFT),
  4665.                             'userId' => $dt['client_id'],
  4666.                             'loginUserName' => $dt['username'],
  4667.                             'email' => $dt['email'],
  4668.                             'phone' => $dt['contact_number'],
  4669.                             'serverId' => $serverId,
  4670.                             'serverUrl' => $serverUrl,
  4671.                             'systemType' => $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_',
  4672.                             'gocId' => $gocId,
  4673.                             'companyId' => $dt['company_id'],
  4674.                             'appId' => $dt['app_id'],
  4675.                             'companyLogoUrl' => $web_root_dir $companyData['image'],
  4676.                             'companyName' => $companyData['name'],
  4677.                             'userCompanyIds' => [],
  4678.                             'userAppIds' => [],
  4679.                             'userCompanyList' => [
  4680.                             ]
  4681.                         );
  4682.                         $returnData[] = $d;
  4683.                         $returnDataByServerId[$serverId][] = $d;
  4684.                     }
  4685.                 }
  4686.                 //now suppliers
  4687.                 $emailFieldName 'email';
  4688.                 $phoneFieldName 'contact_number';
  4689.                 $query "SELECT * from  acc_suppliers   where 1=1 ";
  4690.                 $query .= ($queryStrEmail != '') ? "and $emailFieldName like '$queryStrEmail'" '';
  4691.                 $query .= ($queryStrPhone != '') ? "and $phoneFieldName like '%$queryStrPhone%'" '';
  4692.                 $stmt $em->getConnection()->fetchAllAssociative($query);
  4693.                 $results $stmt;
  4694.                 if (!empty($results)) {
  4695.                     foreach ($results as $dt) {
  4696.                         $dt['company_id'] = "1";
  4697.                         $companyData = isset($companyList[$dt['company_id']]) ? $companyList[$dt['company_id']] : [];
  4698.                         $d = array(
  4699.                             'userType' => strval(UserConstants::USER_TYPE_SUPPLIER),
  4700.                             'userName' => 'SID-' str_pad($dt['supplier_id'], 8'0'STR_PAD_LEFT),
  4701.                             'userId' => $dt['supplier_id'],
  4702.                             'loginUserName' => $dt['username'],
  4703.                             'email' => $dt['email'],
  4704.                             'phone' => $dt['contact_number'],
  4705.                             'serverId' => $serverId,
  4706.                             'serverUrl' => $serverUrl,
  4707.                             'systemType' => $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_',
  4708.                             'gocId' => $gocId,
  4709.                             'companyId' => $dt['company_id'],
  4710.                             'appId' => $dt['app_id'],
  4711.                             'companyLogoUrl' => $web_root_dir $companyData['image'],
  4712.                             'companyName' => $companyData['name'],
  4713.                             'userCompanyIds' => [],
  4714.                             'userAppIds' => [],
  4715.                             'userCompanyList' => [
  4716.                             ]
  4717.                         );
  4718.                         $returnData[] = $d;
  4719.                         $returnDataByServerId[$serverId][] = $d;
  4720.                     }
  4721.                 }
  4722.             }
  4723.         }
  4724.         return new JsonResponse(array(
  4725.             'success' => true,
  4726.             'data' => $returnData,
  4727.             'debugData' => $debugData,
  4728.             'dataByServerId' => $returnDataByServerId,
  4729.             'queryType' => $queryType
  4730.         ));
  4731.     }
  4732.     public function GetHoneybeeServerListAction(Request $request$id 0)
  4733.     {
  4734.         $serverList GeneralConstant::$serverList;
  4735.         return new JsonResponse(array(
  4736.             'success' => true,
  4737.             'data' => $serverList,
  4738.         ));
  4739.     }
  4740.     public function ServerListAction()
  4741.     {
  4742.         $serverList GeneralConstant::$serverList;
  4743.         return new JsonResponse(
  4744.             $serverList
  4745.         );
  4746.     }
  4747.     public function widgetModuleListAction()
  4748.     {
  4749.         $widgetsModuleList = [
  4750.             [
  4751.                 'name' => 'Accounts',
  4752.                 'id' => 1,
  4753.                 'hash' => '_ACC_',
  4754.                 'enabled' => true,
  4755.                 'hidden' => true,
  4756.             ],
  4757.             [
  4758.                 'name' => 'Sales',
  4759.                 'id' => 2,
  4760.                 'hash' => '_SL_',
  4761.                 'enabled' => true,
  4762.                 'hidden' => true,
  4763.             ],
  4764.             [
  4765.                 'name' => 'Human Resource',
  4766.                 'id' => 3,
  4767.                 'hash' => '_HRM_',
  4768.                 'enabled' => true,
  4769.                 'hidden' => true,
  4770.             ],
  4771.             [
  4772.                 'name' => 'Admin',
  4773.                 'id' => 4,
  4774.                 'hash' => '_ADM_',
  4775.                 'enabled' => true,
  4776.                 'hidden' => true,
  4777.             ],
  4778.         ];
  4779.         return new JsonResponse(
  4780.             array(
  4781.                 'success' => true,
  4782.                 'widgetModuleList' => $widgetsModuleList
  4783.             )
  4784.         );
  4785.     }
  4786.     public function widgetListAction()
  4787.     {
  4788.         $widgetsList = [
  4789.             [
  4790.                 'id' => 1,
  4791.                 'name' => 'Expense',
  4792.                 'hash' => '_EXP_',
  4793.                 'widgetModuleId' => 1,
  4794.                 'widgetName' => 'Accounts',
  4795.                 'screenName' => '',
  4796.                 'hidden' => true,
  4797.                 'enabled' => true,
  4798.                 'image' => 'https://e7.pngegg.com/pngimages/640/646/png-clipart-expense-management-computer-icons-finance-others-miscellaneous-text.png',
  4799.                 'showOnHome' => true,
  4800.                 'routeList' => [
  4801.                 ]
  4802.             ],
  4803.             [
  4804.                 'id' => 2,
  4805.                 'name' => 'Attendance',
  4806.                 'hash' => '_ATD_',
  4807.                 'widgetModuleId' => 3,
  4808.                 'widgetName' => 'Human Resource',
  4809.                 'screenName' => '',
  4810.                 'hidden' => true,
  4811.                 'enabled' => true,
  4812.                 'image' => 'https://cdn.iconscout.com/icon/premium/png-256-thumb/biometric-attendance-1-1106795.png',
  4813.                 'showOnHome' => true,
  4814.                 'routeList' => [
  4815.                 ]
  4816.             ],
  4817.             [
  4818.                 'id' => 3,
  4819.                 'name' => 'Payment',
  4820.                 'hash' => '_PMT_',
  4821.                 'widgetModuleId' => 1,
  4822.                 'widgetName' => 'Accounts',
  4823.                 'screenName' => '',
  4824.                 'hidden' => true,
  4825.                 'enabled' => true,
  4826.                 'image' => 'https://banner2.cleanpng.com/20180628/gbi/kisspng-management-accounting-accountant-gestin-kontabil-contador-5b356a344f40d2.2788485015302272523246.jpg',
  4827.                 'showOnHome' => true,
  4828.                 'routeList' => [
  4829.                     ["id" => 3"route" => "create_payment_voucher""name" => "Make Payment""parentId" => 3,],
  4830.                     ["id" => 4"route" => "create_receipt_voucher""name" => "Make Receipt""parentId" => 3,],
  4831.                 ]
  4832.             ],
  4833.             [
  4834.                 'id' => 4,
  4835.                 'name' => 'Report',
  4836.                 'hash' => '_RPRT_',
  4837.                 'widgetModuleId' => 1,
  4838.                 'widgetName' => 'Accounts',
  4839.                 'screenName' => '',
  4840.                 'hidden' => true,
  4841.                 'enabled' => true,
  4842.                 'image' => 'https://cdn-icons-png.flaticon.com/512/3093/3093748.png',
  4843.                 'showOnHome' => true,
  4844.                 'routeList' => [
  4845.                 ]
  4846.             ],
  4847.             [
  4848.                 'id' => 5,
  4849.                 'name' => 'Leave Application',
  4850.                 'hash' => '_LEVAPP_',
  4851.                 'widgetModuleId' => 3,
  4852.                 'widgetName' => 'Human Resource',
  4853.                 'screenName' => '',
  4854.                 'hidden' => true,
  4855.                 'enabled' => true,
  4856.                 'image' => 'https://icons.veryicon.com/png/o/transport/easy-office-system-icon-library/leave-request.png',
  4857.                 'showOnHome' => true,
  4858.                 'routeList' => [
  4859.                 ]
  4860.             ],
  4861.             [
  4862.                 'id' => 6,
  4863.                 'name' => 'Fund Requisition',
  4864.                 'hash' => '_FR_',
  4865.                 'widgetModuleId' => 1,
  4866.                 'widgetName' => 'Accounts',
  4867.                 'screenName' => '',
  4868.                 'hidden' => true,
  4869.                 'enabled' => true,
  4870.                 'image' => 'https://www.pngall.com/wp-content/uploads/13/Fund-PNG-Image.png',
  4871.                 'showOnHome' => true,
  4872.                 'routeList' => [
  4873.                 ]
  4874.             ],
  4875.             [
  4876.                 'id' => 7,
  4877.                 'name' => 'My Task',
  4878.                 'hash' => '_MT_',
  4879.                 'widgetModuleId' => 3,
  4880.                 'widgetName' => 'Human Resource',
  4881.                 'screenName' => '',
  4882.                 'hidden' => true,
  4883.                 'enabled' => true,
  4884.                 'image' => 'https://st.depositphotos.com/44273736/54272/v/450/depositphotos_542726218-stock-illustration-premium-download-icon-task-management.jpg',
  4885.                 'showOnHome' => true,
  4886.                 'routeList' => [
  4887.                 ]
  4888.             ],
  4889.             [
  4890.                 'id' => 8,
  4891.                 'name' => 'Fund Transfer',
  4892.                 'hash' => '_FT_',
  4893.                 'widgetModuleId' => 3,
  4894.                 'widgetName' => 'Accounts',
  4895.                 'screenName' => '',
  4896.                 'hidden' => true,
  4897.                 'enabled' => true,
  4898.                 'image' => 'https://l450v.alamy.com/450v/r1r4rx/money-transfer-vector-icon-isolated-on-transparent-background-money-transfer-transparency-logo-concept-r1r4rx.jpg',
  4899.                 'showOnHome' => true,
  4900.                 'routeList' => [
  4901.                 ]
  4902.             ],
  4903.             [
  4904.                 'id' => 9,
  4905.                 'name' => 'Stock Management',
  4906.                 'hash' => '_SM_',
  4907.                 'widgetModuleId' => 3,
  4908.                 'widgetName' => 'Inventory',
  4909.                 'screenName' => '',
  4910.                 'hidden' => true,
  4911.                 'enabled' => true,
  4912.                 'image' => 'https://l450v.alamy.com/450v/r1r4rx/money-transfer-vector-icon-isolated-on-transparent-background-money-transfer-transparency-logo-concept-r1r4rx.jpg',
  4913.                 'showOnHome' => true,
  4914.                 'routeList' => [
  4915.                 ]
  4916.             ],
  4917.             [
  4918.                 'id' => 10,
  4919.                 'name' => 'Approval',
  4920.                 'hash' => '_ADM_',
  4921.                 'widgetModuleId' => 4,
  4922.                 'widgetName' => 'Inventory',
  4923.                 'screenName' => '',
  4924.                 'hidden' => true,
  4925.                 'enabled' => true,
  4926.                 'image' => 'https://cdn.icon-icons.com/icons2/907/PNG/512/approve-sign-in-a-black-rounded-square-shape_icon-icons.com_70558.png',
  4927.                 'showOnHome' => true,
  4928.                 'routeList' => [
  4929.                 ]
  4930.             ],
  4931.         ];
  4932.         return new JsonResponse(
  4933.             array(
  4934.                 'success' => true,
  4935.                 'widgetList' => $widgetsList
  4936.             )
  4937.         );
  4938.     }
  4939.     public function addRemoveWidgetAction(Request $request$id 0)
  4940.     {
  4941.         $em $this->getDoctrine()->getManager();
  4942. //        $user = $em->getRepository("ApplicationBundle\\Entity\\SysUser")
  4943. //            ->findBy();
  4944.         return new  JsonResponse(
  4945. //            $user
  4946.         );
  4947.     }
  4948.     public function EncryptParentModulesAction(Request $request$appId 0$companyId 0)
  4949.     {
  4950.         $message "";
  4951.         $gocList = [];
  4952.         $outputList = [];
  4953.         $pmodules = [];
  4954.         if ($request->query->has('modulesByComma'))
  4955.             $pmodules explode(','$request->query->get('modulesByComma'));
  4956.         $iv '1234567812345678';
  4957.         $pass $appId '_' $companyId;
  4958.         //        $method = 'aes-256-cbc';
  4959.         $str json_encode($pmodules);
  4960. //                        $str=$request->query->get('modulesByComma');
  4961.         $str $str 'YmLRocksLikeABoss';
  4962.         $data $str;
  4963.         $data openssl_encrypt($str"AES-128-CBC"$pass0$iv);
  4964.         //        $data=$str;
  4965. //                        $data = openssl_decrypt($data, "AES-128-CBC", $pass, 0, $iv);
  4966. //                        $data = openssl_decrypt(base64_decode(base64_encode($data)), "AES-128-CBC", $pass, 0, $iv);
  4967.         return new Response($data);
  4968. //        return new JsonResponse(array(
  4969. //            'encData'=>$data
  4970. //        ));
  4971.     }
  4972.     public function PrepareDatabaseAction(Request $request)
  4973.     {
  4974.         $message "";
  4975.         $gocList = [];
  4976.         $outputList = [];
  4977.         $em $this->getDoctrine()->getManager('company_group');
  4978.         $em->getConnection()->connect();
  4979.         $connected $em->getConnection()->isConnected();
  4980.         if ($connected)
  4981.             $gocList $this->getDoctrine()->getManager('company_group')
  4982.                 ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  4983.                 ->findBy(
  4984.                     array(
  4985.                         'active' => 1
  4986.                     )
  4987.                 );
  4988.         $gocDataList = [];
  4989.         foreach ($gocList as $entry) {
  4990.             $d = array(
  4991.                 'name' => $entry->getName(),
  4992.                 'id' => $entry->getId(),
  4993.                 'dbName' => $entry->getDbName(),
  4994.                 'dbUser' => $entry->getDbUser(),
  4995.                 'dbPass' => $entry->getDbPass(),
  4996.                 'dbHost' => $entry->getDbHost(),
  4997.                 'appId' => $entry->getAppId(),
  4998.                 'companyRemaining' => $entry->getCompanyRemaining(),
  4999.                 'companyAllowed' => $entry->getCompanyAllowed(),
  5000.             );
  5001.             $gocDataList[$entry->getId()] = $d;
  5002.         }
  5003.         $gocDbName '';
  5004.         $gocDbUser '';
  5005.         $gocDbPass '';
  5006.         $gocDbHost '';
  5007.         $gocId 0;
  5008. //        $path = $this->container->get('templating.helper.assets')->getUrl('bundles/tlfront/js/channels.json');
  5009.         $config_dir $this->container->getParameter('kernel.root_dir') . '/gifnoc/';
  5010.         if (!file_exists($config_dir)) {
  5011.             mkdir($config_dir0777true);
  5012.         }
  5013. //        $path = $this->container->getParameter('kernel.root_dir') . '/gifnoc/givnocppa.json';
  5014. //        $content = file_exists($path) ? file_get_contents($path) : null;
  5015.         $content = [];
  5016.         $configJson = array();
  5017.         if ($content)
  5018.             $configJson json_decode($contenttrue);
  5019.         $configJsonOld $configJson;
  5020. //        if($configJson)
  5021. //        {
  5022. //
  5023. //        }
  5024. //        else
  5025.         {
  5026.             $configJson['appVersion'] = GeneralConstant::ENTITY_APP_VERSION;
  5027.             $configJson['dataBaseSchemaUpdateFlag'] = GeneralConstant::ENTITY_APP_FLAG_TRUE;
  5028.             $configJson['initiateDataBaseFlag'] = GeneralConstant::ENTITY_APP_FLAG_FALSE;
  5029.             $configJson['initiateDataBaseFlagByGoc'] = array();
  5030.             $configJson['motherLode'] = "http://innobd.com";
  5031.             foreach ($gocDataList as $gocId => $entry) {
  5032.                 $configJson['initiateDataBaseFlagByGoc'][$gocId "_" $entry['appId']] = GeneralConstant::ENTITY_APP_FLAG_TRUE;
  5033.             }
  5034.         }
  5035.         //now check if database shcema update is true
  5036. //        if($configJson['dataBaseSchemaUpdateFlag']==GeneralConstant::ENTITY_APP_FLAG_TRUE)
  5037.         if (1//temporary overwrite all
  5038.         {
  5039.             //if goclist is not empty switch to each company dbase and schema update
  5040. //            if(!empty($gocDataList))
  5041.             if (1) {
  5042.                 foreach ($gocDataList as $gocId => $entry) {
  5043.                     if ($configJson['initiateDataBaseFlagByGoc'][$gocId "_" $entry['appId']] == GeneralConstant::ENTITY_APP_FLAG_TRUE) {
  5044.                         $connector $this->container->get('application_connector');
  5045.                         $connector->resetConnection(
  5046.                             'default',
  5047.                             $gocDataList[$gocId]['dbName'],
  5048.                             $gocDataList[$gocId]['dbUser'],
  5049.                             $gocDataList[$gocId]['dbPass'],
  5050.                             $gocDataList[$gocId]['dbHost'],
  5051.                             true);
  5052.                         $em $this->getDoctrine()->getManager();
  5053.                         if ($em->getConnection()->isConnected()) {
  5054.                         } else {
  5055.                             $servername $gocDataList[$gocId]['dbHost'];
  5056.                             $username $gocDataList[$gocId]['dbUser'];
  5057.                             $password $gocDataList[$gocId]['dbPass'];
  5058. // Create connection
  5059.                             $conn = new \mysqli($servername$username$password);
  5060. // Check connection
  5061.                             if ($conn->connect_error) {
  5062.                                 die("Connection failed: " $conn->connect_error);
  5063.                             }
  5064. // Create database
  5065.                             $sql "CREATE DATABASE " $gocDataList[$gocId]['dbName'];
  5066.                             if ($conn->query($sql) === TRUE) {
  5067. //                                echo "Database created successfully";
  5068.                             } else {
  5069. //                                echo "Error creating database: " . $conn->error;
  5070.                             }
  5071.                             $conn->close();
  5072.                         }
  5073.                         $connector->resetConnection(
  5074.                             'default',
  5075.                             $gocDataList[$gocId]['dbName'],
  5076.                             $gocDataList[$gocId]['dbUser'],
  5077.                             $gocDataList[$gocId]['dbPass'],
  5078.                             $gocDataList[$gocId]['dbHost'],
  5079.                             true);
  5080.                         $em $this->getDoctrine()->getManager();
  5081.                         $tool = new SchemaTool($em);
  5082.                         $classes $em->getMetadataFactory()->getAllMetadata();
  5083. //                    $tool->createSchema($classes);
  5084.                         $tool->updateSchema($classes);
  5085.                         //new for updating app id
  5086.                         $get_kids_sql "UPDATE `company` set app_id=" $entry['appId'] . " ;
  5087.                                         UPDATE `sys_user` set app_id=" $entry['appId'] . " ;";
  5088.                         $stmt $em->getConnection()->executeStatement($get_kids_sql);
  5089.                         $configJson['initiateDataBaseFlagByGoc'][$gocId "_" $entry['appId']] = GeneralConstant::ENTITY_APP_FLAG_FALSE;
  5090.                         //this is for large amount of goc we will see  later
  5091. //                        file_put_contents($path, json_encode($configJson));//overwrite
  5092. //                        return $this->redirectToRoute('update_database_schema');
  5093.                     }
  5094.                 }
  5095.             } else {
  5096.                 $em $this->getDoctrine()->getManager();
  5097.                 $tool = new SchemaTool($em);
  5098. //                    $classes = array(
  5099. //                        $em->getClassMetadata('Entities\User'),
  5100. //                        $em->getClassMetadata('Entities\Profile')
  5101. //                    );
  5102.                 $classes $em->getMetadataFactory()->getAllMetadata();
  5103. //                    $tool->createSchema($classes);
  5104.                 $tool->updateSchema($classes);
  5105.             }
  5106.         }
  5107.         $allSchemaUpdateDone 1;
  5108.         foreach ($configJson['initiateDataBaseFlagByGoc'] as $flag) {
  5109.             if ($flag == GeneralConstant::ENTITY_APP_FLAG_TRUE)
  5110.                 $allSchemaUpdateDone 0;
  5111.         }
  5112.         if ($allSchemaUpdateDone == 1)
  5113.             $configJson['dataBaseSchemaUpdateFlag'] = GeneralConstant::ENTITY_APP_FLAG_FALSE;
  5114.         ///last
  5115. //        file_put_contents($path, json_encode($configJson));//overwrite
  5116.         return new Response(json_encode($configJsonOld));
  5117.     }
  5118.     public function ConvertSpecificationToSubCategoryAction(Request $request)
  5119.     {
  5120.         $message "";
  5121.         $gocList = [];
  5122.         $outputList = [];
  5123.         $em $this->getDoctrine()->getManager('company_group');
  5124.         $em->getConnection()->connect();
  5125.         $connected $em->getConnection()->isConnected();
  5126.         if ($connected)
  5127.             $gocList $this->getDoctrine()->getManager('company_group')
  5128.                 ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  5129.                 ->findBy(
  5130.                     array(
  5131.                         'active' => 1
  5132.                     )
  5133.                 );
  5134.         $gocDataList = [];
  5135.         foreach ($gocList as $entry) {
  5136.             $d = array(
  5137.                 'name' => $entry->getName(),
  5138.                 'id' => $entry->getId(),
  5139.                 'dbName' => $entry->getDbName(),
  5140.                 'dbUser' => $entry->getDbUser(),
  5141.                 'dbPass' => $entry->getDbPass(),
  5142.                 'dbHost' => $entry->getDbHost(),
  5143.                 'appId' => $entry->getAppId(),
  5144.                 'companyRemaining' => $entry->getCompanyRemaining(),
  5145.                 'companyAllowed' => $entry->getCompanyAllowed(),
  5146.             );
  5147.             $gocDataList[$entry->getId()] = $d;
  5148.         }
  5149.         $gocDbName '';
  5150.         $gocDbUser '';
  5151.         $gocDbPass '';
  5152.         $gocDbHost '';
  5153.         $gocId 0;
  5154. //        $path = $this->container->get('templating.helper.assets')->getUrl('bundles/tlfront/js/channels.json');
  5155.         $config_dir $this->container->getParameter('kernel.root_dir') . '/gifnoc/';
  5156.         if (!file_exists($config_dir)) {
  5157.             mkdir($config_dir0777true);
  5158.         }
  5159. //        $path = $this->container->getParameter('kernel.root_dir') . '/gifnoc/givnocppa.json';
  5160. //        $content = file_exists($path) ? file_get_contents($path) : null;
  5161.         $content = [];
  5162.         $configJson = array();
  5163.         if ($content)
  5164.             $configJson json_decode($contenttrue);
  5165.         $configJsonOld $configJson;
  5166. //        if($configJson)
  5167. //        {
  5168. //
  5169. //        }
  5170. //        else
  5171.         {
  5172.             $configJson['appVersion'] = GeneralConstant::ENTITY_APP_VERSION;
  5173.             $configJson['dataBaseSchemaUpdateFlag'] = GeneralConstant::ENTITY_APP_FLAG_TRUE;
  5174.             $configJson['initiateDataBaseFlag'] = GeneralConstant::ENTITY_APP_FLAG_FALSE;
  5175.             $configJson['initiateDataBaseFlagByGoc'] = array();
  5176.             $configJson['motherLode'] = "http://innobd.com";
  5177.             foreach ($gocDataList as $gocId => $entry) {
  5178.                 $configJson['initiateDataBaseFlagByGoc'][$gocId "_" $entry['appId']] = GeneralConstant::ENTITY_APP_FLAG_TRUE;
  5179.             }
  5180.         }
  5181.         $foundClasses = [];
  5182.         if (1) {
  5183.             foreach ($gocDataList as $gocId => $entry) {
  5184.                 $connector $this->container->get('application_connector');
  5185.                 $connector->resetConnection(
  5186.                     'default',
  5187.                     $gocDataList[$gocId]['dbName'],
  5188.                     $gocDataList[$gocId]['dbUser'],
  5189.                     $gocDataList[$gocId]['dbPass'],
  5190.                     $gocDataList[$gocId]['dbHost'],
  5191.                     $reset true);
  5192.                 $em $this->getDoctrine()->getManager();
  5193. /////////////////////////////Now get all entity and if entity has specificationId (and subcatid) the asssign
  5194.                 $query "show tables;";
  5195.                 $query "SELECT DISTINCT TABLE_NAME
  5196.     FROM INFORMATION_SCHEMA.COLUMNS
  5197.     WHERE COLUMN_NAME IN ('specification_id','sub_category_id')
  5198.         AND TABLE_SCHEMA='" $gocDataList[$gocId]['dbName'] . "' ;";
  5199.                 $stmt $em->getConnection()->fetchAllAssociative($query);
  5200.                 $tables $stmt;
  5201.                 foreach ($tables as $tablename) {
  5202. //                        $theClass=new $entity;
  5203.                     $foundClasses[] = $tablename['TABLE_NAME'];
  5204.                     $query "UPDATE " $tablename['TABLE_NAME'] . " set sub_category_id=specification_id where 1;";
  5205.                     $stmt $em->getConnection()->executeStatement($query);
  5206.                     $query "UPDATE " $tablename['TABLE_NAME'] . " set specification_id=null;";
  5207.                     $stmt $em->getConnection()->executeStatement($query);
  5208.                 }
  5209.                 //now add all spec to cat table
  5210.                 $query "TRUNCATE  inv_product_sub_categories";
  5211.                 $stmt $em->getConnection()->executeStatement($query);
  5212.                 $query "SELECT * FROM inv_product_specifications WHERE 1;";
  5213.                 $stmt $em->getConnection()->fetchAllAssociative($query);
  5214.                 $results $stmt;
  5215.                 foreach ($results as $result) {
  5216.                     foreach ($result as $k => $res) {
  5217.                         if ($res == '')
  5218.                             $result[$k] = 'NULL';
  5219.                     }
  5220.                     $query "INSERT INTO `inv_product_sub_categories`(`id`,  `name`, `status`, `ig_id`, `category_id`, `company_id`,  `created_login_id`, `edited_login_id`, `created_at`, `updated_at`)
  5221. VALUES (" $result['id'] . ",'" str_replace("'""''"$result['name']) . "'," $result['status'] . "," $result['ig_id'] . "," $result['category_id'] . "," $result['company_id'] . "," $result['created_login_id'] . "," $result['edited_login_id'] . ",'" $result['created_at'] . "','" $result['updated_at'] . "')";
  5222.                     $stmt $em->getConnection()->executeStatement($query);
  5223.                 }
  5224.                 $query "TRUNCATE  inv_product_specifications";
  5225.                 $stmt $em->getConnection()->executeStatement($query);
  5226.             }
  5227.         }
  5228.         return new Response(json_encode($foundClasses));
  5229.     }
  5230.     public function initiateAdminAction(Request $request)
  5231.     {
  5232.         $em $this->getDoctrine()->getManager();
  5233.         $em_goc $this->getDoctrine()->getManager('company_group');
  5234.         $em_goc->getConnection()->connect();
  5235.         $gocId 0;
  5236.         $appId 0;
  5237.         $gocEnabled 0;
  5238.         if ($this->container->hasParameter('entity_group_enabled'))
  5239.             $gocEnabled $this->container->getParameter('entity_group_enabled');
  5240.         if ($gocEnabled == 1)
  5241.             $connected $em_goc->getConnection()->isConnected();
  5242.         else
  5243.             $connected false;
  5244.         if ($connected)
  5245.             $gocList $em_goc
  5246.                 ->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
  5247.                 ->findBy(
  5248.                     array(
  5249.                         'active' => 1
  5250.                     )
  5251.                 );
  5252.         $gocDataList = [];
  5253.         $gocDataListForLoginWeb = [];
  5254.         $gocDataListByAppId = [];
  5255.         foreach ($gocList as $entry) {
  5256.             $d = array(
  5257.                 'name' => $entry->getName(),
  5258.                 'id' => $entry->getId(),
  5259.                 'appId' => $entry->getAppId(),
  5260.                 'skipInWebFlag' => $entry->getSkipInWebFlag(),
  5261.                 'skipInAppFlag' => $entry->getSkipInAppFlag(),
  5262.                 'dbName' => $entry->getDbName(),
  5263.                 'dbUser' => $entry->getDbUser(),
  5264.                 'dbPass' => $entry->getDbPass(),
  5265.                 'dbHost' => $entry->getDbHost(),
  5266.                 'companyRemaining' => $entry->getCompanyRemaining(),
  5267.                 'companyAllowed' => $entry->getCompanyAllowed(),
  5268.             );
  5269.             $gocDataList[$entry->getId()] = $d;
  5270.             if (in_array($entry->getSkipInWebFlag(), [0null]))
  5271.                 $gocDataListForLoginWeb[$entry->getId()] = $d;
  5272.             $gocDataListByAppId[$entry->getAppId()] = $d;
  5273.         }
  5274.         if ($request->request->has('gocId') || $request->query->has('gocId')) {
  5275.             $hasGoc 1;
  5276.             $gocId $request->request->get('gocId');
  5277.         }
  5278.         if ($request->request->has('appId') || $request->query->has('appId')) {
  5279.             $hasGoc 1;
  5280.             $appId $request->request->get('appId');
  5281.         }
  5282.         $refRoute $request->request->get('refRoute'$request->query->get('refRoute'''));
  5283.         if ($hasGoc == 1) {
  5284.             if ($gocId != && $gocId != "") {
  5285.                 $appId $gocDataList[$gocId]['appId'];
  5286.                 $connector $this->container->get('application_connector');
  5287.                 $connector->resetConnection(
  5288.                     'default',
  5289.                     $gocDataList[$gocId]['dbName'],
  5290.                     $gocDataList[$gocId]['dbUser'],
  5291.                     $gocDataList[$gocId]['dbPass'],
  5292.                     $gocDataList[$gocId]['dbHost'],
  5293.                     $reset true
  5294.                 );
  5295.             } else if ($appId != && $appId != "") {
  5296.                 $gocDbName $gocDataListByAppId[$appId]['dbName'];
  5297.                 $gocDbUser $gocDataListByAppId[$appId]['dbUser'];
  5298.                 $gocDbPass $gocDataListByAppId[$appId]['dbPass'];
  5299.                 $gocDbHost $gocDataListByAppId[$appId]['dbHost'];
  5300.                 $gocId $gocDataListByAppId[$appId]['id'];
  5301.                 $connector $this->container->get('application_connector');
  5302.                 $connector->resetConnection(
  5303.                     'default',
  5304.                     $gocDbName,
  5305.                     $gocDbUser,
  5306.                     $gocDbPass,
  5307.                     $gocDbHost,
  5308.                     $reset true
  5309.                 );
  5310.             }
  5311.         }
  5312.         $userName $request->request->get('username'$request->query->get('username''admin'));
  5313.         $name $request->request->get('name'$request->query->get('name''System Admin'));
  5314.         $password $request->request->get('password'$request->query->get('password''admin'));
  5315.         $email $request->request->get('email'$request->query->get('email''admin'));
  5316.         $encodedPassword $this->container->get('app.legacy_password_service')->hashWithSalt($password$userName);
  5317.         $companyIds $request->request->get('companyIds'$request->query->get('companyIds', [1]));
  5318.         $branchIds $request->request->get('branchIds'$request->query->get('branchIds', [1]));
  5319.         $appIds $request->request->get('appIds'$request->query->get('appIds', [$appId]));
  5320.         $freshFlag $request->request->get('fresh'$request->query->get('fresh'1));
  5321.         if ($freshFlag == 1) {
  5322.             $query "DELETE FROM sys_user WHERE user_type=1";
  5323.             $stmt $em->getConnection()->executeStatement($query);
  5324.         }
  5325.         $message $this->get('user_module')->addNewUser(
  5326.             $name,
  5327.             $email,
  5328.             $userName,
  5329.             $password,
  5330.             '',
  5331.             0,
  5332.             1,
  5333.             UserConstants::USER_TYPE_SYSTEM,
  5334.             $companyIds,
  5335.             $branchIds,
  5336.             '',
  5337.             "",
  5338.             1
  5339.         );
  5340.         $companyData $message[2];
  5341.         if ($message[0] == 'success') {
  5342.             $oAuthData = [
  5343.                 'email' => $email,
  5344.                 'uniqueId' => '',
  5345.                 'image' => '',
  5346.                 'emailVerified' => '',
  5347.                 'name' => $name,
  5348.                 'type' => '0',
  5349.                 'token' => '',
  5350.             ];
  5351.             if (GeneralConstant::EMAIL_ENABLED == 1) {
  5352.                 $bodyHtml '';
  5353.                 $bodyTemplate '@Application/email/templates/userRegistrationCompleteHoneybee.html.twig';
  5354.                 $bodyData = array(
  5355.                     'name' => $name,
  5356.                     'email' => $email,
  5357.                     'password' => $password,
  5358.                 );
  5359.                 $attachments = [];
  5360.                 $forwardToMailAddress $email;
  5361.                 if (filter_var($forwardToMailAddressFILTER_VALIDATE_EMAIL)) {
  5362. //                    $upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/temp/' . 'ledger' . '.pdf'
  5363.                     $new_mail $this->get('mail_module');
  5364.                     $new_mail->sendMyMail(array(
  5365.                         'senderHash' => '_CUSTOM_',
  5366.                         //                        'senderHash'=>'_CUSTOM_',
  5367.                         'forwardToMailAddress' => $forwardToMailAddress,
  5368.                         'subject' => 'Welcome to Honeybee Ecosystem ',
  5369. //                        'fileName' => 'Order#' . str_pad($id, 8, '0', STR_PAD_LEFT) . '.pdf',
  5370.                         'attachments' => $attachments,
  5371.                         'toAddress' => $forwardToMailAddress,
  5372.                         'fromAddress' => 'accounts@ourhoneybee.eu',
  5373.                         'userName' => 'accounts@ourhoneybee.eu',
  5374.                         'password' => \ApplicationBundle\Helper\MailerConfig::buddybeePassword(),
  5375.                         'smtpServer' => \ApplicationBundle\Helper\MailerConfig::host(),
  5376.                         'smtpPort' => \ApplicationBundle\Helper\MailerConfig::port(),
  5377. //                            'emailBody' => $bodyHtml,
  5378.                         'mailTemplate' => $bodyTemplate,
  5379.                         'templateData' => $bodyData,
  5380. //                        'embedCompanyImage' => 1,
  5381. //                        'companyId' => $companyId,
  5382. //                        'companyImagePath' => $company_data->getImage()
  5383.                     ));
  5384.                 }
  5385.             }
  5386. //            if ($request->request->get('remoteVerify', 0) == 1)
  5387. ////                if(1)
  5388. //                return new JsonResponse(array(
  5389. //                    'success' => true,
  5390. //                    'successStr' => 'Account Created Successfully',
  5391. //                    'id' => $newApplicant->getApplicantId(),
  5392. //                    'oAuthData' => $oAuthData,
  5393. //                    'refRoute' => $refRoute,
  5394. //                    'remoteVerify' => 1,
  5395. //                ));
  5396. //            else
  5397. //                return $this->redirectToRoute("user_login", [
  5398. //                    'id' => $newApplicant->getApplicantId(),
  5399. //                    'oAuthData' => $oAuthData,
  5400. //                    'refRoute' => $refRoute,
  5401. //
  5402. //                ]);
  5403.             $bodyHtml '';
  5404.             $bodyTemplate '@Application/email/user/registration.html.twig';
  5405.             $bodyData = array(
  5406.                 'name' => $request->request->get('name'),
  5407.                 'companyData' => $companyData,
  5408.                 'userName' => $request->request->get('username'),
  5409.                 'password' => $request->request->get('password'),
  5410.             );
  5411.             $attachments = [];
  5412. //                    $upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/temp/' . 'ledger' . '.pdf'
  5413.             $new_mail $this->get('mail_module');
  5414.             $new_mail->sendMyMail(array(
  5415.                 'senderHash' => '_USER_MANAGEMENT_',
  5416.                 //                        'senderHash'=>'_CUSTOM_',
  5417.                 'forwardToMailAddress' => $request->request->get('email'),
  5418.                 'subject' => 'User Registration on HoneyBee Ecosystem under Company ' $companyData->getName(),
  5419.                 'fileName' => '',
  5420.                 'attachments' => $attachments,
  5421.                 'toAddress' => $request->request->get('email'),
  5422. //                        'fromAddress'=>'sales@entity.innobd.com',
  5423. //                        'userName'=>'sales@entity.innobd.com',
  5424. //                        'password'=>'Y41dh8g0112',
  5425. //                        'smtpServer'=>'smtp.hostinger.com',
  5426. //                        'smtpPort'=>587,
  5427. //                        'emailBody'=>$bodyHtml,
  5428.                 'mailTemplate' => $bodyTemplate,
  5429.                 'templateData' => $bodyData,
  5430.                 'embedCompanyImage' => 1,
  5431.                 'companyId' => $request->request->get('company'),
  5432.                 'companyImagePath' => $companyData->getImage()
  5433.             ));
  5434. //                $emailmessage = (new \Swift_Message('Registration to Entity'))
  5435. //                    ->setFrom('registration@entity.innobd.com')
  5436. //                    ->setTo($request->request->get('email'))
  5437. //                    ->setBody(
  5438. //                        $this->renderView(
  5439. //                            'ApplicationBundle:email/user:registration.html.twig',
  5440. //                            array('name' => $request->request->get('name'),
  5441. //                                'companyData' => $companyData,
  5442. //                                'userName' => $request->request->get('email'),
  5443. //                                'password' => $request->request->get('password'),
  5444. //                            )
  5445. //                        ),
  5446. //                        'text/html'
  5447. //                    );
  5448. //                /*
  5449. //                 * If you also want to include a plaintext version of the message
  5450. //                ->addPart(
  5451. //                    $this->renderView(
  5452. //                        'Emails/registration.txt.twig',
  5453. //                        array('name' => $name)
  5454. //                    ),
  5455. //                    'text/plain'
  5456. //                )
  5457. //                */
  5458. ////            ;
  5459. //                $this->get('mailer')->send($emailmessage);
  5460.         }
  5461.         $this->addFlash(
  5462.             $message[0],
  5463.             $message[1]
  5464.         );
  5465. //        MiscActions::initiateAdminUser($em,$freshFlag,$userName,$name,$email,$encodedPassword,$appIds,$companyIds);
  5466.         $this->addFlash(
  5467.             'success',
  5468.             'The Action was Successful.'
  5469.         );
  5470.         return $this->redirectToRoute('user_login');
  5471.     }
  5472.     public function DumpCurrModulesAction(Request $request)
  5473.     {
  5474.         $em $this->getDoctrine()->getManager();
  5475.         $modules $em->getRepository("ApplicationBundle\\Entity\\SysModule")
  5476.             ->findBy(
  5477.                 array(//                    'active'=>1
  5478.                 )
  5479.             );
  5480.         $module_data = [];
  5481.         foreach ($modules as $entry) {
  5482.             $dt = array(
  5483.                 'id' => $entry->getModuleId(),
  5484.                 'route' => $entry->getModuleRoute(),
  5485.                 'name' => $entry->getModuleName(),
  5486.                 'parentId' => $entry->getParentId(),
  5487.                 'level' => $entry->getLevel(),
  5488.                 'eFA' => $entry->getEnabledForAll(),
  5489.             );
  5490.             $module_data[$entry->getModuleId()] = $dt;
  5491.         }
  5492.         return new JsonResponse(
  5493.             $module_data
  5494.         );
  5495.     }
  5496.     public function GetTenantDashboardMetricsAction(Request $request)
  5497.     {
  5498.         $systemType $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
  5499.         if ($systemType === '_CENTRAL_') {
  5500.             return new JsonResponse([
  5501.                 'success' => false,
  5502.                 'message' => 'Tenant metrics are available only on ERP servers.',
  5503.             ], 400);
  5504.         }
  5505.         $days max(1, (int)$request->get('days'30));
  5506.         $requestedAppIds $this->normalizeTenantAppIds($request);
  5507.         $em $this->getDoctrine()->getManager();
  5508.         $conn $em->getConnection();
  5509.         $companyRows $this->loadTenantCompanyRows($conn$requestedAppIds);
  5510.         if (empty($companyRows)) {
  5511.             $companyRows = [
  5512.                 [
  5513.                     'id' => 0,
  5514.                     'appId' => $requestedAppIds[0] ?? 0,
  5515.                     'name' => 'Company',
  5516.                     'email' => '',
  5517.                     'company_status' => 'active',
  5518.                     'package_type' => null,
  5519.                     'subscription_expiry' => null,
  5520.                     'last_activity_at' => null,
  5521.                 ],
  5522.             ];
  5523.         }
  5524.         $userCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM sys_user');
  5525.         $activeUserCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM sys_user WHERE status = 1 OR account_status IN (1, 2, 3)');
  5526.         $loginCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM sys_login_log');
  5527.         $pageVisitCount = (int)$conn->fetchOne("SELECT COUNT(*) FROM user_activity_logs WHERE action_type = 'page_visit'");
  5528.         $apiCallCount = (int)$conn->fetchOne("SELECT COUNT(*) FROM user_activity_logs WHERE action_type = 'api_call'");
  5529.         $salesOrderCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM sales_order');
  5530.         $salesInvoiceCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM sales_invoice');
  5531.         $purchaseOrderCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM purchase_order');
  5532.         $purchaseInvoiceCount = (int)$conn->fetchOne('SELECT COUNT(*) FROM purchase_invoice');
  5533.         $salesInvoiceTotal = (float)$conn->fetchOne("SELECT COALESCE(SUM(CAST(invoice_amount AS DECIMAL(15,2))), 0) FROM sales_invoice");
  5534.         $salesPaidTotal = (float)$conn->fetchOne("SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(received_amount, ''), 0) AS DECIMAL(15,2))), 0) FROM sales_invoice");
  5535.         $purchaseInvoiceTotal = (float)$conn->fetchOne("SELECT COALESCE(SUM(CAST(invoice_amount AS DECIMAL(15,2))), 0) FROM purchase_invoice");
  5536.         $purchasePaidTotal = (float)$conn->fetchOne("SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(paid_amount, ''), 0) AS DECIMAL(15,2))), 0) FROM purchase_invoice");
  5537.         $activityTrend $conn->fetchAllAssociative('
  5538.             SELECT DATE(created_at) AS day, action_type AS activity_type, COUNT(*) AS total
  5539.             FROM user_activity_logs
  5540.             WHERE created_at >= DATE_SUB(NOW(), INTERVAL :days DAY)
  5541.               AND action_type IN (\'page_visit\', \'api_call\')
  5542.             GROUP BY DATE(created_at), action_type
  5543.             ORDER BY day ASC
  5544.         ', ['days' => $days], ['days' => \PDO::PARAM_INT]);
  5545.         $loginTrend $conn->fetchAllAssociative('
  5546.             SELECT DATE(log_time) AS day, COUNT(*) AS total
  5547.             FROM sys_login_log
  5548.             WHERE log_time >= DATE_SUB(NOW(), INTERVAL :days DAY)
  5549.             GROUP BY DATE(log_time)
  5550.             ORDER BY day ASC
  5551.         ', ['days' => $days], ['days' => \PDO::PARAM_INT]);
  5552.         $revenueTrend $conn->fetchAllAssociative("
  5553.             SELECT DATE(sales_invoice_date) AS day, COALESCE(SUM(CAST(COALESCE(NULLIF(received_amount, ''), invoice_amount) AS DECIMAL(15,2))), 0) AS total
  5554.             FROM sales_invoice
  5555.             WHERE sales_invoice_date >= DATE_SUB(NOW(), INTERVAL :days DAY)
  5556.             GROUP BY DATE(sales_invoice_date)
  5557.             ORDER BY day ASC
  5558.         ", ['days' => $days], ['days' => \PDO::PARAM_INT]);
  5559.         $recentActivity $conn->fetchAllAssociative('
  5560.             SELECT
  5561.                 id,
  5562.                 user_id AS userId,
  5563.                 session_id AS sessionId,
  5564.                 route,
  5565.                 action_type AS activityType,
  5566.                 metadata,
  5567.                 duration_seconds AS durationSeconds,
  5568.                 created_at AS createdAt
  5569.             FROM user_activity_logs
  5570.             ORDER BY created_at DESC
  5571.             LIMIT 10
  5572.         ');
  5573.         $recentLogins $conn->fetchAllAssociative('
  5574.             SELECT
  5575.                 login_id AS loginId,
  5576.                 user_id AS userId,
  5577.                 position_id AS positionId,
  5578.                 log_time AS logTime,
  5579.                 log_status AS logStatus
  5580.             FROM sys_login_log
  5581.             ORDER BY log_time DESC
  5582.             LIMIT 10
  5583.         ');
  5584.         $recentSales $conn->fetchAllAssociative('
  5585.             SELECT
  5586.                 sales_invoice_id AS salesInvoiceId,
  5587.                 sales_invoice_number AS salesInvoiceNumber,
  5588.                 company_id AS companyId,
  5589.                 sales_invoice_date AS salesInvoiceDate,
  5590.                 invoice_amount AS invoiceAmount,
  5591.                 received_amount AS paidAmount,
  5592.                 due_amount AS dueAmount
  5593.             FROM sales_invoice
  5594.             ORDER BY sales_invoice_date DESC
  5595.             LIMIT 10
  5596.         ');
  5597.         $firstActivityAt $recentActivity[0]['createdAt'] ?? null;
  5598.         $firstLoginAt $recentLogins[0]['logTime'] ?? null;
  5599.         $firstSalesAt $recentSales[0]['salesInvoiceDate'] ?? null;
  5600.         $companySnapshots = [];
  5601.         $totalLastActivity null;
  5602.         foreach ($companyRows as $row) {
  5603.             $companyLastActivity $this->maxTenantActivityTimestamp(
  5604.                 $row['last_activity_at'] ?? null,
  5605.                 $firstActivityAt,
  5606.                 $firstLoginAt,
  5607.                 $firstSalesAt
  5608.             );
  5609.             $companySnapshots[(int)($row['appId'] ?? 0)] = [
  5610.                 'id' => $row['id'] ?? 0,
  5611.                 'appId' => (int)($row['appId'] ?? 0),
  5612.                 'name' => $row['name'] ?? 'Company',
  5613.                 'email' => $row['email'] ?? '',
  5614.                 'company_status' => $row['company_status'] ?? 'active',
  5615.                 'package_type' => $row['package_type'] ?? null,
  5616.                 'subscription_expiry' => $row['subscription_expiry'] ?? null,
  5617.                 'last_activity_at' => $companyLastActivity,
  5618.                 'user_count' => $userCount,
  5619.                 'active_user_count' => $activeUserCount,
  5620.                 'login_count' => $loginCount,
  5621.                 'page_visit_count' => $pageVisitCount,
  5622.                 'api_call_count' => $apiCallCount,
  5623.                 'sales_order_count' => $salesOrderCount,
  5624.                 'sales_invoice_count' => $salesInvoiceCount,
  5625.                 'purchase_order_count' => $purchaseOrderCount,
  5626.                 'purchase_invoice_count' => $purchaseInvoiceCount,
  5627.                 'sales_invoice_total' => $salesInvoiceTotal,
  5628.                 'sales_paid_total' => $salesPaidTotal,
  5629.                 'purchase_invoice_total' => $purchaseInvoiceTotal,
  5630.                 'purchase_paid_total' => $purchasePaidTotal,
  5631.                 'recent_activity' => $recentActivity,
  5632.                 'recent_logins' => $recentLogins,
  5633.                 'recent_sales' => $recentSales,
  5634.             ];
  5635.             $totalLastActivity $this->maxTenantActivityTimestamp($totalLastActivity$companyLastActivity);
  5636.         }
  5637.         return new JsonResponse([
  5638.             'success' => true,
  5639.             'system_type' => $systemType,
  5640.             'days' => $days,
  5641.             'requested_app_ids' => $requestedAppIds,
  5642.             'company_count' => count($companySnapshots),
  5643.             'companies' => $companySnapshots,
  5644.             'totals' => [
  5645.                 'user_count' => $userCount,
  5646.                 'active_user_count' => $activeUserCount,
  5647.                 'login_count' => $loginCount,
  5648.                 'page_visit_count' => $pageVisitCount,
  5649.                 'api_call_count' => $apiCallCount,
  5650.                 'sales_order_count' => $salesOrderCount,
  5651.                 'sales_invoice_count' => $salesInvoiceCount,
  5652.                 'purchase_order_count' => $purchaseOrderCount,
  5653.                 'purchase_invoice_count' => $purchaseInvoiceCount,
  5654.                 'sales_invoice_total' => $salesInvoiceTotal,
  5655.                 'sales_paid_total' => $salesPaidTotal,
  5656.                 'purchase_invoice_total' => $purchaseInvoiceTotal,
  5657.                 'purchase_paid_total' => $purchasePaidTotal,
  5658.                 'last_activity_at' => $totalLastActivity,
  5659.             ],
  5660.             'trend_rows' => [
  5661.                 'activity' => $activityTrend,
  5662.                 'login' => $loginTrend,
  5663.                 'revenue' => $revenueTrend,
  5664.             ],
  5665.         ]);
  5666.     }
  5667.     private function normalizeTenantAppIds(Request $request)
  5668.     {
  5669.         $appIds $request->get('appIds', []);
  5670.         $appId = (int)$request->get('appId'0);
  5671.         if (is_string($appIds)) {
  5672.             $decoded json_decode($appIdstrue);
  5673.             if (is_array($decoded)) {
  5674.                 $appIds $decoded;
  5675.             } else {
  5676.                 $appIds = [$appIds];
  5677.             }
  5678.         }
  5679.         if (!is_array($appIds)) {
  5680.             $appIds = [];
  5681.         }
  5682.         if ($appId 0) {
  5683.             $appIds[] = $appId;
  5684.         }
  5685.         return array_values(array_unique(array_filter(array_map('intval'$appIds))));
  5686.     }
  5687.     private function loadTenantCompanyRows($conn, array $appIds = [])
  5688.     {
  5689.         $sql '
  5690.             SELECT
  5691.                 id,
  5692.                 app_id AS appId,
  5693.                 name,
  5694.                 email,
  5695.                 company_status,
  5696.                 package_type,
  5697.                 subscription_expiry,
  5698.                 last_activity_at
  5699.             FROM company
  5700.         ';
  5701.         if (!empty($appIds)) {
  5702.             $sql .= ' WHERE app_id IN (' implode(','array_map('intval'$appIds)) . ')';
  5703.         }
  5704.         $sql .= ' ORDER BY id ASC';
  5705.         return $conn->fetchAllAssociative($sql);
  5706.     }
  5707.     private function maxTenantActivityTimestamp(...$values)
  5708.     {
  5709.         $maxTs null;
  5710.         $maxValue null;
  5711.         foreach ($values as $value) {
  5712.             if (empty($value)) {
  5713.                 continue;
  5714.             }
  5715.             $ts strtotime((string)$value);
  5716.             if ($ts === false) {
  5717.                 continue;
  5718.             }
  5719.             if ($maxTs === null || $ts $maxTs) {
  5720.                 $maxTs $ts;
  5721.                 $maxValue is_string($value) ? $value : (string)$value;
  5722.             }
  5723.         }
  5724.         return $maxValue;
  5725.     }
  5726.     private function populateEmployeeCoreFromDetails(Employee $employeeEmployeeDetails $details, array &$stats null)
  5727.     {
  5728.         $changed false;
  5729.         $assignIfEmpty = function ($setter$value$label null) use ($employee, &$changed, &$stats) {
  5730.             if ($value === null || $value === '') {
  5731.                 return;
  5732.             }
  5733.             $getter 'get' substr($setter3);
  5734.             if (method_exists($employee$getter)) {
  5735.                 $current $employee->{$getter}();
  5736.                 if ($current !== null && $current !== '') {
  5737.                     if ($stats !== null && $label !== null && (string)$current !== (string)$value) {
  5738.                         if (!isset($stats['conflict_count'])) {
  5739.                             $stats['conflict_count'] = 0;
  5740.                         }
  5741.                         if (!isset($stats['conflict_fields'])) {
  5742.                             $stats['conflict_fields'] = array();
  5743.                         }
  5744.                         $stats['conflict_count']++;
  5745.                         $stats['conflict_fields'][] = $label;
  5746.                     }
  5747.                     return;
  5748.                 }
  5749.             }
  5750.             if (method_exists($employee$setter)) {
  5751.                 $employee->{$setter}($value);
  5752.                 $changed true;
  5753.             }
  5754.         };
  5755.         $firstName method_exists($details'getFirstname') ? $details->getFirstname() : null;
  5756.         $lastName method_exists($details'getLastname') ? $details->getLastname() : null;
  5757.         $name trim((string)$firstName ' ' . (string)$lastName);
  5758.         if ($name === '') {
  5759.             $name null;
  5760.         }
  5761.         $assignIfEmpty('setFirstName'$firstName'firstName');
  5762.         $assignIfEmpty('setLastName'$lastName'lastName');
  5763.         $assignIfEmpty('setName'$name'name');
  5764.         $assignIfEmpty('setEmail'method_exists($details'getEmail') ? $details->getEmail() : null'email');
  5765.         $phone null;
  5766.         if (method_exists($details'getPhone')) {
  5767.             $phone $details->getPhone();
  5768.         }
  5769.         if (($phone === null || $phone === '') && method_exists($details'getOfficialPhone')) {
  5770.             $phone $details->getOfficialPhone();
  5771.         }
  5772.         $assignIfEmpty('setContactNumber'$phone'contactNumber');
  5773.         $assignIfEmpty('setCurrentAddress'method_exists($details'getCurrAddr') ? $details->getCurrAddr() : null'currentAddress');
  5774.         $assignIfEmpty('setPermanentAddress'method_exists($details'getPermAddr') ? $details->getPermAddr() : null'permanentAddress');
  5775.         $assignIfEmpty('setImage'method_exists($details'getImage') ? $details->getImage() : null'image');
  5776.         $assignIfEmpty('setIdsByDevice'method_exists($details'getIdsByDevice') ? $details->getIdsByDevice() : null'idsByDevice');
  5777.         $assignIfEmpty('setEmployeeCode'method_exists($details'getEmpCode') ? $details->getEmpCode() : null'employeeCode');
  5778.         $assignIfEmpty('setEmployeeLevel'method_exists($details'getEmployeeLevel') ? $details->getEmployeeLevel() : null'employeeLevel');
  5779.         $assignIfEmpty('setUserId'method_exists($details'getUserId') ? $details->getUserId() : null'userId');
  5780.         if (method_exists($details'getEmpStatus')) {
  5781.             $status $details->getEmpStatus();
  5782.             if ($status !== null && $status !== '') {
  5783.                 $assignIfEmpty('setStatus', (string)$status'status');
  5784.             }
  5785.         }
  5786.         if (method_exists($details'getJoiningDate')) {
  5787.             $joiningDate $details->getJoiningDate();
  5788.             if ($joiningDate !== null && method_exists($employee'getJoiningDate')) {
  5789.                 $currentJoiningDate $employee->getJoiningDate();
  5790.                 if ($currentJoiningDate === null || $currentJoiningDate === '') {
  5791.                     if (method_exists($employee'setJoiningDate')) {
  5792.                         $employee->setJoiningDate($joiningDate);
  5793.                         $changed true;
  5794.                     } elseif ($stats !== null) {
  5795.                         if (!isset($stats['conflict_count'])) {
  5796.                             $stats['conflict_count'] = 0;
  5797.                         }
  5798.                         if (!isset($stats['conflict_fields'])) {
  5799.                             $stats['conflict_fields'] = array();
  5800.                         }
  5801.                         $stats['conflict_count']++;
  5802.                         $stats['conflict_fields'][] = 'joiningDate';
  5803.                     }
  5804.                 }
  5805.             }
  5806.         }
  5807.         return $changed;
  5808.     }
  5809.     private function migrateEmployeeDetailsToProfile($em)
  5810.     {
  5811.         $stats = array(
  5812.             'supported' => true,
  5813.             'skipped' => false,
  5814.             'created_profile_table' => false,
  5815.             'profile_rows_synced' => 0,
  5816.             'profile_rows_rekeyed' => 0,
  5817.             'employee_rows_synced' => 0,
  5818.             'created_employee_shells' => 0,
  5819.             'conflict_count' => 0,
  5820.             'conflict_fields' => array(),
  5821.             'messages' => array(),
  5822.         );
  5823.         $conn $em->getConnection();
  5824.         $platformName strtolower((string)$conn->getDatabasePlatform()->getName());
  5825.         if ($platformName !== 'mysql') {
  5826.             $stats['supported'] = false;
  5827.             $stats['skipped'] = true;
  5828.             $stats['messages'][] = 'employee migration is mysql-only';
  5829.             return $stats;
  5830.         }
  5831.         $tableExists = function ($tableName) use ($conn) {
  5832.             $rows $conn->fetchAllAssociative(
  5833.                 "SELECT COUNT(*) AS table_count
  5834.                  FROM INFORMATION_SCHEMA.TABLES
  5835.                  WHERE TABLE_SCHEMA = DATABASE()
  5836.                    AND TABLE_NAME = '" str_replace("'""''"$tableName) . "'"
  5837.             );
  5838.             return isset($rows[0]['table_count']) && (int)$rows[0]['table_count'] > 0;
  5839.         };
  5840.         if (!$tableExists('employee_details')) {
  5841.             $stats['skipped'] = true;
  5842.             $stats['messages'][] = 'employee_details table was not found';
  5843.             return $stats;
  5844.         }
  5845.         if (!$tableExists('employee_profile')) {
  5846.             $ddlRows $conn->fetchAllAssociative('SHOW CREATE TABLE `employee_details`');
  5847.             if (!empty($ddlRows[0])) {
  5848.                 $createSql '';
  5849.                 $rowValues array_values($ddlRows[0]);
  5850.                 foreach ($rowValues as $value) {
  5851.                     if (is_string($value) && stripos($value'CREATE TABLE') === 0) {
  5852.                         $createSql $value;
  5853.                         break;
  5854.                     }
  5855.                 }
  5856.                 if ($createSql === '' && isset($rowValues[1])) {
  5857.                     $createSql $rowValues[1];
  5858.                 }
  5859.                 if ($createSql !== '') {
  5860.                     $createSql str_replace('CREATE TABLE `employee_details`''CREATE TABLE `employee_profile`'$createSql);
  5861.                     $createSql str_replace('`id`''`employee_id`'$createSql);
  5862.                     $conn->executeStatement($createSql);
  5863.                     $stats['created_profile_table'] = true;
  5864.                 }
  5865.             }
  5866.         }
  5867.         $copyColumns = array();
  5868.         $columnRows $conn->fetchAllAssociative('SHOW COLUMNS FROM `employee_details`');
  5869.         foreach ($columnRows as $columnRow) {
  5870.             if (!isset($columnRow['Field'])) {
  5871.                 continue;
  5872.             }
  5873.             if ($columnRow['Field'] === 'id') {
  5874.                 continue;
  5875.             }
  5876.             $copyColumns[] = $columnRow['Field'];
  5877.         }
  5878.         if (!empty($copyColumns) && $tableExists('employee_profile')) {
  5879.             $insertColumns array_merge(array('employee_id'), $copyColumns);
  5880.             $insertColumnsSql = array();
  5881.             foreach ($insertColumns as $columnName) {
  5882.                 $insertColumnsSql[] = '`' $columnName '`';
  5883.             }
  5884.             $selectColumnsSql = array('`id` AS `employee_id`');
  5885.             foreach ($copyColumns as $columnName) {
  5886.                 $selectColumnsSql[] = '`' $columnName '`';
  5887.             }
  5888.             $updateColumnsSql = array();
  5889.             foreach ($copyColumns as $columnName) {
  5890.                 $updateColumnsSql[] = '`' $columnName '` = VALUES(`' $columnName '`)';
  5891.             }
  5892.             $syncSql 'INSERT INTO `employee_profile` (' implode(', '$insertColumnsSql) . ')
  5893.                         SELECT ' implode(', '$selectColumnsSql) . '
  5894.                         FROM `employee_details`
  5895.                         ON DUPLICATE KEY UPDATE ' implode(', '$updateColumnsSql);
  5896.             $conn->executeStatement($syncSql);
  5897.             $stats['profile_rows_synced'] = (int)$conn->fetchOne('SELECT COUNT(*) FROM `employee_profile`');
  5898.         }
  5899.         $detailsRows $em->getRepository('ApplicationBundle\\Entity\\EmployeeDetails')->findBy(array(), array('id' => 'ASC'));
  5900.         $employeeRepo $em->getRepository('ApplicationBundle\\Entity\\Employee');
  5901.         foreach ($detailsRows as $details) {
  5902.             $employee $employeeRepo->findOneBy(array('employeeId' => $details->getId()));
  5903.             if (!$employee && method_exists($details'getUserId') && $details->getUserId()) {
  5904.                 $employee $employeeRepo->findOneBy(array('userId' => $details->getUserId()));
  5905.             }
  5906.             $oldEmployeeId null;
  5907.             if ($employee) {
  5908.                 $oldEmployeeId $employee->getEmployeeId();
  5909.             } else {
  5910.                 $employee = new Employee();
  5911.                 $stats['created_employee_shells']++;
  5912.             }
  5913.             $changed $this->populateEmployeeCoreFromDetails($employee$details$stats);
  5914.             if (!$oldEmployeeId && method_exists($details'getUserId') && $details->getUserId() && method_exists($employee'setUserId')) {
  5915.                 $employee->setUserId($details->getUserId());
  5916.                 $changed true;
  5917.             }
  5918.             if ($changed || !$oldEmployeeId) {
  5919.                 $em->persist($employee);
  5920.                 $em->flush();
  5921.                 $stats['employee_rows_synced']++;
  5922.             } else {
  5923.                 $em->persist($employee);
  5924.             }
  5925.             $newEmployeeId $employee->getEmployeeId();
  5926.             if ((int)$details->getId() !== (int)$newEmployeeId && $tableExists('employee_profile')) {
  5927.                 $conn->executeStatement(
  5928.                     'UPDATE `employee_profile` SET `employee_id` = :new_id WHERE `employee_id` = :old_id',
  5929.                     array(
  5930.                         'new_id' => $newEmployeeId,
  5931.                         'old_id' => $details->getId(),
  5932.                     )
  5933.                 );
  5934.                 $stats['profile_rows_rekeyed']++;
  5935.             }
  5936.         }
  5937.         return $stats;
  5938.     }
  5939.     // =========================================================================
  5940.     // OWNER DASHBOARD SNAPSHOT  (MC-0)
  5941.     // Called by the central server's OwnerDashboardService::curlErpSnapshot().
  5942.     // Returns a JSON snapshot of financials + KPIs for the company owner portal.
  5943.     // No session — this is a server-to-server call; the HMAC SIGNATURE is the credential.
  5944.     //
  5945.     // ⚠⚠ THIS ENDPOINT USED TO HAVE NO AUTHENTICATION AT ALL. It checked only that the box was not
  5946.     // '_CENTRAL_', on a controller that implements LoginInterface (i.e. public). Anyone who could
  5947.     // reach an ERP box — no session, no token, no header — received that company's revenue,
  5948.     // expenses, receivables, PAYABLES, headcount, attendance and a log of recent activity. It also
  5949.     // ignored its own `appId` parameter entirely: the tenant answered was whatever database the
  5950.     // hostname resolved to.
  5951.     //
  5952.     // MC-0 closes both holes and adds a third guarantee:
  5953.     //   1. SIGNED (McSignatureCore, the AIE relay's proven HMAC): appId + timestamp + raw body,
  5954.     //      constant-time compare, ±replay window. No secret configured ⇒ REFUSE (fail-closed).
  5955.     //      The secret is EXPLICIT ONLY — never derived from this box's registry row, because each
  5956.     //      box reads its own registry and a "sensible default" silently differs on the two ends.
  5957.     //   2. IDENTITY ASSERTED BY THE BOX (TenantIdentityCore): the appId the caller signed must equal
  5958.     //      the appId THIS box actually serves. A signature proves a secret-holder asked; it does not
  5959.     //      prove the box being asked is the tenant that was named.
  5960.     //   3. HONEST FIGURES (TenantSnapshotService): `finance.figures[]` carries a currency, an as-of
  5961.     //      and a certification verdict on EVERY entry, produced by the handlers that own the trust
  5962.     //      layer — not by the hand-rolled SQL below.
  5963.     //
  5964.     // The legacy `financials`/`kpis` blocks are still emitted (the existing owner dashboard reads
  5965.     // them) but are now explicitly labelled as unlabelled-currency raw sums so nothing downstream can
  5966.     // treat them as cross-tenant addable by accident.
  5967.     // =========================================================================
  5968.     public function GetOwnerDashboardSnapshotAction(Request $request)
  5969.     {
  5970.         $systemType $this->container->hasParameter('system_type')
  5971.             ? $this->container->getParameter('system_type')
  5972.             : '_ERP_';
  5973.         if ($systemType === '_CENTRAL_') {
  5974.             return new JsonResponse([
  5975.                 'success' => false,
  5976.                 'message' => 'Owner snapshot only available on ERP servers.',
  5977.             ], 400);
  5978.         }
  5979.         $gate $this->mcSnapshotGate($request);
  5980.         if (!$gate['ok']) {
  5981.             return new JsonResponse([
  5982.                 'success' => false,
  5983.                 'error'   => $gate['code'],
  5984.                 'message' => $gate['reason'],
  5985.             ], $gate['status']);
  5986.         }
  5987.         $provenAppId = (int) $gate['app_id'];
  5988.         $em $this->getDoctrine()->getManager();
  5989.         $conn $em->getConnection();
  5990.         // ── Financial data ────────────────────────────────────────────────────
  5991.         $revenueThisMonth 0.0;
  5992.         $revenueLast 0.0;
  5993.         $expensesThisMonth 0.0;
  5994.         $receivables 0.0;
  5995.         $payables 0.0;
  5996.         try {
  5997.             $revenueThisMonth = (float)$conn->fetchOne("
  5998.                 SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(received_amount,''), invoice_amount) AS DECIMAL(15,2))), 0)
  5999.                 FROM sales_invoice
  6000.                 WHERE YEAR(sales_invoice_date)  = YEAR(NOW())
  6001.                   AND MONTH(sales_invoice_date) = MONTH(NOW())
  6002.             ");
  6003.             $revenueLast = (float)$conn->fetchOne("
  6004.                 SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(received_amount,''), invoice_amount) AS DECIMAL(15,2))), 0)
  6005.                 FROM sales_invoice
  6006.                 WHERE sales_invoice_date >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01')
  6007.                   AND sales_invoice_date <  DATE_FORMAT(NOW(), '%Y-%m-01')
  6008.             ");
  6009.             $expensesThisMonth = (float)$conn->fetchOne("
  6010.                 SELECT COALESCE(SUM(CAST(COALESCE(NULLIF(paid_amount,''), invoice_amount) AS DECIMAL(15,2))), 0)
  6011.                 FROM purchase_invoice
  6012.                 WHERE YEAR(invoice_date)  = YEAR(NOW())
  6013.                   AND MONTH(invoice_date) = MONTH(NOW())
  6014.             ");
  6015.             $receivables = (float)$conn->fetchOne("
  6016.                 SELECT COALESCE(SUM(CAST(invoice_amount AS DECIMAL(15,2))), 0)
  6017.                 FROM sales_invoice
  6018.                 WHERE payment_status IS NULL OR payment_status NOT IN ('paid','fully_paid')
  6019.             ");
  6020.             $payables = (float)$conn->fetchOne("
  6021.                 SELECT COALESCE(SUM(CAST(invoice_amount AS DECIMAL(15,2))), 0)
  6022.                 FROM purchase_invoice
  6023.                 WHERE payment_status IS NULL OR payment_status NOT IN ('paid','fully_paid')
  6024.             ");
  6025.         } catch (\Exception $e) {
  6026.             // Tables may not exist on all ERP versions — skip gracefully
  6027.         }
  6028.         $profitThisMonth $revenueThisMonth $expensesThisMonth;
  6029.         // Monthly revenue trend (last 6 months)
  6030.         $monthlyTrend = [];
  6031.         try {
  6032.             $trendRows $conn->fetchAllAssociative("
  6033.                 SELECT DATE_FORMAT(sales_invoice_date, '%Y-%m') AS month,
  6034.                        COALESCE(SUM(CAST(COALESCE(NULLIF(received_amount,''), invoice_amount) AS DECIMAL(15,2))), 0) AS amount
  6035.                 FROM sales_invoice
  6036.                 WHERE sales_invoice_date >= DATE_SUB(NOW(), INTERVAL 6 MONTH)
  6037.                 GROUP BY DATE_FORMAT(sales_invoice_date, '%Y-%m')
  6038.                 ORDER BY month ASC
  6039.             ");
  6040.             foreach ($trendRows as $row) {
  6041.                 $monthlyTrend[] = ['month' => $row['month'], 'amount' => (float)$row['amount']];
  6042.             }
  6043.         } catch (\Exception $e) {
  6044.             // Skip
  6045.         }
  6046.         // ── KPI data ──────────────────────────────────────────────────────────
  6047.         $totalEmployees 0;
  6048.         $presentToday 0;
  6049.         $attendancePct 0.0;
  6050.         $tasksTotal 0;
  6051.         $tasksCompleted 0;
  6052.         $tasksOverdue 0;
  6053.         $taskRate 0.0;
  6054.         $openInvoices 0;
  6055.         $overdueInvoices 0;
  6056.         $totalInvoiceAmt 0.0;
  6057.         try {
  6058.             $totalEmployees = (int)$conn->fetchOne(
  6059.                 "SELECT COUNT(*) FROM employee WHERE status = 1 OR status IS NULL"
  6060.             );
  6061.         } catch (\Exception $e) {
  6062.             try {
  6063.                 $totalEmployees = (int)$conn->fetchOne(
  6064.                     "SELECT COUNT(*) FROM sys_user WHERE status = 1"
  6065.                 );
  6066.             } catch (\Exception $ex) {
  6067.             }
  6068.         }
  6069.         // Attendance: try common table names used by the ERP HR module
  6070.         try {
  6071.             $today date('Y-m-d');
  6072.             $presentToday = (int)$conn->fetchOne(
  6073.                 "SELECT COUNT(DISTINCT employee_id) FROM employee_daily_log
  6074.                  WHERE log_date = :d AND in_time IS NOT NULL",
  6075.                 ['d' => $today]
  6076.             );
  6077.         } catch (\Exception $e) {
  6078.             try {
  6079.                 $today date('Y-m-d');
  6080.                 $presentToday = (int)$conn->fetchOne(
  6081.                     "SELECT COUNT(DISTINCT user_id) FROM user_activity_logs
  6082.                      WHERE DATE(created_at) = :d AND action_type = 'page_visit'",
  6083.                     ['d' => $today]
  6084.                 );
  6085.             } catch (\Exception $ex) {
  6086.             }
  6087.         }
  6088.         if ($totalEmployees 0) {
  6089.             $attendancePct round(($presentToday $totalEmployees) * 1001);
  6090.         }
  6091.         // Tasks: try common task table names
  6092.         try {
  6093.             $tasksTotal = (int)$conn->fetchOne("SELECT COUNT(*) FROM task");
  6094.             $tasksCompleted = (int)$conn->fetchOne("SELECT COUNT(*) FROM task WHERE status IN ('done','completed','closed')");
  6095.             $tasksOverdue = (int)$conn->fetchOne("SELECT COUNT(*) FROM task WHERE due_date < NOW() AND status NOT IN ('done','completed','closed')");
  6096.         } catch (\Exception $e) {
  6097.             try {
  6098.                 $tasksTotal = (int)$conn->fetchOne("SELECT COUNT(*) FROM project_task");
  6099.                 $tasksCompleted = (int)$conn->fetchOne("SELECT COUNT(*) FROM project_task WHERE status IN ('done','completed','closed')");
  6100.                 $tasksOverdue = (int)$conn->fetchOne("SELECT COUNT(*) FROM project_task WHERE due_date < NOW() AND status NOT IN ('done','completed','closed')");
  6101.             } catch (\Exception $ex) {
  6102.             }
  6103.         }
  6104.         if ($tasksTotal 0) {
  6105.             $taskRate round(($tasksCompleted $tasksTotal) * 1001);
  6106.         }
  6107.         // Invoice KPIs
  6108.         try {
  6109.             $openInvoices = (int)$conn->fetchOne("SELECT COUNT(*) FROM sales_invoice WHERE payment_status IS NULL OR payment_status NOT IN ('paid','fully_paid')");
  6110.             $overdueInvoices = (int)$conn->fetchOne("SELECT COUNT(*) FROM sales_invoice WHERE due_date < NOW() AND (payment_status IS NULL OR payment_status NOT IN ('paid','fully_paid'))");
  6111.             $totalInvoiceAmt = (float)$conn->fetchOne("SELECT COALESCE(SUM(CAST(invoice_amount AS DECIMAL(15,2))), 0) FROM sales_invoice");
  6112.         } catch (\Exception $e) {
  6113.         }
  6114.         // ── Recent activity ───────────────────────────────────────────────────
  6115.         $recentActivity = [];
  6116.         try {
  6117.             $rows $conn->fetchAllAssociative("
  6118.                 SELECT action_type AS action, route AS description, created_at AS at
  6119.                 FROM user_activity_logs
  6120.                 ORDER BY created_at DESC
  6121.                 LIMIT 10
  6122.             ");
  6123.             foreach ($rows as $row) {
  6124.                 $recentActivity[] = [
  6125.                     'action' => $row['action'] ?? 'activity',
  6126.                     'description' => $row['description'] ?? '',
  6127.                     'at' => $row['at'] ?? '',
  6128.                 ];
  6129.             }
  6130.         } catch (\Exception $e) {
  6131.         }
  6132.         // ★ THE HONEST BLOCK — per-currency, as-of'd, verdict-carrying, from the trust-layer handlers.
  6133.         // Built AFTER the legacy queries so a handler failure degrades this block only; the legacy
  6134.         // payload the existing dashboard depends on is never taken down by it.
  6135.         $finance null;
  6136.         $financeError null;
  6137.         try {
  6138.             $svc = new \ApplicationBundle\Modules\MultiCompany\Service\TenantSnapshotService($em);
  6139.             $finance $svc->build($provenAppId14);
  6140.             // Refuse to emit a figure that lacks currency/as_of/verdict rather than shipping the exact
  6141.             // defect this slice removes. The audit runs on the way OUT, not only in the selftest.
  6142.             $bad = \ApplicationBundle\Modules\MultiCompany\Service\TenantSnapshotService::auditFigures($finance['figures']);
  6143.             if (!empty($bad)) {
  6144.                 $financeError 'refused to emit unlabelled figures: ' implode('; '$bad);
  6145.                 $finance null;
  6146.             }
  6147.         } catch (\Throwable $e) {
  6148.             $financeError $e->getMessage();
  6149.         }
  6150.         return new JsonResponse([
  6151.             'success' => true,
  6152.             'app_id' => $provenAppId,
  6153.             'identity' => ['proven' => true'source' => $gate['identity_source']],
  6154.             'fetched_at' => (new \DateTime())->format('c'),
  6155.             // ★ PRIMARY TRUTH. `null` when the readers could not run — an absent block, never a
  6156.             // fabricated zero-valued one.
  6157.             'finance' => $finance,
  6158.             'finance_error' => $financeError,
  6159.             // ⚠ LEGACY. Naked floats with no currency: kept only because the existing owner dashboard
  6160.             // template reads them. They are the tenant's own functional-currency-ish raw sums and are
  6161.             // NOT cross-tenant addable. MC-2 will consume `finance.figures[]` instead.
  6162.             'financials' => [
  6163.                 '_warning' => 'UNLABELLED CURRENCY — raw sums, not cross-tenant addable. Use finance.figures[].',
  6164.                 'revenue_this_month' => $revenueThisMonth,
  6165.                 'revenue_last_month' => $revenueLast,
  6166.                 'expenses_this_month' => $expensesThisMonth,
  6167.                 'profit_this_month' => $profitThisMonth,
  6168.                 'outstanding_receivables' => $receivables,
  6169.                 'outstanding_payables' => $payables,
  6170.                 'monthly_revenue_trend' => $monthlyTrend,
  6171.             ],
  6172.             'kpis' => [
  6173.                 'total_employees' => $totalEmployees,
  6174.                 'present_today' => $presentToday,
  6175.                 'attendance_rate_percent' => $attendancePct,
  6176.                 'tasks_total' => $tasksTotal,
  6177.                 'tasks_completed' => $tasksCompleted,
  6178.                 'tasks_overdue' => $tasksOverdue,
  6179.                 'task_completion_rate_percent' => $taskRate,
  6180.                 'open_sales_invoices' => $openInvoices,
  6181.                 'overdue_sales_invoices' => $overdueInvoices,
  6182.                 'total_sales_invoices_amount' => $totalInvoiceAmt,
  6183.             ],
  6184.             'alerts' => [],
  6185.             'recent_activity' => $recentActivity,
  6186.         ]);
  6187.     }
  6188.     // =========================================================================
  6189.     // MC-1b — THE LIST-CLASS CROSS-COMPANY SLICE  (tenant half)
  6190.     // Called by central's McFanOutService::fanOutList(). Same wire as MC-0: same headers, same
  6191.     // per-app secret, same replay window, same box-asserts-its-own-identity gate. One
  6192.     // server-to-server auth mechanism for the whole multi-company surface, not two.
  6193.     //
  6194.     // ★★ THE BOX ENFORCES ITS OWN ACCESS, AND THAT REJECTION IS THE FEATURE.
  6195.     //   The signed body names the CENTRAL applicant the answer is for. A valid signature proves that
  6196.     //   central asked on that person's behalf; it proves NOTHING about whether that person may see
  6197.     //   this company's rows. So this box resolves them locally (sys_user.global_id = applicant id —
  6198.     //   the same join AIE's gateway and the sales digest use) and, if they are absent or deactivated
  6199.     //   HERE, answers 403 with ZERO data rows. Central renders that company as `forbidden`: named,
  6200.     //   visibly missing, and costing trust.complete. That is the owner's rule working as designed.
  6201.     //
  6202.     // ★ NO SILENT ZERO. Any failure this box cannot answer through is an ERROR status, never an
  6203.     //   empty `items` array with a 200 — the exact defect the MC envelope exists to prevent.
  6204.     // =========================================================================
  6205.     public function GetOwnerCrossCompanyListAction(Request $request)
  6206.     {
  6207.         $L = \ApplicationBundle\Modules\MultiCompany\Support\TenantListCore::class;
  6208.         $systemType $this->container->hasParameter('system_type')
  6209.             ? $this->container->getParameter('system_type')
  6210.             : '_ERP_';
  6211.         if ($systemType === '_CENTRAL_') {
  6212.             return new JsonResponse([
  6213.                 'success' => false,
  6214.                 'error' => 'wrong_box',
  6215.                 'message' => 'Cross-company list slices are answered by ERP servers, not central.',
  6216.             ], 400);
  6217.         }
  6218.         // Identical gate to MC-0 — deliberately the same method, so the two endpoints can never drift
  6219.         // apart on signature, replay window or tenant-identity assertion.
  6220.         $gate $this->mcSnapshotGate($request);
  6221.         if (!$gate['ok']) {
  6222.             return new JsonResponse([
  6223.                 'success' => false,
  6224.                 'error'   => $gate['code'],
  6225.                 'message' => $gate['reason'],
  6226.             ], $gate['status']);
  6227.         }
  6228.         $provenAppId = (int) $gate['app_id'];
  6229.         $payload json_decode((string) $request->getContent(), true);
  6230.         if (!is_array($payload)) {
  6231.             return new JsonResponse(['success' => false'error' => 'malformed_body',
  6232.                 'message' => 'the signed body is not a JSON object'], 400);
  6233.         }
  6234.         // The body's own app_id must agree with the one that was signed and proven. Cheap, and it
  6235.         // catches a caller who signed one tenant's headers around another tenant's body.
  6236.         if ((int) (isset($payload['app_id']) ? $payload['app_id'] : 0) !== $provenAppId) {
  6237.             return new JsonResponse(['success' => false'error' => 'body_app_mismatch',
  6238.                 'message' => 'the signed body names a different tenant than the proven one'], 403);
  6239.         }
  6240.         $want strtolower(trim((string) (isset($payload['want']) ? $payload['want'] : '')));
  6241.         if (!$L::isKnownWant($want)) {
  6242.             // Guessing at an unknown list is how a caller gets confidently wrong data.
  6243.             return new JsonResponse(['success' => false'error' => 'unknown_want',
  6244.                 'message' => 'this box does not answer the list "' $want '" (known: '
  6245.                     implode(', '$L::knownWants()) . ')'], 400);
  6246.         }
  6247.         $actingGlobalId = (int) (isset($payload['acting_global_id']) ? $payload['acting_global_id'] : 0);
  6248.         try {
  6249.             $svc = new \ApplicationBundle\Modules\MultiCompany\Service\TenantTaskListService(
  6250.                 $this->getDoctrine()->getManager()->getConnection());
  6251.             $access $svc->resolveUser($actingGlobalId);
  6252.         } catch (\Throwable $e) {
  6253.             return new JsonResponse(['success' => false'error' => 'access_check_failed',
  6254.                 'message' => 'this box could not decide whether that person has access here: ' $e->getMessage()], 500);
  6255.         }
  6256.         if (empty($access['ok'])) {
  6257.             // 403 — central's transport mapper turns 401/403 into `forbidden`. Zero data rows.
  6258.             return new JsonResponse([
  6259.                 'success' => false,
  6260.                 'app_id' => $provenAppId,
  6261.                 'error' => $access['code'],
  6262.                 'message' => $access['reason'],
  6263.                 'items' => [],
  6264.             ], 403);
  6265.         }
  6266.         $meta = [];
  6267.         try {
  6268.             if ($L::isToolWant($want)) {
  6269.                 // ── MCP-4 — THE DRILL-DOWN. Central proxies ONE of this box's own read tools here,
  6270.                 //    on behalf of a human central has proven and this box has just authorised.
  6271.                 //
  6272.                 // ★★ NO NEW AUTHORITY, AND THAT IS STRUCTURAL, NOT A PROMISE. The call goes through
  6273.                 //    McpToolExecutor::callReadTool — the SAME pipeline the per-tenant MCP server uses:
  6274.                 //    the executor refuses anything whose schema risk is not 'read' BEFORE the handler
  6275.                 //    is touched, then ToolPermissionGate → canExecute → validate → execute. So the
  6276.                 //    cross-company front door can never reach a verb the single-company front door
  6277.                 //    would refuse, and the acting identity is the LOCAL user resolved above — not a
  6278.                 //    central super-user, and not the caller's assertion about themselves.
  6279.                 //
  6280.                 // ★ A refusal is a 200 with ok:false (a tool-level error), not a 5xx. The box was
  6281.                 //   reached; saying otherwise would report a healthy company as an outage.
  6282.                 $toolName trim((string) (isset($payload['tool']) ? $payload['tool'] : ''));
  6283.                 if ($toolName === '') {
  6284.                     return new JsonResponse(['success' => false'app_id' => $provenAppId,
  6285.                         'error' => 'tool_required',
  6286.                         'message' => 'the signed body named no tool to run'], 400);
  6287.                 }
  6288.                 $toolArgs = isset($payload['arguments']) && is_array($payload['arguments'])
  6289.                     ? $payload['arguments'] : [];
  6290.                 $registry $this->get('app.ai_command.tool_registry');
  6291.                 $permGate null;
  6292.                 try {
  6293.                     $permGate $this->get('app.ai_command.permission_gate');
  6294.                 } catch (\Throwable $e) {
  6295.                     $permGate null;
  6296.                 }
  6297.                 $ctx = [
  6298.                     'app_id' => $provenAppId,
  6299.                     'user_id' => (int) $access['user_id'],
  6300.                     'login_id' => (int) $access['user_id'],
  6301.                     'company_id' => 1,
  6302.                     'session_id' => 'mcp_central',
  6303.                     // Named distinctly from 'mcp' so an audit can tell a cross-company drill-down
  6304.                     // from a direct per-tenant connection without guessing.
  6305.                     'source' => 'mcp_central',
  6306.                     'idempotency_key' => '',
  6307.                     'risk' => 'read',
  6308.                     'permission_grants' => null,
  6309.                 ];
  6310.                 $run = \ApplicationBundle\Modules\Mcp\Support\McpToolExecutor::callReadTool(
  6311.                     $registry$permGate$toolName$toolArgs$ctx);
  6312.                 $items = [$L::shapeToolRow($toolName, !empty($run['ok']),
  6313.                     isset($run['payload']) ? $run['payload'] : null,
  6314.                     isset($run['error']) ? (string) $run['error'] : '')];
  6315.                 $meta = ['tool' => $toolName'acting_local_user_id' => (int) $access['user_id']];
  6316.             } elseif ($L::isMoneyWant($want)) {
  6317.                 // ── MC-2 — the MONEY want. Same gate, same access decision, a different reader.
  6318.                 //
  6319.                 // ★★ AN EMPTY LIST IS NOT AN ANSWER HERE. If this box cannot certify its own payables
  6320.                 //    it REFUSES (5xx) and central records it as `unreachable` — a named hole in the
  6321.                 //    group total. A 200 with no rows would be scored as "this company owes nothing",
  6322.                 //    which is the exact silent zero the whole multi-company track exists to prevent.
  6323.                 $money = new \ApplicationBundle\Modules\MultiCompany\Service\TenantMoneyListService(
  6324.                     $this->getDoctrine()->getManager());
  6325.                 $out $money->payablesDue($provenAppId,
  6326.                     (int) (isset($payload['window_days']) ? $payload['window_days'] : 0));
  6327.                 if (empty($out['ok'])) {
  6328.                     return new JsonResponse(['success' => false'app_id' => $provenAppId,
  6329.                         'error' => 'money_uncertified',
  6330.                         'message' => (string) $out['reason']], 503);
  6331.                 }
  6332.                 $items $out['rows'];
  6333.                 // Refuse to ship an unlabelled figure, exactly as MC-0 refuses an unlabelled figures[].
  6334.                 $badRows = \ApplicationBundle\Modules\MultiCompany\Service\TenantMoneyListService::auditRows($items);
  6335.                 if (!empty($badRows)) {
  6336.                     return new JsonResponse(['success' => false'app_id' => $provenAppId,
  6337.                         'error' => 'unlabelled_figure',
  6338.                         'message' => 'refusing to emit a money row that carries no currency/as-of/verdict: '
  6339.                             implode('; 'array_slice($badRows05))], 500);
  6340.                 }
  6341.                 $meta = [
  6342.                     'verdict' => $out['verdict'], 'confidence' => $out['confidence'],
  6343.                     'source' => $out['source'], 'window_days' => $out['window_days'],
  6344.                     'caveats' => $out['caveats'],
  6345.                 ];
  6346.             } else {
  6347.                 $items $svc->pendingTasks((int) $access['user_id']);
  6348.             }
  6349.         } catch (\Throwable $e) {
  6350.             // Say it out loud. Central records this company as unreachable rather than as "no tasks".
  6351.             return new JsonResponse(['success' => false'app_id' => $provenAppId,
  6352.                 'error' => 'list_query_failed',
  6353.                 'message' => 'the "' $want '" list could not be read on this box: ' $e->getMessage()], 500);
  6354.         }
  6355.         return new JsonResponse([
  6356.             'success' => true,
  6357.             'app_id' => $provenAppId,
  6358.             // MCP-4 — WHICH LOCK OPENED, stated on every answer. `central_public_key` means this box
  6359.             // needed no per-tenant secret to be trusted; `legacy_shared_secret` means it is still on
  6360.             // the paired-secret model. That is how a fleet migration is OBSERVED rather than believed.
  6361.             'identity' => ['proven' => true'source' => $gate['identity_source'],
  6362.                 'auth_method' => isset($gate['auth_method']) ? $gate['auth_method'] : 'unknown'],
  6363.             'want' => $want,
  6364.             // The tenant's OWN clock — central never restamps this.
  6365.             'as_of' => (new \DateTime())->format('c'),
  6366.             'acting' => ['global_id' => $actingGlobalId'user_id' => (int) $access['user_id'],
  6367.                 'name' => (string) $access['name']],
  6368.             'count' => count($items),
  6369.             'items' => $items,
  6370.             // MC-2: the money want carries its block-level trust next to the rows. Empty for task
  6371.             // wants, so the shape stays one shape.
  6372.             'meta' => $meta,
  6373.         ]);
  6374.     }
  6375.     /**
  6376.      * MC-0 — the snapshot gate. Signature first, then the box's own identity assertion.
  6377.      *
  6378.      * Codes are named so an operator reading a 401 knows which lock refused. The expected signature is
  6379.      * NEVER echoed. Status choice:
  6380.      *   401 unverifiable caller (no/bad signature, stale timestamp)
  6381.      *   503 this box is not configured yet (central should retry once the owner sets the key) —
  6382.      *       distinguishable from "you are not allowed", which matters when diagnosing a fleet.
  6383.      *   403 the signature verified but named a tenant this box does not serve
  6384.      *   409 this box cannot prove which tenant it is (refuses rather than answering as whoever asked)
  6385.      *
  6386.      * @return array ['ok'=>bool,'status'=>int,'code'=>string,'reason'=>string,'app_id'=>int,'identity_source'=>string]
  6387.      */
  6388.     private function mcSnapshotGate(Request $request)
  6389.     {
  6390.         $SIG = \ApplicationBundle\Modules\MultiCompany\Support\McSignatureCore::class;
  6391.         $ID = \ApplicationBundle\Modules\MultiCompany\Support\TenantIdentityCore::class;
  6392.         $raw = (string) $request->getContent();
  6393.         $appId = (int) $request->headers->get($SIG::HEADER_APP0);
  6394.         $ts = (int) $request->headers->get($SIG::HEADER_TIMESTAMP0);
  6395.         $sig = (string) $request->headers->get($SIG::HEADER_SIGNATURE'');
  6396.         // Answer the CALLER's failure before this box's own. Live smoke showed an anonymous POST (no
  6397.         // headers at all) getting `503 not_configured`: misleading for the stranger, a 503 tells a
  6398.         // legitimate central to retry later for something that will never succeed, and it volunteers
  6399.         // to any passer-by that this box has no key set. A caller who sent no credential is simply
  6400.         // unauthenticated — say that, in 401, and say nothing about our configuration.
  6401.         if ($sig === '' || $appId <= 0) {
  6402.             return [
  6403.                 'ok' => false,
  6404.                 'status' => 401,
  6405.                 'code' => $sig === '' 'missing_signature' 'bad_app',
  6406.                 'reason' => $sig === ''
  6407.                     'no ' $SIG::HEADER_SIGNATURE ' header — this endpoint is server-to-server and requires a signed request'
  6408.                     'missing/invalid ' $SIG::HEADER_APP,
  6409.                 'app_id' => 0,
  6410.                 'identity_source' => 'none',
  6411.                 'auth_method' => $SIG::METHOD_NONE,
  6412.             ];
  6413.         }
  6414.         // MCP-4 — ★ ONE VERIFIER, TWO MECHANISMS, CHOSEN BY THE WIRE. `rsa256=` is checked against
  6415.         // central's PUBLIC key (which this box may hold without anyone ever provisioning a secret for
  6416.         // it); `sha256=` is the legacy per-tenant shared secret, byte-identical to what MC-0 shipped.
  6417.         // Which one opened the lock is REPORTED (below, and in the endpoint's `identity` block) rather
  6418.         // than inferred, so an operator migrating a fleet can see a box flip over instead of guessing.
  6419.         $secret = \ApplicationBundle\Helper\McRelayConfig::snapshotSecret($appId);
  6420.         $publicKey = \ApplicationBundle\Helper\McRelayConfig::centralPublicKey();
  6421.         $window = \ApplicationBundle\Helper\McRelayConfig::replayWindow();
  6422.         $verdict $SIG::verifyAny($appId$ts$raw$sig$publicKey$secrettime(), $window);
  6423.         if (empty($verdict['ok'])) {
  6424.             $notConfigured in_array($verdict['code'], ['not_configured''no_public_key''crypto_unavailable'], true);
  6425.             return [
  6426.                 'ok' => false,
  6427.                 // 503 = "this box is not set up yet, retry later"; 401 = "you are not authenticated".
  6428.                 // A box that cannot verify an asymmetric signature is in the FIRST category.
  6429.                 'status' => $notConfigured 503 401,
  6430.                 'code' => $verdict['code'],
  6431.                 'reason' => $verdict['reason'],
  6432.                 'app_id' => 0,
  6433.                 'identity_source' => 'none',
  6434.                 'auth_method' => isset($verdict['method']) ? $verdict['method'] : $SIG::METHOD_NONE,
  6435.             ];
  6436.         }
  6437.         $authMethod = isset($verdict['method']) ? $verdict['method'] : $SIG::METHOD_NONE;
  6438.         // ── who am I? The box answers, not the caller. ──
  6439.         $registryAppId 0;
  6440.         $dbName '';
  6441.         try {
  6442.             $dbName = (string) $this->getDoctrine()->getManager()->getConnection()->getDatabase();
  6443.         } catch (\Throwable $e) {
  6444.             $dbName '';
  6445.         }
  6446.         if (\ApplicationBundle\Helper\McRelayConfig::declaredAppId() <= && $dbName !== '') {
  6447.             try {
  6448.                 // THIS box's OWN registry, about its OWN tenant. Not a cross-box read — CC7 is not
  6449.                 // engaged (same read VaultIngressController already performs).
  6450.                 $row $this->getDoctrine()->getManager('company_group')->getConnection()
  6451.                     ->fetchAssociative('SELECT app_id FROM company_group WHERE db_name = :d LIMIT 1', ['d' => $dbName]);
  6452.                 $registryAppId $row ? (int) $row['app_id'] : 0;
  6453.             } catch (\Throwable $e) {
  6454.                 $registryAppId 0;
  6455.             }
  6456.         }
  6457.         $identity $ID::decide($appId, \ApplicationBundle\Helper\McRelayConfig::declaredAppId(), $registryAppId$dbName);
  6458.         if (empty($identity['ok'])) {
  6459.             return [
  6460.                 'ok' => false,
  6461.                 'status' => $identity['code'] === $ID::UNRESOLVED 409 403,
  6462.                 'code' => $identity['code'],
  6463.                 'reason' => $identity['reason'],
  6464.                 'app_id' => 0,
  6465.                 'identity_source' => $identity['source'],
  6466.                 'auth_method' => $authMethod,
  6467.             ];
  6468.         }
  6469.         return ['ok' => true'status' => 200'code' => 'verified''reason' => $identity['reason'],
  6470.             'app_id' => (int) $identity['app_id'], 'identity_source' => $identity['source'],
  6471.             'auth_method' => $authMethod];
  6472.     }
  6473.     // =========================================================================
  6474.     // CENTRAL SSO ENTRY POINT
  6475.     // The central server redirects the company owner here after generating an
  6476.     // SSO token. This action validates the token with the central server and
  6477.     // auto-logs the user in to the ERP.
  6478.     // =========================================================================
  6479.     public function CentralSsoAction(Request $request)
  6480.     {
  6481.         $token = (string)$request->query->get('token''');
  6482.         $returnUrl = (string)$request->query->get('returnUrl''');
  6483.         if ($token === '') {
  6484.             return $this->render('@Application/pages/error/generic_error.html.twig', [
  6485.                 'message' => 'Invalid SSO token.',
  6486.             ]);
  6487.         }
  6488.         // Ask the central server to validate the token
  6489.         $centralBase $this->container->hasParameter('central_server_url')
  6490.             ? rtrim($this->container->getParameter('central_server_url'), '/')
  6491.             : '';
  6492.         if ($centralBase === '') {
  6493.             return $this->render('@Application/pages/error/generic_error.html.twig', [
  6494.                 'message' => 'Central server URL not configured on this ERP instance.',
  6495.             ]);
  6496.         }
  6497.         $validateUrl $centralBase '/my/sso/validate';
  6498.         $body http_build_query(['token' => $token]);
  6499.         // MC-0: TLS verification is ON. This call carries a one-time SSO token that logs a person in;
  6500.         // with VERIFYPEER/VERIFYHOST off (as it was) anything on the path could present its own
  6501.         // certificate, harvest the token and answer "yes, valid" — a full account takeover over a
  6502.         // link that looks like https. There is no dev convenience worth that.
  6503.         $curl curl_init();
  6504.         curl_setopt_array($curl, [
  6505.             CURLOPT_RETURNTRANSFER => true,
  6506.             CURLOPT_POST => true,
  6507.             CURLOPT_URL => $validateUrl,
  6508.             CURLOPT_CONNECTTIMEOUT => 8,
  6509.             CURLOPT_TIMEOUT => 8,
  6510.             CURLOPT_SSL_VERIFYPEER => true,
  6511.             CURLOPT_SSL_VERIFYHOST => 2,
  6512.             CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
  6513.             CURLOPT_POSTFIELDS => $body,
  6514.         ]);
  6515.         $raw curl_exec($curl);
  6516.         curl_close($curl);
  6517.         if (!$raw) {
  6518.             return $this->render('@Application/pages/error/generic_error.html.twig', [
  6519.                 'message' => 'Could not reach the central server for SSO validation.',
  6520.             ]);
  6521.         }
  6522.         $payload json_decode($rawtrue);
  6523.         if (!is_array($payload) || empty($payload['success'])) {
  6524.             return $this->render('@Application/pages/error/generic_error.html.twig', [
  6525.                 'message' => 'SSO token is invalid or has expired. Please try again.',
  6526.             ]);
  6527.         }
  6528.         $email = (string)($payload['email'] ?? '');
  6529.         if ($email === '') {
  6530.             return $this->render('@Application/pages/error/generic_error.html.twig', [
  6531.                 'message' => 'No email returned from SSO validation.',
  6532.             ]);
  6533.         }
  6534.         // Find the local user by email
  6535.         $em $this->getDoctrine()->getManager();
  6536.         $conn $em->getConnection();
  6537.         $userRow null;
  6538.         try {
  6539.             $userRow $conn->fetchAssociative(
  6540.                 "SELECT * FROM sys_user WHERE email = :email AND status = 1 LIMIT 1",
  6541.                 ['email' => $email]
  6542.             );
  6543.         } catch (\Exception $e) {
  6544.         }
  6545.         if (!$userRow) {
  6546.             return $this->render('@Application/pages/error/generic_error.html.twig', [
  6547.                 'message' => 'No matching active user found in this ERP for email: ' htmlspecialchars($email),
  6548.             ]);
  6549.         }
  6550.         // Auto-login: populate session exactly as the normal login flow does
  6551.         $session $request->getSession();
  6552.         $session->set(\ApplicationBundle\Modules\Authentication\Constants\UserConstants::USER_ID$userRow['user_id'] ?? $userRow['id'] ?? 0);
  6553.         $session->set(\ApplicationBundle\Modules\Authentication\Constants\UserConstants::USER_NAME$userRow['name'] ?? $payload['name'] ?? '');
  6554.         $session->set(\ApplicationBundle\Modules\Authentication\Constants\UserConstants::USER_TYPE$userRow['user_type'] ?? 0);
  6555.         $session->set(\ApplicationBundle\Modules\Authentication\Constants\UserConstants::USER_COMPANY_ID$userRow['user_company_id'] ?? $userRow['company_id'] ?? 0);
  6556.         // Redirect to ERP dashboard or the requested returnUrl
  6557.         if ($returnUrl !== '' && strpos($returnUrl'http') === 0) {
  6558.             return $this->redirect($returnUrl);
  6559.         }
  6560.         return $this->redirectToRoute('central_landing');
  6561.     }
  6562. }