QR_code_generator/app/Models/Companies/Company.php

221 lines
7.8 KiB
PHP

<?php
namespace App\Models\Companies;
use App\Models\Advisories\AdvisoryCompany;
use App\Models\Asset;
use App\Models\User;
use App\Services\DaDataService;
use App\Support\RelationValuesTrait;
use App\Support\UuidScopeTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
class Company extends Model {
use UuidScopeTrait, SoftDeletes, RelationValuesTrait;
protected $dates = [
'tax_registration_date',
'deleted_at'
];
protected $fillable = [
'uuid',
'logo_id',
'name',
'full_name',
'inn',
'kpp',
'ogrn',
'okpo',
'okved',
'okato',
'tax_registration_date',
'is_main'
];
protected $hidden = [
'id',
'deleted_at',
'updated_at',
'pivot'
];
public function logo(): BelongsTo {
return $this->belongsTo(Asset::class);
}
public function types(): HasMany {
return $this->hasMany(CompanyType::class);
}
public function departments(): HasMany {
return $this->hasMany(Department::class);
}
public function members(): HasMany {
return $this->hasMany(CompanyMember::class);
}
public function rootMembers(): HasMany {
return $this->members()->whereNull('department_id');
}
public function management(): HasMany {
return $this->members()->whereIn('status', [CompanyMemberRank::VICE, CompanyMemberRank::CHIEF]);
}
public function vices(): HasMany {
return $this->members()->where(['status' => CompanyMemberRank::VICE]);
}
public function employees(): HasMany {
return $this->members()->where(['status' => CompanyMemberRank::EMPLOYEE]);
}
public function addresses(): HasMany {
return $this->hasMany(Address::class);
}
public function bankDetails(): HasOne {
return $this->hasOne(BankDetails::class);
}
public function contacts(): HasMany {
return $this->hasMany(Contact::class);
}
public function phones(): HasMany {
return $this->contacts()->where(['type' => ContactType::PHONE]);
}
public function emails(): HasMany {
return $this->contacts()->where(['type' => ContactType::EMAIL]);
}
public function advisoryCompanies(): HasMany {
return $this->hasMany(AdvisoryCompany::class);
}
public function scopeByTypes($query, $types) {
return $query->whereHas('types', function($query) use($types) {
$query->whereIn('name', is_array($types) ? $types : [$types]);
});
}
public function getLegalAddressAttribute(): Model {
return $this->addresses()->firstOrCreate(['type' => Address::$TYPE_LEGAL]);
}
public function getActualAddressAttribute(): Model {
return $this->addresses()->firstOrCreate(['type' => Address::$TYPE_ACTUAL]);
}
public function getPhoneAttribute(): Model {
return $this->phones()->firstOrCreate(['type' => ContactType::PHONE]);
}
public function getEmailAttribute(): Model {
return $this->emails()->firstOrCreate(['type' => ContactType::EMAIL]);
}
public function getRootDepartmentAttribute(): Model {
$res = $this->departments()->whereNull('parent_id')->firstOrCreate(['name' => 'root']);
if (!$res->title) $res->update(['title' => 'Дирекция']);
return $res;
}
public function getRepresentativeMemberAttribute() {
return $this->members()->where(['representative' => true])->first();
}
public function getResponsibleMemberAttribute() {
return $this->members()->orderBy('representative', 'desc')->first();
}
public static function getByData($data) {
$result = false;
if (!empty($data['inn'])) {
$result = self::firstOrCreate(['inn' => $data['inn']]);
(new DaDataService($data['inn']))->saveToCompany($result);
if ($val = $data['name'] ?? null) $result->update(['name' => $val, 'full_name' => $val]);
if (($val = $data['address'] ?? null) && $result->legalAddress->full !== $val) $result->setAddress($val);
if ($val = $data['phone'] ?? null) $result->setPhone($val);
if ($val = $data['email'] ?? null) $result->setEmail($val);
if ($val = $data['contacts'] ?? null) $result->setContacts($val);
if ($val = $data['types'] ?? null) $result->setTypes($val);
if ($val = $data['logo'] ?? null) $result->setLogo($val);
if (!$result->name && !is_numeric($result->inn)) $result->update(['name' => $result->inn, 'full_name' => $result->inn]);
}
return $result;
}
public function addMember(User $user, $position, $departmentId = null, $rank = null): Model {
if ($member = $this->members()->where(['user_id' => $user->id, 'position' => $position])->first()) {
if ($departmentId) $member->update(['department_id' => $departmentId]);
if (!is_null($rank)) $member->update(['rank' => $rank]);
} elseif ($member = $this->members()->create(['user_id' => $user->id, 'position' => $position])) {
$member->update(['department_id' => $departmentId ?? $this->rootDepartment->id ?? null, 'rank' => $rank ?? CompanyMemberRank::EMPLOYEE]);
}
return $member;
}
public function isMember(CompanyMember $member): bool {
return $this->members()->where('id', $member->id)->exists();
}
public function findDepartments($search): Collection {
return $this->departments()->where('title', 'like', "%{$search}%")->get();
}
public function findMembers($search): Collection {
return $this->members()->where('position', 'like', "%{$search}%")->orWhereHas('user', function($query) use($search) {
$query->where('name', 'like', "%{$search}%");
})->get();
}
public function setTypes(array $types) {
$exists = collect($types)->map(function($item) {
$name = (is_string($item)) ? $item : $item['id'] ?? null;
return $name ? $this->types()->firstOrCreate(['name' => $name]) : null;
});
$this->types()->whereNotIn('name', $exists->pluck('name')->all())->delete();
}
public function setLogo($val) {
$asset = Asset::byUuid($val)->first();
$this->update(['logo_id' => $asset->id ?? null]);
}
public function setAddress($val) {
$this->legalAddress->setFullAddress($val);
$this->actualAddress->setFullAddress($val);
}
public function setEmail($val): ?Model {
$this->emails()->delete();
return $val ? $this->contacts()->create(['type' => ContactType::EMAIL, 'value' => $val]) : null;
}
public function setPhone($val): ?Model {
$this->phones()->delete();
return $val ? $this->contacts()->create(['type' => ContactType::PHONE, 'value' => $val]) : null;
}
public function setContacts($val) {
$this->contacts()->firstOrCreate(['type' => ContactType::MIXED, 'value' => $val]);
collect(explode(';', $val))->each(function($contact) {
$type = (Str::contains($contact, '@')) ? ContactType::EMAIL : ContactType::PHONE;
$this->contacts()->firstOrCreate(['type' => $type, 'value' => trim($contact)]);
});
}
public function getPermissions(User $user): array {
$result = ['view' => false, 'edit' => false];
if ($user->isAdmin) $result = ['view' => true, 'edit' => true];
elseif ($user->isCompanyMember($this)) {
$result['view'] = true;
if ($this->members()->where(['user_id' => $user->id, 'representative' => 1])->exists()) $result['edit'] = true;
}
return $result;
}
}