<?php
namespace ApplicationBundle\Modules\HoneybeeWeb\Controller;
use ApplicationBundle\Constants\GeneralConstant;
use ApplicationBundle\Constants\HumanResourceConstant;
use ApplicationBundle\Controller\GenericController;
use ApplicationBundle\Entity\EmpLeaveApplication;
use ApplicationBundle\Entity\ReceiptCheck;
use ApplicationBundle\Interfaces\SessionCheckInterface;
use ApplicationBundle\Modules\Authentication\Constants\UserConstants; use ApplicationBundle\Modules\Api\Constants\ApiConstants;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360AccessService;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360ConversionService;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360ExecutionService;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360GridService;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360HybridService;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360ProjectService;
use ApplicationBundle\Modules\HoneybeeWeb\Service\Hb360ReportService;
use ApplicationBundle\Modules\HoneybeeWeb\Support\FunnelManifestCore;
use CompanyGroupBundle\Entity\EntityApplicantDetails;
use CompanyGroupBundle\Entity\EntityCountryConsultantRequirements;
use CompanyGroupBundle\Entity\EntitySkill;
use CompanyGroupBundle\Entity\EntityCreateBlog;
use CompanyGroupBundle\Entity\EntityCreateTopic;
use Ps\PdfBundle\Annotation\Pdf;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Generator\UrlGenerator;
use CompanyGroupBundle\Entity\User;
//use Symfony\Bundle\FrameworkBundle\Console\Application;
//use Symfony\Component\Console\Input\ArrayInput;
//use Symfony\Component\Console\Output\NullOutput;
class HoneybeeWebController extends GenericController implements SessionCheckInterface
{
// ═══ HB360 H1b/H1c — "your saved estimate" behind the signup wall ═══
/**
* Tier gate for a package. Returns null when allowed; otherwise a redirect
* to the estimate page with an upsell notice. SWITCHED OFF by default
* (Hb360AccessService::DEFAULT_MAP is all-free) until the owner maps tiers.
*/
private function hb360TierGate(Request $request, string $package, int $projectId)
{
$check = (new Hb360AccessService($this->container))
->check($package, (int) $this->loggedUserId($request));
if ($check['allowed']) {
return null;
}
return $this->redirectToRoute('hb360_my_estimate', [
'p' => $projectId, 'locked' => $package, 'tier' => $check['required_tier'],
]);
}
/** The saved-estimate home: latest project + Package B report (if generated). */
public function Hb360MyEstimateAction(Request $request)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
$em = $this->getDoctrine()->getManager('company_group');
$svc = new Hb360ProjectService($em);
$applicantId = (int) $this->loggedUserId($request);
// Safety net for the login-time attach (e.g. the estimate was made in
// another tab AFTER logging in): claim anon rows for this cookie now.
try {
$anon = (string) $request->cookies->get('hb360_anon', '');
if ($anon !== '') {
$svc->attachToken($anon, $applicantId, (string) $request->getSession()->get(UserConstants::USER_EMAIL));
}
} catch (\Throwable $e) { /* best-effort */ }
$projects = []; $storageReady = true;
try {
$projects = $svc->listForApplicant($applicantId);
} catch (\Throwable $e) {
$storageReady = false; // hb360_project table not migrated yet
}
$current = null;
$pid = (int) $request->query->get('p', 0);
foreach ($projects as $p) {
if ((int) $p->getId() === $pid) { $current = $p; break; }
}
if (!$current && $projects) { $current = $projects[0]; }
// FUNNEL-1: the attached studio design card for the CURRENT estimate. Best-effort.
$design = null;
try {
if ($current && $current->getDesignJson()) {
$dj = json_decode((string) $current->getDesignJson(), true);
if (is_array($dj) && isset($dj['payload']) && is_array($dj['payload'])) {
$design = array(
'summary' => FunnelManifestCore::summary($dj['payload']),
'hash' => isset($dj['hash']) ? (string) $dj['hash'] : '',
'saved_at' => isset($dj['saved_at']) ? (string) $dj['saved_at'] : null,
);
}
}
} catch (\Throwable $e) { $design = null; }
// ── FUNNEL-3: "My designs" — every attached row carrying a studio design, with
// summary figures + the HONEST handoff status line (read from CENTRAL only —
// sds_funnel_handoff lives where the applicant lives; no tenant DB is touched).
$myDesigns = array();
try {
$handoffByProject = array();
$tenantNames = array();
try {
$conn = $em->getConnection();
if ($conn->getSchemaManager()->tablesExist(array('sds_funnel_handoff'))) {
$rows = $conn->fetchAllAssociative(
'SELECT project_id, target_app_id, status, created_at FROM sds_funnel_handoff'
. ' WHERE project_id IS NOT NULL ORDER BY id ASC');
foreach ($rows as $r) { // ASC ⇒ the LATEST handoff per project wins
$handoffByProject[(int) $r['project_id']] = $r;
}
foreach ($em->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findAll() as $g) {
$tenantNames[(int) $g->getAppId()] = (string) $g->getName();
}
}
} catch (\Throwable $e) { /* status lines are an extra, never a gate */ }
foreach ($projects as $p) {
if (!$p->getDesignJson()) { continue; }
$dj = json_decode((string) $p->getDesignJson(), true);
if (!is_array($dj) || !isset($dj['payload']) || !is_array($dj['payload'])) { continue; }
$entry = array(
'id' => (int) $p->getId(),
'title' => (string) ($p->getTitle() ?: ('Design #' . $p->getId())),
'address' => (string) $p->getAddress(),
'summary' => FunnelManifestCore::summary($dj['payload']),
'saved_at' => isset($dj['saved_at']) ? (string) $dj['saved_at'] : null,
'updated' => $p->getUpdatedAt() ? $p->getUpdatedAt()->format('d M Y H:i') : '',
'offer' => null,
);
if (isset($handoffByProject[(int) $p->getId()])) {
$h = $handoffByProject[(int) $p->getId()];
$label = \ApplicationBundle\Modules\HoneybeeWeb\Support\FunnelWireCore::applicantStatusLabel((string) $h['status']);
if ($label !== '') {
$entry['offer'] = array(
'label' => $label,
'recipient' => isset($tenantNames[(int) $h['target_app_id']])
? $tenantNames[(int) $h['target_app_id']] : null,
'when' => (string) $h['created_at'],
);
}
}
$myDesigns[] = $entry;
}
} catch (\Throwable $e) { $myDesigns = array(); }
return $this->render('@HoneybeeWeb/pages/tools/hb360_my_estimate.html.twig', array(
'page_title' => 'My Solar Estimates | HoneyBee 360',
'projects' => $projects,
'current' => $current,
'estimate' => $current ? json_decode($current->getEstimateJson(), true) : null,
'report' => ($current && $current->getReportJson()) ? json_decode($current->getReportJson(), true) : null,
'design' => $design,
'my_designs' => $myDesigns,
'storage_ready' => $storageReady,
));
}
/** H1c: turn the saved estimate into a Package B feasibility report. */
public function Hb360GenerateReportAction(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
$em = $this->getDoctrine()->getManager('company_group');
$svc = new Hb360ProjectService($em);
$project = $svc->findOwned((int) $id, (int) $this->loggedUserId($request));
if (!$project) {
return $this->redirectToRoute('hb360_my_estimate');
}
$estimate = json_decode($project->getEstimateJson(), true) ?: [];
$report = (new Hb360ReportService())->report($estimate, [
'lat' => $project->getLat() ?: 50,
// Equipment refinement: an explicit config pick from the report form.
'inverterModel' => (string) $request->request->get('inverter_model', ''),
]);
if (!empty($report['ok'])) {
// A refresh recomputes Package B but keeps existing deeper packages.
$old = json_decode((string) $project->getReportJson(), true);
foreach (['package_c', 'package_d', 'package_e', 'package_f'] as $pk) {
if (!empty($old[$pk])) { $report[$pk] = $old[$pk]; }
}
$svc->saveReport($project, $report);
}
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
// ═══ HB360-CONV — "Convert this estimate to an EPC project" (web wire) ═══
//
// Wraps the EXISTING Hb360ConversionService (no re-implementation). Hard
// rules: anonymous visitors hit the wall (the applicant gate below); the
// target tenant resolves ONLY from the authenticated session's app-id list
// (Hb360ConversionService::resolveTenant — a request-supplied id that is
// not in the session list resolves to null); conversion is confirm-before-
// commit, DRAFT-only (existing approval funnel), and idempotent (a stamped
// converted_ref shows the existing document, never a duplicate).
/** The session's workspace list — the ONLY source of a conversion target. */
private function hb360AllowedAppIds(Request $request): array
{
return Hb360ConversionService::allowedAppIds(
$request->getSession()->get(UserConstants::USER_APP_ID_LIST)
);
}
/** Connect a tenant DB (the application_connector reset pattern). */
private function hb360TenantConnect(int $appId): array
{
$emGoc = $this->getDoctrine()->getManager('company_group');
$goc = $emGoc->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findOneBy(['appId' => $appId]);
if (!$goc) {
return [null, null];
}
$this->container->get('application_connector')->resetConnection(
'default', $goc->getDbName(), $goc->getDbUser(), $goc->getDbPass(), $goc->getDbHost(), true
);
return [$this->getDoctrine()->getManager(), $goc];
}
/** Workspace labels + the best-effort ERP deep-link base, from CENTRAL data only. */
private function hb360WorkspaceMeta(array $appIds): array
{
$meta = [];
try {
$emGoc = $this->getDoctrine()->getManager('company_group');
foreach ($appIds as $appId) {
$goc = $emGoc->getRepository('CompanyGroupBundle\\Entity\\CompanyGroup')->findOneBy(['appId' => $appId]);
$addr = $goc ? trim((string) ($goc->getCurrentServerAddress() ?: $goc->getCompanyGroupServerAddress())) : '';
if ($addr !== '' && strpos($addr, 'http') !== 0) { $addr = 'https://' . $addr; }
$meta[$appId] = [
'name' => $goc ? (string) $goc->getName() : ('Workspace #' . $appId),
'erp_base' => $addr !== '' ? rtrim($addr, '/') : null,
];
}
} catch (\Throwable $e) { /* labels are cosmetic — never block the flow */ }
return $meta;
}
/** GET — the confirm step (also the "already converted" landing). */
public function Hb360ConvertConfirmAction(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login'); // the wall — anon never converts
}
$em = $this->getDoctrine()->getManager('company_group');
$project = (new Hb360ProjectService($em))->findOwned((int) $id, (int) $this->loggedUserId($request));
if (!$project) {
return $this->redirectToRoute('hb360_my_estimate');
}
$allowed = $this->hb360AllowedAppIds($request);
$estimate = json_decode($project->getEstimateJson(), true) ?: [];
// Idempotent landing: already converted → link the existing document.
$existing = null;
if ($project->getConvertedRef()) {
[$docHash, $proposalId] = array_pad(explode('#', (string) $project->getConvertedRef(), 2), 2, '');
$wsMeta = $this->hb360WorkspaceMeta([(int) $project->getConvertedAppId()]);
$base = $wsMeta[(int) $project->getConvertedAppId()]['erp_base'] ?? null;
$existing = [
'doc_hash' => $docHash, 'proposal_id' => (int) $proposalId,
'app_id' => (int) $project->getConvertedAppId(),
'workspace' => $wsMeta[(int) $project->getConvertedAppId()]['name'] ?? ('Workspace #' . $project->getConvertedAppId()),
'deep_link' => $base && $proposalId ? $base . '/view_sales_proposal/' . (int) $proposalId : null,
'converted_at' => $project->getConvertedAt(),
];
}
return $this->render('@HoneybeeWeb/pages/tools/hb360_convert.html.twig', array(
'page_title' => 'Convert to EPC project | HoneyBee 360',
'project' => $project,
'estimate' => $estimate,
'allowed' => $allowed,
'workspaces' => $this->hb360WorkspaceMeta($allowed),
'existing' => $existing,
'error' => (string) $request->query->get('e', ''),
));
}
/** POST — the commit: create ONE draft proposal in the session-resolved tenant. */
public function Hb360ConvertCommitAction(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
$emGoc = $this->getDoctrine()->getManager('company_group');
$project = (new Hb360ProjectService($emGoc))->findOwned((int) $id, (int) $this->loggedUserId($request));
if (!$project) {
return $this->redirectToRoute('hb360_my_estimate');
}
// Idempotent replay: a second POST lands on the existing document.
if ($project->getConvertedRef()) {
return $this->redirectToRoute('hb360_convert_confirm', ['id' => $project->getId()]);
}
// Tenant from the SESSION list only — a foreign id resolves to null.
$appId = Hb360ConversionService::resolveTenant(
$this->hb360AllowedAppIds($request), $request->request->get('workspace')
);
if ($appId === null) {
return $this->redirectToRoute('hb360_convert_confirm', ['id' => $project->getId(), 'e' => 'workspace']);
}
[$tenantEm, $goc] = $this->hb360TenantConnect($appId);
if (!$tenantEm) {
return $this->redirectToRoute('hb360_convert_confirm', ['id' => $project->getId(), 'e' => 'workspace']);
}
$session = $request->getSession();
$res = (new Hb360ConversionService())->convert($project, $tenantEm, $emGoc, $appId, false, [
'clientName' => trim((string) ($session->get(UserConstants::USER_NAME) ?: $session->get(UserConstants::USER_EMAIL) ?: '')),
]);
if (empty($res['ok'])) {
return $this->redirectToRoute('hb360_convert_confirm', ['id' => $project->getId(), 'e' => 'convert']);
}
return $this->redirectToRoute('hb360_convert_confirm', ['id' => $project->getId()]);
}
// ── FUNNEL-3: design management on the applicant surface. All three are POST-only,
// applicant-gated, and OWN-SCOPED through findOwned (a foreign id is a redirect,
// never a touch). Delete is SOFT — the retention cron purges it after 30 days. ──
/** The own-scoped project or a safe redirect (shared guard for the three actions). */
private function hb360OwnedOrNull(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return null;
}
$em = $this->getDoctrine()->getManager('company_group');
return (new Hb360ProjectService($em))->findOwned((int) $id, (int) $this->loggedUserId($request));
}
public function Hb360DesignRenameAction(Request $request, $id)
{
try {
$project = $this->hb360OwnedOrNull($request, $id);
if ($project) {
(new Hb360ProjectService($this->getDoctrine()->getManager('company_group')))
->rename($project, (string) $request->request->get('title', ''));
}
} catch (\Throwable $e) { /* fall through to the list */ }
return $this->redirectToRoute('hb360_my_estimate');
}
public function Hb360DesignDuplicateAction(Request $request, $id)
{
try {
$project = $this->hb360OwnedOrNull($request, $id);
if ($project) {
$copy = (new Hb360ProjectService($this->getDoctrine()->getManager('company_group')))
->duplicateForApplicant($project);
return $this->redirectToRoute('hb360_my_estimate', array('p' => $copy->getId()));
}
} catch (\Throwable $e) { /* fall through to the list */ }
return $this->redirectToRoute('hb360_my_estimate');
}
public function Hb360DesignDeleteAction(Request $request, $id)
{
try {
$project = $this->hb360OwnedOrNull($request, $id);
if ($project) {
(new Hb360ProjectService($this->getDoctrine()->getManager('company_group')))
->softDelete($project);
}
} catch (\Throwable $e) { /* fall through to the list */ }
return $this->redirectToRoute('hb360_my_estimate');
}
/** HB360-2: add/refresh the Package C hybrid design (BESS + genset + EVSE + finance). */
public function Hb360GenerateHybridAction(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
$em = $this->getDoctrine()->getManager('company_group');
$svc = new Hb360ProjectService($em);
$project = $svc->findOwned((int) $id, (int) $this->loggedUserId($request));
if (!$project) {
return $this->redirectToRoute('hb360_my_estimate');
}
if ($gate = $this->hb360TierGate($request, 'C', (int) $project->getId())) {
return $gate;
}
$estimate = json_decode($project->getEstimateJson(), true) ?: [];
$report = json_decode((string) $project->getReportJson(), true) ?: [];
if (empty($report['ok'])) {
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
$packageC = (new Hb360HybridService())->design($estimate, $report, [
'dayShare' => (float) $request->request->get('day_share', 60),
'criticalLoadPct' => (float) $request->request->get('critical_load_pct', 30),
'outageHoursYr' => (float) $request->request->get('outage_hours_yr', 0),
'chargers' => [
'ac11' => (int) $request->request->get('ev_ac11', 0),
'ac22' => (int) $request->request->get('ev_ac22', 0),
'dc50' => (int) $request->request->get('ev_dc50', 0),
'dc150' => (int) $request->request->get('ev_dc150', 0),
],
]);
if (!empty($packageC['ok'])) {
$report['package_c'] = $packageC;
$svc->saveReport($project, $report);
}
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
/** HB360-3: add/refresh the Package D grid & connection concept. */
public function Hb360GenerateGridAction(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
$em = $this->getDoctrine()->getManager('company_group');
$svc = new Hb360ProjectService($em);
$project = $svc->findOwned((int) $id, (int) $this->loggedUserId($request));
if (!$project) {
return $this->redirectToRoute('hb360_my_estimate');
}
if ($gate = $this->hb360TierGate($request, 'D', (int) $project->getId())) {
return $gate;
}
$estimate = json_decode($project->getEstimateJson(), true) ?: [];
$report = json_decode((string) $project->getReportJson(), true) ?: [];
if (empty($report['ok'])) {
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
$packageD = (new Hb360GridService())->design($estimate, $report, [
'exportCapPct' => (float) $request->request->get('export_cap_pct', 100),
'existingConnectionKva' => (float) $request->request->get('existing_connection_kva', 0),
], [
'lat' => (float) $project->getLat(), 'lng' => (float) $project->getLng(),
'address' => (string) $project->getAddress(),
]);
if (!empty($packageD['ok'])) {
$report['package_d'] = $packageD;
$svc->saveReport($project, $report);
}
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
/** HB360-4: add/refresh Packages E (execution briefing) + F (operate plan). */
public function Hb360GenerateExecutionAction(Request $request, $id)
{
if ((int) $this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
$em = $this->getDoctrine()->getManager('company_group');
$svc = new Hb360ProjectService($em);
$project = $svc->findOwned((int) $id, (int) $this->loggedUserId($request));
if (!$project) {
return $this->redirectToRoute('hb360_my_estimate');
}
if ($gate = $this->hb360TierGate($request, 'E', (int) $project->getId())) {
return $gate;
}
$estimate = json_decode($project->getEstimateJson(), true) ?: [];
$report = json_decode((string) $project->getReportJson(), true) ?: [];
if (empty($report['ok'])) {
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
$exec = (new Hb360ExecutionService())->design($estimate, $report);
if (!empty($exec['ok'])) {
$report['package_e'] = $exec['package_e'];
$report['package_f'] = $exec['package_f'];
$svc->saveReport($project, $report);
}
return $this->redirectToRoute('hb360_my_estimate', ['p' => $project->getId()]);
}
// My Freelancer Profile
public function CentralMyApplicantProfilePageAction(Request $request)
{
$em = $this->getDoctrine()->getManager('company_group');
$session = $request->getSession();
$details = $em->getRepository(EntityApplicantDetails::class)->find($session->get(UserConstants::USER_ID));
$employmentByCompany = [];
if ($details) {
$employmentByCompany = $this->get('app.applicant_employment_aggregator')->getForApplicant($details);
}
return $this->render('@HoneybeeWeb/pages/my_freelancer_profile.html.twig', array(
'page_title' => 'My Freelancer Profile',
'details' => $details,
'skillDetails' => $em->getRepository(EntitySkill::class)->findAll(),
'employmentByCompany' => $employmentByCompany,
));
}
public function AccountMergePageAction(Request $request)
{
if ((int)$this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return $this->redirectToRoute('central_login');
}
return $this->render('@HoneybeeWeb/pages/merge_accounts.html.twig', [
'page_title' => 'Merge Accounts',
]);
}
public function RequestAccountMergeCodeAction(Request $request): JsonResponse
{
if ((int)$this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return new JsonResponse(['success' => false, 'message' => 'Please sign in first.'], 403);
}
$em = $this->getDoctrine()->getManager('company_group');
$requester = $em->getRepository(EntityApplicantDetails::class)->find((int)$this->loggedUserId($request));
if (!$requester) {
return new JsonResponse(['success' => false, 'message' => 'Applicant account not found.'], 404);
}
$result = $this->get('app.account_merge_service')->requestMergeCode(
$requester,
(string)$request->request->get('email', $request->query->get('email', ''))
);
return new JsonResponse($result, $result['success'] ? 200 : 422);
}
public function ConfirmAccountMergeAction(Request $request): JsonResponse
{
if ((int)$this->loggedUserType($request) !== UserConstants::USER_TYPE_APPLICANT) {
return new JsonResponse(['success' => false, 'message' => 'Please sign in first.'], 403);
}
$em = $this->getDoctrine()->getManager('company_group');
$requester = $em->getRepository(EntityApplicantDetails::class)->find((int)$this->loggedUserId($request));
if (!$requester) {
return new JsonResponse(['success' => false, 'message' => 'Applicant account not found.'], 404);
}
$result = $this->get('app.account_merge_service')->confirmMerge(
$requester,
(string)$request->request->get('email', $request->query->get('email', '')),
(string)$request->request->get('code', $request->query->get('code', '')),
$request->getSession()
);
return new JsonResponse($result, $result['success'] ? 200 : 422);
}
public function viewAsUserAction(Request $request, $id)
{
$session = $request->getSession();
$em_goc = $this->getDoctrine()->getManager('company_group');
$userType = $session->get(UserConstants::USER_TYPE);
$actualUserId = $session->get('actualUserId', $session->get(UserConstants::USER_ID));
$actualUserName = $session->get('actualUserName', $session->get(UserConstants::USER_NAME));
$actualUserType = $session->get('actualUserType', $session->get(UserConstants::USER_TYPE));
$actualUserAdminLevel = $session->get('actualUserAdminLevel', $session->get(UserConstants::BUDDYBEE_ADMIN_LEVEL));
$actualUserIsAdmin = $session->get('actualUserIsAdmin', $session->get(UserConstants::IS_BUDDYBEE_ADMIN));
$actualUserIsModerator = $session->get('actualUserIsModerator', $session->get(UserConstants::IS_BUDDYBEE_MODERATOR));
$switchToUserId = $request->query->get('id', $request->request->get('id', $id));
if ($userType == UserConstants::USER_TYPE_APPLICANT) {
$user = $em_goc->getRepository('CompanyGroupBundle\\Entity\\EntityApplicantDetails')->findOneBy(
array(
'applicantId' => $switchToUserId
)
);
$session->set(UserConstants::USER_ID, $user->getApplicantId());
$session->set(UserConstants::IS_CONSULTANT, $user->getIsConsultant() == 1 ? 1 : 0);
$session->set('BUDDYBEE_BALANCE', 1 * $user->getAccountBalance());
$session->set('BUDDYBEE_COIN_BALANCE', 1 * $user->getSessionCountBalance());
$session->set(UserConstants::IS_BUDDYBEE_RETAILER, $user->getIsRetailer() == 1 ? 1 : 0);
$session->set(UserConstants::BUDDYBEE_RETAILER_LEVEL, $user->getRetailerLevel() == 1 ? 1 : 0);
$session->set(UserConstants::BUDDYBEE_ADMIN_LEVEL, $user->getIsAdmin() == 1 ? (($user->getAdminLevel() != null && $user->getAdminLevel() != 0) ? $user->getAdminLevel() : 1) : ($user->getIsModerator() == 1 ? 1 : 0));
$session->set(UserConstants::IS_BUDDYBEE_MODERATOR, $user->getIsModerator() == 1 ? 1 : 0);
$session->set(UserConstants::IS_BUDDYBEE_ADMIN, $user->getIsAdmin() == 1 ? 1 : 0);
// $session->set(UserConstants::SUPPLIER_ID, $user->getSupplierId());
$session->set(UserConstants::USER_TYPE, UserConstants::USER_TYPE_APPLICANT);
$session->set(UserConstants::USER_EMAIL, $user->getOauthEmail());
$session->set(UserConstants::USER_IMAGE, $user->getImage());
$session->set(UserConstants::USER_NAME, $user->getFirstName() . ' ' . $user->getLastName());
$session->set(UserConstants::USER_DEFAULT_ROUTE, '');
$session->set(UserConstants::USER_COMPANY_ID, 1);
$session->set(UserConstants::USER_COMPANY_ID_LIST, json_encode([]));
$session->set(UserConstants::USER_COMPANY_NAME_LIST, json_encode([]));
$session->set(UserConstants::USER_COMPANY_IMAGE_LIST, json_encode([]));
$session->set('userCompanyDarkVibrantList', json_encode([]));
$session->set('userCompanyVibrantList', json_encode([]));
$session->set('userCompanyLightVibrantList', json_encode([]));
$session->set(UserConstants::USER_COMPANY_IMAGE_LIST, json_encode([]));
$session->set(UserConstants::USER_APP_ID, 0);
$session->set(UserConstants::USER_POSITION_LIST, '[]');
$session->set(UserConstants::ALL_MODULE_ACCESS_FLAG, 0);
$session->set(UserConstants::SESSION_SALT, uniqid(mt_rand()));
$session->set(UserConstants::APPLICATION_SECRET, $this->container->getParameter('secret'));
$session->set(UserConstants::USER_NOTIFICATION_ENABLED, GeneralConstant::NOTIFICATION_ENABLED == 1 ? ($this->getParameter('notification_enabled') == 1 ? 1 : 0) : 0);
$session->set(UserConstants::USER_NOTIFICATION_SERVER, $this->getParameter('notification_server'));
$session->set('oAuthToken', $request->request->get('oAuthToken', ''));
$session->set('locale', $request->request->get('locale', ''));
$session->set('firebaseToken', $request->request->get('firebaseToken', ''));
$session->set('actualUserId', $actualUserId);
$session->set('actualUserName', $actualUserName);
$session->set('actualUserType', $actualUserType);
$session->set('actualUserAdminLevel', $actualUserAdminLevel);
$session->set('actualUserIsAdmin', $actualUserIsAdmin);
$session->set('actualUserIsModerator', $actualUserIsModerator);
$route_list_array = [];
$session->set(UserConstants::USER_CURRENT_POSITION, 0);
// $userAppIds = json_decode($user->getUserAppIds(), true);
$userAppIds = [];
$userSuspendedAppIds = json_decode($user->getUserSuspendedAppIds(), true);
$userTypesByAppIds = json_decode($user->getUserTypesByAppIds(), true);
if ($userAppIds == null) $userAppIds = [];
if ($userSuspendedAppIds == null) $userSuspendedAppIds = [];
if ($userTypesByAppIds == null) $userTypesByAppIds = [];
foreach ($userTypesByAppIds as $aid => $accData)
if (in_array($aid, $userSuspendedAppIds))
unset($userTypesByAppIds[$aid]);
else
$userAppIds[]=$aid;
// $userAppIds=array_diff($userAppIds,$userSuspendedAppIds);
$gocList = $em_goc
->getRepository("CompanyGroupBundle\\Entity\\CompanyGroup")
->findBy(
array(// 'active' => 1
'appId'=>$userAppIds
)
);
$gocDataList = [];
$gocDataListForLoginWeb = [];
$gocDataListByAppId = [];
$accessList=[];
foreach ($gocList as $entry) {
$d = array(
'name' => $entry->getName(),
'image' => $entry->getImage(),
'id' => $entry->getId(),
'appId' => $entry->getAppId(),
'skipInWebFlag' => $entry->getSkipInWebFlag(),
'skipInAppFlag' => $entry->getSkipInAppFlag(),
'dbName' => $entry->getDbName(),
'dbUser' => $entry->getDbUser(),
'dbPass' => $entry->getDbPass(),
'dbHost' => $entry->getDbHost(),
'companyGroupServerAddress' => $entry->getCompanyGroupServerAddress(),
'companyGroupServerId' => $entry->getCompanyGroupServerId(),
'companyGroupServerPort' => $entry->getCompanyGroupServerPort(),
'companyRemaining' => $entry->getCompanyRemaining(),
'companyAllowed' => $entry->getCompanyAllowed(),
);
$gocDataList[$entry->getId()] = $d;
if (in_array($entry->getSkipInWebFlag(), [0, null]))
$gocDataListForLoginWeb[$entry->getId()] = $d;
$gocDataListByAppId[$entry->getAppId()] = $d;
}
foreach ($userTypesByAppIds as $thisUserAppId => $thisUserUserTypes) {
foreach ($thisUserUserTypes as $thisUserUserType) {
if (isset($gocDataListByAppId[$thisUserAppId])) {
$userTypeName = isset(UserConstants::$userTypeName[$thisUserUserType]) ? UserConstants::$userTypeName[$thisUserUserType] : 'Unknown';
$d = array(
'userType' => $thisUserUserType,
// 'userTypeName' => UserConstants::$userTypeName[$thisUserUserType],
'userTypeName' => $userTypeName,
'globalId' => $user->getApplicantId(),
'serverId' => $gocDataListByAppId[$thisUserAppId]['companyGroupServerId'],
'serverUrl' => $gocDataListByAppId[$thisUserAppId]['companyGroupServerAddress'],
'serverPort' => $gocDataListByAppId[$thisUserAppId]['companyGroupServerPort'],
'systemType' => '_ERP_',
'companyId' => 1,
'appId' => $thisUserAppId,
'companyLogoUrl' => $gocDataListByAppId[$thisUserAppId]['image'],
'companyName' => $gocDataListByAppId[$thisUserAppId]['name'],
'authenticationStr' => $this->get('url_encryptor')->encrypt(json_encode(
array(
'globalId' => $user->getApplicantId(),
'appId' => $thisUserAppId,
'authenticate' => 1,
'userType' => $thisUserUserType,
'userTypeName' => $userTypeName
)
)
),
'userCompanyList' => [
]
);
$accessList[] = $d;
}
}
}
$session_data['userAccessList'] = $accessList;
$session->set('userAccessList',$accessList);
$loginID = 0;
// $loginID = MiscActions::addEntityUserLoginLog(
// $em_goc,
// $session->get(UserConstants::USER_ID),
// $session->get(UserConstants::USER_ID),
// 1,
// $request->server->get("REMOTE_ADDR"),
// 0,
// $request->request->get('deviceId', ''),
// $request->request->get('oAuthToken', ''),
// $request->request->get('oAuthType', ''),
// $request->request->get('locale', ''),
// $request->request->get('firebaseToken', '')
//
// );
// $session->set(UserConstants::USER_LOGIN_ID, $loginID);
if ($request->request->has('referer_path')) {
if ($request->request->get('referer_path') != '/' && $request->request->get('referer_path') != '') {
return $this->redirect($request->request->get('referer_path'));
}
}
$redirectRoute = 'central_landing';
return $this->redirectToRoute($redirectRoute);
}
}
public function CentralGetHirePageAction(Request $request,$id=0)
{
$em = $this->getDoctrine()->getManager('company_group');
$session = $request->getSession();
$consultantDetails = $em->getRepository(EntityApplicantDetails::class)->find($session->get(UserConstants::USER_ID));
$consultantRequirementsQry = $em->getRepository(EntityCountryConsultantRequirements::class)->findAll();
$subscribed = false;
$consultantRequirementsByCountryId = [];
foreach ($consultantRequirementsQry as $value) {
$docList = json_decode($value->getDocumentList(), true);
$requiredFields = json_decode($value->getRequiredFields(), true);
if ($docList == null) $docList = [];
if ($requiredFields == null) $requiredFields = [];
$consultantRequirementsByCountryId[$value->getCountryId()] = array(
'documentList' => $docList,
'requiredFields' => $requiredFields,
'contractLetterHtml' => $value->getContractLetterHtml(),
);
}
$documentLists = $em->getRepository('CompanyGroupBundle\\Entity\\EntityCreateDocument')->findAll();;
$docListArray = [];
foreach ($documentLists as $document) {
$docListArray [$document->getId()] = array(
'id' => $document->getId(),
'docName' => $document->getDocumentName(),
'expiryDays' => $document->getExpiryDays(),
'processingDays' => $document->getProcessingDays(),
'emergencyProcessingDays' => $document->getEmergencyProcessingDays(),
'checklist' => json_decode($document->getCheckList()),
);
}
$skillDetails = $em->getRepository(EntitySkill::class)->findAll();
$companyId = $this->getLoggedUserCompanyId($request);
$gender = HumanResourceConstant::$sex;
$blood = HumanResourceConstant::$BloodGroup;
$userId = $session->get(UserConstants::USER_ID);
$education = array(
'instituteName' => $request->get('instituteName'),
'courseOfStudy' => $request->get('courseOfStudy'),
'courseStartDate' => $request->get('courseStartDate'),
'courseEndDate' => $request->get('courseEndDate'),
'result' => $request->get('result'),
'grade' => $request->get('grade'),
'degree' => $request->get('degree'),
);
$workExperience = array(
'title' => $request->get('title'),
'companyName' => $request->get('companyName'),
'jobStartDate' => $request->get('jobStartDate'),
'jobEndDate' => $request->get('jobEndDate'),
'description' => $request->get('workDescription'),
);
$certificate = array(
'certificatename' => $request->get('certificatename'),
'issuedDate' => $request->get('issuedDate'),
);
$courses = array(
'courseName' => $request->get('courseName'),
'date' => $request->get('date'),
'duration' => $request->get('duration')
);
if ($request->isMethod('POST')) {
if ($consultantDetails)
$consultant = $consultantDetails;
else
$consultant = new EntityApplicantDetails();
$consultant->setApplicationText($request->request->get('applicationText'));
$consultant->setFirstname($request->request->get('firstname'));
$consultant->setLastname($request->request->get('lastname'));
$consultant->setIsImgLegal($request->request->get('is_img_legal'));
$consultant->setNid($request->request->get('nid'));
$consultant->setDob(new \DateTime($request->get('dob')));
$consultant->setSex($request->request->get('sex'));
$consultant->setFather($request->request->get('father'));
$consultant->setMother($request->request->get('mother'));
$consultant->setBlood($request->request->get('blood'));
$consultant->setPhone($request->request->get('phone'));
$consultant->setCountry($request->request->get('country'));
$consultant->setCurrentCountryId($request->request->get('currentCountryId'));
$consultant->setCountryId($request->request->get('currentCountryId'));
$consultant->setPostalCode($request->request->get('postalCode'));
$consultant->setDescription($request->request->get('description'));
$consultant->setCurrAddr($request->request->get('curr_addr'));
$consultant->setSkill(json_encode($request->request->get('skill')));
$consultant->setEmergencyContactNumber($request->request->get('emm_contact'));
$consultant->setEmail($request->request->get('oauth_email'));
$consultant->setCurrentEmployment($request->request->get('currentEmployment'));
$consultant->setTin($request->request->get('tin'));
$consultant->setEducationData(json_encode($education));
$consultant->setWorkExperienceData(json_encode($workExperience));
$consultant->setCertificateData(json_encode($certificate));
$consultant->setCoursesData(json_encode($courses));
$consultant->setWorkExperienceText($request->request->get('workExperience'));
$consultant->setUniversityText($request->request->get('universityText'));
$consultant->setEducationText($request->request->get('educationText'));
$consultant->setExperienceText($request->request->get('experienceText'));
$consultant->setSkillstext($request->request->get('skillText'));
$consultant->setSpeciality($request->request->get('speciality'));
$consultant->setDescription($request->request->get('aboutMe'));
$consultant->setApplyForConsultant(1);
$consultant->setApplyForConsultantDate(new \DateTime());
$em->persist($consultant);
$em->flush();
$subscribed = true;
}
return $this->render('@HoneybeeWeb/pages/get_hire.html.twig', array(
'page_title' => 'Get Hired',
'gender' => $gender,
'blood' => $blood,
'consultantDetails' => $consultantDetails,
'consultantRequirementsByCountryId' => $consultantRequirementsByCountryId,
'docListArray' => $docListArray,
'education' => json_decode($consultantDetails->getEducationData(), true),
'workExperience' => json_decode($consultantDetails->getWorkExperienceData(), true),
'certificate' => json_decode($consultantDetails->getCertificateData(), true),
'courses' => json_decode($consultantDetails->getCoursesData(), true),
'languages' => json_decode($consultantDetails->getLanguagesData(), true),
'skillDetails' => $skillDetails,
'subscribed' => $subscribed,
));
}
public function createTopicAction(Request $request,$id =0){
$em = $this->getDoctrine()->getManager('company_group');
if ($request->isMethod('POST')) {
$entityTopic = new EntityCreateTopic();
$entityTopic->setTopicName($request->request->get('catName'));
$em->persist($entityTopic);
$em->flush();
}
$topicDetails = $em->getRepository('CompanyGroupBundle\\Entity\\EntityCreateTopic')->findAll();
return $this->render('@HoneybeeWeb/pages/create_topic.html.twig', [
'page_title' => 'Create Category',
'topics' => $topicDetails
]);
}
public function createBlogAction(Request $request, $id = 0)
{
$em = $this->getDoctrine()->getManager('company_group');
// ── Soft Delete ──────────────────────────────────────────────────
if ($request->isMethod('POST') && $request->request->get('_action') === 'delete') {
$blog = $em->getRepository('CompanyGroupBundle\Entity\EntityCreateBlog')->find($id);
if (!$blog) {
throw $this->createNotFoundException('Blog not found');
}
$blog->setDeleteFlag(true);
$em->flush();
return $this->redirectToRoute('honeybee_blog', ['action' => 'create']);
}
// ── Find or new ───────────────────────────────────────────────────
if ($id > 0) {
$new = $em->getRepository('CompanyGroupBundle\Entity\EntityCreateBlog')->find($id);
if (!$new || $new->getDeleteFlag()) {
throw $this->createNotFoundException('Blog not found');
}
} else {
$new = new \CompanyGroupBundle\Entity\EntityCreateBlog();
}
$topicDetails = $em->getRepository('CompanyGroupBundle\Entity\EntityCreateTopic')->findAll();
if ($request->isMethod('POST')) {
$new->setTopicId($request->request->get('topicId'));
$new->setTitle($request->request->get('blogTitle'));
$new->setContent($request->request->get('blogContent'));
if ($id == 0) {
$session = $request->getSession();
$userName = $session->get(UserConstants::USER_NAME);
if ($userName) {
$new->setAuthorName($userName);
}
}
$em->persist($new);
$em->flush();
$upl_dir = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/BlogImages/';
$uploadedFile = $request->files->get('blogImage', null);
if ($uploadedFile != null) {
$fileName = 'p' . $new->getId() . '.' . $uploadedFile->guessExtension();
if (!file_exists($upl_dir)) {
mkdir($upl_dir, 0777, true);
}
$uploadedFile->move($upl_dir, $fileName);
$new->setMainImage('uploads/BlogImages/' . $fileName);
$em->flush();
}
return $this->redirectToRoute($request->attributes->get('_route'), ['id' => $new->getId()]);
}
// ── List: exclude soft-deleted ────────────────────────────────────
$blogDetails = $em->getRepository('CompanyGroupBundle\Entity\EntityCreateBlog')
->createQueryBuilder('b')
->where('b.deleteFlag != :status')
->orWhere('b.deleteFlag IS NULL')
->setParameter('status', true)
->getQuery()
->getResult();
return $this->render('@HoneybeeWeb/pages/create_blog.html.twig', [
'page_title' => ($id > 0) ? 'Edit Blog' : 'Create Blog',
'blogs' => $blogDetails,
'topics' => $topicDetails,
'blog' => $new,
]);
}
public function LoggedInUserAction(Request $request): JsonResponse
{
$session = $request->getSession();
$userId = $session->get(UserConstants::APPLICANT_ID);
$token = $session->get(UserConstants::USER_TOKEN);
// $providedToken = $request->headers->get('auth-token');
// return new JsonResponse([$token,$providedToken,$userId]);
// if (empty($providedToken) || $providedToken !== $token) {
// return new JsonResponse([
// 'status' => 'error',
// 'message' => 'Token mismatched or missing',
// ], 401);
// }
try {
$em_goc = $this->getDoctrine()->getManager('company_group');
$applicant = $em_goc->getRepository('CompanyGroupBundle\\Entity\\EntityApplicantDetails')
->findOneBy(
array(
'applicantId' => $userId
)
);
if (!$applicant->getApplicantId()) {
return new JsonResponse([
'success' => false,
'error' => [
'code' => 'USER_NOT_FOUND',
'message' => 'Applicant not found for the current session',
'statusCode' => 404,
]
], 404);
}
$educationDataRaw = json_decode($applicant->getEducationData(), true);
$workExperienceDataRaw = json_decode($applicant->getWorkExperienceData(), true);
$certificateDataRaw = json_decode($applicant->getCertificateData(), true);
$absoluteUrl = $this->generateUrl('dashboard', [], UrlGenerator::ABSOLUTE_URL);
$userImage = $session->get(UserConstants::USER_IMAGE);
$educationData = [];
if ($educationDataRaw && isset($educationDataRaw['instituteName'])) {
$count = count($educationDataRaw['instituteName']);
for ($i = 0; $i < $count; $i++) {
$educationData[] = [
'instituteName' => $educationDataRaw['instituteName'][$i] ?? '',
'courseOfStudy' => $educationDataRaw['courseOfStudy'][$i] ?? '',
'courseStartDate' => $educationDataRaw['courseStartDate'][$i] ?? '',
'courseEndDate' => $educationDataRaw['courseEndDate'][$i] ?? '',
'result' => $educationDataRaw['result'][$i] ?? '',
'grade' => $educationDataRaw['grade'][$i] ?? '',
'degree' => $educationDataRaw['degree'][$i] ?? '',
];
}
}
$workExperienceData = [];
if ($workExperienceDataRaw && isset($workExperienceDataRaw['title'])) {
$count = count($workExperienceDataRaw['title']);
for ($i = 0; $i < $count; $i++) {
$workExperienceData[] = [
'title' => $workExperienceDataRaw['title'][$i] ?? '',
'companyName' => $workExperienceDataRaw['companyName'][$i] ?? '',
'jobStartDate' => $workExperienceDataRaw['jobStartDate'][$i] ?? '',
'jobEndDate' => $workExperienceDataRaw['jobEndDate'][$i] ?? '',
'description' => $workExperienceDataRaw['description'][$i] ?? '',
];
}
}
$certificateData = [];
if ($certificateDataRaw && isset($certificateDataRaw['certificatename'])) {
$count = count($certificateDataRaw['certificatename']);
for ($i = 0; $i < $count; $i++) {
$certificateData[] = [
'certificatename' => $certificateDataRaw['certificatename'][$i] ?? '',
'issuedDate' => $certificateDataRaw['issuedDate'][$i] ?? '',
];
}
}
$data = [
'id' => $applicant->getApplicantId(),
'username' => $applicant->getUsername(),
'email' => $applicant->getEmail(),
'firstname' => $applicant->getFirstname(),
'lastname' => $applicant->getLastname(),
'phone' => $applicant->getPhone(),
'accountStatus' => $applicant->getAccountStatus(),
'educationData' => $educationData,
'workExperienceData' => $workExperienceData,
'certificateData' => $certificateData,
'skill' => [
'php',
'java'
],
'jobDone' => 3,
'pointsEarned' => 200,
'reviews' => 4.8,
'userImage' => $absoluteUrl . '' . $userImage
];
$data['Contract'] = [
'supplierName' => 'test',
'Date' => '25-10-2025',
'Summary' => 'summary'
];
return new JsonResponse([
'success' => true,
'data' => $data,
]);
}
catch (\Exception $e) {
return new JsonResponse([
'success' => false,
'error' => [
'code' => 'INTERNAL_ERROR',
'message' => 'Something went wrong',
'statusCode' => 500,
]
], 500);
}
}
public function summaryPlanAction(Request $request)
{
$em_goc = $this->getDoctrine()->getManager('company_group');
$session = $request->getSession();
$userId = $session->get(UserConstants::USER_ID);
$invoiceDetails = $em_goc->getRepository('CompanyGroupBundle\Entity\EntityInvoice')->findBy(
[
'applicantId' => $userId,
]
);
return $this->render('@HoneybeeWeb/pages/summaryPlan.html.twig', [
'page_title' => 'Invoice Summary',
'invoiceDetails' => $invoiceDetails,
]);
}
}