Skip to content

Commit e1f67f1

Browse files
authored
Merge pull request #43 from devaslanphp/dev
Tickets numbers
2 parents c0a10fa + 949f158 commit e1f67f1

20 files changed

Lines changed: 233 additions & 40 deletions
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Models\Ticket;
6+
use Illuminate\Http\RedirectResponse;
7+
use Illuminate\Support\Str;
8+
9+
class TicketNumberController extends Controller
10+
{
11+
12+
/**
13+
* Redirect to a ticket based on it's number
14+
*
15+
* @param string $number
16+
* @return RedirectResponse|void
17+
*/
18+
public function __invoke(string $number)
19+
{
20+
$ticket_prefix = substr($number, 0, 4);
21+
$ticket_number = str_replace($ticket_prefix, "", $number);
22+
$ticket = Ticket::where('number', $ticket_number)
23+
->whereHas('project', fn($query) => $query->where('ticket_prefix', $ticket_prefix))
24+
->first();
25+
if ($ticket) {
26+
return redirect()->route('tickets.details', [
27+
'ticket' => $ticket,
28+
'slug' => Str::slug($ticket->title)
29+
]);
30+
} else {
31+
abort(404);
32+
}
33+
}
34+
35+
}

app/Http/Livewire/ProjectsDialog.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Models\Project;
66
use App\Models\User;
77
use App\Notifications\ProjectCreatedNotification;
8+
use Filament\Forms\Components\Grid;
89
use Filament\Forms\Components\RichEditor;
910
use Filament\Forms\Components\Select;
1011
use Filament\Forms\Components\TextInput;
@@ -26,6 +27,7 @@ class ProjectsDialog extends Component implements HasForms
2627
public function mount(): void {
2728
$this->form->fill([
2829
'name' => $this->project->name,
30+
'ticket_prefix' => $this->project->ticket_prefix,
2931
'description' => $this->project->description,
3032
'owner_id' => $this->project->owner_id ?? auth()->user()->id,
3133
]);
@@ -50,10 +52,22 @@ protected function getFormSchema(): array
5052
->searchable()
5153
->options(User::all()->pluck('name', 'id')),
5254

53-
TextInput::make('name')
54-
->label(__('Full name'))
55-
->maxLength(255)
56-
->required(),
55+
Grid::make(3)
56+
->schema([
57+
TextInput::make('ticket_prefix')
58+
->label(__('Ticket prefix'))
59+
->minLength(4)
60+
->maxLength(4)
61+
->columnSpan(1)
62+
->helperText(__('Used to generate tickets numbers'))
63+
->required(),
64+
65+
TextInput::make('name')
66+
->label(__('Full name'))
67+
->maxLength(255)
68+
->columnSpan(2)
69+
->required(),
70+
]),
5771

5872
RichEditor::make('description')
5973
->label(__('Description'))
@@ -74,7 +88,8 @@ public function save(): void {
7488
Project::create([
7589
'name' => $data['name'],
7690
'description' => $data['description'],
77-
'owner_id' => $data['owner_id']
91+
'owner_id' => $data['owner_id'],
92+
'ticket_prefix' => $data['ticket_prefix']
7893
]);
7994
Notification::make()
8095
->success()
@@ -85,6 +100,7 @@ public function save(): void {
85100
$this->project->name = $data['name'];
86101
$this->project->description = $data['description'];
87102
$this->project->owner_id = $data['owner_id'];
103+
$this->project->ticket_prefix = $data['ticket_prefix'];
88104
$this->project->save();
89105
Notification::make()
90106
->success()

app/Http/Livewire/TicketDetails.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Http\Livewire;
44

55
use App\Models\Ticket;
6+
use Filament\Notifications\Notification;
67
use Livewire\Component;
78

89
class TicketDetails extends Component
@@ -47,4 +48,23 @@ public function ticketSaved(): void
4748
{
4849
$this->ticket = $this->ticket->refresh();
4950
}
51+
52+
/**
53+
* Copy a ticket url
54+
*
55+
* @param Ticket $ticket
56+
* @return void
57+
*/
58+
public function copyTicketUrl(Ticket $ticket): void {
59+
Notification::make()
60+
->success()
61+
->title(__('Ticket url copied'))
62+
->body(__('The ticket url successfully copied to your clipboard'))
63+
->send();
64+
$this->dispatchBrowserEvent('ticketUrlCopied', [
65+
'url' => route('tickets.number', [
66+
'number' => $ticket->ticket_number
67+
])
68+
]);
69+
}
5070
}

app/Http/Livewire/Tickets.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
use Filament\Forms\Components\TextInput;
1313
use Filament\Forms\Concerns\InteractsWithForms;
1414
use Filament\Forms\Contracts\HasForms;
15+
use Filament\Notifications\Actions\Action;
1516
use Filament\Notifications\Notification;
17+
use Illuminate\Support\Str;
1618
use Livewire\Component;
1719

1820
class Tickets extends Component implements HasForms
@@ -231,4 +233,23 @@ public function ticketDeleted()
231233
{
232234
$this->ticketSaved();
233235
}
236+
237+
/**
238+
* Copy a ticket url
239+
*
240+
* @param Ticket $ticket
241+
* @return void
242+
*/
243+
public function copyTicketUrl(Ticket $ticket): void {
244+
Notification::make()
245+
->success()
246+
->title(__('Ticket url copied'))
247+
->body(__('The ticket url successfully copied to your clipboard'))
248+
->send();
249+
$this->dispatchBrowserEvent('ticketUrlCopied', [
250+
'url' => route('tickets.number', [
251+
'number' => $ticket->ticket_number
252+
])
253+
]);
254+
}
234255
}

app/Http/Livewire/TicketsDialog.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use App\Jobs\TicketCreatedJob;
66
use App\Models\Project;
77
use App\Models\Ticket;
8-
use App\Models\User;
98
use Filament\Forms\Components\Grid;
109
use Filament\Forms\Components\RichEditor;
1110
use Filament\Forms\Components\Select;
@@ -14,6 +13,7 @@
1413
use Filament\Forms\Contracts\HasForms;
1514
use Filament\Notifications\Actions\Action;
1615
use Filament\Notifications\Notification;
16+
use Illuminate\Support\Str;
1717
use Livewire\Component;
1818

1919
class TicketsDialog extends Component implements HasForms
@@ -109,6 +109,17 @@ public function save(): void
109109
->success()
110110
->title(__('Ticket created'))
111111
->body(__('The ticket has been successfully created'))
112+
->actions([
113+
Action::make('redirect')
114+
->label(__('See details'))
115+
->color('success')
116+
->button()
117+
->close()
118+
->url(fn() => route('tickets.details', [
119+
'ticket' => $ticket,
120+
'slug' => Str::slug($ticket->title)
121+
]))
122+
])
112123
->send();
113124
$this->emit('ticketSaved');
114125
TicketCreatedJob::dispatch($ticket);

app/Models/Project.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ class Project extends Model
1717
protected $fillable = [
1818
'name',
1919
'description',
20-
'owner_id'
20+
'owner_id',
21+
'ticket_prefix'
2122
];
2223

2324
protected static function boot()

app/Models/Ticket.php

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ class Ticket extends Model
2323
'owner_id',
2424
'responsible_id',
2525
'project_id',
26+
'number',
2627
];
2728

2829
protected $appends = [
29-
'status_object',
30-
'priority_object',
30+
'ticket_number'
3131
];
3232

3333
protected static function boot()
@@ -36,6 +36,9 @@ protected static function boot()
3636
static::addGlobalScope('order', function (Builder $builder) {
3737
$builder->orderBy('created_at', 'desc');
3838
});
39+
static::creating(function (Ticket $ticket) {
40+
$ticket->number = str_pad(Ticket::where('project_id', $ticket->project_id)->withTrashed()->count() + 1, 4, '0', STR_PAD_LEFT);
41+
});
3942
}
4043

4144
public function owner(): BelongsTo
@@ -53,22 +56,15 @@ public function project(): BelongsTo
5356
return $this->belongsTo(Project::class);
5457
}
5558

56-
public function statusObject(): Attribute
59+
public function comments(): HasMany
5760
{
58-
return new Attribute(
59-
get: fn() => config('system.statuses.' . $this->status) ?? null
60-
);
61+
return $this->hasMany(Comment::class);
6162
}
6263

63-
public function priorityObject(): Attribute
64+
public function ticketNumber(): Attribute
6465
{
6566
return new Attribute(
66-
get: fn() => config('system.priorities.' . $this->priority) ?? null
67+
get: fn() => $this->project->ticket_prefix . '' . $this->number
6768
);
6869
}
69-
70-
public function comments(): HasMany
71-
{
72-
return $this->hasMany(Comment::class);
73-
}
7470
}

database/help_desk.sql

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ VALUES (4, 'Dark Vador', 'darkvador@gmail.com', NULL, '$2y$10$4f8HPTwKhVzpAP5kas
1313
'$2y$10$MR51TVg3xzUXs308oTxp8.Pw9sjs7ijaeGYLJZsq85CdY/azYD0bG', NULL, '2022-09-11 15:31:51',
1414
'2022-09-11 15:31:55', 'employee', '82c93eba-9a33-4dbe-abac-22f11f5c1f54', NULL);
1515

