ldc-crm/app/Http/Controllers/Api/V2/CustomerController.php
2021-07-28 14:18:47 +02:00

180 lines
6.5 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V2;
use App\Enums\ApiError;
use App\Exceptions\Api\V2\ApiErrorException;
use App\Exceptions\Api\V2\CrmException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V2\AuthenticateRequest;
use App\Http\Requests\Api\V2\StoreCustomerRequest;
use App\Http\Requests\Api\V2\UpdateCustomerRequest;
use App\Http\Resources\Api\V2\CustomerResource;
use App\Models\Customer;
use App\Models\Service;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\JsonResource;
class CustomerController extends Controller
{
/**
* Store a newly created resource in storage.
*
* @param \App\Request\StoreCustomerRequest $request
* @param \App\Models\Service $service
* @return \Illuminate\Http\Resources\Json\JsonResource
*/
public function store(StoreCustomerRequest $request, Service $service): JsonResource
{
$data = (object)$request->validated();
/** @var \App\Models\Customer */
$customer = Customer::where('email', $data->email)->firstOrCreate([
'email' => $data->email
]);
$customer->saveOrFail();
$customer->setOptIn($service->brand, $data->opt_in);
/** @var \App\Models\CustomerInfo */
$customerInfo = $customer->info($service->brand)->firstOrNew();
if ($customerInfo->id) {
throw new ApiErrorException(ApiError::customerExists());
}
$customerInfo->fill($request->validated());
$customerInfo->brand()->associate($service->brand);
$customerInfo->customer()->associate($customer);
$customerInfo->saveOrFail();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrNew();
$customerLogin->fill($request->validated());
$customerLogin->brand()->associate($service->brand);
$customerLogin->customer()->associate($customer);
$customerLogin->saveOrFail();
return new CustomerResource($service->brand, $customer);
}
/**
* Display the specified resource.
*
* @param \App\Models\Service $service
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\Resources\Json\JsonResource
*/
public function show(Customer $customer, Service $service): JsonResource
{
return new CustomerResource($service->brand, $customer);
}
/**
* Update the specified resource in storage.
*
* @param \App\Request\UpdateCustomerRequest $request
* @param \App\Models\Service $service
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\Resources\Json\JsonResource
*/
public function update(UpdateCustomerRequest $request, Customer $customer, Service $service): JsonResource
{
// To correct with create
$customer->fill($request->all());
if ($customer->saveOrFail() === false) {
throw new CrmException(sprintf('Could not update customer %d', $customer));
}
if ($request->has('opt_in')) {
$customer->setOptIn($service->brand, $request->opt_in);
}
/** @var \App\Models\CustomerInfo */
$customerInfo = $customer->info($service->brand)->firstOrFail();
$customerInfo->fill($request->validated());
$customerInfo->saveOrFail();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrFail();
$customerLogin->fill($request->validated());
$customerLogin->saveOrFail();
return new CustomerResource($service->brand, $customer);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Service $service
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Customer $customer, Service $service): JsonResponse
{
// 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();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrFail();
if (!$customerInfo->delete() || !$customerLogin->delete()) {
throw new CrmException(sprintf('Could not delete customer %d for brand %d', $customer, $service->brand));
}
if (!$customer->logins()->count() and !$customer->infos()->count()) {
if ($customer->delete() === false) {
throw new CrmException(sprintf('Could not delete customer %d', $customer));
}
}
return response()->json();
}
/**
* Authenticate the user
* @param \App\Models\Service $service
* @param \App\Request\AuthenticateRequest $request
* @return \Illuminate\Http\Resources\Json\JsonResource
*/
public function authenticate(AuthenticateRequest $request, Service $service): JsonResource
{
try {
/** @var \App\Models\Customer */
$customer = Customer::where('email', $request->email)->firstOrFail();
/** @var \App\Models\CustomerLogin */
$customerLogin = $customer->login($service->brand)->firstOrFail();
if (!$customerLogin->passwordMatch($request->password)) {
throw new ApiErrorException(ApiError::authFailed());
}
if ($customerLogin->status === 0) {
throw new ApiErrorException(ApiError::customerNotActivated());
}
$customerLogin->last_connection = now();
$customer->logins()->save($customerLogin);
return new CustomerResource($service->brand, $customer);
} catch (ModelNotFoundException $e) {
throw new ApiErrorException(ApiError::authFailed());
}
}
/**
* Activate the account of the user
* @param Customer $customer
* @param Service $service
* @return \Illuminate\Http\JsonResponse
*/
public function activateAccount(Customer $customer, Service $service)
{
$login = $customer->login($service->brand)->firstOrFail();
if ($login->status === 0) {
$login->status = 1;
$login->save();
return response()->json();
} else {
throw new ApiErrorException(ApiError::customerAlreadyActive());
}
}
}