2020-12-01 17:02:10 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
2021-03-14 10:45:42 +01:00
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
2021-08-18 08:26:40 +02:00
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
2020-12-01 17:02:10 +01:00
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
2021-08-23 22:47:42 +02:00
|
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
2020-12-01 17:02:10 +01:00
|
|
|
|
|
|
|
|
class Customer extends Model
|
|
|
|
|
{
|
|
|
|
|
use HasFactory;
|
|
|
|
|
|
2021-08-23 20:20:51 +02:00
|
|
|
public const FIRST_OR_NULL = 0;
|
|
|
|
|
public const FIRST_OR_NEW = 1;
|
|
|
|
|
public const FIRST_OR_FAIL = 2;
|
|
|
|
|
|
2021-12-19 15:57:24 +01:00
|
|
|
/**
|
|
|
|
|
* The attributes that are mass assignable.
|
|
|
|
|
*
|
|
|
|
|
* @var string[]
|
|
|
|
|
*/
|
2021-03-14 10:45:42 +01:00
|
|
|
protected $fillable = [
|
|
|
|
|
'email'
|
|
|
|
|
];
|
|
|
|
|
|
2021-12-19 15:57:24 +01:00
|
|
|
// * RELATIONS
|
|
|
|
|
|
2021-02-28 12:04:49 +01:00
|
|
|
/**
|
|
|
|
|
* CustomerInfo hasMany relation
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
|
|
|
*/
|
|
|
|
|
public function infos()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(CustomerInfo::class);
|
2020-12-01 17:02:10 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-19 15:57:24 +01:00
|
|
|
/**
|
|
|
|
|
* CustomerLogin hasMany relation
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
|
|
|
*/
|
|
|
|
|
public function logins()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(CustomerLogin::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* CustomerOptInHistory hasMany relation
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
|
|
|
*/
|
|
|
|
|
public function optInHistory()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(CustomerOptInHistory::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Customer Brand belongsToMany relation
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
|
|
|
|
|
*/
|
|
|
|
|
public function brands()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsToMany(Brand::class, CustomerInfo::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Answers belongsToMany relation
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
|
|
|
|
*/
|
|
|
|
|
public function answers()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsToMany(Answer::class, 'customer_answer');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// * METHODS
|
|
|
|
|
|
2021-03-14 10:45:42 +01:00
|
|
|
/**
|
|
|
|
|
* Get the CustomerInfo from a specific brand
|
2021-08-23 20:20:51 +02:00
|
|
|
* or create a New one if $firstOrNewOrFail is 1
|
|
|
|
|
* throw model not found exception if firstOrNewOrFail = 2
|
2021-03-14 10:45:42 +01:00
|
|
|
*
|
2021-12-19 15:57:24 +01:00
|
|
|
* @param Brand $brand
|
|
|
|
|
* @param integer $firstOrNewOrFail
|
2021-03-14 10:45:42 +01:00
|
|
|
* @return \Illuminate\Database\Eloquent\Builder
|
|
|
|
|
*/
|
2021-12-19 15:57:24 +01:00
|
|
|
public function info(Brand $brand, int $firstOrNewOrFail = self::FIRST_OR_NULL): ?CustomerInfo
|
2021-03-14 10:45:42 +01:00
|
|
|
{
|
2021-08-23 20:20:51 +02:00
|
|
|
if (isset($this->relations['infos'])) {
|
|
|
|
|
/** @var \App\Models\CustomerInfo $info */
|
|
|
|
|
foreach ($this->relations['infos'] as $info) {
|
|
|
|
|
if ($info->brand_id === $brand->id) {
|
|
|
|
|
return $info;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$query = CustomerInfo::whereHas('brand', function (Builder $query) use ($brand) {
|
2021-03-14 10:45:42 +01:00
|
|
|
$query->where('id', $brand->id);
|
2021-08-23 22:47:42 +02:00
|
|
|
})->whereHas('customer', function (Builder $query) {
|
2021-03-14 10:45:42 +01:00
|
|
|
$query->where('id', $this->id);
|
|
|
|
|
});
|
2021-08-23 20:20:51 +02:00
|
|
|
if ($firstOrNewOrFail === self::FIRST_OR_NEW) {
|
|
|
|
|
return $query->firstOrNew();
|
|
|
|
|
}
|
|
|
|
|
if ($firstOrNewOrFail === self::FIRST_OR_FAIL) {
|
|
|
|
|
return $query->firstOrFail();
|
|
|
|
|
}
|
|
|
|
|
return $query->first();
|
2021-03-14 10:45:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the CustomerLogin from a specific brand
|
2021-08-23 20:20:51 +02:00
|
|
|
* or create a New one if $firstOrNewOrFail is 1
|
|
|
|
|
* throw model not found exception if firstOrNewOrFail = 2
|
2021-03-14 10:45:42 +01:00
|
|
|
*
|
2021-12-19 15:57:24 +01:00
|
|
|
* @param Brand $brand
|
|
|
|
|
* @param integer $firstOrNewOrFail
|
2021-03-14 10:45:42 +01:00
|
|
|
* @return \Illuminate\Database\Eloquent\Builder
|
|
|
|
|
*/
|
2021-12-19 15:57:24 +01:00
|
|
|
public function login(Brand $brand, int $firstOrNewOrFail = self::FIRST_OR_NULL): ?CustomerLogin
|
2021-03-14 10:45:42 +01:00
|
|
|
{
|
2021-08-23 20:20:51 +02:00
|
|
|
if (isset($this->relations['logins'])) {
|
|
|
|
|
/** @var \App\Models\CustomerLogin $login */
|
|
|
|
|
foreach ($this->relations['logins'] as $login) {
|
|
|
|
|
if ($login->brand_id === $brand->id) {
|
|
|
|
|
return $login;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$query = CustomerLogin::whereHas('brand', function (Builder $query) use ($brand) {
|
2021-03-14 10:45:42 +01:00
|
|
|
$query->where('id', $brand->id);
|
|
|
|
|
})->whereHas('customer', function (Builder $query) use ($brand) {
|
|
|
|
|
$query->where('id', $this->id);
|
|
|
|
|
});
|
2021-08-23 20:20:51 +02:00
|
|
|
if ($firstOrNewOrFail === self::FIRST_OR_NEW) {
|
|
|
|
|
return $query->firstOrNew();
|
|
|
|
|
}
|
|
|
|
|
if ($firstOrNewOrFail === self::FIRST_OR_FAIL) {
|
|
|
|
|
return $query->firstOrFail();
|
|
|
|
|
}
|
|
|
|
|
return $query->first();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2021-12-19 15:57:24 +01:00
|
|
|
* Load login and info for this customer and this specific brand.
|
2021-08-23 20:20:51 +02:00
|
|
|
*
|
2021-12-19 15:57:24 +01:00
|
|
|
* @param Brand $brand
|
|
|
|
|
* @param boolean $orFail
|
2021-08-23 20:20:51 +02:00
|
|
|
* @return self
|
2021-12-19 15:57:24 +01:00
|
|
|
* @throws ModelNotFoundException If no login or info was found for the brand.
|
2021-08-23 20:20:51 +02:00
|
|
|
*/
|
2021-08-23 22:47:42 +02:00
|
|
|
public function loadBrandData(Brand $brand, bool $orFail = false): self
|
2021-08-23 20:20:51 +02:00
|
|
|
{
|
2021-08-23 22:47:42 +02:00
|
|
|
$this->load([
|
2021-08-23 20:20:51 +02:00
|
|
|
'logins' => function ($q) use ($brand) {
|
|
|
|
|
$q->where('brand_id', $brand->id);
|
|
|
|
|
},
|
|
|
|
|
'infos' => function ($q) use ($brand) {
|
|
|
|
|
$q->where('brand_id', $brand->id);
|
|
|
|
|
}
|
|
|
|
|
]);
|
2021-08-23 22:47:42 +02:00
|
|
|
if ($orFail and !isset($this->relations['logins'][0])) {
|
|
|
|
|
throw (new ModelNotFoundException())->setModel(CustomerLogin::class);
|
|
|
|
|
}
|
|
|
|
|
if ($orFail and !isset($this->relations['infos'][0])) {
|
|
|
|
|
throw (new ModelNotFoundException())->setModel(CustomerInfo::class);
|
|
|
|
|
}
|
|
|
|
|
return $this;
|
2021-03-14 10:45:42 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-28 12:04:49 +01:00
|
|
|
/**
|
2021-12-19 15:57:24 +01:00
|
|
|
* Set this customer as optin
|
2021-08-11 17:25:24 +02:00
|
|
|
*
|
2021-12-19 15:57:24 +01:00
|
|
|
* @param Brand $brand
|
|
|
|
|
* @param boolean $optIn
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws \Throwable If customer history update failed.
|
2021-08-11 17:25:24 +02:00
|
|
|
*/
|
2021-12-19 15:57:24 +01:00
|
|
|
public function setOptIn(Brand $brand, bool $optIn): void
|
2021-08-11 17:25:24 +02:00
|
|
|
{
|
2021-12-19 15:57:24 +01:00
|
|
|
$this->opt_in = $optIn;
|
2021-08-11 17:25:24 +02:00
|
|
|
|
2021-12-19 15:57:24 +01:00
|
|
|
// * Ajout dans la table d'historique des opt-in de la nouvelle valeur.
|
|
|
|
|
$optInHistory = new CustomerOptInHistory();
|
|
|
|
|
$optInHistory->new_value = $optIn;
|
|
|
|
|
$optInHistory->customer()->associate($this);
|
|
|
|
|
$optInHistory->brand()->associate($brand);
|
2021-03-14 10:45:42 +01:00
|
|
|
$optInHistory->saveOrFail();
|
|
|
|
|
}
|
2021-08-18 08:26:40 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get All answers given by this customer
|
|
|
|
|
* for a specific service
|
|
|
|
|
*
|
|
|
|
|
* @param Service $service
|
|
|
|
|
* @return Collection
|
|
|
|
|
*/
|
|
|
|
|
public function getAnswers(Service $service): Collection
|
|
|
|
|
{
|
|
|
|
|
return Answer::whereHas('customers', function ($q) {
|
|
|
|
|
$q->whereId($this->id);
|
|
|
|
|
})->whereHas('question', function ($q) use ($service) {
|
|
|
|
|
$q->whereHas('brand', function ($q) use ($service) {
|
|
|
|
|
$q->whereId($service->brand->id);
|
|
|
|
|
});
|
|
|
|
|
})->get();
|
|
|
|
|
}
|
2020-12-01 17:02:10 +01:00
|
|
|
}
|