diff --git a/.env.example b/.env.example
index 479a50a..0152884 100644
--- a/.env.example
+++ b/.env.example
@@ -36,8 +36,6 @@ MAIL_ADMIN=equipe.web@ldc.fr
# Sentry
SENTRY_LARAVEL_DSN=
-LDC_STATUS_CHECKER_API_KEY=
-
# ADMIN SECURE
# - API ENDPOINT (Optional)
LDC_WEB_API_ENDPOINT=
@@ -45,3 +43,7 @@ LDC_WEB_API_ENDPOINT=
LDC_WEB_API_KEY=
# - LIST SEPARATED WITH ',' (Optional)
LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=
+
+# GITLAB API
+GITLAB_URL=
+GITLAB_TOKEN=
diff --git a/app/Enums/Invoices/InvoiceStatusEnum.php b/app/Enums/Invoices/InvoiceStatusEnum.php
new file mode 100644
index 0000000..f9e0163
--- /dev/null
+++ b/app/Enums/Invoices/InvoiceStatusEnum.php
@@ -0,0 +1,25 @@
+name => "Ouvert (nouveaux ou en cours)",
+ self::refused->name => "Refusé (par le client ou aucune réponse de sa part)",
+ self::canceled->name => "Annulé (supprimé)",
+ self::archived->name => "Archivé (validé et envoyé à la comptabilité)",
+ ];
+}
diff --git a/app/Enums/Invoice/TaskTypeEnum.php b/app/Enums/Invoices/TaskTypeEnum.php
similarity index 97%
rename from app/Enums/Invoice/TaskTypeEnum.php
rename to app/Enums/Invoices/TaskTypeEnum.php
index 1420f20..2b6c0b7 100644
--- a/app/Enums/Invoice/TaskTypeEnum.php
+++ b/app/Enums/Invoices/TaskTypeEnum.php
@@ -1,6 +1,6 @@
name => "Olivier LEGAT",
+ ];
+}
diff --git a/app/Http/Controllers/Bo/InvoiceController.php b/app/Http/Controllers/Bo/InvoiceController.php
index 87fb954..489e6ab 100644
--- a/app/Http/Controllers/Bo/InvoiceController.php
+++ b/app/Http/Controllers/Bo/InvoiceController.php
@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Bo;
+use App\Enums\Invoices\InvoiceStatusEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\Invoices\StoreInvoiceRequest;
use App\Http\Requests\Bo\Invoices\UpdateInvoiceRequest;
@@ -26,6 +27,10 @@ class InvoiceController extends Controller
{
/** @var \Illuminate\Database\Eloquent\Builder $invoiceModels */
$invoiceModels = Invoice::query();
+ $status = intval($request->status);
+ $invoiceModels = $invoiceModels->when($status, function ($query) use ($status) {
+ $query->where('status', $status);
+ });
/** @var string $search Search field */
$search = $request->search;
@@ -46,7 +51,7 @@ class InvoiceController extends Controller
/** Custom pagination */
$invoiceModels = $this->customPaginate($invoiceModels, $request->pagination);
- return view('bo.pages.invoices.index', compact('invoiceModels', 'search', 'searchFields'));
+ return view('bo.pages.invoices.index', compact('invoiceModels', 'search', 'searchFields', 'status'));
}
/**
@@ -79,6 +84,7 @@ class InvoiceController extends Controller
'packageModels' => $packageModels,
'siteModels' => $siteModels,
'companyModels' => $companyModels,
+ 'invoiceStatusArray' => $invoice->getInvoiceStatusArray($invoice),
]);
}
@@ -130,6 +136,7 @@ class InvoiceController extends Controller
'packageModels' => $packageModels,
'siteModels' => $siteModels,
'companyModels' => $companyModels,
+ 'invoiceStatusArray' => $invoice->getInvoiceStatusArray($invoice),
]);
}
@@ -143,12 +150,7 @@ class InvoiceController extends Controller
public function update(UpdateInvoiceRequest $request, Invoice $invoice): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $invoice) {
- if (isset($invoice->signed_date)) {
- $fields = $request->safe()->only('signed_date', 'sent_client_date', 'sent_accounting_date');
- } else {
- $fields = $request->validated();
- }
- $invoice->fill($fields);
+ $invoice->fill(($invoice->status->value === InvoiceStatusEnum::opened->value) ? $request->validated() : []);
if ($invoice->saveOrFail()) {
return redirect()
->route('bo.invoices.edit', $invoice)
diff --git a/app/Http/Controllers/Bo/SiteController.php b/app/Http/Controllers/Bo/SiteController.php
index 49aca29..f19c2da 100644
--- a/app/Http/Controllers/Bo/SiteController.php
+++ b/app/Http/Controllers/Bo/SiteController.php
@@ -129,7 +129,7 @@ class SiteController extends Controller
{
return DB::transaction(function () use ($request, $site) {
$site->fill($request->validated());
- $site->users()->attach(collect($request->validated('users'))->pluck('id'));
+ $site->users()->sync(collect($request->validated('users'))->pluck('id'));
if ($site->saveOrFail()) {
return redirect()
->route('bo.sites.edit', $site)
diff --git a/app/Http/Controllers/Bo/TicketController.php b/app/Http/Controllers/Bo/TicketController.php
index 506918c..c270fe6 100644
--- a/app/Http/Controllers/Bo/TicketController.php
+++ b/app/Http/Controllers/Bo/TicketController.php
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Bo;
use App\Enums\Tickets\TicketStatusEnum;
use App\Enums\Tickets\TicketTypeEnum;
+use App\Enums\Users\GitlabUsersEnum;
use App\Events\NotifySubscriptions;
use App\Events\TicketStatusChanged;
use App\Http\Controllers\Controller;
@@ -21,6 +22,7 @@ use App\Models\Message;
use App\Models\Site;
use App\Models\Ticket;
use App\Models\User;
+use GrahamCampbell\GitLab\Facades\GitLab;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -541,7 +543,7 @@ class TicketController extends Controller
Session::get('tickets.sort_way')
);
} else {
- $tickets->orderBy('id', 'DESC');
+ $tickets->orderBy('last_activity', 'DESC');
}
return $tickets;
}
@@ -624,4 +626,82 @@ class TicketController extends Controller
);
});
}
+
+ /**
+ * Create a gitlab issue from a ticket.
+ *
+ * @param \App\Models\Ticket $ticket
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function createGitlabIssue(Ticket $ticket)
+ {
+ $gitlabRepoId = $ticket->site->gitlab_project_id;
+ $description = \sprintf("%s
", $ticket->text);
+ $cLabel = match ($ticket->type) {
+ TicketTypeEnum::bug => 'c-bug',
+ TicketTypeEnum::evolution => 'c-feature',
+ };
+
+ try {
+ if (!\is_null($ticket->file)) {
+ $uploadedFile = GitLab::projects()->uploadFile($gitlabRepoId, $ticket->file);
+ $description .= $this->formatGitlabFiles($ticket, $uploadedFile, 1);
+ }
+
+ if (!\is_null($ticket->file2)) {
+ $uploadedFile2 = GitLab::projects()->uploadFile($gitlabRepoId, $ticket->file2);
+ $description .= $this->formatGitlabFiles($ticket, $uploadedFile2, 2);
+ }
+
+ $issue = GitLab::issues()->create($gitlabRepoId, [
+ 'title' => 'ts-' . $ticket->id,
+ 'description' => $description,
+ 'labels' => \implode(",", [
+ 'c-support',
+ $cLabel
+ ]),
+ 'assignee_id' => GitlabUsersEnum::olivier,
+ ]);
+ } catch (\Exception $e) {
+ \report($e);
+ return back()->with('error', \trans("Une erreur est survenue"));
+ } catch (\Throwable $e) {
+ \report($e);
+ return back()->with('error', \trans("Une erreur est survenue"));
+ } //end try
+
+ $ticket->gitlab_issue = $issue['web_url'];
+ $ticket->save();
+
+ return back()->with(
+ 'success',
+ trans("L'issue a été créée sur Gitlab.")
+ );
+ }
+
+ /**
+ * Format files for Gitlab issues
+ *
+ * @param \App\Models\Ticket $ticket
+ * @param array $uploadedFile
+ * @param integer $fileNb
+ * @return string
+ */
+ private function formatGitlabFiles(Ticket $ticket, array $uploadedFile, int $fileNb)
+ {
+ if (Str::endsWith($ticket->file, ['jpg', 'png', 'jpeg'])) {
+ $file = \sprintf(
+ "",
+ $fileNb,
+ $uploadedFile['url']
+ );
+ } else {
+ $file = \sprintf(
+ '%s',
+ $uploadedFile['url'],
+ __('Lien vers le fichier'),
+ );
+ }
+ return \sprintf("
Fichier %d :
%s
", $fileNb, $file);
+ }
}
diff --git a/app/Http/Controllers/Bo/UserController.php b/app/Http/Controllers/Bo/UserController.php
index 1b2bb1d..b5e0cd4 100644
--- a/app/Http/Controllers/Bo/UserController.php
+++ b/app/Http/Controllers/Bo/UserController.php
@@ -120,10 +120,7 @@ class UserController extends Controller
{
return DB::transaction(function () use ($request, $user) {
$user->fill($request->safe()->except(['sites']));
- $user->sites()->detach();
- if (collect($request->validated('sites'))->pluck('id')) {
- $user->sites()->attach(collect($request->validated('sites'))->pluck('id'));
- }
+ $user->sites()->sync(collect($request->validated('sites'))->pluck('id'));
if ($user->saveOrFail()) {
return redirect()
->route('bo.users.edit', $user)
diff --git a/app/Http/Requests/Bo/Invoices/StoreInvoiceRequest.php b/app/Http/Requests/Bo/Invoices/StoreInvoiceRequest.php
index 824a742..d20ddd9 100644
--- a/app/Http/Requests/Bo/Invoices/StoreInvoiceRequest.php
+++ b/app/Http/Requests/Bo/Invoices/StoreInvoiceRequest.php
@@ -2,7 +2,7 @@
namespace App\Http\Requests\Bo\Invoices;
-use App\Enums\Invoice\TaskTypeEnum;
+use App\Enums\Invoices\TaskTypeEnum;
use App\Models\Invoice;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
@@ -90,7 +90,8 @@ class StoreInvoiceRequest extends FormRequest
'invoiced_to_id' => trans('Entité à facturer'),
'signed_date' => trans('Date de signature du Devis'),
'sent_client_date' => trans('Date d\'envoi du Devis au client'),
- 'sent_accounting_date' => trans('Date d\'envoi du Devis à la compta'),
+ 'sent_accounting_date' => trans('Date d\'envoi du Devis à la comptabilité'),
+ 'status' => trans('État du devis'),
];
}
}
diff --git a/app/Http/Requests/Bo/Invoices/UpdateInvoiceRequest.php b/app/Http/Requests/Bo/Invoices/UpdateInvoiceRequest.php
index bef04c2..338d9eb 100644
--- a/app/Http/Requests/Bo/Invoices/UpdateInvoiceRequest.php
+++ b/app/Http/Requests/Bo/Invoices/UpdateInvoiceRequest.php
@@ -2,6 +2,9 @@
namespace App\Http\Requests\Bo\Invoices;
+use App\Enums\Invoices\InvoiceStatusEnum;
+use Illuminate\Validation\Rules\Enum;
+
class UpdateInvoiceRequest extends StoreInvoiceRequest
{
/**
@@ -12,14 +15,34 @@ class UpdateInvoiceRequest extends StoreInvoiceRequest
public function rules()
{
$rules = [];
- if (!$this->route('invoice')->signed_date) {
- $rules = array_merge($rules, parent::rules());
- }
- $rules = array_merge($rules, [
- 'signed_date' => 'sometimes|nullable|date',
- 'sent_client_date' => 'sometimes|nullable|date',
- 'sent_accounting_date' => 'sometimes|nullable|date',
- ]);
+ $model = $this->route('invoice');
+ if ($model->status->value === InvoiceStatusEnum::opened->value) {
+ if (!$model->sent_client_date) {
+ $rules = array_merge($rules, parent::rules());
+ }
+ $rules = array_merge($rules, [
+ 'sent_client_date' => 'required_with:signed_date,sent_accounting_date|sometimes|nullable|date',
+ 'signed_date' => 'required_with:sent_accounting_date|sometimes|nullable|date',
+ 'sent_accounting_date' => 'sometimes|nullable|date',
+ 'status' => [
+ 'required',
+ new Enum(InvoiceStatusEnum::class),
+ //phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
+ function ($attribute, $value, $fail) use ($model) {
+ if (
+ (intval($value) === InvoiceStatusEnum::archived->value) &&
+ (is_null($model->sent_client_date) ||
+ is_null($model->signed_date) ||
+ is_null($model->sent_accounting_date))
+ ) {
+ $fail(__('Le status :status doit être assigné lorsque les 3 dates sont saisies', [
+ 'status' => InvoiceStatusEnum::archived->label()
+ ]));
+ }
+ },
+ ],
+ ]);
+ } //end if
return $rules;
}
}
diff --git a/app/Http/Requests/Bo/Sites/StoreSiteRequest.php b/app/Http/Requests/Bo/Sites/StoreSiteRequest.php
index e85e410..44b5a2d 100644
--- a/app/Http/Requests/Bo/Sites/StoreSiteRequest.php
+++ b/app/Http/Requests/Bo/Sites/StoreSiteRequest.php
@@ -27,7 +27,8 @@ class StoreSiteRequest extends FormRequest
return [
'name' => 'required|string|min:3|max:255',
'users' => 'nullable|array',
- 'users.*.id' => 'required|exists:users,id'
+ 'users.*.id' => 'required|exists:users,id',
+ 'gitlab_project_id' => 'nullable|unique:sites,gitlab_project_id'
];
}
@@ -42,6 +43,7 @@ class StoreSiteRequest extends FormRequest
'name' => trans('Nom du site'),
'users' => trans('Utilisateurs associés au site'),
'users.*.id' => trans('Élément parmis les Utilisateurs associés au site'),
+ 'gitlab_project_id' => trans('ID du dépôt Gitlab')
];
}
}
diff --git a/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php b/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php
index 2f665be..56899c7 100644
--- a/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php
+++ b/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php
@@ -4,4 +4,15 @@ namespace App\Http\Requests\Bo\Sites;
class UpdateSiteRequest extends StoreSiteRequest
{
+ /**
+ * Get the validation rules that apply to the request.
+ *
+ * @return array
+ */
+ public function rules()
+ {
+ return array_merge(parent::rules(), [
+ 'gitlab_project_id' => 'nullable|unique:sites,gitlab_project_id,' . $this->route('site')->id . ',id',
+ ]);
+ }
}
diff --git a/app/Models/Company.php b/app/Models/Company.php
index 06b583b..63cd49d 100644
--- a/app/Models/Company.php
+++ b/app/Models/Company.php
@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Casts\Attribute;
/**
* @property string $name
@@ -21,6 +22,15 @@ class Company extends Model
'name'
];
+ /**
+ * The accessors to append to the model's array form.
+ *
+ * @var array
+ */
+ protected $appends = [
+ 'value'
+ ];
+
/**
* HasMany Invoices
*
@@ -30,4 +40,16 @@ class Company extends Model
{
return $this->hasMany(Invoice::class);
}
+
+ /**
+ * Return value attribute for belongsto search component
+ *
+ * @return \Illuminate\Database\Eloquent\Casts\Attribute
+ */
+ protected function value(): Attribute
+ {
+ return new Attribute(
+ get: fn () => $this->id,
+ );
+ }
}
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index 90abab3..44c5ca3 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -2,7 +2,8 @@
namespace App\Models;
-use App\Enums\Invoice\TaskTypeEnum;
+use App\Enums\Invoices\TaskTypeEnum;
+use App\Enums\Invoices\InvoiceStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
@@ -26,6 +27,7 @@ use Mccarlosen\LaravelMpdf\LaravelMpdf;
* @property Site $site_id
* @property Company $company_id
* @property Company $invoiced_to_id
+ * @property InvoiceStatusEnum $status
*/
class Invoice extends Model
{
@@ -51,7 +53,8 @@ class Invoice extends Model
'sent_accounting_date',
'site_id',
'company_id',
- 'invoiced_to_id'
+ 'invoiced_to_id',
+ 'status',
];
/**
@@ -64,6 +67,7 @@ class Invoice extends Model
'signed_date' => 'date',
'sent_client_date' => 'date',
'sent_accounting_date' => 'date',
+ 'status' => InvoiceStatusEnum::class,
];
/**
@@ -92,6 +96,7 @@ class Invoice extends Model
->reduce(function ($previous, array $task) {
return \floatval($task['amount']) + \floatval($previous);
});
+ $model->status = InvoiceStatusEnum::opened;
});
static::updating(function (self $model) {
$model->total_days = collect($model->tasks)
@@ -215,4 +220,36 @@ class Invoice extends Model
);
return $pdf;
}
+
+ /**
+ * Get the invoice status array depending to the dates entered.
+ *
+ * @param \App\Models\Invoice $invoice
+ * @return array
+ */
+ public static function getInvoiceStatusArray(Invoice $invoice): array
+ {
+ $invoiceStatusArray = [];
+ if ($invoice->signed_date && $invoice->sent_client_date && $invoice->sent_accounting_date) {
+ return array_merge($invoiceStatusArray, [
+ InvoiceStatusEnum::toArray()['opened'],
+ InvoiceStatusEnum::toArray()['archived'],
+ ]);
+ }
+ if ($invoice->signed_date) {
+ return array_merge($invoiceStatusArray, [
+ InvoiceStatusEnum::toArray()['opened']
+ ]);
+ }
+ if ($invoice->sent_client_date) {
+ return array_merge($invoiceStatusArray, [
+ InvoiceStatusEnum::toArray()['opened'],
+ InvoiceStatusEnum::toArray()['refused'],
+ ]);
+ }
+ return array_merge($invoiceStatusArray, [
+ InvoiceStatusEnum::toArray()['opened'],
+ InvoiceStatusEnum::toArray()['canceled'],
+ ]);
+ }
}
diff --git a/app/Models/Message.php b/app/Models/Message.php
index ae3887c..41daedd 100644
--- a/app/Models/Message.php
+++ b/app/Models/Message.php
@@ -51,7 +51,9 @@ class Message extends Model
$q->withTrashed();
}]);
/** @var \App\Models\Ticket $ticket */
- $ticket = $message->ticket;
+ $ticket = $message->ticket;
+ $ticket->last_activity = $message->updated_at;
+ $ticket->saveQuietly();
if ($message->user) {
$ticket->load(['user' => function ($q) {
$q->withTrashed();
diff --git a/app/Models/Site.php b/app/Models/Site.php
index 89c2581..d90b579 100644
--- a/app/Models/Site.php
+++ b/app/Models/Site.php
@@ -4,10 +4,12 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Casts\Attribute;
/**
- * @property string $name
- * @property Brand $brand_id
+ * @property string $name
+ * @property integer $gitlab_project_id
+ * @property Brand $brand_id
*/
class Site extends Model
{
@@ -20,6 +22,16 @@ class Site extends Model
*/
protected $fillable = [
'name',
+ 'gitlab_project_id'
+ ];
+
+ /**
+ * The accessors to append to the model's array form.
+ *
+ * @var array
+ */
+ protected $appends = [
+ 'value'
];
// * RELATIONSHIPS
@@ -64,4 +76,16 @@ class Site extends Model
{
return $this->belongsTo(Project::class);
}
+
+ /**
+ * Return value attribute for belongsto search component
+ *
+ * @return \Illuminate\Database\Eloquent\Casts\Attribute
+ */
+ protected function value(): Attribute
+ {
+ return new Attribute(
+ get: fn () => $this->id,
+ );
+ }
}
diff --git a/app/Models/Ticket.php b/app/Models/Ticket.php
index ba3b00a..899e558 100644
--- a/app/Models/Ticket.php
+++ b/app/Models/Ticket.php
@@ -33,7 +33,8 @@ class Ticket extends Model
'type',
'status',
'text',
- 'is_internal'
+ 'is_internal',
+ 'last_activity',
];
/**
@@ -44,7 +45,8 @@ class Ticket extends Model
protected $casts = [
'is_internal' => 'bool',
'type' => TicketTypeEnum::class,
- 'status' => TicketStatusEnum::class
+ 'status' => TicketStatusEnum::class,
+ 'last_activity' => 'timestamp',
];
/**
diff --git a/app/Policies/TicketPolicy.php b/app/Policies/TicketPolicy.php
index 1b8c828..bcb8074 100644
--- a/app/Policies/TicketPolicy.php
+++ b/app/Policies/TicketPolicy.php
@@ -3,6 +3,7 @@
namespace App\Policies;
use App\Enums\Tickets\TicketStatusEnum;
+use App\Enums\Tickets\TicketTypeEnum;
use App\Enums\Users\RoleEnum;
use App\Models\Ticket;
use App\Models\User;
@@ -260,4 +261,19 @@ class TicketPolicy
return $user->role->equals(RoleEnum::developper)
&& $ticket->estimation()->exists();
}
+
+ /**
+ * Determine if the user can create a gitlab issue from a given ticket.
+ *
+ * @param \App\Models\User $user
+ * @param \App\Models\Ticket $ticket
+ * @return boolean
+ */
+ public function createGitlabIssue(User $user, Ticket $ticket)
+ {
+ return $user->role->equals(RoleEnum::developper)
+ && ($ticket->type->equals(TicketTypeEnum::bug) || $ticket->type->equals(TicketTypeEnum::evolution))
+ && !\is_null($ticket->site->gitlab_project_id)
+ && \is_null($ticket->gitlab_issue);
+ }
}
diff --git a/composer.json b/composer.json
index 543b3d2..7e0f231 100644
--- a/composer.json
+++ b/composer.json
@@ -13,6 +13,7 @@
"carlos-meneses/laravel-mpdf": "^2.1",
"diglactic/laravel-breadcrumbs": "^8.0",
"doctrine/dbal": "^3.1",
+ "graham-campbell/gitlab": "^7.0",
"guzzlehttp/guzzle": "^7.2",
"laravel-lang/lang": "~8.0",
"laravel-validation-rules/colour": "^1.6",
@@ -20,7 +21,6 @@
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"ldc/web-admin-secure-laravel": "^2.0",
- "ldc/web-status-checker-laravel": "^1.0",
"mews/purifier": "^3.4",
"sentry/sentry-laravel": "*",
"uwil/k8s-laravel": "^1.2"
diff --git a/composer.lock b/composer.lock
index 59be3f3..4410ac9 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "8b8d80affdf1ee455767d5e675bf5fe8",
+ "content-hash": "4f5fe189b89c5ccc99fc4c7a913a64a6",
"packages": [
{
"name": "brick/math",
@@ -1251,6 +1251,228 @@
],
"time": "2022-02-20T15:07:15+00:00"
},
+ {
+ "name": "graham-campbell/bounded-cache",
+ "version": "v2.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GrahamCampbell/Bounded-Cache.git",
+ "reference": "2840f46f38185e610e62af3662dac75ca1877a84"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/GrahamCampbell/Bounded-Cache/zipball/2840f46f38185e610e62af3662dac75ca1877a84",
+ "reference": "2840f46f38185e610e62af3662dac75ca1877a84",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0.2",
+ "psr/simple-cache": "^2.0 || ^3.0"
+ },
+ "require-dev": {
+ "graham-campbell/analyzer": "^4.0",
+ "graham-campbell/testbench-core": "^4.0",
+ "mockery/mockery": "^1.5.1",
+ "phpunit/phpunit": "^9.6.3 || ^10.0.12"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "GrahamCampbell\\BoundedCache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ }
+ ],
+ "description": "A Bounded TTL PSR-16 Cache Implementation",
+ "keywords": [
+ "Bounded Cache",
+ "Bounded-Cache",
+ "Graham Campbell",
+ "GrahamCampbell",
+ "bounded",
+ "cache",
+ "psr16"
+ ],
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Bounded-Cache/issues",
+ "source": "https://github.com/GrahamCampbell/Bounded-Cache/tree/v2.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/bounded-cache",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-25T23:00:30+00:00"
+ },
+ {
+ "name": "graham-campbell/gitlab",
+ "version": "v7.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GrahamCampbell/Laravel-GitLab.git",
+ "reference": "fb037dedadacb16e4ab75b8bab58b52b703a4e33"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-GitLab/zipball/fb037dedadacb16e4ab75b8bab58b52b703a4e33",
+ "reference": "fb037dedadacb16e4ab75b8bab58b52b703a4e33",
+ "shasum": ""
+ },
+ "require": {
+ "graham-campbell/bounded-cache": "^1.2 || ^2.0",
+ "graham-campbell/manager": "^5.0",
+ "guzzlehttp/guzzle": "^7.5",
+ "guzzlehttp/psr7": "^2.4",
+ "illuminate/contracts": "^8.75 || ^9.0 || ^10.0",
+ "illuminate/support": "^8.75 || ^9.0 || ^10.0",
+ "m4tthumphrey/php-gitlab-api": "11.9.*",
+ "php": "^7.4.15 || ^8.0.2",
+ "symfony/cache": "^5.4 || ^6.0"
+ },
+ "require-dev": {
+ "graham-campbell/analyzer": "^4.0",
+ "graham-campbell/testbench": "^6.0",
+ "mockery/mockery": "^1.5.1",
+ "phpunit/phpunit": "^9.6.3 || ^10.0.12"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "GrahamCampbell\\GitLab\\GitLabServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GrahamCampbell\\GitLab\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ }
+ ],
+ "description": "GitLab Is A GitLab Bridge For Laravel",
+ "keywords": [
+ "Bridge",
+ "Graham Campbell",
+ "GrahamCampbell",
+ "Laravel GitLab",
+ "Laravel-GitLab",
+ "PHP GitLab API",
+ "framework",
+ "gitlab",
+ "gitlab bridge",
+ "laravel",
+ "php-gitlab-api"
+ ],
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-GitLab/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-GitLab/tree/v7.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/gitlab",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-07T11:41:34+00:00"
+ },
+ {
+ "name": "graham-campbell/manager",
+ "version": "v5.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GrahamCampbell/Laravel-Manager.git",
+ "reference": "f1cf95a0bb11ba086387b8049e0e40b82d01588d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Manager/zipball/f1cf95a0bb11ba086387b8049e0e40b82d01588d",
+ "reference": "f1cf95a0bb11ba086387b8049e0e40b82d01588d",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/contracts": "^8.75 || ^9.0 || ^10.0",
+ "illuminate/support": "^8.75 || ^9.0 || ^10.0",
+ "php": "^7.4.15 || ^8.0.2"
+ },
+ "require-dev": {
+ "graham-campbell/analyzer": "^4.0",
+ "graham-campbell/testbench-core": "^4.0",
+ "mockery/mockery": "^1.5.1",
+ "phpunit/phpunit": "^9.6.3 || ^10.0.12"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "GrahamCampbell\\Manager\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ }
+ ],
+ "description": "Manager Provides Some Manager Functionality For Laravel",
+ "keywords": [
+ "Graham Campbell",
+ "GrahamCampbell",
+ "Laravel Manager",
+ "Laravel-Manager",
+ "connector",
+ "framework",
+ "interface",
+ "laravel",
+ "manager"
+ ],
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-Manager/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-Manager/tree/v5.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/manager",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-25T23:53:34+00:00"
+ },
{
"name": "graham-campbell/result-type",
"version": "v1.1.1",
@@ -2400,113 +2622,6 @@
],
"description": "Restrict access to LDC Network"
},
- {
- "name": "ldc/web-status-checker",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://lab.s-web.fr/ldc-web/projets/ldc-web-status-checker.git",
- "reference": "7ce62449f3eb052de2d7bfa2e32d37d4524d60b0"
- },
- "dist": {
- "type": "zip",
- "url": "https://lab.s-web.fr/api/v4/projects/21/packages/composer/archives/ldc/web-status-checker.zip?sha=7ce62449f3eb052de2d7bfa2e32d37d4524d60b0",
- "reference": "7ce62449f3eb052de2d7bfa2e32d37d4524d60b0",
- "shasum": ""
- },
- "require": {
- "ext-curl": "*",
- "php": "~7.3|7.4|~8"
- },
- "require-dev": {
- "slevomat/coding-standard": "^7.0",
- "squizlabs/php_codesniffer": "^3.5"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "LDC\\WebStatusChecker\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "LDC\\WebStatusChecker\\Tests\\": "tests"
- }
- },
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jérémy Munsch",
- "email": "jeremy.munsch@ldc.fr",
- "homepage": "https://jeremydev.ovh"
- }
- ],
- "description": "Status checker: report status to ldc-web"
- },
- {
- "name": "ldc/web-status-checker-laravel",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://lab.s-web.fr/ldc-web/projets/ldc-web-status-checker-laravel.git",
- "reference": "3918891846f1e8440ba54b23dc47422f005070b9"
- },
- "dist": {
- "type": "zip",
- "url": "https://lab.s-web.fr/api/v4/projects/22/packages/composer/archives/ldc/web-status-checker-laravel.zip?sha=3918891846f1e8440ba54b23dc47422f005070b9",
- "reference": "3918891846f1e8440ba54b23dc47422f005070b9",
- "shasum": ""
- },
- "require": {
- "illuminate/support": "~8|~9|~10",
- "laravel/framework": "~8|~9|~10",
- "ldc/web-status-checker": "^1.1.0",
- "php": "~7.3|7.4|~8"
- },
- "require-dev": {
- "slevomat/coding-standard": "^7.0",
- "squizlabs/php_codesniffer": "^3.5"
- },
- "type": "library",
- "extra": {
- "laravel": {
- "providers": [
- "LDC\\WebStatusCheckerLaravel\\StatusCheckerServiceProvider"
- ]
- }
- },
- "autoload": {
- "psr-4": {
- "LDC\\WebStatusCheckerLaravel\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "LDC\\WebStatusCheckerLaravel\\Tests\\": "tests"
- }
- },
- "scripts": {
- "test": [
- "vendor/bin/phpunit"
- ],
- "post-autoload-dump": [
- "@php ./vendor/bin/testbench package:discover --ansi"
- ]
- },
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jérémy Munsch",
- "email": "jeremy.munsch@ldc.fr",
- "homepage": "https://jeremydev.ovh"
- }
- ],
- "description": "Status checker: report status to ldc-web"
- },
{
"name": "league/commonmark",
"version": "2.4.0",
@@ -2899,6 +3014,96 @@
],
"time": "2022-04-17T13:12:02+00:00"
},
+ {
+ "name": "m4tthumphrey/php-gitlab-api",
+ "version": "11.9.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GitLabPHP/Client.git",
+ "reference": "148ed10609f92e03afbf756e734ee4b76be36832"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/GitLabPHP/Client/zipball/148ed10609f92e03afbf756e734ee4b76be36832",
+ "reference": "148ed10609f92e03afbf756e734ee4b76be36832",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-xml": "*",
+ "php": "^7.4.15 || ^8.0.2",
+ "php-http/cache-plugin": "^1.7.5",
+ "php-http/client-common": "^2.6",
+ "php-http/discovery": "^1.15",
+ "php-http/httplug": "^2.3",
+ "php-http/multipart-stream-builder": "^1.2",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0",
+ "psr/http-client-implementation": "^1.0",
+ "psr/http-factory-implementation": "^1.0",
+ "psr/http-message": "^1.0",
+ "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0",
+ "symfony/polyfill-php80": "^1.26"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "guzzlehttp/guzzle": "^7.5",
+ "http-interop/http-factory-guzzle": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Gitlab\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Bourigault",
+ "email": "bourigaultfabien@gmail.com",
+ "homepage": "https://github.com/fbourigault"
+ },
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Matt Humphrey",
+ "email": "matth@windsor-telecom.co.uk",
+ "homepage": "https://github.com/m4tthumphrey"
+ },
+ {
+ "name": "Miguel Piedrafita",
+ "email": "github@miguelpiedrafita.com",
+ "homepage": "https://github.com/m1guelpf"
+ }
+ ],
+ "description": "GitLab API v4 client for PHP",
+ "keywords": [
+ "api",
+ "gitlab"
+ ],
+ "support": {
+ "issues": "https://github.com/GitLabPHP/Client/issues",
+ "source": "https://github.com/GitLabPHP/Client/tree/11.9.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ }
+ ],
+ "time": "2023-04-30T19:02:00+00:00"
+ },
{
"name": "mews/purifier",
"version": "3.4.0",
@@ -3779,6 +3984,60 @@
},
"time": "2020-10-15T08:29:30+00:00"
},
+ {
+ "name": "php-http/cache-plugin",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-http/cache-plugin.git",
+ "reference": "6bf9fbf66193f61d90c2381b75eb1fa0202fd314"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/6bf9fbf66193f61d90c2381b75eb1fa0202fd314",
+ "reference": "6bf9fbf66193f61d90c2381b75eb1fa0202fd314",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0",
+ "php-http/client-common": "^1.9 || ^2.0",
+ "php-http/message-factory": "^1.0",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0",
+ "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Http\\Client\\Common\\Plugin\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
+ }
+ ],
+ "description": "PSR-6 Cache plugin for HTTPlug",
+ "homepage": "http://httplug.io",
+ "keywords": [
+ "cache",
+ "http",
+ "httplug",
+ "plugin"
+ ],
+ "support": {
+ "issues": "https://github.com/php-http/cache-plugin/issues",
+ "source": "https://github.com/php-http/cache-plugin/tree/1.8.0"
+ },
+ "time": "2023-04-28T10:56:55+00:00"
+ },
{
"name": "php-http/client-common",
"version": "2.7.0",
@@ -4107,6 +4366,62 @@
"abandoned": "psr/http-factory",
"time": "2023-04-14T14:16:17+00:00"
},
+ {
+ "name": "php-http/multipart-stream-builder",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-http/multipart-stream-builder.git",
+ "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/f5938fd135d9fa442cc297dc98481805acfe2b6a",
+ "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0",
+ "php-http/discovery": "^1.15",
+ "psr/http-factory-implementation": "^1.0"
+ },
+ "require-dev": {
+ "nyholm/psr7": "^1.0",
+ "php-http/message": "^1.5",
+ "php-http/message-factory": "^1.0.2",
+ "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Http\\Message\\MultipartStream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com"
+ }
+ ],
+ "description": "A builder class that help you create a multipart stream",
+ "homepage": "http://php-http.org",
+ "keywords": [
+ "factory",
+ "http",
+ "message",
+ "multipart stream",
+ "stream"
+ ],
+ "support": {
+ "issues": "https://github.com/php-http/multipart-stream-builder/issues",
+ "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.0"
+ },
+ "time": "2023-04-28T14:10:22+00:00"
+ },
{
"name": "php-http/promise",
"version": "1.1.0",
@@ -5387,6 +5702,178 @@
],
"time": "2023-02-09T10:38:43+00:00"
},
+ {
+ "name": "symfony/cache",
+ "version": "v6.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/cache.git",
+ "reference": "d176b97600860df13e851538c2df2ad88e9e5ca9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/cache/zipball/d176b97600860df13e851538c2df2ad88e9e5ca9",
+ "reference": "d176b97600860df13e851538c2df2ad88e9e5ca9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/cache": "^2.0|^3.0",
+ "psr/log": "^1.1|^2|^3",
+ "symfony/cache-contracts": "^2.5|^3",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/var-exporter": "^6.2.10"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.13.1",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/http-kernel": "<5.4",
+ "symfony/var-dumper": "<5.4"
+ },
+ "provide": {
+ "psr/cache-implementation": "2.0|3.0",
+ "psr/simple-cache-implementation": "1.0|2.0|3.0",
+ "symfony/cache-implementation": "1.1|2.0|3.0"
+ },
+ "require-dev": {
+ "cache/integration-tests": "dev-master",
+ "doctrine/dbal": "^2.13.1|^3.0",
+ "predis/predis": "^1.1|^2.0",
+ "psr/simple-cache": "^1.0|^2.0|^3.0",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/filesystem": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/messenger": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Cache\\": ""
+ },
+ "classmap": [
+ "Traits/ValueWrapper.php"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides extended PSR-6, PSR-16 (and tags) implementations",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "caching",
+ "psr6"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/cache/tree/v6.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-07-27T16:19:14+00:00"
+ },
+ {
+ "name": "symfony/cache-contracts",
+ "version": "v3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/cache-contracts.git",
+ "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ad945640ccc0ae6e208bcea7d7de4b39b569896b",
+ "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/cache": "^3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Cache\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to caching",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/cache-contracts/tree/v3.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-23T14:45:45+00:00"
+ },
{
"name": "symfony/console",
"version": "v6.3.0",
@@ -7955,6 +8442,80 @@
],
"time": "2023-06-21T12:08:28+00:00"
},
+ {
+ "name": "symfony/var-exporter",
+ "version": "v6.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-exporter.git",
+ "reference": "3400949782c0cb5b3e73aa64cfd71dde000beccc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/3400949782c0cb5b3e73aa64cfd71dde000beccc",
+ "reference": "3400949782c0cb5b3e73aa64cfd71dde000beccc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\VarExporter\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Allows exporting any serializable PHP data structure to plain PHP code",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "clone",
+ "construct",
+ "export",
+ "hydrate",
+ "instantiate",
+ "lazy-loading",
+ "proxy",
+ "serialize"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-exporter/tree/v6.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-07-26T17:39:03+00:00"
+ },
{
"name": "tijsverkoyen/css-to-inline-styles",
"version": "2.2.6",
diff --git a/config/gitlab.php b/config/gitlab.php
new file mode 100644
index 0000000..6f8f388
--- /dev/null
+++ b/config/gitlab.php
@@ -0,0 +1,74 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return [
+
+ /**
+ *--------------------------------------------------------------------------
+ * Default Connection Name
+ *--------------------------------------------------------------------------
+ *
+ * Here you may specify which of the connections below you wish to use as
+ * your default connection for all work. Of course, you may use many
+ * connections at once using the manager class.
+ *
+ */
+
+ 'default' => 'main',
+
+ /**
+ *--------------------------------------------------------------------------
+ * GitLab Connections
+ *--------------------------------------------------------------------------
+ *
+ * Here are each of the connections setup for your application. Example
+ * configuration has been included, but you may add as many connections as
+ * you would like. Note that the 4 supported authentication methods are:
+ * "none", "oauth", "job_token", and "token".
+ *
+ */
+
+ 'connections' => [
+ 'main' => [
+ 'token' => env('GITLAB_TOKEN'),
+ 'method' => 'token',
+ 'url' => env('GITLAB_URL'),
+ ],
+ ],
+
+ /**
+ *--------------------------------------------------------------------------
+ * HTTP Cache
+ *--------------------------------------------------------------------------
+ *
+ * Here are each of the cache configurations setup for your application.
+ * Only the "illuminate" driver is provided out of the box. Example
+ * configuration has been included.
+ *
+ */
+
+ 'cache' => [
+
+ 'main' => [
+ 'driver' => 'illuminate',
+ 'connector' => null,
+ ],
+
+ 'bar' => [
+ 'driver' => 'illuminate',
+ 'connector' => 'redis',
+ ],
+
+ ],
+
+];
diff --git a/database/factories/InvoiceFactory.php b/database/factories/InvoiceFactory.php
index 88673c3..d41b89c 100644
--- a/database/factories/InvoiceFactory.php
+++ b/database/factories/InvoiceFactory.php
@@ -2,7 +2,8 @@
namespace Database\Factories;
-use App\Enums\Invoice\TaskTypeEnum;
+use App\Enums\Invoices\TaskTypeEnum;
+use App\Enums\Invoices\InvoiceStatusEnum;
use App\Models\Invoice;
use App\Models\Package;
use Illuminate\Database\Eloquent\Factories\Factory;
@@ -16,18 +17,58 @@ class InvoiceFactory extends Factory
*/
protected $model = Invoice::class;
+ /**
+ * A JSON object, each line has to be contructed using these
+ * fields description, days, type Invoice\TaskType, amount.
+ *
+ * @var array
+ */
+ protected $tasks = [];
+
+ /**
+ * The total calculated using all tasks.
+ *
+ * @var float
+ */
+ protected $total = 0;
+
+ /**
+ * The total days calculated using all tasks.
+ *
+ * @var float
+ */
+ protected $totalDays = 0;
+
+ /**
+ * The date of the signing.
+ *
+ * @var boolean
+ */
+ protected $signedDateBoolean = 0;
+
+ /**
+ * The date of the shipping to the client.
+ *
+ * @var boolean
+ */
+ protected $sentClientDateBoolean = 0;
+
+ /**
+ * The date of the shipping to the accounting.
+ *
+ * @var boolean
+ */
+ protected $sentAccountingDateBoolean = 0;
+
/**
* Define the model's default state.
*
- * @return array
+ * @return void
*/
- public function definition()
+ private function customData(): void
{
\mt_srand();
- $lines = \mt_rand(2, 9);
- $tasks = [];
- $total = 0;
- $totalDays = 0;
+ $lines = \mt_rand(2, 9);
for ($i = 0; $i < $lines; $i++) {
$days = 0.125 * $this->faker->numberBetween(1, 4);
$type = \collect(TaskTypeEnum::cases())->random();
@@ -47,37 +88,54 @@ class InvoiceFactory extends Factory
$amount = $days * $this->faker->randomFloat(null, 150, 650);
break;
}
- $totalDays += $days;
- $total += $amount;
- /** @var \App\Enums\Invoice\TaskTypeEnum */
- $taskType = \collect(TaskTypeEnum::cases())->random();
- $tasks[] = \array_merge(Invoice::getTaskStructure(), [
+ $this->totalDays += $days;
+ $this->total += $amount;
+ /** @var \App\Enums\Invoices\TaskTypeEnum */
+ $this->tasks[] = \array_merge(Invoice::getTaskStructure(), [
'desc' => $this->faker->words(9, true),
'days' => $days,
- 'type' => $taskType->value,
+ 'type' => \collect(TaskTypeEnum::cases())->random()->value,
'amount' => $amount,
'package' => 1
]);
+ /** Dates */
+ $this->signedDateBoolean = $this->faker->boolean(25);
+ $this->sentClientDateBoolean = $this->faker->boolean(25);
+ $this->sentAccountingDateBoolean = $this->faker->boolean(25);
} //end for
+ }
+ /**
+ * Define the model's default state.
+ *
+ * @return array
+ */
+ public function definition()
+ {
+ $this->customData();
return [
'firstname' => $this->faker->firstName,
'lastname' => $this->faker->lastName,
'object' => $this->faker->words(3, true),
// * constructed object
- 'tasks' => $tasks,
+ 'tasks' => $this->tasks,
// * constructed object result
- 'total' => $total,
+ 'total' => $this->total,
// * constructed object result
- 'total_days' => $totalDays,
+ 'total_days' => $this->totalDays,
'comment' => $this->faker->text(\rand(20, 40)),
'show_days' => $this->faker->boolean(75),
- 'signed_date' => $this->faker->boolean(25) ?
+ 'signed_date' =>
+ $this->signedDateBoolean ?
$this->faker->dateTimeBetween('-1 year', '+1 year') : null,
- 'sent_client_date' => $this->faker->boolean(25) ?
+ 'sent_client_date' =>
+ $this->signedDateBoolean && $this->sentClientDateBoolean ?
$this->faker->dateTimeBetween('-1 year', '+1 year') : null,
- 'sent_accounting_date' => $this->faker->boolean(25) ?
+ 'sent_accounting_date' =>
+ $this->signedDateBoolean && $this->sentClientDateBoolean && $this->sentAccountingDateBoolean ?
$this->faker->dateTimeBetween('-1 year', '+1 year') : null,
+ 'status' => $this->signedDateBoolean && $this->sentClientDateBoolean && $this->sentAccountingDateBoolean ?
+ InvoiceStatusEnum::archived : InvoiceStatusEnum::opened,
];
}
}
diff --git a/database/migrations/2022_08_23_085833_create_invoices_table.php b/database/migrations/2022_08_23_085833_create_invoices_table.php
index a0db936..c079c23 100644
--- a/database/migrations/2022_08_23_085833_create_invoices_table.php
+++ b/database/migrations/2022_08_23_085833_create_invoices_table.php
@@ -34,7 +34,7 @@ class CreateInvoicesTable extends Migration
$table->text('tasks')
->comment(
// phpcs:ignore Generic.Files.LineLength.TooLong
- 'A JSON object, each line has to be contructed using these fields description, days, type Invoice\TaskTypeEnum, amount'
+ 'A JSON object, each line has to be contructed using these fields description, days, type Invoices\TaskTypeEnum, amount'
);
$table->unsignedFloat('total')->comment('The total calculated using all tasks');
diff --git a/database/migrations/2023_08_14_100506_add_status_invoices_table.php b/database/migrations/2023_08_14_100506_add_status_invoices_table.php
new file mode 100644
index 0000000..4b8d827
--- /dev/null
+++ b/database/migrations/2023_08_14_100506_add_status_invoices_table.php
@@ -0,0 +1,37 @@
+unsignedTinyInteger('status')
+ ->default(InvoiceStatusEnum::opened->value)
+ ->comment('Status of the invoice.')
+ ->after('invoiced_to_id');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down(): void
+ {
+ Schema::table('invoices', function (Blueprint $table) {
+ $table->dropColumn('status');
+ });
+ }
+};
diff --git a/database/migrations/2023_08_14_134026_add_gitlab_id_to_sites_table.php b/database/migrations/2023_08_14_134026_add_gitlab_id_to_sites_table.php
new file mode 100644
index 0000000..43f46f5
--- /dev/null
+++ b/database/migrations/2023_08_14_134026_add_gitlab_id_to_sites_table.php
@@ -0,0 +1,36 @@
+unsignedInteger('gitlab_project_id')
+ ->unique()
+ ->nullable()
+ ->comment("ID du dépôt Gitlab")
+ ->after('name');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down(): void
+ {
+ Schema::table('sites', function (Blueprint $table) {
+ $table->dropColumn('gitlab_project_id');
+ });
+ }
+};
diff --git a/database/migrations/2023_08_14_142748_add_last_activity_tickets_table.php b/database/migrations/2023_08_14_142748_add_last_activity_tickets_table.php
new file mode 100644
index 0000000..e4b1128
--- /dev/null
+++ b/database/migrations/2023_08_14_142748_add_last_activity_tickets_table.php
@@ -0,0 +1,43 @@
+timestamp('last_activity')
+ ->default(Carbon::now())
+ ->comment('Last activity on the ticket.')
+ ->after('is_internal');
+ });
+ Ticket::get()->map(function (object $ticket) {
+ $lastMessage = $ticket->messages->whereNotNull('user_id')->sortByDesc('updated_at')->first();
+ $ticket->last_activity =
+ $lastMessage->updated_at ?? $ticket->updated_at;
+ $ticket->saveQuietly();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down(): void
+ {
+ Schema::table('tickets', function (Blueprint $table) {
+ $table->dropColumn('last_activity');
+ });
+ }
+};
diff --git a/database/migrations/2023_08_14_151531_add_gitlab_issue_to_tickets_table.php b/database/migrations/2023_08_14_151531_add_gitlab_issue_to_tickets_table.php
new file mode 100644
index 0000000..cbb42db
--- /dev/null
+++ b/database/migrations/2023_08_14_151531_add_gitlab_issue_to_tickets_table.php
@@ -0,0 +1,35 @@
+string('gitlab_issue')
+ ->nullable()
+ ->comment("URL de l'issue Gitlab")
+ ->after('is_internal');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down(): void
+ {
+ Schema::table('tickets', function (Blueprint $table) {
+ $table->dropColumn('gitlab_issue');
+ });
+ }
+};
diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php
index 825dbe1..b4f16c9 100644
--- a/resources/lang/fr/validation.php
+++ b/resources/lang/fr/validation.php
@@ -155,6 +155,7 @@ return [
'excerpt' => 'extrait',
'firstname' => 'prénom',
'gender' => 'genre',
+ 'gitlab_project_id' => 'id du dépôt Gitlab',
'hour' => 'heure',
'invoiced_to_id' => 'Entité à facturer',
'label' => 'label',
diff --git a/resources/ts/bo/components/CkEditorComponent.vue b/resources/ts/bo/components/CkEditorComponent.vue
index 529910a..dc84daf 100644
--- a/resources/ts/bo/components/CkEditorComponent.vue
+++ b/resources/ts/bo/components/CkEditorComponent.vue
@@ -28,15 +28,6 @@ export default defineComponent({
throw new Error("this component requires json");
}
},
- mounted() {
- const json = String(this.$attrs.json ?? "{}"),
- data = JSON.parse(json);
- this.name = data.name;
- this.internalText = data.text ? String(data.text) : "";
- this.internalId = data.id ? data.id : "";
- this.internalRequired = Boolean(data.required);
- this.makeSuperBuild();
- },
data(): {
name: string;
internalText: string;
@@ -57,6 +48,15 @@ export default defineComponent({
chars: 0,
};
},
+ mounted() {
+ const json = String(this.$attrs.json ?? "{}"),
+ data = JSON.parse(json);
+ this.name = data.name;
+ this.internalText = data.text ? String(data.text) : "";
+ this.internalId = data.id ? data.id : "";
+ this.internalRequired = Boolean(data.required);
+ this.makeSuperBuild();
+ },
watch: {
dbtext() {
if (this.internalText != this.dbtext) {
diff --git a/resources/ts/utilities/fontawesome.ts b/resources/ts/utilities/fontawesome.ts
index 9e6b5d1..35cf7a7 100644
--- a/resources/ts/utilities/fontawesome.ts
+++ b/resources/ts/utilities/fontawesome.ts
@@ -8,7 +8,9 @@ import {
faArrowRightLong,
faArrowUp,
faBan,
+ faBox,
faBoxArchive,
+ faBoxOpen,
faChevronLeft,
faChevronRight,
faClipboard,
@@ -43,7 +45,9 @@ import {
config.autoReplaceSvg = false;
library.add(faTags);
library.add(faSquarePlus);
+library.add(faBox);
library.add(faBoxArchive);
+library.add(faBoxOpen);
library.add(faEraser);
library.add(faSignHanging);
library.add(faDiagramProject);
diff --git a/resources/views/bo/modules/pagination.blade.php b/resources/views/bo/modules/pagination.blade.php
index 9326c83..687ca1b 100644
--- a/resources/views/bo/modules/pagination.blade.php
+++ b/resources/views/bo/modules/pagination.blade.php
@@ -31,7 +31,7 @@
@foreach (\App\Enums\ItemsPerPaginationEnum::toArray() as $itemsPerPaginationEnum)