Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
CompanyRolePlayProject
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
6 / 6
7
100.00% covered (success)
100.00%
1 / 1
 newFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 company
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 creator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 scopeForCompany
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 scopeActive
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 scopeForGroups
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace App\Http\Models;
4
5use App\Http\Models\Admin\Company;
6use App\Http\Models\Auth\User;
7use Database\Factories\Http\Models\CompanyRolePlayProjectFactory;
8use Illuminate\Database\Eloquent\Factories\HasFactory;
9
10/**
11 * CompanyRolePlayProject Model
12 *
13 * Stores company-level roleplay projects that company admins create
14 * for their users to practice with. These projects serve as templates
15 * that can be assigned to specific groups within a company.
16 *
17 * @property string $id The unique identifier
18 * @property string $company_id The ID of the company that owns this project
19 * @property string $created_by The ID of the admin user who created this project
20 * @property string $name The name of the roleplay project
21 * @property string $type The type of call (e.g., 'cold-call', 'discovery-call')
22 * @property string|null $description A description of the roleplay scenario
23 * @property string $industry The target industry for the roleplay
24 * @property array<string> $target_job_titles Array of job titles targeted in this roleplay
25 * @property array<string> $key_features Array of key product/service features
26 * @property string|null $product_description Description of the product being sold
27 * @property int $difficulty_level The difficulty level (1-5)
28 * @property array<array{id: int, company_name: string, company_size: string, budget: string, decision_making: string, urgency_level: string, openess_to_new_solutions: string, communication_style: string, pain_points: string, current_solution: string, personality: string}> $customer_profiles Array of customer profile objects
29 * @property array $training_personalities Array of training personality configurations
30 * @property array<array{name: string, is_default: bool, weight: int, criteria: array}> $scorecard_config Array of scorecard configuration objects
31 * @property array<array{category: string, options: array<string>}> $objections Array of objection objects with categories and options
32 * @property bool $allow_user_customization Whether users can customize the project when cloning
33 * @property array<string> $assigned_groups Array of group IDs this project is assigned to (empty means all users)
34 * @property string $status The project status ('active', 'inactive', 'archived')
35 * @property \Illuminate\Support\Carbon|null $created_at
36 * @property \Illuminate\Support\Carbon|null $updated_at
37 *
38 * @property-read \App\Http\Models\Admin\Company $company
39 * @property-read \App\Http\Models\Auth\User $creator
40 */
41class CompanyRolePlayProject extends Moloquent
42{
43    use HasFactory;
44
45    /**
46     * The database table (collection) used by the model.
47     *
48     * @var string
49     */
50    protected $table = 'company_roleplay_projects';
51
52    /**
53     * The attributes that are mass assignable.
54     *
55     * @var array<int, string>
56     */
57    protected $fillable = [
58        'company_id',
59        'created_by',
60        'name',
61        'type',
62        'description',
63        'industry',
64        'target_job_titles',
65        'key_features',
66        'product_description',
67        'difficulty_level',
68        'customer_profiles',
69        'training_personalities',
70        'scorecard_config',
71        'objections',
72        'allow_user_customization',
73        'assigned_groups',
74        'status',
75    ];
76
77    /**
78     * The attributes that should be cast.
79     *
80     * @var array<string, string>
81     */
82    protected $casts = [
83        'allow_user_customization' => 'boolean',
84        'difficulty_level' => 'integer',
85        'created_at' => 'datetime',
86        'updated_at' => 'datetime',
87    ];
88
89    /**
90     * Create a new factory instance for the model.
91     *
92     * @return \Database\Factories\Http\Models\CompanyRolePlayProjectFactory
93     */
94    protected static function newFactory()
95    {
96        return CompanyRolePlayProjectFactory::new();
97    }
98
99    /**
100     * Get the company that owns this roleplay project.
101     *
102     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
103     */
104    public function company()
105    {
106        return $this->belongsTo(Company::class, 'company_id');
107    }
108
109    /**
110     * Get the admin user who created this project.
111     *
112     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
113     */
114    public function creator()
115    {
116        return $this->belongsTo(User::class, 'created_by');
117    }
118
119    /**
120     * Scope query to projects belonging to a specific company.
121     *
122     * @param \Illuminate\Database\Eloquent\Builder $query
123     * @param string $companyId The company ID to filter by
124     * @return \Illuminate\Database\Eloquent\Builder
125     */
126    public function scopeForCompany($query, $companyId)
127    {
128        return $query->where('company_id', $companyId);
129    }
130
131    /**
132     * Scope query to only active projects.
133     *
134     * @param \Illuminate\Database\Eloquent\Builder $query
135     * @return \Illuminate\Database\Eloquent\Builder
136     */
137    public function scopeActive($query)
138    {
139        return $query->where('status', 'active');
140    }
141
142    /**
143     * Scope query to projects assigned to specific groups.
144     *
145     * Projects with empty or null assigned_groups are available to all users,
146     * so they are always included in the results.
147     *
148     * @param \Illuminate\Database\Eloquent\Builder $query
149     * @param array<string> $groupIds The group IDs to filter by
150     * @return \Illuminate\Database\Eloquent\Builder
151     */
152    public function scopeForGroups($query, array $groupIds)
153    {
154        return $query->where(function ($q) use ($groupIds) {
155            // Match projects assigned to any of the given groups
156            if (! empty($groupIds)) {
157                $q->whereIn('assigned_groups', $groupIds);
158            }
159            // Also include projects with no group restriction (available to all)
160            $q->orWhereNull('assigned_groups')
161                ->orWhere('assigned_groups', []);
162        });
163    }
164}