203 lines
9.0 KiB
PHP
203 lines
9.0 KiB
PHP
<?php
|
|
|
|
use App\Models\Action;
|
|
use App\Models\Activity;
|
|
use App\Models\Client;
|
|
use App\Models\ClientCase;
|
|
use App\Models\Decision;
|
|
use App\Models\Permission;
|
|
use App\Models\Person\Person;
|
|
use App\Models\Person\PersonGroup;
|
|
use App\Models\Person\PersonType;
|
|
use App\Models\Role;
|
|
use App\Models\Segment;
|
|
use App\Models\User;
|
|
|
|
function makeUserWithPermissions(array $perms = ['reports-view', 'reports-export']): \App\Models\User
|
|
{
|
|
$user = User::factory()->create();
|
|
$role = Role::create(['name' => 'Tester', 'slug' => 'tester']);
|
|
foreach ($perms as $slug) {
|
|
$p = Permission::firstOrCreate(['slug' => $slug], ['name' => strtoupper(str_replace('-', ' ', $slug))]);
|
|
$role->permissions()->syncWithoutDetaching($p->id);
|
|
}
|
|
$role->users()->syncWithoutDetaching($user->id);
|
|
|
|
return $user;
|
|
}
|
|
|
|
it('shows reports index with permission', function () {
|
|
$user = makeUserWithPermissions(['reports-view']);
|
|
$this->actingAs($user);
|
|
|
|
$resp = $this->get(route('reports.index'));
|
|
$resp->assertOk();
|
|
});
|
|
|
|
it('counts actions/decisions correctly', function () {
|
|
$user = makeUserWithPermissions(['reports-view']);
|
|
$this->actingAs($user);
|
|
|
|
$action = Action::factory()->create(['name' => 'Klic']);
|
|
$decision = Decision::create(['name' => 'Uspešno']);
|
|
$group = new PersonGroup;
|
|
$group->name = 'grp';
|
|
$group->save();
|
|
$type = PersonType::create(['name' => 'tip']);
|
|
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
|
|
$client = Client::create(['person_id' => $person->id]);
|
|
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
|
|
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
|
|
$resp = $this->getJson(route('reports.data', 'actions-decisions-counts'));
|
|
$resp->assertOk();
|
|
$json = $resp->json();
|
|
expect($json['data'][0]['action_name'])->toBe('Klic');
|
|
expect($json['data'][0]['decision_name'])->toBe('Uspešno');
|
|
expect($json['data'][0]['activities_count'])->toBe(3);
|
|
});
|
|
|
|
it('lists active contracts filtered by client', function () {
|
|
$user = makeUserWithPermissions(['reports-view']);
|
|
$this->actingAs($user);
|
|
|
|
// minimal person/client scaffolding
|
|
$group = new PersonGroup; $group->name = 'grp'; $group->save();
|
|
$type = PersonType::create(['name' => 'tip']);
|
|
$p1 = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
|
|
$p2 = Person::create(['first_name' => 'Bojan', 'last_name' => 'Drugi', 'full_name' => 'Bojan Drugi', 'group_id' => $group->id, 'type_id' => $type->id]);
|
|
|
|
$clientA = App\Models\Client::create(['person_id' => $p1->id]);
|
|
$clientB = App\Models\Client::create(['person_id' => $p2->id]);
|
|
|
|
$caseA = ClientCase::create(['client_id' => $clientA->id, 'person_id' => $p1->id, 'client_ref' => 'A']);
|
|
$caseB = ClientCase::create(['client_id' => $clientB->id, 'person_id' => $p2->id, 'client_ref' => 'B']);
|
|
|
|
$ctype = new App\Models\ContractType;
|
|
$ctype->name = 'Standard';
|
|
$ctype->save();
|
|
|
|
// Active contract for client A
|
|
App\Models\Contract::create([
|
|
'reference' => 'A-001',
|
|
'client_case_id' => $caseA->id,
|
|
'type_id' => $ctype->id,
|
|
'start_date' => now()->subDays(10)->toDateString(),
|
|
'end_date' => null,
|
|
]);
|
|
|
|
// Inactive for client A (ended yesterday)
|
|
App\Models\Contract::create([
|
|
'reference' => 'A-OLD',
|
|
'client_case_id' => $caseA->id,
|
|
'type_id' => $ctype->id,
|
|
'start_date' => now()->subMonths(2)->toDateString(),
|
|
'end_date' => now()->subDay()->toDateString(),
|
|
]);
|
|
|
|
// Active but for different client B (should be excluded by client filter)
|
|
App\Models\Contract::create([
|
|
'reference' => 'B-001',
|
|
'client_case_id' => $caseB->id,
|
|
'type_id' => $ctype->id,
|
|
'start_date' => now()->subDays(3)->toDateString(),
|
|
'end_date' => null,
|
|
]);
|
|
|
|
$resp = $this->getJson(route('reports.data', ['slug' => 'active-contracts', 'client_uuid' => $clientA->uuid, 'as_of' => now()->toDateString()]));
|
|
$resp->assertOk();
|
|
$json = $resp->json();
|
|
|
|
// Should list exactly the active one for client A
|
|
expect($json['data'])->toBeArray();
|
|
// Filter only references from result
|
|
$refs = array_map(fn ($r) => $r['contract_reference'] ?? null, $json['data']);
|
|
expect($refs)->toContain('A-001');
|
|
expect($refs)->not->toContain('A-OLD');
|
|
expect($refs)->not->toContain('B-001');
|
|
});
|
|
|
|
it('counts activities per segment', function () {
|
|
$user = makeUserWithPermissions(['reports-view']);
|
|
$this->actingAs($user);
|
|
|
|
$segment = Segment::create(['name' => 'Prioriteta A', 'description' => 'desc', 'active' => true]);
|
|
$action = Action::factory()->create(['segment_id' => $segment->id]);
|
|
$decision = Decision::create(['name' => 'OK']);
|
|
$group = new PersonGroup;
|
|
$group->name = 'grp';
|
|
$group->save();
|
|
$type = PersonType::create(['name' => 'tip']);
|
|
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
|
|
$client = Client::create(['person_id' => $person->id]);
|
|
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
|
|
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
|
|
$resp = $this->getJson(route('reports.data', 'segment-activity-counts'));
|
|
$resp->assertOk();
|
|
$json = $resp->json();
|
|
expect($json['data'][0]['segment_name'])->toBe('Prioriteta A');
|
|
expect($json['data'][0]['activities_count'])->toBe(2);
|
|
});
|
|
|
|
it('groups activities per day', function () {
|
|
$user = makeUserWithPermissions(['reports-view']);
|
|
$this->actingAs($user);
|
|
|
|
$action = Action::factory()->create();
|
|
$decision = Decision::create(['name' => 'OK']);
|
|
$group = new PersonGroup;
|
|
$group->name = 'grp';
|
|
$group->save();
|
|
$type = PersonType::create(['name' => 'tip']);
|
|
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
|
|
$client = Client::create(['person_id' => $person->id]);
|
|
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
|
|
// Create two today and one yesterday (explicit timestamps via insert to avoid auto-timestamp override)
|
|
Activity::query()->insert([
|
|
['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now(), 'updated_at' => now()],
|
|
['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now(), 'updated_at' => now()],
|
|
['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now()->subDay(), 'updated_at' => now()->subDay()],
|
|
]);
|
|
|
|
$resp = $this->getJson(route('reports.data', ['slug' => 'activities-per-period', 'period' => 'day']));
|
|
$resp->assertOk();
|
|
$json = collect($resp->json('data'));
|
|
// Find today row
|
|
$todayRow = $json->first(function ($r) {
|
|
return str_starts_with((string) $r['period'], date('Y-m-d'));
|
|
});
|
|
expect($todayRow)->not()->toBeNull();
|
|
expect($todayRow['activities_count'])->toBe(2);
|
|
});
|
|
|
|
it('counts activities per decision only', function () {
|
|
$user = makeUserWithPermissions(['reports-view']);
|
|
$this->actingAs($user);
|
|
|
|
$decision = Decision::create(['name' => 'OK']);
|
|
$group = new PersonGroup;
|
|
$group->name = 'grp';
|
|
$group->save();
|
|
$type = PersonType::create(['name' => 'tip']);
|
|
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
|
|
$client = Client::create(['person_id' => $person->id]);
|
|
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
|
|
|
|
$action = Action::factory()->create();
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
|
|
|
|
$resp = $this->getJson(route('reports.data', 'decisions-counts'));
|
|
$resp->assertOk();
|
|
$json = $resp->json();
|
|
expect($json['data'][0]['decision_name'])->toBe('OK');
|
|
expect($json['data'][0]['activities_count'])->toBe(3);
|
|
});
|