<?php
namespace App\Service;
use App\Constant\Common;
use App\Entity\Notification;
use App\Entity\Role;
use App\Entity\Status;
use App\Entity\Profile;
use App\Entity\ProfileNote;
use App\Entity\Campaign;
use App\Repository\ProfileRepository;
use App\Exception\BadRequestException;
use App\Misc\ArrayHelper;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Contracts\HttpClient\HttpClientInterface;
/**
* Class ProfileService
* @package App\Service
*/
class ProfileService extends BaseService
{
/**
* ProfileService constructor.
* @param ProfileRepository $repository
*/
public function __construct(
ProfileRepository $repository,
BaseService $baseService,
SessionInterface $session,
TranslatorInterface $translator,
EventDispatcherInterface $dispatcher,
HttpClientInterface $httpClient
) {
$this->reflectFromParent($baseService);
$this->repository = $repository;
$this->session = $session;
$this->translator = $translator;
$this->dispatcher = $dispatcher;
$this->httpClient = $httpClient;
}
public function getById($id)
{
return $this->repository->getOneBy(
[
'filter_id' => $id
]
);
}
public function getProfileByUserId($userId)
{
return $this->repository->getProfileByUserId($userId);
}
public function addProfile($request, $DTO = null)
{
$user = $this->userService->addUser(array_merge(
$request->get("user"),
[
'password' => $this->container->getParameter('default_user_password'),
'subRoles' => [Role::ROLE_USER]
]
), 'ENTITY');
if($user && $DTO){
$this->userService->updateProfileUser($request, $user);
}
$request->request->set('user', $user->getId());
if ($this->session->get('trackingCode')) {
$mediaChannel = $this->MediaChannelRepo->findOneBy(
[
'name' => $this->session->get('trackingCode')
]
);
if ($mediaChannel) {
$input['mediaChannel'] = $mediaChannel;
}
}
// Add Profile
if($request->get('programs') && is_array($request->get('programs'))){
$input['selectedProgram'] = $request->get('programs')[0];
}
if($request->get('campus1')){
$request->request->set('campus', $request->get('campus1'));
$randCommercial = $this->getRandomComercialOfcampus($request->get('campus1'));
if($randCommercial){
$request->request->set('commercial', $randCommercial);
}
}
$input['status'] = Status::STATUS_NEED_CONTACT;
$profile = $this->add($request, $input, $DTO, 'ENTITY', false, [], true);
if ($profile->getCampaign()) {
if ($profile->getCampaign()->getId() == Campaign::APPLICATION) {
$this->userService->sendWelcomeEmail($profile);
}else if($profile->getCampaign()->getId() == Campaign::DOCUMENT){
$this->userService->sendDocumentEmail($profile);
}
}
// set profile sources
if ($request->get('openDay')) {
$openDay = $this->opendayRepo->findOneBy(['id' => $request->get('openDay')]);
if($openDay) {
$this->profileSourceService->checkandAddProfileSource($profile, $openDay->getName());
}
}else if($request->get('landingpage')) {
$landingpage = $this->landingpageRepo->findOneBy(['id' => $request->get('landingpage')]);
if($landingpage) {
if($landingpage->isIsAgent()){
$this->profileSourceService->checkandAddProfileSource($profile, 'LPA: ' .$landingpage->getName());
}else{
$this->profileSourceService->checkandAddProfileSource($profile, 'LP: ' .$landingpage->getName());
}
}
}else if($request->get('campaign')) {
$campaign = $this->campaignRepo->findOneBy(['id' => $request->get('campaign')]);
if($campaign) {
$this->profileSourceService->checkandAddProfileSource($profile, $campaign->getName());
}
}
// clear tracking code
$this->session->remove('trackingCode');
$token = new UsernamePasswordToken($user, null, 'main', $user->getSubRoleNames());
$this->tokenStorage->setToken($token);
if(!$DTO){
$event = new SecurityEvents($request);
$this->dispatcher->dispatch($event, SecurityEvents::INTERACTIVE_LOGIN);
}
return $profile;
}
public function updateProfile($request, $DTO = 'App\DTO\Profile\UpdateProfileInput', $step4 = null )
{
if($this->getUser()){
$profile = $this->getUser()->getProfiles()[0];
}elseif( $request->get('profileId')){
$profile = $this->get($request->get('profileId'));
}
if($step4 && $profile->getStatus()->getId() < Status::STATUS_APPLICATION_RECEIVED){
$request->request->set('status', Status::STATUS_APPLICATION_RECEIVED);
if(!$request->get('isSent')){
$request->request->set('isSent', 1);
//set profile sources
$campaign = $this->campaignService->get(Campaign::APPLICATION);
if($campaign) {
$this->profileSourceService->checkandAddProfileSource($profile, $campaign->getName());
}
}
}
// set profile sources
if ($request->get('openDay')) {
$openDay = $this->opendayRepo->findOneBy(['id' => $request->get('openDay')]);
if($openDay) {
$this->profileSourceService->checkandAddProfileSource($profile, $openDay->getName());
}
}else if($request->get('landingpage')) {
$landingpage = $this->landingpageRepo->findOneBy(['id' => $request->get('landingpage')]);
if($landingpage) {
if($landingpage->isIsAgent()){
$this->profileSourceService->checkandAddProfileSource($profile, 'LPA: ' .$landingpage->getName());
}else{
$this->profileSourceService->checkandAddProfileSource($profile, 'LP: ' .$landingpage->getName());
}
}
}else if($request->get('campaign')) {
$campaign = $this->campaignRepo->findOneBy(['id' => $request->get('campaign')]);
if($campaign) {
$this->profileSourceService->checkandAddProfileSource($profile, $campaign->getName());
}
}
if($request->get('campus1') && $request->get('campus1') != $profile->getCampus1()->getId()){
$request->request->set('campus', $request->get('campus1'));
$randCommercial = $this->getRandomComercialOfcampus($request->get('campus1'));
if($randCommercial){
$request->request->set('commercial', $randCommercial);
}
}
if($request->get('programs')){
$request->request->set('selectedProgram', $request->get('programs')[0]);
}
if($profile->isIsSent() && $request->get('campus1') != $profile->getCampus1()->getId()){
//send email change campus
if(isset(Common::listEmailAdmission()[$request->get('campus1')])){
$this->userService->sendCampusEmail($profile, Common::listEmailAdmission()[$request->get('campus1')]);
}
}
return $this->update($profile, $request, null, $DTO, 'ENTITY', false, true);
}
public function updateSelectedProgram($request, $DTO = 'App\DTO\Profile\AdminUpdateProfileSelectedProgramInput')
{
$profile = $this->get($request->get('id'));
return $this->update($profile, $request, null, $DTO, 'App\DTO\Profile\ProfileOutput', false, true);
}
public function handleSendMail($statusOld, $profile)
{
// Send Mail if status update
if (
$statusOld != ($profile->status)['id']
&& ($profile->status)['id'] >= Status::STATUS_APPLICATION_RECEIVED
&& !$profile->isAgent
) {
$this->userService->sendNotificationEmailUpdateStatus($profile);
}
}
public function updateProfileAdmin($request)
{
$profile = $this->get($request->get('id'));
if (!$profile) throw new NotFoundHttpException($this->translator->trans('profile_not_found'));
$statusOld = $profile->getStatus()->getId();
$input = [];
if ($request->get('jury')) {
$input['juryDate'] = new \DateTime('now');
}
if ($request->get('oraux')) {
$input['orauxDate'] = new \DateTime('now');
}
if($request->get('status') == Status::STATUS_JURY_ACCEPTED){
if($profile->getSelectedProgram()->getSpecialityId() && !$profile->getQcmToken()){
$user = $profile->getUser();
$now = new \DateTime('now');
$data = [
'civility' => $user->getGender() == 1 ? 'mrs' : 'mr' ,
'firstName' => $user->getFirstName(),
'lastName' => $user->getLastName(),
'email' => $user->getEmail(),
'birthDate' => $user->getBirthDay() ? $user->getBirthDay()->format('Y-m-d') : $now->format('Y-m-d'),
'phone' => $user->getPhone(),
'speciality' => $profile->getSelectedProgram()->getSpecialityId()
];
$responseQcm = $this->callQcmApi($data, '/auth/external/register', 'POST');
if($responseQcm['success'] == true && $responseQcm['data']){
$profile->setQcmToken($responseQcm['data']['password']);
$dataQcmResults = [
'isDoneTest' => $responseQcm['data']['isDoneTest'],
'questions' => $responseQcm['data']['questions']
];
$profile->setQcmResults($dataQcmResults);
}
}elseif ($profile->getSelectedProgram()->getSpecialityId() && $profile->getQcmToken()){
$data = [
'email' => $profile->getUser()->getEmail(),
'password' => $profile->getQcmToken(),
'speciality' => $profile->getSelectedProgram()->getSpecialityId()
];
$responseQcm = $this->callQcmApi($data, '/auth/external/user/update-speciality', 'PATCH');
$dataQcmResults = [
'isDoneTest' => $responseQcm['data']['isDoneTest'],
'questions' => $responseQcm['data']['questions']
];
$profile->setQcmResults($dataQcmResults);
}
}
if($request->get('status') == Status::STATUS_INTERVIEW_INVITED && $profile->getQcmMethod() == Profile::QCM_LOCAL){
if($profile->getOraux()){
$dateStartQCM = $profile->getOraux()->getDate()->format('Y-m-d');
$timeStartQCM = $profile->getOraux()->getHour() ? $profile->getOraux()->getHour()->format(' H:i:s') : '';
}
if(!isset($timeStartQCM)){
$orauxSelected = $this->orauxService->get($request->get('oraux'));
$dateStartQCM = $orauxSelected->getDate()->format('Y-m-d');
$timeStartQCM = $orauxSelected->getHour() ? $orauxSelected->getHour()->format(' H:i:s') : '';
}
$data = [
'email' => $profile->getUser()->getEmail(),
'password' => $profile->getQcmToken(),
'startTestAt' => (new \DateTime($dateStartQCM.$timeStartQCM, new \DateTimeZone($this->container->getParameter('fallback_timezone'))))->format(DATE_ATOM)
];
$this->callQcmApi($data, '/auth/external/user/update-start-test', 'PATCH');
}
if( $request->get('status') == Status::STATUS_STUDENT_ENROLLED ) {
$profile->setEnrolledDate(new \DateTime('now'));
}
// Check campus selected in list campus of commercial
// if ($inputCampus = $request->get('campus')) {
// if ($commercial = $profile->getCommercial()) {
// $campuses = [];
// foreach ($commercial->getCampuses() as $campus) {
// $campuses[] = $campus->getId();
// }
// if (!in_array($inputCampus, $campuses)) {
// $input['commercial'] = 'isNull';
// }
// }
// }
$profile = $this->update(
$profile,
$request,
$input,
'App\DTO\Profile\AdminUpdateProfileInput',
'App\DTO\Profile\ProfileOutput',
false,
true
);
$this->handleSendMail($statusOld, $profile);
if($request->get('campus') && $request->get('campus') != $profile->campus1['id']){
if(isset(Common::listEmailAdmission()[$request->get('campus')])){
$this->userService->sendCampusEmail($profile, Common::listEmailAdmission()[$request->get('campus')]);
}
}
return $profile;
}
public function updateProgramsAdmin($request)
{
$profile = $this->get($request->get('id'));
if (!$profile) throw new NotFoundHttpException($this->translator->trans('profile_not_found'));
$statusOld = $profile->getStatus()->getId();
$profile = $this->update(
$profile,
$request,
null,
'App\DTO\Profile\AdminUpdateProgramsProfileInput',
'App\DTO\Profile\ProfileOutput',
false,
true
);
$this->handleSendMail($statusOld, $profile);
return $profile;
}
public function duplicateProfile($request){
$profile = $this->repository->find($request->get('id'));
$programSelected = $this->programRepo->find($request->get('programId'));
$campusSelected = $this->campusRepo->find($request->get('campusId'));
$cloneCV = $profile->getFileCv() ? clone $profile->getFileCv() : null;
$cloneFileContract = $profile->getFileContract() ? clone $profile->getFileContract() : null;
$cloneLetter = $profile->getFileLetter() ? clone $profile->getFileLetter() : null;
$cloneFileReportCard1 = $profile->getFileReportCard1() ? clone $profile->getFileReportCard1() : null;
$cloneFileReportCard2 = $profile->getFileReportCard2() ? clone $profile->getFileReportCard2() : null;
$cloneFileReportCard3 = $profile->getFileReportCard3() ? clone $profile->getFileReportCard3() : null;
$cloneFileIdentity = $profile->getFileIdentity() ? clone $profile->getFileIdentity() : null;
$cloneFileResidencePermit = $profile->getFileResidencePermit() ? clone $profile->getFileResidencePermit() : null;
$cloneFilePhoto = $profile->getFilePhoto() ? clone $profile->getFilePhoto() : null;
$cloneFileHandicap = $profile->getFileHandicap() ? clone $profile->getFileHandicap() : null;
$profileDuplicate = clone $profile;
$profileDuplicate->setFileCv($cloneCV);
$profileDuplicate->setFileContract($cloneFileContract);
$profileDuplicate->setFileLetter($cloneLetter);
$profileDuplicate->setFileReportCard1($cloneFileReportCard1);
$profileDuplicate->setFileReportCard2($cloneFileReportCard2);
$profileDuplicate->setFileReportCard3($cloneFileReportCard3);
$profileDuplicate->setFileIdentity($cloneFileIdentity);
$profileDuplicate->setFileResidencePermit($cloneFileResidencePermit);
$profileDuplicate->setFilePhoto($cloneFilePhoto);
$profileDuplicate->setFileHandicap($cloneFileHandicap);
$profileDuplicate->setSelectedProgram($programSelected);
$profileDuplicate->addProgram($programSelected);
$profileDuplicate->setCampus($campusSelected);
$profileDuplicate->setCampus1($campusSelected);
$profileDuplicate->setCampus2(null);
$profileDuplicate->setCampus3(null);
$year = date("Y");
if(date("Y-m-d") > date("Y").'-10-01'){
$session = date('Y', strtotime('+1 year')).'-'. date('Y', strtotime('+2 year'));
}else{
$session = $year.'-'. date('Y', strtotime('+1 year'));
}
$profileDuplicate->setYear($session);
if($profile->getProfileNotes()){
foreach($profile->getProfileNotes() as $note){
$profileDuplicate->addProfileNote(clone $note);
}
}
if($profile->getProfileFiles()){
foreach($profile->getProfileFiles() as $file){
$profileDuplicate->addProfileFile(clone $file);
}
}
$profileDuplicate->setIsDuplicate(1);
$this->repository->save($profileDuplicate);
return $this->autoMapper->map($profileDuplicate, 'App\DTO\Profile\ProfileOutput');
}
public function updateProfileNotesAdmin($request)
{
$profile = $this->get($request->get('id'));
if (!$profile) throw new NotFoundHttpException($this->translator->trans('profile_not_found'));
$statusOld = $profile->getStatus()->getId();
$profile = $this->update(
$profile,
$request,
null,
'App\DTO\Profile\AdminUpdateProfileNotesProfileInput',
'App\DTO\Profile\ProfileOutput',
false,
true
);
$this->handleSendMail($statusOld, $profile);
return $profile;
}
public function checkProfileExpired(){
$profiles = $this->repository->findAll();
foreach($profiles as $profile){
if(!$profile->getExpireIdentity() && !$profile->getExpireResidencePermit()) continue;
if($profile->getExpireIdentity()){
$expireIdentity = null;
if($profile->getExpireIdentity()->format('Y-m-d') == date('Y-m-d',strtotime('+60 days'))){
$expireIdentity = Notification::EXPRIRE_TYPE_TWO_MONTH;
} elseif($profile->getExpireIdentity()->format('Y-m-d') == date('Y-m-d',strtotime('+30 days'))){
$expireIdentity = Notification::EXPRIRE_TYPE_ONE_MONTH;
} elseif($profile->getExpireIdentity()->format('Y-m-d') == date('Y-m-d',strtotime('+21 days'))){
$expireIdentity = Notification::EXPRIRE_TYPE_THREE_WEEK;
} elseif($profile->getExpireIdentity()->format('Y-m-d') == date('Y-m-d',strtotime('+14 days'))){
$expireIdentity = Notification::EXPRIRE_TYPE_TWO_WEEK;
} elseif($profile->getExpireIdentity()->format('Y-m-d') == date('Y-m-d',strtotime('+7 days'))){
$expireIdentity = Notification::EXPRIRE_TYPE_ONE_WEEK;
}
if($expireIdentity){
$notification = $this->notificationRepo->findOneBy(['profile' => $profile, 'type' => Notification::TYPE_IDENTITY]);
if(!$notification){
$notification = new Notification;
$notification->setProfile($profile);
}
$notification->setType(Notification::TYPE_IDENTITY);
$notification->setExpireType($expireIdentity);
$notification->setIsSeen(null);
$this->notificationService->repository->save($notification);
}
}
if($profile->getExpireResidencePermit()){
$expireResidencePermit = null;
if($profile->getExpireResidencePermit()->format('Y-m-d') == date('Y-m-d',strtotime('+60 days'))){
$expireResidencePermit = Notification::EXPRIRE_TYPE_TWO_MONTH;
} elseif($profile->getExpireResidencePermit()->format('Y-m-d') == date('Y-m-d',strtotime('+30 days'))){
$expireResidencePermit = Notification::EXPRIRE_TYPE_ONE_MONTH;
} elseif($profile->getExpireResidencePermit()->format('Y-m-d') == date('Y-m-d',strtotime('+21 days'))){
$expireResidencePermit = Notification::EXPRIRE_TYPE_THREE_WEEK;
} elseif($profile->getExpireResidencePermit()->format('Y-m-d') == date('Y-m-d',strtotime('+14 days'))){
$expireResidencePermit = Notification::EXPRIRE_TYPE_TWO_WEEK;
} elseif($profile->getExpireResidencePermit()->format('Y-m-d') == date('Y-m-d',strtotime('+7 days'))){
$expireResidencePermit = Notification::EXPRIRE_TYPE_ONE_WEEK;
}
if($expireResidencePermit){
$notification = $this->notificationRepo->findOneBy(['profile' => $profile, 'type' => Notification::TYPE_RESIDENCE_PERMIT]);
if(!$notification){
$notification = new Notification;
$notification->setProfile($profile);
}
$notification->setType(Notification::TYPE_RESIDENCE_PERMIT);
$notification->setExpireType($expireResidencePermit);
$notification->setIsSeen(null);
$this->notificationService->repository->save($notification);
}
}
}
}
public function checkRegister(){
$profiles = $this->repository->findAll();
foreach($profiles as $profile){
if($profile->getPercent() > 25 ) continue;
$day = null;
if($profile->getCreatedDate()->format('Y-m-d') == date('Y-m-d',strtotime('-1 days'))){
$day = 1;
} elseif($profile->getCreatedDate()->format('Y-m-d') == date('Y-m-d',strtotime('-3 days'))){
$day = 3;
} elseif($profile->getCreatedDate()->format('Y-m-d') == date('Y-m-d',strtotime('-7 days'))){
$day = 7;
}
if($day){
$this->userService->sendNotificationRegisterEmail($profile, $day);
}
}
}
private function callQcmApi($data, $url, $method){
$requestJson = json_encode($data, JSON_THROW_ON_ERROR);
$response = $this->httpClient->request($method, $this->container->getParameter('qcm_api_url').$url, [
'headers' => [
'Content-Type: application/json',
'Accept: application/json',
],
'body' => $requestJson,
]);
$responseJson = $response->getContent();
$responseData = json_decode($responseJson, true);
return $responseData;
}
public function getQcmUrl($profile){
$data = [
'email' => $profile['user']['email'],
'password' => $profile['qcmToken']
];
$requestJson = json_encode($data, JSON_THROW_ON_ERROR);
$response = $this->httpClient->request('POST', $this->container->getParameter('qcm_api_url').'/auth/one-time-token', [
'headers' => [
'Content-Type: application/json',
'Accept: application/json',
],
'body' => $requestJson,
]);
$responseJson = $response->getContent();
$responseData = json_decode($responseJson, true);
$redirectUrl = null;
if($responseData['success'] == true){
$redirectUrl = $responseData['redirectUrl'];
}
return $redirectUrl;
}
public function getRandomComercialOfcampus($campusId)
{
$commercials = $this->campusService->getListUsersActive($campusId);
if (empty($commercials) || count($commercials->toArray()) == 0) {
return null;
}
$randomKey = array_rand($commercials->toArray());
$randomCommercial = $commercials[$randomKey];
return $randomCommercial->getId() ?? null;
}
}