Merge branch 'trunk'

This commit is contained in:
Vincent BRIDIER 2025-09-05 10:22:15 +02:00
commit 0e504be45f
16 changed files with 51 additions and 126 deletions

View file

@ -150,44 +150,6 @@ class SyncController extends Controller
);
}
/**
* @param \Illuminate\Http\Request $request
* @return array
*/
public function getVersion(Request $request): array
{
$app_uuid = $request->app_uuid;
$app_version = $request->app_version;
$version = Setting::query()
->where('tenant_id', \tenant()->getKey())
->where('key', 'version')
->value('value');
$ShowIsActive = Setting::query()
->where('tenant_id', \tenant()->getKey())
->where('key', 'ShowIsActive')
->value('value');
try {
$client = new \GuzzleHttp\Client();
$response = $client->request(
'GET',
'https://store.ldc.fr/api/get-version?token=@P$oi6or!bL2-r%3C&app_uuid=' . $app_uuid
);
$body = $response->getBody();
$storeVersion = json_decode($body)->version;
} catch (ClientException $e) {
$storeVersion = $app_version;
}
if ($storeVersion > $app_version) {
$newApp = true;
} else {
$newApp = false;
}
return ['version' => $version, 'ShowIsActive' => $ShowIsActive, 'newApp' => $newApp];
}
/**
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
@ -220,10 +182,11 @@ class SyncController extends Controller
$exists = Storage::disk('public')
->exists(sprintf('docs/%s/%s.%s', \tenant()->getKey(), $doc['uuid'], $doc['type']));
if ($exists) {
array_push($attach, URL::temporarySignedRoute(
array_push($attach, config('app.url') . URL::temporarySignedRoute(
'docs.download',
now()->addDays(30),
['tenant' => \tenant()->getKey(), 'uuid' => $doc['uuid']]
['tenant' => \tenant()->getKey(), 'uuid' => $doc['uuid']],
false
));
array_push($filesName, $doc['title']);
} else {

View file

@ -22,8 +22,7 @@ class UpdateSettingRequest extends FormRequest
if (
$this->key === "Button1" ||
$this->key === "Button2" ||
$this->key === "Button3" ||
$this->key === "ShowIsActive"
$this->key === "Button3"
) {
return Gate::check('update', $this->route('setting'));
} else {
@ -40,9 +39,7 @@ class UpdateSettingRequest extends FormRequest
*/
protected function prepareForValidation(): void
{
if ($this->key === "ShowIsActive") {
$this->merge(['value' => intval($this->value) ? "true" : "false"]);
} elseif (
if (
$this->key === "Button1" ||
$this->key === "Button2" ||
$this->key === "Button3"

View file

@ -14,7 +14,6 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
* @property integer|null $directory_id Associated directory.
* @property integer $order Directory order.
* @property boolean $needAuthorization Directory authorization.
* @property boolean $is_system Directory system status.
* @property-read \Carbon\Carbon $created_at Created date.
* @property-read \Carbon\Carbon $updated_at Updated date.
*/
@ -32,8 +31,7 @@ class Directory extends Model
'name',
'directory_id',
'order',
'needAuthorization',
'is_system'
'needAuthorization'
];
/**
@ -53,7 +51,6 @@ class Directory extends Model
protected static function booted(): void
{
static::creating(function (self $model) {
self::setIsSystem($model);
self::setOrder($model);
});
static::deleting(function (self $model) {
@ -79,17 +76,6 @@ class Directory extends Model
) + 1;
}
/**
* Set order after the last element of the list.
*
* @param self $model
* @return void
*/
private static function setIsSystem(self $model): void
{
$model->is_system = ($model->is_system) ? $model->is_system : 0;
}
/**
* Render directories.
*
@ -146,30 +132,6 @@ class Directory extends Model
return Directory::renderDirectories($directoriesFiltered);
}
/**
* Set default settings for a specific tenant.
*
* @param \App\Models\Tenant $tenant
* @return void
*/
public function setDefaultDirectories(Tenant $tenant): void
{
// Default locked salon directory.
$directory = new self();
$directory->name = [
"fr" => "Salon",
"en" => "Salon",
"de" => "Wohnzimmer",
"nl" => "Tentoonstelling",
];
$directory->directory_id = null;
$directory->needAuthorization = (bool) 0;
$directory->is_system = (bool) 1;
$directory->order = 1;
$directory->tenant_id = $tenant->getKey();
$directory->saveOrFail();
}
// * RELATIONSHIPS
/**

View file

@ -107,8 +107,6 @@ class Setting extends Model
{
// @phpcs:disable Generic.Files.LineLength.TooLong
$array = [
['key' => 'version', 'value' => '1', 'type' => SettingTypesEnum::numeric],
['key' => 'ShowIsActive', 'value' => '0', 'type' => SettingTypesEnum::boolean],
['key' => 'MainColor', 'value' => '#FFF', 'type' => SettingTypesEnum::color],
['key' => 'SquaredLogo', 'value' => new \SplFileInfo(\resource_path('assets/settings/SquaredLogo.png')), 'type' => SettingTypesEnum::picture],
['key' => 'RectangleLogo', 'value' => new \SplFileInfo(\resource_path('assets/settings/RectangleLogo.png')), 'type' => SettingTypesEnum::picture],
@ -117,10 +115,6 @@ class Setting extends Model
['key' => 'Button1', 'value' => null, 'type' => SettingTypesEnum::directory],
['key' => 'Button2', 'value' => null, 'type' => SettingTypesEnum::directory],
['key' => 'Button3', 'value' => null, 'type' => SettingTypesEnum::directory],
['key' => 'AppStoreUUID', 'value' => 'c4ac09fd-3992-47bc-bdee-0b7f5505e873', 'type' => SettingTypesEnum::string],
['key' => 'FormSelect1', 'value' => '{"title":{"fr":"Travaille avec","en":"Work with","de":"Arbeit mit"},"values":{"pole-sable":{"fr":"P\u00f4le Sabl\u00e9","en":"P\u00f4le Sabl\u00e9","de":"P\u00f4le Sabl\u00e9"},"snv":{"fr":"SNV","en":"SNV","de":"SNV"},"pole-sud-est":{"fr":"P\u00f4le Sud-Est","en":"P\u00f4le Sud-Est","de":"P\u00f4le Sud-Est"},"aquitaine":{"fr":"Aquitaine","en":"Aquitaine","de":"Aquitaine"},"sbv":{"fr":"SBV","en":"SBV","de":"SBV"},"arrive":{"fr":"Arriv\u00e9","en":"Arriv\u00e9","de":"Arriv\u00e9"},"plusieurs-filiales":{"fr":"Plusieurs filiales","en":"Several subsidiaries","de":"Mehrere Filialen"},"autre":{"fr":"Autre","en":"Other","de":"Andere"}}}', 'type' => SettingTypesEnum::json],
['key' => 'FormSelect2', 'value' => '{"title":{"fr":"Type de commerce","en":"Type of business","de":"Art des Gesch\u00e4fts"},"values":{"commerce-de-detail":{"fr":"Commerce de d\u00e9tail","en":"Retail trade","de":"Einzelhandel"},"restauration-commerciale":{"fr":"Restauration Commerciale","en":"Commercial catering","de":"Kommerzielle Restauration"},"restauration-collective":{"fr":"Restauration Collective","en":"Collective catering","de":"Kollektiv Restauration"},"grossiste-distributeur-cash":{"fr":"Grossiste Distributeur Cash","en":"Wholesale Distributor Cash","de":"Gro\u00dfh\u00e4ndler H\u00e4ndler Cash"},"pai":{"fr":"PAI","en":"PAI","de":"PAI"},"home-freezer-center":{"fr":"Home Freezer Center","en":"Home Freezer Center","de":"Home Gefrierzentrum"},"autres":{"fr":"Autre","en":"Other","de":"Andere"}}}', 'type' => SettingTypesEnum::json],
['key' => 'FormCheck', 'value' => '[{"fr":"Frais","en":"Fresh","de":"Frisch"},{"fr":"Surgel\u00e9s","en":"Frozen food","de":"Tiefk\u00fchlkost"},{"fr":"Volailles crues","en":"Raw poultry","de":"Rohes Gefl\u00fcgel"},{"fr":"\u00c9labor\u00e9s crus","en":"Prepared raw","de":"Roh ausgearbeitet"},{"fr":"\u00c9labor\u00e9s cuits","en":"Cooked products","de":"Gekochte Elaborate"},{"fr":"Bio et Label Rouge","en":"Bio and Label Rouge","de":"Bio und Label Rouge"},{"fr":"BBC","en":"BBC","de":"BBC"},{"fr":"Halal","en":"Halal","de":"Halal"},{"fr":"Autre","en":"Other","de":"Andere"}]', 'type' => SettingTypesEnum::json],
];
// @phpcs:enable
collect($array)->map(function (array $item) use ($tenant) {

View file

@ -48,7 +48,6 @@ class Tenant extends BaseTenant implements TenantContract
static::created(function (self $model) {
(new Setting())->setDefaultSettings($model);
(new Formulary())->setDefaultFormularies($model);
(new Directory())->setDefaultDirectories($model);
self::resetCache();
});
static::updating(function (self $model) {

View file

@ -44,25 +44,23 @@ class DirectoryPolicy
/**
* Determine whether the user can update the model.
*
* @param \App\Models\User $authUser
* @param \App\Models\Directory $directory
* @param \App\Models\User $authUser
* @return boolean
*/
public function update(User $authUser, Directory $directory): bool
public function update(User $authUser): bool
{
return !$directory->is_system && UserStaticRules::restrictTenant($authUser);
return UserStaticRules::restrictTenant($authUser);
}
/**
* Determine whether the user can delete the model.
*
* @param \App\Models\User $authUser
* @param \App\Models\Directory $directory
* @param \App\Models\User $authUser
* @return boolean
*/
public function delete(User $authUser, Directory $directory): bool
public function delete(User $authUser): bool
{
return !$directory->is_system && UserStaticRules::restrictTenant($authUser);
return UserStaticRules::restrictTenant($authUser);
}
/**

View file

@ -34,7 +34,6 @@ class DirectoryFactory extends Factory
],
'directory_id' => null,
'needAuthorization' => $this->faker->boolean(50),
'is_system' => 0,
'tenant_id' => Tenant::query()->first('id'),
];
}

View file

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('directories', function (Blueprint $table) {
$table->dropColumn('is_system');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('directories', function (Blueprint $table) {
$table->boolean('is_system')->after('needAuthorization')->comment('Le dossier est-il administrable ?');
});
}
};

View file

@ -17,10 +17,7 @@ class DirectorySeeder extends Seeder
*/
public function run(): void
{
// Default "Salon" directory is created in the Tenant model.
Directory::factory(14)->create();
// Seeder for directory_authorizations table.
$directories = Directory::query()->where('needAuthorization', true)->get();
AppUser::each(function (AppUser $model) use ($directories) {

View file

@ -115,7 +115,6 @@
</rule>
<rule ref="Squiz.Commenting.PostStatementComment"/>
<rule ref="Squiz.Commenting.VariableComment"/>
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse" />
<!-- For Laravel migrations -->
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">

View file

@ -31,8 +31,7 @@
name: string[],
needAuthorization: boolean,
documents_count: number,
children: number[],
is_system: boolean,
children: number[]
},
}"
>
@ -82,7 +81,6 @@
</p>
</div>
<div
v-if="!item.is_system"
class="d-flex justify-content-end align-items-center"
>
<div class="input-group">
@ -200,7 +198,7 @@ function recursiveDir(list: DirectoryObject[], parent: number | null = null) {
return root;
}
/** Check if item is a system item before the move. */
/** Check depth before the move. */
function beforeMove({
dragItem,
pathTo,
@ -208,10 +206,6 @@ function beforeMove({
dragItem: DirectoryObject;
pathTo: number[];
}) {
if (dragItem.is_system) {
if (pathTo.length >= 2) return false;
else return true;
}
if (pathTo.length == 4) {
return false;
}

View file

@ -18,7 +18,6 @@ type DirectoryObj = {
created_at: string;
updated_at: string;
children: Array<DirectoryObj> | undefined;
is_system: boolean | null;
};
// * Laravel Paginator

View file

@ -23,15 +23,13 @@
<span>{{ $documentModel->title }}</span>
</td>
<td class="text-center align-middle">
@if(isset($documentModel->directory->is_system) && !$documentModel->directory->is_system)
<a href="{{ route('bo.directories.edit', ['tenant' => \tenant(), 'directory' => $documentModel->directory_id]) }}">
<button class="btn btn-sm btn-outline-dark"
title="{{ __('Accéder au dossier associé') }}"
data-bs-toggle="tooltip">
{{ $documentModel->directory->name['fr'] }}
</button>
</a>
@endif
<a href="{{ route('bo.directories.edit', ['tenant' => \tenant(), 'directory' => $documentModel->directory_id]) }}">
<button class="btn btn-sm btn-outline-dark"
title="{{ __('Accéder au dossier associé') }}"
data-bs-toggle="tooltip">
{{ $documentModel->directory->name['fr'] }}
</button>
</a>
</td>
<td class="text-center align-middle">
@if(!is_null($documentModel->document_id))

View file

@ -24,8 +24,7 @@
@if (Auth::user()->role->equals(\App\Enums\UserRolesEnum::admin) ||
$settingModel->key === 'Button1' ||
$settingModel->key === 'Button2' ||
$settingModel->key === 'Button3' ||
$settingModel->key === 'ShowIsActive')
$settingModel->key === 'Button3')
<tr>
<td class="text-center align-middle">
{{ $settingModel->key }}

View file

@ -29,7 +29,6 @@ Route::middleware([
Route::get('users', [SyncController::class, 'getUsers'])->name('users.index');
Route::get('directories', [SyncController::class, 'getDirectories'])->name('directories.index');
Route::get('documents', [SyncController::class, 'getDocuments'])->name('documents.index');
Route::get('version', [SyncController::class, 'getVersion'])->name('version');
Route::get('contacts/{app_user}', [SyncController::class, 'getContacts'])->name('contacts.index');
Route::post('contacts/{app_user}', [SyncController::class, 'upsertContact'])->name('contacts.upsert');
Route::delete('contacts/{app_user}', [SyncController::class, 'destroyContacts'])->name('contacts.delete');

View file

@ -110,4 +110,4 @@ Route::middleware(['web', 'admin-secure'])->name('bo.')->group(function () {
// Public files download.
Route::get('/{tenant}/docs/{uuid}/download', [DocumentController::class, 'download'])
->name('docs.download')
->middleware('signed');
->middleware('signed:relative');