├── public
├── favicon.ico
├── robots.txt
├── example
│ ├── attendance_format_1.txt
│ └── attendance_format_2.txt
├── web.config
├── index.php
└── svg
│ ├── 404.svg
│ ├── 503.svg
│ ├── 403.svg
│ └── 500.svg
├── screenshot
├── home.png
├── id-2.png
├── id1.png
├── list.png
├── ce
│ ├── menu.png
│ ├── dashboard.png
│ └── profile-st.png
├── grade.png
├── rules.png
├── marksheet.jpg
├── attendance.jpg
└── site-dashboard.png
├── tests
├── TestCase.php
├── Unit
│ └── ExampleTest.php
├── Feature
│ └── ExampleTest.php
└── CreatesApplication.php
├── app
├── AboutSlider.php
├── AppMeta.php
├── Grade.php
├── AcademicCalendar.php
├── AcademicYear.php
├── AttendanceFileQueue.php
├── ClassProfile.php
├── Event.php
├── AboutContent.php
├── Exam.php
├── Console
│ ├── Kernel.php
│ └── Commands
│ │ ├── SeedEmployeeAttendance.php
│ │ └── SeedStudentAttendance.php
├── ExamRule.php
├── EmployeeAttendance.php
├── Exceptions
│ └── Handler.php
├── Employee.php
└── Http
│ └── Controllers
│ └── Backend
│ └── AcademicController.php
├── bin
└── cloudschool-worker.conf
├── .gitignore
├── database
├── factories
│ ├── WorkousideFactory.php
│ ├── UserFactory.php
│ ├── LeaveFactory.php
│ ├── ExamFactory.php
│ ├── SectionFactory.php
│ ├── SubjectFactory.php
│ ├── StudentFactory.php
│ └── TeacherFactory.php
└── migrations
│ ├── 2018_03_05_000005_create_password_resets_table.php
│ ├── 2018_03_04_000000_create_roles_table.php
│ ├── 2018_07_08_110923_create_site_metas_table.php
│ ├── 2018_08_11_092832_create_app_metas_table.php
│ ├── 2018_03_05_000002_create_permissions_table.php
│ ├── 2018_07_11_035714_create_testimonials_table.php
│ ├── 2018_08_11_121754_create_academic_years_table.php
│ ├── 2018_06_09_065945_create_sliders_table.php
│ ├── 2018_03_05_000001_create_user_roles_table.php
│ ├── 2018_07_14_155755_create_teacher_profiles_table.php
│ ├── 2018_03_05_000003_create_users_permissions_table.php
│ ├── 2018_03_05_000004_create_roles_permissions_table.php
│ ├── 2018_03_05_000000_create_users_table.php
│ ├── 2018_07_14_180514_create_events_table.php
│ ├── 2018_07_14_115139_create_class_profiles_table.php
│ └── 2018_07_06_103920_create_about_content_tables.php
├── routes
├── channels.php
├── api.php
├── console.php
├── website.php
└── web.php
├── server.php
├── phpunit.xml
├── .env.example
├── webpack.frontend.mix.js
├── config
├── hashing.php
├── broadcasting.php
├── filesystems.php
├── cache.php
├── logging.php
├── auth.php
├── database.php
└── app.php
├── bootstrap
└── app.php
├── artisan
├── package.json
├── webpack.backend.mix.js
├── composer.json
└── readme.md
/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/screenshot/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/home.png
--------------------------------------------------------------------------------
/screenshot/id-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/id-2.png
--------------------------------------------------------------------------------
/screenshot/id1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/id1.png
--------------------------------------------------------------------------------
/screenshot/list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/list.png
--------------------------------------------------------------------------------
/screenshot/ce/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/ce/menu.png
--------------------------------------------------------------------------------
/screenshot/grade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/grade.png
--------------------------------------------------------------------------------
/screenshot/rules.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/rules.png
--------------------------------------------------------------------------------
/screenshot/marksheet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/marksheet.jpg
--------------------------------------------------------------------------------
/screenshot/attendance.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/attendance.jpg
--------------------------------------------------------------------------------
/screenshot/ce/dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/ce/dashboard.png
--------------------------------------------------------------------------------
/screenshot/ce/profile-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/ce/profile-st.png
--------------------------------------------------------------------------------
/screenshot/site-dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hindhuja-V/school-management/HEAD/screenshot/site-dashboard.png
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/bin/cloudschool-worker.conf:
--------------------------------------------------------------------------------
1 | [program:cloudschool-worker]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=php /home/hbot/www/public_html/sms/artisan queue:work --tries=3 --sleep=3 --queue=default,commands,absent,sms,email
4 | autostart=true
5 | autorestart=true
6 | user=www-data
7 | numprocs=3
8 | redirect_stderr=true
9 | stdout_logfile=/home/hbot/www/public_html/sms/storage/logs/cloudschool-worker.log
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /public/hot
3 | /public/storage
4 | /public/css
5 | /public/js
6 | /public/fonts
7 | /public/images
8 | /public/frontend
9 | /public/mix-manifest.json
10 | /storage/*.key
11 | /vendor
12 | /.idea
13 | /.vscode
14 | /.vagrant
15 | Homestead.json
16 | Homestead.yaml
17 | npm-debug.log
18 | yarn-error.log
19 | yarn.lock
20 | .env
21 | storage/debugbar
22 | database/seeds/DevPermissionTableSeeder.php
23 |
--------------------------------------------------------------------------------
/tests/Feature/ExampleTest.php:
--------------------------------------------------------------------------------
1 | get('/');
18 |
19 | $response->assertStatus(200);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/AppMeta.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
19 |
20 | return $app;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/AcademicCalendar.php:
--------------------------------------------------------------------------------
1 | define(App\WorkOutside::class, function (Faker $faker) {
6 | return [
7 | 'employee_id' => function () {
8 | // Get random teacher id
9 | return App\Employee::inRandomOrder()->first()->id;
10 | },
11 | 'work_date' => $faker->dateTimeThisMonth($max = 'now', $timezone = "Asia/Dhaka")->format('d/m/Y'),
12 | 'document' => null,
13 | 'description' => $faker->sentence,
14 | ];
15 | });
16 |
--------------------------------------------------------------------------------
/database/factories/UserFactory.php:
--------------------------------------------------------------------------------
1 | define(App\User::class, function (Faker $faker) {
7 | return [
8 | 'name' => $faker->name,
9 | 'username' => $faker->unique()->userName,
10 | 'email' => $faker->unique()->safeEmail,
11 | 'password' => bcrypt('demo123'),
12 | 'status' => '1',
13 | 'force_logout' => 0,
14 | 'remember_token' => Str::random(10),
15 | 'created_by' => 1,
16 | 'created_at' => now()
17 | ];
18 | });
19 |
--------------------------------------------------------------------------------
/routes/channels.php:
--------------------------------------------------------------------------------
1 | id === (int) $id;
16 | });
17 |
--------------------------------------------------------------------------------
/app/AcademicYear.php:
--------------------------------------------------------------------------------
1 | get('/user', function (Request $request) {
17 | return $request->user();
18 | });
19 |
--------------------------------------------------------------------------------
/database/factories/LeaveFactory.php:
--------------------------------------------------------------------------------
1 | define(App\Leave::class, function (Faker $faker) {
6 | return [
7 | 'employee_id' => function () {
8 | // Get random teacher id
9 | return App\Employee::inRandomOrder()->first()->id;
10 | },
11 | 'leave_type' => rand(1,2),
12 | 'leave_date' => $faker->dateTimeThisMonth($max = 'now', $timezone = "Asia/Dhaka")->format('d/m/Y'),
13 | 'document' => null,
14 | 'description' => $faker->sentence,
15 | 'status' => rand(1,3)
16 | ];
17 | });
18 |
--------------------------------------------------------------------------------
/app/AttendanceFileQueue.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
18 | })->describe('Display an inspiring quote');
19 |
--------------------------------------------------------------------------------
/database/factories/ExamFactory.php:
--------------------------------------------------------------------------------
1 | define(App\Exam::class, function (Faker $faker) {
6 | return [
7 | 'name' => $faker->sentence($nbWords = 3, $variableNbWords = true),
8 | 'elective_subject_point_addition' => rand(0,2),
9 | 'marks_distribution_types' => json_encode(array_rand(\App\Http\Helpers\AppHelper::MARKS_DISTRIBUTION_TYPES, 3)),
10 | 'class_id' => function () {
11 | // Get random class id
12 | return App\IClass::where('id','!=',1)->inRandomOrder()->first()->id;
13 | },
14 | 'status' => '1',
15 | ];
16 | });
17 |
--------------------------------------------------------------------------------
/server.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 |
10 | $uri = urldecode(
11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
12 | );
13 |
14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the
15 | // built-in PHP web server. This provides a convenient way to test a Laravel
16 | // application without having installed a "real" web server software here.
17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
18 | return false;
19 | }
20 |
21 | require_once __DIR__.'/public/index.php';
22 |
--------------------------------------------------------------------------------
/database/factories/SectionFactory.php:
--------------------------------------------------------------------------------
1 | define(App\Section::class, function (Faker $faker) {
6 |
7 | return [
8 | 'name' => strtoupper($faker->unique()->randomLetter),
9 | 'capacity' => rand(20,40),
10 | 'class_id' => function(){
11 | return App\IClass::where('id','!=',1)->inRandomOrder()->first()->id;
12 | },
13 | 'teacher_id' => function () {
14 | // Get random teacher id
15 | return App\Employee::where('role_id', \App\Http\Helpers\AppHelper::USER_TEACHER)->inRandomOrder()->first()->id;
16 | },
17 | 'note' => $faker->sentence,
18 | 'status' => '1',
19 | ];
20 | });
21 |
--------------------------------------------------------------------------------
/app/ClassProfile.php:
--------------------------------------------------------------------------------
1 | define(App\Subject::class, function (Faker $faker) {
6 | return [
7 | 'name' => $faker->sentence($nbWords = 3, $variableNbWords = true),
8 | 'code' => $faker->unique()->numberBetween($min = 100, $max = 200),
9 | 'type' => rand(1,2),
10 | 'class_id' => function () {
11 | // Get random class id
12 | return App\IClass::where('id','!=',1)->inRandomOrder()->first()->id;
13 | },
14 | 'teacher_id' => function () {
15 | // Get random teacher id
16 | return App\Employee::where('role_id', \App\Http\Helpers\AppHelper::USER_TEACHER)->inRandomOrder()->first()->id;
17 | },
18 | 'status' => '1',
19 | ];
20 | });
21 |
--------------------------------------------------------------------------------
/app/AboutContent.php:
--------------------------------------------------------------------------------
1 | string('email')->index();
18 | $table->string('token');
19 | $table->timestamp('created_at')->nullable();
20 | });
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | *
26 | * @return void
27 | */
28 | public function down()
29 | {
30 | Schema::dropIfExists('password_resets');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/Exam.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\IClass', 'class_id');
32 | }
33 |
34 | public function scopeIclass($query, $classId)
35 | {
36 | if($classId){
37 | return $query->where('class_id', $classId);
38 | }
39 |
40 | return $query;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/database/migrations/2018_03_04_000000_create_roles_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name')->unique();
19 | $table->boolean('deletable')->default(true);
20 | $table->timestamps();
21 | $table->softDeletes();
22 | $table->userstamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | *
29 | * @return void
30 | */
31 | public function down()
32 | {
33 | Schema::dropIfExists('roles');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/database/migrations/2018_07_08_110923_create_site_metas_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('meta_key');
19 | $table->longText('meta_value');
20 | $table->timestamps();
21 | $table->softDeletes();
22 | $table->userstamps();
23 |
24 | });
25 | }
26 |
27 | /**
28 | * Reverse the migrations.
29 | *
30 | * @return void
31 | */
32 | public function down()
33 | {
34 | Schema::dropIfExists('site_metas');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/database/migrations/2018_08_11_092832_create_app_metas_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('meta_key');
19 | $table->longText('meta_value')->nullable();
20 | $table->timestamps();
21 | $table->softDeletes();
22 | $table->userstamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | *
29 | * @return void
30 | */
31 | public function down()
32 | {
33 | Schema::dropIfExists('app_metas');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/public/example/attendance_format_2.txt:
--------------------------------------------------------------------------------
1 | 197001 2019-01-18 07:38:22 102 4 197001 I 0 1
2 | 197002 2019-01-18 07:44:17 102 4 197002 I 0 1
3 | 197003 2019-01-18 07:44:34 102 4 197003 I 0 1
4 | 197004 2019-01-18 07:45:02 102 4 197004 I 0 1
5 | 197005 2019-01-18 07:45:57 102 4 197005 I 0 1
6 | 197006 2019-01-18 07:56:48 102 4 197006 I 0 1
7 | 197007 2019-01-18 08:06:34 102 4 197007 I 0 1
8 | 197008 2019-01-18 08:06:44 102 4 197008 I 0 1
9 | 197009 2019-01-18 09:11:45 102 4 197009 I 0 1
10 | 197010 2019-01-18 09:12:22 102 4 197010 I 0 1
--------------------------------------------------------------------------------
/public/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')
28 | // ->hourly();
29 | }
30 |
31 | /**
32 | * Register the commands for the application.
33 | *
34 | * @return void
35 | */
36 | protected function commands()
37 | {
38 | $this->load(__DIR__.'/Commands');
39 |
40 | require base_path('routes/console.php');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/database/migrations/2018_03_05_000002_create_permissions_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('slug'); //route name [user.create]
19 | $table->string('name'); // Readable Name [User Create]
20 | $table->string('group')->nullable(); // Group name [site, user, system user]
21 | $table->timestamp("created_at")->useCurrent();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('permissions');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2018_07_11_035714_create_testimonials_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('writer');
19 | $table->text('comments');
20 | $table->string('avatar')->nullable();
21 | $table->integer('order')->default(0);
22 | $table->timestamps();
23 | $table->softDeletes();
24 | $table->userstamps();
25 | });
26 | }
27 |
28 | /**
29 | * Reverse the migrations.
30 | *
31 | * @return void
32 | */
33 | public function down()
34 | {
35 | Schema::dropIfExists('testimonials');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/database/migrations/2018_08_11_121754_create_academic_years_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('title');
19 | $table->date('start_date');
20 | $table->date('end_date');
21 | $table->enum('status', [0,1])->default(0);
22 | $table->timestamps();
23 | $table->softDeletes();
24 | $table->userstamps();
25 | });
26 | }
27 |
28 | /**
29 | * Reverse the migrations.
30 | *
31 | * @return void
32 | */
33 | public function down()
34 | {
35 | Schema::dropIfExists('academic_years');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/database/migrations/2018_06_09_065945_create_sliders_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
19 | $table->string('title');
20 | $table->string('subtitle');
21 | $table->string('image');
22 | $table->integer('order')->default(0);
23 | $table->timestamps();
24 | $table->softDeletes();
25 | $table->userstamps();
26 | }
27 | );
28 | }
29 |
30 | /**
31 | * Reverse the migrations.
32 | *
33 | * @return void
34 | */
35 | public function down()
36 | {
37 | Schema::dropIfExists('sliders');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/database/migrations/2018_03_05_000001_create_user_roles_table.php:
--------------------------------------------------------------------------------
1 | unsignedInteger('user_id');
18 | $table->unsignedInteger('role_id');
19 | $table->timestamps();
20 | $table->softDeletes();
21 | $table->userstamps();
22 |
23 | //FOREIGN KEY CONSTRAINTS
24 | $table->foreign('user_id')->references('id')->on('users');
25 | $table->foreign('role_id')->references('id')->on('roles');
26 |
27 |
28 | //SETTING THE PRIMARY KEYS
29 | $table->primary(['user_id','role_id']);
30 |
31 | });
32 | }
33 |
34 | /**
35 | * Reverse the migrations.
36 | *
37 | * @return void
38 | */
39 | public function down()
40 | {
41 | Schema::dropIfExists('user_roles');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/database/factories/StudentFactory.php:
--------------------------------------------------------------------------------
1 | define(App\Student::class, function (Faker $faker) {
6 |
7 | $user = factory(App\User::class)->create();
8 | return [
9 | 'user_id' => $user->id,
10 | 'name' => $faker->name($gender = 'male'|'female'),
11 | 'dob' => $faker->dateTimeBetween($startDate = '-20 years', $endDate = 'now', $timezone = "Asia/Dhaka")->format('d/m/Y'),
12 | 'gender' => rand(1,2),
13 | 'religion' => rand(1,5),
14 | 'blood_group' => rand(1,8),
15 | 'nationality' => substr($faker->country, 0 , 48),
16 | 'photo' => null,
17 | 'email' => $user->email,
18 | 'phone_no' => $faker->e164PhoneNumber,
19 | 'extra_activity' => '',
20 | 'note' => '',
21 | 'father_name' => $faker->name($gender = 'male'),
22 | 'father_phone_no' => $faker->e164PhoneNumber,
23 | 'mother_name' => $faker->name($gender = 'female'),
24 | 'mother_phone_no' => $faker->e164PhoneNumber,
25 | 'guardian' => null,
26 | 'guardian_phone_no' => null,
27 | 'present_address' => $faker->address,
28 | 'permanent_address' => $faker->address,
29 | 'status' => '1',
30 | ];
31 | });
32 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests/Feature
14 |
15 |
16 |
17 | ./tests/Unit
18 |
19 |
20 |
21 |
22 | ./app
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/database/factories/TeacherFactory.php:
--------------------------------------------------------------------------------
1 | define(App\Employee::class, function (Faker $faker) {
6 | $user = factory(App\User::class)->create();
7 | return [
8 | 'user_id' => $user->id,
9 | 'role_id' => \App\Http\Helpers\AppHelper::USER_TEACHER,
10 | 'id_card' => str_pad($faker->unique()->numberBetween($min = 1, $max = 99),10,'0',STR_PAD_LEFT),
11 | 'name' => $faker->name($gender = 'male'|'female'),
12 | 'designation' => $faker->jobTitle,
13 | 'qualification' => $faker->word,
14 | 'dob' => $faker->dateTimeBetween($startDate = '-20 years', $endDate = 'now', $timezone = "Asia/Dhaka")->format('d/m/Y'),
15 | 'gender' => rand(1,2),
16 | 'religion' => rand(1,5),
17 | 'email' => $user->email,
18 | 'phone_no' => $faker->e164PhoneNumber,
19 | 'address' => $faker->address,
20 | 'joining_date' => $faker->dateTimeBetween($startDate = '-5 years', $endDate = 'now', $timezone = "Asia/Dhaka")->format('d/m/Y'),
21 | 'photo' => null,
22 | 'signature' => null,
23 | 'shift' => rand(1,2),
24 | 'duty_start' => '09:00 am',
25 | 'duty_end' => '05:00 pm',
26 | 'status' => '1'
27 | ];
28 | });
29 |
30 |
--------------------------------------------------------------------------------
/database/migrations/2018_07_14_155755_create_teacher_profiles_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name');
19 | $table->string('designation');
20 | $table->string('image')->nullable();
21 | $table->longText('description')->nullable();
22 | $table->longText('qualification')->nullable();
23 | $table->string('facebook')->nullable();
24 | $table->string('google')->nullable();
25 | $table->string('twitter')->nullable();
26 | $table->timestamps();
27 | $table->softDeletes();
28 | $table->userstamps();
29 | });
30 | }
31 |
32 | /**
33 | * Reverse the migrations.
34 | *
35 | * @return void
36 | */
37 | public function down()
38 | {
39 | Schema::dropIfExists('teacher_profiles');
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/database/migrations/2018_03_05_000003_create_users_permissions_table.php:
--------------------------------------------------------------------------------
1 | integer('user_id')->unsigned();
18 | $table->integer('permission_id')->unsigned();
19 | $table->timestamps();
20 | $table->softDeletes();
21 | $table->userstamps();
22 |
23 | //FOREIGN KEY CONSTRAINTS
24 | $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
25 | $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
26 |
27 | //SETTING THE PRIMARY KEYS
28 | // $table->primary(['user_id','permission_id']);
29 | });
30 | }
31 |
32 | /**
33 | * Reverse the migrations.
34 | *
35 | * @return void
36 | */
37 | public function down()
38 | {
39 | Schema::dropIfExists('users_permissions');
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/database/migrations/2018_03_05_000004_create_roles_permissions_table.php:
--------------------------------------------------------------------------------
1 | integer('role_id')->unsigned();
18 | $table->integer('permission_id')->unsigned();
19 | $table->timestamps();
20 | $table->softDeletes();
21 | $table->userstamps();
22 |
23 | //FOREIGN KEY CONSTRAINTS
24 | $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
25 | $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
26 |
27 | // //SETTING THE PRIMARY KEYS
28 | // $table->primary(['role_id','permission_id']);
29 | });
30 | }
31 |
32 | /**
33 | * Reverse the migrations.
34 | *
35 | * @return void
36 | */
37 | public function down()
38 | {
39 | Schema::dropIfExists('roles_permissions');
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/database/migrations/2018_03_05_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
19 | $table->string('name');
20 | $table->string('username')->unique();
21 | $table->string('email')->unique();
22 | $table->string('phone_no',15)->nullable();
23 | $table->string('password');
24 | $table->rememberToken();
25 | $table->boolean('force_logout')->default(0);
26 | $table->enum('status', [0,1])->default(1);
27 | $table->timestamps();
28 | $table->softDeletes();
29 | $table->userstamps();
30 | }
31 | );
32 | }
33 |
34 | /**
35 | * Reverse the migrations.
36 | *
37 | * @return void
38 | */
39 | public function down()
40 | {
41 | Schema::dropIfExists('users');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/ExamRule.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\IClass', 'class_id');
35 | }
36 | public function exam()
37 | {
38 | return $this->belongsTo('App\Exam', 'exam_id');
39 | }
40 |
41 | public function combineSubject()
42 | {
43 | return $this->belongsTo('App\Subject', 'combine_subject_id');
44 | }
45 |
46 | public function subject()
47 | {
48 | return $this->belongsTo('App\Subject', 'subject_id');
49 | }
50 |
51 | public function grade()
52 | {
53 | return $this->belongsTo('App\Grade', 'grade_id');
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/database/migrations/2018_07_14_180514_create_events_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->dateTime('event_time');
19 | $table->string('title');
20 | $table->string('slug',500);
21 | $table->string('cover_photo')->nullable();
22 | $table->string('cover_video')->nullable();
23 | $table->string('tags')->nullable();
24 | $table->longText('description');
25 | $table->string('slider_1')->nullable();
26 | $table->string('slider_2')->nullable();
27 | $table->string('slider_3')->nullable();
28 | $table->timestamps();
29 | $table->softDeletes();
30 | $table->userstamps();
31 | });
32 |
33 | }
34 |
35 | /**
36 | * Reverse the migrations.
37 | *
38 | * @return void
39 | */
40 | public function down()
41 | {
42 | Schema::dropIfExists('events');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/database/migrations/2018_07_14_115139_create_class_profiles_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name');
19 | $table->string('slug',500);
20 | $table->string('image_sm');
21 | $table->string('image_lg');
22 | $table->string('teacher');
23 | $table->string('room_no',50);
24 | $table->integer('capacity');
25 | $table->string('shift');
26 | $table->longText('short_description');
27 | $table->longText('description')->nullable();
28 | $table->longText('outline')->nullable();
29 | $table->timestamps();
30 | $table->softDeletes();
31 | $table->userstamps();
32 | });
33 | }
34 |
35 | /**
36 | * Reverse the migrations.
37 | *
38 | * @return void
39 | */
40 | public function down()
41 | {
42 | Schema::dropIfExists('class_profiles');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # Application Settings
2 |
3 | APP_NAME=CloudSchool
4 | APP_ENV=production
5 | APP_KEY=base64:+m0h+ObGNu26eF4MVCgqX1ua0IukSUn7lRYInflNt8A=
6 | APP_DEBUG=false
7 | APP_URL=http://localhost
8 | APP_TIMEZONE=Asia/Dhaka
9 | APP_LOCALE=en
10 | MAX_RECORD_PER_PAGE= 25
11 | INSTITUTE_CATEGORY=school
12 | CURRENCY_SYMBOL="tk."
13 | DASHBOARD_SECTION_STUDENT_CLASS_CODE=90,91,92,100,101,102
14 |
15 | # Its only for college. value will the the title of the year
16 | DASHBOARD_STUDENT_COUNT_DEFAULT_ACADEMIC_YEAR=2018
17 |
18 | # Website frontend Settings
19 | MAX_RECORD_PER_PAGE_FRONT= 10
20 | GA_TRACK_ID=
21 |
22 |
23 | # DB Settings
24 |
25 | DB_CONNECTION=mysql
26 | DB_HOST=127.0.0.1
27 | DB_PORT=3306
28 | DB_DATABASE=sms_2_0
29 | DB_USERNAME=root
30 | DB_PASSWORD=root
31 |
32 | # Log, Session, Job Queue Settings
33 |
34 | BROADCAST_DRIVER=log
35 | LOG_CHANNEL=stack
36 | CACHE_DRIVER=file
37 | SESSION_DRIVER=file
38 | SESSION_LIFETIME=120
39 | QUEUE_CONNECTION=database
40 |
41 | # Storage Settings
42 |
43 | FILESYSTEM_DRIVER=local
44 |
45 | # Pusher Settings
46 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
47 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
48 |
49 |
50 | # Email Server Settings
51 |
52 | MAIL_DRIVER=smtp
53 | MAIL_HOST=smtp.mailtrap.io
54 | MAIL_PORT=2525
55 | MAIL_USERNAME=
56 | MAIL_PASSWORD=
57 | MAIL_ENCRYPTION=tls
58 |
59 | # website admin email address for recieve contact email
60 |
61 | MAIL_RECEIVER=dev@hrshadhin.me
62 | MAIL_NO_REPLY_ADDRESS=
63 |
64 |
65 | # Deployment settings
66 |
67 | DEVELOPER_MODE_ENABLED=false
--------------------------------------------------------------------------------
/webpack.frontend.mix.js:
--------------------------------------------------------------------------------
1 | let mixFrontend = require('laravel-mix');
2 |
3 | const fullPublicPath = "public/frontend";
4 | const mixManifest = fullPublicPath + '/mix-manifest.json';
5 | /*
6 | |--------------------------------------------------------------------------
7 | | Mix Frontend Asset Management
8 | |--------------------------------------------------------------------------
9 | |
10 | | Mix provides a clean, fluent API for defining some Webpack build steps
11 | | for your Laravel application. By default, we are compiling the Sass
12 | | file for the application as well as bundling up all the JS files.
13 | |
14 | */
15 |
16 | mixFrontend.setPublicPath(fullPublicPath);
17 |
18 | mixFrontend.js('resources/assets/frontend/js/libs.js', 'public/frontend/js')
19 | .sass('resources/assets/frontend/sass/libs.scss', 'public/frontend/css');
20 |
21 |
22 | mixFrontend.options({
23 | processCssUrls: false,
24 | // uglify: {},
25 | purifyCss: false,
26 | // purifyCss: {},
27 | clearConsole: false
28 | });
29 |
30 |
31 | // copy non processing files to public path
32 | mixFrontend.copyDirectory('resources/assets/frontend/libs/jquery.min.js', 'public/frontend/js/jquery.min.js');
33 | mixFrontend.copyDirectory('resources/assets/frontend/img', 'public/frontend/img');
34 | mixFrontend.copyDirectory('resources/assets/frontend/fonts', 'public/frontend/fonts');
35 | mixFrontend.copyDirectory('resources/assets/frontend/flags', 'public/frontend/flags');
36 | mixFrontend.copyDirectory('resources/assets/frontend/rs-plugin', 'public/frontend/rs-plugin');
37 |
38 | if (mixFrontend.inProduction()) {
39 | mixFrontend.version();
40 | mixFrontend.sourceMaps();
41 | }
42 |
43 | mixFrontend.browserSync({
44 | proxy: 'l5.school.test'
45 | });
--------------------------------------------------------------------------------
/config/hashing.php:
--------------------------------------------------------------------------------
1 | 'bcrypt',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Bcrypt Options
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may specify the configuration options that should be used when
26 | | passwords are hashed using the Bcrypt algorithm. This will allow you
27 | | to control the amount of time it takes to hash the given password.
28 | |
29 | */
30 |
31 | 'bcrypt' => [
32 | 'rounds' => env('BCRYPT_ROUNDS', 10),
33 | ],
34 |
35 | /*
36 | |--------------------------------------------------------------------------
37 | | Argon Options
38 | |--------------------------------------------------------------------------
39 | |
40 | | Here you may specify the configuration options that should be used when
41 | | passwords are hashed using the Argon algorithm. These will allow you
42 | | to control the amount of time it takes to hash the given password.
43 | |
44 | */
45 |
46 | 'argon' => [
47 | 'memory' => 1024,
48 | 'threads' => 2,
49 | 'time' => 2,
50 | ],
51 |
52 | ];
53 |
--------------------------------------------------------------------------------
/bootstrap/app.php:
--------------------------------------------------------------------------------
1 | singleton(
30 | Illuminate\Contracts\Http\Kernel::class,
31 | App\Http\Kernel::class
32 | );
33 |
34 | $app->singleton(
35 | Illuminate\Contracts\Console\Kernel::class,
36 | App\Console\Kernel::class
37 | );
38 |
39 | $app->singleton(
40 | Illuminate\Contracts\Debug\ExceptionHandler::class,
41 | App\Exceptions\Handler::class
42 | );
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Return The Application
47 | |--------------------------------------------------------------------------
48 | |
49 | | This script returns the application instance. The instance is given to
50 | | the calling script so we can separate the building of the instances
51 | | from the actual running of the application and sending responses.
52 | |
53 | */
54 |
55 | return $app;
56 |
--------------------------------------------------------------------------------
/config/broadcasting.php:
--------------------------------------------------------------------------------
1 | env('BROADCAST_DRIVER', 'null'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Broadcast Connections
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may define all of the broadcast connections that will be used
26 | | to broadcast events to other systems or over websockets. Samples of
27 | | each available type of connection are provided inside this array.
28 | |
29 | */
30 |
31 | 'connections' => [
32 |
33 | 'pusher' => [
34 | 'driver' => 'pusher',
35 | 'key' => env('PUSHER_APP_KEY'),
36 | 'secret' => env('PUSHER_APP_SECRET'),
37 | 'app_id' => env('PUSHER_APP_ID'),
38 | 'options' => [
39 | 'cluster' => env('PUSHER_APP_CLUSTER'),
40 | 'encrypted' => true,
41 | ],
42 | ],
43 |
44 | 'redis' => [
45 | 'driver' => 'redis',
46 | 'connection' => 'default',
47 | ],
48 |
49 | 'log' => [
50 | 'driver' => 'log',
51 | ],
52 |
53 | 'null' => [
54 | 'driver' => 'null',
55 | ],
56 |
57 | ],
58 |
59 | ];
60 |
--------------------------------------------------------------------------------
/app/EmployeeAttendance.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\Employee', 'employee_id');
39 | }
40 |
41 | public function setAttendanceDateAttribute($value)
42 | {
43 | $this->attributes['attendance_date'] = Carbon::createFromFormat('d/m/Y', $value)->format('Y-m-d');
44 | }
45 |
46 | public function getAttendanceDateAttribute($value)
47 | {
48 | return Carbon::parse($value)->format('d/m/Y');
49 | }
50 |
51 |
52 | public function getPresentAttribute($value)
53 | {
54 | return Arr::get(AppHelper::ATTENDANCE_TYPE, $value);
55 | }
56 |
57 | public function scopeEmployee($query, $employee)
58 | {
59 | if($employee){
60 | return $query->where('employee_id', $employee);
61 | }
62 |
63 | return $query;
64 | }
65 |
66 | public function scopeCountOrGet($query, $isCount)
67 | {
68 | if($isCount){
69 | return $query->count();
70 | }
71 |
72 | return $query->get();
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
34 |
35 | $status = $kernel->handle(
36 | $input = new Symfony\Component\Console\Input\ArgvInput,
37 | new Symfony\Component\Console\Output\ConsoleOutput
38 | );
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Shutdown The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once Artisan has finished running, we will fire off the shutdown events
46 | | so that any final work may be done by the application before we shut
47 | | down the process. This is the last thing to happen to the request.
48 | |
49 | */
50 |
51 | $kernel->terminate($input, $status);
52 |
53 | exit($status);
54 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 |
10 | define('LARAVEL_START', microtime(true));
11 |
12 | /*
13 | |--------------------------------------------------------------------------
14 | | Register The Auto Loader
15 | |--------------------------------------------------------------------------
16 | |
17 | | Composer provides a convenient, automatically generated class loader for
18 | | our application. We just need to utilize it! We'll simply require it
19 | | into the script here so that we don't have to worry about manual
20 | | loading any of our classes later on. It feels great to relax.
21 | |
22 | */
23 |
24 | require __DIR__.'/../vendor/autoload.php';
25 |
26 | /*
27 | |--------------------------------------------------------------------------
28 | | Turn On The Lights
29 | |--------------------------------------------------------------------------
30 | |
31 | | We need to illuminate PHP development, so let us turn on the lights.
32 | | This bootstraps the framework and gets it ready for use, then it
33 | | will load up this application so that we can run it and send
34 | | the responses back to the browser and delight our users.
35 | |
36 | */
37 |
38 | $app = require_once __DIR__.'/../bootstrap/app.php';
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Run The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once we have the application, we can handle the incoming request
46 | | through the kernel, and send the associated response back to
47 | | the client's browser allowing them to enjoy the creative
48 | | and wonderful application we have prepared for them.
49 | |
50 | */
51 |
52 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
53 |
54 | $response = $kernel->handle(
55 | $request = Illuminate\Http\Request::capture()
56 | );
57 |
58 | $response->send();
59 |
60 | $kernel->terminate($request, $response);
61 |
--------------------------------------------------------------------------------
/database/migrations/2018_07_06_103920_create_about_content_tables.php:
--------------------------------------------------------------------------------
1 | increments('id');
19 | $table->string('why_content',500);
20 | $table->string('key_point_1_title',100);
21 | $table->longText('key_point_1_content');
22 | $table->string('key_point_2_title',100)->nullable();
23 | $table->longText('key_point_2_content')->nullable();
24 | $table->string('key_point_3_title',100)->nullable();
25 | $table->longText('key_point_3_content')->nullable();
26 | $table->string('key_point_4_title',100)->nullable();
27 | $table->longText('key_point_4_content')->nullable();
28 | $table->string('key_point_5_title',100)->nullable();
29 | $table->longText('key_point_5_content')->nullable();
30 | $table->string('about_us',500);
31 | $table->string('who_we_are',1000);
32 | $table->text('intro_video_embed_code');
33 | $table->string('video_site_link',500)->nullable();
34 | $table->timestamps();
35 | $table->userstamps();
36 | }
37 | );
38 | Schema::create(
39 | 'about_sliders', function (Blueprint $table) {
40 | $table->increments('id');
41 | $table->string('image');
42 | $table->integer('order')->default(0);
43 | $table->timestamps();
44 | $table->userstamps();
45 | }
46 | );
47 | }
48 |
49 | /**
50 | * Reverse the migrations.
51 | *
52 | * @return void
53 | */
54 | public function down()
55 | {
56 | Schema::dropIfExists('about_contents');
57 | Schema::dropIfExists('about_sliders');
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/config/filesystems.php:
--------------------------------------------------------------------------------
1 | env('FILESYSTEM_DRIVER', 'local'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Default Cloud Filesystem Disk
21 | |--------------------------------------------------------------------------
22 | |
23 | | Many applications store files both locally and in the cloud. For this
24 | | reason, you may specify a default "cloud" driver here. This driver
25 | | will be bound as the Cloud disk implementation in the container.
26 | |
27 | */
28 |
29 | 'cloud' => env('FILESYSTEM_CLOUD', 's3'),
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Filesystem Disks
34 | |--------------------------------------------------------------------------
35 | |
36 | | Here you may configure as many filesystem "disks" as you wish, and you
37 | | may even configure multiple disks of the same driver. Defaults have
38 | | been setup for each driver as an example of the required options.
39 | |
40 | | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
41 | |
42 | */
43 |
44 | 'disks' => [
45 |
46 | 'local' => [
47 | 'driver' => 'local',
48 | 'root' => storage_path('app'),
49 | ],
50 |
51 | 'public' => [
52 | 'driver' => 'local',
53 | 'root' => storage_path('app/public'),
54 | 'url' => env('APP_URL').'/storage',
55 | 'visibility' => 'public',
56 | ],
57 |
58 | 's3' => [
59 | 'driver' => 's3',
60 | 'key' => env('AWS_ACCESS_KEY_ID'),
61 | 'secret' => env('AWS_SECRET_ACCESS_KEY'),
62 | 'region' => env('AWS_DEFAULT_REGION'),
63 | 'bucket' => env('AWS_BUCKET'),
64 | 'url' => env('AWS_URL'),
65 | ],
66 |
67 | ],
68 |
69 | ];
70 |
--------------------------------------------------------------------------------
/app/Exceptions/Handler.php:
--------------------------------------------------------------------------------
1 | getStatusCode();
58 |
59 | if(!env('APP_DEBUG', false)) {
60 | if (!$request->user() && AppHelper::isFrontendEnabled()) {
61 | $locale = Session::get('user_locale');
62 | App::setLocale($locale);
63 |
64 | if ($statusCode == 404) {
65 | return response()->view('errors.front_404', [], 404);
66 | }
67 |
68 | if ($statusCode == 500) {
69 |
70 | return response()->view('errors.front_500', [], 500);
71 | }
72 |
73 | }
74 | }
75 |
76 | if ($request->user()) {
77 | if ($statusCode == 404) {
78 | return response()->view('errors.back_404', [], 404);
79 | }
80 |
81 | if ($statusCode == 401) {
82 | return response()->view('errors.back_401', [], 404);
83 | }
84 | }
85 |
86 |
87 |
88 | }
89 |
90 |
91 |
92 | return parent::render($request, $exception);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "prefrontend-dev": "rm -rf public/frontend",
5 | "frontend-dev": "npm run frontend-development",
6 | "frontend-development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.frontend.mix.js",
7 | "frontend-watch": "npm run frontend-development -- --watch",
8 | "frontend-prod": "npm run frontend-production",
9 | "frontend-production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.frontend.mix.js",
10 | "prebackend-dev": "rm -rf public/css public/js public/fonts public/images",
11 | "backend-dev": "npm run backend-development",
12 | "backend-development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.backend.mix.js",
13 | "backend-watch": "npm run backend-development -- --watch",
14 | "backend-prod": "npm run backend-production",
15 | "backend-production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.backend.mix.js"
16 | },
17 | "devDependencies": {
18 | "axios": "^0.19.0",
19 | "browser-sync": "^2.26.7",
20 | "browser-sync-webpack-plugin": "^2.2.2",
21 | "cross-env": "^5.2.0",
22 | "laravel-mix": "^4.1.2",
23 | "purify-css": "^1.2.5",
24 | "purifycss-webpack": "^0.7.0",
25 | "resolve-url-loader": "2.3.1",
26 | "sass": "^1.22.7",
27 | "sass-loader": "^7.2.0",
28 | "script-loader": "^0.7.2",
29 | "vue-template-compiler": "^2.6.10"
30 | },
31 | "dependencies": {
32 | "bootstrap": "^3.4.0",
33 | "bootstrap-colorpicker": "^2.5.3",
34 | "chart.js": "^2.7.3",
35 | "datatables.net": "^1.10.15",
36 | "datatables.net-bs": "^1.10.15",
37 | "datatables.net-responsive-bs": "^2.2.1",
38 | "fastclick": "^1.0.6",
39 | "font-awesome": "^4.7.0",
40 | "fs": "0.0.1-security",
41 | "icheck": "^1.0.2",
42 | "install": "^0.11.0",
43 | "jquery": "^3.4.1",
44 | "jquery-slimscroll": "^1.3.8",
45 | "jquery-ui": "^1.12.1",
46 | "jquery-validation": "^1.19.1",
47 | "moment": "^2.23.0",
48 | "popper.js": "^1.14.6",
49 | "remove": "^0.1.5",
50 | "select2": "^4.0.8",
51 | "sweetalert2": "^7.33.1",
52 | "toastr": "^2.1.4"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/Employee.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\User', 'user_id');
51 | }
52 |
53 |
54 | public function getGenderAttribute($value)
55 | {
56 | return Arr::get(AppHelper::GENDER, $value);
57 | }
58 |
59 | public function getShiftAttribute($value)
60 | {
61 | return Arr::get(AppHelper::EMP_SHIFTS, $value);
62 | }
63 | public function setDutyStartAttribute($value)
64 | {
65 | if(strlen($value)){
66 | $this->attributes['duty_start'] = Carbon::createFromFormat('h:i a', $value)->format('H:i:s');
67 | }
68 |
69 | }
70 |
71 | public function getDutyStartAttribute($value)
72 | {
73 | if(!strlen($value)){
74 | return null;
75 | }
76 |
77 | return Carbon::parse($value);
78 |
79 | }
80 |
81 | public function setDutyEndAttribute($value)
82 | {
83 | if(strlen($value)){
84 | $this->attributes['duty_end'] = Carbon::createFromFormat('h:i a', $value)->format('H:i:s');
85 | }
86 |
87 | }
88 |
89 | public function getDutyEndAttribute($value)
90 | {
91 | if(!strlen($value)){
92 | return null;
93 | }
94 | return Carbon::parse($value);
95 |
96 | }
97 |
98 |
99 | public function getReligionAttribute($value)
100 | {
101 | return Arr::get(AppHelper::RELIGION, $value);
102 | }
103 |
104 | public function class()
105 | {
106 | return $this->hasMany('App\IClass', 'teacher_id');
107 | }
108 |
109 | public function section()
110 | {
111 | return $this->hasMany('App\Section', 'teacher_id');
112 | }
113 |
114 | public function role()
115 | {
116 | return $this->belongsTo('App\Role', 'role_id');
117 | }
118 |
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/config/cache.php:
--------------------------------------------------------------------------------
1 | env('CACHE_DRIVER', 'file'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Cache Stores
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may define all of the cache "stores" for your application as
26 | | well as their drivers. You may even define multiple stores for the
27 | | same cache driver to group types of items stored in your caches.
28 | |
29 | */
30 |
31 | 'stores' => [
32 |
33 | 'apc' => [
34 | 'driver' => 'apc',
35 | ],
36 |
37 | 'array' => [
38 | 'driver' => 'array',
39 | ],
40 |
41 | 'database' => [
42 | 'driver' => 'database',
43 | 'table' => 'cache',
44 | 'connection' => null,
45 | ],
46 |
47 | 'file' => [
48 | 'driver' => 'file',
49 | 'path' => storage_path('framework/cache/data'),
50 | ],
51 |
52 | 'memcached' => [
53 | 'driver' => 'memcached',
54 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
55 | 'sasl' => [
56 | env('MEMCACHED_USERNAME'),
57 | env('MEMCACHED_PASSWORD'),
58 | ],
59 | 'options' => [
60 | // Memcached::OPT_CONNECT_TIMEOUT => 2000,
61 | ],
62 | 'servers' => [
63 | [
64 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'),
65 | 'port' => env('MEMCACHED_PORT', 11211),
66 | 'weight' => 100,
67 | ],
68 | ],
69 | ],
70 |
71 | 'redis' => [
72 | 'driver' => 'redis',
73 | 'connection' => 'default',
74 | ],
75 |
76 | ],
77 |
78 | /*
79 | |--------------------------------------------------------------------------
80 | | Cache Key Prefix
81 | |--------------------------------------------------------------------------
82 | |
83 | | When utilizing a RAM based store such as APC or Memcached, there might
84 | | be other applications utilizing the same cache. So, we'll specify a
85 | | value to get prefixed to all our keys so we can avoid collisions.
86 | |
87 | */
88 |
89 | 'prefix' => env(
90 | 'CACHE_PREFIX',
91 | str_slug(env('APP_NAME', 'laravel'), '_').'_cache'
92 | ),
93 |
94 | ];
95 |
--------------------------------------------------------------------------------
/config/logging.php:
--------------------------------------------------------------------------------
1 | env('LOG_CHANNEL', 'stack'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Log Channels
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may configure the log channels for your application. Out of
26 | | the box, Laravel uses the Monolog PHP logging library. This gives
27 | | you a variety of powerful log handlers / formatters to utilize.
28 | |
29 | | Available Drivers: "single", "daily", "slack", "syslog",
30 | | "errorlog", "monolog",
31 | | "custom", "stack"
32 | |
33 | */
34 |
35 | 'channels' => [
36 | 'stack' => [
37 | 'driver' => 'stack',
38 | 'channels' => ['single'],
39 | ],
40 |
41 | 'single' => [
42 | 'driver' => 'single',
43 | 'path' => storage_path('logs/laravel.log'),
44 | 'level' => 'debug',
45 | ],
46 | 'smsLog' => [
47 | 'driver' => 'single',
48 | 'path' => storage_path('logs/sms.log'),
49 | 'level' => 'debug',
50 | ],
51 | 'studentabsentlog' => [
52 | 'driver' => 'single',
53 | 'path' => storage_path('logs/student-absent-job.log'),
54 | 'level' => 'debug',
55 | ],
56 | 'employeeabsentlog' => [
57 | 'driver' => 'single',
58 | 'path' => storage_path('logs/employee-absent-job.log'),
59 | 'level' => 'debug',
60 | ],
61 | 'studentattendancelog' => [
62 | 'driver' => 'single',
63 | 'path' => storage_path('logs/student-attendance-upload.log'),
64 | 'level' => 'debug',
65 | ],
66 | 'employeeattendancelog' => [
67 | 'driver' => 'single',
68 | 'path' => storage_path('logs/employee-attendance-upload.log'),
69 | 'level' => 'debug',
70 | ],
71 | 'daily' => [
72 | 'driver' => 'daily',
73 | 'path' => storage_path('logs/laravel.log'),
74 | 'level' => 'debug',
75 | 'days' => 7,
76 | ],
77 |
78 | 'slack' => [
79 | 'driver' => 'slack',
80 | 'url' => env('LOG_SLACK_WEBHOOK_URL'),
81 | 'username' => 'Laravel Log',
82 | 'emoji' => ':boom:',
83 | 'level' => 'critical',
84 | ],
85 |
86 | 'stderr' => [
87 | 'driver' => 'monolog',
88 | 'handler' => StreamHandler::class,
89 | 'with' => [
90 | 'stream' => 'php://stderr',
91 | ],
92 | ],
93 |
94 | 'syslog' => [
95 | 'driver' => 'syslog',
96 | 'level' => 'debug',
97 | ],
98 |
99 | 'errorlog' => [
100 | 'driver' => 'errorlog',
101 | 'level' => 'debug',
102 | ],
103 | ],
104 |
105 | ];
106 |
--------------------------------------------------------------------------------
/webpack.backend.mix.js:
--------------------------------------------------------------------------------
1 | let mix = require('laravel-mix');
2 | const webpack = require('webpack');
3 |
4 | /*
5 | |--------------------------------------------------------------------------
6 | | Mix Back Panel Asset Management
7 | |--------------------------------------------------------------------------
8 | |
9 | | Mix provides a clean, fluent API for defining some Webpack build steps
10 | | for your Laravel application. By default, we are compiling the Sass
11 | | file for the application as well as bundling up all the JS files.
12 | |
13 | */
14 |
15 | mix.webpackConfig({
16 | plugins: [
17 | // Ignore all locale files of moment.js
18 | // new webpack.IgnorePlugin(
19 | // /^\.\/locale$/, /moment$/,
20 | // )
21 | new webpack.ContextReplacementPlugin(
22 | // The path to directory which should be handled by this plugin
23 | /moment[\/\\]locale/,
24 | /select2[\/\\]dist[\/\\]js[\/\\]i18n/,
25 | )
26 | ]
27 | });
28 |
29 | mix.js('resources/assets/backend/js/app.js', 'public/js')
30 | .js([
31 | 'resources/assets/backend/js/site-dashboard.js',
32 | ], 'public/js/site-dashboard.js')
33 | .js([
34 | 'resources/assets/backend/js/dashboard.js',
35 | ], 'public/js/dashboard.js')
36 | .js([
37 | 'resources/assets/backend/js/adminlte.js',
38 | 'resources/assets/backend/js/theme_settings.js',
39 | 'resources/assets/backend/js/bootstrap-datetimepicker.min.js',
40 | 'resources/assets/backend/js/bootstrap-toggle.min.js',
41 | ], 'public/js/theme.js')
42 | .extract([
43 | 'jquery', 'bootstrap', 'icheck', 'jquery-validation', 'jquery-slimscroll', 'fastclick',
44 | 'datatables.net', 'datatables.net-bs', 'datatables.net-responsive-bs'
45 | ])
46 | .sass('resources/assets/backend/sass/app.scss', 'public/css')
47 | .sass('resources/assets/backend/sass/print.scss', 'public/css')
48 | .sass('resources/assets/backend/sass/vendor.scss', 'public/css')
49 | .sass('resources/assets/backend/sass/colorpicker.scss', 'public/css')
50 | .sass('resources/assets/backend/sass/report.scss', 'public/css')
51 | .js([
52 | 'resources/assets/backend/js/colorpicker.js',
53 | ], 'public/js/colorpicker.js')
54 | .styles([
55 | 'resources/assets/backend/css/AdminLTE.css',
56 | 'resources/assets/backend/css/_all-skins.css',
57 | 'resources/assets/backend/css/bootstrap3-wysihtml5.min.css',
58 | 'resources/assets/backend/css/bootstrap-datetimepicker.min.css',
59 | 'resources/assets/backend/css/bootstrap-toggle.min.css'
60 | ], 'public/css/theme.css')
61 | .styles('resources/assets/backend/css/site-dashboard.css', 'public/css/site-dashboard.css')
62 | .styles('resources/assets/backend/css/pace.css', 'public/css/pace.css')
63 | .autoload({
64 | jquery: ['$', 'window.jQuery', 'jQuery', 'jquery'],
65 | moment: ['window.moment', 'moment'],
66 | });
67 |
68 |
69 | mix.options({
70 | processCssUrls: true,
71 | // uglify: {},
72 | purifyCss: false,
73 | // purifyCss: {},
74 | clearConsole: false
75 | });
76 |
77 |
78 | // copy non processing files to public path
79 | mix.copy('resources/assets/backend/js/bootstrap3-wysihtml5.all.min.js', 'public/js/editor.js');
80 | mix.copy('resources/assets/backend/js/pace.js', 'public/js/pace.js');
81 | mix.copyDirectory('resources/assets/backend/images', 'public/images');
82 |
83 |
84 |
85 | if (mix.inProduction()) {
86 | mix.version();
87 | mix.sourceMaps();
88 | }
89 |
90 | mix.browserSync({
91 | proxy: 'l5.school.test'
92 | });
93 |
--------------------------------------------------------------------------------
/config/auth.php:
--------------------------------------------------------------------------------
1 | [
17 | 'guard' => 'web',
18 | 'passwords' => 'users',
19 | ],
20 |
21 | /*
22 | |--------------------------------------------------------------------------
23 | | Authentication Guards
24 | |--------------------------------------------------------------------------
25 | |
26 | | Next, you may define every authentication guard for your application.
27 | | Of course, a great default configuration has been defined for you
28 | | here which uses session storage and the Eloquent user provider.
29 | |
30 | | All authentication drivers have a user provider. This defines how the
31 | | users are actually retrieved out of your database or other storage
32 | | mechanisms used by this application to persist your user's data.
33 | |
34 | | Supported: "session", "token"
35 | |
36 | */
37 |
38 | 'guards' => [
39 | 'web' => [
40 | 'driver' => 'session',
41 | 'provider' => 'users',
42 | ],
43 |
44 | 'api' => [
45 | 'driver' => 'token',
46 | 'provider' => 'users',
47 | ],
48 | ],
49 |
50 | /*
51 | |--------------------------------------------------------------------------
52 | | User Providers
53 | |--------------------------------------------------------------------------
54 | |
55 | | All authentication drivers have a user provider. This defines how the
56 | | users are actually retrieved out of your database or other storage
57 | | mechanisms used by this application to persist your user's data.
58 | |
59 | | If you have multiple user tables or models you may configure multiple
60 | | sources which represent each model / table. These sources may then
61 | | be assigned to any extra authentication guards you have defined.
62 | |
63 | | Supported: "database", "eloquent"
64 | |
65 | */
66 |
67 | 'providers' => [
68 | 'users' => [
69 | 'driver' => 'cache-user',
70 | 'model' => App\User::class,
71 | ],
72 |
73 | // 'users' => [
74 | // 'driver' => 'database',
75 | // 'table' => 'users',
76 | // ],
77 | ],
78 |
79 | /*
80 | |--------------------------------------------------------------------------
81 | | Resetting Passwords
82 | |--------------------------------------------------------------------------
83 | |
84 | | You may specify multiple password reset configurations if you have more
85 | | than one user table or model in the application and you want to have
86 | | separate password reset settings based on the specific user types.
87 | |
88 | | The expire time is the number of minutes that the reset token should be
89 | | considered valid. This security feature keeps tokens short-lived so
90 | | they have less time to be guessed. You may change this as needed.
91 | |
92 | */
93 |
94 | 'passwords' => [
95 | 'users' => [
96 | 'provider' => 'users',
97 | 'table' => 'password_resets',
98 | 'expire' => 60,
99 | ],
100 | ],
101 |
102 | ];
103 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hrshadhin/school-management-system",
3 | "version": "2.0",
4 | "description": "Another School Management System build with laravel",
5 | "keywords": [
6 | "School",
7 | "Management",
8 | "Web",
9 | "Application",
10 | "Admission",
11 | "Attendance",
12 | "Exam",
13 | "Result",
14 | "Fees",
15 | "Accounting",
16 | "Library",
17 | "Hostel",
18 | "Employees"
19 | ],
20 | "type": "project",
21 | "license": "AGPL-3.0-or-later",
22 | "authors": [
23 | {
24 | "name": "H.R.Shadhin",
25 | "email": "dev@hrshadhin.me",
26 | "homepage": "http://hrshadhin.me",
27 | "role": "Developer"
28 | }
29 | ],
30 | "homepage": "http://school.hrshadhin.me",
31 | "readme": "./readme.xml",
32 | "time": "2018-05-20",
33 | "support": {
34 | "email": "hello@hrshadhin.me",
35 | "issues": "https://github.com/hrshadhin/school-management-system/issues",
36 | "wiki": "https://github.com/hrshadhin/school-management-system/wiki",
37 | "source": "https://github.com/hrshadhin/school-management-system"
38 | },
39 | "repositories": [
40 | {
41 | "url": "https://github.com/hrshadhin/laravel-userstamps.git",
42 | "type": "git"
43 | }
44 | ],
45 | "require": {
46 | "php": "^7.1.3",
47 | "barryvdh/laravel-dompdf": "^0.8.4",
48 | "bonecms/laravel-captcha": "^2.1",
49 | "fideloper/proxy": "^4.0",
50 | "guzzlehttp/guzzle": "^6.3",
51 | "hrshadhin/laravel-userstamps": "dev-master",
52 | "laravel/framework": "5.8.*",
53 | "laravel/tinker": "^1.0",
54 | "laravelcollective/html": "^5.4.0",
55 | "maatwebsite/excel": "^3.1",
56 | "picqer/php-barcode-generator": "^0.3.0",
57 | "rap2hpoutre/laravel-log-viewer": "^1.2",
58 | "twilio/sdk": "^5.28"
59 | },
60 | "require-dev": {
61 | "barryvdh/laravel-debugbar": "^3.2",
62 | "filp/whoops": "^2.0",
63 | "fzaninotto/faker": "^1.4",
64 | "mockery/mockery": "^1.0",
65 | "nunomaduro/collision": "^2.0",
66 | "phpunit/phpunit": "^7.0"
67 | },
68 | "autoload": {
69 | "classmap": [
70 | "database/seeds",
71 | "database/factories"
72 | ],
73 | "psr-4": {
74 | "App\\": "app/"
75 | }
76 | },
77 | "autoload-dev": {
78 | "psr-4": {
79 | "Tests\\": "tests/"
80 | }
81 | },
82 | "extra": {
83 | "laravel": {
84 | "dont-discover": []
85 | }
86 | },
87 | "scripts": {
88 | "post-install-cmd": [
89 | "php artisan config:clear",
90 | "php artisan cache:clear",
91 | "php artisan route:clear",
92 | "php artisan view:clear",
93 | "php artisan clear-compiled",
94 | "php artisan package:discover"
95 | ],
96 | "post-update-cmd": [
97 | "php artisan config:clear",
98 | "php artisan cache:clear",
99 | "php artisan route:clear",
100 | "php artisan view:clear",
101 | "php artisan clear-compiled",
102 | "php artisan package:discover"
103 | ],
104 | "post-create-project-cmd": [
105 | "php -r \"copy('.env.example', '.env');\"",
106 | "php artisan key:generate"
107 | ]
108 | },
109 | "config": {
110 | "preferred-install": "dist",
111 | "sort-packages": true,
112 | "optimize-autoloader": true
113 | },
114 | "minimum-stability": "dev",
115 | "prefer-stable": true
116 | }
117 |
--------------------------------------------------------------------------------
/public/svg/404.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/database.php:
--------------------------------------------------------------------------------
1 | env('DB_CONNECTION', 'mysql'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Database Connections
21 | |--------------------------------------------------------------------------
22 | |
23 | | Here are each of the database connections setup for your application.
24 | | Of course, examples of configuring each database platform that is
25 | | supported by Laravel is shown below to make development simple.
26 | |
27 | |
28 | | All database work in Laravel is done through the PHP PDO facilities
29 | | so make sure you have the driver for your particular database of
30 | | choice installed on your machine before you begin development.
31 | | For long key size replace utf8mb4 to utf8 for both charset and collation
32 | |
33 | */
34 |
35 | 'connections' => [
36 |
37 | 'sqlite' => [
38 | 'driver' => 'sqlite',
39 | 'database' => env('DB_DATABASE', database_path('database.sqlite')),
40 | 'prefix' => '',
41 | ],
42 |
43 | 'mysql' => [
44 | 'driver' => 'mysql',
45 | 'host' => env('DB_HOST', '127.0.0.1'),
46 | 'port' => env('DB_PORT', '3306'),
47 | 'database' => env('DB_DATABASE', 'forge'),
48 | 'username' => env('DB_USERNAME', 'forge'),
49 | 'password' => env('DB_PASSWORD', ''),
50 | 'unix_socket' => env('DB_SOCKET', ''),
51 | 'charset' => 'utf8',
52 | 'collation' => 'utf8_unicode_ci',
53 | 'prefix' => '',
54 | 'strict' => true,
55 | 'engine' => null,
56 | ],
57 |
58 | 'pgsql' => [
59 | 'driver' => 'pgsql',
60 | 'host' => env('DB_HOST', '127.0.0.1'),
61 | 'port' => env('DB_PORT', '5432'),
62 | 'database' => env('DB_DATABASE', 'forge'),
63 | 'username' => env('DB_USERNAME', 'forge'),
64 | 'password' => env('DB_PASSWORD', ''),
65 | 'charset' => 'utf8',
66 | 'prefix' => '',
67 | 'schema' => 'public',
68 | 'sslmode' => 'prefer',
69 | ],
70 |
71 | 'sqlsrv' => [
72 | 'driver' => 'sqlsrv',
73 | 'host' => env('DB_HOST', 'localhost'),
74 | 'port' => env('DB_PORT', '1433'),
75 | 'database' => env('DB_DATABASE', 'forge'),
76 | 'username' => env('DB_USERNAME', 'forge'),
77 | 'password' => env('DB_PASSWORD', ''),
78 | 'charset' => 'utf8',
79 | 'prefix' => '',
80 | ],
81 |
82 | ],
83 |
84 | /*
85 | |--------------------------------------------------------------------------
86 | | Migration Repository Table
87 | |--------------------------------------------------------------------------
88 | |
89 | | This table keeps track of all the migrations that have already run for
90 | | your application. Using this information, we can determine which of
91 | | the migrations on disk haven't actually been run in the database.
92 | |
93 | */
94 |
95 | 'migrations' => 'migrations',
96 |
97 | /*
98 | |--------------------------------------------------------------------------
99 | | Redis Databases
100 | |--------------------------------------------------------------------------
101 | |
102 | | Redis is an open source, fast, and advanced key-value store that also
103 | | provides a richer set of commands than a typical key-value systems
104 | | such as APC or Memcached. Laravel makes it easy to dig right in.
105 | |
106 | */
107 |
108 | 'redis' => [
109 |
110 | 'client' => 'predis',
111 |
112 | 'default' => [
113 | 'host' => env('REDIS_HOST', '127.0.0.1'),
114 | 'password' => env('REDIS_PASSWORD', null),
115 | 'port' => env('REDIS_PORT', 6379),
116 | 'database' => 0,
117 | ],
118 |
119 | ],
120 |
121 | ];
122 |
--------------------------------------------------------------------------------
/public/svg/503.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/routes/website.php:
--------------------------------------------------------------------------------
1 | 'Frontend', 'middleware' => ['frontend']], function () {
17 | Route::get('/', 'HomeController@home')->name('home');
18 | Route::post('site/subscribe','HomeController@subscribe')
19 | ->name('site.subscribe');
20 | Route::get('/class', 'HomeController@classProfile')->name('site.class_profile');
21 | Route::get('/class-details/{name}', 'HomeController@classDetails')->name('site.class_details');
22 | Route::get('/teachers', 'HomeController@teacherProfile')->name('site.teacher_profile');
23 | Route::get('/events', 'HomeController@event')->name('site.event');
24 | Route::get('/events-details/{slug}', 'HomeController@eventDetails')->name('site.event_details');
25 | Route::get('/gallery', 'HomeController@gallery')->name('site.gallery_view');
26 | Route::get('/contact-us', 'HomeController@contactUs')->name('site.contact_us_view');
27 | Route::post('/contact-us', 'HomeController@contactUs')->name('site.contact_us_form');
28 | Route::get('/faq', 'HomeController@faq')->name('site.faq_view');
29 | Route::get('/timeline', 'HomeController@timeline')->name('site.timeline_view');
30 |
31 | });
32 |
33 | //change website locale
34 | Route::get(
35 | '/set-locale/{lang}', function ($lang) {
36 | //set user wanted locale to session
37 | Session::put('user_locale', $lang);
38 | return redirect()->back();
39 | }
40 | )->name('setLocale');
41 |
42 | Route::group(
43 | ['namespace' => 'Backend', 'middleware' => ['auth','permission']], function () {
44 |
45 | /**
46 | * Website contents routes
47 | */
48 |
49 | Route::get('/site/dashboard', 'SiteController@dashboard')
50 | ->name('site.dashboard');
51 | Route::resource('slider','SliderController');
52 | Route::get('/site/about-content', 'SiteController@aboutContent')
53 | ->name('site.about_content');
54 | Route::post('/site/about-content', 'SiteController@aboutContent')
55 | ->name('site.about_content');
56 | Route::get('site/about-content/images','SiteController@aboutContentImage')
57 | ->name('site.about_content_image');
58 | Route::post('site/about-content/images','SiteController@aboutContentImage')
59 | ->name('site.about_content_image');
60 | Route::post('site/about-content/images/{id}','SiteController@aboutContentImageDelete')
61 | ->name('site.about_content_image_delete');
62 | Route::get('site/service','SiteController@serviceContent')
63 | ->name('site.service');
64 | Route::post('site/service','SiteController@serviceContent')
65 | ->name('site.service');
66 | Route::get('site/statistic','SiteController@statisticContent')
67 | ->name('site.statistic');
68 | Route::post('site/statistic','SiteController@statisticContent')
69 | ->name('site.statistic');
70 |
71 | Route::get('site/testimonial','SiteController@testimonialIndex')
72 | ->name('site.testimonial');
73 | Route::post('site/testimonial','SiteController@testimonialIndex')
74 | ->name('site.testimonial_delete');
75 | Route::get('site/testimonial/create','SiteController@testimonialCreate')
76 | ->name('site.testimonial_create');
77 | Route::post('site/testimonial/create','SiteController@testimonialCreate')
78 | ->name('site.testimonial_create');
79 |
80 | Route::get('site/subscribe','SiteController@subscribe')
81 | ->name('site.subscribe');
82 |
83 | Route::resource('class_profile','ClassProfileController');
84 | Route::resource('teacher_profile','TeacherProfileController');
85 | Route::resource('event','EventController');
86 | Route::get('site/gallery','SiteController@gallery')
87 | ->name('site.gallery');
88 | Route::get('site/gallery/add-image','SiteController@galleryAdd')
89 | ->name('site.gallery_image');
90 | Route::post('site/gallery/add-image','SiteController@galleryAdd')
91 | ->name('site.gallery_image');
92 | Route::post('site/gallery/delete-images/{id}','SiteController@galleryDelete')
93 | ->name('site.gallery_image_delete');
94 | Route::get('site/contact-us','SiteController@contactUs')
95 | ->name('site.contact_us');
96 | Route::post('site/contact-us','SiteController@contactUs')
97 | ->name('site.contact_us');
98 | Route::get('site/fqa','SiteController@faq')
99 | ->name('site.faq');
100 | Route::post('site/fqa','SiteController@faq')
101 | ->name('site.faq');
102 | Route::post('site/faq/{id}','SiteController@faqDelete')
103 | ->name('site.faq_delete');
104 | Route::get('site/timeline','SiteController@timeline')
105 | ->name('site.timeline');
106 | Route::post('site/timeline','SiteController@timeline')
107 | ->name('site.timeline');
108 | Route::post('site/timeline/{id}','SiteController@timelineDelete')
109 | ->name('site.timeline_delete');
110 | Route::get('site/settings','SiteController@settings')
111 | ->name('site.settings');
112 | Route::post('site/settings','SiteController@settings')
113 | ->name('site.settings');
114 | Route::get('site/analytics','SiteController@analytics')
115 | ->name('site.analytics');
116 | Route::post('site/analytics','SiteController@analytics')
117 | ->name('site.analytics');
118 | });
119 |
120 |
121 |
--------------------------------------------------------------------------------
/public/svg/403.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # school Management System (SMS)
2 | Another School Management System build with laravel and PHP 7.
3 |
4 | [](https://app.codeship.com/projects/312233)
5 | [](https://www.gnu.org/licenses/agpl-3.0)
6 | [](https://snyk.io/test/github/hrshadhin/school-management-system?targetFile=package.json)
7 |
8 |
9 | :loudspeaker:
10 | **Notic:** Now its version [v2.0](https://github.com/hrshadhin/school-management-system/releases/tag/v2.0) (community edition)
11 | . If you need PHP 5 support then use version [v1.0](https://github.com/hrshadhin/school-management-system/releases/tag/v1.0).
12 | For Enterprise edition checkout here [EE](https://github.com/hrshadhin/school-management-system/tree/empty)
13 |
14 | # Join Our Discord Server
15 | :mega:[CloudSchool](https://discord.gg/7rXyuu8):mega:
16 |
17 | # Features
18 | | Community Edition | Enterprise Edition |
19 | |-----------------------|:-------------------------:|
20 | | Academic Year manage | Academic Year manage |
21 | | Academic Calendar Setup | Academic Calendar Setup |
22 | | Institute Setup | Institute Setup |
23 | | Class & Section Manage | Class & Section Manage |
24 | | Subject & Teacher Manage | Subject & Teacher Manage |
25 | | Student Admission | Student Admission |
26 | | Student Attendance | Student Attendance |
27 | | Exam & Grading Rules | Exam & Grading Rules |
28 | | Makrs & Result | Easy Makrs Entry & Result Manage |
29 | | Employees Manage | Employees Manage |
30 | | Employees Attendance | Employees Attendance |
31 | | Employees Leave | Employees Leave |
32 | | Employees Work Outside | Employees Work Outside |
33 | | SMS Gateway Setup | SMS Gateway Setup |
34 | | Email & SMS Templating | Email & SMS Templating |
35 | | Attendance notification email/sms | Attendance notification email/sms |
36 | | Id Card templates Manage | Id Card templates Manage |
37 | | Employee & Student id card print | Employee & Student id card print |
38 | | User & Role manage with permision grid(ACL) | User & Role manage with permision grid(ACL) |
39 | | User wise Dashboard | User wise Dashboard
40 | | Report Settings | Report Settings |
41 | | Only 5 Reports | **40+** Reports |
42 | | Dynamic Front Website | Dynamic Front Website |
43 | | Website Management Panel | Website Management Panel
44 | | Photo Gallery | Photo Gallery |
45 | | Event Manage | Event Manage |
46 | | Google Analytics | Google Analytics |
47 | | User Notification | User Notification |
48 | | | Online Admission |
49 | | | Online Admit Card & Payslip |
50 | | | Student Promotion |
51 | | | Notice Board |
52 | | | Student & Employee Id card bulk/mass print |
53 | | | Account Manage |
54 | | | Budget Manage |
55 | | | Account Heads |
56 | | | Student Invoice |
57 | | | Income / Expense Manage |
58 | | | Payroll |
59 | | | Salary Template |
60 | | | Employee Salary Payment |
61 | | | Hostel & Collection Manage |
62 | | | Library Manage |
63 | | | Issue book and fine collection |
64 | | | Academic Calendar Print |
65 | | | Bulk SMS and Email Sending |
66 | | | **40+** Reports |
67 |
68 | # Installation and use
69 |
70 | **Dependency**
71 | - PHP >= 7.1.3
72 | - OpenSSL PHP Extension
73 | - PDO PHP Extension
74 | - Mbstring PHP Extension
75 | - Tokenizer PHP Extension
76 | - XML PHP Extension
77 | - Ctype PHP Extension
78 | - JSON PHP Extension
79 | - [hrshadhin/laravel-userstamps](https://github.com/hrshadhin/laravel-userstamps.git)
80 | - NodeJS, npm, webpack
81 |
82 |
83 | ```
84 | $ git clone https://github.com/hrshadhin/school-management-system.git
85 |
86 | ```
87 | ```
88 | $ cd school-management-system
89 | ```
90 | ```
91 | $ cp .env.example .env
92 | ```
93 | **Change configuration according to your need in ".env" file and create Database**
94 | ```
95 | $ composer install
96 | ```
97 | ```
98 | $ php artisan migrate
99 | ```
100 | ```
101 | $ php artisan db:seed
102 | ```
103 | **Load demo data**
104 | ```
105 | $ php artisan db:seed --class DemoSiteDataSeeder
106 | ```
107 | ```
108 | $ php artisan db:seed --class DemoAppDataSeeder
109 | ```
110 | **Clear cache**
111 | ```
112 | $ sudo php artisan cache:clear
113 | ```
114 | ```
115 | $ npm install
116 | ```
117 | ```
118 | $ npm run backend-prod
119 | ```
120 | ```
121 | $ npm run frontend-prod
122 | ```
123 | ```
124 | $ php artisan storage:link
125 | ```
126 | ```
127 | $ php artisan serve
128 | ```
129 | Now visit and login: [http://localhost:8000](http://localhost:8000) \
130 | username: admin\
131 | password: demo123
132 |
133 | **Demo(Community Edition)**\
134 | website url: http://sms.hrshadhin.me \
135 | app login: http://sms.hrshadhin.me/login \
136 | username: admin\
137 | password: demo123
138 |
139 | **Demo(Enterprise Edition)**\
140 | website url: http://cloudschoolbd.com \
141 | app login: http://cloudschoolbd.com/login \
142 | username: admin\
143 | password: demo123
144 |
145 | **N.B:**
146 | - For sms and email processing you need to run laravel queue worker. `bin` folder has supervisor config for start queue worker with supervisor.
147 |
148 | # Screenshot
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 | # Security Vulnerabilities
162 |
163 | If you discover a security vulnerability within SMS, please send an e-mail to H.R. Shadhin via [dev@hrshadhin.me](mailto:dev@hrshadhin.me). All security vulnerabilities will be promptly addressed.
164 |
165 | # License
166 |
167 | SMS is open-sourced software licensed under the AGPL-3.0 license. Frameworks and libraries has it own licensed.
168 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | env('APP_NAME', 'sms'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Application Environment
21 | |--------------------------------------------------------------------------
22 | |
23 | | This value determines the "environment" your application is currently
24 | | running in. This may determine how you prefer to configure various
25 | | services your application utilizes. Set this in your ".env" file.
26 | |
27 | */
28 |
29 | 'env' => env('APP_ENV', 'production'),
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Application Debug Mode
34 | |--------------------------------------------------------------------------
35 | |
36 | | When your application is in debug mode, detailed error messages with
37 | | stack traces will be shown on every error that occurs within your
38 | | application. If disabled, a simple generic error page is shown.
39 | |
40 | */
41 |
42 | 'debug' => env('APP_DEBUG', false),
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Application URL
47 | |--------------------------------------------------------------------------
48 | |
49 | | This URL is used by the console to properly generate URLs when using
50 | | the Artisan command line tool. You should set this to the root of
51 | | your application so that it is used when running Artisan tasks.
52 | |
53 | */
54 |
55 | 'url' => env('APP_URL', 'http://school.hrshadhin.me'),
56 |
57 | /*
58 | |--------------------------------------------------------------------------
59 | | Application Timezone
60 | |--------------------------------------------------------------------------
61 | |
62 | | Here you may specify the default timezone for your application, which
63 | | will be used by the PHP date and date-time functions. We have gone
64 | | ahead and set this to a sensible default for you out of the box.
65 | |
66 | */
67 |
68 | 'timezone' => env('APP_TIMEZONE', 'Asia/Dhaka'),
69 |
70 | /*
71 | |--------------------------------------------------------------------------
72 | | Application Locale Configuration
73 | |--------------------------------------------------------------------------
74 | |
75 | | The application locale determines the default locale that will be used
76 | | by the translation service provider. You are free to set this value
77 | | to any of the locales which will be supported by the application.
78 | |
79 | */
80 |
81 | 'locale' => env('APP_LOCALE', 'en'),
82 |
83 | /*
84 | |--------------------------------------------------------------------------
85 | | Application Fallback Locale
86 | |--------------------------------------------------------------------------
87 | |
88 | | The fallback locale determines the locale to use when the current one
89 | | is not available. You may change the value to correspond to any of
90 | | the language folders that are provided through your application.
91 | |
92 | */
93 |
94 | 'fallback_locale' => 'en',
95 |
96 | /*
97 | |--------------------------------------------------------------------------
98 | | Encryption Key
99 | |--------------------------------------------------------------------------
100 | |
101 | | This key is used by the Illuminate encrypter service and should be set
102 | | to a random, 32 character string, otherwise these encrypted strings
103 | | will not be safe. Please do this before deploying an application!
104 | |
105 | */
106 |
107 | 'key' => env('APP_KEY'),
108 |
109 | 'cipher' => 'AES-256-CBC',
110 |
111 | /*
112 | |--------------------------------------------------------------------------
113 | | Autoloaded Service Providers
114 | |--------------------------------------------------------------------------
115 | |
116 | | The service providers listed here will be automatically loaded on the
117 | | request to your application. Feel free to add your own services to
118 | | this array to grant expanded functionality to your applications.
119 | |
120 | */
121 |
122 | 'providers' => [
123 |
124 | /*
125 | * Laravel Framework Service Providers...
126 | */
127 | Illuminate\Auth\AuthServiceProvider::class,
128 | Illuminate\Broadcasting\BroadcastServiceProvider::class,
129 | Illuminate\Bus\BusServiceProvider::class,
130 | Illuminate\Cache\CacheServiceProvider::class,
131 | Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
132 | Illuminate\Cookie\CookieServiceProvider::class,
133 | Illuminate\Database\DatabaseServiceProvider::class,
134 | Illuminate\Encryption\EncryptionServiceProvider::class,
135 | Illuminate\Filesystem\FilesystemServiceProvider::class,
136 | Illuminate\Foundation\Providers\FoundationServiceProvider::class,
137 | Illuminate\Hashing\HashServiceProvider::class,
138 | Illuminate\Mail\MailServiceProvider::class,
139 | Illuminate\Notifications\NotificationServiceProvider::class,
140 | Illuminate\Pagination\PaginationServiceProvider::class,
141 | Illuminate\Pipeline\PipelineServiceProvider::class,
142 | Illuminate\Queue\QueueServiceProvider::class,
143 | Illuminate\Redis\RedisServiceProvider::class,
144 | Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
145 | Illuminate\Session\SessionServiceProvider::class,
146 | Illuminate\Translation\TranslationServiceProvider::class,
147 | Illuminate\Validation\ValidationServiceProvider::class,
148 | Illuminate\View\ViewServiceProvider::class,
149 |
150 | /*
151 | * Package Service Providers...
152 | */
153 |
154 | /*
155 | * Application Service Providers...
156 | */
157 | App\Providers\AppServiceProvider::class,
158 | App\Providers\AuthServiceProvider::class,
159 | // App\Providers\BroadcastServiceProvider::class,
160 | App\Providers\EventServiceProvider::class,
161 | App\Providers\RouteServiceProvider::class,
162 | App\Providers\ComposerServiceProvider::class,
163 | App\Providers\PermissionsServiceProvider::class,
164 | // Hrshadhin\Userstamps\UserstampsServiceProvider::class,
165 | Collective\Html\HtmlServiceProvider::class,
166 |
167 |
168 | ],
169 |
170 | /*
171 | |--------------------------------------------------------------------------
172 | | Class Aliases
173 | |--------------------------------------------------------------------------
174 | |
175 | | This array of class aliases will be registered when this application
176 | | is started. However, feel free to register as many as you wish as
177 | | the aliases are "lazy" loaded so they don't hinder performance.
178 | |
179 | */
180 |
181 | 'aliases' => [
182 |
183 | 'App' => Illuminate\Support\Facades\App::class,
184 | 'Artisan' => Illuminate\Support\Facades\Artisan::class,
185 | 'Auth' => Illuminate\Support\Facades\Auth::class,
186 | 'Blade' => Illuminate\Support\Facades\Blade::class,
187 | 'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
188 | 'Bus' => Illuminate\Support\Facades\Bus::class,
189 | 'Cache' => Illuminate\Support\Facades\Cache::class,
190 | 'Config' => Illuminate\Support\Facades\Config::class,
191 | 'Cookie' => Illuminate\Support\Facades\Cookie::class,
192 | 'Crypt' => Illuminate\Support\Facades\Crypt::class,
193 | 'DB' => Illuminate\Support\Facades\DB::class,
194 | 'Eloquent' => Illuminate\Database\Eloquent\Model::class,
195 | 'Event' => Illuminate\Support\Facades\Event::class,
196 | 'File' => Illuminate\Support\Facades\File::class,
197 | 'Gate' => Illuminate\Support\Facades\Gate::class,
198 | 'Hash' => Illuminate\Support\Facades\Hash::class,
199 | 'Lang' => Illuminate\Support\Facades\Lang::class,
200 | 'Log' => Illuminate\Support\Facades\Log::class,
201 | 'Mail' => Illuminate\Support\Facades\Mail::class,
202 | 'Notification' => Illuminate\Support\Facades\Notification::class,
203 | 'Password' => Illuminate\Support\Facades\Password::class,
204 | 'Queue' => Illuminate\Support\Facades\Queue::class,
205 | 'Redirect' => Illuminate\Support\Facades\Redirect::class,
206 | 'Redis' => Illuminate\Support\Facades\Redis::class,
207 | 'Request' => Illuminate\Support\Facades\Request::class,
208 | 'Response' => Illuminate\Support\Facades\Response::class,
209 | 'Route' => Illuminate\Support\Facades\Route::class,
210 | 'Schema' => Illuminate\Support\Facades\Schema::class,
211 | 'Session' => Illuminate\Support\Facades\Session::class,
212 | 'Storage' => Illuminate\Support\Facades\Storage::class,
213 | 'URL' => Illuminate\Support\Facades\URL::class,
214 | 'Validator' => Illuminate\Support\Facades\Validator::class,
215 | 'View' => Illuminate\Support\Facades\View::class,
216 | 'AppHelper' => App\Http\Helpers\AppHelper::class,
217 | 'Form' => Collective\Html\FormFacade::class,
218 | 'Html' => Collective\Html\HtmlFacade::class,
219 |
220 | ],
221 |
222 | ];
223 |
--------------------------------------------------------------------------------
/app/Console/Commands/SeedEmployeeAttendance.php:
--------------------------------------------------------------------------------
1 | where('is_imported','=',0)
60 | ->orderBy('created_at', 'DESC')
61 | ->first();
62 |
63 | if(!$pendingFile){
64 | Log::channel('employeeattendancelog')->info('No pending task!');
65 | return false;
66 | }
67 |
68 | //set file format
69 | $this->fileFormatType = intval($pendingFile->file_format);
70 | $this->createdBy = $pendingFile->created_by;
71 |
72 | $filePath = storage_path('app/employee-attendance/').$pendingFile->file_name;
73 | if(!file_exists($filePath)){
74 | Log::channel('employeeattendancelog')->critical('File not found! '.$pendingFile->file_name);
75 | return false;
76 | }
77 |
78 | //data imported class
79 | $presentStudentsByClass = [];
80 |
81 | //process present attendance student
82 | try{
83 |
84 | $dateWiseData = [];
85 | $totalValidRows = 0;
86 | //open the file and get line and process it
87 | $linecount = 0;
88 | $handle = fopen($filePath, "r");
89 | while(!feof($handle)){
90 | $line = fgets($handle, 4096);
91 | $linecount = $linecount + substr_count($line, PHP_EOL);
92 |
93 | if(!$linecount){
94 | throw new Exception("File is empty.");
95 | }
96 |
97 | $valid = AppHelper::isLineValid($line);
98 | if(!$valid){
99 | Log::channel('employeeattendancelog')->critical("Contain invalid data at line number ".$linecount);
100 | }
101 |
102 | $row = AppHelper::parseRowForEmployee($line, $this->fileFormatType);
103 |
104 | if(count($row)){
105 | $dateWiseData[$row['date']][] = [
106 | 'empId' => $row['id'],
107 | 'time' => $row['time']
108 | ];
109 |
110 | }
111 | }
112 | fclose($handle);
113 |
114 |
115 |
116 | $isFail = false;
117 |
118 | //now process data for one day
119 | foreach ($dateWiseData as $key => $oneDayData) {
120 | //build employee wise data
121 | $empWiseData = [];
122 | foreach ($oneDayData as $data) {
123 | $empWiseData[$data['empId']][] = $data['time'];
124 | }
125 |
126 | $atndDate = $key;
127 |
128 | //now clean employee multiple entry
129 | $cleanEmpWiseData = [];
130 | foreach ($empWiseData as $empId => $entries) {
131 | sort($entries);
132 | $entryCount = count($entries);
133 | $inTime = $entries[0];
134 | $outTime = $entryCount > 1 ? $entries[$entryCount - 1] : $inTime;
135 |
136 | $inTimeObject = Carbon::createFromFormat('YmdHis', $atndDate.$inTime);
137 | $outTimeObject = Carbon::createFromFormat('YmdHis', $atndDate.$outTime);
138 | $workTime = $inTimeObject->diff($outTimeObject)->format('%H:%I');
139 |
140 |
141 | $cleanEmpWiseData[$empId] = [
142 | 'inTime' => $inTimeObject,
143 | 'outTime' => $outTimeObject,
144 | 'workingHours' => $workTime
145 | ];
146 |
147 | $totalValidRows++;
148 |
149 | }
150 |
151 | //now push back one day data to $dateWiseDate array
152 | $dateWiseData[$atndDate] = $cleanEmpWiseData;
153 | }
154 |
155 | $pendingFile->total_rows = $totalValidRows;
156 | $pendingFile->imported_rows = 0;
157 | if(!$totalValidRows){
158 | $pendingFile->is_imported = -1;
159 | $pendingFile->save();
160 | throw new Exception('There are no valid data in this file.');
161 | }
162 |
163 | $pendingFile->updated_by = $this->createdBy;
164 | $pendingFile->save();
165 |
166 |
167 | //fetch all employees
168 | $employeesData = Employee::where('status', AppHelper::ACTIVE)->get()->reduce(function ($employeesData, $employee) {
169 | $employeesData[$employee->id_card] = [
170 | 'id' => $employee->id,
171 | 'in_time' => $employee->getOriginal('duty_start'),
172 | 'out_time' => $employee->getOriginal('duty_end'),
173 | ];
174 | return $employeesData;
175 | });
176 |
177 | $totalEmployee = count(array_keys($employeesData));
178 | $absentIds = [];
179 |
180 | if($totalEmployee){
181 | //ready to insert data to db
182 | $dateTimeNow = Carbon::now(env('APP_TIMEZONE','Asia/Dhaka'));
183 |
184 | foreach ($dateWiseData as $date => $employees) {
185 | $atd = new \DateTime(date('Ymd', strtotime($date)));
186 | $attendance_date = $atd->format('Y-m-d');
187 | $attendances = [];
188 |
189 | //check if this date data exists on db or not
190 | $entryExists = $this->isAttendanceExists($attendance_date);
191 | if ($entryExists) {
192 | $msg = "Date '".$atd->format('d/m/Y')."' > attendance override by multiple upload.";
193 | Log::channel('employeeattendancelog')->warning($msg);
194 | DB::table('employee_attendances')->whereDate('attendance_date', '=', $attendance_date)->delete();
195 | }
196 |
197 | DB::beginTransaction();
198 | try {
199 | //now build data array for insert into db table
200 | foreach ($employeesData as $employee => $employeeData) {
201 | $isPresent = "0";
202 | $status = [];
203 |
204 | $inTimeObject = Carbon::createFromFormat('Y-m-dH:i:s', $attendance_date."00:00:00");
205 | $outTimeObject = Carbon::createFromFormat('Y-m-dH:i:s', $attendance_date."00:00:00");
206 | $workingHours = $inTimeObject->diff($outTimeObject)->format('%H:%I');
207 |
208 | //check is this employee present
209 | if (array_key_exists($employee, $employees)) {
210 | $isPresent = "1";
211 | $inTimeObject = $employees[$employee]['inTime'];
212 | $outTimeObject = $employees[$employee]['outTime'];
213 | $workingHours = $employees[$employee]['workingHours'];
214 |
215 | //late or early out find
216 | if($employeeData['in_time'] && $employeeData['out_time']) {
217 | $empIntime = Carbon::createFromFormat('Y-m-d H:i:s',$attendance_date.' '.$employeeData['in_time']);
218 | if ($inTimeObject->greaterThan($empIntime)) {
219 | $status[] = 1;
220 | }
221 |
222 | $empOuttime = Carbon::createFromFormat('Y-m-d H:i:s',$attendance_date.' '.$employeeData['out_time']);
223 | if ($outTimeObject->lessThan($empOuttime)) {
224 | $status[] = 2;
225 | }
226 | }
227 |
228 | }
229 |
230 | $attendances[] = [
231 | "employee_id" => $employeeData['id'],
232 | "attendance_date" => $attendance_date,
233 | "in_time" => $inTimeObject,
234 | "out_time" => $outTimeObject,
235 | "working_hour" => $workingHours,
236 | "status" => implode(',',$status),
237 | "present" => $isPresent,
238 | "created_at" => $dateTimeNow,
239 | "created_by" => $this->createdBy,
240 | ];
241 |
242 | if(!$isPresent){
243 | $absentIds[$attendance_date][] = $employeeData['id'];
244 | }
245 |
246 | }
247 | EmployeeAttendance::insert($attendances);
248 | DB::commit();
249 | $msg = "Date '".$atd->format('d/m/Y')."' Total ".$totalEmployee." entry successfully stored.";
250 | Log::channel('employeeattendancelog')->info($msg);
251 |
252 |
253 | }
254 | catch (\Exception $e) {
255 | DB::rollback();
256 | $msg = "Date '".$atd->format('d/m/Y')."' data insert problem. ".$e->getMessage();
257 | Log::channel('employeeattendancelog')->error($msg);
258 | }
259 |
260 |
261 |
262 | $totalEmployeeInFile = count($employees);
263 | $pendingFile->imported_rows += $totalEmployeeInFile;
264 | $pendingFile->save();
265 |
266 | //write log in more entry found rather than db employee list
267 | if($totalEmployee<$totalEmployeeInFile){
268 | $msg = "Date '".$atd->format('d/m/Y')."' > ".($totalEmployeeInFile-$totalEmployee)." employee not found in db but found in attendance file!";
269 | Log::channel('employeeattendancelog')->warning($msg);
270 | }
271 |
272 |
273 | }
274 | }
275 | else{
276 | $isFail = true;
277 | Log::channel('employeeattendancelog')->critical("Employee not found on Database!");
278 | }
279 |
280 |
281 | if($isFail) {
282 | $pendingFile->is_imported = - 1;
283 | $pendingFile->updated_by = $this->createdBy;
284 | $pendingFile->save();
285 | }
286 |
287 | }
288 | catch (\Exception $e){
289 | $pendingFile->is_imported = -1;
290 | $pendingFile->updated_by = $this->createdBy;
291 | $pendingFile->save();
292 | $errorMSG = $e->getMessage();
293 | Log::channel('employeeattendancelog')->critical($errorMSG);
294 | return false;
295 | }
296 |
297 | //send notification for absent
298 | try {
299 | $sendNotification = AppHelper::getAppSettings('student_attendance_notification', true);
300 | if ($sendNotification != "0" && $pendingFile->send_notification) {
301 | foreach ($absentIds as $attendance_date => $employeeIds) {
302 | PushEmployeeAbsentJob::dispatch($employeeIds, $attendance_date)
303 | ->onQueue('absent');
304 | }
305 | }
306 | $pendingFile->is_imported = 1;
307 | $pendingFile->updated_by = $this->createdBy;
308 | $pendingFile->save();
309 | }
310 | catch (\Exception $e){
311 |
312 | $pendingFile->is_imported = -1;
313 | $pendingFile->updated_by = $this->createdBy;
314 | $pendingFile->save();
315 |
316 | $errorMSG = $e->getMessage();
317 | Log::channel('employeeattendancelog')->critical($errorMSG);
318 | return false;
319 | }
320 |
321 |
322 | $msg = "========File Queue Command Complete========";
323 | Log::channel('employeeattendancelog')->info($msg);
324 |
325 |
326 | }
327 |
328 | private function isAttendanceExists($attendance_date) {
329 | return $attendances = EmployeeAttendance::whereDate('attendance_date', $attendance_date)
330 | ->CountOrGet(true);
331 | }
332 | }
333 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/AcademicController.php:
--------------------------------------------------------------------------------
1 | isMethod('post')) {//
29 | $this->validate($request, [
30 | 'hiddenId' => 'required|integer',
31 | ]);
32 | $iclass = IClass::findOrFail($request->get('hiddenId'));
33 |
34 | $haveSection = Section::where('class_id', $iclass->id)->count();
35 | $haveStudent = Registration::where('class_id', $iclass->id)->count();
36 | if($haveStudent || $haveSection){
37 | return redirect()->route('academic.class')->with('error', 'Can not delete! Class used in section or have student.');
38 | }
39 |
40 | $iclass->delete();
41 |
42 | //now notify the admins about this record
43 | $msg = $iclass->name." class deleted by ".auth()->user()->name;
44 | $nothing = AppHelper::sendNotificationToAdmins('info', $msg);
45 | // Notification end
46 |
47 | //invalid cache
48 | Cache::forget('selected_classes_4_dashboard');
49 |
50 | return redirect()->route('academic.class')->with('success', 'Record deleted!');
51 | }
52 |
53 | //for get request
54 | $iclasses = IClass::select('id','name','numeric_value','order','status','note','group')->orderBy('order', 'asc')->get();
55 |
56 | return view('backend.academic.iclass.list', compact('iclasses'));
57 | }
58 |
59 | /**
60 | * class create, read, update manage
61 | * @return \Illuminate\Http\Response
62 | */
63 | public function classCru(Request $request, $id=0)
64 | {
65 | //for save on POST request
66 | if ($request->isMethod('post')) {
67 | ;
68 | $this->validate($request, [
69 | 'name' => 'required|min:2|max:255',
70 | 'numeric_value' => 'required|integer',
71 | 'order' => 'required|integer',
72 | 'group' => 'nullable|max:20',
73 | 'note' => 'max:500',
74 | ]);
75 |
76 | $data = $request->all();
77 | if(!$id){
78 | $data['status'] = AppHelper::ACTIVE;
79 |
80 | }
81 | else{
82 | unset($data['numeric_value']);
83 | }
84 |
85 | IClass::updateOrCreate(
86 | ['id' => $id],
87 | $data
88 | );
89 |
90 | if(!$id){
91 | //now notify the admins about this record
92 | $msg = $data['name']." class added by ".auth()->user()->name;
93 | $nothing = AppHelper::sendNotificationToAdmins('info', $msg);
94 | // Notification end
95 |
96 | //invalid cache
97 | Cache::forget('selected_classes_4_dashboard');
98 | }
99 |
100 |
101 | $msg = "Class ";
102 | $msg .= $id ? 'updated.' : 'added.';
103 |
104 | return redirect()->route('academic.class')->with('success', $msg);
105 | }
106 |
107 | //for get request
108 | $iclass = IClass::find($id);
109 | $group = 'None';
110 |
111 | if($iclass){
112 | $group = $iclass->group;
113 | }
114 |
115 | return view('backend.academic.iclass.add', compact('iclass','group'));
116 | }
117 |
118 | /**
119 | * class status change
120 | * @return mixed
121 | */
122 | public function classStatus(Request $request, $id=0)
123 | {
124 |
125 | $iclass = IClass::findOrFail($id);
126 | if(!$iclass){
127 | return [
128 | 'success' => false,
129 | 'message' => 'Record not found!'
130 | ];
131 | }
132 |
133 | $iclass->status = (string)$request->get('status');
134 |
135 | $iclass->save();
136 |
137 | return [
138 | 'success' => true,
139 | 'message' => 'Status updated.'
140 | ];
141 |
142 | }
143 |
144 |
145 | /**
146 | * section manage
147 | * @return \Illuminate\Http\Response
148 | */
149 | public function sectionIndex(Request $request)
150 | {
151 |
152 | //for save on POST request
153 | if ($request->isMethod('post')) {//
154 | $this->validate($request, [
155 | 'hiddenId' => 'required|integer',
156 | ]);
157 | $section = Section::findOrFail($request->get('hiddenId'));
158 |
159 | $haveStudent = Registration::where('section_id', $section->id)->count();
160 | if($haveStudent){
161 | return redirect()->route('academic.section')->with('error', 'Can not delete! Section have student.');
162 | }
163 |
164 | $section->delete();
165 |
166 | //now notify the admins about this record
167 | $msg = $section->name." section deleted by ".auth()->user()->name;
168 | $nothing = AppHelper::sendNotificationToAdmins('info', $msg);
169 | // Notification end
170 |
171 | return redirect()->route('academic.section')->with('success', 'Record deleted!');
172 | }
173 |
174 |
175 | // check for ajax request here
176 | if($request->ajax()){
177 | $class_id = $request->query->get('class', 0);
178 | $sections = Section::select('id', 'name as text')->where('class_id',$class_id)->where('status', AppHelper::ACTIVE)->orderBy('name', 'asc')->get();
179 | return $sections;
180 | }
181 |
182 | $sections = Section::with('teacher')->with('class')->orderBy('name', 'asc')->get();
183 |
184 | return view('backend.academic.section.list', compact('sections'));
185 | }
186 |
187 | /**
188 | * section create, read, update manage
189 | * @return \Illuminate\Http\Response
190 | */
191 | public function sectionCru(Request $request, $id=0)
192 | {
193 | //for save on POST request
194 | if ($request->isMethod('post')) {
195 | ;
196 | $this->validate($request, [
197 | 'name' => 'required|min:1|max:255',
198 | 'capacity' => 'required|numeric',
199 | 'class_id' => 'required|integer',
200 | 'teacher_id' => 'required|integer',
201 | 'note' => 'max:500',
202 | ]);
203 |
204 | $data = $request->all();
205 |
206 | Section::updateOrCreate(
207 | ['id' => $id],
208 | $data
209 | );
210 |
211 |
212 | if(!$id){
213 | //now notify the admins about this record
214 | $msg = $data['name']." section added by ".auth()->user()->name;
215 | $nothing = AppHelper::sendNotificationToAdmins('info', $msg);
216 | // Notification end
217 | }
218 |
219 | $msg = "section ";
220 | $msg .= $id ? 'updated.' : 'added.';
221 |
222 | return redirect()->route('academic.section')->with('success', $msg);
223 | }
224 |
225 | //for get request
226 | $section = Section::find($id);
227 |
228 | $teachers = Employee::where('role_id', AppHelper::EMP_TEACHER)
229 | ->where('status', AppHelper::ACTIVE)
230 | ->pluck('name', 'id');
231 | $teacher = null;
232 |
233 | $classes = IClass::where('status', AppHelper::ACTIVE)
234 | ->pluck('name', 'id');
235 | $iclass = null;
236 |
237 | if($section){
238 | $teacher = $section->teacher_id;
239 | $iclass = $section->class_id;
240 | }
241 |
242 | return view('backend.academic.section.add', compact('section', 'iclass', 'classes', 'teachers', 'teacher'));
243 | }
244 |
245 | /**
246 | * section status change
247 | * @return mixed
248 | */
249 | public function sectionStatus(Request $request, $id=0)
250 | {
251 |
252 | $section = Section::findOrFail($id);
253 | if(!$section){
254 | return [
255 | 'success' => false,
256 | 'message' => 'Record not found!'
257 | ];
258 | }
259 |
260 | $section->status = (string)$request->get('status');
261 |
262 | $section->save();
263 |
264 | return [
265 | 'success' => true,
266 | 'message' => 'Status updated.'
267 | ];
268 |
269 | }
270 |
271 |
272 | /**
273 | * subject manage
274 | * @return \Illuminate\Http\Response
275 | */
276 | public function subjectIndex(Request $request)
277 | {
278 |
279 | //for save on POST request
280 | if ($request->isMethod('post')) {//
281 | $this->validate($request, [
282 | 'hiddenId' => 'required|integer',
283 | ]);
284 | $subject = Subject::findOrFail($request->get('hiddenId'));
285 |
286 | //todo: add delete protection here
287 | // $haveExam = Exam::where('section_id', $subject->id)->count();
288 | // if($haveExam){
289 | // return redirect()->route('academic.section')->with('error', 'Can not delete! Section have student.');
290 | // }
291 |
292 | $subject->delete();
293 |
294 | //now notify the admins about this record
295 | $msg = $subject->name." subject deleted by ".auth()->user()->name;
296 | $nothing = AppHelper::sendNotificationToAdmins('info', $msg);
297 | // Notification end
298 |
299 | //invalid dashboard cache
300 | Cache::forget('SubjectCount');
301 |
302 | return redirect()->route('academic.subject')->with('success', 'Record deleted!');
303 | }
304 |
305 |
306 | // check for ajax request here
307 | if($request->ajax()){
308 | $class_id = $request->query->get('class', 0);
309 | $subjectType = $request->query->get('type', 0);
310 | $teacherId = 0;
311 | if(session('user_role_id',0) == AppHelper::USER_TEACHER){
312 | $teacherId = auth()->user()->teacher->id;
313 | }
314 | $subjects = Subject::select('id', 'name as text')
315 | ->where('class_id',$class_id)
316 | ->sType($subjectType)
317 | ->when($teacherId, function ($query) use($teacherId){
318 | $query->where('teacher_id', $teacherId);
319 | })
320 | ->where('status', AppHelper::ACTIVE)
321 | ->orderBy('name', 'asc')
322 | ->get();
323 | return $subjects;
324 | }
325 |
326 |
327 | $class_id = $request->query->get('class',0);
328 | $subjects = Subject::iclass($class_id)->with('teacher')->with('class')->orderBy('name', 'asc')->get();
329 | $classes = IClass::where('status', AppHelper::ACTIVE)
330 | ->pluck('name', 'id');
331 | $iclass = $class_id;
332 |
333 |
334 | return view('backend.academic.subject.list', compact('subjects','classes', 'iclass'));
335 | }
336 |
337 | /**
338 | * subject create, read, update manage
339 | * @return \Illuminate\Http\Response
340 | */
341 | public function subjectCru(Request $request, $id=0)
342 | {
343 | //for save on POST request
344 | if ($request->isMethod('post')) {
345 | ;
346 | $this->validate($request, [
347 | 'name' => 'required|min:1|max:255',
348 | 'code' => 'required|min:1|max:255',
349 | 'type' => 'required|numeric',
350 | 'class_id' => 'required|integer',
351 | 'teacher_id' => 'required|integer',
352 | ]);
353 |
354 | $data = $request->all();
355 |
356 | Subject::updateOrCreate(
357 | ['id' => $id],
358 | $data
359 | );
360 |
361 |
362 | if(!$id){
363 | //now notify the admins about this record
364 | $msg = $data['name']." subject added by ".auth()->user()->name;
365 | $nothing = AppHelper::sendNotificationToAdmins('info', $msg);
366 | // Notification end
367 |
368 | //invalid dashboard cache
369 | Cache::forget('SubjectCount');
370 | }
371 |
372 | $msg = "subject ";
373 | $msg .= $id ? 'updated.' : 'added.';
374 |
375 | return redirect()->route('academic.subject')->with('success', $msg);
376 | }
377 |
378 | //for get request
379 | $subject = Subject::find($id);
380 |
381 | $teachers = Employee::where('role_id', AppHelper::EMP_TEACHER)
382 | ->where('status', AppHelper::ACTIVE)
383 | ->pluck('name', 'id');
384 | $teacher = null;
385 |
386 | $classes = IClass::where('status', AppHelper::ACTIVE)
387 | ->pluck('name', 'id');
388 | $iclass = null;
389 | $subjectType = null;
390 |
391 | if($subject){
392 | $teacher = $subject->teacher_id;
393 | $iclass = $subject->class_id;
394 | $subjectType = $subject->getOriginal('type');
395 | }
396 |
397 | return view('backend.academic.subject.add', compact('subject', 'iclass', 'classes', 'teachers', 'teacher', 'subjectType'));
398 | }
399 |
400 | /**
401 | * subject status change
402 | * @return mixed
403 | */
404 | public function subjectStatus(Request $request, $id=0)
405 | {
406 |
407 | $subject = Subject::findOrFail($id);
408 | if(!$subject){
409 | return [
410 | 'success' => false,
411 | 'message' => 'Record not found!'
412 | ];
413 | }
414 |
415 | $subject->status = (string)$request->get('status');
416 |
417 | $subject->save();
418 |
419 | return [
420 | 'success' => true,
421 | 'message' => 'Status updated.'
422 | ];
423 |
424 | }
425 |
426 |
427 |
428 | }
429 |
--------------------------------------------------------------------------------
/public/svg/500.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/Console/Commands/SeedStudentAttendance.php:
--------------------------------------------------------------------------------
1 | where('is_imported','=',0)
57 | ->orderBy('created_at', 'DESC')
58 | ->first();
59 |
60 | if(!$pendingFile){
61 | Log::channel('studentattendancelog')->info('No pending task!');
62 | return false;
63 | }
64 |
65 | //set file format
66 | $this->fileFormatType = intval($pendingFile->file_format);
67 | $this->createdBy = $pendingFile->created_by;
68 |
69 | $filePath = storage_path('app/student-attendance/').$pendingFile->file_name;
70 | if(!file_exists($filePath)){
71 | Log::channel('studentattendancelog')->critical('File not found! '.$pendingFile->file_name);
72 | return false;
73 | }
74 |
75 | //data imported class
76 | $presentStudentsByClass = [];
77 |
78 | //process present attendance student
79 | try{
80 |
81 | $attendanceData = [];
82 | $totalValidRows = 0;
83 | //open the file and get line and process it
84 | $linecount = 0;
85 | $handle = fopen($filePath, "r");
86 | while(!feof($handle)){
87 | $line = fgets($handle, 4096);
88 | $linecount = $linecount + substr_count($line, PHP_EOL);
89 |
90 | if(!$linecount){
91 | throw new Exception("File is empty.");
92 | }
93 |
94 | $valid = AppHelper::isLineValid($line);
95 | if(!$valid){
96 | Log::channel('studentattendancelog')->critical("Contain invalid data at line number ".$linecount);
97 | }
98 |
99 | $row = AppHelper::parseRow($line, $this->fileFormatType);
100 | if(count($row)){
101 |
102 | $attendanceData[$row['date']][] = [
103 | 'studentId' => $row['id'],
104 | 'time' => $row['time']
105 | ];
106 |
107 | }
108 | }
109 | fclose($handle);
110 |
111 | //now process data for one day
112 | foreach ($attendanceData as $key => $oneDayData) {
113 | //build student wise data
114 | $studentWiseData = [];
115 | foreach ($oneDayData as $data) {
116 | $studentWiseData[$data['studentId']][] = $data['time'];
117 | }
118 |
119 | $atndDate = $key;
120 | //now clean student multiple entry
121 | $cleanstudentWiseData = [];
122 | foreach ($studentWiseData as $studentId => $entries) {
123 | sort($entries);
124 | $entryCount = count($entries);
125 | $inTime = $entries[0];
126 | $outTime = $entryCount > 1 ? $entries[$entryCount - 1] : $inTime;
127 |
128 | $inTimeObject = Carbon::createFromFormat('YmdHis', $atndDate.$inTime);
129 | $outTimeObject = Carbon::createFromFormat('YmdHis', $atndDate.$outTime);
130 | $stayingTime = $inTimeObject->diff($outTimeObject)->format('%H:%I');
131 |
132 |
133 | $cleanstudentWiseData[$studentId] = [
134 | 'inTime' => $inTimeObject,
135 | 'outTime' => $outTimeObject,
136 | 'stayingHours' => $stayingTime
137 | ];
138 |
139 | $totalValidRows++;
140 |
141 | }
142 | //now push back one day data to $dateWiseDate array
143 | $attendanceData[$atndDate] = $cleanstudentWiseData;
144 | }
145 |
146 |
147 | $pendingFile->total_rows = $totalValidRows;
148 | if(!$totalValidRows){
149 | $pendingFile->is_imported = -1;
150 | $pendingFile->save();
151 | throw new Exception('There are no valid data in this file.');
152 | }
153 |
154 | $pendingFile->updated_by = $this->createdBy;
155 | $pendingFile->save();
156 |
157 |
158 | $dateTimeNow = Carbon::now(env('APP_TIMEZONE','Asia/Dhaka'));
159 | $isFail = false;
160 |
161 | //pull shift running time
162 | //fetch institute shift running times
163 | $shiftData = AppHelper::getAppSettings('shift_data', true);
164 | if($shiftData){
165 | $shiftData = json_decode($shiftData, true);
166 | }
167 | $shiftRuningTimes = [];
168 |
169 | foreach ($shiftData as $shift => $times){
170 | $shiftRuningTimes[$shift] = [
171 | 'start' => $times['start'],
172 | 'end' => $times['end']
173 | ];
174 | }
175 |
176 | //now insert those data to db and
177 | foreach ($attendanceData as $kdate => $studentData) {
178 | try
179 | {
180 | $atd = new \DateTime(date('Ymd', strtotime($kdate)));
181 | $attendance_date = $atd->format('Y-m-d');
182 |
183 | // now fetch student id and class info
184 | $regiNumbers = array_keys($studentData);
185 | $presentStudents = Registration::select('id','class_id','regi_no','academic_year_id','shift')
186 | ->where('status', AppHelper::ACTIVE)
187 | ->whereIn('regi_no', $regiNumbers)
188 | ->get();
189 |
190 | $insertCounter = 0;
191 | foreach ($presentStudents as $student){
192 |
193 | //extract class id from here
194 | $presentStudentsByClass[$attendance_date][$student->class_id] = $student->academic_year_id;
195 |
196 | $entryExists = StudentAttendance::whereDate('attendance_date', '=', $attendance_date)
197 | ->where('registration_id', '=', $student->id)
198 | ->where('academic_year_id', $student->academic_year_id)
199 | ->where('class_id', $student->class_id)
200 | ->count();
201 |
202 | if(!$entryExists) {
203 |
204 | //find is late or early out
205 | $inTime = $studentData[$student->regi_no]['inTime'];
206 | $outTime = $studentData[$student->regi_no]['outTime'];
207 | $timeDiff = $inTime->diff($outTime)->format('%H:%I');
208 | $status = [];
209 | //late or early out find
210 | if($timeDiff != "00:00" && strlen($student->shift) && isset($shiftRuningTimes[$student->shift])){
211 |
212 | $shiftStart = Carbon::createFromFormat('Y-m-dh:i a', $attendance_date.$shiftRuningTimes[$student->shift]['start']);
213 | $shiftEnd = Carbon::createFromFormat('Y-m-dh:i a', $attendance_date.$shiftRuningTimes[$student->shift]['end']);
214 |
215 | if($inTime->greaterThan($shiftStart)){
216 | $status[] = 1;
217 | }
218 |
219 | if($outTime->lessThan($shiftEnd)){
220 | $status[] = 2;
221 | }
222 |
223 |
224 |
225 | }
226 |
227 | $singleAttendance = [
228 | "academic_year_id" => $student->academic_year_id,
229 | "class_id" => $student->class_id,
230 | "registration_id" => $student->id,
231 | "attendance_date" => $kdate,
232 | "in_time" => $inTime,
233 | "out_time" => $outTime,
234 | "staying_hour" => $timeDiff,
235 | "status" => implode(',',$status),
236 | "present" => "1",
237 | "created_at" => $dateTimeNow,
238 | "created_by" => $this->createdBy,
239 | ];
240 |
241 | StudentAttendance::insert($singleAttendance);
242 |
243 | $pendingFile->imported_rows = $pendingFile->imported_rows + 1;
244 | $pendingFile->save();
245 |
246 | $insertCounter++;
247 | }
248 | else{
249 | Log::channel('studentattendancelog')->warning('Attendance already exists for '.$student->regi_no.' and '.$kdate);
250 | }
251 |
252 | }
253 |
254 | Log::channel('studentattendancelog')->info('Total '.$insertCounter.' student attendance insert for '.$kdate);
255 |
256 | }catch (\Exception $e) {
257 | $isFail = true;
258 | $msg = "Date '".$kdate."' data insert problem. ".$e->getMessage();
259 | Log::channel('studentattendancelog')->critical($msg);
260 |
261 | }
262 |
263 | }
264 |
265 |
266 | if($isFail) {
267 | $pendingFile->is_imported = - 1;
268 | $pendingFile->updated_by = $this->createdBy;
269 | $pendingFile->save();
270 | }
271 |
272 | }
273 | catch (Exception $e){
274 | $pendingFile->is_imported = -1;
275 | $pendingFile->updated_by = $this->createdBy;
276 | $pendingFile->save();
277 | $errorMSG = $e->getMessage();
278 | Log::channel('studentattendancelog')->critical($errorMSG);
279 | return false;
280 | }
281 |
282 | //process absent attendance student
283 | $absentStudentIdsByDate = [];
284 | try {
285 | //find absent students
286 | foreach ($presentStudentsByClass as $pDate => $stClasses){
287 | $absentAttendances = [];
288 | $dateTimeNow = Carbon::now(env('APP_TIMEZONE','Asia/Dhaka'));
289 |
290 | foreach ($stClasses as $class_id => $academicYear){
291 | $absentStudents = Registration::where('status', AppHelper::ACTIVE)
292 | ->where('academic_year_id', $academicYear)
293 | ->where('class_id', $class_id)
294 | ->whereDoesntHave('attendance' , function ($query) use($pDate, $academicYear, $class_id) {
295 | $query->select('registration_id')
296 | ->where('academic_year_id', $academicYear)
297 | ->where('class_id', $class_id)
298 | ->whereDate('attendance_date', $pDate);
299 | })
300 | ->select('id','regi_no','roll_no','class_id','academic_year_id')
301 | ->get();
302 |
303 | //find is late or early out
304 | $inTime = Carbon::createFromFormat('Y-m-dHis', $pDate.'000000');
305 | $outTime = $inTime;
306 | $timeDiff = $inTime->diff($outTime)->format('%H:%I');
307 | $status = [];
308 |
309 | foreach ($absentStudents as $student){
310 | $absentAttendances[] = [
311 | "academic_year_id" => $student->academic_year_id,
312 | "class_id" => $student->class_id,
313 | "registration_id" => $student->id,
314 | "attendance_date" => $pDate,
315 | "in_time" => $inTime,
316 | "out_time" => $outTime,
317 | "staying_hour" => $timeDiff,
318 | "status" => implode(',',$status),
319 | "present" => "0",
320 | "created_at" => $dateTimeNow,
321 | "created_by" => $this->createdBy,
322 | ];
323 |
324 | $absentStudentIdsByDate[$pDate][] = $student->id;
325 | }
326 | }
327 |
328 | StudentAttendance::insert($absentAttendances);
329 | Log::channel('studentattendancelog')->info('Total '.count($absentAttendances).' absent student attendance insert for '.$pDate);
330 | }
331 | }
332 | catch (Exception $e){
333 | $pendingFile->is_imported = -1;
334 | $pendingFile->updated_by = $this->createdBy;
335 | $pendingFile->save();
336 | $errorMSG = $e->getMessage();
337 | Log::channel('studentattendancelog')->critical($errorMSG);
338 | return false;
339 | }
340 |
341 | //now invalid cache
342 | Cache::forget('student_attendance_count');
343 |
344 | //send notification for absent
345 | try {
346 | $sendNotification = AppHelper::getAppSettings('student_attendance_notification', true);
347 | if ($sendNotification != "0" && $pendingFile->send_notification) {
348 | foreach ($absentStudentIdsByDate as $attendance_date => $absentIds) {
349 | PushStudentAbsentJob::dispatch($absentIds, $attendance_date)
350 | ->onQueue('absent');
351 | }
352 | }
353 | $pendingFile->is_imported = 1;
354 | $pendingFile->updated_by = $this->createdBy;
355 | $pendingFile->save();
356 | }
357 | catch (Exception $e){
358 |
359 | $pendingFile->is_imported = -1;
360 | $pendingFile->updated_by = $this->createdBy;
361 | $pendingFile->save();
362 |
363 | $errorMSG = $e->getMessage();
364 | Log::channel('studentattendancelog')->critical($errorMSG);
365 | return false;
366 | }
367 |
368 |
369 | $msg = "========File Queue Command Complete========";
370 | Log::channel('studentattendancelog')->info($msg);
371 |
372 |
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 | 'role:admin'], function() {
17 | // Route::get('/admin', function() {
18 | // return 'Welcome Admin';
19 | // });
20 | //});
21 |
22 |
23 | /**
24 | * Admin panel routes goes below
25 | */
26 | Route::group(
27 | ['namespace' => 'Backend', 'middleware' => ['guest']], function () {
28 | Route::get('/login', 'UserController@login')->name('login');
29 | Route::post('/login', 'UserController@authenticate');
30 | Route::get('/forgot', 'UserController@forgot')->name('forgot');
31 | Route::post('/forgot', 'UserController@forgot')
32 | ->name('forgot');
33 | Route::get('/reset/{token}', 'UserController@reset')
34 | ->name('reset');
35 | Route::post('/reset/{token}', 'UserController@reset')
36 | ->name('reset');
37 |
38 | }
39 | );
40 |
41 | Route::get('/public/exam', 'Backend\ExamController@indexPublic')->name('public.exam_list');
42 | Route::any('/online-result', 'Backend\ReportController@marksheetPublic')->name('report.marksheet_pub');
43 |
44 | Route::group(
45 | ['namespace' => 'Backend', 'middleware' => ['auth', 'permission']], function () {
46 | Route::get('/logout', 'UserController@logout')->name('logout');
47 | Route::get('/lock', 'UserController@lock')->name('lockscreen');
48 | Route::get('/dashboard', 'UserController@dashboard')->name('user.dashboard');
49 |
50 | //user management
51 | Route::resource('user', 'UserController');
52 | Route::get('/profile', 'UserController@profile')
53 | ->name('profile');
54 | Route::post('/profile', 'UserController@profile')
55 | ->name('profile');
56 | Route::get('/change-password', 'UserController@changePassword')
57 | ->name('change_password');
58 | Route::post('/change-password', 'UserController@changePassword')
59 | ->name('change_password');
60 | Route::post('user/status/{id}', 'UserController@changeStatus')
61 | ->name('user.status');
62 | Route::any('user/{id}/permission', 'UserController@updatePermission')
63 | ->name('user.permission');
64 |
65 | //user notification
66 | Route::get('/notification/unread', 'NotificationController@getUnReadNotification')
67 | ->name('user.notification_unread');
68 | Route::get('/notification/read', 'NotificationController@getReadNotification')
69 | ->name('user.notification_read');
70 | Route::get('/notification/all', 'NotificationController@getAllNotification')
71 | ->name('user.notification_all');
72 |
73 | //system user management
74 | Route::get('/administrator/user', 'AdministratorController@userIndex')
75 | ->name('administrator.user_index');
76 | Route::get('/administrator/user/create', 'AdministratorController@userCreate')
77 | ->name('administrator.user_create');
78 | Route::post('/administrator/user/store', 'AdministratorController@userStore')
79 | ->name('administrator.user_store');
80 | Route::get('/administrator/user/{id}/edit', 'AdministratorController@userEdit')
81 | ->name('administrator.user_edit');
82 | Route::post('/administrator/user/{id}/update', 'AdministratorController@userUpdate')
83 | ->name('administrator.user_update');
84 | Route::post('/administrator/user/{id}/delete', 'AdministratorController@userDestroy')
85 | ->name('administrator.user_destroy');
86 | Route::post('administrator/user/status/{id}', 'AdministratorController@userChangeStatus')
87 | ->name('administrator.user_status');
88 |
89 | Route::any('/administrator/user/reset-password', 'AdministratorController@userResetPassword')
90 | ->name('administrator.user_password_reset');
91 |
92 |
93 |
94 | //user role manage
95 | Route::get('/role', 'UserController@roles')
96 | ->name('user.role_index');
97 | Route::post('/role', 'UserController@roles')
98 | ->name('user.role_destroy');
99 | Route::get('/role/create', 'UserController@roleCreate')
100 | ->name('user.role_create');
101 | Route::post('/role/store', 'UserController@roleCreate')
102 | ->name('user.role_store');
103 | Route::any('/role/update/{id}', 'UserController@roleUpdate')
104 | ->name('user.role_update');
105 |
106 |
107 | // application settings routes
108 | Route::get('settings/institute', 'SettingsController@institute')
109 | ->name('settings.institute');
110 | Route::post('settings/institute', 'SettingsController@institute')
111 | ->name('settings.institute');
112 |
113 | // academic calendar
114 | Route::get('settings/academic-calendar', 'SettingsController@academicCalendarIndex')
115 | ->name('settings.academic_calendar.index');
116 | Route::post('settings/academic-calendar', 'SettingsController@academicCalendarIndex')
117 | ->name('settings.academic_calendar.destroy');
118 | Route::get('settings/academic-calendar/create', 'SettingsController@academicCalendarCru')
119 | ->name('settings.academic_calendar.create');
120 | Route::post('settings/academic-calendar/create', 'SettingsController@academicCalendarCru')
121 | ->name('settings.academic_calendar.store');
122 | Route::get('settings/academic-calendar/edit/{id}', 'SettingsController@academicCalendarCru')
123 | ->name('settings.academic_calendar.edit');
124 | Route::post('settings/academic-calendar/update/{id}', 'SettingsController@academicCalendarCru')
125 | ->name('settings.academic_calendar.update');
126 |
127 | //sms gateways
128 | Route::get('settings/sms-gateway', 'SettingsController@smsGatewayIndex')
129 | ->name('settings.sms_gateway.index');
130 | Route::post('settings/sms-gateway', 'SettingsController@smsGatewayIndex')
131 | ->name('settings.sms_gateway.destroy');
132 | Route::get('settings/sms-gateway/create', 'SettingsController@smsGatewayCru')
133 | ->name('settings.sms_gateway.create');
134 | Route::post('settings/sms-gateway/create', 'SettingsController@smsGatewayCru')
135 | ->name('settings.sms_gateway.store');
136 | Route::get('settings/sms-gateway/edit/{id}', 'SettingsController@smsGatewayCru')
137 | ->name('settings.sms_gateway.edit');
138 | Route::post('settings/sms-gateway/update/{id}', 'SettingsController@smsGatewayCru')
139 | ->name('settings.sms_gateway.update');
140 |
141 | //report settings
142 | Route::get('settings/report', 'SettingsController@report')
143 | ->name('settings.report');
144 | Route::post('settings/report', 'SettingsController@report')
145 | ->name('settings.report');
146 |
147 |
148 | // administrator routes
149 | //academic year
150 | Route::get('administrator/academic_year', 'AdministratorController@academicYearIndex')
151 | ->name('administrator.academic_year');
152 | Route::post('administrator/academic_year', 'AdministratorController@academicYearIndex')
153 | ->name('administrator.academic_year_destroy');
154 | Route::get('administrator/academic_year/create', 'AdministratorController@academicYearCru')
155 | ->name('administrator.academic_year_create');
156 | Route::post('administrator/academic_year/create', 'AdministratorController@academicYearCru')
157 | ->name('administrator.academic_year_store');
158 | Route::get('administrator/academic_year/edit/{id}', 'AdministratorController@academicYearCru')
159 | ->name('administrator.academic_year_edit');
160 | Route::post('administrator/academic_year/update/{id}', 'AdministratorController@academicYearCru')
161 | ->name('administrator.academic_year_update');
162 | Route::post('administrator/academic_year/status/{id}', 'AdministratorController@academicYearChangeStatus')
163 | ->name('administrator.academic_year_status');
164 |
165 | // template
166 | //mail and sms
167 | Route::get('administrator/template-mailandsms', 'AdministratorController@templateMailAndSmsIndex')
168 | ->name('administrator.template.mailsms.index');
169 | Route::post('administrator/template-mailandsms', 'AdministratorController@templateMailAndSmsIndex')
170 | ->name('administrator.template.mailsms.destroy');
171 | Route::get('administrator/template-mailandsms/create', 'AdministratorController@templateMailAndSmsCru')
172 | ->name('administrator.template.mailsms.create');
173 | Route::post('administrator/template-mailandsms/create', 'AdministratorController@templateMailAndSmsCru')
174 | ->name('administrator.template.mailsms.store');
175 | Route::get('administrator/template-mailandsms/edit/{id}', 'AdministratorController@templateMailAndSmsCru')
176 | ->name('administrator.template.mailsms.edit');
177 | Route::post('administrator/template-mailandsms/update/{id}', 'AdministratorController@templateMailAndSmsCru')
178 | ->name('administrator.template.mailsms.update');
179 | // id card
180 | Route::get('administrator/template-idcard', 'AdministratorController@templateIdcardIndex')
181 | ->name('administrator.template.idcard.index');
182 | Route::post('administrator/template-idcard', 'AdministratorController@templateIdcardIndex')
183 | ->name('administrator.template.idcard.destroy');
184 | Route::get('administrator/template-idcard/create', 'AdministratorController@templateIdcardCru')
185 | ->name('administrator.template.idcard.create');
186 | Route::post('administrator/template-idcard/create', 'AdministratorController@templateIdcardCru')
187 | ->name('administrator.template.idcard.store');
188 | Route::get('administrator/template-idcard/edit/{id}', 'AdministratorController@templateIdcardCru')
189 | ->name('administrator.template.idcard.edit');
190 | Route::post('administrator/template-idcard/update/{id}', 'AdministratorController@templateIdcardCru')
191 | ->name('administrator.template.idcard.update');
192 |
193 |
194 | // academic routes
195 | // class
196 | Route::get('academic/class', 'AcademicController@classIndex')
197 | ->name('academic.class');
198 | Route::post('academic/class', 'AcademicController@classIndex')
199 | ->name('academic.class_destroy');
200 | Route::get('academic/class/create', 'AcademicController@classCru')
201 | ->name('academic.class_create');
202 | Route::post('academic/class/create', 'AcademicController@classCru')
203 | ->name('academic.class_store');
204 | Route::get('academic/class/edit/{id}', 'AcademicController@classCru')
205 | ->name('academic.class_edit');
206 | Route::post('academic/class/update/{id}', 'AcademicController@classCru')
207 | ->name('academic.class_update');
208 | Route::post('academic/class/status/{id}', 'AcademicController@classStatus')
209 | ->name('academic.class_status');
210 |
211 | // section
212 | Route::get('academic/section', 'AcademicController@sectionIndex')
213 | ->name('academic.section');
214 | Route::post('academic/section', 'AcademicController@sectionIndex')
215 | ->name('academic.section_destroy');
216 | Route::get('academic/section/create', 'AcademicController@sectionCru')
217 | ->name('academic.section_create');
218 | Route::post('academic/section/create', 'AcademicController@sectionCru')
219 | ->name('academic.section_store');
220 | Route::get('academic/section/edit/{id}', 'AcademicController@sectionCru')
221 | ->name('academic.section_edit');
222 | Route::post('academic/section/update/{id}', 'AcademicController@sectionCru')
223 | ->name('academic.section_update');
224 | Route::post('academic/section/status/{id}', 'AcademicController@sectionStatus')
225 | ->name('academic.section_status');
226 |
227 | // subject
228 | Route::get('academic/subject', 'AcademicController@subjectIndex')
229 | ->name('academic.subject');
230 | Route::post('academic/subject', 'AcademicController@subjectIndex')
231 | ->name('academic.subject_destroy');
232 | Route::get('academic/subject/create', 'AcademicController@subjectCru')
233 | ->name('academic.subject_create');
234 | Route::post('academic/subject/create', 'AcademicController@subjectCru')
235 | ->name('academic.subject_store');
236 | Route::get('academic/subject/edit/{id}', 'AcademicController@subjectCru')
237 | ->name('academic.subject_edit');
238 | Route::post('academic/subject/update/{id}', 'AcademicController@subjectCru')
239 | ->name('academic.subject_update');
240 | Route::post('academic/subject/status/{id}', 'AcademicController@subjectStatus')
241 | ->name('academic.subject_status');
242 |
243 |
244 | // teacher routes
245 | Route::resource('teacher', 'TeacherController');
246 | Route::post('teacher/status/{id}', 'TeacherController@changeStatus')
247 | ->name('teacher.status');
248 |
249 | // student routes
250 | Route::resource('student', 'StudentController');
251 | Route::post('student/status/{id}', 'StudentController@changeStatus')
252 | ->name('student.status');
253 | Route::get('student-list-by-filter', 'StudentController@studentListByFitler')
254 | ->name('student.list_by_fitler');
255 |
256 | // student attendance routes
257 | Route::get('student-attendance', 'StudentAttendanceController@index')->name('student_attendance.index');
258 | Route::any('student-attendance/create', 'StudentAttendanceController@create')->name('student_attendance.create');
259 | Route::post('student-attendance/store', 'StudentAttendanceController@store')->name('student_attendance.store');
260 | Route::post('student-attendance/status/{id}', 'StudentAttendanceController@changeStatus')
261 | ->name('student_attendance.status');
262 | Route::any('student-attendance/file-upload', 'StudentAttendanceController@createFromFile')
263 | ->name('student_attendance.create_file');
264 | Route::get('student-attendance/file-queue-status', 'StudentAttendanceController@fileQueueStatus')
265 | ->name('student_attendance.file_queue_status');
266 |
267 | // HRM
268 | //Employee
269 | Route::resource('hrm/employee', 'EmployeeController', ['as' => 'hrm']);
270 | Route::post('hrm/employee/status/{id}', 'EmployeeController@changeStatus')
271 | ->name('hrm.employee.status');
272 | // Leave
273 | Route::resource('hrm/leave', 'LeaveController', ['as' => 'hrm']);
274 | Route::resource('hrm/work_outside', 'WorkOutsideController', ['as' => 'hrm']);
275 | // policy
276 | Route::get('hrm/policy', 'EmployeeController@hrmPolicy')
277 | ->name('hrm.policy');
278 | Route::post('hrm/policy', 'EmployeeController@hrmPolicy')
279 | ->name('hrm.policy');
280 |
281 | // employee attendance routes
282 | Route::get('employee-attendance', 'EmployeeAttendanceController@index')->name('employee_attendance.index');
283 | Route::get('employee-attendance/create', 'EmployeeAttendanceController@create')->name('employee_attendance.create');
284 | Route::post('employee-attendance/create', 'EmployeeAttendanceController@store')->name('employee_attendance.store');
285 | Route::post('employee-attendance/status/{id}', 'EmployeeAttendanceController@changeStatus')
286 | ->name('employee_attendance.status');
287 | Route::any('employee-attendance/file-upload', 'EmployeeAttendanceController@createFromFile')
288 | ->name('employee_attendance.create_file');
289 | Route::get('employee-attendance/file-queue-status', 'EmployeeAttendanceController@fileQueueStatus')
290 | ->name('employee_attendance.file_queue_status');
291 |
292 |
293 | //exam
294 | Route::get('exam', 'ExamController@index')
295 | ->name('exam.index');
296 | Route::get('exam/create', 'ExamController@create')
297 | ->name('exam.create');
298 | Route::post('exam/store', 'ExamController@store')
299 | ->name('exam.store');
300 | Route::get('exam/edit/{id}', 'ExamController@edit')
301 | ->name('exam.edit');
302 | Route::post('exam/update/{id}', 'ExamController@update')
303 | ->name('exam.update');
304 | Route::post('exam/status/{id}', 'ExamController@changeStatus')
305 | ->name('exam.status');
306 | Route::post('exam/delete/{id}', 'ExamController@destroy')
307 | ->name('exam.destroy');
308 | //grade
309 | Route::get('exam/grade', 'ExamController@gradeIndex')
310 | ->name('exam.grade.index');
311 | Route::post('exam/grade', 'ExamController@gradeIndex')
312 | ->name('exam.grade.destroy');
313 | Route::get('exam/grade/create', 'ExamController@gradeCru')
314 | ->name('exam.grade.create');
315 | Route::post('exam/grade/create', 'ExamController@gradeCru')
316 | ->name('exam.grade.store');
317 | Route::get('exam/grade/edit/{id}', 'ExamController@gradeCru')
318 | ->name('exam.grade.edit');
319 | Route::post('exam/grade/update/{id}', 'ExamController@gradeCru')
320 | ->name('exam.grade.update');
321 | //exam rules
322 | Route::get('exam/rule', 'ExamController@ruleIndex')
323 | ->name('exam.rule.index');
324 | Route::post('exam/rule', 'ExamController@ruleIndex')
325 | ->name('exam.rule.destroy');
326 | Route::get('exam/rule/create', 'ExamController@ruleCreate')
327 | ->name('exam.rule.create');
328 | Route::post('exam/rule/create', 'ExamController@ruleCreate')
329 | ->name('exam.rule.store');
330 | Route::get('exam/rule/edit/{id}', 'ExamController@ruleEdit')
331 | ->name('exam.rule.edit');
332 | Route::post('exam/rule/update/{id}', 'ExamController@ruleEdit')
333 | ->name('exam.rule.update');
334 |
335 | //Marks
336 | Route::any('marks', 'MarkController@index')
337 | ->name('marks.index');
338 | Route::any('marks/create', 'MarkController@create')
339 | ->name('marks.create');
340 | Route::post('marks/store', 'MarkController@store')
341 | ->name('marks.store');
342 | Route::get('marks/edit/{id}', 'MarkController@edit')
343 | ->name('marks.edit');
344 | Route::post('marks/update/{id}', 'MarkController@update')
345 | ->name('marks.update');
346 | //result
347 | Route::any('result', 'MarkController@resultIndex')
348 | ->name('result.index');
349 | Route::any('result/generate', 'MarkController@resultGenerate')
350 | ->name('result.create');
351 | Route::any('result/delete', 'MarkController@resultDelete')
352 | ->name('result.delete');
353 |
354 | // Reporting
355 |
356 | Route::any('report/student-monthly-attendance', 'ReportController@studentMonthlyAttendance')
357 | ->name('report.student_monthly_attendance');
358 | Route::any('report/student-list', 'ReportController@studentList')
359 | ->name('report.student_list');
360 | Route::any('report/employee-list', 'ReportController@employeeList')
361 | ->name('report.employee_list');
362 | Route::any('report/employee-monthly-attendance', 'ReportController@employeeMonthlyAttendance')
363 | ->name('report.employee_monthly_attendance');
364 |
365 | });
366 |
367 | //web artisan routes
368 | Route::get(
369 | '/student-attendance-file-queue-start/{code}', function ($code) {
370 | if($code == "hr799"){
371 | try {
372 | echo '
Started student attendance processing...
';
373 | Artisan::call('attendance:seedStudent');
374 | echo '
Student attendance processing completed.
You will be redirect in 5 seconds.
';
375 | sleep(5);
376 |
377 | return redirect()->route('student_attendance.create_file')->with("success", "Students attendance saved and send sms successfully.");
378 |
379 | } catch (Exception $e) {
380 | Response::make($e->getMessage(), 500);
381 | }
382 | }else{
383 | App::abort(404);
384 | }
385 | }
386 | )->name('student_attendance_seeder');
387 | Route::get(
388 | '/employee-attendance-file-queue-start/{code}', function ($code) {
389 | if($code == "hr799"){
390 | try {
391 | echo '
Started employee attendance processing...
';
392 | Artisan::call('attendance:seedEmployee');
393 | echo '
Employee attendance processing completed.
You will be redirect in 5 seconds.
';
394 | sleep(5);
395 |
396 | return redirect()->route('employee_attendance.create_file')->with("success", "Employee attendance saved and notify successfully.");
397 |
398 | } catch (Exception $e) {
399 | Response::make($e->getMessage(), 500);
400 | }
401 | }else{
402 | App::abort(404);
403 | }
404 | }
405 | )->name('employee_attendance_seeder');
406 |
407 | //dev routes
408 | Route::get(
409 | '/make-link/{code}', function ($code) {
410 | if($code !== '007') {
411 | return 'Wrong code!';
412 | }
413 |
414 | //check if developer mode enabled?
415 | if(!env('DEVELOPER_MODE_ENABLED', false)) {
416 | return "Please enable developer mode in '.env' file.".PHP_EOL."set 'DEVELOPER_MODE_ENABLED=true'";
417 | }
418 | //remove first
419 | if(is_link(public_path('storage'))){
420 | unlink(public_path('storage'));
421 | }
422 |
423 |
424 | //create symbolic link for public image storage
425 | App::make('files')->link(storage_path('app/public'), public_path('storage'));
426 | return 'Done link';
427 | }
428 | );
429 | Route::get(
430 | '/cache-clear/{code}', function ($code) {
431 | if($code !== '007') {
432 | return 'Wrong code!';
433 | }
434 |
435 | //check if developer mode enabled?
436 | if(!env('DEVELOPER_MODE_ENABLED', false)) {
437 | return "Please enable developer mode in '.env' file.".PHP_EOL."set 'DEVELOPER_MODE_ENABLED=true'";
438 | }
439 |
440 | $exitCode = Artisan::call('cache:clear');
441 | $exitCode = Artisan::call('config:clear');
442 | $exitCode = Artisan::call('view:clear');
443 | $exitCode = Artisan::call('route:clear');
444 | return 'clear cache';
445 | }
446 | );
447 | //create tiggers
448 | Route::get(
449 | '/create-triggers/{code}', function ($code) {
450 | if($code !== '007') {
451 | return 'Wrong code!';
452 | }
453 |
454 | //check if developer mode enabled?
455 | if(!env('DEVELOPER_MODE_ENABLED', false)) {
456 | return "Please enable developer mode in '.env' file.".PHP_EOL."set 'DEVELOPER_MODE_ENABLED=true'";
457 | }
458 |
459 | AppHelper::createTriggers();
460 |
461 | return 'Triggers created :)';
462 | }
463 | );
464 | //test sms send
465 | Route::get(
466 | '/test-sms/{code}', function ($code) {
467 | if($code !== '007') {
468 | return 'Wrong code!';
469 | }
470 | //check if developer mode enabled?
471 | if(!env('DEVELOPER_MODE_ENABLED', false)) {
472 | return "Please enable developer mode in '.env' file.".PHP_EOL."set 'DEVELOPER_MODE_ENABLED=true'";
473 | }
474 |
475 | $gateway = \App\AppMeta::where('id', AppHelper::getAppSettings('student_attendance_gateway'))->first();
476 | $gateway = json_decode($gateway->meta_value);
477 | $smsHelper = new \App\Http\Helpers\SmsHelper($gateway);
478 | $res = $smsHelper->sendSms('8801722813644','test sms vai');
479 | dd($res);
480 | }
481 | );
482 |
--------------------------------------------------------------------------------