<?php
namespace CompanyGroupBundle\Controller;
use ApplicationBundle\Constants\ModuleConstant;
use ApplicationBundle\Modules\System\MiscActions;
use ApplicationBundle\Modules\Authentication\Constants\UserConstants;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class SuperAdminDashboardController extends Controller
{
public function indexAction(Request $request)
{
if (!$this->canAccessSuperAdminDashboard($request)) {
return $this->redirectToRoute('dashboard');
}
$service = $this->get('app.admin_dashboard_service');
$metrics = $service->getMetrics();
$companies = $service->listCompanies(12, 0, []);
$usageSummary = $service->getUsageSummary(30);
$alerts = $service->getAlerts();
$chartData = $this->buildChartData($usageSummary);
return $this->render('@CompanyGroup/pages/super_admin_command_center.html.twig', [
'page_title' => 'Super Admin Command Center',
'metrics' => $metrics,
'companies' => $companies,
'usage_summary' => $usageSummary,
'alerts' => $alerts,
'chart_data' => $chartData,
]);
}
public function companyListAction(Request $request)
{
$systemType = $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
if ($systemType !== '_CENTRAL_') {
return $this->redirectToRoute('dashboard');
}
if (!$this->canAccessSuperAdminDashboard($request)) {
return $this->redirectToRoute('dashboard');
}
$page = max(1, (int)$request->query->get('page', 1));
$limit = 25;
$offset = ($page - 1) * $limit;
$filters = array(
'search' => trim((string)$request->query->get('q', '')),
'status' => trim((string)$request->query->get('status', '')),
);
$service = $this->get('app.admin_dashboard_service');
$companies = $service->listCompanies($limit, $offset, $filters);
$total = $this->countCompaniesForAdminList($filters);
$totalPages = max(1, (int)ceil($total / $limit));
$summary = $this->getCompanyListSummary();
return $this->render('@CompanyGroup/pages/admin/companies/list_companies.html.twig', array(
'page_title' => 'Companies',
'companies' => $companies,
'filters' => $filters,
'summary' => $summary,
'total' => $total,
'currentPage' => $page,
'totalPages' => $totalPages,
));
}
public function companyViewAction(Request $request, $appId)
{
$systemType = $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
if ($systemType !== '_CENTRAL_') {
return $this->redirectToRoute('dashboard');
}
if (!$this->canAccessSuperAdminDashboard($request)) {
return $this->redirectToRoute('dashboard');
}
$service = $this->get('app.admin_dashboard_service');
$company = $service->getCompanyByAppId((int)$appId);
if (!$company) {
throw $this->createNotFoundException('Company appId #' . (int)$appId . ' not found.');
}
$em = $this->getDoctrine()->getManager('company_group');
$companyEntity = $em->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findOneBy(array(
'appId' => (int)$appId,
));
$enabledModuleIds = $companyEntity ? $this->parseCompanyModuleIdList($companyEntity->getEnabledModuleIdList()) : array();
if (empty($enabledModuleIds)) {
$enabledModuleIds = $this->getDefaultEnabledCompanyModuleIds();
}
return $this->render('@CompanyGroup/pages/admin/companies/view_company.html.twig', array(
'page_title' => 'Company Details',
'company' => $company,
'company_entity' => $companyEntity,
'enabled_count' => count($enabledModuleIds),
'module_count' => count(ModuleConstant::$moduleList),
));
}
private function canAccessSuperAdminDashboard(Request $request)
{
$session = $request->getSession();
$userId = (int) $session->get(UserConstants::USER_ID, 0);
if ($userId <= 0) {
return false;
}
$userType = (int) $session->get(UserConstants::USER_TYPE, 0);
$isBuddybeeAdmin = (int) $session->get(UserConstants::IS_BUDDYBEE_ADMIN, 0);
$allModuleAccess = (int) $session->get(UserConstants::ALL_MODULE_ACCESS_FLAG, 0);
$allowedTypes = [
UserConstants::USER_TYPE_SYSTEM,
UserConstants::USER_TYPE_MANAGEMENT_USER,
UserConstants::USER_TYPE_GENERAL,
];
return $isBuddybeeAdmin === 1 || $allModuleAccess === 1 || in_array($userType, $allowedTypes, true);
}
private function countCompaniesForAdminList(array $filters)
{
$conn = $this->getDoctrine()->getManager('company_group')->getConnection();
$where = array();
$params = array();
if (!empty($filters['search'])) {
$where[] = '(name LIKE :search OR CAST(app_id AS CHAR) LIKE :search OR email LIKE :search)';
$params['search'] = '%' . $filters['search'] . '%';
}
if (!empty($filters['status'])) {
$where[] = 'company_status = :companyStatus';
$params['companyStatus'] = $filters['status'];
}
$sql = 'SELECT COUNT(*) FROM company_group';
if (!empty($where)) {
$sql .= ' WHERE ' . implode(' AND ', $where);
}
return (int)$conn->fetchOne($sql, $params);
}
private function getCompanyListSummary()
{
$conn = $this->getDoctrine()->getManager('company_group')->getConnection();
return array(
'all' => (int)$conn->fetchOne('SELECT COUNT(*) FROM company_group'),
'active' => (int)$conn->fetchOne("SELECT COUNT(*) FROM company_group WHERE company_status = 'active'"),
'trial' => (int)$conn->fetchOne("SELECT COUNT(*) FROM company_group WHERE company_status = 'trial'"),
'suspended' => (int)$conn->fetchOne("SELECT COUNT(*) FROM company_group WHERE company_status = 'suspended'"),
'expired' => (int)$conn->fetchOne("SELECT COUNT(*) FROM company_group WHERE company_status = 'expired'"),
'enabled' => (int)$conn->fetchOne('SELECT COUNT(*) FROM company_group WHERE active = 1'),
'disabled' => (int)$conn->fetchOne('SELECT COUNT(*) FROM company_group WHERE active = 0'),
);
}
public function companySettingsAction(Request $request, $appId)
{
$systemType = $this->container->hasParameter('system_type') ? $this->container->getParameter('system_type') : '_ERP_';
if ($systemType !== '_CENTRAL_') {
return $this->redirectToRoute('dashboard');
}
if (!$this->canAccessSuperAdminDashboard($request)) {
return $this->redirectToRoute('dashboard');
}
$appId = (int)$appId;
$em = $this->getDoctrine()->getManager('company_group');
$company = $em->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findOneBy(array(
'appId' => $appId,
));
if (!$company) {
throw $this->createNotFoundException('Company appId #' . $appId . ' not found.');
}
if ($request->isMethod('POST')) {
$company->setName($request->request->get('name', $company->getName()));
$company->setAddress($request->request->get('address', $company->getAddress()));
$company->setShippingAddress($request->request->get('shippingAddress', $company->getShippingAddress()));
$company->setBillingAddress($request->request->get('billingAddress', $company->getBillingAddress()));
$company->setMotto($request->request->get('motto', $company->getMotto()));
$company->setInvoiceFooter($request->request->get('invoiceFooter', $company->getInvoiceFooter()));
$company->setGeneralFooter($request->request->get('generalFooter', $company->getGeneralFooter()));
$company->setCompanyDescription($request->request->get('companyDescription', $company->getCompanyDescription()));
$company->setCompanyStatus($request->request->get('companyStatus', $company->getCompanyStatus()));
$company->setPackageType($request->request->get('packageType', $company->getPackageType()));
$company->setActive((int)$request->request->get('active', 0));
$company->setReadOnlyMode((int)$request->request->get('readOnlyMode', 0));
$company->setAdminUserAllowed((int)$request->request->get('adminUserAllowed', 0));
$company->setUserAllowed((int)$request->request->get('userAllowed', 0));
$company->setSubscriptionMonth((int)$request->request->get('subscriptionMonth', 0));
$company->setCurrentSubscriptionPackageId((int)$request->request->get('currentSubscriptionPackageId', 0));
$company->setBillingAmount((int)$request->request->get('billingAmount', 0));
$usageValidUptoDate = $this->dateFromForm($request->request->get('usageValidUptoDate', ''));
$company->setUsageValidUptoDate($usageValidUptoDate);
$company->setUsageValidUptoDateTs($usageValidUptoDate ? $usageValidUptoDate->format('U') : 0);
$subscriptionExpiry = $this->dateFromForm($request->request->get('subscriptionExpiry', ''));
$company->setSubscriptionExpiry($subscriptionExpiry);
$moduleIds = $request->request->get('moduleIds', array());
if (!is_array($moduleIds)) {
$moduleIds = array();
}
$validModuleIds = array();
foreach (ModuleConstant::$moduleList as $module) {
$validModuleIds[(int)$module['id']] = true;
}
$enabledModuleIds = array();
foreach ($moduleIds as $moduleId) {
$moduleId = (int)$moduleId;
if ($moduleId > 0 && isset($validModuleIds[$moduleId])) {
$enabledModuleIds[$moduleId] = $moduleId;
}
}
ksort($enabledModuleIds);
$company->setEnabledModuleIdList(implode(',', array_values($enabledModuleIds)));
$em->flush();
$companySyncResult = $this->syncCompanySettingsToErp($em, $company);
$syncResult = $this->forceCompanyRouteSync($company);
if ($companySyncResult['success'] && $syncResult['success']) {
$this->addFlash('success', 'Company settings were saved and synced to ERP.');
} else {
$this->addFlash('warning', 'Company settings were saved, but ERP sync needs attention. Company sync: ' . $companySyncResult['message'] . ' Route sync: ' . $syncResult['message']);
}
return $this->redirectToRoute('admin_company_settings', array(
'appId' => $appId,
));
}
$enabledModuleIds = $this->parseCompanyModuleIdList($company->getEnabledModuleIdList());
if (empty($enabledModuleIds)) {
$enabledModuleIds = $this->getDefaultEnabledCompanyModuleIds();
}
$enabledLookup = array_fill_keys($enabledModuleIds, true);
$groupedModules = $this->buildGroupedModuleList();
return $this->render('@CompanyGroup/pages/admin/companies/module_settings.html.twig', array(
'page_title' => 'Company Settings',
'company' => $company,
'grouped_modules' => $groupedModules,
'enabled_lookup' => $enabledLookup,
'enabled_count' => count($enabledLookup),
'module_count' => count(ModuleConstant::$moduleList),
));
}
public function companyModuleSettingsAction(Request $request, $appId)
{
return $this->companySettingsAction($request, $appId);
}
private function dateFromForm($value)
{
$value = trim((string)$value);
if ($value === '') {
return null;
}
try {
return new \DateTime($value);
} catch (\Exception $e) {
return null;
}
}
private function syncCompanySettingsToErp($em, $company)
{
$response = MiscActions::updateCompanyToErpServer($em, (int)$company->getAppId(), $this->container->getParameter('kernel.root_dir'));
if (isset($response['success']) && $response['success'] === true) {
return array(
'success' => true,
'message' => isset($response['message']) ? $response['message'] : 'Synced.',
);
}
return array(
'success' => false,
'message' => isset($response['message']) ? $response['message'] : 'Company metadata sync was not confirmed.',
);
}
private function parseCompanyModuleIdList($moduleIdList)
{
$moduleIdList = trim((string)$moduleIdList);
if ($moduleIdList === '') {
return array();
}
$decoded = json_decode($moduleIdList, true);
$rawList = is_array($decoded) ? $decoded : explode(',', $moduleIdList);
$cleanList = array();
foreach ($rawList as $moduleId) {
$moduleId = (int)$moduleId;
if ($moduleId > 0) {
$cleanList[$moduleId] = $moduleId;
}
}
return array_values($cleanList);
}
private function getDefaultEnabledCompanyModuleIds()
{
$moduleIds = array();
foreach (ModuleConstant::$moduleList as $module) {
if ((int)(isset($module['defaultEnabledForCompany']) ? $module['defaultEnabledForCompany'] : 0) === 1) {
$moduleIds[] = (int)$module['id'];
}
}
return $moduleIds;
}
private function buildGroupedModuleList()
{
$groups = array();
foreach (ModuleConstant::$parentModuleList as $parentModule) {
$groups[(int)$parentModule['id']] = array(
'parent' => $parentModule,
'modules' => array(),
);
}
foreach (ModuleConstant::$moduleList as $module) {
$parentId = (int)$module['parentId'];
if (!isset($groups[$parentId])) {
$groups[$parentId] = array(
'parent' => array(
'id' => $parentId,
'name' => 'Other',
),
'modules' => array(),
);
}
$groups[$parentId]['modules'][] = $module;
}
foreach ($groups as $parentId => $group) {
if (empty($group['modules'])) {
unset($groups[$parentId]);
}
}
return $groups;
}
private function forceCompanyRouteSync($company)
{
$serverAddress = rtrim((string)$company->getCompanyGroupServerAddress(), '/');
if ($serverAddress === '') {
return array(
'success' => false,
'message' => 'ERP server address is not configured.',
);
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_URL => $serverAddress . '/update_route_company_wise',
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_POSTFIELDS => http_build_query(array(
'appId' => (int)$company->getAppId(),
)),
));
$response = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
if ($error) {
return array(
'success' => false,
'message' => $error,
);
}
return array(
'success' => true,
'message' => (string)$response,
);
}
private function buildChartData(array $usageSummary)
{
$activityTrend = $usageSummary['activity_trend'] ?? [];
$usageTrend = $usageSummary['usage_trend'] ?? [];
$revenueTrend = $usageSummary['revenue_trend'] ?? [];
$activityByDay = [];
foreach ($activityTrend as $row) {
$day = (string) ($row['day'] ?? '');
if ($day === '') {
continue;
}
if (!isset($activityByDay[$day])) {
$activityByDay[$day] = 0;
}
$activityByDay[$day] += (int) ($row['total'] ?? 0);
}
$usageByDay = [];
foreach ($usageTrend as $row) {
$day = (string) ($row['day'] ?? '');
if ($day === '') {
continue;
}
if (!isset($usageByDay[$day])) {
$usageByDay[$day] = 0;
}
$usageByDay[$day] += (int) ($row['total'] ?? 0);
}
$revenueByDay = [];
foreach ($revenueTrend as $row) {
$day = (string) ($row['day'] ?? '');
if ($day === '') {
continue;
}
$revenueByDay[$day] = (float) ($row['total'] ?? 0);
}
$labels = array_values(array_unique(array_merge(
array_keys($activityByDay),
array_keys($usageByDay),
array_keys($revenueByDay)
)));
sort($labels);
$activitySeries = [];
$usageSeries = [];
$revenueSeries = [];
foreach ($labels as $label) {
$activitySeries[] = (int) ($activityByDay[$label] ?? 0);
$usageSeries[] = (int) ($usageByDay[$label] ?? 0);
$revenueSeries[] = (float) ($revenueByDay[$label] ?? 0);
}
return [
'labels' => $labels,
'activity_series' => $activitySeries,
'usage_series' => $usageSeries,
'revenue_series' => $revenueSeries,
];
}
}