16-
INSERT INTO `projects` (`id`, `name`, `description`, `owner_id`, `deleted_at`, `created_at`, `updated_at`)
16+
INSERT INTO `projects` (`id`, `name`, `description`, `owner_id`, `deleted_at`, `created_at`, `updated_at`, `ticket_prefix`)
1717
VALUES (1, 'Default project',
1818
'<p>This is the default project to associate to any created ticket that are not related to any other projects.</p>',
19-
4, NULL, '2022-09-11 16:29:08', '2022-09-11 16:35:48'),
19+
4, NULL, '2022-09-11 16:29:08', '2022-09-11 16:35:48', 'DEFP'),
2020
(2, 'IDEAO', '<p>Project for managing tickets linked to the IDEAO project</p>', 4, NULL, '2022-09-11 17:09:31',
21-
'2022-09-11 17:12:47'),
21+
'2022-09-11 17:12:47', 'IDEA'),
2222
(3, 'Arena job', '<p>Project for managing tickets linked to the Arena job project</p>', 4, NULL,
23-
'2022-09-11 17:13:05', '2022-09-11 17:13:17'),
23+
'2022-09-11 17:13:05', '2022-09-11 17:13:17', 'ARJO'),
2424
(4, 'ARP', '<p>Project for managing tickets linked to the ARP project</p>', 5, NULL, '2022-09-11 17:13:25',
25-
'2022-09-11 17:15:04');
25+
'2022-09-11 17:15:04', 'ARPT');
2626

2727
INSERT INTO `favorite_projects` (`id`, `user_id`, `project_id`, `created_at`, `updated_at`)
2828
VALUES (6, 4, 2, '2022-09-11 17:09:33', '2022-09-11 17:09:33'),
@@ -31,17 +31,17 @@ VALUES (6, 4, 2, '2022-09-11 17:09:33', '2022-09-11 17:09:33'),
3131
(11, 4, 1, '2022-09-12 11:50:42', '2022-09-12 11:50:42');
3232

3333
INSERT INTO `tickets` (`id`, `title`, `content`, `status`, `priority`, `owner_id`, `responsible_id`, `deleted_at`,
34-
`created_at`, `updated_at`, `project_id`, `type`)
34+
`created_at`, `updated_at`, `project_id`, `type`, `number`)
3535
VALUES (2, 'Cannot access the platform',
3636
'<p>Hello,</p><p>I cannot access the platform with the credentials received by email.</p><p>Can you see what is the problem, please?</p><p>Thanks</p>',
37-
'validated', 'highest', 4, 5, NULL, '2022-09-11 18:27:55', '2022-09-12 11:48:00', 1, 'bug'),
37+
'validated', 'highest', 4, 5, NULL, '2022-09-11 18:27:55', '2022-09-12 11:48:00', 1, 'bug', '0001'),
3838
(3, 'Design enhancement', '<p>Add a logo of the company to the login page.</p>', 'created', 'low', 5, 4, NULL,
39-
'2022-09-11 18:45:55', '2022-09-12 13:08:05', 2, 'improvement'),
39+
'2022-09-11 18:45:55', '2022-09-12 13:08:05', 2, 'improvement', '0001'),
4040
(4, 'Quiz wizard', '<p>Add a wizard system to the quiz page</p>', 'created', 'normal', 4, NULL, NULL,
41-
'2022-09-11 20:37:14', '2022-09-11 20:37:14', 2, 'improvement'),
41+
'2022-09-11 20:37:14', '2022-09-11 20:37:14', 2, 'improvement', '0002'),
4242
(9, 'Internal error - Login page',
4343
'<p>We got an internal error when we visit the login page (url: /auth/login)</p>', 'created', 'highest', 5, 4,
44-
NULL, '2022-09-11 20:58:37', '2022-09-12 13:08:12', 4, 'bug');
44+
NULL, '2022-09-11 20:58:37', '2022-09-12 13:08:12', 4, 'bug', '0001');
4545

4646
INSERT INTO `comments` (`id`, `owner_id`, `ticket_id`, `content`, `deleted_at`, `created_at`, `updated_at`)
4747
VALUES (1, 4, 2, '<p>Hello,</p><p>We are working on it, I let you know ASAP.</p><p>Best regards.</p>', NULL,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('projects', function (Blueprint $table) {
16+
$table->string('ticket_prefix', 4);
17+
});
18+
}
19+
20+
/**
21+
* Reverse the migrations.
22+
*
23+
* @return void
24+
*/
25+
public function down()
26+
{
27+
Schema::table('projects', function (Blueprint $table) {
28+
$table->dropColumn('ticket_prefix');
29+
});
30+
}
31+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('tickets', function (Blueprint $table) {
16+
$table->string('number');
17+
});
18+
}
19+
20+
/**
21+
* Reverse the migrations.
22+
*
23+
* @return void
24+
*/
25+
public function down()
26+
{
27+
Schema::table('tickets', function (Blueprint $table) {
28+
$table->dropColumn('number');
29+
});
30+
}
31+
};

0 commit comments

Comments
 (0)