Created
January 15, 2021 16:02
-
-
Save paulcervov/12f12ac21d7beac512d26b7be0491b23 to your computer and use it in GitHub Desktop.
Laravel code examples for AbeloHost
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\SoftDeletes; | |
class Category extends Model | |
{ | |
use SoftDeletes; | |
const TYPES = [ | |
'groups' => 'Группы', | |
'problems' => 'Проблемы', | |
'services' => 'Услуги', | |
'centers' => 'Центры', | |
]; | |
/** | |
* The attributes that are mass assignable. | |
* | |
* @var array | |
*/ | |
protected $fillable = [ | |
'name', 'slug', 'description', | |
]; | |
/** | |
* The number of models to return for pagination. | |
* | |
* @var int | |
*/ | |
protected $perPage = 5; | |
/** | |
* Get all of the groups that are assigned this category. | |
*/ | |
public function groups() | |
{ | |
return $this->morphedByMany(Group::class, 'categorizable'); | |
} | |
/** | |
* Get all of the problems that are assigned this category. | |
*/ | |
public function problems() | |
{ | |
return $this->morphedByMany(Problem::class, 'categorizable'); | |
} | |
/** | |
* Get all of the services that are assigned this category. | |
*/ | |
public function services() | |
{ | |
return $this->morphedByMany(Service::class, 'categorizable'); | |
} | |
/** | |
* Get all of the centers that are assigned this category. | |
*/ | |
public function centers() | |
{ | |
return $this->morphedByMany(Center::class, 'categorizable'); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers\Api; | |
use App\Center; | |
use App\Http\Controllers\Controller; | |
use App\User; | |
use Illuminate\Http\Response; | |
class CenterController extends Controller | |
{ | |
/** | |
* Display a listing of the resource. | |
* | |
* @return Response | |
*/ | |
public function index() | |
{ | |
return Center::query() | |
->when(request('name'), function ($q, $name) { | |
return $q->where('name', 'like', "%{$name}%"); | |
}) | |
->when(in_array(auth()->user()->role_id, [ | |
User::ID_ROLE_MANAGER, | |
User::ID_ROLE_OWNER | |
]), function ($q) { | |
return $q->whereHas('company', function ($q) { | |
$q | |
->when(in_array(auth()->user()->role_id, [User::ID_ROLE_MANAGER]), function ($q) { | |
return $q->where('manager_id', auth()->id()); | |
}) | |
->when(in_array(auth()->user()->role_id, [User::ID_ROLE_OWNER]), function ($q) { | |
return $q->where('owner_id', auth()->id()); | |
}); | |
}); | |
}) | |
->paginate(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Policies; | |
use App\Company; | |
use App\User; | |
use Illuminate\Auth\Access\HandlesAuthorization; | |
class CompanyPolicy | |
{ | |
use HandlesAuthorization; | |
/** | |
* Determine whether the user can view any models. | |
* | |
* @param \App\User $user | |
* @return mixed | |
*/ | |
public function viewAny(User $user) | |
{ | |
return in_array($user->role_id, [ | |
User::ID_ROLE_ADMINISTRATOR, | |
USER::ID_ROLE_MANAGER, | |
]); | |
} | |
/** | |
* Determine whether the user can create models. | |
* | |
* @param \App\User $user | |
* @return mixed | |
*/ | |
public function create(User $user) | |
{ | |
return in_array($user->role_id, [ | |
User::ID_ROLE_ADMINISTRATOR, | |
USER::ID_ROLE_MANAGER | |
]); | |
} | |
/** | |
* Determine whether the user can update the model. | |
* | |
* @param \App\User $user | |
* @param \App\Company $company | |
* @return mixed | |
*/ | |
public function update(User $user, Company $company) | |
{ | |
if (in_array($user->role_id, [User::ID_ROLE_ADMINISTRATOR])) { | |
return true; | |
} | |
if ( | |
in_array($user->role_id, [User::ID_ROLE_MANAGER]) | |
&& $user->id == $company->manager_id | |
) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Determine whether the user can delete the model. | |
* | |
* @param \App\User $user | |
* @param \App\Company $company | |
* @return mixed | |
*/ | |
public function delete(User $user, Company $company) | |
{ | |
return in_array($user->role_id, [User::ID_ROLE_ADMINISTRATOR]); | |
} | |
/** | |
* Determine whether the user can restore the model. | |
* | |
* @param \App\User $user | |
* @param \App\Company $company | |
* @return mixed | |
*/ | |
public function restore(User $user, Company $company) | |
{ | |
return in_array($user->role_id, [User::ID_ROLE_ADMINISTRATOR]); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<tr class="d-flex"> | |
<td class="col-sm-3">{{ $user->full_name }}</td> | |
<td class="col-sm-3">{{ $user->phone }}</td> | |
<td class="col-sm-2">{{ \App\User::ROLES[$user->role_id] }}</td> | |
<td class="col-sm-2">{{ $user->updated_at->format('d.m.y H:i') }}</td> | |
<td class="col-sm-2 text-right"> | |
@if($user->trashed()) | |
@can('restore', $user) | |
<x-home.shared.list.restore-button | |
:formaction="route('home.users.restore', $user)" | |
class="btn btn-light" | |
form="restoreItem" | |
title="Восстановить" | |
type="submit"/> | |
@endcan | |
@else | |
@can('update', $user) | |
<x-home.shared.list.edit-button | |
:href="route('home.users.edit', $user)" | |
class="btn btn-primary" | |
title="Редактировать"/> | |
@endcan | |
@can('delete', $user) | |
<x-home.shared.list.delete-button | |
type="submit" | |
class="btn btn-danger ml-sm-2" | |
form="deleteItem" | |
:formaction="route('home.users.destroy', $user)" | |
title="Удалить" | |
/> | |
@endcan | |
@endif | |
</td> | |
</tr> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers\Home; | |
use App\Center; | |
use App\Device; | |
use App\Http\Controllers\Controller; | |
use App\Http\Requests\Home\StoreOrderRequest; | |
use App\Http\Requests\Home\UpdateOrderRequest; | |
use App\Order; | |
use App\Service; | |
use Illuminate\Http\RedirectResponse; | |
use Illuminate\Support\Facades\DB; | |
class OrderController extends Controller | |
{ | |
/** | |
* Display a listing of the resource. | |
* | |
* @return \Illuminate\Http\Response | |
*/ | |
public function index() | |
{ | |
$centersQuery = DB::table('centers') | |
->select([ | |
'id as center_id', | |
'name as center_name' | |
]); | |
$centers = Center::query() | |
->where('id', request('center_id')) | |
->get(); | |
$orders = Order::query() | |
->withTrashed() | |
->with('center') | |
->leftJoinSub($centersQuery, 'centers', function($join){ | |
$join->on('centers.center_id', '=', 'orders.center_id'); | |
}) | |
->when(request('column', 'updated_at'), function ($q, $column) { | |
return $q->orderBy($column, request('direction', 'desc')); | |
}) | |
->when(request('center_id'), function ($q, $centerId) { | |
return $q->where('orders.center_id', $centerId); | |
}) | |
->paginate(); | |
return view('home.orders.index', [ | |
'centers' => $centers, | |
'orders' => $orders | |
]); | |
} | |
/** | |
* Show the form for creating a new resource. | |
* | |
* @return \Illuminate\Http\Response | |
*/ | |
public function create() | |
{ | |
$devices = Device::query() | |
->where('id', old('device_id')) | |
->get(); | |
$services = Service::query() | |
->where('id', old('service_id')) | |
->get(); | |
$centers = Center::query() | |
->where('id', old('center_id')) | |
->get(); | |
return view('home.orders.create', [ | |
'devices' => $devices, | |
'services' => $services, | |
'centers' => $centers | |
]); | |
} | |
/** | |
* Store a newly created resource in storage. | |
* | |
* @param StoreOrderRequest $request | |
* @return \Illuminate\Http\Response | |
*/ | |
public function store(StoreOrderRequest $request) | |
{ | |
$input = $request->validated(); | |
Order::create($input); | |
return redirect() | |
->route('home.orders.index') | |
->with('status', __('statuses.order.created')); | |
} | |
/** | |
* Display the specified resource. | |
* | |
* @param \App\Order $order | |
* @return \Illuminate\Http\Response | |
*/ | |
public function show(Order $order) | |
{ | |
// | |
} | |
/** | |
* Show the form for editing the specified resource. | |
* | |
* @param \App\Order $order | |
* @return \Illuminate\Http\Response | |
*/ | |
public function edit(Order $order) | |
{ | |
$devices = Device::query() | |
->where('id', old('device_id', $order->device_id)) | |
->get(); | |
$services = Service::query() | |
->where('id', old('service_id', $order->service_id)) | |
->get(); | |
$centers = Center::query() | |
->where('id', old('center_id', $order->center_id)) | |
->get(); | |
return view('home.orders.edit', [ | |
'devices' => $devices, | |
'services' => $services, | |
'centers' => $centers, | |
'order' => $order | |
]); | |
} | |
/** | |
* Update the specified resource in storage. | |
* | |
* @param UpdateOrderRequest $request | |
* @param \App\Order $order | |
* @return \Illuminate\Http\Response | |
*/ | |
public function update(UpdateOrderRequest $request, Order $order) | |
{ | |
$input = $request->validated(); | |
$order->update($input); | |
return redirect() | |
->route('home.orders.index') | |
->with('status', __('statuses.order.updated')); | |
} | |
/** | |
* Remove the specified resource from storage. | |
* | |
* @param \App\Order $order | |
* @return \Illuminate\Http\Response | |
*/ | |
public function destroy(Order $order) | |
{ | |
$order->delete(); | |
return redirect() | |
->route('home.orders.index') | |
->with('status', __('statuses.order.deleted')); | |
} | |
/** | |
* @param int $id | |
* @return RedirectResponse | |
* @throws \Illuminate\Auth\Access\AuthorizationException | |
*/ | |
public function restore($id) | |
{ | |
$order = Order::onlyTrashed() | |
->findOrFail($id); | |
$order->restore(); | |
return redirect() | |
->route('home.orders.index') | |
->with('status', __('statuses.order.restored')); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Exports; | |
use App\Price; | |
use App\User; | |
use Illuminate\Support\Facades\DB; | |
use Maatwebsite\Excel\Concerns\FromCollection; | |
use Maatwebsite\Excel\Concerns\Exportable; | |
use Maatwebsite\Excel\Concerns\WithHeadings; | |
use Maatwebsite\Excel\Concerns\WithMapping; | |
class PricesExport implements FromCollection, WithHeadings, WithMapping | |
{ | |
use Exportable; | |
private $centerId; | |
private $deviceId; | |
private $serviceId; | |
/** | |
* PricesExport constructor. | |
* @param null|int $centerId | |
* @param null|int $deviceId | |
* @param null|int $serviceId | |
* @return void | |
*/ | |
public function __construct(int $centerId = null, int $deviceId = null, int $serviceId = null) | |
{ | |
$this->centerId = $centerId; | |
$this->deviceId = $deviceId; | |
$this->serviceId = $serviceId; | |
} | |
/** | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function collection() | |
{ | |
return Price::query() | |
->with('center', 'device', 'service') | |
->when($this->centerId, function ($q, $centerId){ | |
return $q->where('center_id', $centerId); | |
}) | |
->when($this->deviceId, function ($q, $deviceId){ | |
return $q->where('device_id', $deviceId); | |
}) | |
->when($this->serviceId, function ($q, $serviceId){ | |
return $q->where('service_id', $serviceId); | |
}) | |
->when(in_array(auth()->user()->role_id, [ | |
User::ID_ROLE_MANAGER | |
]), function ($q){ | |
$q->whereHas('center', function ($q){ | |
return $q->whereHas('company', function ($q){ | |
$q->where('manager_id', auth()->id()); | |
}); | |
}); | |
}) | |
->when(in_array(auth()->user()->role_id, [ | |
User::ID_ROLE_OWNER | |
]), function ($q){ | |
$q->whereHas('center', function ($q){ | |
return $q->whereHas('company', function ($q){ | |
$q->where('owner_id', auth()->id()); | |
}); | |
}); | |
}) | |
->get(); | |
} | |
/** | |
* @param mixed $price | |
* @return array | |
*/ | |
public function map($price) : array | |
{ | |
return [ | |
$price->center_id, | |
$price->center->name, | |
$price->device_id, | |
$price->device->name, | |
$price->service_id, | |
$price->service->name, | |
$price->value, | |
$price->updated_at, | |
]; | |
} | |
/** | |
* @return array | |
*/ | |
public function headings() : array | |
{ | |
return [ | |
'center_id', | |
'center_name', | |
'device_id', | |
'device_name', | |
'service_id', | |
'service_name', | |
'price', | |
'updated_at', | |
]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Tests\Feature\Home; | |
use App\User; | |
use App\Problem; | |
use App\Service; | |
use App\Category; | |
use Exception; | |
use Illuminate\Foundation\Testing\RefreshDatabase; | |
use Illuminate\Foundation\Testing\WithFaker; | |
use Illuminate\Support\Arr; | |
use Tests\TestCase; | |
class ProblemControllerTest extends TestCase | |
{ | |
use RefreshDatabase; | |
/** | |
* Test index method. | |
* | |
* @return void | |
*/ | |
public function testIndex() | |
{ | |
$this->get(route('home.problems.index')) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->get(route('home.problems.index')) | |
->assertOk() | |
->assertViewIs('home.problems.index') | |
->assertViewHas('problems'); | |
} | |
/** | |
* Test create method. | |
* | |
* @return void | |
*/ | |
public function testCreate() | |
{ | |
$this->get(route('home.problems.create')) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->get(route('home.problems.create')) | |
->assertOk() | |
->assertViewIs('home.problems.create'); | |
} | |
/** | |
* Test store method. | |
* | |
* @return void | |
*/ | |
public function testStore() | |
{ | |
$formData = factory(Problem::class)->make()->only([ | |
'name', | |
'slug', | |
'description', | |
'service_id' | |
]); | |
$formData['categories'] = factory(Category::class, 5)->create()->pluck('id')->toArray(); | |
$this->post(route('home.problems.store', $formData)) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->post(route('home.problems.store', $formData)) | |
->assertRedirect(route('home.problems.index')) | |
->assertSessionHas('status', __('statuses.problem.created')); | |
$this->assertDatabaseHas('problems', Arr::only($formData, 'name', 'slug', 'description', 'service_id')); | |
} | |
/** | |
* Test edit method. | |
* | |
* @return void | |
*/ | |
public function testEdit() | |
{ | |
$problem = factory(Problem::class)->create(); | |
$this->get(route('home.problems.edit', $problem)) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->get(route('home.problems.edit', $problem)) | |
->assertOk() | |
->assertViewIs('home.problems.edit') | |
->assertViewHas('problem') | |
->assertViewHas('services') | |
->assertViewHas('categories'); | |
} | |
/** | |
* Test update method. | |
* | |
* @return void | |
*/ | |
public function testUpdate() | |
{ | |
$problem = factory(Problem::class)->create(); | |
$formData= factory(Problem::class)->make()->only([ | |
'name', | |
'slug', | |
'description', | |
'service_id', | |
]); | |
$formData['categories'] = factory(Category::class, 5)->create()->pluck('id')->toArray(); | |
$this->patch(route('home.problems.update', $problem), $formData) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->patch(route('home.problems.update', $problem), $formData) | |
->assertRedirect(route('home.problems.index')) | |
->assertSessionHas('status', __('statuses.problem.updated')); | |
$this->assertDatabaseHas('problems', Arr::only($formData, 'name', 'slug', 'description', 'service_id')); | |
} | |
/** | |
* Test destroy method. | |
* | |
* @return void | |
*/ | |
public function testDestroy() | |
{ | |
$problem = factory(Problem::class)->create(); | |
$this->delete(route('home.problems.destroy', $problem)) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->delete(route('home.problems.destroy', $problem)) | |
->assertSessionHas('status', __('statuses.problem.deleted')); | |
$this->assertSoftDeleted('problems', ['id' => $problem->id]); | |
} | |
/** | |
* Test restore method. | |
* | |
* @return void | |
* @throws Exception | |
*/ | |
public function testRestore() | |
{ | |
$problem = factory(Problem::class)->create(); | |
$problem->delete(); | |
$this->assertSoftDeleted('problems', ['id' => $problem->id]); | |
$this->patch(route('home.problems.restore', $problem)) | |
->assertRedirect(route('login')); | |
$actingUser = factory(User::class)->state('administrator')->make(); | |
$this->actingAs($actingUser) | |
->patch(route('home.problems.restore', $problem)) | |
->assertRedirect(route('home.problems.index')) | |
->assertSessionHas('status', __('statuses.problem.restored')); | |
$this->assertDatabaseHas('problems', [ | |
'id' => $problem->id, | |
'deleted_at' => null, | |
]); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Requests\Home; | |
use App\User; | |
use Illuminate\Foundation\Http\FormRequest; | |
use Illuminate\Validation\Rule; | |
class UpdatePriceRequest extends FormRequest | |
{ | |
/** | |
* Determine if the user is authorized to make this request. | |
* | |
* @return bool | |
*/ | |
public function authorize() | |
{ | |
return true; | |
} | |
/** | |
* Get the validation rules that apply to the request. | |
* | |
* @return array | |
*/ | |
public function rules() | |
{ | |
return [ | |
'device_id' => ['required', 'integer', 'exists:App\Device,id'], | |
'service_id' => ['required', 'integer', 'exists:App\Service,id'], | |
'center_id' => ['required', 'integer', Rule::exists('centers', 'id') | |
->where(function ($q) { | |
$q->when(in_array(auth()->user()->role_id, [User::ID_ROLE_OWNER]), function ($q) { | |
return $q->whereExists(function($q) { | |
$q->select('*') | |
->from('companies') | |
->whereColumn('centers.company_id', 'id') | |
->where('owner_id', auth()->id()); | |
}); | |
}); | |
$q->when(in_array(auth()->user()->role_id, [User::ID_ROLE_MANAGER]), function ($q) { | |
return $q->whereExists(function($q) { | |
$q->select('*') | |
->from('companies') | |
->whereColumn('centers.company_id', 'id') | |
->where('manager_id', auth()->id()); | |
}); | |
}); | |
}) | |
], | |
'value' => ['required', 'numeric', 'min:0', 'max:16777215'], | |
]; | |
} | |
/** | |
* Get custom attributes for validator errors. | |
* | |
* @return array | |
*/ | |
public function attributes() | |
{ | |
return [ | |
'device_id' => 'Устройство', | |
'service_id' => 'Услуга', | |
'center_id' => 'Центр', | |
'value' => 'Цена', | |
]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Database\Eloquent\SoftDeletes; | |
use Illuminate\Foundation\Auth\User as Authenticatable; | |
use Illuminate\Notifications\Notifiable; | |
class User extends Authenticatable | |
{ | |
use Notifiable, SoftDeletes; | |
const ID_ROLE_ADMINISTRATOR = 1; | |
const ID_ROLE_MANAGER = 2; | |
const ID_ROLE_OWNER = 3; | |
const ID_ROLE_CLIENT = 4; | |
const NAME_ROLE_ADMINISTRATOR = 'Администратор'; | |
const NAME_ROLE_MANAGER = 'Менеджер'; | |
const NAME_ROLE_OWNER = 'Владелец'; | |
const NAME_ROLE_CLIENT = 'Клиент'; | |
const ROLES = [ | |
self::ID_ROLE_ADMINISTRATOR => self::NAME_ROLE_ADMINISTRATOR, | |
self::ID_ROLE_MANAGER => self::NAME_ROLE_MANAGER, | |
self::ID_ROLE_OWNER => self::NAME_ROLE_OWNER, | |
self::ID_ROLE_CLIENT => self::NAME_ROLE_CLIENT, | |
]; | |
/** | |
* The attributes that are mass assignable. | |
* | |
* @var array | |
*/ | |
protected $fillable = [ | |
'last_name', 'first_name', 'middle_name', 'phone', 'email', 'password', 'role_id', | |
]; | |
/** | |
* The number of models to return for pagination. | |
* | |
* @var int | |
*/ | |
protected $perPage = 5; | |
/** | |
* The attributes that should be hidden for arrays. | |
* | |
* @var array | |
*/ | |
protected $hidden = [ | |
'password', 'remember_token', | |
]; | |
/** | |
* The attributes that should be cast to native types. | |
* | |
* @var array | |
*/ | |
protected $casts = [ | |
'email_verified_at' => 'datetime', | |
]; | |
/** | |
* Get the user's full name. | |
* | |
* @param string | |
* @return string | |
*/ | |
public function getFullNameAttribute() | |
{ | |
return "{$this->last_name} {$this->first_name} {$this->middle_name}"; | |
} | |
/** | |
* Get the user's initials. | |
* | |
* @param string | |
* @return string | |
*/ | |
public function getInitialsAttribute() | |
{ | |
return $this->last_name . ' ' . mb_substr($this->first_name, 0, 1) . '. ' . mb_substr($this->middle_name, 0, 1) . '.'; | |
} | |
/** | |
* Scope a query to only include managers. | |
* | |
* @param Builder $query | |
* @return Builder | |
*/ | |
public function scopeManager($query) | |
{ | |
return $query->where('role_id', self::ID_ROLE_MANAGER); | |
} | |
/** | |
* Scope a query to only include owners. | |
* | |
* @param Builder $query | |
* @return Builder | |
*/ | |
public function scopeOwner($query) | |
{ | |
return $query->where('role_id', self::ID_ROLE_OWNER); | |
} | |
/** | |
* Get the companies for the owner. | |
*/ | |
public function ownerCompanies() | |
{ | |
return $this->hasMany(Company::class, 'owner_id'); | |
} | |
/** | |
* Get the companies for the manager. | |
*/ | |
public function managerCompanies() | |
{ | |
return $this->hasMany(Company::class, 'manager_id'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment