Tons of fixes Refonte SYNC 1
- Authentification System OK
This commit is contained in:
parent
ffe82091fb
commit
f99e259bd5
122 changed files with 3902 additions and 2907 deletions
127
app/Auth/CrmUserProvider.php
Normal file
127
app/Auth/CrmUserProvider.php
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace App\Auth;
|
||||
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Auth\EloquentUserProvider;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
use Illuminate\Contracts\Auth\UserProvider as UserProviderContract;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
|
||||
/**
|
||||
* Crm user provider to integrate nicely with Laravel
|
||||
*/
|
||||
class CrmUserProvider extends EloquentUserProvider implements UserProviderContract
|
||||
{
|
||||
/**
|
||||
* The model to use, specified in auth config guard.
|
||||
* @var string
|
||||
*/
|
||||
private $usedModel = Customer::class;
|
||||
|
||||
/**
|
||||
* Retrieve a user by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
// * Let laravel find a model
|
||||
$model = parent::retrieveByCredentials($credentials);
|
||||
|
||||
try {
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
// Si pas de compte local.
|
||||
if (!$model) {
|
||||
$crmCustomer = $crm->getCustomer($credentials['email']);
|
||||
|
||||
if (!$crmCustomer) {
|
||||
// * Customer is not found on CRM.
|
||||
return null;
|
||||
}
|
||||
$model = $this->createLocalCustomer($crmCustomer);
|
||||
}
|
||||
|
||||
return $model;
|
||||
} catch (ApiErrorException $e) {
|
||||
// * Customer is not found.
|
||||
if ($e->getApiError()->equals(ApiError::modelNotFound())) {
|
||||
return null;
|
||||
}
|
||||
report($e);
|
||||
Log::error('Unhandled response ', $e->getApiError()->label);
|
||||
} catch (CrmException | \Exception $e) {
|
||||
report($e);
|
||||
// Une erreur critique est survenue avec la CRM.
|
||||
return null;
|
||||
} //end try
|
||||
Log::error(__CLASS__ . '::retrieveByCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user against the given credentials.
|
||||
*
|
||||
* @param UserContract $model
|
||||
* @param array $credentials
|
||||
* @return boolean
|
||||
* @throws \RuntimeException If model provided is not a Customer or connection to server fails.
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException On CRM call error.
|
||||
* @throws \Exception On CRM call error.
|
||||
*/
|
||||
public function validateCredentials(UserContract $model, array $credentials)
|
||||
{
|
||||
// FIXME: handle customerNotActivated
|
||||
/** @var \Illuminate\Database\Eloquent\Model $model */
|
||||
if (\get_class($model) !== $this->usedModel) {
|
||||
throw new \RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
// * Ne devrait pas survenir, $crm->login throws ApiError::authFailed()
|
||||
return $crm->login($credentials['email'], $credentials['password']);
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::authFailed())) {
|
||||
return false;
|
||||
}
|
||||
} catch (CrmException | \Exception $e) {
|
||||
report($e);
|
||||
if (config('app.debug')) {
|
||||
throw $e;
|
||||
}
|
||||
return false;
|
||||
} //end try
|
||||
|
||||
Log::error(__CLASS__ . '::validateCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a local customer
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crmCustomer
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \Throwable If saving to DB failed.
|
||||
*/
|
||||
private function createLocalCustomer(\LDC\LDCCRM\Models\Customer $crmCustomer): Model
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Model $model */
|
||||
$model = $this->usedModel::firstOrNew([
|
||||
'email' => $crmCustomer->email
|
||||
]);
|
||||
$model->hashcode = $crmCustomer->hashcode;
|
||||
$model->saveOrFail();
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
38
app/Enums/UserRole.php
Normal file
38
app/Enums/UserRole.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnumRoutable;
|
||||
|
||||
/**
|
||||
* @method static self admin()
|
||||
* @method static self user()
|
||||
*/
|
||||
final class UserRole extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'admin' => 1,
|
||||
'user' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'admin' => trans('Administrateur'),
|
||||
'user' => trans('Utilisateur'),
|
||||
];
|
||||
}
|
||||
}
|
||||
104
app/Enums/WeightUnit.php
Normal file
104
app/Enums/WeightUnit.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self g()
|
||||
* @method static self kg()
|
||||
* @method static self ton()
|
||||
*/
|
||||
final class WeightUnit extends BaseEnum
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'g' => 'G',
|
||||
'kg' => 'KG',
|
||||
'ton' => 'T',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'g' => __('g'),
|
||||
'kg' => __('kg'),
|
||||
'ton' => __('t'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum conversions a partir de gramme
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function conversions(): array
|
||||
{
|
||||
return [
|
||||
'g' => 1,
|
||||
'kg' => 1000,
|
||||
'ton' => 1000000,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @return integer|string
|
||||
*/
|
||||
public function __get(string $attribute)
|
||||
{
|
||||
if ($attribute === 'conversion') {
|
||||
return $this->conversions()[$this->getDefinition()] ?? null;
|
||||
}
|
||||
return parent::__get($attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format weight into a displayable unit.
|
||||
* @param integer $weightG The weight in grams.
|
||||
* @param \App\Enums\WeightUnit|null $forceUnit To force specific unit display.
|
||||
* @return string
|
||||
*/
|
||||
public static function getDisplayableWeight(int $weightG, self $forceUnit = null): string
|
||||
{
|
||||
if ($forceUnit) {
|
||||
number_format(round($weightG / $forceUnit->conversion, 2), 2, ',', '') . $forceUnit->label;
|
||||
}
|
||||
$displayable = self::convertWeightToAdequatUnit($weightG);
|
||||
return \number_format($displayable->value, 2, ',', '') . ' ' . $displayable->enum->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert value to the adequat unit
|
||||
* @param integer $weightG The weight in grams.
|
||||
* @return object<'enum'|'value',self>
|
||||
*/
|
||||
private function convertWeightToAdequatUnit(int $weightG): object
|
||||
{
|
||||
foreach (self::conversions() as $key => $conversionRate) {
|
||||
$convertedTest = round($weightG / $conversionRate, 2);
|
||||
if ($convertedTest > 0.001 and $convertedTest <= 1000) {
|
||||
return (object)[
|
||||
'enum' => self::make($key),
|
||||
'value' => $convertedTest
|
||||
];
|
||||
}
|
||||
}
|
||||
return (object)[
|
||||
'enum' => \collect(self::toArray())->last(),
|
||||
'value' => $weightG
|
||||
];
|
||||
}
|
||||
}
|
||||
24
app/Events/LogVerifiedUser.php
Normal file
24
app/Events/LogVerifiedUser.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class LogVerifiedUser
|
||||
{
|
||||
/**
|
||||
* Handle the given event.
|
||||
*
|
||||
* @param \Illuminate\Auth\Events\Verified $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Verified $event)
|
||||
{
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = $event->user;
|
||||
Auth::guard('frontend')->login($customer);
|
||||
Session::flash('success', trans('Votre compte à bien été validé, vous êtes à présent connecté.'));
|
||||
}
|
||||
}
|
||||
24
app/Events/PasswordHasReset.php
Normal file
24
app/Events/PasswordHasReset.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class PasswordHasReset
|
||||
{
|
||||
/**
|
||||
* Handle the given event.
|
||||
*
|
||||
* @param \Illuminate\Auth\Events\PasswordReset $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(PasswordReset $event)
|
||||
{
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = $event->user;
|
||||
Auth::guard('frontend')->login($customer);
|
||||
Session::flash('success', trans('Votre mot de passe à bien été réinitialisé, vous êtes à présent connecté.'));
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Exceptions;
|
||||
|
||||
use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
|
@ -23,40 +22,4 @@ class Handler extends ExceptionHandler
|
|||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unauthenticated as exception
|
||||
*
|
||||
* @param mixed $request
|
||||
* @param AuthenticationException $exception
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function unauthenticated($request, AuthenticationException $exception)
|
||||
{
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['error' => 'Unauthenticated.'], 401);
|
||||
}
|
||||
$guard = $exception->guards()[0];
|
||||
switch ($guard) {
|
||||
case 'customer':
|
||||
$login = 'auth.connexion';
|
||||
break;
|
||||
default:
|
||||
$login = 'auth.login';
|
||||
break;
|
||||
}
|
||||
// Cf. issue :
|
||||
// Https://stackoverflow.com/questions/52417438/laravel-unauthenticated-redirect-issue-with-multiple-authentication.
|
||||
// Session::forget('url.intented'); .
|
||||
return redirect()->guest(route($login));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display login form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
// @phpcs:enable
|
||||
return view('auth.login-bo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute login form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'email' => 'required',
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
$credentials = $request->only(['email', 'password']);
|
||||
|
||||
if (Auth::attempt($credentials)) {
|
||||
$user = Auth::user();
|
||||
if ($user->role === 1 || $user->role === 2) {
|
||||
return redirect()->route('bo.dashboard');
|
||||
} else {
|
||||
if ($user->email_verified_at === null) {
|
||||
Auth::logout();
|
||||
return view('auth.login')->withErrors('Compte non activé.');
|
||||
}
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
}
|
||||
return view('auth.login')->withErrors('Informations incorrectes.');
|
||||
}
|
||||
|
||||
/**
|
||||
* logout
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
// @phpcs:enable
|
||||
Auth::logout();
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display register form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
// @phpcs:enable
|
||||
return view('auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute regioster form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
*/
|
||||
public function register(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'lastname' => 'required|string|max:255',
|
||||
'firstname' => 'required|string|max:255',
|
||||
'date_of_birth' => 'required|date|before_or_equal:' . Carbon::now()->subYears(18)->toDateString(),
|
||||
'email' => 'required|string|email|max:255|unique:users|confirmed',
|
||||
'password' => 'required|string|min:8',
|
||||
]);
|
||||
|
||||
User::create([
|
||||
'firstname' => $request->firstname,
|
||||
'lastname' => $request->lastname,
|
||||
'date_of_birth' => $request->date_of_birth,
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
'role' => 3
|
||||
]);
|
||||
|
||||
// Envoi mail activation.
|
||||
return redirect()->route('auth.register')->with('success', 'Mail envoyé pour confirmation');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display reset password form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
// @phpcs:enable
|
||||
return view('auth.reset-password');
|
||||
}
|
||||
}
|
||||
51
app/Http/Controllers/Bo/Auth/LoginController.php
Normal file
51
app/Http/Controllers/Bo/Auth/LoginController.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('back.auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return \route('bo.dashboard');
|
||||
}
|
||||
}
|
||||
31
app/Http/Controllers/Bo/Auth/ResetPasswordController.php
Normal file
31
app/Http/Controllers/Bo/Auth/ResetPasswordController.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return \route('bo.login');
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ class DownloadController extends Controller
|
|||
*/
|
||||
public function download(string $filePath): StreamedResponse
|
||||
{
|
||||
if (!\auth()->check()) {
|
||||
if (!\auth('backend')->check()) {
|
||||
abort(404);
|
||||
}
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use App\Mail\OrderStatusMail;
|
|||
use App\Mail\OrderConfirmMail;
|
||||
use App\Mail\OrderConfirmAdminMail;
|
||||
use App\Jobs\CsvOrderWrite;
|
||||
use App\Models\Customers;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Setting;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonImmutable;
|
||||
|
|
@ -583,7 +583,7 @@ class OrderController extends Controller
|
|||
*/
|
||||
public function getCustomerInfo(int $id, string $mode = null)
|
||||
{
|
||||
$cust = Customers::findOrFail($id);
|
||||
$cust = Customer::findOrFail($id);
|
||||
if (!is_null($mode)) {
|
||||
if ($mode == "tippy") {
|
||||
return view('back.customer.tippy-card', compact('cust'));
|
||||
|
|
|
|||
|
|
@ -44,18 +44,9 @@ class ProductController extends Controller
|
|||
$this->searchQuery(
|
||||
$products,
|
||||
$request->search,
|
||||
// * Search in ranges
|
||||
function ($q) use ($request) {
|
||||
$q->orWhereHas('ranges', function ($q) use ($request) {
|
||||
$q->whereRaw(
|
||||
'UPPER(CONCAT(`ranges`.`name`)) LIKE UPPER(?)',
|
||||
['%' . filter_var($request->range, FILTER_SANITIZE_STRING) . '%']
|
||||
);
|
||||
});
|
||||
},
|
||||
null,
|
||||
'name',
|
||||
'description',
|
||||
'gamme',
|
||||
'reference'
|
||||
);
|
||||
} //end if
|
||||
|
|
|
|||
|
|
@ -1,628 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Fo\CustomerRegisterRequest;
|
||||
use App\Http\Requests\Fo\LoginRequest;
|
||||
use App\Http\Requests\Fo\UpdateInfosRequest;
|
||||
use App\Mail\PasswordResetMail;
|
||||
use App\Mail\RegisterConfirmMail;
|
||||
use App\Models\Customers;
|
||||
use App\Models\Shop;
|
||||
use App\Models\Order;
|
||||
use App\Models\PasswordReset;
|
||||
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\Facades\Validator;
|
||||
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;
|
||||
use LDC\LDCCRM\Models\SingleOptin;
|
||||
|
||||
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 \App\Http\Requests\Fo\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();
|
||||
|
||||
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 \App\Http\Requests\Fo\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 \App\Http\Requests\Fo\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) {
|
||||
$shop = null;
|
||||
} else {
|
||||
$shop = Shop::find($order->timeslot->shop->id);
|
||||
}
|
||||
|
||||
return view('customer.order-detail', compact('order', 'shop'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 \App\Http\Requests\Fo\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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the CRM to add a single optin
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
*/
|
||||
public function addOptIn(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), ['email' => 'required|email']);
|
||||
if ($validator->fails()) {
|
||||
return __('L\'adresse email est incorrecte');
|
||||
}
|
||||
|
||||
try {
|
||||
SingleOptin::setStatus($request->email, true);
|
||||
return trans('Votre inscription à la newsletter a été prise en compte');
|
||||
} catch (ApiErrorException $e) {
|
||||
// * Il y a deja un customerInfo avec optin a true pour ce customer
|
||||
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists())) {
|
||||
return trans('Vous êtes déjà inscrit avec cette adresse email');
|
||||
}
|
||||
report($e);
|
||||
return trans('Une erreur est survenue, merci de réessayer ultérieurement');
|
||||
} catch (CrmException $e) {
|
||||
report($e);
|
||||
return trans('Une erreur est survenue, merci de réessayer ultérieurement');
|
||||
}
|
||||
return trans('Une erreur est survenue, merci de réessayer ultérieurement ');
|
||||
}
|
||||
}
|
||||
35
app/Http/Controllers/Fo/Auth/ConfirmPasswordController.php
Normal file
35
app/Http/Controllers/Fo/Auth/ConfirmPasswordController.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Display the password confirmation view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showConfirmForm()
|
||||
{
|
||||
if (Auth::guard('frontend')->check()) {
|
||||
return \response()->redirectToRoute('home');
|
||||
}
|
||||
return view('front.auth.passwords.confirm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
{
|
||||
return response()->redirectToRoute('home')->getTargetUrl();
|
||||
}
|
||||
}
|
||||
82
app/Http/Controllers/Fo/Auth/ForgotPasswordController.php
Normal file
82
app/Http/Controllers/Fo/Auth/ForgotPasswordController.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
use SendsPasswordResetEmails;
|
||||
|
||||
/**
|
||||
* Message to user
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $message =
|
||||
'Si votre compte existe vous devriez recevoir un message avec un lien pour réinitialiser votre mot de passe';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form to request a password reset link.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showLinkRequestForm()
|
||||
{
|
||||
return view('auth.passwords.email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker()
|
||||
{
|
||||
return Password::broker('customers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a successful password reset link.
|
||||
* ! Dans les deux cas on ne divulgue pas si un user existe.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkResponse()
|
||||
{
|
||||
return back()->with('info', trans($this->message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a failed password reset link.
|
||||
* ! Dans les deux cas on ne divulgue pas si un user existe.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, string $response)
|
||||
{
|
||||
// ! Ne pas notifier que l'utilisateur n'existe pas.
|
||||
if ($response === 'passwords.user') {
|
||||
return back()->with('info', trans($this->message));
|
||||
}
|
||||
// * Renvoyer les autres message d'erreur style throttle.
|
||||
return back()
|
||||
->withInput($request->only('email'))
|
||||
->withErrors(['email' => trans($response)]);
|
||||
}
|
||||
}
|
||||
96
app/Http/Controllers/Fo/Auth/LoginController.php
Normal file
96
app/Http/Controllers/Fo/Auth/LoginController.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use AuthenticatesUsers;
|
||||
use ThrottlesLogins;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend')->except('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has been authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param null $user
|
||||
* @return mixed
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
*/
|
||||
protected function authenticated(Request $request, $user)
|
||||
{
|
||||
/** @var \App\Models\Customer|null */
|
||||
$user = Auth::guard('frontend')->user();
|
||||
if ($user) {
|
||||
$user->saveOrFail();
|
||||
Session::flash('info', trans('Vous êtes à présent connecté'));
|
||||
}
|
||||
// FIXME: Read destroy basket here.
|
||||
// OrderController::detroyCurrentBasket();
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has logged out of the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function loggedOut(Request $request)
|
||||
{
|
||||
Session::flash('info', trans('Vous êtes à présent déconnecté'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
{
|
||||
return response()->redirectToRoute('home')->getTargetUrl();
|
||||
}
|
||||
}
|
||||
174
app/Http/Controllers/Fo/Auth/RegisterController.php
Normal file
174
app/Http/Controllers/Fo/Auth/RegisterController.php
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\CreateAccountRequest;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Enums\Country;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
return view('auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
* @throws \Illuminate\Validation\ValidationException If local client cannot validate data.
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
$data['optin'] = \request()->boolean('optin');
|
||||
$data['ok_cgv'] = \request()->boolean('ok_cgv');
|
||||
|
||||
// * Let Crm client validate data
|
||||
try {
|
||||
(new CrmCustomer())->fill($this->getOnlyCrmData($data));
|
||||
} catch (CrmValidationException $e) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
$request = new CreateAccountRequest();
|
||||
|
||||
$data['phone'] = $data['phone'] ?? null;
|
||||
$data['opt_in'] = ($data['opt_in'] ?? false) ? true : false;
|
||||
return Validator::make(
|
||||
$data,
|
||||
$request->rules(),
|
||||
$request->messages(),
|
||||
$request->attributes()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\Customer
|
||||
* @throws \Illuminate\Validation\ValidationException If there are validation errors.
|
||||
* @throws \RuntimeException On unhandled api Error.
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
$data['country'] = Country::france();
|
||||
|
||||
try {
|
||||
return DB::transaction(function () use ($data) {
|
||||
$crmCustomer = new CrmCustomer($this->getOnlyCrmData($data));
|
||||
|
||||
// * Country Is forced to france
|
||||
$crmCustomer->country = Country::france();
|
||||
$crmCustomer->save();
|
||||
|
||||
// * Enregistrement du Hashcode
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = new Customer($data);
|
||||
$customer->hashcode = $crmCustomer->hashcode;
|
||||
// * Customer will be logged in.
|
||||
$customer->last_connection = \now();
|
||||
$customer->saveOrFail();
|
||||
|
||||
if ($customer->saveOrFail()) {
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
Session::flash('success', trans('Votre compte à bien été crée, vous devez valider votre adresse email, un email de confirmation vous à été envoyé.'));
|
||||
}
|
||||
|
||||
return $customer;
|
||||
});
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::customerExists())) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => 'Un compte est déjà associé à cette adresse email.'
|
||||
]);
|
||||
}
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed())) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
} //end try
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
{
|
||||
return response()->redirectToRoute('account.dashboard')->getTargetUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only data used in crm
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
private function getOnlyCrmData(array $data): array
|
||||
{
|
||||
return \array_intersect_key(
|
||||
$data,
|
||||
[
|
||||
'firstname' => '',
|
||||
'lastname' => '',
|
||||
'birth_date' => '',
|
||||
'address' => '',
|
||||
'postcode' => '',
|
||||
'country' => '',
|
||||
'city' => '',
|
||||
'phone' => '',
|
||||
'email' => '',
|
||||
'password' => '',
|
||||
'opt_in' => '',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
121
app/Http/Controllers/Fo/Auth/ResetPasswordController.php
Normal file
121
app/Http/Controllers/Fo/Auth/ResetPasswordController.php
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as ExceptionsValidationException;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the password reset view for the given token.
|
||||
*
|
||||
* If no token is present, display the link request form.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function showResetForm(Request $request)
|
||||
{
|
||||
$token = $request->route()->parameter('token');
|
||||
|
||||
return view('auth.passwords.reset')->with(
|
||||
['token' => $token, 'email' => $request->email]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param mixed $customer
|
||||
* @param mixed $password
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If something goes wrong.
|
||||
*/
|
||||
protected function resetPassword($customer, $password)
|
||||
{
|
||||
/** @var \App\Models\Customer $user */
|
||||
/** @var string $password */
|
||||
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
try {
|
||||
if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => 'Changement impossible, compte inexistant.'
|
||||
]);
|
||||
}
|
||||
$crmCustomer->password = $password;
|
||||
$crmCustomer->save();
|
||||
} catch (\TypeError | CrmException | ApiErrorException $e) {
|
||||
report($e);
|
||||
throw ValidationException::withMessages([
|
||||
'error' => 'Une erreur est survenue, merci de réessayer ultérieurement.'
|
||||
]);
|
||||
} catch (ExceptionsValidationException $e) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
$customer->setRememberToken(Str::random(60));
|
||||
|
||||
$customer->save();
|
||||
|
||||
event(new PasswordReset($customer));
|
||||
|
||||
$this->guard()->login($customer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
{
|
||||
return response()->redirectToRoute('home')->getTargetUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker()
|
||||
{
|
||||
return Password::broker('customers');
|
||||
}
|
||||
}
|
||||
47
app/Http/Controllers/Fo/Auth/VerificationController.php
Normal file
47
app/Http/Controllers/Fo/Auth/VerificationController.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth:frontend');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the email verification notice.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function show(Request $request)
|
||||
{
|
||||
return $request->user()->hasVerifiedEmail()
|
||||
? redirect($this->redirectPath())
|
||||
: view('auth.verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
{
|
||||
return response()->redirectToRoute('home')->getTargetUrl();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Enums\GeneralConfigType;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
|
|
@ -111,8 +112,8 @@ class BasketController extends Controller
|
|||
$row->setDiscountRate($product->discountRate);
|
||||
|
||||
$cartextendedItem = array(
|
||||
'cartItem' => $row,
|
||||
'product' => $product
|
||||
'cartItem' => $row,
|
||||
'product' => $product
|
||||
);
|
||||
$dbpanier->add($cartextendedItem);
|
||||
}
|
||||
|
|
@ -149,21 +150,19 @@ class BasketController extends Controller
|
|||
'countItems' => Cart::count(),
|
||||
);
|
||||
|
||||
$cartReturn = array($dbpanier,$cartInfosNoPrice);
|
||||
$cartReturn = array($dbpanier, $cartInfosNoPrice);
|
||||
|
||||
/** @var \App\Models\GeneralConfig */
|
||||
$config = Cache::get('GeneralConfigGlobal')->where('type', GeneralConfigType::global())->first();
|
||||
|
||||
if (
|
||||
$config->data['orders_display_prices_for_auth']['value'] and
|
||||
Auth::guard('customer')->check()
|
||||
) {
|
||||
// ? Don't show prices only for auth customers ?
|
||||
if (!$config->data['orders_display_prices_for_auth']['value']) {
|
||||
return $cartReturn;
|
||||
}
|
||||
// ? Customer is auth ?
|
||||
if (Auth::guard('frontend')->check()) {
|
||||
$cartReturn = array($dbpanier, $cartInfos);
|
||||
}
|
||||
if ($config->data['orders_display_prices_for_public']['value']) {
|
||||
$cartReturn = array($dbpanier,$cartInfos);
|
||||
}
|
||||
|
||||
return $cartReturn;
|
||||
}
|
||||
}
|
||||
279
app/Http/Controllers/Fo/CustomerController.php
Normal file
279
app/Http/Controllers/Fo/CustomerController.php
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
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;
|
||||
use App\Models\Shop;
|
||||
use App\Models\Order;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
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('customer.dashboard', compact('customer', 'crmInfos'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show update customer informations form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function email()
|
||||
{
|
||||
return view('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 = \auth('frontend')->user();
|
||||
|
||||
// FIXME:Add warning email to customer !!!
|
||||
|
||||
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('auth.passwords.change');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update customer password
|
||||
*
|
||||
* @param UpdatePasswordRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function passwordSubmit(UpdatePasswordRequest $request)
|
||||
{
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = \auth('frontend')->user();
|
||||
|
||||
// FIXME:Add warning email to customer !!!
|
||||
|
||||
return $this->updateCrmCustomerInfo($customer, ['password' => $request->get('password')]) ?
|
||||
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.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = 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('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 () {
|
||||
|
||||
// FIXME:Add warning email to customer !!!
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
/** @var \Ldc\LDCCRM\Models\Customer */
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
$customer->deleteOrFail();
|
||||
$crmCustomer->delete();
|
||||
|
||||
// * Force logout
|
||||
auth('frontend')->logout();
|
||||
|
||||
return response()->redirectToRoute('home')
|
||||
->with('info', trans(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'Votre compte à bien été supprimé, si vous avez des commandes en cours vous pouvez utiliser le formulaire de contact en cas de besoin.'
|
||||
));
|
||||
});
|
||||
} 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
|
||||
* @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);
|
||||
return $crmCustomer->save();
|
||||
} 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
|
||||
});
|
||||
}
|
||||
|
||||
// * --- END Backoffice ---
|
||||
|
||||
|
||||
/**
|
||||
* 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('frontend')->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('frontend')->user()->id)
|
||||
->firstOrFail();
|
||||
|
||||
if ($order->status_id == 1) {
|
||||
$shop = null;
|
||||
} else {
|
||||
$shop = Shop::find($order->timeslot->shop->id);
|
||||
}
|
||||
|
||||
return view('customer.order-detail', compact('order', 'shop'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the CRM to add a single optin
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
*/
|
||||
public function addOptIn(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), ['email' => 'required|email']);
|
||||
if ($validator->fails()) {
|
||||
return __('L\'adresse email est incorrecte');
|
||||
}
|
||||
|
||||
try {
|
||||
SingleOptin::setStatus($request->email, true);
|
||||
return trans('Votre inscription à la newsletter a été prise en compte');
|
||||
} catch (ApiErrorException $e) {
|
||||
// * Il y a deja un customerInfo avec optin a true pour ce customer
|
||||
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists())) {
|
||||
return trans('Vous êtes déjà inscrit avec cette adresse email');
|
||||
}
|
||||
report($e);
|
||||
return trans('Une erreur est survenue, merci de réessayer ultérieurement');
|
||||
} catch (CrmException $e) {
|
||||
report($e);
|
||||
return trans('Une erreur est survenue, merci de réessayer ultérieurement');
|
||||
}
|
||||
return trans('Une erreur est survenue, merci de réessayer ultérieurement ');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use App\Models\Tag;
|
||||
|
|
@ -43,9 +44,9 @@ class ProductController extends Controller
|
|||
$products = Product::where('range_id', $range->id)->where('status', 1)->paginate(9);
|
||||
// Find promo within range.
|
||||
$offres = Product::where('range_id', $range->id)
|
||||
->where('status', 1)
|
||||
->has('discounts')
|
||||
->with('discounts')->get();
|
||||
->where('status', 1)
|
||||
->has('discounts')
|
||||
->with('discounts')->get();
|
||||
return view('range', compact('range', 'products', 'offres'));
|
||||
}
|
||||
|
||||
|
|
@ -65,17 +66,8 @@ class ProductController extends Controller
|
|||
if (!$product || !$product->status) {
|
||||
abort(404);
|
||||
}
|
||||
$product->additionnalProductInfo = $product->additionnalProductInfo($product->product_type);
|
||||
if ($product->additionnalProductInfo === null && !empty($product_type)) {
|
||||
// N'existe pas on renseigne un vide.
|
||||
$product_type = $product->product_type;
|
||||
$modelClass = 'App\Models\\' . ucfirst($product_type);
|
||||
$product->$product_type = new $modelClass();
|
||||
}
|
||||
|
||||
$associated = $product->products;
|
||||
|
||||
return view('product', compact('product', 'associated'));
|
||||
return view('product', ['productModel' => $product]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ use App\Models\Slider;
|
|||
use App\Models\StaticPage;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StaticPagesController extends Controller
|
||||
class StaticPageController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display static page type home
|
||||
|
|
@ -28,7 +28,7 @@ class StaticPagesController extends Controller
|
|||
$products = Product::where('status', 1)->where('star', 1)->get();
|
||||
|
||||
$slider = Slider::where('slug', 'home')->first();
|
||||
$slides = $slider->showableSlides;
|
||||
$slides = $slider->showable_slides;
|
||||
|
||||
$quickorder_ranges = Range::with('products')->get();
|
||||
foreach ($quickorder_ranges as $range) {
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\IsAdmin;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
|
|
@ -64,7 +63,6 @@ class Kernel extends HttpKernel
|
|||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'is-admin' => IsAdmin::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
|
|
@ -14,8 +15,24 @@ class Authenticate extends Middleware
|
|||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('auth.login');
|
||||
$logins = [
|
||||
'frontend' => route('login'),
|
||||
'backend' => route('bo.login')
|
||||
];
|
||||
if (!$request->expectsJson()) {
|
||||
// * Notify must login
|
||||
Session::flash('warning', trans('Veuillez vous connecter pour continuer'));
|
||||
|
||||
foreach ($request->route()->gatherMiddleware() as $middleware) {
|
||||
if (\is_string($middleware) and strpos($middleware, 'auth:') !== false) {
|
||||
$route = $logins[str_replace('auth:', '', $middleware)] ?? null;
|
||||
if ($route) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
return route('login');
|
||||
}
|
||||
abort(401);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class IsAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$role = Auth::user()->role;
|
||||
if ($role === 1 || $role === 2) {
|
||||
return $next($request);
|
||||
}
|
||||
abort(404, "Cette page n'existe pas.");
|
||||
}
|
||||
}
|
||||
|
|
@ -19,5 +19,8 @@ class TrustProxies extends Middleware
|
|||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers = Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,5 @@ class VerifyCsrfToken extends Middleware
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class DeleteTimeslotExceptionsRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class SaveTimeslotExceptionsRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class ChangeOrderRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class StoreDiscountRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class CreateProductRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Requests\Bo\Products;
|
||||
|
||||
use App\Enums\TaxRate;
|
||||
use App\Enums\WeightUnit;
|
||||
use App\Http\Requests\Bo\UpdateMiniCrudRequest;
|
||||
use App\Models\Product;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
|
|
@ -68,6 +69,7 @@ class StoreProductRequest extends UpdateMiniCrudRequest
|
|||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'weight' => \floatval($this->weight) * WeightUnit::kg()->conversion,
|
||||
'star' => $this->star ? true : false,
|
||||
'status' => $this->status ? true : false,
|
||||
'orderable' => $this->orderable ? true : false,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class FilterRangeRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class StoreRangeRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class StoreShopRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class StoreSliderRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class StoreSlideRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class StoreTagRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class UpdateTimeslotRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth()->check();
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class SearchXmlInco extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() and $this->ajax();
|
||||
return auth('backend')->check() and $this->ajax();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo;
|
||||
|
||||
use App\Enums\GeneralConfigType;
|
||||
use App\Rules\Adult;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CustomerRegisterRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
/** @var \App\Models\GeneralConfig */
|
||||
$config = Cache::get('GeneralConfigGlobal')->where('type', GeneralConfigType::global())->first();
|
||||
|
||||
/**
|
||||
* specify rules for various cases of registration
|
||||
* cf enum for register modes
|
||||
* si register autorisé pour salarié et tout public
|
||||
*/
|
||||
// FIXME: REmove stuff from salaries here.
|
||||
if (
|
||||
config('bosettings.register_salaries') &&
|
||||
$config->data['customer_register_public_mode']['value']
|
||||
) {
|
||||
$matriculeRule = 'nullable|exists:salaries,matricule';
|
||||
$codeRule = [
|
||||
'nullable',
|
||||
Rule::exists('salaries', 'code')
|
||||
->where('matricule', data_get($this->all(), 'matricule'))
|
||||
];
|
||||
} elseif (
|
||||
config('bosettings.register_salaries') &&
|
||||
!$config->data['customer_register_public_mode']['value']
|
||||
) {
|
||||
// * si register autorisé pour salarié seulement
|
||||
$matriculeRule = 'required|exists:salaries,matricule';
|
||||
$codeRule = [
|
||||
'required',
|
||||
Rule::exists('salaries', 'code')
|
||||
->where('matricule', data_get($this->all(), 'matricule'))
|
||||
];
|
||||
} else {
|
||||
// * rien de précisé ou public seulement alors
|
||||
$matriculeRule = 'sometimes';
|
||||
$codeRule = 'sometimes';
|
||||
}//end if
|
||||
|
||||
return [
|
||||
'matricule' => $matriculeRule,
|
||||
'code' => $codeRule,
|
||||
'lastname' => 'required|string|max:255',
|
||||
'firstname' => 'required|string|max:255',
|
||||
'phone' => 'sometimes|max:255',
|
||||
'address' => 'sometimes|max:255',
|
||||
'postal_code' => 'required',
|
||||
'town' => 'required|string|max:255',
|
||||
'email' => 'required|email:rfc,dns,spoof|max:255',
|
||||
'password' => 'required|confirmed|min:8|max:255',
|
||||
'ok_cgv' => 'accepted',
|
||||
'optin' => 'sometimes',
|
||||
'birth_date' => ['required', new Adult()],
|
||||
];
|
||||
}
|
||||
}
|
||||
42
app/Http/Requests/Fo/Customers/ConfirmDeleteRequest.php
Normal file
42
app/Http/Requests/Fo/Customers/ConfirmDeleteRequest.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ConfirmDeleteRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('frontend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'confirm' => 'accepted'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom messages for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'confirm.accepted' => trans('Pour supprimer votre compte vous devez cocher la case de confirmation.')
|
||||
];
|
||||
}
|
||||
}
|
||||
109
app/Http/Requests/Fo/Customers/CreateAccountRequest.php
Normal file
109
app/Http/Requests/Fo/Customers/CreateAccountRequest.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use App\Rules\Adult;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use LDC\LDCCRM\Enums\Country;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
class CreateAccountRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::guard('frontend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'phone' => $this->phone,
|
||||
'opt_in' => $this->opt_in ? true : false
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'lastname' => 'required|string|max:255',
|
||||
'firstname' => 'required|string|max:255',
|
||||
'phone' => 'nullable|max:255|phone:FR',
|
||||
'address' => 'required|string|min:1|max:255',
|
||||
'postcode' => 'required|string|min:1|postal_code:FR',
|
||||
'city' => 'required|string|min:1|max:255',
|
||||
'birth_date' => ['required', new Adult()],
|
||||
'email' => [
|
||||
'required', 'email:rfc,dns,spoof', 'max:255',
|
||||
// * Does email already exists in CRM ?
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function (string $attribute, $value, \Closure $fail) {
|
||||
if (CrmCustomer::findWithEmail(\strval($value))) {
|
||||
$fail('Un compte existe déjà avec cette adresse.');
|
||||
}
|
||||
},
|
||||
'unique:customers,email',
|
||||
],
|
||||
'password' => 'required|confirmed|min:8|max:255',
|
||||
'ok_cgv' => 'accepted',
|
||||
'opt_in' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return [
|
||||
'lastname' => trans('nom'),
|
||||
'firstname' => trans('prénom'),
|
||||
'phone' => trans('téléphone'),
|
||||
'address' => trans('adresse'),
|
||||
'postcode' => trans('code postal'),
|
||||
'city' => trans('ville'),
|
||||
'birth_date' => trans('date de naissance'),
|
||||
'email' => trans('email'),
|
||||
'password' => trans('mot de passe'),
|
||||
'ok_cgv' => trans('conditions d\'utilisation'),
|
||||
'opt_in' => trans('newsletter'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom messages for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'phone.phone' => trans('Le champ :attribute est invalide, il accepte les numéros des pays suivants :countries.', [
|
||||
'countries' => Country::france()->label
|
||||
]),
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'country.in' => trans('Le champ :attribute est invalide, il accepte les pays suivants :countries.', [
|
||||
'countries' => Country::france()->label
|
||||
]),
|
||||
'email.unique' => trans('Un compte existe déjà avec cette adresse.'),
|
||||
'ok_cgv.accepted' => trans('Vous devez accepter les conditions d\'utilisation du site pour continuer.'),
|
||||
];
|
||||
}
|
||||
}
|
||||
48
app/Http/Requests/Fo/Customers/UpdateEmailRequest.php
Normal file
48
app/Http/Requests/Fo/Customers/UpdateEmailRequest.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use App\Rules\CrmCustomerPassword;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Ldc\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
class UpdateEmailRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return \auth('frontend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
/** @var \Ldc\LDCCRM\Models\Customer */
|
||||
$crmCustomer = \auth('frontend')->user()->api_data;
|
||||
return [
|
||||
'password' => [
|
||||
'required',
|
||||
new CrmCustomerPassword($crmCustomer)
|
||||
],
|
||||
'email' => [
|
||||
'required', 'email:rfc,dns,spoof', 'max:255', 'unique:customers,email',
|
||||
// * Does email already exists in CRM ?
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function (string $attribute, $value, \Closure $fail) {
|
||||
if (CrmCustomer::findWithEmail(\strval($value))) {
|
||||
$fail('Un compte existe déjà avec cette adresse.');
|
||||
}
|
||||
},
|
||||
'unique:customers,email',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/Fo/Customers/UpdateInfosRequest.php
Normal file
31
app/Http/Requests/Fo/Customers/UpdateInfosRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
class UpdateInfosRequest extends CreateAccountRequest
|
||||
{
|
||||
/** @var array */
|
||||
private static $skeleton = [
|
||||
'lastname',
|
||||
'firstname',
|
||||
'phone',
|
||||
'address',
|
||||
'postcode',
|
||||
'city',
|
||||
'opt_in',
|
||||
'birth_date'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return \array_intersect_key(
|
||||
parent::rules(),
|
||||
\array_flip(self::$skeleton)
|
||||
);
|
||||
}
|
||||
}
|
||||
54
app/Http/Requests/Fo/Customers/UpdatePasswordRequest.php
Normal file
54
app/Http/Requests/Fo/Customers/UpdatePasswordRequest.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use App\Rules\CrmCustomerPassword;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdatePasswordRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('frontend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
/** @var \Ldc\LDCCRM\Models\Customer */
|
||||
$crmCustomer = \auth('frontend')->user()->api_data;
|
||||
return [
|
||||
'old_password' => [
|
||||
'required',
|
||||
new CrmCustomerPassword($crmCustomer)
|
||||
],
|
||||
'password' => [
|
||||
'required', 'string', 'max:255', 'confirmed',
|
||||
Password::min(8)->mixedCase()->letters()->numbers()->uncompromised()
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return [
|
||||
'old_password' => trans('ancien mot de passe'),
|
||||
'password' => trans('mot de passe'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class LoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$this->merge([
|
||||
'remember' => $this->remember ? true : false
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email:rfc,filter',
|
||||
'password' => 'required',
|
||||
'remember' => 'required|boolean'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UpdateInfosRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::guard('customer')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'firstname' => 'required|string|max:255',
|
||||
'lastname' => 'required|string|max:255',
|
||||
'day' => 'required|numeric|gt:0|lt:32',
|
||||
'month' => 'required|numeric|gt:0|lt:13',
|
||||
'year' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'gt:' . (date('Y') - 101), 'lt:' . (date('Y') + 1),
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attr, $value, $fail) {
|
||||
$MJ = Carbon::now()->subYears(18);
|
||||
$dateTest = Carbon::createFromDate($this->year, $this->month, $this->day);
|
||||
if (
|
||||
$dateTest->format('dmY') !== $this->day . $this->month . $this->year ||
|
||||
$dateTest->getTimestamp() > time()
|
||||
) {
|
||||
$fail(__('Veuillez entrer une date de naissance valide'));
|
||||
}
|
||||
if (!$dateTest->lessThanOrEqualTo($MJ)) {
|
||||
$fail(__("Vous devez être majeur pour vous inscrire."));
|
||||
}
|
||||
}
|
||||
],
|
||||
'address' => 'max:255',
|
||||
'phone' => 'max:255',
|
||||
'city' => 'required|string|max:255',
|
||||
'postcode' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -3,19 +3,19 @@
|
|||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use App\Models\Customers;
|
||||
use App\Models\Customer;
|
||||
|
||||
class CustomerCrmResource extends JsonResource
|
||||
{
|
||||
/** @var \App\Models\Customers */
|
||||
/** @var \App\Models\Customer */
|
||||
private $customer;
|
||||
|
||||
/**
|
||||
* CustomerCrmResource
|
||||
*
|
||||
* @param \App\Models\Customers $customer
|
||||
* @param \App\Models\Customer $customer
|
||||
*/
|
||||
public function __construct(Customers $customer)
|
||||
public function __construct(Customer $customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -468,6 +468,7 @@ class XmlIncoReader extends XmlJobs
|
|||
if (empty($imgName)) {
|
||||
$imgName = strval($xmlData->INCO->NO_ART);
|
||||
}
|
||||
// FIXME: Comply with store image name only.
|
||||
// * Store only picture name.
|
||||
$imgNamePath = $imgName . "_" . $index;
|
||||
|
||||
|
|
|
|||
|
|
@ -205,4 +205,50 @@ class ToolboxHelper
|
|||
}
|
||||
return $ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an object to array
|
||||
*
|
||||
* @param array|object $input
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray($input): array
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (array)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an array to object
|
||||
*
|
||||
* @param array|object $input
|
||||
* @return object
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function arrayToObject($input): object
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (object)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
|
|
@ -13,21 +14,30 @@ class PasswordResetMail extends Mailable implements ShouldQueue
|
|||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* Reset token
|
||||
* target Customer
|
||||
*
|
||||
* @var \App\Models\Customer
|
||||
*/
|
||||
private $customer;
|
||||
|
||||
/**
|
||||
* Reset url
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $token;
|
||||
private $resetUrl;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param string $token
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param string $resetUrl
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $token)
|
||||
public function __construct(Customer $customer, string $resetUrl)
|
||||
{
|
||||
$this->token = $token;
|
||||
$this->customer = $customer;
|
||||
$this->resetUrl = $resetUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,9 +47,10 @@ class PasswordResetMail extends Mailable implements ShouldQueue
|
|||
*/
|
||||
public function build()
|
||||
{
|
||||
$token = $this->token;
|
||||
$resetUrl = $this->resetUrl;
|
||||
return $this->subject(
|
||||
"Réinitialiser votre accès - " . config('theme.site_name')
|
||||
)->view('mails.password-reset', compact('token'));
|
||||
)->to($this->customer->email)
|
||||
->view('mails.password-reset', compact('resetUrl'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Customers;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
|
|
@ -16,10 +16,17 @@ class RegisterConfirmMail extends Mailable implements ShouldQueue
|
|||
/**
|
||||
* target Customer
|
||||
*
|
||||
* @var \App\Models\Customers
|
||||
* @var \App\Models\Customer
|
||||
*/
|
||||
private $customer;
|
||||
|
||||
/**
|
||||
* The confirmation Url
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $confirmUrl;
|
||||
|
||||
/**
|
||||
* Customer's firstname
|
||||
*
|
||||
|
|
@ -30,14 +37,16 @@ class RegisterConfirmMail extends Mailable implements ShouldQueue
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \App\Models\Customers $customer
|
||||
* @param string|null $firstname
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param string $confirmUrl
|
||||
* @param string $firstname
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Customers $customer, string $firstname = null)
|
||||
public function __construct(Customer $customer, string $confirmUrl, string $firstname)
|
||||
{
|
||||
$this->firstname = $firstname;
|
||||
$this->customer = $customer;
|
||||
$this->confirmUrl = $confirmUrl;
|
||||
$this->firstname = $firstname;
|
||||
$this->customer = $customer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,9 +56,11 @@ class RegisterConfirmMail extends Mailable implements ShouldQueue
|
|||
*/
|
||||
public function build()
|
||||
{
|
||||
$customer = $this->customer;
|
||||
$firstname = $this->firstname;
|
||||
$confirmUrl = $this->confirmUrl;
|
||||
$customer = $this->customer;
|
||||
$firstname = $this->firstname;
|
||||
return $this->subject("Confirmation d'inscription " . config('theme.site_name'))
|
||||
->view('mails.register-ok', compact('customer', 'firstname'));
|
||||
->to($customer->email, $firstname)
|
||||
->view('mails.register-ok', compact('customer', 'firstname', 'confirmUrl'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
223
app/Models/Customer.php
Normal file
223
app/Models/Customer.php
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Http\Resources\CustomerCrmResource;
|
||||
use App\Notifications\Customer\ResetPassword as NotificationResetPassword;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use App\Notifications\Customer\VerifyEmail as NotificationVerifyEmail;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
/**
|
||||
* @property \LDC\LDCCRM\Models\Customer api_data
|
||||
* @package App\Models
|
||||
*/
|
||||
class Customer extends Authenticatable implements MustVerifyEmail, CanResetPassword
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'email',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'last_connection' => 'datetime',
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
// * EVENT CLOSURES.
|
||||
static::creating(function (self $model) {
|
||||
static::assertEmailIsUnique($model->id, $model->email);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
static::assertEmailIsUnique($model->id, $model->email);
|
||||
});
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Asserts using validation that the email is unique
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param mixed $email
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If user email as already used.
|
||||
*/
|
||||
private static function assertEmailIsUnique($id, $email)
|
||||
{
|
||||
self::assertFieldIsUnique($id, 'email', $email);
|
||||
}
|
||||
|
||||
// * --- AUTH ---
|
||||
|
||||
/**
|
||||
* Send the email verification notification.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sendEmailVerificationNotification()
|
||||
{
|
||||
$this->notify(new NotificationVerifyEmail());
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the given user's email as verified.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
|
||||
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
|
||||
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
public function markEmailAsVerified()
|
||||
{
|
||||
try {
|
||||
return $this->api_data->activate() && parent::markEmailAsVerified();
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::customerAlreadyActive())) {
|
||||
return true && parent::markEmailAsVerified();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the password reset notification.
|
||||
*
|
||||
* @param mixed $token
|
||||
* @return void
|
||||
*/
|
||||
public function sendPasswordResetNotification($token)
|
||||
{
|
||||
/** @var string $token */
|
||||
$this->notify(new NotificationResetPassword($token));
|
||||
}
|
||||
|
||||
// * --- END AUTH ---
|
||||
|
||||
/**
|
||||
* Asserts that the field is unique
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
*/
|
||||
private static function assertFieldIsUnique($id, string $field, $value)
|
||||
{
|
||||
Validator::make([$field => $value], [
|
||||
$field => Rule::unique('customers', $field)->ignore($id),
|
||||
], [
|
||||
$field . '.unique' => trans('La valeur :value pour le champ :attribute est déjà utilisé', [
|
||||
'attribute' => $field,
|
||||
'value' => $value
|
||||
])
|
||||
])->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the crm Data of a customer
|
||||
*
|
||||
* @return \LDC\LDCCRM\Models\Customer
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException If cannot fetch data from crm.
|
||||
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
||||
*/
|
||||
public function getApiDataAttribute(): CrmCustomer
|
||||
{
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
$crmCustomer = $crm->getCustomer($this->hashcode);
|
||||
if (!$crmCustomer) {
|
||||
throw new CrmException('CRM get Customer returned null');
|
||||
}
|
||||
return $crmCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the crm Data of a customer
|
||||
* @param CustomerCrmResource $resource
|
||||
*
|
||||
* @return CrmCustomer
|
||||
*
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
|
||||
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
|
||||
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
public function updateApiData(CustomerCrmResource $resource): CrmCustomer
|
||||
{
|
||||
$data = $resource->toArray(null);
|
||||
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
$crmCustomer = $crm->getCustomer($data['hashcode']);
|
||||
if (!$crmCustomer) {
|
||||
throw new CrmException('CRM get Customer returned null');
|
||||
}
|
||||
|
||||
$crmCustomer->fill($data);
|
||||
$crmCustomer->save();
|
||||
|
||||
return $crmCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
* This mutate Customer attributes to array
|
||||
* including only non critical properties and crm values
|
||||
* (One that can be send to front office without security breach)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
if ($this->hashcode) {
|
||||
return collect(array_merge(
|
||||
parent::toArray(),
|
||||
(array)$this->apiData
|
||||
))->intersectByKeys([
|
||||
'email' => '',
|
||||
'firstname' => '',
|
||||
'lastname' => '',
|
||||
'address' => '',
|
||||
'address2' => '',
|
||||
'postcode' => '',
|
||||
'birth_date' => '',
|
||||
'city' => '',
|
||||
'country' => '',
|
||||
'opt_in' => '',
|
||||
'phone' => ''
|
||||
])->toArray();
|
||||
} else {
|
||||
return parent::toArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Http\Resources\CustomerCrmResource;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use App\Models\Salarie;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
class Customers extends Authenticatable
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'email',
|
||||
'username'
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
protected $guard = 'customer';
|
||||
|
||||
|
||||
/**
|
||||
* hasOne salarie relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
public function salarie()
|
||||
{
|
||||
return $this->hasOne(Salarie::class, 'customer_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the crm Data of a customer
|
||||
*
|
||||
* @return \LDC\LDCCRM\Models\Customer
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException If cannot fetch data from crm.
|
||||
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
||||
*/
|
||||
public function getApiDataAttribute(): CrmCustomer
|
||||
{
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
$crmCustomer = $crm->getCustomer($this->hashcode);
|
||||
if (!$crmCustomer) {
|
||||
throw new CrmException('CRM get Customer returned null');
|
||||
}
|
||||
return $crmCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the crm Data of a customer
|
||||
* @param CustomerCrmResource $resource
|
||||
*
|
||||
* @return CrmCustomer
|
||||
*
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
|
||||
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
|
||||
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
public function updateApiData(CustomerCrmResource $resource): CrmCustomer
|
||||
{
|
||||
$data = $resource->toArray(null);
|
||||
|
||||
/** @var \LDC\LDCCRM\CrmApiV2 */
|
||||
$crm = app('crmAPI');
|
||||
$crmCustomer = $crm->getCustomer($data['hashcode']);
|
||||
if (!$crmCustomer) {
|
||||
throw new CrmException('CRM get Customer returned null');
|
||||
}
|
||||
|
||||
$crmCustomer->fill($data);
|
||||
$crmCustomer->save();
|
||||
|
||||
return $crmCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
* This mutate Customer attributes to array
|
||||
* including only non critical properties and crm values
|
||||
* (One that can be send to front office without security breach)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
if ($this->hashcode) {
|
||||
return collect(array_merge(
|
||||
parent::toArray(),
|
||||
(array)$this->apiData
|
||||
))->intersectByKeys([
|
||||
'email' => '',
|
||||
'firstname' => '',
|
||||
'lastname' => '',
|
||||
'address' => '',
|
||||
'address2' => '',
|
||||
'postcode' => '',
|
||||
'birth_date' => '',
|
||||
'city' => '',
|
||||
'country' => '',
|
||||
'opt_in' => '',
|
||||
'phone' => ''
|
||||
])->toArray();
|
||||
} else {
|
||||
return parent::toArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ class Order extends Model
|
|||
*/
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo(Customers::class);
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ use Kwaadpepper\Enum\Traits\CastsEnums;
|
|||
* @property float discountedPriceTtc|string Price after discount VAT included
|
||||
* @property float discountAmount Discount amount
|
||||
* @property float discountRate Discount rate
|
||||
* @property array data The overlapped data like defined in template.
|
||||
* @property array dataObject The overlapped data like defined in template as object.
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
|
|
@ -193,19 +195,7 @@ class Product extends Model implements Buyable
|
|||
*/
|
||||
public function discounts()
|
||||
{
|
||||
return $this->belongsToMany(Discount::class)
|
||||
->whereDate('date_start', '<=', now())
|
||||
->whereDate('date_end', '>=', now());
|
||||
}
|
||||
|
||||
/**
|
||||
* belongsTo tax relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function tax()
|
||||
{
|
||||
return $this->belongsTo(TaxRate::class);
|
||||
return $this->belongsToMany(Discount::class, 'product_discount');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -295,15 +285,32 @@ class Product extends Model implements Buyable
|
|||
}
|
||||
|
||||
/**
|
||||
* Get inco nutritionnal values
|
||||
* Getter data_object, the object overloaded attributes from theme
|
||||
*
|
||||
* @return array
|
||||
* @return object
|
||||
*/
|
||||
public function getIncoNutritionalValues(): array
|
||||
public function getDataObjectAttribute(): object
|
||||
{
|
||||
return ToolboxHelper::arrayToObject($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inco nutritionnal values, if product is inco.
|
||||
*
|
||||
* @return object|null
|
||||
*/
|
||||
public function getIncoNutritionalValues(): ?object
|
||||
{
|
||||
if (!$this->hasAndIsInco()) {
|
||||
return null;
|
||||
}
|
||||
$nutri_values = $this->xmlInco->nutritional_values;
|
||||
|
||||
return [
|
||||
if (empty($nutri_values)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (object)[
|
||||
// Pour la ref.
|
||||
'nv_ref_weight_g' => $nutri_values['taille_ref'],
|
||||
// Energie Kj.
|
||||
|
|
@ -610,31 +617,6 @@ class Product extends Model implements Buyable
|
|||
return \intval($this->attributes['price']) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter weight
|
||||
*
|
||||
* ! Stored as integer (grammes)
|
||||
*
|
||||
* @param float $value
|
||||
* @return void
|
||||
*/
|
||||
public function setWeightAttribute(float $value)
|
||||
{
|
||||
$this->attributes['weight'] = \intval($value * 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter weight
|
||||
*
|
||||
* ! Stored as (grammes)
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getWeightAttribute(): float
|
||||
{
|
||||
return \intval($this->attributes['weight']) / 100;
|
||||
}
|
||||
|
||||
// * Dynamic Minicrud inputs
|
||||
|
||||
/**
|
||||
|
|
@ -786,56 +768,42 @@ class Product extends Model implements Buyable
|
|||
/**
|
||||
* Getter for discounted price
|
||||
*
|
||||
* @return float
|
||||
* @return integer
|
||||
*/
|
||||
public function getDiscountedPriceHtAttribute()
|
||||
public function getDiscountedPriceHtAttribute(): int
|
||||
{
|
||||
$discountedPriceHt = $this->priceHt - $this->discountAmount;
|
||||
$roundingdiscountedPriceHt = round($discountedPriceHt * 1000) / 1000;
|
||||
return \floatval($roundingdiscountedPriceHt);
|
||||
return $this->priceHt - $this->discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for net price
|
||||
*
|
||||
* @return float
|
||||
* @return integer
|
||||
*/
|
||||
public function getPriceTtcAttribute()
|
||||
public function getPriceTtcAttribute(): int
|
||||
{
|
||||
$priceTtc = $this->priceHt * (1 + ($this->tax->rate / 100));
|
||||
$priceTtc = $this->priceHt * (1 + ($this->tax_rate->value / 100));
|
||||
/**
|
||||
* On travaille avec des centimes puis on redivise par 100 pour avoir des unités monetaires
|
||||
* on augmente la précision à 3 digits, l'affichage formate les prix sur 2 décimales
|
||||
*/
|
||||
return \floatval(round($priceTtc * 1000) / 1000);
|
||||
return round($priceTtc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for net discounted price
|
||||
*
|
||||
* @return float|string
|
||||
* @return integer
|
||||
*/
|
||||
public function getDiscountedPriceTtcAttribute()
|
||||
{
|
||||
/** @var \App\Models\GeneralConfig */
|
||||
$config = Cache::get('GeneralConfigGlobal')->where('type', GeneralConfigType::global())->first();
|
||||
|
||||
$discountedPriceTtc = $this->discountedPriceHt * (1 + ($this->tax->rate / 100));
|
||||
$discountedPriceTtc = $this->discountedPriceHt * (1 + ($this->tax_rate->value / 100));
|
||||
|
||||
// On travaille avec des centimes puis on redivise par 100 pour avoir des unités monetaires.
|
||||
$roundingDiscountedPriceTTC = \floatval(round($discountedPriceTtc * 1000) / 1000);
|
||||
|
||||
// Prix transmis en fonction du setting show_prices.
|
||||
if (
|
||||
$config->data['orders_display_prices_for_auth']['value'] and
|
||||
Auth::guard('customer')->check()
|
||||
) {
|
||||
return $roundingDiscountedPriceTTC;
|
||||
}
|
||||
if ($config->data['orders_display_prices_for_public']['value']) {
|
||||
return $roundingDiscountedPriceTTC;
|
||||
}
|
||||
return '-.--';
|
||||
// * Show prices for anyone.
|
||||
return $roundingDiscountedPriceTTC;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -900,4 +868,30 @@ class Product extends Model implements Buyable
|
|||
// @phpcs:enable
|
||||
return \floatval($this->priceHt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Config says to display prices ?
|
||||
* @return boolean
|
||||
*/
|
||||
public static function displayPrices(): bool
|
||||
{
|
||||
/** @var \App\Models\GeneralConfig */
|
||||
$config = Cache::get('GeneralConfigGlobal')->where('type', GeneralConfigType::global())->first();
|
||||
if ($config->data['orders_display_prices_for_auth']['value']) {
|
||||
return Auth::guard('frontend')->check();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get displayable price value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
public static function fmtCurrency($value): string
|
||||
{
|
||||
return self::displayPrices() ?
|
||||
sprintf('%s € TTC', number_format(\intval($value) / 100, 2, ',', ' ')) : '-.-- €';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,11 +81,11 @@ class Slider extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* filtered slides relation by showable date
|
||||
* Getter showable_slides filtered slides relation by showable date
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function showableSlides()
|
||||
public function getShowableSlidesAttribute()
|
||||
{
|
||||
$now = Carbon::now();
|
||||
return $this->hasMany(Slide::class, 'slider_id')
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use CastsEnums;
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
|
||||
|
|
@ -45,6 +48,15 @@ class User extends Authenticatable
|
|||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to Enums.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $enumCasts = [
|
||||
'role' => UserRole::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
|
|
|
|||
23
app/Notifications/Customer/ResetPassword.php
Normal file
23
app/Notifications/Customer/ResetPassword.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Notifications\Customer;
|
||||
|
||||
use App\Mail\PasswordResetMail;
|
||||
use Illuminate\Auth\Notifications\ResetPassword as NotificationsResetPassword;
|
||||
|
||||
class ResetPassword extends NotificationsResetPassword
|
||||
{
|
||||
/**
|
||||
* Build the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
/** @var \App\Models\Customer $notifiable */
|
||||
$resetUrl = $this->resetUrl($notifiable);
|
||||
|
||||
return new PasswordResetMail($notifiable, $resetUrl);
|
||||
}
|
||||
}
|
||||
27
app/Notifications/Customer/VerifyEmail.php
Normal file
27
app/Notifications/Customer/VerifyEmail.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Notifications\Customer;
|
||||
|
||||
use App\Mail\RegisterConfirmMail;
|
||||
use Illuminate\Auth\Notifications\VerifyEmail as NotificationsVerifyEmail;
|
||||
|
||||
class VerifyEmail extends NotificationsVerifyEmail
|
||||
{
|
||||
/**
|
||||
* Build the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
/** @var \App\Models\Customer $notifiable */
|
||||
$verificationUrl = $this->verificationUrl($notifiable);
|
||||
|
||||
return new RegisterConfirmMail(
|
||||
$notifiable,
|
||||
$verificationUrl,
|
||||
$notifiable->api_data->firstname
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,8 +21,8 @@ class ProductPolicy
|
|||
}
|
||||
|
||||
/**
|
||||
* @param App\Models\User|App\Models\Customers $user
|
||||
* @param \App\Models\Product $product
|
||||
* @param App\Models\User|App\Models\Customer $user
|
||||
* @param \App\Models\Product $product
|
||||
*
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
|
|
|
|||
|
|
@ -79,13 +79,12 @@ class AppServiceProvider extends ServiceProvider
|
|||
View::share('published_tags', $tags);
|
||||
}
|
||||
|
||||
Blade::directive('fmt_currency', function ($expression) {
|
||||
return "<?php
|
||||
if(is_float($expression)) {
|
||||
echo sprintf('%s € TTC', number_format($expression, 2, ',', ' '));
|
||||
} else {
|
||||
echo $expression;
|
||||
} ?>";
|
||||
Blade::directive('fmt_sellunit', function ($expression) {
|
||||
if (config('bosettings.sell_unit_management') == "strict") {
|
||||
return "<?php if(!empty($expression)) { echo sprintf('/ %s', SellUnit::make($expression)->label); } ?>";
|
||||
} else {
|
||||
return "<?php if(!empty($expression)) { echo sprintf('/ %s', $expression); } ?>";
|
||||
}
|
||||
});
|
||||
|
||||
Blade::directive('excerpt_product_title', function ($expression) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Auth\CrmUserProvider;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
|
|
@ -13,6 +14,10 @@ class AuthServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->app->auth->provider('crm', function ($app, array $config) {
|
||||
return new CrmUserProvider($app['hash'], $config['model']);
|
||||
});
|
||||
|
||||
$this->registerPolicies();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Events\LogVerifiedUser;
|
||||
use App\Events\PasswordHasReset;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
|
|
@ -17,6 +21,12 @@ class EventServiceProvider extends ServiceProvider
|
|||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
Verified::class => [
|
||||
LogVerifiedUser::class
|
||||
],
|
||||
PasswordReset::class => [
|
||||
PasswordHasReset::class
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -43,10 +43,19 @@ class RouteServiceProvider extends ServiceProvider
|
|||
|
||||
$this->routes(function () {
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web-bo.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web-fo.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web-shop.php'));
|
||||
});
|
||||
|
||||
// * BINDERS
|
||||
Route::model('discount', Discount::class);
|
||||
Route::model('product', Product::class);
|
||||
Route::model('range', Range::class);
|
||||
|
|
@ -85,9 +94,15 @@ class RouteServiceProvider extends ServiceProvider
|
|||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(150)->by(optional($request->user())->id ?: app('clientIp'));
|
||||
});
|
||||
RateLimiter::for('web', function (Request $request) {
|
||||
return Limit::perMinute(150)->by(optional($request->user())->id ?: app('clientIp'));
|
||||
});
|
||||
RateLimiter::for('credentials', function (Request $request) {
|
||||
return Limit::perMinute(30)->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
64
app/Rules/CrmCustomerPassword.php
Normal file
64
app/Rules/CrmCustomerPassword.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Models\Customer;
|
||||
|
||||
class CrmCustomerPassword implements Rule
|
||||
{
|
||||
/**
|
||||
* Crm Customer
|
||||
*
|
||||
* @var \LDC\LDCCRM\Models\Customer
|
||||
*/
|
||||
private $crmCustomer;
|
||||
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crmCustomer
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Customer $crmCustomer)
|
||||
{
|
||||
$this->crmCustomer = $crmCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param mixed $attribute
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any unhandled error occurs.
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
// phpcs:enable
|
||||
try {
|
||||
return Customer::login($this->crmCustomer->email, strval($value));
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::authFailed())) {
|
||||
return false;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Pass.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return trans('Votre ancien mot de passe n\'as pu être vérifié');
|
||||
}
|
||||
}
|
||||
0
bootstrap/cache/.gitignore
vendored
Normal file → Executable file
0
bootstrap/cache/.gitignore
vendored
Normal file → Executable file
|
|
@ -22,9 +22,10 @@
|
|||
"kwaadpepper/image-resizer": "^0.1.2",
|
||||
"laravel/framework": "^8.83",
|
||||
"laravel/tinker": "^2.5",
|
||||
"laravel/ui": "^3.4",
|
||||
"ldc/ldccrmv2client": "^3.0",
|
||||
"mews/purifier": "^3.3",
|
||||
"propaganistas/laravel-phone": "^4.3",
|
||||
"propaganistas/laravel-phone": "^4.4",
|
||||
"spatie/laravel-sitemap": "^5.8"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
|
|||
75
composer.lock
generated
75
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c943a3eea10496c9e31f2d7be2a3999c",
|
||||
"content-hash": "889af30f60588d725b5c17d1cacb64eb",
|
||||
"packages": [
|
||||
{
|
||||
"name": "alexusmai/laravel-file-manager",
|
||||
|
|
@ -2078,6 +2078,67 @@
|
|||
},
|
||||
"time": "2022-03-23T12:38:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/ui",
|
||||
"version": "v3.4.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/ui.git",
|
||||
"reference": "65ec5c03f7fee2c8ecae785795b829a15be48c2c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/ui/zipball/65ec5c03f7fee2c8ecae785795b829a15be48c2c",
|
||||
"reference": "65ec5c03f7fee2c8ecae785795b829a15be48c2c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/console": "^8.42|^9.0",
|
||||
"illuminate/filesystem": "^8.42|^9.0",
|
||||
"illuminate/support": "^8.82|^9.0",
|
||||
"illuminate/validation": "^8.42|^9.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^6.23|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Ui\\UiServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Ui\\": "src/",
|
||||
"Illuminate\\Foundation\\Auth\\": "auth-backend/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel UI utilities and presets.",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"ui"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/laravel/ui/tree/v3.4.6"
|
||||
},
|
||||
"time": "2022-05-20T13:38:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ldc/ldccrmv2client",
|
||||
"version": "3.0.5",
|
||||
|
|
@ -3034,16 +3095,16 @@
|
|||
},
|
||||
{
|
||||
"name": "propaganistas/laravel-phone",
|
||||
"version": "4.3.8",
|
||||
"version": "4.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Propaganistas/Laravel-Phone.git",
|
||||
"reference": "5b0fef1d28e720c0a594fe0f22cb1d5b1d576474"
|
||||
"reference": "ba5aa49226793faf4bd37b38bd627d49269611d9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Propaganistas/Laravel-Phone/zipball/5b0fef1d28e720c0a594fe0f22cb1d5b1d576474",
|
||||
"reference": "5b0fef1d28e720c0a594fe0f22cb1d5b1d576474",
|
||||
"url": "https://api.github.com/repos/Propaganistas/Laravel-Phone/zipball/ba5aa49226793faf4bd37b38bd627d49269611d9",
|
||||
"reference": "ba5aa49226793faf4bd37b38bd627d49269611d9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3094,9 +3155,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Propaganistas/Laravel-Phone/issues",
|
||||
"source": "https://github.com/Propaganistas/Laravel-Phone/tree/4.3.8"
|
||||
"source": "https://github.com/Propaganistas/Laravel-Phone/tree/4.4.0"
|
||||
},
|
||||
"time": "2022-09-04T18:30:31+00:00"
|
||||
"time": "2022-11-10T09:52:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ return [
|
|||
*/
|
||||
|
||||
'defaults' => [
|
||||
'guard' => 'web',
|
||||
'guard' => 'backend',
|
||||
'passwords' => 'users',
|
||||
],
|
||||
|
||||
|
|
@ -36,21 +36,21 @@ return [
|
|||
*/
|
||||
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'backend' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'users',
|
||||
],
|
||||
|
||||
'frontend' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'customers',
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'driver' => 'token',
|
||||
'provider' => 'users',
|
||||
'hash' => false,
|
||||
],
|
||||
|
||||
'customer' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'customers',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
@ -70,6 +70,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
// * Added "crm" Provider (AuthServiceProvider)
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
|
|
@ -77,8 +78,8 @@ return [
|
|||
],
|
||||
|
||||
'customers' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => App\Models\Customers::class,
|
||||
'driver' => 'crm',
|
||||
'model' => App\Models\Customer::class,
|
||||
]
|
||||
],
|
||||
|
||||
|
|
@ -98,9 +99,9 @@ return [
|
|||
*/
|
||||
|
||||
'passwords' => [
|
||||
'users' => [
|
||||
'provider' => 'users',
|
||||
'table' => 'password_resets',
|
||||
'customers' => [
|
||||
'provider' => 'customers',
|
||||
'table' => 'customer_password_resets',
|
||||
'expire' => 60,
|
||||
'throttle' => 60,
|
||||
],
|
||||
|
|
|
|||
10
config/ldcweb-cookies.php
Normal file
10
config/ldcweb-cookies.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* LDC Service Web Cookies
|
||||
* Version 2.1.1
|
||||
*/
|
||||
|
||||
return [
|
||||
'analyticsKey' => env('ANALYTICS_GOOGLE_ID')
|
||||
];
|
||||
|
|
@ -38,47 +38,22 @@ class MigrateSettingsToGeneralConfigs extends Migration
|
|||
'tooltip' => 'Adresse email à laquelle seront envoyé les formulaires de contact.'
|
||||
],
|
||||
'confirmed_orders_destination_email' => [
|
||||
'label' => 'Adresse de reception des messages "contactez nous"',
|
||||
'label' => 'Adresse de reception des messages "nouvelle commande"',
|
||||
'inputType' => InputType::email(),
|
||||
'value' => 'equipe.web@ldc.fr',
|
||||
'validate' => 'required|email:strict,rfc,spoof,dns',
|
||||
'helper' => 'Information lorsqu\'un client valide une commande',
|
||||
'tooltip' => ''
|
||||
],
|
||||
'customer_register_public_mode' => [
|
||||
'label' => 'Public',
|
||||
'inputType' => InputType::boolean(),
|
||||
'value' => true,
|
||||
'validate' => 'boolean',
|
||||
'helper' => 'Mode d\'inscription',
|
||||
'tooltip' => sprintf(
|
||||
'%s %s %s',
|
||||
// phpcs:disable
|
||||
'La partie front office de votre boutique doit tenir compte de ce paramètre pour qu\'il prenne effet.',
|
||||
'<br/> Le thème doit indiquer quel modes sont pris en charge via la config de thème: <code>register_mode</code>',
|
||||
'<br/> Si aucun choix ne s\'affiche c\'est que votre boutique ne gère que l\'inscription tous publics.'
|
||||
// phpcs:enable
|
||||
)
|
||||
|
||||
],
|
||||
'orders_display_prices_for_auth' => [
|
||||
'label' => 'Client Connecté ',
|
||||
'label' => 'Prix uniquement pour les clients connectés',
|
||||
'inputType' => InputType::boolean(),
|
||||
'value' => true,
|
||||
'validate' => 'boolean',
|
||||
'helper' => 'Affichage des prix',
|
||||
'helper' => 'Afficher les prix uniquement pour les clients connectés',
|
||||
'tooltip' =>
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'Affichage des prix sous certaines conditions : <ul><li>Client Connecté</li><li>Public</li></ul>'
|
||||
],
|
||||
'orders_display_prices_for_public' => [
|
||||
'label' => 'Public',
|
||||
'inputType' => InputType::boolean(),
|
||||
'value' => true,
|
||||
'validate' => 'boolean',
|
||||
'helper' => '',
|
||||
'tooltip' => ''
|
||||
|
||||
'Affichage des prix sous certaines conditions : <ul><li>Client Connecté</li></ul>'
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\DefaultProductType;
|
||||
use App\Enums\WeightUnit;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -105,13 +106,13 @@ class ReworkProducts extends Migration
|
|||
$products->each(function (object $product) {
|
||||
$weight = 0;
|
||||
if (Str::lower($product->weight_unit) === 'g') {
|
||||
$weight = intval($product->weight);
|
||||
$weight = round($product->weight);
|
||||
}
|
||||
if (Str::lower($product->weight_unit) === 'kg') {
|
||||
$weight = intval($product->weight) * 1000;
|
||||
$weight = round($product->weight * WeightUnit::kg()->conversion);
|
||||
}
|
||||
if (Str::lower($product->weight_unit) === 'ton') {
|
||||
$weight = intval($product->weight) * 1000 * 1000;
|
||||
$weight = round($product->weight * WeightUnit::ton()->conversion);
|
||||
}
|
||||
DB::table('products')->where('id', $product->id)->update([
|
||||
'weight' => $weight,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddDateFiledsOnCustomers extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->timestamp('email_verified_at')->nullable()->after('remember_token');
|
||||
$table->timestamp('last_connection')->nullable()->after('email_verified_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->dropColumn('email_verified_at');
|
||||
$table->dropColumn('last_connection');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('customer_password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('customer_password_resets');
|
||||
}
|
||||
};
|
||||
2107
package-lock.json
generated
2107
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -32,7 +32,7 @@
|
|||
"@voerro/vue-tagsinput": "^2.7.1",
|
||||
"@vue/eslint-config-typescript": "^11.0.1",
|
||||
"axios": "^0.21.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"bootstrap": "^5.2.2",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"cropperjs": "^1.5.12",
|
||||
"eslint": "^8.23.1",
|
||||
|
|
|
|||
4
resources/sass/_bootstrapOverload.scss
vendored
Normal file
4
resources/sass/_bootstrapOverload.scss
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.nav-link.active {
|
||||
color: $primary;
|
||||
font-weight: bold;
|
||||
}
|
||||
98
resources/sass/_dashboard.scss
vendored
98
resources/sass/_dashboard.scss
vendored
|
|
@ -1,102 +1,22 @@
|
|||
body {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.lni {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
font-size: 20px !important;
|
||||
font-weight: bold !important;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
z-index: 100; /* Behind the navbar */
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
/* rtl:raw:
|
||||
right: 0;
|
||||
*/
|
||||
bottom: 0;
|
||||
/* rtl:remove */
|
||||
left: 0;
|
||||
padding: 48px 0 0; /* Height of navbar */
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.1);
|
||||
margin: 48px 0 0;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.sidebar {
|
||||
top: 5rem;
|
||||
}
|
||||
#topNavBar {
|
||||
height: $top-nav-bar-height;
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
#footer {
|
||||
position: relative;
|
||||
top: 0;
|
||||
height: calc(100vh - 48px);
|
||||
padding-top: 0.5rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
z-index: 100;
|
||||
height: $footer-bar-height;
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .lni {
|
||||
margin-right: 8px;
|
||||
color: #727272;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #2470dc;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover .lni,
|
||||
.sidebar .nav-link.active .lni {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/*
|
||||
* Navbar
|
||||
*/
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.25);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.navbar .navbar-toggler {
|
||||
top: 0.25rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: 0.75rem 1rem;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.form-control-dark {
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.form-control-dark:focus {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
|
||||
#mainContainer {
|
||||
min-height: calc(100vh - $top-nav-bar-height - $footer-bar-height);
|
||||
}
|
||||
|
|
|
|||
52
resources/sass/_variables.scss
vendored
52
resources/sass/_variables.scss
vendored
|
|
@ -9,17 +9,6 @@ $font-size-base: 1rem;
|
|||
$line-height-base: 1.6;
|
||||
|
||||
// Colors
|
||||
$blue: #0060df;
|
||||
$indigo: #6574cd;
|
||||
$purple: #9561e2;
|
||||
$pink: #f66d9b;
|
||||
$red: #e3342f;
|
||||
$orange: #f6993f;
|
||||
$yellow: #ffed4a;
|
||||
$green: #38c172;
|
||||
$teal: #4dc0b5;
|
||||
$cyan: #6cb2eb;
|
||||
|
||||
$color1: #f3ebe4;
|
||||
$color2: #07386a;
|
||||
$color3: #0f437e;
|
||||
|
|
@ -32,6 +21,39 @@ $color9: #c6bcb3;
|
|||
$color10: #999595;
|
||||
$color11: #ab9d8e;
|
||||
|
||||
// * Boostrap Colors
|
||||
$white: #fff !default;
|
||||
$gray-100: #f8f9fa !default;
|
||||
$gray-200: #e9ecef !default;
|
||||
$gray-300: #dee2e6 !default;
|
||||
$gray-400: #ced4da !default;
|
||||
$gray-500: #adb5bd !default;
|
||||
$gray-600: #6c757d !default;
|
||||
$gray-700: #495057 !default;
|
||||
$gray-800: #343a40 !default;
|
||||
$gray-900: #212529 !default;
|
||||
$black: #000 !default;
|
||||
|
||||
$blue: #0d6efd !default;
|
||||
$indigo: #6610f2 !default;
|
||||
$purple: #6f42c1 !default;
|
||||
$pink: #d63384 !default;
|
||||
$red: #dc3545 !default;
|
||||
$orange: #fd7e14 !default;
|
||||
$yellow: #ffc107 !default;
|
||||
$green: #198754 !default;
|
||||
$teal: #20c997 !default;
|
||||
$cyan: #0dcaf0 !default;
|
||||
|
||||
$primary: $blue !default;
|
||||
$secondary: $gray-600 !default;
|
||||
$success: $green !default;
|
||||
$info: $cyan !default;
|
||||
$warning: $yellow !default;
|
||||
$danger: $red !default;
|
||||
$light: $gray-100 !default;
|
||||
$dark: $gray-900 !default;
|
||||
|
||||
.large-tooltip .tooltip-inner {
|
||||
width: max-content !important; //uses the content as a guide of default length
|
||||
max-width: 800px !important; //constrained to max width
|
||||
|
|
@ -43,3 +65,11 @@ $color11: #ab9d8e;
|
|||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
// * bootstrap overload
|
||||
$nav-link-color: #000;
|
||||
$nav-link-color-active: $color3;
|
||||
|
||||
// * Layout settings
|
||||
$top-nav-bar-height: 3.6rem;
|
||||
$footer-bar-height: 2.6rem;
|
||||
|
|
|
|||
5
resources/sass/app.scss
vendored
5
resources/sass/app.scss
vendored
|
|
@ -12,12 +12,13 @@
|
|||
@import "icons";
|
||||
|
||||
// Bootstrap
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
@import "~bootstrap";
|
||||
@import "bootstrapOverload";
|
||||
|
||||
// Toastify
|
||||
@import "~toastify-js/src/toastify.css";
|
||||
|
||||
@import "dashboard";
|
||||
|
||||
@import "smoothdnd";
|
||||
@import "forms";
|
||||
|
||||
|
|
|
|||
|
|
@ -83,9 +83,8 @@ export default defineComponent({
|
|||
const self = this,
|
||||
ckeditor = this.$refs.ckeditor as HTMLElement,
|
||||
wordCounter = this.$refs.wordCounter as HTMLElement,
|
||||
// * Specific to Calliope
|
||||
verticalTopMenuOffset = document.querySelector(
|
||||
"body > div> .navbar"
|
||||
verticalTopMenuOffset = document.getElementById(
|
||||
"topNavBar"
|
||||
) as HTMLElement | null;
|
||||
|
||||
if (!verticalTopMenuOffset) {
|
||||
|
|
@ -224,13 +223,13 @@ export default defineComponent({
|
|||
"fullScreen",
|
||||
"sourceEditing",
|
||||
],
|
||||
ui: {
|
||||
viewportOffset: {
|
||||
top: verticalTopMenuOffset.getBoundingClientRect().height,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
},
|
||||
},
|
||||
ui: {
|
||||
viewportOffset: {
|
||||
top: verticalTopMenuOffset.getBoundingClientRect().height,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
},
|
||||
},
|
||||
table: {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ import {
|
|||
faTrash,
|
||||
faPaste,
|
||||
faCalendarDays,
|
||||
faEllipsisVertical,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
// import { faXm } from "@fortawesome/free-brands-svg-icons";
|
||||
import {
|
||||
|
|
@ -168,5 +169,6 @@ library.add(faCopy);
|
|||
library.add(faPaste);
|
||||
library.add(faArrowRight);
|
||||
library.add(faCalendarDays);
|
||||
library.add(faEllipsisVertical);
|
||||
|
||||
dom.watch();
|
||||
|
|
|
|||
73
resources/views/back/auth/login.blade.php
Normal file
73
resources/views/back/auth/login.blade.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
@extends('layouts.bo-layout')
|
||||
|
||||
@section('content')
|
||||
<div class="container p-2 p-md-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Connexion Backoffice') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('bo.login') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Adresse Email') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Mode de passe') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
|
||||
<label class="form-check-label" for="remember">
|
||||
{{ __('Se souvenir de moi') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Connexion') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('bo.password.request'))
|
||||
<a class="btn btn-link" href="{{ route('bo.password.request') }}">
|
||||
{{ __('Mode de passe oublié ?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
49
resources/views/back/auth/passwords/confirm.blade.php
Normal file
49
resources/views/back/auth/passwords/confirm.blade.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
@extends('layouts.back')
|
||||
|
||||
@section('content')
|
||||
<div class="container p-2 p-md-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Confirm Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
{{ __('Please confirm your password before continuing.') }}
|
||||
|
||||
<form method="POST" action="{{ route('bo.password.confirm') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Confirm Password') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('bo.password.request'))
|
||||
<a class="btn btn-link" href="{{ route('bo.password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
47
resources/views/back/auth/passwords/email.blade.php
Normal file
47
resources/views/back/auth/passwords/email.blade.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
@extends('layouts.back')
|
||||
|
||||
@section('content')
|
||||
<div class="container p-2 p-md-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('bo.password.email') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Send Password Reset Link') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
65
resources/views/back/auth/passwords/reset.blade.php
Normal file
65
resources/views/back/auth/passwords/reset.blade.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
@extends('layouts.back')
|
||||
|
||||
@section('content')
|
||||
<div class="container p-2 p-md-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('bo.password.update') }}">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Reset Password') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
68
resources/views/back/layout/header.blade.php
Normal file
68
resources/views/back/layout/header.blade.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<header id="topNavBar" class="sticky-top navbar navbar-expand-md navbar-light bg-white shadow-sm">
|
||||
<div class="container">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContentLeft" aria-controls="navbarSupportedContentLeft" aria-expanded="false" aria-label="{{ __('Afficher/Masquer le menu de navigation') }}">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
</button>
|
||||
|
||||
<a class="navbar-brand" href="{{ url('/') }}">
|
||||
{{ config('app.name', 'Laravel') }}
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Afficher/Masquer le menu d\'utilisateur') }}">
|
||||
<i class="fa-solid fa-bars"></i>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<!-- Left Side Of Navbar -->
|
||||
<ul class="navbar-nav me-auto">
|
||||
{{-- <li class="nav-item">
|
||||
<a class="nav-link" href="#" id="navbarDropdownPages" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ __('Pages') }}
|
||||
</a>
|
||||
</li> --}}
|
||||
</ul>
|
||||
|
||||
<!-- Right Side Of Navbar -->
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<!-- Authentication Links -->
|
||||
@guest
|
||||
@if (Route::has('bo.login'))
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Connexion') }}</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if (Route::has('bo.register'))
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Créer un compte') }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@else
|
||||
@if(Auth::check() and !Auth::user()->role->equals(\App\Enums\UserRole::user()))
|
||||
<li class="nav-item">
|
||||
<span class="nav-link fw-bold {{ Auth::user()->role->equals(\App\Enums\UserRole::admin()) ? 'text-primary' : 'text-success'}}">{{
|
||||
Auth::user()->role->label
|
||||
}}</span>
|
||||
</li>
|
||||
@endif
|
||||
<li class="nav-item dropdown">
|
||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ __('Bonjour') }} {{ Auth::user()->firstname }} {{ Auth::user()->lastname}} <span class="caret"></span>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="{{ route('bo.logout') }}"
|
||||
onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
|
||||
{{ __('Déconnexion') }}
|
||||
</a>
|
||||
|
||||
<form id="logout-form" action="{{ route('bo.logout') }}" method="POST" class="d-none">
|
||||
@csrf
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
@endguest
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
||||
@auth('backend')
|
||||
<nav id="navbarSupportedContentLeft" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse overflow-auto">
|
||||
<div class="position-sticky pt-3">
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{route('home')}}" target="_front">{{ __('Voir le site') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="accordion" id="accordionMenu">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingSliders">
|
||||
|
|
@ -23,11 +19,11 @@
|
|||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingPages">
|
||||
<button class="accordion-button {{ ( request()->routeIs('bo.static_page') || request()->routeIs('bo.faq') ) ? '' : 'collapsed' }}" type="button" data-bs-toggle="collapse" data-bs-target="#collapsePages" aria-expanded="true" aria-controls="collapsePages">
|
||||
<button class="accordion-button {{ ( request()->routeIs('bo.static_page*') ) ? '' : 'collapsed' }}" type="button" data-bs-toggle="collapse" data-bs-target="#collapsePages" aria-expanded="true" aria-controls="collapsePages">
|
||||
<i class="fa fa-file-word"></i> {{ __('models.classes.static_pages') }}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapsePages" class="accordion-collapse collapse {{ ( request()->routeIs('bo.static_page') || request()->routeIs('bo.faq') ) ? 'show' : '' }}" aria-labelledby="headingPages" data-bs-parent="#accordionMenu">
|
||||
<div id="collapsePages" class="accordion-collapse collapse {{ ( request()->routeIs('bo.static_page*') ) ? 'show' : '' }}" aria-labelledby="headingPages" data-bs-parent="#accordionMenu">
|
||||
<div class="accordion-body">
|
||||
<ul class="nav flex-column mb-2">
|
||||
@foreach(App\Enums\StaticPageType::toArray() as $pageType)
|
||||
|
|
@ -88,8 +84,8 @@
|
|||
<div class="accordion-body">
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{route('bo.orders.index')}}">{{ __('models.classes.orders') }}</a>
|
||||
<a class="nav-link" href="{{route('bo.orders.today')}}">{{ __('Commandes à retirer aujourd\'hui') }}</a>
|
||||
<a class="nav-link {{ request()->routeIs('bo.orders.index') ? 'active' : '' }}" href="{{route('bo.orders.index')}}">{{ __('models.classes.orders') }}</a>
|
||||
<a class="nav-link {{ request()->routeIs('bo.orders.today') ? 'active' : '' }}" href="{{route('bo.orders.today')}}">{{ __('Commandes à retirer aujourd\'hui') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -98,7 +94,7 @@
|
|||
<!-- Points de Collecte -->
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingCollecte">
|
||||
<button class="accordion-button {{ ( request()->routeIs('bo.magasins*') || request()->routeIs('bo.creneaux*') ) ? '' : 'collapsed' }}" type="button" data-bs-toggle="collapse" data-bs-target="#collapseCollecte" aria-expanded="true" aria-controls="collapseCollecte">
|
||||
<button class="accordion-button {{ ( request()->routeIs('bo.shops*') || request()->routeIs('bo.creneaux*') ) ? '' : 'collapsed' }}" type="button" data-bs-toggle="collapse" data-bs-target="#collapseCollecte" aria-expanded="true" aria-controls="collapseCollecte">
|
||||
<i class="fas fa-store"></i> {{ __('Points de retrait') }}
|
||||
</button>
|
||||
</h2>
|
||||
|
|
@ -106,7 +102,7 @@
|
|||
<div class="accordion-body">
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {{ request()->routeIs('bo.magasins*') ? 'active' : '' }}" href="{{route('bo.shops.index')}}">{{ __('models.classes.shops') }}</a>
|
||||
<a class="nav-link {{ request()->routeIs('bo.shops*') ? 'active' : '' }}" href="{{route('bo.shops.index')}}">{{ __('models.classes.shops') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -136,3 +132,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@endauth
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="form-group">
|
||||
<div class="word-counter" data-json='@json(['id' => $k])'></div>
|
||||
<div class="word-counter" data-json='@json(['id' => "string{$k}"])'></div>
|
||||
<input id="string{{$k}}" type="text" class="form-control" name="data[{{$k}}][value]"
|
||||
aria-describedby="StringHelp{{$k}}"
|
||||
placeholder="{{ $input['label'] }}" value="{{ old("data.{$k}.value") ?? ($input['value'] ?? '') }}" required>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<div class="input-group mt-1">
|
||||
<label class="input-group-text bg-white text-danger font-weight-bold">{{ __('Inco') }}</label>
|
||||
<input type="text" disabled="disabled" class="form-control" value="{{ $value }}">
|
||||
<button class="btn btn-outline-secondary inco-copy-value" data-input-id={{ $inputId }} type="button">
|
||||
<button class="btn btn-outline-secondary inco-copy-value" data-input-id={{ "{$inputId}" }} type="button">
|
||||
<i class="fa-regular fa-copy"></i>
|
||||
<i class="fa-solid fa-arrow-right"></i>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@
|
|||
<div class="form-group">
|
||||
<label for="productWeight"><b>{{ __('Poids') }}</b></label>
|
||||
<div class="input-group">
|
||||
<input name="weight" type="number" min="0" step="0.001" value="{{ number_format(floatval(old('weight', optional($productModel ?? null)->weight)), 3, '.', '') }}" class="form-control"
|
||||
<input name="weight" type="number" min="0" step="0.001" value="{{ number_format(floatval(old('weight', round(intval(optional($productModel ?? null)->weight) / \App\Enums\WeightUnit::kg()->conversion, 3))), 3, '.', '') }}" class="form-control"
|
||||
id="productWeight" aria-describedby="productWeightHelp">
|
||||
<label class="input-group-text">Kg</label>
|
||||
</div>
|
||||
|
|
@ -395,9 +395,9 @@ $minicrudModel = $productModel ?? (object)['data' => $minicrudData];
|
|||
<fieldset class="border mb-2 p-3">
|
||||
<legend><span class="h3">{{ __("Valeurs Inco") }}</span></legend>
|
||||
@php $incoValues = $productModel->xmlInco->translateToProductIncoInputs(); @endphp
|
||||
@foreach ($productModel->data as $k => $input)
|
||||
<label><b>{{ $input['label'] }}</b></label>
|
||||
@include('back.products.form-xml-attribute', ['inputId' => $k,'value' => $incoValues[$k]])
|
||||
@foreach ($productModel->data_object as $k => $input)
|
||||
<label><b>{{ $input->label }}</b></label>
|
||||
@include('back.products.form-xml-attribute', ['inputId' => $input->inputType->label.$k,'value' => $incoValues[$k]])
|
||||
@endforeach
|
||||
</fieldset>
|
||||
@endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue