Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
RoleplayLevelsReportRequest
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
3 / 3
11
100.00% covered (success)
100.00%
1 / 1
 authorize
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
8
 rules
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 prepareForValidation
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace App\Http\Requests\v2\Admin\Report;
4
5use App\Http\Models\Auth\Role;
6use Illuminate\Foundation\Http\FormRequest;
7
8/**
9 * Validated request for the "roleplay levels" admin distribution report.
10 *
11 * Filters follow the conventions used by the existing admin report endpoints
12 * (see {@see \App\Http\Requests\v2\Reports\GetReportRequest}): `from`/`to`
13 * for the date window and `company_ids` (comma-separated) for company
14 * scoping. `cmc=1` allows a Vengreso super-admin to see a global distribution
15 * across all companies.
16 *
17 * @property string|null $from Inclusive start of the session date range (Y-m-d)
18 * @property string|null $to Inclusive end of the session date range (Y-m-d)
19 * @property string|null $company_ids Comma-separated list of company IDs to scope to
20 * @property bool|null $cmc Whether the caller is in CMC (global) mode
21 * @property string|null $call_type Optional call type filter (cold-call, discovery-call)
22 */
23class RoleplayLevelsReportRequest extends FormRequest
24{
25    /**
26     * Authorize the request. Mirrors the baseline rules used by the existing
27     * reporting endpoints: Vengreso super-admins can use CMC mode and see
28     * everything; company admins can only scope to their own company.
29     */
30    public function authorize(): bool
31    {
32        $user = $this->user();
33        if (! $user) {
34            return false;
35        }
36
37        $roles = $user->roles();
38
39        if (in_array(Role::VENGRESO_ADMIN, $roles, true)) {
40            return true;
41        }
42
43        // Non-super-admins cannot use the CMC (global) flag.
44        if (filter_var($this->input('cmc'), FILTER_VALIDATE_BOOLEAN)) {
45            return false;
46        }
47
48        // All other admin roles must belong to a company.
49        if (empty($user->company_id)) {
50            return false;
51        }
52
53        // Admin/Global/Group/Reporting admins may read their own company's data.
54        $adminRoles = [Role::GLOBAL_ADMIN, Role::GROUP_ADMIN, Role::REPORTING_ADMIN];
55        if (! array_intersect($adminRoles, $roles)) {
56            return false;
57        }
58
59        // If a specific company_ids list is passed, it must match the caller's company.
60        $requested = array_values(array_filter(explode(',', (string) $this->input('company_ids', ''))));
61        if (! empty($requested)) {
62            $unauthorized = array_diff($requested, [$user->company_id]);
63            if (! empty($unauthorized)) {
64                return false;
65            }
66        }
67
68        return true;
69    }
70
71    /**
72     * Validation rules for the roleplay levels report query string.
73     *
74     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
75     */
76    public function rules(): array
77    {
78        return [
79            'cmc' => 'sometimes|boolean',
80            'from' => 'sometimes|date',
81            'to' => 'sometimes|date|after_or_equal:from',
82            'company_ids' => 'sometimes|string',
83            'call_type' => 'sometimes|string|in:cold-call,discovery-call',
84        ];
85    }
86
87    /**
88     * Normalise query-string values before validation runs (GET requests deliver
89     * booleans as strings).
90     */
91    protected function prepareForValidation(): void
92    {
93        if ($this->has('cmc')) {
94            $this->merge([
95                'cmc' => filter_var($this->input('cmc'), FILTER_VALIDATE_BOOLEAN),
96            ]);
97        }
98    }
99}