Merge branch 'develop' into trunk
This commit is contained in:
commit
f150e96d39
44 changed files with 1475 additions and 237 deletions
|
|
@ -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=
|
||||
|
|
|
|||
25
app/Enums/Invoices/InvoiceStatusEnum.php
Normal file
25
app/Enums/Invoices/InvoiceStatusEnum.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Invoices;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum InvoiceStatusEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case opened = 1;
|
||||
case refused = 2;
|
||||
case canceled = 3;
|
||||
case archived = 4;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::opened->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é)",
|
||||
];
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Invoice;
|
||||
namespace App\Enums\Invoices;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
20
app/Enums/Users/GitlabUsersEnum.php
Normal file
20
app/Enums/Users/GitlabUsersEnum.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Users;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum GitlabUsersEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
// Each user is associated to his ID on gitlab.
|
||||
case olivier = 11;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::olivier->name => "Olivier LEGAT",
|
||||
];
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<br>", $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(
|
||||
'<a href="%s" target="_blank">%s</a>',
|
||||
$uploadedFile['url'],
|
||||
__('Lien vers le fichier'),
|
||||
);
|
||||
}
|
||||
return \sprintf("<br><br> Fichier %d : <br>%s<br>", $fileNb, $file);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
777
composer.lock
generated
777
composer.lock
generated
|
|
@ -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",
|
||||
|
|
|
|||
74
config/gitlab.php
Normal file
74
config/gitlab.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of Laravel GitLab.
|
||||
*
|
||||
* (c) Graham Campbell <hello@gjcampbell.co.uk>
|
||||
*
|
||||
* 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',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -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,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\Invoices\InvoiceStatusEnum;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('invoices', function (Blueprint $table) {
|
||||
$table->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');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('sites', function (Blueprint $table) {
|
||||
$table->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');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Ticket;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('tickets', function (Blueprint $table) {
|
||||
$table->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');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('tickets', function (Blueprint $table) {
|
||||
$table->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');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
@foreach (\App\Enums\ItemsPerPaginationEnum::toArray() as $itemsPerPaginationEnum)
|
||||
<li>
|
||||
<a class="dropdown-item text-center user-select-none @if($pagination === $itemsPerPaginationEnum->value) active @endif"
|
||||
href="{{ request()->fullUrlWithQuery(['pagination' => $itemsPerPaginationEnum->value]) . $queryString }}"
|
||||
href="{{ request()->fullUrlWithQuery(['page' => 1, 'pagination' => $itemsPerPaginationEnum->value]) . $queryString }}"
|
||||
role="button">
|
||||
{{ $itemsPerPaginationEnum->value }}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-3">
|
||||
<div class="d-flex flex-row align-items-center">
|
||||
<a href="{{ route('bo.invoices.index') }}"
|
||||
<a href="{{ route('bo.invoices.index', ['status' => \App\Enums\Invoices\InvoiceStatusEnum::opened]) }}"
|
||||
class="btn btn-primary text-decoration-none m-0 me-2"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-3">
|
||||
<div class="d-flex flex-row align-items-start">
|
||||
<a href="{{ route('bo.invoices.index') }}"
|
||||
<a href="{{ route('bo.invoices.index', ['status' => \App\Enums\Invoices\InvoiceStatusEnum::opened]) }}"
|
||||
class="btn btn-primary text-decoration-none m-0 me-2"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
title="{{ __('crud.helpers.view_model', ['model' => __('models.classes.invoices')]) }}">
|
||||
<i class="fa-solid fa-eye"></i>
|
||||
</a>
|
||||
@if($invoiceModel->status->value === \App\Enums\Invoices\InvoiceStatusEnum::opened->value)
|
||||
<button id="formSubmitClone"
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
|
|
@ -33,9 +34,11 @@
|
|||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.invoices')]) }}">
|
||||
{{ __('crud.actions.save') }}
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if($invoiceModel->status->value === \App\Enums\Invoices\InvoiceStatusEnum::opened->value)
|
||||
<form action="{{ route('bo.invoices.update', $invoiceModel->id) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
|
@ -53,4 +56,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@else
|
||||
@include('bo.pages.invoices.form-inputs')
|
||||
@endif
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -1,41 +1,30 @@
|
|||
<div class="row">
|
||||
{{-- DATES/STATUS --}}
|
||||
@if (request()->routeIs('bo.invoices.edit'))
|
||||
@if($invoiceModel->status !== \App\Enums\Invoices\InvoiceStatusEnum::opened || $invoiceModel->signed_date)
|
||||
<div class="col-12">
|
||||
<div class="alert alert-secondary text-white" role="alert">
|
||||
<strong>
|
||||
@if($invoiceModel->status !== \App\Enums\Invoices\InvoiceStatusEnum::opened)
|
||||
{{ __('Impossible de mettre à jour les informations d\'un devis :status.', ['status' => $invoiceModel->status->label()]) }}
|
||||
@elseif($invoiceModel->signed_date)
|
||||
{{ __('Impossible de mettre à jour les informations d\'un devis déjà signé, seule la section "État" est prise en compte') }}
|
||||
@endif
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
{{-- DATES STATUS --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="row border w-100 h-100 bg-white mx-auto p-3">
|
||||
<legend class="p-0">{{ __('Dates') }}</legend>
|
||||
<legend class="p-0">{{ __('État') }}</legend>
|
||||
<div class="row w-100 mx-auto p-0">
|
||||
@if($invoiceModel->signed_date)
|
||||
<div class="col-12 p-0 pe-md-3">
|
||||
<div class="alert alert-secondary text-white" role="alert">
|
||||
<strong>{{ __('Impossible de mettre à jour les informations d\'un devis déjà signé, seules les dates sont prises en compte !') }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
{{-- SIGNED_DATE --}}
|
||||
<div class="col-12 col-sm-6 col-md-4 p-0 pe-md-3">
|
||||
@if(!$invoiceModel->signed_date)
|
||||
@include('bo.partials.inputs.timestamp-datetime', [
|
||||
'id' => 'invoiceSigneddate',
|
||||
'label' => __('Date d\'envoi du :model', [
|
||||
'model' => __('models.classes.invoices'),
|
||||
]),
|
||||
'name' => 'signed_date',
|
||||
'defaultValue' => false,
|
||||
'required' => true,
|
||||
'model' => $invoiceModel ?? null,
|
||||
'helper' => __('Doît être une date réelle et existante.'),
|
||||
])
|
||||
@else
|
||||
<p class="fw-bold text-center m-0">{{ __('Envoyé le :date', ['date' => $invoiceModel->signed_date]) }}</p>
|
||||
@endif
|
||||
</div>
|
||||
{{-- SENT_CLIENT_DATE --}}
|
||||
<div class="col-12 col-sm-6 col-md-4 p-0 pe-md-3">
|
||||
@if(!$invoiceModel->sent_client_date)
|
||||
@include('bo.partials.inputs.timestamp-datetime', [
|
||||
@if($invoiceModel->status === \App\Enums\Invoices\InvoiceStatusEnum::opened AND !$invoiceModel->sent_client_date )
|
||||
@include('bo.partials.inputs.date', [
|
||||
'id' => 'invoiceSentclientdate',
|
||||
'label' => __('Date de signature du :model (client)', [
|
||||
'label' => __('Date d\'envoi du :model', [
|
||||
'model' => __('models.classes.invoices'),
|
||||
]),
|
||||
'name' => 'sent_client_date',
|
||||
|
|
@ -44,16 +33,38 @@
|
|||
'model' => $invoiceModel ?? null,
|
||||
'helper' => __('Doît être une date réelle et existante.'),
|
||||
])
|
||||
@else
|
||||
<p class="fw-bold text-center m-0">{{ __('Signé le :date (client)', ['date' => $invoiceModel->sent_client_date]) }}</p>
|
||||
@elseif ($invoiceModel->sent_client_date)
|
||||
<p class="fw-bold text-center m-0">
|
||||
{{ __('Envoyé le :date', ['date' => \Carbon\Carbon::parse($invoiceModel->sent_client_date)->format('d/m/Y')]) ?? "xxx" }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
{{-- SIGNED_DATE --}}
|
||||
<div class="col-12 col-sm-6 col-md-4 p-0 pe-md-3">
|
||||
@if($invoiceModel->status === \App\Enums\Invoices\InvoiceStatusEnum::opened AND !$invoiceModel->signed_date)
|
||||
@include('bo.partials.inputs.date', [
|
||||
'id' => 'invoiceSigneddate',
|
||||
'label' => __('Date de signature du :model (client)', [
|
||||
'model' => __('models.classes.invoices'),
|
||||
]),
|
||||
'name' => 'signed_date',
|
||||
'defaultValue' => false,
|
||||
'required' => true,
|
||||
'model' => $invoiceModel ?? null,
|
||||
'helper' => __('Doît être une date réelle et existante.'),
|
||||
])
|
||||
@elseif ($invoiceModel->signed_date)
|
||||
<p class="fw-bold text-center m-0">
|
||||
{{ __('Signé le :date (client)', ['date' => \Carbon\Carbon::parse($invoiceModel->signed_date)->format('d/m/Y') ?? "xxx"]) }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
{{-- SENT_ACCOUNTING_DATE --}}
|
||||
<div class="col-12 col-sm-6 col-md-4 p-0 pe-md-3">
|
||||
@if(!$invoiceModel->sent_accounting_date)
|
||||
@include('bo.partials.inputs.timestamp-datetime', [
|
||||
@if($invoiceModel->status === \App\Enums\Invoices\InvoiceStatusEnum::opened AND !$invoiceModel->sent_accounting_date)
|
||||
@include('bo.partials.inputs.date', [
|
||||
'id' => 'invoiceSentaccountingdate',
|
||||
'label' => __('Date d\'envoi du :model à la compta', [
|
||||
'label' => __('Date d\'envoi du :model à la comptabilité', [
|
||||
'model' => __('models.classes.invoices'),
|
||||
]),
|
||||
'name' => 'sent_accounting_date',
|
||||
|
|
@ -62,17 +73,40 @@
|
|||
'model' => $invoiceModel ?? null,
|
||||
'helper' => __('Doît être une date réelle et existante.'),
|
||||
])
|
||||
@else
|
||||
<p class="fw-bold text-center m-0">{{ __('Envoyé à la compta le :date', ['date' => $invoiceModel->sent_accounting_date]) }}</p>
|
||||
@elseif ($invoiceModel->sent_accounting_date)
|
||||
<p class="fw-bold text-center m-0">
|
||||
{{ __('Envoyé à la comptabilité le :date', ['date' => \Carbon\Carbon::parse($invoiceModel->sent_accounting_date)->format('d/m/Y') ?? "xxx"]) }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
{{-- STATUS --}}
|
||||
@if ($invoiceModel->status === \App\Enums\Invoices\InvoiceStatusEnum::opened)
|
||||
<div class="col-12 col-md-6 p-0 pe-md-3">
|
||||
@include('bo.partials.inputs.tinyint-enum', [
|
||||
'id' => 'invoiceStatus',
|
||||
'label' => __('crud.minicrud.associated', [
|
||||
'entity' => 'État',
|
||||
]),
|
||||
'name' => 'status',
|
||||
'model' => $invoiceModel ?? null,
|
||||
'required' => true,
|
||||
'associatedModels' => $invoiceStatusArray,
|
||||
'helper' => __('crud.minicrud.select', [
|
||||
'entity' => 'État',
|
||||
]),
|
||||
])
|
||||
@else
|
||||
<div class="col-12 p-0 pe-md-3">
|
||||
<p class="fw-bold text-warning text-center m-0 mt-3">{{ $invoiceModel->status->label() }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@endif
|
||||
{{-- USER ASSOCIATED --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="row border w-100 h-100 bg-white mx-auto p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="row border w-100 h-100 bg-white mx-auto p-3" @if($invoiceModel->sent_client_date) disabled @endif>
|
||||
<legend class="p-0">{{ __('Informations sur la personne associée') }}</legend>
|
||||
<div class="row w-100 mx-auto p-0">
|
||||
{{-- FIRSTNAME --}}
|
||||
|
|
@ -126,7 +160,7 @@
|
|||
</div>
|
||||
{{-- OBJECT --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="border h-100 bg-white p-3" @if($invoiceModel->sent_client_date) disabled @endif>
|
||||
<legend>{{ Str::ucfirst(__('validation.attributes.object')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
|
@ -156,7 +190,7 @@
|
|||
</div>
|
||||
{{-- TASKS --}}
|
||||
<div class="col-12 pb-3">
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->sent_client_date) disabled @endif>
|
||||
<legend>{{ __('validation.attributes.tasks') }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
|
@ -164,7 +198,7 @@
|
|||
$data = [
|
||||
'companies' => $companyModels,
|
||||
'packages' => $packageModels,
|
||||
'taskTypeEnums' => collect(\App\Enums\Invoice\TaskTypeEnum::toArray())->values(),
|
||||
'taskTypeEnums' => collect(\App\Enums\Invoices\TaskTypeEnum::toArray())->values(),
|
||||
'taskRowModel' => $taskRowModel,
|
||||
'tasks' => $invoiceModel->tasks ?? []
|
||||
];
|
||||
|
|
@ -176,10 +210,13 @@
|
|||
</div>
|
||||
{{-- COMMENT --}}
|
||||
<div class="col-12 pb-3">
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="border bg-white h-100 p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.attributes.comment')) }}</legend>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
@if($invoiceModel->sent_client_date)
|
||||
<textarea class="form-control" disabled>{{ $invoiceModel->comment }}</textarea>
|
||||
@else
|
||||
@include('bo.partials.inputs.text-html', [
|
||||
'id' => 'invoiceComment',
|
||||
'label' => __('Commentaire du :model', [
|
||||
|
|
@ -187,18 +224,19 @@
|
|||
]),
|
||||
'name' => 'comment',
|
||||
'model' => $invoiceModel,
|
||||
'required' => true,
|
||||
'required' => false,
|
||||
'helper' => __('crud.minicrud.text_warning', [
|
||||
'number' => 15
|
||||
]),
|
||||
])
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- SITE_ID --}}
|
||||
<div class="col-12 col-md-6 pb-3">
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->sent_client_date) disabled @endif>
|
||||
<legend>{{ Str::singular(trans('models.classes.sites')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
|
@ -212,7 +250,7 @@
|
|||
'routeName' => 'invoices.json-paginate',
|
||||
'modelRelated' => $siteModels ?? [],
|
||||
'modelSelected' => $invoiceModel->site ?? [],
|
||||
'readonly' => ($invoiceModel->signed_date) ? true : false,
|
||||
'readonly' => ($invoiceModel->sent_client_date) ? true : false,
|
||||
'placeholder' => __('Rechercher une :model', [
|
||||
'model' => Str::singular(trans('models.classes.sites')),
|
||||
]),
|
||||
|
|
@ -227,7 +265,7 @@
|
|||
</div>
|
||||
{{-- COMPANY_ID --}}
|
||||
<div class="col-12 col-md-6 pb-3">
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="border bg-white h-100 p-3" @if($invoiceModel->sent_client_date) disabled @endif>
|
||||
<legend>{{ Str::singular(trans('models.classes.companies')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
|
@ -241,7 +279,7 @@
|
|||
'routeName' => 'invoices.json-paginate',
|
||||
'modelRelated' => $companyModels ?? [],
|
||||
'modelSelected' => $invoiceModel->company ?? [],
|
||||
'readonly' => ($invoiceModel->signed_date) ? true : false,
|
||||
'readonly' => ($invoiceModel->sent_client_date) ? true : false,
|
||||
'placeholder' => __('Rechercher une :model', [
|
||||
'model' => Str::singular(trans('models.classes.companies')),
|
||||
]),
|
||||
|
|
@ -268,7 +306,7 @@
|
|||
'routeName' => 'invoices.json-paginate',
|
||||
'modelRelated' => $companyModels ?? [],
|
||||
'modelSelected' => $invoiceModel->companyInvoiced ?? [],
|
||||
'readonly' => ($invoiceModel->signed_date) ? true : false,
|
||||
'readonly' => ($invoiceModel->sent_client_date) ? true : false,
|
||||
'placeholder' => __('Rechercher une :model', [
|
||||
'model' => Str::singular(trans('models.classes.companies')),
|
||||
]),
|
||||
|
|
@ -283,7 +321,7 @@
|
|||
</div>
|
||||
{{-- SHOW DAYS --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3" @if($invoiceModel->signed_date) disabled @endif>
|
||||
<fieldset class="border h-100 bg-white p-3" @if($invoiceModel->sent_client_date) disabled @endif>
|
||||
<legend>{{ __('Visibilité') }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
|
@ -302,6 +340,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
@if($invoiceModel->status === \App\Enums\Invoices\InvoiceStatusEnum::opened)
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
|
@ -315,3 +354,4 @@
|
|||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -6,13 +6,29 @@
|
|||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center">
|
||||
@include('breadcrumbs.breadcrumb-body')
|
||||
<a href="{{ route('bo.invoices.create') }}"
|
||||
class="btn btn-primary float-right"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('crud.helpers.create_model', ['model' => Str::singular(__('models.classes.invoices'))]) }}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
<form id="invoiceStatus" action="{{ route('bo.invoices.index') }}">
|
||||
<div class="input-group justify-content-end">
|
||||
<select class="form-select w-fit" name="status" id="selectInvoiceStatus">
|
||||
@foreach (\App\Enums\Invoices\InvoiceStatusEnum::toArray() as $invoiceStatusEnum)
|
||||
<option value="{{ $invoiceStatusEnum->value }}" @if($status === $invoiceStatusEnum->value) selected @endif>
|
||||
{{ $invoiceStatusEnum->label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@push('scripts')
|
||||
<script nonce="{{ $nonce }}">document.getElementById('selectInvoiceStatus').addEventListener('change', function (e) {
|
||||
document.getElementById('invoiceStatus').submit();
|
||||
});</script>
|
||||
@endpush
|
||||
<a href="{{ route('bo.invoices.create') }}"
|
||||
class="btn btn-primary float-right"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('crud.helpers.create_model', ['model' => Str::singular(__('models.classes.invoices'))]) }}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@include('bo.modules.search-bar')
|
||||
<table class="table table-hover">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-3">
|
||||
<div class="d-flex flex-row align-items-start">
|
||||
<a href="{{ route('bo.invoices.index') }}"
|
||||
<a href="{{ route('bo.invoices.index', ['status' => \App\Enums\Invoices\InvoiceStatusEnum::opened]) }}"
|
||||
class="btn btn-primary text-decoration-none m-0 me-2"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
|
|
|
|||
|
|
@ -59,6 +59,34 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- GITLAB_PROJECT_ID --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.attributes.gitlab_project_id')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.int-number', [
|
||||
'id' => 'siteGitlabProject',
|
||||
'label' => __(':field du :model', [
|
||||
'field' => Str::ucfirst(__('validation.attributes.gitlab_project_id')),
|
||||
'model' => Str::singular(__('models.classes.sites')),
|
||||
]),
|
||||
'name' => 'gitlab_project_id',
|
||||
'required' => true,
|
||||
'model' => $siteModel ?? null,
|
||||
'helper' => __('validation.integer', [
|
||||
'attribute' => __(':field du :model', [
|
||||
'field' => Str::ucfirst(__('validation.attributes.gitlab_project_id')),
|
||||
'model' => Str::singular(__('models.classes.sites')),
|
||||
]),
|
||||
]),
|
||||
'step' => 1,
|
||||
'min' => 1
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ $userPr = Auth::user()->sites ?? collect([]);
|
|||
<a href="{{ route('bo.labels.index') }}" class="btn btn-info"><i class="fa-solid fa-tags"></i></a>
|
||||
@endcan
|
||||
<a href="{{ route('bo.ticket.create') }}" class="btn btn-primary"><i class="fa-solid fa-square-plus"></i> {{ __('ticket') }}</a>
|
||||
@if(session('tickets.st') == \App\Enums\Tickets\TicketStatusEnum::archived)
|
||||
@if(session('tickets.st') == \App\Enums\Tickets\TicketStatusEnum::archived->value)
|
||||
<a href="{{ route('bo.ticket.index', ['sts' => -1 ]) }}" class="btn btn-success"><i class="fa-solid fa-inbox"></i></a>
|
||||
@else
|
||||
<a href="{{ route('bo.ticket.index', ['st' => \App\Enums\Tickets\TicketStatusEnum::archived]) }}" class="float-end btn btn-secondary"><i class="fa-solid fa-box-archive"></i></a>
|
||||
|
|
@ -172,7 +172,7 @@ $userPr = Auth::user()->sites ?? collect([]);
|
|||
<td>
|
||||
<span class="ticket-index-labels">
|
||||
@foreach ($ticket->labels as $label)
|
||||
<span class="badge label colorize" data-color="{{ $label->color }}">{{ $label->name }}</span>
|
||||
<span class="badge label colorize" data-color="{{ $label->color }}">{{ $label->name }}</span>
|
||||
@endforeach
|
||||
</span>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -256,4 +256,18 @@
|
|||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
@can('createGitlabIssue', $ticket)
|
||||
<form action="{{ route('bo.ticket.create-issue', $ticket) }}" method="POST" id="form_issue" class="col d-flex justify-content-end">
|
||||
@csrf
|
||||
<button class="btn btn-warning align-end" type="submit">{{ __("Créer l'issue Gitlab") }}</button>
|
||||
</form>
|
||||
@else
|
||||
@if (!\is_null($ticket->gitlab_issue))
|
||||
<br>
|
||||
<p>
|
||||
{{ __("Lien vers l'issue Gitlab : ")}}
|
||||
<a href="{{ $ticket->gitlab_issue}}" target="_blank">{{ __("Ouvrir") }}</a>
|
||||
</p>
|
||||
@endif
|
||||
@endcan
|
||||
@endsection
|
||||
|
|
|
|||
15
resources/views/bo/partials/inputs/date.blade.php
Normal file
15
resources/views/bo/partials/inputs/date.blade.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<label for="{{ $id }}">
|
||||
<b>{{ $label }}</b>
|
||||
</label>
|
||||
<input id="{{ $id }}"
|
||||
name="{{ $name }}"
|
||||
class="form-control"
|
||||
type="date"
|
||||
data-form-type="date"
|
||||
aria-describedby="{{ "{$id}Help" }}"
|
||||
value="{{ old($name, ((isset($model) and $model->{$name}) ? ($model->{$name}->format('Y-m-d') ?? ($defaultValue ? Carbon\Carbon::today() : '')) : ($defaultValue ? Carbon\Carbon::today() : ''))) }}">
|
||||
@include('modules.input-error', [
|
||||
'inputName' => $name,
|
||||
'helperId' => "{$id}Help",
|
||||
'helper' => $helper
|
||||
])
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
@if (count($breadcrumbs))
|
||||
<ol class="breadcrumb flex-nowrap border-0 w-100 p-0 m-0">
|
||||
<ol class="breadcrumb flex-nowrap border-0 w-fit p-0 m-0">
|
||||
@foreach ($breadcrumbs as $breadcrumb)
|
||||
@if ($breadcrumb->url && !$loop->last)
|
||||
<li class="breadcrumb-item d-flex h2 fw-bold m-0">
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<a class="dropdown-item @if(Route::is('bo.projects.*'))active @endif" href="{{ route('bo.projects.index') }}">{{ __('models.classes.projects') }}</a>
|
||||
@endcan
|
||||
@can('isAdmin')
|
||||
<a class="dropdown-item @if(Route::is('bo.invoices.*'))active @endif" href="{{ route('bo.invoices.index') }}">{{ __('models.classes.invoices') }}</a>
|
||||
<a class="dropdown-item @if(Route::is('bo.invoices.*'))active @endif" href="{{ route('bo.invoices.index', ['status' => \App\Enums\Invoices\InvoiceStatusEnum::opened]) }}">{{ __('models.classes.invoices') }}</a>
|
||||
@endcan
|
||||
@can('isAdmin')
|
||||
<a class="dropdown-item @if(Route::is('bo.companies.*'))active @endif" href="{{ route('bo.companies.index') }}">{{ __('models.classes.companies') }}</a>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\Invoices\InvoiceStatusEnum;
|
||||
use App\Models\Brand;
|
||||
use App\Models\Company;
|
||||
use App\Models\Dutyhour;
|
||||
|
|
@ -98,7 +99,7 @@ Breadcrumbs::for('bo.companies.edit', function (Generator $trail, Company $compa
|
|||
|
||||
// * INVOICES
|
||||
Breadcrumbs::for('bo.invoices.index', function (Generator $trail) {
|
||||
$trail->push(__('models.classes.invoices'), route('bo.invoices.index'));
|
||||
$trail->push(__('models.classes.invoices'), route('bo.invoices.index', ['status' => InvoiceStatusEnum::opened]));
|
||||
});
|
||||
Breadcrumbs::for('bo.invoices.create', function (Generator $trail) {
|
||||
$trail->parent('bo.invoices.index');
|
||||
|
|
|
|||
|
|
@ -90,7 +90,10 @@ Route::middleware('admin-secure')
|
|||
|
||||
// * TICKETS
|
||||
Route::get('/tickets/json/paginate', [TicketController::class, 'jsonPaginate'])
|
||||
->name('tickets.json-paginate');
|
||||
->name('tickets.json-paginate');
|
||||
Route::post('/ticket/{ticket}/create-issue', [TicketController::class, 'createGitlabIssue'])
|
||||
->middleware('can:createGitlabIssue,ticket')
|
||||
->name('ticket.create-issue');
|
||||
|
||||
// * SCHEDULE
|
||||
Route::prefix('/schedule')
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue