- Implement automated synchronization of employees via Arcadia API (EmployeeSyncService, SynchronizeEmployeesWithArcadiaApi, FetchAndUpsertArcadiaEmployees) - Add Back-Office application settings for employee sites (Setting singleton, GetSettingsQuery, UpdateSettings, SettingsController, EmployeeSitesInputComponent.vue) - Strongly type Employee attributes using Domain Value Objects (ShopperEstablishmentCode, ShopperSiteCode, ShopperServiceCode) and Eloquent Casts - Migrate pagination from Domain to Shared\Pagination namespace across queries and inputs - Remove legacy and dead CSV employee import/export code - Restore Domain\Ports\Services\CsvGenerator interface for Regate order generation - Add comprehensive Pest unit, integration, and feature test coverage
151 lines
4.4 KiB
PHP
151 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Providers;
|
|
|
|
use App\Contracts\Directories\CustomerDirectory;
|
|
use App\Contracts\Directories\EmployeeDirectory;
|
|
use App\Contracts\Directories\OrderDirectory;
|
|
use App\Contracts\Executor;
|
|
use App\Contracts\Repositories\EmployeeRepository;
|
|
use App\Contracts\Repositories\OrderRepository;
|
|
use App\Contracts\Repositories\UserRepository;
|
|
use App\Directories\EloquentCustomerDirectory;
|
|
use App\Directories\EloquentEmployeeDirectory;
|
|
use App\Directories\EloquentOrderDirectory;
|
|
use App\Repositories\EloquentEmployeeRepository;
|
|
use App\Repositories\EloquentOrderRepository;
|
|
use App\Repositories\EloquentUserRepository;
|
|
use App\Services\ActionExecutorService;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Date;
|
|
use Illuminate\Support\Facades\URL;
|
|
use Illuminate\Support\Facades\Vite;
|
|
use Illuminate\Support\ServiceProvider;
|
|
use Mews\Purifier\Purifier;
|
|
use Shared\DDD\Equatable;
|
|
|
|
class AppServiceProvider extends ServiceProvider
|
|
{
|
|
/**
|
|
* Register any application services.
|
|
*
|
|
* @return void
|
|
*/
|
|
#[\Override]
|
|
public function register()
|
|
{
|
|
$this->app->singleton(
|
|
Purifier::class,
|
|
fn () => resolve('purifier')
|
|
);
|
|
|
|
$this->app->singleton('clientIp', function () {
|
|
return request()->ip() ?? request()->getClientIp();
|
|
});
|
|
|
|
$this->app->bind(EmployeeRepository::class, EloquentEmployeeRepository::class);
|
|
$this->app->bind(OrderRepository::class, EloquentOrderRepository::class);
|
|
$this->app->bind(UserRepository::class, EloquentUserRepository::class);
|
|
|
|
$this->app->bind(CustomerDirectory::class, EloquentCustomerDirectory::class);
|
|
$this->app->bind(EmployeeDirectory::class, EloquentEmployeeDirectory::class);
|
|
$this->app->bind(OrderDirectory::class, EloquentOrderDirectory::class);
|
|
$this->app->bind(Executor::class, ActionExecutorService::class);
|
|
}
|
|
|
|
/**
|
|
* Bootstrap any application services.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function boot()
|
|
{
|
|
$this->laravelGlobalSetup();
|
|
$this->dateSetup();
|
|
$this->dateMacro();
|
|
$this->collectionMacro();
|
|
}
|
|
|
|
private function laravelGlobalSetup(): void
|
|
{
|
|
Model::shouldBeStrict(app()->environment('local'));
|
|
|
|
Vite::useCspNonce();
|
|
|
|
URL::forceScheme('https');
|
|
}
|
|
|
|
private function dateSetup(): void
|
|
{
|
|
foreach ([\LC_TIME, \LC_MESSAGES, \LC_COLLATE, \LC_CTYPE, \LC_MONETARY] as $constant) {
|
|
setlocale(
|
|
$constant,
|
|
sprintf(
|
|
'%s_%s.UTF-8',
|
|
config()->string('app.locale'),
|
|
strtoupper(config()->string('app.locale'))
|
|
)
|
|
);
|
|
}
|
|
Date::setLocale(config()->string('app.locale'));
|
|
Date::setFallbackLocale(config()->string('app.fallback_locale'));
|
|
}
|
|
|
|
private function dateMacro(): void
|
|
{
|
|
Date::macro('toLocalInput', function ($date) {
|
|
if (! $date) {
|
|
return null;
|
|
}
|
|
|
|
$timezone = request()->string(
|
|
'client_timezone',
|
|
request()->string(
|
|
'client_timezone',
|
|
'Europe/Paris'
|
|
)->value()
|
|
)->value();
|
|
|
|
return Date::parse($date)
|
|
->setTimezone($timezone)
|
|
->format('Y-m-d\TH:i');
|
|
});
|
|
|
|
Date::macro('forHumans', function ($date) {
|
|
if (! $date) {
|
|
return null;
|
|
}
|
|
|
|
$timezone = request()->string(
|
|
'client_timezone',
|
|
request()->string(
|
|
'client_timezone',
|
|
'Europe/Paris'
|
|
)->value()
|
|
)->value();
|
|
|
|
return Date::parse($date)
|
|
->setTimezone($timezone)
|
|
->isoFormat('ddd DD/MM/Y \à HH:mm');
|
|
});
|
|
}
|
|
|
|
private function collectionMacro(): void
|
|
{
|
|
Collection::macro('uniqueValues', function () {
|
|
return $this->unique(function ($item) {
|
|
if ($item instanceof Equatable) {
|
|
return $item instanceof \Stringable ? (string) $item : json_encode($item);
|
|
}
|
|
if ($item instanceof \Stringable) {
|
|
return (string) $item;
|
|
}
|
|
|
|
return $item;
|
|
});
|
|
});
|
|
}
|
|
}
|