Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX]:- Optimization/hr module codebase #3394

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
158 changes: 3 additions & 155 deletions Modules/HR/Http/Controllers/Recruitment/ApplicationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,17 @@

use App\Helpers\FileHelper;
use App\Models\Setting;
use App\Models\Tag;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Modules\HR\Emails\Recruitment\Application\ApplicationHandover;
use Modules\HR\Emails\Recruitment\Application\JobChanged;
use Modules\HR\Emails\Recruitment\Application\RoundNotConducted;
use Modules\HR\Entities\ApplicantMeta;
use Modules\HR\Entities\Application;
use Modules\HR\Entities\ApplicationMeta;
use Modules\HR\Entities\ApplicationRound;
use Modules\HR\Entities\Job;
use Modules\HR\Entities\Round;
use Modules\HR\Entities\University;
use Modules\HR\Http\Requests\Recruitment\ApplicationRequest;
use Modules\HR\Http\Requests\Recruitment\CustomApplicationMailRequest;
use Modules\HR\Http\Requests\TeamInteractionRequest;
Expand Down Expand Up @@ -54,116 +47,9 @@ public function markInterviewFinished(Request $request)
*/
public function index()
{
$referer = request()->headers->get('referer');
$applicationType = $this->getApplicationType();

// We need this so that we can redirect user to the older page number.
// we can improve this logic in the future.

if (! session()->get('should_skip_page') && Str::endsWith($referer, 'edit')) {
session()->put(['should_skip_page' => true]);

return redirect()->route(request()->route()->getName(), session()->get('previous_application_data'))->with('status', session()->get('status'));
}

session()->put([
'previous_application_data' => request()->all(),
'should_skip_page' => false,
]);

//#TO DO: Move this logic to application service.
$filters = [
'status' => request()->get('status') ?: 'non-rejected',
'job-type' => $this->getApplicationType(),
'job' => request()->get('hr_job_id'),
'university' => request()->get('hr_university_id'),
'graduation_year' => request()->get('end-year'),
// 'sortby' => request()->get('sort_by'), Commenting, as we need to brainstorm on this feature a bit
'search' => request()->get('search'),
'tags' => request()->get('tags'),
'assignee' => request()->get('assignee'), // TODO
'round' => str_replace('-', ' ', request()->get('round')),
'roundFilters' => request()->get('roundFilters'),
];
$loggedInUserId = auth()->id();
$applications = Application::select('hr_applications.*')
->join('hr_application_round', function ($join) {
$join->on('hr_application_round.hr_application_id', '=', 'hr_applications.id')
->where('hr_application_round.is_latest', true);
})
->with(['applicant', 'job', 'tags', 'latestApplicationRound'])
->whereHas('latestApplicationRound')
->applyFilter($filters)
->orderByRaw("FIELD(hr_application_round.scheduled_person_id, {$loggedInUserId} ) DESC")
->orderByRaw('ISNULL(hr_application_round.scheduled_date) ASC')
->orderByRaw('hr_application_round.scheduled_date ASC')
->latest()
->paginate(config('constants.pagination_size'))
->appends(request()->except('page'));
$countFilters = array_except($filters, ['status', 'round']);
$attr = [
'applications' => $applications,
'status' => request()->get('status'),
];
$hrRounds = ['Resume Screening', 'Telephonic Interview', 'Introductory Call', 'Basic Technical Round', 'Detailed Technical Round', 'Team Interaction Round', 'HR Round', 'Trial Program', 'Volunteer Screening'];
$strings = array_pluck(config('constants.hr.status'), 'label');
$hrRoundsCounts = [];

foreach ($strings as $string) {
$attr[camel_case($string) . 'ApplicationsCount'] = Application::applyFilter($countFilters)
->where('status', $string)
->whereHas('latestApplicationRound', function ($subQuery) {
return $subQuery->where('is_latest', true);
})
->count();
}

$jobType = $this->getApplicationType();

foreach ($hrRounds as $round) {
$applicationCount = Application::query()->filterByJobType($jobType)
->whereIn('hr_applications.status', ['in-progress', 'new', 'trial-program'])
->FilterByRoundName($round)
->count();
$hrRoundsCounts[$round] = $applicationCount;
$attr[camel_case($round) . 'Count'] = Application::applyFilter($countFilters)
->where('status', config('constants.hr.status.in-progress.label'))
->whereHas('latestApplicationRound', function ($subQuery) use ($round) {
return $subQuery->where('is_latest', true)
->whereHas('round', function ($subQuery) use ($round) {
return $subQuery->where('name', $round);
});
})
->count();
}

$attr['jobs'] = Job::all();
$attr['universities'] = University::all();
$attr['tags'] = Tag::orderBy('name')->get();
$attr['rounds'] = $hrRoundsCounts;
$attr['roundFilters'] = round::orderBy('name')->get();
$attr['assignees'] = User::whereHas('roles', function ($query) {
$query->whereIn('name', ['super-admin', 'admin', 'hr-manager']);
})->orderby('name', 'asc')->get();

$openApplicationCountForJob = Application::whereIn('hr_job_id', $applications->pluck('hr_job_id'))
->isOpen()
->selectRaw('hr_job_id, COUNT(*) as count')
->groupBy('hr_job_id')
->get()
->keyBy('hr_job_id')
->toArray();

foreach ($applications->items() as $application) {
$attr['openApplicationsCountForJobs'][$application->job->title] = $openApplicationCountForJob[$application->hr_job_id]['count'] ?? 0;
}

$attr['applicantId'] = [];
$applications = Application::pluck('hr_applicant_id');
$applicantData = ApplicantMeta::whereIn('hr_applicant_id', $applications)->get();

foreach ($applicantData as $data) {
$attr['applicantId'][$data->hr_applicant_id] = $data;
}
$attr = $this->service->index($applicationType);

return view('hr.application.index')->with($attr);
}
Expand All @@ -175,47 +61,9 @@ public function index()
*/
public function edit($id)
{
//TODO: We need to refactor the edit code and write it in the service
$application = Application::findOrFail($id);

if ($application->latestApplicationRound->hr_round_id == 1) {
$application->latestApplicationRound->scheduled_date = today()->toDateString();
$application->latestApplicationRound->scheduled_end = today()->toDateString();
$application->latestApplicationRound->scheduled_person_id = auth()->id();
$application->latestApplicationRound->save();
}

$application->load(['evaluations', 'evaluations.evaluationParameter', 'evaluations.evaluationOption', 'job', 'job.rounds', 'job.rounds.evaluationParameters', 'job.rounds.evaluationParameters.options', 'applicant', 'applicant.applications', 'applicationRounds', 'applicationRounds.evaluations', 'applicationRounds.round', 'applicationMeta', 'applicationRounds.followUps', 'tags']);
$job = $application->job;
$approveMailTemplate = Setting::getApplicationApprovedEmail();
$approveMailTemplate = str_replace('|APPLICANT NAME|', $application->applicant->name, $approveMailTemplate);
$approveMailTemplate = str_replace('|JOB TITLE|', $application->job->title, $approveMailTemplate);
$approveMailTemplate = str_replace('|LINK|', config('app.url') . '/viewForm/' . $application->applicant->id . '/' . encrypt($application->applicant->email), $approveMailTemplate);

$offerLetterTemplate = Setting::getOfferLetterTemplate();
$desiredResume = DB::table('hr_applications')->select(['hr_applications.resume'])->where('hr_applications.hr_job_id', '=', $job->id)->where('is_desired_resume', '=', 1)->get();
$attr = [
'applicant' => $application->applicant,
'application' => $application,
'timeline' => $application->applicant->timeline(),
'interviewers' => User::interviewers()->orderBy('name')->get(),
'applicantOpenApplications' => $application->applicant->openApplications(),
'applicationFormDetails' => $application->applicationMeta()->formData()->first(),
'offer_letter' => $application->offer_letter,
'approveMailTemplate' => $approveMailTemplate,
'offerLetterTemplate' => $offerLetterTemplate,
'desiredResume' => $desiredResume,
'settings' => [
'noShow' => Setting::getNoShowEmail(),
],
'type' => config("constants.hr.opportunities.{$job->type}.type"),
'universities' => University::orderBy('name')->get(),
];

if ($job->type == 'job') {
$attr['hasGraduated'] = $application->applicant->hasGraduated();
$attr['internships'] = Job::isInternship()->latest()->get();
}
$attr = $this->service->edit($application);

return view('hr.application.edit')->with($attr);
}
Expand Down
131 changes: 114 additions & 17 deletions Modules/HR/Services/ApplicationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,66 @@

