M3 Integration fixes

This commit is contained in:
Mark Gregory
2026-09-21 10:14:57 +01:00
parent 4af997c465
commit 6d60cbff84
5853 changed files with 79032 additions and 1825 deletions
-14
View File
@@ -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
View File
View File
-5
View File
@@ -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.
+1
View File
@@ -64,6 +64,7 @@
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<caption class="sr-only">Data table</caption>
<thead class="table-light">
<tr>
<th>Metric</th>
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
-5
View File
@@ -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.
+1
View File
@@ -64,6 +64,7 @@
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<caption class="sr-only">Data table</caption>
<thead class="table-light">
<tr>
<th>When</th>
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
+1 -3
View File
@@ -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);
-12
View File
@@ -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.
*
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
View File
-5
View File
@@ -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.
+1
View File
@@ -64,6 +64,7 @@
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<caption class="sr-only">Data table</caption>
<thead class="table-light">
<tr>
<th>Carrier</th>
View File
View File
View File
View File
Regular → Executable
View File
+2 -3
View File
@@ -2,7 +2,6 @@
return [
'name' => 'ChatGPT',
'features' =>
[
],
'features' => [
],
];
Regular → Executable
View File
+28 -29
View File
@@ -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;
}
}
View File
View File
+1 -2
View File
@@ -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");
}
}
View File
+9
View File
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Modules\ChatGPT\Exceptions;
use RuntimeException;
final class OpenAiFileException extends RuntimeException {}
Regular → Executable
View File
+2 -1
View File
@@ -1,4 +1,5 @@
<?php
use Modules\ChatGPT\Support\ModuleInfo;
if (! function_exists('chatgpt_feature_enabled')) {
@@ -7,6 +8,6 @@ if (! function_exists('chatgpt_feature_enabled')) {
*/
function chatgpt_feature_enabled(string $key): bool
{
return (bool) config(ModuleInfo::nameLower().".features.{$key}", false);
return (bool) config(ModuleInfo::nameLower() . ".features.{$key}", false);
}
}
View File
View File
View File
View File
View File
View File
Regular → Executable
View File
+1 -1
View File
@@ -2,8 +2,8 @@
namespace Modules\ChatGPT\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ChatGptApiSetting extends Model
{
View File
+38 -38
View File
@@ -2,31 +2,29 @@
namespace Modules\ChatGPT\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Factory;
use Illuminate\Support\Facades\File;
use Modules\ChatGPT\Support\ModuleInfo;
use Config;
use Illuminate\Support\Facades\File;
use Illuminate\Support\ServiceProvider;
use Modules\ChatGPT\Support\ModuleInfo;
class ChatGPTServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
* @var string
*/
protected string $moduleName = 'ChatGPT';
/**
* @var string $moduleNameLower
* @var string
*/
protected string $moduleNameLower = 'chatgpt';
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides():array
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides(): array
{
return [];
}
@@ -36,7 +34,7 @@ class ChatGPTServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot() : void
public function boot(): void
{
$this->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;
}
}
+1 -13
View File
@@ -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.
*
View File
View File
View File
View File
View File
+11 -6
View File
@@ -65,7 +65,8 @@
</div>
<label class="inline-flex items-center gap-2 text-sm text-slate-700">
<input type="checkbox" name="is_active" value="1" checked class="rounded border-slate-300 text-blue-600 focus:ring-blue-500">
<label for="sonar-input-a09f3b253f" class="visually-hidden">is active</label>
<input type="checkbox" name="is_active" value="1" checked class="rounded border-slate-300 text-blue-600 focus:ring-blue-500" id="sonar-input-a09f3b253f">
Make active key
</label>
@@ -82,6 +83,7 @@
<div class="mt-5 overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<caption class="sr-only">Data table</caption>
<thead class="bg-slate-50 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">
<tr>
<th class="px-4 py-3">Name</th>
@@ -99,24 +101,27 @@
@csrf
@method('PUT')
<input
<label for="sonar-input-30f47d1294" class="visually-hidden">name</label>
<input
name="name"
type="text"
value="{{ old('name', $setting->name) }}"
class="w-full rounded-lg border-slate-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500"
>
id="name">
<input
<label for="sonar-input-707eb8d2ba" class="visually-hidden">Leave blank to keep existing key</label>
<input
name="api_key"
type="password"
value=""
autocomplete="new-password"
placeholder="Leave blank to keep existing key"
class="w-full rounded-lg border-slate-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500"
>
id="sonar-input-707eb8d2ba">
<label class="inline-flex items-center gap-2 text-xs text-slate-600">
<input
<label for="sonar-input-da782f0360" class="visually-hidden">is active</label>
<input
type="checkbox"
name="is_active"
value="1"
View File
Regular → Executable
View File
Regular → Executable
+1 -1
View File
@@ -15,4 +15,4 @@ use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/chatgpt', function (Request $request) {
return $request->user();
});
});
Regular → Executable
View File
+5 -7
View File
@@ -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(),
Regular → Executable
View File
+3 -1
View File
@@ -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
View File

Some files were not shown because too many files have changed in this diff Show More