Passed
Push — master ( 49a2c9...58d635 )
by Thomas
07:31
created

ReportController::genderReport()   B

Complexity

Conditions 8
Paths 1

Size

Total Lines 34
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 24
nc 1
nop 1
dl 0
loc 34
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Models\Config;
6
use App\Models\Course;
7
use App\Models\Partner;
8
use App\Models\Period;
9
use App\Models\Year;
10
use App\Traits\PeriodSelection;
11
use Carbon\Carbon;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Facades\Log;
14
15
class ReportController extends Controller
16
{
17
    use PeriodSelection;
0 ignored issues
show
Bug introduced by
The trait App\Traits\PeriodSelection requires the property $id which is not provided by App\Http\Controllers\ReportController.
Loading history...
18
19
    public function index()
20
    {
21
        $currentPeriod = Period::get_default_period();
22
        $enrollmentsPeriod = Period::get_enrollments_period();
23
24
        return view('reports.index', [
25
            'currentPeriod' => $currentPeriod,
26
            'enrollmentsPeriod' => $enrollmentsPeriod,
27
            'pending_enrollment_count' => $currentPeriod->pending_enrollments_count,
28
            'paid_enrollment_count' => $currentPeriod->paid_enrollments_count,
29
            'total_enrollment_count' => $currentPeriod->internal_enrollments_count,
30
            'students_count' => $currentPeriod->studentCount(),
31
        ]);
32
    }
33
34
    public function external2(Request $request)
35
    {
36
        $data = [];
37
        $report_start_date = $request->report_start_date ?? Carbon::parse('2019-01-01');
38
        $report_end_date = $request->report_end_date ?? Carbon::now();
39
40
        $courses = Course::external()->where('end_date', '>', $report_start_date)->where('start_date', '<', $report_end_date)->get();
41
42
        $data['courses'] = $courses->count();
43
        $data['enrollments'] = $courses->sum('head_count');
44
        $data['students'] = $courses->sum('new_students');
45
        $data['taught_hours'] = $courses->where('parent_course_id', null)->sum('total_volume');
46
        $total = 0;
47
        foreach ($courses->where('parent_course_id', null) as $course) {
48
            $total += $course->total_volume * $course->head_count;
49
        }
50
        $data['sold_hours'] = $total;
51
52
        return view('reports.external2', [
53
            'start' => Carbon::parse($report_start_date)->format('Y-m-d'),
54
            'end' => Carbon::parse($report_end_date)->format('Y-m-d'),
55
            'data' => $data,
56
            'courses' => $courses,
57
        ]);
58
    }
59
60
    public function external(Request $request)
61
    {
62
        $data = [];
63
        $year_data = [];
64
        $years = []; // New array
65
66
        if (! isset($request->period)) {
67
            $startperiod = Period::find(Config::where('name', 'first_external_period')->first()->value ?? Period::first()->id);
68
        } else {
69
            $startperiod = Period::find($request->period);
70
        }
71
72
        $periods = Period::where('id', '>=', $startperiod->id)->get();
73
74
        $current_year_id = $startperiod->year_id;
75
        $year_data[$current_year_id] = [];
76
        $year_data[$current_year_id]['year_name'] = Year::find($current_year_id)->name;
77
        $year_data[$current_year_id]['students'] = 0;
78
        $year_data[$current_year_id]['enrollments'] = 0;
79
        $year_data[$current_year_id]['taught_hours'] = 0;
80
        $year_data[$current_year_id]['sold_hours'] = 0;
81
82
        foreach ($periods as $i => $data_period) {
83
            $data[$data_period->id]['period'] = $data_period->name;
84
            $data[$data_period->id]['year_id'] = $data_period->year_id;
85
            $data[$data_period->id]['courses'] = $data_period->external_courses_count;
86
            $data[$data_period->id]['partnerships'] = $data_period->partnerships_count;
87
            $data[$data_period->id]['enrollments'] = $data_period->external_enrollments_count;
88
            $data[$data_period->id]['students'] = $data_period->external_students_count;
89
            $data[$data_period->id]['taught_hours'] = $data_period->external_taught_hours_count;
90
            $data[$data_period->id]['sold_hours'] = $data_period->external_sold_hours_count;
91
92
            // if we are starting a new year, push the year data to the array
93
            if ($current_year_id != $data_period->year_id) {
94
                $current_year_id = $data_period->year_id;
95
96
                $year_data[$current_year_id] = [];
97
                $year_data[$current_year_id]['year_name'] = Year::find($current_year_id)->name;
98
                $year_data[$current_year_id]['students'] = 0;
99
                $year_data[$current_year_id]['enrollments'] = 0;
100
                $year_data[$current_year_id]['taught_hours'] = 0;
101
                $year_data[$current_year_id]['sold_hours'] = 0;
102
            }
103
104
            $year_data[$current_year_id]['students'] += $data_period->external_students_count;
105
            $year_data[$current_year_id]['enrollments'] += $data_period->external_enrollments_count;
106
            $year_data[$current_year_id]['taught_hours'] += $data_period->external_taught_hours_count;
107
            $year_data[$current_year_id]['sold_hours'] += $data_period->external_sold_hours_count;
108
109
            $year = Year::find($data_period->year_id)->append('partnerships');
110
            $years[$data_period->year_id]['year'] = $year->name; // New array using the Model
111
            $years[$data_period->year_id]['partnerships'] = $year->partnerships;
112
        }
113
114
        return view('reports.external', [
115
            'selected_period' => $startperiod,
116
            'data' => $data,
117
            'year_data' => $year_data, // Existing array
118
            'years' => $years,
119
        ]);
120
    }
121
122
    public function external3()
123
    {
124
        return view('reports.external3', [
125
            'partners' => Partner::all(),
126
        ]);
127
    }
128
129
    public function partner(Partner $partner, Request $request)
130
    {
131
        $data = [];
132
        $report_start_date = $request->report_start_date ?? Carbon::parse('2019-01-01');
133
        $report_end_date = $request->report_end_date ?? Carbon::now();
134
135
        $courses = Course::external()->where('partner_id', $partner->id)->where('end_date', '>', $report_start_date)->where('start_date', '<', $report_end_date)->get();
136
137
        $data['courses'] = $courses->count();
138
        $data['enrollments'] = $courses->sum('head_count');
139
        $data['students'] = $courses->sum('new_students');
140
        $data['taught_hours'] = $courses->where('parent_course_id', null)->sum('total_volume');
141
        $total = 0;
142
        foreach ($courses->where('parent_course_id', null) as $course) {
143
            $total += $course->total_volume * $course->head_count;
144
        }
145
        $data['sold_hours'] = $total;
146
147
        return view('reports.partner', [
148
            'partner' => $partner,
149
            'start' => Carbon::parse($report_start_date)->format('Y-m-d'),
150
            'end' => Carbon::parse($report_end_date)->format('Y-m-d'),
151
            'data' => $data,
152
        ]);
153
    }
154
155
    /**
156
     * The reports dashboard
157
     * Displays last insights on enrollments; along with comparison to previous periods.
158
     *
159
     * Todo - optimize this method: is there another way than using an array? How to reduce the number of queries?
160
     * Todo - Limit to the three last years to keep the figures readable
161
     */
162
    public function internal(Request $request)
163
    {
164
        $period = Period::get_default_period();
165
166
        $startperiod = $this->getStartperiod($request);
167
168
        $periods = Period::orderBy('year_id')->orderBy('order')->orderBy('id')->where('id', '>=', $startperiod->id)->get();
169
170
        $data = [];
171
        $years = [];
172
173
        foreach ($periods as $data_period) {
174
            $data[$data_period->id]['period'] = $data_period->name;
175
            $data[$data_period->id]['year_id'] = $data_period->year_id;
176
177
            $data[$data_period->id]['enrollments'] = $data_period->internal_enrollments_count;
178
            $data[$data_period->id]['students'] = $data_period->studentCount();
179
            $data[$data_period->id]['acquisition_rate'] = $data_period->acquisition_rate;
180
            $data[$data_period->id]['new_students'] = $data_period->newStudents()->count();
181
            $data[$data_period->id]['taught_hours'] = $data_period->period_taught_hours_count;
182
            $data[$data_period->id]['sold_hours'] = $data_period->period_sold_hours_count;
183
            $data[$data_period->id]['takings'] = $data_period->takings;
184
            $data[$data_period->id]['avg_takings'] = $data_period->takings / max(1, $data_period->period_taught_hours_count);
185
            $years[$data_period->year_id] = Year::find($data_period->year_id); // New array using the Model
186
        }
187
188
        return view('reports.internal', [
189
            'pending_enrollment_count' => $period->pending_enrollments_count,
190
            'paid_enrollment_count' => $period->paid_enrollments_count,
191
            'total_enrollment_count' => $period->internal_enrollments_count,
192
            'students_count' => $period->studentCount(),
193
            'data' => $data,
194
            'selected_period' => $startperiod,
195
            'years' => $years, // New array
196
        ]);
197
    }
198
199
    public function genderReport(Request $request)
200
    {
201
        $startperiod = $this->getStartperiod($request);
202
        $data = Period::orderBy('year_id')->orderBy('order')->orderBy('id')
203
            ->where('id', '>=', $startperiod->id)
204
            ->get()
205
            ->groupBy('year_id')
206
            ->map(function($yearData) {
207
                $yearPeriods = [];
208
209
                foreach ($yearData as $period) {
210
                    $studentCountInPeriod = $period->studentCount();
211
212
                    $yearPeriods[$period->id]['period'] = $period->name;
213
                    $yearPeriods[$period->id]['male'] = $studentCountInPeriod > 0 ? 100 * $period->studentCount(2) / $studentCountInPeriod : 0;
214
                    $yearPeriods[$period->id]['female'] = $studentCountInPeriod > 0 ? 100 * $period->studentCount(1) / $studentCountInPeriod : 0;
215
                    $yearPeriods[$period->id]['unknown'] = $studentCountInPeriod > 0 ? 100 * $period->studentCount(0) / $studentCountInPeriod : 0;
216
                }
217
218
                $year = $yearData[0]->year;
219
                $studentCountInYear = $year->studentCount();
220
221
                return [
222
                    'year' => $year->name,
223
                    'male' => $studentCountInYear > 0 ? 100 * $year->studentCount(2) / $studentCountInYear : 0,
224
                    'female' => $studentCountInYear > 0 ? 100 * $year->studentCount(1) / $studentCountInYear : 0,
225
                    'unknown' => $studentCountInYear > 0 ? 100 * $year->studentCount(0) / $studentCountInYear : 0,
226
                    'periods' => $yearPeriods,
227
                ];
228
            });
229
230
        return view('reports.gender', [
231
            'data' => $data,
232
            'selected_period' => $startperiod,
233
        ]);
234
    }
235
236
    /**
237
     * Show the enrollment numbers per rhythm.
238
     */
239
    public function rhythms(Request $request)
240
    {
241
        $period = $this->selectPeriod($request);
242
243
        $count = $period->courses()->where('parent_course_id', null)->with('rhythm')->withCount('enrollments')
244
            ->get()
245
            ->where('enrollments_count', '>', 0)
246
            ->groupBy('rhythm_id');
247
248
        $data = [];
249
250
        foreach ($count as $i => $course) {
251
            $data[$i]['rhythm'] = $course[0]->rhythm->name ?? 'Other';
252
            $data[$i]['enrollment_count'] = $course->sum('enrollments_count');
253
        }
254
255
        return view('reports.rhythms', [
256
            'selected_period' => $period,
257
            'data' => $data,
258
        ]);
259
    }
260
261
    /** Number of students per course */
262
    public function courses(Request $request)
263
    {
264
        $period = $this->selectPeriod($request);
265
266
        $courses = $period->courses()->where('parent_course_id', null)->withCount('enrollments')->orderBy('enrollments_count')->get()->where('enrollments_count', '>', 0);
267
268
        $averageStudentCount = $courses->average('enrollments_count');
269
270
        return view('reports.courses', [
271
            'selected_period' => $period,
272
            'courses' => $courses,
273
            'averageStudentCount' => round($averageStudentCount, 1),
274
        ]);
275
    }
276
277
    /** Number of students per level */
278
    public function levels(Request $request)
279
    {
280
        $period = $this->selectPeriod($request);
281
282
        $count = $period->courses()->where('parent_course_id', null)->with('level')->withCount('enrollments')
283
            ->get()
284
            ->where('enrollments_count', '>', 0)
285
            ->groupBy('level.reference');
286
287
        $data = [];
288
289
        foreach ($count as $i => $coursegroup) {
290
            $data[$i]['level'] = $coursegroup[0]->level->reference ?? 'Other';
291
            $data[$i]['enrollment_count'] = $coursegroup->sum('enrollments_count');
292
            $data[$i]['taught_hours_count'] = $coursegroup->sum('total_volume');
293
294
            $total = 0;
295
            foreach ($coursegroup as $course) {
296
                $total += $course->total_volume * $course->enrollments()->real()->count();
297
            }
298
299
            $data[$i]['sold_hours_count'] = $total;
300
        }
301
302
        return view('reports.levels', [
303
            'selected_period' => $period,
304
            'data' => $data,
305
        ]);
306
    }
307
308
    private function getStartperiod(Request $request)
309
    {
310
        if (!isset($request->period)) {
311
            $startperiod = Period::find(Config::where('name', 'first_period')->first()->value);
312
        } else {
313
            $startperiod = Period::find($request->period);
314
        }
315
        return $startperiod;
316
    }
317
}
318