intial ticket fix partial delete fix
This commit is contained in:
@@ -9,6 +9,7 @@ use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Component;
|
||||
use Modules\Helpdesk\Models\AutomationRule;
|
||||
use Modules\Helpdesk\Models\CannedResponse;
|
||||
@@ -134,7 +135,7 @@ final class SettingsManager extends Component
|
||||
$data = $this->guardDefaultColumn('helpdesk_statuses', $data);
|
||||
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
Status::query()->whereKeyNot($this->statusForm['id'])->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(Status::class, $this->statusForm['id']);
|
||||
}
|
||||
|
||||
$this->persistSettingModel(Status::class, $this->statusForm['id'], $data);
|
||||
@@ -173,7 +174,7 @@ final class SettingsManager extends Component
|
||||
$data = $this->guardDefaultColumn('helpdesk_priorities', $data);
|
||||
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
Priority::query()->whereKeyNot($this->priorityForm['id'])->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(Priority::class, $this->priorityForm['id']);
|
||||
}
|
||||
$this->persistSettingModel(Priority::class, $this->priorityForm['id'], $data);
|
||||
$this->resetPriorityForm();
|
||||
@@ -214,10 +215,7 @@ final class SettingsManager extends Component
|
||||
$data = $this->guardDefaultColumn('helpdesk_categories', $data);
|
||||
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
Category::query()
|
||||
->whereKeyNot($this->categoryForm['id'])
|
||||
->where('company_id', $data['company_id'])
|
||||
->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(Category::class, $this->categoryForm['id'], $data['company_id'] ?? null);
|
||||
}
|
||||
$this->persistSettingModel(Category::class, $this->categoryForm['id'], $data);
|
||||
$this->resetCategoryForm();
|
||||
@@ -258,10 +256,7 @@ final class SettingsManager extends Component
|
||||
$data = $this->guardDefaultColumn('helpdesk_teams', $data);
|
||||
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
Team::query()
|
||||
->whereKeyNot($this->teamForm['id'])
|
||||
->where('company_id', $data['company_id'])
|
||||
->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(Team::class, $this->teamForm['id'], $data['company_id'] ?? null);
|
||||
}
|
||||
$this->persistSettingModel(Team::class, $this->teamForm['id'], $data);
|
||||
$this->resetTeamForm();
|
||||
@@ -303,10 +298,7 @@ final class SettingsManager extends Component
|
||||
$data = $this->guardDefaultColumn('helpdesk_projects', $data);
|
||||
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
Project::query()
|
||||
->whereKeyNot($this->projectForm['id'])
|
||||
->where('company_id', $data['company_id'])
|
||||
->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(Project::class, $this->projectForm['id'], $data['company_id'] ?? null);
|
||||
}
|
||||
$this->persistSettingModel(Project::class, $this->projectForm['id'], $data);
|
||||
$this->resetProjectForm();
|
||||
@@ -352,7 +344,7 @@ final class SettingsManager extends Component
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
KanbanBoard::query()->whereKeyNot($this->boardForm['id'])->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(KanbanBoard::class, $this->boardForm['id']);
|
||||
}
|
||||
|
||||
$board = $this->persistSettingModel(KanbanBoard::class, $this->boardForm['id'], $data);
|
||||
@@ -530,7 +522,7 @@ final class SettingsManager extends Component
|
||||
])['slaForm'];
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
if ((bool) ($data['is_default'] ?? false)) {
|
||||
SlaPolicy::query()->whereKeyNot($this->slaForm['id'])->update(['is_default' => false]);
|
||||
$this->clearOtherDefaults(SlaPolicy::class, $this->slaForm['id']);
|
||||
}
|
||||
$this->persistSettingModel(SlaPolicy::class, $this->slaForm['id'], $data);
|
||||
$this->resetSlaPolicyForm();
|
||||
@@ -797,6 +789,7 @@ final class SettingsManager extends Component
|
||||
private function orderedCategories(): mixed
|
||||
{
|
||||
return Category::query()
|
||||
->with('company')
|
||||
->withCount('tickets')
|
||||
->when($this->hasDefaultColumn('helpdesk_categories'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('name')
|
||||
@@ -806,6 +799,7 @@ final class SettingsManager extends Component
|
||||
private function orderedTeams(): mixed
|
||||
{
|
||||
return Team::query()
|
||||
->with('company')
|
||||
->withCount(['projects', 'tickets'])
|
||||
->when($this->hasDefaultColumn('helpdesk_teams'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('name')
|
||||
@@ -815,7 +809,7 @@ final class SettingsManager extends Component
|
||||
private function orderedProjects(): mixed
|
||||
{
|
||||
return Project::query()
|
||||
->with(['team'])
|
||||
->with(['company', 'team'])
|
||||
->withCount('tickets')
|
||||
->when($this->hasDefaultColumn('helpdesk_projects'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('title')
|
||||
@@ -837,19 +831,47 @@ final class SettingsManager extends Component
|
||||
*/
|
||||
private function persistSettingModel(string $modelClass, int|string|null $id, array $data): object
|
||||
{
|
||||
if (filled($id)) {
|
||||
unset($data['id']);
|
||||
|
||||
try {
|
||||
if (filled($id)) {
|
||||
/** @var TModel $model */
|
||||
$model = $modelClass::query()->findOrFail((int) $id);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/** @var TModel $model */
|
||||
$model = $modelClass::query()->findOrFail((int) $id);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
$model = $modelClass::query()->create($data);
|
||||
|
||||
return $model;
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
throw ValidationException::withMessages([
|
||||
'settings' => 'The record could not be saved. Check the slug is unique for this section/company and try again.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the default flag on every other record without generating invalid null-id SQL.
|
||||
*
|
||||
* @param class-string<\Illuminate\Database\Eloquent\Model> $modelClass
|
||||
*/
|
||||
private function clearOtherDefaults(string $modelClass, int|string|null $currentId, int|string|null $companyId = null): void
|
||||
{
|
||||
$query = $modelClass::query();
|
||||
|
||||
if (filled($currentId)) {
|
||||
$query->whereKeyNot((int) $currentId);
|
||||
}
|
||||
|
||||
/** @var TModel $model */
|
||||
$model = $modelClass::query()->create($data);
|
||||
if (Schema::hasColumn((new $modelClass())->getTable(), 'company_id')) {
|
||||
$query->where('company_id', filled($companyId) ? (int) $companyId : null);
|
||||
}
|
||||
|
||||
return $model;
|
||||
$query->update(['is_default' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Modules\Helpdesk\Models;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
@@ -22,6 +23,12 @@ final class Category extends Model
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['company_id' => 'integer', 'is_default' => 'boolean'];
|
||||
|
||||
/** @return BelongsTo<\App\Models\Company, Category> */
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Company::class, 'company_id');
|
||||
}
|
||||
|
||||
/** @return HasMany<Ticket> */
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
|
||||
@@ -23,6 +23,12 @@ final class Project extends Model
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['company_id' => 'integer', 'team_id' => 'integer', 'archived_at' => 'datetime', 'is_default' => 'boolean'];
|
||||
|
||||
/** @return BelongsTo<\App\Models\Company, Project> */
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Company::class, 'company_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<Team, Project> */
|
||||
public function team(): BelongsTo
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
@@ -26,6 +27,12 @@ final class Team extends Model
|
||||
'is_default' => 'boolean',
|
||||
];
|
||||
|
||||
/** @return BelongsTo<\App\Models\Company, Team> */
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Company::class, 'company_id');
|
||||
}
|
||||
|
||||
/** @return HasMany<Project> */
|
||||
public function projects(): HasMany
|
||||
{
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Tests\Feature;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use Modules\Helpdesk\Livewire\SettingsManager;
|
||||
use Modules\Helpdesk\Models\AutomationRule;
|
||||
use Modules\Helpdesk\Models\CannedResponse;
|
||||
use Modules\Helpdesk\Models\Category;
|
||||
use Modules\Helpdesk\Models\ChecklistTemplate;
|
||||
use Modules\Helpdesk\Models\GitRepository;
|
||||
use Modules\Helpdesk\Models\KanbanBoard;
|
||||
use Modules\Helpdesk\Models\Priority;
|
||||
use Modules\Helpdesk\Models\Product;
|
||||
use Modules\Helpdesk\Models\Project;
|
||||
use Modules\Helpdesk\Models\SlaPolicy;
|
||||
use Modules\Helpdesk\Models\Status;
|
||||
use Modules\Helpdesk\Models\Tag;
|
||||
use Modules\Helpdesk\Models\Team;
|
||||
use Modules\Helpdesk\Models\WorkflowTemplate;
|
||||
use Modules\Helpdesk\Tests\Concerns\BuildsHelpdeskFixtures;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class SettingsCrudTest extends TestCase
|
||||
{
|
||||
use BuildsHelpdeskFixtures;
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_all_helpdesk_settings_create_and_update_actions_persist_records(): void
|
||||
{
|
||||
$fixtures = $this->seedLookupData();
|
||||
$admin = $this->admin(['name' => 'Settings CRUD Admin']);
|
||||
$this->actingAs($admin);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('statusForm.name', 'Awaiting Customer')
|
||||
->set('statusForm.slug', 'awaiting-customer')
|
||||
->set('statusForm.color', 'amber')
|
||||
->set('statusForm.sort_order', 20)
|
||||
->call('saveStatus')
|
||||
->assertHasNoErrors();
|
||||
$status = Status::query()->where('slug', 'awaiting-customer')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editStatus', $status->id)
|
||||
->set('statusForm.name', 'Awaiting Customer Reply')
|
||||
->call('saveStatus')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_statuses', ['id' => $status->id, 'name' => 'Awaiting Customer Reply']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('priorityForm.name', 'Critical')
|
||||
->set('priorityForm.slug', 'critical')
|
||||
->set('priorityForm.color', 'red')
|
||||
->set('priorityForm.sort_order', 1)
|
||||
->call('savePriority')
|
||||
->assertHasNoErrors();
|
||||
$priority = Priority::query()->where('slug', 'critical')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editPriority', $priority->id)
|
||||
->set('priorityForm.name', 'Critical Updated')
|
||||
->call('savePriority')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_priorities', ['id' => $priority->id, 'name' => 'Critical Updated']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('categoryForm.name', 'Billing')
|
||||
->set('categoryForm.slug', 'billing')
|
||||
->set('categoryForm.color', 'blue')
|
||||
->call('saveCategory')
|
||||
->assertHasNoErrors();
|
||||
$category = Category::query()->where('slug', 'billing')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editCategory', $category->id)
|
||||
->set('categoryForm.name', 'Billing Updated')
|
||||
->call('saveCategory')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_categories', ['id' => $category->id, 'name' => 'Billing Updated']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('teamForm.name', 'Second Line')
|
||||
->set('teamForm.slug', 'second-line')
|
||||
->set('teamForm.color', 'indigo')
|
||||
->call('saveTeam')
|
||||
->assertHasNoErrors();
|
||||
$team = Team::query()->where('slug', 'second-line')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editTeam', $team->id)
|
||||
->set('teamForm.name', 'Second Line Updated')
|
||||
->call('saveTeam')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_teams', ['id' => $team->id, 'name' => 'Second Line Updated']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('projectForm.team_id', $fixtures['team']->id)
|
||||
->set('projectForm.title', 'Customer Portal')
|
||||
->set('projectForm.slug', 'customer-portal')
|
||||
->set('projectForm.color', 'cyan')
|
||||
->call('saveProject')
|
||||
->assertHasNoErrors();
|
||||
$project = Project::query()->where('slug', 'customer-portal')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editProject', $project->id)
|
||||
->set('projectForm.title', 'Customer Portal Updated')
|
||||
->call('saveProject')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_projects', ['id' => $project->id, 'title' => 'Customer Portal Updated']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('boardForm.name', 'Escalations')
|
||||
->set('boardForm.slug', 'escalations')
|
||||
->set('boardForm.sort_order', 30)
|
||||
->set('boardForm.status_ids', [$fixtures['open']->id, $fixtures['closed']->id])
|
||||
->call('saveBoard')
|
||||
->assertHasNoErrors();
|
||||
$board = KanbanBoard::query()->where('slug', 'escalations')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editBoard', $board->id)
|
||||
->set('boardForm.name', 'Escalations Updated')
|
||||
->call('saveBoard')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_kanban_boards', ['id' => $board->id, 'name' => 'Escalations Updated']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('repositoryForm.project_id', $fixtures['project']->id)
|
||||
->set('repositoryForm.name', 'WMS Core Repo')
|
||||
->set('repositoryForm.provider', 'github')
|
||||
->set('repositoryForm.remote_url', 'git@example.com:wms/core.git')
|
||||
->set('repositoryForm.default_branch', 'main')
|
||||
->call('saveRepository')
|
||||
->assertHasNoErrors();
|
||||
$repository = GitRepository::query()->where('name', 'WMS Core Repo')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editRepository', $repository->id)
|
||||
->set('repositoryForm.default_branch', 'develop')
|
||||
->call('saveRepository')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_git_repositories', ['id' => $repository->id, 'default_branch' => 'develop']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('workflowForm.name', 'Ticket Created')
|
||||
->set('workflowForm.event', 'ticket.created')
|
||||
->set('workflowForm.subject', 'New ticket')
|
||||
->set('workflowForm.html_body', '<p>Created</p>')
|
||||
->set('workflowForm.to_role', 'requester')
|
||||
->call('saveWorkflowTemplate')
|
||||
->assertHasNoErrors();
|
||||
$workflow = WorkflowTemplate::query()->where('name', 'Ticket Created')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editWorkflowTemplate', $workflow->id)
|
||||
->set('workflowForm.subject', 'New ticket updated')
|
||||
->call('saveWorkflowTemplate')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_workflow_templates', ['id' => $workflow->id, 'subject' => 'New ticket updated']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('cannedForm.category_id', $fixtures['category']->id)
|
||||
->set('cannedForm.team_id', $fixtures['team']->id)
|
||||
->set('cannedForm.name', 'Greeting')
|
||||
->set('cannedForm.slug', 'greeting')
|
||||
->set('cannedForm.body', '<p>Hello</p>')
|
||||
->call('saveCannedResponse')
|
||||
->assertHasNoErrors();
|
||||
$canned = CannedResponse::query()->where('slug', 'greeting')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editCannedResponse', $canned->id)
|
||||
->set('cannedForm.body', '<p>Hello updated</p>')
|
||||
->call('saveCannedResponse')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_canned_responses', ['id' => $canned->id, 'body' => '<p>Hello updated</p>']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('slaForm.priority_id', $fixtures['normal']->id)
|
||||
->set('slaForm.category_id', $fixtures['category']->id)
|
||||
->set('slaForm.name', 'Standard SLA')
|
||||
->set('slaForm.slug', 'standard-sla')
|
||||
->set('slaForm.first_response_minutes', 120)
|
||||
->set('slaForm.resolution_minutes', 1440)
|
||||
->call('saveSlaPolicy')
|
||||
->assertHasNoErrors();
|
||||
$sla = SlaPolicy::query()->where('slug', 'standard-sla')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editSlaPolicy', $sla->id)
|
||||
->set('slaForm.resolution_minutes', 720)
|
||||
->call('saveSlaPolicy')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_sla_policies', ['id' => $sla->id, 'resolution_minutes' => 720]);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('automationForm.name', 'Auto Route')
|
||||
->set('automationForm.slug', 'auto-route')
|
||||
->set('automationForm.set_priority_id', $fixtures['high']->id)
|
||||
->set('automationForm.set_status_id', $fixtures['open']->id)
|
||||
->call('saveAutomationRule')
|
||||
->assertHasNoErrors();
|
||||
$automation = AutomationRule::query()->where('slug', 'auto-route')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editAutomationRule', $automation->id)
|
||||
->set('automationForm.match_subject', 'urgent')
|
||||
->call('saveAutomationRule')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_automation_rules', ['id' => $automation->id, 'match_subject' => 'urgent']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('checklistTemplateForm.category_id', $fixtures['category']->id)
|
||||
->set('checklistTemplateForm.project_id', $fixtures['project']->id)
|
||||
->set('checklistTemplateForm.name', 'Release Checklist')
|
||||
->set('checklistTemplateForm.slug', 'release-checklist')
|
||||
->set('checklistTemplateForm.items_text', "Check logs\nConfirm release")
|
||||
->call('saveChecklistTemplate')
|
||||
->assertHasNoErrors();
|
||||
$checklist = ChecklistTemplate::query()->where('slug', 'release-checklist')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editChecklistTemplate', $checklist->id)
|
||||
->set('checklistTemplateForm.items_text', "Updated item")
|
||||
->call('saveChecklistTemplate')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_checklist_templates', ['id' => $checklist->id]);
|
||||
self::assertSame(['Updated item'], $checklist->refresh()->items);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('tagForm.name', 'VIP')
|
||||
->set('tagForm.slug', 'vip')
|
||||
->set('tagForm.color', 'pink')
|
||||
->call('saveTag')
|
||||
->assertHasNoErrors();
|
||||
$tag = Tag::query()->where('slug', 'vip')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editTag', $tag->id)
|
||||
->set('tagForm.color', 'purple')
|
||||
->call('saveTag')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_tags', ['id' => $tag->id, 'color' => 'purple']);
|
||||
|
||||
Livewire::test(SettingsManager::class)
|
||||
->set('productForm.name', 'WMS')
|
||||
->set('productForm.slug', 'wms')
|
||||
->set('productForm.type', 'service')
|
||||
->call('saveProduct')
|
||||
->assertHasNoErrors();
|
||||
$product = Product::query()->where('slug', 'wms')->firstOrFail();
|
||||
Livewire::test(SettingsManager::class)
|
||||
->call('editProduct', $product->id)
|
||||
->set('productForm.version', '1.1')
|
||||
->call('saveProduct')
|
||||
->assertHasNoErrors();
|
||||
$this->assertDatabaseHas('helpdesk_products', ['id' => $product->id, 'version' => '1.1']);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,10 @@
|
||||
- version: 1.9.29
|
||||
date: 2026-06-18
|
||||
changes:
|
||||
- Hardened every Helpdesk settings create/edit/save path so Livewire CRUD actions persist updates without null primary-key inserts or invalid default-reset queries.
|
||||
- Added company relationships/eager loading for category, team and project settings tables so settings pages render cleanly during edit/save cycles.
|
||||
- Added full SettingsCrudTest coverage for statuses, priorities, categories, teams, projects, boards, Git repositories, workflow templates, canned responses, SLA policies, automation rules, checklist templates, tags and products.
|
||||
|
||||
- version: 1.3.6
|
||||
date: 2026-06-16
|
||||
changes:
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
"Modules\\Helpdesk\\Providers\\HelpdeskServiceProvider"
|
||||
],
|
||||
"files": [],
|
||||
"version": "1.9.28"
|
||||
"version": "1.9.29"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user