Customer::info and Customer::login try to get loaded relations first

This commit is contained in:
Jérémy Munsch 2021-08-23 20:20:51 +02:00
parent f940d7a71d
commit e618e6fb46
9 changed files with 79 additions and 21 deletions

View file

@ -54,7 +54,7 @@ class ArcadiaController extends Controller
$xml = 'none';
try {
/** @var \App\Models\CustomerInfo $customerInfo */
$customerInfo = $customer->info($service->brand)->firstOrFail();
$customerInfo = $customer->info($service->brand, Customer::FIRST_OR_FAIL);
$orderType = ArcadiaOrderType::make(intval($request->state_order));
$xml = $this->makeXml($request, $type, $orderType, $customer, $customerInfo);

View file

@ -45,7 +45,7 @@ class CustomerController extends Controller
}
/** @var \App\Models\CustomerInfo */
$customerInfo = $customer->info($service->brand)->firstOrNew();
$customerInfo = $customer->info($service->brand, Customer::FIRST_OR_NEW);
if ($customerInfo->id) {
throw new ApiErrorException(ApiError::customerExists());
}
@ -55,7 +55,7 @@ class CustomerController extends Controller
$customerInfo->saveOrFail();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrNew();
$customerLogin = $customer->login($service->brand, Customer::FIRST_OR_NEW);
$customerLogin->fill($request->validated());
$customerLogin->brand()->associate($service->brand);
$customerLogin->customer()->associate($customer);
@ -98,12 +98,12 @@ class CustomerController extends Controller
}
/** @var \App\Models\CustomerInfo */
$customerInfo = $customer->info($service->brand)->firstOrFail();
$customerInfo = $customer->info($service->brand, Customer::FIRST_OR_FAIL);
$customerInfo->fill($request->validated());
$customerInfo->saveOrFail();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrFail();
$customerLogin = $customer->login($service->brand, Customer::FIRST_OR_FAIL);
$customerLogin->fill($request->validated());
$customerLogin->saveOrFail();
@ -123,9 +123,9 @@ class CustomerController extends Controller
// TODO : A voir pour les stats, obuton dans le bo qui permet de faire les stats sur les customer puis supprimer
// TODO : Gestion avec mesBR
/** @var \App\Models\CustomerInfo */
$customerInfo = $customer->info($service->brand)->firstOrFail();
$customerInfo = $customer->info($service->brand, Customer::FIRST_OR_FAIL);
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrFail();
$customerLogin = $customer->login($service->brand, Customer::FIRST_OR_FAIL);
if (
!$customerInfo->delete() ||
@ -170,7 +170,7 @@ class CustomerController extends Controller
/** @var \App\Models\Customer */
$customer = Customer::where('email', $request->email)->firstOrFail();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrFail();
$customerLogin = $customer->login($service->brand, Customer::FIRST_OR_FAIL);
if (!$customerLogin->passwordMatch($request->password)) {
throw new ApiErrorException(ApiError::authFailed());
@ -198,7 +198,7 @@ class CustomerController extends Controller
public function activateAccount(Customer $customer, Service $service)
{
$this->authorize('customerBelongsToService', $customer);
$login = $customer->login($service->brand)->firstOrFail();
$login = $customer->login($service->brand, Customer::FIRST_OR_FAIL);
if ($login->status === 0) {
$login->status = 1;

View file

@ -38,8 +38,8 @@ class CustomerResource extends JsonResource
public function __construct(Brand $brand, Customer $customer)
{
$this->customer = $customer;
$this->info = $customer->info($brand)->firstOrFail();
$this->login = $customer->login($brand)->firstOrFail();
$this->info = $customer->info($brand, Customer::FIRST_OR_FAIL);
$this->login = $customer->login($brand, Customer::FIRST_OR_FAIL);
}
/**

View file

@ -11,6 +11,10 @@ class Customer extends Model
{
use HasFactory;
public const FIRST_OR_NULL = 0;
public const FIRST_OR_NEW = 1;
public const FIRST_OR_FAIL = 2;
protected $fillable = [
'email'
];
@ -27,17 +31,35 @@ class Customer extends Model
/**
* Get the CustomerInfo from a specific brand
* or create a New one if $firstOrNewOrFail is 1
* throw model not found exception if firstOrNewOrFail = 2
*
* @param Brand $brand
* @param int $firstOrNewOrFail
* @return \Illuminate\Database\Eloquent\Builder
*/
public function info(Brand $brand)
public function info(Brand $brand, $firstOrNewOrFail = self::FIRST_OR_NULL): ?CustomerInfo
{
return CustomerInfo::whereHas('brand', function (Builder $query) use ($brand) {
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) {
$query->where('id', $brand->id);
})->whereHas('customer', function (Builder $query) use ($brand) {
$query->where('id', $this->id);
});
if ($firstOrNewOrFail === self::FIRST_OR_NEW) {
return $query->firstOrNew();
}
if ($firstOrNewOrFail === self::FIRST_OR_FAIL) {
return $query->firstOrFail();
}
return $query->first();
}
/**
@ -52,17 +74,53 @@ class Customer extends Model
/**
* Get the CustomerLogin from a specific brand
* or create a New one if $firstOrNewOrFail is 1
* throw model not found exception if firstOrNewOrFail = 2
*
* @param Brand $brand
* @param int $firstOrNewOrFail
* @return \Illuminate\Database\Eloquent\Builder
*/
public function login(Brand $brand)
public function login(Brand $brand, $firstOrNewOrFail = self::FIRST_OR_NULL): ?CustomerLogin
{
return CustomerLogin::whereHas('brand', function (Builder $query) use ($brand) {
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) {
$query->where('id', $brand->id);
})->whereHas('customer', function (Builder $query) use ($brand) {
$query->where('id', $this->id);
});
if ($firstOrNewOrFail === self::FIRST_OR_NEW) {
return $query->firstOrNew();
}
if ($firstOrNewOrFail === self::FIRST_OR_FAIL) {
return $query->firstOrFail();
}
return $query->first();
}
/**
* Load login and brand for this customer
*
* @param Brand $brand
* @return self
*/
public function loadBrandData(Brand $brand): self
{
return $this->load([
'logins' => function ($q) use ($brand) {
$q->where('brand_id', $brand->id);
},
'infos' => function ($q) use ($brand) {
$q->where('brand_id', $brand->id);
}
]);
}
/**

View file

@ -12,6 +12,6 @@ class CustomerPolicy
public function customerBelongsToService(Service $service, Customer $customer)
{
return $customer->login($service->brand)->exists();
return !\is_null($customer->login($service->brand));
}
}

View file

@ -94,7 +94,7 @@ class ApiBase extends BaseTestCase
$service->bearer_pwd = $bearer_pwd;
// get customer info
$info = $customer->info($brand)->firstOrFail();
$info = $customer->info($brand, Customer::FIRST_OR_FAIL);
return compact('customer', 'service', 'login', 'brand', 'info');
}

View file

@ -29,8 +29,8 @@ class CustomerTest extends ApiBase
$this->assertInstanceOf(Collection::class, $logins);
$this->assertInstanceOf(Collection::class, $brands);
$this->assertInstanceOf(Collection::class, $optInHistory);
$this->assertInstanceOf(CustomerInfo::class, $customer->info($brands->first())->first());
$this->assertInstanceOf(CustomerLogin::class, $customer->login($brands->first())->first());
$this->assertInstanceOf(CustomerInfo::class, $customer->info($brands->first()));
$this->assertInstanceOf(CustomerLogin::class, $customer->login($brands->first()));
}
/**

View file

@ -59,7 +59,7 @@ abstract class CrmClientTester extends TestCase
$service = $brand->services()->firstOrFail();
// get customer info
$info = $customer->info($brand)->firstOrFail();
$info = $customer->info($brand, Customer::FIRST_OR_FAIL);
// regen bearer token to get the pwd in clear
$bearer_token = $service->generateBearerToken();

View file

@ -133,7 +133,7 @@ class CrmClientV2CustomerTest extends CrmClientTester
/** @var \App\Models\Brand */
$brand = $login->brand;
/** @var \App\Models\CustomerInfo */
$info = $customer->info($brand)->firstOrFail();
$info = $customer->info($brand, ModelsCustomer::FIRST_OR_FAIL);
$api = new CrmApiV2();
$customer = $api->getCustomerOrNew($info->hashcode);