File "StudentsImport.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Imports/StudentsImport.php
File size: 10.83 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Imports;
use App\Jobs\SendBulkStudentEmail;
use App\Repositories\FormField\FormFieldsInterface;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Repositories\Student\StudentInterface;
use App\Repositories\Subscription\SubscriptionInterface;
use App\Repositories\User\UserInterface;
use App\Rules\TrimmedEnum;
use App\Services\CachingService;
use App\Services\ResponseService;
use App\Services\SchoolDataService;
use App\Services\UserService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Validator;
use JsonException;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Str;
use Throwable;
use TypeError;
class StudentsImport implements WithMultipleSheets
{
private mixed $classSectionID;
private mixed $sessionYearID;
private mixed $is_send_notification;
public function __construct($classSectionID, $sessionYearID, $is_send_notification)
{
$this->classSectionID = $classSectionID;
$this->sessionYearID = $sessionYearID;
$this->is_send_notification = $is_send_notification;
}
/**
* @throws Throwable
*/
public function sheets(): array
{
return [
new FirstSheetImport($this->classSectionID, $this->sessionYearID, $this->is_send_notification)
];
}
}
class FirstSheetImport implements ToCollection, WithHeadingRow
{
private mixed $classSectionID;
private mixed $sessionYearID;
private mixed $is_send_notification;
/**
* @param $classSectionID
* @param $sessionYearID
* @param $is_send_notification
*/
// Import the Class Section and Repositories
public function __construct($classSectionID, $sessionYearID, $is_send_notification)
{
$this->classSectionID = $classSectionID;
$this->sessionYearID = $sessionYearID;
$this->is_send_notification = $is_send_notification;
}
/**
* @throws JsonException
* @throws Throwable
*/
public function collection(Collection $collection)
{
$student = app(StudentInterface::class);
$formFields = app(FormFieldsInterface::class);
$sessionYear = app(SessionYearInterface::class);
$subscription = app(SubscriptionInterface::class);
$user = app(UserInterface::class);
$cache = app(CachingService::class);
// $collection->toArray(); if getting null first_name then skip after that row
$collection = $collection->filter(function ($row) {
return $row['first_name'] != '';
});
$validator = Validator::make($collection->toArray(), [
'*.first_name' => 'required',
'*.last_name' => 'required',
'*.mobile' => 'nullable|regex:/^([0-9\s\-\+\(\)]*)$/',
'*.gender' => ['required', new TrimmedEnum(['male', 'female', 'Male', 'Female']), 'regex:/^(male|female)$/i'],
'*.guardian_gender' => ['required', 'regex:/^(male|female)$/i'],
'*.dob' => 'required|date',
'*.admission_date' => 'required|date',
'*.current_address' => 'required',
'*.permanent_address' => 'required',
'*.guardian_email' => 'required|email',
'*.guardian_first_name' => 'required',
'*.guardian_last_name' => 'required',
'*.guardian_mobile' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/',
], [
'*.first_name.required' => 'Please enter the first name.',
'*.last_name.required' => 'Please enter the last name.',
'*.mobile.required' => 'Please enter the mobile number.',
'*.gender.required' => 'Please select the gender.',
'*.gender.regex' => 'Gender must be either Male or Female only.',
'*.guardian_gender.required' => 'Please select the gender.',
'*.guardian_gender.regex' => 'Guardian gender must be either Male or Female only.',
'*.dob.date' => 'Please ensure that the dob date format you use is either DD-MM-YYYY or MM/DD/YYYY.',
'*.admission_date.date' => 'Please ensure that the admission date format you use is either DD-MM-YYYY or MM/DD/YYYY.',
'*.guardian_email.required' => 'Please enter the guardian email.',
'*.guardian_email.email' => 'Please enter a valid email address.',
'*.guardian_first_name.required' => 'Please enter the guardian first name.',
'*.guardian_last_name.required' => 'Please enter the guardian last name.',
'*.guardian_mobile.required' => 'Please enter the guardian mobile number.',
]);
// If Validation fails then this will throw the ValidationFail Exception
$validator->validate();
// Check free trial package
$today_date = Carbon::now()->format('Y-m-d');
$get_subscription = $subscription->builder()->doesntHave('subscription_bill')->whereDate('start_date', '<=', $today_date)->where('end_date', '>=', $today_date)->whereHas('package', function ($q) {
$q->where('is_trial', 1);
})->first();
$userService = app(UserService::class);
$sessionYear = $sessionYear->findById($this->sessionYearID);
DB::beginTransaction();
foreach ($collection as $row) {
// Check free trial package
if ($get_subscription) {
$systemSettings = $cache->getSystemSettings();
$count_student = $user->builder()->role('Student')->withTrashed()->count();
if ($count_student >= $systemSettings['student_limit']) {
$message = "The free trial allows only " . $systemSettings['student_limit'] . " students.";
ResponseService::errorResponse($message);
break;
}
}
$row = $row->toArray();
// Find the index of the key after which to split the array
$splitIndex = array_search('guardian_mobile', array_keys($row)) + 1;
// Get The Extra Details of it
$extraDetailsFields = array_slice($row, $splitIndex);
$guardian = $userService->createOrUpdateParent($row['guardian_first_name'], $row['guardian_last_name'], $row['guardian_email'], $row['guardian_mobile'], $row['guardian_gender']);
// $get_student = $student->builder()->select('user_id')->orderBy('id', 'desc')->first();
// $admission_no = $sessionYear->name . '0' . Auth::user()->school_id . '0' . ($get_student->user_id + 1);
if (!$guardian) {
ResponseService::errorResponse('Email address is already associated with another role. Please use a different email and try again.');
}
// Generate unique uuid
$admission_no = null;
do {
$uuid = mt_rand(100000000, 999999999);
$admission_no = $sessionYear->name . '' . Auth::user()->school_id . '' . $uuid;
} while ($student->builder()->where('admission_no', $admission_no)->exists()); // Check uniqueness;
$extraDetails = array();
// Check that Extra Details Exists
if (!empty($extraDetailsFields)) {
$extraFieldName = array_map(static function ($d) {
return str_replace("_", " ", $d);
}, array_keys($extraDetailsFields));
$formFieldsCollection = $formFields->builder()->whereIn('name', $extraFieldName)->get();
$extraFieldValidationRules = [];
foreach ($formFieldsCollection as $field) {
if ($field->is_required) {
$name = strtolower(str_replace(' ', '_', $field->name));
$extraFieldValidationRules[$name] = 'required';
}
}
$extraFieldValidator = Validator::make($row, $extraFieldValidationRules);
$extraFieldValidator->validate();
// Create Extra Details Array for Student's Extra Form Details
foreach ($extraDetailsFields as $key => $value) {
$formField = $formFieldsCollection->first(function ($data) use ($key) {
return strtolower($data->name) === str_replace("_", " ", $key);
});
if (!empty($formField)) {
// if Form Field is checkbox then make data in json format
$data = $formField->type == 'checkbox' ? explode(',', $value) : $value;
$extraDetails[] = array(
'input_type' => $formField->type,
'form_field_id' => $formField->id,
'data' => (is_array($data)) ? json_encode($data, JSON_THROW_ON_ERROR) : $data
);
}
}
// Make File Input Array to Store the Null Values
$getFileExtraField = $formFields->builder()->where('type', 'file')->get();
foreach ($getFileExtraField as $value) {
$extraDetails[] = array(
'input_type' => 'file',
'form_field_id' => $value->id,
'data' => NULL,
);
}
}
try {
$studentUser = $userService->createStudentUser(
$row['first_name'],
$row['last_name'],
$admission_no,
$row['mobile'],
$row['dob'],
$row['gender'],
null,
$this->classSectionID,
$row['admission_date'],
$row['current_address'],
$row['permanent_address'],
$sessionYear->id,
$guardian->id,
$extraDetails,
0,
false
);
if ($this->is_send_notification) {
SendBulkStudentEmail::dispatch(Auth::user()->school_id, $studentUser->id);
}
} catch (Throwable $e) {
// IF Exception is TypeError and message contains Mail keywords then email is not sent successfully
if ($e instanceof TypeError && Str::contains($e->getMessage(), [
'Mail',
'Mailer',
'MailManager'
])) {
continue;
}
DB::rollBack();
throw $e;
}
}
DB::commit();
return true;
}
}