ldc-boutique-cnc/app/Http/Controllers/Fo/CustomerController.php
2023-03-22 17:17:55 +01:00

264 lines
9 KiB
PHP

<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\Ajax\SubscribeNewsletterRequest;
use App\Http\Requests\Fo\Customers\ConfirmDeleteRequest;
use App\Http\Requests\Fo\Customers\UpdateEmailRequest;
use App\Http\Requests\Fo\Customers\UpdatePasswordRequest;
use App\Http\Requests\Fo\Customers\UpdateInfosRequest;
use App\Models\Customer\Customer;
use App\Models\Shop\Order;
use App\Notifications\Customer\UpdateEmail as NotificationUpdateEmail;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\ValidationException;
use LDC\LDCCRM\Enums\ApiError;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
use LDC\LDCCRM\Models\SingleOptin;
class CustomerController extends Controller
{
// * --- Backoffice ---
/**
* profil client (mon compte)
*
* @return \Illuminate\Contracts\View\View
*/
public function dashboard()
{
// Show Profile.
/** @var \App\Models\Customer|null $customer */
$customer = Auth::guard('frontend')->user();
if (!$customer) {
abort(404);
}
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
$crmCustomer = $customer->apiData;
/** @var object $crmInfos */
$crmInfos = \json_decode(\json_encode($crmCustomer));
return view('theme::pages.customer.dashboard', compact('customer', 'crmInfos'));
}
/**
* Show update customer informations form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function email()
{
return view('theme::auth.change-email');
}
/**
* Uupdate customer email
*
* @param \App\Http\Requests\Fo\Customers\UpdateEmailRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function emailSubmit(UpdateEmailRequest $request)
{
/** @var \App\Models\Customer\Customer */
$customer = \auth('frontend')->user();
$customer->notify(new NotificationUpdateEmail());
return $this->updateCrmCustomerInfo($customer, ['email' => $request->get('email')]) ?
back()->with('success', trans('Vos informations ont bien été enregistrées.')) :
back()->withInput()->withErrors(trans('Une erreur est survenue, merci de réessayer ultérieurement.'));
}
/**
* Show update customer password form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function password()
{
return view('theme::auth.passwords.change');
}
/**
* Update customer password
*
* @param UpdatePasswordRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function passwordSubmit(UpdatePasswordRequest $request)
{
/** @var \App\Models\Customer\Customer */
$customer = \auth('frontend')->user();
if ($this->updateCrmCustomerInfo($customer, ['password' => $request->get('password')])) {
event(new PasswordReset($customer));
return back()->with('success', trans('Vos informations ont bien été enregistrées.'));
}
return back()->withInput()->withErrors(trans('Une erreur est survenue, merci de réessayer ultérieurement.'));
}
/**
* Send a request to the CRM to change the given customer's informations
* @param \App\Http\Requests\Fo\UpdateInfosRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function updateInfos(UpdateInfosRequest $request)
{
/** @var \App\Models\Customer\Customer */
$customer = auth('frontend')->user();
return $this->updateCrmCustomerInfo($customer, $request->validated()) ?
back()->with('success', trans('Vos informations ont bien été enregistrées.')) :
back()->withInput()->withErrors(trans('Une erreur est survenue, merci de réessayer ultérieurement.'));
}
/**
* Show customer delete account page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function destroy()
{
return view('theme::pages.customer.destroy');
}
/**
* Show customer delete account page
*
* @param \App\Http\Requests\Fo\Customers\ConfirmDeleteRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function destroySubmit(ConfirmDeleteRequest $request)
{
if ($request->confirm) {
try {
return DB::transaction(function () {
/** @var \App\Models\Customer\Customer */
$customer = auth('frontend')->user();
$customer->deleteOrFail();
// * Force logout
auth('frontend')->logout();
return response()
->redirectToRoute('home')
->with('info', trans(
'Votre compte à bien été marqué pour supression,
vous pourrez le réactiver en vous reconnectant à celui-ci avant
qu\'il ne soit définitivement supprimé au bout d\'une semaine.'
));
});
} catch (\Exception $e) {
report($e);
Session::flash('error', trans('Une erreur est survenue veuillez réssayer plus tard.'));
} //end try
} //end if
return back();
}
/**
* Updates user info
*
* @param \App\Models\Customer\Customer $customer
* @param array $data
* @return boolean
* @throws \Illuminate\Validation\ValidationException If something failed.
*/
private function updateCrmCustomerInfo(Customer $customer, array $data)
{
return DB::transaction(function () use ($customer, $data) {
try {
/** @var \LDC\LDCCRM\Models\Customer */
$crmCustomer = $customer->apiData;
if (\array_key_exists('email', $data)) {
$customer->email = $data['email'];
$customer->saveOrFail();
}
$crmCustomer->fill($data);
$saved = $crmCustomer->save();
// * Sync with stripe if already known by stripe.
if ($customer->stripe_id) {
$customer->syncStripeCustomerDetails();
}
return $saved;
} catch (CrmValidationException $e) {
throw ValidationException::withMessages([
'error' => $e->getMessage()
]);
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::validationFailed())) {
throw ValidationException::withMessages([
'error' => $e->getMessage()
]);
}
report($e);
return false;
} //end try
});
}
/**
* Affichage des commandes du customer connecté
*
* @return \Illuminate\Contracts\View\View
*/
public function myOrders()
{
/** @var \App\Models\Customer\Customer */
$customer = auth('frontend')->user();
$orders = $customer->orders()->orderBy('created_at', 'DESC')->paginate();
return view('theme::pages.customer.orders', compact('orders'));
}
/**
* Show detail commande
*
* @param \App\Models\Shop\Order $order
* @return \Illuminate\Contracts\View\View
*/
public function orderDetail(Order $order)
{
$order->load('timeslot.shop');
return view('theme::pages.customer.orders.show', compact('order'));
}
// * --- END Backoffice ---
/**
* Call the CRM to add a single optin
*
* @param \App\Http\Requests\Fo\Ajax\SubscribeNewsletterRequest $request
* @return \Illuminate\Http\JsonResponse
*
*/
public function addOptIn(SubscribeNewsletterRequest $request)
{
try {
SingleOptin::setStatus($request->email, true);
return \response()->json();
} catch (ApiErrorException $e) {
// * Il y a deja un customerInfo avec optin a true pour ce customer
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists())) {
return \response()->json([
'errors' => [
'email' => [\trans('Vous êtes déjà inscrit avec cette adresse email')]
]
], 422);
}
report($e);
return \response()->json([], 500);
} catch (CrmException $e) {
report($e);
return \response()->json([], 500);
}
}
}