Skip to content

Commit

Permalink
feat: academic charge files can be uploaded (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
BaaltRodrigo authored Oct 23, 2023
1 parent 889b557 commit b876ea9
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 16 deletions.
21 changes: 16 additions & 5 deletions app/Actions/HandleAcademicChargeFileLoad.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class HandleAcademicChargeFileLoad
{
public function execute(AcademicCharge $charge, array $fileLines)
public static function execute($validated): AcademicCharge
{
// Only for log purposes
$counters = [
Expand All @@ -25,12 +25,23 @@ public function execute(AcademicCharge $charge, array $fileLines)
'duplicate schedules' => 0,
];

// map the headers to line numbers
$headers = array_shift($fileLines);
// Read the file uploaded
$csvData = array_map('str_getcsv', file($validated['file']));
$headers = array_shift($csvData);
// Replace the first element special character \u{FEFF} (zero width no-break space)
$headers[0] = ltrim($headers[0], "\u{FEFF}");
//Map the headers to line numbers
$headers = array_flip($headers);

// Create the academic charge
$charge = AcademicCharge::create([
'year' => $csvData[1][$headers['Año']],
'semester' => $csvData[1][$headers['Período']],
'name' => $csvData[1][$headers['Sede']],
]);

// The following lines will create every necessary model for the academic charge
foreach ($fileLines as $line) {
foreach ($csvData as $line) {
// Create or get the Career
$career = Career::firstOrCreate([
'name' => Str::slug($line[$headers['Carrera']])
Expand Down Expand Up @@ -86,7 +97,7 @@ public function execute(AcademicCharge $charge, array $fileLines)
}
}

info('Lines inside file: ' . count($fileLines));
info('Lines inside file: ' . count($csvData));
info('Careers created: ' . $counters['careers']);
info('Schools created: ' . $counters['schools']);
info('Subjects created: ' . $counters['subjects']);
Expand Down
11 changes: 8 additions & 3 deletions app/Http/Controllers/v1/AcademicChargeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Controllers\v1;

use App\Actions\HandleAcademicChargeFileLoad;
use App\Http\Controllers\Controller;
use App\Http\Requests\ListSectionRequest;
use App\Http\Requests\StoreAcademicChargeRequest as StoreRequest;
Expand All @@ -11,6 +12,7 @@
use App\Http\Resources\Collections\AcademicChargeCollection;
use App\Http\Resources\Collections\CareerCollection;
use App\Http\Resources\Collections\SchoolCollection;
use App\Http\Resources\Identifiers\AcademicChargeIdentifier;
use App\Models\AcademicCharge;
use Illuminate\Http\Request;

Expand Down Expand Up @@ -40,12 +42,15 @@ public function show(AcademicCharge $charge): AcademicChargeResource
return new AcademicChargeResource($charge);
}

public function store(StoreRequest $request): AcademicChargeResource
public function store(StoreRequest $request): AcademicChargeIdentifier
{
$validated = $request->validated();
$academicCharge = AcademicCharge::create($validated);

return new AcademicChargeResource($academicCharge);
// TODO: Optimize this to avoid the creation of the same academic charge
// TODO: Move this to an job or something to avoid frontend waiting for the response
$charge = HandleAcademicChargeFileLoad::execute($validated);

return new AcademicChargeIdentifier($charge);
}

public function update(UpdateRequest $request, AcademicCharge $charge): AcademicChargeResource
Expand Down
5 changes: 1 addition & 4 deletions app/Http/Requests/StoreAcademicChargeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ public function authorize(): Response
public function rules(): array
{
return [
'name' => ['required', 'string'],
'year' => ['required', 'integer'],
'semester' => ['required', 'string'],
'is_hidden' => ['sometimes', 'boolean'],
'file' => ['required', 'file', 'mimes:csv,txt']
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function toArray(Request $request): array
'id' => $this->id,
'name' => str_replace('-', ' ', $this->name),
'season' => "{$this->year}-{$this->semester}",
'is_hidden' => $this->is_hidden,
'url' => route('academic-charges.show', $this->id),
];
}
Expand Down
18 changes: 14 additions & 4 deletions tests/Feature/AcademicChargeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
use App\Models\AcademicCharge;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Tests\TestCase;
use Tests\Traits\UseRolesTable;
use Tests\Traits\UseFirebaseUser;

class AcademicChargeTest extends TestCase
{
private string $CSV_PATH = 'database/data/SAN-JOAQUIN 2023-1.csv';

use RefreshDatabase, UseRolesTable, UseFirebaseUser;

public function test_index_route_is_public(): void
Expand Down Expand Up @@ -42,16 +45,21 @@ public function test_it_shows_available_charges_by_default(): void
$response->assertJsonFragment(['id' => $availableCharge->id]);
}

public function test_it_allows_admin_to_create_academic_charges(): void
public function test_it_allows_admin_to_upload_academic_charge_file(): void
{
$academicCharge = AcademicCharge::factory()->make();
$user = $this->createUserWithRoles(['duoc']);
$this->actingAsFirebaseUser();

$response = $this->postJson(route('academic-charges.store'), $academicCharge->toArray());
// get a file from database/data folder
$file = new UploadedFile($this->CSV_PATH, 'SAN-JOAQUIN 2023-1.csv', 'text/csv', null, true);

$response = $this->postJson(
route('academic-charges.store'),
['file' => $file],
// ['Content-Type' => 'multipart/form-data']
);

$response->assertStatus(201);
$this->assertDatabaseHas('academic_charges', $academicCharge->toArray());
}

public function test_it_allows_admin_to_update_academic_charges(): void
Expand Down Expand Up @@ -123,4 +131,6 @@ public function test_it_denies_common_users_to_delete_academic_charges(): void

$response->assertStatus(403);
}


}

0 comments on commit b876ea9

Please sign in to comment.