'Super Admin', 'guard_name' => 'web']); Permission::firstOrCreate(['name' => 'projects.access', 'guard_name' => 'web']); $this->admin = User::factory()->create([ 'status' => 'active', 'user_type' => 'admin', ]); $this->admin->assignRole($role); $this->project = Project::create([ 'name' => 'Solar Park Substation', 'code' => 'PRJ-SP-2026', 'status' => ProjectStatus::InProgress, 'project_type' => 'standard', 'is_unprofitable' => false, 'contract_value' => 5000000.00, 'current_wizard_step' => 8, ]); } /** @test */ public function test_can_save_daily_report_with_past_date_and_all_nested_relations(): void { $payload = [ 'project_id' => $this->project->id, 'report_number' => 'DR-2026-AUG-20', 'report_date' => '2026-08-20', // past date to verify backdating is allowed 'weather' => 'Partly Cloudy', 'temperature' => '31°C', 'wind' => '15 km/h NE', 'precipitation' => '0mm', 'start_time' => '07:30', 'end_time' => '17:00', 'remarks' => 'Smooth foundation pour without delays.', 'activities' => [ [ 'task_name' => 'Excavation & Rebar Placement', 'quantity_completed' => '45 m3', 'percentage_completed' => 85, 'zone_area' => 'Sector 4', ], [ 'task_name' => '', // empty row should be gracefully ignored ], ], 'labors' => [ [ 'trade' => 'Lead Mason', 'workers_count' => 5, 'hours' => 8, 'notes' => 'Sector 4 concrete works', ], [ 'trade' => '', // empty row ], ], 'equipment' => [ [ 'equipment_name' => 'Komatsu PC200 Excavator', 'hours_used' => 7.5, 'status' => 'Active', ], [ 'equipment_name' => '', // empty row ], ], 'materials' => [ [ 'material_name' => 'Portland Cement Type 1', 'quantity' => 120, 'unit' => 'bags', 'remarks' => 'Delivered in good condition', ], [ 'material_name' => '', // empty row ], ], 'issues' => [ [ 'issue_type' => 'Weather', 'description' => 'Brief morning drizzle delayed rebar layout by 20 mins', 'delay_impact' => '20 mins', ], ], ]; $response = $this->actingAs($this->admin)->post(route('projects.daily-reports.store'), $payload); $response->assertRedirect(route('projects.daily-reports.index', ['project' => $this->project->ulid])); $response->assertSessionHas('success', 'Daily report created successfully.'); $this->assertDatabaseHas('daily_reports', [ 'project_id' => $this->project->id, 'report_number' => 'DR-2026-AUG-20', 'weather' => 'Partly Cloudy', ]); $report = DailyReport::where('report_number', 'DR-2026-AUG-20')->first(); $this->assertNotNull($report); $this->assertCount(1, $report->activities); $this->assertEquals('Excavation & Rebar Placement', $report->activities->first()->task_name); $this->assertCount(1, $report->labors); $this->assertEquals('Lead Mason', $report->labors->first()->trade); $this->assertCount(1, $report->equipment); $this->assertEquals('Komatsu PC200 Excavator', $report->equipment->first()->equipment_name); $this->assertCount(1, $report->materials); $this->assertEquals('Portland Cement Type 1', $report->materials->first()->material_name); $this->assertEquals('120 bags', $report->materials->first()->quantity_received); $this->assertCount(1, $report->issues); $this->assertEquals('Weather', $report->issues->first()->issue_type); } /** @test */ public function test_can_update_daily_report_successfully(): void { $report = DailyReport::create([ 'project_id' => $this->project->id, 'user_id' => $this->admin->id, 'report_number' => 'DR-ORIG-01', 'report_date' => '2026-08-25', 'weather' => 'Sunny', 'start_time' => '08:00', 'end_time' => '17:00', ]); $updatePayload = [ 'project_id' => $this->project->id, 'report_number' => 'DR-ORIG-01-UPDATED', 'report_date' => '2026-08-25', 'weather' => 'Heavy Rain Afternoon', 'start_time' => '08:00', 'end_time' => '15:00', 'remarks' => 'Work suspended at 3pm due to storm', 'activities' => [ [ 'task_name' => 'Drainage Clearing', 'quantity_completed' => '100 m', 'percentage_completed' => 100, 'zone_area' => 'Perimeter', ], ], 'labors' => [ [ 'trade' => 'General Worker', 'workers_count' => 6, 'hours' => 6, ], ], 'materials' => [ [ 'material_name' => 'PVC Pipe 4-inch', 'quantity_received' => '30 pcs', 'condition' => 'Good', ], ], ]; $response = $this->actingAs($this->admin)->put(route('projects.daily-reports.update', $report->id), $updatePayload); $response->assertRedirect(route('projects.daily-reports.index', ['project' => $this->project->ulid])); $response->assertSessionHas('success', 'Daily report updated successfully.'); $this->assertDatabaseHas('daily_reports', [ 'id' => $report->id, 'report_number' => 'DR-ORIG-01-UPDATED', 'weather' => 'Heavy Rain Afternoon', ]); $report->refresh(); $this->assertCount(1, $report->activities); $this->assertEquals('Drainage Clearing', $report->activities->first()->task_name); $this->assertCount(1, $report->labors); $this->assertEquals('General Worker', $report->labors->first()->trade); $this->assertCount(1, $report->materials); $this->assertEquals('30 pcs', $report->materials->first()->quantity_received); } }