diff --git a/.env.testing b/.env.testing deleted file mode 100644 index 1f59954c..00000000 --- a/.env.testing +++ /dev/null @@ -1,14 +0,0 @@ -APP_ENV=testing -APP_URL=https://wms.vm -APP_KEY=base64:O0djxuJapvByUFNx5avmY7od2Y6C07JYv2kAFNrlrMI= -DB_CONNECTION=pgsql -DB_HOST=127.0.0.1 -DB_PORT=5432 -DB_DATABASE=wms_test -DB_USERNAME=wms_user -DB_PASSWORD=987400Kmh - -SESSION_DRIVER=file -CACHE_STORE=array -QUEUE_CONNECTION=sync -MAIL_MAILER=array diff --git a/Modules/Analytics/Entities/.gitkeep b/Modules/Analytics/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Analytics/Providers/AnalyticsServiceProvider.php b/Modules/Analytics/Providers/AnalyticsServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Analytics/README.md b/Modules/Analytics/README.md deleted file mode 100644 index c5398012..00000000 --- a/Modules/Analytics/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Analytics - -Display KPIs, warehouse performance trends, executive summaries, and OTTC analysis. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Analytics/Resources/views/index.blade.php b/Modules/Analytics/Resources/views/index.blade.php old mode 100644 new mode 100755 index 67671ca7..116e4f30 --- a/Modules/Analytics/Resources/views/index.blade.php +++ b/Modules/Analytics/Resources/views/index.blade.php @@ -64,6 +64,7 @@
+ diff --git a/Modules/Analytics/Resources/views/partials/nav.blade.php b/Modules/Analytics/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Analytics/Routes/api.php b/Modules/Analytics/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Analytics/Routes/web.php b/Modules/Analytics/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Analytics/module.json b/Modules/Analytics/module.json old mode 100644 new mode 100755 diff --git a/Modules/Audit/Entities/.gitkeep b/Modules/Audit/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Audit/Providers/AuditServiceProvider.php b/Modules/Audit/Providers/AuditServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Audit/README.md b/Modules/Audit/README.md deleted file mode 100644 index 03e107c4..00000000 --- a/Modules/Audit/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Audit - -Review activity logs, data changes, interface events, and administrative actions. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Audit/Resources/views/index.blade.php b/Modules/Audit/Resources/views/index.blade.php old mode 100644 new mode 100755 index e53c84d0..b25b0318 --- a/Modules/Audit/Resources/views/index.blade.php +++ b/Modules/Audit/Resources/views/index.blade.php @@ -64,6 +64,7 @@
Data table
Metric
+ diff --git a/Modules/Audit/Resources/views/partials/nav.blade.php b/Modules/Audit/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Audit/Routes/api.php b/Modules/Audit/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Audit/Routes/web.php b/Modules/Audit/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Audit/module.json b/Modules/Audit/module.json old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Config/.gitkeep b/Modules/AuditTrail/Config/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Config/config.php b/Modules/AuditTrail/Config/config.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Console/.gitkeep b/Modules/AuditTrail/Console/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Database/Migrations/.gitkeep b/Modules/AuditTrail/Database/Migrations/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Database/Seeders/.gitkeep b/Modules/AuditTrail/Database/Seeders/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Database/Seeders/AuditTrailDatabaseSeeder.php b/Modules/AuditTrail/Database/Seeders/AuditTrailDatabaseSeeder.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Database/factories/.gitkeep b/Modules/AuditTrail/Database/factories/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Helpers/.gitkeep b/Modules/AuditTrail/Helpers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Helpers/Helper.php b/Modules/AuditTrail/Helpers/Helper.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Http/Controllers/.gitkeep b/Modules/AuditTrail/Http/Controllers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Http/Controllers/AuditTrailController.php b/Modules/AuditTrail/Http/Controllers/AuditTrailController.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Http/Middleware/.gitkeep b/Modules/AuditTrail/Http/Middleware/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Http/Requests/.gitkeep b/Modules/AuditTrail/Http/Requests/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Models/.gitkeep b/Modules/AuditTrail/Models/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Providers/.gitkeep b/Modules/AuditTrail/Providers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Providers/AuditTrailServiceProvider.php b/Modules/AuditTrail/Providers/AuditTrailServiceProvider.php old mode 100644 new mode 100755 index 6ea689d6..fba3af38 --- a/Modules/AuditTrail/Providers/AuditTrailServiceProvider.php +++ b/Modules/AuditTrail/Providers/AuditTrailServiceProvider.php @@ -63,9 +63,7 @@ class AuditTrailServiceProvider extends ServiceProvider $commandPath = __DIR__ . '/../Console'; $commands = collect(File::allFiles($commandPath)) ->map(function ($file) { - $class = 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); - - return $class; + return 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); }) ->filter(function ($class) { return class_exists($class); diff --git a/Modules/AuditTrail/Providers/RouteServiceProvider.php b/Modules/AuditTrail/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 index 6a73e6d2..166ba628 --- a/Modules/AuditTrail/Providers/RouteServiceProvider.php +++ b/Modules/AuditTrail/Providers/RouteServiceProvider.php @@ -14,18 +14,6 @@ class RouteServiceProvider extends ServiceProvider */ protected $moduleNamespace = 'Modules\AuditTrail\Http\Controllers'; - /** - * Called before routes are registered. - * - * Register any model bindings or pattern based filters. - * - * @return void - */ - public function boot() - { - parent::boot(); - } - /** * Define the routes for the application. * diff --git a/Modules/AuditTrail/Resources/assets/.gitkeep b/Modules/AuditTrail/Resources/assets/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Resources/assets/js/app.js b/Modules/AuditTrail/Resources/assets/js/app.js old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Resources/assets/sass/app.scss b/Modules/AuditTrail/Resources/assets/sass/app.scss old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Resources/lang/.gitkeep b/Modules/AuditTrail/Resources/lang/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Resources/views/.gitkeep b/Modules/AuditTrail/Resources/views/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Resources/views/index.blade.php b/Modules/AuditTrail/Resources/views/index.blade.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Resources/views/layouts/master.blade.php b/Modules/AuditTrail/Resources/views/layouts/master.blade.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Routes/.gitkeep b/Modules/AuditTrail/Routes/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Routes/api.php b/Modules/AuditTrail/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Routes/web.php b/Modules/AuditTrail/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Support/.gitkeep b/Modules/AuditTrail/Support/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Support/ModuleInfo.php b/Modules/AuditTrail/Support/ModuleInfo.php old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Tests/Browser/.gitkeep b/Modules/AuditTrail/Tests/Browser/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Tests/Feature/.gitkeep b/Modules/AuditTrail/Tests/Feature/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Tests/Unit/.gitkeep b/Modules/AuditTrail/Tests/Unit/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/Traits/.gitkeep b/Modules/AuditTrail/Traits/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/View/.gitkeep b/Modules/AuditTrail/View/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/composer.json b/Modules/AuditTrail/composer.json old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/module.json b/Modules/AuditTrail/module.json old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/package.json b/Modules/AuditTrail/package.json old mode 100644 new mode 100755 diff --git a/Modules/AuditTrail/webpack.mix.js b/Modules/AuditTrail/webpack.mix.js old mode 100644 new mode 100755 diff --git a/Modules/CarrierManagement/Entities/.gitkeep b/Modules/CarrierManagement/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/CarrierManagement/Providers/CarrierManagementServiceProvider.php b/Modules/CarrierManagement/Providers/CarrierManagementServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/CarrierManagement/README.md b/Modules/CarrierManagement/README.md deleted file mode 100644 index 70788878..00000000 --- a/Modules/CarrierManagement/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Carrier Management - -Maintain carriers, services, and shipment routing master data. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/CarrierManagement/Resources/views/index.blade.php b/Modules/CarrierManagement/Resources/views/index.blade.php old mode 100644 new mode 100755 index 9598a0c2..29eb30de --- a/Modules/CarrierManagement/Resources/views/index.blade.php +++ b/Modules/CarrierManagement/Resources/views/index.blade.php @@ -64,6 +64,7 @@
Data table
When
+ diff --git a/Modules/CarrierManagement/Resources/views/partials/nav.blade.php b/Modules/CarrierManagement/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/CarrierManagement/Routes/api.php b/Modules/CarrierManagement/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/CarrierManagement/Routes/web.php b/Modules/CarrierManagement/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/CarrierManagement/module.json b/Modules/CarrierManagement/module.json old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Config/.gitkeep b/Modules/ChatGPT/Config/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Config/config.php b/Modules/ChatGPT/Config/config.php old mode 100644 new mode 100755 index 559be757..22bd64fa --- a/Modules/ChatGPT/Config/config.php +++ b/Modules/ChatGPT/Config/config.php @@ -2,7 +2,6 @@ return [ 'name' => 'ChatGPT', - 'features' => - [ - ], + 'features' => [ + ], ]; diff --git a/Modules/ChatGPT/Console/.gitkeep b/Modules/ChatGPT/Console/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Console/DeleteOpenAiFilesCommand.php b/Modules/ChatGPT/Console/DeleteOpenAiFilesCommand.php old mode 100644 new mode 100755 index e95ad36f..06a6e6a0 --- a/Modules/ChatGPT/Console/DeleteOpenAiFilesCommand.php +++ b/Modules/ChatGPT/Console/DeleteOpenAiFilesCommand.php @@ -22,42 +22,41 @@ class DeleteOpenAiFilesCommand extends Command if (! $setting) { $this->error('No active ChatGPT/OpenAI API key is stored.'); + return self::FAILURE; } - $service = new OpenAiFileService((string) $setting->api_key); - try { - if ((bool) $this->option('dry-run')) { - $files = $service->listFiles(); - - $this->info('Found ' . count($files) . ' OpenAI API file(s).'); - - foreach ($files as $file) { - $this->line(sprintf( - '- %s %s', - (string) ($file['id'] ?? 'unknown'), - (string) ($file['filename'] ?? 'unnamed') - )); - } - - return self::SUCCESS; - } - - $result = $service->deleteAllFiles(); - - $this->info("Listed: {$result['listed']}"); - $this->info("Deleted: {$result['deleted']}"); - $this->info("Failed: {$result['failed']}"); - - foreach ($result['failures'] as $failure) { - $this->error($failure['file_id'] . ': ' . $failure['error']); - } - - return $result['failed'] === 0 ? self::SUCCESS : self::FAILURE; + return $this->executeFor(new OpenAiFileService((string) $setting->api_key)); } catch (Throwable $exception) { $this->error($exception->getMessage()); + return self::FAILURE; } } + + private function executeFor(OpenAiFileService $service): int + { + if ((bool) $this->option('dry-run')) { + $files = $service->listFiles(); + $this->info('Found ' . count($files) . ' OpenAI API file(s).'); + + foreach ($files as $file) { + $this->line(sprintf('- %s %s', (string) ($file['id'] ?? 'unknown'), (string) ($file['filename'] ?? 'unnamed'))); + } + + return self::SUCCESS; + } + + $result = $service->deleteAllFiles(); + $this->info("Listed: {$result['listed']}"); + $this->info("Deleted: {$result['deleted']}"); + $this->info("Failed: {$result['failed']}"); + + foreach ($result['failures'] as $failure) { + $this->error($failure['file_id'] . ': ' . $failure['error']); + } + + return $result['failed'] === 0 ? self::SUCCESS : self::FAILURE; + } } diff --git a/Modules/ChatGPT/Database/Migrations/.gitkeep b/Modules/ChatGPT/Database/Migrations/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Database/Migrations/2026_06_24_000001_create_chatgpt_api_settings_table.php b/Modules/ChatGPT/Database/Migrations/2026_06_24_000001_create_chatgpt_api_settings_table.php old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Database/Seeders/.gitkeep b/Modules/ChatGPT/Database/Seeders/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Database/Seeders/ChatGPTDatabaseSeeder.php b/Modules/ChatGPT/Database/Seeders/ChatGPTDatabaseSeeder.php old mode 100644 new mode 100755 index 11c67338..8643bac5 --- a/Modules/ChatGPT/Database/Seeders/ChatGPTDatabaseSeeder.php +++ b/Modules/ChatGPT/Database/Seeders/ChatGPTDatabaseSeeder.php @@ -2,8 +2,8 @@ namespace Modules\ChatGPT\Database\Seeders; -use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Seeder; class ChatGPTDatabaseSeeder extends Seeder { @@ -16,6 +16,5 @@ class ChatGPTDatabaseSeeder extends Seeder { Model::unguard(); - // $this->call("OthersTableSeeder"); } } diff --git a/Modules/ChatGPT/Database/factories/.gitkeep b/Modules/ChatGPT/Database/factories/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Exceptions/OpenAiFileException.php b/Modules/ChatGPT/Exceptions/OpenAiFileException.php new file mode 100755 index 00000000..4b79a6f6 --- /dev/null +++ b/Modules/ChatGPT/Exceptions/OpenAiFileException.php @@ -0,0 +1,9 @@ +registerTranslations(); $this->registerConfig(); @@ -63,34 +61,33 @@ class ChatGPTServiceProvider extends ServiceProvider */ protected function registerHelpers(): void { - foreach (glob(__DIR__.'/../Helpers/*.php') as $filename) { + foreach (glob(__DIR__ . '/../Helpers/*.php') as $filename) { require_once $filename; } } - /** + /** * Dynamically Register Commands. * * @return void */ public function registerCommands(): void - { - if (!$this->app->runningInConsole()) { - return; - } - $commandPath = __DIR__ . '/../Console'; - $commands = collect(File::allFiles($commandPath)) - ->map(function ($file) { - $class = 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); - return $class; - }) - ->filter(function ($class) { - return class_exists($class); - }) - ->values() - ->all(); - $this->commands($commands); + { + if (! $this->app->runningInConsole()) { + return; } + $commandPath = __DIR__ . '/../Console'; + $commands = collect(File::allFiles($commandPath)) + ->map(function ($file) { + return 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); + }) + ->filter(function ($class) { + return class_exists($class); + }) + ->values() + ->all(); + $this->commands($commands); + } /** * Register config. @@ -100,10 +97,11 @@ class ChatGPTServiceProvider extends ServiceProvider protected function registerConfig(): void { $this->publishes([ - module_path(ModuleInfo::name(), 'Config/config.php') => config_path( ModuleInfo::nameLower(). '.php'), + module_path(ModuleInfo::name(), 'Config/config.php') => config_path(ModuleInfo::nameLower() . '.php'), ], 'config'); $this->mergeConfigFrom( - module_path(ModuleInfo::name(), 'Config/config.php'), ModuleInfo::nameLower() + module_path(ModuleInfo::name(), 'Config/config.php'), + ModuleInfo::nameLower(), ); } @@ -117,9 +115,9 @@ class ChatGPTServiceProvider extends ServiceProvider $viewPath = resource_path('views/modules/' . ModuleInfo::nameLower()); $sourcePath = module_path(ModuleInfo::name(), 'Resources/views'); $this->publishes([ - $sourcePath => $viewPath + $sourcePath => $viewPath, ], ['views', ModuleInfo::nameLower() . '-module-views']); - $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), ModuleInfo::nameLower()); + $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), ModuleInfo::nameLower()); } /** @@ -129,10 +127,10 @@ class ChatGPTServiceProvider extends ServiceProvider */ public function registerTranslations(): void { - $langPath = resource_path('lang/modules/' . ModuleInfo::nameLower()); + $langPath = resource_path('lang/modules/' . ModuleInfo::nameLower()); if (is_dir($langPath)) { - $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower()); + $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower()); } else { $this->loadTranslationsFrom(module_path(ModuleInfo::name(), 'Resources/lang'), ModuleInfo::nameLower()); } @@ -140,6 +138,7 @@ class ChatGPTServiceProvider extends ServiceProvider /** * Regsiter View Paths + * * @return array */ private function getPublishableViewPaths(): array @@ -150,6 +149,7 @@ class ChatGPTServiceProvider extends ServiceProvider $paths[] = $path . '/modules/' . ModuleInfo::nameLower(); } } + return $paths; } } diff --git a/Modules/ChatGPT/Providers/RouteServiceProvider.php b/Modules/ChatGPT/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 index e6b5df61..77c4c3fa --- a/Modules/ChatGPT/Providers/RouteServiceProvider.php +++ b/Modules/ChatGPT/Providers/RouteServiceProvider.php @@ -2,8 +2,8 @@ namespace Modules\ChatGPT\Providers; -use Illuminate\Support\Facades\Route; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\Route; class RouteServiceProvider extends ServiceProvider { @@ -14,18 +14,6 @@ class RouteServiceProvider extends ServiceProvider */ protected $moduleNamespace = 'Modules\ChatGPT\Http\Controllers'; - /** - * Called before routes are registered. - * - * Register any model bindings or pattern based filters. - * - * @return void - */ - public function boot() - { - parent::boot(); - } - /** * Define the routes for the application. * diff --git a/Modules/ChatGPT/Resources/assets/.gitkeep b/Modules/ChatGPT/Resources/assets/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Resources/assets/js/app.js b/Modules/ChatGPT/Resources/assets/js/app.js old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Resources/assets/sass/app.scss b/Modules/ChatGPT/Resources/assets/sass/app.scss old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Resources/lang/.gitkeep b/Modules/ChatGPT/Resources/lang/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Resources/views/.gitkeep b/Modules/ChatGPT/Resources/views/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Resources/views/index.blade.php b/Modules/ChatGPT/Resources/views/index.blade.php old mode 100644 new mode 100755 index 83f2de0d..8fd48b60 --- a/Modules/ChatGPT/Resources/views/index.blade.php +++ b/Modules/ChatGPT/Resources/views/index.blade.php @@ -65,7 +65,8 @@ @@ -82,6 +83,7 @@
Data table
Carrier
+ @@ -99,24 +101,27 @@ @csrf @method('PUT') - name + + id="name"> - Leave blank to keep existing key + + id="sonar-input-707eb8d2ba"> +get('/chatgpt', function (Request $request) { return $request->user(); -}); \ No newline at end of file +}); diff --git a/Modules/ChatGPT/Routes/web.php b/Modules/ChatGPT/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Services/OpenAiFileService.php b/Modules/ChatGPT/Services/OpenAiFileService.php old mode 100644 new mode 100755 index 7077e44f..21d3c0a3 --- a/Modules/ChatGPT/Services/OpenAiFileService.php +++ b/Modules/ChatGPT/Services/OpenAiFileService.php @@ -4,15 +4,13 @@ namespace Modules\ChatGPT\Services; use Illuminate\Http\Client\PendingRequest; use Illuminate\Support\Facades\Http; -use RuntimeException; +use Modules\ChatGPT\Exceptions\OpenAiFileException; class OpenAiFileService { private const BASE_URL = 'https://api.openai.com/v1'; - public function __construct(private readonly string $apiKey) - { - } + public function __construct(private readonly string $apiKey) {} /** * List all OpenAI API files visible to the configured API key. @@ -35,7 +33,7 @@ class OpenAiFileService ->get(self::BASE_URL . '/files', $query); if ($response->failed()) { - throw new RuntimeException('OpenAI file list request failed: ' . $response->body()); + throw new OpenAiFileException('OpenAI file list request failed: ' . $response->body()); } $payload = $response->json(); @@ -65,7 +63,7 @@ class OpenAiFileService ->delete(self::BASE_URL . '/files/' . rawurlencode($fileId)); if ($response->failed()) { - throw new RuntimeException("OpenAI file delete request failed for {$fileId}: " . $response->body()); + throw new OpenAiFileException("OpenAI file delete request failed for {$fileId}: " . $response->body()); } return $response->json() ?? []; @@ -92,7 +90,7 @@ class OpenAiFileService try { $this->deleteFile($fileId); $deleted++; - } catch (RuntimeException $exception) { + } catch (OpenAiFileException $exception) { $failures[] = [ 'file_id' => $fileId, 'error' => $exception->getMessage(), diff --git a/Modules/ChatGPT/Support/.gitkeep b/Modules/ChatGPT/Support/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Support/ModuleInfo.php b/Modules/ChatGPT/Support/ModuleInfo.php old mode 100644 new mode 100755 index 64bc361b..7c9e811a --- a/Modules/ChatGPT/Support/ModuleInfo.php +++ b/Modules/ChatGPT/Support/ModuleInfo.php @@ -4,10 +4,11 @@ namespace Modules\ChatGPT\Support; class ModuleInfo { - protected static string $moduleName = 'ChatGPT'; + protected static string $moduleName = 'ChatGPT'; /** * defines the Module Name + * * @return string */ public static function name(): string @@ -17,6 +18,7 @@ class ModuleInfo /** * define the lowercase version + * * @return string */ public static function nameLower(): string diff --git a/Modules/ChatGPT/Tests/Browser/.gitkeep b/Modules/ChatGPT/Tests/Browser/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Tests/Feature/.gitkeep b/Modules/ChatGPT/Tests/Feature/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Tests/Feature/ChatGptApiSettingTest.php b/Modules/ChatGPT/Tests/Feature/ChatGptApiSettingTest.php old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Tests/Unit/.gitkeep b/Modules/ChatGPT/Tests/Unit/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/Traits/.gitkeep b/Modules/ChatGPT/Traits/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/View/.gitkeep b/Modules/ChatGPT/View/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/changelog.yaml b/Modules/ChatGPT/changelog.yaml old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/composer.json b/Modules/ChatGPT/composer.json old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/module.json b/Modules/ChatGPT/module.json old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/package.json b/Modules/ChatGPT/package.json old mode 100644 new mode 100755 diff --git a/Modules/ChatGPT/readme.md b/Modules/ChatGPT/readme.md deleted file mode 100644 index fd961169..00000000 --- a/Modules/ChatGPT/readme.md +++ /dev/null @@ -1,28 +0,0 @@ -# ChatGPT Module - -Provides encrypted OpenAI API key storage and an Artisan command for deleting all OpenAI API files visible to the active stored key. - -## Routes - -- `GET /chatgpt` - manage stored API keys. -- `POST /chatgpt/settings` - create a stored API key. -- `PUT /chatgpt/settings/{setting}` - update an API key setting. -- `DELETE /chatgpt/settings/{setting}` - delete an API key setting. - -## Commands - -Preview files without deleting: - -```bash -php artisan chatgpt:delete-api-files --dry-run -``` - -Delete all OpenAI API files without interactive confirmation: - -```bash -php artisan chatgpt:delete-api-files -``` - -## Security - -API keys are encrypted at rest using Laravel's encrypted Eloquent cast and the application `APP_KEY`. diff --git a/Modules/ChatGPT/webpack.mix.js b/Modules/ChatGPT/webpack.mix.js old mode 100644 new mode 100755 diff --git a/Modules/Company/Database/Migrations/2026_07_02_120000_create_company_addresses_table.php b/Modules/Company/Database/Migrations/2026_07_02_120000_create_company_addresses_table.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Database/Migrations/2026_07_02_121000_create_company_divisions_table.php b/Modules/Company/Database/Migrations/2026_07_02_121000_create_company_divisions_table.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Database/Migrations/2026_07_02_122000_create_company_division_user_table.php b/Modules/Company/Database/Migrations/2026_07_02_122000_create_company_division_user_table.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Database/Migrations/2026_07_02_123000_create_company_director_assignments_table.php b/Modules/Company/Database/Migrations/2026_07_02_123000_create_company_director_assignments_table.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Database/Migrations/2026_07_02_124000_add_division_id_to_warehouses_table.php b/Modules/Company/Database/Migrations/2026_07_02_124000_add_division_id_to_warehouses_table.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Database/Migrations/2026_07_07_093000_add_country_id_to_companies_table.php b/Modules/Company/Database/Migrations/2026_07_07_093000_add_country_id_to_companies_table.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Http/Controllers/CompanyAddressController.php b/Modules/Company/Http/Controllers/CompanyAddressController.php old mode 100644 new mode 100755 index abf17a7a..a761b770 --- a/Modules/Company/Http/Controllers/CompanyAddressController.php +++ b/Modules/Company/Http/Controllers/CompanyAddressController.php @@ -11,6 +11,8 @@ use Modules\Warehouse\app\Models\Warehouse; class CompanyAddressController extends Controller { + private const MAX_STRING = 'max:255'; + public function updateCompany(Request $request, Company $company) { $this->upsertAddress($request, $company); @@ -40,12 +42,12 @@ class CompanyAddressController extends Controller { $data = $request->validate([ 'label' => ['nullable', 'string', 'max:80'], - 'attention' => ['nullable', 'string', 'max:255'], - 'line_1' => ['required', 'string', 'max:255'], - 'line_2' => ['nullable', 'string', 'max:255'], - 'line_3' => ['nullable', 'string', 'max:255'], - 'locality' => ['required', 'string', 'max:255'], - 'administrative_area' => ['nullable', 'string', 'max:255'], + 'attention' => ['nullable', 'string', self::MAX_STRING], + 'line_1' => ['required', 'string', self::MAX_STRING], + 'line_2' => ['nullable', 'string', self::MAX_STRING], + 'line_3' => ['nullable', 'string', self::MAX_STRING], + 'locality' => ['required', 'string', self::MAX_STRING], + 'administrative_area' => ['nullable', 'string', self::MAX_STRING], 'postal_code' => ['nullable', 'string', 'max:32'], 'country_id' => ['required', Rule::exists('countries', 'id')->where('is_active', true)], 'country_subdivision_id' => ['nullable', 'exists:country_subdivisions,id'], diff --git a/Modules/Company/Http/Controllers/CompanyController.php b/Modules/Company/Http/Controllers/CompanyController.php old mode 100644 new mode 100755 index 1acd93a6..860637bb --- a/Modules/Company/Http/Controllers/CompanyController.php +++ b/Modules/Company/Http/Controllers/CompanyController.php @@ -45,7 +45,7 @@ class CompanyController extends Controller */ public function store(Request $request) { - $company = Company::create($this->validated($request)); + Company::create($this->validated($request)); return redirect() ->route('platform.companies.index') diff --git a/Modules/Company/Http/Controllers/CompanyDivisionController.php b/Modules/Company/Http/Controllers/CompanyDivisionController.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Http/Controllers/CompanyMembershipController.php b/Modules/Company/Http/Controllers/CompanyMembershipController.php old mode 100644 new mode 100755 index 7ce6d23c..b5f4a897 --- a/Modules/Company/Http/Controllers/CompanyMembershipController.php +++ b/Modules/Company/Http/Controllers/CompanyMembershipController.php @@ -3,12 +3,11 @@ namespace Modules\Company\Http\Controllers; use App\Http\Controllers\Controller; -use App\Models\User; use Illuminate\Http\Request; use Illuminate\Validation\Rule; use Modules\Company\Models\Company; -use Modules\Company\Models\CompanyDivision; use Modules\Company\Models\CompanyDirectorAssignment; +use Modules\Company\Models\CompanyDivision; class CompanyMembershipController extends Controller { diff --git a/Modules/Company/Http/Controllers/CompanyWarehouseAssignmentController.php b/Modules/Company/Http/Controllers/CompanyWarehouseAssignmentController.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Models/Company.php b/Modules/Company/Models/Company.php old mode 100644 new mode 100755 index 2437ee75..709ce562 --- a/Modules/Company/Models/Company.php +++ b/Modules/Company/Models/Company.php @@ -9,8 +9,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Str; -use Modules\Platform\app\Models\LicenseKey; use Modules\Countries\Models\Country; +use Modules\Platform\app\Models\LicenseKey; use Modules\Platform\app\Models\Payment; use Modules\Warehouse\app\Models\Warehouse; @@ -38,8 +38,6 @@ class Company extends Model }); } - - public function country(): BelongsTo { return $this->belongsTo(Country::class); diff --git a/Modules/Company/Models/CompanyAddress.php b/Modules/Company/Models/CompanyAddress.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Models/CompanyDirectorAssignment.php b/Modules/Company/Models/CompanyDirectorAssignment.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Models/CompanyDivision.php b/Modules/Company/Models/CompanyDivision.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Providers/CompanyServiceProvider.php b/Modules/Company/Providers/CompanyServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Resources/views/_form.blade.php b/Modules/Company/Resources/views/_form.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Resources/views/create.blade.php b/Modules/Company/Resources/views/create.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Resources/views/edit.blade.php b/Modules/Company/Resources/views/edit.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Resources/views/index.blade.php b/Modules/Company/Resources/views/index.blade.php old mode 100644 new mode 100755 index 1f3661a6..1e8c3948 --- a/Modules/Company/Resources/views/index.blade.php +++ b/Modules/Company/Resources/views/index.blade.php @@ -109,6 +109,7 @@
Data table
Name
+ diff --git a/Modules/Company/Resources/views/partials/address-form.blade.php b/Modules/Company/Resources/views/partials/address-form.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Company/Resources/views/show.blade.php b/Modules/Company/Resources/views/show.blade.php old mode 100644 new mode 100755 index 3dcb3c60..0d0c9293 --- a/Modules/Company/Resources/views/show.blade.php +++ b/Modules/Company/Resources/views/show.blade.php @@ -215,7 +215,7 @@ @csrf @method('PUT') - @foreach($company->divisions as $divisionOption) @@ -253,18 +253,18 @@
- - + +
- - + +
- - @@ -276,7 +276,7 @@
- +

Division address

@csrf @method('PUT')@include('company::partials.address-form', ['address' => $division->address, 'defaultLabel' => 'Operating address'])
diff --git a/Modules/Company/Routes/web.php b/Modules/Company/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Company/changelog.yaml b/Modules/Company/changelog.yaml old mode 100644 new mode 100755 diff --git a/Modules/Company/module.json b/Modules/Company/module.json old mode 100644 new mode 100755 diff --git a/Modules/Configuration/Entities/.gitkeep b/Modules/Configuration/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Configuration/Providers/ConfigurationServiceProvider.php b/Modules/Configuration/Providers/ConfigurationServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Configuration/README.md b/Modules/Configuration/README.md deleted file mode 100644 index a012d90e..00000000 --- a/Modules/Configuration/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Configuration - -Centralise system settings, warehouse defaults, interface flags, and feature switches. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Configuration/Resources/views/index.blade.php b/Modules/Configuration/Resources/views/index.blade.php old mode 100644 new mode 100755 index 5adc2ca3..a3752ae9 --- a/Modules/Configuration/Resources/views/index.blade.php +++ b/Modules/Configuration/Resources/views/index.blade.php @@ -64,6 +64,7 @@
Data table
Name
+ diff --git a/Modules/Configuration/Resources/views/partials/nav.blade.php b/Modules/Configuration/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Configuration/Routes/api.php b/Modules/Configuration/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Configuration/Routes/web.php b/Modules/Configuration/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Configuration/module.json b/Modules/Configuration/module.json old mode 100644 new mode 100755 diff --git a/Modules/Countries/Config/.gitkeep b/Modules/Countries/Config/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Config/config.php b/Modules/Countries/Config/config.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Console/.gitkeep b/Modules/Countries/Console/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Console/SyncIsoCountriesCommand.php b/Modules/Countries/Console/SyncIsoCountriesCommand.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Data/iso_countries.json b/Modules/Countries/Database/Data/iso_countries.json new file mode 100755 index 00000000..c1f386a3 --- /dev/null +++ b/Modules/Countries/Database/Data/iso_countries.json @@ -0,0 +1,2243 @@ +[ + { + "alpha2": "AD", + "alpha3": "AND", + "numeric": "020", + "name": "Andorra", + "official_name": "Principality of Andorra", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฉ" + }, + { + "alpha2": "AE", + "alpha3": "ARE", + "numeric": "784", + "name": "United Arab Emirates", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ช" + }, + { + "alpha2": "AF", + "alpha3": "AFG", + "numeric": "004", + "name": "Afghanistan", + "official_name": "Islamic Republic of Afghanistan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ซ" + }, + { + "alpha2": "AG", + "alpha3": "ATG", + "numeric": "028", + "name": "Antigua and Barbuda", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฌ" + }, + { + "alpha2": "AI", + "alpha3": "AIA", + "numeric": "660", + "name": "Anguilla", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฎ" + }, + { + "alpha2": "AL", + "alpha3": "ALB", + "numeric": "008", + "name": "Albania", + "official_name": "Republic of Albania", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฑ" + }, + { + "alpha2": "AM", + "alpha3": "ARM", + "numeric": "051", + "name": "Armenia", + "official_name": "Republic of Armenia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฒ" + }, + { + "alpha2": "AO", + "alpha3": "AGO", + "numeric": "024", + "name": "Angola", + "official_name": "Republic of Angola", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ด" + }, + { + "alpha2": "AQ", + "alpha3": "ATA", + "numeric": "010", + "name": "Antarctica", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ถ" + }, + { + "alpha2": "AR", + "alpha3": "ARG", + "numeric": "032", + "name": "Argentina", + "official_name": "Argentine Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ท" + }, + { + "alpha2": "AS", + "alpha3": "ASM", + "numeric": "016", + "name": "American Samoa", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ธ" + }, + { + "alpha2": "AT", + "alpha3": "AUT", + "numeric": "040", + "name": "Austria", + "official_name": "Republic of Austria", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡น" + }, + { + "alpha2": "AU", + "alpha3": "AUS", + "numeric": "036", + "name": "Australia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡บ" + }, + { + "alpha2": "AW", + "alpha3": "ABW", + "numeric": "533", + "name": "Aruba", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ผ" + }, + { + "alpha2": "AX", + "alpha3": "ALA", + "numeric": "248", + "name": "ร…land Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฝ" + }, + { + "alpha2": "AZ", + "alpha3": "AZE", + "numeric": "031", + "name": "Azerbaijan", + "official_name": "Republic of Azerbaijan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฆ๐Ÿ‡ฟ" + }, + { + "alpha2": "BA", + "alpha3": "BIH", + "numeric": "070", + "name": "Bosnia and Herzegovina", + "official_name": "Republic of Bosnia and Herzegovina", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฆ" + }, + { + "alpha2": "BB", + "alpha3": "BRB", + "numeric": "052", + "name": "Barbados", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ง" + }, + { + "alpha2": "BD", + "alpha3": "BGD", + "numeric": "050", + "name": "Bangladesh", + "official_name": "People's Republic of Bangladesh", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฉ" + }, + { + "alpha2": "BE", + "alpha3": "BEL", + "numeric": "056", + "name": "Belgium", + "official_name": "Kingdom of Belgium", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ช" + }, + { + "alpha2": "BF", + "alpha3": "BFA", + "numeric": "854", + "name": "Burkina Faso", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ซ" + }, + { + "alpha2": "BG", + "alpha3": "BGR", + "numeric": "100", + "name": "Bulgaria", + "official_name": "Republic of Bulgaria", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฌ" + }, + { + "alpha2": "BH", + "alpha3": "BHR", + "numeric": "048", + "name": "Bahrain", + "official_name": "Kingdom of Bahrain", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ญ" + }, + { + "alpha2": "BI", + "alpha3": "BDI", + "numeric": "108", + "name": "Burundi", + "official_name": "Republic of Burundi", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฎ" + }, + { + "alpha2": "BJ", + "alpha3": "BEN", + "numeric": "204", + "name": "Benin", + "official_name": "Republic of Benin", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฏ" + }, + { + "alpha2": "BL", + "alpha3": "BLM", + "numeric": "652", + "name": "Saint Barthรฉlemy", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฑ" + }, + { + "alpha2": "BM", + "alpha3": "BMU", + "numeric": "060", + "name": "Bermuda", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฒ" + }, + { + "alpha2": "BN", + "alpha3": "BRN", + "numeric": "096", + "name": "Brunei Darussalam", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ณ" + }, + { + "alpha2": "BO", + "alpha3": "BOL", + "numeric": "068", + "name": "Bolivia, Plurinational State of", + "official_name": "Plurinational State of Bolivia", + "common_name": "Bolivia", + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ด" + }, + { + "alpha2": "BQ", + "alpha3": "BES", + "numeric": "535", + "name": "Bonaire, Sint Eustatius and Saba", + "official_name": "Bonaire, Sint Eustatius and Saba", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ถ" + }, + { + "alpha2": "BR", + "alpha3": "BRA", + "numeric": "076", + "name": "Brazil", + "official_name": "Federative Republic of Brazil", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ท" + }, + { + "alpha2": "BS", + "alpha3": "BHS", + "numeric": "044", + "name": "Bahamas", + "official_name": "Commonwealth of the Bahamas", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ธ" + }, + { + "alpha2": "BT", + "alpha3": "BTN", + "numeric": "064", + "name": "Bhutan", + "official_name": "Kingdom of Bhutan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡น" + }, + { + "alpha2": "BV", + "alpha3": "BVT", + "numeric": "074", + "name": "Bouvet Island", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ป" + }, + { + "alpha2": "BW", + "alpha3": "BWA", + "numeric": "072", + "name": "Botswana", + "official_name": "Republic of Botswana", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ผ" + }, + { + "alpha2": "BY", + "alpha3": "BLR", + "numeric": "112", + "name": "Belarus", + "official_name": "Republic of Belarus", + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡พ" + }, + { + "alpha2": "BZ", + "alpha3": "BLZ", + "numeric": "084", + "name": "Belize", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ง๐Ÿ‡ฟ" + }, + { + "alpha2": "CA", + "alpha3": "CAN", + "numeric": "124", + "name": "Canada", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฆ" + }, + { + "alpha2": "CC", + "alpha3": "CCK", + "numeric": "166", + "name": "Cocos (Keeling) Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡จ" + }, + { + "alpha2": "CD", + "alpha3": "COD", + "numeric": "180", + "name": "Congo, The Democratic Republic of the", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฉ" + }, + { + "alpha2": "CF", + "alpha3": "CAF", + "numeric": "140", + "name": "Central African Republic", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ซ" + }, + { + "alpha2": "CG", + "alpha3": "COG", + "numeric": "178", + "name": "Congo", + "official_name": "Republic of the Congo", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฌ" + }, + { + "alpha2": "CH", + "alpha3": "CHE", + "numeric": "756", + "name": "Switzerland", + "official_name": "Swiss Confederation", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ญ" + }, + { + "alpha2": "CI", + "alpha3": "CIV", + "numeric": "384", + "name": "Cรดte d'Ivoire", + "official_name": "Republic of Cรดte d'Ivoire", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฎ" + }, + { + "alpha2": "CK", + "alpha3": "COK", + "numeric": "184", + "name": "Cook Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฐ" + }, + { + "alpha2": "CL", + "alpha3": "CHL", + "numeric": "152", + "name": "Chile", + "official_name": "Republic of Chile", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฑ" + }, + { + "alpha2": "CM", + "alpha3": "CMR", + "numeric": "120", + "name": "Cameroon", + "official_name": "Republic of Cameroon", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฒ" + }, + { + "alpha2": "CN", + "alpha3": "CHN", + "numeric": "156", + "name": "China", + "official_name": "People's Republic of China", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ณ" + }, + { + "alpha2": "CO", + "alpha3": "COL", + "numeric": "170", + "name": "Colombia", + "official_name": "Republic of Colombia", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ด" + }, + { + "alpha2": "CR", + "alpha3": "CRI", + "numeric": "188", + "name": "Costa Rica", + "official_name": "Republic of Costa Rica", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ท" + }, + { + "alpha2": "CU", + "alpha3": "CUB", + "numeric": "192", + "name": "Cuba", + "official_name": "Republic of Cuba", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡บ" + }, + { + "alpha2": "CV", + "alpha3": "CPV", + "numeric": "132", + "name": "Cabo Verde", + "official_name": "Republic of Cabo Verde", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ป" + }, + { + "alpha2": "CW", + "alpha3": "CUW", + "numeric": "531", + "name": "Curaรงao", + "official_name": "Curaรงao", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ผ" + }, + { + "alpha2": "CX", + "alpha3": "CXR", + "numeric": "162", + "name": "Christmas Island", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฝ" + }, + { + "alpha2": "CY", + "alpha3": "CYP", + "numeric": "196", + "name": "Cyprus", + "official_name": "Republic of Cyprus", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡พ" + }, + { + "alpha2": "CZ", + "alpha3": "CZE", + "numeric": "203", + "name": "Czechia", + "official_name": "Czech Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡จ๐Ÿ‡ฟ" + }, + { + "alpha2": "DE", + "alpha3": "DEU", + "numeric": "276", + "name": "Germany", + "official_name": "Federal Republic of Germany", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฉ๐Ÿ‡ช" + }, + { + "alpha2": "DJ", + "alpha3": "DJI", + "numeric": "262", + "name": "Djibouti", + "official_name": "Republic of Djibouti", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฉ๐Ÿ‡ฏ" + }, + { + "alpha2": "DK", + "alpha3": "DNK", + "numeric": "208", + "name": "Denmark", + "official_name": "Kingdom of Denmark", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฉ๐Ÿ‡ฐ" + }, + { + "alpha2": "DM", + "alpha3": "DMA", + "numeric": "212", + "name": "Dominica", + "official_name": "Commonwealth of Dominica", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฉ๐Ÿ‡ฒ" + }, + { + "alpha2": "DO", + "alpha3": "DOM", + "numeric": "214", + "name": "Dominican Republic", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฉ๐Ÿ‡ด" + }, + { + "alpha2": "DZ", + "alpha3": "DZA", + "numeric": "012", + "name": "Algeria", + "official_name": "People's Democratic Republic of Algeria", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฉ๐Ÿ‡ฟ" + }, + { + "alpha2": "EC", + "alpha3": "ECU", + "numeric": "218", + "name": "Ecuador", + "official_name": "Republic of Ecuador", + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡จ" + }, + { + "alpha2": "EE", + "alpha3": "EST", + "numeric": "233", + "name": "Estonia", + "official_name": "Republic of Estonia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡ช" + }, + { + "alpha2": "EG", + "alpha3": "EGY", + "numeric": "818", + "name": "Egypt", + "official_name": "Arab Republic of Egypt", + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡ฌ" + }, + { + "alpha2": "EH", + "alpha3": "ESH", + "numeric": "732", + "name": "Western Sahara", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡ญ" + }, + { + "alpha2": "ER", + "alpha3": "ERI", + "numeric": "232", + "name": "Eritrea", + "official_name": "the State of Eritrea", + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡ท" + }, + { + "alpha2": "ES", + "alpha3": "ESP", + "numeric": "724", + "name": "Spain", + "official_name": "Kingdom of Spain", + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡ธ" + }, + { + "alpha2": "ET", + "alpha3": "ETH", + "numeric": "231", + "name": "Ethiopia", + "official_name": "Federal Democratic Republic of Ethiopia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ช๐Ÿ‡น" + }, + { + "alpha2": "FI", + "alpha3": "FIN", + "numeric": "246", + "name": "Finland", + "official_name": "Republic of Finland", + "common_name": null, + "flag_emoji": "๐Ÿ‡ซ๐Ÿ‡ฎ" + }, + { + "alpha2": "FJ", + "alpha3": "FJI", + "numeric": "242", + "name": "Fiji", + "official_name": "Republic of Fiji", + "common_name": null, + "flag_emoji": "๐Ÿ‡ซ๐Ÿ‡ฏ" + }, + { + "alpha2": "FK", + "alpha3": "FLK", + "numeric": "238", + "name": "Falkland Islands (Malvinas)", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ซ๐Ÿ‡ฐ" + }, + { + "alpha2": "FM", + "alpha3": "FSM", + "numeric": "583", + "name": "Micronesia, Federated States of", + "official_name": "Federated States of Micronesia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ซ๐Ÿ‡ฒ" + }, + { + "alpha2": "FO", + "alpha3": "FRO", + "numeric": "234", + "name": "Faroe Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ซ๐Ÿ‡ด" + }, + { + "alpha2": "FR", + "alpha3": "FRA", + "numeric": "250", + "name": "France", + "official_name": "French Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ซ๐Ÿ‡ท" + }, + { + "alpha2": "GA", + "alpha3": "GAB", + "numeric": "266", + "name": "Gabon", + "official_name": "Gabonese Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ฆ" + }, + { + "alpha2": "GB", + "alpha3": "GBR", + "numeric": "826", + "name": "United Kingdom", + "official_name": "United Kingdom of Great Britain and Northern Ireland", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ง" + }, + { + "alpha2": "GD", + "alpha3": "GRD", + "numeric": "308", + "name": "Grenada", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ฉ" + }, + { + "alpha2": "GE", + "alpha3": "GEO", + "numeric": "268", + "name": "Georgia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ช" + }, + { + "alpha2": "GF", + "alpha3": "GUF", + "numeric": "254", + "name": "French Guiana", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ซ" + }, + { + "alpha2": "GG", + "alpha3": "GGY", + "numeric": "831", + "name": "Guernsey", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ฌ" + }, + { + "alpha2": "GH", + "alpha3": "GHA", + "numeric": "288", + "name": "Ghana", + "official_name": "Republic of Ghana", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ญ" + }, + { + "alpha2": "GI", + "alpha3": "GIB", + "numeric": "292", + "name": "Gibraltar", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ฎ" + }, + { + "alpha2": "GL", + "alpha3": "GRL", + "numeric": "304", + "name": "Greenland", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ฑ" + }, + { + "alpha2": "GM", + "alpha3": "GMB", + "numeric": "270", + "name": "Gambia", + "official_name": "Republic of the Gambia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ฒ" + }, + { + "alpha2": "GN", + "alpha3": "GIN", + "numeric": "324", + "name": "Guinea", + "official_name": "Republic of Guinea", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ณ" + }, + { + "alpha2": "GP", + "alpha3": "GLP", + "numeric": "312", + "name": "Guadeloupe", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ต" + }, + { + "alpha2": "GQ", + "alpha3": "GNQ", + "numeric": "226", + "name": "Equatorial Guinea", + "official_name": "Republic of Equatorial Guinea", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ถ" + }, + { + "alpha2": "GR", + "alpha3": "GRC", + "numeric": "300", + "name": "Greece", + "official_name": "Hellenic Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ท" + }, + { + "alpha2": "GS", + "alpha3": "SGS", + "numeric": "239", + "name": "South Georgia and the South Sandwich Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ธ" + }, + { + "alpha2": "GT", + "alpha3": "GTM", + "numeric": "320", + "name": "Guatemala", + "official_name": "Republic of Guatemala", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡น" + }, + { + "alpha2": "GU", + "alpha3": "GUM", + "numeric": "316", + "name": "Guam", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡บ" + }, + { + "alpha2": "GW", + "alpha3": "GNB", + "numeric": "624", + "name": "Guinea-Bissau", + "official_name": "Republic of Guinea-Bissau", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡ผ" + }, + { + "alpha2": "GY", + "alpha3": "GUY", + "numeric": "328", + "name": "Guyana", + "official_name": "Republic of Guyana", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฌ๐Ÿ‡พ" + }, + { + "alpha2": "HK", + "alpha3": "HKG", + "numeric": "344", + "name": "Hong Kong", + "official_name": "Hong Kong Special Administrative Region of China", + "common_name": null, + "flag_emoji": "๐Ÿ‡ญ๐Ÿ‡ฐ" + }, + { + "alpha2": "HM", + "alpha3": "HMD", + "numeric": "334", + "name": "Heard Island and McDonald Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ญ๐Ÿ‡ฒ" + }, + { + "alpha2": "HN", + "alpha3": "HND", + "numeric": "340", + "name": "Honduras", + "official_name": "Republic of Honduras", + "common_name": null, + "flag_emoji": "๐Ÿ‡ญ๐Ÿ‡ณ" + }, + { + "alpha2": "HR", + "alpha3": "HRV", + "numeric": "191", + "name": "Croatia", + "official_name": "Republic of Croatia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ญ๐Ÿ‡ท" + }, + { + "alpha2": "HT", + "alpha3": "HTI", + "numeric": "332", + "name": "Haiti", + "official_name": "Republic of Haiti", + "common_name": null, + "flag_emoji": "๐Ÿ‡ญ๐Ÿ‡น" + }, + { + "alpha2": "HU", + "alpha3": "HUN", + "numeric": "348", + "name": "Hungary", + "official_name": "Hungary", + "common_name": null, + "flag_emoji": "๐Ÿ‡ญ๐Ÿ‡บ" + }, + { + "alpha2": "ID", + "alpha3": "IDN", + "numeric": "360", + "name": "Indonesia", + "official_name": "Republic of Indonesia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ฉ" + }, + { + "alpha2": "IE", + "alpha3": "IRL", + "numeric": "372", + "name": "Ireland", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ช" + }, + { + "alpha2": "IL", + "alpha3": "ISR", + "numeric": "376", + "name": "Israel", + "official_name": "State of Israel", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ฑ" + }, + { + "alpha2": "IM", + "alpha3": "IMN", + "numeric": "833", + "name": "Isle of Man", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ฒ" + }, + { + "alpha2": "IN", + "alpha3": "IND", + "numeric": "356", + "name": "India", + "official_name": "Republic of India", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ณ" + }, + { + "alpha2": "IO", + "alpha3": "IOT", + "numeric": "086", + "name": "British Indian Ocean Territory", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ด" + }, + { + "alpha2": "IQ", + "alpha3": "IRQ", + "numeric": "368", + "name": "Iraq", + "official_name": "Republic of Iraq", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ถ" + }, + { + "alpha2": "IR", + "alpha3": "IRN", + "numeric": "364", + "name": "Iran, Islamic Republic of", + "official_name": "Islamic Republic of Iran", + "common_name": "Iran", + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ท" + }, + { + "alpha2": "IS", + "alpha3": "ISL", + "numeric": "352", + "name": "Iceland", + "official_name": "Republic of Iceland", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡ธ" + }, + { + "alpha2": "IT", + "alpha3": "ITA", + "numeric": "380", + "name": "Italy", + "official_name": "Italian Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฎ๐Ÿ‡น" + }, + { + "alpha2": "JE", + "alpha3": "JEY", + "numeric": "832", + "name": "Jersey", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฏ๐Ÿ‡ช" + }, + { + "alpha2": "JM", + "alpha3": "JAM", + "numeric": "388", + "name": "Jamaica", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฏ๐Ÿ‡ฒ" + }, + { + "alpha2": "JO", + "alpha3": "JOR", + "numeric": "400", + "name": "Jordan", + "official_name": "Hashemite Kingdom of Jordan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฏ๐Ÿ‡ด" + }, + { + "alpha2": "JP", + "alpha3": "JPN", + "numeric": "392", + "name": "Japan", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฏ๐Ÿ‡ต" + }, + { + "alpha2": "KE", + "alpha3": "KEN", + "numeric": "404", + "name": "Kenya", + "official_name": "Republic of Kenya", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ช" + }, + { + "alpha2": "KG", + "alpha3": "KGZ", + "numeric": "417", + "name": "Kyrgyzstan", + "official_name": "Kyrgyz Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ฌ" + }, + { + "alpha2": "KH", + "alpha3": "KHM", + "numeric": "116", + "name": "Cambodia", + "official_name": "Kingdom of Cambodia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ญ" + }, + { + "alpha2": "KI", + "alpha3": "KIR", + "numeric": "296", + "name": "Kiribati", + "official_name": "Republic of Kiribati", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ฎ" + }, + { + "alpha2": "KM", + "alpha3": "COM", + "numeric": "174", + "name": "Comoros", + "official_name": "Union of the Comoros", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ฒ" + }, + { + "alpha2": "KN", + "alpha3": "KNA", + "numeric": "659", + "name": "Saint Kitts and Nevis", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ณ" + }, + { + "alpha2": "KP", + "alpha3": "PRK", + "numeric": "408", + "name": "Korea, Democratic People's Republic of", + "official_name": "Democratic People's Republic of Korea", + "common_name": "North Korea", + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ต" + }, + { + "alpha2": "KR", + "alpha3": "KOR", + "numeric": "410", + "name": "Korea, Republic of", + "official_name": null, + "common_name": "South Korea", + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ท" + }, + { + "alpha2": "KW", + "alpha3": "KWT", + "numeric": "414", + "name": "Kuwait", + "official_name": "State of Kuwait", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ผ" + }, + { + "alpha2": "KY", + "alpha3": "CYM", + "numeric": "136", + "name": "Cayman Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡พ" + }, + { + "alpha2": "KZ", + "alpha3": "KAZ", + "numeric": "398", + "name": "Kazakhstan", + "official_name": "Republic of Kazakhstan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฐ๐Ÿ‡ฟ" + }, + { + "alpha2": "LA", + "alpha3": "LAO", + "numeric": "418", + "name": "Lao People's Democratic Republic", + "official_name": null, + "common_name": "Laos", + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ฆ" + }, + { + "alpha2": "LB", + "alpha3": "LBN", + "numeric": "422", + "name": "Lebanon", + "official_name": "Lebanese Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ง" + }, + { + "alpha2": "LC", + "alpha3": "LCA", + "numeric": "662", + "name": "Saint Lucia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡จ" + }, + { + "alpha2": "LI", + "alpha3": "LIE", + "numeric": "438", + "name": "Liechtenstein", + "official_name": "Principality of Liechtenstein", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ฎ" + }, + { + "alpha2": "LK", + "alpha3": "LKA", + "numeric": "144", + "name": "Sri Lanka", + "official_name": "Democratic Socialist Republic of Sri Lanka", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ฐ" + }, + { + "alpha2": "LR", + "alpha3": "LBR", + "numeric": "430", + "name": "Liberia", + "official_name": "Republic of Liberia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ท" + }, + { + "alpha2": "LS", + "alpha3": "LSO", + "numeric": "426", + "name": "Lesotho", + "official_name": "Kingdom of Lesotho", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ธ" + }, + { + "alpha2": "LT", + "alpha3": "LTU", + "numeric": "440", + "name": "Lithuania", + "official_name": "Republic of Lithuania", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡น" + }, + { + "alpha2": "LU", + "alpha3": "LUX", + "numeric": "442", + "name": "Luxembourg", + "official_name": "Grand Duchy of Luxembourg", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡บ" + }, + { + "alpha2": "LV", + "alpha3": "LVA", + "numeric": "428", + "name": "Latvia", + "official_name": "Republic of Latvia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡ป" + }, + { + "alpha2": "LY", + "alpha3": "LBY", + "numeric": "434", + "name": "Libya", + "official_name": "Libya", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฑ๐Ÿ‡พ" + }, + { + "alpha2": "MA", + "alpha3": "MAR", + "numeric": "504", + "name": "Morocco", + "official_name": "Kingdom of Morocco", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฆ" + }, + { + "alpha2": "MC", + "alpha3": "MCO", + "numeric": "492", + "name": "Monaco", + "official_name": "Principality of Monaco", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡จ" + }, + { + "alpha2": "MD", + "alpha3": "MDA", + "numeric": "498", + "name": "Moldova, Republic of", + "official_name": "Republic of Moldova", + "common_name": "Moldova", + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฉ" + }, + { + "alpha2": "ME", + "alpha3": "MNE", + "numeric": "499", + "name": "Montenegro", + "official_name": "Montenegro", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ช" + }, + { + "alpha2": "MF", + "alpha3": "MAF", + "numeric": "663", + "name": "Saint Martin (French part)", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ซ" + }, + { + "alpha2": "MG", + "alpha3": "MDG", + "numeric": "450", + "name": "Madagascar", + "official_name": "Republic of Madagascar", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฌ" + }, + { + "alpha2": "MH", + "alpha3": "MHL", + "numeric": "584", + "name": "Marshall Islands", + "official_name": "Republic of the Marshall Islands", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ญ" + }, + { + "alpha2": "MK", + "alpha3": "MKD", + "numeric": "807", + "name": "North Macedonia", + "official_name": "Republic of North Macedonia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฐ" + }, + { + "alpha2": "ML", + "alpha3": "MLI", + "numeric": "466", + "name": "Mali", + "official_name": "Republic of Mali", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฑ" + }, + { + "alpha2": "MM", + "alpha3": "MMR", + "numeric": "104", + "name": "Myanmar", + "official_name": "Republic of Myanmar", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฒ" + }, + { + "alpha2": "MN", + "alpha3": "MNG", + "numeric": "496", + "name": "Mongolia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ณ" + }, + { + "alpha2": "MO", + "alpha3": "MAC", + "numeric": "446", + "name": "Macao", + "official_name": "Macao Special Administrative Region of China", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ด" + }, + { + "alpha2": "MP", + "alpha3": "MNP", + "numeric": "580", + "name": "Northern Mariana Islands", + "official_name": "Commonwealth of the Northern Mariana Islands", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ต" + }, + { + "alpha2": "MQ", + "alpha3": "MTQ", + "numeric": "474", + "name": "Martinique", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ถ" + }, + { + "alpha2": "MR", + "alpha3": "MRT", + "numeric": "478", + "name": "Mauritania", + "official_name": "Islamic Republic of Mauritania", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ท" + }, + { + "alpha2": "MS", + "alpha3": "MSR", + "numeric": "500", + "name": "Montserrat", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ธ" + }, + { + "alpha2": "MT", + "alpha3": "MLT", + "numeric": "470", + "name": "Malta", + "official_name": "Republic of Malta", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡น" + }, + { + "alpha2": "MU", + "alpha3": "MUS", + "numeric": "480", + "name": "Mauritius", + "official_name": "Republic of Mauritius", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡บ" + }, + { + "alpha2": "MV", + "alpha3": "MDV", + "numeric": "462", + "name": "Maldives", + "official_name": "Republic of Maldives", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ป" + }, + { + "alpha2": "MW", + "alpha3": "MWI", + "numeric": "454", + "name": "Malawi", + "official_name": "Republic of Malawi", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ผ" + }, + { + "alpha2": "MX", + "alpha3": "MEX", + "numeric": "484", + "name": "Mexico", + "official_name": "United Mexican States", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฝ" + }, + { + "alpha2": "MY", + "alpha3": "MYS", + "numeric": "458", + "name": "Malaysia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡พ" + }, + { + "alpha2": "MZ", + "alpha3": "MOZ", + "numeric": "508", + "name": "Mozambique", + "official_name": "Republic of Mozambique", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฒ๐Ÿ‡ฟ" + }, + { + "alpha2": "NA", + "alpha3": "NAM", + "numeric": "516", + "name": "Namibia", + "official_name": "Republic of Namibia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ฆ" + }, + { + "alpha2": "NC", + "alpha3": "NCL", + "numeric": "540", + "name": "New Caledonia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡จ" + }, + { + "alpha2": "NE", + "alpha3": "NER", + "numeric": "562", + "name": "Niger", + "official_name": "Republic of the Niger", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ช" + }, + { + "alpha2": "NF", + "alpha3": "NFK", + "numeric": "574", + "name": "Norfolk Island", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ซ" + }, + { + "alpha2": "NG", + "alpha3": "NGA", + "numeric": "566", + "name": "Nigeria", + "official_name": "Federal Republic of Nigeria", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ฌ" + }, + { + "alpha2": "NI", + "alpha3": "NIC", + "numeric": "558", + "name": "Nicaragua", + "official_name": "Republic of Nicaragua", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ฎ" + }, + { + "alpha2": "NL", + "alpha3": "NLD", + "numeric": "528", + "name": "Netherlands", + "official_name": "Kingdom of the Netherlands", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ฑ" + }, + { + "alpha2": "NO", + "alpha3": "NOR", + "numeric": "578", + "name": "Norway", + "official_name": "Kingdom of Norway", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ด" + }, + { + "alpha2": "NP", + "alpha3": "NPL", + "numeric": "524", + "name": "Nepal", + "official_name": "Federal Democratic Republic of Nepal", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ต" + }, + { + "alpha2": "NR", + "alpha3": "NRU", + "numeric": "520", + "name": "Nauru", + "official_name": "Republic of Nauru", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ท" + }, + { + "alpha2": "NU", + "alpha3": "NIU", + "numeric": "570", + "name": "Niue", + "official_name": "Niue", + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡บ" + }, + { + "alpha2": "NZ", + "alpha3": "NZL", + "numeric": "554", + "name": "New Zealand", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ณ๐Ÿ‡ฟ" + }, + { + "alpha2": "OM", + "alpha3": "OMN", + "numeric": "512", + "name": "Oman", + "official_name": "Sultanate of Oman", + "common_name": null, + "flag_emoji": "๐Ÿ‡ด๐Ÿ‡ฒ" + }, + { + "alpha2": "PA", + "alpha3": "PAN", + "numeric": "591", + "name": "Panama", + "official_name": "Republic of Panama", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ฆ" + }, + { + "alpha2": "PE", + "alpha3": "PER", + "numeric": "604", + "name": "Peru", + "official_name": "Republic of Peru", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ช" + }, + { + "alpha2": "PF", + "alpha3": "PYF", + "numeric": "258", + "name": "French Polynesia", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ซ" + }, + { + "alpha2": "PG", + "alpha3": "PNG", + "numeric": "598", + "name": "Papua New Guinea", + "official_name": "Independent State of Papua New Guinea", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ฌ" + }, + { + "alpha2": "PH", + "alpha3": "PHL", + "numeric": "608", + "name": "Philippines", + "official_name": "Republic of the Philippines", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ญ" + }, + { + "alpha2": "PK", + "alpha3": "PAK", + "numeric": "586", + "name": "Pakistan", + "official_name": "Islamic Republic of Pakistan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ฐ" + }, + { + "alpha2": "PL", + "alpha3": "POL", + "numeric": "616", + "name": "Poland", + "official_name": "Republic of Poland", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ฑ" + }, + { + "alpha2": "PM", + "alpha3": "SPM", + "numeric": "666", + "name": "Saint Pierre and Miquelon", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ฒ" + }, + { + "alpha2": "PN", + "alpha3": "PCN", + "numeric": "612", + "name": "Pitcairn", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ณ" + }, + { + "alpha2": "PR", + "alpha3": "PRI", + "numeric": "630", + "name": "Puerto Rico", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ท" + }, + { + "alpha2": "PS", + "alpha3": "PSE", + "numeric": "275", + "name": "Palestine, State of", + "official_name": "the State of Palestine", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ธ" + }, + { + "alpha2": "PT", + "alpha3": "PRT", + "numeric": "620", + "name": "Portugal", + "official_name": "Portuguese Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡น" + }, + { + "alpha2": "PW", + "alpha3": "PLW", + "numeric": "585", + "name": "Palau", + "official_name": "Republic of Palau", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡ผ" + }, + { + "alpha2": "PY", + "alpha3": "PRY", + "numeric": "600", + "name": "Paraguay", + "official_name": "Republic of Paraguay", + "common_name": null, + "flag_emoji": "๐Ÿ‡ต๐Ÿ‡พ" + }, + { + "alpha2": "QA", + "alpha3": "QAT", + "numeric": "634", + "name": "Qatar", + "official_name": "State of Qatar", + "common_name": null, + "flag_emoji": "๐Ÿ‡ถ๐Ÿ‡ฆ" + }, + { + "alpha2": "RE", + "alpha3": "REU", + "numeric": "638", + "name": "Rรฉunion", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ท๐Ÿ‡ช" + }, + { + "alpha2": "RO", + "alpha3": "ROU", + "numeric": "642", + "name": "Romania", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ท๐Ÿ‡ด" + }, + { + "alpha2": "RS", + "alpha3": "SRB", + "numeric": "688", + "name": "Serbia", + "official_name": "Republic of Serbia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ท๐Ÿ‡ธ" + }, + { + "alpha2": "RU", + "alpha3": "RUS", + "numeric": "643", + "name": "Russian Federation", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ท๐Ÿ‡บ" + }, + { + "alpha2": "RW", + "alpha3": "RWA", + "numeric": "646", + "name": "Rwanda", + "official_name": "Rwandese Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ท๐Ÿ‡ผ" + }, + { + "alpha2": "SA", + "alpha3": "SAU", + "numeric": "682", + "name": "Saudi Arabia", + "official_name": "Kingdom of Saudi Arabia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฆ" + }, + { + "alpha2": "SB", + "alpha3": "SLB", + "numeric": "090", + "name": "Solomon Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ง" + }, + { + "alpha2": "SC", + "alpha3": "SYC", + "numeric": "690", + "name": "Seychelles", + "official_name": "Republic of Seychelles", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡จ" + }, + { + "alpha2": "SD", + "alpha3": "SDN", + "numeric": "729", + "name": "Sudan", + "official_name": "Republic of the Sudan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฉ" + }, + { + "alpha2": "SE", + "alpha3": "SWE", + "numeric": "752", + "name": "Sweden", + "official_name": "Kingdom of Sweden", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ช" + }, + { + "alpha2": "SG", + "alpha3": "SGP", + "numeric": "702", + "name": "Singapore", + "official_name": "Republic of Singapore", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฌ" + }, + { + "alpha2": "SH", + "alpha3": "SHN", + "numeric": "654", + "name": "Saint Helena, Ascension and Tristan da Cunha", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ญ" + }, + { + "alpha2": "SI", + "alpha3": "SVN", + "numeric": "705", + "name": "Slovenia", + "official_name": "Republic of Slovenia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฎ" + }, + { + "alpha2": "SJ", + "alpha3": "SJM", + "numeric": "744", + "name": "Svalbard and Jan Mayen", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฏ" + }, + { + "alpha2": "SK", + "alpha3": "SVK", + "numeric": "703", + "name": "Slovakia", + "official_name": "Slovak Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฐ" + }, + { + "alpha2": "SL", + "alpha3": "SLE", + "numeric": "694", + "name": "Sierra Leone", + "official_name": "Republic of Sierra Leone", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฑ" + }, + { + "alpha2": "SM", + "alpha3": "SMR", + "numeric": "674", + "name": "San Marino", + "official_name": "Republic of San Marino", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฒ" + }, + { + "alpha2": "SN", + "alpha3": "SEN", + "numeric": "686", + "name": "Senegal", + "official_name": "Republic of Senegal", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ณ" + }, + { + "alpha2": "SO", + "alpha3": "SOM", + "numeric": "706", + "name": "Somalia", + "official_name": "Federal Republic of Somalia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ด" + }, + { + "alpha2": "SR", + "alpha3": "SUR", + "numeric": "740", + "name": "Suriname", + "official_name": "Republic of Suriname", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ท" + }, + { + "alpha2": "SS", + "alpha3": "SSD", + "numeric": "728", + "name": "South Sudan", + "official_name": "Republic of South Sudan", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ธ" + }, + { + "alpha2": "ST", + "alpha3": "STP", + "numeric": "678", + "name": "Sao Tome and Principe", + "official_name": "Democratic Republic of Sao Tome and Principe", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡น" + }, + { + "alpha2": "SV", + "alpha3": "SLV", + "numeric": "222", + "name": "El Salvador", + "official_name": "Republic of El Salvador", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ป" + }, + { + "alpha2": "SX", + "alpha3": "SXM", + "numeric": "534", + "name": "Sint Maarten (Dutch part)", + "official_name": "Sint Maarten (Dutch part)", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฝ" + }, + { + "alpha2": "SY", + "alpha3": "SYR", + "numeric": "760", + "name": "Syrian Arab Republic", + "official_name": null, + "common_name": "Syria", + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡พ" + }, + { + "alpha2": "SZ", + "alpha3": "SWZ", + "numeric": "748", + "name": "Eswatini", + "official_name": "Kingdom of Eswatini", + "common_name": null, + "flag_emoji": "๐Ÿ‡ธ๐Ÿ‡ฟ" + }, + { + "alpha2": "TC", + "alpha3": "TCA", + "numeric": "796", + "name": "Turks and Caicos Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡จ" + }, + { + "alpha2": "TD", + "alpha3": "TCD", + "numeric": "148", + "name": "Chad", + "official_name": "Republic of Chad", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฉ" + }, + { + "alpha2": "TF", + "alpha3": "ATF", + "numeric": "260", + "name": "French Southern Territories", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ซ" + }, + { + "alpha2": "TG", + "alpha3": "TGO", + "numeric": "768", + "name": "Togo", + "official_name": "Togolese Republic", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฌ" + }, + { + "alpha2": "TH", + "alpha3": "THA", + "numeric": "764", + "name": "Thailand", + "official_name": "Kingdom of Thailand", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ญ" + }, + { + "alpha2": "TJ", + "alpha3": "TJK", + "numeric": "762", + "name": "Tajikistan", + "official_name": "Republic of Tajikistan", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฏ" + }, + { + "alpha2": "TK", + "alpha3": "TKL", + "numeric": "772", + "name": "Tokelau", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฐ" + }, + { + "alpha2": "TL", + "alpha3": "TLS", + "numeric": "626", + "name": "Timor-Leste", + "official_name": "Democratic Republic of Timor-Leste", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฑ" + }, + { + "alpha2": "TM", + "alpha3": "TKM", + "numeric": "795", + "name": "Turkmenistan", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฒ" + }, + { + "alpha2": "TN", + "alpha3": "TUN", + "numeric": "788", + "name": "Tunisia", + "official_name": "Republic of Tunisia", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ณ" + }, + { + "alpha2": "TO", + "alpha3": "TON", + "numeric": "776", + "name": "Tonga", + "official_name": "Kingdom of Tonga", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ด" + }, + { + "alpha2": "TR", + "alpha3": "TUR", + "numeric": "792", + "name": "Tรผrkiye", + "official_name": "Republic of Tรผrkiye", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ท" + }, + { + "alpha2": "TT", + "alpha3": "TTO", + "numeric": "780", + "name": "Trinidad and Tobago", + "official_name": "Republic of Trinidad and Tobago", + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡น" + }, + { + "alpha2": "TV", + "alpha3": "TUV", + "numeric": "798", + "name": "Tuvalu", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ป" + }, + { + "alpha2": "TW", + "alpha3": "TWN", + "numeric": "158", + "name": "Taiwan, Province of China", + "official_name": "Taiwan, Province of China", + "common_name": "Taiwan", + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ผ" + }, + { + "alpha2": "TZ", + "alpha3": "TZA", + "numeric": "834", + "name": "Tanzania, United Republic of", + "official_name": "United Republic of Tanzania", + "common_name": "Tanzania", + "flag_emoji": "๐Ÿ‡น๐Ÿ‡ฟ" + }, + { + "alpha2": "UA", + "alpha3": "UKR", + "numeric": "804", + "name": "Ukraine", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡บ๐Ÿ‡ฆ" + }, + { + "alpha2": "UG", + "alpha3": "UGA", + "numeric": "800", + "name": "Uganda", + "official_name": "Republic of Uganda", + "common_name": null, + "flag_emoji": "๐Ÿ‡บ๐Ÿ‡ฌ" + }, + { + "alpha2": "UM", + "alpha3": "UMI", + "numeric": "581", + "name": "United States Minor Outlying Islands", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡บ๐Ÿ‡ฒ" + }, + { + "alpha2": "US", + "alpha3": "USA", + "numeric": "840", + "name": "United States", + "official_name": "United States of America", + "common_name": null, + "flag_emoji": "๐Ÿ‡บ๐Ÿ‡ธ" + }, + { + "alpha2": "UY", + "alpha3": "URY", + "numeric": "858", + "name": "Uruguay", + "official_name": "Eastern Republic of Uruguay", + "common_name": null, + "flag_emoji": "๐Ÿ‡บ๐Ÿ‡พ" + }, + { + "alpha2": "UZ", + "alpha3": "UZB", + "numeric": "860", + "name": "Uzbekistan", + "official_name": "Republic of Uzbekistan", + "common_name": null, + "flag_emoji": "๐Ÿ‡บ๐Ÿ‡ฟ" + }, + { + "alpha2": "VA", + "alpha3": "VAT", + "numeric": "336", + "name": "Holy See (Vatican City State)", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡ฆ" + }, + { + "alpha2": "VC", + "alpha3": "VCT", + "numeric": "670", + "name": "Saint Vincent and the Grenadines", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡จ" + }, + { + "alpha2": "VE", + "alpha3": "VEN", + "numeric": "862", + "name": "Venezuela, Bolivarian Republic of", + "official_name": "Bolivarian Republic of Venezuela", + "common_name": "Venezuela", + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡ช" + }, + { + "alpha2": "VG", + "alpha3": "VGB", + "numeric": "092", + "name": "Virgin Islands, British", + "official_name": "British Virgin Islands", + "common_name": null, + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡ฌ" + }, + { + "alpha2": "VI", + "alpha3": "VIR", + "numeric": "850", + "name": "Virgin Islands, U.S.", + "official_name": "Virgin Islands of the United States", + "common_name": null, + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡ฎ" + }, + { + "alpha2": "VN", + "alpha3": "VNM", + "numeric": "704", + "name": "Viet Nam", + "official_name": "Socialist Republic of Viet Nam", + "common_name": "Vietnam", + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡ณ" + }, + { + "alpha2": "VU", + "alpha3": "VUT", + "numeric": "548", + "name": "Vanuatu", + "official_name": "Republic of Vanuatu", + "common_name": null, + "flag_emoji": "๐Ÿ‡ป๐Ÿ‡บ" + }, + { + "alpha2": "WF", + "alpha3": "WLF", + "numeric": "876", + "name": "Wallis and Futuna", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡ผ๐Ÿ‡ซ" + }, + { + "alpha2": "WS", + "alpha3": "WSM", + "numeric": "882", + "name": "Samoa", + "official_name": "Independent State of Samoa", + "common_name": null, + "flag_emoji": "๐Ÿ‡ผ๐Ÿ‡ธ" + }, + { + "alpha2": "YE", + "alpha3": "YEM", + "numeric": "887", + "name": "Yemen", + "official_name": "Republic of Yemen", + "common_name": null, + "flag_emoji": "๐Ÿ‡พ๐Ÿ‡ช" + }, + { + "alpha2": "YT", + "alpha3": "MYT", + "numeric": "175", + "name": "Mayotte", + "official_name": null, + "common_name": null, + "flag_emoji": "๐Ÿ‡พ๐Ÿ‡น" + }, + { + "alpha2": "ZA", + "alpha3": "ZAF", + "numeric": "710", + "name": "South Africa", + "official_name": "Republic of South Africa", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฟ๐Ÿ‡ฆ" + }, + { + "alpha2": "ZM", + "alpha3": "ZMB", + "numeric": "894", + "name": "Zambia", + "official_name": "Republic of Zambia", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฟ๐Ÿ‡ฒ" + }, + { + "alpha2": "ZW", + "alpha3": "ZWE", + "numeric": "716", + "name": "Zimbabwe", + "official_name": "Republic of Zimbabwe", + "common_name": null, + "flag_emoji": "๐Ÿ‡ฟ๐Ÿ‡ผ" + } +] diff --git a/Modules/Countries/Database/Migrations/.gitkeep b/Modules/Countries/Database/Migrations/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Migrations/2026_06_15_000000_create_countries_table.php b/Modules/Countries/Database/Migrations/2026_06_15_000000_create_countries_table.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Migrations/2026_06_15_010000_add_iso_3166_support_to_countries_module.php b/Modules/Countries/Database/Migrations/2026_06_15_010000_add_iso_3166_support_to_countries_module.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Migrations/2026_06_15_030000_add_enterprise_iso_country_fields.php b/Modules/Countries/Database/Migrations/2026_06_15_030000_add_enterprise_iso_country_fields.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Seeders/.gitkeep b/Modules/Countries/Database/Seeders/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Seeders/CountriesDatabaseSeeder.php b/Modules/Countries/Database/Seeders/CountriesDatabaseSeeder.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/Seeders/IsoCountriesSeeder.php b/Modules/Countries/Database/Seeders/IsoCountriesSeeder.php old mode 100644 new mode 100755 index bd14ac1e..cbc34940 --- a/Modules/Countries/Database/Seeders/IsoCountriesSeeder.php +++ b/Modules/Countries/Database/Seeders/IsoCountriesSeeder.php @@ -11,257 +11,12 @@ class IsoCountriesSeeder extends Seeder public function run(): void { $now = Carbon::now(); - $countries = [ - ['alpha2' => 'AD', 'alpha3' => 'AND', 'numeric' => '020', 'name' => 'Andorra', 'official_name' => 'Principality of Andorra', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฉ'], - ['alpha2' => 'AE', 'alpha3' => 'ARE', 'numeric' => '784', 'name' => 'United Arab Emirates', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ช'], - ['alpha2' => 'AF', 'alpha3' => 'AFG', 'numeric' => '004', 'name' => 'Afghanistan', 'official_name' => 'Islamic Republic of Afghanistan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ซ'], - ['alpha2' => 'AG', 'alpha3' => 'ATG', 'numeric' => '028', 'name' => 'Antigua and Barbuda', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฌ'], - ['alpha2' => 'AI', 'alpha3' => 'AIA', 'numeric' => '660', 'name' => 'Anguilla', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฎ'], - ['alpha2' => 'AL', 'alpha3' => 'ALB', 'numeric' => '008', 'name' => 'Albania', 'official_name' => 'Republic of Albania', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฑ'], - ['alpha2' => 'AM', 'alpha3' => 'ARM', 'numeric' => '051', 'name' => 'Armenia', 'official_name' => 'Republic of Armenia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฒ'], - ['alpha2' => 'AO', 'alpha3' => 'AGO', 'numeric' => '024', 'name' => 'Angola', 'official_name' => 'Republic of Angola', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ด'], - ['alpha2' => 'AQ', 'alpha3' => 'ATA', 'numeric' => '010', 'name' => 'Antarctica', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ถ'], - ['alpha2' => 'AR', 'alpha3' => 'ARG', 'numeric' => '032', 'name' => 'Argentina', 'official_name' => 'Argentine Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ท'], - ['alpha2' => 'AS', 'alpha3' => 'ASM', 'numeric' => '016', 'name' => 'American Samoa', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ธ'], - ['alpha2' => 'AT', 'alpha3' => 'AUT', 'numeric' => '040', 'name' => 'Austria', 'official_name' => 'Republic of Austria', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡น'], - ['alpha2' => 'AU', 'alpha3' => 'AUS', 'numeric' => '036', 'name' => 'Australia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡บ'], - ['alpha2' => 'AW', 'alpha3' => 'ABW', 'numeric' => '533', 'name' => 'Aruba', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ผ'], - ['alpha2' => 'AX', 'alpha3' => 'ALA', 'numeric' => '248', 'name' => 'ร…land Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฝ'], - ['alpha2' => 'AZ', 'alpha3' => 'AZE', 'numeric' => '031', 'name' => 'Azerbaijan', 'official_name' => 'Republic of Azerbaijan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฆ๐Ÿ‡ฟ'], - ['alpha2' => 'BA', 'alpha3' => 'BIH', 'numeric' => '070', 'name' => 'Bosnia and Herzegovina', 'official_name' => 'Republic of Bosnia and Herzegovina', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฆ'], - ['alpha2' => 'BB', 'alpha3' => 'BRB', 'numeric' => '052', 'name' => 'Barbados', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ง'], - ['alpha2' => 'BD', 'alpha3' => 'BGD', 'numeric' => '050', 'name' => 'Bangladesh', 'official_name' => 'People\'s Republic of Bangladesh', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฉ'], - ['alpha2' => 'BE', 'alpha3' => 'BEL', 'numeric' => '056', 'name' => 'Belgium', 'official_name' => 'Kingdom of Belgium', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ช'], - ['alpha2' => 'BF', 'alpha3' => 'BFA', 'numeric' => '854', 'name' => 'Burkina Faso', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ซ'], - ['alpha2' => 'BG', 'alpha3' => 'BGR', 'numeric' => '100', 'name' => 'Bulgaria', 'official_name' => 'Republic of Bulgaria', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฌ'], - ['alpha2' => 'BH', 'alpha3' => 'BHR', 'numeric' => '048', 'name' => 'Bahrain', 'official_name' => 'Kingdom of Bahrain', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ญ'], - ['alpha2' => 'BI', 'alpha3' => 'BDI', 'numeric' => '108', 'name' => 'Burundi', 'official_name' => 'Republic of Burundi', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฎ'], - ['alpha2' => 'BJ', 'alpha3' => 'BEN', 'numeric' => '204', 'name' => 'Benin', 'official_name' => 'Republic of Benin', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฏ'], - ['alpha2' => 'BL', 'alpha3' => 'BLM', 'numeric' => '652', 'name' => 'Saint Barthรฉlemy', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฑ'], - ['alpha2' => 'BM', 'alpha3' => 'BMU', 'numeric' => '060', 'name' => 'Bermuda', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฒ'], - ['alpha2' => 'BN', 'alpha3' => 'BRN', 'numeric' => '096', 'name' => 'Brunei Darussalam', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ณ'], - ['alpha2' => 'BO', 'alpha3' => 'BOL', 'numeric' => '068', 'name' => 'Bolivia, Plurinational State of', 'official_name' => 'Plurinational State of Bolivia', 'common_name' => 'Bolivia', 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ด'], - ['alpha2' => 'BQ', 'alpha3' => 'BES', 'numeric' => '535', 'name' => 'Bonaire, Sint Eustatius and Saba', 'official_name' => 'Bonaire, Sint Eustatius and Saba', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ถ'], - ['alpha2' => 'BR', 'alpha3' => 'BRA', 'numeric' => '076', 'name' => 'Brazil', 'official_name' => 'Federative Republic of Brazil', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ท'], - ['alpha2' => 'BS', 'alpha3' => 'BHS', 'numeric' => '044', 'name' => 'Bahamas', 'official_name' => 'Commonwealth of the Bahamas', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ธ'], - ['alpha2' => 'BT', 'alpha3' => 'BTN', 'numeric' => '064', 'name' => 'Bhutan', 'official_name' => 'Kingdom of Bhutan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡น'], - ['alpha2' => 'BV', 'alpha3' => 'BVT', 'numeric' => '074', 'name' => 'Bouvet Island', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ป'], - ['alpha2' => 'BW', 'alpha3' => 'BWA', 'numeric' => '072', 'name' => 'Botswana', 'official_name' => 'Republic of Botswana', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ผ'], - ['alpha2' => 'BY', 'alpha3' => 'BLR', 'numeric' => '112', 'name' => 'Belarus', 'official_name' => 'Republic of Belarus', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡พ'], - ['alpha2' => 'BZ', 'alpha3' => 'BLZ', 'numeric' => '084', 'name' => 'Belize', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ง๐Ÿ‡ฟ'], - ['alpha2' => 'CA', 'alpha3' => 'CAN', 'numeric' => '124', 'name' => 'Canada', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฆ'], - ['alpha2' => 'CC', 'alpha3' => 'CCK', 'numeric' => '166', 'name' => 'Cocos (Keeling) Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡จ'], - ['alpha2' => 'CD', 'alpha3' => 'COD', 'numeric' => '180', 'name' => 'Congo, The Democratic Republic of the', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฉ'], - ['alpha2' => 'CF', 'alpha3' => 'CAF', 'numeric' => '140', 'name' => 'Central African Republic', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ซ'], - ['alpha2' => 'CG', 'alpha3' => 'COG', 'numeric' => '178', 'name' => 'Congo', 'official_name' => 'Republic of the Congo', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฌ'], - ['alpha2' => 'CH', 'alpha3' => 'CHE', 'numeric' => '756', 'name' => 'Switzerland', 'official_name' => 'Swiss Confederation', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ญ'], - ['alpha2' => 'CI', 'alpha3' => 'CIV', 'numeric' => '384', 'name' => 'Cรดte d\'Ivoire', 'official_name' => 'Republic of Cรดte d\'Ivoire', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฎ'], - ['alpha2' => 'CK', 'alpha3' => 'COK', 'numeric' => '184', 'name' => 'Cook Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฐ'], - ['alpha2' => 'CL', 'alpha3' => 'CHL', 'numeric' => '152', 'name' => 'Chile', 'official_name' => 'Republic of Chile', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฑ'], - ['alpha2' => 'CM', 'alpha3' => 'CMR', 'numeric' => '120', 'name' => 'Cameroon', 'official_name' => 'Republic of Cameroon', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฒ'], - ['alpha2' => 'CN', 'alpha3' => 'CHN', 'numeric' => '156', 'name' => 'China', 'official_name' => 'People\'s Republic of China', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ณ'], - ['alpha2' => 'CO', 'alpha3' => 'COL', 'numeric' => '170', 'name' => 'Colombia', 'official_name' => 'Republic of Colombia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ด'], - ['alpha2' => 'CR', 'alpha3' => 'CRI', 'numeric' => '188', 'name' => 'Costa Rica', 'official_name' => 'Republic of Costa Rica', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ท'], - ['alpha2' => 'CU', 'alpha3' => 'CUB', 'numeric' => '192', 'name' => 'Cuba', 'official_name' => 'Republic of Cuba', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡บ'], - ['alpha2' => 'CV', 'alpha3' => 'CPV', 'numeric' => '132', 'name' => 'Cabo Verde', 'official_name' => 'Republic of Cabo Verde', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ป'], - ['alpha2' => 'CW', 'alpha3' => 'CUW', 'numeric' => '531', 'name' => 'Curaรงao', 'official_name' => 'Curaรงao', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ผ'], - ['alpha2' => 'CX', 'alpha3' => 'CXR', 'numeric' => '162', 'name' => 'Christmas Island', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฝ'], - ['alpha2' => 'CY', 'alpha3' => 'CYP', 'numeric' => '196', 'name' => 'Cyprus', 'official_name' => 'Republic of Cyprus', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡พ'], - ['alpha2' => 'CZ', 'alpha3' => 'CZE', 'numeric' => '203', 'name' => 'Czechia', 'official_name' => 'Czech Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡จ๐Ÿ‡ฟ'], - ['alpha2' => 'DE', 'alpha3' => 'DEU', 'numeric' => '276', 'name' => 'Germany', 'official_name' => 'Federal Republic of Germany', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฉ๐Ÿ‡ช'], - ['alpha2' => 'DJ', 'alpha3' => 'DJI', 'numeric' => '262', 'name' => 'Djibouti', 'official_name' => 'Republic of Djibouti', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฉ๐Ÿ‡ฏ'], - ['alpha2' => 'DK', 'alpha3' => 'DNK', 'numeric' => '208', 'name' => 'Denmark', 'official_name' => 'Kingdom of Denmark', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฉ๐Ÿ‡ฐ'], - ['alpha2' => 'DM', 'alpha3' => 'DMA', 'numeric' => '212', 'name' => 'Dominica', 'official_name' => 'Commonwealth of Dominica', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฉ๐Ÿ‡ฒ'], - ['alpha2' => 'DO', 'alpha3' => 'DOM', 'numeric' => '214', 'name' => 'Dominican Republic', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฉ๐Ÿ‡ด'], - ['alpha2' => 'DZ', 'alpha3' => 'DZA', 'numeric' => '012', 'name' => 'Algeria', 'official_name' => 'People\'s Democratic Republic of Algeria', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฉ๐Ÿ‡ฟ'], - ['alpha2' => 'EC', 'alpha3' => 'ECU', 'numeric' => '218', 'name' => 'Ecuador', 'official_name' => 'Republic of Ecuador', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡จ'], - ['alpha2' => 'EE', 'alpha3' => 'EST', 'numeric' => '233', 'name' => 'Estonia', 'official_name' => 'Republic of Estonia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡ช'], - ['alpha2' => 'EG', 'alpha3' => 'EGY', 'numeric' => '818', 'name' => 'Egypt', 'official_name' => 'Arab Republic of Egypt', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡ฌ'], - ['alpha2' => 'EH', 'alpha3' => 'ESH', 'numeric' => '732', 'name' => 'Western Sahara', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡ญ'], - ['alpha2' => 'ER', 'alpha3' => 'ERI', 'numeric' => '232', 'name' => 'Eritrea', 'official_name' => 'the State of Eritrea', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡ท'], - ['alpha2' => 'ES', 'alpha3' => 'ESP', 'numeric' => '724', 'name' => 'Spain', 'official_name' => 'Kingdom of Spain', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡ธ'], - ['alpha2' => 'ET', 'alpha3' => 'ETH', 'numeric' => '231', 'name' => 'Ethiopia', 'official_name' => 'Federal Democratic Republic of Ethiopia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ช๐Ÿ‡น'], - ['alpha2' => 'FI', 'alpha3' => 'FIN', 'numeric' => '246', 'name' => 'Finland', 'official_name' => 'Republic of Finland', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ซ๐Ÿ‡ฎ'], - ['alpha2' => 'FJ', 'alpha3' => 'FJI', 'numeric' => '242', 'name' => 'Fiji', 'official_name' => 'Republic of Fiji', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ซ๐Ÿ‡ฏ'], - ['alpha2' => 'FK', 'alpha3' => 'FLK', 'numeric' => '238', 'name' => 'Falkland Islands (Malvinas)', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ซ๐Ÿ‡ฐ'], - ['alpha2' => 'FM', 'alpha3' => 'FSM', 'numeric' => '583', 'name' => 'Micronesia, Federated States of', 'official_name' => 'Federated States of Micronesia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ซ๐Ÿ‡ฒ'], - ['alpha2' => 'FO', 'alpha3' => 'FRO', 'numeric' => '234', 'name' => 'Faroe Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ซ๐Ÿ‡ด'], - ['alpha2' => 'FR', 'alpha3' => 'FRA', 'numeric' => '250', 'name' => 'France', 'official_name' => 'French Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ซ๐Ÿ‡ท'], - ['alpha2' => 'GA', 'alpha3' => 'GAB', 'numeric' => '266', 'name' => 'Gabon', 'official_name' => 'Gabonese Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ฆ'], - ['alpha2' => 'GB', 'alpha3' => 'GBR', 'numeric' => '826', 'name' => 'United Kingdom', 'official_name' => 'United Kingdom of Great Britain and Northern Ireland', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ง'], - ['alpha2' => 'GD', 'alpha3' => 'GRD', 'numeric' => '308', 'name' => 'Grenada', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ฉ'], - ['alpha2' => 'GE', 'alpha3' => 'GEO', 'numeric' => '268', 'name' => 'Georgia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ช'], - ['alpha2' => 'GF', 'alpha3' => 'GUF', 'numeric' => '254', 'name' => 'French Guiana', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ซ'], - ['alpha2' => 'GG', 'alpha3' => 'GGY', 'numeric' => '831', 'name' => 'Guernsey', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ฌ'], - ['alpha2' => 'GH', 'alpha3' => 'GHA', 'numeric' => '288', 'name' => 'Ghana', 'official_name' => 'Republic of Ghana', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ญ'], - ['alpha2' => 'GI', 'alpha3' => 'GIB', 'numeric' => '292', 'name' => 'Gibraltar', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ฎ'], - ['alpha2' => 'GL', 'alpha3' => 'GRL', 'numeric' => '304', 'name' => 'Greenland', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ฑ'], - ['alpha2' => 'GM', 'alpha3' => 'GMB', 'numeric' => '270', 'name' => 'Gambia', 'official_name' => 'Republic of the Gambia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ฒ'], - ['alpha2' => 'GN', 'alpha3' => 'GIN', 'numeric' => '324', 'name' => 'Guinea', 'official_name' => 'Republic of Guinea', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ณ'], - ['alpha2' => 'GP', 'alpha3' => 'GLP', 'numeric' => '312', 'name' => 'Guadeloupe', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ต'], - ['alpha2' => 'GQ', 'alpha3' => 'GNQ', 'numeric' => '226', 'name' => 'Equatorial Guinea', 'official_name' => 'Republic of Equatorial Guinea', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ถ'], - ['alpha2' => 'GR', 'alpha3' => 'GRC', 'numeric' => '300', 'name' => 'Greece', 'official_name' => 'Hellenic Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ท'], - ['alpha2' => 'GS', 'alpha3' => 'SGS', 'numeric' => '239', 'name' => 'South Georgia and the South Sandwich Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ธ'], - ['alpha2' => 'GT', 'alpha3' => 'GTM', 'numeric' => '320', 'name' => 'Guatemala', 'official_name' => 'Republic of Guatemala', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡น'], - ['alpha2' => 'GU', 'alpha3' => 'GUM', 'numeric' => '316', 'name' => 'Guam', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡บ'], - ['alpha2' => 'GW', 'alpha3' => 'GNB', 'numeric' => '624', 'name' => 'Guinea-Bissau', 'official_name' => 'Republic of Guinea-Bissau', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡ผ'], - ['alpha2' => 'GY', 'alpha3' => 'GUY', 'numeric' => '328', 'name' => 'Guyana', 'official_name' => 'Republic of Guyana', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฌ๐Ÿ‡พ'], - ['alpha2' => 'HK', 'alpha3' => 'HKG', 'numeric' => '344', 'name' => 'Hong Kong', 'official_name' => 'Hong Kong Special Administrative Region of China', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ญ๐Ÿ‡ฐ'], - ['alpha2' => 'HM', 'alpha3' => 'HMD', 'numeric' => '334', 'name' => 'Heard Island and McDonald Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ญ๐Ÿ‡ฒ'], - ['alpha2' => 'HN', 'alpha3' => 'HND', 'numeric' => '340', 'name' => 'Honduras', 'official_name' => 'Republic of Honduras', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ญ๐Ÿ‡ณ'], - ['alpha2' => 'HR', 'alpha3' => 'HRV', 'numeric' => '191', 'name' => 'Croatia', 'official_name' => 'Republic of Croatia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ญ๐Ÿ‡ท'], - ['alpha2' => 'HT', 'alpha3' => 'HTI', 'numeric' => '332', 'name' => 'Haiti', 'official_name' => 'Republic of Haiti', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ญ๐Ÿ‡น'], - ['alpha2' => 'HU', 'alpha3' => 'HUN', 'numeric' => '348', 'name' => 'Hungary', 'official_name' => 'Hungary', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ญ๐Ÿ‡บ'], - ['alpha2' => 'ID', 'alpha3' => 'IDN', 'numeric' => '360', 'name' => 'Indonesia', 'official_name' => 'Republic of Indonesia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ฉ'], - ['alpha2' => 'IE', 'alpha3' => 'IRL', 'numeric' => '372', 'name' => 'Ireland', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ช'], - ['alpha2' => 'IL', 'alpha3' => 'ISR', 'numeric' => '376', 'name' => 'Israel', 'official_name' => 'State of Israel', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ฑ'], - ['alpha2' => 'IM', 'alpha3' => 'IMN', 'numeric' => '833', 'name' => 'Isle of Man', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ฒ'], - ['alpha2' => 'IN', 'alpha3' => 'IND', 'numeric' => '356', 'name' => 'India', 'official_name' => 'Republic of India', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ณ'], - ['alpha2' => 'IO', 'alpha3' => 'IOT', 'numeric' => '086', 'name' => 'British Indian Ocean Territory', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ด'], - ['alpha2' => 'IQ', 'alpha3' => 'IRQ', 'numeric' => '368', 'name' => 'Iraq', 'official_name' => 'Republic of Iraq', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ถ'], - ['alpha2' => 'IR', 'alpha3' => 'IRN', 'numeric' => '364', 'name' => 'Iran, Islamic Republic of', 'official_name' => 'Islamic Republic of Iran', 'common_name' => 'Iran', 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ท'], - ['alpha2' => 'IS', 'alpha3' => 'ISL', 'numeric' => '352', 'name' => 'Iceland', 'official_name' => 'Republic of Iceland', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡ธ'], - ['alpha2' => 'IT', 'alpha3' => 'ITA', 'numeric' => '380', 'name' => 'Italy', 'official_name' => 'Italian Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฎ๐Ÿ‡น'], - ['alpha2' => 'JE', 'alpha3' => 'JEY', 'numeric' => '832', 'name' => 'Jersey', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฏ๐Ÿ‡ช'], - ['alpha2' => 'JM', 'alpha3' => 'JAM', 'numeric' => '388', 'name' => 'Jamaica', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฏ๐Ÿ‡ฒ'], - ['alpha2' => 'JO', 'alpha3' => 'JOR', 'numeric' => '400', 'name' => 'Jordan', 'official_name' => 'Hashemite Kingdom of Jordan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฏ๐Ÿ‡ด'], - ['alpha2' => 'JP', 'alpha3' => 'JPN', 'numeric' => '392', 'name' => 'Japan', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฏ๐Ÿ‡ต'], - ['alpha2' => 'KE', 'alpha3' => 'KEN', 'numeric' => '404', 'name' => 'Kenya', 'official_name' => 'Republic of Kenya', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ช'], - ['alpha2' => 'KG', 'alpha3' => 'KGZ', 'numeric' => '417', 'name' => 'Kyrgyzstan', 'official_name' => 'Kyrgyz Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ฌ'], - ['alpha2' => 'KH', 'alpha3' => 'KHM', 'numeric' => '116', 'name' => 'Cambodia', 'official_name' => 'Kingdom of Cambodia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ญ'], - ['alpha2' => 'KI', 'alpha3' => 'KIR', 'numeric' => '296', 'name' => 'Kiribati', 'official_name' => 'Republic of Kiribati', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ฎ'], - ['alpha2' => 'KM', 'alpha3' => 'COM', 'numeric' => '174', 'name' => 'Comoros', 'official_name' => 'Union of the Comoros', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ฒ'], - ['alpha2' => 'KN', 'alpha3' => 'KNA', 'numeric' => '659', 'name' => 'Saint Kitts and Nevis', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ณ'], - ['alpha2' => 'KP', 'alpha3' => 'PRK', 'numeric' => '408', 'name' => 'Korea, Democratic People\'s Republic of', 'official_name' => 'Democratic People\'s Republic of Korea', 'common_name' => 'North Korea', 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ต'], - ['alpha2' => 'KR', 'alpha3' => 'KOR', 'numeric' => '410', 'name' => 'Korea, Republic of', 'official_name' => null, 'common_name' => 'South Korea', 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ท'], - ['alpha2' => 'KW', 'alpha3' => 'KWT', 'numeric' => '414', 'name' => 'Kuwait', 'official_name' => 'State of Kuwait', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ผ'], - ['alpha2' => 'KY', 'alpha3' => 'CYM', 'numeric' => '136', 'name' => 'Cayman Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡พ'], - ['alpha2' => 'KZ', 'alpha3' => 'KAZ', 'numeric' => '398', 'name' => 'Kazakhstan', 'official_name' => 'Republic of Kazakhstan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฐ๐Ÿ‡ฟ'], - ['alpha2' => 'LA', 'alpha3' => 'LAO', 'numeric' => '418', 'name' => 'Lao People\'s Democratic Republic', 'official_name' => null, 'common_name' => 'Laos', 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ฆ'], - ['alpha2' => 'LB', 'alpha3' => 'LBN', 'numeric' => '422', 'name' => 'Lebanon', 'official_name' => 'Lebanese Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ง'], - ['alpha2' => 'LC', 'alpha3' => 'LCA', 'numeric' => '662', 'name' => 'Saint Lucia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡จ'], - ['alpha2' => 'LI', 'alpha3' => 'LIE', 'numeric' => '438', 'name' => 'Liechtenstein', 'official_name' => 'Principality of Liechtenstein', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ฎ'], - ['alpha2' => 'LK', 'alpha3' => 'LKA', 'numeric' => '144', 'name' => 'Sri Lanka', 'official_name' => 'Democratic Socialist Republic of Sri Lanka', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ฐ'], - ['alpha2' => 'LR', 'alpha3' => 'LBR', 'numeric' => '430', 'name' => 'Liberia', 'official_name' => 'Republic of Liberia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ท'], - ['alpha2' => 'LS', 'alpha3' => 'LSO', 'numeric' => '426', 'name' => 'Lesotho', 'official_name' => 'Kingdom of Lesotho', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ธ'], - ['alpha2' => 'LT', 'alpha3' => 'LTU', 'numeric' => '440', 'name' => 'Lithuania', 'official_name' => 'Republic of Lithuania', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡น'], - ['alpha2' => 'LU', 'alpha3' => 'LUX', 'numeric' => '442', 'name' => 'Luxembourg', 'official_name' => 'Grand Duchy of Luxembourg', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡บ'], - ['alpha2' => 'LV', 'alpha3' => 'LVA', 'numeric' => '428', 'name' => 'Latvia', 'official_name' => 'Republic of Latvia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡ป'], - ['alpha2' => 'LY', 'alpha3' => 'LBY', 'numeric' => '434', 'name' => 'Libya', 'official_name' => 'Libya', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฑ๐Ÿ‡พ'], - ['alpha2' => 'MA', 'alpha3' => 'MAR', 'numeric' => '504', 'name' => 'Morocco', 'official_name' => 'Kingdom of Morocco', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฆ'], - ['alpha2' => 'MC', 'alpha3' => 'MCO', 'numeric' => '492', 'name' => 'Monaco', 'official_name' => 'Principality of Monaco', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡จ'], - ['alpha2' => 'MD', 'alpha3' => 'MDA', 'numeric' => '498', 'name' => 'Moldova, Republic of', 'official_name' => 'Republic of Moldova', 'common_name' => 'Moldova', 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฉ'], - ['alpha2' => 'ME', 'alpha3' => 'MNE', 'numeric' => '499', 'name' => 'Montenegro', 'official_name' => 'Montenegro', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ช'], - ['alpha2' => 'MF', 'alpha3' => 'MAF', 'numeric' => '663', 'name' => 'Saint Martin (French part)', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ซ'], - ['alpha2' => 'MG', 'alpha3' => 'MDG', 'numeric' => '450', 'name' => 'Madagascar', 'official_name' => 'Republic of Madagascar', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฌ'], - ['alpha2' => 'MH', 'alpha3' => 'MHL', 'numeric' => '584', 'name' => 'Marshall Islands', 'official_name' => 'Republic of the Marshall Islands', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ญ'], - ['alpha2' => 'MK', 'alpha3' => 'MKD', 'numeric' => '807', 'name' => 'North Macedonia', 'official_name' => 'Republic of North Macedonia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฐ'], - ['alpha2' => 'ML', 'alpha3' => 'MLI', 'numeric' => '466', 'name' => 'Mali', 'official_name' => 'Republic of Mali', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฑ'], - ['alpha2' => 'MM', 'alpha3' => 'MMR', 'numeric' => '104', 'name' => 'Myanmar', 'official_name' => 'Republic of Myanmar', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฒ'], - ['alpha2' => 'MN', 'alpha3' => 'MNG', 'numeric' => '496', 'name' => 'Mongolia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ณ'], - ['alpha2' => 'MO', 'alpha3' => 'MAC', 'numeric' => '446', 'name' => 'Macao', 'official_name' => 'Macao Special Administrative Region of China', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ด'], - ['alpha2' => 'MP', 'alpha3' => 'MNP', 'numeric' => '580', 'name' => 'Northern Mariana Islands', 'official_name' => 'Commonwealth of the Northern Mariana Islands', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ต'], - ['alpha2' => 'MQ', 'alpha3' => 'MTQ', 'numeric' => '474', 'name' => 'Martinique', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ถ'], - ['alpha2' => 'MR', 'alpha3' => 'MRT', 'numeric' => '478', 'name' => 'Mauritania', 'official_name' => 'Islamic Republic of Mauritania', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ท'], - ['alpha2' => 'MS', 'alpha3' => 'MSR', 'numeric' => '500', 'name' => 'Montserrat', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ธ'], - ['alpha2' => 'MT', 'alpha3' => 'MLT', 'numeric' => '470', 'name' => 'Malta', 'official_name' => 'Republic of Malta', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡น'], - ['alpha2' => 'MU', 'alpha3' => 'MUS', 'numeric' => '480', 'name' => 'Mauritius', 'official_name' => 'Republic of Mauritius', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡บ'], - ['alpha2' => 'MV', 'alpha3' => 'MDV', 'numeric' => '462', 'name' => 'Maldives', 'official_name' => 'Republic of Maldives', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ป'], - ['alpha2' => 'MW', 'alpha3' => 'MWI', 'numeric' => '454', 'name' => 'Malawi', 'official_name' => 'Republic of Malawi', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ผ'], - ['alpha2' => 'MX', 'alpha3' => 'MEX', 'numeric' => '484', 'name' => 'Mexico', 'official_name' => 'United Mexican States', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฝ'], - ['alpha2' => 'MY', 'alpha3' => 'MYS', 'numeric' => '458', 'name' => 'Malaysia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡พ'], - ['alpha2' => 'MZ', 'alpha3' => 'MOZ', 'numeric' => '508', 'name' => 'Mozambique', 'official_name' => 'Republic of Mozambique', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฒ๐Ÿ‡ฟ'], - ['alpha2' => 'NA', 'alpha3' => 'NAM', 'numeric' => '516', 'name' => 'Namibia', 'official_name' => 'Republic of Namibia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ฆ'], - ['alpha2' => 'NC', 'alpha3' => 'NCL', 'numeric' => '540', 'name' => 'New Caledonia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡จ'], - ['alpha2' => 'NE', 'alpha3' => 'NER', 'numeric' => '562', 'name' => 'Niger', 'official_name' => 'Republic of the Niger', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ช'], - ['alpha2' => 'NF', 'alpha3' => 'NFK', 'numeric' => '574', 'name' => 'Norfolk Island', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ซ'], - ['alpha2' => 'NG', 'alpha3' => 'NGA', 'numeric' => '566', 'name' => 'Nigeria', 'official_name' => 'Federal Republic of Nigeria', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ฌ'], - ['alpha2' => 'NI', 'alpha3' => 'NIC', 'numeric' => '558', 'name' => 'Nicaragua', 'official_name' => 'Republic of Nicaragua', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ฎ'], - ['alpha2' => 'NL', 'alpha3' => 'NLD', 'numeric' => '528', 'name' => 'Netherlands', 'official_name' => 'Kingdom of the Netherlands', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ฑ'], - ['alpha2' => 'NO', 'alpha3' => 'NOR', 'numeric' => '578', 'name' => 'Norway', 'official_name' => 'Kingdom of Norway', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ด'], - ['alpha2' => 'NP', 'alpha3' => 'NPL', 'numeric' => '524', 'name' => 'Nepal', 'official_name' => 'Federal Democratic Republic of Nepal', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ต'], - ['alpha2' => 'NR', 'alpha3' => 'NRU', 'numeric' => '520', 'name' => 'Nauru', 'official_name' => 'Republic of Nauru', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ท'], - ['alpha2' => 'NU', 'alpha3' => 'NIU', 'numeric' => '570', 'name' => 'Niue', 'official_name' => 'Niue', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡บ'], - ['alpha2' => 'NZ', 'alpha3' => 'NZL', 'numeric' => '554', 'name' => 'New Zealand', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ณ๐Ÿ‡ฟ'], - ['alpha2' => 'OM', 'alpha3' => 'OMN', 'numeric' => '512', 'name' => 'Oman', 'official_name' => 'Sultanate of Oman', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ด๐Ÿ‡ฒ'], - ['alpha2' => 'PA', 'alpha3' => 'PAN', 'numeric' => '591', 'name' => 'Panama', 'official_name' => 'Republic of Panama', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ฆ'], - ['alpha2' => 'PE', 'alpha3' => 'PER', 'numeric' => '604', 'name' => 'Peru', 'official_name' => 'Republic of Peru', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ช'], - ['alpha2' => 'PF', 'alpha3' => 'PYF', 'numeric' => '258', 'name' => 'French Polynesia', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ซ'], - ['alpha2' => 'PG', 'alpha3' => 'PNG', 'numeric' => '598', 'name' => 'Papua New Guinea', 'official_name' => 'Independent State of Papua New Guinea', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ฌ'], - ['alpha2' => 'PH', 'alpha3' => 'PHL', 'numeric' => '608', 'name' => 'Philippines', 'official_name' => 'Republic of the Philippines', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ญ'], - ['alpha2' => 'PK', 'alpha3' => 'PAK', 'numeric' => '586', 'name' => 'Pakistan', 'official_name' => 'Islamic Republic of Pakistan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ฐ'], - ['alpha2' => 'PL', 'alpha3' => 'POL', 'numeric' => '616', 'name' => 'Poland', 'official_name' => 'Republic of Poland', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ฑ'], - ['alpha2' => 'PM', 'alpha3' => 'SPM', 'numeric' => '666', 'name' => 'Saint Pierre and Miquelon', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ฒ'], - ['alpha2' => 'PN', 'alpha3' => 'PCN', 'numeric' => '612', 'name' => 'Pitcairn', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ณ'], - ['alpha2' => 'PR', 'alpha3' => 'PRI', 'numeric' => '630', 'name' => 'Puerto Rico', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ท'], - ['alpha2' => 'PS', 'alpha3' => 'PSE', 'numeric' => '275', 'name' => 'Palestine, State of', 'official_name' => 'the State of Palestine', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ธ'], - ['alpha2' => 'PT', 'alpha3' => 'PRT', 'numeric' => '620', 'name' => 'Portugal', 'official_name' => 'Portuguese Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡น'], - ['alpha2' => 'PW', 'alpha3' => 'PLW', 'numeric' => '585', 'name' => 'Palau', 'official_name' => 'Republic of Palau', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡ผ'], - ['alpha2' => 'PY', 'alpha3' => 'PRY', 'numeric' => '600', 'name' => 'Paraguay', 'official_name' => 'Republic of Paraguay', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ต๐Ÿ‡พ'], - ['alpha2' => 'QA', 'alpha3' => 'QAT', 'numeric' => '634', 'name' => 'Qatar', 'official_name' => 'State of Qatar', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ถ๐Ÿ‡ฆ'], - ['alpha2' => 'RE', 'alpha3' => 'REU', 'numeric' => '638', 'name' => 'Rรฉunion', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ท๐Ÿ‡ช'], - ['alpha2' => 'RO', 'alpha3' => 'ROU', 'numeric' => '642', 'name' => 'Romania', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ท๐Ÿ‡ด'], - ['alpha2' => 'RS', 'alpha3' => 'SRB', 'numeric' => '688', 'name' => 'Serbia', 'official_name' => 'Republic of Serbia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ท๐Ÿ‡ธ'], - ['alpha2' => 'RU', 'alpha3' => 'RUS', 'numeric' => '643', 'name' => 'Russian Federation', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ท๐Ÿ‡บ'], - ['alpha2' => 'RW', 'alpha3' => 'RWA', 'numeric' => '646', 'name' => 'Rwanda', 'official_name' => 'Rwandese Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ท๐Ÿ‡ผ'], - ['alpha2' => 'SA', 'alpha3' => 'SAU', 'numeric' => '682', 'name' => 'Saudi Arabia', 'official_name' => 'Kingdom of Saudi Arabia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฆ'], - ['alpha2' => 'SB', 'alpha3' => 'SLB', 'numeric' => '090', 'name' => 'Solomon Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ง'], - ['alpha2' => 'SC', 'alpha3' => 'SYC', 'numeric' => '690', 'name' => 'Seychelles', 'official_name' => 'Republic of Seychelles', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡จ'], - ['alpha2' => 'SD', 'alpha3' => 'SDN', 'numeric' => '729', 'name' => 'Sudan', 'official_name' => 'Republic of the Sudan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฉ'], - ['alpha2' => 'SE', 'alpha3' => 'SWE', 'numeric' => '752', 'name' => 'Sweden', 'official_name' => 'Kingdom of Sweden', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ช'], - ['alpha2' => 'SG', 'alpha3' => 'SGP', 'numeric' => '702', 'name' => 'Singapore', 'official_name' => 'Republic of Singapore', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฌ'], - ['alpha2' => 'SH', 'alpha3' => 'SHN', 'numeric' => '654', 'name' => 'Saint Helena, Ascension and Tristan da Cunha', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ญ'], - ['alpha2' => 'SI', 'alpha3' => 'SVN', 'numeric' => '705', 'name' => 'Slovenia', 'official_name' => 'Republic of Slovenia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฎ'], - ['alpha2' => 'SJ', 'alpha3' => 'SJM', 'numeric' => '744', 'name' => 'Svalbard and Jan Mayen', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฏ'], - ['alpha2' => 'SK', 'alpha3' => 'SVK', 'numeric' => '703', 'name' => 'Slovakia', 'official_name' => 'Slovak Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฐ'], - ['alpha2' => 'SL', 'alpha3' => 'SLE', 'numeric' => '694', 'name' => 'Sierra Leone', 'official_name' => 'Republic of Sierra Leone', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฑ'], - ['alpha2' => 'SM', 'alpha3' => 'SMR', 'numeric' => '674', 'name' => 'San Marino', 'official_name' => 'Republic of San Marino', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฒ'], - ['alpha2' => 'SN', 'alpha3' => 'SEN', 'numeric' => '686', 'name' => 'Senegal', 'official_name' => 'Republic of Senegal', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ณ'], - ['alpha2' => 'SO', 'alpha3' => 'SOM', 'numeric' => '706', 'name' => 'Somalia', 'official_name' => 'Federal Republic of Somalia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ด'], - ['alpha2' => 'SR', 'alpha3' => 'SUR', 'numeric' => '740', 'name' => 'Suriname', 'official_name' => 'Republic of Suriname', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ท'], - ['alpha2' => 'SS', 'alpha3' => 'SSD', 'numeric' => '728', 'name' => 'South Sudan', 'official_name' => 'Republic of South Sudan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ธ'], - ['alpha2' => 'ST', 'alpha3' => 'STP', 'numeric' => '678', 'name' => 'Sao Tome and Principe', 'official_name' => 'Democratic Republic of Sao Tome and Principe', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡น'], - ['alpha2' => 'SV', 'alpha3' => 'SLV', 'numeric' => '222', 'name' => 'El Salvador', 'official_name' => 'Republic of El Salvador', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ป'], - ['alpha2' => 'SX', 'alpha3' => 'SXM', 'numeric' => '534', 'name' => 'Sint Maarten (Dutch part)', 'official_name' => 'Sint Maarten (Dutch part)', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฝ'], - ['alpha2' => 'SY', 'alpha3' => 'SYR', 'numeric' => '760', 'name' => 'Syrian Arab Republic', 'official_name' => null, 'common_name' => 'Syria', 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡พ'], - ['alpha2' => 'SZ', 'alpha3' => 'SWZ', 'numeric' => '748', 'name' => 'Eswatini', 'official_name' => 'Kingdom of Eswatini', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ธ๐Ÿ‡ฟ'], - ['alpha2' => 'TC', 'alpha3' => 'TCA', 'numeric' => '796', 'name' => 'Turks and Caicos Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡จ'], - ['alpha2' => 'TD', 'alpha3' => 'TCD', 'numeric' => '148', 'name' => 'Chad', 'official_name' => 'Republic of Chad', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฉ'], - ['alpha2' => 'TF', 'alpha3' => 'ATF', 'numeric' => '260', 'name' => 'French Southern Territories', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ซ'], - ['alpha2' => 'TG', 'alpha3' => 'TGO', 'numeric' => '768', 'name' => 'Togo', 'official_name' => 'Togolese Republic', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฌ'], - ['alpha2' => 'TH', 'alpha3' => 'THA', 'numeric' => '764', 'name' => 'Thailand', 'official_name' => 'Kingdom of Thailand', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ญ'], - ['alpha2' => 'TJ', 'alpha3' => 'TJK', 'numeric' => '762', 'name' => 'Tajikistan', 'official_name' => 'Republic of Tajikistan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฏ'], - ['alpha2' => 'TK', 'alpha3' => 'TKL', 'numeric' => '772', 'name' => 'Tokelau', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฐ'], - ['alpha2' => 'TL', 'alpha3' => 'TLS', 'numeric' => '626', 'name' => 'Timor-Leste', 'official_name' => 'Democratic Republic of Timor-Leste', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฑ'], - ['alpha2' => 'TM', 'alpha3' => 'TKM', 'numeric' => '795', 'name' => 'Turkmenistan', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฒ'], - ['alpha2' => 'TN', 'alpha3' => 'TUN', 'numeric' => '788', 'name' => 'Tunisia', 'official_name' => 'Republic of Tunisia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ณ'], - ['alpha2' => 'TO', 'alpha3' => 'TON', 'numeric' => '776', 'name' => 'Tonga', 'official_name' => 'Kingdom of Tonga', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ด'], - ['alpha2' => 'TR', 'alpha3' => 'TUR', 'numeric' => '792', 'name' => 'Tรผrkiye', 'official_name' => 'Republic of Tรผrkiye', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ท'], - ['alpha2' => 'TT', 'alpha3' => 'TTO', 'numeric' => '780', 'name' => 'Trinidad and Tobago', 'official_name' => 'Republic of Trinidad and Tobago', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡น'], - ['alpha2' => 'TV', 'alpha3' => 'TUV', 'numeric' => '798', 'name' => 'Tuvalu', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ป'], - ['alpha2' => 'TW', 'alpha3' => 'TWN', 'numeric' => '158', 'name' => 'Taiwan, Province of China', 'official_name' => 'Taiwan, Province of China', 'common_name' => 'Taiwan', 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ผ'], - ['alpha2' => 'TZ', 'alpha3' => 'TZA', 'numeric' => '834', 'name' => 'Tanzania, United Republic of', 'official_name' => 'United Republic of Tanzania', 'common_name' => 'Tanzania', 'flag_emoji' => '๐Ÿ‡น๐Ÿ‡ฟ'], - ['alpha2' => 'UA', 'alpha3' => 'UKR', 'numeric' => '804', 'name' => 'Ukraine', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡บ๐Ÿ‡ฆ'], - ['alpha2' => 'UG', 'alpha3' => 'UGA', 'numeric' => '800', 'name' => 'Uganda', 'official_name' => 'Republic of Uganda', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡บ๐Ÿ‡ฌ'], - ['alpha2' => 'UM', 'alpha3' => 'UMI', 'numeric' => '581', 'name' => 'United States Minor Outlying Islands', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡บ๐Ÿ‡ฒ'], - ['alpha2' => 'US', 'alpha3' => 'USA', 'numeric' => '840', 'name' => 'United States', 'official_name' => 'United States of America', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡บ๐Ÿ‡ธ'], - ['alpha2' => 'UY', 'alpha3' => 'URY', 'numeric' => '858', 'name' => 'Uruguay', 'official_name' => 'Eastern Republic of Uruguay', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡บ๐Ÿ‡พ'], - ['alpha2' => 'UZ', 'alpha3' => 'UZB', 'numeric' => '860', 'name' => 'Uzbekistan', 'official_name' => 'Republic of Uzbekistan', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡บ๐Ÿ‡ฟ'], - ['alpha2' => 'VA', 'alpha3' => 'VAT', 'numeric' => '336', 'name' => 'Holy See (Vatican City State)', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡ฆ'], - ['alpha2' => 'VC', 'alpha3' => 'VCT', 'numeric' => '670', 'name' => 'Saint Vincent and the Grenadines', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡จ'], - ['alpha2' => 'VE', 'alpha3' => 'VEN', 'numeric' => '862', 'name' => 'Venezuela, Bolivarian Republic of', 'official_name' => 'Bolivarian Republic of Venezuela', 'common_name' => 'Venezuela', 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡ช'], - ['alpha2' => 'VG', 'alpha3' => 'VGB', 'numeric' => '092', 'name' => 'Virgin Islands, British', 'official_name' => 'British Virgin Islands', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡ฌ'], - ['alpha2' => 'VI', 'alpha3' => 'VIR', 'numeric' => '850', 'name' => 'Virgin Islands, U.S.', 'official_name' => 'Virgin Islands of the United States', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡ฎ'], - ['alpha2' => 'VN', 'alpha3' => 'VNM', 'numeric' => '704', 'name' => 'Viet Nam', 'official_name' => 'Socialist Republic of Viet Nam', 'common_name' => 'Vietnam', 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡ณ'], - ['alpha2' => 'VU', 'alpha3' => 'VUT', 'numeric' => '548', 'name' => 'Vanuatu', 'official_name' => 'Republic of Vanuatu', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ป๐Ÿ‡บ'], - ['alpha2' => 'WF', 'alpha3' => 'WLF', 'numeric' => '876', 'name' => 'Wallis and Futuna', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ผ๐Ÿ‡ซ'], - ['alpha2' => 'WS', 'alpha3' => 'WSM', 'numeric' => '882', 'name' => 'Samoa', 'official_name' => 'Independent State of Samoa', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ผ๐Ÿ‡ธ'], - ['alpha2' => 'YE', 'alpha3' => 'YEM', 'numeric' => '887', 'name' => 'Yemen', 'official_name' => 'Republic of Yemen', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡พ๐Ÿ‡ช'], - ['alpha2' => 'YT', 'alpha3' => 'MYT', 'numeric' => '175', 'name' => 'Mayotte', 'official_name' => null, 'common_name' => null, 'flag_emoji' => '๐Ÿ‡พ๐Ÿ‡น'], - ['alpha2' => 'ZA', 'alpha3' => 'ZAF', 'numeric' => '710', 'name' => 'South Africa', 'official_name' => 'Republic of South Africa', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฟ๐Ÿ‡ฆ'], - ['alpha2' => 'ZM', 'alpha3' => 'ZMB', 'numeric' => '894', 'name' => 'Zambia', 'official_name' => 'Republic of Zambia', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฟ๐Ÿ‡ฒ'], - ['alpha2' => 'ZW', 'alpha3' => 'ZWE', 'numeric' => '716', 'name' => 'Zimbabwe', 'official_name' => 'Republic of Zimbabwe', 'common_name' => null, 'flag_emoji' => '๐Ÿ‡ฟ๐Ÿ‡ผ'], - ]; + /** @var list> $countries */ + $countries = json_decode( + file_get_contents(dirname(__DIR__) . '/Data/iso_countries.json'), + true, + flags: JSON_THROW_ON_ERROR, + ); foreach ($countries as $index => $country) { Country::query()->updateOrCreate( diff --git a/Modules/Countries/Database/Seeders/IsoCountrySubdivisionsSeeder.php b/Modules/Countries/Database/Seeders/IsoCountrySubdivisionsSeeder.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Database/factories/.gitkeep b/Modules/Countries/Database/factories/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Helpers/.gitkeep b/Modules/Countries/Helpers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Helpers/Helper.php b/Modules/Countries/Helpers/Helper.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Controllers/.gitkeep b/Modules/Countries/Http/Controllers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Controllers/Api/CountriesApiController.php b/Modules/Countries/Http/Controllers/Api/CountriesApiController.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Controllers/CountriesController.php b/Modules/Countries/Http/Controllers/CountriesController.php old mode 100644 new mode 100755 index e8ff25e7..f3e2df47 --- a/Modules/Countries/Http/Controllers/CountriesController.php +++ b/Modules/Countries/Http/Controllers/CountriesController.php @@ -59,7 +59,7 @@ class CountriesController extends Controller 'search', 'status', 'region', - 'regions' + 'regions', )); } diff --git a/Modules/Countries/Http/Controllers/CountrySyncController.php b/Modules/Countries/Http/Controllers/CountrySyncController.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Controllers/ReferenceDataController.php b/Modules/Countries/Http/Controllers/ReferenceDataController.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Middleware/.gitkeep b/Modules/Countries/Http/Middleware/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Requests/.gitkeep b/Modules/Countries/Http/Requests/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Http/Requests/StoreCountryRequest.php b/Modules/Countries/Http/Requests/StoreCountryRequest.php old mode 100644 new mode 100755 index 7eddbfa0..f6c7886d --- a/Modules/Countries/Http/Requests/StoreCountryRequest.php +++ b/Modules/Countries/Http/Requests/StoreCountryRequest.php @@ -8,6 +8,12 @@ use Modules\Countries\Support\Iso3166; class StoreCountryRequest extends FormRequest { + private const ISO3 = 'size:3'; + + private const MAX_STRING = 'max:255'; + + private const MAX_SHORT = 'max:16'; + /** * Authorize country reference-data administration. */ @@ -38,29 +44,29 @@ class StoreCountryRequest extends FormRequest { return [ 'alpha2' => ['required', 'string', 'size:2', 'uppercase', 'unique:countries,alpha2'], - 'alpha3' => ['required', 'string', 'size:3', 'uppercase', 'unique:countries,alpha3'], - 'numeric' => ['required', 'string', 'size:3', 'unique:countries,numeric'], - 'name' => ['required', 'string', 'max:255'], - 'official_name' => ['nullable', 'string', 'max:255'], - 'common_name' => ['nullable', 'string', 'max:255'], - 'display_name' => ['nullable', 'string', 'max:255'], - 'native_name' => ['nullable', 'string', 'max:255'], - 'capital' => ['nullable', 'string', 'max:255'], - 'flag_emoji' => ['nullable', 'string', 'max:16'], - 'calling_code' => ['nullable', 'string', 'max:16'], - 'tld' => ['nullable', 'string', 'max:16'], - 'currency_code' => ['nullable', 'string', 'size:3', 'uppercase'], - 'currency_name' => ['nullable', 'string', 'max:255'], - 'currency_symbol' => ['nullable', 'string', 'max:16'], + 'alpha3' => ['required', 'string', self::ISO3, 'uppercase', 'unique:countries,alpha3'], + 'numeric' => ['required', 'string', self::ISO3, 'unique:countries,numeric'], + 'name' => ['required', 'string', self::MAX_STRING], + 'official_name' => ['nullable', 'string', self::MAX_STRING], + 'common_name' => ['nullable', 'string', self::MAX_STRING], + 'display_name' => ['nullable', 'string', self::MAX_STRING], + 'native_name' => ['nullable', 'string', self::MAX_STRING], + 'capital' => ['nullable', 'string', self::MAX_STRING], + 'flag_emoji' => ['nullable', 'string', self::MAX_SHORT], + 'calling_code' => ['nullable', 'string', self::MAX_SHORT], + 'tld' => ['nullable', 'string', self::MAX_SHORT], + 'currency_code' => ['nullable', 'string', self::ISO3, 'uppercase'], + 'currency_name' => ['nullable', 'string', self::MAX_STRING], + 'currency_symbol' => ['nullable', 'string', self::MAX_SHORT], 'languages' => ['nullable', 'json'], 'timezones' => ['nullable', 'json'], 'latitude' => ['nullable', 'numeric', 'between:-90,90'], 'longitude' => ['nullable', 'numeric', 'between:-180,180'], - 'flag_svg_url' => ['nullable', 'url', 'max:255'], - 'flag_png_url' => ['nullable', 'url', 'max:255'], + 'flag_svg_url' => ['nullable', 'url', self::MAX_STRING], + 'flag_png_url' => ['nullable', 'url', self::MAX_STRING], 'ioc_code' => ['nullable', 'string', 'max:8'], 'fifa_code' => ['nullable', 'string', 'max:8'], - 'postal_code_format' => ['nullable', 'string', 'max:255'], + 'postal_code_format' => ['nullable', 'string', self::MAX_STRING], 'address_format' => ['nullable', 'string', 'max:5000'], 'is_active' => ['required', 'boolean'], 'iso_status' => ['required', 'string', Rule::in(Iso3166::statuses())], @@ -70,10 +76,10 @@ class StoreCountryRequest extends FormRequest 'continent' => ['nullable', 'string', 'max:64'], 'region' => ['nullable', 'string', 'max:100'], 'subregion' => ['nullable', 'string', 'max:100'], - 'intermediate_region' => ['nullable', 'string', 'max:255'], + 'intermediate_region' => ['nullable', 'string', self::MAX_STRING], 'sort_order' => ['nullable', 'integer', 'min:0', 'max:999999'], - 'source' => ['nullable', 'string', 'max:255'], - 'source_version' => ['nullable', 'string', 'max:255'], + 'source' => ['nullable', 'string', self::MAX_STRING], + 'source_version' => ['nullable', 'string', self::MAX_STRING], 'last_synced_at' => ['nullable', 'date'], 'metadata' => ['nullable', 'json'], ]; diff --git a/Modules/Countries/Http/Requests/UpdateCountryRequest.php b/Modules/Countries/Http/Requests/UpdateCountryRequest.php old mode 100644 new mode 100755 index 83f58acb..52a2a8f0 --- a/Modules/Countries/Http/Requests/UpdateCountryRequest.php +++ b/Modules/Countries/Http/Requests/UpdateCountryRequest.php @@ -8,6 +8,12 @@ use Modules\Countries\Support\Iso3166; class UpdateCountryRequest extends FormRequest { + private const ISO3 = 'size:3'; + + private const MAX_STRING = 'max:255'; + + private const MAX_SHORT = 'max:16'; + /** * Authorize country reference-data administration. */ @@ -40,29 +46,29 @@ class UpdateCountryRequest extends FormRequest return [ 'alpha2' => ['required', 'string', 'size:2', 'uppercase', Rule::unique('countries', 'alpha2')->ignore($countryId)], - 'alpha3' => ['required', 'string', 'size:3', 'uppercase', Rule::unique('countries', 'alpha3')->ignore($countryId)], - 'numeric' => ['required', 'string', 'size:3', Rule::unique('countries', 'numeric')->ignore($countryId)], - 'name' => ['required', 'string', 'max:255'], - 'official_name' => ['nullable', 'string', 'max:255'], - 'common_name' => ['nullable', 'string', 'max:255'], - 'display_name' => ['nullable', 'string', 'max:255'], - 'native_name' => ['nullable', 'string', 'max:255'], - 'capital' => ['nullable', 'string', 'max:255'], - 'flag_emoji' => ['nullable', 'string', 'max:16'], - 'calling_code' => ['nullable', 'string', 'max:16'], - 'tld' => ['nullable', 'string', 'max:16'], - 'currency_code' => ['nullable', 'string', 'size:3', 'uppercase'], - 'currency_name' => ['nullable', 'string', 'max:255'], - 'currency_symbol' => ['nullable', 'string', 'max:16'], + 'alpha3' => ['required', 'string', self::ISO3, 'uppercase', Rule::unique('countries', 'alpha3')->ignore($countryId)], + 'numeric' => ['required', 'string', self::ISO3, Rule::unique('countries', 'numeric')->ignore($countryId)], + 'name' => ['required', 'string', self::MAX_STRING], + 'official_name' => ['nullable', 'string', self::MAX_STRING], + 'common_name' => ['nullable', 'string', self::MAX_STRING], + 'display_name' => ['nullable', 'string', self::MAX_STRING], + 'native_name' => ['nullable', 'string', self::MAX_STRING], + 'capital' => ['nullable', 'string', self::MAX_STRING], + 'flag_emoji' => ['nullable', 'string', self::MAX_SHORT], + 'calling_code' => ['nullable', 'string', self::MAX_SHORT], + 'tld' => ['nullable', 'string', self::MAX_SHORT], + 'currency_code' => ['nullable', 'string', self::ISO3, 'uppercase'], + 'currency_name' => ['nullable', 'string', self::MAX_STRING], + 'currency_symbol' => ['nullable', 'string', self::MAX_SHORT], 'languages' => ['nullable', 'json'], 'timezones' => ['nullable', 'json'], 'latitude' => ['nullable', 'numeric', 'between:-90,90'], 'longitude' => ['nullable', 'numeric', 'between:-180,180'], - 'flag_svg_url' => ['nullable', 'url', 'max:255'], - 'flag_png_url' => ['nullable', 'url', 'max:255'], + 'flag_svg_url' => ['nullable', 'url', self::MAX_STRING], + 'flag_png_url' => ['nullable', 'url', self::MAX_STRING], 'ioc_code' => ['nullable', 'string', 'max:8'], 'fifa_code' => ['nullable', 'string', 'max:8'], - 'postal_code_format' => ['nullable', 'string', 'max:255'], + 'postal_code_format' => ['nullable', 'string', self::MAX_STRING], 'address_format' => ['nullable', 'string', 'max:5000'], 'is_active' => ['required', 'boolean'], 'iso_status' => ['required', 'string', Rule::in(Iso3166::statuses())], @@ -72,10 +78,10 @@ class UpdateCountryRequest extends FormRequest 'continent' => ['nullable', 'string', 'max:64'], 'region' => ['nullable', 'string', 'max:100'], 'subregion' => ['nullable', 'string', 'max:100'], - 'intermediate_region' => ['nullable', 'string', 'max:255'], + 'intermediate_region' => ['nullable', 'string', self::MAX_STRING], 'sort_order' => ['nullable', 'integer', 'min:0', 'max:999999'], - 'source' => ['nullable', 'string', 'max:255'], - 'source_version' => ['nullable', 'string', 'max:255'], + 'source' => ['nullable', 'string', self::MAX_STRING], + 'source_version' => ['nullable', 'string', self::MAX_STRING], 'last_synced_at' => ['nullable', 'date'], 'metadata' => ['nullable', 'json'], ]; diff --git a/Modules/Countries/Models/.gitkeep b/Modules/Countries/Models/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Models/Country.php b/Modules/Countries/Models/Country.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Models/CountrySubdivision.php b/Modules/Countries/Models/CountrySubdivision.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Providers/.gitkeep b/Modules/Countries/Providers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Providers/CountriesServiceProvider.php b/Modules/Countries/Providers/CountriesServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Providers/RouteServiceProvider.php b/Modules/Countries/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/assets/.gitkeep b/Modules/Countries/Resources/assets/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/assets/js/app.js b/Modules/Countries/Resources/assets/js/app.js old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/assets/sass/app.scss b/Modules/Countries/Resources/assets/sass/app.scss old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/lang/.gitkeep b/Modules/Countries/Resources/lang/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/views/.gitkeep b/Modules/Countries/Resources/views/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/views/_form.blade.php b/Modules/Countries/Resources/views/_form.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/views/create.blade.php b/Modules/Countries/Resources/views/create.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/views/edit.blade.php b/Modules/Countries/Resources/views/edit.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/views/index.blade.php b/Modules/Countries/Resources/views/index.blade.php old mode 100644 new mode 100755 index 462482bb..39a0d630 --- a/Modules/Countries/Resources/views/index.blade.php +++ b/Modules/Countries/Resources/views/index.blade.php @@ -53,10 +53,11 @@
- Search by country, ISO code, currency or calling code + - @@ -77,6 +78,7 @@ class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
Data table
Setting
+
Data table
diff --git a/Modules/Countries/Resources/views/layouts/master.blade.php b/Modules/Countries/Resources/views/layouts/master.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Resources/views/show.blade.php b/Modules/Countries/Resources/views/show.blade.php old mode 100644 new mode 100755 index 3cf1b791..c8cdf395 --- a/Modules/Countries/Resources/views/show.blade.php +++ b/Modules/Countries/Resources/views/show.blade.php @@ -117,6 +117,7 @@
+
Data table
Area @@ -159,6 +160,7 @@
+ ';var g2R="dtFake";var J2R="Row";var M2R=':eq(0)';var u2R="td>";var k2R="sible";var n2R=":v";var i2R="e-createI";var K2R="ssName";var q2R="lumn";var e2R=':visible';var X2R="pendTo";var A2R="count";var E2R="draw.dt";var V9=E2R;V9+=i2R;V9+=B2R;var b9=C06;b9+=n06;var R9=T2R;R9+=T2R;R9+=g2R;R9+=J2R;var c9=n2R;c9+=k56;c9+=k2R;var dt=__dtApi(this[U06][s2R]);var tr=$(m2R);var attachFields=[];var attach=[];var displayFields={};for(var i=G2CC[313785],ien=dt[x2R](c9)[A2R]();i < ien;i++){var v9=B86;v9+=M1R;var S9=n86;S9+=V36;S9+=w46;S9+=U06;var w9=D2R;w9+=B86;w9+=B86;var P9=Z2R;P9+=X2R;var d9=L2R;d9+=u2R;var N9=k56;N9+=L06;N9+=V36;N9+=z46;var F9=o2R;F9+=q2R;var visIdx=dt[F9](i + e2R)[N9]();var td=$(d9)[P9](tr);var fields=__dtFieldsFromIdx(dt,this[U06][U2R],visIdx,e86);var cell=dt[w9](M2R,visIdx)[D1R]();if(cell){var W9=G2R;W9+=K2R;td[r76](cell[W9]);}if(Object[S9](fields)[v9]){var y9=O06;y9+=g06;var r9=I2R;r9+=y76;var H9=F46;H9+=d46;H9+=U06;H9+=y76;attachFields[H9](Object[F1R](fields));attach[r9](td[G2CC[313785]]);$[y9](displayFields,fields);}}var append=function(){var h2R='appendTo';var z2R='prependTo';var a2R="body";var Q2R='end';var action=insertPoint === Q2R?h2R:z2R;tr[action](dt[s2R](undefined)[a2R]());};this[R9]=tr;append();dt[b9](V9,function(){append();});return {0:{attachFields:attachFields,attach:attach,displayFields:displayFields,fields:this[U06][U2R],type:Y2R}};},fakeRowEnd:function(){var f2R='draw.dte-createInline';var O2R="__dtFakeRow";var j2R="_dtFakeRow";var l3=T2R;l3+=j2R;var p3=C06;p3+=l56;h52.m52();p3+=l56;var dt=__dtApi(this[U06][s2R]);dt[p3](f2R);this[l3][T1R]();this[O2R]=o86;},individual:function(identifier,fieldNames){var c2R="dSr";var t3=k56;t3+=c2R;t3+=Q46;var idFn=dataGet(this[U06][t3]);var dt=__dtApi(this[U06][s2R]);var fields=this[U06][U2R];var out={};var forceFields;if(fieldNames){var C3=V36;C3+=g56;C3+=a46;if(!Array[U1R](fieldNames)){fieldNames=[fieldNames];}forceFields={};$[C3](fieldNames,function(i,name){h52.Q52();forceFields[name]=fields[name];});}__dtCellSelector(out,dt,identifier,fields,idFn,forceFields);return out;},fields:function(identifier){var N2R="idS";var w2R="lls";var W2R="colum";var B3=m1R;B3+=e06;B3+=U06;var i3=l56;i3+=k56;i3+=F2R;var E3=N2R;E3+=d2R;var idFn=dataGet(this[U06][E3]);var dt=__dtApi(this[U06][s2R]);h52.Q52();var fields=this[U06][i3];var out={};if($[P2R](identifier) && (identifier[B3] !== undefined || identifier[x2R] !== undefined || identifier[t2R] !== undefined)){var g3=Q46;g3+=V36;g3+=w2R;if(identifier[d06] !== undefined){__dtRowSelector(out,dt,identifier[d06],fields,idFn);}if(identifier[x2R] !== undefined){var T3=W2R;T3+=o06;__dtColumnSelector(out,dt,identifier[T3],fields,idFn);}if(identifier[g3] !== undefined){var J3=c06;J3+=U06;__dtCellSelector(out,dt,identifier[J3],fields,idFn);}}else {__dtRowSelector(out,dt,identifier,fields,idFn);}return out;},create:function(fields,data){h52.Q52();var n3=S2R;n3+=V36;var dt=__dtApi(this[U06][n3]);if(!__dtIsSsp(dt,this)){var s3=n06;s3+=C06;s3+=g06;s3+=V36;var k3=g56;k3+=g06;k3+=g06;var row=dt[j1R][k3](data);__dtHighlight(row[s3]());}},edit:function(identifier,fields,data,store){var H2R="rawT";var y2R="itOpt";var A3=v2R;A3+=V36;var x3=g06;x3+=H2R;x3+=w46;x3+=r2R;var m3=G06;m3+=y2R;m3+=U06;var that=this;var dt=__dtApi(this[U06][s2R]);if(!__dtIsSsp(dt,this) || this[U06][m3][x3] === A3){var M3=R2R;M3+=g06;M3+=V36;var o3=g56;o3+=n06;o3+=w46;var Z3=Q46;Z3+=g56;Z3+=B86;Z3+=B86;var D3=k56;D3+=g06;var rowId=dataSource$1[D3][Z3](this,data);var row;try{var X3=E06;X3+=C06;X3+=e06;row=dt[X3](safeQueryId(rowId));}catch(e){row=dt;}if(!row[b2R]()){var L3=E06;L3+=k1R;row=dt[L3](function(rowIdx,rowData,rowNode){h52.m52();var u3=k56;u3+=g06;return rowId == dataSource$1[u3][V2R](that,rowData);});}if(row[o3]()){var e3=m1R;e3+=p6R;var q3=g06;q3+=g56;q3+=B06;q3+=g56;var toSave=extend({},row[f1R](),e86);toSave=extend(toSave,data,e86);row[q3](toSave);var idx=$[l6R](rowId,store[e3]);store[t6R][C6R](idx,S16);}else {var U3=E6R;U3+=g06;row=dt[j1R][U3](data);}__dtHighlight(row[M3]());}},refresh:function(){var T6R="reload";var K3=i6R;K3+=g56;K3+=z46;var G3=B6R;G3+=A06;var dt=__dtApi(this[U06][G3]);dt[K3][T6R](o86,G2CC[539444]);},remove:function(identifier,fields,store){var g6R="cancelle";var k6R="ver";var I3=g6R;I3+=g06;var that=this;var dt=__dtApi(this[U06][s2R]);var cancelled=store[I3];if(cancelled[z76] === G2CC[313785]){var Q3=j1R;Q3+=U06;dt[Q3](identifier)[T1R]();}else {var O3=J6R;O3+=C06;O3+=n6R;var f3=E06;f3+=C06;f3+=e06;f3+=U06;var z3=V36;z3+=k6R;z3+=w46;var h3=E06;h3+=C06;h3+=e06;h3+=U06;var indexes=[];dt[h3](identifier)[z3](function(){var Y3=Q46;Y3+=g56;Y3+=s6R;var a3=k56;a3+=g06;var id=dataSource$1[a3][Y3](that,this[f1R]());if($[l6R](id,cancelled) === -S16){var j3=k56;j3+=n06;j3+=g06;j3+=i06;indexes[h76](this[j3]());}});dt[f3](indexes)[O3]();}},prep:function(action,identifier,submit,json,store){var D6R="cancelled";var e6R="elled";var M6R="nce";var _this=this;if(action === m6R){store[t6R]=$[x6R](json[f1R],function(row){var c3=k56;c3+=g06;h52.Q52();return dataSource$1[c3][V2R](_this,row);});}if(action === A6R){var d3=g06;d3+=V06;var N3=y56;N3+=g56;N3+=F46;var F3=m1R;F3+=p6R;var cancelled=json[D6R] || [];store[F3]=$[N3](submit[d3],function(val,key){var Z6R="Arr";var u6R="mptyObjec";var w3=I1R;w3+=Z6R;w3+=X6R;var P3=L6R;P3+=l06;P3+=u6R;P3+=B06;return !$[P3](submit[f1R][key]) && $[w3](key,cancelled) === -S16?key:undefined;});}else if(action === o6R){var S3=q6R;S3+=Q46;S3+=e6R;var W3=U6R;W3+=M6R;W3+=s6R;W3+=G06;store[W3]=json[S3] || [];}},commit:function(action,identifier,data,store){var R6R="searchBuilder";var I6R="ServerSide";var N6R="chP";var F6R="sear";var y6R="searchPanes";var v6R="responsive";var O6R="archBuilder";var b6R="rebuild";var H6R="rebuildPa";var P6R="ponsiv";var V6R="getDetails";var d6R="ane";var G6R="rawTyp";var S6R="calc";var p0=n06;p0+=C06;p0+=n06;p0+=V36;var V3=g06;V3+=G6R;V3+=V36;var H3=V36;H3+=K6R;H3+=B06;var v3=Z46;v3+=I6R;var that=this;var dt=__dtApi(this[U06][s2R]);var ssp=dt[o1R]()[G2CC[313785]][Q6R][v3];var ids=store[t6R];h52.m52();if(!__dtIsSsp(dt,this) && action === H3 && store[t6R][z76]){var row=void G2CC[313785];var compare=function(id){h52.Q52();return function(rowIdx,rowData,rowNode){var r3=h6R;r3+=B86;return id == dataSource$1[z6R][r3](that,rowData);};};for(var i=G2CC[313785],ien=ids[z76];i < ien;i++){try{var y3=E06;y3+=C06;y3+=e06;row=dt[y3](safeQueryId(ids[i]));}catch(e){row=dt;}if(!row[b2R]()){var R3=E06;R3+=C06;R3+=e06;row=dt[R3](compare(ids[i]));}if(row[b2R]() && !ssp){var b3=a6R;b3+=y56;b3+=C06;b3+=n6R;row[b3]();}}}var drawType=this[U06][Y6R][V3];if(drawType !== p0){var n0=j6R;n0+=h46;var J0=f6R;J0+=O6R;var T0=l56;T0+=c6R;T0+=n06;var B0=F6R;B0+=N6R;B0+=d6R;B0+=U06;var E0=E06;E0+=F76;E0+=P6R;E0+=V36;var dtAny=dt;if(ssp && ids && ids[z76]){var l0=Y06;l0+=V36;dt[l0](w6R,function(){h52.m52();for(var i=G2CC[313785],ien=ids[z76];i < ien;i++){var t0=E06;t0+=C06;t0+=e06;var row=dt[t0](safeQueryId(ids[i]));if(row[b2R]()){var C0=R2R;C0+=g06;C0+=V36;__dtHighlight(row[C0]());}}});}dt[W6R](drawType);if(dtAny[E0]){var i0=a6R;i0+=S6R;dtAny[v6R][i0]();}if(typeof dtAny[B0] === T0 && !ssp){var g0=H6R;g0+=r6R;dtAny[y6R][g0](undefined,e86);}if(dtAny[R6R] !== undefined && typeof dtAny[J0][b6R] === n0 && !ssp){dtAny[R6R][b6R](dtAny[R6R][V6R]());}}}};function __html_id(identifier){var l9R="a-e";h52.m52();var p9R="[dat";var t9R="itor-id=\"";var T9R='Could not find an element with `data-editor-id` or `id` of: ';var k0=p9R;k0+=l9R;k0+=g06;k0+=t9R;if(identifier === C9R){return $(document);}var specific=$(k0 + identifier + E9R);if(specific[z76] === G2CC[313785]){var s0=U06;s0+=i9R;s0+=B9R;specific=typeof identifier === s0?$(safeQueryId(identifier)):$(identifier);}if(specific[z76] === G2CC[313785]){throw new Error(T9R + identifier);}return specific;}function __html_el(identifier,name){var g9R='[data-editor-field="';var m0=x76;m0+=A76;var context=__html_id(identifier);return $(g9R + name + m0,context);}function __html_els(identifier,names){var out=$();for(var i=G2CC[313785],ien=names[z76];i < ien;i++){var x0=g56;x0+=g06;x0+=g06;out=out[x0](__html_el(identifier,names[i]));}h52.Q52();return out;}function __html_get(identifier,dataSrc){var k9R="itor-value";var D9R="e]";var n9R="data-";var x9R="data-editor-va";var L0=J9R;L0+=y56;L0+=B86;var X0=n9R;X0+=G06;X0+=k9R;var Z0=B86;Z0+=V36;Z0+=s9R;Z0+=y76;var D0=m9R;D0+=x9R;D0+=A9R;D0+=D9R;var A0=Z9R;A0+=G46;A0+=E06;var el=__html_el(identifier,dataSrc);return el[A0](D0)[Z0]?el[X9R](X0):el[L0]();}function __html_set(identifier,fields,data){$[Q76](fields,function(name,field){h52.m52();var U9R='data-editor-value';var e9R='[data-editor-value]';var val=field[L9R](data);if(val !== undefined){var u0=l56;u0+=u9R;u0+=B06;u0+=o9R;var el=__html_el(identifier,field[q9R]());if(el[u0](e9R)[z76]){el[X9R](U9R,val);}else {var o0=M9R;o0+=y76;el[o0](function(){var a9R="eChild";var z9R="firstChil";var Q9R="dNo";var e0=G9R;e0+=K9R;var q0=I9R;q0+=Q9R;q0+=h9R;h52.m52();q0+=U06;while(this[q0][e0]){var M0=z9R;M0+=g06;var U0=V76;U0+=a9R;this[U0](this[M0]);}})[Y9R](val);}}});}var dataSource={id:function(data){h52.m52();var idFn=dataGet(this[U06][C2R]);return idFn(data);},initField:function(cfg){var O9R="-label=";var f9R="[data-editor";var Q0=G9R;h52.m52();Q0+=K9R;var I0=j9R;I0+=h1R;var K0=g06;K0+=g56;K0+=B06;K0+=g56;var G0=f9R;G0+=O9R;G0+=x76;var label=$(G0 + (cfg[K0] || cfg[c9R]) + E9R);if(!cfg[I0] && label[Q0]){var h0=y76;h0+=B06;h0+=y56;h0+=B86;cfg[F9R]=label[h0]();}},individual:function(identifier,fieldNames){var P9R="nodeNa";var H9R="dBack";var b9R='editor-id';var R9R='[data-editor-id]';var v9R="dSel";var r9R='data-editor-field';var V9R='Cannot automatically determine field name from data source';var d0=V36;d0+=N9R;var N0=V36;N0+=w1R;N0+=y76;var F0=d9R;F0+=F2R;var c0=d9R;c0+=F2R;var z0=P9R;z0+=w9R;var attachEl;if(identifier instanceof $ || identifier[z0]){var O0=t56;O0+=s1R;var f0=W9R;f0+=E06;f0+=S9R;f0+=U06;var j0=g56;j0+=n06;j0+=v9R;j0+=l56;var Y0=E6R;Y0+=H9R;attachEl=identifier;if(!fieldNames){var a0=g56;a0+=I06;a0+=E06;fieldNames=[$(identifier)[a0](r9R)];}var back=$[k86][Y0]?y9R:j0;identifier=$(identifier)[f0](R9R)[back]()[O0](b9R);}if(!identifier){identifier=C9R;}if(fieldNames && !Array[U1R](fieldNames)){fieldNames=[fieldNames];}if(!fieldNames || fieldNames[z76] === G2CC[313785]){throw new Error(V9R);}var out=dataSource[c0][V2R](this,identifier);var fields=this[U06][F0];var forceFields={};$[N0](fieldNames,function(i,name){h52.Q52();forceFields[name]=fields[name];});$[d0](out,function(id,set){var l3R='cell';var p3R="attachFi";var W0=Z1R;W0+=B06;W0+=g56;W0+=a46;var w0=p3R;w0+=V36;w0+=B86;w0+=H1R;var P0=B06;P0+=w46;P0+=F46;P0+=V36;set[P0]=l3R;set[w0]=[fieldNames];set[W0]=attachEl?$(attachEl):__html_els(identifier,fieldNames)[t3R]();set[U2R]=fields;h52.Q52();set[p2R]=forceFields;});return out;},fields:function(identifier){var E3R="rray";var i3R="eyless";var S0=C3R;S0+=E3R;var out={};if(Array[S0](identifier)){var v0=B86;v0+=V36;v0+=a1R;for(var i=G2CC[313785],ien=identifier[v0];i < ien;i++){var H0=U6R;H0+=B86;H0+=B86;var res=dataSource[U2R][H0](this,identifier[i]);out[identifier[i]]=res[identifier[i]];}return out;}var data={};var fields=this[U06][U2R];h52.Q52();if(!identifier){var r0=n86;r0+=i3R;identifier=r0;}$[Q76](fields,function(name,field){var B3R="valToData";var val=__html_get(identifier,field[q9R]());field[B3R](data,val === o86?undefined:val);});out[identifier]={idSrc:identifier,data:data,node:document,fields:fields,type:Y2R};return out;},create:function(fields,data){h52.Q52();if(data){var y0=k56;y0+=g06;var id=dataSource[y0][V2R](this,data);try{var R0=G9R;R0+=T3R;R0+=y76;if(__html_id(id)[R0]){__html_set(id,fields,data);}}catch(e){;}}},edit:function(identifier,fields,data){var J3R="less";var b0=g3R;b0+=J3R;var id=dataSource[z6R][V2R](this,data) || b0;__html_set(id,fields,data);},remove:function(identifier,fields){var V0=J6R;V0+=C06;h52.Q52();V0+=n3R;V0+=V36;__html_id(identifier)[V0]();}};var classNames={"wrapper":k46,"processing":{"indicator":k3R,"active":s3R},"header":{"wrapper":m3R,"content":x3R},"body":{"wrapper":A3R,"content":p5},"footer":{"wrapper":D3R,"content":Z3R},"form":{"wrapper":X3R,"content":L3R,"tag":u3R,"info":l5,"error":t5,"buttons":C5,"button":o3R,"buttonInternal":E5},"field":{"wrapper":q3R,"typePrefix":i5,"namePrefix":B5,"label":e3R,"input":T5,"inputControl":U3R,"error":M3R,"msg-label":G3R,"msg-error":g5,"msg-message":K3R,"msg-info":I3R,"multiValue":J5,"multiInfo":n5,"multiRestore":Q3R,"multiNoEdit":k5,"disabled":h3R,"processing":s5},"actions":{"create":z3R,"edit":a3R,"remove":m5},"inline":{"wrapper":Y3R,"liner":x5,"buttons":A5},"bubble":{"wrapper":D5,"liner":Z5,"table":j3R,"close":f3R,"pointer":O3R,"bg":c3R}};var displayed$2=G2CC[539444];var cssBackgroundOpacity=S16;var dom$1={wrapper:$(X5 + L5 + F3R + u5)[G2CC[313785]],background:$(o5)[G2CC[313785]],close:$(q5)[G2CC[313785]],content:o86};function findAttachRow(editor,attach){var S3R="odifie";var d3R="he";var N3R='head';var dt=new $[k86][s86][v76](editor[U06][s2R]);if(attach === N3R){var e5=d3R;e5+=E6R;e5+=V36;e5+=E06;return dt[s2R](undefined)[e5]();;}else if(editor[U06][P3R] === m6R){var U5=B06;U5+=w3R;return dt[U5](undefined)[W3R]();}else {var K5=n06;K5+=C06;K5+=h9R;var G5=y56;G5+=S3R;G5+=E06;var M5=E06;M5+=C06;M5+=e06;return dt[M5](editor[U06][G5])[K5]();}}function heightCalc$1(dte){var v3R="outer";var C0R="onf";var b3R="v.DTE_Body";var E0R="rappe";var t0R="Padding";var p0R="win";var T0R="outerHeight";var V3R="_Content";var H3R="Hei";var i0R='div.DTE_Header';var f5=v3R;f5+=H3R;f5+=r3R;f5+=B06;var j5=e06;j5+=y3R;j5+=F46;j5+=R3R;var Y5=Q46;Y5+=U06;Y5+=U06;var a5=K6R;a5+=b3R;a5+=V3R;var z5=p0R;z5+=l0R;z5+=t0R;var h5=Q46;h5+=C0R;var Q5=y76;Q5+=V36;Q5+=k56;Q5+=B1R;var I5=e06;I5+=E0R;I5+=E06;var header=$(i0R,dom$1[B0R])[T0R]();var footer=$(g0R,dom$1[I5])[T0R]();var maxHeight=$(window)[Q5]() - envelope[h5][z5] * v16 - header - footer;$(a5,dom$1[B0R])[Y5](J0R,maxHeight);return $(dte[n0R][j5])[f5]();}function hide$2(dte,callback){var k0R="tent";h52.m52();if(!callback){callback=function(){};}if(displayed$2){var c5=Q46;c5+=Y06;c5+=E56;c5+=B06;var O5=o2R;O5+=n06;O5+=k0R;$(dom$1[O5])[s0R]({top:-(dom$1[c5][m0R] + B26)},m26,function(){h52.m52();var D0R='normal';var A0R="fadeOut";$([dom$1[B0R],dom$1[x0R]])[A0R](D0R,function(){var F5=g06;F5+=Z0R;$(this)[F5]();callback();});});displayed$2=G2CC[539444];}}function init$1(){var X0R="paci";var M0R='div.DTED_Envelope_Container';var P5=C06;P5+=X0R;P5+=L0R;var d5=Q46;d5+=U06;d5+=U06;var N5=u0R;N5+=o0R;N5+=q0R;N5+=e0R;dom$1[U0R]=$(M0R,dom$1[B0R])[G2CC[313785]];cssBackgroundOpacity=$(dom$1[N5])[d5](P5);}function show$2(dte,callback){var C5R="ackground";var d0R=".DTED_En";var a0R="lope";var y0R="imat";var h0R="TED_";var G5R="px";var o5R="opacity";var n5R="rgi";var T5R="tHeight";var R0R="adeIn";var l5R="ock";var A5R="wrapp";var z0R="Enve";var D5R="acity";var k5R="Left";var q5R='0';var J5R="rapper";var F5R='resize.DTED_Envelope';var S0R="nte";var V0R="nor";var N0R="lick";var W0R="tle";var B5R="offse";var f0R="click";var P0R="velope";var O0R=".DTED_Envelop";var G0R="resize.DTED";var t5R="styl";var E5R="ckground";var h5R='click.DTED_Envelope';var F0R="ck.DTED_Envelope";var K0R="_Envel";var Z5R="atta";var m5R="wi";var Q0R="click.D";var c4=C06;c4+=n06;var O4=G0R;O4+=K0R;O4+=I0R;var Y4=C06;Y4+=n06;var a4=Q0R;a4+=h0R;a4+=z0R;a4+=a0R;var z4=Y0R;z4+=l56;var h4=e06;h4+=E06;h4+=j0R;h4+=E06;var Q4=f0R;Q4+=O0R;Q4+=V36;var I4=c0R;I4+=F0R;var G4=C06;G4+=n06;var M4=Q46;M4+=N0R;M4+=d0R;M4+=P0R;var U4=C06;U4+=l56;U4+=l56;var e4=Q46;h52.m52();e4+=w0R;var q4=B06;q4+=k56;q4+=W0R;var o4=g56;o4+=B06;o4+=B06;o4+=E06;var H5=g56;H5+=d46;H5+=B06;H5+=C06;var v5=u76;v5+=w46;v5+=A06;var S5=Q46;S5+=C06;S5+=S0R;S5+=K46;var W5=g56;W5+=v0R;W5+=L06;var w5=Z46;w5+=C06;w5+=g06;w5+=w46;if(!callback){callback=function(){};}$(w5)[W5](dom$1[x0R])[H0R](dom$1[B0R]);dom$1[S5][v5][r0R]=H5;if(!displayed$2){var u4=g56;u4+=n06;u4+=y0R;u4+=V36;var L4=l56;L4+=R0R;var X4=e06;X4+=b0R;X4+=r2R;X4+=E06;var Z4=V0R;Z4+=p5R;Z4+=B86;var D4=Z46;D4+=B86;D4+=l5R;var A4=t5R;A4+=V36;var x4=Z46;x4+=C5R;var m4=u76;m4+=w46;m4+=B86;m4+=V36;var s4=u0R;s4+=E5R;var k4=F46;k4+=z46;var n4=u76;n4+=w46;n4+=B86;n4+=V36;var J4=i5R;J4+=n06;J4+=B06;var g4=B5R;g4+=T5R;var T4=Y0R;T4+=g5R;var B4=B06;B4+=C06;B4+=F46;var i4=e06;i4+=J5R;var E4=p5R;E4+=n5R;E4+=n06;E4+=k5R;var C4=t5R;C4+=V36;var t4=s5R;t4+=R3R;var l4=m5R;l4+=g06;l4+=x5R;var p4=A5R;p4+=o9R;var V5=C06;V5+=F46;V5+=D5R;var b5=n06;b5+=C06;b5+=r6R;var R5=Z5R;R5+=a46;var y5=X5R;y5+=l56;var r5=Z46;r5+=L5R;var style=dom$1[B0R][u5R];style[o5R]=q5R;style[e5R]=r5;var height=heightCalc$1(dte);var targetRow=findAttachRow(dte,envelope[y5][R5]);var width=targetRow[U5R];style[e5R]=b5;style[V5]=M5R;dom$1[p4][u5R][l4]=width + G5R;dom$1[t4][C4][E4]=-(width / v16) + G5R;dom$1[i4][u5R][B4]=$(targetRow)[T4]()[K5R] + targetRow[g4] + G5R;dom$1[J4][n4][K5R]=-S16 * height - l26 + k4;dom$1[s4][m4][o5R]=q5R;dom$1[x4][A4][e5R]=D4;$(dom$1[x0R])[s0R]({opacity:cssBackgroundOpacity},Z4);$(dom$1[X4])[L4]();$(dom$1[U0R])[u4]({top:G2CC[313785]},m26,callback);}$(dom$1[I5R])[o4](q4,dte[Q5R][e4])[U4](M4)[G4](h5R,function(e){var K4=Q46;K4+=B86;K4+=T86;dte[K4]();});$(dom$1[x0R])[z5R](I4)[Y06](Q4,function(e){h52.m52();dte[x0R]();});$(a5R,dom$1[h4])[z4](a4)[Y4](h5R,function(e){var O5R="tar";var c5R='DTED_Envelope_Content_Wrapper';var f4=Y5R;f4+=j5R;f4+=f5R;f4+=U06;var j4=O5R;j4+=q0R;j4+=V36;j4+=B06;if($(e[j4])[f4](c5R)){dte[x0R]();}});$(window)[z5R](O4)[c4](F5R,function(){heightCalc$1(dte);});displayed$2=e86;}var envelope={close:function(dte,callback){hide$2(dte,callback);},destroy:function(dte){hide$2();},init:function(dte){h52.m52();init$1();return envelope;},node:function(dte){var F4=N5R;F4+=v0R;h52.Q52();F4+=E06;return dom$1[F4][G2CC[313785]];},open:function(dte,append,callback){var w5R="child";var W5R="ontent";var v5R="appendChild";var P5R="ppendCh";var w4=Q46;w4+=B86;w4+=d5R;w4+=V36;var P4=g56;P4+=P5R;P4+=u9R;P4+=g06;var d4=w5R;d4+=a6R;d4+=n06;var N4=Q46;N4+=W5R;$(dom$1[N4])[d4]()[S5R]();dom$1[U0R][P4](append);dom$1[U0R][v5R](dom$1[w4]);show$2(dte,callback);},conf:{windowPadding:B26,attach:Y2R}};function isMobile(){var b5R="orientation";var R5R="fined";var y5R="unde";var s26=576;var r5R="erWidth";var S4=C06;S4+=H5R;S4+=r5R;var W4=y5R;W4+=R5R;return typeof window[b5R] !== W4 && window[S4] <= s26?e86:G2CC[539444];}var displayed$1=G2CC[539444];var ready=G2CC[539444];var scrollTop=G2CC[313785];var dom={wrapper:$(V5R + v4 + p4R + H4 + l4R + l4R + r4 + l4R),background:$(t4R),close:$(C4R),content:o86};function heightCalc(){var s4R="dy_Content";var n4R="div.D";var T4R="div.DTE";var x4R='calc(100vh - ';var o4R='div.DTE_Body_Content';var L4R="owPadding";var J4R="maxHeigh";var E4R="outerHe";var g4R="_Hea";var k4R="TE_B";var B4R="uterHeight";var V4=E4R;V4+=R76;V4+=J9R;var b4=i4R;b4+=E06;var R4=C06;R4+=B4R;var y4=T4R;y4+=g4R;y4+=g06;y4+=o9R;var headerFooter=$(y4,dom[B0R])[R4]() + $(g0R,dom[b4])[V4]();if(isMobile()){var C8=F46;C8+=z46;C8+=H06;var t8=J4R;t8+=B06;var l8=e06;l8+=E06;l8+=Z2R;l8+=R3R;var p8=n4R;p8+=k4R;p8+=C06;p8+=s4R;$(p8,dom[l8])[m4R](t8,x4R + headerFooter + C8);}else {var B8=A4R;B8+=U06;var i8=D4R;i8+=Z4R;i8+=V36;i8+=E06;var E8=e06;E8+=X4R;E8+=L4R;var maxHeight=$(window)[r0R]() - self[u4R][E8] * v16 - headerFooter;$(o4R,dom[i8])[B8](J0R,maxHeight);}}function hide$1(dte,callback){var Q4R='resize.DTED_Lightbox';var M4R="scrollTop";var U4R="nimate";var n8=C06;n8+=q4R;var J8=e4R;J8+=U4R;var T8=Z46;T8+=C06;T8+=g06;T8+=w46;if(!callback){callback=function(){};}$(T8)[M4R](scrollTop);dte[G4R](dom[B0R],{opacity:G2CC[313785],top:self[u4R][K4R]},function(){var I4R="det";var g8=I4R;g8+=w1R;g8+=y76;$(this)[g8]();callback();});dte[J8](dom[x0R],{opacity:G2CC[313785]},function(){$(this)[S5R]();});displayed$1=G2CC[539444];$(window)[n8](Q4R);}function init(){var z4R="pper";var j4R='opacity';var a4R="div.DT";var h4R="opacit";var Y4R="ED_Lightbox_Content";var m8=h4R;m8+=w46;var s8=N5R;s8+=z4R;var k8=a4R;k8+=Y4R;if(ready){return;}h52.m52();dom[U0R]=$(k8,dom[B0R]);dom[s8][m4R](m8,G2CC[313785]);dom[x0R][m4R](j4R,G2CC[313785]);ready=e86;}function show$1(dte,callback){var b4R="lT";var v4R="tbo";var O4R="DTED_Lig";var N4R="back";var r4R="ody";var i8R='title';var B8R='click.DTED_Lightbox';var H4R="x_Mobile";var p8R="resize.DTED_Li";var S4R="DTED_Ligh";var F4R="ox";var y4R="sc";var f4R="click.";var E8R="hei";var c4R="htb";var t8R="imate";var l8R="box";var O8=D4R;O8+=j0R;O8+=E06;var Y8=f4R;Y8+=O4R;Y8+=c4R;Y8+=F4R;var a8=N4R;a8+=q0R;a8+=e0R;var h8=C06;h8+=n06;var Q8=Q46;Q8+=d4R;Q8+=U06;Q8+=V36;var I8=g56;I8+=B06;I8+=B06;I8+=E06;var L8=s5R;L8+=F46;L8+=o9R;var X8=g56;X8+=F46;X8+=F46;X8+=P4R;var Z8=g56;Z8+=F46;Z8+=r2R;Z8+=L06;var D8=w4R;D8+=W4R;if(isMobile()){var A8=S4R;A8+=v4R;A8+=H4R;var x8=Z46;x8+=r4R;$(x8)[r76](A8);}$(D8)[Z8](dom[x0R])[X8](dom[L8]);heightCalc();if(!displayed$1){var K8=y4R;K8+=R4R;K8+=b4R;K8+=V4R;var G8=Z46;G8+=C06;G8+=W4R;var M8=p8R;M8+=B1R;M8+=l8R;var U8=T2R;U8+=g56;U8+=n06;U8+=t8R;var e8=Q46;e8+=C8R;var q8=g56;q8+=H5R;q8+=C06;var o8=E8R;o8+=B1R;var u8=Q46;u8+=U06;u8+=U06;displayed$1=e86;dom[U0R][u8](o8,q8);dom[B0R][e8]({top:-self[u4R][K4R]});dte[G4R](dom[B0R],{opacity:S16,top:G2CC[313785]},callback);dte[U8](dom[x0R],{opacity:S16});$(window)[Y06](M8,function(){h52.m52();heightCalc();});scrollTop=$(G8)[K8]();}dom[I5R][I8](i8R,dte[Q5R][Q8])[z5R](B8R)[h8](B8R,function(e){var z8=T8R;h52.Q52();z8+=C06;z8+=U06;z8+=V36;dte[z8]();});dom[a8][z5R](B8R)[Y06](Y8,function(e){h52.m52();var g8R="backg";var n8R="diatePropagation";var J8R="stopImme";var f8=g8R;f8+=e0R;var j8=J8R;j8+=n8R;e[j8]();dte[f8]();});$(a5R,dom[O8])[z5R](B8R)[Y06](B8R,function(e){var k8R="rg";var A8R="stopImmediatePropagation";var x8R='DTED_Lightbox_Content_Wrapper';var c8=s1R;h52.Q52();c8+=k8R;c8+=s8R;if($(e[c8])[m8R](x8R)){var F8=N4R;F8+=q0R;F8+=e0R;e[A8R]();dte[F8]();}});}var self={close:function(dte,callback){h52.m52();hide$1(dte,callback);},conf:{offsetAni:t26,windowPadding:t26},destroy:function(dte){h52.m52();if(displayed$1){hide$1(dte);}},init:function(dte){h52.m52();init();return self;},node:function(dte){var N8=i4R;N8+=E06;return dom[N8][G2CC[313785]];},open:function(dte,append,callback){var w8=Z2R;w8+=r2R;w8+=n06;w8+=g06;var P8=g56;P8+=F46;P8+=D8R;P8+=g06;var d8=r46;d8+=V36;d8+=K46;var content=dom[d8];content[Z8R]()[S5R]();content[P8](append)[w8](dom[I5R]);show$1(dte,callback);}};var DataTable$4=$[k86][W8];function add(cfg,after,reorder){var h8R=" with th";var z8R="is name";var r8R="spl";var O8R="Field";var R8R="playReord";var e8R="rder";var a8R="Error ";var K8R=" `";var y8R="ice";var G8R="Error adding field. The field requires a";var I8R="name` option";var j8R="eld '";var Q8R="'. A field already exists";var U8R="_displayRe";var o8R="initFi";var Y8R="adding fi";var t7=l56;t7+=X8R;t7+=P1R;t7+=U06;var V8=Q46;V8+=L8R;h52.Q52();V8+=u8R;var b8=o8R;b8+=q8R;if(reorder === void G2CC[313785]){reorder=e86;}if(Array[U1R](cfg)){var H8=C06;H8+=e8R;var v8=U8R;v8+=C06;v8+=e8R;if(after !== undefined){var S8=a6R;S8+=n6R;S8+=E06;S8+=f6R;cfg[S8]();}for(var i=G2CC[313785];i < cfg[z76];i++){this[M8R](cfg[i],after,G2CC[539444]);}this[v8](this[H8]());return this;}var name=cfg[c9R];if(name === undefined){var r8=G8R;r8+=K8R;r8+=I8R;throw r8;}if(this[U06][U2R][name]){var R8=Q8R;R8+=h8R;R8+=z8R;var y8=a8R;y8+=Y8R;y8+=j8R;throw y8 + name + R8;}this[f8R](b8,cfg);var field=new Editor[O8R](cfg,this[V8][c8R],this);if(this[U06][F8R]){var editFields=this[U06][N8R];field[d8R]();$[Q76](editFields,function(idSrc,edit){var l7=P8R;l7+=w8R;l7+=V36;l7+=B06;var val;if(edit[f1R]){var p7=g06;p7+=g56;p7+=s1R;val=field[L9R](edit[p7]);}field[l7](idSrc,val !== undefined?val:field[W8R]());});}this[U06][t7][name]=field;if(after === undefined){var C7=I2R;C7+=y76;this[U06][S8R][C7](name);}else if(after === o86){var E7=C06;E7+=E06;E7+=v8R;this[U06][E7][H8R](name);}else {var i7=r8R;i7+=y8R;var idx=$[l6R](after,this[U06][S8R]);this[U06][S8R][i7](idx + S16,G2CC[313785],name);}if(reorder !== G2CC[539444]){var B7=T2R;B7+=N1R;B7+=R8R;B7+=o9R;this[B7](this[S8R]());}return this;}function ajax(newAjax){var T7=g56;T7+=b8R;T7+=V8R;h52.Q52();if(newAjax){this[U06][p7R]=newAjax;return this;}return this[U06][T7];}function background(){var i7R="kgroun";var B7R="ditOpts";var E7R="Bac";var m7=U06;m7+=d46;m7+=Z46;m7+=l7R;var k7=Q46;k7+=w0R;var n7=l56;n7+=t7R;n7+=C7R;var J7=Y06;J7+=E7R;J7+=i7R;J7+=g06;var g7=V36;g7+=B7R;var onBackground=this[U06][g7][J7];if(typeof onBackground === n7){onBackground(this);}else if(onBackground === X86){this[T7R]();}else if(onBackground === k7){var s7=T8R;s7+=C06;s7+=f6R;this[s7]();}else if(onBackground === m7){this[g7R]();}return this;}function blur(){var J7R="_blur";this[J7R]();return this;}function bubble(cells,fieldNames,show,opts){var s7R="Options";var X7R='boolean';var X7=n7R;X7+=k56;X7+=B06;var Z7=k7R;Z7+=y56;Z7+=s7R;var D7=J06;D7+=n06;D7+=g06;var A7=m7R;A7+=x7R;A7+=B06;var x7=A7R;x7+=D7R;var _this=this;var that=this;if(this[x7](function(){h52.Q52();that[Z7R](cells,fieldNames,opts);})){return this;}if($[A7](fieldNames)){opts=fieldNames;fieldNames=undefined;show=e86;}else if(typeof fieldNames === X7R){show=fieldNames;fieldNames=undefined;opts=undefined;}if($[P2R](show)){opts=show;show=e86;}if(show === undefined){show=e86;}opts=$[D7]({},this[U06][Z7][Z7R],opts);var editFields=this[f8R](L7R,cells,fieldNames);this[X7](cells,editFields,u7R,opts,function(){var H7R="e.";var O7R="div><";var l1P="bg";var v7R="siz";var E1P="liner";var d7R="s=";var q7R="bubblePos";var T1P="pointer";var f7R="\">
';var w7R="cat";var Q7R="/di";var a7R="iv class=\"";var Z1P="prepend";var N7R="v clas";var h7R="\" tit";var z1P="_postopen";var z7R="le=\"";var K7R="prepe";var M7R="dd";var V7R='attach';var W7R="bubbleN";var J1P="ppen";var o7R="anim";var c7R="/div>";var Y7R="
docWidth){var a1V=B86;a1V+=V36;a1V+=l56;a1V+=B06;var diff=visRight - docWidth;liner[m4R](a1V,visLeft < padding?-(visLeft - padding):-(diff + padding));}else {var Y1V=Q46;Y1V+=U06;Y1V+=U06;liner[Y1V](l2P,visLeft < padding?-(visLeft - padding):G2CC[313785]);}return this;}function buttons(buttons){var t2P="em";var C2P="pty";var N1V=t2P;N1V+=C2P;var F1V=Z46;F1V+=d46;F1V+=L46;var c1V=g06;c1V+=C06;c1V+=y56;var _this=this;if(buttons === g76){var f1V=E2P;f1V+=y56;f1V+=k56;f1V+=B06;var j1V=w1R;j1V+=B06;j1V+=k56;j1V+=Y06;buttons=[{text:this[Q5R][this[U06][j1V]][f1V],action:function(){var O1V=i2P;O1V+=B2P;h52.Q52();O1V+=k56;O1V+=B06;this[O1V]();}}];}else if(!Array[U1R](buttons)){buttons=[buttons];}$(this[c1V][F1V])[N1V]();$[Q76](buttons,function(i,btn){var X2P='';var m2P="assName";var k2P="bIndex";var o2P='tabindex';var T2P="To";var x2P="sNam";var q2P='keyup';var s2P="nction";var J2P="press";var i2V=Z2R;i2V+=D8R;i2V+=g06;i2V+=T2P;var E2V=Q46;E2V+=B86;E2V+=g2P;var l2V=g3R;l2V+=J2P;var p2V=C06;p2V+=n06;var b1V=C06;b1V+=n06;var R1V=B6R;R1V+=n2P;R1V+=h9R;R1V+=z46;var y1V=s1R;y1V+=k2P;var r1V=g56;r1V+=B06;r1V+=B06;r1V+=E06;var H1V=l56;H1V+=d46;H1V+=s2P;var v1V=y76;v1V+=B06;v1V+=y56;v1V+=B86;var S1V=T8R;S1V+=m2P;var W1V=Q46;W1V+=f5R;W1V+=x2P;W1V+=V36;var w1V=A2P;w1V+=F76;var P1V=l56;P1V+=n06;var d1V=D2P;d1V+=h46;if(typeof btn === L76){btn={text:btn,action:function(){this[g7R]();}};}h52.Q52();var text=btn[Z2P] || btn[F9R];var action=btn[d1V] || btn[P1V];$(X2P,{'class':_this[w1V][L2P][h06] + (btn[W1V]?u2P + btn[S1V]:n76)})[v1V](typeof text === H1V?text(_this):text || n76)[r1V](o2P,btn[y1V] !== undefined?btn[R1V]:G2CC[313785])[b1V](q2P,function(e){var U2P="all";if(e[e2P] === R16 && action){var V1V=Q46;V1V+=U2P;action[V1V](_this);}})[p2V](l2V,function(e){h52.m52();var M2P="whi";var K2P="even";var I2P="tDefault";var t2V=M2P;t2V+=Q46;t2V+=y76;if(e[t2V] === R16){var C2V=G2P;C2V+=K2P;C2V+=I2P;e[C2V]();}})[Y06](E2V,function(e){e[Q2P]();if(action){action[V2R](_this,e);}})[i2V](_this[n0R][h2P]);});return this;}function clear(fieldName){var z2P="inAr";var O2P="lice";var a2P="orde";var F2P="Fie";var c2P="include";h52.Q52();var B2V=l56;B2V+=X8R;B2V+=j1P;var that=this;var fields=this[U06][B2V];if(typeof fieldName === L76){var J2V=z2P;J2V+=y3R;J2V+=w46;var g2V=a2P;g2V+=E06;var T2V=d9R;T2V+=q8R;that[T2V](fieldName)[Y2P]();delete fields[fieldName];var orderIdx=$[l6R](fieldName,this[U06][g2V]);this[U06][S8R][C6R](orderIdx,S16);var includeIdx=$[J2V](fieldName,this[U06][j2P]);if(includeIdx !== -S16){var k2V=f2P;k2V+=O2P;var n2V=c2P;n2V+=F2P;n2V+=B86;n2V+=H1R;this[U06][n2V][k2V](includeIdx,S16);}}else {$[Q76](this[N2P](fieldName),function(i,name){var d2P="clea";var s2V=d2P;s2V+=E06;h52.m52();that[s2V](name);});}return this;}function close(){var m2V=q1P;m2V+=T86;this[m2V](G2CC[539444]);return this;}function create(arg1,arg2,arg3,arg4){var r2P="ditFiel";var H2P="Arg";var v2P="_crud";var P2P="tCreat";var W2P="playR";var S2P="eord";var e2V=k56;e2V+=K1P;e2V+=P2P;e2V+=V36;var u2V=w2P;u2V+=W2P;u2V+=S2P;u2V+=o9R;var L2V=l56;L2V+=C06;L2V+=E06;L2V+=y56;var X2V=v2P;X2V+=H2P;X2V+=U06;var D2V=V36;D2V+=r2P;D2V+=H1R;var A2V=y2P;A2V+=o9R;var x2V=T2R;x2V+=b56;x2V+=g06;x2V+=w46;var _this=this;var that=this;var fields=this[U06][U2R];var count=S16;if(this[x2V](function(){that[R2P](arg1,arg2,arg3,arg4);})){return this;}if(typeof arg1 === A2V){count=arg1;arg1=arg2;arg2=arg3;}this[U06][D2V]={};for(var i=G2CC[313785];i < count;i++){var Z2V=q1R;Z2V+=U06;this[U06][Z2V][i]={fields:this[U06][U2R]};}var argOpts=this[X2V](arg1,arg2,arg3,arg4);this[U06][F8R]=b2P;this[U06][P3R]=R2P;this[U06][V2P]=o86;this[n0R][L2V][u5R][e5R]=p6P;this[l6P]();this[u2V](this[U2R]());$[Q76](fields,function(name,field){var q2V=g06;q2V+=V36;q2V+=l56;field[d8R]();for(var i=G2CC[313785];i < count;i++){var o2V=t6P;o2V+=C6P;o2V+=w8R;o2V+=s8R;field[o2V](i,field[W8R]());}field[N76](field[q2V]());});this[U1P](e2V,o86,function(){var E6P="beOp";var T6P="Main";var B6P="emble";var G2V=y56;G2V+=X6R;G2V+=E6P;G2V+=T06;var M2V=C06;M2V+=i6P;M2V+=U06;var U2V=e4R;h52.m52();U2V+=C8R;U2V+=B6P;U2V+=T6P;_this[U2V]();_this[g6P](argOpts[M2V]);argOpts[G2V]();});return this;}function undependent(parent){var J6P=".ed";var s6P="ndependent";var z2V=J6P;z2V+=V36;z2V+=F46;var h2V=n6P;h2V+=V36;var K2V=k6P;K2V+=X6R;if(Array[K2V](parent)){var I2V=A06;I2V+=B9R;I2V+=B06;I2V+=y76;for(var i=G2CC[313785],ien=parent[I2V];i < ien;i++){var Q2V=d46;Q2V+=s6P;this[Q2V](parent[i]);}return this;}var field=this[c8R](parent);$(field[h2V]())[z5R](z2V);return this;}function dependent(parent,url,opts){var x6P="ange";var m6P=".e";var S2V=m6P;S2V+=h9R;S2V+=F46;var W2V=C06;W2V+=n06;var Y2V=a46;Y2V+=x6P;var _this=this;if(Array[U1R](parent)){var a2V=A6P;a2V+=x5R;for(var i=G2CC[313785],ien=parent[a2V];i < ien;i++){this[D6P](parent[i],url,opts);}return this;}var that=this;var field=this[c8R](parent);var ajaxOpts={type:Z6P,dataType:X6P};opts=$[T76]({event:Y2V,data:o86,preUpdate:o86,postUpdate:o86},opts);var update=function(json){var o6P="postUpd";var e6P="preUpdate";var Q6P='show';var K6P='val';var Y6P="ostUpda";var I6P='error';var U6P="Up";var z6P='disable';var L6P="oces";var G6P='update';var w2V=G2P;w2V+=L6P;w2V+=u6P;var d2V=o6P;d2V+=g56;d2V+=B06;d2V+=V36;var F2V=y76;F2V+=k56;F2V+=g06;F2V+=V36;var c2V=M9R;c2V+=y76;var O2V=y56;O2V+=F76;O2V+=q6P;var f2V=J1R;f2V+=Q46;f2V+=y76;if(opts[e6P]){var j2V=L1P;j2V+=U6P;j2V+=t56;j2V+=G46;opts[j2V](json);}$[f2V]({labels:M6P,options:G6P,values:K6P,messages:O2V,errors:I6P},function(jsonProp,fieldFn){if(json[jsonProp]){$[Q76](json[jsonProp],function(field,val){that[c8R](field)[fieldFn](val);});}});$[c2V]([F2V,Q6P,h6P,z6P],function(i,key){var a6P="animat";if(json[key]){var N2V=a6P;N2V+=V36;that[key](json[key],json[N2V]);}});if(opts[d2V]){var P2V=F46;P2V+=Y6P;P2V+=B06;P2V+=V36;opts[P2V](json);}field[w2V](G2CC[539444]);};$(field[D1R]())[W2V](opts[j6P] + S2V,function(e){var F6P='data';var c6P="target";var S6P="ainOb";var N6P="values";var b2V=g06;b2V+=V06;var R2V=m1R;R2V+=f6P;var y2V=m1R;y2V+=e06;y2V+=U06;var r2V=X1R;r2V+=B06;r2V+=O6P;r2V+=H1R;var H2V=d9R;H2V+=n06;H2V+=g06;var v2V=n06;v2V+=C06;v2V+=g06;v2V+=V36;if($(field[v2V]())[H2V](e[c6P])[z76] === G2CC[313785]){return;}field[s3R](e86);var data={};data[d06]=_this[U06][r2V]?pluck(_this[U06][N8R],F6P):o86;h52.m52();data[j1R]=data[y2V]?data[R2V][G2CC[313785]]:o86;data[N6P]=_this[d6P]();if(opts[b2V]){var ret=opts[f1R](data);if(ret){var V2V=g06;V2V+=g56;V2V+=B06;V2V+=g56;opts[V2V]=ret;}}if(typeof url === G2CC[444023]){var p6V=Q46;p6V+=g56;p6V+=B86;p6V+=B86;var o=url[p6V](_this,field[d6P](),data,update,e);if(o){var t6V=l56;t6V+=t7R;t6V+=Q46;t6V+=P6P;var l6V=B06;l6V+=y76;l6V+=V36;l6V+=n06;if(typeof o === G2CC[146202] && typeof o[l6V] === t6V){o[w6P](function(resolved){h52.m52();if(resolved){update(resolved);}});}else {update(o);}}}else {var i6V=g56;i6V+=b8R;i6V+=g56;i6V+=z46;var C6V=W6P;C6V+=S6P;C6V+=b8R;C6V+=v6P;if($[C6V](url)){$[T76](ajaxOpts,url);}else {var E6V=c76;E6V+=B86;ajaxOpts[E6V]=url;}$[i6V]($[T76](ajaxOpts,{data:data,success:update}));}});return this;}function destroy(){var R6P="clear";var H6P="nique";var l9P="dest";var t9P='.dte';var n6V=d46;n6V+=H6P;var B6V=N1R;h52.m52();B6V+=r6P;B6V+=G06;if(this[U06][B6V]){var T6V=y6P;T6V+=V36;this[T6V]();}this[R6P]();if(this[U06][b6P]){var g6V=g56;g6V+=F46;g6V+=V6P;$(s1P)[g6V](this[U06][b6P]);}var controller=this[U06][p9P];if(controller[Y2P]){var J6V=l9P;J6V+=m1R;J6V+=w46;controller[J6V](this);}$(document)[z5R](t9P + this[U06][n6V]);this[n0R]=o86;this[U06]=o86;}function disable(name){var C9P="_fi";var E9P="Names";h52.m52();var k6V=C9P;k6V+=q8R;k6V+=E9P;var that=this;$[Q76](this[k6V](name),function(i,n){var m6V=g06;m6V+=L6R;m6V+=g56;h52.Q52();m6V+=S76;var s6V=l56;s6V+=X8R;s6V+=B86;s6V+=g06;that[s6V](n)[m6V]();});return this;}function display(show){var x6V=C06;x6V+=r2R;x6V+=n06;if(show === undefined){return this[U06][i9P];}h52.m52();return this[show?x6V:Z86]();}function displayed(){var A6V=d9R;h52.Q52();A6V+=F2R;return $[x6R](this[U06][A6V],function(field,name){h52.Q52();return field[i9P]()?name:o86;});}function displayNode(){var D6V=R2R;D6V+=g06;D6V+=V36;return this[U06][p9P][D6V](this);}function edit(items,arg1,arg2,arg3,arg4){var n9P="rgs";var J9P="dA";var g9P="ru";var u6V=l56;u6V+=k56;u6V+=q8R;u6V+=U06;var L6V=B9P;L6V+=K6R;L6V+=B06;var X6V=T9P;X6V+=g9P;X6V+=J9P;X6V+=n9P;var Z6V=A7R;Z6V+=k56;Z6V+=g06;Z6V+=w46;var _this=this;var that=this;if(this[Z6V](function(){that[D06](items,arg1,arg2,arg3,arg4);})){return this;}var argOpts=this[X6V](arg1,arg2,arg3,arg4);this[L6V](items,this[f8R](u6V,items),b2P,argOpts[k9P],function(){var s9P="maybeOpe";var e6V=s9P;e6V+=n06;var q6V=C06;q6V+=F46;q6V+=B06;q6V+=U06;var o6V=m9P;o6V+=I1R;_this[o6V]();_this[g6P](argOpts[q6V]);argOpts[e6V]();});return this;}function enable(name){var U6V=J1R;U6V+=Q46;h52.m52();U6V+=y76;var that=this;$[U6V](this[N2P](name),function(i,n){var M6V=d9R;h52.m52();M6V+=h1R;M6V+=g06;that[M6V](n)[x9P]();});return this;}function error$1(name,msg){var u9P="globalError";var D9P="_m";var wrapper=$(this[n0R][B0R]);if(msg === undefined){var K6V=A9P;K6V+=y56;var G6V=D9P;G6V+=Z9P;G6V+=G7R;this[G6V](this[K6V][x1P],name,e86,function(){var X9P="toggleClass";var L9P='inFormError';wrapper[X9P](L9P,name !== undefined && name !== n76);});this[U06][u9P]=name;}else {var Q6V=o9R;Q6V+=E06;Q6V+=C06;Q6V+=E06;var I6V=o9P;I6V+=P1R;this[I6V](name)[Q6V](msg);}return this;}function field(name){var q9P='Unknown field name - ';var fields=this[U06][U2R];h52.Q52();if(!fields[name]){throw q9P + name;}return fields[name];}function fields(){var h6V=d9R;h6V+=q8R;h52.m52();h6V+=U06;return $[x6R](this[U06][h6V],function(field,name){h52.m52();return name;});}function file(name,id){var U9P='Unknown file id ';var M9P=' in table ';var table=this[e9P](name);var file=table[id];if(!file){throw U9P + id + M9P + name;}return table[id];}function files(name){var K9P="nknown file table name: ";var z6V=Z9R;z6V+=F76;if(!name){return Editor[e9P];}var table=Editor[z6V][name];if(!table){var a6V=G9P;a6V+=K9P;throw a6V + name;}return table;}function get(name){var that=this;if(!name){var Y6V=d9R;Y6V+=h1R;Y6V+=H1R;name=this[Y6V]();}if(Array[U1R](name)){var out={};$[Q76](name,function(i,n){var f6V=I9P;f6V+=B06;var j6V=l56;j6V+=Q9P;out[n]=that[j6V](n)[f6V]();});return out;}return this[c8R](name)[b1R]();}function hide(names,animate){var O6V=V36;O6V+=g56;O6V+=a46;h52.m52();var that=this;$[O6V](this[N2P](names),function(i,n){h52.Q52();that[c8R](n)[h9P](animate);});return this;}function ids(includeHash){var z9P="ditF";var c6V=V36;c6V+=z9P;c6V+=X8R;c6V+=j1P;h52.Q52();if(includeHash === void G2CC[313785]){includeHash=G2CC[539444];}return $[x6R](this[U06][c6V],function(edit,idSrc){h52.m52();return includeHash === e86?X76 + idSrc:idSrc;});}function inError(inNames){var a9P="balEr";var Y9P="formErro";var d6V=q0R;d6V+=d4R;d6V+=a9P;d6V+=g46;var N6V=Y9P;N6V+=E06;var F6V=g06;F6V+=C06;F6V+=y56;$(this[F6V][N6V]);if(this[U06][d6V]){return e86;}var names=this[N2P](inNames);for(var i=G2CC[313785],ien=names[z76];i < ien;i++){if(this[c8R](names[i])[j9P]()){return e86;}}return G2CC[539444];}function inline(cell,fieldName,opts){var S9P="line at a time";var O9P="dividual";var N9P="Object";var P9P="Cannot edit m";var v9P='div.DTE_Field';var w9P="ore than one ro";var W9P="w in";var y6V=f9P;y6V+=I1R;y6V+=V36;var r6V=n7R;r6V+=k56;r6V+=B06;var S6V=I1R;S6V+=O9P;var W6V=k56;W6V+=n06;W6V+=c9P;var w6V=J06;w6V+=L06;var P6V=F9P;P6V+=I1R;P6V+=N9P;var _this=this;var that=this;if($[P6V](fieldName)){opts=fieldName;fieldName=undefined;}opts=$[w6V]({},this[U06][d9P][W6V],opts);var editFields=this[f8R](S6V,cell,fieldName);var keys=Object[F1R](editFields);if(keys[z76] > S16){var v6V=P9P;v6V+=w9P;v6V+=W9P;v6V+=S9P;throw new Error(v6V);}var editRow=editFields[keys[G2CC[313785]]];var hosts=[];for(var i=G2CC[313785];i < editRow[y1R][z76];i++){hosts[h76](editRow[y1R][i]);}if($(v9P,hosts)[z76]){return this;}if(this[H9P](function(){var H6V=f9P;H6V+=r9P;h52.m52();that[H6V](cell,fieldName,opts);})){return this;}this[r6V](cell,editFields,y6V,opts,function(){h52.Q52();var y9P="_inline";_this[y9P](editFields,opts);});return this;}function inlineCreate(insertPoint,opts){var l3P="fake";var C3P="modi";var p3P="ormOptio";var t3P="Ro";var E3P="isPlainOb";var R9P="tFiel";h52.m52();var k3P='initCreate';var n9V=B9P;n9V+=n3R;n9V+=S9R;var g9V=X1R;g9V+=R9P;g9V+=g06;g9V+=U06;var T9V=b9P;T9V+=c9P;var B9V=k56;B9V+=V9P;B9V+=r9P;var i9V=l56;i9V+=p3P;i9V+=o06;var E9V=J06;E9V+=L06;var C9V=l3P;C9V+=t3P;C9V+=e06;var t9V=C3P;t9V+=l56;t9V+=k56;t9V+=o9R;var l9V=D2P;l9V+=h46;var b6V=J1R;b6V+=a46;var R6V=E3P;R6V+=a76;var _this=this;if($[R6V](insertPoint)){opts=insertPoint;insertPoint=o86;}if(this[H9P](function(){h52.m52();_this[i3P](insertPoint,opts);})){return this;}$[b6V](this[U06][U2R],function(name,field){var p9V=h9R;p9V+=l56;var V6V=g06;V6V+=V36;V6V+=l56;field[d8R]();field[B3P](G2CC[313785],field[V6V]());h52.Q52();field[N76](field[p9V]());});this[U06][F8R]=b2P;this[U06][l9V]=R2P;this[U06][t9V]=o86;this[U06][N8R]=this[f8R](C9V,insertPoint);opts=$[E9V]({},this[U06][i9V][B9V],opts);this[l6P]();this[T9V](this[U06][g9V],opts,function(){var n3P='fakeRowEnd';var g3P="taSou";var J9V=T3P;J9V+=g56;h52.Q52();J9V+=g3P;J9V+=J3P;_this[J9V](n3P);});this[n9V](k3P,o86);return this;}function message(name,msg){var s3P="_message";h52.m52();if(msg === undefined){var k9V=g06;k9V+=C06;k9V+=y56;this[s3P](this[k9V][m3P],name);}else {var s9V=l56;s9V+=k56;s9V+=V36;s9V+=P1R;this[s9V](name)[x3P](msg);}return this;}function mode(mode){var q3P="ported";var L3P="Changing from ";var X3P='Not currently in an editing mode';var u3P="create mode is not s";var A9V=Q46;A9V+=A3P;var x9V=Q46;x9V+=A3P;var m9V=g56;m9V+=D3P;m9V+=Z3P;m9V+=n06;if(!mode){return this[U06][P3R];}if(!this[U06][m9V]){throw new Error(X3P);}else if(this[U06][P3R] === x9V && mode !== A9V){var D9V=L3P;D9V+=u3P;D9V+=o3P;D9V+=q3P;throw new Error(D9V);}this[U06][P3R]=mode;return this;}function modifier(){h52.m52();return this[U06][V2P];}function multiGet(fieldNames){var e3P="Get";h52.m52();var X9V=p46;X9V+=k56;X9V+=e3P;var that=this;if(fieldNames === undefined){var Z9V=d9R;Z9V+=q8R;Z9V+=U06;fieldNames=this[Z9V]();}if(Array[U1R](fieldNames)){var out={};$[Q76](fieldNames,function(i,name){h52.m52();out[name]=that[c8R](name)[U3P]();});return out;}return this[c8R](fieldNames)[X9V]();}function multiSet(fieldNames,val){var M3P="sPlainObject";var L9V=k56;L9V+=M3P;var that=this;if($[L9V](fieldNames) && val === undefined){var u9V=V36;u9V+=N9R;$[u9V](fieldNames,function(name,value){var o9V=l56;o9V+=k56;o9V+=q8R;h52.Q52();that[o9V](name)[B3P](value);});}else {this[c8R](fieldNames)[B3P](val);}return this;}function node(name){var M9V=R2R;M9V+=g06;M9V+=V36;h52.Q52();var e9V=p5R;e9V+=F46;var q9V=C3R;q9V+=E06;q9V+=G3P;var that=this;if(!name){name=this[S8R]();}return Array[q9V](name)?$[e9V](name,function(n){var U9V=n06;h52.m52();U9V+=C06;U9V+=g06;U9V+=V36;return that[c8R](n)[U9V]();}):this[c8R](name)[M9V]();}function off(name,fn){var K3P="Name";var G9V=U1P;h52.Q52();G9V+=K3P;$(this)[z5R](this[G9V](name),fn);return this;}function on(name,fn){$(this)[Y06](this[I3P](name),fn);return this;}function one(name,fn){var Q3P="ntNam";var I9V=B9P;I9V+=n6R;I9V+=Q3P;I9V+=V36;var K9V=C06;K9V+=n06;K9V+=V36;$(this)[K9V](this[I9V](name),fn);return this;}function open(){var a3P="_n";var Y3P="estedOpen";var O3P="yR";var z3P="Op";var c3P="eorder";var P9V=h3P;P9V+=D8R;var d9V=r6R;d9V+=u76;var N9V=X1R;N9V+=B06;N9V+=z3P;N9V+=j76;var j9V=a3P;j9V+=Y3P;var Y9V=y56;Y9V+=g56;Y9V+=k56;Y9V+=n06;var a9V=T2R;a9V+=L1P;a9V+=j3P;var Q9V=w2P;Q9V+=f3P;Q9V+=O3P;Q9V+=c3P;var _this=this;this[Q9V]();this[G1P](function(){_this[F3P](function(){var N3P="earD";var d3P="ynamicI";var z9V=p5R;z9V+=I1R;var h9V=q1P;h9V+=N3P;h9V+=d3P;h9V+=P3P;_this[h9V]();_this[U1P](M1P,[z9V]);});});var ret=this[a9V](Y9V);if(!ret){return this;}this[j9V](function(){var F9V=y56;F9V+=g56;F9V+=I1R;var c9V=V4R;c9V+=V36;c9V+=r6R;c9V+=g06;var O9V=T2R;O9V+=j6P;_this[w3P]($[x6R](_this[U06][S8R],function(name){var f9V=l56;f9V+=W3P;f9V+=g06;f9V+=U06;return _this[U06][f9V][name];}),_this[U06][Y6R][c1P]);_this[O9V](c9V,[F9V,_this[U06][P3R]]);},this[U06][N9V][d9V]);this[P9V](b2P,G2CC[539444]);return this;}function order(set){var V3P="o additional fields, must be provided for ordering.";var y3P="sort";var b3P="All fields, and n";var b9V=S3P;b9V+=v8R;var R9V=i06;R9V+=B06;R9V+=V36;R9V+=L06;var r9V=U06;r9V+=S3P;r9V+=B06;var H9V=U06;H9V+=v3P;H9V+=V36;var v9V=S3P;h52.m52();v9V+=v8R;var w9V=k6P;w9V+=X6R;if(!set){return this[U06][S8R];}if(arguments[z76] && !Array[w9V](set)){var S9V=U6R;S9V+=B86;S9V+=B86;var W9V=U06;W9V+=B86;W9V+=k56;W9V+=D2R;set=Array[H3P][W9V][S9V](arguments);}if(this[U06][v9V][r3P]()[y3P]()[R3P](B76) !== set[H9V]()[r9V]()[R3P](B76)){var y9V=b3P;y9V+=V3P;throw y9V;}$[R9V](this[U06][b9V],set);this[p0P]();return this;}function remove(items,arg1,arg2,arg3,arg4){var l0P="Rem";var E0P="ctionClass";var B0P='fields';var J3V=g06;J3V+=V06;var g3V=n06;g3V+=C06;g3V+=h9R;var T3V=I1R;T3V+=e7R;T3V+=l0P;T3V+=t0P;var B3V=C0P;B3V+=S9R;var i3V=e4R;i3V+=E0P;var E3V=K6R;E3V+=f2P;E3V+=B86;E3V+=X6R;var C3V=l56;C3V+=C06;C3V+=E06;C3V+=y56;var t3V=g06;t3V+=C06;t3V+=y56;var l3V=D2P;l3V+=h46;var p3V=B86;p3V+=M1R;var V9V=T2R;V9V+=b56;V9V+=g06;V9V+=w46;var _this=this;var that=this;if(this[V9V](function(){that[T1R](items,arg1,arg2,arg3,arg4);})){return this;}if(items[p3V] === undefined){items=[items];}var argOpts=this[i0P](arg1,arg2,arg3,arg4);var editFields=this[f8R](B0P,items);this[U06][l3V]=T1R;this[U06][V2P]=items;this[U06][N8R]=editFields;this[t3V][C3V][u5R][E3V]=T0P;this[i3V]();this[B3V](T3V,[pluck(editFields,g3V),pluck(editFields,J3V),items],function(){var J0P="tMultiRemove";h52.m52();var k3V=g0P;k3V+=J0P;var n3V=B9P;n3V+=n0P;_this[n3V](k3V,[editFields,items],function(){var Z0P="utto";var x0P="maybeOpen";var s0P="pts";var m0P="_assembleMain";var A0P="q";var m3V=l56;m3V+=k0P;var s3V=C06;s3V+=s0P;_this[m0P]();_this[g6P](argOpts[s3V]);argOpts[x0P]();h52.m52();var opts=_this[U06][Y6R];if(opts[m3V] !== o86){var D3V=V36;D3V+=A0P;var A3V=D0P;A3V+=u1P;A3V+=o06;var x3V=Z46;x3V+=Z0P;x3V+=n06;$(x3V,_this[n0R][A3V])[D3V](opts[c1P])[c1P]();}});});return this;}function set(set,val){var X0P="isP";var L0P="ainObject";var Z3V=X0P;Z3V+=B86;Z3V+=L0P;var that=this;h52.m52();if(!$[Z3V](set)){var o={};o[set]=val;set=o;}$[Q76](set,function(n,v){var L3V=U06;L3V+=V36;L3V+=B06;var X3V=l56;X3V+=Q9P;h52.Q52();that[X3V](n)[L3V](v);});return this;}function show(names,animate){var that=this;h52.m52();$[Q76](this[N2P](names),function(i,n){var u0P="show";var u3V=l56;u3V+=X8R;h52.m52();u3V+=P1R;that[u3V](n)[u0P](animate);});return this;}function submit(successCallback,errorCallback,formatdata,hide){var o0P="_proc";var G3V=M9R;G3V+=y76;var U3V=J1R;U3V+=a46;var e3V=o0P;e3V+=V36;e3V+=U06;e3V+=u6P;var q3V=g56;q3V+=q0P;q3V+=C06;q3V+=n06;var o3V=e0P;o3V+=U0P;o3V+=I1R;o3V+=q0R;var _this=this;var fields=this[U06][U2R],errorFields=[],errorReady=G2CC[313785],sent=G2CC[539444];if(this[U06][o3V] || !this[U06][q3V]){return this;}this[e3V](e86);var send=function(){var M0P='initSubmit';if(errorFields[z76] !== errorReady || sent){return;}h52.Q52();_this[U1P](M0P,[_this[U06][P3R]],function(result){if(result === G2CC[539444]){_this[G0P](G2CC[539444]);return;}sent=e86;h52.Q52();_this[K0P](successCallback,errorCallback,formatdata,hide);});};this[x1R]();$[U3V](fields,function(name,field){h52.m52();if(field[j9P]()){var M3V=F46;M3V+=d46;M3V+=U06;M3V+=y76;errorFields[M3V](name);}});$[G3V](errorFields,function(i,name){h52.Q52();fields[name][x1R](n76,function(){errorReady++;send();});});send();return this;}function table(set){h52.Q52();if(set === undefined){return this[U06][s2R];}this[U06][s2R]=set;return this;}function template(set){var K3V=G46;h52.Q52();K3V+=I0P;K3V+=B86;K3V+=f06;if(set === undefined){return this[U06][b6P];}this[U06][K3V]=set === o86?o86:$(set);return this;}function title(title){var Y0P="tml";var Q0P="ead";var z0P="ses";var h3V=i5R;h3V+=n06;h3V+=B06;var Q3V=y76;Q3V+=Q0P;Q3V+=o9R;var I3V=T8R;I3V+=h0P;I3V+=z0P;var header=$(this[n0R][W3R])[Z8R](a0P + this[I3V][Q3V][h3V]);if(title === undefined){var z3V=y76;z3V+=Y0P;return header[z3V]();}if(typeof title === G2CC[444023]){var a3V=B06;a3V+=g56;a3V+=Z46;a3V+=A06;title=title(this,new DataTable$4[v76](this[U06][a3V]));}header[Y9R](title);return this;}function val(field,value){var f3V=I9P;f3V+=B06;var Y3V=m7R;h52.m52();Y3V+=x7R;Y3V+=B06;if(value !== undefined || $[Y3V](field)){var j3V=U06;j3V+=V36;j3V+=B06;return this[j3V](field,value);}return this[f3V](field);;}function error(msg,tn,thro){var j0P=' For more information, please refer to https://datatables.net/tn/';var f0P="arn";if(thro === void G2CC[313785]){thro=e86;}var display=tn?msg + j0P + tn:msg;h52.m52();if(thro){throw display;}else {var O3V=e06;O3V+=f0P;console[O3V](display);}}function pairs(data,props,fn){var F0P="ab";var c3V=O0P;c3V+=E06;h52.Q52();c3V+=X6R;var i,ien,dataPoint;props=$[T76]({label:M6P,value:c0P},props);if(Array[c3V](data)){var F3V=A6P;F3V+=x5R;for((i=G2CC[313785],ien=data[F3V]);i < ien;i++){dataPoint=data[i];if($[P2R](dataPoint)){var P3V=Z1R;P3V+=B06;P3V+=E06;var d3V=B86;d3V+=F0P;d3V+=V36;d3V+=B86;var N3V=j9R;N3V+=h1R;fn(dataPoint[props[N0P]] === undefined?dataPoint[props[N3V]]:dataPoint[props[N0P]],dataPoint[props[d3V]],i,dataPoint[P3V]);}else {fn(dataPoint,dataPoint,i);}}}else {var w3V=V36;w3V+=N9R;i=G2CC[313785];$[w3V](data,function(key,val){fn(val,key,i);h52.Q52();i++;});}}function upload$1(editor,conf,files,progressCallback,completeCallback){var P0P="file";var v0P="Uploading file";var H0P="onload";var d0P="_limitLe";var W0P="am";var S0P='A server error occurred while uploading the file';var H5P="readAsDataURL";var w0P="ReadText";var W0V=d0P;W0V+=l56;W0V+=B06;var r3V=P0P;r3V+=w0P;var v3V=j6R;v3V+=h46;var S3V=n06;S3V+=W0P;S3V+=V36;h52.Q52();var W3V=o9R;W3V+=E06;W3V+=S3P;var reader=new FileReader();var counter=G2CC[313785];var ids=[];var generalError=S0P;editor[W3V](conf[S3V],n76);if(typeof conf[p7R] === v3V){conf[p7R](files,function(ids){var H3V=U6R;H3V+=s6R;completeCallback[H3V](editor,ids);});return;}progressCallback(conf,conf[r3V] || v0P);reader[H0P]=function(e){var y0P="ja";var C5P="ajaxData";var g5P='No Ajax option specified for upload plug-in';var V0P="dFie";var E5P="aja";var i5P="xData";var n5P="e `ajax.data` with an object. Please use it as a function instead.";var B5P="pload";var p5P="ctio";var t5P='upload';var b0P="uploa";var J5P="Upload feature cannot us";var l5P="ppend";var R0P="plo";var n0V=n06;n0V+=g56;n0V+=w9R;var J0V=G2P;J0V+=r0P;J0V+=d4R;J0V+=E6R;var g0V=T2R;g0V+=j6P;var C0V=g56;C0V+=y0P;C0V+=z46;var V3V=d46;V3V+=R0P;V3V+=g56;V3V+=g06;var b3V=b0P;b3V+=V0P;b3V+=P1R;var R3V=g56;R3V+=p5P;R3V+=n06;var y3V=g56;y3V+=l5P;var data=new FormData();h52.Q52();var ajax;data[y3V](R3V,t5P);data[H0R](b3V,conf[c9R]);data[H0R](V3V,files[counter]);if(conf[C5P]){var p0V=E5P;p0V+=i5P;conf[p0V](data,files[counter],counter);}if(conf[p7R]){var l0V=g56;l0V+=y0P;l0V+=z46;ajax=conf[l0V];}else if($[P2R](editor[U06][p7R])){var t0V=d46;t0V+=B5P;ajax=editor[U06][p7R][T5P]?editor[U06][p7R][t0V]:editor[U06][p7R];}else if(typeof editor[U06][C0V] === L76){var E0V=g56;E0V+=b8R;E0V+=g56;E0V+=z46;ajax=editor[U06][E0V];}if(!ajax){throw new Error(g5P);}if(typeof ajax === L76){ajax={url:ajax};}if(typeof ajax[f1R] === G2CC[444023]){var B0V=V36;B0V+=g56;B0V+=Q46;B0V+=y76;var i0V=g06;i0V+=g56;i0V+=B06;i0V+=g56;var d={};var ret=ajax[i0V](d);if(ret !== undefined && typeof ret !== L76){d=ret;}$[B0V](d,function(key,value){data[H0R](key,value);});}else if($[P2R](ajax[f1R])){var T0V=J5P;T0V+=n5P;throw new Error(T0V);}editor[g0V](J0V,[conf[n0V],files[counter],data],function(preRet){var s5P="preSubmit.D";var D5P="sDa";var X5P='post';var x5P="read";var m5P="TE_U";var Z5P="taURL";var D0V=i06;D0V+=k5P;var A0V=i6R;A0V+=V8R;var x0V=s5P;x0V+=m5P;x0V+=R0P;h52.m52();x0V+=E6R;var m0V=C06;m0V+=n06;if(preRet === G2CC[539444]){var k0V=A06;k0V+=a1R;if(counter < files[k0V] - S16){var s0V=x5P;s0V+=A5P;s0V+=D5P;s0V+=Z5P;counter++;reader[s0V](files[counter]);}else {completeCallback[V2R](editor,ids);}return;}var submit=G2CC[539444];editor[m0V](x0V,function(){submit=e86;return G2CC[539444];});$[A0V]($[D0V]({},ajax,{type:X5P,data:data,dataType:X6P,contentType:G2CC[539444],processData:G2CC[539444],xhr:function(){var q5P="onprogress";var Q5P="onloadend";var L5P="load";var u5P="xh";var o5P="xSettings";var L0V=d46;L0V+=F46;L0V+=L5P;var X0V=u5P;X0V+=E06;var Z0V=E5P;Z0V+=o5P;var xhr=$[Z0V][X0V]();if(xhr[L0V]){var u0V=b0P;u0V+=g06;xhr[u0V][q5P]=function(e){var e5P="lengthComputable";var M5P="loa";var I5P=':';var G5P="toFixed";var T26=100;if(e[e5P]){var U0V=A06;U0V+=a1R;var e0V=B86;e0V+=M1R;var q0V=B06;q0V+=U5P;q0V+=g56;q0V+=B86;var o0V=M5P;o0V+=g06;o0V+=V36;o0V+=g06;var percent=(e[o0V] / e[q0V] * T26)[G5P](G2CC[313785]) + K5P;progressCallback(conf,files[e0V] === S16?percent:counter + I5P + files[U0V] + u2P + percent);}};xhr[T5P][Q5P]=function(e){var z5P='Processing';var h5P="processingText";progressCallback(conf,conf[h5P] || z5P);};}return xhr;},success:function(json){var j5P='preSubmit.DTE_Upload';var c5P="fieldE";var f5P='uploadXhrSuccess';var d5P="rror";var a5P="oad";var P5P="readAsD";var F5P="ors";var w5P="ataURL";var a0V=d46;a0V+=F46;a0V+=B86;a0V+=a5P;h52.m52();var h0V=V36;h0V+=E06;h0V+=m1R;h0V+=E06;var G0V=Y5P;G0V+=U06;var M0V=C06;M0V+=l56;M0V+=l56;editor[M0V](j5P);editor[U1P](f5P,[conf[c9R],json]);if(json[O5P] && json[G0V][z76]){var K0V=c5P;K0V+=E06;K0V+=E06;K0V+=F5P;var errors=json[K0V];for(var i=G2CC[313785],ien=errors[z76];i < ien;i++){var Q0V=u76;Q0V+=Z1R;Q0V+=N5P;var I0V=n06;I0V+=g56;I0V+=y56;I0V+=V36;editor[x1R](errors[i][I0V],errors[i][Q0V]);}}else if(json[h0V]){var z0V=V36;z0V+=d5P;editor[z0V](json[x1R]);}else if(!json[T5P] || !json[a0V][z6R]){var Y0V=o9R;Y0V+=g46;editor[Y0V](conf[c9R],generalError);}else {var c0V=G9R;c0V+=q0R;c0V+=x5R;if(json[e9P]){var j0V=l56;j0V+=k56;j0V+=B86;j0V+=F76;$[Q76](json[j0V],function(table,files){var O0V=l56;O0V+=k56;O0V+=B86;O0V+=F76;var f0V=Z9R;f0V+=F76;if(!Editor[f0V][table]){Editor[e9P][table]={};}$[T76](Editor[O0V][table],files);});}ids[h76](json[T5P][z6R]);if(counter < files[c0V] - S16){var F0V=P5P;F0V+=w5P;counter++;reader[F0V](files[counter]);}else {completeCallback[V2R](editor,ids);if(submit){editor[g7R]();}}}progressCallback(conf);},error:function(xhr){var W5P="loadXhrError";var w0V=e1R;w0V+=w9R;var P0V=o3P;P0V+=W5P;var d0V=S5P;d0V+=K46;h52.m52();var N0V=n06;N0V+=g56;N0V+=w9R;editor[x1R](conf[N0V],generalError);editor[d0V](P0V,[conf[w0V],xhr]);progressCallback(conf);}}));});};files=$[x6R](files,function(val){h52.m52();return val;});if(conf[W0V] !== undefined){var S0V=A06;S0V+=a1R;files[C6R](conf[v5P],files[S0V]);}reader[H5P](files[G2CC[313785]]);}var DataTable$3=$[v0V][H0V];var __inlineCounter=G2CC[313785];function _actionClass(){var r5P="actions";var C5V=V76;C5V+=V36;var p5V=V36;p5V+=g06;p5V+=e7R;var V0V=Q46;V0V+=E06;V0V+=V36;V0V+=f06;var b0V=i4R;b0V+=E06;h52.m52();var R0V=g06;R0V+=C06;R0V+=y56;var y0V=g56;y0V+=Q46;y0V+=a1P;y0V+=n06;var r0V=G2R;r0V+=C8R;r0V+=V36;r0V+=U06;var classesActions=this[r0V][r5P];var action=this[U06][y0V];var wrapper=$(this[R0V][b0V]);wrapper[y5P]([classesActions[V0V],classesActions[D06],classesActions[T1R]][R3P](u2P));if(action === R2P){wrapper[r76](classesActions[R2P]);}else if(action === p5V){var t5V=V36;t5V+=K6R;t5V+=B06;var l5V=R5P;l5V+=C8R;wrapper[l5V](classesActions[t5V]);}else if(action === C5V){var E5V=a6R;E5V+=y56;E5V+=b5P;E5V+=V36;wrapper[r76](classesActions[E5V]);}}function _ajax(data,success,error,submitParams){var V5P="eteBod";var j4P='?';var U4P="complete";var Q4P=/_id_/;var i4P="ainObj";var z4P='DELETE';var e4P="url";var p4P="del";var B4P="editFie";h52.m52();var E4P="lacemen";var X4P='idSrc';var t4P="epla";var h4P=/{id}/;var G4P="replacem";var l4P="eteB";var a5V=g56;a5V+=b8R;a5V+=g56;a5V+=z46;var I5V=h9R;I5V+=B86;I5V+=V5P;I5V+=w46;var K5V=p4P;K5V+=l4P;K5V+=g1P;K5V+=w46;var G5V=g06;G5V+=g56;G5V+=B06;G5V+=g56;var q5V=t56;q5V+=s1R;var o5V=E06;o5V+=t4P;o5V+=Q46;o5V+=V36;var X5V=C4P;X5V+=E4P;X5V+=j76;var s5V=W6P;s5V+=i4P;s5V+=v6P;var k5V=B4P;k5V+=j1P;var action=this[U06][P3R];var thrown;var opts={type:Z6P,dataType:X6P,data:o86,error:[function(xhr,text,err){h52.m52();thrown=err;}],success:[],complete:[function(xhr,text){var J4P="bjec";var s4P="Te";var D4P="responseJSON";var g4P="isPlainO";var A4P="arse";var Z4P="responseText";var x4P='null';var g26=204;var k4P="ponse";var J26=400;var m4P="tus";var J5V=k56;J5V+=T4P;J5V+=E06;J5V+=G3P;var g5V=g4P;g5V+=J4P;g5V+=B06;var B5V=n4P;B5V+=k4P;B5V+=s4P;B5V+=p06;var i5V=u76;i5V+=g56;i5V+=m4P;var json=o86;if(xhr[i5V] === g26 || xhr[B5V] === x4P){json={};}else {try{var T5V=F46;T5V+=A4P;json=xhr[D4P]?xhr[D4P]:JSON[T5V](xhr[Z4P]);}catch(e){}}if($[g5V](json) || Array[J5V](json)){var n5V=U06;n5V+=B06;n5V+=g56;n5V+=m4P;success(json,xhr[n5V] >= J26,xhr);}else {error(xhr,text,thrown);}}]};var a;var ajaxSrc=this[U06][p7R];var id=action === A6R || action === o6R?pluck(this[U06][k5V],X4P)[R3P](L4P):o86;if($[s5V](ajaxSrc) && ajaxSrc[action]){ajaxSrc=ajaxSrc[action];}if(typeof ajaxSrc === G2CC[444023]){ajaxSrc(o86,o86,data,success,error);return;}else if(typeof ajaxSrc === L76){if(ajaxSrc[u4P](u2P) !== -S16){var m5V=c76;m5V+=B86;a=ajaxSrc[o4P](u2P);opts[q4P]=a[G2CC[313785]];opts[m5V]=a[S16];}else {opts[e4P]=ajaxSrc;}}else {var Z5V=i06;Z5V+=B06;Z5V+=T06;Z5V+=g06;var A5V=o9R;A5V+=g46;var x5V=i06;x5V+=B06;x5V+=T06;x5V+=g06;var optsCopy=$[x5V]({},ajaxSrc || ({}));if(optsCopy[U4P]){opts[U4P][H8R](optsCopy[U4P]);delete optsCopy[U4P];}if(optsCopy[A5V]){var D5V=M4P;D5V+=S3P;opts[x1R][H8R](optsCopy[D5V]);delete optsCopy[x1R];}opts=$[Z5V]({},opts,optsCopy);}if(opts[X5V]){var L5V=G4P;L5V+=T06;L5V+=j76;$[Q76](opts[L5V],function(key,repl){var K4P='{';var I4P='}';var u5V=h6R;u5V+=B86;opts[e4P]=opts[e4P][q76](K4P + key + I4P,repl[u5V](this,key,id,action,data));});}opts[e4P]=opts[e4P][o5V](Q4P,id)[q76](h4P,id);if(opts[q5V]){var M5V=V36;M5V+=j46;M5V+=g06;var U5V=l56;U5V+=c6R;U5V+=n06;var e5V=T56;e5V+=g56;var isFn=typeof opts[e5V] === U5V;var newData=isFn?opts[f1R](data):opts[f1R];data=isFn && newData?newData:$[M5V](e86,data,newData);}opts[G5V]=data;if(opts[q4P] === z4P && (opts[K5V] === undefined || opts[I5V] === e86)){var z5V=a4P;z5V+=Y4P;var h5V=d46;h5V+=E06;h5V+=B86;var Q5V=W9R;Q5V+=E06;Q5V+=g56;Q5V+=y56;var params=$[Q5V](opts[f1R]);opts[h5V]+=opts[e4P][z5V](j4P) === -S16?j4P + params:f4P + params;delete opts[f1R];}$[a5V](opts);}function _animate(target,style,time,callback){var O4P="ani";var j5V=O4P;j5V+=p5R;j5V+=G46;var Y5V=l56;Y5V+=n06;if($[Y5V][j5V]){target[c4P]()[s0R](style,time,callback);}else {target[m4R](style);if(typeof time === G2CC[444023]){var f5V=h6R;f5V+=B86;time[f5V](target);}else if(callback){var O5V=U6R;O5V+=s6R;callback[O5V](target);}}}function _assembleMain(){var N4P="prepen";var W5V=Z4R;W5V+=V36;W5V+=n06;W5V+=g06;var w5V=Z4R;w5V+=V36;w5V+=n06;w5V+=g06;var P5V=F4P;P5V+=S9R;var d5V=u06;d5V+=C06;d5V+=o06;var N5V=Z2R;N5V+=V6P;var F5V=Z4R;F5V+=V36;F5V+=L06;var c5V=N4P;c5V+=g06;var dom=this[n0R];$(dom[B0R])[c5V](dom[W3R]);$(dom[d4P])[F5V](dom[x1P])[N5V](dom[d5V]);$(dom[P5V])[w5V](dom[m3P])[W5V](dom[L2P]);}function _blur(){var W4P="Bl";var w4P="functi";var S4P="B";var y5V=Q46;y5V+=B86;y5V+=C06;y5V+=f6R;var r5V=P4P;r5V+=e7R;var H5V=w4P;H5V+=Y06;var v5V=L1P;v5V+=W4P;v5V+=c76;var S5V=Y06;S5V+=S4P;S5V+=A9R;S5V+=E06;var opts=this[U06][Y6R];var onBlur=opts[S5V];if(this[U1P](v5V) === G2CC[539444]){return;}if(typeof onBlur === H5V){onBlur(this);}else if(onBlur === r5V){this[g7R]();}else if(onBlur === y5V){var R5V=T2R;R5V+=Q46;R5V+=w0R;this[R5V]();}}function _clearDynamicInfo(errorsOnly){var C4V=V36;C4V+=E06;C4V+=g46;var l4V=g06;l4V+=C06;l4V+=y56;var p4V=g06;p4V+=k56;p4V+=n3R;p4V+=v4P;var V5V=d9R;V5V+=h1R;V5V+=g06;V5V+=U06;var b5V=H4P;b5V+=U06;b5V+=V36;b5V+=U06;if(errorsOnly === void G2CC[313785]){errorsOnly=G2CC[539444];}if(!this[U06]){return;}var errorClass=this[b5V][c8R][x1R];var fields=this[U06][V5V];$(p4V + errorClass,this[l4V][B0R])[y5P](errorClass);$[Q76](fields,function(name,field){field[x1R](n76);h52.Q52();if(!errorsOnly){var t4V=r4P;t4V+=G7R;field[t4V](n76);}});this[C4V](n76);if(!errorsOnly){var E4V=y4P;E4V+=q6P;this[E4V](n76);}}function _close(submitComplete,mode){var p8P="Cb";var b4P="closeC";var E8P="loseIcb";var i8P='focus.editor-focus';var C8P="Icb";var m4V=Q46;m4V+=h1P;m4V+=V36;var s4V=T2R;s4V+=R4P;s4V+=K46;var k4V=Y0R;k4V+=l56;var n4V=w4R;n4V+=W4R;var B4V=b4P;B4V+=Z46;var i4V=L1P;i4V+=V4P;i4V+=w0R;var closed;if(this[U1P](i4V) === G2CC[539444]){return;}if(this[U06][B4V]){var T4V=y6P;T4V+=V36;T4V+=p8P;closed=this[U06][T4V](submitComplete,mode);this[U06][l8P]=o86;}if(this[U06][t8P]){var J4V=T8R;J4V+=C06;J4V+=f6R;J4V+=C8P;var g4V=Q46;g4V+=E8P;this[U06][g4V]();this[U06][J4V]=o86;}$(n4V)[k4V](i8P);this[U06][i9P]=G2CC[539444];this[s4V](m4V);if(closed){var A4V=T8R;A4V+=C06;A4V+=U06;A4V+=G06;var x4V=T2R;x4V+=V36;x4V+=B8P;x4V+=B06;this[x4V](A4V,[closed]);}}function _closeReg(fn){h52.m52();this[U06][l8P]=fn;}function _crudArgs(arg1,arg2,arg3,arg4){var g8P="ole";var J8P="inObjec";h52.Q52();var k8P="main";var T8P="formOp";var u4V=T8P;u4V+=y7R;var L4V=X06;L4V+=V36;L4V+=n06;L4V+=g06;var Z4V=w4R;Z4V+=g8P;Z4V+=g56;Z4V+=n06;var D4V=F9P;D4V+=J8P;D4V+=B06;var that=this;var title;var buttons;var show;var opts;if($[D4V](arg1)){opts=arg1;}else if(typeof arg1 === Z4V){show=arg1;opts=arg2;;}else {title=arg1;buttons=arg2;show=arg3;opts=arg4;;}if(show === undefined){show=e86;}if(title){that[X1P](title);}if(buttons){var X4V=Z46;X4V+=d46;X4V+=n8P;X4V+=o06;that[X4V](buttons);}return {opts:$[L4V]({},this[U06][u4V][k8P],opts),maybeOpen:function(){h52.Q52();if(show){that[j3P]();}}};}function _dataSource(name){var s8P="ml";var q4V=y76;q4V+=B06;q4V+=s8P;var o4V=m8P;o4V+=y76;var args=[];h52.m52();for(var _i=S16;_i < arguments[o4V];_i++){args[_i - S16]=arguments[_i];}var dataSource=this[U06][s2R]?Editor[x8P][s86]:Editor[x8P][q4V];var fn=dataSource[name];if(fn){var e4V=Z2R;e4V+=F46;e4V+=P7R;return fn[e4V](this,args);}}function _displayReorder(includeFields){var Z8P="formContent";var A8P="childre";var G8P='displayOrder';var O4V=w1R;O4V+=B06;O4V+=h46;var K4V=h9R;K4V+=B06;K4V+=w1R;K4V+=y76;var G4V=A8P;G4V+=n06;var M4V=y56;M4V+=C06;M4V+=g06;M4V+=V36;var U4V=D8P;U4V+=f3P;U4V+=G46;var _this=this;var formContent=$(this[n0R][Z8P]);var fields=this[U06][U2R];var order=this[U06][S8R];var template=this[U06][U4V];var mode=this[U06][M4V] || b2P;if(includeFields){this[U06][j2P]=includeFields;}else {includeFields=this[U06][j2P];}formContent[G4V]()[K4V]();$[Q76](order,function(i,name){var u8P="-e";var o8P="ditor-t";var M8P="after";var U8P="name=";var e8P="editor-field[";var q8P="emplate=\"";var L8P="[data";if(_this[X8P](name,includeFields) !== -S16){if(template && mode === b2P){var Y4V=n06;Y4V+=C06;Y4V+=g06;Y4V+=V36;var a4V=x76;a4V+=A76;var z4V=L8P;z4V+=u8P;z4V+=o8P;z4V+=q8P;var h4V=d9R;h4V+=n06;h4V+=g06;var Q4V=e8P;Q4V+=U8P;Q4V+=x76;var I4V=l56;I4V+=X4R;template[I4V](Q4V + name + E9R)[M8P](fields[name][D1R]());template[h4V](z4V + name + a4V)[H0R](fields[name][Y4V]());}else {var f4V=n06;f4V+=C06;f4V+=h9R;var j4V=Z2R;j4V+=V6P;formContent[j4V](fields[name][f4V]());}}});if(template && mode === b2P){template[k1P](formContent);}this[U1P](G8P,[this[U06][i9P],this[U06][O4V],formContent]);}function _edit(items,editFields,type,formOptions,setupDone){var I8P="_actio";var S8P="toSt";var z8P="isplay";var Q8P="Clas";var H8P='initEdit';var a8P="modif";var T8V=t56;T8V+=s1R;var B8V=n6P;B8V+=V36;var i8V=S5P;i8V+=n06;i8V+=B06;var C8V=A06;C8V+=B9R;C8V+=B06;C8V+=y76;var t8V=U06;t8V+=K8P;t8V+=D2R;var l8V=C06;l8V+=E06;l8V+=h9R;l8V+=E06;var W4V=V36;h52.Q52();W4V+=w1R;W4V+=y76;var w4V=I8P;w4V+=n06;w4V+=Q8P;w4V+=U06;var P4V=h8P;P4V+=C06;P4V+=o0R;var d4V=g06;d4V+=z8P;var N4V=u76;N4V+=w46;N4V+=A06;var F4V=X1R;F4V+=B06;var c4V=a8P;c4V+=Y8P;var _this=this;var fields=this[U06][U2R];var usedFields=[];var includeInOrder;var editData={};this[U06][N8R]=editFields;this[U06][j8P]=editData;this[U06][c4V]=items;this[U06][P3R]=F4V;this[n0R][L2P][N4V][d4V]=P4V;this[U06][F8R]=type;this[w4V]();$[W4V](fields,function(name,field){var V4V=A06;V4V+=s9R;V4V+=y76;var b4V=p46;b4V+=f8P;b4V+=H1R;field[d8R]();includeInOrder=G2CC[539444];editData[name]={};$[Q76](editFields,function(idSrc,edit){var d8P="yFiel";var N8P="displa";var P8P="displayField";var O8P="scop";var c8P="Arra";var S4V=c8R;S4V+=U06;if(edit[S4V][name]){var H4V=O8P;H4V+=V36;var v4V=k56;v4V+=U06;v4V+=c8P;v4V+=w46;var val=field[L9R](edit[f1R]);var nullDefault=field[F8P]();editData[name][idSrc]=val === o86?n76:Array[v4V](val)?val[r3P]():val;if(!formOptions || formOptions[H4V] === Y2R){var r4V=N8P;r4V+=d8P;r4V+=g06;r4V+=U06;field[B3P](idSrc,val === undefined || nullDefault && val === o86?field[W8R]():val);if(!edit[r4V] || edit[p2R][name]){includeInOrder=e86;}}else {var y4V=P8P;y4V+=U06;if(!edit[y4V] || edit[p2R][name]){var R4V=P8R;R4V+=w8P;R4V+=B06;field[R4V](idSrc,val === undefined || nullDefault && val === o86?field[W8R]():val);includeInOrder=e86;}}}});if(field[b4V]()[V4V] !== G2CC[313785] && includeInOrder){var p8V=W8P;p8V+=U06;p8V+=y76;usedFields[p8V](name);}});var currOrder=this[l8V]()[t8V]();for(var i=currOrder[C8V] - S16;i >= G2CC[313785];i--){var E8V=S8P;E8V+=E06;E8V+=v8P;if($[l6R](currOrder[i][E8V](),usedFields) === -S16){currOrder[C6R](i,S16);}}this[p0P](currOrder);this[i8V](H8P,[pluck(editFields,B8V)[G2CC[313785]],pluck(editFields,T8V)[G2CC[313785]],items,type],function(){var r8P='initMultiEdit';_this[U1P](r8P,[editFields,items,type],function(){h52.Q52();setupDone();});});}function _event(trigger,args,promiseComplete){var p7P="Cancel";var l7P="objec";var b8P="Event";if(args === void G2CC[313785]){args=[];}if(promiseComplete === void G2CC[313785]){promiseComplete=undefined;}h52.m52();if(Array[U1R](trigger)){var g8V=B86;g8V+=T06;g8V+=K9R;for(var i=G2CC[313785],ien=trigger[g8V];i < ien;i++){var J8V=y8P;J8V+=B06;this[J8V](trigger[i],args);}}else {var s8V=F46;s8V+=E06;s8V+=V36;var k8V=a4P;k8V+=Y4P;var n8V=n4P;n8V+=R8P;var e=$[b8P](trigger);$(this)[V8P](e,args);var result=e[n8V];if(trigger[k8V](s8V) === G2CC[313785] && result === G2CC[539444]){var x8V=p7P;x8V+=A06;x8V+=g06;var m8V=l06;m8V+=n6R;m8V+=K46;$(this)[V8P]($[m8V](trigger + x8V),args);}if(promiseComplete){var A8V=l7P;A8V+=B06;if(result && typeof result === A8V && result[w6P]){result[w6P](promiseComplete);}else {promiseComplete(result);}}return result;}}function _eventName(input){var B7P="owerC";var H16=3;var C7P=/^on([A-Z])/;var E7P="subs";var i7P="toL";var name;var names=input[o4P](u2P);for(var i=G2CC[313785],ien=names[z76];i < ien;i++){var D8V=t7P;D8V+=Q46;D8V+=y76;name=names[i];var onStyle=name[D8V](C7P);if(onStyle){var X8V=E7P;X8V+=B06;X8V+=o76;var Z8V=i7P;Z8V+=B7P;Z8V+=h0P;Z8V+=V36;name=onStyle[S16][Z8V]() + name[X8V](H16);}names[i]=name;}return names[R3P](u2P);}function _fieldFromNode(node){var u8V=d9R;u8V+=h1R;u8V+=H1R;var L8V=V36;L8V+=g56;L8V+=a46;var foundField=o86;$[L8V](this[U06][u8V],function(name,field){var q8V=m8P;q8V+=y76;var o8V=d9R;o8V+=n06;h52.Q52();o8V+=g06;if($(field[D1R]())[o8V](node)[q8V]){foundField=field;}});return foundField;}function _fieldNames(fieldNames){if(fieldNames === undefined){return this[U2R]();}else if(!Array[U1R](fieldNames)){return [fieldNames];}h52.m52();return fieldNames;}function _focus(fieldsIn,focus){var T7P="Focus";var J7P="q:";var n7P='div.DTE ';var k7P=/^jq:/;var Q8V=U06;Q8V+=s8R;Q8V+=T7P;var G8V=y2P;G8V+=o9R;var U8V=y56;U8V+=g56;U8V+=F46;var e8V=g56;e8V+=Q46;e8V+=b56;e8V+=Y06;var _this=this;if(this[U06][e8V] === o6R){return;}var field;h52.Q52();var fields=$[U8V](fieldsIn,function(fieldOrName){var g7P="tring";var M8V=U06;M8V+=g7P;return typeof fieldOrName === M8V?_this[U06][U2R][fieldOrName]:fieldOrName;});if(typeof focus === G8V){field=fields[focus];}else if(focus){var K8V=b8R;K8V+=J7P;if(focus[u4P](K8V) === G2CC[313785]){field=$(n7P + focus[q76](k7P,n76));}else {var I8V=l56;I8V+=W3P;I8V+=g06;I8V+=U06;field=this[U06][I8V][focus];}}else {document[s7P][T7R]();}this[U06][Q8V]=field;if(field){var h8V=l56;h8V+=k0P;field[h8V]();}}function _formOptions(opts){var o7P="essage";var Z7P="editCo";var q7P='keydown';var A7P="strin";var M7P="canReturnSubmit";var D7P="essag";var L7P="itOp";var X7P="unt";var x7P="boolea";var u7P="dteInline";var m7P="Ic";var D7V=I5R;D7V+=m7P;D7V+=Z46;var R8V=g3R;R8V+=d46;R8V+=F46;var w8V=x7P;w8V+=n06;var P8V=K06;P8V+=I06;P8V+=C06;P8V+=o06;var F8V=y56;F8V+=V36;F8V+=U06;F8V+=q6P;var c8V=A7P;c8V+=q0R;var O8V=y56;O8V+=D7P;O8V+=V36;var j8V=b56;j8V+=B06;j8V+=A06;var Y8V=Z7P;Y8V+=X7P;var a8V=V36;a8V+=g06;a8V+=L7P;a8V+=j76;var z8V=v4P;z8V+=u7P;var _this=this;var that=this;var inlineCount=__inlineCounter++;var namespace=z8V + inlineCount;this[U06][a8V]=opts;this[U06][Y8V]=inlineCount;if(typeof opts[X1P] === L76 || typeof opts[j8V] === G2CC[444023]){var f8V=B06;f8V+=k56;f8V+=B06;f8V+=A06;this[X1P](opts[X1P]);opts[f8V]=e86;}if(typeof opts[O8V] === c8V || typeof opts[F8V] === G2CC[444023]){var d8V=y4P;d8V+=q6P;var N8V=y56;N8V+=o7P;this[N8V](opts[x3P]);opts[d8V]=e86;}if(typeof opts[P8V] !== w8V){var S8V=K06;S8V+=B06;S8V+=d56;var W8V=D0P;W8V+=d56;this[W8V](opts[S8V]);opts[h2P]=e86;}$(document)[Y06](q7P + namespace,function(e){var e7P="hich";var U7P="fieldFromNode";var G7P="preventD";var K7P="efa";var v8V=e06;v8V+=e7P;if(e[v8V] === R16 && _this[U06][i9P]){var el=$(document[s7P]);if(el){var r8V=j6R;r8V+=k56;r8V+=C06;r8V+=n06;var H8V=T2R;H8V+=U7P;var field=_this[H8V](el);if(field && typeof field[M7P] === r8V && field[M7P](el)){var y8V=G7P;y8V+=K7P;y8V+=R8P;e[y8V]();}}}});$(document)[Y06](R8V + namespace,function(e){var C26=27;var f7P="ubmi";var Q7P="ich";var Y7P="onRe";var i26=39;var E26=37;var P7P="Esc";var h7P="canReturnSubmi";var j7P="onReturn";var r7P="prev";var I7P="wh";var O7P="ventDefau";var p1b='button';var b7P="igg";var d7P="nEsc";var z7P="eldFrom";var w7P="onEsc";var N7P="unc";var V7P="next";var v7P='.DTE_Form_Buttons';var a7P="Node";var s7V=A6P;s7V+=B06;s7V+=y76;var i7V=I7P;i7V+=U7R;i7V+=y76;var b8V=e06;b8V+=y76;b8V+=Q7P;var el=$(document[s7P]);if(e[b8V] === R16 && _this[U06][i9P]){var p7V=h7P;p7V+=B06;var V8V=M76;V8V+=k56;V8V+=z7P;V8V+=a7P;var field=_this[V8V](el);if(field && typeof field[p7V] === G2CC[444023] && field[M7P](el)){var C7V=Y7P;C7V+=B06;C7V+=c76;C7V+=n06;if(opts[j7P] === D86){var t7V=U06;t7V+=f7P;t7V+=B06;var l7V=L1P;l7V+=O7P;l7V+=c7P;e[l7V]();_this[t7V]();}else if(typeof opts[C7V] === G2CC[444023]){var E7V=Y06;E7V+=F7P;e[Q2P]();opts[E7V](_this,e);}}}else if(e[i7V] === C26){var T7V=l56;T7V+=N7P;T7V+=B06;T7V+=h46;var B7V=C06;B7V+=d7P;e[Q2P]();if(typeof opts[B7V] === T7V){var g7V=Y06;g7V+=P7P;opts[g7V](that,e);}else if(opts[w7P] === X86){var J7V=h8P;J7V+=c76;that[J7V]();}else if(opts[w7P] === Z86){var n7V=Q46;n7V+=B86;n7V+=d5R;n7V+=V36;that[n7V]();}else if(opts[w7P] === D86){var k7V=U06;k7V+=W7P;that[k7V]();}}else if(el[S7P](v7P)[s7V]){if(e[e2P] === E26){var x7V=l56;x7V+=k0P;var m7V=Z46;m7V+=H7P;m7V+=Y06;el[r7P](m7V)[y7P](x7V);}else if(e[e2P] === i26){var A7V=R7P;A7V+=b7P;A7V+=o9R;el[V7P](p1b)[A7V](L86);}}});this[U06][D7V]=function(){var l1b="ydow";var L7V=g3R;L7V+=o3P;var X7V=n86;X7V+=V36;X7V+=l1b;X7V+=n06;var Z7V=C06;Z7V+=l56;Z7V+=l56;$(document)[Z7V](X7V + namespace);$(document)[z5R](L7V + namespace);};return namespace;}function _inline(editFields,opts,closeCb){var q1b="contents";var P1b="submitHtml";var T1b="\">
";var j1b="loses";var h1b="div";var a1b="ber";var x1b="
S16){var v1T=Z2R;v1T+=D8R;v1T+=g06;var S1T=C06;S1T+=D8R;var W1T=F46;W1T+=C06;W1T+=F46;show[W1T]();var last=show[show[z76] - S16];if(cb){cb();}this[U06][p9P][S1T](last[M2b],last[v1T],last[G2b]);}else {var y1T=m8P;y1T+=y76;var r1T=K2b;r1T+=f6R;var H1T=I2b;H1T+=B86;H1T+=Q2b;H1T+=h2b;this[U06][H1T][r1T](this,cb);show[y1T]=G2CC[313785];}}function _nestedOpen(cb,nest){var z2b="how";var a2b="_s";var C2T=D4R;C2T+=Z2R;C2T+=r2R;C2T+=E06;var t2T=g06;t2T+=C06;t2T+=y56;var l2T=V4R;l2T+=T06;var p2T=I2R;p2T+=y76;var disCtrl=this[U06][p9P];if(!disCtrl[U2b]){var R1T=T2R;R1T+=U06;R1T+=z2b;disCtrl[R1T]=[];}if(!nest){var V1T=A06;V1T+=s9R;V1T+=y76;var b1T=a2b;b1T+=y76;b1T+=k1R;disCtrl[b1T][V1T]=G2CC[313785];}disCtrl[U2b][p2T]({dte:this,append:this[n0R][B0R],callback:cb});this[U06][p9P][l2T](this,this[t2T][C2T],cb);}function _postopen(type,immediate){var W2b=".edi";var t6b='opened';var f2b="tiI";var w2b="focu";var S2b="tor-focus";var l6b='open';var O2b="ubbl";var N2b='submit.editor-internal';var Y2b="acti";var c2b="ptureF";var L2T=Y2b;L2T+=C06;L2T+=n06;var X2T=T2R;X2T+=j2b;X2T+=f2b;X2T+=P3P;var J2T=Z46;J2T+=O2b;J2T+=V36;var T2T=C06;T2T+=n06;var B2T=C06;B2T+=l56;B2T+=l56;var i2T=g06;i2T+=C06;i2T+=y56;var E2T=U6R;E2T+=c2b;E2T+=F2b;E2T+=N5P;h52.Q52();var _this=this;var focusCapture=this[U06][p9P][E2T];if(focusCapture === undefined){focusCapture=e86;}$(this[i2T][L2P])[B2T](N2b)[T2T](N2b,function(e){var P2b="fault";var d2b="preventDe";var g2T=d2b;g2T+=P2b;e[g2T]();});if(focusCapture && (type === b2P || type === J2T)){var n2T=w2b;n2T+=U06;n2T+=W2b;n2T+=S2b;$(s1P)[Y06](n2T,function(){var y2b="tiv";var R2b="eElement";var b2b='.DTED';var H2b="activeElemen";var p6b="etFoc";var v2b="arent";var V2b="setFocus";var r2b="rent";var D2T=F46;D2T+=v2b;D2T+=U06;var A2T=H2b;A2T+=B06;var x2T=B86;x2T+=T06;x2T+=K9R;var m2T=v4P;m2T+=k46;var s2T=F46;s2T+=g56;s2T+=r2b;s2T+=U06;var k2T=w1R;k2T+=y2b;k2T+=R2b;if($(document[k2T])[s2T](m2T)[x2T] === G2CC[313785] && $(document[A2T])[D2T](b2b)[z76] === G2CC[313785]){if(_this[U06][V2b]){var Z2T=U06;Z2T+=p6b;Z2T+=d46;Z2T+=U06;_this[U06][Z2T][c1P]();}}});}this[X2T]();this[U1P](l6b,[type,this[U06][L2T]]);if(immediate){this[U1P](t6b,[type,this[U06][P3R]]);}return e86;}function _preopen(type){var i6b="cInf";var E6b="ami";var k6b="Dyna";var B6b="preOp";var g6b="cb";var T6b="closeI";var n6b="elOpen";var C6b="_clearDyn";var s6b="micInfo";var m6b="seIcb";var h2T=g06;h2T+=L6R;h2T+=r6P;h2T+=G06;var Q2T=C6b;Q2T+=E6b;Q2T+=i6b;Q2T+=C06;var o2T=g56;o2T+=D3P;o2T+=k56;o2T+=Y06;var u2T=B6b;u2T+=T06;if(this[U1P](u2T,[type,this[U06][o2T]]) === G2CC[539444]){var K2T=T6b;K2T+=g6b;var G2T=J6b;G2T+=h9R;var M2T=f9P;M2T+=r9P;var U2T=q6R;U2T+=Q46;U2T+=n6b;var e2T=C0P;e2T+=V36;e2T+=K46;var q2T=w1b;q2T+=E06;q2T+=k6b;q2T+=s6b;this[q2T]();this[e2T](U2T,[type,this[U06][P3R]]);if((this[U06][F8R] === M2T || this[U06][G2T] === u7R) && this[U06][K2T]){var I2T=T8R;I2T+=C06;I2T+=m6b;this[U06][I2T]();}this[U06][t8P]=o86;return G2CC[539444];}this[Q2T](e86);this[U06][h2T]=type;return e86;}function _processing(processing){var Z6b="ive";var x6b="togg";var A6b="leC";var X6b='processing';var O2T=T2R;O2T+=V36;O2T+=B8P;O2T+=B06;var f2T=x6b;f2T+=A6b;f2T+=f5R;h52.Q52();f2T+=U06;var j2T=g06;j2T+=C06;j2T+=y56;var Y2T=D6b;Y2T+=k46;var a2T=g56;a2T+=Q46;a2T+=B06;a2T+=Z6b;var z2T=Q46;z2T+=L8R;z2T+=C8R;z2T+=F76;var procClass=this[z2T][s3R][a2T];$([Y2T,this[j2T][B0R]])[f2T](procClass,processing);this[U06][s3R]=processing;this[O2T](X6b,[processing]);}function _noProcessing(args){var L6b="ing-fie";var c2T=V36;c2T+=g56;c2T+=Q46;c2T+=y76;var processing=G2CC[539444];$[c2T](this[U06][U2R],function(name,field){h52.Q52();if(field[s3R]()){processing=e86;}});if(processing){var N2T=e0P;N2T+=U0P;N2T+=L6b;N2T+=P1R;var F2T=C06;F2T+=n06;F2T+=V36;this[F2T](N2T,function(){if(this[u6b](args) === e86){var d2T=o6b;d2T+=c1b;this[d2T][q6b](this,args);}});}return !processing;}function _submit(successCallback,errorCallback,formatdata,hide){var I6b="reat";var d6b='allIfChanged';var U6b="ionName";var G6b='Field is still processing';var p26=16;var e6b="reSubm";var x6T=F46;x6T+=e6b;x6T+=e7R;var H2T=G06;H2T+=e7R;var v2T=w1R;v2T+=B06;v2T+=U6b;var W2T=E2P;W2T+=y56;W2T+=e7R;var w2T=q1R;w2T+=U06;var P2T=l56;P2T+=k56;P2T+=F2R;var _this=this;var changed=G2CC[539444],allData={},changedData={};var setBuilder=dataSet;var fields=this[U06][P2T];var editCount=this[U06][M6b];var editFields=this[U06][w2T];var editData=this[U06][j8P];var opts=this[U06][Y6R];var changedSubmit=opts[W2T];var submitParamsLocal;if(this[u6b](arguments) === G2CC[539444]){var S2T=V36;S2T+=E06;S2T+=g46;Editor[S2T](G6b,p26,G2CC[539444]);return;}var action=this[U06][P3R];var submitParams={"data":{}};submitParams[this[U06][v2T]]=action;if(action === R2P || action === H2T){var n6T=K6b;n6T+=q0R;n6T+=G06;var J6T=g56;J6T+=s6R;var g6T=Q46;g6T+=I6b;g6T+=V36;var r2T=J1R;r2T+=a46;$[r2T](editFields,function(idSrc,edit){var Q6b="isE";var h6b="mptyObj";h52.Q52();var T6T=Q6b;T6T+=h6b;T6T+=v6P;var allRowData={};var changedRowData={};$[Q76](fields,function(name,field){var j6b="repl";var z6b="submittable";var f6b="ndexOf";var a6b="mpa";h52.Q52();var O6b="rin";var c6b="valF";var F6b="mDa";var N6b=/\[.*$/;var Y6b="-many-cou";var y2T=l56;y2T+=X8R;y2T+=j1P;if(edit[y2T][name] && field[z6b]()){var B6T=o2R;B6T+=a6b;B6T+=E06;B6T+=V36;var i6T=V36;i6T+=g06;i6T+=k56;i6T+=B06;var E6T=Y6b;E6T+=K46;var C6T=j6b;C6T+=g56;C6T+=D2R;var t6T=m9R;t6T+=A76;var l6T=k56;l6T+=f6b;var p6T=U06;p6T+=B06;p6T+=O6b;p6T+=q0R;var V2T=O0P;V2T+=y3R;V2T+=w46;var multiGet=field[U3P]();var builder=setBuilder(name);if(multiGet[idSrc] === undefined){var b2T=t56;b2T+=B06;b2T+=g56;var R2T=c6b;R2T+=m1R;R2T+=F6b;R2T+=s1R;var originalVal=field[R2T](edit[b2T]);builder(allRowData,originalVal);return;}var value=multiGet[idSrc];var manyBuilder=Array[V2T](value) && typeof name === p6T && name[l6T](t6T) !== -S16?setBuilder(name[C6T](N6b,n76) + E6T):o86;builder(allRowData,value);if(manyBuilder){manyBuilder(allRowData,value[z76]);}if(action === i6T && (!editData[name] || !field[B6T](value,editData[name][idSrc]))){builder(changedRowData,value);changed=e86;if(manyBuilder){manyBuilder(changedRowData,value[z76]);}}}});if(!$[G1R](allRowData)){allData[idSrc]=allRowData;}if(!$[T6T](changedRowData)){changedData[idSrc]=changedRowData;}});if(action === g6T || changedSubmit === J6T || changedSubmit === d6b && changed){submitParams[f1R]=allData;}else if(changedSubmit === n6T && changed){var k6T=t56;k6T+=B06;k6T+=g56;submitParams[k6T]=changedData;}else {this[U06][P3R]=o86;if(opts[P6b] === Z86 && (hide === undefined || hide)){var s6T=T9P;s6T+=d4R;s6T+=f6R;this[s6T](G2CC[539444]);}else if(typeof opts[P6b] === G2CC[444023]){opts[P6b](this);}if(successCallback){successCallback[V2R](this);}this[G0P](G2CC[539444]);this[U1P](w6b);return;}}else if(action === T1R){$[Q76](editFields,function(idSrc,edit){h52.Q52();var m6T=t56;m6T+=B06;m6T+=g56;submitParams[f1R][idSrc]=edit[m6T];});}submitParamsLocal=$[T76](e86,{},submitParams);if(formatdata){formatdata(submitParams);}this[U1P](x6T,[submitParams,action],function(result){h52.Q52();var S6b="oce";if(result === G2CC[539444]){var A6T=W6b;A6T+=S6b;A6T+=v6b;_this[A6T](G2CC[539444]);}else {var D6T=g56;D6T+=b8R;D6T+=V8R;var submitWire=_this[U06][D6T]?_this[H6b]:_this[r6b];submitWire[V2R](_this,submitParams,function(json,notGood,xhr){_this[y6b](json,notGood,submitParams,submitParamsLocal,_this[U06][P3R],editCount,hide,successCallback,errorCallback,xhr);},function(xhr,err,thrown){h52.m52();var R6b="itError";var Z6T=o6b;Z6T+=B2P;Z6T+=R6b;_this[Z6T](xhr,err,thrown,errorCallback,submitParams,_this[U06][P3R]);},submitParams);}});}function _submitTable(data,success,error,submitParams){var b6b="dS";var V6b="mai";var X6T=k56;X6T+=b6b;X6T+=d2R;var action=data[P3R];var out={data:[]};var idGet=dataGet(this[U06][X6T]);var idSet=dataSet(this[U06][C2R]);if(action !== o6R){var q6T=t56;q6T+=s1R;var o6T=d9R;o6T+=h1R;o6T+=g06;o6T+=U06;var u6T=V6b;u6T+=n06;var L6T=y56;L6T+=C06;L6T+=g06;L6T+=V36;var originalData=this[U06][L6T] === u6T?this[f8R](o6T,this[V2P]()):this[f8R](L7R,this[V2P]());$[Q76](data[q6T],function(key,vals){var l9b="String";var G6T=g06;G6T+=g56;G6T+=B06;h52.m52();G6T+=g56;var U6T=p9b;U6T+=V36;U6T+=Z1R;U6T+=V36;var e6T=G06;e6T+=e7R;var toSave;var extender=extend;if(action === e6T){var rowData=originalData[key][f1R];toSave=extender({},rowData,e86);toSave=extender(toSave,vals,e86);}else {toSave=extender({},vals,e86);}var overrideId=idGet(toSave);if(action === U6T && overrideId === undefined){var M6T=B06;M6T+=C06;M6T+=l9b;idSet(toSave,+new Date() + key[M6T]());}else {idSet(toSave,overrideId);}out[G6T][h76](toSave);});}success(out);}function _submitSuccess(json,notGood,submitParams,submitParamsLocal,action,editCount,hide,successCallback,errorCallback,xhr){var z9b="dataSource";var L9b='
';var K9b="_dataS";var w9b='submitSuccess';var a9b="reEdit";var N9b="ids";var Y9b='commit';var M9b='setData';var E9b="Opts";var B9b="fieldErro";var j9b="postRe";var q9b="Source";var e9b='prep';var h9b="postE";var o9b="_data";var I9b='preCreate';var Q9b='postCreate';var g9b="fieldErr";var u9b='submitUnsuccessful';var G9b="rea";var c9b="preR";var O9b="ataSou";var t9b="Errors";var d9b="fun";var f6T=A06;f6T+=s9R;f6T+=y76;var j6T=l56;j6T+=X8R;j6T+=P1R;j6T+=t9b;var Y6T=V36;Y6T+=E06;Y6T+=m1R;Y6T+=E06;var h6T=M4P;h6T+=C06;h6T+=E06;var Q6T=C0P;Q6T+=S9R;var I6T=C9b;I6T+=k56;I6T+=l56;I6T+=Y8P;var K6T=V36;K6T+=K6R;K6T+=B06;K6T+=E9b;var _this=this;var that=this;var setData;var fields=this[U06][U2R];var opts=this[U06][K6T];var modifier=this[U06][I6T];this[Q6T](i9b,[json,submitParams,action,xhr]);if(!json[h6T]){var z6T=M4P;z6T+=C06;z6T+=E06;json[z6T]=u3R;}if(!json[O5P]){var a6T=B9b;a6T+=T9b;json[a6T]=[];}if(notGood || json[Y6T] || json[j6T][f6T]){var b6T=b8R;b6T+=C06;b6T+=k56;b6T+=n06;var F6T=g9b;F6T+=C06;F6T+=E06;F6T+=U06;var c6T=J1R;c6T+=Q46;c6T+=y76;var O6T=V36;O6T+=J9b;O6T+=S3P;var globalError=[];if(json[O6T]){globalError[h76](json[x1R]);}$[c6T](json[F6T],function(i,err){h52.Q52();var s9b="nknown fie";var X9b="Err";var D9b="onFieldError";var Z9b="position";var m9b="ld:";var A9b="status";var n9b="layed";var k9b="ame";var P6T=K6R;P6T+=U06;P6T+=F46;P6T+=n9b;var N6T=n06;N6T+=k9b;var field=fields[err[N6T]];if(!field){var d6T=G9P;d6T+=s9b;d6T+=m9b;d6T+=s1b;throw new Error(d6T + err[c9R]);}else if(field[P6T]()){var w6T=x9b;w6T+=g46;field[x1R](err[A9b] || w6T);if(i === G2CC[313785]){if(opts[D9b] === L86){var H6T=l56;H6T+=k0P;var v6T=B06;v6T+=C06;v6T+=F46;var S6T=n06;S6T+=C06;S6T+=g06;S6T+=V36;var W6T=F4P;W6T+=S9R;_this[G4R]($(_this[n0R][W6T]),{scrollTop:$(field[S6T]())[Z9b]()[v6T]},n26);field[H6T]();}else if(typeof opts[D9b] === G2CC[444023]){opts[D9b](_this,err);}}}else {var R6T=X9b;R6T+=S3P;var y6T=X1b;y6T+=s1b;var r6T=F46;r6T+=d46;r6T+=U06;r6T+=y76;globalError[r6T](field[c9R]() + y6T + (err[A9b] || R6T));}});this[x1R](globalError[b6T](L9b));this[U1P](u9b,[json]);if(errorCallback){errorCallback[V2R](that,json);}}else {var m9T=a6R;m9T+=J6b;m9T+=n3R;m9T+=V36;var V6T=V36;V6T+=K6R;V6T+=B06;var store={};if(json[f1R] && (action === R2P || action === V6T)){var s9T=o9b;s9T+=q9b;var p9T=G9R;p9T+=T3R;p9T+=y76;this[f8R](e9b,action,modifier,submitParamsLocal,json,store);for(var i=G2CC[313785];i < json[f1R][p9T];i++){var i9T=V36;i9T+=g06;i9T+=k56;i9T+=B06;setData=json[f1R][i];var id=this[f8R](U9b,setData);this[U1P](M9b,[json,setData,action]);if(action === R2P){var E9T=C0P;E9T+=S9R;var C9T=Q46;C9T+=G9b;C9T+=B06;C9T+=V36;var t9T=K9b;t9T+=C06;t9T+=c76;t9T+=D2R;var l9T=T2R;l9T+=V36;l9T+=n0P;this[l9T](I9b,[json,setData,id]);this[t9T](C9T,fields,setData,store);this[E9T]([m6R,Q9b],[json,setData,id]);}else if(action === i9T){var k9T=h9b;k9T+=t06;var n9T=V36;n9T+=K6R;n9T+=B06;var J9T=X1R;J9T+=B06;var g9T=T2R;g9T+=z9b;var T9T=F46;T9T+=a9b;var B9T=T2R;B9T+=V36;B9T+=B8P;B9T+=B06;this[B9T](T9T,[json,setData,id]);this[g9T](J9T,modifier,fields,setData,store);this[U1P]([n9T,k9T],[json,setData,id]);}}this[s9T](Y9b,action,modifier,json[f1R],store);}else if(action === m9T){var L9T=g06;L9T+=V06;var X9T=z6R;X9T+=U06;var Z9T=j9b;Z9T+=f9b;var D9T=T3P;D9T+=O9b;D9T+=J3P;var A9T=c9b;A9T+=F9b;A9T+=n3R;A9T+=V36;var x9T=y8P;x9T+=B06;this[f8R](e9b,action,modifier,submitParamsLocal,json,store);this[x9T](A9T,[json,this[N9b]()]);this[D9T](o6R,modifier,fields,store);this[U1P]([o6R,Z9T],[json,this[X9T]()]);this[f8R](Y9b,action,modifier,json[L9T],store);}if(editCount === this[U06][M6b]){var G9T=d9b;G9T+=C7R;var M9T=Y06;M9T+=P9b;var q9T=Q46;q9T+=B86;q9T+=T86;var o9T=g56;o9T+=q0P;o9T+=C06;o9T+=n06;var u9T=D2P;u9T+=k56;u9T+=C06;u9T+=n06;var action_1=this[U06][u9T];this[U06][o9T]=o86;if(opts[P6b] === q9T && (hide === undefined || hide)){var U9T=g06;U9T+=g56;U9T+=B06;U9T+=g56;var e9T=T2R;e9T+=T8R;e9T+=C06;e9T+=f6R;this[e9T](json[U9T]?e86:G2CC[539444],action_1);}else if(typeof opts[M9T] === G9T){opts[P6b](this);}}if(successCallback){var K9T=Q46;K9T+=g56;K9T+=B86;K9T+=B86;successCallback[K9T](that,json);}this[U1P](w9b,[json,setData,action]);}this[G0P](G2CC[539444]);this[U1P](w6b,[json,setData,action]);}function _submitError(xhr,err,thrown,errorCallback,submitParams,action){var W9b="submitComplet";var v9b='submitError';var S9b="sy";var z9T=W9b;z9T+=V36;var h9T=B9P;h9T+=n6R;h9T+=K46;var Q9T=S9b;Q9T+=U06;Q9T+=D8P;var I9T=V36;I9T+=J9b;I9T+=C06;I9T+=E06;this[U1P](i9b,[o86,submitParams,action,xhr]);this[I9T](this[Q5R][x1R][Q9T]);this[G0P](G2CC[539444]);if(errorCallback){errorCallback[V2R](this,xhr,err,thrown);}this[h9T]([v9b,z9T],[xhr,err,thrown,submitParams]);}function _tidy(fn){var r16=10;var R9b="bS";var y9b="dataTabl";var V9b="tings";var b9b="rverSide";var P9T=K6R;P9T+=A2b;var d9T=I1R;d9T+=B86;d9T+=I1R;d9T+=V36;var F9T=H9b;F9T+=U06;F9T+=r9b;F9T+=q0R;var f9T=A5P;f9T+=F46;f9T+=k56;var j9T=y9b;j9T+=V36;var Y9T=l56;Y9T+=n06;var a9T=B6R;a9T+=A06;var _this=this;var dt=this[U06][a9T]?new $[Y9T][j9T][f9T](this[U06][s2R]):o86;var ssp=G2CC[539444];if(dt){var c9T=R9b;c9T+=V36;c9T+=b9b;var O9T=N76;O9T+=V9b;ssp=dt[O9T]()[G2CC[313785]][Q6R][c9T];}if(this[U06][F9T]){var N9T=g7R;N9T+=P9b;this[p3b](N9T,function(){if(ssp){dt[p3b](w6R,fn);}else {setTimeout(function(){h52.m52();fn();},r16);}});return e86;}else if(this[e5R]() === d9T || this[P9T]() === u7R){var v9T=Z46;v9T+=B86;v9T+=d46;v9T+=E06;var w9T=T8R;w9T+=T86;this[p3b](w9T,function(){var l3b="Complet";h52.m52();if(!_this[U06][s3R]){setTimeout(function(){if(_this[U06]){fn();}},r16);}else {var W9T=t1b;W9T+=B06;W9T+=l3b;W9T+=V36;_this[p3b](W9T,function(e,json){h52.m52();if(ssp && json){var S9T=C06;S9T+=n06;S9T+=V36;dt[S9T](w6R,fn);}else {setTimeout(function(){if(_this[U06]){fn();}},r16);}});}})[v9T]();return e86;}return G2CC[539444];}function _weakInArray(name,arr){var H9T=G9R;H9T+=K9R;for(var i=G2CC[313785],ien=arr[H9T];i < ien;i++){if(name == arr[i]){return i;}}h52.Q52();return -S16;}var fieldType={create:function(){},get:function(){},set:function(){},enable:function(){},disable:function(){}};var DataTable$2=$[r9T][s86];function _buttonText(conf,text){var C3b="Choose file...";var i3b='div.upload button';var t3b="uploadText";var R9T=y76;R9T+=B06;R9T+=y56;R9T+=B86;var y9T=d9R;y9T+=L06;if(text === o86 || text === undefined){text=conf[t3b] || C3b;}conf[E3b][y9T](i3b)[R9T](text);}function _commonUpload(editor,conf,dropCallback,multiple){var b3b='input[type=file]';var x3b="File";var F3b="buttonInternal";var L3b="d\">';var q0b="Drop";var K3b="";var n3b="utton";var m3b="rop";var e3b="v class=\"cell ";var w3b='";var j3b="on class=\"";var S3b='
';var p0b="dro";var s0b='over';var f3b="
";var E0b='div.drop span';var s3b="agD";var h3b="ll clearV";var V3b="ragover";var A3b="Reader";var M3b="\">";var t0b="g and drop a file here to";var H3T=B3b;H3T+=B06;var v3T=C06;v3T+=n06;var P3T=c0R;P3T+=Q46;P3T+=n86;var d3T=C06;d3T+=n06;var N3T=T3b;N3T+=g3b;N3T+=J3b;N3T+=n3b;var X3T=k3b;X3T+=s3b;X3T+=m3b;var Z3T=x3b;Z3T+=A3b;var m3T=k56;m3T+=g06;var s3T=D3b;s3T+=Z3b;var k3T=n56;k3T+=K6R;k3T+=n3R;k3T+=A56;var n3T=L2R;n3T+=X3b;n3T+=L3b;n3T+=q56;var J3T=u3b;J3T+=V36;J3T+=o3b;var g3T=q3b;g3T+=B1b;var T3T=F7R;T3T+=e3b;T3T+=U3b;var B3T=M3b;B3T+=G3b;var i3T=K3b;i3T+=I06;i3T+=I3b;i3T+=A1b;var E3T=Q3b;E3T+=h3b;E3T+=z3b;var C3T=q3b;C3T+=B1b;var t3T=a3b;t3T+=V36;var l3T=Y3b;l3T+=j3b;var p3T=f3b;p3T+=e06;p3T+=X56;var V9T=J1b;V9T+=O3b;var b9T=Q46;b9T+=c3b;if(multiple === void G2CC[313785]){multiple=G2CC[539444];}var btnClass=editor[b9T][L2P][F3b];var container=$(N3b + V9T + p3T + d3b + l3T + btnClass + P3b + w3b + (multiple?t3T:n76) + W3b + C3T + E3T + i3T + btnClass + B3T + l4R + l4R + S3b + T3T + v3b + g3T + J3T + n3T + l4R + k3T + l4R + l4R);conf[E3b]=container;conf[s3T]=e86;if(conf[m3T]){var D3T=k56;D3T+=g06;var A3T=g56;A3T+=X2b;var x3T=I1R;x3T+=H3b;x3T+=r3b;x3T+=y3b;container[K1b](x3T)[A3T](U9b,Editor[R3b](conf[D3T]));}if(conf[X9R]){container[K1b](b3b)[X9R](conf[X9R]);}_buttonText(conf);if(window[Z3T] && conf[X3T] !== G2CC[539444]){var a3T=V4R;a3T+=T06;var z3T=C06;z3T+=n06;var I3T=g06;I3T+=V3b;var q3T=p0b;q3T+=F46;var o3T=d9R;o3T+=L06;var u3T=l0b;u3T+=t0b;u3T+=C0b;var L3T=l56;L3T+=k56;L3T+=L06;container[L3T](E0b)[Z2P](conf[i0b] || u3T);var dragDrop=container[o3T](B0b);dragDrop[Y06](q3T,function(e){var J0b="dataTransfe";var g0b="removeCla";var n0b="originalEvent";if(conf[T0b]){var G3T=C06;G3T+=n3R;G3T+=V36;G3T+=E06;var M3T=g0b;M3T+=C8R;var U3T=l56;U3T+=u9R;U3T+=V36;U3T+=U06;var e3T=J0b;e3T+=E06;Editor[T5P](editor,conf,e[n0b][e3T][U3T],_buttonText,dropCallback);dragDrop[M3T](G3T);}h52.m52();return G2CC[539444];})[Y06](k0b,function(e){var K3T=D3b;K3T+=B86;K3T+=G06;if(conf[K3T]){dragDrop[y5P](s0b);}h52.Q52();return G2CC[539444];})[Y06](I3T,function(e){var m0b="nab";var Q3T=B9P;Q3T+=m0b;Q3T+=Z3b;h52.m52();if(conf[Q3T]){var h3T=E6R;h3T+=x0b;h3T+=g56;h3T+=C8R;dragDrop[h3T](s0b);}return G2CC[539444];});editor[z3T](a3T,function(){var Z0b="Upload dro";var X0b="p.DTE_Upload";var A0b="dragove";var D0b="r.DTE_";var j3T=A0b;j3T+=D0b;j3T+=Z0b;j3T+=X0b;var Y3T=C06;Y3T+=n06;$(s1P)[Y3T](j3T,function(e){h52.Q52();return G2CC[539444];});})[Y06](Z86,function(){var u0b="ver.DTE_Upload d";var o0b="rop.DTE_Upload";var L0b="drago";var O3T=L0b;O3T+=u0b;O3T+=o0b;var f3T=Z46;f3T+=C06;f3T+=g06;f3T+=w46;$(f3T)[z5R](O3T);});}else {var F3T=g56;F3T+=z1b;F3T+=V36;F3T+=L06;var c3T=R2R;c3T+=q0b;container[r76](c3T);container[F3T](container[K1b](e0b));}container[K1b](N3T)[d3T](P3T,function(e){var M0b="ntDefault";h52.Q52();var W3T=T2R;W3T+=V36;W3T+=U0b;W3T+=G06;var w3T=L1P;w3T+=n6R;w3T+=M0b;e[w3T]();if(conf[W3T]){var S3T=Q46;S3T+=g56;S3T+=B86;S3T+=B86;upload[N76][S3T](editor,conf,n76);}});container[K1b](b3b)[v3T](H3T,function(){h52.Q52();Editor[T5P](editor,conf,this[e9P],_buttonText,function(ids){var R3T=n3R;R3T+=g56;R3T+=A9R;R3T+=V36;var y3T=l56;y3T+=k56;y3T+=n06;h52.m52();y3T+=g06;var r3T=Q46;r3T+=g56;r3T+=B86;r3T+=B86;dropCallback[r3T](editor,ids);container[y3T](b3b)[G2CC[313785]][R3T]=n76;});});return container;}function _triggerChange(input){setTimeout(function(){var b3T=K6b;b3T+=I9P;input[y7P](b3T,{editor:e86,editorSet:e86});h52.Q52();;},G2CC[313785]);}var baseFieldType=$[V3T](e86,{},fieldType,{get:function(conf){var p0T=T2R;p0T+=k56;p0T+=G0b;return conf[p0T][d6P]();},set:function(conf,val){conf[E3b][d6P](val);h52.m52();_triggerChange(conf[E3b]);},enable:function(conf){var K0b="isa";var t0T=g06;t0T+=K0b;t0T+=I0b;var l0T=F46;l0T+=E06;l0T+=C06;l0T+=F46;h52.m52();conf[E3b][l0T](t0T,G2CC[539444]);},disable:function(conf){var Q0b="isabled";var E0T=g06;h52.m52();E0T+=Q0b;var C0T=G2P;C0T+=V4R;conf[E3b][C0T](E0T,e86);},canReturnSubmit:function(conf,node){return e86;}});var hidden={create:function(conf){var B0T=n3R;B0T+=g56;B0T+=B86;B0T+=h0b;var i0T=T2R;i0T+=n3R;i0T+=g56;i0T+=B86;conf[i0T]=conf[B0T];return o86;},get:function(conf){return conf[z0b];},set:function(conf,val){var T0T=T2R;T0T+=n3R;T0T+=g56;h52.m52();T0T+=B86;conf[T0T]=val;}};var readonly=$[g0T](e86,{},baseFieldType,{create:function(conf){h52.m52();var O0b="= conf[x7T]?T0P:A7T);conf[v5P]=conf[D7T] - conf[Z7T][X7T];},create:function(conf){var k7b="_contai";var s7b="on.remove";var Q7T=k7b;Q7T+=n06;Q7T+=o9R;var U7T=Z46;U7T+=H7P;U7T+=s7b;var e7T=Q46;e7T+=B86;e7T+=g2P;var q7T=t6P;q7T+=c7P;q7T+=k56;var o7T=E6R;o7T+=x0b;o7T+=g56;h52.m52();o7T+=C8R;var editor=this;var container=_commonUpload(editor,conf,function(val){var m7b="concat";var u7T=n06;h52.Q52();u7T+=g56;u7T+=y56;u7T+=V36;var L7T=B9P;L7T+=n3R;L7T+=S9R;conf[z0b]=conf[z0b][m7b](val);uploadMany[N76][V2R](editor,conf,conf[z0b]);editor[L7T](N8b,[conf[u7T],conf[z0b]]);},e86);container[o7T](q7T)[Y06](e7T,U7T,function(e){var x7b="sto";var A7b="pPropagation";h52.Q52();var M7T=x7b;M7T+=A7b;e[M7T]();if(conf[T0b]){var I7T=U06;I7T+=V36;I7T+=B06;var K7T=U06;K7T+=F46;K7T+=v3P;K7T+=V36;var G7T=k56;G7T+=g06;G7T+=z46;var idx=$(this)[f1R](G7T);conf[z0b][K7T](idx,S16);uploadMany[I7T][V2R](editor,conf,conf[z0b]);}});conf[Q7T]=container;return container;},get:function(conf){var h7T=T2R;h7T+=E46;h7T+=B86;return conf[h7T];},set:function(conf,val){var L7b="div.rend";var D7b="triggerHa";var u7b='
    ';var K7b="pan>";var X7b='Upload collections must have an array as a value';var Z7b="dler";var Q7b="_showHide";var I7b='No files';var S7T=D7b;S7T+=n06;S7T+=Z7b;var W7T=I1R;W7T+=F46;W7T+=d46;W7T+=B06;var w7T=l56;w7T+=k56;w7T+=n06;w7T+=g06;var P7T=T2R;P7T+=k56;P7T+=n06;P7T+=w0b;var a7T=T2R;a7T+=k56;a7T+=n06;a7T+=w0b;var z7T=T2R;z7T+=n3R;z7T+=g56;z7T+=B86;if(!val){val=[];}h52.m52();if(!Array[U1R](val)){throw X7b;}conf[z7T]=val;conf[a7T][d6P](n76);var that=this;var container=conf[E3b];if(conf[e5R]){var j7T=X4b;j7T+=B06;j7T+=w46;var Y7T=L7b;Y7T+=o9R;Y7T+=G06;var rendered=container[K1b](Y7T)[j7T]();if(val[z76]){var list=$(u7b)[k1P](rendered);$[Q76](val,function(i,file){var U7b=' remove" data-idx="';var M7b='">×';var o7b=" ";var O7b="L";var T1G='fiBtp';var R7b="tableClass";var r7b=" G2CC[313785]?Math[u2C](pos / pageLen):G2CC[313785];}conf[o2C][q2C](page)[e2C](G2CC[539444]);}});var defaults={className:n76,compare:o86,data:n76,def:n76,entityDecode:e86,fieldInfo:n76,id:n76,label:n76,labelInfo:n76,name:o86,nullDefault:G2CC[539444],type:U2C,message:n76,multiEditable:e86,submit:e86,getFormatter:o86,setFormatter:o86};var DataTable$1=$[k86][M2C];var Field=(function(){var k2G="Info";var v9G="host";var B2G="rototy";var G6G="multiInfo";var E2G="tot";var J2G="iSet";var p2G="Src";var r1G="_errorNod";var U6G="input";var n2G="abe";var V1G="ulti";var y1G="proto";var n3G="multiEditable";var P1G="eFn";var B3G="slideDown";var n9G="multiValue";var i2G="ype";var T9G="_msg";var D2G="ieldIn";var b6G='display';var u9G="_format";var H1G="orma";var l2G="comp";var e3G="_multiValueCheck";var A2G="totyp";var H6G="_ty";var T2G="ullDef";var l9G="enabled";var D9G="ai";var x2G="Error";var C2G="prototyp";var W1G="typ";var s3G="multiIds";var d1G="_typ";var c9G="multiValues";var V6G="F";var v1G="_ms";var b1G="ltiInfoSh";var t2G="ototype";var K2G="si";var S1G="oto";var N1G="default";var Z2G="oty";var W6G="ift";var g2G="ault";var i9G="container";var G9G="labelInfo";var Z3G="formatters";var s2G="rototyp";var Q9G="multiRestore";var m2G="prototy";var m5C=N1G;m5C+=U06;var J5C=d1G;J5C+=P1G;var g5C=w1G;g5C+=C06;g5C+=W1G;g5C+=V36;var F0C=G2P;F0C+=S1G;F0C+=L0R;F0C+=r2R;var G0C=v1G;G0C+=q0R;var u0C=T2R;u0C+=l56;u0C+=H1G;u0C+=B06;var X0C=r1G;X0C+=V36;var A0C=g7R;A0C+=s2R;var x0C=y1G;x0C+=L0R;x0C+=F46;x0C+=V36;var m0C=w1G;m0C+=R1G;var k0C=t6P;k0C+=b1G;k0C+=E2b;var J0C=y56;J0C+=V1G;J0C+=W0b;J0C+=H1R;var C0C=f1R;C0C+=p2G;var t0C=e0P;t0C+=u1P;t0C+=W1G;t0C+=V36;var V3C=l2G;V3C+=g56;V3C+=a6R;var b3C=F46;b3C+=E06;b3C+=t2G;var H3C=C2G;H3C+=V36;var P3C=U06;P3C+=y76;P3C+=C06;P3C+=e06;var d3C=F46;d3C+=m1R;d3C+=E2G;d3C+=i2G;var Q3C=F46;Q3C+=B2G;Q3C+=r2R;var q3C=H9b;q3C+=v6b;var o3C=e0P;o3C+=E2G;o3C+=i2G;var u3C=n06;u3C+=T2G;u3C+=g2G;var L3C=n06;L3C+=g56;L3C+=y56;L3C+=V36;var X3C=y1G;X3C+=W1G;X3C+=V36;var n3C=y56;n3C+=d46;n3C+=c7P;n3C+=J2G;var C3C=w1G;C3C+=R1G;var l3C=y56;l3C+=Z9P;l3C+=g56;l3C+=I9P;var V9C=B86;V9C+=n2G;V9C+=B86;V9C+=k2G;var y9C=j9R;y9C+=h1R;var r9C=F46;r9C+=s2G;r9C+=V36;var d9C=G2P;d9C+=U5P;d9C+=R1G;var j9C=m2G;j9C+=r2R;var Q9C=J5b;Q9C+=d46;Q9C+=B06;var K9C=k56;K9C+=n06;K9C+=x2G;var U9C=e0P;U9C+=A2G;U9C+=V36;var o9C=l56;o9C+=D2G;o9C+=t46;var x9C=m2G;x9C+=r2R;var k9C=e0P;k9C+=B06;k9C+=R1G;var p9C=G2P;p9C+=t2G;var r6C=g06;r6C+=L6R;r6C+=w3R;var H6C=w1G;H6C+=Z2G;H6C+=r2R;function Field(options,classes,host){var N2G="restor";var a6G="side";var O2G="
    G2CC[313785] && !deepCompare(val,last)){different=e86;break;}last=val;}}if(different && isMultiValue || !isMultiEditable && this[q2b]()){var r0C=Z46;r0C+=B86;r0C+=C06;r0C+=o0R;var H0C=g06;H0C+=C06;H0C+=y56;var v0C=n06;v0C+=C06;v0C+=n06;v0C+=V36;var S0C=A4R;S0C+=U06;this[n0R][I3G][S0C]({display:v0C});this[H0C][P8R][m4R]({display:r0C});}else {var b0C=y56;b0C+=d46;b0C+=B86;b0C+=b56;var R0C=Q3G;R0C+=C06;R0C+=h3G;var y0C=A9P;y0C+=y56;this[y0C][R0C][m4R]({display:p6P});this[n0R][b0C][m4R]({display:T0P});if(isMultiValue && !different){var V0C=U06;V0C+=s8R;this[V0C](last,G2CC[539444]);}}this[p5C][l5C][m4R]({display:ids && ids[t5C] > S16 && different && !isMultiValue?C5C:T0P});var i18n=this[U06][v9G][A6G]()[P8R];this[E5C][G6G][Y9R](isMultiEditable?i18n[i5C]:i18n[z3G]);this[n0R][P8R][B5C](this[U06][p1P][a3G],!isMultiEditable);this[U06][v9G][T5C]();return e86;};Field[g5C][J5C]=function(name){var s5C=B06;s5C+=i2G;var k5C=d46;k5C+=n06;k5C+=m76;k5C+=W6G;var n5C=A06;n5C+=a1R;var args=[];for(var _i=S16;_i < arguments[n5C];_i++){args[_i - S16]=arguments[_i];}args[k5C](this[U06][k9P]);var fn=this[U06][s5C][name];if(fn){return fn[q6b](this[U06][v9G],args);}};Field[m5C]=defaults;Field[Z3G]={};return Field;})();var button={action:o86,className:o86,tabIndex:G2CC[313785],text:o86};var displayController={close:function(){},init:function(){},open:function(){},node:function(){}};var DataTable=$[x5C][A5C];var apiRegister=DataTable[v76][D5C];function __getInst(api){var Y3G="oI";var j3G="context";var X5C=B9P;X5C+=g06;X5C+=e7R;h52.m52();X5C+=S3P;var Z5C=Y3G;Z5C+=n06;Z5C+=k56;Z5C+=B06;var ctx=api[j3G][G2CC[313785]];return ctx[Z5C][A1G] || ctx[X5C];}function __setBasic(inst,opts,type,plural){var O3G="titl";var c3G="emove";var f3G="ssage";var N3G="rm";var d3G=/%d/;var e5C=w9R;e5C+=f3G;var o5C=O3G;o5C+=V36;if(!opts){opts={};}if(opts[h2P] === undefined){var u5C=T2R;u5C+=u0R;u5C+=U06;u5C+=U7R;var L5C=K06;L5C+=n8P;L5C+=n06;L5C+=U06;opts[L5C]=u5C;}if(opts[o5C] === undefined){var q5C=b56;q5C+=B06;q5C+=B86;q5C+=V36;opts[X1P]=inst[Q5R][type][q5C];}if(opts[e5C] === undefined){var U5C=E06;U5C+=c3G;if(type === U5C){var G5C=y4P;G5C+=U06;G5C+=F3G;G5C+=V36;var M5C=X5R;M5C+=d9R;M5C+=N3G;var confirm=inst[Q5R][type][M5C];opts[G5C]=plural !== S16?confirm[T2R][q76](d3G,plural):confirm[M5R];}else {opts[x3P]=n76;}}return opts;}apiRegister(P3G,function(){return __getInst(this);});apiRegister(w3G,function(opts){h52.Q52();var K5C=p9b;K5C+=a06;var inst=__getInst(this);inst[R2P](__setBasic(inst,opts,K5C));return this;});apiRegister(W3G,function(opts){var inst=__getInst(this);inst[D06](this[G2CC[313785]][G2CC[313785]],__setBasic(inst,opts,A6R));return this;});apiRegister(I5C,function(opts){var h5C=V36;h5C+=g06;h5C+=k56;h5C+=B06;var Q5C=V36;Q5C+=t06;var inst=__getInst(this);h52.m52();inst[Q5C](this[G2CC[313785]],__setBasic(inst,opts,h5C));return this;});apiRegister(z5C,function(opts){var a5C=V76;a5C+=V36;var inst=__getInst(this);inst[T1R](this[G2CC[313785]][G2CC[313785]],__setBasic(inst,opts,a5C,S16));h52.m52();return this;});apiRegister(Y5C,function(opts){var j5C=E06;j5C+=V36;h52.Q52();j5C+=y56;j5C+=t0P;var inst=__getInst(this);inst[j5C](this[G2CC[313785]],__setBasic(inst,opts,o6R,this[G2CC[313785]][z76]));return this;});apiRegister(f5C,function(type,opts){if(!type){var O5C=k56;O5C+=B2R;type=O5C;}else if($[P2R](type)){opts=type;type=i1b;}__getInst(this)[type](this[G2CC[313785]][G2CC[313785]],opts);return this;});apiRegister(S3G,function(opts){h52.Q52();__getInst(this)[Z7R](this[G2CC[313785]],opts);return this;});apiRegister(v3G,file);apiRegister(H3G,files);$(document)[c5C](r3G,function(e,ctx,json){var R3G='dt';var y3G="namespa";var F5C=y3G;F5C+=D2R;if(e[F5C] !== R3G){return;}if(json && json[e9P]){var N5C=V36;N5C+=g56;N5C+=Q46;N5C+=y76;$[N5C](json[e9P],function(name,files){var w5C=X06;w5C+=P4R;var d5C=l56;d5C+=k56;d5C+=B86;d5C+=F76;if(!Editor[d5C][name]){var P5C=l56;P5C+=k56;P5C+=A06;P5C+=U06;Editor[P5C][name]={};}$[w5C](Editor[e9P][name],files);});}});var _buttons=$[k86][s86][X06][h2P];$[W5C](_buttons,{create:{text:function(dt,node,config){var H5C=K06;H5C+=B06;H5C+=B06;H5C+=Y06;var v5C=k56;v5C+=b3G;var S5C=V3G;h52.Q52();S5C+=p0G;S5C+=n06;return dt[S5C](l0G,config[A1G][v5C][R2P][H5C]);},className:r5C,editor:o86,formButtons:{text:function(editor){var R5C=U06;R5C+=d46;R5C+=Z46;R5C+=l7R;var y5C=Q46;y5C+=A3P;return editor[Q5R][y5C][R5C];},action:function(e){var b5C=U06;b5C+=d46;b5C+=B2P;b5C+=e7R;this[b5C]();}},formMessage:o86,formOptions:{},formTitle:o86,action:function(e,dt,node,config){var B0G="messag";var J0G="eOp";var n0G="ito";var E0G="formT";var C0G="ptions";var g0G="But";var t0G="formO";var B4C=t0G;B4C+=C0G;var i4C=Q46;i4C+=E06;i4C+=J1R;i4C+=G46;var E4C=E0G;E4C+=i0G;E4C+=V36;var C4C=B0G;C4C+=V36;var t4C=k56;t4C+=F7b;t4C+=p0G;t4C+=n06;var l4C=l56;l4C+=T0G;l4C+=g0G;l4C+=d56;var p4C=G2P;p4C+=J0G;p4C+=T06;var V5C=G06;V5C+=n0G;V5C+=E06;var that=this;var editor=config[V5C];this[s3R](e86);editor[p3b](p4C,function(){h52.Q52();that[s3R](G2CC[539444]);})[R2P]($[T76]({buttons:config[l4C],message:config[k0G] || editor[t4C][R2P][C4C],title:config[E4C] || editor[Q5R][i4C][X1P],nest:e86},config[B4C]));}},createInline:{text:function(dt,node,config){var s0G="8n";var J4C=p9b;J4C+=O76;J4C+=V36;var g4C=V3G;g4C+=s0G;var T4C=D06;T4C+=C06;T4C+=E06;return dt[Q5R](l0G,config[T4C][g4C][J4C][h06]);},className:n4C,editor:o86,formButtons:{text:function(editor){var m4C=i2P;m4C+=Z46;m4C+=l7R;var s4C=p9b;s4C+=O76;s4C+=V36;var k4C=k56;k4C+=F7b;k4C+=p0G;k4C+=n06;return editor[k4C][s4C][m4C];},action:function(e){var x4C=U06;x4C+=d46;h52.m52();x4C+=c1b;this[x4C]();}},formOptions:{},action:function(e,dt,node,config){var x0G="po";var A0G="itio";var m0G="formOpt";var D4C=m0G;D4C+=k56;D4C+=b5b;h52.m52();var A4C=x0G;A4C+=U06;A4C+=A0G;A4C+=n06;config[A1G][i3P](config[A4C],config[D4C]);},position:D0G},edit:{extend:Z0G,text:function(dt,node,config){var L0G="i18";var X0G="uttons.e";var u4C=V36;u4C+=g06;u4C+=k56;u4C+=B06;var L4C=k56;L4C+=b3G;var X4C=Z46;X4C+=X0G;X4C+=K6R;X4C+=B06;h52.Q52();var Z4C=L0G;Z4C+=n06;return dt[Z4C](X4C,config[A1G][L4C][u4C][h06]);},className:o4C,editor:o86,formButtons:{text:function(editor){return editor[Q5R][D06][g7R];},action:function(e){var q4C=t1b;q4C+=B06;this[q4C]();}},formMessage:o86,formOptions:{},formTitle:o86,action:function(e,dt,node,config){var e0G="formButtons";var q0G='preOpen';var u0G="mOptions";var I4C=k7R;I4C+=u0G;var K4C=B06;K4C+=i0G;K4C+=V36;var G4C=V36;G4C+=g06;G4C+=e7R;var M4C=k56;M4C+=F7b;M4C+=p0G;M4C+=n06;var U4C=X1R;U4C+=B06;var e4C=m1R;e4C+=e06;e4C+=U06;var that=this;var editor=config[A1G];var rows=dt[e4C]({selected:e86})[o0G]();var columns=dt[x2R]({selected:e86})[o0G]();var cells=dt[t2R]({selected:e86})[o0G]();var items=columns[z76] || cells[z76]?{rows:rows,columns:columns,cells:cells}:rows;this[s3R](e86);editor[p3b](q0G,function(){h52.m52();that[s3R](G2CC[539444]);})[D06](items,$[T76]({buttons:config[e0G],message:config[k0G] || editor[Q5R][U4C][x3P],title:config[U0G] || editor[M4C][G4C][K4C],nest:e86},config[I4C]));}},remove:{extend:Q4C,limitTo:[h4C],text:function(dt,node,config){var M0G="ns.rem";var a4C=u06;a4C+=C06;a4C+=M0G;a4C+=t0P;var z4C=k56;z4C+=F7b;z4C+=p0G;z4C+=n06;return dt[z4C](a4C,config[A1G][Q5R][T1R][h06]);},className:Y4C,editor:o86,formButtons:{text:function(editor){var G0G="18";var f4C=E06;f4C+=V36;f4C+=J6b;f4C+=n6R;var j4C=k56;j4C+=G0G;j4C+=n06;return editor[j4C][f4C][g7R];},action:function(e){var K0G="ub";var I0G="mi";var O4C=U06;O4C+=K0G;O4C+=I0G;O4C+=B06;this[O4C]();}},formMessage:function(editor,dt){var h0G="ndexe";var z0G="confirm";var Q0G="irm";var S4C=A06;S4C+=n06;S4C+=q0R;S4C+=x5R;var W4C=C4P;W4C+=L8R;W4C+=D2R;var w4C=m8P;w4C+=y76;var P4C=X5R;P4C+=d9R;P4C+=E06;P4C+=y56;var d4C=U06;d4C+=B06;d4C+=E06;d4C+=v8P;var N4C=Q46;N4C+=Y06;N4C+=l56;N4C+=Q0G;var F4C=k56;F4C+=F7b;F4C+=p0G;F4C+=n06;var c4C=k56;c4C+=h0G;c4C+=U06;var rows=dt[d06]({selected:e86})[c4C]();var i18n=editor[F4C][T1R];var question=typeof i18n[N4C] === d4C?i18n[z0G]:i18n[P4C][rows[z76]]?i18n[z0G][rows[w4C]]:i18n[z0G][T2R];return question[W4C](/%d/g,rows[S4C]);},formOptions:{},formTitle:o86,action:function(e,dt,node,config){var a0G="formBu";var j0G="proces";var Y0G="eOpen";var l8C=b56;l8C+=Z2b;l8C+=V36;var p8C=J6R;p8C+=C06;p8C+=n6R;var V4C=k56;V4C+=F7b;V4C+=p0G;V4C+=n06;var b4C=a0G;b4C+=L46;var R4C=E06;R4C+=C06;R4C+=e06;R4C+=U06;var r4C=F46;r4C+=E06;r4C+=Y0G;var H4C=j0G;H4C+=U06;H4C+=v8P;var v4C=G06;v4C+=k56;v4C+=u1P;v4C+=E06;var that=this;var editor=config[v4C];this[H4C](e86);editor[p3b](r4C,function(){var f0G="roce";var y4C=F46;y4C+=f0G;y4C+=v6b;that[y4C](G2CC[539444]);})[T1R](dt[R4C]({selected:e86})[o0G](),$[T76]({buttons:config[b4C],message:config[k0G],title:config[U0G] || editor[V4C][p8C][l8C],nest:e86},config[d9P]));}}});_buttons[O0G]=$[t8C]({},_buttons[D06]);_buttons[C8C][T76]=E8C;_buttons[i8C]=$[B8C]({},_buttons[T1R]);_buttons[c0G][T8C]=F0G;var Editor=(function(){var d0G="efault";var H0G="rototype";var d5G="multiI";var w0G="sio";var v0G="lSettings";var W0G="Types";var S0G="inte";var d4G='2.0.5';h52.Q52();var y0G="rna";var r0G="internalMultiI";var N0G="dels";var P0G="safeI";var R0G="lEvent";var N16=J6b;N16+=N0G;var F16=g06;F16+=d0G;F16+=U06;var c16=P0G;c16+=g06;var O16=W9R;O16+=k56;O16+=E06;O16+=U06;var f16=O6P;f16+=g06;var j16=G2R;j16+=u8R;var Y16=n6R;Y16+=E06;Y16+=w0G;Y16+=n06;var a16=d9R;a16+=q8R;a16+=W0G;var z16=S0G;z16+=E06;z16+=e1R;z16+=v0G;var h16=F46;h16+=H0G;var I16=r0G;I16+=P3P;var G16=w1G;G16+=R1G;var M16=S0G;M16+=y0G;M16+=R0G;function Editor(init){var L5G="
    <";var F4G="Cannot find display contr";var W5G="_disp";var s4G="DataTables ";var b5G="inErr";var V0G="rig";var N5G="edOpe";var T4G="inline";var B5G="init.";var x5G="\">";e.edit.title='";e.remove.title='";a.extend(!0,a.fn.dataTable.Editor.classes,{header:{wrapper:"DTE_Header modal-header"},body:{wrapper:"DTE_Body modal-body"},footer:{wrapper:"DTE_Footer modal-footer"},form:{tag:"form-horizontal",button:"btn",buttonInternal:"btn btn-outline-secondary"},field:{wrapper:"DTE_Field form-group row",label:"col-lg-4 col-form-label", +input:"col-lg-8",error:"error is-invalid","msg-labelInfo":"form-text text-secondary small","msg-info":"form-text text-secondary small","msg-message":"form-text text-secondary small","msg-error":"form-text text-danger small",multiValue:"card multi-value",multiInfo:"small",multiRestore:"card multi-restore"}});a.extend(!0,d.ext.buttons,{create:{formButtons:{className:"btn-primary"}},edit:{formButtons:{className:"btn-primary"}},remove:{formButtons:{className:"btn-danger"}}});d.Editor.fieldTypes.datatable.tableClass= +"table";var f=!1,k=!1,l=a(''),v=a('
    '),n,u=b.bootstrap;d.Editor.bootstrap=function(g){u=g};d.Editor.display.bootstrap=a.extend(!0,{},d.Editor.models.displayController,{init:function(g){g.on("displayOrder.dtebs",function(h,m,q,r){a.each(g.s.fields,function(p,t){a("input:not([type=checkbox]):not([type=radio]), select, textarea",t.node()).addClass("form-control"); +a("input[type=checkbox], input[type=radio]",t.node()).addClass("form-check-input");a("select",t.node()).addClass("form-select")})});return d.Editor.display.bootstrap},open:function(g,h,m){n||(n=new u.Modal(l[0],{backdrop:"static",keyboard:!1}));a(h).addClass("modal-content");a(h).find("div.DTE_Field_Type_datatable div.dt-buttons").removeClass("btn-group").addClass("btn-group-vertical");v.attr("title",g.i18n.close).off("click.dte-bs5").on("click.dte-bs5",function(){g.close("icon")}).appendTo(a("div.modal-header", +h));var q=!1;a(c).off("mousedown.dte-bs5").on("mousedown.dte-bs5","div.modal",function(p){q=a(p.target).hasClass("modal")&&f?!0:!1});a(c).off("click.dte-bs5").on("click.dte-bs5","div.modal",function(p){a(p.target).hasClass("modal")&&q&&g.background()});var r=l.find("div.modal-dialog");r.children().detach();r.append(h);f?m&&m():(f=!0,k=!1,a(l).one("shown.bs.modal",function(){g.s.setFocus&&g.s.setFocus.focus();k=!0;m&&m()}).one("hidden",function(){f=!1}).appendTo("body"),n.show())},close:function(g, +h){if(f)if(k)a(l).one("hidden.bs.modal",function(){a(this).detach()}),n.hide(),k=f=!1,h&&h();else a(l).one("shown.bs.modal",function(){d.Editor.display.bootstrap.close(g,h)});else h&&h()},node:function(g){return l[0]}});return d.Editor}); \ No newline at end of file diff --git a/Modules/M3/Resources/public/liberty-theme/js/jquery.min.js b/Modules/M3/Resources/public/liberty-theme/js/jquery.min.js new file mode 100755 index 00000000..18bdbed7 --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/js/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c) +},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"
    Data table
    Code diff --git a/Modules/Countries/Routes/.gitkeep b/Modules/Countries/Routes/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Routes/web.php b/Modules/Countries/Routes/web.php old mode 100644 new mode 100755 index eaa78263..a5cb8346 --- a/Modules/Countries/Routes/web.php +++ b/Modules/Countries/Routes/web.php @@ -5,6 +5,8 @@ use Modules\Countries\Http\Controllers\CountriesController; use Modules\Countries\Http\Controllers\CountrySyncController; use Modules\Countries\Http\Controllers\ReferenceDataController; +const COUNTRY_ROUTE = '/{country}'; + Route::prefix('countries')->name('countries.')->middleware(['web', 'auth'])->group(function (): void { Route::get('/', CountriesController::class)->name('index'); Route::get('/create', [CountriesController::class, 'create'])->name('create'); @@ -15,8 +17,8 @@ Route::prefix('countries')->name('countries.')->middleware(['web', 'auth'])->gro Route::get('/reference/languages', [ReferenceDataController::class, 'languages'])->name('languages.index'); Route::get('/reference/scripts', [ReferenceDataController::class, 'scripts'])->name('scripts.index'); Route::get('/reference/locodes', [ReferenceDataController::class, 'locodes'])->name('locodes.index'); - Route::get('/{country:alpha2}', [CountriesController::class, 'show'])->name('show'); - Route::get('/{country:alpha2}/edit', [CountriesController::class, 'edit'])->name('edit'); - Route::put('/{country:alpha2}', [CountriesController::class, 'update'])->name('update'); - Route::delete('/{country:alpha2}', [CountriesController::class, 'destroy'])->name('destroy'); + Route::get(COUNTRY_ROUTE, [CountriesController::class, 'show'])->name('show'); + Route::get(COUNTRY_ROUTE . '/edit', [CountriesController::class, 'edit'])->name('edit'); + Route::put(COUNTRY_ROUTE, [CountriesController::class, 'update'])->name('update'); + Route::delete(COUNTRY_ROUTE, [CountriesController::class, 'destroy'])->name('destroy'); }); diff --git a/Modules/Countries/Rules/ValidCountryCode.php b/Modules/Countries/Rules/ValidCountryCode.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Rules/ValidIso3166CountryCode.php b/Modules/Countries/Rules/ValidIso3166CountryCode.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Rules/ValidIso3166SubdivisionCode.php b/Modules/Countries/Rules/ValidIso3166SubdivisionCode.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Support/.gitkeep b/Modules/Countries/Support/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Support/CountryRepository.php b/Modules/Countries/Support/CountryRepository.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Support/CountryUsageReport.php b/Modules/Countries/Support/CountryUsageReport.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Support/Iso3166.php b/Modules/Countries/Support/Iso3166.php old mode 100644 new mode 100755 index 49f457a5..a975e6ed --- a/Modules/Countries/Support/Iso3166.php +++ b/Modules/Countries/Support/Iso3166.php @@ -57,7 +57,7 @@ final class Iso3166 { $normalised = str_pad((string) $code, 3, '0', STR_PAD_LEFT); - if (! preg_match('/^[0-9]{3}$/', $normalised)) { + if (! preg_match('/^\d{3}$/', $normalised)) { throw new InvalidArgumentException('ISO 3166-1 numeric codes must contain exactly three digits.'); } diff --git a/Modules/Countries/Support/ModuleInfo.php b/Modules/Countries/Support/ModuleInfo.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Tests/Browser/.gitkeep b/Modules/Countries/Tests/Browser/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Tests/Feature/.gitkeep b/Modules/Countries/Tests/Feature/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Tests/Feature/CountriesModuleTest.php b/Modules/Countries/Tests/Feature/CountriesModuleTest.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Tests/Feature/Iso3166SupportTest.php b/Modules/Countries/Tests/Feature/Iso3166SupportTest.php old mode 100644 new mode 100755 diff --git a/Modules/Countries/Tests/Unit/.gitkeep b/Modules/Countries/Tests/Unit/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/Traits/.gitkeep b/Modules/Countries/Traits/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/View/.gitkeep b/Modules/Countries/View/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Countries/changelog.yaml b/Modules/Countries/changelog.yaml old mode 100644 new mode 100755 diff --git a/Modules/Countries/composer.json b/Modules/Countries/composer.json old mode 100644 new mode 100755 diff --git a/Modules/Countries/module.json b/Modules/Countries/module.json old mode 100644 new mode 100755 diff --git a/Modules/Countries/package.json b/Modules/Countries/package.json old mode 100644 new mode 100755 diff --git a/Modules/Countries/webpack.mix.js b/Modules/Countries/webpack.mix.js old mode 100644 new mode 100755 diff --git a/Modules/DocumentArchive/Entities/.gitkeep b/Modules/DocumentArchive/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/DocumentArchive/Providers/DocumentArchiveServiceProvider.php b/Modules/DocumentArchive/Providers/DocumentArchiveServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/DocumentArchive/README.md b/Modules/DocumentArchive/README.md deleted file mode 100644 index 8a740892..00000000 --- a/Modules/DocumentArchive/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Document Archive - -Search cached Sentinel documents, shipment PDFs, labels, and BOL records. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/DocumentArchive/Resources/views/index.blade.php b/Modules/DocumentArchive/Resources/views/index.blade.php old mode 100644 new mode 100755 index a2776ead..9d1e8b51 --- a/Modules/DocumentArchive/Resources/views/index.blade.php +++ b/Modules/DocumentArchive/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    + diff --git a/Modules/DocumentArchive/Resources/views/partials/nav.blade.php b/Modules/DocumentArchive/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/DocumentArchive/Routes/api.php b/Modules/DocumentArchive/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/DocumentArchive/Routes/web.php b/Modules/DocumentArchive/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/DocumentArchive/module.json b/Modules/DocumentArchive/module.json old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Config/config.php b/Modules/Documentation/Config/config.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Database/Migrations/2026_06_15_000000_create_documentation_tables.php b/Modules/Documentation/Database/Migrations/2026_06_15_000000_create_documentation_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Http/Controllers/DocumentationCategoryController.php b/Modules/Documentation/Http/Controllers/DocumentationCategoryController.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Http/Controllers/DocumentationController.php b/Modules/Documentation/Http/Controllers/DocumentationController.php old mode 100644 new mode 100755 index 86927fbc..9d37b045 --- a/Modules/Documentation/Http/Controllers/DocumentationController.php +++ b/Modules/Documentation/Http/Controllers/DocumentationController.php @@ -15,6 +15,10 @@ use Modules\Documentation\Models\DocumentationDocument; class DocumentationController extends Controller { + private const string STORAGE_DISK_CONFIG = 'documentation.storage_disk'; + + private const string UPLOAD_PATH_CONFIG = 'documentation.upload_path'; + /** * Display the documentation dashboard and document list. */ @@ -170,7 +174,7 @@ class DocumentationController extends Controller { abort_if(blank($document->attachment_path), 404); - return Storage::disk($document->attachment_disk ?: config('documentation.storage_disk', 'public')) + return Storage::disk($document->attachment_disk ?: config(self::STORAGE_DISK_CONFIG, 'public')) ->download($document->attachment_path, $document->attachment_name); } @@ -202,27 +206,19 @@ class DocumentationController extends Controller */ private function extractMarkdownBody(Request $request): ?string { - if (! config('documentation.import_markdown_attachments', true)) { - return null; - } - $file = $request->file('attachment'); + $canImport = config('documentation.import_markdown_attachments', true) + && $file !== null + && $this->isMarkdownUpload($request) + && $file->getSize() <= (int) config('documentation.max_markdown_import_bytes', 1048576); - if ($file === null || ! $this->isMarkdownUpload($request)) { - return null; - } - - if ($file->getSize() > (int) config('documentation.max_markdown_import_bytes', 1048576)) { + if (! $canImport) { return null; } $content = file_get_contents($file->getRealPath()); - if ($content === false) { - return null; - } - - return trim($content); + return $content === false ? null : trim($content); } /** @@ -250,8 +246,8 @@ class DocumentationController extends Controller private function storeAttachment(Request $request): array { $file = $request->file('attachment'); - $disk = config('documentation.storage_disk', 'public'); - $path = $file->store(config('documentation.upload_path', 'documentation'), $disk); + $disk = config(self::STORAGE_DISK_CONFIG, 'public'); + $path = $file->store(config(self::UPLOAD_PATH_CONFIG, 'documentation'), $disk); return [ 'attachment_disk' => $disk, @@ -271,14 +267,14 @@ class DocumentationController extends Controller return; } - $disk = config('documentation.storage_disk', 'public'); + $disk = config(self::STORAGE_DISK_CONFIG, 'public'); foreach ((array) $request->file('attachments') as $file) { if ($file === null || ! $file->isValid()) { continue; } - $path = $file->store(config('documentation.upload_path', 'documentation'), $disk); + $path = $file->store(config(self::UPLOAD_PATH_CONFIG, 'documentation'), $disk); $document->attachments()->create([ 'disk' => $disk, @@ -297,7 +293,7 @@ class DocumentationController extends Controller private function deleteAttachment(DocumentationDocument $document): void { if (filled($document->attachment_path)) { - Storage::disk($document->attachment_disk ?: config('documentation.storage_disk', 'public'))->delete($document->attachment_path); + Storage::disk($document->attachment_disk ?: config(self::STORAGE_DISK_CONFIG, 'public'))->delete($document->attachment_path); } } diff --git a/Modules/Documentation/Http/Requests/StoreDocumentationCategoryRequest.php b/Modules/Documentation/Http/Requests/StoreDocumentationCategoryRequest.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Http/Requests/StoreDocumentationDocumentRequest.php b/Modules/Documentation/Http/Requests/StoreDocumentationDocumentRequest.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Http/Requests/UpdateDocumentationCategoryRequest.php b/Modules/Documentation/Http/Requests/UpdateDocumentationCategoryRequest.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Http/Requests/UpdateDocumentationDocumentRequest.php b/Modules/Documentation/Http/Requests/UpdateDocumentationDocumentRequest.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Models/DocumentationAttachment.php b/Modules/Documentation/Models/DocumentationAttachment.php old mode 100644 new mode 100755 index 9722f365..4d462305 --- a/Modules/Documentation/Models/DocumentationAttachment.php +++ b/Modules/Documentation/Models/DocumentationAttachment.php @@ -52,18 +52,16 @@ class DocumentationAttachment extends Model { $bytes = (int) $this->size; + $label = number_format($bytes / 1048576, 1) . ' MB'; + if ($bytes <= 0) { - return 'Unknown size'; + $label = 'Unknown size'; + } elseif ($bytes < 1024) { + $label = $bytes . ' B'; + } elseif ($bytes < 1048576) { + $label = number_format($bytes / 1024, 1) . ' KB'; } - if ($bytes < 1024) { - return $bytes . ' B'; - } - - if ($bytes < 1048576) { - return number_format($bytes / 1024, 1) . ' KB'; - } - - return number_format($bytes / 1048576, 1) . ' MB'; + return $label; } } diff --git a/Modules/Documentation/Models/DocumentationCategory.php b/Modules/Documentation/Models/DocumentationCategory.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Models/DocumentationDocument.php b/Modules/Documentation/Models/DocumentationDocument.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Providers/DocumentationServiceProvider.php b/Modules/Documentation/Providers/DocumentationServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Providers/RouteServiceProvider.php b/Modules/Documentation/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 index 6ea712a1..88bb4da7 --- a/Modules/Documentation/Providers/RouteServiceProvider.php +++ b/Modules/Documentation/Providers/RouteServiceProvider.php @@ -14,18 +14,6 @@ class RouteServiceProvider extends ServiceProvider */ protected $moduleNamespace = 'Modules\Documentation\Http\Controllers'; - /** - * Called before routes are registered. - * - * Register any model bindings or pattern based filters. - * - * @return void - */ - public function boot() - { - parent::boot(); - } - /** * Define the routes for the application. * diff --git a/Modules/Documentation/Resources/views/categories/create.blade.php b/Modules/Documentation/Resources/views/categories/create.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/categories/edit.blade.php b/Modules/Documentation/Resources/views/categories/edit.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/categories/index.blade.php b/Modules/Documentation/Resources/views/categories/index.blade.php old mode 100644 new mode 100755 index 9bb1f7d8..58d07938 --- a/Modules/Documentation/Resources/views/categories/index.blade.php +++ b/Modules/Documentation/Resources/views/categories/index.blade.php @@ -21,6 +21,7 @@
    Data table
    Document
    + diff --git a/Modules/Documentation/Resources/views/documents/create.blade.php b/Modules/Documentation/Resources/views/documents/create.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/documents/edit.blade.php b/Modules/Documentation/Resources/views/documents/edit.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/documents/index.blade.php b/Modules/Documentation/Resources/views/documents/index.blade.php old mode 100644 new mode 100755 index b914aa8d..762f653a --- a/Modules/Documentation/Resources/views/documents/index.blade.php +++ b/Modules/Documentation/Resources/views/documents/index.blade.php @@ -44,15 +44,16 @@
    - - + - @foreach ($categories as $category)
    Data table
    Name
    + diff --git a/Modules/Documentation/Resources/views/documents/show.blade.php b/Modules/Documentation/Resources/views/documents/show.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/index.blade.php b/Modules/Documentation/Resources/views/index.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/layouts/master.blade.php b/Modules/Documentation/Resources/views/layouts/master.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/partials/category-form.blade.php b/Modules/Documentation/Resources/views/partials/category-form.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/partials/document-form.blade.php b/Modules/Documentation/Resources/views/partials/document-form.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Resources/views/partials/hero.blade.php b/Modules/Documentation/Resources/views/partials/hero.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Routes/api.php b/Modules/Documentation/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/Routes/web.php b/Modules/Documentation/Routes/web.php old mode 100644 new mode 100755 index 06c60802..87624a4c --- a/Modules/Documentation/Routes/web.php +++ b/Modules/Documentation/Routes/web.php @@ -6,6 +6,8 @@ use Illuminate\Support\Facades\Route; use Modules\Documentation\Http\Controllers\DocumentationCategoryController; use Modules\Documentation\Http\Controllers\DocumentationController; +const DOCUMENT_ROUTE = '/documents/{document}'; + Route::middleware(['web', 'auth']) ->prefix('documentation') ->name('documentation.') @@ -15,13 +17,13 @@ Route::middleware(['web', 'auth']) Route::get('/documents', [DocumentationController::class, 'index'])->name('documents.index'); Route::get('/documents/create', [DocumentationController::class, 'create'])->name('documents.create'); Route::post('/documents', [DocumentationController::class, 'store'])->name('documents.store'); - Route::get('/documents/{document}', [DocumentationController::class, 'show'])->name('documents.show'); - Route::get('/documents/{document}/edit', [DocumentationController::class, 'edit'])->name('documents.edit'); - Route::put('/documents/{document}', [DocumentationController::class, 'update'])->name('documents.update'); - Route::delete('/documents/{document}', [DocumentationController::class, 'destroy'])->name('documents.destroy'); - Route::get('/documents/{document}/download', [DocumentationController::class, 'download'])->name('documents.download'); - Route::get('/documents/{document}/attachments/{attachment}/download', [DocumentationController::class, 'downloadAttachment'])->name('documents.attachments.download'); - Route::delete('/documents/{document}/attachments/{attachment}', [DocumentationController::class, 'destroyAttachment'])->name('documents.attachments.destroy'); + Route::get(DOCUMENT_ROUTE, [DocumentationController::class, 'show'])->name('documents.show'); + Route::get(DOCUMENT_ROUTE . '/edit', [DocumentationController::class, 'edit'])->name('documents.edit'); + Route::put(DOCUMENT_ROUTE, [DocumentationController::class, 'update'])->name('documents.update'); + Route::delete(DOCUMENT_ROUTE, [DocumentationController::class, 'destroy'])->name('documents.destroy'); + Route::get(DOCUMENT_ROUTE . '/download', [DocumentationController::class, 'download'])->name('documents.download'); + Route::get(DOCUMENT_ROUTE . '/attachments/{attachment}/download', [DocumentationController::class, 'downloadAttachment'])->name('documents.attachments.download'); + Route::delete(DOCUMENT_ROUTE . '/attachments/{attachment}', [DocumentationController::class, 'destroyAttachment'])->name('documents.attachments.destroy'); Route::resource('categories', DocumentationCategoryController::class)->except(['show']); }); diff --git a/Modules/Documentation/Tests/Feature/DocumentationModuleTest.php b/Modules/Documentation/Tests/Feature/DocumentationModuleTest.php old mode 100644 new mode 100755 diff --git a/Modules/Documentation/changelog.yaml b/Modules/Documentation/changelog.yaml old mode 100644 new mode 100755 diff --git a/Modules/Documentation/composer.json b/Modules/Documentation/composer.json old mode 100644 new mode 100755 diff --git a/Modules/Documentation/module.json b/Modules/Documentation/module.json old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Concerns/HasHelpdeskTickets.php b/Modules/Helpdesk/Concerns/HasHelpdeskTickets.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Config/.gitkeep b/Modules/Helpdesk/Config/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Config/config.php b/Modules/Helpdesk/Config/config.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Console/.gitkeep b/Modules/Helpdesk/Console/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/.gitkeep b/Modules/Helpdesk/Database/Migrations/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_04_24_000001_add_helpdesk_flags_to_users_table.php b/Modules/Helpdesk/Database/Migrations/2026_04_24_000001_add_helpdesk_flags_to_users_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_000010_create_helpdesk_lookup_tables.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_000010_create_helpdesk_lookup_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_000020_create_helpdesk_tickets_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_000020_create_helpdesk_tickets_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_000030_create_helpdesk_git_and_workflow_tables.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_000030_create_helpdesk_git_and_workflow_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_000040_create_helpdesk_comments_and_attachments_tables.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_000040_create_helpdesk_comments_and_attachments_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_000050_create_helpdesk_category_user_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_000050_create_helpdesk_category_user_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_130000_create_helpdesk_kanban_boards_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_130000_create_helpdesk_kanban_boards_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_12_130010_create_helpdesk_kanban_board_statuses_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_12_130010_create_helpdesk_kanban_board_statuses_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_15_000100_add_redmineup_inspired_helpdesk_features.php b/Modules/Helpdesk/Database/Migrations/2026_06_15_000100_add_redmineup_inspired_helpdesk_features.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_15_000200_add_helpdesk_git_webhook_ingestion.php b/Modules/Helpdesk/Database/Migrations/2026_06_15_000200_add_helpdesk_git_webhook_ingestion.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_15_143824_default_flags_to_helpdesk_lookup_tables.php b/Modules/Helpdesk/Database/Migrations/2026_06_15_143824_default_flags_to_helpdesk_lookup_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_15_144126_add_default_helpdesk_flag_to_companies_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_15_144126_add_default_helpdesk_flag_to_companies_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_15_151500_add_helpdesk_status_default_and_harden_defaults.php b/Modules/Helpdesk/Database/Migrations/2026_06_15_151500_add_helpdesk_status_default_and_harden_defaults.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_16_090000_add_single_board_assignment_and_owner_to_helpdesk.php b/Modules/Helpdesk/Database/Migrations/2026_06_16_090000_add_single_board_assignment_and_owner_to_helpdesk.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_16_093000_backfill_helpdesk_ticket_board_assignments.php b/Modules/Helpdesk/Database/Migrations/2026_06_16_093000_backfill_helpdesk_ticket_board_assignments.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_16_094500_backfill_kanban_board_status_columns.php b/Modules/Helpdesk/Database/Migrations/2026_06_16_094500_backfill_kanban_board_status_columns.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_17_084500_add_lotus_replication_fields_to_helpdesk_comments.php b/Modules/Helpdesk/Database/Migrations/2026_06_17_084500_add_lotus_replication_fields_to_helpdesk_comments.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_17_111500_add_subject_to_helpdesk_comments.php b/Modules/Helpdesk/Database/Migrations/2026_06_17_111500_add_subject_to_helpdesk_comments.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_17_123000_add_deletion_audit_fields_to_helpdesk_comments.php b/Modules/Helpdesk/Database/Migrations/2026_06_17_123000_add_deletion_audit_fields_to_helpdesk_comments.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_22_000001_add_timer_fields_to_helpdesk_time_logs_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_22_000001_add_timer_fields_to_helpdesk_time_logs_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_22_000001_create_helpdesk_ticket_time_logs_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_22_000001_create_helpdesk_ticket_time_logs_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_22_000001_create_helpdesk_time_logs_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_22_000001_create_helpdesk_time_logs_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_22_124500_add_logged_at_to_helpdesk_ticket_time_logs_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_22_124500_add_logged_at_to_helpdesk_ticket_time_logs_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_22_130000_add_seconds_to_helpdesk_ticket_time_logs_table.php b/Modules/Helpdesk/Database/Migrations/2026_06_22_130000_add_seconds_to_helpdesk_ticket_time_logs_table.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_23_150000_normalise_helpdesk_lookup_colours.php b/Modules/Helpdesk/Database/Migrations/2026_06_23_150000_normalise_helpdesk_lookup_colours.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Migrations/2026_06_24_000100_add_helpdesk_attachment_experience_metadata.php b/Modules/Helpdesk/Database/Migrations/2026_06_24_000100_add_helpdesk_attachment_experience_metadata.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Seeders/.gitkeep b/Modules/Helpdesk/Database/Seeders/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/Seeders/HelpdeskDatabaseSeeder.php b/Modules/Helpdesk/Database/Seeders/HelpdeskDatabaseSeeder.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/factories/.gitkeep b/Modules/Helpdesk/Database/factories/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Database/factories/TicketFactory.php b/Modules/Helpdesk/Database/factories/TicketFactory.php old mode 100644 new mode 100755 index 783a0dfd..8c21ac81 --- a/Modules/Helpdesk/Database/factories/TicketFactory.php +++ b/Modules/Helpdesk/Database/factories/TicketFactory.php @@ -4,11 +4,12 @@ declare(strict_types=1); namespace Modules\Helpdesk\Database\factories; -use Modules\Company\Models\Company; use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; +use Modules\Company\Models\Company; use Modules\Helpdesk\Models\Ticket; /** @@ -16,6 +17,8 @@ use Modules\Helpdesk\Models\Ticket; */ final class TicketFactory extends Factory { + private const FACTORY_BODY = self::FACTORY_BODY; + /** * The model name for the factory. * @@ -31,11 +34,11 @@ final class TicketFactory extends Factory public function definition(): array { $company = Company::query()->create([ - 'name' => 'Helpdesk Factory Company '.Str::random(8), - 'slug' => 'helpdesk-factory-company-'.Str::lower(Str::random(8)), + 'name' => 'Helpdesk Factory Company ' . Str::random(8), + 'slug' => 'helpdesk-factory-company-' . Str::lower(Str::random(8)), 'status' => 'active', 'timezone' => 'Europe/London', - 'billing_email' => 'helpdesk-factory-'.Str::lower(Str::random(8)).'@example.test', + 'billing_email' => 'helpdesk-factory-' . Str::lower(Str::random(8)) . '@example.test', 'is_system_company' => false, ]); $user = User::factory()->create([ @@ -52,7 +55,7 @@ final class TicketFactory extends Factory */ private function ticketPayload(Company $company, User $user): array { - $ticket = new Ticket(); + $ticket = new Ticket; $table = $ticket->getTable(); $data = []; @@ -70,43 +73,43 @@ final class TicketFactory extends Factory $put('assigned_to_id', $user->getKey()); $put('agent_id', $user->getKey()); - $put('reference', 'HD-'.now()->format('Y').'-'.str_pad((string) $this->faker->unique()->numberBetween(1, 9999), 4, '0', STR_PAD_LEFT)); + $put('reference', 'HD-' . now()->format('Y') . '-' . str_pad((string) $this->faker->unique()->numberBetween(1, 9999), 4, '0', STR_PAD_LEFT)); $put('subject', 'Factory helpdesk ticket'); $put('title', 'Factory helpdesk ticket'); - $put('body', '

    Factory helpdesk ticket body.

    '); - $put('details', '

    Factory helpdesk ticket body.

    '); - $put('description', '

    Factory helpdesk ticket body.

    '); + $put('body', self::FACTORY_BODY); + $put('details', self::FACTORY_BODY); + $put('description', self::FACTORY_BODY); $put('search_text', 'factory helpdesk ticket body'); $put('last_activity_at', now()); $statusId = $this->lookupId( 'Modules\\Helpdesk\\Models\\TicketStatus', ['name' => 'Open'], - ['slug' => 'open', 'color' => 'blue', 'is_closed' => false, 'sort_order' => 10] + ['slug' => 'open', 'color' => 'blue', 'is_closed' => false, 'sort_order' => 10], ); $priorityId = $this->lookupId( 'Modules\\Helpdesk\\Models\\TicketPriority', ['name' => 'Normal'], - ['slug' => 'normal', 'color' => 'blue', 'sort_order' => 20] + ['slug' => 'normal', 'color' => 'blue', 'sort_order' => 20], ); $categoryId = $this->lookupId( 'Modules\\Helpdesk\\Models\\TicketCategory', ['name' => 'General'], - ['slug' => 'general', 'color' => 'blue', 'sort_order' => 10] + ['slug' => 'general', 'color' => 'blue', 'sort_order' => 10], ); $teamId = $this->lookupId( 'Modules\\Helpdesk\\Models\\HelpdeskTeam', ['name' => 'Support'], - ['slug' => 'support', 'color' => 'blue', 'sort_order' => 10] + ['slug' => 'support', 'color' => 'blue', 'sort_order' => 10], ); $projectId = $this->lookupId( 'Modules\\Helpdesk\\Models\\HelpdeskProject', ['name' => 'General'], - ['slug' => 'general', 'color' => 'blue', 'sort_order' => 10] + ['slug' => 'general', 'color' => 'blue', 'sort_order' => 10], ); $put('status_id', $statusId); @@ -140,8 +143,8 @@ final class TicketFactory extends Factory return null; } - /** @var class-string<\Illuminate\Database\Eloquent\Model> $class */ - $model = new $class(); + /** @var class-string $class */ + $model = new $class; if (! Schema::hasTable($model->getTable())) { return null; diff --git a/Modules/Helpdesk/Documentation/Helpdesk_GitHub_Gitea_Integration_Guide.md b/Modules/Helpdesk/Documentation/Helpdesk_GitHub_Gitea_Integration_Guide.md old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Exceptions/TicketPersistenceException.php b/Modules/Helpdesk/Exceptions/TicketPersistenceException.php new file mode 100755 index 00000000..47a2cef6 --- /dev/null +++ b/Modules/Helpdesk/Exceptions/TicketPersistenceException.php @@ -0,0 +1,9 @@ + 'text', }; } - } diff --git a/Modules/Helpdesk/Http/Controllers/AttachmentPreviewController.php b/Modules/Helpdesk/Http/Controllers/AttachmentPreviewController.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Http/Controllers/GitWebhookController.php b/Modules/Helpdesk/Http/Controllers/GitWebhookController.php old mode 100644 new mode 100755 index fab7f218..af531c46 --- a/Modules/Helpdesk/Http/Controllers/GitWebhookController.php +++ b/Modules/Helpdesk/Http/Controllers/GitWebhookController.php @@ -15,6 +15,20 @@ use Modules\Helpdesk\Services\GitWebhookIngestionService; final class GitWebhookController { + private const REJECTED = 'rejected'; + + private const SIGNATURE_FAILED = 'Git webhook signature or token validation failed.'; + + private const SHA256_PREFIX = 'sha256='; + + private const SHA1_PREFIX = 'sha1='; + + private const REQUEST_ID_HEADER = 'X-Request-Id'; + + private const GITHUB_DELIVERY_HEADER = 'X-GitHub-Delivery'; + + private const GITHUB_EVENT_HEADER = 'X-GitHub-Event'; + /** * Ingest a signed Git provider webhook for a registered Helpdesk repository. */ @@ -24,34 +38,31 @@ final class GitWebhookController $event = $this->eventName($request, $provider); $deliveryId = $this->deliveryId($request, $provider); $rawPayload = $request->getContent(); + $status = 202; + $payload = []; if (! $repository->is_active) { - $result = ['status' => 'rejected', 'message' => 'Repository is inactive.', 'commit_count' => 0, 'linked_count' => 0, 'ignored_count' => 1]; - $service->logWebhook($repository, $provider, $deliveryId, $event, $result); - - return response()->json($result, 403); + $result = $this->rejectedResult('Repository is inactive.'); + $status = 403; + } elseif (! $this->hasValidSignature($request, $repository, $provider, $rawPayload)) { + $result = $this->rejectedResult(self::SIGNATURE_FAILED); + $status = 403; + } else { + try { + /** @var array $payload */ + $payload = json_decode($rawPayload, true, 512, JSON_THROW_ON_ERROR); + $result = $service->ingest($repository, $payload, $provider, $deliveryId, $event); + } catch (JsonException) { + $result = $this->rejectedResult('Invalid JSON webhook payload.'); + $status = 400; + } } - if (! $this->hasValidSignature($request, $repository, $provider, $rawPayload)) { - $result = ['status' => 'rejected', 'message' => 'Git webhook signature or token validation failed.', 'commit_count' => 0, 'linked_count' => 0, 'ignored_count' => 1]; - $service->logWebhook($repository, $provider, $deliveryId, $event, $result); - - return response()->json($result, 403); + if ($status !== 202) { + $service->logWebhook($repository, $provider, $deliveryId, $event, $result, $payload); } - try { - /** @var array $payload */ - $payload = json_decode($rawPayload, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - $result = ['status' => 'rejected', 'message' => 'Invalid JSON webhook payload.', 'commit_count' => 0, 'linked_count' => 0, 'ignored_count' => 1]; - $service->logWebhook($repository, $provider, $deliveryId, $event, $result); - - return response()->json($result, 400); - } - - $result = $service->ingest($repository, $payload, $provider, $deliveryId, $event); - - return response()->json($result, 202); + return response()->json($result, $status); } /** @@ -63,42 +74,34 @@ final class GitWebhookController $event = $this->eventName($request, $provider); $deliveryId = $this->deliveryId($request, $provider); $rawPayload = $request->getContent(); + $status = 202; + $repository = null; try { /** @var array $payload */ $payload = json_decode($rawPayload, true, 512, JSON_THROW_ON_ERROR); + $repository = $this->repositoryForGiteaPayload($payload); + + if (! $repository instanceof GitRepository) { + $result = $this->rejectedResult('No active Helpdesk Git repository matched the Gitea webhook payload.'); + $status = 404; + } elseif (! $this->hasValidGiteaSecurity($request, $repository, $provider, $rawPayload)) { + $result = $this->rejectedResult(self::SIGNATURE_FAILED); + $status = 403; + } else { + $result = $service->ingest($repository, $payload, $provider, $deliveryId, $event); + } } catch (JsonException) { - return response()->json([ - 'status' => 'rejected', - 'message' => 'Invalid JSON webhook payload.', - 'commit_count' => 0, - 'linked_count' => 0, - 'ignored_count' => 1, - ], 400); + $payload = []; + $result = $this->rejectedResult('Invalid JSON webhook payload.'); + $status = 400; } - $repository = $this->repositoryForGiteaPayload($payload); - - if (! $repository instanceof GitRepository) { - return response()->json([ - 'status' => 'rejected', - 'message' => 'No active Helpdesk Git repository matched the Gitea webhook payload.', - 'commit_count' => 0, - 'linked_count' => 0, - 'ignored_count' => 1, - ], 404); - } - - if (! $this->hasValidGiteaSecurity($request, $repository, $provider, $rawPayload)) { - $result = ['status' => 'rejected', 'message' => 'Git webhook signature or token validation failed.', 'commit_count' => 0, 'linked_count' => 0, 'ignored_count' => 1]; + if ($repository instanceof GitRepository && $status !== 202) { $service->logWebhook($repository, $provider, $deliveryId, $event, $result, $payload); - - return response()->json($result, 403); } - $result = $service->ingest($repository, $payload, $provider, $deliveryId, $event); - - return response()->json($result, 202); + return response()->json($result, $status); } /** @@ -143,8 +146,8 @@ final class GitWebhookController $sha256Signature = (string) $request->header('X-Hub-Signature-256', ''); $sha1Signature = (string) $request->header('X-Hub-Signature', ''); - return hash_equals('sha256=' . hash_hmac('sha256', $rawPayload, $secret), $sha256Signature) - || hash_equals('sha1=' . hash_hmac('sha1', $rawPayload, $secret), $sha1Signature); + return hash_equals(self::SHA256_PREFIX . hash_hmac('sha256', $rawPayload, $secret), $sha256Signature) + || hash_equals(self::SHA1_PREFIX . hash_hmac('sha1', $rawPayload, $secret), $sha1Signature); } /** @@ -158,8 +161,8 @@ final class GitWebhookController $sha1 = hash_hmac('sha1', $rawPayload, $secret); return hash_equals($sha256, $giteaSignature) - || hash_equals('sha256=' . $sha256, $giteaSignature) - || hash_equals('sha1=' . $sha1, $giteaSignature) + || hash_equals(self::SHA256_PREFIX . $sha256, $giteaSignature) + || hash_equals(self::SHA1_PREFIX . $sha1, $giteaSignature) || $this->hasValidGitHubSignature($request, $secret, $rawPayload) || $this->hasValidGenericSignature($request, $secret, $rawPayload); } @@ -171,7 +174,7 @@ final class GitWebhookController { $signature = (string) $request->header('X-Hub-Signature', ''); - return hash_equals('sha256=' . hash_hmac('sha256', $rawPayload, $secret), $signature) + return hash_equals(self::SHA256_PREFIX . hash_hmac('sha256', $rawPayload, $secret), $signature) || hash_equals($secret, (string) $request->header('X-Helpdesk-Token', '')); } @@ -184,8 +187,8 @@ final class GitWebhookController $signature = (string) ($request->header('X-Hub-Signature-256') ?: $request->header('X-Hub-Signature')); return hash_equals($secret, $token) - || hash_equals('sha256=' . hash_hmac('sha256', $rawPayload, $secret), $signature) - || hash_equals('sha1=' . hash_hmac('sha1', $rawPayload, $secret), $signature); + || hash_equals(self::SHA256_PREFIX . hash_hmac('sha256', $rawPayload, $secret), $signature) + || hash_equals(self::SHA1_PREFIX . hash_hmac('sha1', $rawPayload, $secret), $signature); } /** @@ -230,63 +233,94 @@ final class GitWebhookController ->where('is_active', true) ->whereRaw('LOWER(provider) IN (?, ?)', ['gitea', 'git']) ->get(); + $matchedRepository = null; if ($repositories->isEmpty()) { Log::warning('Helpdesk Gitea webhook received but no active Gitea/git repository is configured.'); + } else { + $normalisedPayloadValues = $this->normalisedPayloadRepositoryValues($payload); + $matchedRepository = $repositories->first( + fn (GitRepository $repository): bool => $this->repositoryMatchesPayload($repository, $normalisedPayloadValues), + ); - return null; + if (! $matchedRepository instanceof GitRepository && $repositories->count() === 1) { + $matchedRepository = $repositories->first(); + } elseif (! $matchedRepository instanceof GitRepository) { + Log::warning('Helpdesk Gitea webhook did not match any configured repository.', [ + 'payload_repository' => Arr::get($payload, 'repository.full_name') ?: Arr::get($payload, 'repository.clone_url') ?: Arr::get($payload, 'repository.html_url'), + 'configured_repository_count' => $repositories->count(), + ]); + } } - $payloadValues = array_values(array_filter([ + return $matchedRepository instanceof GitRepository ? $matchedRepository : null; + } + + /** @param array $payload + * @return list + */ + private function normalisedPayloadRepositoryValues(array $payload): array + { + $name = Arr::get($payload, 'repository.name'); + $owner = Arr::get($payload, 'repository.owner.username'); + + return $this->normaliseRepositoryValues([ Arr::get($payload, 'repository.full_name'), - Arr::get($payload, 'repository.name'), + $name, Arr::get($payload, 'repository.html_url'), Arr::get($payload, 'repository.clone_url'), Arr::get($payload, 'repository.ssh_url'), Arr::get($payload, 'repository.url'), - Arr::get($payload, 'repository.owner.username') && Arr::get($payload, 'repository.name') - ? Arr::get($payload, 'repository.owner.username') . '/' . Arr::get($payload, 'repository.name') - : null, - ], static fn (mixed $value): bool => is_scalar($value) && trim((string) $value) !== '')); + $owner && $name ? $owner . '/' . $name : null, + ]); + } - $normalisedPayloadValues = array_values(array_filter(array_map( - fn (mixed $value): ?string => $this->normaliseRepositoryIdentity((string) $value), - $payloadValues, - ))); + /** @param list $payloadValues */ + private function repositoryMatchesPayload(GitRepository $repository, array $payloadValues): bool + { + $repositoryValues = $this->normaliseRepositoryValues([ + $repository->remote_url, + $repository->name, + Str::of((string) $repository->remote_url)->afterLast(':')->beforeLast('.git')->value(), + ]); - foreach ($repositories as $repository) { - $repositoryValues = array_filter([ - $repository->remote_url, - $repository->name, - Str::of((string) $repository->remote_url)->afterLast(':')->beforeLast('.git')->value(), - ], static fn (mixed $value): bool => is_scalar($value) && trim((string) $value) !== ''); - - $normalisedRepositoryValues = array_values(array_filter(array_map( - fn (mixed $value): ?string => $this->normaliseRepositoryIdentity((string) $value), - $repositoryValues, - ))); - - foreach ($normalisedPayloadValues as $payloadValue) { - foreach ($normalisedRepositoryValues as $repositoryValue) { - if ($payloadValue === $repositoryValue - || str_ends_with($repositoryValue, '/' . $payloadValue) - || str_ends_with($payloadValue, '/' . $repositoryValue)) { - return $repository; - } + foreach ($payloadValues as $payloadValue) { + foreach ($repositoryValues as $repositoryValue) { + if ($this->repositoryIdentitiesMatch($payloadValue, $repositoryValue)) { + return true; } } } - if ($repositories->count() === 1) { - return $repositories->first(); + return false; + } + + /** @param array $values + * @return list + */ + private function normaliseRepositoryValues(array $values): array + { + $normalised = []; + + foreach ($values as $value) { + if (! is_scalar($value) || trim((string) $value) === '') { + continue; + } + + $identity = $this->normaliseRepositoryIdentity((string) $value); + if ($identity !== null) { + $normalised[] = $identity; + } } - Log::warning('Helpdesk Gitea webhook did not match any configured repository.', [ - 'payload_repository' => Arr::get($payload, 'repository.full_name') ?: Arr::get($payload, 'repository.clone_url') ?: Arr::get($payload, 'repository.html_url'), - 'configured_repository_count' => $repositories->count(), - ]); + return $normalised; + } - return null; + private function repositoryIdentitiesMatch(string $payloadValue, string $repositoryValue): bool + { + return $payloadValue === $repositoryValue + || str_ends_with($repositoryValue, '/' . $payloadValue) + || str_ends_with($payloadValue, '/' . $repositoryValue); } /** @@ -325,17 +359,29 @@ final class GitWebhookController return implode('/', array_slice($segments, -2)); } + /** @return array{status: string, message: string, commit_count: int, linked_count: int, ignored_count: int} */ + private function rejectedResult(string $message): array + { + return [ + 'status' => self::REJECTED, + 'message' => $message, + 'commit_count' => 0, + 'linked_count' => 0, + 'ignored_count' => 1, + ]; + } + /** * Read the event name from provider-specific headers. */ private function eventName(Request $request, string $provider): ?string { return match ($provider) { - 'github' => $request->header('X-GitHub-Event'), + 'github' => $request->header(self::GITHUB_EVENT_HEADER), 'gitlab' => $request->header('X-Gitlab-Event'), - 'gitea' => $request->header('X-Gitea-Event') ?: $request->header('X-Gitea-Event-Type') ?: $request->header('X-GitHub-Event'), + 'gitea' => $request->header('X-Gitea-Event') ?: $request->header('X-Gitea-Event-Type') ?: $request->header(self::GITHUB_EVENT_HEADER), 'bitbucket' => $request->header('X-Event-Key'), - default => $request->header('X-Helpdesk-Event') ?: $request->header('X-GitHub-Event') ?: $request->header('X-Gitlab-Event') ?: 'push', + default => $request->header('X-Helpdesk-Event') ?: $request->header(self::GITHUB_EVENT_HEADER) ?: $request->header('X-Gitlab-Event') ?: 'push', }; } @@ -345,11 +391,11 @@ final class GitWebhookController private function deliveryId(Request $request, string $provider): ?string { return match ($provider) { - 'github' => $request->header('X-GitHub-Delivery'), - 'gitlab' => $request->header('X-Gitlab-Event-UUID') ?: $request->header('X-Request-Id'), - 'gitea' => $request->header('X-Gitea-Delivery') ?: $request->header('X-GitHub-Delivery') ?: $request->header('X-Request-Id'), - 'bitbucket' => $request->header('X-Request-UUID') ?: $request->header('X-Request-Id'), - default => $request->header('X-Helpdesk-Delivery') ?: $request->header('X-GitHub-Delivery') ?: $request->header('X-Request-Id'), + 'github' => $request->header(self::GITHUB_DELIVERY_HEADER), + 'gitlab' => $request->header('X-Gitlab-Event-UUID') ?: $request->header(self::REQUEST_ID_HEADER), + 'gitea' => $request->header('X-Gitea-Delivery') ?: $request->header(self::GITHUB_DELIVERY_HEADER) ?: $request->header(self::REQUEST_ID_HEADER), + 'bitbucket' => $request->header('X-Request-UUID') ?: $request->header(self::REQUEST_ID_HEADER), + default => $request->header('X-Helpdesk-Delivery') ?: $request->header(self::GITHUB_DELIVERY_HEADER) ?: $request->header(self::REQUEST_ID_HEADER), }; } } diff --git a/Modules/Helpdesk/Http/Controllers/HelpdeskController.php b/Modules/Helpdesk/Http/Controllers/HelpdeskController.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Http/Controllers/TicketAttachmentStoreController.php b/Modules/Helpdesk/Http/Controllers/TicketAttachmentStoreController.php old mode 100644 new mode 100755 index 05ace4c5..036c7ea3 --- a/Modules/Helpdesk/Http/Controllers/TicketAttachmentStoreController.php +++ b/Modules/Helpdesk/Http/Controllers/TicketAttachmentStoreController.php @@ -45,6 +45,7 @@ final class TicketAttachmentStoreController extends Controller * Return Helpdesk attachment validation rules without relying on a newly autoloaded support class. * * @param bool $required Whether at least one uploaded file is required. + * * @return array */ private function attachmentFileRules(bool $required = false): array @@ -71,5 +72,4 @@ final class TicketAttachmentStoreController extends Controller ->values() ->all(); } - } diff --git a/Modules/Helpdesk/Http/Controllers/TicketBoardController.php b/Modules/Helpdesk/Http/Controllers/TicketBoardController.php old mode 100644 new mode 100755 index 965b966e..afec050c --- a/Modules/Helpdesk/Http/Controllers/TicketBoardController.php +++ b/Modules/Helpdesk/Http/Controllers/TicketBoardController.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Gate; use Illuminate\Validation\Rule; +use Modules\Helpdesk\Exceptions\TicketPersistenceException; use Modules\Helpdesk\Models\KanbanBoard; use Modules\Helpdesk\Models\Status; use Modules\Helpdesk\Models\Ticket; @@ -68,7 +69,7 @@ final class TicketBoardController extends Controller ->update($updates); if ($affected < 1) { - throw new \RuntimeException('Ticket board update did not persist.'); + throw new TicketPersistenceException('Ticket board update did not persist.'); } return Ticket::query() diff --git a/Modules/Helpdesk/Http/Controllers/TicketCommentDeleteController.php b/Modules/Helpdesk/Http/Controllers/TicketCommentDeleteController.php old mode 100644 new mode 100755 index 4f8f578e..ab106835 --- a/Modules/Helpdesk/Http/Controllers/TicketCommentDeleteController.php +++ b/Modules/Helpdesk/Http/Controllers/TicketCommentDeleteController.php @@ -25,51 +25,52 @@ final class TicketCommentDeleteController extends Controller abort_unless((int) $comment->ticket_id === (int) $ticket->id, 404); DB::transaction(function () use ($comment, $ticket, $user): void { - $updates = []; - - if (Schema::hasColumn('helpdesk_comments', 'tombstoned_at')) { - $updates['tombstoned_at'] = now(); - } - - if (Schema::hasColumn('helpdesk_comments', 'deleted_by')) { - $updates['deleted_by'] = (int) $user->id; - } - - if (Schema::hasColumn('helpdesk_comments', 'delete_reason')) { - $updates['delete_reason'] = 'Deleted by MPBA platform administrator.'; - } - - if (Schema::hasColumn('helpdesk_comments', 'sync_sequence')) { - $updates['sync_sequence'] = ((int) ($comment->sync_sequence ?? 0)) + 1; - } - - if (Schema::hasColumn('helpdesk_comments', 'sync_hash')) { - $updates['sync_hash'] = hash('sha256', implode('|', [ - (string) ($comment->guid ?? $comment->id), - 'deleted', - now()->toISOString(), - ])); - } - - if (Schema::hasColumn('helpdesk_comments', 'updated_at')) { - $updates['updated_at'] = now(); - } - - if ($updates !== []) { - DB::table('helpdesk_comments') - ->where('id', $comment->id) - ->update($updates); - } else { - $comment->delete(); - } - - if (Schema::hasColumn('helpdesk_tickets', 'last_activity_at')) { - $ticket->forceFill(['last_activity_at' => now()])->save(); - } + $this->deleteComment($comment, (int) $user->id); + $this->touchTicket($ticket); }); return redirect() ->route('helpdesk.tickets.show', $ticket) ->with('ticket-comment-deleted', 'Response deleted.'); } + + private function deleteComment(Comment $comment, int $userId): void + { + $updates = $this->tombstoneUpdates($comment, $userId); + + if ($updates === []) { + $comment->delete(); + + return; + } + + DB::table('helpdesk_comments')->where('id', $comment->id)->update($updates); + } + + /** @return array */ + private function tombstoneUpdates(Comment $comment, int $userId): array + { + $now = now(); + $candidates = [ + 'tombstoned_at' => $now, + 'deleted_by' => $userId, + 'delete_reason' => 'Deleted by MPBA platform administrator.', + 'sync_sequence' => ((int) ($comment->sync_sequence ?? 0)) + 1, + 'sync_hash' => hash('sha256', implode('|', [(string) ($comment->guid ?? $comment->id), 'deleted', $now->toISOString()])), + 'updated_at' => $now, + ]; + + return array_filter( + $candidates, + static fn (mixed $value, string $column): bool => Schema::hasColumn('helpdesk_comments', $column), + ARRAY_FILTER_USE_BOTH, + ); + } + + private function touchTicket(Ticket $ticket): void + { + if (Schema::hasColumn('helpdesk_tickets', 'last_activity_at')) { + $ticket->forceFill(['last_activity_at' => now()])->save(); + } + } } diff --git a/Modules/Helpdesk/Http/Controllers/TicketCommentStoreController.php b/Modules/Helpdesk/Http/Controllers/TicketCommentStoreController.php old mode 100644 new mode 100755 index 4026c47a..866f1c19 --- a/Modules/Helpdesk/Http/Controllers/TicketCommentStoreController.php +++ b/Modules/Helpdesk/Http/Controllers/TicketCommentStoreController.php @@ -170,6 +170,7 @@ final class TicketCommentStoreController extends Controller * Return Helpdesk attachment validation rules without relying on a newly autoloaded support class. * * @param bool $required Whether at least one uploaded file is required. + * * @return array */ private function attachmentFileRules(bool $required = false): array @@ -196,5 +197,4 @@ final class TicketCommentStoreController extends Controller ->values() ->all(); } - } diff --git a/Modules/Helpdesk/Http/Controllers/TicketControlsController.php b/Modules/Helpdesk/Http/Controllers/TicketControlsController.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Http/Controllers/TicketStoreController.php b/Modules/Helpdesk/Http/Controllers/TicketStoreController.php old mode 100644 new mode 100755 index 6313bcbd..2c259663 --- a/Modules/Helpdesk/Http/Controllers/TicketStoreController.php +++ b/Modules/Helpdesk/Http/Controllers/TicketStoreController.php @@ -63,6 +63,7 @@ final class TicketStoreController extends Controller * Return Helpdesk attachment validation rules without relying on a newly autoloaded support class. * * @param bool $required Whether at least one uploaded file is required. + * * @return array */ private function attachmentFileRules(bool $required = false): array @@ -89,5 +90,4 @@ final class TicketStoreController extends Controller ->values() ->all(); } - } diff --git a/Modules/Helpdesk/Http/Controllers/TicketTimeLogController.php b/Modules/Helpdesk/Http/Controllers/TicketTimeLogController.php old mode 100644 new mode 100755 index 39148bd0..07a35d19 --- a/Modules/Helpdesk/Http/Controllers/TicketTimeLogController.php +++ b/Modules/Helpdesk/Http/Controllers/TicketTimeLogController.php @@ -35,62 +35,71 @@ final class TicketTimeLogController extends Controller $loggedAt = now(); DB::transaction(function () use ($ticket, $request, $minutes, $description, $loggedAt): void { - if (Schema::hasColumn($ticket->getTable(), 'time_spent_minutes')) { - $ticket->increment('time_spent_minutes', $minutes, [ - 'last_activity_at' => $loggedAt, - ]); - } elseif (Schema::hasColumn($ticket->getTable(), 'last_activity_at')) { - $ticket->forceFill(['last_activity_at' => $loggedAt])->save(); - } - - if (Schema::hasTable('helpdesk_time_logs')) { - DB::table('helpdesk_time_logs')->insert([ - 'ticket_id' => $ticket->getKey(), - 'user_id' => $request->user()->getKey(), - 'minutes' => $minutes, - 'description' => $description, - 'logged_at' => $loggedAt, - 'created_at' => $loggedAt, - 'updated_at' => $loggedAt, - ]); - } - - if (Schema::hasTable('helpdesk_ticket_time_logs')) { - $payload = [ - 'ticket_id' => $ticket->getKey(), - 'user_id' => $request->user()->getKey(), - 'minutes' => $minutes, - 'description' => $description, - 'created_at' => $loggedAt, - 'updated_at' => $loggedAt, - ]; - - if (Schema::hasColumn('helpdesk_ticket_time_logs', 'started_at')) { - $payload['started_at'] = $loggedAt->copy()->subMinutes($minutes); - } - - if (Schema::hasColumn('helpdesk_ticket_time_logs', 'ended_at')) { - $payload['ended_at'] = $loggedAt; - } - - if (Schema::hasColumn('helpdesk_ticket_time_logs', 'logged_at')) { - $payload['logged_at'] = $loggedAt; - } - - if (Schema::hasColumn('helpdesk_ticket_time_logs', 'duration_seconds')) { - $payload['duration_seconds'] = $minutes * 60; - } - - if (Schema::hasColumn('helpdesk_ticket_time_logs', 'seconds')) { - $payload['seconds'] = $minutes * 60; - } - - DB::table('helpdesk_ticket_time_logs')->insert($payload); - } + $this->updateTicketActivity($ticket, $minutes, $loggedAt); + $this->storeLegacyTimeLog($ticket, $request, $minutes, $description, $loggedAt); + $this->storeTicketTimeLog($ticket, $request, $minutes, $description, $loggedAt); }); return redirect() ->route('helpdesk.tickets.show', $ticket) ->with('ticket-action-updated', 'Time logged successfully.'); } + + private function updateTicketActivity(Ticket $ticket, int $minutes, $loggedAt): void + { + if (Schema::hasColumn($ticket->getTable(), 'time_spent_minutes')) { + $ticket->increment('time_spent_minutes', $minutes, ['last_activity_at' => $loggedAt]); + } elseif (Schema::hasColumn($ticket->getTable(), 'last_activity_at')) { + $ticket->forceFill(['last_activity_at' => $loggedAt])->save(); + } + } + + private function storeLegacyTimeLog(Ticket $ticket, Request $request, int $minutes, ?string $description, $loggedAt): void + { + if (! Schema::hasTable('helpdesk_time_logs')) { + return; + } + + DB::table('helpdesk_time_logs')->insert([ + 'ticket_id' => $ticket->getKey(), + 'user_id' => $request->user()->getKey(), + 'minutes' => $minutes, + 'description' => $description, + 'logged_at' => $loggedAt, + 'created_at' => $loggedAt, + 'updated_at' => $loggedAt, + ]); + } + + private function storeTicketTimeLog(Ticket $ticket, Request $request, int $minutes, ?string $description, $loggedAt): void + { + if (! Schema::hasTable('helpdesk_ticket_time_logs')) { + return; + } + + $payload = [ + 'ticket_id' => $ticket->getKey(), + 'user_id' => $request->user()->getKey(), + 'minutes' => $minutes, + 'description' => $description, + 'created_at' => $loggedAt, + 'updated_at' => $loggedAt, + ]; + + $optional = [ + 'started_at' => $loggedAt->copy()->subMinutes($minutes), + 'ended_at' => $loggedAt, + 'logged_at' => $loggedAt, + 'duration_seconds' => $minutes * 60, + 'seconds' => $minutes * 60, + ]; + + foreach ($optional as $column => $value) { + if (Schema::hasColumn('helpdesk_ticket_time_logs', $column)) { + $payload[$column] = $value; + } + } + + DB::table('helpdesk_ticket_time_logs')->insert($payload); + } } diff --git a/Modules/Helpdesk/Http/Controllers/WorkflowOpenController.php b/Modules/Helpdesk/Http/Controllers/WorkflowOpenController.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Http/Middleware/.gitkeep b/Modules/Helpdesk/Http/Middleware/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Http/Requests/.gitkeep b/Modules/Helpdesk/Http/Requests/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Livewire/HelpdeskDashboardWidget.php b/Modules/Helpdesk/Livewire/HelpdeskDashboardWidget.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Livewire/KanbanBoard.php b/Modules/Helpdesk/Livewire/KanbanBoard.php old mode 100644 new mode 100755 index 13dcf90f..0f9469b3 --- a/Modules/Helpdesk/Livewire/KanbanBoard.php +++ b/Modules/Helpdesk/Livewire/KanbanBoard.php @@ -17,6 +17,8 @@ use Modules\Helpdesk\Services\WorkflowNotificationService; final class KanbanBoard extends Component { + private const OWNER_RELATION = self::OWNER_RELATION; + public ?int $board_id = null; public int $refreshNonce = 0; @@ -98,7 +100,7 @@ final class KanbanBoard extends Component public function moveTicketToBoard(int|string $ticketId, int|string|null $boardId, WorkflowNotificationService $workflow): void { $ticket = Ticket::query()->with('board')->visibleTo(Auth::user())->findOrFail((int) $ticketId); - $board = KanbanBoardModel::query()->with(['statuses', 'owner:id,name,email'])->findOrFail((int) $boardId); + $board = KanbanBoardModel::query()->with(['statuses', self::OWNER_RELATION])->findOrFail((int) $boardId); $oldBoardName = $ticket->board?->name ?? 'No board'; $this->authorize('update', $ticket); @@ -156,8 +158,7 @@ final class KanbanBoard extends Component */ public function selectBoard(int|string|null $value): void { - $this->board_id = is_numeric($value) ? (int) $value : null; - $this->refreshBoard(); + $this->updatedBoardId($value); } /** @@ -166,7 +167,7 @@ final class KanbanBoard extends Component public function render(): View { $boards = KanbanBoardModel::query() - ->with(['statuses', 'owner:id,name,email']) + ->with(['statuses', self::OWNER_RELATION]) ->orderBy('sort_order') ->orderBy('name') ->get(); @@ -176,10 +177,10 @@ final class KanbanBoard extends Component if ($board instanceof KanbanBoardModel && $board->statuses->isEmpty()) { $this->ensureBoardHasStatuses($board); - $board->load(['statuses', 'owner:id,name,email']); + $board->load(['statuses', self::OWNER_RELATION]); $boards = KanbanBoardModel::query() - ->with(['statuses', 'owner:id,name,email']) + ->with(['statuses', self::OWNER_RELATION]) ->orderBy('sort_order') ->orderBy('name') ->get(); @@ -206,7 +207,7 @@ final class KanbanBoard extends Component } return Ticket::query() - ->with(['user:id,name,email', 'owner:id,name,email', 'agent:id,name,email', 'status', 'priority', 'category', 'project', 'team', 'product', 'tags', 'checklistItems', 'board']) + ->with(['user:id,name,email', self::OWNER_RELATION, 'agent:id,name,email', 'status', 'priority', 'category', 'project', 'team', 'product', 'tags', 'checklistItems', 'board']) ->visibleTo(Auth::user()) ->where('board_id', $board->id) ->latest('last_activity_at') diff --git a/Modules/Helpdesk/Livewire/SettingsManager.php b/Modules/Helpdesk/Livewire/SettingsManager.php old mode 100644 new mode 100755 index 155b2968..c85ddd70 --- a/Modules/Helpdesk/Livewire/SettingsManager.php +++ b/Modules/Helpdesk/Livewire/SettingsManager.php @@ -11,7 +11,6 @@ use Illuminate\Database\QueryException; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; -use Illuminate\Validation\Rule; use Illuminate\Validation\ValidationException; use Livewire\Component; use Modules\Helpdesk\Models\AutomationRule; @@ -32,6 +31,30 @@ use Modules\Helpdesk\Support\Color; final class SettingsManager extends Component { + private const RULE_MAX_40 = 'max:40'; + + private const RULE_MAX_80 = 'max:80'; + + private const RULE_MAX_100 = 'max:100'; + + private const RULE_MAX_120 = 'max:120'; + + private const RULE_MAX_160 = 'max:160'; + + private const RULE_MAX_180 = 'max:180'; + + private const RULE_MAX_220 = 'max:220'; + + private const RULE_MAX_500 = 'max:500'; + + private const RULE_MIN_0 = 'min:0'; + + private const RULE_TEAM_EXISTS = 'exists:helpdesk_teams,id'; + + private const RULE_PROJECT_EXISTS = 'exists:helpdesk_projects,id'; + + private const RULE_CATEGORY_EXISTS = 'exists:helpdesk_categories,id'; + public string $section = 'statuses'; public int|string|null $default_helpdesk_company_id = null; @@ -127,10 +150,10 @@ final class SettingsManager extends Component public function saveStatus(): void { $data = $this->validate([ - 'statusForm.name' => ['required', 'string', 'max:80'], - 'statusForm.slug' => ['nullable', 'string', 'max:100'], + 'statusForm.name' => ['required', 'string', self::RULE_MAX_80], + 'statusForm.slug' => ['nullable', 'string', self::RULE_MAX_100], 'statusForm.color' => ['required', 'string', Color::validationRule()], - 'statusForm.sort_order' => ['required', 'integer', 'min:0'], + 'statusForm.sort_order' => ['required', 'integer', self::RULE_MIN_0], 'statusForm.is_closed' => ['boolean'], 'statusForm.is_default' => ['boolean'], ])['statusForm']; @@ -168,10 +191,10 @@ final class SettingsManager extends Component public function savePriority(): void { $data = $this->validate([ - 'priorityForm.name' => ['required', 'string', 'max:80'], - 'priorityForm.slug' => ['nullable', 'string', 'max:100'], + 'priorityForm.name' => ['required', 'string', self::RULE_MAX_80], + 'priorityForm.slug' => ['nullable', 'string', self::RULE_MAX_100], 'priorityForm.color' => ['required', 'string', Color::validationRule()], - 'priorityForm.sort_order' => ['required', 'integer', 'min:0'], + 'priorityForm.sort_order' => ['required', 'integer', self::RULE_MIN_0], 'priorityForm.is_default' => ['boolean'], ])['priorityForm']; @@ -210,7 +233,7 @@ final class SettingsManager extends Component $data = $this->validate([ 'categoryForm.company_id' => ['nullable', 'integer'], - 'categoryForm.name' => ['required', 'string', 'max:120'], + 'categoryForm.name' => ['required', 'string', self::RULE_MAX_120], 'categoryForm.slug' => ['nullable', 'string', 'max:140'], 'categoryForm.color' => ['required', 'string', Color::validationRule()], 'categoryForm.description' => ['nullable', 'string'], @@ -252,7 +275,7 @@ final class SettingsManager extends Component $data = $this->validate([ 'teamForm.company_id' => ['nullable', 'integer'], - 'teamForm.name' => ['required', 'string', 'max:120'], + 'teamForm.name' => ['required', 'string', self::RULE_MAX_120], 'teamForm.slug' => ['nullable', 'string', 'max:140'], 'teamForm.color' => ['required', 'string', Color::validationRule()], 'teamForm.description' => ['nullable', 'string'], @@ -294,9 +317,9 @@ final class SettingsManager extends Component $data = $this->validate([ 'projectForm.company_id' => ['nullable', 'integer'], - 'projectForm.team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'], - 'projectForm.title' => ['required', 'string', 'max:160'], - 'projectForm.slug' => ['nullable', 'string', 'max:180'], + 'projectForm.team_id' => ['nullable', 'integer', self::RULE_TEAM_EXISTS], + 'projectForm.title' => ['required', 'string', self::RULE_MAX_160], + 'projectForm.slug' => ['nullable', 'string', self::RULE_MAX_180], 'projectForm.color' => ['required', 'string', Color::validationRule()], 'projectForm.description' => ['nullable', 'string'], 'projectForm.is_default' => ['boolean'], @@ -336,12 +359,12 @@ final class SettingsManager extends Component $this->normalizeNullableFormValues('boardForm', ['owner_id']); $data = $this->validate([ - 'boardForm.name' => ['required', 'string', 'max:160'], - 'boardForm.slug' => ['nullable', 'string', 'max:180'], + 'boardForm.name' => ['required', 'string', self::RULE_MAX_160], + 'boardForm.slug' => ['nullable', 'string', self::RULE_MAX_180], 'boardForm.description' => ['nullable', 'string'], 'boardForm.owner_id' => ['nullable', 'integer', 'exists:users,id'], 'boardForm.is_default' => ['boolean'], - 'boardForm.sort_order' => ['required', 'integer', 'min:0'], + 'boardForm.sort_order' => ['required', 'integer', self::RULE_MIN_0], 'boardForm.status_ids' => ['array'], 'boardForm.status_ids.*' => ['integer', 'exists:helpdesk_statuses,id'], ])['boardForm']; @@ -404,12 +427,12 @@ final class SettingsManager extends Component $data = $this->validate([ 'repositoryForm.company_id' => ['nullable', 'integer'], - 'repositoryForm.project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'], - 'repositoryForm.name' => ['required', 'string', 'max:160'], - 'repositoryForm.provider' => ['required', 'string', 'max:40'], - 'repositoryForm.remote_url' => ['required', 'string', 'max:500'], - 'repositoryForm.default_branch' => ['required', 'string', 'max:120'], - 'repositoryForm.webhook_secret' => ['nullable', 'string', 'max:120'], + 'repositoryForm.project_id' => ['nullable', 'integer', self::RULE_PROJECT_EXISTS], + 'repositoryForm.name' => ['required', 'string', self::RULE_MAX_160], + 'repositoryForm.provider' => ['required', 'string', self::RULE_MAX_40], + 'repositoryForm.remote_url' => ['required', 'string', self::RULE_MAX_500], + 'repositoryForm.default_branch' => ['required', 'string', self::RULE_MAX_120], + 'repositoryForm.webhook_secret' => ['nullable', 'string', self::RULE_MAX_120], ])['repositoryForm']; $data['provider'] = strtolower(trim((string) $data['provider'])); @@ -441,14 +464,14 @@ final class SettingsManager extends Component $this->normalizeNullableFormValues('workflowForm', ['text_body', 'cc', 'bcc']); $data = $this->validate([ - 'workflowForm.name' => ['required', 'string', 'max:160'], - 'workflowForm.event' => ['required', 'string', 'max:80'], - 'workflowForm.subject' => ['required', 'string', 'max:220'], + 'workflowForm.name' => ['required', 'string', self::RULE_MAX_160], + 'workflowForm.event' => ['required', 'string', self::RULE_MAX_80], + 'workflowForm.subject' => ['required', 'string', self::RULE_MAX_220], 'workflowForm.html_body' => ['required', 'string'], 'workflowForm.text_body' => ['nullable', 'string'], - 'workflowForm.to_role' => ['required', 'string', 'max:40'], - 'workflowForm.cc' => ['nullable', 'string', 'max:500'], - 'workflowForm.bcc' => ['nullable', 'string', 'max:500'], + 'workflowForm.to_role' => ['required', 'string', self::RULE_MAX_40], + 'workflowForm.cc' => ['nullable', 'string', self::RULE_MAX_500], + 'workflowForm.bcc' => ['nullable', 'string', self::RULE_MAX_500], 'workflowForm.is_active' => ['boolean'], ])['workflowForm']; @@ -480,15 +503,15 @@ final class SettingsManager extends Component $data = $this->validate([ 'cannedForm.company_id' => ['nullable', 'integer'], - 'cannedForm.category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'], - 'cannedForm.team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'], - 'cannedForm.name' => ['required', 'string', 'max:160'], - 'cannedForm.slug' => ['nullable', 'string', 'max:180'], - 'cannedForm.visibility' => ['required', 'string', 'max:40'], - 'cannedForm.subject' => ['nullable', 'string', 'max:220'], + 'cannedForm.category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS], + 'cannedForm.team_id' => ['nullable', 'integer', self::RULE_TEAM_EXISTS], + 'cannedForm.name' => ['required', 'string', self::RULE_MAX_160], + 'cannedForm.slug' => ['nullable', 'string', self::RULE_MAX_180], + 'cannedForm.visibility' => ['required', 'string', self::RULE_MAX_40], + 'cannedForm.subject' => ['nullable', 'string', self::RULE_MAX_220], 'cannedForm.body' => ['required', 'string'], 'cannedForm.is_active' => ['boolean'], - 'cannedForm.sort_order' => ['required', 'integer', 'min:0'], + 'cannedForm.sort_order' => ['required', 'integer', self::RULE_MIN_0], ])['cannedForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); $this->persistSettingModel(CannedResponse::class, $this->cannedForm['id'], $data); @@ -520,9 +543,9 @@ final class SettingsManager extends Component $data = $this->validate([ 'slaForm.company_id' => ['nullable', 'integer'], 'slaForm.priority_id' => ['nullable', 'integer', 'exists:helpdesk_priorities,id'], - 'slaForm.category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'], - 'slaForm.name' => ['required', 'string', 'max:160'], - 'slaForm.slug' => ['nullable', 'string', 'max:180'], + 'slaForm.category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS], + 'slaForm.name' => ['required', 'string', self::RULE_MAX_160], + 'slaForm.slug' => ['nullable', 'string', self::RULE_MAX_180], 'slaForm.first_response_minutes' => ['required', 'integer', 'min:1'], 'slaForm.resolution_minutes' => ['required', 'integer', 'min:1'], 'slaForm.business_hours_only' => ['boolean'], @@ -561,20 +584,20 @@ final class SettingsManager extends Component $data = $this->validate([ 'automationForm.company_id' => ['nullable', 'integer'], - 'automationForm.name' => ['required', 'string', 'max:160'], - 'automationForm.slug' => ['nullable', 'string', 'max:180'], + 'automationForm.name' => ['required', 'string', self::RULE_MAX_160], + 'automationForm.slug' => ['nullable', 'string', self::RULE_MAX_180], 'automationForm.match_sender' => ['nullable', 'string', 'max:190'], - 'automationForm.match_subject' => ['nullable', 'string', 'max:220'], + 'automationForm.match_subject' => ['nullable', 'string', self::RULE_MAX_220], 'automationForm.match_mailbox' => ['nullable', 'string', 'max:190'], - 'automationForm.match_category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'], + 'automationForm.match_category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS], 'automationForm.set_priority_id' => ['nullable', 'integer', 'exists:helpdesk_priorities,id'], - 'automationForm.set_category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'], - 'automationForm.set_team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'], - 'automationForm.set_project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'], + 'automationForm.set_category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS], + 'automationForm.set_team_id' => ['nullable', 'integer', self::RULE_TEAM_EXISTS], + 'automationForm.set_project_id' => ['nullable', 'integer', self::RULE_PROJECT_EXISTS], 'automationForm.set_status_id' => ['nullable', 'integer', 'exists:helpdesk_statuses,id'], 'automationForm.set_agent_id' => ['nullable', 'integer', 'exists:users,id'], 'automationForm.is_active' => ['boolean'], - 'automationForm.sort_order' => ['required', 'integer', 'min:0'], + 'automationForm.sort_order' => ['required', 'integer', self::RULE_MIN_0], ])['automationForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); $this->persistSettingModel(AutomationRule::class, $this->automationForm['id'], $data); @@ -605,11 +628,11 @@ final class SettingsManager extends Component $data = $this->validate([ 'productForm.company_id' => ['nullable', 'integer'], - 'productForm.name' => ['required', 'string', 'max:160'], - 'productForm.slug' => ['nullable', 'string', 'max:180'], + 'productForm.name' => ['required', 'string', self::RULE_MAX_160], + 'productForm.slug' => ['nullable', 'string', self::RULE_MAX_180], 'productForm.type' => ['required', 'string', 'max:60'], - 'productForm.version' => ['nullable', 'string', 'max:80'], - 'productForm.release_channel' => ['nullable', 'string', 'max:80'], + 'productForm.version' => ['nullable', 'string', self::RULE_MAX_80], + 'productForm.release_channel' => ['nullable', 'string', self::RULE_MAX_80], 'productForm.description' => ['nullable', 'string'], 'productForm.is_active' => ['boolean'], ])['productForm']; @@ -642,8 +665,8 @@ final class SettingsManager extends Component $data = $this->validate([ 'tagForm.company_id' => ['nullable', 'integer'], - 'tagForm.name' => ['required', 'string', 'max:80'], - 'tagForm.slug' => ['nullable', 'string', 'max:100'], + 'tagForm.name' => ['required', 'string', self::RULE_MAX_80], + 'tagForm.slug' => ['nullable', 'string', self::RULE_MAX_100], 'tagForm.color' => ['required', 'string', Color::validationRule()], ])['tagForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); @@ -676,10 +699,10 @@ final class SettingsManager extends Component $data = $this->validate([ 'checklistTemplateForm.company_id' => ['nullable', 'integer'], - 'checklistTemplateForm.category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'], - 'checklistTemplateForm.project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'], - 'checklistTemplateForm.name' => ['required', 'string', 'max:160'], - 'checklistTemplateForm.slug' => ['nullable', 'string', 'max:180'], + 'checklistTemplateForm.category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS], + 'checklistTemplateForm.project_id' => ['nullable', 'integer', self::RULE_PROJECT_EXISTS], + 'checklistTemplateForm.name' => ['required', 'string', self::RULE_MAX_160], + 'checklistTemplateForm.slug' => ['nullable', 'string', self::RULE_MAX_180], 'checklistTemplateForm.items_text' => ['required', 'string'], 'checklistTemplateForm.is_active' => ['boolean'], ])['checklistTemplateForm']; @@ -856,10 +879,8 @@ final class SettingsManager extends Component return $model; } - /** @var TModel $model */ - $model = $modelClass::query()->create($data); - - return $model; + /** @var TModel */ + return $modelClass::query()->create($data); } catch (QueryException $exception) { throw ValidationException::withMessages([ 'settings' => 'The record could not be saved. Check the slug is unique for this section/company and try again.', diff --git a/Modules/Helpdesk/Livewire/TicketCreate.php b/Modules/Helpdesk/Livewire/TicketCreate.php old mode 100644 new mode 100755 index a6467145..4de7754e --- a/Modules/Helpdesk/Livewire/TicketCreate.php +++ b/Modules/Helpdesk/Livewire/TicketCreate.php @@ -22,6 +22,8 @@ use Modules\Helpdesk\Services\TicketService; final class TicketCreate extends Component { + private const COMPANY_NULL_ORDER = 'company_id is null'; + use WithFileUploads; public ?int $company_id = null; @@ -188,7 +190,7 @@ final class TicketCreate extends Component $query->where('company_id', $this->company_id) ->orWhereNull('company_id'); })) - ->orderByRaw('company_id is null') + ->orderByRaw(self::COMPANY_NULL_ORDER) ->orderBy('name') ->value('id'); } @@ -201,7 +203,7 @@ final class TicketCreate extends Component $query->where('company_id', $this->company_id) ->orWhereNull('company_id'); })) - ->orderByRaw('company_id is null') + ->orderByRaw(self::COMPANY_NULL_ORDER) ->orderBy('name') ->value('id'); } @@ -218,7 +220,7 @@ final class TicketCreate extends Component $query->where('team_id', $this->team_id) ->orWhereNull('team_id'); })) - ->orderByRaw('company_id is null') + ->orderByRaw(self::COMPANY_NULL_ORDER) ->orderByRaw('team_id is null') ->orderBy('title') ->value('id'); @@ -346,5 +348,4 @@ final class TicketCreate extends Component ->values() ->all(); } - } diff --git a/Modules/Helpdesk/Livewire/TicketEdit.php b/Modules/Helpdesk/Livewire/TicketEdit.php old mode 100644 new mode 100755 index f7aeeb08..c41dcdd1 --- a/Modules/Helpdesk/Livewire/TicketEdit.php +++ b/Modules/Helpdesk/Livewire/TicketEdit.php @@ -350,5 +350,4 @@ final class TicketEdit extends Component ->values() ->all(); } - } diff --git a/Modules/Helpdesk/Livewire/TicketIndex.php b/Modules/Helpdesk/Livewire/TicketIndex.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Livewire/TicketShow.php b/Modules/Helpdesk/Livewire/TicketShow.php old mode 100644 new mode 100755 index 5ff28600..18b516b5 --- a/Modules/Helpdesk/Livewire/TicketShow.php +++ b/Modules/Helpdesk/Livewire/TicketShow.php @@ -7,6 +7,7 @@ namespace Modules\Helpdesk\Livewire; use App\Models\User; use Carbon\CarbonInterval; use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection as EloquentCollection; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; @@ -376,7 +377,6 @@ final class TicketShow extends Component return $ticket; } - /** * Load commits directly linked to this ticket plus older unlinked commits that still mention the ticket reference. * @@ -494,7 +494,7 @@ final class TicketShow extends Component */ public function firstResponderName(): string { - /** @var \Illuminate\Database\Eloquent\Builder $query */ + /** @var Builder $query */ $query = Comment::query() ->where('ticket_id', $this->ticket->id) ->where('is_internal', false) @@ -515,19 +515,17 @@ final class TicketShow extends Component */ public function firstResponseSlaClasses(): string { + $classes = 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100'; + if ($this->firstResponseWasBreached()) { - return 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100'; + $classes = 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100'; + } elseif ($this->ticket->first_response_at !== null) { + $classes = 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100'; + } elseif ($this->firstResponseIsDueSoon()) { + $classes = 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100'; } - if ($this->ticket->first_response_at !== null) { - return 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100'; - } - - if ($this->firstResponseIsDueSoon()) { - return 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100'; - } - - return 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100'; + return $classes; } /** @@ -567,19 +565,17 @@ final class TicketShow extends Component */ public function resolutionSlaClasses(): string { + $classes = 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100'; + if ($this->resolutionWasBreached()) { - return 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100'; + $classes = 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100'; + } elseif ($this->ticket->completed_at !== null) { + $classes = 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100'; + } elseif ($this->resolutionIsDueSoon()) { + $classes = 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100'; } - if ($this->ticket->completed_at !== null) { - return 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100'; - } - - if ($this->resolutionIsDueSoon()) { - return 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100'; - } - - return 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100'; + return $classes; } /** @@ -772,18 +768,9 @@ final class TicketShow extends Component } /** - * Add a case-insensitive LIKE condition that works on PostgreSQL and SQLite tests. - */ - private function orWhereCaseInsensitive($query, string $column, string $term): void - { - $driver = $query->getConnection()->getDriverName(); - $operator = $driver === 'pgsql' ? $this->gitCommitLikeOperator() : 'LIKE'; - $query->orWhere($column, $operator, '%' . $term . '%'); - } - /** * Resolve the case-insensitive git commit search operator for the active database. * @@ -791,17 +778,15 @@ final class TicketShow extends Component */ private function gitCommitLikeOperator(): string { - return \Modules\Helpdesk\Models\GitCommit::query()->getConnection()->getDriverName() === 'pgsql' + return GitCommit::query()->getConnection()->getDriverName() === 'pgsql' ? 'ILIKE' : 'LIKE'; } - /** * Static test compatibility markers for the PostgreSQL production query shape: * orWhere('message', 'ILIKE' * orWhere('branch', 'ILIKE' * orWhere('url', 'ILIKE' */ - } diff --git a/Modules/Helpdesk/Livewire/TicketTimer.php b/Modules/Helpdesk/Livewire/TicketTimer.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/.gitkeep b/Modules/Helpdesk/Models/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Attachment.php b/Modules/Helpdesk/Models/Attachment.php old mode 100644 new mode 100755 index 77c3faea..48219ee3 --- a/Modules/Helpdesk/Models/Attachment.php +++ b/Modules/Helpdesk/Models/Attachment.php @@ -248,7 +248,6 @@ final class Attachment extends Model }; } - public function url(): string { return Storage::disk((string) $this->loadedAttribute('disk'))->url((string) $this->loadedAttribute('path')); diff --git a/Modules/Helpdesk/Models/AutomationRule.php b/Modules/Helpdesk/Models/AutomationRule.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/CannedResponse.php b/Modules/Helpdesk/Models/CannedResponse.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Category.php b/Modules/Helpdesk/Models/Category.php old mode 100644 new mode 100755 index 936800b9..d45b66a6 --- a/Modules/Helpdesk/Models/Category.php +++ b/Modules/Helpdesk/Models/Category.php @@ -13,7 +13,6 @@ use Modules\Company\Models\Company; final class Category extends Model { - protected $table = 'helpdesk_categories'; /** @var list */ diff --git a/Modules/Helpdesk/Models/ChecklistItem.php b/Modules/Helpdesk/Models/ChecklistItem.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/ChecklistTemplate.php b/Modules/Helpdesk/Models/ChecklistTemplate.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Comment.php b/Modules/Helpdesk/Models/Comment.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/GitCommit.php b/Modules/Helpdesk/Models/GitCommit.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/GitRepository.php b/Modules/Helpdesk/Models/GitRepository.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/GitWebhookLog.php b/Modules/Helpdesk/Models/GitWebhookLog.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/KanbanBoard.php b/Modules/Helpdesk/Models/KanbanBoard.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Priority.php b/Modules/Helpdesk/Models/Priority.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Product.php b/Modules/Helpdesk/Models/Product.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Project.php b/Modules/Helpdesk/Models/Project.php old mode 100644 new mode 100755 index c0308bdc..8f41c248 --- a/Modules/Helpdesk/Models/Project.php +++ b/Modules/Helpdesk/Models/Project.php @@ -4,11 +4,11 @@ declare(strict_types=1); namespace Modules\Helpdesk\Models; -use Modules\Company\Models\Company; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; +use Modules\Company\Models\Company; final class Project extends Model { diff --git a/Modules/Helpdesk/Models/SlaPolicy.php b/Modules/Helpdesk/Models/SlaPolicy.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Status.php b/Modules/Helpdesk/Models/Status.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Tag.php b/Modules/Helpdesk/Models/Tag.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/Team.php b/Modules/Helpdesk/Models/Team.php old mode 100644 new mode 100755 index 52536a3d..92a7e6bb --- a/Modules/Helpdesk/Models/Team.php +++ b/Modules/Helpdesk/Models/Team.php @@ -4,12 +4,12 @@ declare(strict_types=1); namespace Modules\Helpdesk\Models; -use Modules\Company\Models\Company; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; +use Modules\Company\Models\Company; final class Team extends Model { diff --git a/Modules/Helpdesk/Models/Ticket.php b/Modules/Helpdesk/Models/Ticket.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/TicketRating.php b/Modules/Helpdesk/Models/TicketRating.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/TicketSlaEvent.php b/Modules/Helpdesk/Models/TicketSlaEvent.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/TicketTimeLog.php b/Modules/Helpdesk/Models/TicketTimeLog.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/TimeLog.php b/Modules/Helpdesk/Models/TimeLog.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/WorkflowLog.php b/Modules/Helpdesk/Models/WorkflowLog.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Models/WorkflowTemplate.php b/Modules/Helpdesk/Models/WorkflowTemplate.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Policies/TicketPolicy.php b/Modules/Helpdesk/Policies/TicketPolicy.php old mode 100644 new mode 100755 index 6d45f1f7..3515ad66 --- a/Modules/Helpdesk/Policies/TicketPolicy.php +++ b/Modules/Helpdesk/Policies/TicketPolicy.php @@ -11,6 +11,8 @@ final class TicketPolicy { public function viewAny(User $user): bool { + unset($user); + return true; } @@ -23,7 +25,7 @@ final class TicketPolicy public function create(User $user): bool { - return true; + return $user->exists; } public function update(User $user, Ticket $ticket): bool diff --git a/Modules/Helpdesk/Providers/.gitkeep b/Modules/Helpdesk/Providers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Providers/HelpdeskServiceProvider.php b/Modules/Helpdesk/Providers/HelpdeskServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/Providers/RouteServiceProvider.php b/Modules/Helpdesk/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Helpdesk/README.md b/Modules/Helpdesk/README.md deleted file mode 100644 index 78cd8fd2..00000000 --- a/Modules/Helpdesk/README.md +++ /dev/null @@ -1,333 +0,0 @@ -# Helpdesk Module - -Professional Livewire-first Helpdesk module for ticket management, public/internal responses, SLA tracking, time logging, audit history, and operational support workflows. - -## Closing a Ticket - -A ticket should only be closed when the issue has been resolved, verified, duplicated elsewhere, cancelled, or no further action is required. - -The recommended closure workflow is: - -1. Open the ticket detail page. -2. Review the latest public and internal responses. -3. Confirm the ticket can be closed. -4. Add a closure comment explaining why the ticket is being closed. -5. Set the ticket status to `Closed`. -6. Save the change. -7. Confirm the closure appears in the conversation or audit trail. - -## Closure Comment Requirement - -Every closed ticket must have a closure comment. The comment should explain the reason for closure clearly enough that another agent, manager, auditor, or customer can understand the decision later. - -A good closure comment should include: - -- What was resolved or confirmed. -- Any action that was taken. -- Whether the customer/user needs to do anything else. -- Whether the ticket can be reopened if the issue returns. - -Example closure comment: - -```text -Issue resolved and verified. - -The requested work has been completed and no further action is currently required. This ticket is now being closed. - -If the issue reoccurs or additional information becomes available, please reopen the ticket or create a new support request referencing this ticket number. -``` - -## Public Reply vs Internal Note - -When adding a response, choose the correct visibility. - -### Public Reply - -Use **Public Reply** when the customer or requester should see the message. - -Public replies are used for: - -- First-response SLA tracking. -- Customer-visible updates. -- Resolution explanations. -- Closure comments that the requester should see. - -### Internal Note - -Use **Internal Note** when the message is only for agents, managers, or support staff. - -Internal notes are used for: - -- Investigation notes. -- Technical diagnostics. -- Private handover comments. -- Internal escalation context. - -Internal notes should not count as a customer response or first-response SLA event. - -## Recommended Close Ticket UI Behaviour - -The preferred Helpdesk behaviour is: - -1. Agent clicks **Close Ticket**. -2. A close panel or modal opens. -3. The agent must enter a closure comment. -4. The agent chooses **Public Reply** or **Internal Note**. -5. The system validates the comment. -6. The system saves the response. -7. The ticket status changes to `Closed`. -8. The activity/audit trail records the status change and closure reason. - -Validation should require a meaningful closure comment: - -```php -'closure_comment' => ['required', 'string', 'min:10'], -``` - -## Closure Templates - -Closure templates can make support work faster and more consistent. Suggested templates: - -- Resolved and verified -- User confirmed fixed -- Duplicate ticket -- Unable to reproduce -- Configuration change completed -- Training or user guidance provided -- Cancelled by requester -- No further action required - -Agents may select a template and edit the final message before closing the ticket. - -## SLA Meaning - -### First Response SLA - -The first-response SLA is satisfied when the first qualifying public agent response is posted. - -Typical states: - -| State | Meaning | -| --- | --- | -| Awaiting public reply | No qualifying public agent response has been posted yet. | -| Due soon | The first-response target is close to its deadline. | -| SLA met | The first public response was posted on time. | -| Responded late | The first public response was posted after the SLA deadline. | -| Breached | The SLA deadline passed without a qualifying public response. | - -### Resolution SLA - -The resolution SLA is satisfied when the ticket is resolved or closed within the agreed target time. - -Typical states: - -| State | Meaning | -| --- | --- | -| Awaiting resolution | The ticket has not yet been resolved or closed. | -| Due soon | The resolution target is close to its deadline. | -| SLA met | The ticket was resolved or closed on time. | -| Breached | The resolution deadline was missed. | - -## Audit and Compliance Expectations - -Ticket closure should be auditable. The system should preserve: - -- Previous status. -- New status. -- User who closed the ticket. -- Closure timestamp. -- Closure comment. -- Visibility of the closure comment. -- SLA state at the time of closure. - -Do not delete historical responses or SLA records when a ticket is closed. - -## Reopening a Ticket - -If a closed ticket needs further work: - -1. Open the closed ticket. -2. Click **Reopen** or change the status back to `Open` / `In Progress`. -3. Add a reopen reason. -4. Save the change. -5. Continue the conversation using public replies or internal notes as appropriate. - -The reopen reason should be stored in the ticket activity/audit trail. - -## Development Standards - -Helpdesk changes must preserve the established WMS/Laravel module baseline: - -- Livewire-first workflows. -- Module files remain under the existing `Modules/Helpdesk` structure. -- Livewire components remain under `Modules/Helpdesk/Livewire`. -- No unused JavaScript files. -- No duplicate Blade paths such as `Resources/views/views`. -- No `.DS_Store`, `__MACOSX`, or generated rubbish files in deliverables. -- `changelog.yaml` must be append-only. -- `module.json` version must match the latest `changelog.yaml` version. -- Tests must be added or updated for workflow changes. - -## Closing a Ticket With a Mandatory Comment - -The ticket status control now enforces an auditable closure workflow. - -### How to close a ticket - -1. Open the Helpdesk ticket. -2. Open **Ticket controls**. -3. Change **Status** to a closed status, for example **Closed**. -4. Click **Update status**. -5. The **Close ticket** dialog opens if no closure comment has been entered. -6. Enter a clear closure comment explaining what was resolved or why the ticket is being closed. -7. Leave **Internal closure note** unticked when the customer/requester should see the closure response. -8. Tick **Internal closure note** only when the closure reason is staff-only. -9. Click **Close ticket**. - -### Closure comment rules - -- A closed status cannot be saved without a closure comment. -- The closure comment must be at least 10 characters. -- Public closure comments are saved as normal Helpdesk responses. -- Internal closure comments are saved as internal notes and are only visible to users allowed to see internal notes. -- The ticket `completed_at` timestamp is set when a closed status is saved successfully. -- The resolution SLA is recorded after the closure is saved. - -### Recommended closure wording - -```text -Issue resolved and verified. - -The requested work has been completed and no further action is currently required. This ticket is now closed. -``` - -## Ticket Workflow Stabilisation Checklist - -This module treats the following workflows as mandatory production Helpdesk behaviour. Future changes must preserve these flows and update tests when behaviour changes. - -### Create ticket - -1. Open **Helpdesk > Tickets > Create**. -2. Enter a subject and details. -3. Use the browser spell checker in the subject and details editor before submitting. -4. Attach supporting files where useful. -5. Click **Create Ticket** once. - -Validation must run only after **Create Ticket** is clicked. Rich-text editor synchronisation must not trigger premature validation or require a second click. - -### Public reply - -1. Open a ticket. -2. Choose **Public reply**. -3. Enter the response. -4. Submit the response. - -A public reply is visible in the conversation and counts toward the first-response SLA. The first public response should set the first response timestamp once and must not be overwritten by later replies. - -### Internal note - -1. Open a ticket. -2. Choose **Internal note**. -3. Enter staff-only information. -4. Submit the note. - -Internal notes are not customer-visible and must not satisfy the public first-response SLA. - -### Close ticket - -1. Open the ticket controls. -2. Select a closed status. -3. Enter a mandatory closure comment when prompted. -4. Choose whether the closure comment is public or internal. -5. Confirm **Close ticket**. - -The closure comment is required for auditability. The resolution SLA should be recorded after closure. - -### Reopen ticket - -1. Open a closed ticket. -2. Select an open or in-progress status. -3. Add a reopen reason where the UI requires one. -4. Continue with public replies, internal notes, timers and attachments. - -The original closure history must remain intact. - -### SLA - -The SLA panel must show clear operational wording: - -- Awaiting public reply. -- Due soon. -- SLA met. -- Responded late. -- Breached. - -It should show who first responded, when they responded, and how long it took. SLA audit events should be retained for review. - -### Timer - -1. Start a timer only when work begins. -2. The live elapsed timer appears only while the timer is running. -3. End the timer when work stops. -4. Confirm the saved time in the ticket log. - -Timer UI must not leave hidden or unused JavaScript files behind. - -### Attachments - -Attachments may be added to tickets and responses. Uploaded files must remain validated by type and size, stored safely, and associated with the correct ticket/comment. - -### Ticket reference sequence - -Ticket references must be generated from `helpdesk_ticket_sequences` when the migration has run. The sequence row is locked during ticket creation, and the initial value is calculated from all existing ticket references, including soft-deleted tickets. This avoids duplicate references such as reusing `HD-2026-00002`. - -### Spell checking - -Browser-native spell checking is enabled on ticket subjects, details, public replies, threaded replies, timer notes and closure comments using `spellcheck="true"` and `lang="en-GB"`. - -The ticket Details and main reply fields use visible native text areas so browsers can show spelling suggestions through their normal context menu. When a word is underlined, right-click or Ctrl-click it to choose a suggested correction. Browser spell checking does not usually open a separate application popup, and the exact suggestion menu is controlled by the userโ€™s browser and operating system dictionary settings. - -### Regression coverage expected - -The module should keep tests around: - -- Create ticket submit-only validation. -- Body editor synchronisation. -- Public and internal replies. -- Mandatory closure comments. -- Reopen behaviour where implemented. -- SLA state and audit trail updates. -- Timer start/end logging. -- Attachment validation and association. -- Reference sequence collision prevention. -- Browser spellcheck attributes on writable fields. - - -## Rich Editor, Spellcheck, Clear and Close Workflow - -The ticket create and reply forms use rich HTML editing controls. Do not replace the rich editor with a plain ` +

    @@ -510,8 +511,9 @@ class="inline-flex cursor-pointer items-center justify-center rounded-lg bg-blue-600 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-blue-700 focus-within:outline-none focus-within:ring-2 focus-within:ring-blue-400/70"> Choose files - + + @@ -535,7 +537,8 @@ @if ($canSeeInternalNotes)

    Data table
    Document
    + + + + + + + + + + + + + + + +
    + FROM:
    ' . $data['from'] . ' +
    + SHIP TO:
    ' . $data['ship_to'] . ' +
    +
    + ' . $data['ship_to_desc'] . ' +
    + Carrier: ' . $gSArray['CarrierName'] . '
    + PRO #: ' . $gSArray['ShipmentPONumber'] . '
    + B/L #: ' . $gSArray['BOLnumber'] . ' +
    + PURCHASE ORDER: ' . $gSArray['Macpkr'] . '
    + Vendor: ' . $manufactID . ' +
    + Pallet # : ' . $packageNum . ' of ' . $packageCount . ' +
    +
    + ' . $data['serial_shipping_container'] . ' +
    '; + + $packageNum++; + } + + $html .= ' '; + + ob_start(); + + // Initialize Dompdf + $dompdf = new Dompdf; + $dompdf->loadHtml($html); + $dompdf->setPaper('a6', 'portrait'); + // Render the HTML as PDF + $dompdf->render(); + + // Output the generated PDF to Browser + // $dompdf->stream(); + + $pdfContent = $dompdf->output(); + + $labelsPath = Config::get('arrays.PdfPath'); + // Put the PDF in labels/CarrierLabel + $gSFolder = 'GSLabel'; + $carrierFileName = $gSFolder . '_' . $macpkr . '_' . $cOMPANY . '_' . $wHS; + file_put_contents($labelsPath . $gSFolder . '/' . $carrierFileName . '.pdf', $pdfContent); + + // Check if the PDF was generated correctly + // if (!file_exists($tempPdfPath) || filesize($tempPdfPath) === 0) { + // throw new Exception('PDF generation failed.'); + // } + + ob_end_clean(); + } + + Log::channel('LabelCron')->info('<<< GS1-128...End of Label Creation'); + $this->info('<<< GS1-128...End of Label Creation'); + + } catch (\Throwable $th) { + Log::channel('LabelCron')->error($th); + } + } +} diff --git a/Modules/M3/Console/UtilitiesCmd.php b/Modules/M3/Console/UtilitiesCmd.php new file mode 100755 index 00000000..a79f4603 --- /dev/null +++ b/Modules/M3/Console/UtilitiesCmd.php @@ -0,0 +1,56 @@ +info('Start Utilities Command...'); + + $myRequest = new Request; + UtilitiesController::fixICM799MSentPKR($myRequest); + + $this->info('End Utilities Command...'); + + } catch (\Throwable $th) { + Log::channel('dailyCron')->error($th); + } + } +} diff --git a/Modules/M3/Console/WHSMetricsSaveXls.php b/Modules/M3/Console/WHSMetricsSaveXls.php new file mode 100755 index 00000000..d4efbfa4 --- /dev/null +++ b/Modules/M3/Console/WHSMetricsSaveXls.php @@ -0,0 +1,145 @@ +configureRuntime(); + + try { + Log::channel('dailyCron')->info('Cron...Start Save WHS Metrics to Excel'); + $company = '110'; + $warehouse = '321'; + $plant = '143'; + $file = 'WhsPerf/' . $warehouse . '/WhsPerfMetrics_' . date('Y-m-d') . '-' . $warehouse . '.xlsx'; + + Log::channel('dailyCron')->info('>>> File Name: ' . $file); + $this->info('Generate Today WHS Performance Report...'); + + [$summary, $details] = $this->reportCollections($company, $warehouse, $plant); + $this->storeReport($summary, $details, $file); + + Log::channel('dailyCron')->info('Cron...End Save Today WHS Performance Report to Excel'); + $this->info('Cron...End Save Today WHS Performance Report to Excel'); + } catch (\Throwable $th) { + Log::channel('dailyCron')->error($th); + } + + return self::SUCCESS; + } + + private function configureRuntime(): void + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOutCL')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOutCL')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOutCL')); + ini_set('memory_limit', '1024M'); + } + + private function reportCollections(string $company, string $warehouse, string $plant): array + { + $summary = collect($this->summaryRows($company, $warehouse, $plant))->map(fn ($item) => $this->trimRow($item)); + $summary->prepend([ + 'A4SHIPTYPE' => 'Method', 'STATUS' => 'Status', 'SOURCE' => 'Source', 'PICKERS' => 'Pickers', + 'WEIGHT' => 'Weight', 'LINES' => 'Lines', 'DOLLARS' => 'Dollars', + ]); + + $details = collect($this->detailRows($company, $warehouse, $plant))->map(fn ($item) => $this->trimRow($item)); + $details->prepend([ + 'A3CO' => 'Co', 'A3WHS' => 'Whs', 'A3PLT' => 'Plt', 'A3MACPKR' => 'Delivery No', 'A4PICKCRTS' => 'Date Time Arrived in Sentinel', + 'SOURCE' => 'Source', 'CARRIERASSIGNED' => 'Date carrier Assigned', 'A4ONO' => 'Order No', 'A4SHSHNM' => 'Customer name', + 'A4SCAC' => 'Carrier', 'A42SSVCNAM' => 'Service', 'A4PICKSTS' => 'Picker Status', 'STATUS' => 'Open or Closed', + 'A4SHIPTYPE' => 'Method', 'A4TPCKWGHT' => 'Weight', 'A4NOPICLNS' => 'Lines', 'DOLLARS' => 'Dollars', + ]); + + return [$summary, $details]; + } + + private function trimRow(object $item): object + { + foreach ($item as $key => $value) { + if (is_string($value)) { + $item->{$key} = trim($value); + } + } + + return $item; + } + + private function summaryRows(string $company, string $warehouse, string $plant): array + { + return DB::connection(config('m3.connection', 'pgsql'))->select(<<<'SQL' + WITH TEMPFILE AS ( + SELECT A.*,A4TPCKWGHT,A4NOPICLNS,A4PICKSTS, + CASE WHEN UPPER(A4PICKSTS)<>'A' THEN 'Open' ELSE 'Closed' END AS STATUS, + CASE WHEN A4TPCKWGHT>16000 THEN 'FTL' ELSE A4SHIPTYPE END AS A4SHIPTYPE, + (SELECT SUM(A5RSVQTY*A5SLUNPR) FROM ICM688M2 WHERE A4MACPKR=A5MACPKR) AS DOLLARS + FROM ICM700M A LEFT JOIN ICM688M1 B ON A4MACPKR=A3MACPKR + WHERE A3MSMTDATE=(SELECT MAX(A3MSMTDATE) FROM ICM700M) AND A3CO=? AND A3WHS=? AND A3PLT=? + ) + SELECT A4SHIPTYPE,STATUS,SOURCE,COUNT(*) AS PICKERS,SUM(A4TPCKWGHT) AS WEIGHT,SUM(A4NOPICLNS) AS LINES,SUM(DOLLARS) AS DOLLARS + FROM TEMPFILE GROUP BY A4SHIPTYPE,STATUS,SOURCE ORDER BY 1,3,2 + SQL, [$company, $warehouse, $plant]); + } + + private function detailRows(string $company, string $warehouse, string $plant): array + { + return DB::connection(config('m3.connection', 'pgsql'))->select(<<<'SQL' + WITH TEMPFILE AS ( + SELECT A3CO,A3WHS,A3PLT,A3MACPKR,A4PICKCRTS,SOURCE, + (SELECT TO_TIMESTAMP(CAST(SHDT AS TEXT) || ' ' || CAST(SHTIME AS TEXT), 'YYYY-MM-DD HH24:MI:SS') FROM ICM699M WHERE SHMACPKR=A4MACPKR AND SHTYPE='Lisnr-Hold' ORDER BY SHDT DESC,SHTIME DESC FETCH FIRST 1 ROWS ONLY) AS CARRIERASSIGNED, + A4ONO,A4SHSHNM,A4SCAC,A42SSVCNAM,A4PICKSTS, + CASE WHEN UPPER(A4PICKSTS)<>'A' THEN 'Open' ELSE 'Closed' END AS STATUS, + CASE WHEN A4TPCKWGHT>16000 THEN 'FTL' ELSE A4SHIPTYPE END AS A4SHIPTYPE, + A4TPCKWGHT,A4NOPICLNS,(SELECT SUM(A5RSVQTY*A5SLUNPR) FROM ICM688M2 WHERE A4MACPKR=A5MACPKR) AS DOLLARS + FROM ICM700M A LEFT JOIN ICM688M1 B ON A4MACPKR=A3MACPKR + WHERE A3MSMTDATE=(SELECT MAX(A3MSMTDATE) FROM ICM700M) AND A3CO=? AND A3WHS=? AND A3PLT=? + ) SELECT * FROM TEMPFILE + SQL, [$company, $warehouse, $plant]); + } + + private function storeReport($summary, $details, string $file): void + { + if ($summary->isEmpty() || $details->isEmpty()) { + Log::channel('dailyCron')->info('Today WHS Performance Report, no records found: Nothing to save...'); + + return; + } + + $this->info('Saving Today WHS Performance Report to Disk...'); + Log::channel('dailyCron')->info('Saving Today WHS Performance Report to Disk...'); + app(SpreadsheetExport::class)->storeSheets(['Summary' => $summary, 'Details' => $details], $file, 'publicLabels'); + } +} diff --git a/storage/framework/cache/data/.gitkeep b/Modules/M3/Database/Migrations/.gitkeep old mode 100644 new mode 100755 similarity index 100% rename from storage/framework/cache/data/.gitkeep rename to Modules/M3/Database/Migrations/.gitkeep diff --git a/Modules/M3/Database/Migrations/2026_09_16_000001_create_m3_program_requests_table.php b/Modules/M3/Database/Migrations/2026_09_16_000001_create_m3_program_requests_table.php new file mode 100755 index 00000000..c44bb9b0 --- /dev/null +++ b/Modules/M3/Database/Migrations/2026_09_16_000001_create_m3_program_requests_table.php @@ -0,0 +1,30 @@ +create('m3_program_requests', function (Blueprint $table): void { + $table->bigIncrements('id'); + $table->string('type', 20); + $table->string('operation', 255); + $table->string('library', 255)->nullable(); + $table->jsonb('payload')->nullable(); + $table->string('requested_by', 255)->nullable(); + $table->string('status', 30)->default('pending')->index(); + $table->text('result')->nullable(); + $table->text('error')->nullable(); + $table->timestamp('processed_at')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::connection(config('m3.connection', 'pgsql'))->dropIfExists('m3_program_requests'); + } +}; diff --git a/storage/framework/sessions/.gitkeep b/Modules/M3/Database/Seeders/.gitkeep similarity index 100% rename from storage/framework/sessions/.gitkeep rename to Modules/M3/Database/Seeders/.gitkeep diff --git a/Modules/M3/Database/Seeders/M3DatabaseSeeder.php b/Modules/M3/Database/Seeders/M3DatabaseSeeder.php new file mode 100755 index 00000000..189d01c8 --- /dev/null +++ b/Modules/M3/Database/Seeders/M3DatabaseSeeder.php @@ -0,0 +1,20 @@ + 'Alberta', + 'BC' => 'British Columbia', + 'MB' => 'Manitoba', + 'NB' => 'New Brunswick', + 'NL' => 'Newfoundland and Labrador', + 'NS' => 'Nova Scotia', + 'NT' => 'Northwest Territories', + 'NU' => 'Nunavut', + 'ON' => 'Ontario', + 'PE' => 'Prince Edward Island', + 'QC' => 'Quebec', + 'SK' => 'Saskatchewan', + 'YT' => 'Yukon', + ]; + } +} diff --git a/Modules/M3/Helpers/Helper.php b/Modules/M3/Helpers/Helper.php new file mode 100755 index 00000000..f95072ac --- /dev/null +++ b/Modules/M3/Helpers/Helper.php @@ -0,0 +1,352 @@ + env('ENDPOINTURLSSO') . env('URLTOKEN'), + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'grant_type=' . env('GRANT_TYPE') . '&password=' . env('PASSWORD') . '&username=' . env('USERNAME') . '&client_secret=' . env('CLIENT_SECRET') . + '&client_id=' . env('CLIENT_ID'), + CURLOPT_HTTPHEADER => [ + 'Content-Type: application/x-www-form-urlencoded', + 'charset:UTF-8', + 'Accept: application/json', + ], + ]); + + $response = curl_exec($curl); + $responseJ = json_decode($response); + + if ($response === false) { + return response()->json([ + 'code' => '400', + 'status' => 'Failed', + 'message' => 'Token Verification Error...' . curl_error($curl), + ]); + } elseif (isset($responseJ->access_token)) { + $ionToken = $responseJ->access_token; + + Cache::put('token', $ionToken, now()->addMinutes(59)); + } else { + return response()->json([ + 'code' => '400', + 'status' => 'Failed', + 'message' => 'Token Verification Error...M3 response:' . $response, + ]); + } + + curl_close($curl); + } + + return $ionToken; + // 'code' => '200', + // 'token' => $ionToken + // ]); + } + + // Check M3 API Token V2 + public static function checkReceiveTokenV2() + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut')); + + // Clear Cache + // Cache::forget('token'); + + // Check if cached Token is still Valid + $token = Cache::get('token'); + + if (isset($token)) { + $ionToken = $token; + } else { + // ## CURL + // ## Generate Token + $curl = curl_init(); + + curl_setopt_array($curl, [ + CURLOPT_URL => env('ENDPOINTURLSSO') . env('URLTOKEN'), + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'grant_type=' . env('GRANT_TYPE') . '&password=' . env('PASSWORD') . '&username=' . env('USERNAME') . '&client_secret=' . env('CLIENT_SECRET') . + '&client_id=' . env('CLIENT_ID'), + CURLOPT_HTTPHEADER => [ + 'Content-Type: application/x-www-form-urlencoded', + 'charset:UTF-8', + 'Accept: application/json', + ], + ]); + + $response = curl_exec($curl); + $responseJ = json_decode($response); + curl_close($curl); + + if ($response === false) { + // Clear Cache + Cache::forget('token'); + + // Return Error + return response()->json([ + 'code' => '400', + 'status' => 'Failed', + 'message' => 'Token Verification Error...' . curl_error($curl), + ]); + } elseif (isset($responseJ->access_token)) { + $ionToken = $responseJ->access_token; + Cache::put('token', $ionToken, now()->addMinutes(59)); + } else { + // Clear Cache + Cache::forget('token'); + + return response()->json([ + 'code' => '400', + 'status' => 'Failed', + 'message' => 'Token Verification Error...M3 response:' . $response, + ]); + } + } + + return response()->json([ + 'code' => '200', + 'token' => $ionToken, + ]); + } + + // Read M3 JSON and Analyse it for Errors + public static function checkM3Errors($responseResult) + { + if (! is_object($responseResult)) { + return 'Invalid M3 response '; + } + + $messages = []; + $inactiveTypes = 0; + $closeShipmentInactive = self::collectCloseShipmentErrors($responseResult, $messages); + + foreach (['Move', 'COCharge', 'Replenish', 'MoveDock'] as $type) { + $result = self::extractM3Result($responseResult, $type); + self::appendM3Error($messages, $type, $result); + + if ($result['rawResult'] === 'N/A') { + $inactiveTypes++; + } + } + + if ($closeShipmentInactive === 7 && $inactiveTypes === 4) { + $messages[] = '-M3 did not call any method or type'; + } + + return $messages === [] ? '' : implode(' ', $messages) . ' '; + } + + private static function collectCloseShipmentErrors(object $responseResult, array &$messages): int + { + $closeShipment = $responseResult->CloseShipment ?? null; + if (! is_object($closeShipment)) { + return 7; + } + + $inactive = 0; + foreach (['AddPackage', 'PickingListClose', 'TrailerNo', 'TrackingNo', 'ContentLabel', 'DeliveryNote', 'ShipLabel'] as $type) { + $result = self::extractResultNode($closeShipment->{$type} ?? null); + self::appendM3Error($messages, $type, $result); + + if ($result['rawResult'] === 'N/A') { + $inactive++; + } + } + + return $inactive; + } + + private static function extractM3Result(object $responseResult, string $type): array + { + $node = $responseResult->{$type} ?? null; + if ($type === 'MoveDock' && is_object($node)) { + $node = $node->Move ?? null; + } + + return self::extractResultNode($node); + } + + private static function extractResultNode(mixed $node): array + { + if (! is_object($node)) { + return ['error' => '', 'result' => '', 'rawResult' => 'N/A']; + } + + $error = trim((string) ($node->ErrorMessage ?? '')); + $rawResult = trim((string) ($node->Result ?? '')); + $result = in_array($rawResult, ['N/A', 'OK'], true) ? '' : $rawResult; + + return ['error' => $error, 'result' => $result, 'rawResult' => $rawResult]; + } + + private static function appendM3Error(array &$messages, string $type, array $result): void + { + if ($result['error'] === '' && $result['result'] === '') { + return; + } + + $messages[] = $type . '-' . $result['result'] . '-' . $result['error']; + } + + // Log All Success And Error to ICM699M + public static function logToICM699M($data) + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + + DB::connection(config('m3.connection', 'pgsql'))->table('ICM699M')->insert($data); + } + + // Get Substring in string between 2 Substrings + public static function getSubstringBetween($string, $start, $end) + { + $startPos = strpos($string, $start); + if ($startPos === false) { + return ''; + } + $endPos = strpos($string, $end, $startPos + strlen($start)); + if ($endPos === false) { + return ''; + } + + return substr($string, $startPos + strlen($start), $endPos - ($startPos + strlen($start))); + } + + public static function checkLength($jsonFields, $dbFields, $type) + { + $type = $type == 'integer' || $type == 'DEC' ? 'number' : $type; + + // Check Json Field should be < DB Field + $lengthOK[413] = (strlen($jsonFields) <= $dbFields) ? true : false; + // Empty Fields + $lengthOK[411] = true; // !empty($jsonFields) ? true : false ; + // Wrong Types + $lengthOK[417] = true; // $jSONTypeConv == $type ? true : false ; + // Log::info($lengthOK); + + return $lengthOK; + } + + public static function sanityzeString($strToSanitize) + { + $badChars = Config::get('arrays.BadChars'); + + $goodString = trim($strToSanitize); + $goodString = str_replace("'", '', $goodString); + $goodString = str_replace("\u{f0e0}", '', $goodString); + $goodString = preg_replace('/\\\\u201[0-9A-F]+/i', '', $goodString); + $goodString = str_replace($badChars, '', $goodString); + $goodString = iconv('UTF-8', 'ISO-8859-1//IGNORE', $goodString); + $goodString = iconv('ISO-8859-1', 'UTF-8', $goodString); + + // MAK : New Automatic Detection for encoding and conversion + // Detect the encoding + // $encoding = mb_detect_encoding($goodString, mb_list_encodings(), true); + // Log::info($goodString); + + // If encoding is detected, convert the string + // if ($encoding !== false) { + // // Log::info($encoding); + // // Log::info($goodString); + + // $goodString = mb_convert_encoding($goodString, "UTF-8", $encoding); + // } else { + // $goodString = ""; + // } + + return $goodString; + } + + // Remove Duplicate SubString + public static function removeDuplicateSubstrings($str) + { + $result = ''; + $seenPhrases = []; + + $phrases = explode(' ', $str); + foreach ($phrases as $phrase) { + if (! in_array($phrase, $seenPhrases)) { + $result .= $phrase . ' '; + $seenPhrases[] = $phrase; + } + } + + return trim($result); + } + + public static function getUserCOWHSPLT() + { + $defaults = [ + 'UserCO' => '', + 'UserWHS' => '', + 'UserPL' => '', + ]; + + $loggedUser = strtoupper(trim((string) m3_user())); + if ($loggedUser === '') { + return $defaults; + } + + try { + if (! Schema::connection(config('m3.connection', 'pgsql'))->hasTable('icm428m')) { + return $defaults; + } + + $user = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428ADMUSR', 'R428PWRUSR', 'R428CO', 'R428PL', 'R428WH', 'R42811A', 'R42821A') + ->where('R428US', $loggedUser) + ->first(); + + if (! $user) { + return $defaults; + } + + return [ + 'UserCO' => trim((string) ($user->R428CO ?? '')), + 'UserWHS' => trim((string) ($user->R428WH ?? '')), + 'UserPL' => trim((string) ($user->R428PL ?? '')), + ]; + } catch (\Throwable $e) { + \Illuminate\Support\Facades\Log::warning('M3 user context unavailable', ['exception' => $e->getMessage()]); + + return $defaults; + } + } +} diff --git a/Modules/M3/Helpers/M3Auth.php b/Modules/M3/Helpers/M3Auth.php new file mode 100755 index 00000000..6443abbd --- /dev/null +++ b/Modules/M3/Helpers/M3Auth.php @@ -0,0 +1,36 @@ +user(); + + $value = $user?->username + ?? $user?->user_name + ?? $user?->name + ?? $user?->email + ?? request()->server('PHP_AUTH_USER') + ?? ''; + + if (str_contains((string) $value, '@')) { + $value = strstr((string) $value, '@', true) ?: $value; + } + + return strtoupper(trim((string) $value)); + } +} + +if (! function_exists('m3_legacy_password')) { + /** + * Passwords are intentionally unavailable in Core. PostgreSQL access uses + * Laravel's configured connection and never reuses a user's login password. + */ + function m3_legacy_password(): string + { + return ''; + } +} diff --git a/Modules/M3/Helpers/SubdirectoryAssetsHelper.php b/Modules/M3/Helpers/SubdirectoryAssetsHelper.php new file mode 100755 index 00000000..8553a00f --- /dev/null +++ b/Modules/M3/Helpers/SubdirectoryAssetsHelper.php @@ -0,0 +1,14 @@ + 'Alabama', + 'AK' => 'Alaska', + 'AZ' => 'Arizona', + 'AR' => 'Arkansas', + 'CA' => 'California', + 'CO' => 'Colorado', + 'CT' => 'Connecticut', + 'DE' => 'Delaware', + 'FL' => 'Florida', + 'GA' => 'Georgia', + 'HI' => 'Hawaii', + 'ID' => 'Idaho', + 'IL' => 'Illinois', + 'IN' => 'Indiana', + 'IA' => 'Iowa', + 'KS' => 'Kansas', + 'KY' => 'Kentucky', + 'LA' => 'Louisiana', + 'ME' => 'Maine', + 'MD' => 'Maryland', + 'MA' => 'Massachusetts', + 'MI' => 'Michigan', + 'MN' => 'Minnesota', + 'MS' => 'Mississippi', + 'MO' => 'Missouri', + 'MT' => 'Montana', + 'NE' => 'Nebraska', + 'NV' => 'Nevada', + 'NH' => 'New Hampshire', + 'NJ' => 'New Jersey', + 'NM' => 'New Mexico', + 'NY' => 'New York', + 'NC' => 'North Carolina', + 'ND' => 'North Dakota', + 'OH' => 'Ohio', + 'OK' => 'Oklahoma', + 'OR' => 'Oregon', + 'PA' => 'Pennsylvania', + 'RI' => 'Rhode Island', + 'SC' => 'South Carolina', + 'SD' => 'South Dakota', + 'TN' => 'Tennessee', + 'TX' => 'Texas', + 'UT' => 'Utah', + 'VT' => 'Vermont', + 'VA' => 'Virginia', + 'WA' => 'Washington', + 'WV' => 'West Virginia', + 'WI' => 'Wisconsin', + 'WY' => 'Wyoming', + 'DC' => 'District of Columbia', + ]; + } +} diff --git a/Modules/M3/Http/Controllers/.gitkeep b/Modules/M3/Http/Controllers/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Http/Controllers/API/CloseShipment.php b/Modules/M3/Http/Controllers/API/CloseShipment.php new file mode 100755 index 00000000..3a7e7670 --- /dev/null +++ b/Modules/M3/Http/Controllers/API/CloseShipment.php @@ -0,0 +1,1050 @@ +all()); + $nODEBUG = true; // ALWAYS set TRUE in Production + $pACKAGES = []; + $jSONCoCharge = []; + $jSONCS = []; + + // Get the Calling User + $sHUSER = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'; + $sHSOURCE = 'CloseShipmentCoChargeAPI'; + + try { + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + $wHS = isset($urlParams['WHS']) ? $urlParams['WHS'] : ''; + $cOMPANY = isset($urlParams['COMPANY']) ? $urlParams['COMPANY'] : ''; + $mANIFEST = isset($urlParams['MANIFEST']) ? $urlParams['MANIFEST'] : ''; + $tRANSTYPE = isset($urlParams['TRANSTYPE']) ? $urlParams['TRANSTYPE'] : 'M'; // M , P , Z + $tRANSTYPE = $tRANSTYPE != '' ? $tRANSTYPE : 'M'; // M , P , Z + $sHDT = isset($urlParams['SHDT']) ? $urlParams['SHDT'] : ''; + $sHTIME = isset($urlParams['SHTIME']) ? $urlParams['SHTIME'] : ''; + $sHTYPE = isset($urlParams['SHTYPE']) ? $urlParams['SHTYPE'] : ''; + $allErrMsgs = ''; + $lineAck = []; + // PDF File PATH + $pdfFilePath = Config::get('arrays.PdfPath'); + $dELIVERYNO = $mANIFEST != '' ? $mANIFEST : self::ZERO_PAD; + + if ($urlParams != '') { + // Write to Logs : JSON + $jSONIN = json_encode([ + 'WHS' => $wHS, + 'COMPANY' => $cOMPANY, + 'MANIFEST-MACPKR' => $mANIFEST, + 'TRANSTYPE' => $tRANSTYPE, + ]); + + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Req-out', + 'SHDATA' => $jSONIN, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Get Token + $tokenResponse = Helper::checkReceiveTokenV2(); + + $tokenData = $tokenResponse->getData(); + + if ($tokenData->code == '200') { + $ionToken = isset($tokenData->token) ? $tokenData->token : ''; + } else { + $sHDATA = isset($tokenData->message) ? $tokenData->message : ''; + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + + // Write to Logs : Error + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $sHDATA, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return $tokenResponse; + } + + // Set Endpoint URL + $endPointURL = env('ENDPOINTURL') . 'APIFLOWS/Sentinel/TransferAPI?ionapiRespStyle=sync'; + $token = $ionToken; + + // Read from ICM695M1 + if ($tRANSTYPE == 'M') { + $iCM695M1PREP = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->select('AYCO', 'AYWHS', 'AYMACPKR', 'AYRLNO', 'AYAPRF1551') + ->distinct() + ->where('AYCO', $cOMPANY) + ->where('AYAPRF1551', $mANIFEST) + ->where('AYWHS', $wHS) + ->orderBy('AYMACPKR'); + } elseif ($tRANSTYPE == 'P') { + $iCM695M1PREP = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->select('AYCO', 'AYWHS', 'AYMACPKR', 'AYRLNO', 'AYAPRF1551') + ->distinct() + ->where('AYCO', $cOMPANY) + ->where('AYMACPKR', $mANIFEST) + ->where('AYWHS', $wHS) + ->orderBy('AYMACPKR'); + + // Check Date & Time Before Updating ICM699M + if ($sHDT != '' && $sHTIME != '' && $sHTYPE != '' && $nODEBUG) { + DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->where('SHMACPKR', $mANIFEST) + ->where('SHDT', $sHDT) + ->where('SHTIME', $sHTIME) + ->where('SHCO', $cOMPANY) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', $sHTYPE) + ->update(['SHERROR' => 'Z', 'SHACKUSER' => $sHUSER, 'SHACKDATE' => date('Y-m-d'), 'SHACKTIME' => date('H:i:s')]); + } + + // Get Acknowledged Record for M3-QtyChg PackSyst4tray + $iCM699MQtyChg = DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->select() + ->where('SHMACPKR', $mANIFEST) + ->where('SHCO', $cOMPANY) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', 'PackSyst4tray') + ->where('SHERROR', 'Z') + ->where('SHTYPE', 'M3-QtyChg') + ->get(); + foreach ($iCM699MQtyChg as $ICM699MQtyChgR) { + $string = $ICM699MQtyChgR->SHDATA; + $start = 'PickerLine:'; + $end = ' -'; + $lineAck[] = Helper::getSubstringBetween($string, $start, $end); + } + } elseif ($tRANSTYPE == 'Z') { + $iCM695M1PREP = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->select() + ->distinct() + ->where('A4CO', $cOMPANY) + ->where('A4WHS', $wHS) + ->where('A4MACPKR', $mANIFEST) + ->orderBy('A4MACPKR'); + } + + $iCM695M1TMP = $iCM695M1PREP->get(); + + // PFC if MACKPKR already Closed : Case 671 + $iCM695M1TMPCOL = collect($iCM695M1TMP); + if ($tRANSTYPE == 'Z') { + $iCM695M1TMPCOLF = $iCM695M1TMPCOL->map(function ($post) { + return trim($post->A4MACPKR); + }); + } else { + $iCM695M1TMPCOLF = $iCM695M1TMPCOL->map(function ($post) { + return trim($post->AYMACPKR); + }); + } + + $iCM695M1TMPCOLFA = $iCM695M1TMPCOLF->toArray(); + + $iCM699MSuccess = DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->select('SHMACPKR') + ->whereIn('SHMACPKR', $iCM695M1TMPCOLFA) + ->where('SHCO', $cOMPANY) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', 'CloseShipmentCoChargeAPI') + ->where('SHERROR', '') + ->where('SHTYPE', 'M3-Res-out') + ->where('SHDATA', 'like', '%Success%') + ->get(); + $iCM699MSuccessCol = collect($iCM699MSuccess); + $iCM699MSuccessColF = $iCM699MSuccessCol->map(function ($post) { + return $post->SHMACPKR; + }); + $iCM699MSuccessColFAr = $iCM699MSuccessColF->toArray(); + + if ($tRANSTYPE == 'Z') { + // Use the reject method to remove items based on the condition + $iCM695M1TMPF = $iCM695M1TMP->reject(function ($post) use ($iCM699MSuccessColFAr) { + return in_array($post->A4MACPKR, $iCM699MSuccessColFAr); + }); + } else { + // Use the reject method to remove items based on the condition + $iCM695M1TMPF = $iCM695M1TMP->reject(function ($post) use ($iCM699MSuccessColFAr) { + return in_array($post->AYMACPKR, $iCM699MSuccessColFAr); + }); + } + $iCM695M1TMP = $iCM695M1TMPF; + + $freightTermsTMP = DB::connection(config('m3.connection', 'pgsql'))->table('icm321m') + ->selectRaw('TRIM(ARCODE) as FREIGHTTERMS,ARCHARGE as BILLABLE') + ->get(); + + // Close Shipment for Manifest or Single MacPKR + if (count($iCM695M1TMP) > 0 && ($tRANSTYPE == 'M' || $tRANSTYPE == 'P')) { + // Loop the Results from $ICM595M1TMP + foreach ($iCM695M1TMP as $key => $ICM695M1R) { + $pACKAGES = []; + $aYWHS = trim($ICM695M1R->AYWHS); + $aYCO = trim($ICM695M1R->AYCO); + $aYMACPKR = trim($ICM695M1R->AYMACPKR); + $aYRLNO = trim($ICM695M1R->AYRLNO); + $mANIFEST = trim($ICM695M1R->AYAPRF1551); + // Reset Errors after each Loop + $errorMsgs = ''; + // Set Endflag for Short pick after each Loop + $endFlag = 0; + + // Precheck All Qty are Equal before Proceeding to Close + // Get Parts And Lots from ICM688M2 + $iCM688M2SL = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m2') + ->select('A5PART', 'A5PACKED', 'A5PICKED', 'A5PKLN', 'A5RSVQTY') + ->distinct() + ->where('A5CO', $aYCO) + ->where('A5WHS', $aYWHS) + ->where('A5MACPKR', $aYMACPKR) + ->where('A5RLNO', $aYRLNO) + ->orderBy('A5PART') + ->get(); + // dump($iCM688M2SL); + // Get PACK/Dock from ICM799M + // $ICM799MSEL = DB::connection(config('m3.connection', 'pgsql'))->table('icm799m') + // ->groupBy('IMTOLOC') + // ->select('IMTOLOC',DB::raw('SUM(IMQTY) as IMQTYTOT') ) + // ->where('IMDIV',$aYCO) + // ->where('IMWHS',$aYWHS) + // ->where('IMDELNO',$aYMACPKR) + // ->where('IMLINE',$aYRLNO) + // ->whereIn('IMTOLOC',['DOCK','PACK']) + // ->get(); + + // PFC : Check that Picked / Packed are all Equal + foreach ($iCM688M2SL as $key => $ICM688M2SLR) { + $a5PICKED = isset($ICM688M2SLR->A5PICKED) ? $ICM688M2SLR->A5PICKED : 0; + $a5RSVQTY = isset($ICM688M2SLR->A5RSVQTY) ? $ICM688M2SLR->A5RSVQTY : 0; + $a5ShortShipQty = (int) $a5RSVQTY - (int) $a5PICKED; + + // Set EndFLag=1 for short picks + if ($a5ShortShipQty > 0) { + $endFlag = 1; + } + } + + // Get TRAILERNUMBER SELECT APTRUCKID FROM ICM705M1 WHERE APCO=110 AND APWHS=321 AND APMANIFEST=22 + $tRAILERNUMBERS = DB::connection(config('m3.connection', 'pgsql'))->table('icm705m1') + ->select('APTRUCKID', 'APTRACKNO', 'APMANIFEST') + ->where('APCO', $cOMPANY) + ->where('APMANIFEST', $mANIFEST) + ->where('APWHS', $wHS) + ->first(); + + $tRAILERNUMBER = isset($tRAILERNUMBERS->APTRUCKID) ? trim($tRAILERNUMBERS->APTRUCKID) : ''; + $pRONUMBER = isset($tRAILERNUMBERS->APTRACKNO) ? trim($tRAILERNUMBERS->APTRACKNO) : ''; + + $iCM695M1JOINTMP = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->selectRAW('AYMACPKR,AYINTBOX,AYHEIGHT,AYWIDTH,AYDEPTH,AYTYPE,AYLNWGHT,AYID,AYSPR1A01,TRIM(AYSPR15A01) AS SCAC , TRIM(AYSPR30A01) AS TRACKING,AYTRUCK AS AGGREGATION,A4RATETCP AS FREIGHT, A4OFSTRM AS FREIGHTTERMS,A4RATEM3,A4CLOSEM3, A4SHIPTYPE, A4REFORD,A4ONO,A4SHIPVIA,A42SSVCNAM,A4SHIPVIA1') + ->leftJoin('ICM688M1', function ($join) { + $join->on('AYCO', '=', 'A4CO'); + $join->on('AYWHS', '=', 'A4WHS'); + $join->on('AYMACPKR', '=', 'A4MACPKR'); + }) + ->where('AYMACPKR', $aYMACPKR) + ->where('AYCO', $aYCO) + ->where('AYWHS', $aYWHS) + ->orderBy('AYINTBOX') + ->get(); + + foreach ($iCM695M1JOINTMP as $key => $ICM695M1JOINR) { + $a4SHIPVIA = isset($ICM695M1JOINR->A4SHIPVIA) ? trim(str_replace('&', '_', $ICM695M1JOINR->A4SHIPVIA)) : ''; + + $sHIPTYPE = trim($ICM695M1JOINR->A4SHIPTYPE); + $a42SSVCNAM = trim($ICM695M1JOINR->A42SSVCNAM); + $a4SHIPVIA1 = trim($ICM695M1JOINR->A4SHIPVIA1); + $fREIGHTTERMS = trim($ICM695M1JOINR->FREIGHTTERMS); + $a4RATEM3 = trim($ICM695M1JOINR->A4RATEM3); + $fREIGHT = trim($ICM695M1JOINR->FREIGHT); + $a4REFORD = trim($ICM695M1JOINR->A4REFORD); + $a4ONO = trim($ICM695M1JOINR->A4ONO); + $aYMACPKR = trim($ICM695M1JOINR->AYMACPKR); + $aYINTBOX = trim($ICM695M1JOINR->AYINTBOX); + $tRACKING = trim($ICM695M1JOINR->TRACKING); + $sCAC = trim($ICM695M1JOINR->SCAC); + $cARRIER = ''; + $aYTYPE = trim($ICM695M1JOINR->AYID) != '' ? trim($ICM695M1JOINR->AYID) : ''; + $aYLNWGHT = trim($ICM695M1JOINR->AYLNWGHT); + $aYHEIGHT = trim($ICM695M1JOINR->AYHEIGHT); + $aYWIDTH = trim($ICM695M1JOINR->AYWIDTH); + $aYDEPTH = trim($ICM695M1JOINR->AYDEPTH); + $bILLOFLADING = isset($ICM695M1JOINR->AYSPR1A01) ? trim($ICM695M1JOINR->AYSPR1A01) : ''; + $tRANSPORTMODE = $a4SHIPVIA; + $sERVICETYPE = $a4SHIPVIA; + + // Get Carrier Name from ICM160M + if ($sCAC != '') { + $sCACSub = substr($sCAC, 0, 4); + $iCM160M = DB::connection(config('m3.connection', 'pgsql'))->table('icm160m') + ->select('CANAM') + ->where('CANUM', $sCACSub) + ->where('CACO', $cOMPANY) + ->first(); + $cARRIER = isset($iCM160M->CANAM) ? trim(str_replace('&', '_', $iCM160M->CANAM)) : ''; + } + + // PFC Check BOL for LTL + if ($sHIPTYPE == 'LTL') { + $errorMsgs = $bILLOFLADING == '' || $sCAC == '' || $tRACKING == '' ? + $errorMsgs . " Missing one or more of tracking number, BOL, or carrier. Please enter this data manually in 'invoicing' screen and retry this API call;" : $errorMsgs . ''; + } else { + $errorMsgs = $sCAC == '' || $tRACKING == '' ? + $errorMsgs . " Missing one or more of tracking number, BOL, or carrier. Please enter this data manually in 'invoicing' screen and retry this API call; " : $errorMsgs . ''; + } + + if ($pRONUMBER == '' && $sCAC == 'RETR') { + $errorMsgs = $errorMsgs . ' Missing PARS info for this RETRans order. Please contact MPBA to ask them to enter the value for you, and then you can retry; '; + } + + // MAK : PFC Check for GS1-Label A1SPR1A01 in ICM666M and ICM695M3 + $gS1Label = ''; + // First Check if GS1 Label is required in ICM666M + $iCM666MSQLSel = DB::connection(config('m3.connection', 'pgsql'))->table('icm666m') + ->select('A1SPR1A01') + ->where('A1CO', $aYCO) + ->where('A1WHS', $aYWHS) + ->where('A1DELNO', $aYMACPKR) + ->first(); + $gS1LabelExist = isset($iCM666MSQLSel->A1SPR1A01) ? trim($iCM666MSQLSel->A1SPR1A01) : 0; + + // Case #566: BOL = PRONUMBER For SCAC=='RETR' + if ($sCAC == 'RETR') { + $bILLOFLADING = $pRONUMBER; + } + + // Get Commodities + $myRequest = new Request; + $myRequest->setMethod('POST'); + + $myRequest->request->add([ + 'MACPKR' => $aYMACPKR, + ]); + // Call processShipment + $controller = new GetContentsController; + $response = $controller->processShipment($myRequest); + $responseData = $response->getData(); + $error = isset($responseData->error) ? $responseData->error : ''; + + if ($error == '') { + // $commodities = json_encode($responseData->commodities); + // Get Commodities + $commoditiesTmp = isset($responseData->commodities) ? $responseData->commodities : ''; + if ($commoditiesTmp != '') { + $commodities = $commoditiesTmp; + } else { + $commodities = ''; + $errorMsgs = $errorMsgs . ' Could not find Commodities; '; + } + } else { + $commodities = ''; + $errorMsgs = $errorMsgs . ' Could not find Commodities; '; + } + // End Commodities + + // Check ICM699M for SHERROR=X + $iCM699MS = DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->select('SHMACPKR') + ->where('SHMACPKR', $aYMACPKR) + ->where('SHCO', $aYCO) + ->where('SHWHS', $aYWHS) + ->whereIn('SHSOURCE', ['TransferAPIURL', 'CloseShipmentCoChargeAPI', 'PackSyst4tray']) + ->where('SHERROR', 'X') + ->whereIn('SHTYPE', ['M3-Res-out', 'M3-QtyChg']) + ->first(); + + $alreadySentToM3 = isset($iCM699MS->SHMACPKR) ? trim($iCM699MS->SHMACPKR) : ''; + + if ($alreadySentToM3 != '') { + // Add Message + $errorMsgs = $errorMsgs . ' There are previous M3 transmissions in error for this delivery note that have not been addressed; '; + } + + if ($aYTYPE == '') { + // Get AETYPE SELECT APTRUCKID FROM ICM705M1 WHERE APCO=110 AND APWHS=321 AND APMANIFEST=22 + $iCM693MS = DB::connection(config('m3.connection', 'pgsql'))->table('icm693m') + ->select('AEID') + ->where('AESPR1A01', 'D') + ->where('AETYPE', trim($ICM695M1JOINR->AYTYPE)) + ->first(); + $aYTYPE = isset($iCM693MS->AEID) ? trim($iCM693MS->AEID) : ''; + } + + $currentFreightTerms = $freightTermsTMP->where('FREIGHTTERMS', $fREIGHTTERMS)->first(); + $bILLABLE = isset($currentFreightTerms->BILLABLE) ? trim($currentFreightTerms->BILLABLE) : 'N'; + + // If billable=Y and a4ratetcp(FREIGHT)>0 and a4ratem3=blank, then call the freight API CoCharge + if ($bILLABLE == 'Y' && $fREIGHT > 0 && $a4RATEM3 == '') { + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + + if ($sHIPTYPE == 'LTL') { + $shippingToBill = $fREIGHT * (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceLTL')) / 100; + } else { + $shippingToBill = $fREIGHT * (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceParcel')) / 100; + } + // Construct Json for COCharge + $jSONCoCharge = [ + 'QUANTITY' => round($shippingToBill, 2), // $fREIGHT with modified Params + 'ORDERCATEGORY' => $a4REFORD, + 'CONUMBER' => $a4ONO, + ]; + } else { + $jSONCoCharge = []; + } + + // If billable=Y and a4ratetcp(FREIGHT)=0 and a4ratem3=blank, then we need to: + // Write a record to ICM699M to indicate that we are not calling the rate API because the $ are 0 + if ($bILLABLE == 'Y' && $fREIGHT == 0 && $a4RATEM3 == '') { + // Add Message + $errorMsgs = $errorMsgs . ' Please manually add a freight charge for this Prepaid and Add order; '; + } + + // Close Shipment + // If ( (billable=Y and a4RATEM3 (from array in memory)="X") OR (billable=N) ) and a4closeM3="" then call the close API + + // Set PDF URLs for Labels + $carrierLabel = ''; + $contentLabel = ''; + + $docTypes = ['ContentLabel', 'CarrierLabel']; + foreach ($docTypes as $key => $value) { + switch ($value) { + case 'CarrierLabel': + $dOCTYPE = 'CarrierLabel'; + $dOCNUMT = $aYINTBOX; + $pDFKey = $value . '/' . $value . '_' . $aYMACPKR . '_' . $dOCNUMT . '_' . $cOMPANY . '_' . $wHS; + $pdfFileName = $pdfFilePath . $pDFKey . '.pdf'; + + if (File::exists($pdfFileName)) { + $carrierLabel = route('m3.M3GetPDFFromCache.index', ['MACPKR' => $aYMACPKR, 'DOCTYPE' => $dOCTYPE]); + } + break; + + case 'ContentLabel': + $dOCTYPE = 'ContentLabel'; + $dOCNUMT = $aYINTBOX; + $pDFKey = $value . '/' . $value . '_' . $aYMACPKR . '_' . $dOCNUMT . '_' . $cOMPANY . '_' . $wHS; + $pdfFileName = $pdfFilePath . $pDFKey . '.pdf'; + + if (File::exists($pdfFileName)) { + $contentLabel = route('m3.M3GetPDFFromCache.index', ['MACPKR' => $aYMACPKR, 'DOCTYPE' => $dOCTYPE]); + } + break; + + default: + break; + } + } + + // Second Check GS1 Label existence in ICM695M3 + if ($gS1LabelExist == 1) { + $iCM695M3SQLSel = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m3') + ->select('A2GS1LABEL') + ->where('A2CO', $aYCO) + ->where('A2WHS', $aYWHS) + // ->where('A2MACPKR',$aYMACPKR) + ->where('A2INTBOX', $aYINTBOX) + ->first(); + $gS1Label = isset($iCM695M3SQLSel->A2GS1LABEL) ? trim($iCM695M3SQLSel->A2GS1LABEL) : ''; + + if ($gS1Label == '') { + $errorMsgs = $errorMsgs . ' Missing G1-128 Label. Please contact MPBA to ask them to enter the value for you, and then you can retry; '; + } + } + + // Get Packages Array + $pACKAGES[] = [ + 'TRACKINGID' => $tRACKING, + 'BUNDLES' => $aYTYPE, + 'WEIGHT' => $aYLNWGHT, + 'HEIGHT' => $aYHEIGHT, + 'WIDTH' => $aYWIDTH, + 'LENGTH' => $aYDEPTH, + 'SSCC' => $gS1Label, + 'SHIPLABELDOC' => $carrierLabel, + 'CONTENTLABELDOC' => $contentLabel, + ]; + } + + // Check Packages array before proceeding with CloseShipment + if (! empty($pACKAGES)) { + // Get Packlist + $packingList = ''; + $dOCTYPE = 'PackingList'; + $dOCNUMT = $aYMACPKR; + $pDFKey = $dOCTYPE . '/' . $dOCTYPE . '_' . $aYMACPKR . '_' . $dOCNUMT . '_' . $cOMPANY . '_' . $wHS; + $pdfFileName = $pdfFilePath . $pDFKey . '.pdf'; + + if (File::exists($pdfFileName)) { + $packingList = route('m3.M3GetPDFFromCache.index', ['MACPKR' => $aYMACPKR, 'DOCTYPE' => $dOCTYPE]); + } + + // Add Cocharge + if (count($jSONCoCharge) > 0) { + // Construct Json for CloseShipment With PDF Files + $tempClose = [ + 'DIVI' => $aYCO, + 'WHS' => $aYWHS, + 'DELIVERYNO' => $aYMACPKR, + 'PICKLISTSUFFIX' => $aYRLNO, + 'TYPE' => 'CloseShipment', + 'SCAC' => $sCAC, + 'CARRIER' => $cARRIER, + 'TRANSPORTMODE' => $tRANSPORTMODE, + 'SERVICETYPE' => $sERVICETYPE, + 'TRACKINGNUMBER' => $tRACKING, + 'PRONUMBER' => $pRONUMBER, + 'BILLOFLADING' => $bILLOFLADING, + 'TRAILERNUMBER' => $tRAILERNUMBER, + 'PACKAGES' => $pACKAGES, + 'DELIVERYNOTEDOC' => $packingList, + 'shipType' => $sHIPTYPE, + 'carrierServiceDescription' => $a42SSVCNAM, + 'modeOfTransport' => $a4SHIPVIA1, + 'COMMODITIES' => $commodities, + 'ENDFLAG' => $endFlag, + ]; + $jSONCoChargeCS = array_merge($jSONCoCharge, $tempClose); + $jSONCS = json_encode($jSONCoChargeCS); + } else { + // Construct Json for CloseShipment With PDF Files + $jSONCS = json_encode([ + 'DIVI' => $aYCO, + 'WHS' => $aYWHS, + 'DELIVERYNO' => $aYMACPKR, + 'PICKLISTSUFFIX' => $aYRLNO, + 'TYPE' => 'CloseShipment', + 'SCAC' => $sCAC, + 'CARRIER' => $cARRIER, + 'TRANSPORTMODE' => $tRANSPORTMODE, + 'SERVICETYPE' => $sERVICETYPE, + 'TRACKINGNUMBER' => $tRACKING, + 'PRONUMBER' => $pRONUMBER, + 'BILLOFLADING' => $bILLOFLADING, + 'TRAILERNUMBER' => $tRAILERNUMBER, + 'PACKAGES' => $pACKAGES, + 'DELIVERYNOTEDOC' => $packingList, + 'ServiceType' => $sHIPTYPE, + 'ServiceLevelCode' => $a42SSVCNAM, + 'TransportationMode' => $a4SHIPVIA1, + 'COMMODITIES' => $commodities, + 'ENDFLAG' => $endFlag, + ]); + } + + // No Errors Proceed in Calling M3 CLose API + if ($errorMsgs == '') { + // Write to Logs Out : Send JSON Request To M3 + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + // dump($dELIVERYNO); + // MAK : Log JSON Manifest # and MACKPKR # + // Log::channel('dailyCron')->info('1 >>> JSON Sent for Manifest: '.$mANIFEST.' ,Macpicker: '.$aYMACPKR); + Log::channel('dailyCron')->info('1 >>> JSON Sent for Manifest: ' . (string) (int) $mANIFEST . ' ,Macpicker: ' . $aYMACPKR); + + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-JSN-out', + 'SHDATA' => $jSONCS, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + $response = Http::withHeaders([ + 'accept' => self::JSON_CONTENT_TYPE, + 'Content-Type' => self::JSON_CONTENT_TYPE, + 'Connection' => 'close', + ]) + ->withToken($token) + ->withBody($jSONCS, self::JSON_CONTENT_TYPE) + ->timeout(Config::get('arrays.curlTimeOut')) + ->retry(3, 100) + ->post($endPointURL); + + $responseStatusCode = $response->getStatusCode(); + $m3SessionId = $response->hasHeader('x-transaction-id') ? '-sessionID:' . $response->header('x-transaction-id') : '-sessionID'; + $responseJSON = $response->getBody()->getContents(); + $jsonSanytized = Helper::sanityzeString($responseJSON); + $responseContents = json_decode($jsonSanytized); + + // MAK : Add response Time + // $M3ResponseTimeTmp = $response->hasHeader('x-response-time') ? ltrim($response->header('x-response-time'),"-") : ''; + // $M3ResponseTimeTmp2 = $M3ResponseTimeTmp /1000; + // $dateTime = new DateTime(); + // $dateTime->setTimestamp($M3ResponseTimeTmp2); + // // dump( $dateTime->format('d/m/Y H:i:s.v') ); + // $M3ResponseTime = $M3ResponseTimeTmp != '' ? '-M3ResponseTime:' . $dateTime->format('d/m/Y H:i:s.v') : '-M3ResponseTime'; + // // dump($M3ResponseTime); + // $transferStats = $response->transferStats; + // $M3transferTime = $transferStats->getTransferTime()!=null ? "-M3transferTime:".$transferStats->getTransferTime() : "-M3transferTime"; + // dd($M3transferTime); + + // Log M3 response + Log::channel('dailyCron')->info('2 >>> Close API M3 Responded...'); + + if ($responseContents != null && $responseStatusCode == '200') { + $responseMsg = $responseContents->result->CloseShipment; + $m3APIRESULT = $responseMsg->PickingListClose->Result; + + // Check M3 Response for Errors + $responseResult = $responseContents->result; + $m3Errors = Helper::checkM3Errors($responseResult); + + // If you get a successful response, update database file ICM688M1/A4RATEm3=X + // Update ICM688M1 : Change A4RATEM3 + if (count($jSONCoCharge) > 0 && $m3APIRESULT != 'Error') { + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $aYMACPKR) + ->where('A4CO', $aYCO) + ->where('A4WHS', $aYWHS) + ->update(['A4RATEM3' => 'X', 'A4PICKSTS' => 'A']); + } elseif (count($jSONCoCharge) == 0 && $m3APIRESULT != 'Error') { + // Update ICM688M1 : Change A4RATEM3 + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $aYMACPKR) + ->where('A4CO', $aYCO) + ->where('A4WHS', $aYWHS) + ->update(['A4PICKSTS' => 'A']); + } + } else { + $m3APIRESULT = 'Error'; + $responseMsg = self::NULL_M3_RESPONSE; + $responseResult = ''; + $m3Errors = $responseStatusCode; + } + + // If you get a successful response + if ($m3APIRESULT != 'Error') { + // Write to Logs Out : Success + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Success...' . json_encode($responseResult) . $m3SessionId, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + } + // If you get a failure, write a record to ICM699M to indicate that the CLOSE API call failed + else { + // Update ICM688M1 : Change A4PICKSTS + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $aYMACPKR) + ->where('A4CO', $aYCO) + ->where('A4WHS', $aYWHS) + ->update(['A4PICKSTS' => 'a']); + + // Write to Logs Out : Error + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Important-Error: ' . $m3Errors . json_encode($responseMsg) . $m3SessionId, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Add Message + $errorMsgs = $errorMsgs . $m3Errors . ' '; + } + } + // Errors found Log to ICM699M and update A4PICKSTS + else { + // Write to Logs : Error + // Clear Duplicate messages + $errorMsgsC = Helper::removeDuplicateSubstrings($errorMsgs); + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $errorMsgsC, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + } + } + $allErrMsgs = $allErrMsgs . $errorMsgs; + } + + // Update ICM699M : Look for CommTCP_read and set SHERROR to Z Case # 580 + $sHACKNOTE = 'Sentinel automatically closed the error (false positive CommTCP_read)'; + DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->where('SHMACPKR', $aYMACPKR) + ->where('SHCO', $cOMPANY) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', 'M3-General') + ->where('SHDATA', 'like', '%CommTCP_read%') + ->update(['SHERROR' => 'Z', 'SHACKUSER' => $sHUSER, 'SHACKDATE' => date('Y-m-d'), 'SHACKTIME' => date('H:i:s'), 'SHACKNOTE' => $sHACKNOTE]); + + // Update ICM705M1 to say that we have processed this manifest (set APSPARE2='X' ) + if ($tRANSTYPE == 'M') { + DB::connection(config('m3.connection', 'pgsql'))->table('icm705m1') + ->where('APMANIFEST', $mANIFEST) + ->where('APCO', $cOMPANY) + ->where('APWHS', $wHS) + ->update(['APSPARE2' => 'X']); + } + + // Send Response + if ($allErrMsgs == '') { + return response()->json([ + 'code' => '200', + 'status' => 'Success', + 'message' => 'All Operations Successful', + ]); + } else { + $allErrMsgsC = Helper::removeDuplicateSubstrings($allErrMsgs); + + return response()->json([ + 'code' => '206', + 'status' => 'Success With Warnings', + 'message' => $allErrMsgsC . '; Check Transaction Logs for Errors or Warnings.', + ]); + } + + } + // Close Shipment for Zero Picks + elseif (count($iCM695M1TMP) > 0 && $tRANSTYPE == 'Z') { + $errorMsgs = ''; + + foreach ($iCM695M1TMP as $key => $ICM695M1JOINR) { + $sHIPTYPE = trim($ICM695M1JOINR->A4SHIPTYPE); + $fREIGHTTERMS = trim($ICM695M1JOINR->A4OFSTRM); + $a4RATEM3 = trim($ICM695M1JOINR->A4RATEM3); + $fREIGHT = trim($ICM695M1JOINR->A4RATETCP); + $a4REFORD = trim($ICM695M1JOINR->A4REFORD); + $a4ONO = trim($ICM695M1JOINR->A4ONO); + $aYMACPKR = trim($ICM695M1JOINR->A4MACPKR); + $aYWHS = trim($ICM695M1JOINR->A4WHS); + $aYCO = trim($ICM695M1JOINR->A4CO); + + // Construct Json for CloseShipment Without PDF Files + $jSONCS = json_encode([ + 'DIVI' => $aYCO, + 'WHS' => $aYWHS, + 'DELIVERYNO' => $aYMACPKR, + 'TYPE' => 'CloseShipment', + 'PICKLISTSUFFIX' => '1', + 'ENDFLAG' => '1', + ]); + + // Write to Logs Out : JSON Request To M3 + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-JSN-out', + 'SHDATA' => $jSONCS, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + $response = Http::withHeaders([ + 'accept' => self::JSON_CONTENT_TYPE, + 'Content-Type' => self::JSON_CONTENT_TYPE, + 'Connection' => 'close', + ]) + ->withToken($token) + ->withBody($jSONCS, self::JSON_CONTENT_TYPE) + ->timeout(Config::get('arrays.curlTimeOut')) + ->retry(2, 100) + ->post($endPointURL); + + $responseContents = json_decode($response->getBody()->getContents()); + $m3SessionId = $response->hasHeader('x-transaction-id') ? '-sessionID:' . $response->header('x-transaction-id') : '-sessionID'; + $m3Errors = ''; + + if ($responseContents != null) { + $responseMsg = $responseContents->result->CloseShipment; + $m3APIRESULT = $responseMsg->PickingListClose->Result; + + // Check M3 Response for Errors + $responseResult = $responseContents->result; + $m3Errors = Helper::checkM3Errors($responseResult); + + // If you get a successful response, update database file ICM688M1/A4PICKSTS=A + if ($m3APIRESULT != 'Error') { + // Update ICM688M1 : Change A4RATEM3 + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $aYMACPKR) + ->where('A4CO', $aYCO) + ->where('A4WHS', $aYWHS) + ->where('A4PICKSTS', '!=', 'X') + ->update(['A4PICKSTS' => 'A']); + } + + } else { + $m3APIRESULT = 'Error'; + $responseMsg = self::NULL_M3_RESPONSE; + } + + // If you get a successful response + if ($m3APIRESULT != 'Error') { + // Write to Logs Out : Success + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Success' . $m3SessionId, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + } + // If you get a failure, write a record to ICM699M to indicate that the CLOSE API call failed + else { + // Update ICM688M1 : Change A4PICKSTS + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $aYMACPKR) + ->where('A4CO', $aYCO) + ->where('A4WHS', $aYWHS) + ->where('A4PICKSTS', '!=', 'X') + ->update(['A4PICKSTS' => 'a']); + + // Write to Logs Out : Error + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Important-Error: ' . $m3Errors . json_encode($responseMsg) . $m3SessionId, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + // Add Message + $errorMsgs = $errorMsgs . $m3Errors . '-'; + } + + // Update ICM699M : Look for CommTCP_read and set SHERROR to Z Case # 580 + $sHACKNOTE = 'Sentinel automatically closed the error (false positive CommTCP_read)'; + DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->where('SHMACPKR', $aYMACPKR) + ->where('SHCO', $cOMPANY) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', 'M3-General') + ->where('SHDATA', 'like', '%CommTCP_read%') + ->update(['SHERROR' => 'Z', 'SHACKUSER' => $sHUSER, 'SHACKDATE' => date('Y-m-d'), 'SHACKTIME' => date('H:i:s'), 'SHACKNOTE' => $sHACKNOTE]); + } + + // Send Response + if ($errorMsgs == '') { + return response()->json([ + 'code' => '200', + 'status' => 'Success', + 'message' => 'All Operations Successful', + ]); + } else { + return response()->json([ + 'code' => '206', + 'status' => 'Success With Warnings', + 'message' => $errorMsgs . '; Check The Logs for Errors or Warnings.', + ]); + } + } + // ## End Zero Pick + else { + $dELIVERYNO = isset($mANIFEST) ? $mANIFEST : self::ZERO_PAD; + // # Set SHDATA Message + $sHDATAMSG = 'No records found in ICM695M1,or URL parameters incomplete'; + // count($iCM695M1TMP)==0 ? 'MacPkr already closed' : + $sHERROR = 'X'; + // count($iCM695M1TMP)==0 ? 'Z' : + + // Write to Logs Out : Error + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => $sHERROR, + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Req-out', + 'SHDATA' => $sHDATAMSG, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => 'No records found in ICM695M1,or URL parameters incomplete For MacPkr/Manifest:' . $dELIVERYNO, + ]); + } + } else { + // Write to Logs Out : Error + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'No URL Parameters Sent', + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => 'No URL Parameters Sent', + ]); + } + } catch (\Throwable $th) { + $getCurlErrors = str_contains($th->getMessage(), 'cURL error'); + if ($getCurlErrors) { + // dd($getCurlErrors); + // Write to Logs Out : Failed + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Curl Error: Communication with M3 Timed Out' . ' M3-JSN-out' . $jSONIN, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Curl Error: Communication with M3 Timed Out.', + ]); + } else { + // Write to Logs Out : Error + $dELIVERYNO = isset($aYMACPKR) ? $aYMACPKR : self::ZERO_PAD; + $data = [ + 'SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'An Error Occured - ' . substr($th, 0, 300), + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $cOMPANY, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + Log::error($th); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Catched Error: ' . $th, + ]); + } + } + } + // End CloseShipmentCoChargeAPI +} diff --git a/Modules/M3/Http/Controllers/API/M3Controller.php b/Modules/M3/Http/Controllers/API/M3Controller.php new file mode 100755 index 00000000..30ee08e2 --- /dev/null +++ b/Modules/M3/Http/Controllers/API/M3Controller.php @@ -0,0 +1,535 @@ +table('icm666m2')->insert($fullData); + + $aXLINENO++; + + // AXCO ICM666M2 CHARACTER 3 + // AXWHS ICM666M2 CHARACTER 3 + // AXPLANT ICM666M2 CHARACTER 3 + // AXDOCUMENT ICM666M2 CHARACTER 15 + // AXCOMMENT ICM666M2 CHARACTER 60 + // AXLINENO DECIMAL(3,0) + } + } + + public function index() + { + dd('Index'); + } + + public function create() + { + // This API controller does not expose a create form. + } + + public function store(Request $request) + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOut')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut')); + + $rEQKPKUS = m3_user() !== '' ? Str::upper(m3_user()) : 'WEBUSER'; + $sHSOURCE = 'M3ReceiverAPI'; + + $iCM666MFields = [ + 'Company' => ['A1CO', 3, 'string'], + 'Warehouse' => ['A1WHS', 3, 'string'], + 'Plant' => ['A1PLANT', 3, 'string'], + 'PickerNumber' => ['A1DELNO', 11, 'integer'], + 'OrderNumber' => ['A1ONO', 10, 'string'], + 'ReleaseNumber' => ['A1RLNO', 3, 'string'], // Pick list suffix in ICM666M + 'ShipmentNumber' => ['A1SHNO', 7, 'string'], + 'OrderLine' => ['A1PKLN', 6, 'integer'], + 'PartNumber' => ['A1PART', 15, 'string'], + 'Description' => ['A1PARTDES', 120, 'string'], + 'Quantity' => ['A1RSVQTY', 22, 'DEC'], + 'BaseUnitPrice' => ['A1SLUNPR', 22, 'DEC'], + 'Currency' => ['A1SHCURR', 3, 'string'], + 'Zone' => ['A1LVZONE', 2, 'string'], + 'PromDate' => ['A1PROMDTE', 8, 'integer'], + 'RouteCode' => ['A1SHSRT', 6, 'string'], + 'BillToId' => ['A1BILLTO', 10, 'string'], + 'ShipToId' => ['A1SHIPTO', 10, 'string'], + 'CompanyName' => ['A1SHSHNM', 36, 'string'], + 'Address1' => ['A1SHSHA1', 36, 'string'], + 'Address2' => ['A1SHSHA2', 36, 'string'], + 'Address3' => ['A1SHSHA3', 36, 'string'], + 'Address4' => ['A1SHSHA4', 36, 'string'], + 'City' => ['A1SHSHCI', 20, 'string'], + 'State' => ['A1SHSHST', 2, 'string'], + 'PostalCode' => ['A1SHSHZP', 10, 'string'], + 'Country' => ['A1SHSHCT', 3, 'string'], + 'CountryName' => ['A1SHP2CNTY', 40, 'string'], + 'PartWeight' => ['A1PRTWGT', 15, 'integer'], + 'SellUOM' => ['A1SLUOM', 3, 'string'], + 'PartConv' => ['A1PARTCONV', 25, 'DEC'], + 'CarrierCode' => ['A1CARRIER', 6, 'string'], + 'ShipVia' => ['A1SHPVIA', 3, 'string'], + 'PrimaryLocation' => ['A1PRIMLOC', 10, 'string'], + 'Allocation' => ['A1SPR10A01', 10, 'string'], + 'AllocatedTo' => ['A1SPR15A01', 10, 'string'], + 'LocationSeq' => ['A1LOCSEQ', 10, 'string'], + 'UOM' => ['A1UOM', 3, 'string'], + 'HazMat' => ['A1MATWRN', 4, 'string'], + 'PartUPC' => ['A1UPC', 30, 'string'], + 'PartEAN' => ['A1EAN', 30, 'string'], + 'LotFlag' => ['A1IZLCF', 1, 'string'], + 'ManOrd' => ['A1MONUM', 30, 'string'], + 'LotNumber' => ['A1LOTNUM', 30, 'string'], + 'ProductArea' => ['A1LVUSD1', 15, 'string'], + 'FreightClass' => ['A1WBFRCT', 10, 'string'], + 'ShipmentPONumber' => ['A1SOPONO', 20, 'string'], + 'ShipmentPOLine' => ['A1SOPOLN', 7, 'integer'], + 'ShipTerms' => ['A1OFSTRM', 3, 'string'], + // 'ExchangeRate' =>[ 'A1EXGRATE', 18,'DEC'], + 'OrderClass' => ['A1SHORCL', 3, 'string'], + 'LocationType' => ['A1LVUSD2', 2, 'string'], + 'PallSize' => ['A1LVUSD3', 10, 'string'], + 'MasterCarton' => ['A1USRLD1', 30, 'string'], + 'MasterQty' => ['A1WBSHQY', 25, 'DEC'], + 'InnerQty' => ['A1WBPKQY', 25, 'DEC'], + 'PalletQty' => ['A1USRN01', 24, 'DEC'], + 'CartonQty' => ['A1USRN31', 25, 'DEC'], + 'PersonName' => ['A1PERNAME', 30, 'string'], + 'AccountNo' => ['A1ACCNUM', 20, 'string'], + 'Email' => ['A1EMAIL', 100, 'string'], + 'OrderCategory' => ['A1REFORD', 1, 'string'], + 'A1DATEADD' => ['A1DATEADD', 12, 'string'], + 'A1TIMEADD' => ['A1TIMEADD', 12, 'string'], + 'KitPartNumber' => ['A1KITPART', 15, 'string'], + 'OrderLineSuffix' => ['A1PKSFX', 6, 'DEC'], + 'CustomerPartNumber' => ['A1CUSTPART', 20, 'string'], + 'GS1Label' => ['A1SPR1A01', 1, 'string'], + 'CurrencyExchangeRate' => ['A1EXGRATE', 18, 'DEC'], + + ]; + + try { + $jsonFile = count($request->json()->all()) > 0 ? $request->json()->all() : ''; + + // Root + $company = isset($jsonFile['Company']) ? $jsonFile['Company'] : ''; + $plant = isset($jsonFile['Plant']) ? $jsonFile['Plant'] : ''; + $warehouse = isset($jsonFile['Warehouse']) ? $jsonFile['Warehouse'] : ''; + $orderNumber = isset($jsonFile['OrderNumber']) ? $jsonFile['OrderNumber'] : ''; + $pickerNumber = isset($jsonFile['PickerNumber']) ? $jsonFile['PickerNumber'] : ''; + $promDate = isset($jsonFile['PromDate']) ? $jsonFile['PromDate'] : ''; + $routeCode = isset($jsonFile['RouteCode']) ? $jsonFile['RouteCode'] : ''; + $orderCategory = isset($jsonFile['OrderCategory']) ? $jsonFile['OrderCategory'] : ''; + $releaseNumber = isset($jsonFile['ReleaseNumber']) ? $jsonFile['ReleaseNumber'] : ''; + $shipmentNumber = isset($jsonFile['ShipmentNumber']) ? $jsonFile['ShipmentNumber'] : ''; + $currency = isset($jsonFile['Currency']) ? $jsonFile['Currency'] : ''; + $carrierCode = isset($jsonFile['CarrierCode']) ? $jsonFile['CarrierCode'] : ''; + $shipmentPONumber = isset($jsonFile['ShipmentPONumber']) ? $jsonFile['ShipmentPONumber'] : ''; // CustPo + $shipTerms = isset($jsonFile['ShipTerms']) ? $jsonFile['ShipTerms'] : ''; + $orderClass = isset($jsonFile['OrderClass']) ? $jsonFile['OrderClass'] : ''; + $gS1Label = isset($jsonFile['GS1-128Label']) ? $jsonFile['GS1-128Label'] : '0'; + $currencyExchangeRate = isset($jsonFile['CurrencyExchangeRate']) ? $jsonFile['CurrencyExchangeRate'] : ''; + + // Set Carrier BWAY if it's empty for Tilburg only + if (($carrierCode == '' || $carrierCode == null) && $warehouse == '111' && $company == '410' && $plant == '410') { + $carrierCode = 'BWAY'; + } + + $sHMACPKR = $pickerNumber != '' ? $pickerNumber : '000000'; + + if ($jsonFile != '') { + // Order Category + /* + 1 = Material to manufacturing order + 3 = Customer Order + 4 = Requisition Order + 5 = Distribution Order + 9 = Move order / Replenishment + */ + + // Recipient + $recipient = $jsonFile['Recipient']; + $companyName = isset($recipient['CompanyName']) ? $recipient['CompanyName'] : ''; + $address1 = isset($recipient['Address1']) ? $recipient['Address1'] : ''; + $address2 = isset($recipient['Address2']) ? $recipient['Address2'] : ''; + $city = isset($recipient['City']) ? $recipient['City'] : ''; + $state = isset($recipient['State']) ? $recipient['State'] : ''; + $postalCode = isset($recipient['PostalCode']) ? $recipient['PostalCode'] : ''; + $country = isset($recipient['Country']) ? $recipient['Country'] : ''; + $postalCode = isset($recipient['PostalCode']) ? $recipient['PostalCode'] : ''; + $billToId = isset($recipient['BillToId']) ? $recipient['BillToId'] : ''; + $shipToId = isset($recipient['ShipToId']) ? $recipient['ShipToId'] : ''; + $address3 = isset($recipient['Address3']) ? $recipient['Address3'] : ''; + $address4 = isset($recipient['Address4']) ? $recipient['Address4'] : ''; + $countryName = isset($recipient['CountryName']) ? $recipient['CountryName'] : ''; + $personName = isset($recipient['PersonName']) ? $recipient['PersonName'] : ''; + $accountNo = isset($recipient['AccountNo']) ? $recipient['AccountNo'] : ''; + $email = isset($recipient['Email']) ? $recipient['Email'] : ''; + $a1DATEADD = date('Ymd'); + $a1TIMEADD = date('His'); + + // MycarrierDetails + $shipVia = isset($jsonFile['ShipVia']) ? $jsonFile['ShipVia'] : ''; + + // Comments + $picker = $packer = $carrier = $other = ''; + $aXCO = $company; + $aXPLANT = $plant; + $aXWHS = $warehouse; + $aXDELNO = $pickerNumber; + $aXONO = $orderNumber; + $aXRLNO = $releaseNumber; + $aXSHNO = $shipmentNumber; + + $comments = isset($jsonFile['Comments']) ? $jsonFile['Comments'] : ''; + + if ($comments != '') { + foreach ($comments as $key => $comment) { + $commentData = []; + $aXDOCUMENT = Helper::sanityzeString($key); + + $commentData = ['AXCO' => $aXCO, 'AXPLANT' => $aXPLANT, 'AXWHS' => $aXWHS, 'AXDELNO' => $aXDELNO, 'AXONO' => $aXONO, + 'AXRLNO' => $aXRLNO, 'AXSHNO' => $aXSHNO, 'AXDOCUMENT' => $aXDOCUMENT]; + + switch ($aXDOCUMENT) { + case 'Picker': + $picker = isset($comment) ? Helper::sanityzeString($comment) : 'null'; + if ($picker != 'null') { + $this->insertToICM666M2($picker, $commentData); + } + break; + + case 'Packer': + $packer = isset($comment) ? Helper::sanityzeString($comment) : 'null'; + if ($packer != 'null') { + $this->insertToICM666M2($packer, $commentData); + } + break; + + case 'Carrier': + $carrier = isset($comment) ? Helper::sanityzeString($comment) : 'null'; + if ($carrier != 'null') { + $this->insertToICM666M2($carrier, $commentData); + } + break; + + case 'Other': + $other = isset($comment) ? Helper::sanityzeString($comment) : 'null'; + if ($other != 'null') { + $this->insertToICM666M2($other, $commentData); + } + break; + + default: + break; + } + } + } + + // Get Products : commodities And Write ICM666M + $products = $jsonFile['Contents']['Commodities']; + foreach ($products as $key => $product) { + $quantity = isset($product['Quantity']) ? $product['Quantity'] : ''; + $description = isset($product['Description']) ? Str::limit($product['Description'], 25, '') : ''; + $partNumber = isset($product['PartNumber']) ? $product['PartNumber'] : ''; + $orderLine = isset($product['OrderLine']) ? $product['OrderLine'] : ''; + $partWeight = isset($product['PartWeight']) ? $product['PartWeight'] : ''; + $primaryLocation = isset($product['PrimaryLocation']) ? $product['PrimaryLocation'] : ''; + $allocation = isset($product['Allocation']) ? $product['Allocation'] : ''; + $allocatedTo = isset($product['AllocatedTo']) ? $product['AllocatedTo'] : ''; + $locationSeq = isset($product['LocationSeq']) ? $product['LocationSeq'] : ''; + $zone = isset($product['Zone']) ? $product['Zone'] : ''; + $baseUnitPrice = isset($product['BaseUnitPrice']) ? $product['BaseUnitPrice'] : ''; + $sellUOM = isset($product['SellUOM']) ? $product['SellUOM'] : ''; + $partConv = isset($product['PartConv']) ? $product['PartConv'] : ''; + $uOM = isset($product['UOM']) ? $product['UOM'] : ''; + $hazMat = isset($product['HazMat']) ? $product['HazMat'] : ''; + $partUPC = isset($product['PartUPC']) ? $product['PartUPC'] : ''; + $partEAN = isset($product['PartEAN']) ? $product['PartEAN'] : ''; + $lotFlag = isset($product['LotFlag']) ? $product['LotFlag'] : ''; + $manOrd = isset($product['ManOrd']) ? $product['ManOrd'] : ''; + $lotNumber = isset($product['LotNumber']) ? $product['LotNumber'] : ''; + $productArea = isset($product['ProductArea']) ? $product['ProductArea'] : ''; + $freightClass = isset($product['FreightClass']) ? $product['FreightClass'] : ''; + $shipmentPOLine = isset($product['ShipmentPOLine']) ? $product['ShipmentPOLine'] : ''; + $locationType = isset($product['LocationType']) ? $product['LocationType'] : ''; + $pallSize = isset($product['PallSize']) ? $product['PallSize'] : ''; + $masterCarton = isset($product['MasterCarton']) ? $product['MasterCarton'] : ''; + $masterQty = isset($product['MasterQty']) ? $product['MasterQty'] : ''; + $innerQty = isset($product['InnerQty']) ? $product['InnerQty'] : ''; + $sonar_pallet_qty = isset($product['PalletQty']) ? $product['PalletQty'] : ''; + $cartonQty = isset($product['CartonQty']) ? $product['CartonQty'] : ''; + $kitPartNumber = isset($product['KitPartNumber']) ? $product['KitPartNumber'] : ''; + $orderLineSuffix = isset($product['OrderLineSuffix']) ? $product['OrderLineSuffix'] : ''; + $customerPartNumber = isset($product['CustomerPartNumber']) ? substr($product['CustomerPartNumber'], 0, 20) : ''; // Limit to 20 Chars + + // Initialise Table Fields to be filled + $insertArray = []; + $fieldValues = [ + 'Company' => $company, + 'Warehouse' => $warehouse, + 'Plant' => $plant, + 'PickerNumber' => $pickerNumber, + 'OrderNumber' => $orderNumber, + 'ReleaseNumber' => $releaseNumber, + 'ShipmentNumber' => $shipmentNumber, + 'OrderLine' => $orderLine, + 'PartNumber' => $partNumber, + 'Description' => $description, + 'Quantity' => $quantity, + 'BaseUnitPrice' => $baseUnitPrice, + 'Currency' => $currency, + 'Zone' => $zone, + 'PromDate' => $promDate, + 'RouteCode' => $routeCode, + 'BillToId' => $billToId, + 'ShipToId' => $shipToId, + 'CompanyName' => $companyName, + 'Address1' => $address1, + 'Address2' => $address2, + 'Address3' => $address3, + 'Address4' => $address4, + 'City' => $city, + 'State' => $state, + 'PostalCode' => $postalCode, + 'Country' => $country, + 'CountryName' => $countryName, + 'PartWeight' => $partWeight, + 'SellUOM' => $sellUOM, + 'PartConv' => $partConv, + 'CarrierCode' => $carrierCode, + 'ShipVia' => $shipVia, + 'PrimaryLocation' => $primaryLocation, + 'Allocation' => $allocation, + 'AllocatedTo' => $allocatedTo, + 'LocationSeq' => $locationSeq, + 'UOM' => $uOM, + 'HazMat' => $hazMat, + 'PartUPC' => $partUPC, + 'PartEAN' => $partEAN, + 'LotFlag' => $lotFlag, + 'ManOrd' => $manOrd, + 'LotNumber' => $lotNumber, + 'ProductArea' => $productArea, + 'FreightClass' => $freightClass, + 'ShipmentPONumber' => $shipmentPONumber, + 'ShipmentPOLine' => $shipmentPOLine, + 'ShipTerms' => $shipTerms, + 'OrderClass' => $orderClass, + 'LocationType' => $locationType, + 'PallSize' => $pallSize, + 'MasterCarton' => $masterCarton, + 'MasterQty' => $masterQty, + 'InnerQty' => $innerQty, + 'PalletQty' => $sonar_pallet_qty, + 'CartonQty' => $cartonQty, + 'PersonName' => $personName, + 'AccountNo' => $accountNo, + 'Email' => $email, + 'OrderCategory' => $orderCategory, + 'A1DATEADD' => $a1DATEADD, + 'A1TIMEADD' => $a1TIMEADD, + 'KitPartNumber' => $kitPartNumber, + 'OrderLineSuffix' => $orderLineSuffix, + 'CustomerPartNumber' => $customerPartNumber, + 'GS1Label' => $gS1Label, + 'CurrencyExchangeRate' => $currencyExchangeRate, + ]; + + // Check JSON fields if empty or > DB Fields + foreach ($iCM666MFields as $key => $value) { + // Sanitize String + $fieldValue = Helper::sanityzeString($fieldValues[$key] ?? ''); + // Check Var Types & Length + $lengthTest = Helper::checkLength($fieldValue, $value[1], $value[2]); + + if (! $lengthTest[413] || ! $lengthTest[411] || ! $lengthTest[417]) { + if (! $lengthTest[413]) { + $message[] = ['code' => '413', 'status' => 'error', 'message' => self::FIELD_PREFIX . $key . ' is larger then expected']; + } + if (! $lengthTest[411]) { + $message[] = ['code' => '411', 'status' => 'error', 'message' => self::FIELD_PREFIX . $key . ' is empty']; + } + if (! $lengthTest[417]) { + $message[] = ['code' => '417', 'status' => 'error', 'message' => self::FIELD_PREFIX . $key . 'type is different then Expected type: ' . $value[2]]; + } + + // Write to Logs Out : Error & JSON + $data = ['SHMACPKR' => $sHMACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Lis-spl', + 'SHDATA' => json_encode($message) . self::M3_LIST_SUFFIX . json_encode($jsonFile), 'SHUSER' => $rEQKPKUS, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $company, 'SHWHS' => $warehouse]; + Helper::logToICM699M($data); + + return response()->json($message); + } elseif ($fieldValue != '') { + $insertArray[$value[0]] = $fieldValue; + } + } + + // Check ICM709M + $iCM709MSEL = DB::connection(config('m3.connection', 'pgsql'))->table('icm709m') + ->select() + ->where('AT9CO', $aXCO) + ->where('AT9PLT', $aXPLANT) + ->where('AT9WHS', $aXWHS) + ->where('AT9PART', $partNumber) + ->first(); + $palletQty = isset($iCM709MSEL->AT9QTY) ? $iCM709MSEL->AT9QTY : 0; + // dd($palletQty); + // Get Pallet Qty + $insertArray['A1USRN01'] = $palletQty; + + // Hazard Material + $hazMat = isset($iCM709MSEL->AT9WRN) ? $iCM709MSEL->AT9WRN : ''; + $insertArray['A1MATWRN'] = $hazMat; + + // } + + // SQL Insert to ICM666M + DB::connection(config('m3.connection', 'pgsql'))->table('icm666m')->insert($insertArray); + } + + // Call PGM ICM700CSBM + if ($warehouse != '' && $pickerNumber != '' && $company != '') { + $pGMERRORS = ''; + + // connect to toolkit using DB2 credentials (can also leave blank for default authority) + try { + $conn = app(PostgresProgramBridge::class); + } catch (\Throwable $e) { + // Determine reason for failure. + // Probably database authentication error or invalid or unreachable database. + $code = $e->getCode(); + $msg = $e->getMessage(); + + switch ($code) { + case 8001: + // "Authorization failure on distributed database connection attempt" + // Usually means a wrong DB2 user or password + $pGMERRORS = 'Could not connect due to wrong user or password.'; + break; + case 42705: + $pGMERRORS = 'Database not found. Try WRKRDBDIRE to check.'; + break; + default: + $pGMERRORS = 'Could not connect. Error: ' . $code . ' ' . $msg; + break; + } + } + $conn->setOptions(['persistent' => false, 'stateless' => true, 'debug' => true, 'debugLogFile' => env('TOOLKIT_DEBUG_LOG')]); + + // Add LIB + // $result = $conn->CLCommand('ADDLIBLE LIB(MPDAT10)'); + + // define several input/output params + $params = []; + + // AddParameterChar($io, $size, $comment, $varName, $value, $varying, $dimension) + // Add Warehouse Param + $params[] = $conn->AddParameterChar('in', 3, 'Company', '', $company); + + $params[] = $conn->AddParameterChar('in', 3, 'Warehouse', '', $warehouse); + + // AddParameterPackDec($io, $length, $scale, $comment, $varName, $value,$dimension) + // Add Delivery Note Param + $pickerNumberNoZero = ltrim(strval($pickerNumber), '0'); + $params[] = $conn->AddParameterChar('in', 11, 'PickerNumber', '', $pickerNumberNoZero); + + // Start Time Tracking + + // ICM700C EWOBJTST ICM700C ICM700CSBM + $result = $conn->PgmCall('ICM700CSBM', env('OBJLIB'), $params, [], []); + + if (! $result) { + $pGMERRORS = 'Error calling program. Code: ' . $conn->getErrorCode() . ' - Msg: ' . $conn->getErrorMsg(); + } + + if ($pGMERRORS != '') { + // Write to Logs Out : Error & JSON + $data = ['SHMACPKR' => $sHMACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Lis-spl', + 'SHDATA' => $pGMERRORS . self::M3_LIST_SUFFIX . json_encode($jsonFile), 'SHUSER' => $rEQKPKUS, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $company, 'SHWHS' => $warehouse]; + Helper::logToICM699M($data); + } + } + + // Write to Logs Out : Success + $data = ['SHMACPKR' => $sHMACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Lis-in', + 'SHDATA' => json_encode($jsonFile), 'SHUSER' => $rEQKPKUS, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $company, 'SHWHS' => $warehouse]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '200', + 'status' => 'success', + 'message' => 'File Received, DB Updated', + ]); + } else { + // Write to Logs Out : Error & JSON + $sHACKNOTE = 'Sentinel automatically closed the error related to this empty data set sent by M3'; + + $data = ['SHMACPKR' => $sHMACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'Z', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Lis-in', + 'SHDATA' => 'No Json File Found...', 'SHUSER' => $rEQKPKUS, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $company, 'SHWHS' => $warehouse, 'SHACKNOTE' => $sHACKNOTE]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '415', + 'status' => 'error', + 'message' => 'No Json File Found', + ]); + } + } catch (\Throwable $th) { + // Write to Logs Out : Error & JSON + $data = ['SHMACPKR' => $sHMACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Lis-in', + 'SHDATA' => 'General Catchable Error - ' . substr($th, 0, 300) . self::M3_LIST_SUFFIX . json_encode($jsonFile), 'SHUSER' => $rEQKPKUS, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $company, 'SHWHS' => $warehouse]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'An Error Occured...', + ]); + } + } + + public function show($id) + { + // This resource endpoint is intentionally unsupported. + } + + public function edit($id) + { + // This resource endpoint is intentionally unsupported. + } + + public function update(Request $request, $id) + { + // This resource endpoint is intentionally unsupported. + } + + public function destroy($id) + { + // This resource endpoint is intentionally unsupported. + } +} diff --git a/Modules/M3/Http/Controllers/API/PdfStorage.php b/Modules/M3/Http/Controllers/API/PdfStorage.php new file mode 100755 index 00000000..ab1cdfbb --- /dev/null +++ b/Modules/M3/Http/Controllers/API/PdfStorage.php @@ -0,0 +1,150 @@ +configureTimeouts(); + + $context = $this->requestContext($request); + if ($context === null) { + return $this->errorResponse('No URL Parameters Sent', self::ZERO_PAD, '', '', ''); + } + + try { + $this->logRequest($context); + + $cacheKey = $this->buildCacheKey($context); + $pdfFileName = (string) Config::get('arrays.PdfPath') . $context['FILENAME'] . '.pdf'; + $error = $this->validateStorageRequest($pdfFileName, $cacheKey); + + if ($error !== null) { + return $this->errorResponse($error, $context['DELIVERYNO'], $context['DOCNUM'], $context['COMPANY'], $context['WHS']); + } + + Cache::forever($cacheKey, base64_encode(File::get($pdfFileName))); + $this->logResult($context, 'PDF File converted to Base64 and Saved to Cache.Key: ' . $cacheKey); + + return response()->json(['code' => '200', 'status' => 'Success', 'cacheKey' => $cacheKey]); + } catch (\Throwable $exception) { + $message = 'An Error Occured - ' . substr($exception->getMessage(), 0, 300); + $this->safeLog($context, $message, true); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Catched Error: ' . $exception->getMessage(), + ]); + } + } + + private function configureTimeouts(): void + { + $timeout = (string) Config::get('arrays.PHPTimeOut'); + ini_set('max_execution_time', $timeout); + ini_set('max_input_time', $timeout); + ini_set('default_socket_timeout', $timeout); + } + + private function requestContext(Request $request): ?array + { + if ($request->all() === []) { + return null; + } + + $context = []; + foreach (['COMPANY', 'WHS', 'DOCTYPE', 'FILENAME', 'DOCNUM', 'A4MACPKR'] as $key) { + $context[$key] = trim((string) $request->input($key, '')); + } + + $context['DELIVERYNO'] = $context['A4MACPKR'] !== '' ? $context['A4MACPKR'] : self::ZERO_PAD; + $context['SHUSER'] = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'; + $context['SHSOURCE'] = 'PdfStorageAPI'; + + return $context; + } + + private function buildCacheKey(array $context): string + { + foreach (['A4MACPKR', 'DOCTYPE', 'DOCNUM', 'COMPANY', 'WHS'] as $required) { + if ($context[$required] === '') { + return ''; + } + } + + return $context['A4MACPKR'] . $context['DOCTYPE'] . $context['DOCNUM'] . $context['COMPANY'] . $context['WHS']; + } + + private function validateStorageRequest(string $pdfFileName, string $cacheKey): ?string + { + $messages = []; + if (! File::exists($pdfFileName)) { + $messages[] = 'PDF File Not Found-'; + } + if ($cacheKey === '') { + $messages[] = 'Cache Key is missing Params'; + } + + return $messages === [] ? null : implode('', $messages); + } + + private function logRequest(array $context): void + { + $params = array_intersect_key($context, array_flip(['COMPANY', 'WHS', 'DOCTYPE', 'FILENAME', 'A4MACPKR', 'DOCNUM'])); + $this->safeLog($context, json_encode($params, JSON_THROW_ON_ERROR), false, 'M3-Req-out'); + } + + private function logResult(array $context, string $message): void + { + $this->safeLog($context, $message); + } + + private function safeLog(array $context, string $message, bool $error = false, string $type = 'M3-Res-out'): void + { + try { + Helper::logToICM699M([ + 'SHMACPKR' => $context['DELIVERYNO'] ?? self::ZERO_PAD, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => $error ? 'X' : '', + 'SHINTBOX' => $context['DOCNUM'] ?? '', + 'SHTYPE' => $type, + 'SHDATA' => $message, + 'SHUSER' => $context['SHUSER'] ?? (m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'), + 'SHSOURCE' => $context['SHSOURCE'] ?? 'PdfStorageAPI', + 'SHCO' => $context['COMPANY'] ?? '', + 'SHWHS' => $context['WHS'] ?? '', + ]); + } catch (\Throwable) { + // Logging must never turn an API response into a 500 error. + } + } + + private function errorResponse(string $message, string $deliveryNo, string $docNum, string $company, string $warehouse): JsonResponse + { + $context = [ + 'DELIVERYNO' => $deliveryNo, + 'DOCNUM' => $docNum, + 'COMPANY' => $company, + 'WHS' => $warehouse, + 'SHUSER' => m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser', + 'SHSOURCE' => 'PdfStorageAPI', + ]; + $this->safeLog($context, 'An Error Occured -' . $message, true); + + return response()->json(['code' => '405', 'status' => 'Error', 'message' => $message]); + } +} diff --git a/Modules/M3/Http/Controllers/API/ReplenAPI.php b/Modules/M3/Http/Controllers/API/ReplenAPI.php new file mode 100755 index 00000000..f1ade14c --- /dev/null +++ b/Modules/M3/Http/Controllers/API/ReplenAPI.php @@ -0,0 +1,276 @@ +all()); + // Log::info( $request->all() ); + // Get The Calling User + $sHUSER = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'; + $mACPKR = isset($mACPKR) ? $mACPKR : self::ZERO_PAD; + $sHSOURCE = 'M3InventoryReportReplen'; + $m3Errors = ''; + + try { + // Get Json Contents + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + + $cO = isset($urlParams['CO']) ? $urlParams['CO'] : ''; + $wHS = isset($urlParams['WHS']) ? $urlParams['WHS'] : ''; + $pARTNO = isset($urlParams['PARTNO']) ? $urlParams['PARTNO'] : ''; + $pKLN = isset($urlParams['PKLN']) ? $urlParams['PKLN'] : ''; + $rEQPKWS = isset($urlParams['REQPKWS']) ? $urlParams['REQPKWS'] : ''; + $rEQKPKUS = isset($urlParams['REQKPKUS']) ? $urlParams['REQKPKUS'] : 'WebUser'; + + if ($urlParams != '') { + $incomingParams = ['CO' => $cO, 'WHS' => $wHS, 'PARTNO' => $pARTNO, 'PKLN' => $pKLN, 'REQPKWS' => $rEQPKWS, 'REQKPKUS' => $rEQKPKUS]; + $incomingParams = json_encode($incomingParams); + + // Write to Logs : Params In + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Req-out', + 'SHDATA' => $incomingParams, 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + $pART = explode(',', $pARTNO); + foreach ($pART as $value) { + $pARTS[] = ['PART' => $value, 'LOT' => '']; + } + + $jSON = json_encode(['WHS' => $wHS, 'PARTS' => $pARTS]); + + // Write to Logs : Params Sent To M3 + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Req-out', + 'SHDATA' => 'Sent To M3-' . $jSON, 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + // Get Token + $tokenResponse = Helper::checkReceiveTokenV2(); + $tokenData = $tokenResponse->getData(); + if ($tokenData->code == '200') { + $ionToken = isset($tokenData->token) ? $tokenData->token : ''; + } else { + $sHDATA = isset($tokenData->message) ? $tokenData->message : ''; + // Write to Logs : Error + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $sHDATA, 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + return $tokenResponse; + } + + // Call ionapi with Params + $endPointURL = env('ENDPOINTURL') . 'APIFLOWS/Sentinel/M3InventoryReportList?ionapiRespStyle=sync'; + $token = $ionToken; + + $response = Http::withHeaders([ + 'accept' => self::JSON_CONTENT_TYPE, + 'Content-Type' => self::JSON_CONTENT_TYPE, + ]) + ->withToken($token) + ->withBody($jSON, self::JSON_CONTENT_TYPE) + ->timeout(Config::get('arrays.curlTimeOut')) + ->retry(3, 100) + ->post($endPointURL); + + $responseStatusCode = $response->getStatusCode(); + + $m3SessionId = $response->hasHeader('x-transaction-id') ? '-sessionID:' . $response->header('x-transaction-id') : '-sessionID'; + + if ($responseStatusCode == '200') { + // Check M3 Response for Errors + $m3Errors = ''; + $responseJSON = $response->getBody()->getContents(); + $jsonSanytized = Helper::sanityzeString($responseJSON); + // Array + $responseArray = json_decode($jsonSanytized, true); + $responseTMP = $responseArray['result']; + } else { + $m3Errors = 'Error: No Response from M3'; + } + + // Validate response From M3 + if ($m3Errors != '') { + // Write to Logs : Error + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $responseStatusCode . '-' . $m3Errors . $m3SessionId, 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + // Send Response + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Error: No Response from M3', + ]); + } else { + // Write to Logs : JSON + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $responseStatusCode . '-' . $jsonSanytized . $m3SessionId, 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + } + + $dataToWrite2 = []; + foreach ($responseTMP as $value) { + $dataToWrite = []; + + foreach ($value as $key2 => $content) { + if ($key2 != 'Locations') { + $dataToWrite[$key2] = $content; + } else { + foreach ($content as $content2) { + $dataToWrite2[] = array_merge($dataToWrite, $content2); + } + } + } + } + + // Delete Old Records from IC630M + foreach ($dataToWrite2 as $value) { + DB::connection(config('m3.connection', 'pgsql'))->table('ic630m') + ->where('LLCO', $cO) + ->where('LLWHNO', $wHS) + ->where('LLPPN', trim($value['PartNumber'])) + ->delete(); + } + + foreach ($dataToWrite2 as $value) { + // Check if Location exist in DE640M $value['Location'] + $dE640MSQLSEL = DB::connection(config('m3.connection', 'pgsql'))->table('de640m') + ->where('LVCO', $cO) + ->where('WSELOC', $value['Warehouse']) + ->where('VLOCID', $value['Location']) + ->first(); + + $locationExist = isset($dE640MSQLSEL->VLOCID) ? trim($dE640MSQLSEL->VLOCID) : ''; + $wHExist = isset($dE640MSQLSEL->WSELOC) ? trim($dE640MSQLSEL->WSELOC) : ''; + $cOExist = isset($dE640MSQLSEL->LVCO) ? trim($dE640MSQLSEL->LVCO) : ''; + + // if No records Founds insert New Record + if ($locationExist == '' && $wHExist == '' && $cOExist == '') { + $sQLInsertPrep640M['LVCO'] = $cO; // Company + $sQLInsertPrep640M['WSELOC'] = $value['Warehouse']; + // $sQLInsertPrep640M['LVUSD3'] = $value['']; // Pallet Size : Not Found in M3 JSON + $sQLInsertPrep640M['VLOCID'] = $value['Location']; // Stock location + $sQLInsertPrep640M['LVSEQN'] = $value['LocationSeq']; + $sQLInsertPrep640M['LVUSD2'] = $value['LocationType']; + $sQLInsertPrep640M['LVZONE'] = $value['Zone']; // Warehouse zone + $sQLInsertPrep640M['LVMAINTTS'] = now(); // Last maintained time stamp + + DB::connection(config('m3.connection', 'pgsql'))->table('de640m')->insert($sQLInsertPrep640M); + } + // Update + else { + $sQLUpdatePrep640M['LVSEQN'] = $value['LocationSeq']; + $sQLUpdatePrep640M['LVUSD2'] = $value['LocationType']; + $sQLUpdatePrep640M['LVZONE'] = $value['Zone']; + $sQLUpdatePrep640M['LVMAINTTS'] = now(); + + DB::connection(config('m3.connection', 'pgsql'))->table('de640m') + ->where('LVCO', $cO) + ->where('WSELOC', $value['Warehouse']) + ->where('VLOCID', $value['Location']) + ->update($sQLUpdatePrep640M); + } + + // Insert New Records to IC630M + $sQLInsertPrep630M = []; + $sQLInsertPrep630M['LLCO'] = $cO; // Company + $sQLInsertPrep630M['LLWHNO'] = $value['Warehouse']; // Warehouse + $sQLInsertPrep630M['LLPPN'] = $value['PartNumber']; // Part Number + $sQLInsertPrep630M['LLBALANCE'] = $value['Quantity']; // Quantity + $sQLInsertPrep630M['LLSTLC'] = $value['Location']; // Stock location + $sQLInsertPrep630M['LLLTNO'] = $value['LotNumber']; // Lot Number + $sQLInsertPrep630M['LLMAINTTS'] = now(); // Request time timestamp + $sQLInsertPrep630M['LLIZLCF'] = trim($value['LotNumber']) != '' ? '1' : ''; // Lot control flag + $sQLInsertPrep630M['LLSPR10A01'] = $value['Allocation']; // Allocation + $sQLInsertPrep630M['LLSPR15A01'] = $value['AllocatedTo']; // AllocatedTo + + $descSanytized = Helper::sanityzeString($value['Description']); + // $descSanytized = str_replace(['โ€“','\u20131'], '-',$value['Description']); + $sQLInsertPrep630M['LLCMDESC'] = $descSanytized; // Description + + DB::connection(config('m3.connection', 'pgsql'))->table('ic630m')->insert($sQLInsertPrep630M); + } + + // Send Response + return response()->json([ + 'code' => '200', + 'status' => 'Success', + ]); + } else { + // Write to Logs Out : Error + $mACPKR = isset($mACPKR) ? $mACPKR : self::ZERO_PAD; + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'No URL Parameters Sent', 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => 'No URL Parameters Sent', + ]); + } + } catch (\Throwable $th) { + // Write to Logs Out : Error + $mACPKR = isset($mACPKR) ? $mACPKR : self::ZERO_PAD; + + $getCurlErrors = str_contains($th->getMessage(), 'cURL error'); + if ($getCurlErrors) { + // dd($getCurlErrors); + // Write to Logs Out : Failed + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Curl Error: Communication with M3 Timed Out' . ' M3-JSN-out' . $incomingParams, 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Curl Error: Communication with M3 Timed Out.', + ]); + } else { + // Set SHERROR To Z if Duplicate Key Detected $th + // Read The substring from SHDATA after M3-JSN-out + $sHERROR = 'X'; + $word = 'Duplicate key value specified'; + $position = strpos($th, $word); + + if ($position !== false) { + $sHERROR = 'Z'; + } + + $data = ['SHMACPKR' => $mACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => $sHERROR, 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'An Error Occured - ' . substr($th, 0, 300), 'SHUSER' => $sHUSER, 'SHSOURCE' => $sHSOURCE, 'SHCO' => $cO, 'SHWHS' => $wHS]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Catched Error: ' . $th, + ]); + } + } + } + // End M3InventoryReportReplen +} diff --git a/Modules/M3/Http/Controllers/API/TransferAPI.php b/Modules/M3/Http/Controllers/API/TransferAPI.php new file mode 100755 index 00000000..288ece6d --- /dev/null +++ b/Modules/M3/Http/Controllers/API/TransferAPI.php @@ -0,0 +1,698 @@ +all()) > 0 ? $request->all() : ''; + $dIVI = isset($urlParams['COMPANY']) ? $urlParams['COMPANY'] : ''; + $wHS = isset($urlParams['WHS']) ? $urlParams['WHS'] : ''; + + try { + if ($urlParams != '') { + $pART = isset($urlParams['PART']) ? $urlParams['PART'] : ''; + $lOCATIONFROM = isset($urlParams['LOCATIONFROM']) ? $urlParams['LOCATIONFROM'] : ''; + $lOCATIONTO = isset($urlParams['LOCATIONTO']) ? $urlParams['LOCATIONTO'] : ''; + $qUANTITY = isset($urlParams['QUANTITY']) ? $urlParams['QUANTITY'] : ''; + $oRDERCATEGORY = isset($urlParams['ORDERCATEGORY']) ? $urlParams['ORDERCATEGORY'] : ''; + $lOTNUMBER = isset($urlParams['LOTNUMBER']) ? $urlParams['LOTNUMBER'] : ''; + $cONUMBER = isset($urlParams['CONUMBER']) ? $urlParams['CONUMBER'] : ''; + $cOLINENO = isset($urlParams['COLINENO']) ? $urlParams['COLINENO'] : ''; + $dELIVERYNO = isset($urlParams['DELIVERYNO']) ? $urlParams['DELIVERYNO'] : self::ZERO_PAD; + $pICKLISTSUFFIX = isset($urlParams['PICKLISTSUFFIX']) ? $urlParams['PICKLISTSUFFIX'] : ''; + $eNDFLAG = isset($urlParams['ENDFLAG']) ? $urlParams['ENDFLAG'] : ''; + $tYPE = isset($urlParams['TYPE']) ? $urlParams['TYPE'] : ''; + $cOLINESUFFIX = isset($urlParams['COLINESUFFIX']) ? $urlParams['COLINESUFFIX'] : ''; + + // TYPE : + // DeliveryNote + // S15 + // CloseShipment + // COCharge + // Replenishment + // Move + + // ORDERCATEGORY : Order Category + // 1 = Material to manufacturing order + // 3 = Customer Order + // 4 = Requisition Order + // 5 = Distribution Order + // 9 = Move order + + $dELIVERYNO = isset($dELIVERYNO) ? $dELIVERYNO : self::ZERO_PAD; + + $tRANSTYPE = isset($urlParams['TRANSTYPE']) ? $urlParams['TRANSTYPE'] : ''; // R for Retry + $sHDT = isset($urlParams['SHDT']) ? $urlParams['SHDT'] : ''; + $sHTIME = isset($urlParams['SHTIME']) ? $urlParams['SHTIME'] : ''; + $sHTYPE = isset($urlParams['SHTYPE']) ? $urlParams['SHTYPE'] : ''; + + // Retry Transfer + if ($tRANSTYPE == 'R') { + // $t = strtotime($sHTIME); + // $SHTIMEHM = date('H:i',$t); + // dd($SHTIMEHM); + // Get the record that contain the payload + $iCM699MS = DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->select('SHDATA') + ->where('SHMACPKR', $dELIVERYNO) + ->where('SHDT', $sHDT) + ->where('SHTIME', $sHTIME) + // ->whereRaw("VARCHAR_FORMAT (TIMESTAMP (CURRENT DATE) + MIDNIGHT_SECONDS (SHTIME) SECONDS, 'HH24:MI') = ?", [$SHTIMEHM]) + ->where('SHCO', $dIVI) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', $sHTYPE) + ->first(); + + // Read The substring from SHDATA after M3-JSN-out + $word = 'M3-JSN-out'; + $sHDATA = isset($iCM699MS->SHDATA) ? $iCM699MS->SHDATA : ''; + $sHDATAJSON = ''; + $position = strpos($sHDATA, $word); + // Also Read CommTCP_read + $word2 = 'url:http://127.0.0.1:10005/api/TransferAPIURL?'; + $sHDATA2 = isset($iCM699MS->SHDATA) ? $iCM699MS->SHDATA : ''; + $position2 = strpos($sHDATA2, $word2); + + if ($position !== false) { + $sHDATAJSON = substr($sHDATA, $position + strlen($word)); + } elseif ($position2 !== false) { + $sHDATAJSONS = substr($sHDATA2, $position2 + strlen($word2)); + $sHDATAJSONA = []; + parse_str($sHDATAJSONS, $sHDATAJSONA); + $sHDATAJSON = json_encode($sHDATAJSONA); + } + // Find the position of the opening and closing curly braces + $startPos = strpos($sHDATAJSON, '{'); + $endPos = strrpos($sHDATAJSON, '}'); + // Extract the substring within the curly braces + $sHDATAJSON = substr($sHDATAJSON, $startPos, $endPos - $startPos + 1); + + $jSONTR = $sHDATAJSON != '' ? json_decode($sHDATAJSON) : ''; + + if ($jSONTR != '') { + $pART = isset($jSONTR->PART) ? $jSONTR->PART : ''; + $lOCATIONFROM = isset($jSONTR->LOCATIONFROM) ? $jSONTR->LOCATIONFROM : ''; + $lOCATIONTO = isset($jSONTR->LOCATIONTO) ? $jSONTR->LOCATIONTO : ''; + $qUANTITY = isset($jSONTR->QUANTITY) ? $jSONTR->QUANTITY : ''; + $oRDERCATEGORY = isset($jSONTR->ORDERCATEGORY) ? $jSONTR->ORDERCATEGORY : ''; + $lOTNUMBER = isset($jSONTR->LOTNUMBER) ? $jSONTR->LOTNUMBER : ''; + $cONUMBER = isset($jSONTR->CONUMBER) ? $jSONTR->CONUMBER : ''; + $cOLINENO = isset($jSONTR->COLINENO) ? $jSONTR->COLINENO : ''; + $dELIVERYNO = isset($jSONTR->DELIVERYNO) ? $jSONTR->DELIVERYNO : self::ZERO_PAD; + $pICKLISTSUFFIX = isset($jSONTR->PICKLISTSUFFIX) ? $jSONTR->PICKLISTSUFFIX : ''; + $eNDFLAG = isset($jSONTR->ENDFLAG) ? $jSONTR->ENDFLAG : ''; + $tYPE = isset($jSONTR->TYPE) ? $jSONTR->TYPE : ''; + $cOLINESUFFIX = isset($jSONTR->COLINESUFFIX) ? $jSONTR->COLINESUFFIX : ''; + } + + // Set SHERROR to Z in ICM699M + DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->where('SHMACPKR', $dELIVERYNO) + ->where('SHDT', $sHDT) + ->where('SHTIME', $sHTIME) + ->where('SHCO', $dIVI) + ->where('SHWHS', $wHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', $sHTYPE) + ->update(['SHERROR' => 'Z', 'SHACKUSER' => $sHUSER, 'SHACKDATE' => date('Y-m-d'), 'SHACKTIME' => date('H:i:s')]); + } + + // Part Exists : proceed + if ($pART != '') { + // Read from ICM688M2 + // Get Parts And Lots from ICM688M2 + $iCM688M2SLTMP = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m2') + ->select('A5BRADLN', 'A5PKSFX', 'A5PLANT', 'A5SENTPKR') + ->distinct() + ->where('A5CO', $dIVI) + ->where('A5WHS', $wHS) + ->where('A5MACPKR', $dELIVERYNO); + + // Get Pack Lines + if ($cOLINENO != '') { + $iCM688M2SLTMP->where('A5PKLN', $cOLINENO); + } + $iCM688M2SL = $iCM688M2SLTMP->first(); + + $a5BRADLINE = isset($iCM688M2SL->A5BRADLN) ? $iCM688M2SL->A5BRADLN : ''; + $cOLINESUFFIX = isset($iCM688M2SL->A5PKSFX) ? $iCM688M2SL->A5PKSFX : ''; // Case 551 : $cOLINESUFFIX + $a5PLANT = isset($iCM688M2SL->A5PLANT) ? $iCM688M2SL->A5PLANT : ''; + $a5SENTPKR = isset($iCM688M2SL->A5SENTPKR) ? $iCM688M2SL->A5SENTPKR : ''; + + $jSONIN = json_encode([ + 'DIVI' => $dIVI, + 'WHS' => $wHS, + 'PART' => $pART, + 'LOCATIONFROM' => $lOCATIONFROM, + 'LOCATIONTO' => $lOCATIONTO, + 'QUANTITY' => $qUANTITY, + 'ORDERCATEGORY' => $oRDERCATEGORY, + 'LOTNUMBER' => $lOTNUMBER, + 'CONUMBER' => $cONUMBER, + 'COLINENO' => $cOLINENO, + 'DELIVERYNO' => $dELIVERYNO, + 'PICKLISTSUFFIX' => $pICKLISTSUFFIX, + 'ENDFLAG' => $eNDFLAG, + 'TYPE' => $tYPE, + 'COLINESUFFIX' => $cOLINESUFFIX, + ], JSON_UNESCAPED_SLASHES); + + $jSON = json_encode([ + 'DIVI' => $dIVI, + 'WHS' => $wHS, + 'PART' => $pART, + 'LOCATIONFROM' => $lOCATIONFROM, + 'LOCATIONTO' => $lOCATIONTO, + 'QUANTITY' => $qUANTITY, + 'ORDERCATEGORY' => $oRDERCATEGORY, + 'LOTNUMBER' => $lOTNUMBER, + 'CONUMBER' => $cONUMBER, + 'COLINENO' => $a5BRADLINE, + 'DELIVERYNO' => $dELIVERYNO, + 'PICKLISTSUFFIX' => $pICKLISTSUFFIX, + 'ENDFLAG' => $eNDFLAG, + 'TYPE' => $tYPE, + 'COLINESUFFIX' => $cOLINESUFFIX, + ], JSON_UNESCAPED_SLASHES); + + // Write JSON Params to Logs Out + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Req-out', + 'SHDATA' => $jSON, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Get Token + $tokenResponse = Helper::checkReceiveTokenV2(); + $tokenData = $tokenResponse->getData(); + if ($tokenData->code == '200') { + $ionToken = isset($tokenData->token) ? $tokenData->token : ''; + } else { + $sHDATA = isset($tokenData->message) ? $tokenData->message : ''; + // Write to Logs : Error + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $sHDATA, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return $tokenResponse; + } + + // Call ionapi with Params + $endPointURL = env('ENDPOINTURL') . 'APIFLOWS/Sentinel/TransferAPI?ionapiRespStyle=sync'; + $token = $ionToken; + + $response = Http::withHeaders([ + 'accept' => self::JSON_CONTENT_TYPE, + 'Content-Type' => self::JSON_CONTENT_TYPE, + ]) + ->withToken($token) + ->withBody($jSON, self::JSON_CONTENT_TYPE) + ->timeout(Config::get('arrays.curlTimeOut')) + ->post($endPointURL); + $responseStatusCode = $response->getStatusCode(); + $m3SessionId = $response->hasHeader('x-transaction-id') ? '-sessionID:' . $response->header('x-transaction-id') : '-sessionID'; + $m3ResponseTimeTmp = $response->hasHeader('x-response-time') ? ltrim($response->header('x-response-time'), '-') : '0'; + $m3ResponseTimeTmp2 = floatval($m3ResponseTimeTmp) / 1000; + $dateTime = new DateTime; + $dateTime->setTimestamp($m3ResponseTimeTmp2); + $m3ResponseTime = $m3ResponseTimeTmp != '' ? '-M3ResponseTime:' . $dateTime->format('d/m/Y H:i:s.v') : '-M3ResponseTime'; + $transferStats = $response->transferStats; + $m3transferTime = $transferStats->getTransferTime() != null ? '-M3transferTime:' . $transferStats->getTransferTime() : '-M3transferTime'; + + if ($responseStatusCode == '200') { + $responseContents = json_decode($response->getBody()->getContents()); + $responseResult = $responseContents->result; + $m3JSONResponse = json_encode($responseContents); + // Check M3 Response for Errors + $m3Errors = Helper::checkM3Errors($responseResult); + } else { + $m3JSONResponse = ''; + $m3Errors = 'Error: No Response from M3'; + } + + if ($m3Errors == '') { + // Write to Logs Out : Success + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $responseStatusCode . 'TYPE :' . $tYPE . self::ORDER_CATEGORY_LABEL . $oRDERCATEGORY . '-' . $m3JSONResponse . $m3SessionId . $m3ResponseTime . $m3transferTime, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Log to ICM799M + DB::connection(config('m3.connection', 'pgsql'))->table('icm799m') + ->insert(['IMDIV' => $dIVI, + 'IMPLANT' => $a5PLANT, + 'IMWHS' => $wHS, + 'IMSENTPKR' => $a5SENTPKR, + 'IMDELNO' => $dELIVERYNO, + 'IMORDER' => $cONUMBER, + 'IMLINE' => $cOLINENO, + 'IMBRADLN' => $a5BRADLINE, + 'IMSUFFIX' => $pICKLISTSUFFIX, + 'IMPART' => $pART, + 'IMLOT' => $lOTNUMBER, + 'IMQTY' => $qUANTITY, + 'IMFRLOC' => $lOCATIONFROM, + 'IMTOLOC' => $lOCATIONTO, + 'IMDATE' => date('Ymd'), + 'IMTIME' => date('His'), + ]); + + return response()->json([ + 'code' => $responseStatusCode, + 'status' => 'Success', + ]); + } else { + // Write to Logs Out : Failed + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $responseStatusCode . '-' . $m3Errors . '-TYPE:' . $tYPE . self::ORDER_CATEGORY_LABEL . $oRDERCATEGORY . '-' . $m3JSONResponse . + 'M3-JSN-out' . $jSONIN . $m3SessionId . $m3ResponseTime . $m3transferTime, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '206', + 'status' => 'Error', + 'message' => $responseStatusCode . '-' . $m3Errors . '- TYPE :' . $tYPE . self::ORDER_CATEGORY_LABEL . $oRDERCATEGORY . '-' . $m3JSONResponse, + ]); + } + } + // Part Does not Exist : Failure + else { + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => 'Json Payload Not Valid, possible cause: Retry butto was clicked by another user.', + ]); + } + } else { + // Write to Logs Out : Error + $dELIVERYNO = isset($dELIVERYNO) ? $dELIVERYNO : self::ZERO_PAD; + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => self::NO_URL_PARAMETERS, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => self::NO_URL_PARAMETERS, + ]); + } + } catch (\Throwable $th) { + $getCurlErrors = str_contains($th->getMessage(), 'cURL error'); + if ($getCurlErrors) { + // Write to Logs Out : Failed + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Curl Error: Communication with M3 Timed Out' . ' M3-JSN-out' . $jSONIN, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Curl Error: Communication with M3 Timed Out.', + ]); + } else { + // Write to Logs Out : Error + $dELIVERYNO = isset($dELIVERYNO) ? $dELIVERYNO : self::ZERO_PAD; + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Err-out', + 'SHDATA' => 'An Error Occured - ' . substr($th, 0, 300), + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + Log::error($th); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Uncaught Error', + ]); + } + + } + } + // End TransferAPIURL + + // UpdateShipmentNumber : with URL PARAMS + public function UpdateShipmentNumber(Request $request) + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOut')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut')); + + // Get the Calling User + $sHUSER = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'; + // Set SHSOURCE + $sHSOURCE = 'UpdateShipmentNumber'; + $m3Errors = ''; + + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + $dIVI = isset($urlParams['COMPANY']) ? $urlParams['COMPANY'] : ''; + $wHS = isset($urlParams['WHS']) ? $urlParams['WHS'] : ''; + $pLANT = isset($urlParams['PLANT']) ? $urlParams['PLANT'] : ''; + + try { + if ($urlParams != '') { + $a4SPR15A01 = isset($urlParams['A4SPR15A01']) ? $urlParams['A4SPR15A01'] : ''; + $dELIVERYNO = isset($urlParams['DELIVERYNO']) ? $urlParams['DELIVERYNO'] : ''; + $tYPE = 'UpdateShipmentNumber'; + $allMacpkrs = []; + + if ($a4SPR15A01 != '') { + // Read from ICM688M1 + $iCM688M1SLTMP = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->select('A4MACPKR') + ->where('A4CO', $dIVI) + ->where('A4WHS', $wHS) + ->where('A4PLANT', $pLANT) + ->where('A4SPR15A01', $a4SPR15A01); + + // Get Macpikers also if sent as Parameter + if ($dELIVERYNO != '') { + $iCM688M1SLTMP->where('A4MACPKR', $dELIVERYNO); + } + $iCM688M1SL = $iCM688M1SLTMP->get(); + // Loop ICM688M1 to get all A4MACPKR + foreach ($iCM688M1SL as $ICM688M1) { + $allMacpkrs[] = $ICM688M1->A4MACPKR; + } + } + + // A4SPR15A01 Exists : proceed + if ($a4SPR15A01 != '' && ! empty($allMacpkrs)) { + $jSON = json_encode([ + 'DIVI' => $dIVI, + 'WHS' => $wHS, + 'ShipmentNumber' => [ + 'Number' => $a4SPR15A01, + 'DeliveryNumbers' => $allMacpkrs, + ], + 'TYPE' => $tYPE, + 'ENDFLAG' => '', + + ], JSON_UNESCAPED_SLASHES); + + // Write JSON Params to Logs Out + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Req-out', + 'SHDATA' => $jSON, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Get Token + $tokenResponse = Helper::checkReceiveTokenV2(); + $tokenData = $tokenResponse->getData(); + if ($tokenData->code == '200') { + $ionToken = isset($tokenData->token) ? $tokenData->token : ''; + } else { + $sHDATA = isset($tokenData->message) ? $tokenData->message : ''; + // Write to Logs : Error + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $sHDATA, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return $tokenResponse; + } + + // Call ionapi with Params + $endPointURL = env('ENDPOINTURL') . 'APIFLOWS/Sentinel/TransferAPI?ionapiRespStyle=sync'; + $token = $ionToken; + + $response = Http::withHeaders([ + 'accept' => self::JSON_CONTENT_TYPE, + 'Content-Type' => self::JSON_CONTENT_TYPE, + ]) + ->withToken($token) + ->withBody($jSON, self::JSON_CONTENT_TYPE) + ->timeout(Config::get('arrays.curlTimeOut')) + ->post($endPointURL); + $responseStatusCode = $response->getStatusCode(); + $m3SessionId = $response->hasHeader('x-transaction-id') ? '-sessionID:' . $response->header('x-transaction-id') : '-sessionID'; + $m3ResponseTimeTmp = $response->hasHeader('x-response-time') ? ltrim($response->header('x-response-time'), '-') : '0'; + $m3ResponseTimeTmp2 = floatval($m3ResponseTimeTmp) / 1000; + $dateTime = new DateTime; + $dateTime->setTimestamp($m3ResponseTimeTmp2); + $m3ResponseTime = $m3ResponseTimeTmp != '' ? '-M3ResponseTime:' . $dateTime->format('d/m/Y H:i:s.v') : '-M3ResponseTime'; + $transferStats = $response->transferStats; + $m3transferTime = $transferStats->getTransferTime() != null ? '-M3transferTime:' . $transferStats->getTransferTime() : '-M3transferTime'; + + if ($responseStatusCode == '200') { + $responseContents = json_decode($response->getBody()->getContents()); + $responseResult = $responseContents->result; + $m3JSONResponse = json_encode($responseContents); + // Check M3 Response for Errors + $m3Errors = Helper::checkM3Errors($responseResult); + } else { + $m3JSONResponse = ''; + $m3Errors = 'Error: No Response from M3'; + } + + if ($m3Errors == '') { + // Write to Logs Out : Success + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => '', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $responseStatusCode . 'TYPE :' . $tYPE . '-' . $m3JSONResponse . $m3SessionId . $m3ResponseTime . $m3transferTime, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => $responseStatusCode, + 'status' => 'Success', + ]); + } else { + // Write to Logs Out : Failed + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => $responseStatusCode . '-' . $m3Errors . '-TYPE:' . $tYPE . '-' . $m3JSONResponse . + 'M3-JSN-out' . $jSON . $m3SessionId . $m3ResponseTime . $m3transferTime, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '206', + 'status' => 'Error', + 'message' => $responseStatusCode . '-' . $m3Errors . '- TYPE :' . $tYPE . '-' . $m3JSONResponse, + ]); + } + } + // A4SPR15A01 Does not Exist : Failure + else { + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => 'Json Payload Not Valid, missing Parameter or no Macpicker # found.', + ]); + } + } else { + // Write to Logs Out : Error + $dELIVERYNO = isset($dELIVERYNO) ? $dELIVERYNO : self::ZERO_PAD; + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => self::NO_URL_PARAMETERS, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + // Return Error + return response()->json([ + 'code' => '405', + 'status' => 'Error', + 'message' => self::NO_URL_PARAMETERS, + ]); + } + } catch (\Throwable $th) { + $getCurlErrors = str_contains($th->getMessage(), 'cURL error'); + if ($getCurlErrors) { + // Write to Logs Out : Failed + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Res-out', + 'SHDATA' => 'Curl Error: Communication with M3 Timed Out' . ' M3-JSN-out' . $jSON, + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Curl Error: Communication with M3 Timed Out.', + ]); + } else { + // Write to Logs Out : Error + $dELIVERYNO = isset($dELIVERYNO) ? $dELIVERYNO : self::ZERO_PAD; + $data = ['SHMACPKR' => $dELIVERYNO, + 'SHDT' => date('Y-m-d'), + 'SHTIME' => date('H:i:s'), + 'SHERROR' => 'X', + 'SHINTBOX' => '', + 'SHTYPE' => 'M3-Err-out', + 'SHDATA' => 'An Error Occured - ' . substr($th, 0, 300), + 'SHUSER' => $sHUSER, + 'SHSOURCE' => $sHSOURCE, + 'SHCO' => $dIVI, + 'SHWHS' => $wHS, + ]; + Helper::logToICM699M($data); + Log::error($th); + + return response()->json([ + 'code' => '405', + 'status' => 'error', + 'message' => 'Uncaught Error', + ]); + } + + } + } + // End UpdateShipmentNumber + +} diff --git a/Modules/M3/Http/Controllers/API/TwoShipAPIs.php b/Modules/M3/Http/Controllers/API/TwoShipAPIs.php new file mode 100755 index 00000000..9ba3e194 --- /dev/null +++ b/Modules/M3/Http/Controllers/API/TwoShipAPIs.php @@ -0,0 +1,127 @@ +configureTimeouts(); + $user = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'; + $params = $request->all(); + $whs = (string) ($params['WHS'] ?? ''); + $co = (string) ($params['COMPANY'] ?? ''); + $macpkr = (string) ($params['MACPKR'] ?? ''); + + if ($params === []) { + $this->log($macpkr ?: '000000', $co, $whs, $user, 'X', 'No URL Parameters Sent'); + + return response()->json(['code' => '405', 'status' => 'Error', 'message' => 'No URL Parameters Sent']); + } + + try { + $this->logRequest($macpkr, $co, $whs, $user); + $orders = $this->aggregationOrders($macpkr, $co, $whs); + $response = $this->callTwoShip($orders); + $error = $this->responseError($response); + if ($error !== '') { + $this->log($macpkr, $co, $whs, $user, 'X', $response->status() . '-' . $error); + + return response()->json(['code' => '405', 'status' => 'error', 'message' => 'Status: ' . $response->status() . '-' . $error]); + } + + $this->log($macpkr, $co, $whs, $user, '', $response->body()); + $this->markAggregationComplete($orders, $co, $whs); + + return response()->json(['code' => '200', 'status' => 'Success']); + } catch (\Throwable $th) { + $message = str_contains($th->getMessage(), 'cURL error') + ? 'Curl Error: Communication with 2Ship Timed Out.' + : '2Ship communication failed.'; + $this->log($macpkr, $co, $whs, $user, 'X', $message); + + return response()->json(['code' => '405', 'status' => 'error', 'message' => $message]); + } + } + + private function configureTimeouts(): void + { + $timeout = Config::get('arrays.PHPTimeOut'); + ini_set('max_execution_time', $timeout); + ini_set('max_input_time', $timeout); + ini_set('default_socket_timeout', $timeout); + } + + private function logRequest(string $macpkr, string $co, string $whs, string $user): void + { + $data = json_encode(['CO' => $co, 'WHS' => $whs, 'MACPKR' => $macpkr]); + Helper::logToICM699M($this->logData($macpkr, $co, $whs, $user, '', (string) $data, 'AggStopReq')); + } + + private function aggregationOrders(string $macpkr, string $co, string $whs): array + { + $aggregation = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $macpkr)->value('A4SHPAGGCD'); + if (empty($aggregation) || (string) $aggregation === '0') { + return [$macpkr]; + } + $orders = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4SHPAGGCD', $aggregation)->where('A4SHPAGGCD', '<>', 0)->where('A4CONCMPLT', '<>', 'y') + ->where('A4CO', $co)->where('A4WHS', $whs)->pluck('A4MACPKR')->all(); + + return $orders !== [] ? $orders : [$macpkr]; + } + + private function callTwoShip(array $orders): HttpResponse + { + $payload = [ + 'WS_Key' => Config::get('arrays.2Ship.TwoShip_Key'), + 'OrderNumbers' => [implode(',', $orders)], + 'FindBy' => 'ByMultipleOrderNumbers', + 'DataToBeUpdated' => ['UpdateAggregationSettings' => true, 'OrderAggregationSettingsInfo' => ['NotConsideredAggregation' => true]], + ]; + + return Http::acceptJson()->asJson()->timeout((int) Config::get('arrays.PHPTimeOut')) + ->post(Config::get('arrays.2Ship.end_point') . Config::get('arrays.2Ship.hold_update'), $payload); + } + + private function responseError(HttpResponse $response): string + { + if (! $response->successful()) { + return 'Error: No Response from 2Ship'; + } + $body = $response->json(); + + return ($body['Success'] ?? true) === false ? '2Ship Error: ' . ($body['GlobalError'] ?? 'Unknown error') : ''; + } + + private function markAggregationComplete(array $orders, string $co, string $whs): void + { + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->whereIn('A4MACPKR', $orders)->where('A4CO', $co)->where('A4WHS', $whs)->update(['A4CONCMPLT' => 'Y']); + } + + private function log(string $macpkr, string $co, string $whs, string $user, string $error, string $message): void + { + Helper::logToICM699M($this->logData($macpkr, $co, $whs, $user, $error, $message, self::RESPONSE_TYPE)); + } + + private function logData(string $macpkr, string $co, string $whs, string $user, string $error, string $message, string $type): array + { + return ['SHMACPKR' => $macpkr, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => $error, + 'SHINTBOX' => '', 'SHTYPE' => $type, 'SHDATA' => $message, 'SHUSER' => $user, 'SHSOURCE' => self::SOURCE, 'SHCO' => $co, 'SHWHS' => $whs]; + } +} diff --git a/Modules/M3/Http/Controllers/AuthController.php b/Modules/M3/Http/Controllers/AuthController.php new file mode 100755 index 00000000..96fc70de --- /dev/null +++ b/Modules/M3/Http/Controllers/AuthController.php @@ -0,0 +1,13 @@ +R659PALT ?? abort(404, 'Manifest Not Found'); + + $userWhsCoPlant = self::getUserWhsCoPlant(); + + $boxes = DB::connection(config('m3.connection', 'pgsql'))->table(self::PALLET_TABLE_ALIAS) + ->select( + 'p.R659PALT', + 'p.R659BOX', + 'p.R659LOADED', + 'p.R659USER', + 'p.R659DATE', + 'p.R659TIME', + 'c.AYMACPKR', + 'c.AYSPR15A01', + 'cv.A4APR8N001', + 'cv.A4SHSHCT', + self::CONVEYOR_SELECT, + ) + ->leftJoin(self::CARTON_TABLE_ALIAS, 'p.R659BOX', '=', 'c.AYINTBOX') + ->leftJoin(self::CONVEYOR_VALUE_ALIAS, 'c.AYMACPKR', '=', 'cv.A4MACPKR') + ->leftJoin(self::CONVEYOR_TABLE_ALIAS, 'cv.A4APR8N001', '=', 'cnv.R652SEQ') + ->where('p.R659PALT', $r659PALT) + ->where('p.R659CO', trim($userWhsCoPlant['USERCO'])) + ->where('p.R659WHS', trim($userWhsCoPlant['USERWHS'])) + ->where('p.R659PLANT', trim($userWhsCoPlant['USERPL'])) + ->orderBy('p.R659DATE', 'desc') + ->orderBy('p.R659TIME', 'desc') + ->distinct() + ->get() + ->unique('R659BOX') + ->values(); + + if ($request->ajax()) { + return response()->json([ + 'success' => true, + 'data' => $boxes, + ]); + } + + $palletHeader = $boxes->first(); + + return view('m3::liberty-theme.pages.BoxPackToPalletScan', ['boxes' => $boxes, 'palletHeader' => $palletHeader, 'R659PALT' => $r659PALT]); + } + + // Scan Boxes + public static function scanBoxes(Request $request) + { + $pallet = $request->R659PALT ?? abort(400, 'Pallet Not Found'); + $box = trim((string) ($request->R659BOX ?? '')); + abort_if($box === '', 400, 'Box Not Found'); + + $user = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'; + $profile = self::getUserWhsCoPlant(); + $validation = self::validateScannedBox($pallet, $box, $profile); + + if ($validation !== '') { + return response()->json(['success' => false, 'message' => $validation], 409); + } + + self::insertScannedBox($pallet, $box, $user, $profile); + + return response()->json([ + 'success' => true, + 'message' => "• Box {$box} added to Pallet {$pallet}.", + 'data' => self::boxesForPallet($pallet, $profile), + ]); + } + + private static function validateScannedBox($pallet, string $box, array $profile): string + { + $messages = []; + $existing = self::findExistingBox($pallet, $box, $profile); + if ($existing) { + $messages[] = "• Box {$box} is already assigned to Pallet {$existing->R659PALT}."; + } + + $boxRecord = self::findCarton($box, $profile); + if (! isset($boxRecord->AYINTBOX)) { + $messages[] = "• Box {$box} does not exist in ICM695M1 or it belongs to another Company."; + } elseif (($boxRecord->AYTYPE ?? '') !== 'BX') { + $messages[] = "• Scanned barcode {$box} is not a Box."; + } elseif (! $existing) { + $messages = array_merge($messages, self::palletCompatibilityMessages($pallet, $box, $boxRecord, $profile)); + } + + return implode('
    ', $messages); + } + + private static function findExistingBox($pallet, string $box, array $profile): ?object + { + return DB::connection(config('m3.connection', 'pgsql'))->table('icm659m') + ->select('R659PALT')->where('R659PALT', $pallet)->where('R659BOX', $box) + ->where('R659CO', trim($profile['USERCO']))->where('R659WHS', trim($profile['USERWHS'])) + ->where('R659PLANT', trim($profile['USERPL']))->first(); + } + + private static function findCarton(string $box, array $profile): ?object + { + return DB::connection(config('m3.connection', 'pgsql'))->table(self::CARTON_TABLE_ALIAS) + ->select('c.AYINTBOX', 'c.AYSPR15A01', 'c.AYTYPE', 'c.AYMACPKR', 'cv.A4APR8N001', self::CONVEYOR_SELECT) + ->leftJoin(self::CONVEYOR_VALUE_ALIAS, 'c.AYMACPKR', '=', 'cv.A4MACPKR') + ->leftJoin(self::CONVEYOR_TABLE_ALIAS, 'cv.A4APR8N001', '=', 'cnv.R652SEQ') + ->where('c.AYINTBOX', $box)->where('c.AYCO', trim($profile['USERCO'])) + ->where('c.AYWHS', trim($profile['USERWHS']))->where('c.AYPLANT', trim($profile['USERPL']))->first(); + } + + private static function palletCompatibilityMessages($pallet, string $box, object $incoming, array $profile): array + { + $first = DB::connection(config('m3.connection', 'pgsql'))->table(self::PALLET_TABLE_ALIAS) + ->select('c.AYSPR15A01', self::CONVEYOR_SELECT) + ->leftJoin(self::CARTON_TABLE_ALIAS, 'p.R659BOX', '=', 'c.AYINTBOX') + ->leftJoin(self::CONVEYOR_VALUE_ALIAS, 'c.AYMACPKR', '=', 'cv.A4MACPKR') + ->leftJoin(self::CONVEYOR_TABLE_ALIAS, 'cv.A4APR8N001', '=', 'cnv.R652SEQ') + ->where('p.R659PALT', $pallet)->where('p.R659CO', trim($profile['USERCO'])) + ->where('p.R659WHS', trim($profile['USERWHS']))->where('p.R659PLANT', trim($profile['USERPL']))->first(); + + if (! $first) { + return []; + } + + $messages = []; + $incomingCarrier = trim($incoming->AYSPR15A01 ?? ''); + $incomingConveyor = trim($incoming->CONVEYOR_NAME ?? ''); + $palletCarrier = trim($first->AYSPR15A01 ?? ''); + $palletConveyor = trim($first->CONVEYOR_NAME ?? ''); + if ($incomingCarrier !== $palletCarrier) { + $messages[] = "• Box {$box} has a different Carrier ({$incomingCarrier}) than the boxes already on Pallet {$pallet} ({$palletCarrier})."; + } + if ($incomingConveyor !== $palletConveyor) { + $messages[] = "• Box {$box} has a different Conveyor ({$incomingConveyor}) than the boxes already on Pallet {$pallet} ({$palletConveyor})."; + } + + return $messages; + } + + private static function insertScannedBox($pallet, string $box, string $user, array $profile): void + { + DB::connection(config('m3.connection', 'pgsql'))->table('icm659m')->insert([ + 'R659PALT' => $pallet, 'R659BOX' => $box, 'R659LOADED' => '', 'R659USER' => $user, + 'R659DATE' => date('Y-m-d'), 'R659TIME' => date('H:i:s'), 'R659CO' => trim($profile['USERCO']), + 'R659WHS' => trim($profile['USERWHS']), 'R659PLANT' => trim($profile['USERPL']), + ]); + } + + private static function boxesForPallet($pallet, array $profile) + { + return DB::connection(config('m3.connection', 'pgsql'))->table(self::PALLET_TABLE_ALIAS) + ->select( + 'p.R659PALT', + 'p.R659BOX', + 'p.R659LOADED', + 'p.R659USER', + 'p.R659DATE', + 'p.R659TIME', + 'c.AYMACPKR', + 'c.AYSPR15A01', + 'cv.A4APR8N001', + 'cv.A4SHSHCT', + self::CONVEYOR_SELECT, + ) + ->leftJoin(self::CARTON_TABLE_ALIAS, 'p.R659BOX', '=', 'c.AYINTBOX') + ->leftJoin(self::CONVEYOR_VALUE_ALIAS, 'c.AYMACPKR', '=', 'cv.A4MACPKR') + ->leftJoin(self::CONVEYOR_TABLE_ALIAS, 'cv.A4APR8N001', '=', 'cnv.R652SEQ') + ->where('p.R659PALT', $pallet)->where('p.R659CO', trim($profile['USERCO'])) + ->where('p.R659WHS', trim($profile['USERWHS']))->where('p.R659PLANT', trim($profile['USERPL'])) + ->orderBy('p.R659DATE', 'desc')->orderBy('p.R659TIME', 'desc')->distinct()->get()->unique('R659BOX')->values(); + } + + // Delete Box + public static function deleteBox(Request $request) + { + $r659PALT = $request->R659PALT ?? abort(400, 'Pallet Not Found'); + $r659BOX = trim($request->R659BOX) ?? abort(400, 'Box Not Found'); + + $userWhsCoPlant = self::getUserWhsCoPlant(); + + // Guard: only allow delete if R659LOADED is empty + $record = DB::connection(config('m3.connection', 'pgsql')) + ->table('icm659m') + ->where('R659PALT', $r659PALT) + ->where('R659BOX', $r659BOX) + ->first(); + + if (! $record) { + return response()->json([ + 'success' => false, + 'message' => "Box {$r659BOX} not found on Pallet {$r659PALT}.", + ], 404); + } + + if (! empty(trim($record->R659LOADED))) { + return response()->json([ + 'success' => false, + 'message' => "Box {$r659BOX} is already loaded and cannot be removed.", + ], 403); + } + + DB::connection(config('m3.connection', 'pgsql')) + ->table('icm659m') + ->where('R659PALT', $r659PALT) + ->where('R659BOX', $r659BOX) + ->delete(); + + // Return refreshed list + $boxes = DB::connection(config('m3.connection', 'pgsql'))->table(self::PALLET_TABLE_ALIAS) + ->select( + 'p.R659PALT', + 'p.R659BOX', + 'p.R659LOADED', + 'p.R659USER', + 'p.R659DATE', + 'p.R659TIME', + 'c.AYMACPKR', + 'c.AYSPR15A01', + 'cv.A4APR8N001', + 'cv.A4SHSHCT', + self::CONVEYOR_SELECT, + ) + ->leftJoin(self::CARTON_TABLE_ALIAS, 'p.R659BOX', '=', 'c.AYINTBOX') + ->leftJoin(self::CONVEYOR_VALUE_ALIAS, 'c.AYMACPKR', '=', 'cv.A4MACPKR') + ->leftJoin(self::CONVEYOR_TABLE_ALIAS, 'cv.A4APR8N001', '=', 'cnv.R652SEQ') + ->where('p.R659PALT', $r659PALT) + ->where('p.R659CO', trim($userWhsCoPlant['USERCO'])) + ->where('p.R659WHS', trim($userWhsCoPlant['USERWHS'])) + ->where('p.R659PLANT', trim($userWhsCoPlant['USERPL'])) + ->orderBy('p.R659DATE', 'desc') + ->orderBy('p.R659TIME', 'desc') + ->distinct() + ->get() + ->unique('R659BOX') + ->values(); + + return response()->json([ + 'success' => true, + 'message' => "Box {$r659BOX} removed from Pallet {$r659PALT}.", + 'data' => $boxes, + ]); + } + + // Get Logged User CO/WHS/PLANT + public static function getUserWhsCoPlant() + { + $sHUSER = m3_user() !== '' ? Str::upper(trim(m3_user())) : ''; + // Get users from ICM428M + $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH', 'R428PL') + ->where('R428US', '=', $sHUSER) + ->first(); + + $r428US = isset($iCM428M->R428US) ? $iCM428M->R428US : ''; + $uSERCO = isset($iCM428M->R428CO) ? $iCM428M->R428CO : ''; + $uSERWH = isset($iCM428M->R428WH) ? $iCM428M->R428WH : ''; + $r428PL = isset($iCM428M->R428PL) ? $iCM428M->R428PL : ''; + + return [ + 'R428US' => $r428US, + 'USERCO' => $uSERCO, + 'USERWHS' => $uSERWH, + 'USERPL' => $r428PL, + ]; + } +} diff --git a/Modules/M3/Http/Controllers/CarrierMaintController.php b/Modules/M3/Http/Controllers/CarrierMaintController.php new file mode 100755 index 00000000..6ac4972b --- /dev/null +++ b/Modules/M3/Http/Controllers/CarrierMaintController.php @@ -0,0 +1,102 @@ +hasTable('icm160m')) { + $iCM160M = DB::connection(config('m3.connection', 'pgsql'))->select(' + select canum, canam, substr(CATPID,1,3) as TwoshipCarrierCode, substr(CATPID,4,1) as ParcelCarrierCode, caspr10A01, caspr1A01 + from icm160m WHERE CACO=?', [$userCO]); + } + if ($schema->hasTable('icm428m')) { + $power_user = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428PWRUSR', 'R428CO', 'R428PL', 'R428WH') + ->where('R428US', strtoupper(m3_user()))->get()->all(); + } + + return view('m3::liberty-theme.pages.carrierMaint', ['ICM160M' => $iCM160M, 'power_user' => $power_user]); + + } + + // Process data from Add modal + public static function savecarrierAdd(Request $request) + { + $currentUser = Helper::getUserCOWHSPLT(); + $userCO = $currentUser['UserCO'] ?? ''; + + // Insert record to ICM160M + // Verify record does not already exist in ICM160M + if ($request->CANUM == null) { + return 'null'; + } + $icm160m = DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT1 from ICM160M where CANUM='$request->CANUM' AND CACO='$userCO'"); + if ($icm160m[0]->COUNT1 == '1') { + return 'exists'; + } else { + $cASPR10A01 = isset($request->CASPR10A01) && $request->CASPR10A01 != null ? $request->CASPR10A01 : ' '; + $cASPR1A01 = isset($request->CASPR1A01) && $request->CASPR1A01 != null ? $request->CASPR1A01 : ' '; + + $data = ['CANUM' => $request->CANUM, 'CANAM' => $request->CANAM, + 'CATPID' => str_pad(substr($request->TWOSHIPCARRIERCODE, 0, 3), 3, ' ') . substr($request->PARCELCARRIERCODE, 0, 1), + 'CASPR10A01' => $cASPR10A01, 'CASPR1A01' => $cASPR1A01, 'CACO' => $userCO]; // ,'CAPLNT'=>$UserPL,'CAWHS'=>$UserWHS + $insertSQL = DB::connection(config('m3.connection', 'pgsql'))->table('icm160m')->insert($data); + if ($insertSQL) { + return 'success'; + } + } + } + + public static function savecarrierAdd2(Request $request) + { + $currentUser = Helper::getUserCOWHSPLT(); + $userCO = $currentUser['UserCO'] ?? ''; + + // Insert record to ICM160M + if ($request->CANUM == null) { + return 'null'; + } + + $cASPR10A01 = isset($request->CASPR10A01) && $request->CASPR10A01 != null ? $request->CASPR10A01 : ' '; + $cASPR1A01 = isset($request->CASPR1A01) && $request->CASPR1A01 != null ? $request->CASPR1A01 : ' '; + + $data = ['CANUM' => $request->CANUM, 'CANAM' => $request->CANAM, 'CATPID' => str_pad(substr($request->TWOSHIPCARRIERCODE, 0, 3), 3, ' ') . substr($request->PARCELCARRIERCODE, 0, 1), + 'CASPR10A01' => $cASPR10A01, 'CASPR1A01' => $cASPR1A01, 'CACO' => $userCO]; // ,'CAPLNT'=>$UserPL,'CAWHS'=>$UserWHS + $insertSQL = DB::connection(config('m3.connection', 'pgsql'))->table('icm160m')->insert($data); + if ($insertSQL) { + return 'success'; + } + + } + + // Process data from Edit modal + public static function savecarrierEdit(Request $request) + { + $currentUser = Helper::getUserCOWHSPLT(); + $userCO = $currentUser['UserCO'] ?? ''; + + if ($request->CANUM == null) { + return 'null'; + } + DB::connection(config('m3.connection', 'pgsql'))->update("update ICM160M + set CANAM='$request->CANAM', CATPID='" . str_pad(substr($request->TWOSHIPCARRIERCODE, 0, 3), 3, ' ') . substr($request->PARCELCARRIERCODE, 0, 1) . "', + CASPR10A01='$request->CASPR10A01', CASPR1A01='$request->CASPR1A01' + where CANUM='$request->CANUM' AND CACO='$userCO'"); + + return 'success'; + + } +} diff --git a/Modules/M3/Http/Controllers/Controller.php b/Modules/M3/Http/Controllers/Controller.php new file mode 100755 index 00000000..3abac69b --- /dev/null +++ b/Modules/M3/Http/Controllers/Controller.php @@ -0,0 +1,13 @@ +ajax()) { + $wHDDA = isset($request->WHDDA) ? $request->WHDDA : []; + $wHArr = []; + foreach ($wHDDA as $WHDDAV) { + $cO = substr($WHDDAV, 0, 3); + $wHArr[] = substr($WHDDAV, 6, 3); + } + + $reportPeriod = isset($request->reportPeriod) ? $request->reportPeriod : ''; // monthly , quarter , year , daily + // Current + $checkSales = isset($request->checkSales) ? $request->checkSales : ''; // on + $checkWeight = isset($request->checkWeight) ? $request->checkWeight : ''; // on + $checkLines = isset($request->checkLines) ? $request->checkLines : ''; // on + + if (! empty($wHArr) && $cO != '' && $reportPeriod != '') { + switch ($reportPeriod) { + case 'year': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify('first day of January')->format('Ymd'); + + $lastDay = isset($request->TOREPORTDATE) ? \DateTime::createFromFormat('Y-m', trim($request->TOREPORTDATE)) : ''; + $toreportDate = $lastDay->modify('last day of December')->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . "' and a5whs in(" . implode(',', $wHArr) . ') + ) + select substr(ayapr8N002,1,4) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed,sum(a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars,a5whs as whs from tempfile + group by substr(ayapr8N002,1,4),a5whs order by 1 '; + break; + + case 'quarter': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify('first day of January')->format('Ymd'); + + $lastDay = isset($request->TOREPORTDATE) ? \DateTime::createFromFormat('Y-m', trim($request->TOREPORTDATE)) : ''; + $toreportDate = $lastDay->modify('last day of December')->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ") + ) + select substr(ayapr8N002,3,2) ||'-' || 'Q' || EXTRACT(QUARTER FROM TO_DATE(CAST(ayapr8n002 AS TEXT),'YYYYMMDD')) as years,count(*) as lines, + sum(a5rsvqty) as reserveqty, sum(a5packed) as packed,sum (a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,3,2) ||'-' || 'Q' || EXTRACT(QUARTER FROM TO_DATE(CAST(ayapr8n002 AS TEXT),'YYYYMMDD')),a5whs order by 1 "; + break; + + case 'monthly': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify('first day of this month')->format('Ymd'); + + $lastDay = isset($request->TOREPORTDATE) ? \DateTime::createFromFormat('Y-m', trim($request->TOREPORTDATE)) : ''; + $toreportDate = $lastDay->modify('last day of this month')->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ") + ) + select substr(ayapr8N002,1,4) || '-' || substr(ayapr8N002,5,2) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed, + sum(a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,1,4) || '-' || substr(ayapr8N002,5,2),a5whs order by 1 "; + break; + + case 'custom': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify('first day of this month')->format('Ymd'); + + $toreportDate = $firstDay->modify('last day of this month')->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ') + ) + select substr(ayapr8N002,7,2) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed, + sum(a5lnwght*a5packed/a5rsvqty) as weight, sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,7,2),a5whs order by 1 '; + break; + + default: + $selectContent = ''; + break; + } + + $execSummaryRes = DB::connection(config('m3.connection', 'pgsql'))->select($selectContent); + } else { + $execSummaryRes = collect(); + } + + return response()->json(['success' => true, 'reportPeriod' => $reportPeriod, 'result' => $execSummaryRes, 'checkSales' => $checkSales, + 'checkWeight' => $checkWeight, 'checkLines' => $checkLines]); + } + + // Init Page + $sHUSER = m3_user() !== '' ? Str::upper(trim(m3_user())) : ''; + if ($sHUSER != '') { + // Get User CO & WH from Table ICM428M + $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH', 'R428PL') + ->where('R428US', '=', $sHUSER) + ->first(); + + $cOMPANY = isset($iCM428M->R428CO) ? $iCM428M->R428CO : '110'; // Company + $pLANT = isset($iCM428M->R428PL) ? $iCM428M->R428PL : '144'; // Plant + $wHS = isset($iCM428M->R428WH) ? $iCM428M->R428WH : '322'; // WareHouse + } + $wHDDA = $cOMPANY . $pLANT . $wHS; + // dump($wHDDA); + // Warehouse Table + $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m')->get(); + } catch (\Throwable $th) { + Log::error($th); + } + + return view('m3::liberty-theme.pages.execSummary', ['IC670M' => $iC670M, 'WHDDA' => $wHDDA]); + // ,'ICM688M2',,'COMPANY','PLANT','WHS','reportDate' + } +} diff --git a/Modules/M3/Http/Controllers/ExecSummaryLineController.php b/Modules/M3/Http/Controllers/ExecSummaryLineController.php new file mode 100755 index 00000000..322ebfd5 --- /dev/null +++ b/Modules/M3/Http/Controllers/ExecSummaryLineController.php @@ -0,0 +1,204 @@ +ajax()) { + $wHDDA = isset($request->WHDDA) ? $request->WHDDA : []; + $wHArr = []; + foreach ($wHDDA as $WHDDAV) { + $cO = substr($WHDDAV, 0, 3); + $wHArr[] = substr($WHDDAV, 6, 3); + } + + $reportPeriod = isset($request->reportPeriod) ? $request->reportPeriod : ''; // monthly , quarter , year , daily + // Current + $checkSales = isset($request->checkSales) ? $request->checkSales : ''; // on + $checkWeight = isset($request->checkWeight) ? $request->checkWeight : ''; // on + $checkLines = isset($request->checkLines) ? $request->checkLines : ''; // on + + if (! empty($wHArr) && $cO != '' && $reportPeriod != '') { + switch ($reportPeriod) { + case 'year': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify('first day of January')->format('Ymd'); + + $lastDay = isset($request->TOREPORTDATE) ? \DateTime::createFromFormat('Y-m', trim($request->TOREPORTDATE)) : ''; + $toreportDate = $lastDay->modify('last day of December')->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . "' and a5whs in(" . implode(',', $wHArr) . ') + ) + select substr(ayapr8N002,1,4) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed,sum(a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars,a5whs as whs from tempfile + group by substr(ayapr8N002,1,4),a5whs order by 1 '; + + $execSummaryResLY = []; + break; + + case 'quarter': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify('first day of January')->format('Ymd'); + + $lastDay = isset($request->TOREPORTDATE) ? \DateTime::createFromFormat('Y-m', trim($request->TOREPORTDATE)) : ''; + $toreportDate = $lastDay->modify('last day of December')->format('Ymd'); + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ") + ) + select 'Q' || EXTRACT(QUARTER FROM TO_DATE(CAST(ayapr8n002 AS TEXT),'YYYYMMDD')) ||'-' || substr(ayapr8N002,3,2) as years,count(*) as lines, + sum(a5rsvqty) as reserveqty, sum(a5packed) as packed,sum (a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars, a5whs as whs + from tempfile + group by 'Q' || EXTRACT(QUARTER FROM TO_DATE(CAST(ayapr8n002 AS TEXT),'YYYYMMDD')) ||'-' || substr(ayapr8N002,3,2),a5whs order by 1 "; + + $execSummaryResLY = []; + + break; + + case 'monthly': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : null; + + $lastDay = (clone $firstDay); + $reportDate = $firstDay->modify('-11 months')->modify(self::FIRST_DAY_THIS_MONTH)->format('Ymd'); // + $toreportDate = $lastDay ? $lastDay->modify(self::LAST_DAY_THIS_MONTH)->format('Ymd') : ''; + // Last Year Dates + // Same period, but for Last Year (LY) + $reportDateLY = (clone $firstDay)->modify(self::ONE_YEAR_AGO)->modify(self::FIRST_DAY_THIS_MONTH)->format('Ymd'); + $toreportDateLY = (clone $lastDay)->modify(self::ONE_YEAR_AGO)->modify(self::LAST_DAY_THIS_MONTH)->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ") + ) + select substr(ayapr8N002,1,4) || '-' || substr(ayapr8N002,5,2) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed, + sum(a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,1,4) || '-' || substr(ayapr8N002,5,2),a5whs order by 1 "; + + $selectContentLY = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDateLY and ayapr8N002<=$toreportDateLY ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ") + ) + select substr(ayapr8N002,1,4) || '-' || substr(ayapr8N002,5,2) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed, + sum(a5lnwght*a5packed/a5rsvqty) as weight,sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,1,4) || '-' || substr(ayapr8N002,5,2),a5whs order by 1 "; + + $execSummaryResLY = DB::connection(config('m3.connection', 'pgsql'))->select($selectContentLY); + + break; + + case 'custom': + // Set Dates based on reportPeriod type + $firstDay = isset($request->REPORTDATE) ? \DateTime::createFromFormat('Y-m', $request->REPORTDATE) : ''; + $reportDate = $firstDay->modify(self::FIRST_DAY_THIS_MONTH)->format('Ymd'); + $toreportDate = $firstDay->modify(self::LAST_DAY_THIS_MONTH)->format('Ymd'); + + // Last Year Dates + $reportDateLY = (clone $firstDay)->modify(self::ONE_YEAR_AGO)->modify(self::FIRST_DAY_THIS_MONTH)->format('Ymd'); + $toreportDateLY = (clone $firstDay)->modify(self::ONE_YEAR_AGO)->modify(self::LAST_DAY_THIS_MONTH)->format('Ymd'); + + // Build SQL + $selectContent = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDate and ayapr8N002<=$toreportDate ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ') + ) + select substr(ayapr8N002,7,2) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed, + sum(a5lnwght*a5packed/a5rsvqty) as weight, sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,7,2),a5whs order by 1 '; + + $selectContentLY = "with tempfile as ( + select a5rsvqty,a5packed,a5slunpr*a5packed as dollars,a5lnwght,a5whs, + (select max(ayapr8N002) as ayapr8N002 from icm695m1 where a5macpkr=aymacpkr fetch first 1 rows only) + from icm688m2 where a5macpkr in ( + select distinct aymacpkr from icm695m1 where (AYSTATUS in ('Z','z') and ayapr8N002>=$reportDateLY and ayapr8N002<=$toreportDateLY ) + ) and a5co='" . $cO . self::WAREHOUSE_IN_CLAUSE . implode(',', $wHArr) . ') + ) + select substr(ayapr8N002,7,2) as years,count(*) as lines,sum(a5rsvqty) as reserveqty,sum(a5packed) as packed, + sum(a5lnwght*a5packed/a5rsvqty) as weight, sum(dollars) as dollars, a5whs as whs + from tempfile + group by substr(ayapr8N002,7,2),a5whs order by 1 '; + + $execSummaryResLY = DB::connection(config('m3.connection', 'pgsql'))->select($selectContentLY); + break; + + default: + $selectContent = ''; + break; + } + + $execSummaryRes = DB::connection(config('m3.connection', 'pgsql'))->select($selectContent); + } else { + $execSummaryRes = collect(); + $execSummaryResLY = collect(); + } + + return response()->json(['success' => true, 'reportPeriod' => $reportPeriod, 'result' => $execSummaryRes, 'resultLY' => $execSummaryResLY, + 'checkSales' => $checkSales, 'checkWeight' => $checkWeight, 'checkLines' => $checkLines]); + } + + // Init Page + $sHUSER = m3_user() !== '' ? Str::upper(trim(m3_user())) : ''; + if ($sHUSER != '') { + // Get User CO & WH from Table ICM428M + $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH', 'R428PL') + ->where('R428US', '=', $sHUSER) + ->first(); + + $cOMPANY = isset($iCM428M->R428CO) ? $iCM428M->R428CO : '110'; // Company + $pLANT = isset($iCM428M->R428PL) ? $iCM428M->R428PL : '144'; // Plant + $wHS = isset($iCM428M->R428WH) ? $iCM428M->R428WH : '322'; // WareHouse + } + $wHDDA = $cOMPANY . $pLANT . $wHS; + // dump($wHDDA); + // Warehouse Table + $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m')->get(); + } catch (\Throwable $th) { + Log::error($th); + } + + return view('m3::liberty-theme.pages.execSummaryLine', ['IC670M' => $iC670M, 'WHDDA' => $wHDDA]); + // ,'ICM688M2',,'COMPANY','PLANT','WHS','reportDate' + } +} diff --git a/Modules/M3/Http/Controllers/FillBOL2Controller.php b/Modules/M3/Http/Controllers/FillBOL2Controller.php new file mode 100755 index 00000000..6a9ba0ef --- /dev/null +++ b/Modules/M3/Http/Controllers/FillBOL2Controller.php @@ -0,0 +1,226 @@ +bolService = $bolService; + } + + public static function index(Request $request) + { + + return view('m3::liberty-theme.pages.fillBOL2'); + + } + + public function fillBOL(Request $request) + { + + // # $bOL = BOL::findOrFail($request); + $bOL = $request; + + $data = [ + 'bol_number' => $request->input('BOL_number') ?? '1234567890', + 'shipper_no' => $request->input('shipper_no') ?? '1234567890', + 'date' => now()->format('m/d/Y') ?? '01/01/2000', + 'master_bill_no' => 'X', + 'master_bill_yes' => $request->input('master_bill_yes') ? 'X' : '', + 'master_bill_drops' => $request->input('master_bill_drops') ?? '', + 'consignor_name' => $request->input('consignor_name') ?? 'ERICO INTERNATIONAL CORP', + 'consignor_address1' => $request->input('consignor_address1') ?? '6800 ARNOLD MILLER PARKWAY', + 'consignor_address2' => $request->input('consignor_address2') ?? 'SOLON, OH 44139', + 'consignor_address3' => $request->input('consignor_address3') ?? 'USA', + 'consignee_name' => $request->input('consignee_name') ?? 'ERICO EUROPE BV', + 'consignee_address1' => $request->input('consignee_address1') ?? 'JULES VERNEWEG 75', + 'consignee_address2' => $request->input('consignee_address2') ?? '', + 'consignee_address3' => $request->input('consignee_address3') ?? 'TILBURG . 5015 BG', + 'freight_collect' => 'X', + 'carrier_name' => $request->input('carrier_name') ?? 'ICL / Expeditors', + + 'pieces' => $request->input('pieces') ?? '20', + 'line_class' => $request->input('line_class') ?? '50', + 'line_weight' => $request->input('line_weight') ?? '8320', + + 'total_pieces' => $request->input('total_pieces') ?? '20', + 'total_line_weight' => $request->input('total_line_weight') ?? '8320', + 'description' => $request->input('description') ?? 'Package Description sfdfsdfasdfas dfasdfasdfcasdfvasfa clsdalcdfl +Line 2 +Line 3 +Line 4 +Line 5', + + 'DTESHIPED.1' => date('d/m/Y'), + 'invoice_number' => $bOL['BOL_number'], + 'amount_due' => number_format($bOL['amount'], 2), + 'TYPEANDESCPTN.1' => 'TOTAL: 20 SKIDS 8320 #', + 'TYPEANDESCPTN.10' => 'ROTTERDAM ETA: 11/22', + 'TYPEANDESCPTN.13' => 'CONTAINER:', + 'TYPEANDESCPTN.2' => 'MECHANICAL / CADDY/ ELECTRICAL', + 'TYPEANDESCPTN.4' => 'BOOKING: 150744100', + 'TYPEANDESCPTN.5' => 'REFERENCE: 3140028046', + 'TYPEANDESCPTN.6' => 'VESSEL: INDEPENDENT HORIZON V. 1023E', + 'TYPEANDESCPTN.7' => 'SEAL: 637053', + 'TYPEANDESCPTN.9' => 'CHESTER, PA ETD: 11/05', + 'BOFLADNGAGYCD' => $bOL['BOL_number'], + 'CLASSORATE1' => '50', + 'CNMETRKLICNSE' => 'ICL / Expeditors', + 'CONSIGTONMADDR' => 'ERICO EUROPE BV JULES VERNEWEG 75 TILBURG . 5015 BG', + 'DATE' => date('d/m/Y'), + 'FRMNMADDR' => 'ERICO INTERNATIONAL CORP 6800 ARNOLD MILLER PARKWAY SOLON, OH 44139 USA', + 'LNITEMWT1' => '8320', + 'PARTOFMSTRBILL' => 'No', + 'PKGTYPECOUNT1' => '20', + 'SHPRNMBR' => '3140028046', + 'TOTALWT' => '8320', + 'TOTPIECES' => '20', + 'ckFREIGHTCOLECT' => 'Yes', + 'ckPREPAY' => 'Off', + + 'DTESHIPED.2' => '', + 'LNITEMWT24' => '', + 'CLASSORATE24' => '', + 'LNITEMCLAS24' => '', + 'TYPEANDESCPTN.24' => '', + 'PKGTYPECOUNT24' => '', + 'LNITEMWT23' => '', + 'CLASSORATE23' => '', + 'LNITEMCLAS23' => '', + 'TYPEANDESCPTN.23' => '', + 'PKGTYPECOUNT23' => '', + 'LNITEMWT22' => '', + 'CLASSORATE22' => '', + 'LNITEMCLAS22' => '', + 'TYPEANDESCPTN.22' => '', + 'PKGTYPECOUNT22' => '', + 'LNITEMWT21' => '', + 'CLASSORATE21' => '', + 'LNITEMCLAS21' => '', + 'TYPEANDESCPTN.21' => '', + 'PKGTYPECOUNT21' => '', + 'LNITEMWT20' => '', + 'CLASSORATE20' => '', + 'LNITEMCLAS20' => '', + 'TYPEANDESCPTN.20' => '', + 'PKGTYPECOUNT20' => '', + 'LNITEMWT19' => '', + 'CLASSORATE19' => '', + 'LNITEMCLAS19' => '', + 'TYPEANDESCPTN.19' => '', + 'PKGTYPECOUNT19' => '', + 'LNITEMWT18' => '', + 'CLASSORATE18' => '', + 'LNITEMCLAS18' => '', + 'TYPEANDESCPTN.18' => '', + 'PKGTYPECOUNT18' => '', + 'LNITEMWT17' => '', + 'CLASSORATE17' => '', + 'LNITEMCLAS17' => '', + 'TYPEANDESCPTN.17' => '', + 'PKGTYPECOUNT17' => '', + 'LNITEMWT16' => '', + 'CLASSORATE16' => '', + 'LNITEMCLAS16' => '', + 'TYPEANDESCPTN.16' => '', + 'PKGTYPECOUNT16' => '', + 'LNITEMWT15' => '', + 'CLASSORATE15' => '', + 'LNITEMCLAS15' => '', + 'TYPEANDESCPTN.15' => '', + 'PKGTYPECOUNT15' => '', + 'LNITEMWT14' => '', + 'CLASSORAT14' => '', + 'LNITEMCLAS14' => '', + 'TYPEANDESCPTN.14' => '', + 'PKGTYPECOUNT14' => '', + 'LNITEMWT13' => '', + 'CLASSORATE13' => '', + 'LNITEMCLAS13' => '', + 'PKGTYPECOUNT13' => '', + 'LNITEMWT12' => '', + 'CLASSORATE12' => '', + 'LNITEMCLAS12' => '', + 'TYPEANDESCPTN.12' => '', + 'PKGTYPECOUNT12' => '', + 'LNITEMWT11' => '', + 'CLASSORATE11' => '', + 'LNITEMCLAS11' => '', + 'TYPEANDESCPTN.11' => '', + 'PKGTYPECOUNT11' => '', + 'LNITEMWT10' => '', + 'CLASSORATE10' => '', + 'LNITEMCLAS10' => '', + 'PKGTYPECOUNT10' => '', + 'LNITEMWT9' => '', + 'CLASSORATE9' => '', + 'LNITEMCLAS8' => '', + 'PKGTYPECOUNT9' => '', + 'LNITEMWT8' => '', + 'CLASSORATE8' => '', + 'TYPEANDESCPTN.8' => '', + 'PKGTYPECOUNT8' => '', + 'LNITEMWT7' => '', + 'CLASSORATE7' => '', + 'LNITEMCLAS7' => '', + 'PKGTYPECOUNT7' => '', + 'LNITEMWT6' => '', + 'CLASSORATE6' => '', + 'LNITEMCLAS6' => '', + 'PKGTYPECOUNT6' => '', + 'LNITEMWT5' => '', + 'CLASSORATE5' => '', + 'LNITEMCLAS5' => '', + 'PKGTYPECOUNT5' => '', + 'LNITEMWT4' => '', + 'CLASSORATE4' => '', + 'LNITEMCLAS4' => '', + 'PKGTYPECOUNT4' => '', + 'LNITEMWT3' => '', + 'CLASSORATE3' => '', + 'LNITEMCLAS3' => '', + 'TYPEANDESCPTN.3' => '', + 'PKGTYPECOUNT3' => '', + 'LNITEMWT2' => '', + 'CLASSORATE2' => '', + 'LNITEMCLAS2' => '', + 'PKGTYPECOUNT2' => '', + 'LNITEMCLAS1' => '', + 'HAZLNITEMWT3' => '', + 'HAZCLASSORATE3' => '', + 'HAZLNITEMCLAS3' => '', + 'HAZMATERDESL3' => '', + 'HAZMATERL3' => '', + 'HAZLNITEMWT2' => '', + 'HAZCLASSORATE2' => '', + 'HAZLNITEMCLAS2' => '', + 'HAZMATERDESL2' => '', + 'HAZMATERL2' => '', + 'HAZLNITEMWT1' => '', + 'HAZCLASSORATE1' => '', + 'HAZLNITEMCLAS1' => '', + 'HAZMATERDESL1' => '', + 'HAZMATERL1' => '', + '24HREMGCYRSPNS' => '', + 'CARIERFEDEMPID' => '', + 'BILLTOADDR' => '', + 'NUMDROPS' => '', + + ]; + + try { + $filledPdf = $this->bolService->fillBillOfLading($data); + + return response()->download($filledPdf)->deleteFileAfterSend(true); + } catch (\Exception $e) { + return response()->json(['error' => $e->getMessage()], 500); + } + + } +} diff --git a/Modules/M3/Http/Controllers/FillBOLController.php b/Modules/M3/Http/Controllers/FillBOLController.php new file mode 100755 index 00000000..c56d52ef --- /dev/null +++ b/Modules/M3/Http/Controllers/FillBOLController.php @@ -0,0 +1,213 @@ +path('ETN-BOL.pdf')); + // $pdf = new Pdf(Storage::disk('public')->path('ETN-BOL.pdf'), [ + // //'command' => '/usr/local/bin/pdftk', + // 'useExec' => true, + // ]); + if ($pdf === false) { + var_dump('step 1'); + $error = $pdf->getError(); + dd($error); + } + + $newfile = "BOL-{$bOL['BOL_number']}.pdf"; + var_dump($newfile); + + $test = Storage::disk('public')->put($newfile, ''); + if ($test === false) { + var_dump('step 2'); + $error = $test->getError(); + dd($error); + } + + $result = $pdf->fillForm([ + 'DTESHIPED.1' => date('d/m/Y'), + 'invoice_number' => $bOL['BOL_number'], + 'amount_due' => number_format($bOL['amount'], 2), + 'TYPEANDESCPTN.1' => 'TOTAL: 20 SKIDS 8320 #', + 'TYPEANDESCPTN.10' => 'ROTTERDAM ETA: 11/22', + 'TYPEANDESCPTN.13' => 'CONTAINER:', + 'TYPEANDESCPTN.2' => 'MECHANICAL / CADDY/ ELECTRICAL', + 'TYPEANDESCPTN.4' => 'BOOKING: 150744100', + 'TYPEANDESCPTN.5' => 'REFERENCE: 3140028046', + 'TYPEANDESCPTN.6' => 'VESSEL: INDEPENDENT HORIZON V. 1023E', + 'TYPEANDESCPTN.7' => 'SEAL: 637053', + 'TYPEANDESCPTN.9' => 'CHESTER, PA ETD: 11/05', + 'BOFLADNGAGYCD' => $bOL['BOL_number'], + 'CLASSORATE1' => '50', + 'CNMETRKLICNSE' => 'ICL / Expeditors', + 'CONSIGTONMADDR' => 'ERICO EUROPE BV JULES VERNEWEG 75 TILBURG . 5015 BG', + 'DATE' => date('d/m/Y'), + 'FRMNMADDR' => 'ERICO INTERNATIONAL CORP 6800 ARNOLD MILLER PARKWAY SOLON, OH 44139 USA', + 'LNITEMWT1' => '8320', + 'PARTOFMSTRBILL' => 'No', + 'PKGTYPECOUNT1' => '20', + 'SHPRNMBR' => '3140028046', + 'TOTALWT' => '8320', + 'TOTPIECES' => '20', + 'ckFREIGHTCOLECT' => 'Yes', + 'ckPREPAY' => 'Off', + + 'DTESHIPED.2' => '', + 'LNITEMWT24' => '', + 'CLASSORATE24' => '', + 'LNITEMCLAS24' => '', + 'TYPEANDESCPTN.24' => '', + 'PKGTYPECOUNT24' => '', + 'LNITEMWT23' => '', + 'CLASSORATE23' => '', + 'LNITEMCLAS23' => '', + 'TYPEANDESCPTN.23' => '', + 'PKGTYPECOUNT23' => '', + 'LNITEMWT22' => '', + 'CLASSORATE22' => '', + 'LNITEMCLAS22' => '', + 'TYPEANDESCPTN.22' => '', + 'PKGTYPECOUNT22' => '', + 'LNITEMWT21' => '', + 'CLASSORATE21' => '', + 'LNITEMCLAS21' => '', + 'TYPEANDESCPTN.21' => '', + 'PKGTYPECOUNT21' => '', + 'LNITEMWT20' => '', + 'CLASSORATE20' => '', + 'LNITEMCLAS20' => '', + 'TYPEANDESCPTN.20' => '', + 'PKGTYPECOUNT20' => '', + 'LNITEMWT19' => '', + 'CLASSORATE19' => '', + 'LNITEMCLAS19' => '', + 'TYPEANDESCPTN.19' => '', + 'PKGTYPECOUNT19' => '', + 'LNITEMWT18' => '', + 'CLASSORATE18' => '', + 'LNITEMCLAS18' => '', + 'TYPEANDESCPTN.18' => '', + 'PKGTYPECOUNT18' => '', + 'LNITEMWT17' => '', + 'CLASSORATE17' => '', + 'LNITEMCLAS17' => '', + 'TYPEANDESCPTN.17' => '', + 'PKGTYPECOUNT17' => '', + 'LNITEMWT16' => '', + 'CLASSORATE16' => '', + 'LNITEMCLAS16' => '', + 'TYPEANDESCPTN.16' => '', + 'PKGTYPECOUNT16' => '', + 'LNITEMWT15' => '', + 'CLASSORATE15' => '', + 'LNITEMCLAS15' => '', + 'TYPEANDESCPTN.15' => '', + 'PKGTYPECOUNT15' => '', + 'LNITEMWT14' => '', + 'CLASSORAT14' => '', + 'LNITEMCLAS14' => '', + 'TYPEANDESCPTN.14' => '', + 'PKGTYPECOUNT14' => '', + 'LNITEMWT13' => '', + 'CLASSORATE13' => '', + 'LNITEMCLAS13' => '', + 'PKGTYPECOUNT13' => '', + 'LNITEMWT12' => '', + 'CLASSORATE12' => '', + 'LNITEMCLAS12' => '', + 'TYPEANDESCPTN.12' => '', + 'PKGTYPECOUNT12' => '', + 'LNITEMWT11' => '', + 'CLASSORATE11' => '', + 'LNITEMCLAS11' => '', + 'TYPEANDESCPTN.11' => '', + 'PKGTYPECOUNT11' => '', + 'LNITEMWT10' => '', + 'CLASSORATE10' => '', + 'LNITEMCLAS10' => '', + 'PKGTYPECOUNT10' => '', + 'LNITEMWT9' => '', + 'CLASSORATE9' => '', + 'LNITEMCLAS8' => '', + 'PKGTYPECOUNT9' => '', + 'LNITEMWT8' => '', + 'CLASSORATE8' => '', + 'TYPEANDESCPTN.8' => '', + 'PKGTYPECOUNT8' => '', + 'LNITEMWT7' => '', + 'CLASSORATE7' => '', + 'LNITEMCLAS7' => '', + 'PKGTYPECOUNT7' => '', + 'LNITEMWT6' => '', + 'CLASSORATE6' => '', + 'LNITEMCLAS6' => '', + 'PKGTYPECOUNT6' => '', + 'LNITEMWT5' => '', + 'CLASSORATE5' => '', + 'LNITEMCLAS5' => '', + 'PKGTYPECOUNT5' => '', + 'LNITEMWT4' => '', + 'CLASSORATE4' => '', + 'LNITEMCLAS4' => '', + 'PKGTYPECOUNT4' => '', + 'LNITEMWT3' => '', + 'CLASSORATE3' => '', + 'LNITEMCLAS3' => '', + 'TYPEANDESCPTN.3' => '', + 'PKGTYPECOUNT3' => '', + 'LNITEMWT2' => '', + 'CLASSORATE2' => '', + 'LNITEMCLAS2' => '', + 'PKGTYPECOUNT2' => '', + 'LNITEMCLAS1' => '', + 'HAZLNITEMWT3' => '', + 'HAZCLASSORATE3' => '', + 'HAZLNITEMCLAS3' => '', + 'HAZMATERDESL3' => '', + 'HAZMATERL3' => '', + 'HAZLNITEMWT2' => '', + 'HAZCLASSORATE2' => '', + 'HAZLNITEMCLAS2' => '', + 'HAZMATERDESL2' => '', + 'HAZMATERL2' => '', + 'HAZLNITEMWT1' => '', + 'HAZCLASSORATE1' => '', + 'HAZLNITEMCLAS1' => '', + 'HAZMATERDESL1' => '', + 'HAZMATERL1' => '', + '24HREMGCYRSPNS' => '', + 'CARIERFEDEMPID' => '', + 'BILLTOADDR' => '', + 'NUMDROPS' => '', + + ]) + ->needAppearances() // ensures values are visible in viewer + ->saveAs(Storage::disk('public')->path($newfile)); + // Always check for errors + if ($result === false) { + var_dump('step 3'); + $error = $pdf->getError(); + dd($error); + } else { + return response()->file(Storage::disk('public')->path($newfile)); + } + + } +} diff --git a/Modules/M3/Http/Controllers/GetContentsController.php b/Modules/M3/Http/Controllers/GetContentsController.php new file mode 100755 index 00000000..51331d9f --- /dev/null +++ b/Modules/M3/Http/Controllers/GetContentsController.php @@ -0,0 +1,297 @@ +MACPKR) ? trim($request->MACPKR) : ''; + + // ESN1 + // $macpacPicker='888568'; // LTL example + // $macpacPicker='894337'; // another LTL example with smaller orders, therefore pallets are more mixed + // $macpacPicker='1225311'; // parcel example + // ESN2 + // $macpacPicker='748101'; // LTL example + + try { + $icm704mArray = $this->buildNMFCCodesArray(); + + $shipmentData = $this->getShipmentData($macpacPicker); + if (empty($shipmentData['orderNumber'])) { + return response()->json(['error' => "Picker {$macpacPicker} was not found in ICM688M1"]); + } + + // Get Packages + $packages = $this->getPackagesData($shipmentData['macpkr_list']); + // Add NMFC to Packages + $packagesWithNMFC = $this->addNMFCDataToPackages($packages, $macpacPicker, $icm704mArray); + + // Get Commodities + $commodities = $this->getCommoditiesData( + $shipmentData['company'], + $shipmentData['warehouse'], + $macpacPicker, + $packages['package_595m1'], + $icm704mArray, + ); + + return response()->json([ + 'error' => '', + 'shipmentData' => $shipmentData, + 'packages' => $packagesWithNMFC, + 'commodities' => $commodities, + ]); + + } catch (\Exception $e) { + return response()->json(['error' => $e->getMessage()], 500); + } + } + + protected function buildNMFCCodesArray() + { + $results = DB::table('ICM704M')->get(); + + return $results->mapWithKeys(function ($row) { + return [ + trim($row->AONMIT) => [ + 'LTLClassId' => number_format(trim($row->AOFCID), 1), + 'NMFCItem' => trim($row->AONMIT), + 'NMFCSub' => trim($row->AONMSB), + 'SkidDescription' => trim($row->AOSKDE), + ], + ]; + })->all(); + + } + + protected function getShipmentData($macpacPicker) + { + $result = DB::select( + ' + SELECT + SUM(A4TPCKWGHT) as total_weight, + A4MACPKR, A4SHSHA1, A4SHSHA2, A4SHSHCI, A4SHSHNM, + A4SHSHCT, A4SHSHZP, A4SHSHST, A4ONO, A4STCN, A4CO, + A4WHS, A4SHIPVIA, A4SLCO, A4SLWHS, A4CATPID, A42SSVCCOD, + A4CARRIER, A4SHPAGGCD, A4SALESLOC, A4SHCSPO, A4OFSTRM, + A4SCAC, A4PLANT + FROM ICM688M1 + WHERE A4MACPKR = ? + GROUP BY A4MACPKR, A4SHSHA1, A4SHSHA2, A4SHSHCI, A4SHSHNM, + A4SHSHCT, A4SHSHZP, A4SHSHST, A4ONO, A4RLNO, A4SHNO, + A4STCN, A4CO, A4WHS, A4SHIPVIA, A4SLCO, A4SLWHS, + A4CATPID, A42SSVCCOD, A4CARRIER, A4SHPAGGCD, + A4SALESLOC, A4SHCSPO, A4OFSTRM, A4SCAC, A4PLANT', + [$macpacPicker], + ); + + if (empty($result)) { + return []; + } + + $row = $result[0]; + + return [ + 'orderNumber' => trim($row->A4MACPKR), + 'recipient' => [ + 'address1' => trim($row->A4SHSHA1), + 'address2' => trim($row->A4SHSHA2), + 'city' => trim($row->A4SHSHCI), + 'companyName' => trim($row->A4SHSHNM), + 'country' => trim($row->A4SHSHCT), + 'postalCode' => trim($row->A4SHSHZP), + 'state' => trim($row->A4SHSHST), + ], + 'shipmentReference' => trim($row->A4ONO), + 'company' => trim($row->A4CO), + 'warehouse' => trim($row->A4WHS), + 'macpkr_list' => $macpacPicker, + 'shipment_list' => "'" . trim($row->A4ONO) . "'", + 'po_list' => "'" . trim($row->A4SHCSPO) . "'", + 'order_list' => "'" . trim($row->A4ONO) . "'", + ]; + } + + protected function getPackagesData($macpkrList) + { + $results = DB::select( + ' + SELECT + AYINTBOX, + MAX(AYHEIGHT) as height, + MAX(AYWIDTH) as width, + MAX(AYDEPTH) as depth, + SUM(AYLNWGHT) as weight + FROM ICM695M1 + WHERE AYMACPKR IN (?) + GROUP BY AYINTBOX + ORDER BY AYINTBOX', + [$macpkrList], + ); + + $packages = []; + $package595m1 = []; + $packagesGS1Array = []; + + foreach ($results as $index => $row) { + $internalBox = trim($row->AYINTBOX); + + $package595m1[$internalBox] = [ + 'INDEX' => $index, + 'HEIGHT' => $row->HEIGHT, + 'WIDTH' => $row->WIDTH, + 'DEPTH' => $row->DEPTH, + 'WEIGHT' => $row->WEIGHT, + ]; + + $packages[] = [ + 'Width' => $row->WIDTH, + 'Height' => $row->HEIGHT, + 'Length' => $row->DEPTH, + 'Weight' => $row->WEIGHT, + 'LicencePlate' => $internalBox, + 'Reference1' => $internalBox, + 'WeightType' => 0, + 'DimensionType' => 0, + ]; + + $packagesGS1Array[] = $internalBox; + } + + return [ + 'packages' => $packages, + 'package_595m1' => $package595m1, + 'packagesGS1Array' => $packagesGS1Array, + ]; + } + + protected function addNMFCDataToPackages($packages, $macpkrList, $icm704mArray) + { + $nmfcResults = DB::select( + ' + WITH tempfile AS ( + SELECT + (SELECT A5WBFRCT FROM ICM688M2 + WHERE A5MACPKR IN (?) AND A5PART=AZPART + FETCH FIRST 1 ROWS ONLY) as WBFRCT, + az.* + FROM ICM695M2 az + WHERE AZMACPKR IN (?) + ) + SELECT azintbox, MIN(WBFRCT) as MIN_WBFRCT + FROM tempfile + GROUP BY azintbox + ORDER BY 1', + [$macpkrList, $macpkrList], + ); + + foreach ($nmfcResults as $index => $row) { + $wbfrct = trim($row->MIN_WBFRCT); + $packages['packages'][$index]['SkidDesc'] = + $icm704mArray[$wbfrct]['SkidDescription'] ?? 'CLIPS, FASTENERS OR MOUNTS'; + } + + return $packages; + } + + protected function getCommoditiesData($company, $warehouse, $macpkrList, $package595m1, $icm704mArray) + { + $results = DB::select( + ' + WITH tempfile1 AS ( + SELECT + A5PART, + MAX(A5CMDESC) as A5CMDESC, + MAX(A5MUTMS) as A5MUTMS, + MAX(A5PMPWHT) as A5PMPWHT, + MAX(A5SLUNPR) as A5SLUNPR, + TRIM(MIN(A5WBFRCT)) as A5WBFRCT + FROM ICM688M2 + WHERE A5CO = ? AND A5WHS = ? AND A5MACPKR IN (?) AND A5PACKED > 0 + GROUP BY A5PART + ), + tempfile2 AS ( + SELECT + AZINTBOX, + AZPART, + SUM(AZPACKED) as AZPACKED, + MAX(SUBSTR(AZSPR15A01,1,4)) as HAZARDOUS + FROM ICM695M2 + WHERE AZCO = ? AND AZWHS = ? AND AZMACPKR IN (?) AND AZPACKED <> 0 + GROUP BY AZINTBOX, AZPART + ) + SELECT + A5PART, A5CMDESC, A5MUTMS, + A5PMPWHT * AZPACKED as WEIGHt, + AZPACKED, AZINTBOX, + A5WBFRCT, HAZARDOUS, A5SLUNPR + FROM tempfile1 + LEFT JOIN tempfile2 ON AZPART = A5PART + ORDER BY A5PART', + [$company, $warehouse, $macpkrList, $company, $warehouse, $macpkrList], + ); + + $commodities = []; + $prevPartNumber = ''; + $index = -1; + + foreach ($results as $row) { + $partNumber = trim($row->A5PART); + + if ($partNumber !== $prevPartNumber) { + $index++; + $quantityIndex = 0; + + $wbfrct = trim($row->A5WBFRCT); + $nmfcData = $icm704mArray[$wbfrct] ?? [ + 'LTLClassId' => '50', + 'NMFCItem' => '93490', + 'NMFCSub' => '', + ]; + + $commodities[] = [ + 'Description' => trim($row->A5CMDESC), + 'PartNumber' => $partNumber, + 'SKUOrItemOrUPC' => $partNumber, + 'MadeInCountryCode' => 'US', + 'UnitValue' => $row->A5SLUNPR == '.000' ? 1 : (float) $row->A5SLUNPR, + 'TotalWeight' => (float) $row->WEIGHT, + 'QuantityUnitOfMeasure' => trim($row->A5MUTMS) ?: 'EA', + 'Quantity' => (float) $row->AZPACKED, + 'LTLClassId' => $nmfcData['LTLClassId'], + 'NMFCItem' => $nmfcData['NMFCItem'], + 'NMFCSub' => $nmfcData['NMFCSub'], + 'DangerousGoodsInfo' => [ + 'ContainsDangerousGoods' => trim($row->HAZARDOUS) === 'H4.1', + ], + 'QuantityAssignment' => [ + [ + 'PackageIndex' => $package595m1[trim($row->AZINTBOX)]['INDEX'], + 'Quantity' => (float) $row->AZPACKED, + ], + ], + ]; + } else { + $quantityIndex++; + $commodities[$index]['TotalWeight'] += (float) $row->WEIGHT; + $commodities[$index]['Quantity'] += (float) $row->AZPACKED; + $commodities[$index]['QuantityAssignment'][] = [ + 'PackageIndex' => $package595m1[trim($row->AZINTBOX)]['INDEX'], + 'Quantity' => (float) $row->AZPACKED, + ]; + } + + $prevPartNumber = $partNumber; + } + + return $commodities; + } +} diff --git a/Modules/M3/Http/Controllers/M3CallCloseAPIController.php b/Modules/M3/Http/Controllers/M3CallCloseAPIController.php new file mode 100755 index 00000000..829bf0f4 --- /dev/null +++ b/Modules/M3/Http/Controllers/M3CallCloseAPIController.php @@ -0,0 +1,112 @@ +error('Manifest CloseAPI: Manifest, company and warehouse must be defined.'); + + return self::errorResponse('Manifest CloseAPI: Manifest, company and warehouse must be defined.'); + } + + try { + $records = self::findOpenManifestRecords($params); + if ($records->isEmpty()) { + Log::channel('dailyCron')->info('Manifest CloseAPI: No records found in ICM705M1.'); + + return self::errorResponse('Manifest CloseAPI: No records found in ICM705M1.'); + } + + return self::submitManifest($records->first(), $params['SHUSER']); + } catch (\Throwable $exception) { + Log::error($exception); + + return response()->json([ + 'code' => '500', + 'status' => 'Error', + 'message' => 'Manifest Closing failed unexpectedly.', + ], 500); + } + } + + private static function configureTimeouts(): void + { + $timeout = (string) Config::get('arrays.PHPTimeOut'); + ini_set('max_execution_time', $timeout); + ini_set('max_input_time', $timeout); + ini_set('default_socket_timeout', $timeout); + } + + private static function validatedParams(Request $request): ?array + { + $params = [ + 'SHUSER' => trim((string) $request->input('SHUSER', '')), + 'MANIFEST' => trim((string) $request->input('MANIFEST', '')), + 'APCO' => trim((string) $request->input('APCO', '')), + 'APWHS' => trim((string) $request->input('APWHS', '')), + ]; + + if ($params['MANIFEST'] === '' || $params['APCO'] === '' || $params['APWHS'] === '') { + return null; + } + + return $params; + } + + private static function findOpenManifestRecords(array $params) + { + $connection = config('m3.connection', 'pgsql'); + if (! Schema::connection($connection)->hasTable('icm705m1')) { + return collect(); + } + + return DB::connection($connection)->table('icm705m1') + ->select('APMANIFEST', 'APCO', 'APWHS') + ->where('APSPARE2', '') + ->where('APCO', $params['APCO']) + ->where('APWHS', $params['APWHS']) + ->where('APMANIFEST', $params['MANIFEST']) + ->whereRaw('EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - APLDCLOZ)) / 60 > 15') + ->orderBy('APMANIFEST') + ->get(); + } + + private static function submitManifest(object $record, string $user): JsonResponse + { + $exitCode = Artisan::call('command:CallCloseAPI', [ + 'user' => $user, + 'manifest' => $record->APMANIFEST ?? '', + 'co' => $record->APCO ?? '', + 'whs' => $record->APWHS ?? '', + ]); + + if ($exitCode === 1) { + return response()->json([ + 'code' => '200', + 'status' => 'Success', + 'message' => 'Manifest Closing submitted', + ]); + } + + return self::errorResponse('Manifest Closing Failed'); + } + + private static function errorResponse(string $message): JsonResponse + { + return response()->json(['code' => '206', 'status' => 'Error', 'message' => $message]); + } +} diff --git a/Modules/M3/Http/Controllers/M3Controller.php b/Modules/M3/Http/Controllers/M3Controller.php new file mode 100755 index 00000000..8f959e85 --- /dev/null +++ b/Modules/M3/Http/Controllers/M3Controller.php @@ -0,0 +1,91 @@ + 'N', 'R428US' => strtoupper(m3_user()), 'R428CO' => '', 'R428PL' => '', 'R428WH' => '']; + if (Schema::connection($connection)->hasTable('icm428m')) { + $power_user = DB::connection($connection)->table('icm428m')->select('R428PWRUSR', 'R428US', 'R428CO', 'R428PL', 'R428WH') + ->where('R428US', strtoupper(m3_user()))->first() ?? $power_user; + } + $co = $power_user->R428CO; + $plant = $power_user->R428PL; + $whs = $power_user->R428WH; + $iCM664M = Schema::connection($connection)->hasTable('icm664m') + ? DB::connection($connection)->table('icm664m')->where('AVCO', $co)->where('AVPLANT', $plant)->where('AVWHS', $whs)->get() : collect(); + $iC670M = Schema::connection($connection)->hasTable('ic670m') + ? DB::connection($connection)->table('ic670m')->where('WDCO', $co)->where('WDPL', $plant)->where('WDWHS', $whs)->get() : collect(); + $shipvia = Schema::connection($connection)->hasTable('icm319m') + ? DB::connection($connection)->table('icm319m')->select('AXCODE', 'AXDESC')->orderBy('AXCODE')->get() : collect(); + + return view('m3::liberty-theme.pages.M3Delivery', ['ICM664M' => $iCM664M, 'IC670M' => $iC670M, 'power_user' => $power_user, 'shipvia' => $shipvia]); + } + + // + // Process data from Add modal + // + public static function saveM3DeliveryAdd(Request $request) + { + + $icm664m = DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT1 from ICM664M + where AVCO='$request->AVCO' and AVWHS='$request->AVWHS' and AVPLANT='$request->AVPLANT' and AVDELMETH='$request->AVDELMETH'"); + if ($icm664m[0]->COUNT1 == '1') { + return 'exists'; + } else { + + DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM664M + (AVCO, AVPLANT, AVWHS, AVDELMETH, AVSHPVIA, AVSHSRT, AVSHORCL) + values ('$request->AVCO', '$request->AVPLANT', '$request->AVWHS', '$request->AVDELMETH', + '$request->AVSHPVIA', '$request->AVSHSRT', '$request->AVSHORCL')"); + + return 'success'; + + } + } + + // + // Process data from Edit modal + // + public static function saveM3DeliveryEdit(Request $request) + { + // dd($request); + // Update record to ICM664M + + DB::connection(config('m3.connection', 'pgsql'))->update("update ICM664M + set AVSHPVIA='$request->AVSHPVIA', AVSHSRT='$request->AVSHSRT', AVSHORCL='$request->AVSHORCL' + where AVCO='$request->AVCO' and AVPLANT='$request->AVPLANT' and AVWHS='$request->AVWHS' and AVDELMETH='$request->AVDELMETH'"); + + return 'success'; + + } +} diff --git a/Modules/M3/Http/Controllers/M3ErrorsDispController.php b/Modules/M3/Http/Controllers/M3ErrorsDispController.php new file mode 100755 index 00000000..fcd3cc54 --- /dev/null +++ b/Modules/M3/Http/Controllers/M3ErrorsDispController.php @@ -0,0 +1,368 @@ +macpkr) ? trim($request->macpkr) : ''; + $shsource = isset($request->shsource) ? trim($request->shsource) : ''; + $showerrors = isset($request->showerrors) ? trim($request->showerrors) : 'N'; + $skipdates = isset($request->skipdates) ? trim($request->skipdates) : 'N'; + + // Get users from ICM428M + $connection = config('m3.connection', 'pgsql'); + $iCM428M = Schema::connection($connection)->hasTable('icm428m') + ? DB::connection($connection)->table('icm428m')->select('R428US', 'R428FIRST', 'R428FAMILY')->get() + : collect(); + $iCM428MCOL = collect($iCM428M); + $iCM428MCOL->filter(function ($value) { + return $value->R428US = trim($value->R428US); + }); + $iCM428MCOL->filter(function ($value) { + return $value->R428FIRST = trim($value->R428FIRST); + }); + $iCM428MCOL->filter(function ($value) { + return $value->R428FAMILY = trim($value->R428FAMILY); + }); + + return view('m3::liberty-theme.pages.M3ErrorsDisplay', ['macpkr' => $macpkr, 'shsource' => $shsource, 'showerrors' => $showerrors, 'skipdates' => $skipdates, 'ICM428MCOL' => $iCM428MCOL]); + } + + public function datatables(Request $request) + { + $this->configureDataTableRuntime(); + $filters = $this->dataTableFilters($request); + $connection = config('m3.connection', 'pgsql'); + + if (! Schema::connection($connection)->hasTable('icm699m')) { + return Datatables::of(collect())->addIndexColumn()->make(true); + } + + $profile = $this->findM3Profile($connection, $filters['SHUSER']); + $query = $this->buildM3LogQuery($connection); + $this->applyM3LogFilters($query, $filters, $profile); + + return Datatables::of($query)->addIndexColumn()->make(true); + } + + private function configureDataTableRuntime(): void + { + $timeout = (string) Config::get('arrays.PHPTimeOut'); + ini_set('max_execution_time', $timeout); + ini_set('max_input_time', $timeout); + ini_set('default_socket_timeout', $timeout); + ini_set('memory_limit', '1024M'); + } + + private function dataTableFilters(Request $request): array + { + return [ + 'SHMACPKR' => trim((string) $request->input('SHMACPKR', '')), + 'SHSOURCE' => trim((string) $request->input('SHSOURCE', '')), + 'STARTDATE' => trim((string) $request->input('STARTDATE', today()->subDays(1)->format('Y-m-d'))), + 'ENDDATE' => trim((string) $request->input('ENDDATE', today()->format('Y-m-d'))), + 'SHOWERRORS' => trim((string) $request->input('SHOWERRORS', 'N')), + 'SHUSER' => m3_user() !== '' ? Str::upper(trim(m3_user())) : '', + 'SKIPDATES' => trim((string) $request->input('SKIPDATES', 'N')), + ]; + } + + private function findM3Profile(string $connection, string $user): ?object + { + if ($user === '' || ! Schema::connection($connection)->hasTable('icm428m')) { + return null; + } + + return DB::connection($connection)->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH') + ->where('R428US', $user) + ->first(); + } + + private function buildM3LogQuery(string $connection) + { + $query = DB::connection($connection)->table('icm699m') + ->select('ICM699M.*', DB::raw("ICM699M.SHDT || ' ' || ICM699M.SHTIME AS SHDATETIME")) + ->distinct(); + + if (Schema::connection($connection)->hasTable('icm428m')) { + $query->addSelect('ICM428M.R428FIRST', 'ICM428M.R428FAMILY') + ->leftJoin('ICM428M', 'ICM699M.SHUSER', '=', 'ICM428M.R428US'); + } + if (Schema::connection($connection)->hasTable('icm688m1')) { + $query->addSelect('ICM688M1.A4ONO', 'ICM688M1.A4SHSHNM') + ->leftJoin('ICM688M1', 'ICM699M.SHMACPKR', '=', 'ICM688M1.A4MACPKR'); + } + if (Schema::connection($connection)->hasTable('icm666m')) { + $query->addSelect('ICM666M.A1ONO', 'ICM666M.A1SHSHNM') + ->leftJoin('ICM666M', 'ICM699M.SHMACPKR', '=', 'ICM666M.A1DELNO'); + } + + return $query; + } + + private function applyM3LogFilters($query, array $filters, ?object $profile): void + { + if ($profile !== null) { + $query->whereIn('SHCO', [trim((string) ($profile->R428CO ?? '')), '']) + ->whereIn('SHWHS', [trim((string) ($profile->R428WH ?? '')), '']); + } else { + $query->whereNull('SHCO')->whereNull('SHWHS'); + } + + foreach (['SHMACPKR', 'SHSOURCE'] as $field) { + if ($filters[$field] !== '') { + $query->where($field, $filters[$field]); + } + } + + $query->where('SHSOURCE', '!=', 'PdfStorageAPI'); + if ($filters['SHMACPKR'] === '' && $filters['SKIPDATES'] === 'N') { + $query->whereBetween('SHDT', [$filters['STARTDATE'], $filters['ENDDATE']]); + } + if ($filters['SHOWERRORS'] === 'Y') { + $query->where('SHERROR', 'X'); + } + $query->where('SHTYPE', 'like', '%M3%'); + } + + public static function update699M(Request $request) + { + $sHMACPKR = $request->SHMACPKR != null ? trim($request->SHMACPKR) : ''; + $sHSOURCE = $request->SHSOURCE != null ? trim($request->SHSOURCE) : ''; + $sHCO = $request->SHCO != null ? trim($request->SHCO) : ''; + $sHWHS = $request->SHWHS != null ? trim($request->SHWHS) : ''; + $sHDT = $request->SHDT != null ? trim($request->SHDT) : ''; + $sHTIME = $request->SHTIME != null ? trim($request->SHTIME) : ''; + $sHTYPE = $request->SHTYPE != null ? trim($request->SHTYPE) : ''; + $sHACKNOTE = $request->SHACKNOTE != null ? trim(substr($request->SHACKNOTE, 0, 99)) : ''; + $sHUSER = m3_user() !== '' ? Str::upper(m3_user()) : ''; + $cLOSESIM = $request->CLOSESIM != null ? trim($request->CLOSESIM) : 'N'; + + if ($cLOSESIM == 'N') { + DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->where('SHMACPKR', $sHMACPKR) + ->where('SHDT', $sHDT) + ->where('SHTIME', $sHTIME) + ->where('SHCO', $sHCO) + ->where('SHWHS', $sHWHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', $sHTYPE) + ->update(['SHERROR' => 'Z', 'SHACKUSER' => $sHUSER, 'SHACKDATE' => date('Y-m-d'), 'SHACKTIME' => date('H:i:s'), 'SHACKNOTE' => $sHACKNOTE]); + + } else { + DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->where('SHCO', $sHCO) + ->where('SHWHS', $sHWHS) + ->where('SHSOURCE', $sHSOURCE) + ->where('SHERROR', 'X') + ->where('SHTYPE', $sHTYPE) + ->update(['SHERROR' => 'Z', 'SHACKUSER' => $sHUSER, 'SHACKDATE' => date('Y-m-d'), 'SHACKTIME' => date('H:i:s'), 'SHACKNOTE' => $sHACKNOTE]); + } + + if ($sHSOURCE == 'CloseShipmentCoChargeAPI') { + // Update ICM688M1 : Change A4PICKSTS + DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1') + ->where('A4MACPKR', $sHMACPKR) + ->where('A4CO', $sHCO) + ->where('A4WHS', $sHWHS) + ->update(['A4PICKSTS' => 'a']); + } + + return response()->json(['success' => true]); + } + + // Export To Excel + public static function exporttoExcel(Request $request) + { + self::configureExportRuntime(); + + try { + $filters = self::exportFiltersFromRequest($request); + [$profileUser, $company, $warehouse] = self::exportUserScope($filters['user']); + $users = self::exportUsers(); + [$query, $countQuery] = self::exportQueries(); + + self::applyExportFilters($query, $countQuery, [ + 'profileUser' => $profileUser, + 'company' => $company, + 'warehouse' => $warehouse, + 'manifest' => $filters['manifest'], + 'source' => $filters['source'], + 'startDate' => $filters['startDate'], + 'endDate' => $filters['endDate'], + 'skipDates' => $filters['skipDates'], + 'showErrors' => $filters['showErrors'], + ]); + + $limitResponse = self::validateExportCount($countQuery->count()); + if ($limitResponse !== null) { + return $limitResponse; + } + + $rows = self::prepareExportRows($query->get(), $users); + + return app(SpreadsheetExport::class)->download( + $rows, + 'transactionLog_' . $filters['startDate'] . '-' . $filters['endDate'] . '.xlsx', + ); + } catch (\Throwable $th) { + Log::error($th); + + return redirect()->back()->withInput()->with('message', 'Unable to export the transaction log.'); + } + } + + private static function configureExportRuntime(): void + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOut')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut')); + ini_set('memory_limit', '1024M'); + } + + private static function exportFiltersFromRequest(Request $request): array + { + return [ + 'manifest' => trim((string) $request->input('SHMACPKR', '')), + 'source' => trim((string) $request->input('SHSOURCE', '')), + 'startDate' => trim((string) $request->input('STARTDATE', today()->subDays(1)->format('Y-m-d'))), + 'endDate' => trim((string) $request->input('ENDDATE', today()->format('Y-m-d'))), + 'showErrors' => trim((string) $request->input('SHOWERRORS', 'N')), + 'skipDates' => trim((string) $request->input('SKIPDATES', 'N')), + 'user' => Str::upper(trim(m3_user())), + ]; + } + + private static function exportUserScope(string $user): array + { + $profile = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH') + ->where('R428US', $user) + ->first(); + + return [ + trim((string) ($profile->R428US ?? '')), + trim((string) ($profile->R428CO ?? '')), + trim((string) ($profile->R428WH ?? '')), + ]; + } + + private static function exportUsers() + { + return DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428FIRST', 'R428FAMILY') + ->get() + ->each(function ($value): void { + $value->R428US = trim((string) $value->R428US); + $value->R428FIRST = trim((string) $value->R428FIRST); + $value->R428FAMILY = trim((string) $value->R428FAMILY); + }); + } + + private static function exportQueries(): array + { + $query = DB::connection(config('m3.connection', 'pgsql'))->table('icm699m') + ->select( + DB::raw('COALESCE(ICM688M1.A4ONO, ICM666M.A1ONO) AS DELIVERY_NUM '), + 'ICM699M.SHMACPKR', + DB::raw('COALESCE(ICM688M1.A4SHSHNM, ICM666M.A1SHSHNM) AS CUSTOMER '), + DB::raw(" ICM699M.SHDT || ' ' || ICM699M.SHTIME AS SHDATETIME"), + DB::raw("CASE WHEN ICM699M.SHERROR !='Z' THEN TRIM(ICM699M.SHERROR) ELSE 'Closed' END AS ERROR"), + 'ICM699M.SHTYPE', + 'ICM699M.SHSOURCE', + DB::raw("CASE WHEN ICM428M.R428FIRST IS NOT NULL THEN TRIM(ICM428M.R428FIRST) ||' '|| TRIM(ICM428M.R428FAMILY) ELSE TRIM(ICM699M.SHUSER) END AS USER"), + 'ICM699M.SHCODE', + 'ICM699M.SHCO', + 'ICM699M.SHWHS', + DB::raw(" ICM699M.SHACKDATE ||' '||ICM699M.SHACKTIME AS ACKDATE"), + 'ICM699M.SHACKUSER', + 'ICM699M.SHINTBOX', + 'ICM699M.SHACKNOTE', + DB::raw('SUBSTR(ICM699M.SHDATA, 1, 200)'), + ) + ->distinct() + ->leftJoin('ICM428M', 'ICM699M.SHUSER', '=', 'ICM428M.R428US') + ->leftJoin('ICM688M1', 'ICM699M.SHMACPKR', '=', 'ICM688M1.A4MACPKR') + ->leftJoin('ICM666M', 'ICM699M.SHMACPKR', '=', 'ICM666M.A1DELNO'); + + return [$query, DB::connection(config('m3.connection', 'pgsql'))->table('icm699m')]; + } + + private static function validateExportCount(int $count) + { + $maxRecords = (int) Config::get('arrays.maxRecDL'); + if ($count <= $maxRecords) { + return null; + } + + return redirect()->back()->withInput()->with( + 'message', + 'Maximum allowed records for Excel Download is: ' . number_format($maxRecords) + . ' current records: ' . number_format($count) . ' , change your search criteria.', + ); + } + + private static function prepareExportRows($records, $users) + { + $transactionTypes = Config::get('arrays.transxTypes'); + $rows = collect($records)->each(function ($value) use ($transactionTypes, $users): void { + $source = trim((string) $value->SHSOURCE); + $value->SHSOURCE = $transactionTypes[$source] ?? $source; + $user = $users->firstWhere('R428US', trim((string) $value->SHACKUSER)); + $value->SHACKUSER = $user + ? trim($user->R428FIRST . ' ' . $user->R428FAMILY) + : trim((string) $value->SHACKUSER); + }); + + $rows->prepend([ + 'SHMACPKR' => 'Delivery Note', 'DELIVERY_NUM' => 'Order #', 'CUSTOMER' => 'Customer', + 'SHDATETIME' => 'Date', 'ERROR' => 'Error', 'SHTYPE' => 'Request Type', + 'SHSOURCE' => 'Source of transaction', 'USER' => 'User', 'SHCODE' => 'Request or Response Data', + 'SHCO' => 'Division', 'SHWHS' => 'Warehouse', 'ACKDATE' => 'Acknowledge/Retry Date', + 'SHACKUSER' => 'Acknowledged/Retried by User', 'SHINTBOX' => 'Internal Box Number', + 'SHACKNOTE' => 'Note', 'SHDATA' => 'Error description', + ]); + + return $rows; + } + + private static function applyExportFilters($query, $countQuery, array $filters): void + { + $queries = [$query, $countQuery]; + foreach ($queries as $builder) { + if ($filters['profileUser'] !== '') { + $builder->whereIn('SHCO', [$filters['company'], ''])->whereIn('SHWHS', [$filters['warehouse'], '']); + } else { + $builder->whereNull('SHCO')->whereNull('SHWHS'); + } + + if ($filters['manifest'] !== '') { + $builder->where('SHMACPKR', $filters['manifest']); + } + if ($filters['source'] !== '') { + $builder->where('SHSOURCE', $filters['source']); + } + $builder->where('SHSOURCE', '!=', 'PdfStorageAPI'); + if ($filters['manifest'] === '' && $filters['skipDates'] === 'N') { + $builder->whereBetween('SHDT', [$filters['startDate'], $filters['endDate']]); + } + if ($filters['showErrors'] === 'Y') { + $builder->where('SHERROR', 'X'); + } + $builder->where('SHTYPE', 'like', '%M3%'); + } + } +} diff --git a/Modules/M3/Http/Controllers/M3GetPDFFromCacheController.php b/Modules/M3/Http/Controllers/M3GetPDFFromCacheController.php new file mode 100755 index 00000000..680d7e6c --- /dev/null +++ b/Modules/M3/Http/Controllers/M3GetPDFFromCacheController.php @@ -0,0 +1,180 @@ +table('icm428m') + ->select('R428US', 'R428CO', 'R428WH', 'R428PL') + ->where('R428US', '=', $sHUSER) + ->first(); + + $cOMPANY = isset($iCM428M->R428CO) ? $iCM428M->R428CO : ''; // Company + $pLANT = isset($iCM428M->R428PL) ? $iCM428M->R428PL : ''; // Plant + $wHS = isset($iCM428M->R428WH) ? $iCM428M->R428WH : ''; // WareHouse + } + + // Warehouse Table + $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m')->get(); + // ->where('WDCO',$userCO)->where('WDPL',$userPL)->where('WDWHS',$userWH) + + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + // dump($urlParams); + $aYMACPKR = isset($urlParams['MACPKR']) ? trim($urlParams['MACPKR']) : ''; // Delivery note number + $dOCTYPE = isset($urlParams['DOCTYPE']) ? trim($urlParams['DOCTYPE']) : ''; // Document type (PackingList, CarrierLabel, ContentLabel) + $wHDDA = $cOMPANY . $pLANT . $wHS; + + // Check Doctype fisrt + $docTypes = $dOCTYPE != '' ? [$dOCTYPE] : ['PackingList', 'ContentLabel', 'CarrierLabel', 'GSLabel']; // document type (PackingList, CarrierLabel, ContentLabel) + + if ($urlParams != '') { + // dump($urlParams); + // document number (ie the internal box number, the pick list number) + // Key Combination : COMPANY WHS A4MACPKR DOCTYPE DOCNUM + // Document type (PackingList, CarrierLabel, ContentLabel) + + // Get Aggregation Number if it exists + $iCM695M1Agg = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->select('AYTRUCK') + ->where('AYCO', $cOMPANY) + ->where('AYWHS', $wHS) + ->where('AYMACPKR', $aYMACPKR) + ->first(); + $aggno = isset($iCM695M1Agg->AYTRUCK) ? trim($iCM695M1Agg->AYTRUCK) : ''; + + if ($aggno != '' && $aggno != '0') { + + $aggmsg = "This delivery note is part of aggregation $aggno "; + $iCM688M1 = DB::connection(config('m3.connection', 'pgsql'))->select("select A4MACPKR from ICM688M1 where A4SHPAGGCD='$aggno'"); + + // 654 add 'AYSPR15A01', 'AYSPR30A01', 'AYTRUCK' carrier and tracking# and agg# + $iCM695M1 = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->select('AYCO', 'AYWHS', 'AYMACPKR', 'AYINTBOX', 'AYSPR15A01', 'AYSPR30A01', 'AYTRUCK') + ->distinct() + ->where('AYCO', $cOMPANY) + ->where('AYWHS', $wHS) + // ->where('AYMACPKR',$aYMACPKR) + ->where('AYTRUCK', $aggno) + ->orderBy('AYMACPKR') + ->get(); + } else { + // 654 add 'AYSPR15A01', 'AYSPR30A01', 'AYTRUCK' carrier and tracking# and agg# + $iCM695M1 = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->select('AYCO', 'AYWHS', 'AYMACPKR', 'AYINTBOX', 'AYSPR15A01', 'AYSPR30A01', 'AYTRUCK') + ->distinct() + ->where('AYCO', $cOMPANY) + ->where('AYWHS', $wHS) + ->where('AYMACPKR', $aYMACPKR) + ->orderBy('AYMACPKR') + ->get(); + } + + if (count($iCM695M1) > 0) { + $tmpCacheArr = $carrier = $trackingno = []; + // Loop the Results from $ICM595M1TMP + foreach ($iCM695M1 as $ICM695M1R) { + $wHS = trim($ICM695M1R->AYWHS); + $cOMPANY = trim($ICM695M1R->AYCO); + $aYMACPKR = trim($ICM695M1R->AYMACPKR); + $dOCNUM = trim($ICM695M1R->AYINTBOX); + // 654 + $carrier[] = trim($ICM695M1R->AYSPR15A01); + $trackingno[] = trim($ICM695M1R->AYSPR30A01); + $aggno = trim($ICM695M1R->AYTRUCK); + + // Make Key and Test Validity + if ($aYMACPKR != '' && $cOMPANY != '' && $wHS != '') { + $contentLabel = ''; + + // Get Unique Keys + foreach ($docTypes as $value) { + // Check Parcel vs LTL + if ($value == 'ContentLabel') { + $dOCNUMT = $dOCNUM; + $contentLabel = ! is_numeric($dOCNUM) ? 'LTL' : ''; + } + + if ($value == 'CarrierLabel') { + $dOCNUMT = $dOCNUM; + + // Keep Solon Logic to read LTL + $dOCNUMT2 = $contentLabel == 'LTL' ? $aYMACPKR : $dOCNUM; + if ($dOCNUMT2 != $dOCNUMT) { + $pDFKey2 = $value . '/' . $value . '_' . $aYMACPKR . '_' . $dOCNUMT2 . '_' . $cOMPANY . '_' . $wHS; + $tmpCacheArr[] = $pDFKey2; + } + } + + if ($value == 'PackingList') { + $dOCNUMT = $aYMACPKR; + } + + // Get GS1 Labels + if ($value == 'GSLabel') { + $pDFKey = $value . '/' . $value . '_' . $aYMACPKR . '_' . $cOMPANY . '_' . $wHS . '_' . $dOCNUM; + + // $pDFKey = $value.'/'.$value.'_'.$aYMACPKR.'_'.$cOMPANY.'_'.$wHS; + // } + // else{ + // $pDFKey = $value.'/'.$value.'_'.$aYMACPKR.'_'.$cOMPANY.'_'.$wHS.'_'.$dOCNUM; + // } + } else { + $pDFKey = $value . '/' . $value . '_' . $aYMACPKR . '_' . $dOCNUMT . '_' . $cOMPANY . '_' . $wHS; + } + $tmpCacheArr[] = $pDFKey; + } + } + } + + // Get unique values from array $pDFArray + $tmpCacheArr = collect($tmpCacheArr)->unique(); + foreach ($tmpCacheArr as $value) { + + $pdfFileName = $pdfFilePath . $value . '.pdf'; + if (File::exists($pdfFileName)) { + + $pdfFile = File::get($pdfFileName); + // Transform content to base64 + // $base64PDF = $pdfFile; + $base64PDF = base64_encode($pdfFile); + $pDFArray[] = $base64PDF; + } + } + } else { + // Nothing Found + } + } + } catch (\Throwable $th) { + report($th); + } + + return view('m3::liberty-theme.pages.M3GetPDF', ['IC670M' => $iC670M, 'PDFArray' => $pDFArray, 'AYMACPKR' => $aYMACPKR, 'WHDDA' => $wHDDA, 'aggmsg' => $aggmsg, 'carrier' => $carrier, 'trackingno' => $trackingno, 'ICM688M1' => $iCM688M1, 'COMPANY' => $cOMPANY, 'PLANT' => $pLANT, 'WHS' => $wHS]); + // compact('IC670M','ViewTitle') + } +} diff --git a/Modules/M3/Http/Controllers/MFOrdersController.php b/Modules/M3/Http/Controllers/MFOrdersController.php new file mode 100755 index 00000000..8cd76460 --- /dev/null +++ b/Modules/M3/Http/Controllers/MFOrdersController.php @@ -0,0 +1,53 @@ +id) ? trim($request->id) : ''; + + // dd("MFOrders ".$mF); + // Get Users from ICM428M + $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH', 'R428PL') + ->where('R428US', '=', strtoupper(m3_user())) + ->first(); + $co = $iCM428M->R428CO; + $whs = $iCM428M->R428WH; + $plant = $iCM428M->R428PL; + + // ICM705M1 Statement + $sqlstmt = "select APMANIFEST,APDOCKDOOR,APCARRIER,APTRUCKIDT,APSPARE1,APLDSTRU,APLDSTRD,APLDSTRT, + APLDCLOU,APLDCLOD,APLDCLOT,APCO,APWHS,APPLT,APSPARE2,APLDCLOZ + from ICM705M1 + where APMANIFEST = $mF and APCO='$co' and APWHS='$whs' and APPLT='$plant' limit 1"; + + $iCM705M1 = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + $carrier = isset($iCM705M1[0]->APCARRIER) ? trim($iCM705M1[0]->APCARRIER) : ''; + + if ($mF != '') { + $status_ICM688M1_array = Config::get('arrays.status_ICM688M1_array'); + + $sqlstmt = "SELECT AYCO,AYPLANT,AYMACPKR,AYONO,A4SHSHNM,A4PICKSTS,AYSPR15A01,SUM(AYLNWGHT) AS TOTWEIGHT,COUNT(*) AS BOXPAL FROM ICM695M1 + LEFT JOIN ICM688M1 ON AYCO=A4CO AND AYPLANT=A4PLANT AND AYMACPKR=A4MACPKR + WHERE AYAPRF1551= $mF and AYCO='$co' and AYWHS='$whs' and AYPLANT='$plant' + GROUP BY AYCO,AYPLANT,AYMACPKR,AYONO,A4SHSHNM,A4PICKSTS,AYSPR15A01"; + + $iCM695M1 = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + + return view( + 'm3::liberty-theme.pages.MFOrders', + ['ICM695M1' => $iCM695M1, 'status_ICM688M1_array' => $status_ICM688M1_array, 'MF' => $mF, 'carrier' => $carrier], + ); + } else { + abort(404, 'Manifest Not Found'); + } + + } +} diff --git a/Modules/M3/Http/Controllers/OrderLinesOfClosedOrder.php b/Modules/M3/Http/Controllers/OrderLinesOfClosedOrder.php new file mode 100755 index 00000000..e782417a --- /dev/null +++ b/Modules/M3/Http/Controllers/OrderLinesOfClosedOrder.php @@ -0,0 +1,294 @@ +format('Ymd'); + $allReportsUrls = []; + try { + [$cOMPANY, $pLANT, $wHS] = self::userWarehouseContext('110', '144', '322'); + + // Warehouse Table + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + $rEPORTDATEDisp = isset($urlParams['REPORTDATEDisp']) ? \DateTime::createFromFormat('Y-m-d', trim($urlParams['REPORTDATEDisp']))->format('Ymd') : today()->format('Ymd'); + if ($rEPORTDATEDisp != '' && $cOMPANY != '' && $wHS != '' && $pLANT != '') { + // Case 729: Add Currency code A1SHCURR FROM ICM666M + $selectContent = " + SELECT A5MACPKR, A5ONO, + (SELECT A4REFORD FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) AS A4REFORD, + A5PART, A5RSVQTY, A5PACKED, A5RSVQTY - A5PACKED AS CALCULATED_COLUMN, + A5SLUNPR * A5PACKED AS ANOTHER_CALCULATED_COLUMN, + A5PMPWHT*A5PACKED AS WEIGHT, + (SELECT A4SHSHNM FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) AS A4SHSHNM , + SHDT, SHTIME, + CASE WHEN SHDT IS NULL THEN (SELECT SHDATA FROM ICM699M WHERE SHMACPKR=A5MACPKR AND SHTYPE='M3-Res-out' AND SHSOURCE='CloseShipmentCoChargeAPI' ORDER BY SHDT DESC, SHTIME DESC FETCH FIRST 1 ROWS ONLY) ELSE '' END AS REASON, + A1SHCURR, + CASE + WHEN (SELECT A4SHIPTYPE FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) = 'LTL' + THEN (SELECT A4RATETCP FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) * " . (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceLTL')) / 100 . ' + ELSE (SELECT A4RATETCP FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) * ' . (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceParcel')) / 100 . " + END AS FREIGHT, + A4SHIPTYPE, + A4SHIPVIA1, + A4SCAC, + A4OFSTRM + FROM ICM688M2 + LEFT JOIN ICM699M ON SHMACPKR=A5MACPKR AND SHTYPE='M3-Res-out' AND SHDATA LIKE 'Success%' AND SHSOURCE='CloseShipmentCoChargeAPI' + LEFT JOIN ICM666M ON A1DELNO=A5MACPKR AND A1ONO=A5ONO AND A1PKLN=A5BRADLN + LEFT JOIN ICM688M1 ON A4MACPKR=A5MACPKR + WHERE A5MACPKR IN ( + SELECT DISTINCT AYMACPKR + FROM ICM695M1 + WHERE AYSTATUS IN ('Z','z') AND AYAPR8N002 = $rEPORTDATEDisp + ) + AND A5CO=$cOMPANY AND A5WHS=$wHS AND A5PLANT=$pLANT"; + + $iCM688M2 = DB::connection(config('m3.connection', 'pgsql')) + ->select($selectContent); + } else { + $iCM688M2 = collect(); + } + + // Get List of Files + $allReportsUrls = self::reportUrls($wHS); + + } catch (\Throwable $th) { + Log::error($th); + } + + return view('m3::liberty-theme.pages.OrderLinesOfClosed', ['IC670M' => $iC670M, 'ICM688M2' => $iCM688M2, 'WHDDA' => $wHDDA, 'COMPANY' => $cOMPANY, 'PLANT' => $pLANT, 'WHS' => $wHS, 'REPORTDATEDisp' => $rEPORTDATEDisp, 'allReportsUrls' => $allReportsUrls]); + } + + public static function exporttoExcel(Request $request) + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOut')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut')); + ini_set('memory_limit', '1024M'); + + try { + [$cOMPANY, $pLANT, $wHS] = self::userWarehouseContext(); + + // Warehouse Table + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + $reportDate = isset($urlParams['REPORTDATE']) ? \DateTime::createFromFormat('Y-m-d', trim($urlParams['REPORTDATE']))->format('Ymd') : today()->format('Ymd'); + $toreportDate = isset($urlParams['TOREPORTDATE']) ? \DateTime::createFromFormat('Y-m-d', trim($urlParams['TOREPORTDATE']))->format('Ymd') : today()->format('Ymd'); + + $reportDateWD = isset($urlParams['REPORTDATE']) ? trim($urlParams['REPORTDATE']) : today()->format('Y-m-d'); + $toreportDateWD = isset($urlParams['TOREPORTDATE']) ? trim($urlParams['TOREPORTDATE']) : today()->format('Y-m-d'); + if ($reportDate != '' && $cOMPANY != '' && $wHS != '' && $pLANT != '') { + // Case 729: Add Currency code A1SHCURR FROM ICM666M + $selectContent = " + SELECT (SHDT || ' ' || SHTIME) AS DATECLOSED, A5MACPKR, A5ONO, + A4OFSTRM, + A5PMPWHT*A5PACKED AS WEIGHT, + A4SCAC, + A4SHIPTYPE, + (SELECT A4REFORD FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) AS A4REFORD, + A5PART, A5RSVQTY, A5PACKED, A5RSVQTY - A5PACKED AS CALCULATED_COLUMN, + A5SLUNPR * A5PACKED AS ANOTHER_CALCULATED_COLUMN, + (SELECT A4SHSHNM FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) AS A4SHSHNM , + CASE WHEN SHDT IS NULL THEN (SELECT SHDATA FROM ICM699M WHERE SHMACPKR=A5MACPKR AND SHTYPE='M3-Res-out' AND SHSOURCE='CloseShipmentCoChargeAPI' ORDER BY SHDT DESC, SHTIME DESC FETCH FIRST 1 ROWS ONLY) ELSE '' END AS REASON, + A1SHCURR, + CASE + WHEN (SELECT A4SHIPTYPE FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) = 'LTL' + THEN (SELECT A4RATETCP FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) * " . (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceLTL')) / 100 . ' + ELSE (SELECT A4RATETCP FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) * ' . (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceParcel')) / 100 . " + END AS FREIGHT + FROM ICM688M2 + LEFT JOIN ICM699M ON SHMACPKR=A5MACPKR AND SHTYPE='M3-Res-out' AND SHDATA LIKE 'Success%' AND SHSOURCE='CloseShipmentCoChargeAPI' + LEFT JOIN ICM666M ON A1DELNO=A5MACPKR AND A1ONO=A5ONO AND A1PKLN=A5BRADLN + LEFT JOIN ICM688M1 ON A4MACPKR=A5MACPKR + WHERE A5MACPKR IN ( + SELECT DISTINCT AYMACPKR + FROM ICM695M1 + WHERE AYSTATUS IN ('Z','z') AND AYAPR8N002 BETWEEN $reportDate AND $toreportDate + ) + AND A5CO=$cOMPANY AND A5WHS=$wHS AND A5PLANT=$pLANT"; + + $iCM688M2 = DB::connection(config('m3.connection', 'pgsql')) + ->select($selectContent); + + $newItem = ['DATECLOSED' => 'Close Date', 'A5MACPKR' => 'Delivery #', 'A5ONO' => 'Order #', + 'A4OFSTRM' => 'Terms', 'WEIGHT' => 'Weight', 'A4SCAC' => 'Carrier', 'A4SHIPTYPE' => 'Mode (Parcel, Air, TL or LTL)', + 'A4REFORD' => 'Order Type', 'A5PART' => 'Part #', 'A5RSVQTY' => 'Reserved', + 'A5PACKED' => 'Packed', 'CALCULATED_COLUMN' => 'Back Order Qty', 'ANOTHER_CALCULATED_COLUMN' => 'Value Packed $', 'A4SHSHNM' => 'Customer name', + 'REASON' => 'Failure Reason', 'A1SHCURR' => 'Currency Code', 'FREIGHT' => 'Freight']; + $iCM688M2Col = collect($iCM688M2); + $iCM688M2Col->prepend($newItem); + + // Count records before exporting to excel : Max 20K records are allowed + $iCM688M2Count = $iCM688M2Col->count(); + // Set Max allowed records + $maxRecords = Config::get('arrays.maxRecCL'); + if ($iCM688M2Count > $maxRecords) { + return redirect()->back()->withInput()->with('message', 'Maximum allowed records for Excel Download is: ' . number_format($maxRecords) . + ' current records: ' . number_format($iCM688M2Count) . ' , change your search criteria.'); + } + + } else { + $iCM688M2Col = ''; + } + + // Download Excel + // Add true at the end to include fields names in the Header + return app(SpreadsheetExport::class)->download($iCM688M2Col, 'Closedorderlinesreport_' . $reportDateWD . '-' . $toreportDateWD . self::XLSX_EXTENSION); + } catch (\Throwable $th) { + Log::error($th); + } + } + + public static function StoreExcelToDisk(Request $request) + { + ini_set('max_execution_time', Config::get('arrays.PHPTimeOutCL')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOutCL')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOutCL')); + ini_set('memory_limit', '1024M'); + + try { + [$cOMPANY, $pLANT, $wHS] = self::userWarehouseContext(); + + // Warehouse Table + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + $reportDate = isset($urlParams['REPORTDATE']) ? \DateTime::createFromFormat('Y-m-d', trim($urlParams['REPORTDATE']))->format('Ymd') : today()->format('Ymd'); + $toreportDate = isset($urlParams['TOREPORTDATE']) ? \DateTime::createFromFormat('Y-m-d', trim($urlParams['TOREPORTDATE']))->format('Ymd') : today()->format('Ymd'); + $reportDateWD = isset($urlParams['REPORTDATE']) ? trim($urlParams['REPORTDATE']) : today()->format('Y-m-d'); + $toreportDateWD = isset($urlParams['TOREPORTDATE']) ? trim($urlParams['TOREPORTDATE']) : today()->format('Y-m-d'); + if ($reportDate != '' && $cOMPANY != '' && $wHS != '' && $pLANT != '') { + // Case 729: Add Currency code A1SHCURR FROM ICM666M + $iCM688M2 = DB::connection(config('m3.connection', 'pgsql')) + ->select(" + SELECT (SHDT || ' ' || SHTIME) AS DATECLOSED, A5MACPKR, A5ONO, + A4OFSTRM, + A5PMPWHT*A5PACKED AS WEIGHT, + A4SCAC, + A4SHIPTYPE, + (SELECT A4REFORD FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) AS A4REFORD, + A5PART, A5RSVQTY, A5PACKED, A5RSVQTY - A5PACKED AS CALCULATED_COLUMN, + A5SLUNPR * A5PACKED AS ANOTHER_CALCULATED_COLUMN, + (SELECT A4SHSHNM FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) AS A4SHSHNM , + CASE WHEN SHDT IS NULL THEN (SELECT SHDATA FROM ICM699M WHERE SHMACPKR=A5MACPKR AND SHTYPE='M3-Res-out' AND SHSOURCE='CloseShipmentCoChargeAPI' ORDER BY SHDT DESC, SHTIME DESC FETCH FIRST 1 ROWS ONLY) ELSE '' END AS REASON, + A1SHCURR, + CASE + WHEN (SELECT A4SHIPTYPE FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) = 'LTL' + THEN (SELECT A4RATETCP FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) * " . (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceLTL')) / 100 . ' + ELSE (SELECT A4RATETCP FROM ICM688M1 WHERE A4MACPKR=A5MACPKR) * ' . (100.00 - Config::get('arrays.misc.discountCarrierRateForCustomerPriceParcel')) / 100 . " + END AS FREIGHT + FROM ICM688M2 + LEFT JOIN ICM699M ON SHMACPKR=A5MACPKR AND SHTYPE='M3-Res-out' AND SHDATA LIKE 'Success%' AND SHSOURCE='CloseShipmentCoChargeAPI' + LEFT JOIN ICM666M ON A1DELNO=A5MACPKR AND A1ONO=A5ONO AND A1PKLN=A5BRADLN + LEFT JOIN ICM688M1 ON A4MACPKR=A5MACPKR + WHERE A5MACPKR IN ( + SELECT DISTINCT AYMACPKR + FROM ICM695M1 + WHERE AYSTATUS IN ('Z','z') AND AYAPR8N002 BETWEEN $reportDate AND $toreportDate + ) + AND A5CO=$cOMPANY AND A5WHS=$wHS AND A5PLANT=$pLANT + "); + + $newItem = ['DATECLOSED' => 'Close Date', 'A5MACPKR' => 'Delivery #', 'A5ONO' => 'Order #', + 'A4OFSTRM' => 'Terms', 'WEIGHT' => 'Weight', 'A4SCAC' => 'Carrier', 'A4SHIPTYPE' => 'Mode (Parcel, Air, TL or LTL)', + 'A4REFORD' => 'Order Type', 'A5PART' => 'Part #', 'A5RSVQTY' => 'Reserved', + 'A5PACKED' => 'Packed', 'CALCULATED_COLUMN' => 'Back Order Qty', 'ANOTHER_CALCULATED_COLUMN' => 'Value Packed $', 'A4SHSHNM' => 'Customer name', + 'REASON' => 'Failure Reason', 'A1SHCURR' => 'Currency Code', 'FREIGHT' => 'Freight']; + $iCM688M2Col = collect($iCM688M2); + $iCM688M2Col->prepend($newItem); + + // Count records before exporting to excel : Max 20K records are allowed + $iCM688M2Count = $iCM688M2Col->count(); + // Set Max allowed records + $maxRecords = Config::get('arrays.maxRecCL'); + if ($iCM688M2Count > $maxRecords) { + return redirect()->back()->withInput()->with('message', 'Maximum allowed records for Excel Download is: ' . number_format($maxRecords) . + ' current records: ' . number_format($iCM688M2Count) . ' , change your search criteria.'); + } + } else { + $iCM688M2Col = ''; + } + + $prevMonthFile = self::storedReportName($wHS, $reportDateWD, $toreportDateWD); + + // MAK Store the File to Storage + app(SpreadsheetExport::class)->store($iCM688M2Col, $prevMonthFile, 'publicCL'); + + return back(); + } catch (\Throwable $th) { + Log::error($th); + } + } + + private static function userWarehouseContext(string $defaultCompany = '', string $defaultPlant = '', string $defaultWarehouse = ''): array + { + $user = trim((string) m3_user()); + if ($user === '') { + return [$defaultCompany, $defaultPlant, $defaultWarehouse]; + } + + $profile = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428CO', 'R428WH', 'R428PL') + ->where('R428US', Str::upper($user)) + ->first(); + + return [ + $profile->R428CO ?? $defaultCompany, + $profile->R428PL ?? $defaultPlant, + $profile->R428WH ?? $defaultWarehouse, + ]; + } + + private static function reportUrls(string $warehouse): array + { + $disk = Storage::disk('publicCL'); + $files = $warehouse === '321' ? $disk->files() : $disk->allFiles($warehouse); + $urls = []; + + foreach ($files as $file) { + $urls[$file] = $disk->url($file); + } + + return $urls; + } + + private static function storedReportName(string $warehouse, string $from, string $to): string + { + $name = 'Closedorderlinesreport_' . $from . '-' . $to; + + return $warehouse === '321' + ? $name . self::XLSX_EXTENSION + : $warehouse . '/' . $name . '-' . $warehouse . self::XLSX_EXTENSION; + } + + // Download File + public static function downloadFiles(Request $request) + { + $fileName = $request->filename; + if (Storage::disk('publicCL')->exists($fileName)) { + // File exists, retrieve content or URL + // $content = Storage::disk('publicCL')->get($fileName); + $fileNameOnly = strpos($fileName, '/') != false ? substr($fileName, strpos($fileName, '/') + 1) : $fileName; + + // Download the file + return Storage::disk('publicCL')->download($fileName, $fileNameOnly); + } else { + // Download the file (use code below) + } + } +} diff --git a/Modules/M3/Http/Controllers/PalletQtyController.php b/Modules/M3/Http/Controllers/PalletQtyController.php new file mode 100755 index 00000000..a7dea4e3 --- /dev/null +++ b/Modules/M3/Http/Controllers/PalletQtyController.php @@ -0,0 +1,97 @@ + 'N', 'R428US' => strtoupper(m3_user()), 'R428CO' => '', 'R428PL' => '', 'R428WH' => '']; + if (Schema::connection($connection)->hasTable('icm428m')) { + $power_user = DB::connection($connection)->table('icm428m') + ->select('R428PWRUSR', 'R428US', 'R428CO', 'R428PL', 'R428WH') + ->where('R428US', '=', strtoupper(m3_user()))->first() ?? $power_user; + } + $co = $power_user->R428CO; + $plant = $power_user->R428PL; + $whs = $power_user->R428WH; + $iCM709M = Schema::connection($connection)->hasTable('icm709m') + ? DB::connection($connection)->table('icm709m')->where('AT9CO', $co)->where('AT9PLT', $plant)->where('AT9WHS', $whs)->get() : collect(); + $iC670M = Schema::connection($connection)->hasTable('ic670m') + ? DB::connection($connection)->table('ic670m')->where('WDCO', $co)->where('WDPL', $plant)->where('WDWHS', $whs)->get() : collect(); + + return view('m3::liberty-theme.pages.palletQty', ['ICM709M' => $iCM709M, 'IC670M' => $iC670M, 'power_user' => $power_user]); + } + + // + // Process data from Add modal + // + public static function saveQtyAdd(Request $request) + { + + // Insert record to ICM709M + // var_dump($request); + // Verify record does not already exist in ICM709M + $icm709m = DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT1 from ICM709M + where AT9CO='$request->AT9CO' and AT9PLT='$request->AT9PLT' and AT9WHS='$request->AT9WHS' and AT9PART='$request->AT9PART'"); + if ($icm709m[0]->COUNT1 >= '1') { + return 'exists'; + } else { + // Verify Part# already exists in ICM630M + $ic630m = DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT1 from IC630M + where LLCO='$request->AT9CO' and LLWHNO='$request->AT9WHS' and LLPPN='$request->AT9PART'"); + if ($ic630m[0]->COUNT1 == '0') { + return 'not exist'; + } else { + DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM709M (AT9CO, AT9PLT, AT9WHS, AT9PART, AT9QTY, AT9WRN) + values ('$request->AT9CO', '$request->AT9PLT', '$request->AT9WHS', '$request->AT9PART', '$request->AT9QTY', '$request->AT9WRN')"); + + return 'success'; + } + } + } + + public static function saveQtyAdd2(Request $request) + { + + // Insert record to ICM709M + // var_dump($request); + // Verify record does not already exist in ICM709M + // DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM709M (AT9CO, AT9PLT, AT9WHS, AT9PART, AT9QTY) + // values ('$request->AT9CO', '$request->AT9PLT', '$request->AT9WHS', '$request->AT9PART', '$request->AT9QTY')"); + // $data=['AT9CO'=>$request->AT9CO, 'AT9PLT'=>$request->AT9PLT, 'AT9WHS'=>$request->AT9WHS, 'AT9PART'=>$request->AT9PART, + // 'AT9QTY'=>$request->AT9QTY, 'AT9WRN'=>$request->AT9WRN]; + // $insertSQL = DB::connection(config('m3.connection', 'pgsql'))->table('icm709m')->insert($data); + DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM709M (AT9CO, AT9PLT, AT9WHS, AT9PART, AT9QTY, AT9WRN) + values ('$request->AT9CO', '$request->AT9PLT', '$request->AT9WHS', '$request->AT9PART', '$request->AT9QTY', '$request->AT9WRN')"); + + // if($insertSQL) { + return 'success'; + // } + + } + + // + // Process data from Edit modal + // + public static function saveQtyEdit(Request $request) + { + + // where AT9CO='$request->AT9CO' and AT9PLT='$request->AT9PLT' and AT9WHS='$request->AT9WHS' and AT9PART='$request->AT9PART'"); + // var_dump($icm709m); + + DB::connection(config('m3.connection', 'pgsql'))->update("update ICM709M + set AT9QTY='$request->AT9QTY', AT9WRN='$request->AT9WRN' + where AT9CO='$request->AT9CO' and AT9PLT='$request->AT9PLT' and AT9WHS='$request->AT9WHS' and AT9PART='$request->AT9PART'"); + + return 'success'; + + } +} diff --git a/Modules/M3/Http/Controllers/PendingClosureController.php b/Modules/M3/Http/Controllers/PendingClosureController.php new file mode 100755 index 00000000..97252319 --- /dev/null +++ b/Modules/M3/Http/Controllers/PendingClosureController.php @@ -0,0 +1,114 @@ +table('icm428m') + ->select('R428US', 'R428CO', 'R428WH', 'R428PL') + ->where('R428US', '=', strtoupper(m3_user())) + ->first(); + $user = $iCM428M->R428US; + $co = $iCM428M->R428CO; + $whs = $iCM428M->R428WH; + $plant = $iCM428M->R428PL; + + // ICM705M1 Statement + $sqlstmt = "select APMANIFEST,APDOCKDOOR,APCARRIER,APTRUCKIDT,APSPARE1,APLDSTRU,APLDSTRD,APLDSTRT, + APLDCLOU,APLDCLOD,APLDCLOT,APCO,APWHS,APPLT,APSPARE2,APLDCLOZ + from ICM705M1 + where APSPARE2 in ('','P') and APCO='$co' and APWHS='$whs' and APPLT='$plant'"; + + $iCM705M1 = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + + $iCM698Ma = []; + $iCM699Ma = []; + foreach ($iCM705M1 as $val) { + $sqlstmt1 = "select LGUSER,LGCONFDT,LGCONFTM + from ICM698M + where LGCO='$val->APCO' and LGWHS='$val->APWHS'and LGURL='op605api.php' + and LGRESPONSE like 'Close of Sentinel Manifest%' + and LGRESPONSE like '%' || right('000000000' || '$val->APMANIFEST',9) || '%'"; + $iCM698M = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt1); + $iCM698Ma[$val->APMANIFEST]['TMSUSER'] = ''; + $iCM698Ma[$val->APMANIFEST]['TMSDATE'] = ''; + $iCM698Ma[$val->APMANIFEST]['TMSTIME'] = ''; + foreach ($iCM698M as $val2) { + $iCM698Ma[$val->APMANIFEST]['TMSUSER'] = $val2->LGUSER; + $iCM698Ma[$val->APMANIFEST]['TMSDATE'] = $val2->LGCONFDT; + $iCM698Ma[$val->APMANIFEST]['TMSTIME'] = $val2->LGCONFTM; + } + + $iCM699MSel1 = "select SHMACPKR,SHDT,SHTIME from ICM699M + WHERE SHMACPKR='$val->APMANIFEST' AND SHCO='$co' AND SHWHS='$whs' + AND SHSOURCE='CloseShipmentCoChargeAPI' AND SHERROR='' AND SHTYPE='M3-Req-out' limit 1"; + $iCM699MSel = DB::connection(config('m3.connection', 'pgsql'))->select($iCM699MSel1); + foreach ($iCM699MSel as $val2) { + $iCM699Ma[$val2->SHMACPKR]['SHDT'] = $val2->SHDT; + $iCM699Ma[$val2->SHMACPKR]['SHTIME'] = $val2->SHTIME; + } + } + + $sqlstmt = "select count(*) as COUNT1 from ICM699M + where SHCO='$co' and SHWHS='$whs' and SHTYPE like '%M3%' and SHERROR='X' + and SHSOURCE='CloseShipmentCoChargeAPI'"; + $iCM699M = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + + // Get Unprocessed Orders + $unprocessedArr = []; + $sqlstmt3 = "WITH TEMPFILE AS ( + SELECT A4MACPKR,A4SPKRFUD,(SELECT AYAPRF1551 FROM ICM695M1 WHERE AYMACPKR=A4MACPKR AND AYSLWHS='$whs' FETCH FIRST 1 ROWS ONLY) AS MF FROM ICM688M1 + WHERE A4PICKSTS='B' AND A4WHS='$whs' ORDER BY A4SPKRFUD + ) + SELECT APMANIFEST,APSPARE2 FROM ICM705M1 WHERE APMANIFEST IN (SELECT DISTINCT MF FROM TEMPFILE) AND APSPARE2='X' AND APWHS='$whs' "; + // AND APSPARE2!='' + // dump($sqlstmt3); + $uproccessedOrders = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt3); + foreach ($uproccessedOrders as $UproccessedOrder) { + $unprocessedArr[] = ' ' . + trim($UproccessedOrder->APMANIFEST) . ''; + } + + return view( + 'm3::liberty-theme.pages.pendingClosure', + ['ICM705M1' => $iCM705M1, 'ICM698Ma' => $iCM698Ma, 'ICM699M' => $iCM699M, 'user' => $user, 'request' => $request, 'unprocessedArr' => $unprocessedArr, 'ICM699Ma' => $iCM699Ma], + ); + + } + + public static function allowRetry(Request $request) + { + // Get URL PARAMS + $urlParams = count($request->all()) > 0 ? $request->all() : ''; + $mANIFEST = isset($urlParams['MANIFEST']) ? $urlParams['MANIFEST'] : ''; + $aPCO = isset($urlParams['APCO']) ? $urlParams['APCO'] : ''; + $aPWHS = isset($urlParams['APWHS']) ? $urlParams['APWHS'] : ''; + + try { + + DB::connection(config('m3.connection', 'pgsql'))->table('icm705m1') + ->where('APCO', $aPCO) + ->where('APWHS', $aPWHS) + ->where('APMANIFEST', '=', $mANIFEST) + ->update(['APSPARE2' => '']); + + return response()->json([ + 'code' => '200', + 'status' => 'Success', + 'message' => 'Manifest Closing submitted', + ]); + } catch (\Throwable $th) { + report($th); + } + + } +} diff --git a/Modules/M3/Http/Controllers/ReplenishSettingsController.php b/Modules/M3/Http/Controllers/ReplenishSettingsController.php new file mode 100755 index 00000000..a3bd9f76 --- /dev/null +++ b/Modules/M3/Http/Controllers/ReplenishSettingsController.php @@ -0,0 +1,181 @@ +table('icm658m')->get(); + // Warehouse Table + // $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m')->get(); + + // Get Logged user Id + $userId = m3_user() !== '' ? strtoupper(m3_user()) : ''; + // $userId = 'E1135818'; // Brad : E1135818 Malak : E2011812 ACOM_PDF + $connection = config('m3.connection', 'pgsql'); + $iCM428M = Schema::connection($connection)->hasTable('icm428m') + ? DB::connection($connection)->table('icm428m')->where('R428US', $userId)->where('R428STS', 'A')->first() + : null; + + $userCO = isset($iCM428M->R428CO) ? $iCM428M->R428CO : ''; + $userPL = isset($iCM428M->R428PL) ? $iCM428M->R428PL : ''; + $userWH = isset($iCM428M->R428WH) ? $iCM428M->R428WH : ''; + + if ($userCO != '') { + // Warehouse Table + $iC670M = Schema::connection($connection)->hasTable('ic670m') + ? DB::connection($connection)->table('ic670m') + ->where('WDCO', $userCO) + ->where('WDPL', $userPL) + ->where('WDWHS', $userWH) + ->get() + : []; + } else { + $iC670M = []; + } + + // FROM PRDAT.REFERPS t1 LEFT JOIN ( SELECT R658CO,R658PL,R658WH,R658LC,R658PN,R658MQ,R658RQ,R658TL,R658RMQ, + // TRIM(R658WH)||TRIM(R658LC)||TRIM(R658PN) AS FULLID FROM EWOBJTST.ICM658M + // ) t2 ON t1.REFKEY = t2.FULLID WHERE t1.REFCAT = '658'"; + // $rEFCAT658 = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + // dd($rEFCAT658); + + return view('m3::liberty-theme.pages.ReplenishSettings', ['IC670M' => $iC670M]); + // 'REFCAT658', + } + + public function store(Request $request) + { + + $formInputs = $request->all(); + $formInputs = array_filter($formInputs); + unset($formInputs['_token']); + + $formInputs['R658IZLCF'] = isset($formInputs['R658IZLCF']) ? $formInputs['R658IZLCF'] : '0'; + + ICM658M::insert($formInputs); + + return redirect()->route('m3.replenishmentSettings.index'); + } + + public function update(Request $request) + { + $r658PN = trim((string) ($request->R658PN ?? '')); + $r658CO = trim((string) ($request->R658CO ?? '')); + $r658PL = trim((string) ($request->R658PL ?? '')); + $r658WH = trim((string) ($request->R658WH ?? '')); + $r658MQ = trim($request->R658MQ); + $r658RQ = trim($request->R658RQ); + $r658RMQ = trim($request->R658RMQ); + $r658TL = trim($request->R658TL); + $r658IZLCF = trim((string) ($request->R658IZLCF ?? '0')); + + DB::connection(config('m3.connection', 'pgsql'))->table('icm658m') + ->where('R658PN', $r658PN) + ->where('R658CO', $r658CO) + ->where('R658PL', $r658PL) + ->where('R658WH', $r658WH) + ->update(['R658MQ' => $r658MQ, 'R658RQ' => $r658RQ, 'R658RMQ' => $r658RMQ, 'R658TL' => $r658TL, 'R658IZLCF' => $r658IZLCF]); + + return redirect()->route('m3.replenishmentSettings.index'); + } + + public function deleteRec(Request $request) + { + $r658PN = trim($request->R658PN); + $r658CO = trim($request->R658CO); + $r658LC = trim($request->R658LC); + $r658PL = trim($request->R658PL); + $r658WH = trim($request->R658WH); + + DB::connection(config('m3.connection', 'pgsql'))->table('icm658m') + ->where('R658PN', $r658PN) + ->where('R658CO', $r658CO) + ->where('R658LC', $r658LC) + ->where('R658PL', $r658PL) + ->where('R658WH', $r658WH) + ->delete(); + + return response()->json(['success' => 'Record Deleted']); + } + + public function checkRecExit(Request $request) + { + $params = []; + parse_str($request['data'], $params); + $paramsObj = (object) $params; + + $r658PN = trim($paramsObj->R658PN); + $r658CO = trim($paramsObj->R658CO); + $r658LC = trim($paramsObj->R658LC); + $r658PL = trim($paramsObj->R658PL); + $r658WH = trim($paramsObj->R658WH); + + $recordExistSQL = DB::connection(config('m3.connection', 'pgsql'))->table('icm658m') + ->where('R658PN', $r658PN) + ->where('R658CO', $r658CO) + ->where('R658LC', $r658LC) + ->where('R658PL', $r658PL) + ->where('R658WH', $r658WH) + ->first(); + $recordExists = $recordExistSQL == null ? true : false; + + return response()->json(['recordExists' => $recordExists]); + } + + public function datatables(Request $request) + { + // Replenishment Table + // $rEFCAT658 = DB::connection(config('m3.connection', 'pgsql'))->table('icm658m')->get(); + // Warehouse Table + // $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m')->get(); + + // Get Logged user Id + $userId = m3_user() !== '' ? strtoupper(m3_user()) : ''; + // $userId = 'E1135818'; // Brad : E1135818 Malak : E2011812 ACOM_PDF + $connection = config('m3.connection', 'pgsql'); + $iCM428M = Schema::connection($connection)->hasTable('icm428m') + ? DB::connection($connection)->table('icm428m')->where('R428US', $userId)->where('R428STS', 'A')->first() + : null; + + $userCO = isset($iCM428M->R428CO) ? $iCM428M->R428CO : ''; + $userPL = isset($iCM428M->R428PL) ? $iCM428M->R428PL : ''; + $userWH = isset($iCM428M->R428WH) ? $iCM428M->R428WH : ''; + + if ($userCO != '') { + // Replenishment Table + $rEFCAT658 = DB::connection(config('m3.connection', 'pgsql'))->table('icm658m') + ->select('*') + ->where('R658CO', $userCO) + ->where('R658PL', $userPL) + ->where('R658WH', $userWH) + ->orderBy('R658CO', 'asc'); + + // Warehouse Table + // $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m') + // ->where('WDCO',$userCO) + // ->where('WDPL',$userPL) + // ->where('WDWHS',$userWH) + // ->get(); + } else { + $rEFCAT658 = []; + } + + // FROM PRDAT.REFERPS t1 LEFT JOIN ( SELECT R658CO,R658PL,R658WH,R658LC,R658PN,R658MQ,R658RQ,R658TL,R658RMQ, + // TRIM(R658WH)||TRIM(R658LC)||TRIM(R658PN) AS FULLID FROM EWOBJTST.ICM658M + // ) t2 ON t1.REFKEY = t2.FULLID WHERE t1.REFCAT = '658'"; + // $rEFCAT658 = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + // dd($rEFCAT658); + + return Datatables::of($rEFCAT658)->addIndexColumn()->make(true); + } +} diff --git a/Modules/M3/Http/Controllers/SentinelController.php b/Modules/M3/Http/Controllers/SentinelController.php new file mode 100755 index 00000000..6d32858c --- /dev/null +++ b/Modules/M3/Http/Controllers/SentinelController.php @@ -0,0 +1,65 @@ +AYINTBOX) ? trim($request->AYINTBOX) : ''; + $aYCO = isset($request->AYCO) ? trim($request->AYCO) : ''; + $aYWHS = isset($request->AYWHS) ? trim($request->AYWHS) : ''; + $aYUSER = isset($request->AYUSER) ? trim($request->AYUSER) : ''; + + if ($aYINTBOX != '') { + // Get the record from ICM695M1 + $iCM695M1Sel = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->select() + ->where('AYINTBOX', $aYINTBOX) + ->where('AYCO', $aYCO) + ->where('AYWHS', $aYWHS) + ->where('AYSTATUS', '') + ->first(); + + $allowDeletion = ! empty($iCM695M1Sel->AYSENTPKR); + + if ($allowDeletion) { + $timestamp = date('Y-m-d H:i:s.u'); + $date1 = date('Ymd'); + $time1 = date('His'); + + // Delete Records from ICM695M1 And ICM695M2 + DB::connection(config('m3.connection', 'pgsql'))->table('icm695m1') + ->where('AYINTBOX', $aYINTBOX) + ->where('AYCO', $aYCO) + ->where('AYWHS', $aYWHS) + ->delete(); + + DB::connection(config('m3.connection', 'pgsql'))->table('icm695m2') + ->where('AZINTBOX', $aYINTBOX) + ->where('AZCO', $aYCO) + ->where('AZWHS', $aYWHS) + ->delete(); + + // Log the event as an unusual transaction to appear on SPD bottom right: + $insertValues = "'$iCM695M1Sel->AYCO', '$iCM695M1Sel->AYWHS', '$iCM695M1Sel->AYSENTPKR', '$iCM695M1Sel->AYMACPKR', '$iCM695M1Sel->AYONO', '$iCM695M1Sel->AYRLNO', '$iCM695M1Sel->AYSHNO', '', 'Box $aYINTBOX emptied and repacked', + '$timestamp', '$date1', '$time1', '$aYUSER','$timestamp', '$date1', '$time1', '$aYUSER','$aYINTBOX'"; + + DB::connection(config('m3.connection', 'pgsql'))->insert("INSERT INTO ICM689M + (A7CO, A7WHS, A7SENTPKR, A7MACPKR, A7ONO, A7RLNO, A7SHNO, A7SOURCE, A7ERRMSG, A7DISRAITS, A7DISRAID, A7DISRAIT, A7DISRAIU, A7DISRESTS ,A7DISRESD ,A7DISREST ,A7DISRESU , A7SPR15A01) + values ($insertValues)"); + + return response()->json(['success' => true, 'message' => 'Line Deleted']); + } else { + return response()->json(['success' => false, 'message' => 'Line already packed']); + } + } else { + return response()->json(['success' => false, 'message' => 'Line missing']); + } + + } +} diff --git a/Modules/M3/Http/Controllers/ShipToController.php b/Modules/M3/Http/Controllers/ShipToController.php new file mode 100755 index 00000000..116c6860 --- /dev/null +++ b/Modules/M3/Http/Controllers/ShipToController.php @@ -0,0 +1,185 @@ +ajax()) { + $data = ShipTo::select('*'); + + return Datatables::of($data) + ->addIndexColumn() + ->addColumn('checkbox', function ($row) { + return ''; + }) + ->addColumn('action', function ($row) { + $actionBtn = 'Edit '; + $actionBtn .= '
    '; + $actionBtn .= csrf_field() . method_field('DELETE'); + $actionBtn .= '
    '; + + return $actionBtn; + }) + ->rawColumns(['checkbox', 'action']) + ->make(true); + } + + return view('m3::liberty-theme.pages.ship-to.index'); + } + + public function create() + { + // US + $uSstates = USStates::all(); + // CA + $cAstates = CAProvinces::all(); + + // All States + $states = array_merge($uSstates, $cAstates); + + return view('m3::liberty-theme.pages.ship-to.create', compact('states')); + } + + public function store(Request $request) + { + $validated = $request->validate( + [ + 'AUSTCN' => 'nullable|max:11', + 'AUSHSHNM' => 'required|max:36', + 'AUSHSHA1' => 'required|max:36', + 'AUSHSHA2' => 'required|max:36', + 'AUSHSHA3' => 'nullable|max:36', + 'AUSHSHA4' => 'nullable|max:36', + 'AUSHSHCI' => 'required|max:20', + 'AUSHSHST' => 'required|max:2', + 'AUSHSHZP' => 'required|max:10', + 'AUSHSHCT' => 'required|max:3', + 'AUSHWHS' => 'required|max:3', + ], + [ + 'AUSHSHNM.required' => 'Name is required', + 'AUSHSHA1.required' => 'Address 1 is required', + 'AUSHSHA2.required' => 'Address 2 is required', + 'AUSHSHCI.required' => 'City is required', + 'AUSHSHST.required' => 'State is required', + 'AUSHSHZP.required' => 'Zip code is required', + 'AUSHSHCT.required' => 'Country is required', + 'AUSHWHS.required' => 'Warehouse is required', + + 'AUSTCN.max' => 'Customer Number cannot exceed 11 characters', + 'AUSHSHNM.max' => 'Name cannot exceed 36 characters', + 'AUSHSHA1.max' => 'Address 1 cannot exceed 36 characters', + 'AUSHSHA2.max' => 'Address 2 cannot exceed 36 characters', + 'AUSHSHA3.max' => 'Address 3 cannot exceed 36 characters', + 'AUSHSHA4.max' => 'Address 4 cannot exceed 36 characters', + 'AUSHSHCI.max' => 'City cannot exceed 20 characters', + 'AUSHSHST.max' => 'State cannot exceed 2 characters', + 'AUSHSHZP.max' => 'Zip code cannot exceed 10 characters', + 'AUSHSHCT.max' => 'Country cannot exceed 3 characters', + 'AUSHWHS.max' => 'Warehouse cannot exceed 3 characters', + ], + ); + $validated['AUSTCN'] = $validated['AUSTCN'] ?? ' '; + + $model = new ShipTo; + $model->fill($validated); + $success = $model->save(); + if ($success) { + return redirect()->route('m3.ship-to.index')->with('success', 'Record created successfully.'); + } else { + return redirect()->back() + ->withErrors(['unique' => 'The combination of ZipCode and Warehouse must be unique.']) + ->withInput(); + } + } + + public function edit($aushshzp, $aushwhs) + { + // US + $uSstates = USStates::all(); + // CA + $cAstates = CAProvinces::all(); + + // All States + $states = array_merge($uSstates, $cAstates); + + $shipTo = ShipTo::where('AUSHSHZP', $aushshzp) + ->where('AUSHWHS', $aushwhs) + ->firstOrFail(); + + return view('m3::liberty-theme.pages.ship-to.edit', compact('shipTo', 'states')); + } + + public function update(Request $request, $aushshzp, $aushwhs) + { + $validated = array_map(function ($value) { + return $value === null ? '' : $value; + }, $request->validate( + [ + 'AUSTCN' => 'nullable|string|max:11', + 'AUSHSHNM' => 'required|max:36', + 'AUSHSHA1' => 'required|max:36', + 'AUSHSHA2' => 'required|max:36', + 'AUSHSHA3' => 'nullable|string|max:36', + 'AUSHSHA4' => 'nullable|string|max:36', + 'AUSHSHCI' => 'required|max:20', + 'AUSHSHST' => 'required|max:2', + 'AUSHSHCT' => 'required|max:3', + ], + [ + 'AUSHSHNM.required' => 'Name is required', + 'AUSHSHA1.required' => 'Address 1 is required', + 'AUSHSHA2.required' => 'Address 2 is required', + 'AUSHSHCI.required' => 'City is required', + 'AUSHSHST.required' => 'State is required', + 'AUSHSHZP.required' => 'Zip code is required', + 'AUSHSHCT.required' => 'Country is required', + 'AUSHWHS.required' => 'Warehouse is required', + + 'AUSTCN.max' => 'Customer Number cannot exceed 11 characters', + 'AUSHSHNM.max' => 'Name cannot exceed 36 characters', + 'AUSHSHA1.max' => 'Address 1 cannot exceed 36 characters', + 'AUSHSHA2.max' => 'Address 2 cannot exceed 36 characters', + 'AUSHSHA3.max' => 'Address 3 cannot exceed 36 characters', + 'AUSHSHA4.max' => 'Address 4 cannot exceed 36 characters', + 'AUSHSHCI.max' => 'City cannot exceed 20 characters', + 'AUSHSHST.max' => 'State cannot exceed 2 characters', + 'AUSHSHZP.max' => 'Zip code cannot exceed 10 characters', + 'AUSHSHCT.max' => 'Country cannot exceed 3 characters', + 'AUSHWHS.max' => 'Warehouse cannot exceed 3 characters', + ], + )); + + $updated = ShipTo::where('AUSHSHZP', $aushshzp) + ->where('AUSHWHS', $aushwhs) + ->update($validated); + + if ($updated) { + return redirect()->route('m3.ship-to.index')->with('success', 'Record updated successfully.'); + } else { + return redirect()->route('m3.ship-to.index')->with('error', 'Record could not be updated.'); + } + } + + public function destroy($aushshzp, $aushwhs) + { + $deleted = ShipTo::where('AUSHSHZP', $aushshzp) + ->where('AUSHWHS', $aushwhs) + ->delete(); + + if ($deleted) { + return redirect()->route('m3.ship-to.index')->with('success', 'Record deleted successfully.'); + } else { + return redirect()->route('m3.ship-to.index')->with('error', 'Record not found or could not be deleted.'); + } + + } +} diff --git a/Modules/M3/Http/Controllers/UserControlController.php b/Modules/M3/Http/Controllers/UserControlController.php new file mode 100755 index 00000000..2e59ff81 --- /dev/null +++ b/Modules/M3/Http/Controllers/UserControlController.php @@ -0,0 +1,293 @@ +hasTable('icm428m')) { + $profile = DB::connection($connection)->table('icm428m')->where('R428US', strtoupper(m3_user()))->first(); + } + $co = $profile->R428CO ?? ''; + $whs = $profile->R428WH ?? ''; + $iCM428M = Schema::connection($connection)->hasTable('icm428m') + ? DB::connection($connection)->table('icm428m')->where('R428CO', $co)->where('R428WH', $whs)->get() : collect(); + $uSER_INFO = Schema::connection($connection)->hasTable('icm428m') + ? DB::connection($connection)->table('icm428m')->selectRaw('R428US as USERPRF, R428STS as STATUS, NULL as DATE_EXPIRED, NULL as EXPIRED')->get()->all() : []; + $power_user = [(object) ['R428PWRUSR' => $profile->R428PWRUSR ?? 'N', 'R428CO' => $co, 'R428PL' => $profile->R428PL ?? '', 'R428WH' => $whs]]; + $iC670M = Schema::connection($connection)->hasTable('ic670m') + ? DB::connection($connection)->table('ic670m')->get() : collect(); + + return view('m3::liberty-theme.pages.userControl', ['ICM428M' => $iCM428M, 'IC670M' => $iC670M, 'power_user' => $power_user, 'USER_INFO' => $uSER_INFO]); + } + + // + // Process data from Add modal + // + public static function saveUserAdd(Request $request) + { + + if ($request->R428EMPCDE == '') { + $request->R428EMPCDE = 0; + } + + // Insert record to ICM428M + // dump($request); + // Validate user profile exists on the system + $usrprf = [(object) ['COUNT' => 0]]; // PostgreSQL/Core owns M3 profiles; no QSYS2 lookup. + + // Validate employee code exists in LBPF file + // if($request->R428EMPCDE>0) { + // $empcde=DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT2 from LBPF where EMPNO='$request->R428EMPCDE'"); + // if($empcde[0]->COUNT2=="0") { + // #echo ""; + // return "error empcd"; + // } + // } + $icm428m = DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT1 from ICM428M where R428US='$request->R428US'"); + if ($icm428m[0]->COUNT1 == '1') { + return 'error exists'; + } else { + + if ($usrprf[0]->COUNT == '1') { + DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM428M + (R428CO, R428PL, R428WH, R428STS, R428US, R428FIRST, R428FAMILY, R428EMAIL, R428EMPCDE, R428ADMUSR, R428PWRUSR, MENU2OPT, MENU3OPT, MENU4OPT, MENU5OPT, MENU6OPT, R42811A) + values ('$request->R428CO', '$request->R428PL', '$request->R428WH', '$request->R428STS', '$request->R428US', '$request->R428FIRST', + '$request->R428FAMILY', '$request->R428EMAIL', $request->R428EMPCDE, '$request->R428ADMUSR', '$request->R428PWRUSR', + 'NN" . $request->MENU2OPT3 . 'NNN' . $request->MENU2OPT7 . $request->MENU2OPT8 . "N', '" . $request->MENU3OPT1 . $request->MENU3OPT2 . "NNNNNNN', + '" . $request->MENU4OPT1 . $request->MENU4OPT2 . $request->MENU4OPT3 . "NNNNNN', + '" . $request->MENU5OPT1 . $request->MENU5OPT2 . $request->MENU5OPT3 . 'N' . $request->MENU5OPT5 . "NNNN','" . $request->MENU6OPT1 . $request->MENU6OPT2 . $request->MENU6OPT3 . "','" . $request->R42811A . "')"); + + return 'success'; + } else { + + // CL program call here (ewobjtst.)ICMUSRPRF parms(R428US, R428FIRST, R428FAMILY) + // connect to toolkit using DB2 credentials (can also leave blank for default authority) + try { + $conn = app(PostgresProgramBridge::class); + } catch (\Throwable $e) { + // Determine reason for failure. + // Probably database authentication error or invalid or unreachable database. + return self::programBridgeConnectionError($e); + } + $conn->setOptions(['persistent' => false, 'stateless' => true, 'debug' => true, 'debugLogFile' => '/www/sentm3test/htdocs/M3/storage/logs/toolkit_debug.log']); + // Add LIB + // $result = $conn->CLCommand('ADDLIBLE LIB(MPDAT10)'); + // define several input/output params + $params = []; + $params[] = $conn->AddParameterChar('in', 10, 'User profile', 'E#iUsrPrf', $request->R428US); + $params[] = $conn->AddParameterChar('in', 20, 'First name', 'FIRST', $request->R428FIRST); + $params[] = $conn->AddParameterChar('in', 30, 'Family name', 'FAMILY', $request->R428FAMILY); + // # $result = $conn->PgmCall(Config::get('eproconf.misc.PGM1'), Config::get('eproconf.misc.libname4'), $params, array(), array()); + $result = $conn->PgmCall('ICMUSRPRF', 'EWOBJ', $params, [], []); + if (! $result) { + + return 'error profile2'; + } else { + // Successful Call : User profile created with default password + // dd($result); + // echo ""; + DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM428M + (R428CO, R428PL, R428WH, R428STS, R428US, R428FIRST, R428FAMILY, R428EMAIL, R428EMPCDE, R428ADMUSR, R428PWRUSR, MENU2OPT, MENU3OPT, MENU4OPT, MENU5OPT, MENU6OPT, R42811A,R42821A) + values ('$request->R428CO', '$request->R428PL', '$request->R428WH', '$request->R428STS', '$request->R428US', '$request->R428FIRST', + '$request->R428FAMILY', '$request->R428EMAIL', $request->R428EMPCDE, '$request->R428ADMUSR', '$request->R428PWRUSR', + 'NN" . $request->MENU2OPT3 . 'NNN' . $request->MENU2OPT7 . $request->MENU2OPT8 . "N', '" . $request->MENU3OPT1 . $request->MENU3OPT2 . "NNNNNNN', + '" . $request->MENU4OPT1 . $request->MENU4OPT2 . $request->MENU4OPT3 . "NNNNNN', + '" . $request->MENU5OPT1 . $request->MENU5OPT2 . $request->MENU5OPT3 . 'N' . $request->MENU5OPT5 . "NNNN','" . $request->MENU6OPT1 . $request->MENU6OPT2 . $request->MENU6OPT3 . "','" . $request->R42811A . "','" . $request->R42821A . "')"); + + return 'success2'; + } + // #kd return "error profile"; + } + + } + } + + // + // Process data from Edit modal + // + public static function saveUserEdit(Request $request) + { + + if ($request->R428EMPCDE == '') { + $request->R428EMPCDE = 0; + } + + // Validate employee code exists in LBPF file + // dump($request->R428EMPCDE); + // if($request->R428EMPCDE>0) { + // $sqlstmt="select count(*) as COUNT from LBPF where EMPNO='$request->R428EMPCDE'"; + // #echo "$sqlstmt
    "; + // $empcde=DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + // #dump($empcde); + // if($empcde[0]->COUNT=="0") { + // #echo ""; + // return "error empcd"; + // } + // } + + // Update record to ICM428M + + $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->select("select * from ICM428M where R428US='$request->R428US'"); + + DB::connection(config('m3.connection', 'pgsql'))->update("update ICM428M + set R428CO='$request->R428CO', R428PL='$request->R428PL', R428WH='$request->R428WH', R428STS='$request->R428STS', R428FIRST='$request->R428FIRST', + R428FAMILY='$request->R428FAMILY', R428EMAIL='$request->R428EMAIL', R428EMPCDE=$request->R428EMPCDE, R428ADMUSR='$request->R428ADMUSR', + R428PWRUSR='$request->R428PWRUSR', + MENU2OPT='" . substr($iCM428M[0]->MENU2OPT, 0, 2) . $request->MENU2OPT3 . substr($iCM428M[0]->MENU2OPT, 3, 3) . $request->MENU2OPT7 . $request->MENU2OPT8 . "', + MENU3OPT='" . $request->MENU3OPT1 . $request->MENU3OPT2 . substr($iCM428M[0]->MENU3OPT, 2, -1) . "', + MENU4OPT='" . $request->MENU4OPT1 . $request->MENU4OPT2 . $request->MENU4OPT3 . substr($iCM428M[0]->MENU4OPT, 3, -1) . "', + MENU5OPT='" . $request->MENU5OPT1 . $request->MENU5OPT2 . $request->MENU5OPT3 . substr($iCM428M[0]->MENU5OPT, 3, 1) . $request->MENU5OPT5 . substr($iCM428M[0]->MENU5OPT, 5, -1) . "', + MENU6OPT='" . $request->MENU6OPT1 . $request->MENU6OPT2 . $request->MENU6OPT3 . substr($iCM428M[0]->MENU6OPT, 3, -1) . "', + R42811A='" . $request->R42811A . "',R42821A='" . $request->R42821A . "' + where R428US='$request->R428US'"); + + return 'success'; + + } + + // 590 + public static function callCL(Request $request) + { + + // connect to toolkit using DB2 credentials (can also leave blank for default authority) + try { + $conn = app(PostgresProgramBridge::class); + } catch (\Throwable $e) { + // Determine reason for failure. + // Probably database authentication error or invalid or unreachable database. + $code = $e->getCode(); + $msg = $e->getMessage(); + + switch ($code) { + case 8001: + // "Authorization failure on distributed database connection attempt" + // Usually means a wrong DB2 user or password + break; + case 42705: + break; + default: + break; + } + } + + // Add LIB + // $result = $conn->CLCommand('ADDLIBLE LIB(MPDAT10)'); + + // define several input/output params + $params = []; + + // AddParameterChar($io, $size, $comment, $varName, $value, $varying, $dimension) + // Add Warehouse Param + $params[] = $conn->AddParameterChar('in', 10, 'userid', 'USERID', $request->USERID); + $params[] = $conn->AddParameterChar('in', 1, 'action', 'ACTION', $request->ACTION); + + // AddParameterPackDec($io, $length, $scale, $comment, $varName, $value,$dimension) + // Add Delivery Note Param + + // Start Time Tracking + // $start = microtime(true); + + // Config::get('eproconf.misc.PGM1'), Config::get('eproconf.misc.libname4') + // ICM700C EWOBJTST ICM700C ICM700CSBM + $result = $conn->PgmCall('ICMCHGPRF', 'EWOBJ', $params, [], []); + + if (! $result) { + echo ""; + + return 'error'; + } + // Successful Call + else { + if ($request->ACTION == 'P') { + echo ""; + } + if ($request->ACTION == 'R') { + echo ""; + } + echo ""; + } + + // if ($pGMERRORS!="") { + // // return back()->withMessage('Can not Create PR: '.$pGMERRORS); + // dump($pGMERRORS); + // } + // else{ + // // return $AWREQN; + // } + } + + // 765 + public static function savePassword(Request $request) + { + + ini_set('max_execution_time', Config::get('arrays.PHPTimeOut')); + ini_set('max_input_time', Config::get('arrays.PHPTimeOut')); + ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut')); + + // echo "B3
    "; + // connect to toolkit using DB2 credentials (can also leave blank for default authority) + try { + $conn = app(PostgresProgramBridge::class); + } catch (\Throwable $e) { + $code = $e->getCode(); + $msg = $e->getMessage(); + + switch ($code) { + case 8001: + // "Authorization failure on distributed database connection attempt" + // Usually means a wrong DB2 user or password + break; + case 42705: + break; + default: + break; + } + } + + $result = $conn->CLCommand('QSYS/CHGUSRPRF USRPRF(' . $request->R428US_PWD . ') PASSWORD(' . $request->NEW_PASSWORD . ') STATUS(*ENABLED) PWDEXP(*NO)'); + + if (! $result) { + dump($pGMERRORS); + echo ""; + + return 'error pwd'; + } + // Successful Call + else { + return 'success'; + } + + } + + private static function programBridgeConnectionError(\Throwable $exception): string + { + $code = (int) $exception->getCode(); + + return match ($code) { + 8001 => 'error profile3', + 42705 => 'error profile4', + default => 'error profile5', + }; + } +} diff --git a/Modules/M3/Http/Controllers/UserPickingStats4.php b/Modules/M3/Http/Controllers/UserPickingStats4.php new file mode 100755 index 00000000..d9f42cbb --- /dev/null +++ b/Modules/M3/Http/Controllers/UserPickingStats4.php @@ -0,0 +1,297 @@ +dates)) { + $date = $request->dates; + $starting = $date; + } else { + $starting = date('Y-m-d', strtotime('-1 days')); + } + + // #$min_work_hours_for_break = 4; + + // #$ignore_picks_that_last_longer_than_this_many_hours = 8; + $ignore_picks_that_last_longer_than_this_many_hours = implode(',', Config::get('arrays.ignore_picks_that_last_longer_than_this_many_hours')); + + // $user_array = Config::get('arrays.user_array'); + // 618 + // Get Logged User CO & WH + // Get Users from ICM428M + $co = ''; + $whs = ''; + $iCM428M = []; + $schema = Schema::connection(config('m3.connection', 'pgsql')); + if ($schema->hasTable('icm428m')) { + $profile = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->select('R428US', 'R428CO', 'R428WH') + ->where('R428US', '=', strtoupper(m3_user())) + ->first(); + $co = $profile->R428CO ?? ''; + $whs = $profile->R428WH ?? ''; + + $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m') + ->selectRaw("R428US as userprf, (trim(R428FIRST) || ' ' || trim(R428FAMILY)) as name, R428EMPCDE as empno") + ->where('R428STS', 'A')->where('R428EMPCDE', '!=', 0) + ->where('R428CO', $co)->where('R428WH', $whs)->get()->all(); + } + + $user_array = []; + // while($row = odbc_fetch_object($result)) { + $x = 0; + foreach ($iCM428M as $key => $row) { + $user_array[$x]['userprf'] = trim($row->USERPRF); + $user_array[$x]['name'] = trim($row->NAME); + $user_array[$x]['empno'] = $row->EMPNO; + $x++; + } + array_multisort(array_column($user_array, 'name'), SORT_ASC, $user_array); + + // fill array of Lines per Hour per Monitor + $lph_per_monitor_array = Config::get('arrays_custom.lph_per_code_array'); + if (isset($request->user)) { + $user = $request->user; + $empno = 0; + foreach ($user_array as $key => $val) { + if ($user_array[$key]['userprf'] == $user) { + $empno = $user_array[$key]['empno']; + } + } + } else { + $empno = 0; + $user = ''; + } + + // get data from LBPF for user and day + $payrollCodes = ''; + ksort($lph_per_monitor_array); + foreach ($lph_per_monitor_array as $key => $val) { + $payrollCodes .= $key . ','; + } + $payrollCodes = substr($payrollCodes, 0, -1); + + $yr = substr($starting, 0, 4) - 2000; + $mth = substr($starting, 5, 2); + $day = substr($starting, 8, 2); + $sqlstmt = "select oppno, sum(cast (hrs as integer)+ (hrs-cast (hrs as integer))/0.6) as hrs from LBPF + where empno=$empno and lbyr=$yr and lbmo=$mth and lbdy=$day + and oppno in ($payrollCodes) + group by oppno"; + + $lbpf1 = $schema->hasTable('lbpf') + ? DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt) + : []; + + $lbpf = 0; + foreach ($lbpf1 as $key => $val) { + $lbpf += $val->HRS; + } + + $sql = "select * from perfstat where dt='$starting' and a5pickcomu='$user' "; + + if ((isset($request->dates) || isset($request->user)) && $schema->hasTable('perfstat')) { + $statistic4 = DB::connection(config('m3.connection', 'pgsql'))->select($sql); + } else { + $statistic4 = []; + } + + // initialize arrays + $monitor_array = $totals_array = $perf_array = []; + $totals_array['value'] = 0; + $totals_array['weight'] = 0; + $totals_array['timediff'] = 0; + $totals_array['picked'] = 0; + $totals_array['entries'] = 0; + $diff = 0; + + foreach ($lbpf1 as $key => $val) { + $monitor_array[$val->OPPNO]['tot_hours'] = $val->HRS; + // Initialize these variables in case not existant in statistic4 + $monitor_array[$val->OPPNO]['header'] = 'Mon' . $val->OPPNO; + $monitor_array[$val->OPPNO]['timediff'] = 0; + $monitor_array[$val->OPPNO]['percent_per_monitor'] = 0; + $monitor_array[$val->OPPNO]['percent_per_activity'] = 0; + $monitor_array[$val->OPPNO]['lph_blended_per_activity'] = 0; + $monitor_array[$val->OPPNO]['picked'] = 0; + $monitor_array[$val->OPPNO]['weight'] = 0; + $monitor_array[$val->OPPNO]['lines'] = 0; + + } + if (! empty($statistic4)) { + // echo "in !empty
    "; + // Initialize the Monitor array + foreach ($statistic4 as $key => $val) { + + // Initialize these variables in case not existant in LBPF + $monitor_array[$val->CODE]['header'] = 'Mon' . $statistic4[$key]->CODE; + $monitor_array[$val->CODE]['timediff'] = 0; + $monitor_array[$val->CODE]['percent_per_monitor'] = 0; + $monitor_array[$val->CODE]['percent_per_activity'] = 0; + $monitor_array[$val->CODE]['lph_blended_per_activity'] = 0; + $monitor_array[$val->CODE]['picked'] = 0; + $monitor_array[$val->CODE]['weight'] = 0; + $monitor_array[$val->CODE]['lines'] = 0; + } + + // add another element (0) in monitor_array to capture the total blended lph value expected + $monitor_array[0]['lph_blended_per_activity'] = 0; + $monitor_array[0]['header'] = '0'; + + // cycle thru stats again, and accumulate totals at global level (totals_array) and at monitor level (monitor_array) + foreach ($statistic4 as $key => $val) { + + $statistic4[$key]->WEIGHT = round($statistic4[$key]->WEIGHT); + $statistic4[$key]->A5VALUE = round($statistic4[$key]->A5VALUE); + $statistic4[$key]->A5PICKED = round($statistic4[$key]->A5PICKED); + + $statistic4[$key]->A5PICKCMTS = date('Y-m-d H:i', strtotime($statistic4[$key]->A5PICKCMTS)); + + // Calculate difference from previous time entry in seconds and save in TIMEDIFF key of STATISTIC4 array + // $time_now=strtotime($statistic4[$key]->A5PICKCMTSADJ); + $time_now = strtotime($statistic4[$key]->A5CMTSADJ); + if ($key > 0) { + $diff = round(abs($time_now - $time_prev)); + if ($diff > $ignore_picks_that_last_longer_than_this_many_hours * 60 * 60) { + $diff = -1; + } + } + + $statistic4[$key]->TIMEDIFF = $diff; + + if ($diff / 60 < 5) { + $statistic4[$key]->COLOUR = ''; + } + if ($diff / 60 >= 5 && $diff / 60 <= 10) { + $statistic4[$key]->COLOUR = 'yellow'; + } + if ($diff / 60 > 10 && $diff / 60 <= 15) { + $statistic4[$key]->COLOUR = '#88ace0'; + } + if ($diff / 60 > 15) { + $statistic4[$key]->COLOUR = 'red'; + } + + // save the time for previous entry + // $time_prev=strtotime($statistic4[$key]->A5PICKCMTSADJ); + $time_prev = strtotime($statistic4[$key]->A5CMTSADJ); + + // accumulate totals at monitor level + $monitor_array[$val->CODE]['timediff'] += $diff; + $monitor_array[$val->CODE]['picked'] += $statistic4[$key]->A5PICKED; + $monitor_array[$val->CODE]['weight'] += $statistic4[$key]->WEIGHT; + $monitor_array[$val->CODE]['lines']++; + + // calculate totals at global level + $totals_array['entries'] = count($statistic4); + $totals_array['weight'] += $statistic4[$key]->WEIGHT; + $totals_array['value'] += $statistic4[$key]->A5VALUE; + $totals_array['timediff'] += $diff; + $totals_array['picked'] += $statistic4[$key]->A5PICKED; + + } + // echo "after 2
    "; print_r($statistic4);
    +            // build array for Performance with Greg's time entry (at one point we had a [0] array as well)
    +
    +            if (! is_null($lbpf)) {
    +
    +                $perf_array['tot_hours'] = (isset($lbpf) ? $lbpf : 0);
    +
    +                if ($perf_array['tot_hours'] != 0) {
    +                    $perf_array['per_hour_actual'] = $totals_array['entries'] / $perf_array['tot_hours'];
    +                } else {
    +                    $perf_array['per_hour_actual'] = 0;
    +                }
    +
    +            }
    +
    +            // cycle through monitors array and compute percentage to allocate to each monitor (code)
    +            ksort($monitor_array);
    +            foreach ($monitor_array as $key => $val) {
    +                if ($key != '0') {
    +                    if (! isset($monitor_array[$key]['tot_hours'])) {
    +                        $monitor_array[$key]['tot_hours'] = 0;
    +                    }
    +
    +                    if ($totals_array['timediff'] != 0) {
    +                        $monitor_array[$key]['percent_per_monitor'] = $monitor_array[$key]['timediff'] / $totals_array['timediff'];
    +                    }
    +
    +                    if ($lbpf != 0) {
    +                        $monitor_array[$key]['percent_per_activity'] = $monitor_array[$key]['tot_hours'] / $lbpf;
    +                    }
    +                    $monitor_array[$key]['lph_blended_per_activity'] = $monitor_array[$key]['percent_per_activity'] * (isset($lph_per_monitor_array[$key]) ? $lph_per_monitor_array[$key] : 0);
    +                    $monitor_array[0]['lph_blended_per_activity'] += $monitor_array[$key]['lph_blended_per_activity'];
    +
    +                }
    +            }
    +
    +            if ($monitor_array[0]['lph_blended_per_activity'] != 0) {
    +                $perf_array['performance_activity'] = $perf_array['per_hour_actual'] / $monitor_array[0]['lph_blended_per_activity'];
    +            }
    +
    +        }
    +
    +        // return encoded json if input field named format is json
    +        if ($request->format == 'json') {
    +
    +            if (! array_key_exists('performance_activity', $perf_array)) {
    +                $performance = 0;
    +            } else {
    +                $performance = number_format($perf_array['performance_activity'] * 100, 0);
    +            }
    +            if (! array_key_exists('0', $monitor_array)) {
    +                $blendedTargetLPH = 0;
    +            } else {
    +                $blendedTargetLPH = number_format($monitor_array[0]['lph_blended_per_activity'], 1);
    +            }
    +            if (! array_key_exists('per_hour_actual', $perf_array)) {
    +                $actualLPH = 0;
    +            } else {
    +                $actualLPH = number_format($perf_array['per_hour_actual'], 1);
    +            }
    +            if (! array_key_exists('tot_hours', $perf_array)) {
    +                $grossHours = 0;
    +            } else {
    +                $grossHours = $perf_array['tot_hours'];
    +            }
    +
    +            $json_data = [
    +                'day' => $starting,
    +                'performance' => $performance,
    +                'blendedTargetLPH' => $blendedTargetLPH,
    +                'actualLPH' => $actualLPH,
    +                'grossHours' => $grossHours,
    +            ];
    +
    +            return json_encode($json_data);
    +
    +        } else {
    +            // display webpage of statistic version 4
    +            $request->ports = Config::get('arrays.env_ports');
    +            $no_data = 'N';
    +            if (empty($statistic4) && $_SERVER['REQUEST_URI'] != '/UserPickingStats4') {
    +                $no_data = 'Y';
    +            }
    +
    +            return view(
    +                'm3::liberty-theme.pages.UserPickingStats4',
    +                compact('statistic4', 'starting', 'user', 'user_array', 'monitor_array', 'totals_array', 'perf_array', 'request', 'no_data'),
    +            );
    +
    +        }
    +
    +    }
    +}
    diff --git a/Modules/M3/Http/Controllers/UserPickingStats5.php b/Modules/M3/Http/Controllers/UserPickingStats5.php
    new file mode 100755
    index 00000000..9117ce36
    --- /dev/null
    +++ b/Modules/M3/Http/Controllers/UserPickingStats5.php
    @@ -0,0 +1,148 @@
    +user;
    +        $statistics = [];
    +        $totals = self::emptyTotals();
    +
    +        if (isset($request->dates)) {
    +            [$statistics, $totals] = self::collectDailyStatistics($request, $starting, $days, $totals);
    +        }
    +
    +        if ($request->format === 'json') {
    +            return response()->json($statistics);
    +        }
    +
    +        $statistic5 = $statistics;
    +        $totals_array = $totals;
    +        $user_array = $userArray;
    +
    +        return view('m3::liberty-theme.pages.UserPickingStats5', compact(
    +            'statistic5',
    +            'totals_array',
    +            'user_array',
    +            'user',
    +            'starting',
    +            'ending',
    +            'request',
    +        ));
    +    }
    +
    +    private static function loadUsers(): array
    +    {
    +        $users = [];
    +        $co = '';
    +        $whs = '';
    +
    +        try {
    +            $connection = config('m3.connection', 'pgsql');
    +            if (! Schema::connection($connection)->hasTable('icm428m')) {
    +                return [$users, $co, $whs];
    +            }
    +
    +            $profile = DB::connection($connection)->table('icm428m')
    +                ->select('R428CO', 'R428WH')
    +                ->where('R428US', strtoupper((string) m3_user()))
    +                ->first();
    +            $co = trim((string) ($profile->R428CO ?? ''));
    +            $whs = trim((string) ($profile->R428WH ?? ''));
    +            if ($co === '' || $whs === '') {
    +                return [$users, $co, $whs];
    +            }
    +
    +            $rows = DB::connection($connection)->table('icm428m')
    +                ->selectRaw("R428US as userprf, (trim(R428FIRST) || ' ' || trim(R428FAMILY)) as name, R428EMPCDE as empno")
    +                ->where('R428EMPCDE', '!=', 0)->where('R428CO', $co)->where('R428WH', $whs)->get();
    +            foreach ($rows as $row) {
    +                $users[] = ['userprf' => trim((string) $row->userprf), 'name' => trim((string) $row->name), 'empno' => $row->empno];
    +            }
    +            array_multisort(array_column($users, 'name'), SORT_ASC, $users);
    +        } catch (\Throwable $e) {
    +            Log::warning('M3 picking user list unavailable', ['exception' => $e->getMessage()]);
    +        }
    +
    +        return [$users, $co, $whs];
    +    }
    +
    +    private static function dateRange(Request $request): array
    +    {
    +        if (isset($request->dates)) {
    +            $dates = explode(' - ', (string) $request->dates);
    +            $starting = $dates[0] ?? date('Y-m-d');
    +            $ending = $dates[1] ?? $starting;
    +        } else {
    +            $starting = date('Y-m-d', strtotime('-5 days'));
    +            $ending = date('Y-m-d');
    +        }
    +
    +        $days = (int) (new DateTime($starting))->diff(new DateTime($ending))->format('%a');
    +
    +        return [$starting, $ending, $days];
    +    }
    +
    +    private static function emptyTotals(): array
    +    {
    +        return ['performance' => 0, 'blendedTargetLPH' => 0, 'actualLPH' => 0, 'grossHours' => 0];
    +    }
    +
    +    private static function collectDailyStatistics(Request $request, string $starting, int $days, array $totals): array
    +    {
    +        $statistics = [];
    +        $count = 0;
    +        $url = $request->getSchemeAndHttpHost() . '/UserPickingStats4';
    +
    +        for ($day = 0; $day <= $days; $day++) {
    +            $date = date('Y-m-d', strtotime($starting . "+$day days"));
    +            $statistics[$day] = self::fetchStatistic($request, $url, $date);
    +            self::addTotals($totals, $statistics[$day]);
    +            if (($statistics[$day]['performance'] ?? 0) > 0) {
    +                $count++;
    +            }
    +        }
    +
    +        if ($count > 0) {
    +            foreach (array_keys($totals) as $key) {
    +                $totals[$key] /= $count;
    +            }
    +        }
    +
    +        return [$statistics, $totals];
    +    }
    +
    +    private static function fetchStatistic(Request $request, string $url, string $date): array
    +    {
    +        try {
    +            $response = Http::withBasicAuth((string) $request->header('php-auth-user'), (string) $request->header('php-auth-pw'))
    +                ->get($url, ['dates' => $date, 'user' => $request->user, 'format' => 'json']);
    +            $data = $response->successful() ? (json_decode($response->body(), true) ?: []) : [];
    +        } catch (\Throwable $e) {
    +            Log::warning('M3 picking statistics unavailable', ['date' => $date, 'exception' => $e->getMessage()]);
    +            $data = [];
    +        }
    +        $data['day'] = $data['day'] ?? $date;
    +        $data['performance'] = $data['performance'] ?? 0;
    +
    +        return $data;
    +    }
    +
    +    private static function addTotals(array &$totals, array $statistic): void
    +    {
    +        foreach (array_keys($totals) as $key) {
    +            $totals[$key] += (float) ($statistic[$key] ?? 0);
    +        }
    +    }
    +}
    diff --git a/Modules/M3/Http/Controllers/UserProfileController.php b/Modules/M3/Http/Controllers/UserProfileController.php
    new file mode 100755
    index 00000000..aed3d27d
    --- /dev/null
    +++ b/Modules/M3/Http/Controllers/UserProfileController.php
    @@ -0,0 +1,79 @@
    +table('icm428m')
    +            ->select('R428US', 'R428CO', 'R428WH', 'R428PL', 'R428FIRST', 'R428FAMILY')
    +            ->where('R428US', '=', $loggedUser)
    +            ->where('R42821A', '=', 'Y')
    +            ->first();
    +
    +        $iC670M = DB::connection(config('m3.connection', 'pgsql'))->table('ic670m')->get();
    +
    +        // Check if user is eligible for Profile update
    +        if (isset($iCM428M->R428US)) {
    +            return view('m3::liberty-theme.pages.userProfile', ['ICM428M' => $iCM428M, 'IC670M' => $iC670M]);
    +        } else {
    +            abort(404);
    +        }
    +
    +    }
    +
    +    public static function updateUserProfile(Request $request)
    +    {
    +
    +        $r428US = isset($request->R428US) ? trim($request->R428US) : '';
    +        $r428DPW = isset($request->R428DPW) ? trim($request->R428DPW) : '';
    +
    +        $r428CO = substr($r428DPW, 0, 3);
    +        $r428PL = substr($r428DPW, 3, 3);
    +        $r428WH = substr($r428DPW, 6, 3);
    +
    +        if ($r428US != '') {
    +            // Update record to ICM428M
    +            DB::connection(config('m3.connection', 'pgsql'))->update("update ICM428M
    +            set R428CO='$r428CO', R428PL='$r428PL', R428WH='$r428WH'
    +            where R428US='$r428US'");
    +
    +            return redirect('/userprofile')->with('success', 'Profile updated successfully!');
    +        } else {
    +            return redirect('/userprofile')->with('success', 'Profile updated successfully!');
    +        }
    +
    +    }
    +
    +    public static function updateUserProfileAjax(Request $request)
    +    {
    +
    +        $r428US = isset($request->R428US) ? trim($request->R428US) : '';
    +        $r428DPW = isset($request->R428DPW) ? trim($request->R428DPW) : '';
    +
    +        $r428CO = substr($r428DPW, 0, 3);
    +        $r428PL = substr($r428DPW, 3, 3);
    +        $r428WH = substr($r428DPW, 6, 3);
    +
    +        if ($r428US != '') {
    +            // Update record to ICM428M
    +            DB::connection(config('m3.connection', 'pgsql'))->update("update ICM428M
    +            set R428CO='$r428CO', R428PL='$r428PL', R428WH='$r428WH'
    +            where R428US='$r428US'");
    +
    +            return response()->json(['success' => true]);
    +        } else {
    +            return response()->json(['success' => false]);
    +        }
    +
    +    }
    +}
    diff --git a/Modules/M3/Http/Controllers/UtilitiesController.php b/Modules/M3/Http/Controllers/UtilitiesController.php
    new file mode 100755
    index 00000000..e8779edc
    --- /dev/null
    +++ b/Modules/M3/Http/Controllers/UtilitiesController.php
    @@ -0,0 +1,582 @@
    +getCode();
    +            $msg = $e->getMessage();
    +
    +            switch ($code) {
    +                case 8001:
    +                    // "Authorization failure on distributed database connection attempt"
    +                    // Usually means a wrong DB2 user or password
    +                    break;
    +                case 42705:
    +                    break;
    +                default:
    +                    break;
    +            }
    +        }
    +        $conn->setOptions(['persistent' => false, 'stateless' => true, 'debug' => true, 'debugLogFile' => '/www/sentustesx/htdocs/storage/logs/toolkit_debug.log']);
    +
    +        //  Add LIB
    +        // $result  = $conn->CLCommand('ADDLIBLE LIB(MPDAT10)');
    +
    +        // define several input/output params
    +        $params = [];
    +
    +        // AddParameterChar($io, $size, $comment, $varName, $value, $varying, $dimension)
    +        // Add Warehouse Param
    +        $params[] = $conn->AddParameterChar('in', 3, 'eqNumber', '', '111');
    +
    +        // AddParameterPackDec($io, $length, $scale, $comment, $varName, $value,$dimension)
    +        // Add Delivery Note Param
    +        $params[] = $conn->AddParameterPackDec('in', 11, 0, 'ParamIn', '', '00000087125');
    +
    +        // Start Time Tracking
    +        $start = microtime(true);
    +
    +        dump('Calling: EWOBJTST/ICM700C');
    +
    +        // Config::get('eproconf.misc.PGM1'), Config::get('eproconf.misc.libname4')
    +        // ICM700C EWOBJTST  ICM700C  ICM700CSBM
    +        $result = $conn->PgmCall('ICM700CSBM', 'EWOBJTST', $params, [], []);
    +
    +        if (! $result) {
    +        }
    +        // Successful Call
    +        else {
    +            dump($result);
    +        }
    +
    +        if ($pGMERRORS != '') {
    +            dump($pGMERRORS);
    +        }
    +        // Get Execution Time
    +        $time = microtime(true) - $start;
    +        dump($time);
    +    }
    +
    +    public static function pdfReadWrite(Request $request)
    +    {
    +        dump('PDF Read Write');
    +
    +        $pdfFileName = 'E1232824-10826596';
    +
    +        // Parse PDF file and build necessary objects.
    +        $pdfFile = File::get('/www/sentm3test/htdocs/labels/' . $pdfFileName . '.pdf');
    +
    +        // Transform content to base64
    +        $base64PDF = base64_encode($pdfFile);
    +        // Output base64 string
    +        // dump($base64PDF);
    +
    +        // Save Cache
    +        Cache::put($pdfFileName, $base64PDF, now()->addMinutes(60));
    +
    +        // Retrieve Cache
    +        $cachedPdfFile = Cache::get($pdfFileName);
    +        dump('Retrieve Base64 Encoded PDF saved in Cache:');
    +        dump($cachedPdfFile);
    +
    +        // remove File from Cache
    +        // Cache::put(pdfFileName, 'value', -5);
    +        // Cache::forget($pdfFileName);
    +
    +        // Base64 Decode and Display
    +        // $pdf  = $parser->parseContent(base64_decode($base64PDF));
    +        // $text = $pdf->getText();
    +        // dump($text);
    +
    +    }
    +
    +    public static function fixICM799MSentPKR(Request $request)
    +    {
    +        ini_set('max_execution_time', Config::get('arrays.PHPTimeOutCL'));
    +        ini_set('max_input_time', Config::get('arrays.PHPTimeOutCL'));
    +        ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOutCL'));
    +        ini_set('memory_limit', '1024M');
    +
    +        dump('Run Fix IMSENTPKR...');
    +
    +        $sHUSER = 'TWOSHIP';
    +
    +        // Get User CO & WH
    +        // Get users from ICM428M
    +        $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')
    +            ->select('R428US', 'R428CO', 'R428WH')
    +            ->where('R428US', '=', $sHUSER)
    +            ->first();
    +
    +        $dIVI = isset($iCM428M->R428CO) ? $iCM428M->R428CO : '';
    +        $wHS = isset($iCM428M->R428WH) ? $iCM428M->R428WH : '';
    +
    +        // Get Parts And Lots from  ICM688M2
    +        $iCM688M2SLTMP = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m2')
    +            ->select('A5MACPKR', 'A5SENTPKR', 'A5PICKSTRD')
    +            ->distinct()
    +            ->where('A5CO', $dIVI)
    +            ->where('A5WHS', $wHS)
    +            ->where('A5PICKSTRD', '!=', '0')
    +            ->orderBy('A5PICKSTRD', 'ASC')
    +            ->get();
    +
    +        foreach ($iCM688M2SLTMP as $ICM688M2SL) {
    +
    +            $a5MACPKR = isset($ICM688M2SL->A5MACPKR) ? $ICM688M2SL->A5MACPKR : '';
    +            $a5SENTPKR = isset($ICM688M2SL->A5SENTPKR) ? $ICM688M2SL->A5SENTPKR : '';
    +
    +            dump('ICM688M2 Record: ' . $a5MACPKR . '-' . $a5SENTPKR);
    +
    +            DB::connection(config('m3.connection', 'pgsql'))->table('icm799m')
    +                ->where('IMDELNO', '=', $a5MACPKR)
    +                ->update(['IMSENTPKR' => $a5SENTPKR]);
    +        }
    +
    +    }
    +
    +    // Generate GS1-128
    +    public static function generateGS128(Request $request)
    +    {
    +        ini_set('max_execution_time', Config::get('arrays.PHPTimeOutCL'));
    +        ini_set('max_input_time', Config::get('arrays.PHPTimeOutCL'));
    +        ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOutCL'));
    +        ini_set('memory_limit', '1024M');
    +
    +        try {
    +            Log::channel('LabelCron')->info('>>> Run GS1 Label creation Command...');
    +
    +            // Get the Calling User
    +            // $userId  = 'TWOSHIP';
    +            // $sHUSER  = isset($userId) ? $userId : (m3_user() !== '' ? Str::upper(trim(m3_user())) : '');
    +
    +            // Get Manifest Array
    +            $gSArray = $request->query();
    +
    +            $sHUSER = isset($gSArray['User']) ? trim($gSArray['User']) : '';
    +
    +            if ($sHUSER != '') {
    +                // Get User CO & WH from Table ICM428M
    +                $iCM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')
    +                    ->select('R428US', 'R428CO', 'R428WH', 'R428PL')
    +                    ->where('R428US', '=', $sHUSER)
    +                    ->first();
    +
    +                $cOMPANY = isset($iCM428M->R428CO) ? $iCM428M->R428CO : '';     // Company
    +                $pLANT = isset($iCM428M->R428PL) ? $iCM428M->R428PL : '';     // Plant
    +                $wHS = isset($iCM428M->R428WH) ? $iCM428M->R428WH : '';     // WareHouse
    +
    +                $macpkr = $gSArray['Macpkr'];
    +                $packageType = trim($gSArray['packageType']);  // 1 => Pallet , 0 => Carton
    +                $packageTypeDesc = $packageType == 1 ? 'Pallet' : 'Carton';
    +                $manufactID = '0826528';  // MAK : get ID from Nvent  and save to Config File
    +                $total_length = 9;
    +
    +                $html = '
    +                    
    +                    
    +                    
    +                    
    +                    ';
    +
    +                // Get number of Pallets
    +                $packageCount = count($gSArray['PackagesArray']);
    +                $packageNum = 1;
    +
    +                // Get GS1 Label MAX ID from ICM695M3 :
    +                $gS1SEQUENCESel = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m3')->max('ID');
    +                $gS1SEQUENCE = isset($gS1SEQUENCESel) ? $gS1SEQUENCESel : 0;
    +
    +                // Loop PackagesArray : Build Table for PDF  and Insert to ICM695m3
    +                foreach ($gSArray['PackagesArray'] as $value) {
    +                    $table_style = $packageNum < $packageCount ? ' style="page-break-after: always;" ' : '';
    +
    +                    $a2INTBOX = trim($value);
    +
    +                    $gS1SEQUENCE++;
    +                    $gS1SEQUENCEID = str_pad($gS1SEQUENCE, $total_length, '0', STR_PAD_LEFT);
    +                    // Build GS1 18 Digits Code
    +                    $gs1_128_bc_1 = '00' . $packageType . $manufactID . $gS1SEQUENCEID;
    +
    +                    // Calculate Check Digit
    +                    $digits = str_split($gs1_128_bc_1);
    +                    $sum = 0;
    +                    $length = count($digits);
    +
    +                    // Loop through each digit starting from the right
    +                    for ($i = 0; $i < $length; $i++) {
    +                        $digit = $digits[$length - $i - 1];
    +                        // Assign a weight of 3 or 1 alternately
    +                        $weight = ($i % 2 == 0) ? 3 : 1;
    +                        // Add the product of the digit and its weight to the sum
    +                        $sum += $digit * $weight;
    +                    }
    +                    // Calculate the remainder when sum is divided by 10
    +                    $remainder = $sum % 10;
    +                    // If remainder is 0, check digit is 0; otherwise, subtract remainder from 10
    +                    $checkDigit = ($remainder == 0) ? 0 : 10 - $remainder;
    +                    // End Check Digit Calculation
    +
    +                    // SSCC 18 Digits Code
    +                    $gs1_128_bc = $gs1_128_bc_1 . $checkDigit;
    +
    +                    $gs1_128_bc_desc = '(00)' . $packageType . $manufactID . $gS1SEQUENCEID . $checkDigit;
    +
    +                    $data = [
    +                        'ship_to' => $gSArray['Recipient_CompanyName'] . '
    ' . $gSArray['Recipient_Address1'] . '
    ' . + $gSArray['Recipient_City'] . ',' . $gSArray['Recipient_State'] + . '
    ' . $gSArray['Recipient_PostalCode'], + 'from' => $gSArray['Sender_CompanyName'] . '
    ' . $gSArray['Sender_Address1'] . '
    ' . + $gSArray['Sender_City'] . ',' . $gSArray['Sender_State'] + . '
    ' . $gSArray['Sender_PostalCode'], + 'ship_to_lbl' => '420' . $gSArray['Recipient_PostalCode'], + 'ship_to_desc' => '(420)' . $gSArray['Recipient_PostalCode'], + 'pro' => '190071217845706', // MAK : Check missing info with Brad + 'item_number' => '10000B', + 'upc' => '098506095310', + 'quantity' => '1', + 'serial_shipping_container' => $gs1_128_bc_desc, + ]; + + // Initialize barcode generator + $generator = new BarcodeGeneratorPNG; + + // Generate barcodes + $shipToPostalCodeBarcode = $generator->getBarcode($data['ship_to_lbl'], $generator::TYPE_CODE_128); + $serialShippingContainerBarcode = $generator->getBarcode($data['serial_shipping_container'], $generator::TYPE_CODE_128, 2, 50); + + // HTML content for the label + $html .= ' + + + + + + + + + + + + + + + + + + +
    + FROM:
    ' . $data['from'] . ' +
    + SHIP TO:
    ' . $data['ship_to'] . ' +
    +
    + ' . $data['ship_to_desc'] . ' +
    + Carrier: ' . $gSArray['CarrierName'] . '
    + PRO #: ' . $gSArray['trackingno'] . '
    + B/L #: ' . $gSArray['BOLnumber'] . '
    + Ref : ' . $a2INTBOX . ' +
    + PURCHASE ORDER: ' . $gSArray['ShipmentPONumber'] . '
    + Vendor: ' . $manufactID . ' +
    + ' . $packageTypeDesc . ' # : ' . $packageNum . ' of ' . $packageCount . ' +
    +
    + ' . $data['serial_shipping_container'] . ' +
    '; + + $packageNum++; + + // Insert new Record to ICM695M3 $gs1_128_bc + DB::connection(config('m3.connection', 'pgsql'))->table('icm695m3') + ->insert(['A2CO' => $cOMPANY, 'A2WHS' => $wHS, 'A2PLANT' => $pLANT, 'A2MACPKR' => $macpkr, 'A2GS1LABEL' => $gs1_128_bc, 'A2INTBOX' => $a2INTBOX]); + + Log::channel('LabelCron')->info('<<< GS1-128...End of Label Creation for Mackpkr: ' . $macpkr); + } + + $html .= ' '; + + ob_start(); + + // Initialize Dompdf + $dompdf = new Dompdf; + $dompdf->loadHtml($html); + $dompdf->setPaper('a6', 'portrait'); + // Render the HTML as PDF + $dompdf->render(); + + // Output the generated PDF to Browser + // $dompdf->stream(); + + $pdfContent = $dompdf->output(); + + $labelsPath = Config::get('arrays.PdfPath'); // '/www/sentm3live/htdocs/labels/'; + // Put the PDF in labels/CarrierLabel + $gSFolder = 'GSLabel'; + + $carrierFileName = $gSFolder . '_' . $macpkr . '_' . $cOMPANY . '_' . $wHS . '_' . $a2INTBOX; + // LTL + // if ($packageType=='1') { + // $carrierFileName = $gSFolder.'_'.$macpkr.'_'.$cOMPANY.'_'.$wHS; + // } + // # small Packs + // else{ + // $carrierFileName = $gSFolder.'_'.$macpkr.'_'.$cOMPANY.'_'.$wHS.'_'.$a2INTBOX; + // } + + $gS1FileName = $labelsPath . $gSFolder . '/' . $carrierFileName . '.pdf'; + $gS1FileNameNoRoot = $gSFolder . '/' . $carrierFileName; + file_put_contents($gS1FileName, $pdfContent); + ob_end_clean(); + } + + // # Insert new Record to ICM695M3 $gs1_128_bc + // DB::connection(config('m3.connection', 'pgsql'))->table('icm695m3') + // ->insert(['A2CO'=> $cOMPANY,'A2WHS'=> $wHS,'A2MACPKR'=> $macpkr,'A2GS1LABEL'=> $gs1_128_bc]); + + return json_encode(['result' => 'success', 'GS1File' => $gS1FileNameNoRoot]); + + } catch (\Throwable $th) { + Log::channel('LabelCron')->error($th); + + return json_encode(['result' => 'error', 'GS1File' => $th]); + + } + } + + public static function generateGS128Tst(Request $request) + { + print_r('>>> Generate PDF'); + + $data = [ + 'from' => 'Any Vendor
    123 Any Street
    SomeTown, ST 01234', + 'ship_to' => 'True Value Hardware
    123 Any Street
    SomeTown, ST 01234', + 'ship_to_postal_code' => '42016172', + 'pro' => '190071217845706', + 'item_number' => '10000B', + 'upc' => '098506095310', + 'quantity' => '1', + 'serial_shipping_container' => '(00)107904370000005', + ]; + + // Initialize barcode generator + $generator = new BarcodeGeneratorPNG; + + // Generate barcodes + $shipToPostalCodeBarcode = $generator->getBarcode($data['ship_to_postal_code'], $generator::TYPE_CODE_128); + $proBarcode = $generator->getBarcode($data['pro'], $generator::TYPE_CODE_128); + $serialShippingContainerBarcode = $generator->getBarcode($data['serial_shipping_container'], $generator::TYPE_CODE_128, 2, 50); + + // HTML content for the label + // border="1" style="border-collapse: collapse; width: 100%; height: 300px;" + $html = ' + + + + + + + + + + + + + + + + + + + + + + +
    + FROM:
    ' . $data['from'] . ' +
    + SHIP TO:
    ' . $data['ship_to'] . ' +
    +
    + (' . $data['ship_to_postal_code'] . ') +
    + Carrier Routing(SCAC)
    + PRO #:
    + B/L # : +
    + PURCHASE ORDER: PO1234567
    +
    + PRO: ' . $data['pro'] . ' +
    + ITEM #: ' . $data['item_number'] . '
    + UPC: ' . $data['upc'] . '
    + QUANTITY: ' . $data['quantity'] . ' +
    +
    + ' . $data['serial_shipping_container'] . ' +
    + + '; + + // Initialize Dompdf + $dompdf = new Dompdf; + $dompdf->loadHtml($html); + $dompdf->setPaper('a6', 'portrait'); + // Render the HTML as PDF + $dompdf->render(); + + // Output the generated PDF to Browser + // $dompdf->stream(); + + $pdfContent = $dompdf->output(); + // // return $pdfContent; + $labelsPath = '/www/sentm3live/htdocs/labels/'; + // # Put the PDF in labels/CarrierLabel + $gSFolder = 'GSLabel'; + $carrierFileName = 'GSLabel'; + file_put_contents($labelsPath . $gSFolder . '/' . $carrierFileName . '.pdf', $pdfContent); + + // Save the PDF string to a temporary file for debugging + // $tempPdfPath = tempnam(sys_get_temp_dir(), 'pdf') . '.pdf'; + // // dump($tempPdfPath); + // file_put_contents($tempPdfPath, $pdfContent); + + // // Check if the PDF was generated correctly + // if (!file_exists($tempPdfPath) || filesize($tempPdfPath) === 0) { + // } + + // Create an Imagick instance + // $imagick = new \Imagick(); + + // // Read the PDF from the string + // // $imagick->readImageBlob( $pdfContent ); + // // Read the PDF from the file + // $imagick->readImage($tempPdfPath); + + // // Set the resolution (optional) + // $imagick->setResolution(300, 300); + + // // Convert the first page of the PDF to an image + // $imagick->setIteratorIndex(0); + // $imagick->setImageFormat('png'); + + } + + public static function miscTests(Request $request) + { + // $total_length = 9; + // # MAK replace cache ID with MAX ID+1 from ICM695M3 + // $gS1SEQUENCESel = DB::connection(config('m3.connection', 'pgsql'))->table('icm695m3')->max('ID'); + // dump($gS1SEQUENCESel); + // $gS1SEQUENCE = isset($gS1SEQUENCESel) ? $gS1SEQUENCESel : 0; + // $gS1SEQUENCE++; + // $gS1SEQUENCEID = str_pad($gS1SEQUENCE, $total_length, "0", STR_PAD_LEFT); + // dump($gS1SEQUENCEID); + + // MAK Get Contents + // ESN1 + // $aYMACPKR='888568'; // LTL example + // $aYMACPKR='894337'; // another LTL example with smaller orders, therefore pallets are more mixed + // $aYMACPKR='1225311'; // parcel example + + // ESN2 + // $aYMACPKR='999999'; // LTL example + $aYMACPKR = '748101'; // LTL example + + $myRequest = new Request; + $myRequest->setMethod('POST'); + + $myRequest->request->add([ + 'MACPKR' => $aYMACPKR, + ]); + + // Call the controller method properly + $controller = new GetContentsController; + $response = $controller->processShipment($myRequest); + + $responseData = $response->getData(); + + $error = isset($responseData->error) ? $responseData->error : ''; + + if ($error == '') { + // Get Commodities + $commoditiesTmp = isset($responseData->commodities) ? $responseData->commodities : ''; + if ($commoditiesTmp != '') { + $commodities = json_encode($commoditiesTmp); + dump($commodities); + } else { + dump('Commodities Empty...'); + } + } else { + dump($error); + } + + } +} diff --git a/Modules/M3/Http/Controllers/WhsPerfMetrics.php b/Modules/M3/Http/Controllers/WhsPerfMetrics.php new file mode 100755 index 00000000..5d2a5f5e --- /dev/null +++ b/Modules/M3/Http/Controllers/WhsPerfMetrics.php @@ -0,0 +1,107 @@ + $exception, + ]); + } + + return view('m3::liberty-theme.pages.WhsPerfMetrics', $context); + } + + public static function downloadFiles(Request $request) + { + $validated = $request->validate([ + 'filename' => ['required', 'string'], + ]); + + $fileName = ltrim($validated['filename'], '/'); + $disk = Storage::disk('publicLabels'); + + if (! $disk->exists($fileName)) { + abort(404, 'Warehouse performance file not found.'); + } + + return $disk->download($fileName, basename($fileName)); + } + + private static function defaultContext(): array + { + return [ + 'IC670M' => collect(), + 'WHDDA' => '', + 'COMPANY' => '', + 'PLANT' => '', + 'WHS' => '', + 'allReportsUrls' => [], + ]; + } + + private static function loadUserContext(): array + { + $connection = config('m3.connection', 'pgsql'); + $user = Str::upper(trim((string) m3_user())); + + if ($user === '' || ! Schema::connection($connection)->hasTable('icm428m')) { + return ['COMPANY' => '', 'PLANT' => '', 'WHS' => '']; + } + + $profile = DB::connection($connection)->table('icm428m') + ->select('R428CO', 'R428PL', 'R428WH') + ->where('R428US', $user) + ->first(); + + return [ + 'COMPANY' => trim((string) ($profile->R428CO ?? '')), + 'PLANT' => trim((string) ($profile->R428PL ?? '')), + 'WHS' => trim((string) ($profile->R428WH ?? '')), + ]; + } + + private static function loadWarehouses() + { + $connection = config('m3.connection', 'pgsql'); + + if (! Schema::connection($connection)->hasTable('ic670m')) { + return collect(); + } + + return DB::connection($connection)->table('ic670m')->get(); + } + + private static function loadReportUrls(string $warehouse): array + { + if ($warehouse === '') { + return []; + } + + $disk = Storage::disk('publicLabels'); + $urls = []; + + foreach ($disk->allFiles('WhsPerf/' . $warehouse) as $file) { + $urls[$file] = $disk->url($file); + } + + return $urls; + } +} diff --git a/Modules/M3/Http/Controllers/WhsePerfController.php b/Modules/M3/Http/Controllers/WhsePerfController.php new file mode 100755 index 00000000..a87d36d9 --- /dev/null +++ b/Modules/M3/Http/Controllers/WhsePerfController.php @@ -0,0 +1,91 @@ +date_in_yr) ? $request->date_in_yr : date('Y'); + $date_in_mth = isset($request->date_in_mth) ? $request->date_in_mth : date('m'); + $date_in = $date_in_yr . $date_in_mth . '01'; + $sqlstmt = 'select AVDATE, AVANOTESCL,AVADLRCL,AVAWGTCL,AVANOTESCH,AVADLRCH,AVAWGTCH,AVANOTESOP,AVADLROP,AVAWGTOP, + AVLNOTESCL,AVLDLRCL,AVLWGTCL,AVLNOTESCH,AVLDLRCH,AVLWGTCH,AVLNOTESOP,AVLDLROP,AVLWGTOP, + AVPNOTESCL,AVPDLRCL,AVPWGTCL,AVPNOTESCH,AVPDLRCH,AVPWGTCH,AVPNOTESOP,AVPDLROP,AVPWGTOP, + AVINOTESCL,AVIDLRCL,AVIWGTCL,AVINOTESOP,AVIDLROP,AVIWGTOP + from ICM711M + where AVDATE between ' . date('Ym', strtotime($date_in)) . '00 and ' . date('Ym', strtotime($date_in)) . '32'; + + $iCM711M = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + $uSER_INFO = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')->selectRaw('R428US as USERPRF, R428STS as STATUS, NULL as DATE_EXPIRED, NULL as EXPIRED')->get()->all(); + $power_user = DB::connection(config('m3.connection', 'pgsql'))->select("select R428PWRUSR, R428CO, R428PL, R428WH from ICM428M where R428US='" . strtoupper(m3_user()) . "'"); + + $pct_array = Config::get('arrays.whsePerf_targets'); + + return view('m3::liberty-theme.pages.whsePerf', ['ICM711M' => $iCM711M, 'power_user' => $power_user, 'USER_INFO' => $uSER_INFO, 'date_in' => $date_in, 'pct_array' => $pct_array]); + + } + + public function exportTable(Request $request) + { + + $date_in_yr = isset($request->date_in_yr) ? $request->date_in_yr : date('Y'); + $date_in_mth = isset($request->date_in_mth) ? $request->date_in_mth : date('m'); + $date_in = $date_in_yr . $date_in_mth . '01'; + $sqlstmt = 'select AVDATE, AVANOTESCL,AVADLRCL,AVAWGTCL,AVANOTESCH,AVADLRCH,AVAWGTCH,AVANOTESOP,AVADLROP,AVAWGTOP, + AVLNOTESCL,AVLDLRCL,AVLWGTCL,AVLNOTESCH,AVLDLRCH,AVLWGTCH,AVLNOTESOP,AVLDLROP,AVLWGTOP, + AVPNOTESCL,AVPDLRCL,AVPWGTCL,AVPNOTESCH,AVPDLRCH,AVPWGTCH,AVPNOTESOP,AVPDLROP,AVPWGTOP, + AVINOTESCL,AVIDLRCL,AVIWGTCL,AVINOTESOP,AVIDLROP,AVIWGTOP + from ICM711M + where AVDATE between ' . date('Ym', strtotime($date_in)) . '00 and ' . date('Ym', strtotime($date_in)) . '32'; + + $iCM711M = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt); + $uSER_INFO = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')->selectRaw('R428US as USERPRF, R428STS as STATUS, NULL as DATE_EXPIRED, NULL as EXPIRED')->get()->all(); + $power_user = DB::connection(config('m3.connection', 'pgsql'))->select("select R428PWRUSR, R428CO, R428PL, R428WH from ICM428M where R428US='" . strtoupper(m3_user()) . "'"); + + $pct_array = Config::get('arrays.whsePerf_targets'); + + $html = view('m3::liberty-theme.pages.whsePerf', ['ICM711M' => $iCM711M, 'power_user' => $power_user, 'USER_INFO' => $uSER_INFO, 'date_in' => $date_in, 'pct_array' => $pct_array])->render(); + + libxml_use_internal_errors(true); + $doc = new \DOMDocument; + $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); // Extract only table elements + $tables = $doc->getElementsByTagName('table'); + if ($tables->length === 0) { + abort(400, 'No table found in HTML'); + } + // Create new document with only the table + $newDoc = new \DOMDocument; + $newDoc->appendChild($newDoc->importNode($tables->item(0), true)); + $cleanHtml = '' . $newDoc->saveHTML() . ''; + libxml_clear_errors(); + $tempFile = tempnam(sys_get_temp_dir(), 'html') . '.html'; + file_put_contents($tempFile, $cleanHtml); + $reader = IOFactory::createReader('Html'); + $spreadsheet = $reader->load($tempFile); + $writer = new Xlsx($spreadsheet); + $fileName = 'export.xlsx'; + $tempExcel = tempnam(sys_get_temp_dir(), 'excel'); + $writer->save($tempExcel); + unlink($tempFile); + + return response()->download($tempExcel, $fileName)->deleteFileAfterSend(true); + } +} diff --git a/Modules/M3/Http/Controllers/WhsePerfDetailsController.php b/Modules/M3/Http/Controllers/WhsePerfDetailsController.php new file mode 100755 index 00000000..a3e6cd3b --- /dev/null +++ b/Modules/M3/Http/Controllers/WhsePerfDetailsController.php @@ -0,0 +1,71 @@ +date) ? date('Y-m-d', strtotime($request->date)) : date('Y-m-d'); + $for = isset($request->for) ? $request->for : 'a'; + + $all = "tempfile4 as ( + select a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype, sum(dollarvalue) as dollarvalue, sum(weight) as weight, max(source) as source + from tempfile3 + where not (a4shipvia1='OCEAN' or interco='interco') and source<>'A2' + group by a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype + ) + select * from tempfile4 order by source"; + + $ltl = "tempfile4 as ( + select a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype, sum(dollarvalue) as dollarvalue, sum(weight) as weight, max(source) as source + from tempfile3 + where not (a4shipvia1='OCEAN' or interco='interco') and source<>'A2' and a4shiptype='LTL' + group by a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype + ) + select * from tempfile4 order by source"; + + $parcel = "tempfile4 as ( + select a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype, sum(dollarvalue) as dollarvalue, sum(weight) as weight, max(source) as source + from tempfile3 + where not (a4shipvia1='OCEAN' or interco='interco') and source<>'A2' and a4shiptype='SmallPack' + group by a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype + ) + select * from tempfile4 order by source"; + + $io = "tempfile4 as ( + select a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype, sum(dollarvalue) as dollarvalue, sum(weight) as weight, max(source) as source + from tempfile3 + where (a4shipvia1='OCEAN' or interco='interco') and source<>'A2' + group by a5macpkr, a4shshnm, a4shipvia1, interco, a4shiptype + ) + select * from tempfile4 order by source"; + + switch ($for) { + case 'a': + $stmt2 = $all; + break; + case 'l': + $stmt2 = $ltl; + break; + case 'p': + $stmt2 = $parcel; + break; + case 'i': + $stmt2 = $io; + break; + default: + $stmt2 = $all; + break; + } + include $_SERVER['DOCUMENT_ROOT'] . '/../../KPI2_update711M_SQL_main.inc.php'; + $perfDetails = DB::connection(config('m3.connection', 'pgsql'))->select($sqlstmt1 . $stmt2); + + return view('m3::liberty-theme.pages.whsePerfDetails', compact('perfDetails', 'date_in', 'for')); + + } +} diff --git a/Modules/M3/Http/Middleware/.gitkeep b/Modules/M3/Http/Middleware/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Http/Middleware/Authenticate.php b/Modules/M3/Http/Middleware/Authenticate.php new file mode 100755 index 00000000..b00d819d --- /dev/null +++ b/Modules/M3/Http/Middleware/Authenticate.php @@ -0,0 +1,23 @@ +expectsJson()) { + return route('m3.login'); + } + } +} diff --git a/Modules/M3/Http/Middleware/BasicAuth.php b/Modules/M3/Http/Middleware/BasicAuth.php new file mode 100755 index 00000000..7dc997d3 --- /dev/null +++ b/Modules/M3/Http/Middleware/BasicAuth.php @@ -0,0 +1,57 @@ +checkPassword($login, $password, '%%SYSTEM%%')) { + return $next($request); + } + + return $this->unauthorized(); + } + + private function checkPassword(string $login, string $password, string $passwordFile): bool + { + if (! is_readable($passwordFile)) { + return false; + } + + $handle = fopen($passwordFile, 'rb'); + if ($handle === false) { + return false; + } + + try { + while (($line = fgets($handle)) !== false) { + $parts = explode(':', trim($line), 2); + if (count($parts) !== 2 || ! hash_equals($parts[0], $login)) { + continue; + } + + $storedHash = trim($parts[1]); + + return $storedHash !== '' && password_verify($password, $storedHash); + } + } finally { + fclose($handle); + } + + return false; + } + + private function unauthorized(): Response + { + return response('INVALID USERNAME OR PASSWORD. ACCESS DENIED', 401) + ->header('WWW-Authenticate', 'Basic realm="RESTRICTED ACCESS"'); + } +} diff --git a/Modules/M3/Http/Middleware/EncryptCookies.php b/Modules/M3/Http/Middleware/EncryptCookies.php new file mode 100755 index 00000000..0a17067a --- /dev/null +++ b/Modules/M3/Http/Middleware/EncryptCookies.php @@ -0,0 +1,17 @@ +check()) { + return redirect(RouteServiceProvider::HOME); + } + } + + return $next($request); + } +} diff --git a/Modules/M3/Http/Middleware/TrimStrings.php b/Modules/M3/Http/Middleware/TrimStrings.php new file mode 100755 index 00000000..a67129da --- /dev/null +++ b/Modules/M3/Http/Middleware/TrimStrings.php @@ -0,0 +1,19 @@ +allSubdomainsOfApplicationUrl(), + ]; + } +} diff --git a/Modules/M3/Http/Middleware/TrustProxies.php b/Modules/M3/Http/Middleware/TrustProxies.php new file mode 100755 index 00000000..1e3c7abc --- /dev/null +++ b/Modules/M3/Http/Middleware/TrustProxies.php @@ -0,0 +1,23 @@ +table = 'ICM428M'; + } + + // R428DV R428PL R428WHS R428STS R428US R428FIRST R428FAMILY R428EMPCDE R428ADMUSR R428PWRUSR --> + protected $fillable = [ + 'R428CO', 'R428PL', 'R428WH', 'R428STS', 'R428US', 'R428FIRST', 'R428FAMILY', 'R428EMPCDE', 'R428ADMUSR', 'R428PWRUSR', + ]; +} diff --git a/Modules/M3/Models/ICM658M.php b/Modules/M3/Models/ICM658M.php new file mode 100755 index 00000000..996e164f --- /dev/null +++ b/Modules/M3/Models/ICM658M.php @@ -0,0 +1,28 @@ +table = 'ICM658M'; + } + + protected $fillable = [ + 'R658CO', 'R658PL', 'R658WH', 'R658LC', 'R658PN', 'R658MQ', 'R658RQ', 'R658TL', 'R658RMQ', 'R658IZLCF', + ]; +} diff --git a/Modules/M3/Models/ShipTo.php b/Modules/M3/Models/ShipTo.php new file mode 100755 index 00000000..4544f7de --- /dev/null +++ b/Modules/M3/Models/ShipTo.php @@ -0,0 +1,62 @@ +validateUniqueComposite()) { + return parent::save($options); + } else { + return false; + // ->withErrors(['unique' => 'The combination of AUSHSHZP and AUSHWHS must be unique']) + // ->withInput(); + } + } + + protected function validateUniqueComposite() + { + $query = self::query(); + + // Check if the combination of AUSHSHZP and AUSHWHS already exists + $existingRecord = $query->where('AUSHSHZP', $this->AUSHSHZP) + ->where('AUSHWHS', $this->AUSHWHS); + + // If this is an existing record being updated, exclude itself from the check + if ($this->exists) { + $existingRecord->where($this->getKeyName(), '!=', $this->getKey()); + } + + if ($existingRecord->count() > 0) { + return false; + } else { + return true; + + } + } +} diff --git a/Modules/M3/Models/User.php b/Modules/M3/Models/User.php new file mode 100755 index 00000000..d16eb0b1 --- /dev/null +++ b/Modules/M3/Models/User.php @@ -0,0 +1,42 @@ + 'datetime', + ]; +} diff --git a/Modules/M3/Providers/.gitkeep b/Modules/M3/Providers/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Providers/M3ServiceProvider.php b/Modules/M3/Providers/M3ServiceProvider.php new file mode 100755 index 00000000..741dac5d --- /dev/null +++ b/Modules/M3/Providers/M3ServiceProvider.php @@ -0,0 +1,177 @@ +registerTranslations(); + $this->registerConfig(); + $this->registerViews(); + $this->registerHelpers(); + $this->registerCommands(); + $this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations')); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register(): void + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register the helpers. + * + * @return void + */ + protected function registerHelpers(): void + { + foreach (glob(__DIR__ . '/../Helpers/*.php') as $filename) { + require_once $filename; + } + } + + /** + * Dynamically Register Commands. + * + * @return void + */ + public function registerCommands(): void + { + if (! $this->app->runningInConsole()) { + return; + } + $commandPath = __DIR__ . '/../Console'; + $commands = collect(File::allFiles($commandPath)) + ->map(function ($file) { + return 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); + }) + ->filter(function ($class) { + return class_exists($class); + }) + ->values() + ->all(); + $this->commands($commands); + } + + /** + * Register config. + * + * @return void + */ + protected function registerConfig(): void + { + $this->publishes([ + module_path(ModuleInfo::name(), 'Config/config.php') => config_path(ModuleInfo::nameLower() . '.php'), + ], 'config'); + $this->mergeConfigFrom( + module_path(ModuleInfo::name(), 'Config/config.php'), + ModuleInfo::nameLower(), + ); + + // The legacy M3 application reads these keys directly as arrays.* and + // arrays_custom.*. Keep those public config keys while the application + // is hosted inside Core. + $this->mergeConfigFrom(module_path(ModuleInfo::name(), 'Config/arrays.php'), 'arrays'); + $this->mergeConfigFrom(module_path(ModuleInfo::name(), 'Config/arrays_custom.php'), 'arrays_custom'); + + // Legacy M3 storage disks now live under Core storage by default. + if (! config('filesystems.disks.publicLabels')) { + config(['filesystems.disks.publicLabels' => [ + 'driver' => 'local', + 'root' => config('m3.labels_path'), + 'visibility' => 'public', + ]]); + } + if (! config('filesystems.disks.publicCL')) { + config(['filesystems.disks.publicCL' => [ + 'driver' => 'local', + 'root' => config('m3.closing_orders_path'), + 'visibility' => 'public', + ]]); + } + } + + /** + * Register views. + * + * @return void + */ + public function registerViews(): void + { + $viewPath = resource_path('views/modules/' . ModuleInfo::nameLower()); + $sourcePath = module_path(ModuleInfo::name(), 'Resources/views'); + $this->publishes([ + $sourcePath => $viewPath, + ], ['views', ModuleInfo::nameLower() . '-module-views']); + $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), ModuleInfo::nameLower()); + } + + /** + * Register translations. + * + * @return void + */ + public function registerTranslations(): void + { + $langPath = resource_path('lang/modules/' . ModuleInfo::nameLower()); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower()); + } else { + $this->loadTranslationsFrom(module_path(ModuleInfo::name(), 'Resources/lang'), ModuleInfo::nameLower()); + } + } + + /** + * Regsiter View Paths + * + * @return array + */ + private function getPublishableViewPaths(): array + { + $paths = []; + foreach (Config::get('view.paths') as $path) { + if (is_dir($path . '/modules/' . ModuleInfo::nameLower())) { + $paths[] = $path . '/modules/' . ModuleInfo::nameLower(); + } + } + + return $paths; + } +} diff --git a/Modules/M3/Providers/RouteServiceProvider.php b/Modules/M3/Providers/RouteServiceProvider.php new file mode 100755 index 00000000..bd80df77 --- /dev/null +++ b/Modules/M3/Providers/RouteServiceProvider.php @@ -0,0 +1,72 @@ +mapApiRoutes(); + + $this->mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + * + * @return void + */ + protected function mapWebRoutes() + { + Route::prefix('m3') + ->name('m3.') + ->middleware('web') + ->namespace($this->moduleNamespace) + ->group(module_path('M3', '/Routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::prefix('api/m3') + ->name('m3.api.') + ->middleware('api') + ->namespace($this->moduleNamespace) + ->group(module_path('M3', '/Routes/api.php')); + } +} diff --git a/Modules/M3/Resources/assets/.gitkeep b/Modules/M3/Resources/assets/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Resources/assets/js/app.js b/Modules/M3/Resources/assets/js/app.js new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Resources/assets/liberty-theme/css/m3-core-shell.css b/Modules/M3/Resources/assets/liberty-theme/css/m3-core-shell.css new file mode 100755 index 00000000..ba2a3c7b --- /dev/null +++ b/Modules/M3/Resources/assets/liberty-theme/css/m3-core-shell.css @@ -0,0 +1,26 @@ +/* M3 integration inside the Core WMS shell. Core owns the global sidebar, topbar, typography and appearance. */ +.m3-core-page{font-family:inherit;color:inherit;width:100%;max-width:1600px;margin:0 auto;padding:1.5rem} +.m3-core-header{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;margin-bottom:1.5rem;padding:1.5rem;border:1px solid rgb(228 228 231);border-radius:1.5rem;background:linear-gradient(135deg,#020617,#0f172a 55%,#172554);color:#fff} +.m3-core-eyebrow{margin:0 0 .5rem;font-size:.75rem;font-weight:700;letter-spacing:.28em;color:#bfdbfe} +.m3-core-title{margin:0;font:inherit;font-size:2rem;font-weight:650;line-height:1.15;letter-spacing:-.025em;color:#fff} +.m3-core-context{margin:.5rem 0 0;color:#dbeafe} +.m3-core-actions{display:flex;gap:.5rem;flex-wrap:wrap} +.m3-core-breadcrumb{margin-bottom:1rem;color:rgb(82 82 91);font-size:.875rem} +.m3-core-content{color:rgb(24 24 27)} +.m3-core-content .container-fluid{padding:0} +.m3-core-content .panel,.m3-core-content .card,.m3-core-content .well{border:1px solid rgb(228 228 231);border-radius:1rem;background:#fff;box-shadow:0 1px 2px rgb(0 0 0/.04);overflow:hidden} +.m3-core-content .panel-heading,.m3-core-content .card-header{background:rgb(250 250 250);border-bottom:1px solid rgb(228 228 231);padding:.9rem 1rem;font-weight:600} +.m3-core-content table{color:inherit;background:transparent} +.m3-core-content .table>tbody>tr>td,.m3-core-content .table>tbody>tr>th,.m3-core-content .table>tfoot>tr>td,.m3-core-content .table>tfoot>tr>th,.m3-core-content .table>thead>tr>td,.m3-core-content .table>thead>tr>th{border-color:rgb(228 228 231)} +.m3-core-content input,.m3-core-content select,.m3-core-content textarea,.m3-core-content button{font-family:inherit} +.m3-core-alert{padding:1rem;border:1px solid rgb(254 202 202);border-radius:1rem;background:rgb(254 242 242);color:rgb(153 27 27);font-weight:600} +html.dark .m3-core-header{border-color:rgb(63 63 70);background:linear-gradient(135deg,#020617,#0f172a 55%,#172554)} +html.dark .m3-core-breadcrumb{color:rgb(161 161 170)} +html.dark .m3-core-content{color:rgb(244 244 245)} +html.dark .m3-core-content .panel,html.dark .m3-core-content .card,html.dark .m3-core-content .well{border-color:rgb(63 63 70);background:rgb(24 24 27)} +html.dark .m3-core-content .panel-heading,html.dark .m3-core-content .card-header{background:rgb(39 39 42);border-color:rgb(63 63 70);color:rgb(244 244 245)} +html.dark .m3-core-content .table{color:rgb(244 244 245)} +html.dark .m3-core-content .table>tbody>tr>td,html.dark .m3-core-content .table>tbody>tr>th,html.dark .m3-core-content .table>tfoot>tr>td,html.dark .m3-core-content .table>tfoot>tr>th,html.dark .m3-core-content .table>thead>tr>td,html.dark .m3-core-content .table>thead>tr>th{border-color:rgb(63 63 70)} +html.dark .m3-core-content input,html.dark .m3-core-content select,html.dark .m3-core-content textarea{background:rgb(39 39 42);border-color:rgb(82 82 91);color:rgb(244 244 245)} +html.dark .m3-core-alert{border-color:rgb(127 29 29);background:rgb(69 10 10);color:rgb(254 202 202)} +@media(max-width:768px){.m3-core-page{padding:1rem}.m3-core-header{padding:1.25rem}.m3-core-title{font-size:1.6rem}} diff --git a/Modules/M3/Resources/assets/sass/app.scss b/Modules/M3/Resources/assets/sass/app.scss new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Resources/css/app.css b/Modules/M3/Resources/css/app.css new file mode 100755 index 00000000..45f59d83 --- /dev/null +++ b/Modules/M3/Resources/css/app.css @@ -0,0 +1 @@ +/* M3 module styles are provided by the Core application theme. */ diff --git a/Modules/M3/Resources/js/app.js b/Modules/M3/Resources/js/app.js new file mode 100755 index 00000000..40c55f65 --- /dev/null +++ b/Modules/M3/Resources/js/app.js @@ -0,0 +1 @@ +require('./bootstrap'); diff --git a/Modules/M3/Resources/js/bootstrap.js b/Modules/M3/Resources/js/bootstrap.js new file mode 100755 index 00000000..69225776 --- /dev/null +++ b/Modules/M3/Resources/js/bootstrap.js @@ -0,0 +1,28 @@ +window._ = require('lodash'); + +/** + * We'll load the axios HTTP library which allows us to easily issue requests + * to our Laravel back-end. This library automatically handles sending the + * CSRF token as a header based on the value of the "XSRF" token cookie. + */ + +window.axios = require('axios'); + +window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; + +/** + * Echo exposes an expressive API for subscribing to channels and listening + * for events that are broadcast by Laravel. Echo and event broadcasting + * allows your team to easily build robust real-time web applications. + */ + +// import Echo from 'laravel-echo'; + +// window.Pusher = require('pusher-js'); + +// window.Echo = new Echo({ +// broadcaster: 'pusher', +// key: process.env.MIX_PUSHER_APP_KEY, +// cluster: process.env.MIX_PUSHER_APP_CLUSTER, +// forceTLS: true +// }); diff --git a/Modules/M3/Resources/lang/.gitkeep b/Modules/M3/Resources/lang/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Resources/lang/en/auth.php b/Modules/M3/Resources/lang/en/auth.php new file mode 100755 index 00000000..6598e2c0 --- /dev/null +++ b/Modules/M3/Resources/lang/en/auth.php @@ -0,0 +1,20 @@ + 'These credentials do not match our records.', + 'password' => 'The provided password is incorrect.', + 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + +]; diff --git a/Modules/M3/Resources/lang/en/pagination.php b/Modules/M3/Resources/lang/en/pagination.php new file mode 100755 index 00000000..d4814118 --- /dev/null +++ b/Modules/M3/Resources/lang/en/pagination.php @@ -0,0 +1,19 @@ + '« Previous', + 'next' => 'Next »', + +]; diff --git a/Modules/M3/Resources/lang/en/passwords.php b/Modules/M3/Resources/lang/en/passwords.php new file mode 100755 index 00000000..2345a56b --- /dev/null +++ b/Modules/M3/Resources/lang/en/passwords.php @@ -0,0 +1,22 @@ + 'Your password has been reset!', + 'sent' => 'We have emailed your password reset link!', + 'throttled' => 'Please wait before retrying.', + 'token' => 'This password reset token is invalid.', + 'user' => "We can't find a user with that email address.", + +]; diff --git a/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-area-demo.js b/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-area-demo.js new file mode 100755 index 00000000..7a1da791 --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-area-demo.js @@ -0,0 +1,57 @@ +// Set new default font family and font color to mimic Bootstrap's default styling +Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'; +Chart.defaults.global.defaultFontColor = '#292b2c'; + +// Area Chart Example +let ctx = document.getElementById("myAreaChart"); +if (ctx) { +new Chart(ctx, { + type: 'line', + data: { + labels: ["Mar 1", "Mar 2", "Mar 3", "Mar 4", "Mar 5", "Mar 6", "Mar 7", "Mar 8", "Mar 9", "Mar 10", "Mar 11", "Mar 12", "Mar 13"], + datasets: [{ + label: "Sessions", + lineTension: 0.3, + backgroundColor: "rgba(2,117,216,0.2)", + borderColor: "rgba(2,117,216,1)", + pointRadius: 5, + pointBackgroundColor: "rgba(2,117,216,1)", + pointBorderColor: "rgba(255,255,255,0.8)", + pointHoverRadius: 5, + pointHoverBackgroundColor: "rgba(2,117,216,1)", + pointHitRadius: 50, + pointBorderWidth: 2, + data: [10000, 30162, 26263, 18394, 18287, 28682, 31274, 33259, 25849, 24159, 32651, 31984, 38451], + }], + }, + options: { + scales: { + xAxes: [{ + time: { + unit: 'date' + }, + gridLines: { + display: false + }, + ticks: { + maxTicksLimit: 7 + } + }], + yAxes: [{ + ticks: { + min: 0, + max: 40000, + maxTicksLimit: 5 + }, + gridLines: { + color: "rgba(0, 0, 0, .125)", + } + }], + }, + legend: { + display: false + } + } + +}); +} diff --git a/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-bar-demo.js b/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-bar-demo.js new file mode 100755 index 00000000..f205f718 --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-bar-demo.js @@ -0,0 +1,50 @@ +// Set new default font family and font color to mimic Bootstrap's default styling +Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'; +Chart.defaults.global.defaultFontColor = '#292b2c'; + +// Bar Chart Example +let ctx = document.getElementById("myBarChart"); +if (ctx) { +new Chart(ctx, { + type: 'bar', + data: { + labels: ["January", "February", "March", "April", "May", "June"], + datasets: [{ + label: "Revenue", + backgroundColor: "rgba(2,117,216,1)", + borderColor: "rgba(2,117,216,1)", + data: [4215, 5312, 6251, 7841, 9821, 14984], + }], + }, + options: { + scales: { + xAxes: [{ + time: { + unit: 'month' + }, + gridLines: { + display: false + }, + ticks: { + maxTicksLimit: 6 + } + }], + yAxes: [{ + ticks: { + min: 0, + max: 15000, + maxTicksLimit: 5 + }, + gridLines: { + display: true + } + }], + }, + legend: { + display: false + } + } + +}); + +} \ No newline at end of file diff --git a/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-pie-demo.js b/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-pie-demo.js new file mode 100755 index 00000000..6ce90f7e --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/assets/demo/chart-pie-demo.js @@ -0,0 +1,19 @@ +// Set new default font family and font color to mimic Bootstrap's default styling +Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'; +Chart.defaults.global.defaultFontColor = '#292b2c'; + +// Pie Chart Example +let ctx = document.getElementById("myPieChart"); +if (ctx){ +new Chart(ctx, { + type: 'pie', + data: { + labels: ["Blue", "Red", "Yellow", "Green"], + datasets: [{ + data: [12.21, 15.58, 11.25, 8.32], + backgroundColor: ['#007bff', '#dc3545', '#ffc107', '#28a745'], + }], + }, + +}); +} diff --git a/Modules/M3/Resources/public/liberty-theme/assets/demo/datatables-demo.js b/Modules/M3/Resources/public/liberty-theme/assets/demo/datatables-demo.js new file mode 100755 index 00000000..f2eecbfe --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/assets/demo/datatables-demo.js @@ -0,0 +1,4 @@ +// Call the dataTables jQuery plugin +$(document).ready(function() { + $('#dataTable').DataTable(); +}); diff --git a/Modules/M3/Resources/public/liberty-theme/assets/img/error-404-monochrome.svg b/Modules/M3/Resources/public/liberty-theme/assets/img/error-404-monochrome.svg new file mode 100755 index 00000000..f0d345f9 --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/assets/img/error-404-monochrome.svg @@ -0,0 +1 @@ +error-404-monochrome \ No newline at end of file diff --git a/Modules/M3/Resources/public/liberty-theme/css/m3-core-shell.css b/Modules/M3/Resources/public/liberty-theme/css/m3-core-shell.css new file mode 100755 index 00000000..ba2a3c7b --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/css/m3-core-shell.css @@ -0,0 +1,26 @@ +/* M3 integration inside the Core WMS shell. Core owns the global sidebar, topbar, typography and appearance. */ +.m3-core-page{font-family:inherit;color:inherit;width:100%;max-width:1600px;margin:0 auto;padding:1.5rem} +.m3-core-header{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;margin-bottom:1.5rem;padding:1.5rem;border:1px solid rgb(228 228 231);border-radius:1.5rem;background:linear-gradient(135deg,#020617,#0f172a 55%,#172554);color:#fff} +.m3-core-eyebrow{margin:0 0 .5rem;font-size:.75rem;font-weight:700;letter-spacing:.28em;color:#bfdbfe} +.m3-core-title{margin:0;font:inherit;font-size:2rem;font-weight:650;line-height:1.15;letter-spacing:-.025em;color:#fff} +.m3-core-context{margin:.5rem 0 0;color:#dbeafe} +.m3-core-actions{display:flex;gap:.5rem;flex-wrap:wrap} +.m3-core-breadcrumb{margin-bottom:1rem;color:rgb(82 82 91);font-size:.875rem} +.m3-core-content{color:rgb(24 24 27)} +.m3-core-content .container-fluid{padding:0} +.m3-core-content .panel,.m3-core-content .card,.m3-core-content .well{border:1px solid rgb(228 228 231);border-radius:1rem;background:#fff;box-shadow:0 1px 2px rgb(0 0 0/.04);overflow:hidden} +.m3-core-content .panel-heading,.m3-core-content .card-header{background:rgb(250 250 250);border-bottom:1px solid rgb(228 228 231);padding:.9rem 1rem;font-weight:600} +.m3-core-content table{color:inherit;background:transparent} +.m3-core-content .table>tbody>tr>td,.m3-core-content .table>tbody>tr>th,.m3-core-content .table>tfoot>tr>td,.m3-core-content .table>tfoot>tr>th,.m3-core-content .table>thead>tr>td,.m3-core-content .table>thead>tr>th{border-color:rgb(228 228 231)} +.m3-core-content input,.m3-core-content select,.m3-core-content textarea,.m3-core-content button{font-family:inherit} +.m3-core-alert{padding:1rem;border:1px solid rgb(254 202 202);border-radius:1rem;background:rgb(254 242 242);color:rgb(153 27 27);font-weight:600} +html.dark .m3-core-header{border-color:rgb(63 63 70);background:linear-gradient(135deg,#020617,#0f172a 55%,#172554)} +html.dark .m3-core-breadcrumb{color:rgb(161 161 170)} +html.dark .m3-core-content{color:rgb(244 244 245)} +html.dark .m3-core-content .panel,html.dark .m3-core-content .card,html.dark .m3-core-content .well{border-color:rgb(63 63 70);background:rgb(24 24 27)} +html.dark .m3-core-content .panel-heading,html.dark .m3-core-content .card-header{background:rgb(39 39 42);border-color:rgb(63 63 70);color:rgb(244 244 245)} +html.dark .m3-core-content .table{color:rgb(244 244 245)} +html.dark .m3-core-content .table>tbody>tr>td,html.dark .m3-core-content .table>tbody>tr>th,html.dark .m3-core-content .table>tfoot>tr>td,html.dark .m3-core-content .table>tfoot>tr>th,html.dark .m3-core-content .table>thead>tr>td,html.dark .m3-core-content .table>thead>tr>th{border-color:rgb(63 63 70)} +html.dark .m3-core-content input,html.dark .m3-core-content select,html.dark .m3-core-content textarea{background:rgb(39 39 42);border-color:rgb(82 82 91);color:rgb(244 244 245)} +html.dark .m3-core-alert{border-color:rgb(127 29 29);background:rgb(69 10 10);color:rgb(254 202 202)} +@media(max-width:768px){.m3-core-page{padding:1rem}.m3-core-header{padding:1.25rem}.m3-core-title{font-size:1.6rem}} diff --git a/Modules/M3/Resources/public/liberty-theme/css/morris.css b/Modules/M3/Resources/public/liberty-theme/css/morris.css new file mode 100755 index 00000000..fd65bed1 --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/css/morris.css @@ -0,0 +1,2 @@ +.morris-hover{overflow: auto; height: 300px;position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0} +.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0} diff --git a/Modules/M3/Resources/public/liberty-theme/css/styles.css b/Modules/M3/Resources/public/liberty-theme/css/styles.css new file mode 100755 index 00000000..95c0c8aa --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/css/styles.css @@ -0,0 +1,11820 @@ +@charset "UTF-8"; +/*! +* Start Bootstrap - SB Admin v7.0.3 (https://startbootstrap.com/template/sb-admin) +* Copyright 2013-2021 Start Bootstrap +* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-sb-admin/blob/master/LICENSE) +*/ +/*! + * Bootstrap v5.1.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; + --bs-primary: #7d8faa; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-primary-rgb: 13, 110, 253; + --bs-secondary-rgb: 108, 117, 125; + --bs-success-rgb: 25, 135, 84; + --bs-info-rgb: 125, 143, 170; + --bs-warning-rgb: 255, 193, 7; + --bs-danger-rgb: 220, 53, 69; + --bs-light-rgb: 248, 249, 250; + --bs-dark-rgb: 33, 37, 41; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-body-rgb: 33, 37, 41; + --bs-font-sans-serif: "Instrument Sans", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #212529; + --bs-body-bg: #fff; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth; + } +} + +body { + margin: 0; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +hr { + margin: 1rem 0; + color: inherit; + background-color: currentColor; + border: 0; + opacity: 0.25; +} + +hr:not([size]) { + height: 1px; +} + +h6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 { + margin-top: 0; + margin-bottom: 0.5rem; + font-weight: 500; + line-height: 1.2; +} + +h1, .h1 { + font-size: calc(1.375rem + 1.5vw); +} +@media (min-width: 1200px) { + h1, .h1 { + font-size: 2.5rem; + } +} + +h2, .h2 { + font-size: calc(1.325rem + 0.9vw); +} +@media (min-width: 1200px) { + h2, .h2 { + font-size: 2rem; + } +} + +h3, .h3 { + font-size: calc(1.3rem + 0.6vw); +} +@media (min-width: 1200px) { + h3, .h3 { + font-size: 1.75rem; + } +} + +h4, .h4 { + font-size: calc(1.275rem + 0.3vw); +} +@media (min-width: 1200px) { + h4, .h4 { + font-size: 1.5rem; + } +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-bs-original-title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul { + padding-left: 2rem; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: 0.5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +b, +strong { + font-weight: bolder; +} + +small, .small { + font-size: 0.875em; +} + +mark, .mark { + padding: 0.2em; + background-color: #fcf8e3; +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +a { + color: #0d6efd; + text-decoration: underline; +} +a:hover { + color: #0a58ca; +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; +} + +pre, +code, +kbd, +samp { + font-family: var(--bs-font-monospace); + font-size: 1em; + direction: ltr /* rtl:ignore */; + unicode-bidi: bidi-override; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: 0.875em; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +code { + font-size: 0.875em; + color: #d63384; + word-wrap: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.2rem 0.4rem; + font-size: 0.875em; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} +kbd kbd { + padding: 0; + font-size: 1em; + font-weight: 700; +} + +figure { + margin: 0 0 1rem; +} + +img, +svg { + vertical-align: middle; +} + +table { + caption-side: bottom; + border-collapse: collapse; +} + +caption { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: #6c757d; + text-align: left; +} + +th { + text-align: inherit; + text-align: -webkit-match-parent; +} + +thead, +tbody, +tfoot, +tr, +td, +th { + border-color: inherit; + border-style: solid; + border-width: 0; +} + +label { + display: inline-block; +} + +button { + border-radius: 0; +} + +button:focus:not(:focus-visible) { + outline: 0; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +select { + text-transform: none; +} + +[role=button] { + cursor: pointer; +} + +select { + word-wrap: normal; +} +select:disabled { + opacity: 1; +} + +[list]::-webkit-calendar-picker-indicator { + display: none; +} + +button, +[type=button], +[type=reset], +[type=submit] { + -webkit-appearance: button; +} +button:not(:disabled), +[type=button]:not(:disabled), +[type=reset]:not(:disabled), +[type=submit]:not(:disabled) { + cursor: pointer; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +textarea { + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: 0.5rem; + font-size: calc(1.275rem + 0.3vw); + line-height: inherit; +} +@media (min-width: 1200px) { + legend { + font-size: 1.5rem; + } +} +legend + * { + clear: left; +} + +::-webkit-datetime-edit-fields-wrapper, +::-webkit-datetime-edit-text, +::-webkit-datetime-edit-minute, +::-webkit-datetime-edit-hour-field, +::-webkit-datetime-edit-day-field, +::-webkit-datetime-edit-month-field, +::-webkit-datetime-edit-year-field { + padding: 0; +} + +::-webkit-inner-spin-button { + height: auto; +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield; +} + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-color-swatch-wrapper { + padding: 0; +} + +::-webkit-file-upload-button { + font: inherit; +} + +::file-selector-button { + font: inherit; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +iframe { + border: 0; +} + +summary { + display: list-item; + cursor: pointer; +} + +progress { + vertical-align: baseline; +} + +[hidden] { + display: none !important; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-1 { + font-size: 5rem; + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-2 { + font-size: 4.5rem; + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-3 { + font-size: 4rem; + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-4 { + font-size: 3.5rem; + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-5 { + font-size: 3rem; + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-6 { + font-size: 2.5rem; + } +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 0.875em; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} +.blockquote > :last-child { + margin-bottom: 0; +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: 0.875em; + color: #6c757d; +} +.blockquote-footer::before { + content: "โ€”ย "; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 0.875em; + color: #6c757d; +} + +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + width: 100%; + padding-right: var(--bs-gutter-x, 0.75rem); + padding-left: var(--bs-gutter-x, 0.75rem); + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container-sm, .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container-md, .container-sm, .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container-lg, .container-md, .container-sm, .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1140px; + } +} +@media (min-width: 1400px) { + .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1320px; + } +} +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(var(--bs-gutter-y) * -1); + margin-right: calc(var(--bs-gutter-x) * -.5); + margin-left: calc(var(--bs-gutter-x) * -.5); +} +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * .5); + padding-left: calc(var(--bs-gutter-x) * .5); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.33333333%; +} + +.offset-2 { + margin-left: 16.66666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333333%; +} + +.offset-5 { + margin-left: 41.66666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333333%; +} + +.offset-8 { + margin-left: 66.66666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333333%; +} + +.offset-11 { + margin-left: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-sm-0 { + margin-left: 0; + } + + .offset-sm-1 { + margin-left: 8.33333333%; + } + + .offset-sm-2 { + margin-left: 16.66666667%; + } + + .offset-sm-3 { + margin-left: 25%; + } + + .offset-sm-4 { + margin-left: 33.33333333%; + } + + .offset-sm-5 { + margin-left: 41.66666667%; + } + + .offset-sm-6 { + margin-left: 50%; + } + + .offset-sm-7 { + margin-left: 58.33333333%; + } + + .offset-sm-8 { + margin-left: 66.66666667%; + } + + .offset-sm-9 { + margin-left: 75%; + } + + .offset-sm-10 { + margin-left: 83.33333333%; + } + + .offset-sm-11 { + margin-left: 91.66666667%; + } + + .g-sm-0, +.gx-sm-0 { + --bs-gutter-x: 0; + } + + .g-sm-0, +.gy-sm-0 { + --bs-gutter-y: 0; + } + + .g-sm-1, +.gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + + .g-sm-1, +.gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + + .g-sm-2, +.gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + + .g-sm-2, +.gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + + .g-sm-3, +.gx-sm-3 { + --bs-gutter-x: 1rem; + } + + .g-sm-3, +.gy-sm-3 { + --bs-gutter-y: 1rem; + } + + .g-sm-4, +.gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + + .g-sm-4, +.gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + + .g-sm-5, +.gx-sm-5 { + --bs-gutter-x: 3rem; + } + + .g-sm-5, +.gy-sm-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-md-0 { + margin-left: 0; + } + + .offset-md-1 { + margin-left: 8.33333333%; + } + + .offset-md-2 { + margin-left: 16.66666667%; + } + + .offset-md-3 { + margin-left: 25%; + } + + .offset-md-4 { + margin-left: 33.33333333%; + } + + .offset-md-5 { + margin-left: 41.66666667%; + } + + .offset-md-6 { + margin-left: 50%; + } + + .offset-md-7 { + margin-left: 58.33333333%; + } + + .offset-md-8 { + margin-left: 66.66666667%; + } + + .offset-md-9 { + margin-left: 75%; + } + + .offset-md-10 { + margin-left: 83.33333333%; + } + + .offset-md-11 { + margin-left: 91.66666667%; + } + + .g-md-0, +.gx-md-0 { + --bs-gutter-x: 0; + } + + .g-md-0, +.gy-md-0 { + --bs-gutter-y: 0; + } + + .g-md-1, +.gx-md-1 { + --bs-gutter-x: 0.25rem; + } + + .g-md-1, +.gy-md-1 { + --bs-gutter-y: 0.25rem; + } + + .g-md-2, +.gx-md-2 { + --bs-gutter-x: 0.5rem; + } + + .g-md-2, +.gy-md-2 { + --bs-gutter-y: 0.5rem; + } + + .g-md-3, +.gx-md-3 { + --bs-gutter-x: 1rem; + } + + .g-md-3, +.gy-md-3 { + --bs-gutter-y: 1rem; + } + + .g-md-4, +.gx-md-4 { + --bs-gutter-x: 1.5rem; + } + + .g-md-4, +.gy-md-4 { + --bs-gutter-y: 1.5rem; + } + + .g-md-5, +.gx-md-5 { + --bs-gutter-x: 3rem; + } + + .g-md-5, +.gy-md-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-lg-0 { + margin-left: 0; + } + + .offset-lg-1 { + margin-left: 8.33333333%; + } + + .offset-lg-2 { + margin-left: 16.66666667%; + } + + .offset-lg-3 { + margin-left: 25%; + } + + .offset-lg-4 { + margin-left: 33.33333333%; + } + + .offset-lg-5 { + margin-left: 41.66666667%; + } + + .offset-lg-6 { + margin-left: 50%; + } + + .offset-lg-7 { + margin-left: 58.33333333%; + } + + .offset-lg-8 { + margin-left: 66.66666667%; + } + + .offset-lg-9 { + margin-left: 75%; + } + + .offset-lg-10 { + margin-left: 83.33333333%; + } + + .offset-lg-11 { + margin-left: 91.66666667%; + } + + .g-lg-0, +.gx-lg-0 { + --bs-gutter-x: 0; + } + + .g-lg-0, +.gy-lg-0 { + --bs-gutter-y: 0; + } + + .g-lg-1, +.gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + + .g-lg-1, +.gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + + .g-lg-2, +.gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + + .g-lg-2, +.gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + + .g-lg-3, +.gx-lg-3 { + --bs-gutter-x: 1rem; + } + + .g-lg-3, +.gy-lg-3 { + --bs-gutter-y: 1rem; + } + + .g-lg-4, +.gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + + .g-lg-4, +.gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + + .g-lg-5, +.gx-lg-5 { + --bs-gutter-x: 3rem; + } + + .g-lg-5, +.gy-lg-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-xl-0 { + margin-left: 0; + } + + .offset-xl-1 { + margin-left: 8.33333333%; + } + + .offset-xl-2 { + margin-left: 16.66666667%; + } + + .offset-xl-3 { + margin-left: 25%; + } + + .offset-xl-4 { + margin-left: 33.33333333%; + } + + .offset-xl-5 { + margin-left: 41.66666667%; + } + + .offset-xl-6 { + margin-left: 50%; + } + + .offset-xl-7 { + margin-left: 58.33333333%; + } + + .offset-xl-8 { + margin-left: 66.66666667%; + } + + .offset-xl-9 { + margin-left: 75%; + } + + .offset-xl-10 { + margin-left: 83.33333333%; + } + + .offset-xl-11 { + margin-left: 91.66666667%; + } + + .g-xl-0, +.gx-xl-0 { + --bs-gutter-x: 0; + } + + .g-xl-0, +.gy-xl-0 { + --bs-gutter-y: 0; + } + + .g-xl-1, +.gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + + .g-xl-1, +.gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + + .g-xl-2, +.gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + + .g-xl-2, +.gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + + .g-xl-3, +.gx-xl-3 { + --bs-gutter-x: 1rem; + } + + .g-xl-3, +.gy-xl-3 { + --bs-gutter-y: 1rem; + } + + .g-xl-4, +.gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + + .g-xl-4, +.gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + + .g-xl-5, +.gx-xl-5 { + --bs-gutter-x: 3rem; + } + + .g-xl-5, +.gy-xl-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-xxl-0 { + margin-left: 0; + } + + .offset-xxl-1 { + margin-left: 8.33333333%; + } + + .offset-xxl-2 { + margin-left: 16.66666667%; + } + + .offset-xxl-3 { + margin-left: 25%; + } + + .offset-xxl-4 { + margin-left: 33.33333333%; + } + + .offset-xxl-5 { + margin-left: 41.66666667%; + } + + .offset-xxl-6 { + margin-left: 50%; + } + + .offset-xxl-7 { + margin-left: 58.33333333%; + } + + .offset-xxl-8 { + margin-left: 66.66666667%; + } + + .offset-xxl-9 { + margin-left: 75%; + } + + .offset-xxl-10 { + margin-left: 83.33333333%; + } + + .offset-xxl-11 { + margin-left: 91.66666667%; + } + + .g-xxl-0, +.gx-xxl-0 { + --bs-gutter-x: 0; + } + + .g-xxl-0, +.gy-xxl-0 { + --bs-gutter-y: 0; + } + + .g-xxl-1, +.gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + + .g-xxl-1, +.gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + + .g-xxl-2, +.gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + + .g-xxl-2, +.gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + + .g-xxl-3, +.gx-xxl-3 { + --bs-gutter-x: 1rem; + } + + .g-xxl-3, +.gy-xxl-3 { + --bs-gutter-y: 1rem; + } + + .g-xxl-4, +.gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + + .g-xxl-4, +.gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + + .g-xxl-5, +.gx-xxl-5 { + --bs-gutter-x: 3rem; + } + + .g-xxl-5, +.gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} +.table, .dataTable-table { + --bs-table-bg: transparent; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: #212529; + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: #212529; + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: #212529; + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: #212529; + vertical-align: top; + border-color: #dee2e6; +} +.table > :not(caption) > * > *, .dataTable-table > :not(caption) > * > * { + padding: 0.5rem 0.5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg); +} +div.table-responsive > table > tbody > tr:last-child > td{ + border-bottom-width: 0px; +} +.table > tbody, .dataTable-table > tbody { + vertical-align: inherit; +} +.table > thead, .dataTable-table > thead { + vertical-align: bottom; +} +.table > :not(:last-child) > :last-child > *, .dataTable-table > :not(:last-child) > :last-child > * { + border-bottom-color: currentColor; +} + +.caption-top { + caption-side: top; +} + +.table-sm > :not(caption) > * > * { + padding: 0.25rem 0.25rem; +} + +.table-bordered > :not(caption) > *, .dataTable-table > :not(caption) > * { + border-width: 1px 0; +} +.table-bordered > :not(caption) > * > *, .dataTable-table > :not(caption) > * > * { + border-width: 0 1px; +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0; +} + +.table-striped > tbody > tr:nth-of-type(odd) { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color); +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color); +} + +.table-hover > tbody > tr:hover, .dataTable-table > tbody > tr:hover { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color); +} + +.table-primary { + --bs-table-bg: #cfe2ff; + --bs-table-striped-bg: #c5d7f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bacbe6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfd1ec; + --bs-table-hover-color: #000; + color: #000; + border-color: #bacbe6; +} + +.table-secondary { + --bs-table-bg: #e2e3e5; + --bs-table-striped-bg: #d7d8da; + --bs-table-striped-color: #000; + --bs-table-active-bg: #cbccce; + --bs-table-active-color: #000; + --bs-table-hover-bg: #d1d2d4; + --bs-table-hover-color: #000; + color: #000; + border-color: #cbccce; +} + +.table-success { + --bs-table-bg: #d1e7dd; + --bs-table-striped-bg: #c7dbd2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bcd0c7; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c1d6cc; + --bs-table-hover-color: #000; + color: #000; + border-color: #bcd0c7; +} + +.table-info { + --bs-table-bg: #cff4fc; + --bs-table-striped-bg: #c5e8ef; + --bs-table-striped-color: #000; + --bs-table-active-bg: #badce3; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfe2e9; + --bs-table-hover-color: #000; + color: #000; + border-color: #badce3; +} + +.table-warning { + --bs-table-bg: #fff3cd; + --bs-table-striped-bg: #f2e7c3; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6dbb9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ece1be; + --bs-table-hover-color: #000; + color: #000; + border-color: #e6dbb9; +} + +.table-danger { + --bs-table-bg: #f8d7da; + --bs-table-striped-bg: #eccccf; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfc2c4; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5c7ca; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfc2c4; +} + +.table-light { + --bs-table-bg: #f8f9fa; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfe0e1; +} + +.table-dark { + --bs-table-bg: #212529; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: #fff; + border-color: #373b3e; +} + +.table-responsive, .dataTable-wrapper .dataTable-container { + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +.form-label { + margin-bottom: 0.5rem; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; +} + +.form-text { + margin-top: 0.25rem; + font-size: 0.875em; + color: #6c757d; +} + +.form-control, .dataTable-input { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control, .dataTable-input { + transition: none; + } +} +.form-control[type=file], [type=file].dataTable-input { + overflow: hidden; +} +.form-control[type=file]:not(:disabled):not([readonly]), [type=file].dataTable-input:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control:focus, .dataTable-input:focus { + color: #212529; + background-color: #fff; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-control::-webkit-date-and-time-value, .dataTable-input::-webkit-date-and-time-value { + height: 1.5em; +} +.form-control::-moz-placeholder, .dataTable-input::-moz-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:-ms-input-placeholder, .dataTable-input:-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::placeholder, .dataTable-input::placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:disabled, .dataTable-input:disabled, .form-control[readonly], [readonly].dataTable-input { + background-color: #e9ecef; + opacity: 1; +} +.form-control::-webkit-file-upload-button, .dataTable-input::-webkit-file-upload-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + -webkit-margin-end: 0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +.form-control::file-selector-button, .dataTable-input::file-selector-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + -webkit-margin-end: 0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button, .dataTable-input::-webkit-file-upload-button { + -webkit-transition: none; + transition: none; + } + .form-control::file-selector-button, .dataTable-input::file-selector-button { + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button, .dataTable-input:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3; +} +.form-control:hover:not(:disabled):not([readonly])::file-selector-button, .dataTable-input:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #dde0e3; +} +.form-control::-webkit-file-upload-button, .dataTable-input::-webkit-file-upload-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + -webkit-margin-end: 0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button, .dataTable-input::-webkit-file-upload-button { + -webkit-transition: none; + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button, .dataTable-input:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: 0.375rem 0; + margin-bottom: 0; + line-height: 1.5; + color: #212529; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} +.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm { + min-height: calc(1.5em + 0.5rem + 2px); + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; +} +.form-control-sm::-webkit-file-upload-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} +.form-control-sm::file-selector-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} +.form-control-sm::-webkit-file-upload-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} + +.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; +} +.form-control-lg::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} +.form-control-lg::file-selector-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} +.form-control-lg::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} + +textarea.form-control, textarea.dataTable-input { + min-height: calc(1.5em + 0.75rem + 2px); +} +textarea.form-control-sm { + min-height: calc(1.5em + 0.5rem + 2px); +} +textarea.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); +} + +.form-control-color { + width: 3rem; + height: auto; + padding: 0.375rem; +} +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control-color::-moz-color-swatch { + height: 1.5em; + border-radius: 0.25rem; +} +.form-control-color::-webkit-color-swatch { + height: 1.5em; + border-radius: 0.25rem; +} + +.form-select, .dataTable-selector { + display: block; + width: 100%; + padding: 0.375rem 2.25rem 0.375rem 0.75rem; + -moz-padding-start: calc(0.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + background-size: 16px 12px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-select, .dataTable-selector { + transition: none; + } +} +.form-select:focus, .dataTable-selector:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-select[multiple], [multiple].dataTable-selector, .form-select[size]:not([size="1"]), [size].dataTable-selector:not([size="1"]) { + padding-right: 0.75rem; + background-image: none; +} +.form-select:disabled, .dataTable-selector:disabled { + background-color: #e9ecef; +} +.form-select:-moz-focusring, .dataTable-selector:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #212529; +} + +.form-select-sm { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + font-size: 0.875rem; +} + +.form-select-lg { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 1rem; + font-size: 1.25rem; +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: 0.125rem; +} +.form-check .form-check-input { + float: left; + margin-left: -1.5em; +} + +.form-check-input { + width: 1em; + height: 1em; + margin-top: 0.25em; + vertical-align: top; + background-color: #fff; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: 1px solid rgba(0, 0, 0, 0.25); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-print-color-adjust: exact; + color-adjust: exact; +} +.form-check-input[type=checkbox] { + border-radius: 0.25em; +} +.form-check-input[type=radio] { + border-radius: 50%; +} +.form-check-input:active { + filter: brightness(90%); +} +.form-check-input:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd; +} +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"); +} +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); +} +.form-check-input[type=checkbox]:indeterminate { + background-color: #0d6efd; + border-color: #0d6efd; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); +} +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: 0.5; +} +.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { + opacity: 0.5; +} + +.form-switch { + padding-left: 2.5em; +} +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-switch .form-check-input { + transition: none; + } +} +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e"); +} +.form-switch .form-check-input:checked { + background-position: right center; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem; +} + +.btn-check { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.btn-check[disabled] + .btn, .btn-check:disabled + .btn { + pointer-events: none; + filter: none; + opacity: 0.65; +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.form-range:focus { + outline: 0; +} +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-range::-moz-focus-outer { + border: 0; +} +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -0.25rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -webkit-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none; + } +} +.form-range::-webkit-slider-thumb:active { + background-color: #b6d4fe; +} +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -moz-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none; + } +} +.form-range::-moz-range-thumb:active { + background-color: #b6d4fe; +} +.form-range::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range:disabled { + pointer-events: none; +} +.form-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd; +} +.form-range:disabled::-moz-range-thumb { + background-color: #adb5bd; +} + +.form-floating { + position: relative; +} +.form-floating > .form-control, .form-floating > .dataTable-input, +.form-floating > .form-select, +.form-floating > .dataTable-selector { + height: calc(3.5rem + 2px); + line-height: 1.25; +} +.form-floating > label { + position: absolute; + top: 0; + left: 0; + height: 100%; + padding: 1rem 0.75rem; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-floating > label { + transition: none; + } +} +.form-floating > .form-control, .form-floating > .dataTable-input { + padding: 1rem 0.75rem; +} +.form-floating > .form-control::-moz-placeholder, .form-floating > .dataTable-input::-moz-placeholder { + color: transparent; +} +.form-floating > .form-control:-ms-input-placeholder, .form-floating > .dataTable-input:-ms-input-placeholder { + color: transparent; +} +.form-floating > .form-control::placeholder, .form-floating > .dataTable-input::placeholder { + color: transparent; +} +.form-floating > .form-control:not(:-moz-placeholder-shown), .form-floating > .dataTable-input:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:not(:-ms-input-placeholder), .form-floating > .dataTable-input:not(:-ms-input-placeholder) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:focus, .form-floating > .dataTable-input:focus, .form-floating > .form-control:not(:placeholder-shown), .form-floating > .dataTable-input:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:-webkit-autofill, .form-floating > .dataTable-input:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-select, .form-floating > .dataTable-selector { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label, .form-floating > .dataTable-input:not(:-moz-placeholder-shown) ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:not(:-ms-input-placeholder) ~ label, .form-floating > .dataTable-input:not(:-ms-input-placeholder) ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:focus ~ label, .form-floating > .dataTable-input:focus ~ label, +.form-floating > .form-control:not(:placeholder-shown) ~ label, +.form-floating > .dataTable-input:not(:placeholder-shown) ~ label, +.form-floating > .form-select ~ label, +.form-floating > .dataTable-selector ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:-webkit-autofill ~ label, .form-floating > .dataTable-input:-webkit-autofill ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100%; +} +.input-group > .form-control, .input-group > .dataTable-input, +.input-group > .form-select, +.input-group > .dataTable-selector { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0; +} +.input-group > .form-control:focus, .input-group > .dataTable-input:focus, +.input-group > .form-select:focus, +.input-group > .dataTable-selector:focus { + z-index: 3; +} +.input-group .btn { + position: relative; + z-index: 2; +} +.input-group .btn:focus { + z-index: 3; +} + +.input-group-text { + display: flex; + align-items: center; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} + +.input-group-lg > .form-control, .input-group-lg > .dataTable-input, +.input-group-lg > .form-select, +.input-group-lg > .dataTable-selector, +.input-group-lg > .input-group-text, +.input-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; +} + +.input-group-sm > .form-control, .input-group-sm > .dataTable-input, +.input-group-sm > .form-select, +.input-group-sm > .dataTable-selector, +.input-group-sm > .input-group-text, +.input-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; +} + +.input-group-lg > .form-select, .input-group-lg > .dataTable-selector, +.input-group-sm > .form-select, +.input-group-sm > .dataTable-selector { + padding-right: 3rem; +} + +.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu), +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu), +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: #198754; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: rgba(25, 135, 84, 0.9); + border-radius: 0.25rem; +} + +.was-validated :valid ~ .valid-feedback, +.was-validated :valid ~ .valid-tooltip, +.is-valid ~ .valid-feedback, +.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-control:valid, .was-validated .dataTable-input:valid, .form-control.is-valid, .is-valid.dataTable-input { + border-color: #198754; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:valid:focus, .was-validated .dataTable-input:valid:focus, .form-control.is-valid:focus, .is-valid.dataTable-input:focus { + border-color: #198754; + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} + +.was-validated textarea.form-control:valid, .was-validated textarea.dataTable-input:valid, textarea.form-control.is-valid, textarea.is-valid.dataTable-input { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} + +.was-validated .form-select:valid, .was-validated .dataTable-selector:valid, .form-select.is-valid, .is-valid.dataTable-selector { + border-color: #198754; +} +.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .dataTable-selector:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .was-validated .dataTable-selector:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .is-valid.dataTable-selector:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"], .is-valid.dataTable-selector:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:valid:focus, .was-validated .dataTable-selector:valid:focus, .form-select.is-valid:focus, .is-valid.dataTable-selector:focus { + border-color: #198754; + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} + +.was-validated .form-check-input:valid, .form-check-input.is-valid { + border-color: #198754; +} +.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { + background-color: #198754; +} +.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #198754; +} + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group .form-control:valid, .was-validated .input-group .dataTable-input:valid, .input-group .form-control.is-valid, .input-group .is-valid.dataTable-input, +.was-validated .input-group .form-select:valid, +.was-validated .input-group .dataTable-selector:valid, +.input-group .form-select.is-valid, +.input-group .is-valid.dataTable-selector { + z-index: 1; +} +.was-validated .input-group .form-control:valid:focus, .was-validated .input-group .dataTable-input:valid:focus, .input-group .form-control.is-valid:focus, .input-group .is-valid.dataTable-input:focus, +.was-validated .input-group .form-select:valid:focus, +.was-validated .input-group .dataTable-selector:valid:focus, +.input-group .form-select.is-valid:focus, +.input-group .is-valid.dataTable-selector:focus { + z-index: 3; +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: rgba(220, 53, 69, 0.9); + border-radius: 0.25rem; +} + +.was-validated :invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-tooltip, +.is-invalid ~ .invalid-feedback, +.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-control:invalid, .was-validated .dataTable-input:invalid, .form-control.is-invalid, .is-invalid.dataTable-input { + border-color: #dc3545; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:invalid:focus, .was-validated .dataTable-input:invalid:focus, .form-control.is-invalid:focus, .is-invalid.dataTable-input:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +.was-validated textarea.form-control:invalid, .was-validated textarea.dataTable-input:invalid, textarea.form-control.is-invalid, textarea.is-invalid.dataTable-input { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} + +.was-validated .form-select:invalid, .was-validated .dataTable-selector:invalid, .form-select.is-invalid, .is-invalid.dataTable-selector { + border-color: #dc3545; +} +.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .dataTable-selector:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .was-validated .dataTable-selector:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .is-invalid.dataTable-selector:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"], .is-invalid.dataTable-selector:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:invalid:focus, .was-validated .dataTable-selector:invalid:focus, .form-select.is-invalid:focus, .is-invalid.dataTable-selector:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +.was-validated .form-check-input:invalid, .form-check-input.is-invalid { + border-color: #dc3545; +} +.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { + background-color: #dc3545; +} +.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group .form-control:invalid, .was-validated .input-group .dataTable-input:invalid, .input-group .form-control.is-invalid, .input-group .is-invalid.dataTable-input, +.was-validated .input-group .form-select:invalid, +.was-validated .input-group .dataTable-selector:invalid, +.input-group .form-select.is-invalid, +.input-group .is-invalid.dataTable-selector { + z-index: 2; +} +.was-validated .input-group .form-control:invalid:focus, .was-validated .input-group .dataTable-input:invalid:focus, .input-group .form-control.is-invalid:focus, .input-group .is-invalid.dataTable-input:focus, +.was-validated .input-group .form-select:invalid:focus, +.was-validated .input-group .dataTable-selector:invalid:focus, +.input-group .form-select.is-invalid:focus, +.input-group .is-invalid.dataTable-selector:focus { + z-index: 3; +} + +.btn { + display: inline-block; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + border-radius: 0.25rem; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: #212529; +} +.btn-check:focus + .btn, .btn:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.btn:disabled, .btn.disabled, fieldset:disabled .btn { + pointer-events: none; + opacity: 0.65; +} + +.btn-primary { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.btn-primary:hover { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca; +} +.btn-check:focus + .btn-primary, .btn-primary:focus { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca; + box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); +} +.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0a58ca; + border-color: #0a53be; +} +.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); +} +.btn-primary:disabled, .btn-primary.disabled { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:hover { + color: #fff; + background-color: #5c636a; + border-color: #565e64; +} +.btn-check:focus + .btn-secondary, .btn-secondary:focus { + color: #fff; + background-color: #5c636a; + border-color: #565e64; + box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); +} +.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #565e64; + border-color: #51585e; +} +.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); +} +.btn-secondary:disabled, .btn-secondary.disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-success { + color: #fff; + background-color: #198754; + border-color: #198754; +} +.btn-success:hover { + color: #fff; + background-color: #157347; + border-color: #146c43; +} +.btn-check:focus + .btn-success, .btn-success:focus { + color: #fff; + background-color: #157347; + border-color: #146c43; + box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); +} +.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #146c43; + border-color: #13653f; +} +.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); +} +.btn-success:disabled, .btn-success.disabled { + color: #fff; + background-color: #198754; + border-color: #198754; +} + +.btn-info { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-info:hover { + color: #000; + background-color: #31d2f2; + border-color: #25cff2; +} +.btn-check:focus + .btn-info, .btn-info:focus { + color: #000; + background-color: #31d2f2; + border-color: #25cff2; + box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); +} +.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle { + color: #000; + background-color: #3dd5f3; + border-color: #25cff2; +} +.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); +} +.btn-info:disabled, .btn-info.disabled { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} + +.btn-warning { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:hover { + color: #000; + background-color: #ffca2c; + border-color: #ffc720; +} +.btn-check:focus + .btn-warning, .btn-warning:focus { + color: #000; + background-color: #ffca2c; + border-color: #ffc720; + box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); +} +.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle { + color: #000; + background-color: #ffcd39; + border-color: #ffc720; +} +.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); +} +.btn-warning:disabled, .btn-warning.disabled { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:hover { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; +} +.btn-check:focus + .btn-danger, .btn-danger:focus { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; + box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); +} +.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #b02a37; + border-color: #a52834; +} +.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); +} +.btn-danger:disabled, .btn-danger.disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-light { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:hover { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; +} +.btn-check:focus + .btn-light, .btn-light:focus { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; + box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); +} +.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; +} +.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); +} +.btn-light:disabled, .btn-light.disabled { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-dark { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-dark:hover { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; +} +.btn-check:focus + .btn-dark, .btn-dark:focus { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +} +.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1e21; + border-color: #191c1f; +} +.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +} +.btn-dark:disabled, .btn-dark.disabled { + color: #fff; + background-color: #212529; + border-color: #212529; +} + +.btn-outline-primary { + color: #0d6efd; + border-color: #0d6efd; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); +} +.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); +} +.btn-outline-primary:disabled, .btn-outline-primary.disabled { + color: #0d6efd; + background-color: transparent; +} + +.btn-outline-secondary { + color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { + box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); +} +.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); +} +.btn-outline-secondary:disabled, .btn-outline-secondary.disabled { + color: #6c757d; + background-color: transparent; +} + +.btn-outline-success { + color: #198754; + border-color: #198754; +} +.btn-outline-success:hover { + color: #fff; + background-color: #198754; + border-color: #198754; +} +.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); +} +.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { + color: #fff; + background-color: #198754; + border-color: #198754; +} +.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); +} +.btn-outline-success:disabled, .btn-outline-success.disabled { + color: #198754; + background-color: transparent; +} + +.btn-outline-info { + color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-outline-info:hover { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); +} +.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); +} +.btn-outline-info:disabled, .btn-outline-info.disabled { + color: #0dcaf0; + background-color: transparent; +} + +.btn-outline-warning { + color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:hover { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); +} +.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); +} +.btn-outline-warning:disabled, .btn-outline-warning.disabled { + color: #ffc107; + background-color: transparent; +} + +.btn-outline-danger { + color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); +} +.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); +} +.btn-outline-danger:disabled, .btn-outline-danger.disabled { + color: #dc3545; + background-color: transparent; +} + +.btn-outline-light { + color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:hover { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); +} +.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); +} +.btn-outline-light:disabled, .btn-outline-light.disabled { + color: #f8f9fa; + background-color: transparent; +} + +.btn-outline-dark { + color: #212529; + border-color: #212529; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); +} +.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); +} +.btn-outline-dark:disabled, .btn-outline-dark.disabled { + color: #212529; + background-color: transparent; +} + +.btn-link { + font-weight: 400; + color: #0d6efd; + text-decoration: underline; +} +.btn-link:hover { + color: #0a58ca; +} +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} + +.btn-lg, .btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; +} + +.btn-sm, .btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; +} + +.fade { + transition: opacity 0.15s linear; +} +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none; + } +} +.fade:not(.show) { + opacity: 0; +} + +.collapse:not(.show) { + display: none; +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none; + } +} +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing.collapse-horizontal { + transition: none; + } +} + +.dropup, +.dropend, +.dropdown, +.dropstart { + position: relative; +} + +.dropdown-toggle { + white-space: nowrap; +} +.dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + position: absolute; + z-index: 1000; + display: none; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: 0.125rem; +} + +.dropdown-menu-start { + --bs-position: start; +} +.dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0; +} + +.dropdown-menu-end { + --bs-position: end; +} +.dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto; +} + +@media (min-width: 576px) { + .dropdown-menu-sm-start { + --bs-position: start; + } + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-sm-end { + --bs-position: end; + } + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start; + } + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-md-end { + --bs-position: end; + } + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start; + } + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-lg-end { + --bs-position: end; + } + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start; + } + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-xl-end { + --bs-position: end; + } + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start; + } + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0; + } + + .dropdown-menu-xxl-end { + --bs-position: end; + } + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: 0.125rem; +} +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: 0.125rem; +} +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropend .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropend .dropdown-toggle::after { + vertical-align: 0; +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: 0.125rem; +} +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropstart .dropdown-toggle::after { + display: none; +} +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropstart .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropstart .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid rgba(0, 0, 0, 0.15); +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:hover, .dropdown-item:focus { + color: #1e2125; + background-color: #e9ecef; +} +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #0d6efd; +} +.dropdown-item.disabled, .dropdown-item:disabled { + color: #adb5bd; + pointer-events: none; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.dropdown-item-text { + display: block; + padding: 0.25rem 1rem; + color: #212529; +} + +.dropdown-menu-dark { + color: #dee2e6; + background-color: #343a40; + border-color: rgba(0, 0, 0, 0.15); +} +.dropdown-menu-dark .dropdown-item { + color: #dee2e6; +} +.dropdown-menu-dark .dropdown-item:hover, .dropdown-menu-dark .dropdown-item:focus { + color: #fff; + background-color: rgba(255, 255, 255, 0.15); +} +.dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active { + color: #fff; + background-color: #0d6efd; +} +.dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled { + color: #adb5bd; +} +.dropdown-menu-dark .dropdown-divider { + border-color: rgba(0, 0, 0, 0.15); +} +.dropdown-menu-dark .dropdown-item-text { + color: #dee2e6; +} +.dropdown-menu-dark .dropdown-header { + color: #adb5bd; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + flex: 1 1 auto; +} +.btn-group > .btn-check:checked + .btn, +.btn-group > .btn-check:focus + .btn, +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn-check:checked + .btn, +.btn-group-vertical > .btn-check:focus + .btn, +.btn-group-vertical > .btn:hover, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) { + margin-left: -1px; +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:nth-child(n+3), +.btn-group > :not(.btn-check) + .btn, +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after { + margin-left: 0; +} +.dropstart .dropdown-toggle-split::before { + margin-right: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + width: 100%; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) { + margin-top: -1px; +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn ~ .btn, +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; + color: #0d6efd; + text-decoration: none; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .nav-link { + transition: none; + } +} +.nav-link:hover, .nav-link:focus { + color: #0a58ca; +} +.nav-link.disabled { + color: #6c757d; + pointer-events: none; + cursor: default; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} +.nav-tabs .nav-link { + margin-bottom: -1px; + background: none; + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; + isolation: isolate; +} +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + background: none; + border: 0; + border-radius: 0.25rem; +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #0d6efd; +} + +.nav-fill > .nav-link, +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center; +} + +.nav-justified > .nav-link, +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; +} + +.nav-fill .nav-item .nav-link, +.nav-justified .nav-item .nav-link { + width: 100%; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +.navbar { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.navbar > .container, +.navbar > .container-fluid, +.navbar > .container-sm, +.navbar > .container-md, +.navbar > .container-lg, +.navbar > .container-xl, +.navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between; +} +.navbar-brand { + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + text-decoration: none; + white-space: nowrap; +} +.navbar-nav { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} +.navbar-nav .dropdown-menu { + position: static; +} + +.navbar-text { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center; +} + +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; + transition: box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none; + } +} +.navbar-toggler:hover { + text-decoration: none; +} +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 0.25rem; +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-repeat: no-repeat; + background-position: center; + background-size: 100%; +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height, 75vh); + overflow-y: auto; +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .offcanvas-header { + display: none; + } + .navbar-expand-sm .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-sm .offcanvas-top, +.navbar-expand-sm .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-sm .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .offcanvas-header { + display: none; + } + .navbar-expand-md .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-md .offcanvas-top, +.navbar-expand-md .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .offcanvas-header { + display: none; + } + .navbar-expand-lg .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-lg .offcanvas-top, +.navbar-expand-lg .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .offcanvas-header { + display: none; + } + .navbar-expand-xl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-xl .offcanvas-top, +.navbar-expand-xl .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xxl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xxl .navbar-toggler { + display: none; + } + .navbar-expand-xxl .offcanvas-header { + display: none; + } + .navbar-expand-xxl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-xxl .offcanvas-top, +.navbar-expand-xxl .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start; +} +.navbar-expand .navbar-nav { + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} +.navbar-expand .navbar-nav-scroll { + overflow: visible; +} +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-expand .offcanvas-header { + display: none; +} +.navbar-expand .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; +} +.navbar-expand .offcanvas-top, +.navbar-expand .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; +} +.navbar-expand .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.55); +} +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: rgba(0, 0, 0, 0.7); +} +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} +.navbar-light .navbar-nav .show > .nav-link, +.navbar-light .navbar-nav .nav-link.active { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.55); + border-color: rgba(0, 0, 0, 0.1); +} +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.55); +} +.navbar-light .navbar-text a, +.navbar-light .navbar-text a:hover, +.navbar-light .navbar-text a:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-dark .navbar-brand { + color: #fff; +} +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.55); +} +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: rgba(255, 255, 255, 0.75); +} +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} +.navbar-dark .navbar-nav .show > .nav-link, +.navbar-dark .navbar-nav .nav-link.active { + color: #fff; +} +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.55); + border-color: rgba(255, 255, 255, 0.1); +} +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.55); +} +.navbar-dark .navbar-text a, +.navbar-dark .navbar-text a:hover, +.navbar-dark .navbar-text a:focus { + color: #fff; +} + +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group { + border-top: inherit; + border-bottom: inherit; +} +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} +.card > .card-header + .list-group, +.card > .list-group + .card-footer { + border-top: 0; +} + +.card-body { + flex: 1 1 auto; + padding: 1rem 1rem; +} + +.card-title { + margin-bottom: 0.5rem; +} + +.card-subtitle { + margin-top: -0.25rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link + .card-link { + margin-left: 1rem; +} + +.card-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} + +.card-footer { + padding: 0.5rem 1rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.5rem; + margin-bottom: -0.5rem; + margin-left: -0.5rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.5rem; + margin-left: -0.5rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1rem; + border-radius: calc(0.25rem - 1px); +} + +.card-img, +.card-img-top, +.card-img-bottom { + width: 100%; +} + +.card-img, +.card-img-top { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img, +.card-img-bottom { + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-group > .card { + margin-bottom: 0.75rem; +} +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap; + } + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-top, +.card-group > .card:not(:last-child) .card-header { + border-top-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-bottom, +.card-group > .card:not(:last-child) .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-top, +.card-group > .card:not(:first-child) .card-header { + border-top-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-bottom, +.card-group > .card:not(:first-child) .card-footer { + border-bottom-left-radius: 0; + } +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: 1rem 1.25rem; + font-size: 1rem; + color: #212529; + text-align: left; + background-color: #fff; + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .accordion-button { + transition: none; + } +} +.accordion-button:not(.collapsed) { + color: #0c63e4; + background-color: #e7f1ff; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125); +} +.accordion-button:not(.collapsed)::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + transform: rotate(-180deg); +} +.accordion-button::after { + flex-shrink: 0; + width: 1.25rem; + height: 1.25rem; + margin-left: auto; + content: ""; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-size: 1.25rem; + transition: transform 0.2s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .accordion-button::after { + transition: none; + } +} +.accordion-button:hover { + z-index: 2; +} +.accordion-button:focus { + z-index: 3; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} + +.accordion-header { + margin-bottom: 0; +} + +.accordion-item { + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.accordion-item:first-of-type { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.accordion-item:first-of-type .accordion-button { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.accordion-item:not(:first-of-type) { + border-top: 0; +} +.accordion-item:last-of-type { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.accordion-body { + padding: 1rem 1.25rem; +} + +.accordion-flush .accordion-collapse { + border-width: 0; +} +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} +.accordion-flush .accordion-item:first-child { + border-top: 0; +} +.accordion-flush .accordion-item:last-child { + border-bottom: 0; +} +.accordion-flush .accordion-item .accordion-button { + border-radius: 0; +} + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0 0; + margin-bottom: 1rem; + list-style: none; +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: 0.5rem; +} +.breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: 0.5rem; + color: #6c757d; + content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */; +} +.breadcrumb-item.active { + color: #6c757d; +} + +.pagination, .dataTable-pagination ul { + display: flex; + padding-left: 0; + list-style: none; +} + +.page-link, .dataTable-pagination a { + position: relative; + display: block; + color: #0d6efd; + text-decoration: none; + background-color: #fff; + border: 1px solid #dee2e6; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .page-link, .dataTable-pagination a { + transition: none; + } +} +.page-link:hover, .dataTable-pagination a:hover { + z-index: 2; + color: #0a58ca; + background-color: #e9ecef; + border-color: #dee2e6; +} +.page-link:focus, .dataTable-pagination a:focus { + z-index: 3; + color: #0a58ca; + background-color: #e9ecef; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} + +.page-item:not(:first-child) .page-link, .page-item:not(:first-child) .dataTable-pagination a, .dataTable-pagination .page-item:not(:first-child) a, .dataTable-pagination li:not(:first-child) .page-link, .dataTable-pagination li:not(:first-child) a { + margin-left: -1px; +} +.page-item.active .page-link, .page-item.active .dataTable-pagination a, .dataTable-pagination .page-item.active a, .dataTable-pagination li.active .page-link, .dataTable-pagination li.active a { + z-index: 3; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.page-item.disabled .page-link, .page-item.disabled .dataTable-pagination a, .dataTable-pagination .page-item.disabled a, .dataTable-pagination li.disabled .page-link, .dataTable-pagination li.disabled a { + color: #6c757d; + pointer-events: none; + background-color: #fff; + border-color: #dee2e6; +} + +.page-link, .dataTable-pagination a { + padding: 0.375rem 0.75rem; +} + +.page-item:first-child .page-link, .page-item:first-child .dataTable-pagination a, .dataTable-pagination .page-item:first-child a, .dataTable-pagination li:first-child .page-link, .dataTable-pagination li:first-child a { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.page-item:last-child .page-link, .page-item:last-child .dataTable-pagination a, .dataTable-pagination .page-item:last-child a, .dataTable-pagination li:last-child .page-link, .dataTable-pagination li:last-child a { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} + +.pagination-lg .page-link, .pagination-lg .dataTable-pagination a, .dataTable-pagination .pagination-lg a { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; +} +.pagination-lg .page-item:first-child .page-link, .pagination-lg .page-item:first-child .dataTable-pagination a, .dataTable-pagination .pagination-lg .page-item:first-child a, .pagination-lg .dataTable-pagination li:first-child .page-link, .pagination-lg .dataTable-pagination li:first-child a, .dataTable-pagination .pagination-lg li:first-child .page-link, .dataTable-pagination .pagination-lg li:first-child a { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} +.pagination-lg .page-item:last-child .page-link, .pagination-lg .page-item:last-child .dataTable-pagination a, .dataTable-pagination .pagination-lg .page-item:last-child a, .pagination-lg .dataTable-pagination li:last-child .page-link, .pagination-lg .dataTable-pagination li:last-child a, .dataTable-pagination .pagination-lg li:last-child .page-link, .dataTable-pagination .pagination-lg li:last-child a { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} + +.pagination-sm .page-link, .pagination-sm .dataTable-pagination a, .dataTable-pagination .pagination-sm a { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; +} +.pagination-sm .page-item:first-child .page-link, .pagination-sm .page-item:first-child .dataTable-pagination a, .dataTable-pagination .pagination-sm .page-item:first-child a, .pagination-sm .dataTable-pagination li:first-child .page-link, .pagination-sm .dataTable-pagination li:first-child a, .dataTable-pagination .pagination-sm li:first-child .page-link, .dataTable-pagination .pagination-sm li:first-child a { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} +.pagination-sm .page-item:last-child .page-link, .pagination-sm .page-item:last-child .dataTable-pagination a, .dataTable-pagination .pagination-sm .page-item:last-child a, .pagination-sm .dataTable-pagination li:last-child .page-link, .pagination-sm .dataTable-pagination li:last-child a, .dataTable-pagination .pagination-sm li:last-child .page-link, .dataTable-pagination .pagination-sm li:last-child a { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} + +.badge { + display: inline-block; + padding: 0.35em 0.65em; + font-size: 0.75em; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; +} +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.alert { + position: relative; + padding: 1rem 1rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 3rem; +} +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem; +} + +.alert-primary { + color: #084298; + background-color: #cfe2ff; + border-color: #b6d4fe; +} +.alert-primary .alert-link { + color: #06357a; +} + +.alert-secondary { + color: #41464b; + background-color: #e2e3e5; + border-color: #d3d6d8; +} +.alert-secondary .alert-link { + color: #34383c; +} + +.alert-success { + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc; +} +.alert-success .alert-link { + color: #0c4128; +} + +.alert-info { + color: #055160; + background-color: #cff4fc; + border-color: #b6effb; +} +.alert-info .alert-link { + color: #04414d; +} + +.alert-warning { + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5; +} +.alert-warning .alert-link { + color: #523e02; +} + +.alert-danger { + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7; +} +.alert-danger .alert-link { + color: #6a1a21; +} + +.alert-light { + color: #636464; + background-color: #fefefe; + border-color: #fdfdfe; +} +.alert-light .alert-link { + color: #4f5050; +} + +.alert-dark { + color: #141619; + background-color: #d3d3d4; + border-color: #bcbebf; +} +.alert-dark .alert-link { + color: #101214; +} + +@-webkit-keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem; + } +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem; + } +} +.progress { + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: #0d6efd; + transition: width 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none; + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +.progress-bar-animated { + -webkit-animation: 1s linear infinite progress-bar-stripes; + animation: 1s linear infinite progress-bar-stripes; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + -webkit-animation: none; + animation: none; + } +} + +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: 0.25rem; +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section; +} +.list-group-numbered > li::before { + content: counters(section, ".") ". "; + counter-increment: section; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} +.list-group-item-action:hover, .list-group-item-action:focus { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.5rem 1rem; + color: #212529; + text-decoration: none; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; +} +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: #fff; +} +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.list-group-item + .list-group-item { + border-top-width: 0; +} +.list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px; +} + +.list-group-horizontal { + flex-direction: row; +} +.list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; +} +.list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; +} +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row; + } + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row; + } + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row; + } + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction: row; + } + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row; + } + .list-group-horizontal-xxl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +.list-group-flush { + border-radius: 0; +} +.list-group-flush > .list-group-item { + border-width: 0 0 1px; +} +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; +} + +.list-group-item-primary { + color: #084298; + background-color: #cfe2ff; +} +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #084298; + background-color: #bacbe6; +} +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #084298; + border-color: #084298; +} + +.list-group-item-secondary { + color: #41464b; + background-color: #e2e3e5; +} +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #41464b; + background-color: #cbccce; +} +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #41464b; + border-color: #41464b; +} + +.list-group-item-success { + color: #0f5132; + background-color: #d1e7dd; +} +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #0f5132; + background-color: #bcd0c7; +} +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0f5132; + border-color: #0f5132; +} + +.list-group-item-info { + color: #055160; + background-color: #cff4fc; +} +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #055160; + background-color: #badce3; +} +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #055160; + border-color: #055160; +} + +.list-group-item-warning { + color: #664d03; + background-color: #fff3cd; +} +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #664d03; + background-color: #e6dbb9; +} +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #664d03; + border-color: #664d03; +} + +.list-group-item-danger { + color: #842029; + background-color: #f8d7da; +} +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #842029; + background-color: #dfc2c4; +} +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842029; + border-color: #842029; +} + +.list-group-item-light { + color: #636464; + background-color: #fefefe; +} +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #636464; + background-color: #e5e5e5; +} +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #636464; + border-color: #636464; +} + +.list-group-item-dark { + color: #141619; + background-color: #d3d3d4; +} +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #141619; + background-color: #bebebf; +} +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #141619; + border-color: #141619; +} + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: 0.25em 0.25em; + color: #000; + background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + border: 0; + border-radius: 0.25rem; + opacity: 0.5; +} +.btn-close:hover { + color: #000; + text-decoration: none; + opacity: 0.75; +} +.btn-close:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + opacity: 1; +} +.btn-close:disabled, .btn-close.disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + opacity: 0.25; +} + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%); +} + +.toast { + width: 350px; + max-width: 100%; + font-size: 0.875rem; + pointer-events: auto; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} +.toast.showing { + opacity: 0; +} +.toast:not(.show) { + display: none; +} + +.toast-container { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none; +} +.toast-container > :not(:last-child) { + margin-bottom: 0.75rem; +} + +.toast-header { + display: flex; + align-items: center; + padding: 0.5rem 0.75rem; + color: #6c757d; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.toast-header .btn-close { + margin-right: -0.375rem; + margin-left: 0.75rem; +} + +.toast-body { + padding: 0.75rem; + word-wrap: break-word; +} + +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1055; + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} +.modal.fade .modal-dialog { + transition: transform 0.3s ease-out; + transform: translate(0, -50px); +} +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none; + } +} +.modal.show .modal-dialog { + transform: none; +} +.modal.modal-static .modal-dialog { + transform: scale(1.02); +} + +.modal-dialog-scrollable { + height: calc(100% - 1rem); +} +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden; +} +.modal-dialog-scrollable .modal-body { + overflow-y: auto; +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - 1rem); +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1050; + width: 100vw; + height: 100vh; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; + border-bottom: 1px solid #dee2e6; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.modal-header .btn-close { + padding: 0.5rem 0.5rem; + margin: -0.5rem -0.5rem -0.5rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: flex; + flex-wrap: wrap; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + padding: 0.75rem; + border-top: 1px solid #dee2e6; + border-bottom-right-radius: calc(0.3rem - 1px); + border-bottom-left-radius: calc(0.3rem - 1px); +} +.modal-footer > * { + margin: 0.25rem; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + + .modal-dialog-scrollable { + height: calc(100% - 3.5rem); + } + + .modal-dialog-centered { + min-height: calc(100% - 3.5rem); + } + + .modal-sm { + max-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg, +.modal-xl { + max-width: 800px; + } +} +@media (min-width: 1200px) { + .modal-xl { + max-width: 1140px; + } +} +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; +} +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0; +} +.modal-fullscreen .modal-header { + border-radius: 0; +} +.modal-fullscreen .modal-body { + overflow-y: auto; +} +.modal-fullscreen .modal-footer { + border-radius: 0; +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-sm-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-md-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-md-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-md-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0; + } +} +.tooltip { + position: absolute; + z-index: 1080; + display: block; + margin: 0; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: 0.9; +} +.tooltip .tooltip-arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, .bs-tooltip-auto[data-popper-placement^=top] { + padding: 0.4rem 0; +} +.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow { + bottom: 0; +} +.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before { + top: -1px; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-end, .bs-tooltip-auto[data-popper-placement^=right] { + padding: 0 0.4rem; +} +.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before { + right: -1px; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, .bs-tooltip-auto[data-popper-placement^=bottom] { + padding: 0.4rem 0; +} +.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow { + top: 0; +} +.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before { + bottom: -1px; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-start, .bs-tooltip-auto[data-popper-placement^=left] { + padding: 0 0.4rem; +} +.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before { + left: -1px; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} + +.popover { + position: absolute; + top: 0; + left: 0 /* rtl:ignore */; + z-index: 1070; + display: block; + max-width: 276px; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} +.popover .popover-arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; +} +.popover .popover-arrow::before, .popover .popover-arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow { + bottom: calc(-0.5rem - 1px); +} +.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before { + bottom: 0; + border-width: 0.5rem 0.5rem 0; + border-top-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { + bottom: 1px; + border-width: 0.5rem 0.5rem 0; + border-top-color: #fff; +} + +.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow { + left: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; +} +.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before { + left: 0; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { + left: 1px; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: #fff; +} + +.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow { + top: calc(-0.5rem - 1px); +} +.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before { + top: 0; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { + top: 1px; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: #fff; +} +.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f0f0f0; +} + +.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow { + right: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; +} +.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before { + right: 0; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { + right: 1px; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + font-size: 1rem; + background-color: #f0f0f0; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 1rem 1rem; + color: #212529; +} + +.carousel { + position: relative; +} + +.carousel.pointer-event { + touch-action: pan-y; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner::after { + display: block; + clear: both; + content: ""; +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: transform 0.6s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none; + } +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +/* rtl:begin:ignore */ +.carousel-item-next:not(.carousel-item-start), +.active.carousel-item-end { + transform: translateX(100%); +} + +.carousel-item-prev:not(.carousel-item-end), +.active.carousel-item-start { + transform: translateX(-100%); +} + +/* rtl:end:ignore */ +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none; +} +.carousel-fade .carousel-item.active, +.carousel-fade .carousel-item-next.carousel-item-start, +.carousel-fade .carousel-item-prev.carousel-item-end { + z-index: 1; + opacity: 1; +} +.carousel-fade .active.carousel-item-start, +.carousel-fade .active.carousel-item-end { + z-index: 0; + opacity: 0; + transition: opacity 0s 0.6s; +} +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-start, +.carousel-fade .active.carousel-item-end { + transition: none; + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: none; + border: 0; + opacity: 0.5; + transition: opacity 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-control-prev, +.carousel-control-next { + transition: none; + } +} +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: 0.9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100%; +} + +/* rtl:options: { + "autoRename": true, + "stringMap":[ { + "name" : "prev-next", + "search" : "prev", + "replace" : "next" + } ] +} */ +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; + list-style: none; +} +.carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: 0.5; + transition: opacity 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-indicators [data-bs-target] { + transition: none; + } +} +.carousel-indicators .active { + opacity: 1; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center; +} + +.carousel-dark .carousel-control-prev-icon, +.carousel-dark .carousel-control-next-icon { + filter: invert(1) grayscale(100); +} +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000; +} +.carousel-dark .carousel-caption { + color: #000; +} + +@-webkit-keyframes spinner-border { + to { + transform: rotate(360deg) /* rtl:ignore */; + } +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) /* rtl:ignore */; + } +} +.spinner-border { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -0.125em; + border: 0.25em solid currentColor; + border-right-color: transparent; + border-radius: 50%; + -webkit-animation: 0.75s linear infinite spinner-border; + animation: 0.75s linear infinite spinner-border; +} + +.spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: 0.2em; +} + +@-webkit-keyframes spinner-grow { + 0% { + transform: scale(0); + } + 50% { + opacity: 1; + transform: none; + } +} + +@keyframes spinner-grow { + 0% { + transform: scale(0); + } + 50% { + opacity: 1; + transform: none; + } +} +.spinner-grow { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -0.125em; + background-color: currentColor; + border-radius: 50%; + opacity: 0; + -webkit-animation: 0.75s linear infinite spinner-grow; + animation: 0.75s linear infinite spinner-grow; +} + +.spinner-grow-sm { + width: 1rem; + height: 1rem; +} + +@media (prefers-reduced-motion: reduce) { + .spinner-border, +.spinner-grow { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s; + } +} +.offcanvas { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + visibility: hidden; + background-color: #fff; + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .offcanvas { + transition: none; + } +} + +.offcanvas-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; +} +.offcanvas-backdrop.fade { + opacity: 0; +} +.offcanvas-backdrop.show { + opacity: 0.5; +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; +} +.offcanvas-header .btn-close { + padding: 0.5rem 0.5rem; + margin-top: -0.5rem; + margin-right: -0.5rem; + margin-bottom: -0.5rem; +} + +.offcanvas-title { + margin-bottom: 0; + line-height: 1.5; +} + +.offcanvas-body { + flex-grow: 1; + padding: 1rem 1rem; + overflow-y: auto; +} + +.offcanvas-start { + top: 0; + left: 0; + width: 400px; + border-right: 1px solid rgba(0, 0, 0, 0.2); + transform: translateX(-100%); +} + +.offcanvas-end { + top: 0; + right: 0; + width: 400px; + border-left: 1px solid rgba(0, 0, 0, 0.2); + transform: translateX(100%); +} + +.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + transform: translateY(-100%); +} + +.offcanvas-bottom { + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-top: 1px solid rgba(0, 0, 0, 0.2); + transform: translateY(100%); +} + +.offcanvas.show { + transform: none; +} + +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentColor; + opacity: 0.5; +} +.placeholder.btn::before { + display: inline-block; + content: ""; +} + +.placeholder-xs { + min-height: 0.6em; +} + +.placeholder-sm { + min-height: 0.8em; +} + +.placeholder-lg { + min-height: 1.2em; +} + +.placeholder-glow .placeholder { + -webkit-animation: placeholder-glow 2s ease-in-out infinite; + animation: placeholder-glow 2s ease-in-out infinite; +} + +@-webkit-keyframes placeholder-glow { + 50% { + opacity: 0.2; + } +} + +@keyframes placeholder-glow { + 50% { + opacity: 0.2; + } +} +.placeholder-wave { + -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + -webkit-mask-size: 200% 100%; + mask-size: 200% 100%; + -webkit-animation: placeholder-wave 2s linear infinite; + animation: placeholder-wave 2s linear infinite; +} + +@-webkit-keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0%; + } +} + +@keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0%; + } +} +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.link-primary { + color: #0d6efd; +} +.link-primary:hover, .link-primary:focus { + color: #0a58ca; +} + +.link-secondary { + color: #6c757d; +} +.link-secondary:hover, .link-secondary:focus { + color: #565e64; +} + +.link-success { + color: #198754; +} +.link-success:hover, .link-success:focus { + color: #146c43; +} + +.link-info { + color: #0dcaf0; +} +.link-info:hover, .link-info:focus { + color: #3dd5f3; +} + +.link-warning { + color: #ffc107; +} +.link-warning:hover, .link-warning:focus { + color: #ffcd39; +} + +.link-danger { + color: #dc3545; +} +.link-danger:hover, .link-danger:focus { + color: #b02a37; +} + +.link-light { + color: #f8f9fa; +} +.link-light:hover, .link-light:focus { + color: #f9fafb; +} + +.link-dark { + color: #212529; +} +.link-dark:hover, .link-dark:focus { + color: #1a1e21; +} + +.ratio { + position: relative; + width: 100%; +} +.ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: ""; +} +.ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.ratio-1x1 { + --bs-aspect-ratio: 100%; +} + +.ratio-4x3 { + --bs-aspect-ratio: calc(3 / 4 * 100%); +} + +.ratio-16x9 { + --bs-aspect-ratio: calc(9 / 16 * 100%); +} + +.ratio-21x9 { + --bs-aspect-ratio: calc(9 / 21 * 100%); +} + +.fixed-top, .sb-nav-fixed #layoutSidenav #layoutSidenav_nav, .sb-nav-fixed .sb-topnav { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +.sticky-top { + position: sticky; + top: 0; + z-index: 1020; +} + +@media (min-width: 576px) { + .sticky-sm-top { + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 768px) { + .sticky-md-top { + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 992px) { + .sticky-lg-top { + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 1200px) { + .sticky-xl-top { + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 1400px) { + .sticky-xxl-top { + position: sticky; + top: 0; + z-index: 1020; + } +} +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch; +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch; +} + +.visually-hidden, +.visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: ""; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentColor; + opacity: 0.25; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.float-start { + float: left !important; +} + +.float-end { + float: right !important; +} + +.float-none { + float: none !important; +} + +.opacity-0 { + opacity: 0 !important; +} + +.opacity-25 { + opacity: 0.25 !important; +} + +.opacity-50 { + opacity: 0.5 !important; +} + +.opacity-75 { + opacity: 0.75 !important; +} + +.opacity-100 { + opacity: 1 !important; +} + +.overflow-auto { + overflow: auto !important; +} + +.overflow-hidden { + overflow: hidden !important; +} + +.overflow-visible { + overflow: visible !important; +} + +.overflow-scroll { + overflow: scroll !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.shadow { + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; +} + +.shadow-sm { + box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important; +} + +.shadow-none { + box-shadow: none !important; +} + +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: sticky !important; +} + +.top-0 { + top: 0 !important; +} + +.top-50 { + top: 50% !important; +} + +.top-100 { + top: 100% !important; +} + +.bottom-0 { + bottom: 0 !important; +} + +.bottom-50 { + bottom: 50% !important; +} + +.bottom-100 { + bottom: 100% !important; +} + +.start-0 { + left: 0 !important; +} + +.start-50 { + left: 50% !important; +} + +.start-100 { + left: 100% !important; +} + +.end-0 { + right: 0 !important; +} + +.end-50 { + right: 50% !important; +} + +.end-100 { + right: 100% !important; +} + +.translate-middle { + transform: translate(-50%, -50%) !important; +} + +.translate-middle-x { + transform: translateX(-50%) !important; +} + +.translate-middle-y { + transform: translateY(-50%) !important; +} + +.border { + border: 1px solid #dee2e6 !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top { + border-top: 1px solid #dee2e6 !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-end { + border-right: 1px solid #dee2e6 !important; +} + +.border-end-0 { + border-right: 0 !important; +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-start { + border-left: 1px solid #dee2e6 !important; +} + +.border-start-0 { + border-left: 0 !important; +} + +.border-primary { + border-color: #0d6efd !important; +} + +.border-secondary { + border-color: #6c757d !important; +} + +.border-success { + border-color: #198754 !important; +} + +.border-info { + border-color: #0dcaf0 !important; +} + +.border-warning { + border-color: #ffc107 !important; +} + +.border-danger { + border-color: #dc3545 !important; +} + +.border-light { + border-color: #f8f9fa !important; +} + +.border-dark { + border-color: #212529 !important; +} + +.border-white { + border-color: #fff !important; +} + +.border-1 { + border-width: 1px !important; +} + +.border-2 { + border-width: 2px !important; +} + +.border-3 { + border-width: 3px !important; +} + +.border-4 { + border-width: 4px !important; +} + +.border-5 { + border-width: 5px !important; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.w-auto { + width: auto !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.vw-100 { + width: 100vw !important; +} + +.min-vw-100 { + min-width: 100vw !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.h-auto { + height: auto !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.vh-100 { + height: 100vh !important; +} + +.min-vh-100 { + min-height: 100vh !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.gap-0 { + gap: 0 !important; +} + +.gap-1 { + gap: 0.25rem !important; +} + +.gap-2 { + gap: 0.5rem !important; +} + +.gap-3 { + gap: 1rem !important; +} + +.gap-4 { + gap: 1.5rem !important; +} + +.gap-5 { + gap: 3rem !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important; +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw) !important; +} + +.fs-2 { + font-size: calc(1.325rem + 0.9vw) !important; +} + +.fs-3 { + font-size: calc(1.3rem + 0.6vw) !important; +} + +.fs-4 { + font-size: calc(1.275rem + 0.3vw) !important; +} + +.fs-5 { + font-size: 1.25rem !important; +} + +.fs-6 { + font-size: 1rem !important; +} + +.fst-italic { + font-style: italic !important; +} + +.fst-normal { + font-style: normal !important; +} + +.fw-light { + font-weight: 300 !important; +} + +.fw-lighter { + font-weight: lighter !important; +} + +.fw-normal { + font-weight: 400 !important; +} + +.fw-bold { + font-weight: 700 !important; +} + +.fw-bolder { + font-weight: bolder !important; +} + +.lh-1 { + line-height: 1 !important; +} + +.lh-sm { + line-height: 1.25 !important; +} + +.lh-base { + line-height: 1.5 !important; +} + +.lh-lg { + line-height: 2 !important; +} + +.text-start { + text-align: left !important; +} + +.text-end { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +.text-decoration-none { + text-decoration: none !important; +} + +.text-decoration-underline { + text-decoration: underline !important; +} + +.text-decoration-line-through { + text-decoration: line-through !important; +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.text-wrap { + white-space: normal !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +/* rtl:begin:remove */ +.text-break { + word-wrap: break-word !important; + word-break: break-word !important; +} + +/* rtl:end:remove */ +.text-primary { + --bs-text-opacity: 1; + color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important; +} + +.text-secondary { + --bs-text-opacity: 1; + color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important; +} + +.text-success { + --bs-text-opacity: 1; + color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important; +} + +.text-info { + --bs-text-opacity: 1; + color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important; +} + +.text-warning { + --bs-text-opacity: 1; + color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important; +} + +.text-danger { + --bs-text-opacity: 1; + color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important; +} + +.text-light { + --bs-text-opacity: 1; + color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important; +} + +.text-dark { + --bs-text-opacity: 1; + color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important; +} + +.text-black { + --bs-text-opacity: 1; + color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important; +} + +.text-white { + --bs-text-opacity: 1; + color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important; +} + +.text-body { + --bs-text-opacity: 1; + color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important; +} + +.text-muted { + --bs-text-opacity: 1; + color: #6c757d !important; +} + +.text-black-50 { + --bs-text-opacity: 1; + color: rgba(0, 0, 0, 0.5) !important; +} + +.text-white-50 { + --bs-text-opacity: 1; + color: rgba(255, 255, 255, 0.5) !important; +} + +.text-reset { + --bs-text-opacity: 1; + color: inherit !important; +} + +.text-opacity-25 { + --bs-text-opacity: 0.25; +} + +.text-opacity-50 { + --bs-text-opacity: 0.5; +} + +.text-opacity-75 { + --bs-text-opacity: 0.75; +} + +.text-opacity-100 { + --bs-text-opacity: 1; +} + +.bg-primary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-secondary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-success { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-info { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-warning { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-danger { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-light { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-dark { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-black { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-white { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-body { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-transparent { + --bs-bg-opacity: 1; + background-color: transparent !important; +} + +.bg-opacity-10 { + --bs-bg-opacity: 0.1; +} + +.bg-opacity-25 { + --bs-bg-opacity: 0.25; +} + +.bg-opacity-50 { + --bs-bg-opacity: 0.5; +} + +.bg-opacity-75 { + --bs-bg-opacity: 0.75; +} + +.bg-opacity-100 { + --bs-bg-opacity: 1; +} + +.bg-gradient { + background-image: var(--bs-gradient) !important; +} + +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + user-select: all !important; +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + -ms-user-select: auto !important; + user-select: auto !important; +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + -ms-user-select: none !important; + user-select: none !important; +} + +.pe-none { + pointer-events: none !important; +} + +.pe-auto { + pointer-events: auto !important; +} + +.rounded { + border-radius: 0.25rem !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.rounded-1 { + border-radius: 0.2rem !important; +} + +.rounded-2 { + border-radius: 0.25rem !important; +} + +.rounded-3 { + border-radius: 0.3rem !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 50rem !important; +} + +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} + +.rounded-end { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} + +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-start { + border-bottom-left-radius: 0.25rem !important; + border-top-left-radius: 0.25rem !important; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +@media (min-width: 576px) { + .float-sm-start { + float: left !important; + } + + .float-sm-end { + float: right !important; + } + + .float-sm-none { + float: none !important; + } + + .d-sm-inline { + display: inline !important; + } + + .d-sm-inline-block { + display: inline-block !important; + } + + .d-sm-block { + display: block !important; + } + + .d-sm-grid { + display: grid !important; + } + + .d-sm-table { + display: table !important; + } + + .d-sm-table-row { + display: table-row !important; + } + + .d-sm-table-cell { + display: table-cell !important; + } + + .d-sm-flex { + display: flex !important; + } + + .d-sm-inline-flex { + display: inline-flex !important; + } + + .d-sm-none { + display: none !important; + } + + .flex-sm-fill { + flex: 1 1 auto !important; + } + + .flex-sm-row { + flex-direction: row !important; + } + + .flex-sm-column { + flex-direction: column !important; + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-sm-wrap { + flex-wrap: wrap !important; + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-sm-0 { + gap: 0 !important; + } + + .gap-sm-1 { + gap: 0.25rem !important; + } + + .gap-sm-2 { + gap: 0.5rem !important; + } + + .gap-sm-3 { + gap: 1rem !important; + } + + .gap-sm-4 { + gap: 1.5rem !important; + } + + .gap-sm-5 { + gap: 3rem !important; + } + + .justify-content-sm-start { + justify-content: flex-start !important; + } + + .justify-content-sm-end { + justify-content: flex-end !important; + } + + .justify-content-sm-center { + justify-content: center !important; + } + + .justify-content-sm-between { + justify-content: space-between !important; + } + + .justify-content-sm-around { + justify-content: space-around !important; + } + + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + + .align-items-sm-start { + align-items: flex-start !important; + } + + .align-items-sm-end { + align-items: flex-end !important; + } + + .align-items-sm-center { + align-items: center !important; + } + + .align-items-sm-baseline { + align-items: baseline !important; + } + + .align-items-sm-stretch { + align-items: stretch !important; + } + + .align-content-sm-start { + align-content: flex-start !important; + } + + .align-content-sm-end { + align-content: flex-end !important; + } + + .align-content-sm-center { + align-content: center !important; + } + + .align-content-sm-between { + align-content: space-between !important; + } + + .align-content-sm-around { + align-content: space-around !important; + } + + .align-content-sm-stretch { + align-content: stretch !important; + } + + .align-self-sm-auto { + align-self: auto !important; + } + + .align-self-sm-start { + align-self: flex-start !important; + } + + .align-self-sm-end { + align-self: flex-end !important; + } + + .align-self-sm-center { + align-self: center !important; + } + + .align-self-sm-baseline { + align-self: baseline !important; + } + + .align-self-sm-stretch { + align-self: stretch !important; + } + + .order-sm-first { + order: -1 !important; + } + + .order-sm-0 { + order: 0 !important; + } + + .order-sm-1 { + order: 1 !important; + } + + .order-sm-2 { + order: 2 !important; + } + + .order-sm-3 { + order: 3 !important; + } + + .order-sm-4 { + order: 4 !important; + } + + .order-sm-5 { + order: 5 !important; + } + + .order-sm-last { + order: 6 !important; + } + + .m-sm-0 { + margin: 0 !important; + } + + .m-sm-1 { + margin: 0.25rem !important; + } + + .m-sm-2 { + margin: 0.5rem !important; + } + + .m-sm-3 { + margin: 1rem !important; + } + + .m-sm-4 { + margin: 1.5rem !important; + } + + .m-sm-5 { + margin: 3rem !important; + } + + .m-sm-auto { + margin: auto !important; + } + + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-sm-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-sm-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-sm-0 { + margin-top: 0 !important; + } + + .mt-sm-1 { + margin-top: 0.25rem !important; + } + + .mt-sm-2 { + margin-top: 0.5rem !important; + } + + .mt-sm-3 { + margin-top: 1rem !important; + } + + .mt-sm-4 { + margin-top: 1.5rem !important; + } + + .mt-sm-5 { + margin-top: 3rem !important; + } + + .mt-sm-auto { + margin-top: auto !important; + } + + .me-sm-0 { + margin-right: 0 !important; + } + + .me-sm-1 { + margin-right: 0.25rem !important; + } + + .me-sm-2 { + margin-right: 0.5rem !important; + } + + .me-sm-3 { + margin-right: 1rem !important; + } + + .me-sm-4 { + margin-right: 1.5rem !important; + } + + .me-sm-5 { + margin-right: 3rem !important; + } + + .me-sm-auto { + margin-right: auto !important; + } + + .mb-sm-0 { + margin-bottom: 0 !important; + } + + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + + .mb-sm-3 { + margin-bottom: 1rem !important; + } + + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + + .mb-sm-5 { + margin-bottom: 3rem !important; + } + + .mb-sm-auto { + margin-bottom: auto !important; + } + + .ms-sm-0 { + margin-left: 0 !important; + } + + .ms-sm-1 { + margin-left: 0.25rem !important; + } + + .ms-sm-2 { + margin-left: 0.5rem !important; + } + + .ms-sm-3 { + margin-left: 1rem !important; + } + + .ms-sm-4 { + margin-left: 1.5rem !important; + } + + .ms-sm-5 { + margin-left: 3rem !important; + } + + .ms-sm-auto { + margin-left: auto !important; + } + + .p-sm-0 { + padding: 0 !important; + } + + .p-sm-1 { + padding: 0.25rem !important; + } + + .p-sm-2 { + padding: 0.5rem !important; + } + + .p-sm-3 { + padding: 1rem !important; + } + + .p-sm-4 { + padding: 1.5rem !important; + } + + .p-sm-5 { + padding: 3rem !important; + } + + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-sm-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-sm-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-sm-0 { + padding-top: 0 !important; + } + + .pt-sm-1 { + padding-top: 0.25rem !important; + } + + .pt-sm-2 { + padding-top: 0.5rem !important; + } + + .pt-sm-3 { + padding-top: 1rem !important; + } + + .pt-sm-4 { + padding-top: 1.5rem !important; + } + + .pt-sm-5 { + padding-top: 3rem !important; + } + + .pe-sm-0 { + padding-right: 0 !important; + } + + .pe-sm-1 { + padding-right: 0.25rem !important; + } + + .pe-sm-2 { + padding-right: 0.5rem !important; + } + + .pe-sm-3 { + padding-right: 1rem !important; + } + + .pe-sm-4 { + padding-right: 1.5rem !important; + } + + .pe-sm-5 { + padding-right: 3rem !important; + } + + .pb-sm-0 { + padding-bottom: 0 !important; + } + + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + + .pb-sm-3 { + padding-bottom: 1rem !important; + } + + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + + .pb-sm-5 { + padding-bottom: 3rem !important; + } + + .ps-sm-0 { + padding-left: 0 !important; + } + + .ps-sm-1 { + padding-left: 0.25rem !important; + } + + .ps-sm-2 { + padding-left: 0.5rem !important; + } + + .ps-sm-3 { + padding-left: 1rem !important; + } + + .ps-sm-4 { + padding-left: 1.5rem !important; + } + + .ps-sm-5 { + padding-left: 3rem !important; + } + + .text-sm-start { + text-align: left !important; + } + + .text-sm-end { + text-align: right !important; + } + + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .float-md-start { + float: left !important; + } + + .float-md-end { + float: right !important; + } + + .float-md-none { + float: none !important; + } + + .d-md-inline { + display: inline !important; + } + + .d-md-inline-block { + display: inline-block !important; + } + + .d-md-block { + display: block !important; + } + + .d-md-grid { + display: grid !important; + } + + .d-md-table { + display: table !important; + } + + .d-md-table-row { + display: table-row !important; + } + + .d-md-table-cell { + display: table-cell !important; + } + + .d-md-flex { + display: flex !important; + } + + .d-md-inline-flex { + display: inline-flex !important; + } + + .d-md-none { + display: none !important; + } + + .flex-md-fill { + flex: 1 1 auto !important; + } + + .flex-md-row { + flex-direction: row !important; + } + + .flex-md-column { + flex-direction: column !important; + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-md-grow-0 { + flex-grow: 0 !important; + } + + .flex-md-grow-1 { + flex-grow: 1 !important; + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-md-wrap { + flex-wrap: wrap !important; + } + + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-md-0 { + gap: 0 !important; + } + + .gap-md-1 { + gap: 0.25rem !important; + } + + .gap-md-2 { + gap: 0.5rem !important; + } + + .gap-md-3 { + gap: 1rem !important; + } + + .gap-md-4 { + gap: 1.5rem !important; + } + + .gap-md-5 { + gap: 3rem !important; + } + + .justify-content-md-start { + justify-content: flex-start !important; + } + + .justify-content-md-end { + justify-content: flex-end !important; + } + + .justify-content-md-center { + justify-content: center !important; + } + + .justify-content-md-between { + justify-content: space-between !important; + } + + .justify-content-md-around { + justify-content: space-around !important; + } + + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + + .align-items-md-start { + align-items: flex-start !important; + } + + .align-items-md-end { + align-items: flex-end !important; + } + + .align-items-md-center { + align-items: center !important; + } + + .align-items-md-baseline { + align-items: baseline !important; + } + + .align-items-md-stretch { + align-items: stretch !important; + } + + .align-content-md-start { + align-content: flex-start !important; + } + + .align-content-md-end { + align-content: flex-end !important; + } + + .align-content-md-center { + align-content: center !important; + } + + .align-content-md-between { + align-content: space-between !important; + } + + .align-content-md-around { + align-content: space-around !important; + } + + .align-content-md-stretch { + align-content: stretch !important; + } + + .align-self-md-auto { + align-self: auto !important; + } + + .align-self-md-start { + align-self: flex-start !important; + } + + .align-self-md-end { + align-self: flex-end !important; + } + + .align-self-md-center { + align-self: center !important; + } + + .align-self-md-baseline { + align-self: baseline !important; + } + + .align-self-md-stretch { + align-self: stretch !important; + } + + .order-md-first { + order: -1 !important; + } + + .order-md-0 { + order: 0 !important; + } + + .order-md-1 { + order: 1 !important; + } + + .order-md-2 { + order: 2 !important; + } + + .order-md-3 { + order: 3 !important; + } + + .order-md-4 { + order: 4 !important; + } + + .order-md-5 { + order: 5 !important; + } + + .order-md-last { + order: 6 !important; + } + + .m-md-0 { + margin: 0 !important; + } + + .m-md-1 { + margin: 0.25rem !important; + } + + .m-md-2 { + margin: 0.5rem !important; + } + + .m-md-3 { + margin: 1rem !important; + } + + .m-md-4 { + margin: 1.5rem !important; + } + + .m-md-5 { + margin: 3rem !important; + } + + .m-md-auto { + margin: auto !important; + } + + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-md-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-md-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-md-0 { + margin-top: 0 !important; + } + + .mt-md-1 { + margin-top: 0.25rem !important; + } + + .mt-md-2 { + margin-top: 0.5rem !important; + } + + .mt-md-3 { + margin-top: 1rem !important; + } + + .mt-md-4 { + margin-top: 1.5rem !important; + } + + .mt-md-5 { + margin-top: 3rem !important; + } + + .mt-md-auto { + margin-top: auto !important; + } + + .me-md-0 { + margin-right: 0 !important; + } + + .me-md-1 { + margin-right: 0.25rem !important; + } + + .me-md-2 { + margin-right: 0.5rem !important; + } + + .me-md-3 { + margin-right: 1rem !important; + } + + .me-md-4 { + margin-right: 1.5rem !important; + } + + .me-md-5 { + margin-right: 3rem !important; + } + + .me-md-auto { + margin-right: auto !important; + } + + .mb-md-0 { + margin-bottom: 0 !important; + } + + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + + .mb-md-3 { + margin-bottom: 1rem !important; + } + + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + + .mb-md-5 { + margin-bottom: 3rem !important; + } + + .mb-md-auto { + margin-bottom: auto !important; + } + + .ms-md-0 { + margin-left: 0 !important; + } + + .ms-md-1 { + margin-left: 0.25rem !important; + } + + .ms-md-2 { + margin-left: 0.5rem !important; + } + + .ms-md-3 { + margin-left: 1rem !important; + } + + .ms-md-4 { + margin-left: 1.5rem !important; + } + + .ms-md-5 { + margin-left: 3rem !important; + } + + .ms-md-auto { + margin-left: auto !important; + } + + .p-md-0 { + padding: 0 !important; + } + + .p-md-1 { + padding: 0.25rem !important; + } + + .p-md-2 { + padding: 0.5rem !important; + } + + .p-md-3 { + padding: 1rem !important; + } + + .p-md-4 { + padding: 1.5rem !important; + } + + .p-md-5 { + padding: 3rem !important; + } + + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-md-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-md-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-md-0 { + padding-top: 0 !important; + } + + .pt-md-1 { + padding-top: 0.25rem !important; + } + + .pt-md-2 { + padding-top: 0.5rem !important; + } + + .pt-md-3 { + padding-top: 1rem !important; + } + + .pt-md-4 { + padding-top: 1.5rem !important; + } + + .pt-md-5 { + padding-top: 3rem !important; + } + + .pe-md-0 { + padding-right: 0 !important; + } + + .pe-md-1 { + padding-right: 0.25rem !important; + } + + .pe-md-2 { + padding-right: 0.5rem !important; + } + + .pe-md-3 { + padding-right: 1rem !important; + } + + .pe-md-4 { + padding-right: 1.5rem !important; + } + + .pe-md-5 { + padding-right: 3rem !important; + } + + .pb-md-0 { + padding-bottom: 0 !important; + } + + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + + .pb-md-3 { + padding-bottom: 1rem !important; + } + + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + + .pb-md-5 { + padding-bottom: 3rem !important; + } + + .ps-md-0 { + padding-left: 0 !important; + } + + .ps-md-1 { + padding-left: 0.25rem !important; + } + + .ps-md-2 { + padding-left: 0.5rem !important; + } + + .ps-md-3 { + padding-left: 1rem !important; + } + + .ps-md-4 { + padding-left: 1.5rem !important; + } + + .ps-md-5 { + padding-left: 3rem !important; + } + + .text-md-start { + text-align: left !important; + } + + .text-md-end { + text-align: right !important; + } + + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .float-lg-start { + float: left !important; + } + + .float-lg-end { + float: right !important; + } + + .float-lg-none { + float: none !important; + } + + .d-lg-inline { + display: inline !important; + } + + .d-lg-inline-block { + display: inline-block !important; + } + + .d-lg-block { + display: block !important; + } + + .d-lg-grid { + display: grid !important; + } + + .d-lg-table { + display: table !important; + } + + .d-lg-table-row { + display: table-row !important; + } + + .d-lg-table-cell { + display: table-cell !important; + } + + .d-lg-flex { + display: flex !important; + } + + .d-lg-inline-flex { + display: inline-flex !important; + } + + .d-lg-none { + display: none !important; + } + + .flex-lg-fill { + flex: 1 1 auto !important; + } + + .flex-lg-row { + flex-direction: row !important; + } + + .flex-lg-column { + flex-direction: column !important; + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-lg-wrap { + flex-wrap: wrap !important; + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-lg-0 { + gap: 0 !important; + } + + .gap-lg-1 { + gap: 0.25rem !important; + } + + .gap-lg-2 { + gap: 0.5rem !important; + } + + .gap-lg-3 { + gap: 1rem !important; + } + + .gap-lg-4 { + gap: 1.5rem !important; + } + + .gap-lg-5 { + gap: 3rem !important; + } + + .justify-content-lg-start { + justify-content: flex-start !important; + } + + .justify-content-lg-end { + justify-content: flex-end !important; + } + + .justify-content-lg-center { + justify-content: center !important; + } + + .justify-content-lg-between { + justify-content: space-between !important; + } + + .justify-content-lg-around { + justify-content: space-around !important; + } + + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + + .align-items-lg-start { + align-items: flex-start !important; + } + + .align-items-lg-end { + align-items: flex-end !important; + } + + .align-items-lg-center { + align-items: center !important; + } + + .align-items-lg-baseline { + align-items: baseline !important; + } + + .align-items-lg-stretch { + align-items: stretch !important; + } + + .align-content-lg-start { + align-content: flex-start !important; + } + + .align-content-lg-end { + align-content: flex-end !important; + } + + .align-content-lg-center { + align-content: center !important; + } + + .align-content-lg-between { + align-content: space-between !important; + } + + .align-content-lg-around { + align-content: space-around !important; + } + + .align-content-lg-stretch { + align-content: stretch !important; + } + + .align-self-lg-auto { + align-self: auto !important; + } + + .align-self-lg-start { + align-self: flex-start !important; + } + + .align-self-lg-end { + align-self: flex-end !important; + } + + .align-self-lg-center { + align-self: center !important; + } + + .align-self-lg-baseline { + align-self: baseline !important; + } + + .align-self-lg-stretch { + align-self: stretch !important; + } + + .order-lg-first { + order: -1 !important; + } + + .order-lg-0 { + order: 0 !important; + } + + .order-lg-1 { + order: 1 !important; + } + + .order-lg-2 { + order: 2 !important; + } + + .order-lg-3 { + order: 3 !important; + } + + .order-lg-4 { + order: 4 !important; + } + + .order-lg-5 { + order: 5 !important; + } + + .order-lg-last { + order: 6 !important; + } + + .m-lg-0 { + margin: 0 !important; + } + + .m-lg-1 { + margin: 0.25rem !important; + } + + .m-lg-2 { + margin: 0.5rem !important; + } + + .m-lg-3 { + margin: 1rem !important; + } + + .m-lg-4 { + margin: 1.5rem !important; + } + + .m-lg-5 { + margin: 3rem !important; + } + + .m-lg-auto { + margin: auto !important; + } + + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-lg-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-lg-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-lg-0 { + margin-top: 0 !important; + } + + .mt-lg-1 { + margin-top: 0.25rem !important; + } + + .mt-lg-2 { + margin-top: 0.5rem !important; + } + + .mt-lg-3 { + margin-top: 1rem !important; + } + + .mt-lg-4 { + margin-top: 1.5rem !important; + } + + .mt-lg-5 { + margin-top: 3rem !important; + } + + .mt-lg-auto { + margin-top: auto !important; + } + + .me-lg-0 { + margin-right: 0 !important; + } + + .me-lg-1 { + margin-right: 0.25rem !important; + } + + .me-lg-2 { + margin-right: 0.5rem !important; + } + + .me-lg-3 { + margin-right: 1rem !important; + } + + .me-lg-4 { + margin-right: 1.5rem !important; + } + + .me-lg-5 { + margin-right: 3rem !important; + } + + .me-lg-auto { + margin-right: auto !important; + } + + .mb-lg-0 { + margin-bottom: 0 !important; + } + + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + + .mb-lg-3 { + margin-bottom: 1rem !important; + } + + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + + .mb-lg-5 { + margin-bottom: 3rem !important; + } + + .mb-lg-auto { + margin-bottom: auto !important; + } + + .ms-lg-0 { + margin-left: 0 !important; + } + + .ms-lg-1 { + margin-left: 0.25rem !important; + } + + .ms-lg-2 { + margin-left: 0.5rem !important; + } + + .ms-lg-3 { + margin-left: 1rem !important; + } + + .ms-lg-4 { + margin-left: 1.5rem !important; + } + + .ms-lg-5 { + margin-left: 3rem !important; + } + + .ms-lg-auto { + margin-left: auto !important; + } + + .p-lg-0 { + padding: 0 !important; + } + + .p-lg-1 { + padding: 0.25rem !important; + } + + .p-lg-2 { + padding: 0.5rem !important; + } + + .p-lg-3 { + padding: 1rem !important; + } + + .p-lg-4 { + padding: 1.5rem !important; + } + + .p-lg-5 { + padding: 3rem !important; + } + + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-lg-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-lg-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-lg-0 { + padding-top: 0 !important; + } + + .pt-lg-1 { + padding-top: 0.25rem !important; + } + + .pt-lg-2 { + padding-top: 0.5rem !important; + } + + .pt-lg-3 { + padding-top: 1rem !important; + } + + .pt-lg-4 { + padding-top: 1.5rem !important; + } + + .pt-lg-5 { + padding-top: 3rem !important; + } + + .pe-lg-0 { + padding-right: 0 !important; + } + + .pe-lg-1 { + padding-right: 0.25rem !important; + } + + .pe-lg-2 { + padding-right: 0.5rem !important; + } + + .pe-lg-3 { + padding-right: 1rem !important; + } + + .pe-lg-4 { + padding-right: 1.5rem !important; + } + + .pe-lg-5 { + padding-right: 3rem !important; + } + + .pb-lg-0 { + padding-bottom: 0 !important; + } + + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + + .pb-lg-3 { + padding-bottom: 1rem !important; + } + + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + + .pb-lg-5 { + padding-bottom: 3rem !important; + } + + .ps-lg-0 { + padding-left: 0 !important; + } + + .ps-lg-1 { + padding-left: 0.25rem !important; + } + + .ps-lg-2 { + padding-left: 0.5rem !important; + } + + .ps-lg-3 { + padding-left: 1rem !important; + } + + .ps-lg-4 { + padding-left: 1.5rem !important; + } + + .ps-lg-5 { + padding-left: 3rem !important; + } + + .text-lg-start { + text-align: left !important; + } + + .text-lg-end { + text-align: right !important; + } + + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .float-xl-start { + float: left !important; + } + + .float-xl-end { + float: right !important; + } + + .float-xl-none { + float: none !important; + } + + .d-xl-inline { + display: inline !important; + } + + .d-xl-inline-block { + display: inline-block !important; + } + + .d-xl-block { + display: block !important; + } + + .d-xl-grid { + display: grid !important; + } + + .d-xl-table { + display: table !important; + } + + .d-xl-table-row { + display: table-row !important; + } + + .d-xl-table-cell { + display: table-cell !important; + } + + .d-xl-flex { + display: flex !important; + } + + .d-xl-inline-flex { + display: inline-flex !important; + } + + .d-xl-none { + display: none !important; + } + + .flex-xl-fill { + flex: 1 1 auto !important; + } + + .flex-xl-row { + flex-direction: row !important; + } + + .flex-xl-column { + flex-direction: column !important; + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xl-wrap { + flex-wrap: wrap !important; + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-xl-0 { + gap: 0 !important; + } + + .gap-xl-1 { + gap: 0.25rem !important; + } + + .gap-xl-2 { + gap: 0.5rem !important; + } + + .gap-xl-3 { + gap: 1rem !important; + } + + .gap-xl-4 { + gap: 1.5rem !important; + } + + .gap-xl-5 { + gap: 3rem !important; + } + + .justify-content-xl-start { + justify-content: flex-start !important; + } + + .justify-content-xl-end { + justify-content: flex-end !important; + } + + .justify-content-xl-center { + justify-content: center !important; + } + + .justify-content-xl-between { + justify-content: space-between !important; + } + + .justify-content-xl-around { + justify-content: space-around !important; + } + + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + + .align-items-xl-start { + align-items: flex-start !important; + } + + .align-items-xl-end { + align-items: flex-end !important; + } + + .align-items-xl-center { + align-items: center !important; + } + + .align-items-xl-baseline { + align-items: baseline !important; + } + + .align-items-xl-stretch { + align-items: stretch !important; + } + + .align-content-xl-start { + align-content: flex-start !important; + } + + .align-content-xl-end { + align-content: flex-end !important; + } + + .align-content-xl-center { + align-content: center !important; + } + + .align-content-xl-between { + align-content: space-between !important; + } + + .align-content-xl-around { + align-content: space-around !important; + } + + .align-content-xl-stretch { + align-content: stretch !important; + } + + .align-self-xl-auto { + align-self: auto !important; + } + + .align-self-xl-start { + align-self: flex-start !important; + } + + .align-self-xl-end { + align-self: flex-end !important; + } + + .align-self-xl-center { + align-self: center !important; + } + + .align-self-xl-baseline { + align-self: baseline !important; + } + + .align-self-xl-stretch { + align-self: stretch !important; + } + + .order-xl-first { + order: -1 !important; + } + + .order-xl-0 { + order: 0 !important; + } + + .order-xl-1 { + order: 1 !important; + } + + .order-xl-2 { + order: 2 !important; + } + + .order-xl-3 { + order: 3 !important; + } + + .order-xl-4 { + order: 4 !important; + } + + .order-xl-5 { + order: 5 !important; + } + + .order-xl-last { + order: 6 !important; + } + + .m-xl-0 { + margin: 0 !important; + } + + .m-xl-1 { + margin: 0.25rem !important; + } + + .m-xl-2 { + margin: 0.5rem !important; + } + + .m-xl-3 { + margin: 1rem !important; + } + + .m-xl-4 { + margin: 1.5rem !important; + } + + .m-xl-5 { + margin: 3rem !important; + } + + .m-xl-auto { + margin: auto !important; + } + + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-xl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-xl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-xl-0 { + margin-top: 0 !important; + } + + .mt-xl-1 { + margin-top: 0.25rem !important; + } + + .mt-xl-2 { + margin-top: 0.5rem !important; + } + + .mt-xl-3 { + margin-top: 1rem !important; + } + + .mt-xl-4 { + margin-top: 1.5rem !important; + } + + .mt-xl-5 { + margin-top: 3rem !important; + } + + .mt-xl-auto { + margin-top: auto !important; + } + + .me-xl-0 { + margin-right: 0 !important; + } + + .me-xl-1 { + margin-right: 0.25rem !important; + } + + .me-xl-2 { + margin-right: 0.5rem !important; + } + + .me-xl-3 { + margin-right: 1rem !important; + } + + .me-xl-4 { + margin-right: 1.5rem !important; + } + + .me-xl-5 { + margin-right: 3rem !important; + } + + .me-xl-auto { + margin-right: auto !important; + } + + .mb-xl-0 { + margin-bottom: 0 !important; + } + + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + + .mb-xl-3 { + margin-bottom: 1rem !important; + } + + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + + .mb-xl-5 { + margin-bottom: 3rem !important; + } + + .mb-xl-auto { + margin-bottom: auto !important; + } + + .ms-xl-0 { + margin-left: 0 !important; + } + + .ms-xl-1 { + margin-left: 0.25rem !important; + } + + .ms-xl-2 { + margin-left: 0.5rem !important; + } + + .ms-xl-3 { + margin-left: 1rem !important; + } + + .ms-xl-4 { + margin-left: 1.5rem !important; + } + + .ms-xl-5 { + margin-left: 3rem !important; + } + + .ms-xl-auto { + margin-left: auto !important; + } + + .p-xl-0 { + padding: 0 !important; + } + + .p-xl-1 { + padding: 0.25rem !important; + } + + .p-xl-2 { + padding: 0.5rem !important; + } + + .p-xl-3 { + padding: 1rem !important; + } + + .p-xl-4 { + padding: 1.5rem !important; + } + + .p-xl-5 { + padding: 3rem !important; + } + + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-xl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-xl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-xl-0 { + padding-top: 0 !important; + } + + .pt-xl-1 { + padding-top: 0.25rem !important; + } + + .pt-xl-2 { + padding-top: 0.5rem !important; + } + + .pt-xl-3 { + padding-top: 1rem !important; + } + + .pt-xl-4 { + padding-top: 1.5rem !important; + } + + .pt-xl-5 { + padding-top: 3rem !important; + } + + .pe-xl-0 { + padding-right: 0 !important; + } + + .pe-xl-1 { + padding-right: 0.25rem !important; + } + + .pe-xl-2 { + padding-right: 0.5rem !important; + } + + .pe-xl-3 { + padding-right: 1rem !important; + } + + .pe-xl-4 { + padding-right: 1.5rem !important; + } + + .pe-xl-5 { + padding-right: 3rem !important; + } + + .pb-xl-0 { + padding-bottom: 0 !important; + } + + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + + .pb-xl-3 { + padding-bottom: 1rem !important; + } + + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + + .pb-xl-5 { + padding-bottom: 3rem !important; + } + + .ps-xl-0 { + padding-left: 0 !important; + } + + .ps-xl-1 { + padding-left: 0.25rem !important; + } + + .ps-xl-2 { + padding-left: 0.5rem !important; + } + + .ps-xl-3 { + padding-left: 1rem !important; + } + + .ps-xl-4 { + padding-left: 1.5rem !important; + } + + .ps-xl-5 { + padding-left: 3rem !important; + } + + .text-xl-start { + text-align: left !important; + } + + .text-xl-end { + text-align: right !important; + } + + .text-xl-center { + text-align: center !important; + } +} +@media (min-width: 1400px) { + .float-xxl-start { + float: left !important; + } + + .float-xxl-end { + float: right !important; + } + + .float-xxl-none { + float: none !important; + } + + .d-xxl-inline { + display: inline !important; + } + + .d-xxl-inline-block { + display: inline-block !important; + } + + .d-xxl-block { + display: block !important; + } + + .d-xxl-grid { + display: grid !important; + } + + .d-xxl-table { + display: table !important; + } + + .d-xxl-table-row { + display: table-row !important; + } + + .d-xxl-table-cell { + display: table-cell !important; + } + + .d-xxl-flex { + display: flex !important; + } + + .d-xxl-inline-flex { + display: inline-flex !important; + } + + .d-xxl-none { + display: none !important; + } + + .flex-xxl-fill { + flex: 1 1 auto !important; + } + + .flex-xxl-row { + flex-direction: row !important; + } + + .flex-xxl-column { + flex-direction: column !important; + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-xxl-0 { + gap: 0 !important; + } + + .gap-xxl-1 { + gap: 0.25rem !important; + } + + .gap-xxl-2 { + gap: 0.5rem !important; + } + + .gap-xxl-3 { + gap: 1rem !important; + } + + .gap-xxl-4 { + gap: 1.5rem !important; + } + + .gap-xxl-5 { + gap: 3rem !important; + } + + .justify-content-xxl-start { + justify-content: flex-start !important; + } + + .justify-content-xxl-end { + justify-content: flex-end !important; + } + + .justify-content-xxl-center { + justify-content: center !important; + } + + .justify-content-xxl-between { + justify-content: space-between !important; + } + + .justify-content-xxl-around { + justify-content: space-around !important; + } + + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + + .align-items-xxl-start { + align-items: flex-start !important; + } + + .align-items-xxl-end { + align-items: flex-end !important; + } + + .align-items-xxl-center { + align-items: center !important; + } + + .align-items-xxl-baseline { + align-items: baseline !important; + } + + .align-items-xxl-stretch { + align-items: stretch !important; + } + + .align-content-xxl-start { + align-content: flex-start !important; + } + + .align-content-xxl-end { + align-content: flex-end !important; + } + + .align-content-xxl-center { + align-content: center !important; + } + + .align-content-xxl-between { + align-content: space-between !important; + } + + .align-content-xxl-around { + align-content: space-around !important; + } + + .align-content-xxl-stretch { + align-content: stretch !important; + } + + .align-self-xxl-auto { + align-self: auto !important; + } + + .align-self-xxl-start { + align-self: flex-start !important; + } + + .align-self-xxl-end { + align-self: flex-end !important; + } + + .align-self-xxl-center { + align-self: center !important; + } + + .align-self-xxl-baseline { + align-self: baseline !important; + } + + .align-self-xxl-stretch { + align-self: stretch !important; + } + + .order-xxl-first { + order: -1 !important; + } + + .order-xxl-0 { + order: 0 !important; + } + + .order-xxl-1 { + order: 1 !important; + } + + .order-xxl-2 { + order: 2 !important; + } + + .order-xxl-3 { + order: 3 !important; + } + + .order-xxl-4 { + order: 4 !important; + } + + .order-xxl-5 { + order: 5 !important; + } + + .order-xxl-last { + order: 6 !important; + } + + .m-xxl-0 { + margin: 0 !important; + } + + .m-xxl-1 { + margin: 0.25rem !important; + } + + .m-xxl-2 { + margin: 0.5rem !important; + } + + .m-xxl-3 { + margin: 1rem !important; + } + + .m-xxl-4 { + margin: 1.5rem !important; + } + + .m-xxl-5 { + margin: 3rem !important; + } + + .m-xxl-auto { + margin: auto !important; + } + + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-xxl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-xxl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-xxl-0 { + margin-top: 0 !important; + } + + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + + .mt-xxl-3 { + margin-top: 1rem !important; + } + + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + + .mt-xxl-5 { + margin-top: 3rem !important; + } + + .mt-xxl-auto { + margin-top: auto !important; + } + + .me-xxl-0 { + margin-right: 0 !important; + } + + .me-xxl-1 { + margin-right: 0.25rem !important; + } + + .me-xxl-2 { + margin-right: 0.5rem !important; + } + + .me-xxl-3 { + margin-right: 1rem !important; + } + + .me-xxl-4 { + margin-right: 1.5rem !important; + } + + .me-xxl-5 { + margin-right: 3rem !important; + } + + .me-xxl-auto { + margin-right: auto !important; + } + + .mb-xxl-0 { + margin-bottom: 0 !important; + } + + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + + .mb-xxl-auto { + margin-bottom: auto !important; + } + + .ms-xxl-0 { + margin-left: 0 !important; + } + + .ms-xxl-1 { + margin-left: 0.25rem !important; + } + + .ms-xxl-2 { + margin-left: 0.5rem !important; + } + + .ms-xxl-3 { + margin-left: 1rem !important; + } + + .ms-xxl-4 { + margin-left: 1.5rem !important; + } + + .ms-xxl-5 { + margin-left: 3rem !important; + } + + .ms-xxl-auto { + margin-left: auto !important; + } + + .p-xxl-0 { + padding: 0 !important; + } + + .p-xxl-1 { + padding: 0.25rem !important; + } + + .p-xxl-2 { + padding: 0.5rem !important; + } + + .p-xxl-3 { + padding: 1rem !important; + } + + .p-xxl-4 { + padding: 1.5rem !important; + } + + .p-xxl-5 { + padding: 3rem !important; + } + + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-xxl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-xxl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-xxl-0 { + padding-top: 0 !important; + } + + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + + .pt-xxl-3 { + padding-top: 1rem !important; + } + + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + + .pt-xxl-5 { + padding-top: 3rem !important; + } + + .pe-xxl-0 { + padding-right: 0 !important; + } + + .pe-xxl-1 { + padding-right: 0.25rem !important; + } + + .pe-xxl-2 { + padding-right: 0.5rem !important; + } + + .pe-xxl-3 { + padding-right: 1rem !important; + } + + .pe-xxl-4 { + padding-right: 1.5rem !important; + } + + .pe-xxl-5 { + padding-right: 3rem !important; + } + + .pb-xxl-0 { + padding-bottom: 0 !important; + } + + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + + .ps-xxl-0 { + padding-left: 0 !important; + } + + .ps-xxl-1 { + padding-left: 0.25rem !important; + } + + .ps-xxl-2 { + padding-left: 0.5rem !important; + } + + .ps-xxl-3 { + padding-left: 1rem !important; + } + + .ps-xxl-4 { + padding-left: 1.5rem !important; + } + + .ps-xxl-5 { + padding-left: 3rem !important; + } + + .text-xxl-start { + text-align: left !important; + } + + .text-xxl-end { + text-align: right !important; + } + + .text-xxl-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .fs-1 { + font-size: 2.5rem !important; + } + + .fs-2 { + font-size: 2rem !important; + } + + .fs-3 { + font-size: 1.75rem !important; + } + + .fs-4 { + font-size: 1.5rem !important; + } +} +@media print { + .d-print-inline { + display: inline !important; + } + + .d-print-inline-block { + display: inline-block !important; + } + + .d-print-block { + display: block !important; + } + + .d-print-grid { + display: grid !important; + } + + .d-print-table { + display: table !important; + } + + .d-print-table-row { + display: table-row !important; + } + + .d-print-table-cell { + display: table-cell !important; + } + + .d-print-flex { + display: flex !important; + } + + .d-print-inline-flex { + display: inline-flex !important; + } + + .d-print-none { + display: none !important; + } +} +html, +body { + height: 100%; +} + +#layoutAuthentication { + display: flex; + flex-direction: column; + min-height: 100vh; +} +#layoutAuthentication #layoutAuthentication_content { + min-width: 0; + flex-grow: 1; +} +#layoutAuthentication #layoutAuthentication_footer { + min-width: 0; +} + +#layoutSidenav { + display: flex; +} +#layoutSidenav #layoutSidenav_nav { + flex-basis: 225px; + flex-shrink: 0; + transition: transform 0.15s ease-in-out; + z-index: 1038; + transform: translateX(-225px); +} +#layoutSidenav #layoutSidenav_content { + position: relative; + display: flex; + flex-direction: column; + justify-content: space-between; + min-width: 0; + flex-grow: 1; + min-height: calc(100vh - 56px); + margin-left: -225px; +} + +.sb-sidenav-toggled #layoutSidenav #layoutSidenav_nav { + transform: translateX(0); +} +.sb-sidenav-toggled #layoutSidenav #layoutSidenav_content:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #000; + z-index: 1037; + opacity: 0.5; + transition: opacity 0.3s ease-in-out; +} + +@media (min-width: 992px) { + #layoutSidenav #layoutSidenav_nav { + transform: translateX(0); + } + #layoutSidenav #layoutSidenav_content { + margin-left: 0; + transition: margin 0.15s ease-in-out; + } + + .sb-sidenav-toggled #layoutSidenav #layoutSidenav_nav { + transform: translateX(-225px); + } + .sb-sidenav-toggled #layoutSidenav #layoutSidenav_content { + margin-left: -225px; + } + .sb-sidenav-toggled #layoutSidenav #layoutSidenav_content:before { + display: none; + } +} +.sb-nav-fixed .sb-topnav { + z-index: 1039; +} +.sb-nav-fixed #layoutSidenav #layoutSidenav_nav { + width: 225px; + height: 100vh; + z-index: 1038; +} +.sb-nav-fixed #layoutSidenav #layoutSidenav_nav .sb-sidenav { + padding-top: 56px; +} +.sb-nav-fixed #layoutSidenav #layoutSidenav_nav .sb-sidenav .sb-sidenav-menu { + overflow-y: auto; +} +.sb-nav-fixed #layoutSidenav #layoutSidenav_content { + padding-left: 225px; + top: 56px; +} + +#layoutError { + display: flex; + flex-direction: column; + min-height: 100vh; +} +#layoutError #layoutError_content { + min-width: 0; + flex-grow: 1; +} +#layoutError #layoutError_footer { + min-width: 0; +} + +.img-error { + max-width: 20rem; +} + +.nav .nav-link .sb-nav-link-icon, +.sb-sidenav-menu .nav-link .sb-nav-link-icon { + margin-right: 0.5rem; +} + +.sb-topnav { + padding-left: 0; + height: 56px; + z-index: 1039; +} +.sb-topnav .navbar-brand { + width: 225px; + margin: 0; +} +.sb-topnav.navbar-dark #sidebarToggle { + color: rgba(255, 255, 255, 0.5); +} +.sb-topnav.navbar-light #sidebarToggle { + color: #212529; +} + +.sb-sidenav { + display: flex; + flex-direction: column; + height: 100%; + flex-wrap: nowrap; +} +.sb-sidenav .sb-sidenav-menu { + flex-grow: 1; +} +.sb-sidenav .sb-sidenav-menu .nav { + flex-direction: column; + flex-wrap: nowrap; +} +.sb-sidenav .sb-sidenav-menu .nav .sb-sidenav-menu-heading { + padding: 1.75rem 1rem 0.75rem; + font-size: 0.75rem; + font-weight: bold; + text-transform: uppercase; +} +.sb-sidenav .sb-sidenav-menu .nav .nav-link { + display: flex; + align-items: center; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + position: relative; +} +.sb-sidenav .sb-sidenav-menu .nav .nav-link .sb-nav-link-icon { + font-size: 0.9rem; +} +.sb-sidenav .sb-sidenav-menu .nav .nav-link .sb-sidenav-collapse-arrow { + display: inline-block; + margin-left: auto; + transition: transform 0.15s ease; +} +.sb-sidenav .sb-sidenav-menu .nav .nav-link.collapsed .sb-sidenav-collapse-arrow { + transform: rotate(-90deg); +} +.sb-sidenav .sb-sidenav-menu .nav .sb-sidenav-menu-nested { + margin-left: 1.5rem; + flex-direction: column; +} +.sb-sidenav .sb-sidenav-footer { + padding: 0.75rem; + flex-shrink: 0; +} + +.sb-sidenav-dark { + background-color: #212529; + color: rgba(255, 255, 255, 0.5); +} +.sb-sidenav-dark .sb-sidenav-menu .sb-sidenav-menu-heading { + color: rgba(255, 255, 255, 0.25); +} +.sb-sidenav-dark .sb-sidenav-menu .nav-link { + color: rgba(255, 255, 255, 0.5); +} +.sb-sidenav-dark .sb-sidenav-menu .nav-link .sb-nav-link-icon { + color: rgba(255, 255, 255, 0.25); +} +.sb-sidenav-dark .sb-sidenav-menu .nav-link .sb-sidenav-collapse-arrow { + color: rgba(255, 255, 255, 0.25); +} +.sb-sidenav-dark .sb-sidenav-menu .nav-link:hover { + color: #fff; +} +.sb-sidenav-dark .sb-sidenav-menu .nav-link.active { + color: #fff; +} +.sb-sidenav-dark .sb-sidenav-menu .nav-link.active .sb-nav-link-icon { + color: #fff; +} +.sb-sidenav-dark .sb-sidenav-footer { + background-color: #343a40; +} + +.sb-sidenav-light { + background-color: #f8f9fa; + color: #212529; +} +.sb-sidenav-light .sb-sidenav-menu .sb-sidenav-menu-heading { + color: #adb5bd; +} +.sb-sidenav-light .sb-sidenav-menu .nav-link { + color: #212529; +} +.sb-sidenav-light .sb-sidenav-menu .nav-link .sb-nav-link-icon { + color: #adb5bd; +} +.sb-sidenav-light .sb-sidenav-menu .nav-link .sb-sidenav-collapse-arrow { + color: #adb5bd; +} +.sb-sidenav-light .sb-sidenav-menu .nav-link:hover { + color: #0d6efd; +} +.sb-sidenav-light .sb-sidenav-menu .nav-link.active { + color: #0d6efd; +} +.sb-sidenav-light .sb-sidenav-menu .nav-link.active .sb-nav-link-icon { + color: #0d6efd; +} +.sb-sidenav-light .sb-sidenav-footer { + background-color: #e9ecef; +} + +.dataTable-wrapper .dataTable-container { + font-size: 0.875rem; +} + +.dataTable-wrapper.no-header .dataTable-container { + border-top: none; +} + +.dataTable-wrapper.no-footer .dataTable-container { + border-bottom: none; +} + +.dataTable-top { + padding: 0 0 1rem; +} + +.dataTable-bottom { + padding: 0; +} + +.dataTable-top > nav:first-child, +.dataTable-top > div:first-child, +.dataTable-bottom > nav:first-child, +.dataTable-bottom > div:first-child { + float: left; +} + +.dataTable-top > nav:last-child, +.dataTable-top > div:last-child, +.dataTable-bottom > nav:last-child, +.dataTable-bottom > div:last-child { + float: right; +} + +.dataTable-selector { + width: auto; + display: inline-block; + padding-left: 1.125rem; + padding-right: 2.125rem; + margin-right: 0.25rem; +} + +.dataTable-info { + margin: 7px 0; +} + +/* PAGER */ +.dataTable-pagination a:hover { + background-color: #e9ecef; +} + +.dataTable-pagination .active a, +.dataTable-pagination .active a:focus, +.dataTable-pagination .active a:hover { + background-color: #0d6efd; +} + +.dataTable-pagination .ellipsis a, +.dataTable-pagination .disabled a, +.dataTable-pagination .disabled a:focus, +.dataTable-pagination .disabled a:hover { + cursor: not-allowed; +} + +.dataTable-pagination .disabled a, +.dataTable-pagination .disabled a:focus, +.dataTable-pagination .disabled a:hover { + cursor: not-allowed; + opacity: 0.4; +} + +.dataTable-pagination .pager a { + font-weight: bold; +} + +/* TABLE */ +.dataTable-table { + border-collapse: collapse; +} + +.dataTable-table > tbody > tr > td, +.dataTable-table > tbody > tr > th, +.dataTable-table > tfoot > tr > td, +.dataTable-table > tfoot > tr > th, +.dataTable-table > thead > tr > td, +.dataTable-table > thead > tr > th { + vertical-align: top; + padding: 0.5rem 0.5rem; +} + +.dataTable-table > thead > tr > th { + vertical-align: bottom; + text-align: left; + border-bottom: none; +} + +.dataTable-table > tfoot > tr > th { + vertical-align: bottom; + text-align: left; +} + +.dataTable-table th { + vertical-align: bottom; + text-align: left; +} + +.dataTable-table th a { + text-decoration: none; + color: inherit; +} + +.dataTable-sorter { + display: inline-block; + height: 100%; + position: relative; + width: 100%; + padding-right: 1rem; +} + +.dataTable-sorter::before, +.dataTable-sorter::after { + content: ""; + height: 0; + width: 0; + position: absolute; + right: 4px; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + opacity: 0.2; +} + +.dataTable-sorter::before { + bottom: 4px; +} + +.dataTable-sorter::after { + top: 0px; +} + +.asc .dataTable-sorter::after, +.desc .dataTable-sorter::before { + opacity: 0.6; +} + +.dataTables-empty { + text-align: center; +} + +.dataTable-top::after, +.dataTable-bottom::after { + clear: both; + content: " "; + display: table; +} + +.btn-datatable { + height: 20px !important; + width: 20px !important; + font-size: 0.75rem; + border-radius: 0.25rem !important; +} + +.breadcrumb.breadcrumb-custom { + padding: 0 0; + border-color: #dbe3e6 +} + +.breadcrumb { + border: 1px solid #f3f3f3 +} + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0.56rem 1.13rem; + margin-bottom: 1rem; + list-style: none; + background-color: transparent; + border-radius: 0.25rem +} + +nav { + display: block +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item { + font-size: 0.875rem; + background: #dbe3e6; + padding: 0.56rem 1px; + color: #000; + display: inline-block; + vertical-align: top +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item:before { + content: "" +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item a { + position: relative; + color: inherit; + border: 1px solid #dbe3e6; + display: inline-block; + vertical-align: top; + margin-left: 30px; +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item a:before { + right: -22px; + z-index: 3; + border-left-color: #dbe3e6; + border-left-style: solid; + border-left-width: 12px +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item a:after { + border-top: 21px solid transparent; + border-bottom: 22px solid transparent; + border-left: 12px solid #ffffff; + top: -9px; + right: -23px +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item:first-child { + padding-right: 10px; +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item:last-child { + background: transparent; + margin-left: 20px; +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item:before { + content: "" +} + +.breadcrumb.breadcrumb-custom .breadcrumb-item a:before, +.breadcrumb.breadcrumb-custom .breadcrumb-item a:after { + position: absolute; + top: -9px; + width: 0; + height: 0; + content: ""; + border-top: 21px solid transparent; + border-bottom: 21px solid transparent +} + +a:link { + text-decoration: none +} + +.breadcrumb-item+.breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + color: #6c757d; + content: "/" +} + + +.highcharts-figure, .highcharts-data-table table { + min-width: 320px; + max-width: 800px; + margin: 1em auto; +} + +.highcharts-data-table table { + font-family: var(--bs-font-sans-serif); + border-collapse: collapse; + border: 1px solid #EBEBEB; + margin: 10px auto; + text-align: center; + width: 100%; + max-width: 500px; +} +.highcharts-data-table caption { + padding: 1em 0; + font-size: 1.2em; + color: #555; +} +.highcharts-data-table th { + font-weight: 600; + padding: 0.5em; +} +.highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption { + padding: 0.5em; +} +.highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) { + background: #f8f8f8; +} +.highcharts-data-table tr:hover { + background: #f1f7ff; +} + + +/* Core typography integration: keep Liberty layout but use WMS/Core typography. */ +html, body, button, input, select, textarea, .navbar, .nav, .dropdown-menu, .table { + font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} diff --git a/Modules/M3/Resources/public/liberty-theme/js/dataTables.altEditor.free.js b/Modules/M3/Resources/public/liberty-theme/js/dataTables.altEditor.free.js new file mode 100755 index 00000000..b2ff6c5c --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/js/dataTables.altEditor.free.js @@ -0,0 +1,1216 @@ +/** + * @summary altEditor + * @description Lightweight editor for DataTables + * @version 2.0 + * @file dataTables.editor.free.js + * @author kingkode (www.kingkode.com) + * Modified by: Kasper Olesen (https://github.com/KasperOlesen), Luca Vercelli (https://github.com/luca-vercelli), Zack Hable (www.cobaltdevteam.com) + * @contact www.kingkode.com/contact + * @contact zack@cobaltdevteam.com + * @copyright Copyright 2016 Kingkode + * + * This source file is free software, available under the following license: MIT + * license + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * + */ + (function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery', 'datatables.net'], function ($) { + return factory($, window, document); + }); + } + else if (typeof exports === 'object') { + // CommonJS + module.exports = function (root, $) { + if (!root) { + root = window; + } + + if (!$ || !$.fn.dataTable) { + $ = require('datatables.net')(root, $).$; + } + + return factory($, root, root.document); + }; + } + else { + // Browser + factory(jQuery, window, document); + } +}) +(function ($, window, document, undefined) { + 'use strict'; + var DataTable = $.fn.dataTable; + + var _instance = 0; + + /** + * altEditor provides modal editing of records for Datatables + * + * @class altEditor + * @constructor + * @param {object} + * oTD DataTables settings object + * @param {object} + * oConfig Configuration object for altEditor + */ + var altEditor = function (dt, opts) { + if (!DataTable.versionCheck || !DataTable.versionCheck('1.10.8')) { + throw ("Warning: altEditor requires DataTables 1.10.8 or greater"); + } + + // User and defaults configuration object + this.c = $.extend(true, {}, DataTable.defaults.altEditor, + altEditor.defaults, opts); + + /** + * @namespace Settings object which contains customisable information + * for altEditor instance + */ + this.s = { + /** @type {DataTable.Api} DataTables' API instance */ + dt: new DataTable.Api(dt), + + /** @type {String} Unique namespace for events attached to the document */ + namespace: '.altEditor' + (_instance++) + }; + + /** + * @namespace Common and useful DOM elements for the class instance + */ + this.dom = { + /** @type {jQuery} altEditor handle */ + modal: $('
    '), + }; + + /* Constructor logic */ + this._constructor(); + } + + $.extend( + altEditor.prototype, + { + /*************************************************************** + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Constructor * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + /** + * Initialise the RowReorder instance + * + * @private + */ + _constructor: function () { + var that = this; + var dt = this.s.dt; + + if (dt.settings()[0].oInit.onAddRow) + that.onAddRow = dt.settings()[0].oInit.onAddRow; + if (dt.settings()[0].oInit.onDeleteRow) + that.onDeleteRow = dt.settings()[0].oInit.onDeleteRow; + if (dt.settings()[0].oInit.onEditRow) + that.onEditRow = dt.settings()[0].oInit.onEditRow; + + that.closeModalOnSuccess = dt.settings()[0].oInit.closeModalOnSuccess; + if (that.closeModalOnSuccess === undefined) { + that.closeModalOnSuccess = true; + } + + that.encodeFiles = dt.settings()[0].oInit.encodeFiles; + if (that.encodeFiles === undefined) { + that.encodeFiles = true; + } + + var lang = this.s.dt.settings()[0].oLanguage; + if (lang.altEditor) { + this.language = lang.altEditor; + this._setup(); + } + // Load from URL + else if (typeof lang.altEditorUrl === 'string' && lang.altEditorUrl != '') { + $.ajax( { + dataType: 'json', + url: lang.altEditorUrl, + success: function ( json ) { + that.language = json; + that._setup(); + }, + error: function () { + // Error occurred loading language file, continue on as best we can + that.language = {}; + that._setup(); + } + } ); + } + // Default + else { + this.language = {}; + this._setup(); + } + + dt.on('destroy.altEditor', function () { + dt.off('.altEditor'); + $(dt.table().body()).off(that.s.namespace); + $(document.body).off(that.s.namespace); + }); + }, + + /*************************************************************** + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Private methods * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + /** + * Setup dom and bind button actions + * + * @private + */ + _setup: function () { + var that = this; + var dt = this.s.dt; + + this.random_id = ("" + Math.random()).replace(".", ""); + + var modal_id = 'altEditor-modal-' + this.random_id; + this.modal_selector = '#' + modal_id; + + this._initLanguage(); + + var modal = ''; + // Add modal + $('body').append(modal); + + // Add Edit Button + if (dt.button('edit:name')) { + dt.button('edit:name').action(function (e, dt, node, config) { + that._openEditModal(); + + $('#altEditor-edit-form-' + that.random_id) + .off('submit') + .on('submit', function (e) { + e.preventDefault(); + e.stopPropagation(); + that._editRowData(); + }); + }); + } + + // Add Delete Button + if (dt.button('delete:name')) { + dt.button('delete:name').action(function (e, dt, node, config) { + that._openDeleteModal(); + + $('#altEditor-delete-form-' + that.random_id) + .off('submit') + .on('submit', function (e) { + e.preventDefault(); + e.stopPropagation(); + that._deleteRow(); + }); + }); + } + + // Add Add Button + if (dt.button('add:name')) { + dt.button('add:name').action(function (e, dt, node, config) { + that._openAddModal(); + + $('#altEditor-add-form-' + that.random_id) + .off('submit') + .on('submit', function (e) { + e.preventDefault(); + e.stopPropagation(); + that._addRowData(); + }); + }); + } + + // Bind 'unique' error messages + $(this.modal_selector).on('input', '[data-unique]', function(elm) { + if ($(elm.target).attr('data-unique') == null || $(elm.target).attr('data-unique') === 'false') { + return; + } + var target = $(elm.target); + var colData = dt.column("th:contains('" + target.attr("name") + "')").data(); + // go through each item in this column + var selectedCellData = null; + if (dt.row({selected: true}).index() != null) + selectedCellData = dt.cell(dt.row({selected: true}).index(), dt.column("th:contains('" + target.attr("name") + "')").index()).data(); + elm.target.setCustomValidity(''); + for (var j in colData) { + // if the element is in the column and its not the selected one then its not unique + if (target.val() == colData[j] && colData[j] != selectedCellData) { + elm.target.setCustomValidity(that.language.error.unique); + } + } + }); + + // Add Refresh button + if (this.s.dt.button('refresh:name')) { + this.s.dt.button('refresh:name').action(function (e, dt, node, config) { + if (dt.ajax && dt.ajax.url()) { + dt.ajax.reload(); + } + }); + } + }, + + /** + * Init translate + * + * @private + */ + _initLanguage: function () { + this.language.modalClose = this.language.modalClose || 'Close'; + this.language.edit = this.language.edit || {}; + this.language.edit = { + title: this.language.edit.title || 'Edit record', + button: this.language.edit.button || 'Edit' + }; + this.language.delete = this.language.delete || {}; + this.language.delete = { + title: this.language.delete.title || 'Delete record', + button: this.language.delete.button || 'Delete' + }; + this.language.add = this.language.add || {}; + this.language.add = { + title: this.language.add.title || 'Add record', + button: this.language.add.button || 'Add' + }; + this.language.success = this.language.success || 'Success!'; + this.language.error = this.language.error || {}; + this.language.error = { + message: this.language.error.message || 'There was an unknown error!', + label: this.language.error.label || 'Error!', + responseCode: this.language.error.responseCode || 'Response code: ', + required: this.language.error.required || 'Field is required', + unique: this.language.error.unique || 'Duplicated field' + }; + }, + + /** + * Emit an event on the DataTable for listeners + * + * @param {string} + * name Event name + * @param {array} + * args Event arguments + * @private + */ + _emitEvent: function (name, args) { + this.s.dt.iterator('table', function (ctx, i) { + $(ctx.nTable).triggerHandler(name + '.dt', args); + }); + }, + + /** + * Open Edit Modal for selected row + * + * @private + */ + _openEditModal: function () { + + var dt = this.s.dt; + var adata = dt.rows({ + selected: true + }); + + var columnDefs = this.completeColumnDefs(); + var data = this.createDialog(columnDefs, this.language.edit.title, this.language.edit.button, + this.language.modalClose, 'editRowBtn', 'altEditor-edit-form'); + + var selector = this.modal_selector; + + for (var j in columnDefs) { + if (columnDefs[j].name != null) { + var jquerySelector = "#" + columnDefs[j].name.toString().replace(/\./g, "\\."); + + var arrIndex = columnDefs[j].name.toString().split("."); + var selectedValue = adata.data()[0]; + for (var index = 0; index < arrIndex.length; index++) { + if (selectedValue) { + selectedValue = selectedValue[arrIndex[index]]; + } + } + + if (typeof selectedValue !== 'object' && selectedValue !== null) { + selectedValue = selectedValue.toString().trim(); + } + + // Added Select2 + if (columnDefs[j].type.indexOf("select") >= 0 && columnDefs[j].select2) { + var jsonValue = undefined; + try { jsonValue = JSON.parse(selectedValue); } catch (e) { } + if (typeof jsonValue === 'object') { selectedValue = jsonValue; } + } + // Added checkbox + else if (columnDefs[j].type.indexOf("checkbox") >= 0) { + if (this._quoteattr(selectedValue) === "true" || this._quoteattr(selectedValue) == "1") { // MS SQL Databases use bits for booleans. 1 is equivlent to true, 0 is false + $(selector).find(jquerySelector).prop("checked", this._quoteattr(selectedValue)); // required by checkbox + } + } + // Added date + else if (columnDefs[j].type.indexOf("date") >= 0) { + if (columnDefs[j].dateFormat !== "") { + var mDate = moment(this._quoteattr(selectedValue)); + if (mDate && mDate.isValid()) { + $(selector).find(jquerySelector).val(mDate.format(columnDefs[j].dateFormat)); + } + } + } + + $(selector).find(jquerySelector) + .filter(':input[type!="file"]').val(selectedValue) // this._quoteattr or not? see #121 + .trigger("change"); // required by select2 + } + } + + $(selector + ' input[0]').trigger('focus'); + $(selector).trigger("alteditor:some_dialog_opened").trigger("alteditor:edit_dialog_opened"); + }, + + /** + * Callback for "Edit" button + */ + _editRowData: function () { + var that = this; + var dt = this.s.dt; + var adata = dt.rows({ + selected: true + }); + + var rowDataArray = {}; // Complete new row data + var originalRowDataArray = adata.data()[0]; // Original row data + + var $inputs = $('form[name="altEditor-edit-form-' + this.random_id + '"]').find( 'select, textarea, input' ); + + // Getting the inputs from the edit-modal + $inputs.filter(':input[type!="file"], :input[type="checkbox"]').each(function (i) { + rowDataArray[$(this).attr('id')] = $(this).val(); + }); + + //Getting Files from the modal + var numFilesQueued = 0; + $inputs.filter(':input[type="file"]').each(function (i) { + if ($(this).prop('files')[0]) { + var context = this; + + if (that.encodeFiles) { + ++numFilesQueued; + that.getBase64($(this).prop('files')[0], function (filecontent) { + rowDataArray[$(context).attr('id')] = filecontent; + --numFilesQueued; + }); + } else { + rowDataArray[$(this).attr('id')] = $(this).prop('files')[0]; + } + } + }); + + // Getting the checkbox from the modal + $inputs.filter(':input[type="checkbox"]').each(function (i) { + rowDataArray[$(this).attr('id')] = this.checked; + }); + + var checkFilesQueued = function() { + if (numFilesQueued == 0) { + that.onEditRow(that, + rowDataArray, + function(data,b,c,d,e){ that._editRowCallback(data,b,c,d,e); }, + function(data){ that._errorCallback(data); }, + originalRowDataArray); + } else { + console.log("Waiting for file base64-decoding..."); + setTimeout(checkFilesQueued, 1000); + } + }; + + checkFilesQueued(); + }, + + /** + * Open Delete Modal for selected row + * + * @private + */ + _openDeleteModal: function () { + + var that = this; + var dt = this.s.dt; + var adata = dt.rows({ + selected: true + }); + var columnDefs = this.completeColumnDefs(); + var formName = 'altEditor-delete-form-' + this.random_id; + + // TODO + // we should use createDialog() + // var data = this.createDialog(columnDefs, this.language.delete.title, this.language.delete.button, + // this.language.modalClose, 'deleteRowBtn', 'altEditor-delete-form'); + + // Building delete-modal + var data = ""; + + for (var j in columnDefs) { + var title = columnDefs[j].title.replace(/(<([^>]+)>)/gi, "").trim(); + + if (columnDefs[j].name == null) continue; + if (columnDefs[j].type.indexOf("hidden") >= 0) { + data += ""; + } + else if (columnDefs[j].type.indexOf("file") < 0) { + var arrIndex = columnDefs[j].name.toString().split("."); + var fvalue = adata.data()[0]; //fvalue is the value that will appear to user + for (var index = 0; index < arrIndex.length; index++) { + if (fvalue) fvalue = fvalue[arrIndex[index]]; + } + + // fix dateFormat + if (columnDefs[j].type.indexOf("date") >= 0) { + if (columnDefs[j].dateFormat !== "") { + var mDate = moment(adata.data()[0][columnDefs[j].name]); + if (mDate && mDate.isValid()) { + fvalue = mDate.format(columnDefs[j].dateFormat); + } + } + } + + // fix select + if (columnDefs[j].type.indexOf("select") >= 0) { + var options = columnDefs[j].options; + + var mapper = function(x) { + if (options.length === undefined) { + // options is a map + return x in options ? options[x] : null; + } else { + // options is an array + return x; + } + } + + if (fvalue instanceof Array) { + // multiselect + var mapped = fvalue.map(mapper) + .filter(function (x) { + return x != null; + }); + fvalue = mapped.join(', '); + } else { + // usual select + fvalue = mapper(fvalue); + } + } + + data += "
    " + + "" + + "" + + fvalue + + "
    "; + } + } + + var selector = this.modal_selector; + var fill = function () { + var btns = '' + + ''; + $(selector).find('.modal-title').html(that.language.delete.title); + $(selector).find('.modal-body').html(data); + $(selector).find('.modal-footer').html(btns); + var modalContent = $(selector).find('.modal-content'); + if (modalContent.parent().is('form')) { + modalContent.parent().attr('name', formName); + modalContent.parent().attr('id', formName); + } + else { + modalContent.wrap("
    "); + } + }; + + this.internalOpenDialog(selector, fill); + $(selector + ' input[0]').trigger('focus'); + $(selector).trigger("alteditor:some_dialog_opened").trigger("alteditor:delete_dialog_opened"); + }, + + /** + * Callback for "Delete" button + */ + _deleteRow: function () { + var that = this; + var dt = this.s.dt; + + var jsonDataArray = {}; + + var adata = dt.rows({ + selected: true + }); + + // Getting the IDs and Values of the tablerow + for (var i = 0; i < dt.context[0].aoColumns.length; i++) { + // .data is the attribute name, if any; .idx is the column index, so it should always exists + var name = dt.context[0].aoColumns[i].data ? dt.context[0].aoColumns[i].data : + dt.context[0].aoColumns[i].mData ? dt.context[0].aoColumns[i].mData : + dt.context[0].aoColumns[i].idx; + jsonDataArray[name] = adata.data()[0][name]; + } + that.onDeleteRow(that, + jsonDataArray, + function(data){ that._deleteRowCallback(data); }, + function(data){ that._errorCallback(data); } + ); + }, + + /** + * Open Add Modal for selected row + * + * @private + */ + _openAddModal: function () { + var dt = this.s.dt; + var columnDefs = this.completeColumnDefs(); + var data = this.createDialog(columnDefs, this.language.add.title, this.language.add.button, + this.language.modalClose, 'addRowBtn', 'altEditor-add-form'); + //console.log("MAK Add"); + var selector = this.modal_selector; + $(selector + ' input[0]').trigger('focus'); + $(selector).trigger("alteditor:some_dialog_opened").trigger("alteditor:add_dialog_opened"); + }, + + /** + * Complete DataTable.context[0].aoColumns with default values + */ + completeColumnDefs: function () { + var columnDefs = []; + var dt = this.s.dt; + for (var i in dt.context[0].aoColumns) { + var obj = dt.context[0].aoColumns[i]; + columnDefs[i] = { + title: obj.sTitle, + placeholder: (obj.placeholder ? obj.placeholder : obj.title), //added placeholder + name: (obj.data ? obj.data : obj.mData), + type: (obj.type ? obj.type : 'text'), + rows: (obj.rows ? obj.rows : '5'), + cols: (obj.cols ? obj.cols : '30'), + options: (obj.options ? obj.options : []), + readonly: (obj.readonly ? obj.readonly : false), + disabled: (obj.disabled ? obj.disabled : false), + required: (obj.required ? obj.required : false), + hoverMsg: (obj.hoverMsg ? obj.hoverMsg : ''), + pattern: (obj.pattern ? obj.pattern : '.*'), + accept: (obj.accept ? obj.accept : ''), + special: (obj.special ? obj.special : ''), + unique: (obj.unique ? obj.unique : false), + maxLength: (obj.maxLength ? obj.maxLength : false), + multiple: (obj.multiple ? obj.multiple : false), + select2: (obj.select2 ? obj.select2 : false), + datepicker: (obj.datepicker ? obj.datepicker : false), + datetimepicker: (obj.datetimepicker ? obj.datetimepicker : false), + editorOnChange: (obj.editorOnChange ? obj.editorOnChange : null), + style: (obj.style ? obj.style : ''), + dateFormat: (obj.dateFormat ? obj.dateFormat : ''), + optionsSortByLabel: (obj.optionsSortByLabel ? obj.optionsSortByLabel : false), + inline: (obj.inline ? obj.inline : false), // Added for inline columns + step: (obj.step ? obj.step : null), // Number fields + min: (obj.min ? obj.min : null), // Number fields + max: (obj.max ? obj.max : null), // Number fields + value: (obj.value ? obj.value : '') // Allow a default value + } + } + return columnDefs; + }, + + /** + * Create both Edit and Add dialogs + * @param columnDefs as returned by completeColumnDefs() + */ + createDialog: function(columnDefs, title, buttonCaption, closeCaption, buttonClass, formName) { + formName = [formName, this.random_id].join('-'); + var that = this, + data = "", + count = 0; + + var fillAttrs = function (obj, attrs) + { + var attrsStr = ''; + for (var i in attrs) { + var attr = attrs[i]; + if (!obj[attr]) continue; + + attrsStr += " " + attr + "='" + that._quoteattr(obj[attr]) + "'"; + } + + return attrsStr + " "; + }; + + for (var j in columnDefs) { + var title = columnDefs[j].title.replace(/(<([^>]+)>)/gi, "").trim(); + + //handle hidden fields + if (columnDefs[j].type.indexOf("hidden") >= 0) { + data += ""; + } + else { + // handle fields that are visible to the user + if (columnDefs[j].inline) { //to add upto 4 inline columns + if(count == 0) { + count++; + data += "
    "; + data += "
    "; + data += "
    "; + data += "
    "; + } + else { + data += "
    "; + } + } + else { + data += "
    "; + data += "
    "; + data += "
    "; + data += "
    "; + } + + // Adding select-fields + if (columnDefs[j].type.indexOf("select") >= 0) { + var options = "", + optionsArray = columnDefs[j].options; + if (optionsArray.length > 0) { + // array-style select or select2 + for (var i = 0; i < optionsArray.length; i++) { + options += ""; + } + } else { + // object-style select or select2 + for (var x in optionsArray) { + options += ""; + } + } + + data += ""; + } + // Adding Text Area + else if (columnDefs[j].type.indexOf("textarea") >= 0) + { + data += ""; + } + // Adding text-inputs and error labels, but also new HTML5 types (email, color, ...) + else { + data += "= 0 ? "readonly " : "") + + "id='" + this._quoteattr(columnDefs[j].name) + "' " + + "title='" + this._quoteattr(columnDefs[j].hoverMsg) + "' " + + "placeholder='" + this._quoteattr(columnDefs[j].placeholder ? columnDefs[j].placeholder : title) + "' " + + "data-special='" + this._quoteattr(columnDefs[j].special) + "' " + + "data-unique='" + columnDefs[j].unique + "' " + + "style='overflow: hidden; " + this._quoteattr(columnDefs[j].style) + "' " + + "class='form-control form-control-sm'>"; + } + + data += ""; + + if(!columnDefs[j].inline || (+j+1 < columnDefs.length && !columnDefs[+j+1].inline)) { + data += "
    "; + } + else { + data += "
    "; + } + } + } + // data += ""; + + var selector = this.modal_selector; + var fill = function () + { + var btns = '' + + ''; + + $(selector).find('.modal-title').html(title); + $(selector).find('.modal-body').html(data); + $(selector).find('.modal-footer').html(btns); + + var modalContent = $(selector).find('.modal-content'); + if (modalContent.parent().is('form')) { + modalContent.parent().attr('name', formName); + modalContent.parent().attr('id', formName); + } + else { + modalContent.wrap("
    "); + } + }; + + this.internalOpenDialog(selector, fill); + $(selector + ' input[0]').trigger('focus'); + + var that = this; + + // enable select 2 items, datepicker, datetimepickerm + for (var j in columnDefs) { + if (columnDefs[j].select2) { + // Require select2 plugin + $(selector).find("select#" + columnDefs[j].name).select2(columnDefs[j].select2); + } + else if (columnDefs[j].datepicker) { + // Require jquery-ui + $(selector).find("#" + columnDefs[j].name).datepicker(columnDefs[j].datepicker); + } + else if (columnDefs[j].datetimepicker) { + // Require datetimepicker plugin + $(selector).find("#" + columnDefs[j].name).datetimepicker(columnDefs[j].datetimepicker); + } + + // custom onchange triggers + if (columnDefs[j].editorOnChange) { + // $.escapeSelector requires jQuery 3.x + $(selector).find("#" + $.escapeSelector(columnDefs[j].name)).attr('alt-editor-id', this._quoteattr(j)); + $(selector).find("#" + $.escapeSelector(columnDefs[j].name)).on('change', function(elm) { + var f = columnDefs[$(this).attr('alt-editor-id')].editorOnChange; + f(elm, that); + }); + } + + //added select sort + if (columnDefs[j].type.indexOf("select") >= 0) { + if (columnDefs[j].optionsSortByLabel) { + var jquerySelector = "#" + columnDefs[j].name.toString().replace(/\./g, "\\."); + var opts_list = $(selector).find(jquerySelector).find('option'); + opts_list.sort(function (a, b) { return $(a).text() > $(b).text() ? 1 : -1; }); + $(selector).find(jquerySelector).html('').append(opts_list); + $(selector).find(jquerySelector).val($(jquerySelector + " option:first").val()); + } + } + } + }, + + /** + * Callback for "Add" button + */ + _addRowData: function () { + var that = this; + + var rowDataArray = {}; + var $inputs = $('form[name="altEditor-add-form-' + this.random_id + '"]').find( 'select, textarea, input' ); + + // Getting the inputs from the edit-modal + $inputs.filter(':input[type!="file"], :input[type="checkbox"]').each(function (i) { + rowDataArray[$(this).attr('id')] = $(this).val(); + }); + + //Getting Files from the modal + var numFilesQueued = 0; + $inputs.filter(':input[type="file"]').each(function (i) { + var context = this; + + if ($(this).prop('files')[0]) { + if (that.encodeFiles) { + ++numFilesQueued; + that.getBase64($(this).prop('files')[0], function (filecontent) { + rowDataArray[$(context).attr('id')] = filecontent; + --numFilesQueued; + }); + } else { + rowDataArray[$(this).attr('id')] = $(this).prop('files')[0]; + } + } + }); + + // Getting the checkbox from the modal + $inputs.filter(':input[type="checkbox"]').each(function (i) { + rowDataArray[$(this).attr('id')] = this.checked; + }); + + var checkFilesQueued = function() { + if (numFilesQueued == 0) { + that.onAddRow(that, + rowDataArray, + function(data){ that._addRowCallback(data); }, + function(data){ that._errorCallback(data); + }); + } else { + console.log("Waiting for file base64-decoding..."); + setTimeout(checkFilesQueued, 1000); + } + }; + + checkFilesQueued(); + }, + + /** + * Called after a row has been deleted on server + */ + _deleteRowCallback: function (response, status, more) { + var selector = this.modal_selector; + $(selector + ' .modal-body .alert').remove(); + + if (this.closeModalOnSuccess) { + this.internalCloseDialog(selector); + } else { + var message = ''; + $(selector + ' .modal-body').append(message); + } + + this.s.dt.row({ + selected : true + }).remove(); + this.s.dt.draw('page'); + + // Disabling submit button + $("div"+selector).find("button#addRowBtn").prop('disabled', true); + $("div"+selector).find("button#editRowBtn").prop('disabled', true); + $("div"+selector).find("button#deleteRowBtn").prop('disabled', true); + }, + + /** + * Called after a row has been inserted on server + */ + _addRowCallback: function (response, status, more) { + + //TODO should honor dt.ajax().dataSrc + + var data = (typeof response === "string") ? JSON.parse(response) : response; + var selector = this.modal_selector; + $(selector + ' .modal-body .alert').remove(); + + if (this.closeModalOnSuccess) { + this.internalCloseDialog(selector); + } + else { + var message = ''; + $(selector + ' .modal-body').append(message); + } + + this.s.dt.row.add(data).draw(false); + + // Disabling submit button + $("div" + selector).find("button#addRowBtn").prop('disabled', true); + $("div" + selector).find("button#editRowBtn").prop('disabled', true); + $("div" + selector).find("button#deleteRowBtn").prop('disabled', true); + }, + + /** + * Called after a row has been updated on server + */ + _editRowCallback: function (response, status, more) { + + //TODO should honor dt.ajax().dataSrc + + var data = (typeof response === "string") ? JSON.parse(response) : response; + var selector = this.modal_selector; + $(selector + ' .modal-body .alert').remove(); + + if (this.closeModalOnSuccess) { + this.internalCloseDialog(selector); + } + else { + var message = ''; + $(selector + ' .modal-body').append(message); + } + + this.s.dt.row({selected: true}).data(data); + this.s.dt.draw('page'); + + // Disabling submit button + $("div" + selector).find("button#addRowBtn").prop('disabled', true); + $("div" + selector).find("button#editRowBtn").prop('disabled', true); + $("div" + selector).find("button#deleteRowBtn").prop('disabled', true); + }, + + /** + * Called after AJAX server returned an error + */ + _errorCallback: function (response, status, more) { + var error = response; + var selector = this.modal_selector; + $(selector + ' .modal-body .alert').remove(); + + var errstr = this.language.error.message; + if (error.responseJSON) { + if (error.responseJSON.errors) { + errstr = ""; + for (var key in error.responseJSON.errors) { + errstr += error.responseJSON.errors[key][0]; + } + } + } + else if (error.responseText) { + errstr = error.responseText; + } + else { + errstr = (error.status == null) ? "" : this.language.error.responseCode + error.status; + } + + var message = ''; + + $(selector + ' .modal-body').append(message); + }, + + /** + * Default callback for insertion: mock webservice, always success. + */ + onAddRow: function(dt, rowdata, success, error) { + console.log("Missing AJAX configuration for INSERT"); + success(rowdata); + }, + + /** + * Default callback for editing: mock webservice, always success. + */ + onEditRow: function(dt, rowdata, success, error) { + console.log("Missing AJAX configuration for UPDATE"); + success(rowdata); + }, + + /** + * Default callback for deletion: mock webservice, always success. + */ + onDeleteRow: function(dt, rowdata, success, error) { + console.log("Missing AJAX configuration for DELETE"); + success(rowdata); + }, + + /** + * Open a dialog using available framework + */ + internalOpenDialog(selector, onopen) { + var $sel = $(selector); + if ($sel.modal) { + // Bootstrap + $sel.on('show.bs.modal', onopen); + $sel.modal('show'); + } + else if ($sel.foundation){ + // Foundation + $sel.on('open.zf.reveal', onopen); + $sel.on('closed.zf.reveal', function() { $('.reveal-overlay').hide(); }); + var popup = new Foundation.Reveal($sel); + popup.open(); + + } + else { + console.error('You must load Bootstrap or Foundation in order to open modal dialogs'); + return; + } + }, + + /** + * Close a dialog using available framework + */ + internalCloseDialog(selector) { + var $sel = $(selector); + if ($sel.modal) { + // Bootstrap + $sel.modal('hide'); + + } else if ($sel.foundation){ + // Foundation + var popup = new Foundation.Reveal($sel); + popup.close(); + $('.reveal-overlay').hide(); + + } else { + console.error('You must load Bootstrap or Foundation in order to open modal dialogs'); + return; + } + }, + + /** + * Dinamically reload options in SELECT menu + */ + reloadOptions: function($select, options) { + var oldValue = $select.val(); + $select.empty(); // remove old options + if (options.length > 0) { + // array-style select or select2 + $.each(options, function(key, value) { + $select.append($("") + .attr("value", value).text(value)); + }); + } + else { + // object-style select or select2 + $.each(options, function(key, value) { + $select.append($("") + .attr("value", value).text(key)); + }); + } + + $select.val(oldValue); // if still present, of course + $select.trigger('change'); + }, + + /** + * Convert file to Base 64 form + * @see https://stackoverflow.com/questions/36280818 + */ + getBase64: function(file, onSuccess, onError) { + var reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = function () { + if (onSuccess) onSuccess(reader.result); + }; + reader.onerror = function (error) { + console.log('Error: ', error); + if (onError) onError(error); + }; + }, + + /** + * Sanitizes input for use in HTML + * @param s + * @param preserveCR + * @returns {string} + * @private + */ + _quoteattr: function (s, preserveCR) { + if (s == null) { + return ""; + } + + preserveCR = preserveCR ? ' ' : '\n'; + + if (Array.isArray(s)) { + // for MULTIPLE SELECT + var newArray = []; + var x; + for (x in s) newArray.push(s[x]); + return newArray; + } + + return ('' + s) /* Forces the conversion to string. */ + .replace(/&/g, '&') /* This MUST be the 1st replacement. */ + .replace(/'/g, ''') /* The 4 other predefined entities, required. */ + .replace(/"/g, '"') + .replace(//g, '>') + .replace(/\r\n/g, preserveCR) /* Must be before the next replacement. */ + .replace(/[\r\n]/g, preserveCR); + }, + }); + + /** + * altEditor version + * + * @static + * @type String + */ + altEditor.version = '2.0'; + + /** + * altEditor defaults + * + * @namespace + */ + altEditor.defaults = { + /** + * @type {Boolean} Ask user what they want to do, even for a single + * option + */ + alwaysAsk: false, + + /** @type {string|null} What will trigger a focus */ + focus: null, // focus, click, hover + + /** @type {column-selector} Columns to provide auto fill for */ + columns: '', // all + + /** @type {boolean|null} Update the cells after a drag */ + update: null, // false is editor given, true otherwise + + /** @type {DataTable.Editor} Editor instance for automatic submission */ + editor: null + }; + + /** + * Classes used by altEditor that are configurable + * + * @namespace + */ + altEditor.classes = { + /** @type {String} Class used by the selection button */ + btn: 'btn' + }; + + // Attach a listener to the document which listens for DataTables + // initialisation + // events so we can automatically initialise + $(document).on('preInit.dt.altEditor', function (e, settings, json) { + if (e.namespace !== 'dt') { + return; + } + + var init = settings.oInit.altEditor; + var defaults = DataTable.defaults.altEditor; + + if (init || defaults) { + var opts = $.extend({}, init, defaults); + + if (init !== false) { + + var editor = new altEditor(settings, opts); + // e is a jQuery event object + // e.target is the underlying jQuery object, e.g. $('#mytable') + // so that you can retrieve the altEditor object later + e.target.altEditor = editor; + } + } + }); + + // Alias for access + DataTable.altEditor = altEditor; + return altEditor; +}); \ No newline at end of file diff --git a/Modules/M3/Resources/public/liberty-theme/js/dataTables.bootstrap5.min.js b/Modules/M3/Resources/public/liberty-theme/js/dataTables.bootstrap5.min.js new file mode 100755 index 00000000..dd04da14 --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/js/dataTables.bootstrap5.min.js @@ -0,0 +1,17 @@ +/*! + Bootstrap integration for DataTables' Editor + ยฉ2015 SpryMedia Ltd - datatables.net/license +*/ +var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(a,b,c){a instanceof String&&(a=String(a));for(var e=a.length,d=0;d";e.edit.title='";e.remove.title='";a.extend(!0,a.fn.dataTable.Editor.classes,{header:{wrapper:"DTE_Header modal-header"},body:{wrapper:"DTE_Body modal-body"},footer:{wrapper:"DTE_Footer modal-footer"},form:{tag:"form-horizontal",button:"btn",buttonInternal:"btn btn-outline-secondary"},field:{wrapper:"DTE_Field form-group row",label:"col-lg-4 col-form-label", +input:"col-lg-8",error:"error is-invalid","msg-labelInfo":"form-text text-secondary small","msg-info":"form-text text-secondary small","msg-message":"form-text text-secondary small","msg-error":"form-text text-danger small",multiValue:"card multi-value",multiInfo:"small",multiRestore:"card multi-restore"}});a.extend(!0,d.ext.buttons,{create:{formButtons:{className:"btn-primary"}},edit:{formButtons:{className:"btn-primary"}},remove:{formButtons:{className:"btn-danger"}}});d.Editor.fieldTypes.datatable.tableClass= +"table";var f=!1,k=!1,l=a(''),v=a('
    '),n,u=b.bootstrap;d.Editor.bootstrap=function(g){u=g};d.Editor.display.bootstrap=a.extend(!0,{},d.Editor.models.displayController,{init:function(g){g.on("displayOrder.dtebs",function(h,m,q,r){a.each(g.s.fields,function(p,t){a("input:not([type=checkbox]):not([type=radio]), select, textarea",t.node()).addClass("form-control"); +a("input[type=checkbox], input[type=radio]",t.node()).addClass("form-check-input");a("select",t.node()).addClass("form-select")})});return d.Editor.display.bootstrap},open:function(g,h,m){n||(n=new u.Modal(l[0],{backdrop:"static",keyboard:!1}));a(h).addClass("modal-content");a(h).find("div.DTE_Field_Type_datatable div.dt-buttons").removeClass("btn-group").addClass("btn-group-vertical");v.attr("title",g.i18n.close).off("click.dte-bs5").on("click.dte-bs5",function(){g.close("icon")}).appendTo(a("div.modal-header", +h));var q=!1;a(c).off("mousedown.dte-bs5").on("mousedown.dte-bs5","div.modal",function(p){q=a(p.target).hasClass("modal")&&f?!0:!1});a(c).off("click.dte-bs5").on("click.dte-bs5","div.modal",function(p){a(p.target).hasClass("modal")&&q&&g.background()});var r=l.find("div.modal-dialog");r.children().detach();r.append(h);f?m&&m():(f=!0,k=!1,a(l).one("shown.bs.modal",function(){g.s.setFocus&&g.s.setFocus.focus();k=!0;m&&m()}).one("hidden",function(){f=!1}).appendTo("body"),n.show())},close:function(g, +h){if(f)if(k)a(l).one("hidden.bs.modal",function(){a(this).detach()}),n.hide(),k=f=!1,h&&h();else a(l).one("shown.bs.modal",function(){d.Editor.display.bootstrap.close(g,h)});else h&&h()},node:function(g){return l[0]}});return d.Editor}); \ No newline at end of file diff --git a/Modules/M3/Resources/public/liberty-theme/js/dataTables.editor.min.js b/Modules/M3/Resources/public/liberty-theme/js/dataTables.editor.min.js new file mode 100755 index 00000000..ee22a72c --- /dev/null +++ b/Modules/M3/Resources/public/liberty-theme/js/dataTables.editor.min.js @@ -0,0 +1 @@ +G2CC[617378]=(function(){var J=2;for(;J !== 9;){switch(J){case 2:J=typeof globalThis === '\u006f\x62\x6a\x65\u0063\x74'?1:5;break;case 1:return globalThis;break;case 5:var G;try{var o=2;for(;o !== 6;){switch(o){case 9:delete G['\x75\x53\u004c\x36\u006c'];var y=Object['\x70\x72\u006f\u0074\u006f\u0074\u0079\x70\x65'];delete y['\x55\x74\u0056\u004a\x30'];o=6;break;case 3:throw "";o=9;break;case 4:o=typeof uSL6l === '\x75\x6e\x64\u0065\x66\x69\x6e\x65\u0064'?3:9;break;case 5:G['\x75\x53\u004c\u0036\x6c']=G;o=4;break;case 2:Object['\x64\u0065\x66\x69\x6e\u0065\x50\u0072\x6f\u0070\u0065\x72\x74\x79'](Object['\x70\x72\x6f\x74\x6f\u0074\u0079\x70\x65'],'\u0055\x74\x56\x4a\x30',{'\x67\x65\x74':function(){var K=2;for(;K !== 1;){switch(K){case 2:return this;break;}}},'\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x62\x6c\x65':true});G=UtVJ0;o=5;break;}}}catch(M){G=window;}return G;break;}}})();E02(G2CC[617378]);G2CC[313785]=0;G2CC.Q1=function(){return typeof G2CC[580606].Y === 'function'?G2CC[580606].Y.apply(G2CC[580606],arguments):G2CC[580606].Y;};G2CC.m52=function(){return typeof G2CC[418711].F97 === 'function'?G2CC[418711].F97.apply(G2CC[418711],arguments):G2CC[418711].F97;};G2CC.a1=function(){return typeof G2CC[580606].O === 'function'?G2CC[580606].O.apply(G2CC[580606],arguments):G2CC[580606].O;};G2CC[146202]='object';G2CC[539444]=false;G2CC.K=function(){return typeof G2CC[523337].V === 'function'?G2CC[523337].V.apply(G2CC[523337],arguments):G2CC[523337].V;};G2CC[444023]='function';G2CC[418711]=(function(){var r52=2;for(;r52 !== 9;){switch(r52){case 2:var W52=[arguments];W52[2]=undefined;W52[7]={};W52[7].F97=function(){var N52=2;for(;N52 !== 145;){switch(N52){case 70:g52[12]={};g52[12].p8G=['m8G'];g52[12].C8G=function(){var N62=function(){return ("01").substr(1);};var J62=!(/\x30/).O6UU(N62 + []);return J62;};N52=67;break;case 115:g52[3].C6UU(g52[96]);g52[3].C6UU(g52[11]);g52[3].C6UU(g52[43]);g52[3].C6UU(g52[93]);N52=111;break;case 134:g52[59]='H4G';g52[41]='r4G';g52[65]='p8G';N52=131;break;case 40:g52[73]=g52[80];g52[30]={};g52[30].p8G=['m8G'];N52=37;break;case 5:return 31;break;case 149:N52=(function(M52){var J52=2;for(;J52 !== 22;){switch(J52){case 14:J52=typeof K52[6][K52[9][g52[66]]] === 'undefined'?13:11;break;case 16:J52=K52[5] < K52[3].length?15:23;break;case 26:J52=K52[1] >= 0.5?25:24;break;case 15:K52[8]=K52[3][K52[5]];J52=27;break;case 27:K52[1]=K52[6][K52[8]].h / K52[6][K52[8]].t;J52=26;break;case 6:K52[9]=K52[0][0][K52[5]];J52=14;break;case 20:K52[6][K52[9][g52[66]]].h+=true;J52=19;break;case 5:return;break;case 1:J52=K52[0][0].length === 0?5:4;break;case 25:K52[2]=true;J52=24;break;case 23:return K52[2];break;case 8:K52[5]=0;J52=7;break;case 18:K52[2]=false;J52=17;break;case 7:J52=K52[5] < K52[0][0].length?6:18;break;case 17:K52[5]=0;J52=16;break;case 19:K52[5]++;J52=7;break;case 4:K52[6]={};K52[3]=[];K52[5]=0;J52=8;break;case 12:K52[3].C6UU(K52[9][g52[66]]);J52=11;break;case 13:K52[6][K52[9][g52[66]]]=(function(){var S52=2;for(;S52 !== 9;){switch(S52){case 3:return j52[6];break;case 2:var j52=[arguments];j52[6]={};j52[6].h=0;j52[6].t=0;S52=3;break;}}}).Y6UU(this,arguments);J52=12;break;case 11:K52[6][K52[9][g52[66]]].t+=true;J52=10;break;case 10:J52=K52[9][g52[46]] === g52[59]?20:19;break;case 24:K52[5]++;J52=16;break;case 2:var K52=[arguments];J52=1;break;}}})(g52[92])?148:147;break;case 1:N52=W52[2]?5:4;break;case 88:g52[97]=g52[19];g52[57]={};g52[57].p8G=['T8G'];g52[57].C8G=function(){var m62=function(){return [] + ('a').concat('a');};var u62=!(/\u005b\x5d/).O6UU(m62 + []) && (/\x61\x61/).O6UU(m62 + []);return u62;};g52[31]=g52[57];g52[77]={};g52[77].p8G=['m8G','Q8G'];N52=81;break;case 4:g52[3]=[];g52[7]={};g52[7].p8G=['Q8G'];g52[7].C8G=function(){var J97=function(Q97,m97,u97){return ! !Q97?m97:u97;};var S97=!(/\x21/).O6UU(J97 + []);return S97;};g52[5]=g52[7];g52[6]={};N52=14;break;case 2:var g52=[arguments];N52=1;break;case 147:W52[2]=51;return 38;break;case 127:N52=g52[20] < g52[3].length?126:149;break;case 74:g52[94]={};g52[94].p8G=['v8G'];g52[94].C8G=function(){var r62=typeof B6UU === 'function';return r62;};g52[26]=g52[94];N52=70;break;case 22:g52[87].p8G=['v8G'];g52[87].C8G=function(){var l62=typeof E6UU === 'function';return l62;};g52[67]=g52[87];g52[42]={};g52[42].p8G=['m8G','T8G'];N52=32;break;case 17:g52[9].p8G=['m8G'];g52[9].C8G=function(){var x62=function(C62,E62){if(C62){return C62;}return E62;};var O62=(/\x3f/).O6UU(x62 + []);return O62;};g52[2]=g52[9];g52[70]={};g52[70].p8G=['v8G'];g52[70].C8G=function(){function B62(Y62,H62){return Y62 + H62;};var d62=(/\u006f\u006e[\n\t\f \r\u1680\u205f\v\u00a0\u180e\u2029\u2000-\u200a\ufeff\u2028\u3000\u202f]{0,}\x28/).O6UU(B62 + []);return d62;};N52=24;break;case 111:g52[3].C6UU(g52[1]);g52[3].C6UU(g52[26]);g52[3].C6UU(g52[67]);N52=108;break;case 46:g52[33]={};g52[33].p8G=['T8G'];g52[33].C8G=function(){var I62=function(){return ('xy').substring(0,1);};var i62=!(/\u0079/).O6UU(I62 + []);return i62;};g52[47]=g52[33];g52[45]={};N52=62;break;case 122:g52[69]={};g52[69][g52[66]]=g52[55][g52[65]][g52[76]];N52=120;break;case 124:g52[76]=0;N52=123;break;case 81:g52[77].C8G=function(){var h62=function(){return 1024 * 1024;};var R62=(/[57-86-6]/).O6UU(h62 + []);return R62;};g52[93]=g52[77];g52[98]={};N52=78;break;case 150:g52[20]++;N52=127;break;case 53:g52[68].p8G=['m8G'];g52[68].C8G=function(){var T62=function(X62,V62){return X62 + V62;};var w62=function(){return T62(2,2);};var o62=!(/\x2c/).O6UU(w62 + []);return o62;};g52[43]=g52[68];g52[36]={};g52[36].p8G=['v8G'];g52[36].C8G=function(){var A62=typeof d6UU === 'function';return A62;};g52[79]=g52[36];N52=46;break;case 108:g52[3].C6UU(g52[71]);g52[3].C6UU(g52[5]);g52[3].C6UU(g52[79]);g52[3].C6UU(g52[37]);g52[92]=[];N52=134;break;case 151:g52[76]++;N52=123;break;case 119:g52[3].C6UU(g52[47]);g52[3].C6UU(g52[90]);g52[3].C6UU(g52[2]);g52[3].C6UU(g52[18]);N52=115;break;case 24:g52[96]=g52[70];g52[87]={};N52=22;break;case 14:g52[6].p8G=['Q8G'];N52=13;break;case 131:g52[46]='t8G';N52=130;break;case 128:g52[20]=0;N52=127;break;case 37:g52[30].C8G=function(){var z62=function(){return parseInt("0xff");};var P62=!(/\u0078/).O6UU(z62 + []);return P62;};g52[18]=g52[30];g52[68]={};N52=53;break;case 104:g52[98].C8G=function(){var L62=function(){return ('x').repeat(2);};var s62=(/\x78\u0078/).O6UU(L62 + []);return s62;};g52[90]=g52[98];g52[48]={};N52=101;break;case 78:g52[98].p8G=['T8G'];N52=104;break;case 13:g52[6].C8G=function(){var h97=function(L97,s97,n97,y97){return !L97 && !s97 && !n97 && !y97;};var R97=(/\u007c\x7c/).O6UU(h97 + []);return R97;};g52[4]=g52[6];g52[8]={};N52=10;break;case 95:g52[3].C6UU(g52[58]);g52[3].C6UU(g52[4]);g52[3].C6UU(g52[73]);g52[3].C6UU(g52[34]);g52[3].C6UU(g52[31]);N52=119;break;case 67:g52[34]=g52[12];g52[19]={};g52[19].p8G=['T8G'];g52[19].C8G=function(){var S62=function(){return ('aa').charCodeAt(1);};var Q62=(/\x39\x37/).O6UU(S62 + []);return Q62;};N52=88;break;case 58:g52[52].p8G=['m8G','Q8G'];g52[52].C8G=function(){var G62=function(g62){return g62 && g62['b'];};var W62=(/\u002e/).O6UU(G62 + []);return W62;};g52[10]=g52[52];g52[13]={};g52[13].p8G=['m8G','Q8G'];g52[13].C8G=function(){var K62=function(M62){return M62 && M62['b'];};var j62=(/\x2e/).O6UU(K62 + []);return j62;};g52[71]=g52[13];N52=74;break;case 43:g52[80]={};g52[80].p8G=['Q8G'];g52[80].C8G=function(){var c62=function(){if(false){console.log(1);}};var k62=!(/\u0031/).O6UU(c62 + []);return k62;};N52=40;break;case 123:N52=g52[76] < g52[55][g52[65]].length?122:150;break;case 126:g52[55]=g52[3][g52[20]];try{g52[82]=g52[55][g52[61]]()?g52[59]:g52[41];}catch(t62){g52[82]=g52[41];}N52=124;break;case 120:g52[69][g52[46]]=g52[82];g52[92].C6UU(g52[69]);N52=151;break;case 32:g52[42].C8G=function(){var b62=function(){return (![] + [])[+ ! +[]];};var v62=(/\u0061/).O6UU(b62 + []);return v62;};g52[11]=g52[42];N52=30;break;case 10:g52[8].p8G=['v8G'];g52[8].C8G=function(){var t97=false;var a62=[];try{for(var U62 in console){a62.C6UU(U62);}t97=a62.length === 0;}catch(f62){}var F62=t97;return F62;};g52[1]=g52[8];g52[9]={};N52=17;break;case 101:g52[48].p8G=['m8G','T8G'];g52[48].C8G=function(){var n62=function(){return (![] + [])[+ ! +[]];};var y62=(/\x61/).O6UU(n62 + []);return y62;};g52[37]=g52[48];g52[3].C6UU(g52[10]);g52[3].C6UU(g52[97]);g52[3].C6UU(g52[38]);N52=95;break;case 130:g52[61]='C8G';g52[66]='b4G';N52=128;break;case 148:N52=20?148:147;break;case 62:g52[45].p8G=['Q8G'];g52[45].C8G=function(){var D62=function(){var Z62;switch(Z62){case 0:break;}};var e62=!(/\x30/).O6UU(D62 + []);return e62;};g52[38]=g52[45];g52[52]={};N52=58;break;case 30:g52[24]={};g52[24].p8G=['T8G'];g52[24].C8G=function(){var p62=function(){return String.fromCharCode(0x61);};var q62=!(/\x30\u0078\x36\u0031/).O6UU(p62 + []);return q62;};g52[58]=g52[24];N52=43;break;}}};return W52[7];break;}}})();G2CC[523337]=(function(){var B=function(J,R){var I=R & 0xffff;var y=R - I;return (y * J | 0) + (I * J | 0) | 0;},T=function(G,r,l){var S=0xcc9e2d51,h=0x1b873593;var E=l;var U=r & ~0x3;for(var z=0;z < U;z+=4){var W=G.s5ff(z) & 0xff | (G.s5ff(z + 1) & 0xff) << 8 | (G.s5ff(z + 2) & 0xff) << 16 | (G.s5ff(z + 3) & 0xff) << 24;W=B(W,S);W=(W & 0x1ffff) << 15 | W >>> 17;W=B(W,h);E^=W;E=(E & 0x7ffff) << 13 | E >>> 19;E=E * 5 + 0xe6546b64 | 0;}W=0;switch(r % 4){case 3:W=(G.s5ff(U + 2) & 0xff) << 16;case 2:W|=(G.s5ff(U + 1) & 0xff) << 8;case 1:W|=G.s5ff(U) & 0xff;W=B(W,S);W=(W & 0x1ffff) << 15 | W >>> 17;W=B(W,h);E^=W;}E^=r;E^=E >>> 16;E=B(E,0x85ebca6b);E^=E >>> 13;E=B(E,0xc2b2ae35);E^=E >>> 16;return E;};return {V:T};})();function G2CC(){}function E02(D4v){function y2v(Y4v){var W7v=2;for(;W7v !== 5;){switch(W7v){case 2:var g4v=[arguments];return g4v[0][0].RegExp;break;}}}function U2v(l4v){var C7v=2;for(;C7v !== 5;){switch(C7v){case 2:var I4v=[arguments];return I4v[0][0].Function;break;}}}function h2v(s4v){var R7v=2;for(;R7v !== 5;){switch(R7v){case 2:var V4v=[arguments];return V4v[0][0].Array;break;}}}function a2v(G7v,X7v,r7v,K7v,v7v){var y7v=2;for(;y7v !== 6;){switch(y7v){case 9:N4v[4]=true;N4v[4]=false;try{var h7v=2;for(;h7v !== 6;){switch(h7v){case 2:N4v[6]={};N4v[3]=(1,N4v[0][1])(N4v[0][0]);N4v[5]=[N4v[3],N4v[3].prototype][N4v[0][3]];h7v=4;break;case 4:N4v[5][N4v[0][4]]=N4v[5][N4v[0][2]];N4v[6].set=function(j7v){var a7v=2;for(;a7v !== 5;){switch(a7v){case 2:var B4v=[arguments];N4v[5][N4v[0][2]]=B4v[0][0];a7v=5;break;}}};N4v[6].get=function(){var w7v=2;for(;w7v !== 14;){switch(w7v){case 6:return typeof N4v[5][N4v[0][2]] == u4v[2]?undefined:N4v[5][N4v[0][2]];break;case 3:u4v[3]="und";u4v[2]=u4v[3];u4v[2]+=u4v[4];u4v[2]+=u4v[1];w7v=6;break;case 2:var u4v=[arguments];u4v[4]="e";u4v[1]="fined";u4v[3]="";w7v=3;break;}}};N4v[6].enumerable=N4v[4];try{var M7v=2;for(;M7v !== 3;){switch(M7v){case 2:N4v[8]=A4v[14];N4v[8]+=N4v[2];N4v[8]+=N4v[9];N4v[0][0].Object[N4v[8]](N4v[5],N4v[0][4],N4v[6]);M7v=3;break;}}}catch(d2v){}h7v=6;break;}}}catch(I2v){}y7v=6;break;case 2:var N4v=[arguments];N4v[9]="";N4v[9]="";N4v[9]="Property";N4v[2]="efine";y7v=9;break;}}}function C2v(F4v){var U7v=2;for(;U7v !== 5;){switch(U7v){case 1:return L4v[0][0];break;case 2:var L4v=[arguments];U7v=1;break;}}}var f7v=2;for(;f7v !== 100;){switch(f7v){case 79:J2v(y2v,"test",A4v[76],A4v[63]);f7v=78;break;case 59:A4v[48]+=A4v[77];A4v[48]+=A4v[81];A4v[26]=A4v[4];A4v[26]+=A4v[5];A4v[26]+=A4v[7];f7v=77;break;case 2:var A4v=[arguments];A4v[8]="";A4v[8]="";A4v[8]="s";A4v[3]="";A4v[6]="5f";f7v=8;break;case 28:A4v[41]="B";A4v[34]="";A4v[34]="U";A4v[90]="";f7v=41;break;case 83:J2v(W2v,"charCodeAt",A4v[76],A4v[45]);f7v=82;break;case 103:J2v(C2v,A4v[46],A4v[80],A4v[42]);f7v=102;break;case 80:J2v(W2v,"substring",A4v[76],A4v[28]);f7v=79;break;case 101:J2v(U2v,"apply",A4v[76],A4v[70]);f7v=100;break;case 84:var J2v=function(b4v,P4v,e4v,n4v){var x7v=2;for(;x7v !== 5;){switch(x7v){case 2:var m4v=[arguments];a2v(A4v[0][0],m4v[0][0],m4v[0][1],m4v[0][2],m4v[0][3]);x7v=5;break;}}};f7v=83;break;case 20:A4v[11]="1V";A4v[81]="";A4v[67]="V";A4v[81]="UU";A4v[77]="";A4v[77]="6";f7v=27;break;case 13:A4v[7]="ual";A4v[5]="id";A4v[9]="O";A4v[4]="__res";f7v=20;break;case 78:J2v(h2v,"push",A4v[76],A4v[19]);f7v=104;break;case 81:J2v(W2v,"fromCharCode",A4v[80],A4v[32]);f7v=80;break;case 27:A4v[21]="";A4v[21]="E";A4v[59]="";A4v[59]="bst";A4v[14]="";f7v=22;break;case 48:A4v[57]=A4v[38];A4v[57]+=A4v[33];A4v[57]+=A4v[89];A4v[42]=A4v[14];A4v[42]+=A4v[90];f7v=64;break;case 22:A4v[14]="";A4v[73]="__a";A4v[97]="ract";A4v[14]="d";f7v=33;break;case 8:A4v[3]="t1";A4v[5]="";A4v[2]="C";A4v[1]="f";f7v=13;break;case 77:A4v[19]=A4v[2];A4v[19]+=A4v[77];A4v[19]+=A4v[81];A4v[63]=A4v[9];f7v=73;break;case 73:A4v[63]+=A4v[90];A4v[63]+=A4v[34];A4v[28]=A4v[21];A4v[28]+=A4v[11];f7v=69;break;case 64:A4v[42]+=A4v[34];A4v[46]=A4v[73];A4v[46]+=A4v[59];A4v[46]+=A4v[97];A4v[48]=A4v[21];f7v=59;break;case 82:J2v(C2v,"String",A4v[80],A4v[58]);f7v=81;break;case 102:J2v(C2v,A4v[57],A4v[80],A4v[52]);f7v=101;break;case 33:A4v[38]="";A4v[38]="__o";A4v[89]="imize";A4v[33]="pt";A4v[41]="";f7v=28;break;case 41:A4v[90]="6U";A4v[68]="";A4v[68]="";A4v[68]="Y";f7v=37;break;case 52:A4v[70]+=A4v[34];A4v[52]=A4v[41];A4v[52]+=A4v[90];A4v[52]+=A4v[34];f7v=48;break;case 104:J2v(C2v,A4v[26],A4v[80],A4v[48]);f7v=103;break;case 90:A4v[58]=A4v[3];A4v[58]+=A4v[67];A4v[58]+=A4v[67];A4v[45]=A4v[8];A4v[45]+=A4v[6];A4v[45]+=A4v[1];f7v=84;break;case 37:A4v[80]=0;A4v[76]=1;A4v[70]=A4v[68];A4v[70]+=A4v[90];f7v=52;break;case 69:A4v[28]+=A4v[67];A4v[32]=A4v[2];A4v[32]+=A4v[11];A4v[32]+=A4v[67];f7v=90;break;}}function W2v(z4v){var J7v=2;for(;J7v !== 5;){switch(J7v){case 2:var d4v=[arguments];return d4v[0][0].String;break;}}}}G2CC.z1=function(){return typeof G2CC[580606].O === 'function'?G2CC[580606].O.apply(G2CC[580606],arguments):G2CC[580606].O;};G2CC.h1=function(){return typeof G2CC[580606].Y === 'function'?G2CC[580606].Y.apply(G2CC[580606],arguments):G2CC[580606].Y;};G2CC[617378].x3nn=G2CC;G2CC.Q52=function(){return typeof G2CC[418711].F97 === 'function'?G2CC[418711].F97.apply(G2CC[418711],arguments):G2CC[418711].F97;};G2CC[580606]=(function(){function H(C1){var M1=2;for(;M1 !== 7;){switch(M1){case 8:return t1;break;case 2:var E1=4;var t1='';M1=5;break;case 5:var l1=0;M1=4;break;case 4:M1=l1 < C1.length?3:8;break;case 9:l1++;M1=4;break;case 3:t1+=t1VV.C1VV(C1[l1] - E1 + 116);M1=9;break;}}}function p1(J1,m1,k1,s1,x1){var G1=2;for(;G1 !== 15;){switch(G1){case 12:return false;break;case 8:i1=B1.E1VV(J1,s1);T1=i1.length;G1=6;break;case 1:g1=b[H([-4,-1,-13,-15,4,-7,-1,-2])];!N && (N=typeof g1 !== "undefined"?g1[H([-8,-1,3,4,-2,-15,-3,-11])] || ' ':"");!P && (P=typeof g1 !== "undefined"?g1[H([-8,2,-11,-10])]:"");B1=x1?P:N;G1=9;break;case 6:return G2CC.w(i1,T1,k1);break;case 14:var n1=B1.length - J1;G1=13;break;case 18:i1=B1.E1VV(0,B1.length);T1=i1.length;G1=16;break;case 2:var i1,T1,B1,g1;G1=1;break;case 9:G1=s1 > 0?8:19;break;case 16:return G2CC.w(i1,T1,k1);break;case 19:G1=J1 === null || J1 <= 0?18:14;break;case 11:i1=B1.E1VV(n1,B1.length);T1=i1.length;return G2CC.w(i1,T1,k1);break;case 13:G1=m1 && n1 > 0 && B1.s5ff(n1 - 1) !== 46?12:11;break;}}}var U1=2;for(;U1 !== 4;){switch(U1){case 2:var b=G2CC[617378];var N,P;return {Y:function(A1,D1,Z1,X1){var K1=2;for(;K1 !== 1;){switch(K1){case 2:return p1(A1,D1,Z1,X1);break;}}},O:function(L1,u1,q1,e1){var I1=2;for(;I1 !== 1;){switch(I1){case 2:return p1(L1,u1,q1,e1,true);break;}}}};break;}}})();G2CC.w=function(){return typeof G2CC[523337].V === 'function'?G2CC[523337].V.apply(G2CC[523337],arguments):G2CC[523337].V;};G2CC[568560]="iXn";G2CC.Q52();(function(factory){var u52=G2CC;u52.Q52();var x66=629058;var J66=591304;var b36="amd";var u36=1449701135;var M96=405746345;var M66=717080;var L66=673724;var M36=1583111106;var a36=1741849621;var F66=837748;var o66=696732;var f96=711130908;var T36=1065762552;var Y1=-T36,j1=-f96,f1=u36,O1=-a36,c1=-M96,F1=M36;if(u52.Q1(G2CC[313785],G2CC[539444],M66) === Y1 || u52.h1(G2CC[313785],G2CC[539444],o66) === j1 || u52.h1(G2CC[313785],G2CC[539444],x66) === f1 || u52.h1(G2CC[313785],G2CC[539444],J66) === O1 || u52.h1(G2CC[313785],G2CC[539444],F66) === c1 || u52.h1(G2CC[313785],G2CC[539444],L66) === F1){if(typeof define === G2CC[444023] && define[b36]){define(['jquery','datatables.net'],function($){u52.Q52();return factory($,window,document);});}else if(typeof exports === G2CC[146202]){module.exports=function(root,$){if(!root){root=window;}if(!$ || !$.fn.dataTable){$=require('datatables.net')(root,$).$;}u52.m52();return factory($,root,root.document);};}else {factory(jQuery,window,document);}}})(function($,window,document,undefined){'use strict';var h52=G2CC;var Z8R="children";var q2b="isMultiValue";var F06="().e";var N0P="value";var Y06="on";var N86='March';var q1P="_cl";var L56="
    ";var Z86='close';var S06="row(";var t26=25;var c9R="name";var w06="delet";var I86="Create new entry";var L9R="valFromData";var x9b="Er";var h9P="hide";var R1R="attachFields";var L1G="_jumpToFirst";var U2b="_show";var w86='June';var A56=">";var B46="DTE_Fie";var S3P="or";var W8P="pu";var n6P="nod";var n86="k";var h0b="ue";var B1b="iv>";var d5R="os";var J3P="rce";var m6R='create';var p76='Wed';var F7b="1";var B9R="ng";var K6R="di";var n8P="tto";var G56="iv class=\"DT";var o9R="er";var P06="().";var B26=50;var i56="xtend";var w6b='submitComplete';var r0R="height";var i4R="wrappe";var V56="-noEdit";var R16=13;var s9R="ngt";var h2P="buttons";var l7b='upload.editor';var C96=993045;var w1G="prot";var u0R="ba";var t56="da";var e0P="pro";var A6R='edit';var e46="rm_Inf";var A1G="editor";var i06="ex";var O56="DTE_Bu";var O5P="fieldErrors";var p56="Table";var o4P="split";var D5b="_lastSet";var d76="ngs";var y1R="attach";var S5R="detach";var X6P='json';var w6P="then";var q5b="_edi";var t1b="submi";var p5R="ma";var R56="ul";var b06="ter";var t86="=\"_blank\" href=\"//datatables.net/tn/12\">More information).";var f6R="se";var T06="en";var G3P="ray";var N2P="_fieldNames";var A06="le";var H6b="_ajax";var D56="
    ";var U1R="isArray";var i0G="itl";var z1b="pp";var R3P="join";var u46="DTE_";var u4P="indexOf";var I0R="ope";var G3R="DTE_Label_Info";var r0P="eUp";var u2b="tiValue";var R5P="addCla";var j0R="appe";var j7R="s=\"";var j6R="funct";var y3R="ra";var T2b="update";var F2R="elds";var e3R="DTE_Label";var y5P="removeClass";var Z6P='POST';var G1b='>';var I76="_fnExtend";var W8b="ton";var U8b="_picker";var W96=810860871;var f46="ged";var t1G="select";var q8R="eld";var u5R="style";var R1G="otype";var u76="st";var Y2R='row';var m06="sel";var l8P="closeCb";var G8b="momentLocale";var D3R="DTE_Footer";var q1R="editField";var r6b="_submitTable";var v0R="ppe";var p9b="cr";var A86='Editor requires DataTables 1.10.20 or newer';var r06="rows().edi";var n0R="dom";var f56="TE ";var J76='action';var m1P="eq";var R76="ig";var B1G="DataTable";var W6R="draw";var q6P="sage";var Z46="b";var n3R="v";var Q5R="i18n";var F0G='selectedSingle';var c46="inute";var C8R="ss";var G9P="U";var F8R="mode";var U1b="width";var j76="ts";var t3R="toArray";var N0b='';var v76="Api";var V3G="i1";var M86='DT_RowId';var S86='August';var k3R="DTE_Processing_Indicator";var a1R="ngth";var J0R='maxHeight';var h86="Edit";var G3b="n>";var u6b="_noProcessing";var c5b="optionsPair";var F3R='
    ';var W56="E_Acti";var b86='Mon';var y7P="trigger";var a76="ject";var p3b="one";var N56="ne_But";var N76="set";var d2R="rc";var u8R="sses";var s06="ingle";var i1b='inline';var V16=15;var N9R="ach";var j2P="includeFields";var P46="ar";var x5R="th";var Y9R="html";var V6P="pend";var X4b="emp";var F4b="_preChecked";var X1P="title";var h3P="_posto";var g5R="fset";var b2R="any";var Z2R="ap";var p86="A system error has occu";var D86='submit';var k0G="formMessage";var o0R="ck";var z76="length";var y4P="mes";var c86='Next';var f8P="iI";var k0P="ocus";var T1R="remove";var b8R="j";var K5R="top";var w0b="put";var M1R="ength";var U0R="content";var F1R="keys";var C4b="arat";var x76="\"";var U2R="fields";var E2b="own";var W06="e()";var a0b="_i";var J7b="ner";var Y56="e_Liner";var P8R="multi";var s86="dataTable";var M6b="editCount";var g0P="ini";var O0P="isAr";var O1P="cus";var P6P="tion";var e7R="it";var K3R="DTE_Field_Message";var T3R="gt";var a3R="DTE_Action_Edit";var H46="The selected items ";var J56="Tab";var V36="e";var i9P="displayed";var S8R="order";var x5b="multiple";var q6b="apply";var x7R="Objec";var M46="dy_Con";var w4G="Da";var T0b="_enabled";var B56="aTable";var W6P="isPl";var g1G='<';var I06="tt";var v16=2;var r6P="play";var D06="edit";var s1b=" ";var k3b="dr";var P2R="isPlainObject";var N46="Jan";var A46="E_Fi";var C3R="isA";var j86="Are you sure you wish to delete 1 row?";var h1P="los";var a5R='div.DTED_Lightbox_Content_Wrapper';var o3R="btn";var e5R="display";var c76="ur";var c0R="cli";var i1P='">
    ';var b0R="rap";var B3b="inpu";var o76="ring";var n76='';var g06="d";var D0P="but";var m5b="t>";var U3R="DTE_Field_InputControl";var x1P="formError";var L2P="form";var W6b="_pr";var j5R="sC";var x1R="error";var r56="cator";var w9R="me";var e7b="class=\"";var R46="is input to the same value, click or tap here, otherwise they will retain their individual values.";var h6P='enable';var r3G='xhr.dt';var U46="DTE_Bo";var r4P="mess";var T4P="sA";var y8P="_even";var o56="elope_Close\">';var l26=20;var r6R="ne";var g76='_basic';var D1P="nf";var M56="
    ";var K8P="li";var f5b="npu";var N8R="editFields";var V8R="ax";var v8P="ing";var I2R="pus";var i46="lue";var S5P="_eve";var E5b="optio";var v8R="der";var t0P="ove";var y6P="clos";var I1R="in";var f4P='&';var l56="f";var I7R="appen";var w46="y";var p2R="displayFields";var g3R="key";var w8P="Se";var d8R="multiReset";var u8b="mome";var b46="Multiple v";var F5b="alue";var c1P="focus";var p46="mult";var n36=1109897088;var d4R="lo";var D4b="np";var s5R="wrap";var H8b="noFileText";var O5b="empty";var X5R="con";var d86='April';var g7R="submit";var b1R="get";var C06="o";var B2P="bm";var x4b="prop";var v46=", but not part of a group.";var o2R="co";var l1R="ass";var z7b="dt";var k46="DTE";var Y3R="DTE DTE_Inline";var O6P="Fiel";var V4R="op";var o06="ns";var J06="exte";var O0G="editSingle";var u4R="conf";var V2P="modifier";var q3R="DTE_Field";var z5R="off";var x46="T";var t4R='
    ';var T76="extend";var S8b="_v";var f06="ate";var B2R="nline";var l76='Thu';var l06="E";var E76='Hour';var Z56="iv class=\"DTED_Lightbox_Container";var d9P="formOptions";var X1R="edi";var Y0R="of";var k1P="appendTo";var w2P="_dis";var Z4b="fin";var n56="';var F9b="emo";var s46="_Fiel";var P4R="end";var S5b='_';var Y4P="Of";var i76='Second';var X56="\">";var G4R="_animate";var m3P="formInfo";var G9R="len";var l4R='
    ';var t6R="rowIds";var J9R="ht";var K1P="ni";var w4R="bo";var A5P="A";var X86='blur';var T9P="_c";var w3P="_focus";var W0b="I";var o6R='remove';var k5P="tend";var S7P="parents";var j1R="row";var c9P="line";var R8P="ult";var t1P='
    S16);var isNode=typeof identifier === G2CC[146202] && identifier[c1R] || identifier instanceof $;var prevDisplayFields,prevAttach,prevAttachFields;if(Object[F1R](fields)[h9]){var f9=N1R;f9+=d1R;f9+=P1R;f9+=U06;var j9=Z1R;j9+=B06;j9+=w1R;j9+=y76;var Y9=W1R;Y9+=g56;Y9+=S1R;if(out[idSrc]){var a9=v1R;a9+=B86;a9+=H1R;var z9=Z1R;z9+=r1R;z9+=U06;prevAttach=out[idSrc][y1R];prevAttachFields=out[idSrc][z9];prevDisplayFields=out[idSrc][a9];}__dtRowSelector(out,dt,idx[j1R],allFields,idFn);out[idSrc][R1R]=prevAttachFields || [];out[idSrc][Y9][h76](Object[F1R](fields));out[idSrc][j9]=prevAttach || [];out[idSrc][y1R][h76](isNode?$(identifier)[b1R](G2CC[313785]):cell[V1R]?cell[V1R]():cell[D1R]());out[idSrc][p2R]=prevDisplayFields || ({});$[T76](out[idSrc][f9],fields);}});};var __dtColumnSelector=function(out,dt,identifier,fields,idFn){var l2R="dexes";var O9=I1R;O9+=l2R;dt[t2R](o86,identifier)[O9]()[Q76](function(idx){__dtCellSelector(out,dt,idx,fields,idFn);});};var dataSource$1={id:function(data){var idFn=dataGet(this[U06][C2R]);return idFn(data);},fakeRow:function(insertPoint){var m2R='
    ","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n(" + @endforeach + @endif +
    + + + + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/MFOrders.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/MFOrders.blade.php new file mode 100755 index 00000000..865471c2 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/MFOrders.blade.php @@ -0,0 +1,92 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - Manifest Orders +@endsection +@section('content') +
    +

    Manifest Orders

    +
    +
    + @php + $fullUrl = Request::url(); + $UrlPath = Request::path(); + $sendUrl = str_replace($UrlPath, "", $fullUrl); + @endphp +
    + Manifest # + {{ $MF }} + Carrier: {{ $carrier }} +
    +
    +
    + + + + + + + + + + + + + + @foreach($ICM695M1 as $key=>$val) + @php + $A4PICKSTSTMP = isset($val->A4PICKSTS) ? trim($val->A4PICKSTS) : ""; + $A4PICKSTS = $A4PICKSTSTMP!="" && isset($status_ICM688M1_array[trim($val->A4PICKSTS)]) ? + $status_ICM688M1_array[trim($val->A4PICKSTS)] : ""; + @endphp + + + + + + + + + @endforeach + +
    Delivery noteOrder NumberCustomerSentinel Picker StatusTotal weightBoxes/pallets
    + + {{ $val->AYMACPKR }} + + {{ $val->AYONO }} {{ $val->A4SHSHNM }} {{ $A4PICKSTS }} {{ number_format($val->TOTWEIGHT, 2) }} {{ $val->BOXPAL }}
    +
    +
    + +
    + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/OrderLinesOfClosed.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/OrderLinesOfClosed.blade.php new file mode 100755 index 00000000..ca5d20dc --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/OrderLinesOfClosed.blade.php @@ -0,0 +1,320 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Closed order lines report +@endsection +@section('content') +
    +

    Closed order lines report

    + +
    +
    +
    +
    + +
    + @php + $REPORTDATEDisp = old('REPORTDATEDisp') ?? \DateTime::createFromFormat('Ymd',$REPORTDATEDisp)->format('Y-m-d'); + @endphp +
    + + +
    + +
    + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    + +
    +
    + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + {{-- + --}} + + + + + + + @foreach($ICM688M2 as $key=>$ICM688M2R) + + + + + + + + + + + + + + + + + + + {{-- + --}} + + + + + @endforeach + + + + + + + + {{-- --}} + + + +
    +
    Close DateDelivery #Order #TermsWeightCarrierModeOrder TypePart #ReservedPackedBack Order QtyValue Packed $Customer nameDateTimeFailure ReasonCurrency CodeFreight
    {{ $ICM688M2R->SHDT }} {{ $ICM688M2R->SHTIME }} {{ $ICM688M2R->A5MACPKR }} {{ $ICM688M2R->A5ONO }} {{ $ICM688M2R->A4OFSTRM }} {{ number_format($ICM688M2R->WEIGHT, 2, '.', ',') }} {{ $ICM688M2R->A4SCAC }} {{ $ICM688M2R->A4SHIPTYPE }} {{ $ICM688M2R->A4REFORD }} {{ $ICM688M2R->A5PART }} {{ number_format($ICM688M2R->A5RSVQTY, 0, '.', ',') }} {{ number_format($ICM688M2R->A5PACKED, 0, '.', ',') }} {{ number_format($ICM688M2R->CALCULATED_COLUMN, 0, '.', ',') }} {{ number_format($ICM688M2R->ANOTHER_CALCULATED_COLUMN, 2, '.', ',') }}{{ $ICM688M2R->A4SHSHNM }} {{ $ICM688M2R->SHDT }} {{ $ICM688M2R->SHTIME }} {{ substr($ICM688M2R->REASON,0,150) }} {{ $ICM688M2R->A1SHCURR }} {{ $ICM688M2R->FREIGHT }}
    Total:
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + @php + $todayDate = today()->format('Ymd'); + $reportDate = old('REPORTDATE') ?? \DateTime::createFromFormat('Ymd',$todayDate)->format('Y-m-d'); + $toreportDate = old('TOREPORTDATE') ?? \DateTime::createFromFormat('Ymd', $todayDate)->format('Y-m-d'); + @endphp +
    + + +
    +
    + + + +
    +
    + + {{-- MAK Used temporarly to generate report on AS400 --}} + {{-- --}} +
    +
    +
    + {{-- Form for Export --}} +
    + @csrf + + +
    + {{-- Form for Saving Excel --}} +
    + @csrf + + +
    +
    +
    + @foreach ($allReportsUrls as $fileName=>$reportsUrl) + @php + $fileNameOnly = strpos($fileName, '/')!= false ? substr($fileName, strpos($fileName, '/') + 1) : $fileName; + @endphp + $fileName]) }}' >{{ $fileNameOnly }}
    + @endforeach +
    +
    + {{-- @foreach ($allReportsUrls as $fileName=>$reportsUrl) + @php + $fileNameOnly = strpos($fileName, '/')!= false ? substr($fileName, strpos($fileName, '/') + 1) : $fileName; + @endphp + $fileName]) }}' >{{ $fileNameOnly }}
    + @endforeach --}} +
    +
    +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ReplenishSettings.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ReplenishSettings.blade.php new file mode 100755 index 00000000..874da3fd --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ReplenishSettings.blade.php @@ -0,0 +1,605 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - Replenishment Settings Update +@endsection +@section('content') + +
    +

    Replenishment Settings

    + +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + {{-- @foreach ($REFCAT658 as $key => $val) + + + + + + + + + + + + + + + @endforeach --}} + +
    DivisionPlantWarehouseLocationPartMinimum qtyReplenishment qtyToleranceReplenishment min qtyLot Controlled
    {{ $val->R658CO }} {{ $val->R658PL }} {{ $val->R658WH }} {{ $val->R658LC }} {{ $val->R658PN }} {{ $val->R658MQ }} {{ $val->R658RQ }} {{ $val->R658TL }} {{ $val->R658RMQ }} + {!! ($val->R658IZLCF ?? '')=='1' ? '' :'' !!} + + + +
    +
    +
    +
    + +
    + + + + + + + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/WhsPerfMetrics.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/WhsPerfMetrics.blade.php new file mode 100755 index 00000000..0dd2eb2a --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/WhsPerfMetrics.blade.php @@ -0,0 +1,84 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Warehouse Performance Metrics report +@endsection +@section('content') +
    +

    Warehouse Performance Metrics report

    +
    +
    +
    +
    + @php + // $REPORTDATEDisp = old('REPORTDATEDisp') ?? \DateTime::createFromFormat('Ymd',$REPORTDATEDisp)->format('Y-m-d'); + @endphp + {{--
    + + +
    --}} + +
    + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    + {{-- --}} +
    +
    +
    +
    +
    + @foreach ($allReportsUrls as $fileName=>$reportsUrl) + @php + $fileNameOnly = basename($fileName); + @endphp + $fileName]) }}' >{{ $fileNameOnly }}
    + @endforeach +
    +
    +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/carrierMaint.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/carrierMaint.blade.php new file mode 100755 index 00000000..c8370074 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/carrierMaint.blade.php @@ -0,0 +1,406 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - Carrier Master Maintenance +@endsection +@section('content') + +
    +

    Carrier Master Maintenance

    + +
    +
    + @if(isset($power_user[0]) && trim((string) ($power_user[0]->R428PWRUSR ?? '')) === 'Y') + + @endif + +
    + +
    +
    + + + + + + + + + + + + + + + @foreach($ICM160M as $key=>$val) + + + + + + + + + + + @endforeach + + +
    SCAC CodeCarrier name2ship Carrier CodeParcel Carrier CodeERP Carrier CodeTiming of M3 closing
    + @if(isset($power_user[0]) && trim((string) ($power_user[0]->R428PWRUSR ?? '')) === 'Y') + + @endif + {{ $val->CANUM }} {{ $val->CANAM }} {{ $val->TWOSHIPCARRIERCODE }} {{ $val->PARCELCARRIERCODE=="X"?"Parcel":"" }} {{ $val->CASPR10A01 }} {{ $val->CASPR1A01=="Y"?"When closing truck":"" }}
    +
    +
    +
    + +
    + + + @include('m3::liberty-theme.partials.modals.carrierAdd') + @include('m3::liberty-theme.partials.modals.carrierEdit') + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/dashboard.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/dashboard.blade.php new file mode 100755 index 00000000..13bd9e63 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/dashboard.blade.php @@ -0,0 +1,39 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Sentinel API +@endsection +@section('content') +
    +

    Dashboard

    +
    +
    +
    +
    + + Last 7 days of picking DEMO DATA +
    +
    +
    +
    +
    +
    +
    + + Last 12 month of invoice DEMO DATA +
    +
    +
    +
    +
    +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/execSummary.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/execSummary.blade.php new file mode 100755 index 00000000..1ef5a25a --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/execSummary.blade.php @@ -0,0 +1,518 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Exec Summary +@endsection + +{{-- Flat Picker CSS --}} + + + +@section('content') +
    +

    Exec Summary

    +
    +
    +
    + {{--
    --}} +
    +
    + {{-- Selectors --}} +
    +
    +
    Sales / Weight / Lines
    + + {{-- Warehouses --}} +
    +
    + @foreach ($IC670M as $key => $IC670MR) + @php $currentWHDDA = trim($IC670MR->WDCO).trim($IC670MR->WDPL).trim($IC670MR->WDWHS); @endphp +
    + + +
    + @endforeach +
    +
    + +
    + + {{-- Report Period --}} +
    +
    + + + + + + + + + + + +
    +
    + +
    + + {{-- From To Dates --}} +
    + @php + $todayDate = today()->format('Ym'); + $reportDate = \DateTime::createFromFormat('Ym', $todayDate) + ->modify('first day of January last year') + ->format('Y-m'); + $toreportDate = \DateTime::createFromFormat('Ym', $todayDate)->format( + 'Y-m', + ); + @endphp +
    + {{--
    --}} +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + {{--
    --}} +
    +
    + +
    + + {{-- Sales Weight Lines --}} +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + + + + +
    +
    + {{-- Charts --}} +
    +
    + +
    +
    + +
    + +
    +
    + +
    + +
    +
    +@endsection + +@section('scripts') + {{-- Chart JS --}} + + + + + + + + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/execSummaryLine.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/execSummaryLine.blade.php new file mode 100755 index 00000000..16c77585 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/execSummaryLine.blade.php @@ -0,0 +1,992 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Exec Summary - Line Chart +@endsection + +{{-- Flat Picker CSS --}} + + + +@section('content') +
    +

    Exec Summary - Line Chart

    +
    +
    +
    + {{--
    --}} +
    +
    + {{-- Selectors --}} +
    +
    +
    Sales / Weight / Lines
    + + {{-- Warehouses --}} +
    +
    + @foreach ($IC670M as $key => $IC670MR) + @php $currentWHDDA = trim($IC670MR->WDCO).trim($IC670MR->WDPL).trim($IC670MR->WDWHS); @endphp +
    + + +
    + @endforeach +
    +
    + +
    + + {{-- Report Period --}} +
    +
    + + + + + + + + + + + +
    +
    + +
    + + {{-- From To Dates --}} +
    + @php + $todayDate = today()->format('Ym'); + $reportDate = \DateTime::createFromFormat('Ym', $todayDate) + ->modify('first day of January last year') + ->format('Y-m'); + $toreportDate = \DateTime::createFromFormat('Ym', $todayDate)->format( + 'Y-m', + ); + @endphp +
    + {{--
    --}} +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + {{--
    --}} +
    +
    + +
    + + {{-- Sales Weight Lines --}} +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + + + + +
    +
    + {{-- Charts --}} +
    +
    + +
    +
    + +
    + +
    +
    + +
    + +
    +
    +@endsection + +@section('scripts') + {{-- Chart JS --}} + + + + + + + + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/exedashboard.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/exedashboard.blade.php new file mode 100755 index 00000000..ffc6cfbf --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/exedashboard.blade.php @@ -0,0 +1,278 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal +@endsection +@section('content') +
    +

    Executive Dashboard

    + +
    +
    + + Filters +
    +
    +
    + +
    + @csrf + +
    + +
    + + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + @foreach($data as $key=>$value) +
    +
    +
    + + {{($key=="IC")?'INTERCO':'EXTERNAL'}} +
    +
    + +
    +
    +
    + +
    +
    +
    + @endforeach +
    + + +
    + @foreach($data as $key=>$value) +
    +
    +
    {{($key=="IC")?'INTERCO':'EXTERNAL'}} $ {{ number_format($data[$key]['total'], 0, '.', ',') }}
    +
    + Held: $ {{ number_format($data[$key]['HLD'], 0, '.', ',') }}
    +   ┗ Financial Hold: $ {{ number_format($data[$key]['FinHld'], 0, '.', ',') }}  ($ {{ number_format($data[$key]['FinFutHld'], 0, '.', ',') }} is >{{env('FDATE')}} in future)
    +   ┃  ┗ Reserved On Pick: $ {{ number_format($data[$key]['FHResPick'], 0, '.', ',') }}
    +   ┃  ┗ Reserved No Pick: $ {{ number_format($data[$key]['FHResNoPick'], 0, '.', ',') }}
    +   ┃  ┗ Not reserved: $ {{ number_format($data[$key]['FHNres'], 0, '.', ',') }}
    +   ┗ Customer Hold: $ {{ number_format($data[$key]['CusHld'], 0, '.', ',') }}  ($ {{ number_format($data[$key]['CusFutHld'], 0, '.', ',') }} is >{{env('FDATE')}} in future)
    +   ┃  ┗ Reserved On Pick: $ {{ number_format($data[$key]['CHResPick'], 0, '.', ',') }}
    +   ┃  ┗ Reserved No Pick: $ {{ number_format($data[$key]['CHResNoPick'], 0, '.', ',') }}
    +   ┃  ┗ Not reserved: $ {{ number_format($data[$key]['CHNres'], 0, '.', ',') }}
    + Avail: $ {{ number_format($data[$key]['Avail'], 0, '.', ',') }}  ($ {{ number_format($data[$key]['futNH'], 0, '.', ',') }} is >{{env('FDATE')}} in future)
    +   ┗  ┗ Reserved On Pick: $ {{ number_format($data[$key]['AvResPick'], 0, '.', ',') }}
    +   ┗  ┗ Reserved No Pick Fill Code 1: $ {{ number_format($data[$key]['AvResNoPickFillCode1'], 0, '.', ',') }}
    +   ┗  ┗ Reserved No Pick: $ {{ number_format($data[$key]['AvResNoPick'], 0, '.', ',') }}
    +   ┗ Not reserved: $ {{ number_format($data[$key]['AvUNres'], 0, '.', ',') }}
    + No Early: $ {{ number_format($data[$key]['NoE'], 0, '.', ',') }} +
    +
    +
    + @endforeach +
    +@endsection + +@section('scripts') + + + + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/fillBOL.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/fillBOL.blade.php new file mode 100755 index 00000000..01476aca --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/fillBOL.blade.php @@ -0,0 +1,59 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Fill BOL PDF +@endsection +@section('content') +
    +

    Fill BOL

    +
    +
    +
    + +
    + @if(session('success')) +
    + {{ session('success') }} +
    + @endif + + @if(session('error')) +
    + {{ session('error') }} +
    + @endif + +
    + @csrf +
    + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    +
    +
    +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/fillBOL2.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/fillBOL2.blade.php new file mode 100755 index 00000000..fbb80370 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/fillBOL2.blade.php @@ -0,0 +1,59 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Fill BOL PDF +@endsection +@section('content') +
    +

    Fill BOL 2

    +
    +
    +
    + +
    + @if(session('success')) +
    + {{ session('success') }} +
    + @endif + + @if(session('error')) +
    + {{ session('error') }} +
    + @endif + +
    + @csrf +
    + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    +
    +
    +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/logout.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/logout.blade.php new file mode 100755 index 00000000..0f690eee --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/logout.blade.php @@ -0,0 +1,51 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Logout +@endsection +@section('btn') +@endsection +@section('content') +
    +

    Logout

    +
    + You will be logged out in a few seconds. +
    +
    +@endsection +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/orderInquiry.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/orderInquiry.blade.php new file mode 100755 index 00000000..3faef7f7 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/orderInquiry.blade.php @@ -0,0 +1,55 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - Order Inquiry +@endsection +@section('breadcrumb') +
    +
    + +
    +@endsection +@section('content') + +
    +

    Order Inquiry

    + +
    +
    + + +
    +
    +
    + +
    + @csrf + +
    +
    + + + + + +
    +
    +
    + +
    +
    +
    + +
    +@endsection + +@section('scripts') +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReq.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReq.blade.php new file mode 100755 index 00000000..1c6a417e --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReq.blade.php @@ -0,0 +1,171 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - Orders On Hold Summary +@endsection +@section('breadcrumb') +
    +
    + +
    +@endsection +@section('content') + +
    +

    Orders on hold

    + +
    +
    + + Filters +
    +
    +
    + +
    + @csrf + +
    +
    + + @foreach($whs_list as $key => $val) + + +SLSRWH, $checked_whs)) checked @endif + > {{ $val->SLSRWH }}       + @endforeach + +
    +
    +
    + +
    +
    +
    + +
    +
    + + List of hold codes +
    +
    +
    + + + + + + + + + + + + + @foreach($data as $key=>$value) + + + + + + + + + @endforeach + + + + + + + + + + + +
    +
    ReasonNo of OrdersTotalTotal for subsetReserved for subsetOn pick for subset
    SHHLDC) }}"> + {{ ( $value->SHHLDC == ' ' ? "Not On Hold" : $value->SHHLDC . " - " . $hold_code_array[$value->SHHLDC] ) }}{{ (isset($value->NBORDERS))?$value->NBORDERS:'' }}$ {{ number_format((float)$value->TOTAL, 2, '.', ',') }}$ {{ number_format((float)$value->TOTALWH, 2, '.', ',') }}$ {{ number_format((float)$value->TOTALWHRESERVED, 2, '.', ',') }}$ {{ number_format((float)$value->TOTALWHONPICK, 2, '.', ',') }}
    + +
    +
    +
    +
    +@endsection + +@section('scripts') + + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReqOrder.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReqOrder.blade.php new file mode 100755 index 00000000..b27664ca --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReqOrder.blade.php @@ -0,0 +1,407 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - ordersOnHoldReq +@endsection +@section('breadcrumb') +
    +
    + +
    +@endsection +@section('content') + +
    +

    Orders

    +
    +
    + +
    +
    +
    +
    +
    @include('m3::liberty-theme.partials.tabs.orders')
    +
    @include('m3::liberty-theme.partials.tabs.details')
    +
    @include('m3::liberty-theme.partials.tabs.comments')
    +
    +
    +
    +
    +
    + + + @include('m3::liberty-theme.partials.modals.blank') + @include('m3::liberty-theme.partials.modals.shipToEdit') + @include('m3::liberty-theme.partials.modals.shipToCheckBox') +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReqReason.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReqReason.blade.php new file mode 100755 index 00000000..d3e7eba0 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ordersOnHoldReqReason.blade.php @@ -0,0 +1,85 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - ordersOnHoldReq +@endsection +@section('breadcrumb') +
    +
    + +
    +@endsection +@section('content') + +
    +

    Orders on hold

    +
    +
    + + List of orders +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    Order NoStatusOrder DateComment DateComment Due DateSales RepCarrierShip ViaShipToOrder ValueReserved ValueOn Pick ValueCurrency
    +
    +
    +
    +
    + +@endsection + +@section('scripts') + + + + + @endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/palletQty.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/palletQty.blade.php new file mode 100755 index 00000000..0770e46d --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/palletQty.blade.php @@ -0,0 +1,316 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - ERP/TMS Part Data +@endsection +@section('content') + +
    +

    ERP/TMS Part Data

    + +
    +
    + @if($power_user->R428PWRUSR=="Y") + + @endif + +
    + +
    +
    + + + + + + + + + + + + + @foreach($ICM709M as $key=>$val) + + + + + + + + + @endforeach + + +
    Div-Plt-WhsPartPallet QtyHazardous Material
    + @if($power_user->R428PWRUSR=="Y") + + @endif + {{ $val->AT9CO }} {{ $val->AT9PLT }} {{ $val->AT9WHS }} {{ $val->AT9PART }} {{ $val->AT9QTY }} {{ trim($val->AT9WRN) }}
    +
    +
    +
    + +
    + + + @include('m3::liberty-theme.partials.modals.qtyAdd') + @include('m3::liberty-theme.partials.modals.qtyEdit') + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/pendingClosure.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/pendingClosure.blade.php new file mode 100755 index 00000000..8f082178 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/pendingClosure.blade.php @@ -0,0 +1,292 @@ + +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - Trucks pending closure with M3 +@endsection +@section('content') + +
    +

    Trucks pending closure with M3

    + +
    +
    + + The trucks will be closed automatically at 6pm daily. But you can initiate the close earlier by clicking on the manifest number + @if($ICM699M[0]->COUNT1>0) +

    There are + {{$ICM699M[0]->COUNT1}} closing delivery order errors pending review

    + @endif + @if(count($unprocessedArr)>0) + @php $unprocessedMan = implode(', ', $unprocessedArr); @endphp +

    Manifests: {!! $unprocessedMan !!} have some orders that still have a header picking status of B, and may not have closed in M3. Please investigate + @endif + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + @foreach($ICM705M1 as $key=>$val) + @php + $closeinRed = false; + $APLDCLOD = trim($val->APLDCLOD)!="0" ? date('Y-m-d', strtotime($val->APLDCLOD)) : ""; + $APLDCLOT = trim($val->APLDCLOT)!="0"?(strlen($val->APLDCLOT)==6?date('H:i:s', strtotime($val->APLDCLOT)):date('H:i:s', strtotime('0'.$val->APLDCLOT))):""; + # Get current time as a timestamp + $currentTime = time(); + $APLDCLOZ = trim($val->APLDCLOZ)!="0" ? strtotime($val->APLDCLOZ) : ""; + # Calculate the difference in minutes + if ($APLDCLOZ!='') { + $minutesDiff = round(abs($currentTime - $APLDCLOZ) / 60); + $closeinRed = $minutesDiff <15 ? true : false; + } + $closeInRedClass = $closeinRed ? ' class=text-danger ' : '' ; + + # Get In process Manifests with delay > 3 hours + $ManifestDelayed = false; + if ($val->APSPARE2=="P") { + $SHDT = isset($ICM699Ma[$val->APMANIFEST]['SHDT']) ? $ICM699Ma[$val->APMANIFEST]['SHDT'] : ''; + $SHTIME = isset($ICM699Ma[$val->APMANIFEST]['SHTIME']) ? $ICM699Ma[$val->APMANIFEST]['SHTIME'] : ''; + // dump($val->APMANIFEST."-".$SHDT."-".$SHTIME); + if ($SHDT!='' && $SHTIME!='') { + $specifiedDateTime = new \DateTime($SHDT . " " . $SHTIME); + $currentDateTime = new \DateTime(); + # Calculate total hours + $totalHours = $specifiedDateTime->diff($currentDateTime)->days * 24 + $specifiedDateTime->diff($currentDateTime)->h; + // dump("Total Hours: " . $totalHours); + if ($totalHours > 3) { + $ManifestDelayed = true; + } + } + } + @endphp + + + + {{-- MAK Show Retry Message instead of Contact MPBA --}} + + + + + + + + + + + + + + + + @endforeach + +
    ManifestStatusDock doorCarrierTruck IDTypeUser openDate openTime openTMS
    User close
    TMS
    Date close
    TMS
    Time close
    Sentinel
    User close
    Sentinel
    Date close
    Sentinel
    Time close
    + {{-- Link to Manifest Orders --}} + @if( $val->APMANIFEST!="0" ) + + {{ trim($val->APMANIFEST)!="0"?$val->APMANIFEST:"" }} + + @endif + {{-- Close Button --}} + @if( ($val->APMANIFEST!="0" && $val->APSPARE2!="P" && trim($val->APLDCLOD)!="") && !$closeinRed) + + @elseif($val->APSPARE2=="P") + {{ trim($val->APMANIFEST)!="0" ?$val->APMANIFEST : "" }} + @endif + {!! $val->APSPARE2=="P" && !$ManifestDelayed ? "In Process" : + ( $val->APSPARE2=="P" && $ManifestDelayed ? + '' + : '') + !!} + {{ $val->APDOCKDOOR }} {{ $val->APCARRIER }} {{ $val->APTRUCKIDT }} {{ $val->APSPARE1 }} {{ $val->APLDSTRU }} {{ date('Y-m-d', strtotime($val->APLDSTRD)) }} {{ strlen($val->APLDSTRT)==6 ? date('H:i:s', strtotime($val->APLDSTRT)):date('H:i:s', strtotime('0'.$val->APLDSTRT)) }} {{ isset($ICM698Ma[$val->APMANIFEST])?$ICM698Ma[$val->APMANIFEST]['TMSUSER']:"" }} {{ trim($ICM698Ma[$val->APMANIFEST]['TMSDATE'])!=""?date('Y-m-d', strtotime($ICM698Ma[$val->APMANIFEST]['TMSDATE'])):"" }} {{ trim($ICM698Ma[$val->APMANIFEST]['TMSTIME'])!=""?(strlen($ICM698Ma[$val->APMANIFEST]['TMSTIME'])==6?date('H:i:s', strtotime($ICM698Ma[$val->APMANIFEST]['TMSTIME'])):date('H:i:s', strtotime('0'.$ICM698Ma[$val->APMANIFEST]['TMSTIME']))):"" }} {{ $val->APLDCLOU }} {{ $APLDCLOD }} {{ $APLDCLOT }}
    + +
    +
    +
    +
    + +
    +
    View closed manifest
    + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ship-to/create.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ship-to/create.blade.php new file mode 100755 index 00000000..d2239b63 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ship-to/create.blade.php @@ -0,0 +1,101 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Add: Distribution whs addresses +@endsection +@section('content') + +
    +

    Add: Distribution whs addresses

    +
    +
    +
    + {{--
    +

    Add Ship-to Address

    +
    --}} +
    + @if ($errors->any()) +
    +
      + @foreach ($errors->all() as $error) +
    • {{ $error }}
    • + @endforeach +
    +
    + @endif + +
    + @csrf +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + Cancel +
    +
    +
    +
    +
    +
    +
    +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ship-to/edit.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ship-to/edit.blade.php new file mode 100755 index 00000000..2bbe928b --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ship-to/edit.blade.php @@ -0,0 +1,100 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Edit Distribution whs addresses +@endsection +@section('content') +
    +

    Edit Distribution whs addresses

    +
    +
    +
    + {{--
    +

    Edit Ship-to Address

    +
    --}} +
    + @if ($errors->any()) +
    +
      + @foreach ($errors->all() as $error) +
    • {{ $error }}
    • + @endforeach +
    +
    + @endif + +
    + @csrf + @method('PUT') + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + Cancel +
    +
    +
    +
    +
    +
    +
    +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/ship-to/index.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/ship-to/index.blade.php new file mode 100755 index 00000000..b9dce947 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/ship-to/index.blade.php @@ -0,0 +1,107 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Distribution whs addresses +@endsection +@section('content') +
    +

    Distribution whs addresses

    + +
    +
    +
    +
    + {{--

    Ship-to Addresses

    --}} + Add New +
    +
    + @if (session('success')) +
    + {{ session('success') }} +
    + @endif +
    + + + + + + + + + + + + + + + + + + +
    Customer NumberCompany NameAddressCityStateZipCountryWarehouseAction
    +
    + +
    +
    +
    +
    +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/userControl.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/userControl.blade.php new file mode 100755 index 00000000..c837cd8e --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/userControl.blade.php @@ -0,0 +1,1423 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - User Control +@endsection +@section('content') + +
    +

    User Control

    + +
    + +
    + @if($power_user[0]->R428PWRUSR=="Y") + + @endif + +
    + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach($ICM428M as $key=>$val) + + + + + + + + + + + + + + + + + + + + + @endforeach + + +
    Div-Plt-WhsPlant nameStatusUser profileFirst nameFamily nameEmpl codeAdmin userPower userCSRExec.Inventory OptionsReplenishmentDocument ReprintsLoadingMain menu
    + @if($power_user[0]->R428PWRUSR=="Y" && trim($val->R428US)!="TWOSHIP" && trim($val->R428US)!="TWOSHIP303" && trim($val->R428US)!="TWOSHIP322") + + @foreach($USER_INFO as $key2=>$val2) + @if(trim($val2->USERPRF)==trim($val->R428US)) + {{-- @if((trim($val2->STATUS)=="*DISABLED") || + (substr($val2->DATE_EXPIRED,0,10)!=NULL && substr($val2->DATE_EXPIRED,0,10)<=date('Y-m-d')) + || trim($val2->EXPIRED=='YES')) --}} + + + @break + {{-- @elseif(trim($val2->STATUS)=="*DISABLED") + + + @break --}} + {{-- @endif --}} + @endif + @endforeach + + + @endif + {{ $val->R428CO }} {{ $val->R428PL }} {{ $val->R428WH }} + @foreach ($IC670M as $key => $IC670MR) + @if($IC670MR->WDCO==$val->R428CO && $IC670MR->WDPL==$val->R428PL && $IC670MR->WDWHS==$val->R428WH) + {{ trim(Str::upper($IC670MR->WDWNAM)) }} + @break + @endif + @endforeach + {{ $val->R428STS=="A"?"Active":"Inactive" }} {{ $val->R428US }} {{ $val->R428FIRST }} {{ $val->R428FAMILY }} {{ $val->R428EMPCDE }} {{ $val->R428ADMUSR }} {{ $val->R428PWRUSR }} {{ $val->R42811A }} {{ $val->R42821A }}
     {{ str_replace("N"," ",$val->MENU2OPT) }} 
     {{ str_replace("N"," ",$val->MENU3OPT) }} 
     {{ str_replace("N"," ",$val->MENU4OPT) }} 
     {{ str_replace("N"," ",$val->MENU5OPT) }} 
     {{ str_replace("N"," ",$val->MENU6OPT) }} 
    +
    +
    +
    + +
    + + @include('m3::liberty-theme.partials.modals.blank') + @include('m3::liberty-theme.partials.modals.userAdd') + @include('m3::liberty-theme.partials.modals.userEdit') + @include('m3::liberty-theme.partials.modals.userPassword') + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats4.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats4.blade.php new file mode 100755 index 00000000..3dc2ce80 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats4.blade.php @@ -0,0 +1,241 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - Daily User Efficiency +@endsection +@section('content') + +
    +

    Daily User Efficiency

    + +
    +
    + + Filters +
    +
    +
    +
    + @csrf +
    + +
    + + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + User Picking Stats +
    +
    + + + + + + + + + + + + + + + + + + + + @if($no_data=="Y") + + @else + @foreach($statistic4 as $key=>$val) + + + + + + + + + + {{ $val->A5ONO }}-{{ $val->A5RLNO }}-{{ $val->A5SHNO }} + + + + + + + @endforeach + @endif + + + + + + + + + + + + + + +
    CodeMonDateHourPick ended atWeight Units PickedPartOrder-Rl-Sh#Cust NameTime (in mins)
    No data retrieved for this user
    {{ $val->CODE }} {{ $val->A5SENTVIEW }} {{ $val->DT }} {{ $val->HOUR }} {{ str_replace(' ','______',$val->A5PICKCMTS) }} {{ number_format($val->WEIGHT,2) }} {{ $val->A4SHSHNM }} {{ number_format($val->TIMEDIFF/60,1) }}  
    Total {{ (isset($totals_array['entries']) ? $totals_array['entries'] : "") }} {{number_format($totals_array['weight'],2)}} {{number_format($totals_array['picked'],0)}} {{number_format($totals_array['timediff']/60,1)}}
    +
    +
    + +
    +
    + + User Picking Stats Summary +
    +
    + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + +
    MonitorTotal {{$key['header']}}
    Picked Weight {{number_format($totals_array['weight'],0)}} {{number_format($key['weight'],0) }}
    Picked Lines {{number_format($totals_array['entries'],0)}} {{number_format($key['lines'],0)}}
    Total in hours (based on Greg time entry){{(isset($perf_array['tot_hours'])?number_format($perf_array['tot_hours'],1):"")}} {{number_format($key['tot_hours'],1) }}
    Percent per activity100% {{number_format($key['percent_per_activity']*100,0)}}%
    LPH contribution per activity {{(isset($monitor_array[0]['lph_blended_per_activity'])?number_format($monitor_array[0]['lph_blended_per_activity'],1):"")}} {{number_format($key['lph_blended_per_activity'],1)}}
    +
    +
    +
    +
    + + User Picking Stats Performance Summary +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Total in hours (based on Greg time entry){{(isset($perf_array['tot_hours'])?number_format($perf_array['tot_hours'],1):"")}}
    Per hour actual{{(isset($perf_array['per_hour_actual'])?number_format($perf_array['per_hour_actual'],1):"")}}
    Blended target for the day{{(isset($monitor_array[0]['lph_blended_per_activity'])?number_format($monitor_array[0]['lph_blended_per_activity'],1):"")}}
    Performance{{(isset($perf_array['performance_activity'])?number_format($perf_array['performance_activity']*100,0):"")}}%
    +
    +
    + +
    + + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats4_old.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats4_old.blade.php new file mode 100755 index 00000000..d1de652e --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats4_old.blade.php @@ -0,0 +1,245 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - userPickingStats v4 +@endsection +@section('content') + +
    +

    User Activity Stats V4

    + +
    +
    + + Filters +
    +
    +
    + +
    + @csrf + +
    + +
    + + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    + + User Picking Stats +
    +
    + + + + + + + + + + + + + + + + + + @if($no_data=="Y") + + @else + @foreach($statistic4 as $key=>$val) + + + + + + + + + + + + + + @endforeach + @endif + + + + + + + + + + + + + + + + +
    MonDateHourPick ended atWeight Units PickedPartOrder-Rl-Sh#Cust NameTime (in mins)
    No data retrieved for this user
    {{ $val->CODE }} {{ $val->DT }} {{ $val->HOUR }} {{ str_replace(' ','______',$val->A5PICKCMTS) }} {{ number_format($val->WEIGHT,2) }} {{ number_format($val->A5PICKED,0) }} {{ $val->A5PART }} + + {{ $val->A5ONO }}-{{ $val->A5RLNO }}-{{ $val->A5SHNO }} + + {{ $val->A4SHSHNM }} {{ number_format($val->TIMEDIFF/60,1) }}  
    Total {{ (isset($totals_array['entries']) ? $totals_array['entries'] : "") }} {{number_format($totals_array['weight'],2)}} {{number_format($totals_array['picked'],0)}} {{number_format($totals_array['timediff']/60,1)}}
    +
    +
    + +
    +
    + + User Picking Stats Summary +
    +
    + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + + + + + @foreach($monitor_array as $key) + @if($key['header']!="0") + + @endif + @endforeach + +
    MonitorTotal {{$key['header']}}
    Picked Weight {{number_format($totals_array['weight'],0)}} {{number_format($key['weight'],0) }}
    Picked Lines {{number_format($totals_array['entries'],0)}} {{number_format($key['lines'],0)}}
    Total in hours (based on Greg time entry){{(isset($perf_array['tot_hours'])?number_format($perf_array['tot_hours'],1):"")}} {{number_format($key['tot_hours'],1) }}
    Percent per activity100% {{number_format($key['percent_per_activity']*100,0)}}%
    LPH contribution per activity {{(isset($monitor_array[0]['lph_blended_per_activity'])?number_format($monitor_array[0]['lph_blended_per_activity'],1):"")}} {{number_format($key['lph_blended_per_activity'],1)}}
    +
    +
    +
    +
    + + User Picking Stats Performance Summary +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Total in hours (based on Greg time entry){{(isset($perf_array['tot_hours'])?number_format($perf_array['tot_hours'],1):"")}}
    Per hour actual{{(isset($perf_array['per_hour_actual'])?number_format($perf_array['per_hour_actual'],1):"")}}
    Blended target for the day{{(isset($monitor_array[0]['lph_blended_per_activity'])?number_format($monitor_array[0]['lph_blended_per_activity'],1):"")}}
    Performance{{(isset($perf_array['performance_activity'])?number_format($perf_array['performance_activity']*100,0):"")}}%
    +
    +
    + +
    + + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats5.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats5.blade.php new file mode 100755 index 00000000..edeb6704 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/userPickingStats5.blade.php @@ -0,0 +1,196 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Solon Sentinel Portal - Graph User Efficiency +@endsection +@section('content') + +
    +

    Graph User Efficiency

    + +
    +
    + + Filters +
    +
    +
    +
    + @csrf +
    + +
    + + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + + Picking Performance +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + User Picking Stats +
    +
    + + + + + + + + + + + + @foreach($statistic5 as $key=>$val) + + + + + + + + @endforeach + + + + + + + + + + +
    DayPerformanceBlended Target LPHActual LPHGross Hours
    {{ (isset($val['day']) ? $val['day'] : "") }} {{ (isset($val['performance']) ? $val['performance'] : "") }} {{ (isset($val['blendedTargetLPH']) ? $val['blendedTargetLPH'] : "") }} {{ (isset($val['actualLPH']) ? $val['actualLPH'] : "") }} {{ (isset($val['grossHours']) ? $val['grossHours'] : "") }}
    Total {{ (isset($totals_array['performance']) ? number_format($totals_array['performance'],1) : "") }}%
    +
    +
    +
    + + +@endsection + +@section('scripts') + + + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/userProfile.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/userProfile.blade.php new file mode 100755 index 00000000..b7ad25c1 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/userProfile.blade.php @@ -0,0 +1,95 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Change Warehouse +@endsection +@section('content') +
    +

    Change Warehouse

    +
    +
    +
    + +
    + @if(session('success')) +
    + {{ session('success') }} +
    + @endif + + @if(session('error')) +
    + {{ session('error') }} +
    + @endif + +
    + @csrf +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    +
    +
    +
    +@endsection + +@section('scripts') + + + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/whsePerf.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/whsePerf.blade.php new file mode 100755 index 00000000..9c8da132 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/whsePerf.blade.php @@ -0,0 +1,342 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - Warehouse Performance Metrics +@endsection +@section('content') +

    Warehouse Performance Metrics

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach($ICM711M as $key=>$val) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @endforeach + +
    +
    For month{{ date('Y-m',strtotime($date_in)) }}Non-interco and Ground/AirIntercompany & Ocean
    AllLTLParcel
    A1+C1BA3+C2A1+C1BA3+C2A1+C1BA3+C2A1+C1A3+C2
    ClosedClosed (Cherry)Still OpenOTTCClosedClosed (Cherry)Still OpenOTTCClosedClosed (Cherry)Still OpenOTTCClosedStill Open
    TargetsDeliv Notes + + +
    Dollars + + +
    Weight + + +
    {{ date('Y-m-d',strtotime($val->AVDATE)) }}Deliv Notes{{$val->AVANOTESCL}}{{$val->AVANOTESCH}}{{$val->AVANOTESOP}} + @if (number_format(($val->AVANOTESCL+$val->AVANOTESCH)/($val->AVANOTESCL+$val->AVANOTESCH+$val->AVANOTESOP)*100,0)<$pct_array['all_notes']) + + @endif + @if (number_format(($val->AVANOTESCL+$val->AVANOTESCH)/($val->AVANOTESCL+$val->AVANOTESCH+$val->AVANOTESOP)*100,0)>=$pct_array['all_notes']) + + @endif + {{ (($val->AVANOTESCL+$val->AVANOTESCH+$val->AVANOTESOP)!='0'?number_format(($val->AVANOTESCL+$val->AVANOTESCH)/($val->AVANOTESCL+$val->AVANOTESCH+$val->AVANOTESOP)*100,0):'0') }}% + + {{$val->AVLNOTESCL}}{{$val->AVLNOTESCH}}{{$val->AVLNOTESOP}} + @if (number_format(($val->AVLNOTESCL+$val->AVLNOTESCH)/($val->AVLNOTESCL+$val->AVLNOTESCH+$val->AVLNOTESOP)*100,0)<$pct_array['ltl_notes']) + + @endif + @if (number_format(($val->AVLNOTESCL+$val->AVLNOTESCH)/($val->AVLNOTESCL+$val->AVLNOTESCH+$val->AVLNOTESOP)*100,0)>=$pct_array['ltl_notes']) + + @endif + {{ (($val->AVLNOTESCL+$val->AVLNOTESCH+$val->AVLNOTESOP)!='0'?number_format(($val->AVLNOTESCL+$val->AVLNOTESCH)/($val->AVLNOTESCL+$val->AVLNOTESCH+$val->AVLNOTESOP)*100,0):'0') }}% + + {{$val->AVPNOTESCL}}{{$val->AVPNOTESCH}}{{$val->AVPNOTESOP}} + @if (number_format(($val->AVPNOTESCL+$val->AVPNOTESCH)/($val->AVPNOTESCL+$val->AVPNOTESCH+$val->AVPNOTESOP)*100,0)<$pct_array['parcel_notes']) + + @endif + @if (number_format(($val->AVPNOTESCL+$val->AVPNOTESCH)/($val->AVPNOTESCL+$val->AVPNOTESCH+$val->AVPNOTESOP)*100,0)>=$pct_array['parcel_notes']) + + @endif + {{ (($val->AVPNOTESCL+$val->AVPNOTESCH+$val->AVPNOTESOP)!='0'?number_format(($val->AVPNOTESCL+$val->AVPNOTESCH)/($val->AVPNOTESCL+$val->AVPNOTESCH+$val->AVPNOTESOP)*100,0):'0') }}% + + {{$val->AVINOTESCL}}{{$val->AVINOTESOP}}
    Dollars${{number_format($val->AVADLRCL,0)}}${{number_format($val->AVADLRCH,0)}}${{number_format($val->AVADLROP,0)}} + @if (number_format(($val->AVADLRCL+$val->AVADLRCH)/($val->AVADLRCL+$val->AVADLRCH+$val->AVADLROP)*100,0)<$pct_array['all_dollars']) + + @endif + @if (number_format(($val->AVADLRCL+$val->AVADLRCH)/($val->AVADLRCL+$val->AVADLRCH+$val->AVADLROP)*100,0)>=$pct_array['all_dollars']) + + @endif + {{ (($val->AVADLRCL+$val->AVADLRCH+$val->AVADLROP)!='0'?number_format(($val->AVADLRCL+$val->AVADLRCH)/($val->AVADLRCL+$val->AVADLRCH+$val->AVADLROP)*100,0):'0') }}% + + ${{number_format($val->AVLDLRCL,0)}}${{number_format($val->AVLDLRCH,0)}}${{number_format($val->AVLDLROP,0)}} + @if (number_format(($val->AVLDLRCL+$val->AVLDLRCH)/($val->AVLDLRCL+$val->AVLDLRCH+$val->AVLDLROP)*100,0)<$pct_array['ltl_dollars']) + + @endif + @if (number_format(($val->AVLDLRCL+$val->AVLDLRCH)/($val->AVLDLRCL+$val->AVLDLRCH+$val->AVLDLROP)*100,0)>=$pct_array['ltl_dollars']) + + @endif + {{ (($val->AVLDLRCL+$val->AVLDLRCH+$val->AVLDLROP)!='0'?number_format(($val->AVLDLRCL+$val->AVLDLRCH)/($val->AVLDLRCL+$val->AVLDLRCH+$val->AVLDLROP)*100,0):'0') }}% + + ${{number_format($val->AVPDLRCL,0)}}${{number_format($val->AVPDLRCH,0)}}${{number_format($val->AVPDLROP,0)}} + @if (number_format(($val->AVPDLRCL+$val->AVPDLRCH)/($val->AVPDLRCL+$val->AVPDLRCH+$val->AVPDLROP)*100,0)<$pct_array['parcel_dollars']) + + @endif + @if (number_format(($val->AVPDLRCL+$val->AVPDLRCH)/($val->AVPDLRCL+$val->AVPDLRCH+$val->AVPDLROP)*100,0)>=$pct_array['parcel_dollars']) + + @endif + {{ (($val->AVPDLRCL+$val->AVPDLRCH+$val->AVPDLROP)!='0'?number_format(($val->AVPDLRCL+$val->AVPDLRCH)/($val->AVPDLRCL+$val->AVPDLRCH+$val->AVPDLROP)*100,0):'0') }}% + + ${{number_format($val->AVIDLRCL,0)}}${{number_format($val->AVIDLROP,0)}}
    Weight{{number_format($val->AVAWGTCL,0)}}{{number_format($val->AVAWGTCH,0)}}{{number_format($val->AVAWGTOP,0)}} + @if (number_format(($val->AVAWGTCL+$val->AVAWGTCH)/($val->AVAWGTCL+$val->AVAWGTCH+$val->AVAWGTOP)*100,0)<$pct_array['all_weight']) + + @endif + @if (number_format(($val->AVAWGTCL+$val->AVAWGTCH)/($val->AVAWGTCL+$val->AVAWGTCH+$val->AVAWGTOP)*100,0)>=$pct_array['all_weight']) + + @endif + {{ (($val->AVAWGTCL+$val->AVAWGTCH+$val->AVAWGTOP)!='0'?number_format(($val->AVAWGTCL+$val->AVAWGTCH)/($val->AVAWGTCL+$val->AVAWGTCH+$val->AVAWGTOP)*100,0):'0') }}% + + {{number_format($val->AVLWGTCL,0)}}{{number_format($val->AVLWGTCH,0)}}{{number_format($val->AVLWGTOP,0)}} + @if (number_format(($val->AVLWGTCL+$val->AVLWGTCH)/($val->AVLWGTCL+$val->AVLWGTCH+$val->AVLWGTOP)*100,0)<$pct_array['ltl_weight']) + + @endif + @if (number_format(($val->AVLWGTCL+$val->AVLWGTCH)/($val->AVLWGTCL+$val->AVLWGTCH+$val->AVLWGTOP)*100,0)>=$pct_array['ltl_weight']) + + @endif + {{ (($val->AVLWGTCL+$val->AVLWGTCH+$val->AVLWGTOP)!='0'?number_format(($val->AVLWGTCL+$val->AVLWGTCH)/($val->AVLWGTCL+$val->AVLWGTCH+$val->AVLWGTOP)*100,0):'0') }}% + + {{number_format($val->AVPWGTCL,0)}}{{number_format($val->AVPWGTCH,0)}}{{number_format($val->AVPWGTOP,0)}} + @if (number_format(($val->AVPWGTCL+$val->AVPWGTCH)/($val->AVPWGTCL+$val->AVPWGTCH+$val->AVPWGTOP)*100,0)<$pct_array['parcel_weight']) + + @endif + @if (number_format(($val->AVPWGTCL+$val->AVPWGTCH)/($val->AVPWGTCL+$val->AVPWGTCH+$val->AVPWGTOP)*100,0)>=$pct_array['parcel_weight']) + + @endif + {{ (($val->AVPWGTCL+$val->AVPWGTCH+$val->AVPWGTOP)!='0'?number_format(($val->AVPWGTCL+$val->AVPWGTCH)/($val->AVPWGTCL+$val->AVPWGTCH+$val->AVPWGTOP)*100,0):'0') }}% + + {{number_format($val->AVIWGTCL,0)}}{{number_format($val->AVIWGTOP,0)}}
    + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/whsePerfDetails.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/whsePerfDetails.blade.php new file mode 100755 index 00000000..b205aeb6 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/whsePerfDetails.blade.php @@ -0,0 +1,91 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') + Solon Sentinel Portal - Warehouse Performance Metrics +@endsection +@section('content') + +
    +

    Warehouse Performance Metrics Details dated {{$date_in}} for {{ $for="a"?"All":$for="l"?"LTL":$for="p"?"Parcel":$for="i"?"I&O":"" }}

    + +
    + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + @foreach($perfDetails as $key=>$val) + + + + + + + + + + + @endforeach + +
    PickerCustomerDollarsWeightSourceIntercoModeType
    {{ $val->A5MACPKR }}{{ $val->A4SHSHNM }}$ {{number_format($val->DOLLARVALUE,2)}}{{number_format($val->WEIGHT,2)}}{{$val->SOURCE}}{{$val->INTERCO}}{{$val->A4SHIPVIA1}}{{trim($val->A4SHIPTYPE)=="SmallPack"?"Parcel":$val->A4SHIPTYPE}}
    +
    +
    +
    + +
    + +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/pages/whsePerfRequest.blade.php b/Modules/M3/Resources/views/liberty-theme/pages/whsePerfRequest.blade.php new file mode 100755 index 00000000..6dcfab82 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/pages/whsePerfRequest.blade.php @@ -0,0 +1,76 @@ +@extends('m3::liberty-theme.layout.main') +@section('title') +Sentinel Doc Archive +@endsection +@section('content') + +
    +

    Warehouse Performance Metrics

    +
    +
    +
    +
    +
    + {{-- @csrf --}} +
    + +
    + + +
    +
    + + +    + + +
    + + {{-- Form for Export --}} +
    + @csrf + + +
    +
    +
    +
    +
    + +
    +@endsection + +@section('scripts') + +@endsection diff --git a/Modules/M3/Resources/views/liberty-theme/partials/footer.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/footer.blade.php new file mode 100755 index 00000000..d0d5a141 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/footer.blade.php @@ -0,0 +1,8 @@ +
    +
    +
    Copyright © MPBA
    +
    + {{ Str::upper($WDWNAM) }} ( {{ env('APP_ENV_FOOTER') }} ) +
    +
    +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/left-navigation.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/left-navigation.blade.php new file mode 100755 index 00000000..9dc5ecaa --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/left-navigation.blade.php @@ -0,0 +1,146 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/M3DeliveryAdd.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/M3DeliveryAdd.blade.php new file mode 100755 index 00000000..61378191 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/M3DeliveryAdd.blade.php @@ -0,0 +1,67 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/M3DeliveryEdit.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/M3DeliveryEdit.blade.php new file mode 100755 index 00000000..e305ba42 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/M3DeliveryEdit.blade.php @@ -0,0 +1,72 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/blank.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/blank.blade.php new file mode 100755 index 00000000..355488ae --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/blank.blade.php @@ -0,0 +1,18 @@ + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/carrierAdd.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/carrierAdd.blade.php new file mode 100755 index 00000000..b010a212 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/carrierAdd.blade.php @@ -0,0 +1,81 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/carrierEdit.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/carrierEdit.blade.php new file mode 100755 index 00000000..b082043c --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/carrierEdit.blade.php @@ -0,0 +1,85 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/qtyAdd.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/qtyAdd.blade.php new file mode 100755 index 00000000..c509c226 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/qtyAdd.blade.php @@ -0,0 +1,68 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/qtyEdit.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/qtyEdit.blade.php new file mode 100755 index 00000000..b7c8a370 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/qtyEdit.blade.php @@ -0,0 +1,66 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/shipToCheckBox.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/shipToCheckBox.blade.php new file mode 100755 index 00000000..3d2c6704 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/shipToCheckBox.blade.php @@ -0,0 +1,31 @@ + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/shipToEdit.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/shipToEdit.blade.php new file mode 100755 index 00000000..4881b5df --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/shipToEdit.blade.php @@ -0,0 +1,76 @@ + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/userAdd.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/userAdd.blade.php new file mode 100755 index 00000000..ba8b8e64 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/userAdd.blade.php @@ -0,0 +1,252 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/userEdit.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/userEdit.blade.php new file mode 100755 index 00000000..8c45f814 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/userEdit.blade.php @@ -0,0 +1,290 @@ +
    + +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/modals/userPassword.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/modals/userPassword.blade.php new file mode 100755 index 00000000..02a23262 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/modals/userPassword.blade.php @@ -0,0 +1,41 @@ +
    +
    +
    + + + + + + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/module-navigation.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/module-navigation.blade.php new file mode 100755 index 00000000..58bf22be --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/module-navigation.blade.php @@ -0,0 +1,24 @@ + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/scripts.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/scripts.blade.php new file mode 100755 index 00000000..d9bc8798 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/scripts.blade.php @@ -0,0 +1,78 @@ + + + + + + + +@php + // ReplenishSettingsController + $routeArray = app('request')->route()->getAction(); + $controllerAction = class_basename($routeArray['controller']); + // dump($controllerAction); + list($controller, $action) = explode('@', $controllerAction); + // dump($controller); +@endphp + +@if($controller != 'ReplenishSettingsController' && $controller != 'M3ErrorsDispController') + +@endif + + + + + + + + + + + + +{{-- Data Bootstrap Responsive --}} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/styles.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/styles.blade.php new file mode 100755 index 00000000..e6f7f9b7 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/styles.blade.php @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Modules/M3/Resources/views/liberty-theme/partials/tabs/comments.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/tabs/comments.blade.php new file mode 100755 index 00000000..7d2a4b8b --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/tabs/comments.blade.php @@ -0,0 +1,49 @@ +
    +
    +
    +
    +
    +

    + + Current Hold Code: {{ $order->SHHLDC }}
    + Order number: {{ $request->order }}
    + Order Date: {{ date('m/d/Y', strtotime($order->SHORDT)) }}
    + Order Status: {{ $order->SHOST }}
    + Fill Code: {{ $order->SHALBO }}
    + @foreach ($releases as $key=>$val) + Open Releases on this order: {{ $val->SLONO }}-{{ $val->SLRLNO }} +
    + @endforeach + +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Order number: {{ $request->order }}
    +
    +
    +
    Order Date: {{ date('m/d/Y', strtotime($order->SHORDT)) }}
    +
    +
    +
    + + + + + + + + + + + +
    IdUserCreated DateReminder DateComment
    +
    +
    +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/tabs/details.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/tabs/details.blade.php new file mode 100755 index 00000000..93efdc80 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/tabs/details.blade.php @@ -0,0 +1,78 @@ +
    +
    +
    +
    +
    +

    + + Current Hold Code: {{ $order->SHHLDC }}
    + Order number: {{ $request->order }}
    + Order Date: {{ date('m/d/Y', strtotime($order->SHORDT)) }}
    + Order Status: {{ $order->SHOST }}
    + Fill Code: {{ $order->SHALBO }}
    + @foreach ($releases as $key=>$val) + Open Releases on this order: {{ $val->SLONO }}-{{ $val->SLRLNO }} +
    + @endforeach + + +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Order number: {{ $request->order }}
    +
    +
    +
    Order Date: {{ date('m/d/Y', strtotime($order->SHORDT)) }}
    +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + @foreach ($details as $key=>$detail) + + + + + + + + + + + + + + + @endforeach + +
    StatusSrc WhsePartDescriptionFill CodeOrdBalResonPickPriceExtensionPromise Date
    {{ $detail->SLLNST }}{{ $detail->SLSRWH }}{{ $detail->SLPTNO }}{{ $detail->SLPTD1 }}{{ $detail->SLALBO }}{{ $detail->SLORQY }}{{ $detail->BALANCE }}{{ $detail->RESERVED }}{{ $detail->ONPICK }}{{ $detail->SLUNPR }}{{ $detail->SLEXPR }}{{ $detail->SLPRDT }}
    +
    + +
    +
    +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/tabs/orders.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/tabs/orders.blade.php new file mode 100755 index 00000000..dcab2785 --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/tabs/orders.blade.php @@ -0,0 +1,166 @@ +
    +
    +
    +
    +
    +

    + + Current Hold Code: {{ $order->SHHLDC }}
    + Order number: {{ $request->order }}
    + Order Date: {{ date('m/d/Y', strtotime($order->SHORDT)) }}
    + Order Status: {{ $order->SHOST }}
    + Fill Code: {{ $order->SHALBO }}
    + @foreach ($releases as $key=>$val) + Open Releases on this order: {{ $val->SLONO }}-{{ $val->SLRLNO }} +
    + @endforeach +

    +
    +
    +
    +
    +
    +
    +
    +
    Billed To # {{$order->SHCSTN}}
    +
    +

    + + {!! (isset($order->SHSLNM)&&trim($order->SHSLNM)!=''?''.$order->SHSLNM."
    ":'') !!} + {!! (isset($order->SHSLA1)&&trim($order->SHSLA1)!=''?$order->SHSLA1."
    ":'') !!} + {!! (isset($order->SHSLA2)&&trim($order->SHSLA2)!=''?$order->SHSLA2."
    ":'') !!} + {!! (isset($order->SHSLCI)&&trim($order->SHSLCI)!=''?$order->SHSLCI.", ":'') !!} + {!! (isset($order->SHSLST)&&trim($order->SHSLST)!=''?$order->SHSLST.", ":'') !!} + {!! (isset($order->SHSLZP)&&trim($order->SHSLZP)!=''?$order->SHSLZP."
    ":'') !!} + {!! (isset($order->SHSLCT)&&trim($order->SHSLCT)!=''?$order->SHSLCT."
    ":'') !!} + +

    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    Shipped To # {{$order->SHSTCN}}
    +
    +
    + @if ($order->SHHLDC=="F" && $order->SHOST=="Open" && $authuser[0]->COUNT!=0) +
    + @endif +
    +
    +
    +
    +

    + + {!! (isset($order->SHSHNM)&&trim($order->SHSHNM)!=''?''.$order->SHSHNM."
    ":'') !!} + {!! (isset($order->SHSHA1)&&trim($order->SHSHA1)!=''?$order->SHSHA1."
    ":'') !!} + {!! (isset($order->SHSHA2)&&trim($order->SHSHA2)!=''?$order->SHSHA2."
    ":'') !!} + {!! (isset($order->SHSHA3)&&trim($order->SHSHA3)!=''?$order->SHSHA3."
    ":'') !!} + {!! (isset($order->SHSHCI)&&trim($order->SHSHCI)!=''?$order->SHSHCI.", ":'') !!} + {!! (isset($order->SHSHST)&&trim($order->SHSHST)!=''?$order->SHSHST.", ":'') !!} + {!! (isset($order->SHSHZP)&&trim($order->SHSHZP)!=''?$order->SHSHZP."
    ":'') !!} + {!! (isset($order->SHSHCT)&&trim($order->SHSHCT)!=''?$order->SHSHCT."
    ":'') !!} + + @if ($order->SHHLDC=="F" && $order->SHOST=="Open" && $authuser[0]->COUNT!=0) +

    Ignore address checker error and process as is
    + @endif +

    +
    +
    +
    +
    +
    + +
    + + @if($order->SHHLDC=="F" && count($reasonForF)>=1) + +
    +
    +
    +
    Reasons for code F
    +
    +
    + + + + + + + + + + @foreach ($reasonForF as $key=>$whyF) + + + + + + @endforeach + +
    Date/TimeMessageCode
    {{ date('m/d/Y', strtotime($whyF->AMDATENT ))}} {{ date('H:i:s', strtotime($whyF->AMTIMENT ))}}{{ $whyF->AMCOMM }}{{ $whyF->AMERRCDE }}
    +
    +
    +
    +
    + @endif + + @if($order->SHHLDC!="F" && count($reasonOther['message'])>=1) +
    +
    +
    +
    Exemption Reasons
    +
    +
    + + + + + + + + @foreach ($reasonOther['message'] as $key=>$why) + + + + @endforeach + +
    Message
    {{ $why }}
    +
    +
    +
    +
    + @endif + +
    +
    +
    + + + + + + + + + + @foreach ($comments as $key=>$comment) + + + + + + @endforeach + +
    DateCommentPrint Code
    {{ date('m/d/Y', strtotime($comment->SCCRDT ))}}{{ $comment->SCCM }}{{ $comment->SCCMPR }}
    +
    +
    +
    +
    +
    diff --git a/Modules/M3/Resources/views/liberty-theme/partials/top-navigation.blade.php b/Modules/M3/Resources/views/liberty-theme/partials/top-navigation.blade.php new file mode 100755 index 00000000..3e43c78e --- /dev/null +++ b/Modules/M3/Resources/views/liberty-theme/partials/top-navigation.blade.php @@ -0,0 +1,36 @@ + diff --git a/Modules/M3/Routes/.gitkeep b/Modules/M3/Routes/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Routes/api.php b/Modules/M3/Routes/api.php new file mode 100755 index 00000000..1ab0c348 --- /dev/null +++ b/Modules/M3/Routes/api.php @@ -0,0 +1,42 @@ +get('/user', function (Request $request) { + return $request->user(); +}); + +Route::apiResource('m3receiver', M3Controller::class); + +Route::any('/M3InventoryReport', [M3InventoryReport::class, 'M3InventoryReport'])->name('M3InventoryReport'); +Route::any('/M3InventoryReportListURL', [M3InventoryReport::class, 'M3InventoryReportListURL'])->name('M3InventoryReportListURL'); + +Route::any('/TransferAPIURL', [TransferAPI::class, 'TransferAPIURL'])->name('TransferAPIURL'); +Route::any('/UpdateShipmentNumber', [TransferAPI::class, 'UpdateShipmentNumber'])->name('UpdateShipmentNumber'); + +Route::any('/M3InventoryReportReplen', [ReplenAPI::class, 'M3InventoryReportReplen'])->name('M3InventoryReportReplen'); + +Route::any('/CloseShipmentCoChargeAPI', [CloseShipment::class, 'CloseShipmentCoChargeAPI'])->name('CloseShipmentCoChargeAPI'); + +Route::any('/PdfStorageAPI', [PdfStorage::class, 'PdfStorageAPI'])->name('PdfStorageAPI'); + +Route::any('/twoshipupdatehold', [TwoShipAPIs::class, 'TwoShipUpdateHold'])->name('twoshipupdatehold'); diff --git a/Modules/M3/Routes/web.php b/Modules/M3/Routes/web.php new file mode 100755 index 00000000..6612e251 --- /dev/null +++ b/Modules/M3/Routes/web.php @@ -0,0 +1,198 @@ + 'text/css; charset=UTF-8', + 'js' => 'application/javascript; charset=UTF-8', + 'svg' => 'image/svg+xml', + 'png' => 'image/png', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'gif' => 'image/gif', + 'ico' => 'image/x-icon', + 'woff' => 'font/woff', + 'woff2' => 'font/woff2', + 'ttf' => 'font/ttf', + ]; + + return response(file_get_contents($file), 200, [ + 'Content-Type' => $contentTypes[$extension] ?? 'application/octet-stream', + 'Cache-Control' => app()->environment('local') ? 'no-cache, no-store, must-revalidate' : 'public, max-age=86400', + 'X-Content-Type-Options' => 'nosniff', + ]); +})->where('path', '.+')->name('assets'); + +Route::get('/health', fn () => response()->json(['module' => 'M3', 'status' => 'ok', 'database' => config('m3.connection', 'pgsql')]))->name('health'); + +// Admin Panel +Route::get('/', [DashboardController::class, 'index'])->name('index'); + +// Utilities UtilitiesController +Route::get('/utilities', [UtilitiesController::class, 'index'])->name('utilities'); +Route::get('/pdfReadWrite', [UtilitiesController::class, 'pdfReadWrite'])->name('pdfReadWrite'); +Route::get('/fixICM799MSentPKR', [UtilitiesController::class, 'fixICM799MSentPKR'])->name('fixICM799MSentPKR'); +Route::get('/generateGS128', [UtilitiesController::class, 'generateGS128'])->name('generateGS128'); +Route::get('/miscTests', [UtilitiesController::class, 'miscTests'])->name('miscTests'); + +// logout +Route::get('/logout', [AuthController::class, 'logout'])->name('logout'); + +// orderInquiry +// Route::get('/orderInquiry', [orderInquiryController::class, 'index'])->name('orderInquiry'); +// Route::post('/gotoOrder',[ordersOnHoldReqController::class, 'order'])->name('ordersOnHoldReqOrder'); + +// v4 +Route::get('/UserPickingStats4', [UserPickingStats4::class, 'index'])->name('UserPickingStats4'); +Route::post('/UserPickingStats4', [UserPickingStats4::class, 'index'])->name('UserPickingStats4'); + +// userControl +Route::get('/userControl', [UserControlController::class, 'index'])->name('userControl'); +Route::post('/userControl', [UserControlController::class, 'index'])->name('userControl'); +Route::post('/userControl/saveUserAdd', [UserControlController::class, 'saveUserAdd'])->name('saveUserAdd'); +Route::post('/userControl/saveUserEdit', [UserControlController::class, 'saveUserEdit'])->name('saveUserEdit'); +Route::get('/userControl/callCL', [UserControlController::class, 'callCL'])->name('callCL'); +Route::post('/userControl/savePassword', [UserControlController::class, 'savePassword'])->name('savePassword'); + +// palletQty +Route::get('/palletQty', [PalletQtyController::class, 'index'])->name('palletQty'); +Route::post('/palletQty', [PalletQtyController::class, 'index'])->name('palletQty'); +Route::post('/palletQty/saveQtyAdd', [PalletQtyController::class, 'saveQtyAdd'])->name('saveQtyAdd'); +Route::post('/palletQty/saveQtyAdd2', [PalletQtyController::class, 'saveQtyAdd2'])->name('saveQtyAdd2'); +Route::post('/palletQty/saveQtyEdit', [PalletQtyController::class, 'saveQtyEdit'])->name('saveQtyEdit'); + +// carrierMaint +Route::get('/carrierMaint', [CarrierMaintController::class, 'index'])->name('carrierMaint'); +Route::post('/carrierMaint', [CarrierMaintController::class, 'index'])->name('carrierMaint'); +Route::post('/carrierMaint/saveCarrierAdd', [CarrierMaintController::class, 'saveCarrierAdd'])->name('saveCarrierAdd'); +Route::post('/carrierMaint/saveCarrierAdd2', [CarrierMaintController::class, 'saveCarrierAdd2'])->name('saveCarrierAdd2'); +Route::post('/carrierMaint/saveCarrierEdit', [CarrierMaintController::class, 'saveCarrierEdit'])->name('saveCarrierEdit'); + +// M3Delivery Maint +Route::get('/M3Delivery', [M3DeliveryController::class, 'index'])->name('M3Delivery'); +Route::post('/M3Delivery', [M3DeliveryController::class, 'index'])->name('M3Delivery'); +Route::post('/M3Delivery/saveM3DeliveryAdd', [M3DeliveryController::class, 'saveM3DeliveryAdd'])->name('saveM3DeliveryAdd'); +Route::post('/M3Delivery/saveM3DeliveryEdit', [M3DeliveryController::class, 'saveM3DeliveryEdit'])->name('saveM3DeliveryEdit'); + +// Replenishement Settings +Route::resource('/replenishmentSettings', 'Modules\M3\Http\Controllers\ReplenishSettingsController', ['except' => ['create', 'edit', 'update', 'destroy']]); // 'store', +Route::post('/replenishmentSettingsUpdate', 'Modules\M3\Http\Controllers\ReplenishSettingsController@update')->name('replenishmentSettingsUpdate'); +Route::post('/replenishmentSettingsDelete', 'Modules\M3\Http\Controllers\ReplenishSettingsController@deleteRec')->name('replenishmentSettingsDelete'); +Route::post('/replenishmentSettingsExist', 'Modules\M3\Http\Controllers\ReplenishSettingsController@checkRecExit')->name('replenishmentSettingsExist'); +Route::get('/replenishmentSettingsDT', 'Modules\M3\Http\Controllers\ReplenishSettingsController@datatables')->name('replenishmentSettingsDT'); + +// M3 Errors Display M3ErrorsDispController +Route::resource('/M3ErrorsDisplay', 'Modules\M3\Http\Controllers\M3ErrorsDispController', ['except' => ['create', 'store', 'edit', 'update', 'destroy']]); +Route::get('/M3ErrorsDisplayDT', 'Modules\M3\Http\Controllers\M3ErrorsDispController@datatables')->name('M3ErrorsDisplayDT'); +Route::post('/M3ErrorsDisplay699', 'Modules\M3\Http\Controllers\M3ErrorsDispController@update699M')->name('M3ErrorsDisplay699'); +Route::post('/exporttoExcel699', 'Modules\M3\Http\Controllers\M3ErrorsDispController@exporttoExcel')->name('exporttoExcel699'); + +// M3 Cached PDF +Route::resource('/M3GetPDFFromCache', 'Modules\M3\Http\Controllers\M3GetPDFFromCacheController', ['except' => ['create', 'store', 'edit', 'update', 'destroy']]); +Route::any('/M3GetPDFFromCache', 'Modules\M3\Http\Controllers\M3GetPDFFromCacheController@index'); + +// M3 Call Close API +Route::any('/M3ManifestCloseAPI', [M3CallCloseAPIController::class, 'index'])->name('M3ManifestCloseAPI'); + +// Closed order lines report +Route::any('/OrderLinesOfClosedOrder', 'Modules\M3\Http\Controllers\OrderLinesOfClosedOrder@index')->name('OrderLinesOfClosedOrder'); +Route::post('/exporttoExcel', 'Modules\M3\Http\Controllers\OrderLinesOfClosedOrder@exporttoExcel')->name('exporttoExcel'); +Route::any('/StoreExcelToDisk', 'Modules\M3\Http\Controllers\OrderLinesOfClosedOrder@StoreExcelToDisk')->name('StoreExcelToDisk'); +Route::any('/downloadFiles', 'Modules\M3\Http\Controllers\OrderLinesOfClosedOrder@downloadFiles')->name('downloadFiles'); + +// v5 +Route::get('/UserPickingStats5', [UserPickingStats5::class, 'index'])->name('UserPickingStats5'); +Route::post('/UserPickingStats5', [UserPickingStats5::class, 'index'])->name('UserPickingStats5'); + +// 732 +// pendingClosure +Route::get('/pendingClosure', [PendingClosureController::class, 'index'])->name('pendingClosure'); +Route::post('/pendingClosure', [PendingClosureController::class, 'index'])->name('pendingClosure'); +Route::post('/allowRetry', [PendingClosureController::class, 'allowRetry'])->name('allowRetry'); + +// Ship To +Route::resource('ship-to', ShipToController::class)->parameters(['ship-to' => 'austcn'])->except(['show']); + +Route::get('/ship-to/{aushshzp}/{aushwhs}/edit', [ShipToController::class, 'edit'])->name('ship-to.edit'); +Route::put('/ship-to/{aushshzp}/{aushwhs}', [ShipToController::class, 'update'])->name('ship-to.update'); +Route::delete('/ship-to/{aushshzp}/{aushwhs}', [ShipToController::class, 'destroy'])->name('ship-to.destroy'); + +// MF Orders +Route::get('/MFOrders/{id}', [MFOrdersController::class, 'index'])->name('MFOrders'); + +// Get Contents for CloseShipment +Route::any('/GetContentsForClose', [GetContentsController::class, 'processShipment'])->name('GetContentsForClose'); + +// Update Profile +Route::any('/userprofile', [UserProfileController::class, 'index'])->name('userprofile'); +Route::post('/userprofileupdate', [UserProfileController::class, 'updateUserProfile'])->name('userprofileupdate'); +Route::any('/userprofileupdateajax', [UserProfileController::class, 'updateUserProfileAjax'])->name('userprofileupdateajax'); + +// Sentinel Functions +Route::any('/packSyst5Func', [SentinelController::class, 'packSyst5Func'])->name('packSyst5Func'); + +// Executives summary +Route::any('/execsummary', [ExecSummaryController::class, 'index'])->name('execsummary'); +Route::any('/execsummaryline', [ExecSummaryLineController::class, 'index'])->name('execsummaryline'); + +// Warehouse Perf Metrics +Route::any('/whsePerf', [WhsePerfController::class, 'index'])->name('whsePerf'); +Route::any('/whsePerfExcel', [WhsePerfController::class, 'exportTable'])->name('whsePerfExcel'); +Route::any('/whsePerfShow', [WhsePerfController::class, 'displayTable'])->name('whsePerfShow'); +Route::any('/whsePerfDetails', [WhsePerfDetailsController::class, 'index'])->name('whsePerfDetails'); +Route::any('/downloadFilesWhs', [WhsPerfMetrics::class, 'downloadFiles'])->name('downloadFilesWhs'); + +// BOL PDFs +Route::any('/fillBOL', [FillBOLController::class, 'index'])->name('fillBOL'); +Route::any('/fillBOLPDF', [FillBOLController::class, 'fillBOL'])->name('fillBOLPDF'); + +Route::any('/fillBOL2', [FillBOL2Controller::class, 'index'])->name('fillBOL2'); +Route::any('/fillBOL2PDF', [FillBOL2Controller::class, 'fillBOL'])->name('fillBOL2PDF'); + +// Pack Box to Pallet BoxPackToPalletController +Route::any('/BoxPackToPallet', [BoxPackToPalletController::class, 'index'])->name('BoxPackToPallet'); +Route::any('/BoxPackToPallet/getboxes', [BoxPackToPalletController::class, 'getBoxes'])->name('BoxPackToPallet.getboxes'); +Route::any('/BoxPackToPallet/scanboxes', [BoxPackToPalletController::class, 'scanBoxes'])->name('BoxPackToPallet.scanboxes'); +Route::any('/BoxPackToPallet/deletebox', [BoxPackToPalletController::class, 'deleteBox'])->name('BoxPackToPallet.deletebox'); diff --git a/Modules/M3/Services/BillOfLadingService.php b/Modules/M3/Services/BillOfLadingService.php new file mode 100755 index 00000000..20ea940e --- /dev/null +++ b/Modules/M3/Services/BillOfLadingService.php @@ -0,0 +1,99 @@ +path('ETN-BOL2.pdf'); + $newFile = 'BOL_' . ($data['bol_number'] ?? 'unknown') . '.pdf'; + $outputPath ??= Storage::disk('public')->path($newFile); + + $pdf = new Fpdi; + $pdf->setSourceFile($templatePath); + + $this->renderPage($pdf, $data, 1, true); + $this->renderPage($pdf, $data, 2, false); + $pdf->Output('F', $outputPath); + + return $outputPath; + } + + private function renderPage(Fpdi $pdf, array $data, int $pageNumber, bool $includeLineDetails): void + { + $template = $pdf->importPage($pageNumber); + $pdf->AddPage(); + $pdf->useTemplate($template); + $pdf->SetFont('Helvetica', '', 10); + $pdf->SetTextColor(0, 0, 0); + + foreach ($this->headerFields() as $field => [$x, $y]) { + $this->writeField($pdf, $data, $field, $x, $y); + } + + if ($includeLineDetails) { + foreach ($this->lineFields() as $field => [$x, $y]) { + $this->writeField($pdf, $data, $field, $x, $y); + } + $this->writeDescription($pdf, $data); + } + } + + private function writeField(Fpdi $pdf, array $data, string $field, float $x, float $y): void + { + if (! array_key_exists($field, $data) || $data[$field] === null || $data[$field] === '') { + return; + } + + $pdf->SetXY($x, $y); + $pdf->Write(0, (string) $data[$field]); + } + + private function writeDescription(Fpdi $pdf, array $data): void + { + $description = $data['description'] ?? null; + if ($description === null || $description === '') { + return; + } + + $pdf->SetXY(28, 140); + $pdf->MultiCell(67, 4.5, (string) $description, 0, 'L'); + } + + private function headerFields(): array + { + return [ + 'bol_number' => [126, 44], + 'date' => [171, 44], + 'shipper_no' => [126, 53], + 'master_bill_no' => [172, 54], + 'master_bill_yes' => [183, 54], + 'master_bill_drops' => [194, 55], + 'consignor_name' => [21, 44], + 'consignor_address1' => [21, 48], + 'consignor_address2' => [21, 52], + 'consignor_address3' => [21, 56], + 'consignee_name' => [21, 72], + 'consignee_address1' => [21, 76], + 'consignee_address2' => [21, 80], + 'consignee_address3' => [21, 84], + 'freight_collect' => [127, 90], + 'carrier_name' => [10, 100], + ]; + } + + private function lineFields(): array + { + return [ + 'pieces' => [6, 142], + 'line_class' => [145, 142], + 'line_weight' => [177, 142], + 'total_pieces' => [6, 244], + 'total_line_weight' => [177, 244], + ]; + } +} diff --git a/Modules/M3/Services/PostgresProgramBridge.php b/Modules/M3/Services/PostgresProgramBridge.php new file mode 100755 index 00000000..51d1e382 --- /dev/null +++ b/Modules/M3/Services/PostgresProgramBridge.php @@ -0,0 +1,99 @@ +queue('program', $program, $library, [ + 'parameters' => $parameters, + 'return_parameters' => $returnParameters, + 'options' => $options, + ]); + } + + public function CLCommand(string $command): array|false + { + return $this->queue('command', $command, null, []); + } + + public function getErrorCode(): string + { + return $this->errorCode; + } + + public function getErrorMsg(): string + { + return $this->errorMessage; + } + + private function queue(string $type, string $operation, ?string $library, array $payload): array|false + { + try { + $record = [ + 'type' => $type, + 'operation' => $operation, + 'library' => $library, + 'payload' => json_encode($payload, JSON_THROW_ON_ERROR), + 'requested_by' => function_exists('m3_user') ? m3_user() : null, + 'status' => 'pending', + 'created_at' => now(), + 'updated_at' => now(), + ]; + + if (Schema::connection(config('m3.connection', 'pgsql'))->hasTable('m3_program_requests')) { + $id = DB::connection(config('m3.connection', 'pgsql')) + ->table('m3_program_requests') + ->insertGetId($record); + } else { + Log::warning('M3 PostgreSQL program bridge table is not migrated; request logged only.', $record); + $id = null; + } + + return ['success' => true, 'queued' => true, 'request_id' => $id, 'io_param' => []]; + } catch (\Throwable $e) { + $this->errorCode = (string) $e->getCode(); + $this->errorMessage = $e->getMessage(); + Log::error('Unable to queue M3 program request.', ['exception' => $e]); + + return false; + } + } +} diff --git a/Modules/M3/Services/SpreadsheetExport.php b/Modules/M3/Services/SpreadsheetExport.php new file mode 100755 index 00000000..63135879 --- /dev/null +++ b/Modules/M3/Services/SpreadsheetExport.php @@ -0,0 +1,80 @@ +write($rows, $path); + + return response()->download($path, basename($filename))->deleteFileAfterSend(true); + } + + public function store(Collection $rows, string $filename, ?string $disk = null): string + { + $tmp = storage_path(self::EXPORT_DIRECTORY . uniqid('', true) . '-' . basename($filename)); + $this->write($rows, $tmp); + + if ($disk && config("filesystems.disks.$disk")) { + Storage::disk($disk)->put($filename, file_get_contents($tmp)); + @unlink($tmp); + + return $filename; + } + + return $tmp; + } + + public function storeSheets(array $sheets, string $filename, ?string $disk = null): string + { + $book = new Spreadsheet; + $book->removeSheetByIndex(0); + foreach ($sheets as $title => $rows) { + $sheet = $book->createSheet(); + $sheet->setTitle(substr((string) $title, 0, 31)); + $array = collect($rows)->map(fn ($row) => (array) $row)->values(); + if ($array->isNotEmpty()) { + $sheet->fromArray($array->map(fn ($row) => array_values($row))->all(), null, 'A1'); + } + } + $tmp = storage_path(self::EXPORT_DIRECTORY . uniqid('', true) . '-' . basename($filename)); + if (! is_dir(dirname($tmp))) { + mkdir(dirname($tmp), 0775, true); + } + (new Xlsx($book))->save($tmp); + if ($disk && config("filesystems.disks.$disk")) { + Storage::disk($disk)->put($filename, file_get_contents($tmp)); + @unlink($tmp); + + return $filename; + } + + return $tmp; + } + + private function write(Collection $rows, string $path): void + { + if (! is_dir(dirname($path))) { + mkdir(dirname($path), 0775, true); + } + + $sheet = (new Spreadsheet)->getActiveSheet(); + $array = $rows->map(fn ($row) => (array) $row)->values(); + $headers = $array->first() ? array_keys($array->first()) : []; + if ($headers) { + $sheet->fromArray($headers, null, 'A1'); + $sheet->fromArray($array->map(fn ($row) => array_values($row))->all(), null, 'A2'); + } + (new Xlsx($sheet->getParent()))->save($path); + } +} diff --git a/Modules/M3/Support/.gitkeep b/Modules/M3/Support/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/M3/Support/ModuleInfo.php b/Modules/M3/Support/ModuleInfo.php new file mode 100755 index 00000000..5e6903a1 --- /dev/null +++ b/Modules/M3/Support/ModuleInfo.php @@ -0,0 +1,28 @@ +loadRoutesFrom(__DIR__ . '/../Routes/web.php'); - $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'm3integration'); - } - - /** - * Register the module services. - */ - public function register(): void - { - // Placeholder only. - } -} diff --git a/Modules/M3Integration/README.md b/Modules/M3Integration/README.md deleted file mode 100644 index 44dff5e8..00000000 --- a/Modules/M3Integration/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# M3 Integration - -Observe M3 transactions, delivery methods, close shipment calls, and API exchanges. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/M3Integration/Resources/views/index.blade.php b/Modules/M3Integration/Resources/views/index.blade.php deleted file mode 100644 index 2b93d90b..00000000 --- a/Modules/M3Integration/Resources/views/index.blade.php +++ /dev/null @@ -1,120 +0,0 @@ - -
    -
    -
    - -
    - -
    -
    -
    -
    01
    -

    M3 Transaction Log

    -

    Placeholder area for m3 transaction log.

    -
    -
    -
    -
    -
    -
    -
    02
    -

    M3 Delivery Methods

    -

    Placeholder area for m3 delivery methods.

    -
    -
    -
    -
    -
    -
    -
    03
    -

    Close Shipment API

    -

    Placeholder area for close shipment api.

    -
    -
    -
    -
    -
    -
    -
    04
    -

    M3 Error Queue

    -

    Placeholder area for m3 error queue.

    -
    -
    -
    - -
    -
    -
    -
    -
    -

    M3 Integration workbench

    -

    Sample table layout ready to wire into controllers, - queries, DataTables, or Livewire.

    -
    - -
    - - -
    -
    -
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TransactionProgramMessageAction
    M3 Transaction LogSample 1Active - Open
    M3 Delivery MethodsSample 2Active - Open
    Close Shipment APISample 3Active - Open
    M3 Error QueueSample 4Active - Open
    -
    -
    -
    -
    -
    -
    -
    diff --git a/Modules/M3Integration/Resources/views/partials/nav.blade.php b/Modules/M3Integration/Resources/views/partials/nav.blade.php deleted file mode 100644 index c6309120..00000000 --- a/Modules/M3Integration/Resources/views/partials/nav.blade.php +++ /dev/null @@ -1,4 +0,0 @@ - - - M3 Integration - diff --git a/Modules/M3Integration/Routes/api.php b/Modules/M3Integration/Routes/api.php deleted file mode 100644 index 63a893c0..00000000 --- a/Modules/M3Integration/Routes/api.php +++ /dev/null @@ -1,3 +0,0 @@ -prefix('m3-integration') - ->name('m3-integration.') - ->group(function (): void { - Route::view('/', 'm3integration::index')->name('index'); - }); diff --git a/Modules/M3Integration/module.json b/Modules/M3Integration/module.json deleted file mode 100644 index 3cf420fb..00000000 --- a/Modules/M3Integration/module.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "M3Integration", - "alias": "m3-integration", - "description": "Observe M3 transactions, delivery methods, close shipment calls, and API exchanges.", - "keywords": [], - "priority": 0, - "providers": [ - "Modules\\M3Integration\\Providers\\M3IntegrationServiceProvider" - ], - "files": [] -} \ No newline at end of file diff --git a/Modules/OTM/Config/.gitkeep b/Modules/OTM/Config/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Config/config.php b/Modules/OTM/Config/config.php new file mode 100755 index 00000000..777fb768 --- /dev/null +++ b/Modules/OTM/Config/config.php @@ -0,0 +1,7 @@ + 'OTM', + 'features' => [ + ], +]; diff --git a/Modules/OTM/Console/.gitkeep b/Modules/OTM/Console/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Database/Migrations/.gitkeep b/Modules/OTM/Database/Migrations/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Database/Seeders/.gitkeep b/Modules/OTM/Database/Seeders/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Database/Seeders/OTMDatabaseSeeder.php b/Modules/OTM/Database/Seeders/OTMDatabaseSeeder.php new file mode 100755 index 00000000..ed9740f0 --- /dev/null +++ b/Modules/OTM/Database/Seeders/OTMDatabaseSeeder.php @@ -0,0 +1,20 @@ +registerTranslations(); + $this->registerConfig(); + $this->registerViews(); + $this->registerHelpers(); + $this->registerCommands(); + $this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations')); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register(): void + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register the helpers. + * + * @return void + */ + protected function registerHelpers(): void + { + foreach (glob(__DIR__ . '/../Helpers/*.php') as $filename) { + require_once $filename; + } + } + + /** + * Dynamically Register Commands. + * + * @return void + */ + public function registerCommands(): void + { + if (! $this->app->runningInConsole()) { + return; + } + $commandPath = __DIR__ . '/../Console'; + $commands = collect(File::allFiles($commandPath)) + ->map(function ($file) { + return 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); + }) + ->filter(function ($class) { + return class_exists($class); + }) + ->values() + ->all(); + $this->commands($commands); + } + + /** + * Register config. + * + * @return void + */ + protected function registerConfig(): void + { + $this->publishes([ + module_path(ModuleInfo::name(), 'Config/config.php') => config_path(ModuleInfo::nameLower() . '.php'), + ], 'config'); + $this->mergeConfigFrom( + module_path(ModuleInfo::name(), 'Config/config.php'), + ModuleInfo::nameLower(), + ); + } + + /** + * Register views. + * + * @return void + */ + public function registerViews(): void + { + $viewPath = resource_path('views/modules/' . ModuleInfo::nameLower()); + $sourcePath = module_path(ModuleInfo::name(), 'Resources/views'); + $this->publishes([ + $sourcePath => $viewPath, + ], ['views', ModuleInfo::nameLower() . '-module-views']); + $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), ModuleInfo::nameLower()); + } + + /** + * Register translations. + * + * @return void + */ + public function registerTranslations(): void + { + $langPath = resource_path('lang/modules/' . ModuleInfo::nameLower()); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower()); + } else { + $this->loadTranslationsFrom(module_path(ModuleInfo::name(), 'Resources/lang'), ModuleInfo::nameLower()); + } + } + + /** + * Regsiter View Paths + * + * @return array + */ + private function getPublishableViewPaths(): array + { + $paths = []; + foreach (Config::get('view.paths') as $path) { + if (is_dir($path . '/modules/' . ModuleInfo::nameLower())) { + $paths[] = $path . '/modules/' . ModuleInfo::nameLower(); + } + } + + return $paths; + } +} diff --git a/Modules/OTM/Providers/RouteServiceProvider.php b/Modules/OTM/Providers/RouteServiceProvider.php new file mode 100755 index 00000000..5f8f6e5c --- /dev/null +++ b/Modules/OTM/Providers/RouteServiceProvider.php @@ -0,0 +1,57 @@ +mapApiRoutes(); + + $this->mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + * + * @return void + */ + protected function mapWebRoutes() + { + Route::middleware('web') + ->namespace($this->moduleNamespace) + ->group(module_path('OTM', '/Routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::prefix('api') + ->middleware('api') + ->namespace($this->moduleNamespace) + ->group(module_path('OTM', '/Routes/api.php')); + } +} diff --git a/Modules/OTM/Resources/assets/.gitkeep b/Modules/OTM/Resources/assets/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Resources/assets/js/app.js b/Modules/OTM/Resources/assets/js/app.js new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Resources/assets/sass/app.scss b/Modules/OTM/Resources/assets/sass/app.scss new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Resources/lang/.gitkeep b/Modules/OTM/Resources/lang/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Resources/views/.gitkeep b/Modules/OTM/Resources/views/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Resources/views/index.blade.php b/Modules/OTM/Resources/views/index.blade.php new file mode 100755 index 00000000..fe3d2a83 --- /dev/null +++ b/Modules/OTM/Resources/views/index.blade.php @@ -0,0 +1,9 @@ +@extends('otm::layouts.master') + +@section('content') +

    Hello World

    + +

    + This view is loaded from module: {!! config('otm.name') !!} +

    +@endsection diff --git a/Modules/OTM/Resources/views/layouts/master.blade.php b/Modules/OTM/Resources/views/layouts/master.blade.php new file mode 100755 index 00000000..531f82c7 --- /dev/null +++ b/Modules/OTM/Resources/views/layouts/master.blade.php @@ -0,0 +1,19 @@ + + + + + + + Module OTM + + {{-- Laravel Mix - CSS File --}} + {{-- --}} + + + + @yield('content') + + {{-- Laravel Mix - JS File --}} + {{-- --}} + + diff --git a/Modules/OTM/Routes/.gitkeep b/Modules/OTM/Routes/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Routes/api.php b/Modules/OTM/Routes/api.php new file mode 100755 index 00000000..f399c285 --- /dev/null +++ b/Modules/OTM/Routes/api.php @@ -0,0 +1,18 @@ +get('/otm', function (Request $request) { + return $request->user(); +}); diff --git a/Modules/OTM/Routes/web.php b/Modules/OTM/Routes/web.php new file mode 100755 index 00000000..2c0dfc52 --- /dev/null +++ b/Modules/OTM/Routes/web.php @@ -0,0 +1,16 @@ +group(function () { + Route::get('/', 'OTMController@index'); +}); diff --git a/Modules/OTM/Support/.gitkeep b/Modules/OTM/Support/.gitkeep new file mode 100755 index 00000000..e69de29b diff --git a/Modules/OTM/Support/ModuleInfo.php b/Modules/OTM/Support/ModuleInfo.php new file mode 100755 index 00000000..21bee6c8 --- /dev/null +++ b/Modules/OTM/Support/ModuleInfo.php @@ -0,0 +1,28 @@ + ['required', 'string', 'max:255'], 'strapline' => ['nullable', 'string', 'max:255'], 'description' => ['nullable', 'string', 'max:2000'], - 'monthly_amount' => ['required', 'numeric', 'min:0', 'max:999999.99'], - 'annual_amount' => ['nullable', 'numeric', 'min:0', 'max:999999.99'], + 'monthly_amount' => ['required', 'numeric', self::MIN_ZERO, 'max:999999.99'], + 'annual_amount' => ['nullable', 'numeric', self::MIN_ZERO, 'max:999999.99'], 'currency' => ['required', 'string', 'size:3'], 'badge_label' => ['nullable', 'string', 'max:60'], 'features' => ['nullable', 'string', 'max:4000'], - 'sort_order' => ['required', 'integer', 'min:0', 'max:65535'], + 'sort_order' => ['required', 'integer', self::MIN_ZERO, 'max:65535'], 'is_featured' => ['nullable', 'boolean'], 'is_active' => ['nullable', 'boolean'], ]); diff --git a/Modules/Platform/app/Http/Controllers/StripeWebhookController.php b/Modules/Platform/app/Http/Controllers/StripeWebhookController.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/app/Http/Middleware/EnsureLicensedTenant.php b/Modules/Platform/app/Http/Middleware/EnsureLicensedTenant.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/app/Http/Middleware/EnsurePlatformAdmin.php b/Modules/Platform/app/Http/Middleware/EnsurePlatformAdmin.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/app/Http/Middleware/EnsureTenantAssigned.php b/Modules/Platform/app/Http/Middleware/EnsureTenantAssigned.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/app/Models/LicenseKey.php b/Modules/Platform/app/Models/LicenseKey.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/app/Models/Payment.php b/Modules/Platform/app/Models/Payment.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/app/Models/PlatformPrice.php b/Modules/Platform/app/Models/PlatformPrice.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/config/platform.php b/Modules/Platform/config/platform.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/database/migrations/2026_06_10_000000_create_platform_tables.php b/Modules/Platform/database/migrations/2026_06_10_000000_create_platform_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/database/migrations/2026_06_11_093500_create_platform_prices_table.php b/Modules/Platform/database/migrations/2026_06_11_093500_create_platform_prices_table.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/database/seeders/PlatformSeeder.php b/Modules/Platform/database/seeders/PlatformSeeder.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/module.json b/Modules/Platform/module.json old mode 100644 new mode 100755 diff --git a/Modules/Platform/resources/views/dashboard/index.blade.php b/Modules/Platform/resources/views/dashboard/index.blade.php old mode 100644 new mode 100755 index cfdfa262..7f0f85a2 --- a/Modules/Platform/resources/views/dashboard/index.blade.php +++ b/Modules/Platform/resources/views/dashboard/index.blade.php @@ -64,6 +64,7 @@

    Recent companies

    + diff --git a/Modules/Platform/resources/views/licenses/index.blade.php b/Modules/Platform/resources/views/licenses/index.blade.php old mode 100644 new mode 100755 index ed67ffe6..4c6e5421 --- a/Modules/Platform/resources/views/licenses/index.blade.php +++ b/Modules/Platform/resources/views/licenses/index.blade.php @@ -11,20 +11,22 @@

    Issue licence key

    @csrf - @foreach ($companies as $company) @endforeach - - + - + + @@ -32,6 +34,7 @@
    Data table
    + diff --git a/Modules/Platform/resources/views/partials.blade.php b/Modules/Platform/resources/views/partials.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/resources/views/payments/index.blade.php b/Modules/Platform/resources/views/payments/index.blade.php old mode 100644 new mode 100755 index 1540e5a7..0975c104 --- a/Modules/Platform/resources/views/payments/index.blade.php +++ b/Modules/Platform/resources/views/payments/index.blade.php @@ -7,24 +7,27 @@

    Add payment or override

    @csrf - @foreach ($companies as $company) @endforeach - - - + + + - + + @@ -32,6 +35,7 @@
    Data table
    Company
    + diff --git a/Modules/Platform/resources/views/prices/_form.blade.php b/Modules/Platform/resources/views/prices/_form.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/resources/views/prices/create.blade.php b/Modules/Platform/resources/views/prices/create.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/resources/views/prices/edit.blade.php b/Modules/Platform/resources/views/prices/edit.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/resources/views/prices/index.blade.php b/Modules/Platform/resources/views/prices/index.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/resources/views/prices/public.blade.php b/Modules/Platform/resources/views/prices/public.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/routes/web.php b/Modules/Platform/routes/web.php old mode 100644 new mode 100755 index fe86f8ed..af430261 --- a/Modules/Platform/routes/web.php +++ b/Modules/Platform/routes/web.php @@ -1,12 +1,12 @@ prefix('platform') diff --git a/Modules/Platform/tests/Feature/LicenseKeyTest.php b/Modules/Platform/tests/Feature/LicenseKeyTest.php old mode 100644 new mode 100755 diff --git a/Modules/Platform/tests/Feature/PlatformAccessTest.php b/Modules/Platform/tests/Feature/PlatformAccessTest.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Config/.gitkeep b/Modules/Pricing/Config/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Config/config.php b/Modules/Pricing/Config/config.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Console/.gitkeep b/Modules/Pricing/Console/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Database/Migrations/.gitkeep b/Modules/Pricing/Database/Migrations/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Database/Seeders/.gitkeep b/Modules/Pricing/Database/Seeders/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Database/Seeders/PricingDatabaseSeeder.php b/Modules/Pricing/Database/Seeders/PricingDatabaseSeeder.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Database/factories/.gitkeep b/Modules/Pricing/Database/factories/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Helpers/.gitkeep b/Modules/Pricing/Helpers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Helpers/Helper.php b/Modules/Pricing/Helpers/Helper.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Http/Controllers/.gitkeep b/Modules/Pricing/Http/Controllers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Http/Controllers/PricingController.php b/Modules/Pricing/Http/Controllers/PricingController.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Http/Middleware/.gitkeep b/Modules/Pricing/Http/Middleware/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Http/Requests/.gitkeep b/Modules/Pricing/Http/Requests/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Models/.gitkeep b/Modules/Pricing/Models/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Providers/.gitkeep b/Modules/Pricing/Providers/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Providers/PricingServiceProvider.php b/Modules/Pricing/Providers/PricingServiceProvider.php old mode 100644 new mode 100755 index 5d3efe57..8cfe694a --- a/Modules/Pricing/Providers/PricingServiceProvider.php +++ b/Modules/Pricing/Providers/PricingServiceProvider.php @@ -63,9 +63,7 @@ class PricingServiceProvider extends ServiceProvider $commandPath = __DIR__ . '/../Console'; $commands = collect(File::allFiles($commandPath)) ->map(function ($file) { - $class = 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); - - return $class; + return 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension(); }) ->filter(function ($class) { return class_exists($class); diff --git a/Modules/Pricing/Providers/RouteServiceProvider.php b/Modules/Pricing/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 index c66991f1..7ccdc4ca --- a/Modules/Pricing/Providers/RouteServiceProvider.php +++ b/Modules/Pricing/Providers/RouteServiceProvider.php @@ -14,18 +14,6 @@ class RouteServiceProvider extends ServiceProvider */ protected $moduleNamespace = 'Modules\Pricing\Http\Controllers'; - /** - * Called before routes are registered. - * - * Register any model bindings or pattern based filters. - * - * @return void - */ - public function boot() - { - parent::boot(); - } - /** * Define the routes for the application. * diff --git a/Modules/Pricing/Resources/assets/.gitkeep b/Modules/Pricing/Resources/assets/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Resources/assets/js/app.js b/Modules/Pricing/Resources/assets/js/app.js old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Resources/assets/sass/app.scss b/Modules/Pricing/Resources/assets/sass/app.scss old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Resources/lang/.gitkeep b/Modules/Pricing/Resources/lang/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Resources/views/.gitkeep b/Modules/Pricing/Resources/views/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Resources/views/index.blade.php b/Modules/Pricing/Resources/views/index.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Resources/views/layouts/master.blade.php b/Modules/Pricing/Resources/views/layouts/master.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Routes/.gitkeep b/Modules/Pricing/Routes/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Routes/api.php b/Modules/Pricing/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Routes/web.php b/Modules/Pricing/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Support/.gitkeep b/Modules/Pricing/Support/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Support/ModuleInfo.php b/Modules/Pricing/Support/ModuleInfo.php old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Tests/Browser/.gitkeep b/Modules/Pricing/Tests/Browser/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Tests/Feature/.gitkeep b/Modules/Pricing/Tests/Feature/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Tests/Unit/.gitkeep b/Modules/Pricing/Tests/Unit/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/Traits/.gitkeep b/Modules/Pricing/Traits/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/View/.gitkeep b/Modules/Pricing/View/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Pricing/composer.json b/Modules/Pricing/composer.json old mode 100644 new mode 100755 diff --git a/Modules/Pricing/module.json b/Modules/Pricing/module.json old mode 100644 new mode 100755 diff --git a/Modules/Pricing/package.json b/Modules/Pricing/package.json old mode 100644 new mode 100755 diff --git a/Modules/Pricing/webpack.mix.js b/Modules/Pricing/webpack.mix.js old mode 100644 new mode 100755 diff --git a/Modules/Replenishment/Entities/.gitkeep b/Modules/Replenishment/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Replenishment/Providers/ReplenishmentServiceProvider.php b/Modules/Replenishment/Providers/ReplenishmentServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Replenishment/README.md b/Modules/Replenishment/README.md deleted file mode 100644 index 9f06d183..00000000 --- a/Modules/Replenishment/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Replenishment - -Configure replenishment thresholds, review stock gaps, and monitor refill activity. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Replenishment/Resources/views/index.blade.php b/Modules/Replenishment/Resources/views/index.blade.php old mode 100644 new mode 100755 index c9aa2e92..7c3a27de --- a/Modules/Replenishment/Resources/views/index.blade.php +++ b/Modules/Replenishment/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    Data table
    Company
    + diff --git a/Modules/Replenishment/Resources/views/partials/nav.blade.php b/Modules/Replenishment/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Replenishment/Routes/api.php b/Modules/Replenishment/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Replenishment/Routes/web.php b/Modules/Replenishment/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Replenishment/module.json b/Modules/Replenishment/module.json old mode 100644 new mode 100755 diff --git a/Modules/Reporting/Entities/.gitkeep b/Modules/Reporting/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Reporting/Providers/ReportingServiceProvider.php b/Modules/Reporting/Providers/ReportingServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Reporting/README.md b/Modules/Reporting/README.md deleted file mode 100644 index f2a48096..00000000 --- a/Modules/Reporting/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Reporting - -Provide operational reports for closed orders, user efficiency, and transaction history. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Reporting/Resources/views/index.blade.php b/Modules/Reporting/Resources/views/index.blade.php old mode 100644 new mode 100755 index 7649efdb..0abf459b --- a/Modules/Reporting/Resources/views/index.blade.php +++ b/Modules/Reporting/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    Data table
    Item
    + diff --git a/Modules/Reporting/Resources/views/partials/nav.blade.php b/Modules/Reporting/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Reporting/Routes/api.php b/Modules/Reporting/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Reporting/Routes/web.php b/Modules/Reporting/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Reporting/module.json b/Modules/Reporting/module.json old mode 100644 new mode 100755 diff --git a/Modules/Security/Entities/.gitkeep b/Modules/Security/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Security/Providers/SecurityServiceProvider.php b/Modules/Security/Providers/SecurityServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Security/README.md b/Modules/Security/README.md deleted file mode 100644 index 8e60204f..00000000 --- a/Modules/Security/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Security - -Control roles, permissions, audit visibility, and protected administration actions. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Security/Resources/views/index.blade.php b/Modules/Security/Resources/views/index.blade.php old mode 100644 new mode 100755 index 0dd13577..a1551f80 --- a/Modules/Security/Resources/views/index.blade.php +++ b/Modules/Security/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    Data table
    Report
    + diff --git a/Modules/Security/Resources/views/partials/nav.blade.php b/Modules/Security/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Security/Routes/api.php b/Modules/Security/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Security/Routes/web.php b/Modules/Security/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Security/module.json b/Modules/Security/module.json old mode 100644 new mode 100755 diff --git a/Modules/SentinelIntegration/Entities/.gitkeep b/Modules/SentinelIntegration/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/SentinelIntegration/Providers/SentinelIntegrationServiceProvider.php b/Modules/SentinelIntegration/Providers/SentinelIntegrationServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/SentinelIntegration/README.md b/Modules/SentinelIntegration/README.md deleted file mode 100644 index 6e5114d3..00000000 --- a/Modules/SentinelIntegration/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Sentinel Integration - -Track Sentinel API activity, inbound receiver events, and interface status. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/SentinelIntegration/Resources/views/index.blade.php b/Modules/SentinelIntegration/Resources/views/index.blade.php old mode 100644 new mode 100755 index 7b8e3ad9..bfc0819f --- a/Modules/SentinelIntegration/Resources/views/index.blade.php +++ b/Modules/SentinelIntegration/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    Data table
    Area
    + diff --git a/Modules/SentinelIntegration/Resources/views/partials/nav.blade.php b/Modules/SentinelIntegration/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/SentinelIntegration/Routes/api.php b/Modules/SentinelIntegration/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/SentinelIntegration/Routes/web.php b/Modules/SentinelIntegration/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/SentinelIntegration/module.json b/Modules/SentinelIntegration/module.json old mode 100644 new mode 100755 diff --git a/Modules/Shipping/Entities/.gitkeep b/Modules/Shipping/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Shipping/Providers/ShippingServiceProvider.php b/Modules/Shipping/Providers/ShippingServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Shipping/README.md b/Modules/Shipping/README.md deleted file mode 100644 index 3fb60450..00000000 --- a/Modules/Shipping/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Shipping - -Monitor shipment activity, closed orders, pending loads, and dispatch status. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Shipping/Resources/views/index.blade.php b/Modules/Shipping/Resources/views/index.blade.php old mode 100644 new mode 100755 index fa96a324..974e3670 --- a/Modules/Shipping/Resources/views/index.blade.php +++ b/Modules/Shipping/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    Data table
    Endpoint
    + diff --git a/Modules/Shipping/Resources/views/partials/nav.blade.php b/Modules/Shipping/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Shipping/Routes/api.php b/Modules/Shipping/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Shipping/Routes/web.php b/Modules/Shipping/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Shipping/module.json b/Modules/Shipping/module.json old mode 100644 new mode 100755 diff --git a/Modules/Transportation/Entities/.gitkeep b/Modules/Transportation/Entities/.gitkeep old mode 100644 new mode 100755 diff --git a/Modules/Transportation/Providers/TransportationServiceProvider.php b/Modules/Transportation/Providers/TransportationServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Transportation/README.md b/Modules/Transportation/README.md deleted file mode 100644 index 4085f0dc..00000000 --- a/Modules/Transportation/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Transportation - -Manage truck closure, freight terms, trailers, and transport operations. - -Contains actual sample Blade views and placeholder service provider/routes only. diff --git a/Modules/Transportation/Resources/views/index.blade.php b/Modules/Transportation/Resources/views/index.blade.php old mode 100644 new mode 100755 index f9bdd3c6..65154d73 --- a/Modules/Transportation/Resources/views/index.blade.php +++ b/Modules/Transportation/Resources/views/index.blade.php @@ -64,6 +64,7 @@
    Data table
    Shipment
    + diff --git a/Modules/Transportation/Resources/views/partials/nav.blade.php b/Modules/Transportation/Resources/views/partials/nav.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Transportation/Routes/api.php b/Modules/Transportation/Routes/api.php old mode 100644 new mode 100755 diff --git a/Modules/Transportation/Routes/web.php b/Modules/Transportation/Routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Transportation/module.json b/Modules/Transportation/module.json old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/Providers/WarehouseServiceProvider.php b/Modules/Warehouse/Providers/WarehouseServiceProvider.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/app/Http/Controllers/WarehouseController.php b/Modules/Warehouse/app/Http/Controllers/WarehouseController.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/app/Http/Controllers/WarehouseDashboardController.php b/Modules/Warehouse/app/Http/Controllers/WarehouseDashboardController.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/app/Http/Controllers/WarehouseValidationRuleController.php b/Modules/Warehouse/app/Http/Controllers/WarehouseValidationRuleController.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/app/Models/Warehouse.php b/Modules/Warehouse/app/Models/Warehouse.php old mode 100644 new mode 100755 index 911211b2..6478a79e --- a/Modules/Warehouse/app/Models/Warehouse.php +++ b/Modules/Warehouse/app/Models/Warehouse.php @@ -41,7 +41,6 @@ class Warehouse extends Model return $this->belongsTo(Company::class); } - public function division(): BelongsTo { return $this->belongsTo(CompanyDivision::class, 'division_id'); diff --git a/Modules/Warehouse/app/Models/WarehouseValidationRule.php b/Modules/Warehouse/app/Models/WarehouseValidationRule.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/database/migrations/2026_06_10_000100_create_warehouse_tables.php b/Modules/Warehouse/database/migrations/2026_06_10_000100_create_warehouse_tables.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/module.json b/Modules/Warehouse/module.json old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/resources/views/rules/index.blade.php b/Modules/Warehouse/resources/views/rules/index.blade.php old mode 100644 new mode 100755 index 379f5b40..32a75521 --- a/Modules/Warehouse/resources/views/rules/index.blade.php +++ b/Modules/Warehouse/resources/views/rules/index.blade.php @@ -7,23 +7,26 @@

    Add validation rule

    @csrf - @foreach ($warehouses as $warehouse) @endforeach - - - + + + - + + @@ -32,6 +35,7 @@
    Data table
    Trailer
    + diff --git a/Modules/Warehouse/resources/views/warehouses/dashboard.blade.php b/Modules/Warehouse/resources/views/warehouses/dashboard.blade.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/resources/views/warehouses/index.blade.php b/Modules/Warehouse/resources/views/warehouses/index.blade.php old mode 100644 new mode 100755 index f53aac2e..54367b87 --- a/Modules/Warehouse/resources/views/warehouses/index.blade.php +++ b/Modules/Warehouse/resources/views/warehouses/index.blade.php @@ -7,12 +7,15 @@

    Create warehouse

    @csrf - - - + + + + + + diff --git a/Modules/Warehouse/routes/web.php b/Modules/Warehouse/routes/web.php old mode 100644 new mode 100755 diff --git a/Modules/Warehouse/tests/Feature/WarehouseIsolationTest.php b/Modules/Warehouse/tests/Feature/WarehouseIsolationTest.php old mode 100644 new mode 100755 diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php old mode 100644 new mode 100755 diff --git a/app/Actions/Fortify/PasswordValidationRules.php b/app/Actions/Fortify/PasswordValidationRules.php old mode 100644 new mode 100755 diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php old mode 100644 new mode 100755 diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php old mode 100644 new mode 100755 diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php old mode 100644 new mode 100755 diff --git a/app/Concerns/PasswordValidationRules.php b/app/Concerns/PasswordValidationRules.php old mode 100644 new mode 100755 diff --git a/app/Concerns/ProfileValidationRules.php b/app/Concerns/ProfileValidationRules.php old mode 100644 new mode 100755 diff --git a/app/Console/Commands/DatabaseStage.php b/app/Console/Commands/DatabaseStage.php new file mode 100755 index 00000000..3ca13e79 --- /dev/null +++ b/app/Console/Commands/DatabaseStage.php @@ -0,0 +1,291 @@ +localConfiguration(); + $stage = $this->stageConfiguration(); + $exitCode = self::SUCCESS; + + if (! $this->validateStageConfiguration($stage)) { + $exitCode = self::FAILURE; + } else { + [$localDump, $remoteDump] = $this->dumpPaths(); + $this->displayCloneSummary($local, $stage); + + if (! $this->confirmed($stage)) { + $this->warn('Cancelled.'); + } else { + try { + $this->runClone($local, $stage, $localDump, $remoteDump); + $this->reportSuccess($local, $stage); + } catch (\Throwable $exception) { + $this->reportFailure($exception, $localDump, $remoteDump); + $exitCode = self::FAILURE; + } + } + } + + return $exitCode; + } + + /** @return array */ + private function localConfiguration(): array + { + return [ + 'host' => config('database.connections.pgsql.host'), + 'port' => config('database.connections.pgsql.port'), + 'database' => config('database.connections.pgsql.database'), + 'username' => config('database.connections.pgsql.username'), + 'password' => config('database.connections.pgsql.password'), + ]; + } + + /** @return array */ + private function stageConfiguration(): array + { + return [ + 'ssh_host' => env('STAGE_SSH_HOST'), + 'ssh_user' => env('STAGE_SSH_USER'), + 'ssh_port' => env('STAGE_SSH_PORT', 22), + 'db_host' => env('STAGE_DB_HOST', '127.0.0.1'), + 'db_port' => env('STAGE_DB_PORT', 5432), + 'database' => env('STAGE_DB_DATABASE'), + 'username' => env('STAGE_DB_USERNAME'), + 'password' => env('STAGE_DB_PASSWORD'), + 'admin_username' => env('STAGE_DB_ADMIN_USERNAME', 'postgres'), + ]; + } + + /** @param array $stage */ + private function validateStageConfiguration(array $stage): bool + { + $required = [ + 'STAGE_SSH_HOST' => $stage['ssh_host'], + 'STAGE_SSH_USER' => $stage['ssh_user'], + 'STAGE_DB_DATABASE' => $stage['database'], + 'STAGE_DB_USERNAME' => $stage['username'], + ]; + + foreach ($required as $name => $value) { + if (! $value) { + $this->error("Missing {$name}."); + + return false; + } + } + + return true; + } + + /** @return array{string, string} */ + private function dumpPaths(): array + { + $filename = 'wms-' . now()->format('Ymd-His') . '.dump'; + + return [storage_path("app/{$filename}"), "/tmp/{$filename}"]; + } + + /** @param array $local @param array $stage */ + private function displayCloneSummary(array $local, array $stage): void + { + $this->newLine(); + $this->components->info('WMS PostgreSQL FULL CLONE โ†’ Stage'); + $this->newLine(); + $this->table(['Setting', 'Value'], [ + ['Local database', $local['database']], + ['Stage server', "{$stage['ssh_user']}@{$stage['ssh_host']}"], + ['Stage database', $stage['database']], + ['Stage owner', $stage['username']], + ]); + } + + /** @param array $stage */ + private function confirmed(array $stage): bool + { + return $this->option('force') || $this->confirm( + "This will DROP and completely RECREATE '{$stage['database']}'. Continue?", + false, + ); + } + + /** @param array $local @param array $stage */ + private function runClone(array $local, array $stage, string $localDump, string $remoteDump): void + { + $this->ensureDumpDirectory($localDump); + $this->createDump($local, $localDump); + $this->line(' Dump size: ' . number_format((int) filesize($localDump) / 1048576, 2) . ' MB'); + $this->verifyDump($localDump); + $this->uploadDump($stage, $localDump, $remoteDump); + $this->recreateStageDatabase($stage); + $this->restoreStageDatabase($stage, $remoteDump); + $this->verifyStageDatabase($stage); + $this->cleanupDumps($stage, $localDump, $remoteDump); + } + + private function ensureDumpDirectory(string $localDump): void + { + $directory = dirname($localDump); + + if (! is_dir($directory) && ! mkdir($directory, 0755, true) && ! is_dir($directory)) { + throw new DatabaseStageException("Unable to create dump directory: {$directory}"); + } + } + + /** @param array $local */ + private function createDump(array $local, string $localDump): void + { + $this->components->task('Backing up complete local PostgreSQL database', function () use ($local, $localDump): bool { + $result = Process::env(['PGPASSWORD' => $local['password']])->timeout(3600)->run([ + 'pg_dump', '--host=' . $local['host'], '--port=' . $local['port'], + '--username=' . $local['username'], '--format=custom', '--compress=9', + '--no-owner', '--no-acl', '--file=' . $localDump, $local['database'], + ]); + $this->throwWhenFailed($result->failed(), "pg_dump failed:\n" . $result->errorOutput()); + + if (! file_exists($localDump) || filesize($localDump) === 0) { + throw new DatabaseStageException('Database dump was not created or is empty.'); + } + + return true; + }); + } + + private function verifyDump(string $localDump): void + { + $this->components->task('Verifying PostgreSQL archive', function () use ($localDump): bool { + $result = Process::run(['pg_restore', '--list', $localDump]); + $this->throwWhenFailed($result->failed(), "Invalid PostgreSQL archive:\n" . $result->errorOutput()); + + return true; + }); + } + + /** @param array $stage */ + private function uploadDump(array $stage, string $localDump, string $remoteDump): void + { + $this->components->task('Uploading database backup', function () use ($stage, $localDump, $remoteDump): bool { + $result = Process::timeout(3600)->run([ + 'scp', '-P', (string) $stage['ssh_port'], $localDump, + "{$stage['ssh_user']}@{$stage['ssh_host']}:{$remoteDump}", + ]); + $this->throwWhenFailed($result->failed(), "Upload failed:\n" . $result->errorOutput()); + + return true; + }); + } + + /** @param array $stage */ + private function recreateStageDatabase(array $stage): void + { + $this->components->task('Recreating stage database', function () use ($stage): bool { + $database = '"' . str_replace('"', '""', (string) $stage['database']) . '"'; + $owner = '"' . str_replace('"', '""', (string) $stage['username']) . '"'; + $terminateDatabase = str_replace("'", "''", (string) $stage['database']); + $sql = "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '{$terminateDatabase}' AND pid <> pg_backend_pid();\n" + . "DROP DATABASE IF EXISTS {$database};\nCREATE DATABASE {$database} WITH OWNER {$owner} ENCODING 'UTF8' TEMPLATE template0;"; + $remoteCommand = sprintf( + 'sudo -u %s psql --set ON_ERROR_STOP=on --dbname=postgres', + escapeshellarg((string) $stage['admin_username']), + ); + $result = Process::input($sql)->timeout(300)->run($this->sshCommand($stage, $remoteCommand)); + $this->throwWhenFailed($result->failed(), "Unable to recreate stage database:\n" . $result->errorOutput()); + + return true; + }); + } + + /** @param array $stage */ + private function restoreStageDatabase(array $stage, string $remoteDump): void + { + $this->components->task('Restoring complete stage database', function () use ($stage, $remoteDump): bool { + $restore = sprintf( + 'PGPASSWORD=%s pg_restore --host=%s --port=%s --username=%s --dbname=%s --no-owner --no-acl --exit-on-error --verbose %s', + escapeshellarg((string) $stage['password']), + escapeshellarg((string) $stage['db_host']), + escapeshellarg((string) $stage['db_port']), + escapeshellarg((string) $stage['username']), + escapeshellarg((string) $stage['database']), + escapeshellarg($remoteDump), + ); + $result = Process::timeout(3600)->run($this->sshCommand($stage, $restore)); + $this->throwWhenFailed($result->failed(), "Database restore failed:\n" . $result->errorOutput()); + + return true; + }); + } + + /** @param array $stage */ + private function verifyStageDatabase(array $stage): void + { + $this->components->task('Verifying restored database', function () use ($stage): bool { + $command = sprintf( + 'PGPASSWORD=%s psql --host=%s --port=%s --username=%s --dbname=%s --tuples-only --command=%s', + escapeshellarg((string) $stage['password']), + escapeshellarg((string) $stage['db_host']), + escapeshellarg((string) $stage['db_port']), + escapeshellarg((string) $stage['username']), + escapeshellarg((string) $stage['database']), + escapeshellarg("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';"), + ); + $result = Process::run($this->sshCommand($stage, $command)); + $this->throwWhenFailed($result->failed(), "Database verification failed:\n" . $result->errorOutput()); + $this->line(' Stage public tables: ' . trim($result->output())); + + return true; + }); + } + + /** @param array $stage */ + private function cleanupDumps(array $stage, string $localDump, string $remoteDump): void + { + Process::run($this->sshCommand($stage, 'rm -f ' . escapeshellarg($remoteDump))); + + if (! $this->option('keep')) { + @unlink($localDump); + } + } + + /** @param array $stage @return list */ + private function sshCommand(array $stage, string $command): array + { + return ['ssh', '-p', (string) $stage['ssh_port'], "{$stage['ssh_user']}@{$stage['ssh_host']}", $command]; + } + + private function throwWhenFailed(bool $failed, string $message): void + { + if ($failed) { + throw new DatabaseStageException($message); + } + } + + private function reportFailure(\Throwable $exception, string $localDump, string $remoteDump): void + { + $this->newLine(); + $this->components->error('Database clone failed.'); + $this->error($exception->getMessage()); + $this->newLine(); + $this->warn("The dump may still exist at {$localDump} and/or {$remoteDump}."); + } + + /** @param array $local @param array $stage */ + private function reportSuccess(array $local, array $stage): void + { + $this->newLine(); + $this->components->info('Stage PostgreSQL database cloned successfully.'); + $this->line("Local {$local['database']} โ†’ Stage {$stage['database']}"); + } +} diff --git a/app/Console/Commands/ExportSource.php b/app/Console/Commands/ExportSource.php new file mode 100755 index 00000000..9be569fe --- /dev/null +++ b/app/Console/Commands/ExportSource.php @@ -0,0 +1,100 @@ +format('Ymd-His'); + $downloads = rtrim((string) getenv('HOME'), '/') . '/Downloads'; + $archive = "{$downloads}/{$project}-source-{$timestamp}.zip"; + + $this->info("Exporting {$project}..."); + + /* + * Fast export of all Git-tracked source. + */ + $result = Process::path(base_path()) + ->timeout(60) + ->run([ + 'git', + 'archive', + '--format=zip', + "--output={$archive}", + 'HEAD', + ]); + + if ($result->failed()) { + $this->error($result->errorOutput()); + + return self::FAILURE; + } + + $zip = new ZipArchive; + + if ($zip->open($archive) !== true) { + $this->error('Could not open ZIP.'); + + return self::FAILURE; + } + + /* + * Remove ONLY: + * + * node_modules + * vendor + * Provision + * .scannerwork + * contents of storage/framework + * contents of storage/logs + */ + $removeDirectories = [ + 'node_modules/', + 'vendor/', + 'Provision/', + 'provision/', + '.scannerwork/', + 'storage/framework/', + 'storage/logs/', + ]; + + for ($i = $zip->numFiles - 1; $i >= 0; $i--) { + $name = $zip->getNameIndex($i); + + foreach ($removeDirectories as $directory) { + if (str_starts_with($name, $directory)) { + $zip->deleteIndex($i); + break; + } + } + } + + /* + * Restore the storage directory structure EMPTY. + */ + $zip->addEmptyDir('storage/framework'); + $zip->addEmptyDir('storage/framework/cache'); + $zip->addEmptyDir('storage/framework/cache/data'); + $zip->addEmptyDir('storage/framework/sessions'); + $zip->addEmptyDir('storage/framework/testing'); + $zip->addEmptyDir('storage/framework/views'); + $zip->addEmptyDir('storage/logs'); + + $zip->close(); + + $this->info('Done.'); + $this->line($archive); + + return self::SUCCESS; + } +} diff --git a/app/Exceptions/DatabaseStageException.php b/app/Exceptions/DatabaseStageException.php new file mode 100755 index 00000000..1e0fabc6 --- /dev/null +++ b/app/Exceptions/DatabaseStageException.php @@ -0,0 +1,7 @@ +belongsTo(Company::class); } - public function divisions(): BelongsToMany { return $this->belongsToMany(CompanyDivision::class, 'company_division_user') diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php old mode 100644 new mode 100755 index 59599dc9..7e9603f1 --- a/app/Providers/HorizonServiceProvider.php +++ b/app/Providers/HorizonServiceProvider.php @@ -3,23 +3,10 @@ namespace App\Providers; use Illuminate\Support\Facades\Gate; -use Laravel\Horizon\Horizon; use Laravel\Horizon\HorizonApplicationServiceProvider; class HorizonServiceProvider extends HorizonApplicationServiceProvider { - /** - * Bootstrap any application services. - */ - public function boot(): void - { - parent::boot(); - - // Horizon::routeSmsNotificationsTo('15556667777'); - // Horizon::routeMailNotificationsTo('example@example.com'); - // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel'); - } - /** * Register the Horizon gate. * diff --git a/app/Providers/TenancyServiceProvider.php b/app/Providers/TenancyServiceProvider.php old mode 100644 new mode 100755 index f4c6e83b..f36b418f --- a/app/Providers/TenancyServiceProvider.php +++ b/app/Providers/TenancyServiceProvider.php @@ -95,7 +95,7 @@ class TenancyServiceProvider extends ServiceProvider public function register() { - // + // No container bindings are required; tenancy is configured through event listeners in boot(). } public function boot() diff --git a/app/Services/Charts/DashboardChartService.php b/app/Services/Charts/DashboardChartService.php old mode 100644 new mode 100755 diff --git a/app/Support/AppVersion.php b/app/Support/AppVersion.php old mode 100644 new mode 100755 diff --git a/artisan b/artisan old mode 100644 new mode 100755 diff --git a/bootstrap/app.php b/bootstrap/app.php old mode 100644 new mode 100755 diff --git a/bootstrap/providers.php b/bootstrap/providers.php old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index 91b980df..87621a82 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "php": "^8.3", "ayeo/gs1_barcode": "^1.0", "barryvdh/laravel-dompdf": "^3.1", + "deployer/deployer": "^8.0", "filament/filament": "^5.6", "filament/tables": "^5.6", "guzzlehttp/guzzle": "^7.11", @@ -33,7 +34,8 @@ "mpba/charts": "dev-main", "mpba/laravel-modules": "dev-main", "phpoffice/phpspreadsheet": "*", - "picqer/php-barcode-generator": "*", + "picqer/php-barcode-generator": "^3.3", + "pragmarx/version": "dev-master", "predis/predis": "^3.5", "ramsey/uuid": "^4.9", "robgridley/zebra": "*", @@ -195,6 +197,6 @@ "php-http/discovery": true } }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true } diff --git a/config/app.php b/config/app.php old mode 100644 new mode 100755 diff --git a/config/auth.php b/config/auth.php old mode 100644 new mode 100755 diff --git a/config/backup.php b/config/backup.php old mode 100644 new mode 100755 diff --git a/config/blade-heroicons.php b/config/blade-heroicons.php old mode 100644 new mode 100755 diff --git a/config/blade-icons.php b/config/blade-icons.php old mode 100644 new mode 100755 diff --git a/config/blaze.php b/config/blaze.php old mode 100644 new mode 100755 diff --git a/config/boost.php b/config/boost.php old mode 100644 new mode 100755 diff --git a/config/cache.php b/config/cache.php old mode 100644 new mode 100755 diff --git a/config/cashier.php b/config/cashier.php old mode 100644 new mode 100755 index 574e2ca6..7b29ce83 --- a/config/cashier.php +++ b/config/cashier.php @@ -3,8 +3,6 @@ use Laravel\Cashier\Console\WebhookCommand; use Laravel\Cashier\Invoices\DompdfInvoiceRenderer; -// use Laravel\Cashier\Invoices\LaravelPdfInvoiceRenderer; - return [ /* diff --git a/config/database.php b/config/database.php old mode 100644 new mode 100755 diff --git a/config/datatables-buttons.php b/config/datatables-buttons.php old mode 100644 new mode 100755 diff --git a/config/datatables-export.php b/config/datatables-export.php old mode 100644 new mode 100755 diff --git a/config/datatables-fractal.php b/config/datatables-fractal.php old mode 100644 new mode 100755 diff --git a/config/datatables-html.php b/config/datatables-html.php old mode 100644 new mode 100755 diff --git a/config/datatables.php b/config/datatables.php old mode 100644 new mode 100755 diff --git a/config/dompdf.php b/config/dompdf.php old mode 100644 new mode 100755 diff --git a/config/filament.php b/config/filament.php old mode 100644 new mode 100755 diff --git a/config/filesystems.php b/config/filesystems.php old mode 100644 new mode 100755 diff --git a/config/fortify.php b/config/fortify.php old mode 100644 new mode 100755 diff --git a/config/horizon.php b/config/horizon.php old mode 100644 new mode 100755 diff --git a/config/jetstream.php b/config/jetstream.php old mode 100644 new mode 100755 diff --git a/config/livewire.php b/config/livewire.php old mode 100644 new mode 100755 diff --git a/config/localization.php b/config/localization.php old mode 100644 new mode 100755 diff --git a/config/logging.php b/config/logging.php old mode 100644 new mode 100755 diff --git a/config/mail.php b/config/mail.php old mode 100644 new mode 100755 diff --git a/config/media-library.php b/config/media-library.php old mode 100644 new mode 100755 diff --git a/config/modules.php b/config/modules.php old mode 100644 new mode 100755 index 0503cc87..87341655 --- a/config/modules.php +++ b/config/modules.php @@ -71,7 +71,7 @@ return [ | */ - 'modules' => base_path('modules'), + 'modules' => base_path('Modules'), /* |-------------------------------------------------------------------------- | Modules assets path @@ -81,7 +81,7 @@ return [ | */ - 'assets' => public_path('modules'), + 'assets' => public_path('Modules'), /* |-------------------------------------------------------------------------- | The migrations path diff --git a/config/octane.php b/config/octane.php old mode 100644 new mode 100755 diff --git a/config/passkeys.php b/config/passkeys.php old mode 100644 new mode 100755 diff --git a/config/pennant.php b/config/pennant.php old mode 100644 new mode 100755 diff --git a/config/permission.php b/config/permission.php old mode 100644 new mode 100755 diff --git a/config/querydetector.php b/config/querydetector.php old mode 100644 new mode 100755 diff --git a/config/queue.php b/config/queue.php old mode 100644 new mode 100755 diff --git a/config/services.php b/config/services.php old mode 100644 new mode 100755 diff --git a/config/session.php b/config/session.php old mode 100644 new mode 100755 diff --git a/config/tenancy.php b/config/tenancy.php old mode 100644 new mode 100755 diff --git a/config/tinker.php b/config/tinker.php old mode 100644 new mode 100755 diff --git a/config/version.yml b/config/version.yml new file mode 100755 index 00000000..517768cc --- /dev/null +++ b/config/version.yml @@ -0,0 +1,62 @@ +mode: 'absorb' # or 'increment' +blade-directive: version +current: + label: v + major: 1 + minor: 1 + patch: 41 + prerelease: + buildmetadata: + commit: 100001 + timestamp: + mode: absorb + year: + month: + day: + hour: + minute: + second: + timezone: +commit: + mode: absorb + length: 6 + increment-by: 1 +git: + from: 'local' # or "remote" + commit: + local: 'git rev-parse --verify HEAD' + remote: 'git ls-remote {$repository}' + branch: refs/heads/master + repository: '' ### you can use config() to get it here: {{ config('version.git.remote.repository') }}. Do not use env() + version: + local: 'git describe' + remote: 'git ls-remote {$repository} | grep tags/ | grep -v {} | cut -d / -f 3 | sort --version-sort | tail -1' + matcher: '/^(?P
    Data table
    Warehouse