diff --git a/app/Actions/Entries/UpdateEntry.php b/app/Actions/Entries/UpdateEntry.php
index eeb8d90..9fe0bba 100644
--- a/app/Actions/Entries/UpdateEntry.php
+++ b/app/Actions/Entries/UpdateEntry.php
@@ -86,7 +86,9 @@ class UpdateEntry
if ($this->entry->scoreSheets()->count() > 0) {
throw new ManageEntryException('Cannot change the audition for an entry with scores');
}
- if (Entry::where('student_id', $this->entry->student_id)->where('audition_id', $audition->id)->exists()) {
+ if ($audition->id !== $this->entry->audition_id &&
+ Entry::where('student_id', $this->entry->student_id)
+ ->where('audition_id', $audition->id)->exists()) {
throw new ManageEntryException('That student is already entered in that audition');
}
// OK we're allowed to change the audition
diff --git a/app/Http/Controllers/Admin/EntryController.php b/app/Http/Controllers/Admin/EntryController.php
index d6025a9..78c7d6d 100644
--- a/app/Http/Controllers/Admin/EntryController.php
+++ b/app/Http/Controllers/Admin/EntryController.php
@@ -161,6 +161,7 @@ class EntryController extends Controller
$validData['for_seating'] = $request->get('for_seating') ? 1 : 0;
$validData['for_advancement'] = $request->get('for_advancement') ? 1 : 0;
+ $validData['late_fee_waived'] = $request->get('late_fee_waived') ? 1 : 0;
// If the audition is not set to advance to the next round, then the entry must be for seating
if (! auditionSetting('advanceTo')) {
@@ -171,12 +172,11 @@ class EntryController extends Controller
} catch (ManageEntryException $e) {
return redirect()->route('admin.entries.index')->with('error', $e->getMessage());
}
-
- // $entry->update([
- // 'audition_id' => $validData['audition_id'],
- // 'for_seating' => $validData['for_seating'],
- // 'for_advancement' => $validData['for_advancement'],
- // ]);
+ if ($validData['late_fee_waived']) {
+ $entry->addFlag('late_fee_waived');
+ } else {
+ $entry->removeFlag('late_fee_waived');
+ }
return to_route('admin.entries.index')->with('success', 'Entry updated successfully');
}
diff --git a/app/Services/Invoice/InvoiceOneFeePerEntry.php b/app/Services/Invoice/InvoiceOneFeePerEntry.php
index 1ca5b34..6577546 100644
--- a/app/Services/Invoice/InvoiceOneFeePerEntry.php
+++ b/app/Services/Invoice/InvoiceOneFeePerEntry.php
@@ -39,7 +39,8 @@ class InvoiceOneFeePerEntry implements InvoiceDataService
foreach ($school->students as $student) {
foreach ($entries[$student->id] ?? [] as $entry) {
$entryFee = $entry->audition->entry_fee / 100;
- $lateFee = $this->entryService->isEntryLate($entry) ? auditionSetting('late_fee') / 100 : 0;
+ $lateFee = ($this->entryService->isEntryLate($entry) && ! $entry->hasFlag('late_fee_waived'))
+ ? auditionSetting('late_fee') / 100 : 0;
$invoiceData['lines'][] = [
'student_name' => $student->full_name(true),
diff --git a/app/Services/Invoice/InvoiceOneFeePerStudent.php b/app/Services/Invoice/InvoiceOneFeePerStudent.php
index c5090ac..69b5fe5 100644
--- a/app/Services/Invoice/InvoiceOneFeePerStudent.php
+++ b/app/Services/Invoice/InvoiceOneFeePerStudent.php
@@ -41,7 +41,8 @@ class InvoiceOneFeePerStudent implements InvoiceDataService
foreach ($entries[$student->id] ?? [] as $entry) {
if ($firstEntryForStudent) {
$entryFee = $entry->audition->entry_fee / 100;
- $lateFee = $this->entryService->entryIsLate($entry) ? auditionSetting('late_fee') / 100 : 0;
+ $lateFee = ($this->entryService->isEntryLate($entry) && ! $entry->hasFlag('late_fee_waived'))
+ ? auditionSetting('late_fee') / 100 : 0;
} else {
$entryFee = 0;
$lateFee = 0;
diff --git a/resources/views/admin/entries/edit.blade.php b/resources/views/admin/entries/edit.blade.php
index f34193a..8c96f7e 100644
--- a/resources/views/admin/entries/edit.blade.php
+++ b/resources/views/admin/entries/edit.blade.php
@@ -35,7 +35,8 @@
- {{ auditionSetting('auditionAbbreviation') }} Total + {{ auditionSetting('auditionAbbreviation') }} Total {{ $score->totalScore('seating')[0] }}
diff --git a/tests/Feature/Pages/Admin/EntriesEditTest.php b/tests/Feature/Pages/Admin/EntriesEditTest.php index 121d0c2..63ebfe2 100644 --- a/tests/Feature/Pages/Admin/EntriesEditTest.php +++ b/tests/Feature/Pages/Admin/EntriesEditTest.php @@ -236,7 +236,7 @@ it('has a link to delete scores', function () { // Act & Assert $scoreSheet = ScoreSheet::where('entry_id', $entry->id)->first(); actAsAdmin(); - $response = get(route('admin.entries.edit', $entry)) + get(route('admin.entries.edit', $entry)) ->assertSee(route('scores.destroy', ['score' => $scoreSheet])); }); @@ -286,3 +286,20 @@ it('does not allow an admin to delete an entry if that entries advancement is pu ->assertRedirect(route('admin.entries.index')); expect(Entry::find($this->entry->id))->not->toBeNull(); }); +it('allows an admin to waive a late fee on an entry', function () { + // Arrange + $newAudition = Audition::factory()->create(['minimum_grade' => 1, 'maximum_grade' => 20]); + actAsAdmin(); + // Act & Assert + /** @noinspection PhpUnhandledExceptionInspection */ + patch(route('admin.entries.update', $this->entry), ['audition_id' => $newAudition->id, 'late_fee_waived' => 1]) + ->assertSessionHasNoErrors() + ->assertSessionMissing('error') + ->assertSessionHas('success', 'Entry updated successfully') + ->assertRedirect(route('admin.entries.index')); + $this->entry->refresh(); + expect($this->entry->audition_id)->toBe($newAudition->id) + ->and($this->entry->for_seating)->toBe(0) + ->and($this->entry->for_advancement)->toBe(0); + $this->assertDatabaseHas('entry_flags', ['entry_id' => $this->entry->id, 'flag_name' => 'late_fee_waived']); +});