diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php
index 5b2c14b..dc551f4 100644
--- a/app/Http/Controllers/DashboardController.php
+++ b/app/Http/Controllers/DashboardController.php
@@ -2,13 +2,20 @@
namespace App\Http\Controllers;
-use Illuminate\Http\Request;
+use App\Services\Invoice\InvoiceDataService;
use Illuminate\Support\Facades\Auth;
-use function dd;
+
use function redirect;
class DashboardController extends Controller
{
+ protected InvoiceDataService $invoiceService;
+
+ public function __construct(InvoiceDataService $invoiceService)
+ {
+ $this->invoiceService = $invoiceService;
+ }
+
public function profile()
{
return view('dashboard.profile');
@@ -22,10 +29,23 @@ class DashboardController extends Controller
public function my_school()
{
if (Auth::user()->school) {
- return redirect('/schools/' . Auth::user()->school->id);
+ return redirect('/schools/'.Auth::user()->school->id);
}
$possibilities = Auth::user()->possibleSchools();
- if (count($possibilities) < 1) return view('schools.create');
+ if (count($possibilities) < 1) {
+ return view('schools.create');
+ }
+
return view('dashboard.select_school', ['possibilities' => $possibilities]);
}
+
+ public function my_invoice()
+ {
+ if (! Auth::user()->school_id) {
+ return redirect()->route('dashboard')->with('error', 'You do not have a school to get an invoice for');
+ }
+ $invoiceData = $this->invoiceService->allData(Auth::user()->school_id);
+ $school = Auth::user()->school;
+ return view('dashboard.invoice', compact('school', 'invoiceData'));
+ }
}
diff --git a/app/Http/Controllers/TestController.php b/app/Http/Controllers/TestController.php
index c24fbfe..99fc429 100644
--- a/app/Http/Controllers/TestController.php
+++ b/app/Http/Controllers/TestController.php
@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Services\AuditionService;
+use App\Services\Invoice\InvoiceDataService;
use App\Services\TabulationService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
@@ -11,16 +12,22 @@ class TestController extends Controller
{
protected $scoringGuideCacheService;
protected $tabulationService;
+ protected $invoiceService;
- public function __construct(AuditionService $scoringGuideCacheService, TabulationService $tabulationService)
- {
+ public function __construct(
+ AuditionService $scoringGuideCacheService,
+ TabulationService $tabulationService,
+ InvoiceDataService $invoiceService
+ ) {
$this->scoringGuideCacheService = $scoringGuideCacheService;
$this->tabulationService = $tabulationService;
+ $this->invoiceService = $invoiceService;
}
public function flashTest(Request $request)
{
- $auditions = $this->tabulationService->getAuditionsWithStatus();
- return view('test', compact('auditions'));
+ $lines = $this->invoiceService->getLines(12);
+ $totalFees = $this->invoiceService->getGrandTotal(12);
+ return view('test', compact('lines','totalFees'));
}
}
diff --git a/app/Models/School.php b/app/Models/School.php
index af18e16..93c886e 100644
--- a/app/Models/School.php
+++ b/app/Models/School.php
@@ -17,25 +17,28 @@ class School extends Model
{
return $this->hasMany(User::class);
}
+
public function users(): HasMany
{
return $this->hasMany(User::class);
}
+
public function emailDomains(): HasMany
{
return $this->hasMany(SchoolEmailDomain::class);
}
- public function initialLetterImageURL($bg_color = '4f46e5', $text_color='fff'): string
+ public function initialLetterImageURL($bg_color = '4f46e5', $text_color = 'fff'): string
{
$img = "https://ui-avatars.com/api/?background=$bg_color&color=$text_color&name=";
- $img .= substr($this->name,0,1);
+ $img .= substr($this->name, 0, 1);
+
return $img;
}
public function students(): HasMany
{
- return $this->hasMany(Student::class);
+ return $this->hasMany(Student::class)->orderBy('last_name')->orderBy('first_name');
}
public function entries(): HasManyThrough
@@ -48,5 +51,4 @@ class School extends Model
'id',
'id');
}
-
}
diff --git a/app/Providers/InvoiceDataServiceProvider.php b/app/Providers/InvoiceDataServiceProvider.php
new file mode 100644
index 0000000..6556ed4
--- /dev/null
+++ b/app/Providers/InvoiceDataServiceProvider.php
@@ -0,0 +1,38 @@
+app->singleton(InvoiceDataService::class, function ($app) {
+ // Default binding, can be overridden in booth method
+ return new InvoiceOneFeePerEntry($app->make(EntryService::class));
+ });
+ }
+
+ /**
+ * Bootstrap services.
+ */
+ public function boot(): void
+ {
+ $this->app->singleton(InvoiceDataService::class, function ($app) {
+ return match (auditionSetting('fee_structure')) {
+ 'oneFeePerEntry' => new InvoiceOneFeePerEntry($app->make(EntryService::class)),
+ 'oneFeePerStudent' => new InvoiceOneFeePerStudent($app->make(EntryService::class)),
+ default => throw new \Exception('Unknown Invoice Method'),
+ };
+ });
+ }
+}
diff --git a/app/Services/Invoice/InvoiceAllStudentsPay.php b/app/Services/Invoice/InvoiceAllStudentsPay.php
deleted file mode 100644
index 14adc18..0000000
--- a/app/Services/Invoice/InvoiceAllStudentsPay.php
+++ /dev/null
@@ -1,47 +0,0 @@
-entryService = $entryService;
+ }
+
+ public function allData($schoolId)
+ {
+ static $schoolInvoiceData = [];
+
+ if (Arr::has($schoolInvoiceData, $schoolId)) {
+ return $schoolInvoiceData[$schoolId];
+ }
+ $school = School::findOrFail($schoolId);
+
+ $invoiceData['lines'] = [];
+ $invoiceData['linesTotal'] = 0;
+ $invoiceData['lateFeesTotal'] = 0;
+ /** @noinspection PhpArrayIndexImmediatelyRewrittenInspection */
+ $invoiceData['grandTotal'] = 0;
+
+ $entries = $school->entries()->with('audition')->orderBy('created_at', 'desc')->get()->groupBy('student_id');
+ foreach ($school->students as $student) {
+ foreach ($entries[$student->id] as $entry) {
+ $entryFee = $entry->audition->entry_fee / 100;
+ $lateFee = $this->entryService->entryIsLate($entry) ? auditionSetting('late_fee') / 100 : 0;
+
+ $invoiceData['lines'][] = [
+ 'student_name' => $student->full_name(true),
+ 'audition' => $entry->audition->name,
+ 'entry_timestamp' => $entry->created_at,
+ 'entry_fee' => $entryFee,
+ 'late_fee' => $lateFee,
+ ];
+ $invoiceData['linesTotal'] += $entryFee;
+ $invoiceData['lateFeesTotal'] += $lateFee;
+ }
+ }
+ // School Fee Total
+ if (! auditionSetting('school_fee')) {
+ $invoiceData['schoolFeeTotal'] = 0;
+ } else {
+ $invoiceData['schoolFeeTotal'] = auditionSetting('school_fee') / 100;
+ }
+
+ $invoiceData['grandTotal'] = $invoiceData['linesTotal'] + $invoiceData['lateFeesTotal'] + $invoiceData['schoolFeeTotal'];
+ $schoolInvoiceData[$school->id] = $invoiceData;
+
+ return $invoiceData;
+ }
+
+ public function getLines($schoolId)
+ {
+ return $this->allData($schoolId)['lines'];
+ }
+
+ public function getLinesTotal($schoolId)
+ {
+ return $this->allData($schoolId)['linesTotal'];
+ }
+
+ public function getLateFeesTotal($schoolId)
+ {
+ return $this->allData($schoolId)['lateFeesTotal'];
+ }
+
+ public function getSchoolFeeTotal($schoolId)
+ {
+ return $this->allData($schoolId)['schoolFeeTotal'];
+
+ }
+
+ public function getGrandTotal($schoolId)
+ {
+ return $this->allData($schoolId)['grandTotal'];
+ }
+}
diff --git a/app/Services/Invoice/InvoiceOneFeePerStudent.php b/app/Services/Invoice/InvoiceOneFeePerStudent.php
new file mode 100644
index 0000000..3bf9f99
--- /dev/null
+++ b/app/Services/Invoice/InvoiceOneFeePerStudent.php
@@ -0,0 +1,100 @@
+entryService = $entryService;
+ }
+
+ public function allData($schoolId)
+ {
+ static $schoolInvoiceData = [];
+
+ if (Arr::has($schoolInvoiceData, $schoolId)) {
+ return $schoolInvoiceData[$schoolId];
+ }
+ $school = School::findOrFail($schoolId);
+
+ $invoiceData['lines'] = [];
+ $invoiceData['linesTotal'] = 0;
+ $invoiceData['lateFeesTotal'] = 0;
+ /** @noinspection PhpArrayIndexImmediatelyRewrittenInspection */
+ $invoiceData['grandTotal'] = 0;
+
+ $entries = $school->entries()->with('audition')->orderBy('created_at', 'desc')->get()->groupBy('student_id');
+ foreach ($school->students as $student) {
+ $firstEntryForStudent = true;
+ foreach ($entries[$student->id] as $entry) {
+ if ($firstEntryForStudent) {
+ $entryFee = $entry->audition->entry_fee / 100;
+ $lateFee = $this->entryService->entryIsLate($entry) ? auditionSetting('late_fee') / 100 : 0;
+ } else {
+ $entryFee = 0;
+ $lateFee = 0;
+ }
+
+ $invoiceData['lines'][] = [
+ 'student_name' => $student->full_name(true),
+ 'audition' => $entry->audition->name,
+ 'entry_timestamp' => $entry->created_at,
+ 'entry_fee' => $entryFee,
+ 'late_fee' => $lateFee,
+ ];
+ $invoiceData['linesTotal'] += $entryFee;
+ $invoiceData['lateFeesTotal'] += $lateFee;
+ $firstEntryForStudent = false;
+ }
+ }
+ // School Fee Total
+ if (! auditionSetting('school_fee')) {
+ $invoiceData['schoolFeeTotal'] = 0;
+ } else {
+ $invoiceData['schoolFeeTotal'] = auditionSetting('school_fee') / 100;
+ }
+
+ $invoiceData['grandTotal'] = $invoiceData['linesTotal'] + $invoiceData['lateFeesTotal'] + $invoiceData['schoolFeeTotal'];
+ $schoolInvoiceData[$school->id] = $invoiceData;
+
+ return $invoiceData;
+ }
+
+ public function getLines($schoolId)
+ {
+ return $this->allData($schoolId)['lines'];
+ }
+
+ public function getLinesTotal($schoolId)
+ {
+ return $this->allData($schoolId)['linesTotal'];
+ }
+
+ public function getLateFeesTotal($schoolId)
+ {
+ return $this->allData($schoolId)['lateFeesTotal'];
+ }
+
+ public function getSchoolFeeTotal($schoolId)
+ {
+ return $this->allData($schoolId)['schoolFeeTotal'];
+
+ }
+
+ public function getGrandTotal($schoolId)
+ {
+ return $this->allData($schoolId)['grandTotal'];
+ }
+}
diff --git a/bootstrap/providers.php b/bootstrap/providers.php
index 0ad9c57..9edefb0 100644
--- a/bootstrap/providers.php
+++ b/bootstrap/providers.php
@@ -3,4 +3,5 @@
return [
App\Providers\AppServiceProvider::class,
App\Providers\FortifyServiceProvider::class,
+ App\Providers\InvoiceDataServiceProvider::class,
];
diff --git a/resources/views/dashboard/invoice.blade.php b/resources/views/dashboard/invoice.blade.php
new file mode 100644
index 0000000..a8afc96
--- /dev/null
+++ b/resources/views/dashboard/invoice.blade.php
@@ -0,0 +1,44 @@
+@props(['school', 'invoiceData'])
+
+
+ Invoice - {{ $school->name }}
+ @php( dump($invoiceData ))
+
+ Invoice
+
+
+ Student Name
+ Audition
+ Entry Timestamp
+ Entry Fee
+ Late Fee
+
+
+
+ @foreach($invoiceData['lines'] as $line)
+
+ {{ $line['student_name'] }}
+ {{ $line['audition'] }}
+ {{ $line['entry_timestamp']->setTimezone('America/Chicago')->format('m/d/Y g:i:s A') }}
+ ${{ number_format($line['entry_fee'],2) }}
+ ${{ number_format($line['late_fee'],2) }}
+
+ @endforeach
+
+
+
+ Totals
+ ${{ number_format($invoiceData['linesTotal'],2) }}
+ ${{ number_format($invoiceData['lateFeesTotal'],2) }}
+
+
+ School Fee
+ ${{ number_format($invoiceData['schoolFeeTotal'],2) }}
+
+
+ Grand Total
+ ${{ number_format($invoiceData['grandTotal'],2) }}
+
+
+
+
diff --git a/resources/views/test.blade.php b/resources/views/test.blade.php
index 861bdbf..ddd5fa6 100644
--- a/resources/views/test.blade.php
+++ b/resources/views/test.blade.php
@@ -16,9 +16,9 @@
Test Page
@php
- $schools = School::all();
+ dump($totalFees);
+ dump($lines);
- }
@endphp
diff --git a/routes/user.php b/routes/user.php
index 3974d1a..8be2957 100644
--- a/routes/user.php
+++ b/routes/user.php
@@ -12,6 +12,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'dashboard'])->name('dashboard');
Route::get('/profile', [DashboardController::class, 'profile']);
Route::get('/my_school', [DashboardController::class, 'my_school']);
+ Route::get('/my_invoice', [DashboardController::class, 'my_invoice'])->name('my_invoice');
});
// Entry Related Routes