633 lines
22 KiB
PHP
633 lines
22 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\CustomerRegisterRequest;
|
|
use App\Http\Requests\LoginRequest;
|
|
use App\Http\Requests\UpdateInfosRequest;
|
|
use App\Mail\OrderCanceledConfirmMail;
|
|
use App\Mail\PasswordResetMail;
|
|
use App\Mail\RegisterConfirmMail;
|
|
use App\Models\Customers;
|
|
use App\Models\Magasin;
|
|
use App\Models\Order;
|
|
use App\Models\PasswordReset;
|
|
use App\Models\Salarie;
|
|
use App\Models\Setting;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\Session;
|
|
use Illuminate\Support\Str;
|
|
use LDC\LDCCRM\Enums\ApiError;
|
|
use LDC\LDCCRM\Enums\Country;
|
|
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
|
use LDC\LDCCRM\Exceptions\CrmException;
|
|
use LDC\LDCCRM\Exceptions\ValidationException;
|
|
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
|
|
|
class CustomerController extends Controller
|
|
{
|
|
/**
|
|
* Affiche la page d'inscription
|
|
*
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function registerForm()
|
|
{
|
|
if (Auth::guard('customer')->check()) {
|
|
return redirect()->route('home');
|
|
}
|
|
|
|
return view('auth.register');
|
|
}
|
|
|
|
/**
|
|
* Enregistre le customer dans la base de données
|
|
* et CRM
|
|
*
|
|
* @param CustomerRegisterRequest $request
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function register(CustomerRegisterRequest $request)
|
|
{
|
|
try {
|
|
return DB::transaction(function () use ($request) {
|
|
$crmCustomer = new CrmCustomer(\array_intersect_key(
|
|
$request->validated(),
|
|
[
|
|
'firstname' => '',
|
|
'lastname' => '',
|
|
'birth_date' => '',
|
|
'address' => '',
|
|
'postcode' => '',
|
|
'country' => '',
|
|
'city' => '',
|
|
'phone' => '',
|
|
'email' => '',
|
|
'password' => '',
|
|
'opt_in' => '',
|
|
]
|
|
));
|
|
|
|
$crmCustomer->city = $request->town;
|
|
$crmCustomer->postcode = $request->postal_code;
|
|
$crmCustomer->opt_in = $request->optin ? true : false;
|
|
|
|
// * Country Is forced to france
|
|
$crmCustomer->country = Country::france();
|
|
$crmCustomer->save();
|
|
|
|
// * Enrregistrement du Hashcode
|
|
/** @var \App\Models\Customers $customer */
|
|
$customer = new Customers($request->all());
|
|
$customer->hashcode = $crmCustomer->hashcode;
|
|
$customer->saveOrFail();
|
|
|
|
// * liaison éventuelle avec la table salaries
|
|
if ($request->matricule && $request->code) {
|
|
/** @var \App\Models\Salarie $salarie */
|
|
$salarie = Salarie::where('matricule', '=', $request->matricule)
|
|
->where('code', '=', $request->code)
|
|
->firstOrFail();
|
|
$salarie->customer()->associate($customer);
|
|
$salarie->saveOrFail();
|
|
}
|
|
|
|
Mail::to($request->email)->send(new RegisterConfirmMail($customer, $request->firstname));
|
|
|
|
return view('auth.register-success', ['mail' => $request->email]);
|
|
});
|
|
} catch (ApiErrorException $e) {
|
|
if ($e->getApiError()->equals(ApiError::customerExists())) {
|
|
return back()->withInput()->withErrors('Un compte est déjà associé à cette adresse email.');
|
|
}
|
|
if ($e->getApiError()->equals(ApiError::validationFailed())) {
|
|
return back()->withInput()->withErrors($e->getMessage());
|
|
}
|
|
report($e);
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} catch (ModelNotFoundException $e) {
|
|
return back()->withErrors("Salarié $request->matricule, $request->code introuvable.");
|
|
} catch (ValidationException $e) {
|
|
return back()->withErrors($e->getMessage());
|
|
} catch (\Exception | \TypeError | CrmException $e) {
|
|
report($e);
|
|
// * Une erreur critique est survenue avec la CRM
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} //end try
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
}
|
|
|
|
/**
|
|
* Retourne la page de connexion
|
|
*
|
|
* @param Request $request
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function authenticateForm(Request $request)
|
|
{
|
|
if (Auth::guard('customer')->check()) {
|
|
return redirect()->route('account.dashboard');
|
|
}
|
|
if ($request->get('url')) {
|
|
Session::put('url.intended', $request->get('url'));
|
|
Session::save();
|
|
}
|
|
return view('auth.login');
|
|
}
|
|
|
|
/**
|
|
* Gère l'authentification des customers
|
|
*
|
|
* @param LoginRequest $request
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function authenticate(LoginRequest $request)
|
|
{
|
|
/** @var Customers|null */
|
|
$customer = Customers::where('email', $request->email)->first();
|
|
|
|
try {
|
|
/** @var \LDC\LDCCRM\CrmApiV2 */
|
|
$crm = app('crmAPI');
|
|
|
|
// * Ne devrait pas survenir, $crm->login throws ApiError::authFailed()
|
|
if (!$crm->login($request->email, $request->password)) {
|
|
// * mauvais identifiants
|
|
return back()->withErrors('Email ou mot de passe incorrect.');
|
|
}
|
|
|
|
// Dans tout les cas : récupérer le crm user.
|
|
$crmCustomer = $crm->getCustomer($request->email);
|
|
|
|
// Si pas de compte local mais existe en CRM.
|
|
if (!$customer) {
|
|
$customer = $this->createLocalCustomer($crmCustomer);
|
|
}
|
|
|
|
return $this->processLogin($customer, $request->remember);
|
|
} catch (ApiErrorException $e) {
|
|
return $this->handleLoginApiErrorException($e, $request);
|
|
} catch (CrmException | \Exception $e) {
|
|
report($e);
|
|
// Une erreur critique est survenue avec la CRM.
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} //end try
|
|
}
|
|
|
|
/**
|
|
* Active le compte d'un customer
|
|
*
|
|
* @param mixed $hashcode
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
*/
|
|
public function activate($hashcode)
|
|
{
|
|
$hashcode = filter_var($hashcode, FILTER_SANITIZE_STRING);
|
|
if (!($customer = Customers::select('hashcode')->where('hashcode', $hashcode)->first())) {
|
|
return view('auth.activate')->with('message', 'Ce lien d\'activation n\'est pas valide.');
|
|
}
|
|
try {
|
|
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
|
$crmCustomer = $customer->apiData;
|
|
if ($crmCustomer->activate()) {
|
|
return view('auth.activate')
|
|
->with('message', 'Votre compte a bien été activé, vous pouvez désormais vous connecter.');
|
|
}
|
|
} catch (ApiErrorException $e) {
|
|
if ($e->getApiError()->equals(ApiError::customerAlreadyActive())) {
|
|
// phpcs:disable Generic.Files.LineLength.TooLong
|
|
return view('auth.activate')
|
|
->with('message', 'Votre compte est déjà activé, vous pouvez dès à présent vous connecter avec celui-ci.');
|
|
}
|
|
report($e);
|
|
// Une erreur critique est survenue avec la CRM.
|
|
return view('auth.activate')
|
|
->with('message', 'Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} catch (CrmException $e) {
|
|
report($e);
|
|
// Une erreur critique est survenue avec la CRM.
|
|
return view('auth.activate')
|
|
->with('message', 'Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} //end try
|
|
return view('auth.activate')->with('message', 'Ce lien d\'activation n\'est pas valide.');
|
|
}
|
|
|
|
/**
|
|
* deconnexion customer
|
|
*
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function logout()
|
|
{
|
|
if (Auth::guard('customer')->check()) {
|
|
Auth::guard('customer')->logout();
|
|
return redirect()->route('home');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* page d'accès à la procédure mdp oublié
|
|
*
|
|
* @param \Illuminate\Http\Request $request
|
|
* @return \Illuminate\Contracts\View\View
|
|
*
|
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
|
*/
|
|
public function forgotPasswordForm(Request $request)
|
|
{
|
|
// @phpcs:enable
|
|
return view('auth.passwords.forgot');
|
|
}
|
|
|
|
/**
|
|
* initialisation de la procédure de mdp oublié
|
|
*
|
|
* @param Request $request
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function passwordReset(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email:rfc|max:255',
|
|
]);
|
|
|
|
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
|
|
|
|
$customerExist = Customers::where('email', $email)->count() === 0 ? false : true;
|
|
|
|
if ($customerExist) {
|
|
// Suppression des anciens tokens.
|
|
PasswordReset::where('email', $email)->delete();
|
|
|
|
$token = Str::random(80);
|
|
|
|
$passwordReset = new PasswordReset();
|
|
$passwordReset->email = $email;
|
|
$passwordReset->token = $token;
|
|
$passwordReset->created_at = now();
|
|
$passwordReset->save();
|
|
|
|
Mail::to($email)->send(new PasswordResetMail($token));
|
|
return back()->with(
|
|
'success',
|
|
__("La procédure pour changer votre mot de passe a été envoyé sur votre email.")
|
|
);
|
|
} else {
|
|
return back()->withErrors(__("Cette adresse email n'est pas enregistrée dans nos services."));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Print the view used to change the password of a user when he required it
|
|
* @param string $token Token used to identificate the user to change the password.
|
|
* @return \Illuminate\Contracts\View\View The view to print
|
|
*/
|
|
public function viewChangePassword(string $token)
|
|
{
|
|
$pwdReset = PasswordReset::where('token', $token)->first();
|
|
if (!$pwdReset) {
|
|
abort(419);
|
|
}
|
|
$customer = Customers::where('email', $pwdReset->email)->first();
|
|
if (!$customer) {
|
|
abort(404);
|
|
}
|
|
|
|
return view('auth.passwords.reset', compact('customer'))->with('token', $token);
|
|
}
|
|
|
|
/**
|
|
* changement de mot de passe (depuis la procédure de mdp oublié)
|
|
*
|
|
* @param Request $request
|
|
* @param mixed $token
|
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
*/
|
|
public function changePassword(Request $request, $token)
|
|
{
|
|
$request->validate([
|
|
'password' => 'required|confirmed|min:8|max:255'
|
|
]);
|
|
|
|
/** @var \App\Models\PasswordReset $passwordReset */
|
|
$passwordReset = PasswordReset::where('token', $token)->first();
|
|
/** @var \App\Models\Customers $customer */
|
|
$customer = Customers::where('email', optional($passwordReset)->email)->firstOrFail();
|
|
|
|
/** @var \LDC\LDCCRM\CrmApiV2 */
|
|
$crm = app('crmAPI');
|
|
|
|
try {
|
|
if ($crm->login($customer->email, $request->password)) {
|
|
return back()->withErrors('Vous ne pouvez pas utiliser un de vos anciens mot de passe.');
|
|
}
|
|
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
|
|
} catch (ApiErrorException $e) {
|
|
// * continue
|
|
}
|
|
|
|
try {
|
|
if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) {
|
|
return back()
|
|
->withErrors('Changement impossible, compte inexistant.');
|
|
}
|
|
$crmCustomer->password = $request->password;
|
|
$crmCustomer->save();
|
|
} catch (\TypeError | CrmException | ApiErrorException $e) {
|
|
report($e);
|
|
// Une erreur critique est survenue avec la CRM.
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} catch (ValidationException $e) {
|
|
return back()->withErrors(sprintf('Nouveau mot de passe : %s', $e->getMessage()));
|
|
}
|
|
|
|
$passwordReset->deleteOrFail();
|
|
|
|
return view('auth.passwords.reset-ok', compact('customer'));
|
|
}
|
|
|
|
/**
|
|
* profil client (mon compte)
|
|
*
|
|
* @param Request $request
|
|
* @return \Illuminate\Contracts\View\View
|
|
*
|
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
|
*/
|
|
public function dashboard(Request $request)
|
|
{
|
|
// @phpcs:enable
|
|
// Show Profile.
|
|
/** @var \App\Models\Customers|null $customer */
|
|
$customer = Auth::guard('customer')->user();
|
|
if (!$customer) {
|
|
abort(404);
|
|
}
|
|
|
|
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
|
$crmCustomer = $customer->apiData;
|
|
|
|
/** @var object $crmInfos */
|
|
$crmInfos = \json_decode(\json_encode($crmCustomer));
|
|
$birthDate = explode('-', $crmCustomer->birth_date);
|
|
|
|
return view('customer.dashboard', compact('customer', 'crmInfos', 'birthDate'));
|
|
}
|
|
|
|
|
|
/**
|
|
* Send a request to the CRM to change the given customer's informations
|
|
* @param UpdateInfosRequest $request
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function updateInfos(UpdateInfosRequest $request)
|
|
{
|
|
if (($result = $this->updateUserInfo($request)) === true) {
|
|
return back()->with('success', trans(
|
|
'Vos informations ont bien été enregistrées.'
|
|
));
|
|
}
|
|
return back()->withInput()->withErrors(
|
|
$result !== false ? $result : trans(
|
|
'Une erreur est survenue, merci de réessayer ultérieurement.'
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* changement de mot de passe depuis le profil
|
|
*
|
|
* @param Request $request
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function changePasswordWhenAuthenticated(Request $request)
|
|
{
|
|
$request->validate([
|
|
'password' => 'required|min:8|confirmed|max:255'
|
|
]);
|
|
|
|
$crm = app('crmApi');
|
|
$customer = $crm->changePwdCustomer(Auth::guard('customer')->user()->crm_id, $request->password);
|
|
|
|
if ($customer->status === "OK") {
|
|
return back()->with('success', __("Modifications enregistrés !"));
|
|
} else {
|
|
return back()->withErrors(__("Une erreur est survenue, merci de réessayer ultérieurement."));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* affichage des commandes du customer connecté
|
|
*
|
|
* @param Request $request
|
|
* @return \Illuminate\Contracts\View\View
|
|
*
|
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
|
*/
|
|
public function myOrders(Request $request)
|
|
{
|
|
// @phpcs:enable
|
|
$orders = Order::where('customer_id', Auth::guard('customer')->user()->id)->orderBy('date', 'DESC')->get();
|
|
return view('customer.my-orders', compact('orders'));
|
|
}
|
|
|
|
/**
|
|
* Show detail commande
|
|
*
|
|
* @param string $reference
|
|
* @return \Illuminate\Contracts\View\View
|
|
*/
|
|
public function orderDetail(string $reference)
|
|
{
|
|
$order = Order::where('reference', '=', $reference)
|
|
->where('customer_id', Auth::guard('customer')->user()->id)
|
|
->firstOrFail();
|
|
|
|
if ($order->status_id == 1) {
|
|
$magasin = null;
|
|
} else {
|
|
$magasin = Magasin::find($order->timeslot->magasin->id);
|
|
}
|
|
|
|
return view('customer.order-detail', compact('order', 'magasin'));
|
|
}
|
|
|
|
/**
|
|
* mise au statut annulé d'une commande
|
|
*
|
|
* @param string $reference
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function cancelOrder(string $reference)
|
|
{
|
|
$order = Order::where('reference', $reference)->first();
|
|
$order->status_id = 7;
|
|
$order->save();
|
|
|
|
// Envoi du mail d'annulation aux admins site.
|
|
$toMailSetting = Setting::where('key', 'send_order_confirm_mail_to')->first();
|
|
if (empty($toMailSetting->value)) {
|
|
$toMail = config('mail.from.address');
|
|
} else {
|
|
$toMail = $toMailSetting->value;
|
|
}
|
|
|
|
Mail::to($toMail)->queue(new OrderCanceledConfirmMail($order));
|
|
|
|
return back()->with('success', "La commande " . $order->reference . " à été annulée.");
|
|
}
|
|
|
|
/**
|
|
* delete customers
|
|
*
|
|
* @param integer $id
|
|
* @return void
|
|
*/
|
|
public function delete(int $id)
|
|
{
|
|
dump('deleting' . $id);
|
|
die('Not implemented yet');
|
|
}
|
|
|
|
/**
|
|
* Create a local customer
|
|
*
|
|
* @param CrmCustomer $crmCustomer
|
|
* @return \app\Models\Customers
|
|
* @throws \Throwable If saving to DB failed.
|
|
*/
|
|
private function createLocalCustomer(CrmCustomer $crmCustomer): Customers
|
|
{
|
|
/** @var \App\Models\Customers $customer */
|
|
$customer = Customers::firstOrNew([
|
|
'email' => $crmCustomer->email
|
|
]);
|
|
$customer->hashcode = $crmCustomer->hashcode;
|
|
$customer->saveOrFail();
|
|
|
|
return $customer;
|
|
}
|
|
|
|
/**
|
|
* Handle Api error exception
|
|
*
|
|
* @param ApiErrorException $e
|
|
* @param LoginRequest $request
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
private function handleLoginApiErrorException(ApiErrorException $e, LoginRequest $request)
|
|
{
|
|
/** @var Customers|null */
|
|
$customer = Customers::where('email', $request->email)->first();
|
|
/** @var \LDC\LDCCRM\CrmApiV2 */
|
|
$crm = app('crmAPI');
|
|
|
|
switch ($e->getApiError()) {
|
|
case ApiError::authFailed():
|
|
// * mauvais identifiants
|
|
return back()->withErrors('Email ou mot de passe incorrect.');
|
|
case ApiError::customerNotActivated():
|
|
// * le compte n'est pas activé
|
|
if (!$customer) {
|
|
try {
|
|
if (!($crmCustomer = $crm->getCustomer($request->email))) {
|
|
Log::critical(sprintf('Customer %s coulnd not be retrieved from crm', $request->email));
|
|
return back()->withErrors(
|
|
trans('Une erreur est survenue, merci de réessayer ultérieurement.')
|
|
);
|
|
}
|
|
$customer = $this->createLocalCustomer($crmCustomer);
|
|
} catch (CrmException | ApiErrorException $e) {
|
|
report($e);
|
|
// Une erreur critique est survenue avec la CRM.
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
}
|
|
}
|
|
Mail::to($request->email)->send(new RegisterConfirmMail($customer, null));
|
|
return back()
|
|
->withErrors(
|
|
trans('Votre compte n\'est pas activé, vérifiez dans vos emails pour y trouver
|
|
le mail de confirmation. Un lien d\'activation vous a été renvoyé.')
|
|
);
|
|
default:
|
|
report($e);
|
|
// * une erreur non gérée
|
|
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
|
|
} //end switch
|
|
}
|
|
|
|
/**
|
|
* Login a customer
|
|
*
|
|
* @param Customers $customer
|
|
* @param boolean $remember
|
|
* @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
|
|
*/
|
|
private function processLogin(Customers $customer, bool $remember)
|
|
{
|
|
/** @var \Illuminate\Auth\SessionGuard */
|
|
$guard = auth('customer');
|
|
$guard->login($customer, $remember);
|
|
$url = Session::pull('url.intended');
|
|
Session::forget('url.intended');
|
|
Session::save();
|
|
return !empty($url) ? redirect()->to($url) : redirect()->route('account.dashboard');
|
|
}
|
|
|
|
/**
|
|
* Updates user info
|
|
*
|
|
* @param UpdateInfosRequest $request
|
|
* @return boolean|string return strictly true if success,
|
|
* false il failed, could be a string with message error if failed
|
|
*/
|
|
private function updateUserInfo(UpdateInfosRequest $request)
|
|
{
|
|
/** @var \App\Models\Customers */
|
|
$customer = auth('customer')->user();
|
|
if (!$customer) {
|
|
return \redirect()->back();
|
|
}
|
|
|
|
/** @var \LDC\LDCCRM\Models\Customer */
|
|
$crmCustomer = $customer->apiData;
|
|
|
|
$data = [
|
|
'firstname' => $request->firstname,
|
|
'lastname' => $request->lastname,
|
|
'birth_date' => $request->year . '-' . $request->month . '-' . $request->day,
|
|
'address' => $request->address,
|
|
'postcode' => $request->postcode,
|
|
'city' => $request->city,
|
|
'phone' => \strval($request->phone),
|
|
'opt_in' => \boolval($request->optin),
|
|
];
|
|
|
|
// * remove phone if empty
|
|
if (isset($data['phone']) and !strlen($data['phone'])) {
|
|
unset($data['phone']);
|
|
}
|
|
|
|
try {
|
|
$crmCustomer->fill($data);
|
|
$crmCustomer->save();
|
|
} catch (ValidationException $e) {
|
|
return $e->getMessage();
|
|
} catch (ApiErrorException $e) {
|
|
if ($e->getApiError()->equals(ApiError::validationFailed())) {
|
|
return $e->getMessage();
|
|
}
|
|
report($e);
|
|
return false;
|
|
} catch (CrmException | \TypeError $e) {
|
|
report($e);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|