namespace Modules\HR\Services;

use App\Models\Setting;
use App\Models\Tag;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Module;
use Illuminate\Support\Str;
use Modules\HR\Contracts\ApplicationServiceContract;
use Modules\HR\Entities\Applicant;
use Modules\HR\Entities\ApplicantMeta;
use Modules\HR\Entities\Application;
use Modules\HR\Entities\Job;
use Modules\HR\Entities\Round;
use Modules\HR\Entities\University;
use Modules\HR\Events\CustomMailTriggeredForApplication;
use Modules\User\Entities\User;

class ApplicationService implements ApplicationServiceContract
{
public function index($applicationType)
{
$referer = request()->headers->get('referer');

if (! session()->get('should_skip_page') && Str::endsWith($referer, 'edit')) {
session()->put(['should_skip_page' => true]);

return redirect()->route(request()->route()->getName(), session()->get('previous_application_data'))->with('status', session()->get('status'));
}

session()->put([
'previous_application_data' => request()->all(),
'should_skip_page' => false,
]);

$filters = [
'status' => request()->get('status') ?: 'non-rejected',
'job-type' => $applicationType,
'job' => request()->get('hr_job_id'),
'university' => request()->get('hr_university_id'),
'graduation_year' => request()->get('end-year'),
// 'sortby' => request()->get('sort_by'), Commenting, as we need to brainstorm on this feature a bit
'search' => request()->get('search'),
'tags' => request()->get('tags'),
'assignee' => request()->get('assignee'), // TODO
'round' => str_replace('-', ' ', request()->get('round')),
'roundFilters' => request()->get('roundFilters'),
];

$loggedInUserId = auth()->id();
$applications = Application::join('hr_application_round', function ($join) {
$join->on('hr_application_round.hr_application_id', '=', 'hr_applications.id')
->where('hr_application_round.is_latest', true);
})
$applications = Application::select('hr_applications.*')
->join('hr_application_round', function ($join) {
$join->on('hr_application_round.hr_application_id', '=', 'hr_applications.id')
->where('hr_application_round.is_latest', true);
})
->with(['applicant', 'job', 'tags', 'latestApplicationRound'])
->whereHas('latestApplicationRound')
->applyFilter($filters)
->orderByRaw("FIELD(hr_application_round.scheduled_person_id, {$loggedInUserId} ) DESC")
->orderByRaw('ISNULL(hr_application_round.scheduled_date) ASC')
->orderByRaw('hr_application_round.scheduled_date ASC')
->select('hr_applications.*')
->latest()
->paginate(config('constants.pagination_size'))
->appends(request()->except('page'));
Expand All @@ -49,6 +71,8 @@ public function index($applicationType)
'status' => request()->get('status'),
];
$hrRounds = ['Resume Screening', 'Telephonic Interview', 'Introductory Call', 'Basic Technical Round', 'Detailed Technical Round', 'Team Interaction Round', 'HR Round', 'Trial Program', 'Volunteer Screening'];
$strings = array_pluck(config('constants.hr.status'), 'label');
$hrRoundsCounts = [];
$strings = array_pluck(config('hr.status'), 'label');

foreach ($strings as $string) {
Expand All @@ -60,9 +84,16 @@ public function index($applicationType)
->count();
}

$jobType = $applicationType;

foreach ($hrRounds as $round) {
$applicationCount = Application::query()->filterByJobType($jobType)
->whereIn('hr_applications.status', ['in-progress', 'new', 'trial-program'])
->FilterByRoundName($round)
->count();
$hrRoundsCounts[$round] = $applicationCount;
$attr[camel_case($round) . 'Count'] = Application::applyFilter($countFilters)
->where('status', config('hr.status.in-progress.label'))
->where('status', config('constants.hr.status.in-progress.label'))
->whereHas('latestApplicationRound', function ($subQuery) use ($round) {
return $subQuery->where('is_latest', true)
->whereHas('round', function ($subQuery) use ($round) {
Expand All @@ -73,10 +104,76 @@ public function index($applicationType)
}

$attr['jobs'] = Job::all();
$attr['universities'] = University::all();
$attr['tags'] = Tag::orderBy('name')->get();
$attr['rounds'] = $hrRoundsCounts;
$attr['roundFilters'] = round::orderBy('name')->get();
$attr['assignees'] = User::whereHas('roles', function ($query) {
$query->whereIn('name', ['super-admin', 'admin', 'hr-manager']);
})->orderby('name', 'asc')->get();

$openApplicationCountForJob = Application::whereIn('hr_job_id', $applications->pluck('hr_job_id'))
->isOpen()
->selectRaw('hr_job_id, COUNT(*) as count')
->groupBy('hr_job_id')
->get()
->keyBy('hr_job_id')
->toArray();

foreach ($applications->items() as $application) {
$attr['openApplicationsCountForJobs'][$application->job->title] = $openApplicationCountForJob[$application->hr_job_id]['count'] ?? 0;
}

if (Module::has('User')) {
$attr['assignees'] = User::orderBy('name')->get();
$attr['applicantId'] = [];
$applications = Application::pluck('hr_applicant_id');
$applicantData = ApplicantMeta::whereIn('hr_applicant_id', $applications)->get();

foreach ($applicantData as $data) {
$attr['applicantId'][$data->hr_applicant_id] = $data;
}

return $attr;
}

public function edit($application)
{
if ($application->latestApplicationRound->hr_round_id == 1) {
$application->latestApplicationRound->scheduled_date = today()->toDateString();
$application->latestApplicationRound->scheduled_end = today()->toDateString();
$application->latestApplicationRound->scheduled_person_id = auth()->id();
$application->latestApplicationRound->save();
}

$application->load(['evaluations', 'evaluations.evaluationParameter', 'evaluations.evaluationOption', 'job', 'job.rounds', 'job.rounds.evaluationParameters', 'job.rounds.evaluationParameters.options', 'applicant', 'applicant.applications', 'applicationRounds', 'applicationRounds.evaluations', 'applicationRounds.round', 'applicationMeta', 'applicationRounds.followUps', 'tags']);
$job = $application->job;
$approveMailTemplate = Setting::getApplicationApprovedEmail();
$approveMailTemplate = str_replace('|APPLICANT NAME|', $application->applicant->name, $approveMailTemplate);
$approveMailTemplate = str_replace('|JOB TITLE|', $application->job->title, $approveMailTemplate);
$approveMailTemplate = str_replace('|LINK|', config('app.url') . '/viewForm/' . $application->applicant->id . '/' . encrypt($application->applicant->email), $approveMailTemplate);

$offerLetterTemplate = Setting::getOfferLetterTemplate();
$desiredResume = DB::table('hr_applications')->select(['hr_applications.resume'])->where('hr_applications.hr_job_id', '=', $job->id)->where('is_desired_resume', '=', 1)->get();
$attr = [
'applicant' => $application->applicant,
'application' => $application,
'timeline' => $application->applicant->timeline(),
'interviewers' => User::interviewers()->orderBy('name')->get(),
'applicantOpenApplications' => $application->applicant->openApplications(),
'applicationFormDetails' => $application->applicationMeta()->formData()->first(),
'offer_letter' => $application->offer_letter,
'approveMailTemplate' => $approveMailTemplate,
'offerLetterTemplate' => $offerLetterTemplate,
'desiredResume' => $desiredResume,
'settings' => [
'noShow' => Setting::getNoShowEmail(),
],
'type' => config("constants.hr.opportunities.{$job->type}.type"),
'universities' => University::orderBy('name')->get(),
];

if ($job->type == 'job') {
$attr['hasGraduated'] = $application->applicant->hasGraduated();
$attr['internships'] = Job::isInternship()->latest()->get();
}

return $attr;
Expand Down Expand Up @@ -123,15 +220,15 @@ public function addSubscriberToCampaigns($parameters, $subscriptionLists)

Http::withHeaders([
'Accept' => 'application/json',
'Content-Type'=>'application/json',
'Content-Type' => 'application/json',
])
->withToken($token)
->post($url, [
'name' => $name,
'email' => $parameters['email'],
'phone' => $parameters['phone'],
'subscription_lists' => $subscriptionLists,
]);
->withToken($token)
->post($url, [
'name' => $name,
'email' => $parameters['email'],
'phone' => $parameters['phone'],
'subscription_lists' => $subscriptionLists,
]);
}

public function getToken()
Expand Down
Loading