PDF Invoices Working #9
|
|
@ -0,0 +1,143 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\School;
|
||||||
|
use App\Services\Invoice\InvoiceDataService;
|
||||||
|
use Codedge\Fpdf\Fpdf\Fpdf;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use function auditionSetting;
|
||||||
|
|
||||||
|
class PdfInvoiceController extends Controller
|
||||||
|
{
|
||||||
|
protected $pdf;
|
||||||
|
|
||||||
|
protected $margin = .3;
|
||||||
|
|
||||||
|
protected $entriesPerPage = 45;
|
||||||
|
|
||||||
|
protected $invoiceTitle;
|
||||||
|
|
||||||
|
protected $paymentAddress;
|
||||||
|
|
||||||
|
protected $school;
|
||||||
|
|
||||||
|
protected $invoiceDataService;
|
||||||
|
|
||||||
|
protected $invoiceData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the incoming request.
|
||||||
|
*/
|
||||||
|
public function __construct(InvoiceDataService $invoiceDataService)
|
||||||
|
{
|
||||||
|
$this->invoiceDataService = $invoiceDataService;
|
||||||
|
|
||||||
|
// Set up our PDF
|
||||||
|
$this->pdf = new Fpdf('P', 'in', 'letter');
|
||||||
|
$this->pdf->AliasNbPages();
|
||||||
|
$this->pdf->SetMargins($this->margin, $this->margin);
|
||||||
|
$this->pdf->SetAutoPageBreak(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(Request $request, School $school)
|
||||||
|
{
|
||||||
|
$this->school = $school;
|
||||||
|
$this->invoiceData = $this->invoiceDataService->allData($school->id);
|
||||||
|
$this->invoiceTitle = auditionSetting('auditionAbbreviation').' entry report for '.$this->school->name;
|
||||||
|
$this->paymentAddress = auditionSetting('auditionName')."\n".
|
||||||
|
auditionSetting('payment_address')."\n".
|
||||||
|
auditionSetting('payment_city').', '.auditionSetting('payment_state').' '.auditionSetting('payment_zip');
|
||||||
|
|
||||||
|
$this->newInvoicePage();
|
||||||
|
$this->itemizeEntries();
|
||||||
|
$this->entryTotals();
|
||||||
|
if (auditionSetting('school_fee') > 0) {
|
||||||
|
$this->schoolFee(number_format(auditionSetting('school_fee') / 100, 2));
|
||||||
|
}
|
||||||
|
$this->grandTotal();
|
||||||
|
$this->output();
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newInvoicePage()
|
||||||
|
{
|
||||||
|
$this->pdf->AddPage();
|
||||||
|
$this->pdf->SetFont('Arial', 'B', 12);
|
||||||
|
$this->pdf->cell(4, .3, $this->invoiceTitle, 0, 1);
|
||||||
|
$this->pdf->SetFont('Arial', '', 9);
|
||||||
|
$this->pdf->cell(4, .1, 'Reflects entries as of '.date('g:i A').' on '.date('F j, Y'), 0, 1);
|
||||||
|
$this->pdf->cell(4, .15, 'Additional entries may result in additional charges');
|
||||||
|
$this->pdf->setXY(-3, $this->margin + .45);
|
||||||
|
$this->pdf->cell(0, 0, 'Page '.$this->pdf->PageNo().' of {nb}', 0, 0, 'R');
|
||||||
|
$this->pdf->line($this->margin, .6 + $this->margin, 8.5 - $this->margin, .6 + $this->margin);
|
||||||
|
$this->pdf->setXY($this->margin, $this->margin + .65);
|
||||||
|
$this->pdf->SetFont('Arial', 'B', 9);
|
||||||
|
$this->pdf->cell(0, .15, 'SEND PAYMENT TO:', 0, 1);
|
||||||
|
$this->pdf->SetFont('Arial', '', 9);
|
||||||
|
$this->pdf->MultiCell(0, .12, $this->paymentAddress);
|
||||||
|
$this->pdf->setXY($this->margin, $this->margin + 1.4);
|
||||||
|
|
||||||
|
$this->pdf->SetFont('Arial', 'B', 9);
|
||||||
|
|
||||||
|
$this->pdf->Cell(2.1, .15, 'Student Name', 1);
|
||||||
|
$this->pdf->Cell(2.1, .15, 'Instrument', 1);
|
||||||
|
$this->pdf->Cell(1.7, .15, 'Entry Timestamp', 1);
|
||||||
|
$this->pdf->Cell(1, .15, 'Entry Fee', 1);
|
||||||
|
$this->pdf->Cell(1, .15, 'Late Fee', 1, 1);
|
||||||
|
$this->pdf->SetFont('Arial', '', 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function itemizeEntries()
|
||||||
|
{
|
||||||
|
$entriesThisPage = 0;
|
||||||
|
foreach ($this->invoiceData['lines'] as $line) {
|
||||||
|
if ($entriesThisPage >= $this->entriesPerPage) {
|
||||||
|
$this->newInvoicePage();
|
||||||
|
$entriesThisPage = 0;
|
||||||
|
}
|
||||||
|
$this->pdf->Cell(2.1, .15, $line['student_name'], 1);
|
||||||
|
$this->pdf->Cell(2.1, .15, $line['audition'], 1);
|
||||||
|
$this->pdf->Cell(1.7, .15, $line['entry_timestamp'], 1);
|
||||||
|
$this->pdf->Cell(1, .15, number_format($line['entry_fee'], 2), 1);
|
||||||
|
$this->pdf->Cell(1, .15, number_format($line['late_fee'], 2), 1, 1);
|
||||||
|
$entriesThisPage++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function entryTotals()
|
||||||
|
{
|
||||||
|
$this->pdf->SetFont('Arial', 'B', 9);
|
||||||
|
$this->pdf->Cell(2.1, .3, '', 0);
|
||||||
|
$this->pdf->Cell(2.1, .3, '', 0);
|
||||||
|
$this->pdf->Cell(1.7, .3, 'TOTAL', 1);
|
||||||
|
$this->pdf->Cell(1, .3, '$'.number_format($this->invoiceData['linesTotal'], 2), 1);
|
||||||
|
$this->pdf->Cell(1, .3, '$'.number_format($this->invoiceData['lateFeesTotal'], 2), 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function schoolFee($fee)
|
||||||
|
{
|
||||||
|
$this->pdf->Cell(2.1, .3, '', 0);
|
||||||
|
$this->pdf->Cell(2.1, .3, '', 0);
|
||||||
|
$this->pdf->Cell(1.7, .3, 'SCHOOL FEE', 1);
|
||||||
|
$this->pdf->Cell(2, .3, '$'.$fee, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function grandTotal()
|
||||||
|
{
|
||||||
|
$this->pdf->Cell(2.1, .3, '', 0);
|
||||||
|
$this->pdf->Cell(2.1, .3, '', 0);
|
||||||
|
$this->pdf->Cell(1.7, .3, 'GRAND TOTAL', 1);
|
||||||
|
$this->pdf->Cell(2, .3, '$'.number_format($this->invoiceData['grandTotal'], 2), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function output($dest = 'D', $name = null)
|
||||||
|
{
|
||||||
|
if (! $name) {
|
||||||
|
$name = auditionSetting('auditionAbbreviation').' Invoice for '.$this->school->name.'.pdf';
|
||||||
|
$this->pdf->Output($dest, $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"codedge/laravel-fpdf": "^1.12",
|
||||||
"laravel/fortify": "^1.21",
|
"laravel/fortify": "^1.21",
|
||||||
"laravel/framework": "^11.0",
|
"laravel/framework": "^11.0",
|
||||||
"laravel/tinker": "^2.9",
|
"laravel/tinker": "^2.9",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "621017524a521b75138e8a946978fb42",
|
"content-hash": "8a539bb700e8acfbb39c896521c16609",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
|
|
@ -189,6 +189,73 @@
|
||||||
],
|
],
|
||||||
"time": "2024-02-09T16:56:22+00:00"
|
"time": "2024-02-09T16:56:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "codedge/laravel-fpdf",
|
||||||
|
"version": "1.12.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/codedge/laravel-fpdf.git",
|
||||||
|
"reference": "9319768852f483ec5a3b00ca19b2157349c88fb9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/codedge/laravel-fpdf/zipball/9319768852f483ec5a3b00ca19b2157349c88fb9",
|
||||||
|
"reference": "9319768852f483ec5a3b00ca19b2157349c88fb9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/support": "^9.0 || ^10.0 || ^11.0",
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ergebnis/composer-normalize": "^2.39",
|
||||||
|
"orchestra/testbench": "^7.35.0 || ^8.0 || ^9.0",
|
||||||
|
"phpunit/phpunit": "^9.6.0 || ^10.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"Fpdf": "Codedge\\Fpdf\\Facades\\Fpdf"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Codedge\\Fpdf\\FpdfServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Codedge\\Fpdf\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Holger Lösken",
|
||||||
|
"email": "holger.loesken@codedge.de"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Laravel package to include Fpdf. It ships with Fpdf 1.86.",
|
||||||
|
"keywords": [
|
||||||
|
"fpdf",
|
||||||
|
"laravel",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/codedge/laravel-fpdf/issues",
|
||||||
|
"source": "https://github.com/codedge/laravel-fpdf"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/codedge",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-03-19T13:25:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dasprid/enum",
|
"name": "dasprid/enum",
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default configuration for FPDF
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Specify the default values for creating a PDF with FPDF
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'orientation' => 'P',
|
||||||
|
'unit' => 'in',
|
||||||
|
'size' => 'Letter',
|
||||||
|
'font_path' => env('FPDF_FONTPATH'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| With Laravel Vapor hosting
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If the application is to be hosted in the Laravel Vapor hosting platform,
|
||||||
|
| a special header needs to be attached to each download response.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'useVaporHeaders' => env('FPDF_VAPOR_HEADERS', false),
|
||||||
|
|
||||||
|
];
|
||||||
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
<x-slot:page_title>Invoice - {{ $school->name }}</x-slot:page_title>
|
<x-slot:page_title>Invoice - {{ $school->name }}</x-slot:page_title>
|
||||||
|
<x-slot:title_bar_right>
|
||||||
|
<x-form.button href="{{ route('pdf_invoice',$school->id) }}">Download PDF Invoice</x-form.button>
|
||||||
|
</x-slot:title_bar_right>
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<x-table.table class="">
|
<x-table.table class="">
|
||||||
<thead class="">
|
<thead class="">
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// Dashboard Related Routes
|
// Dashboard Related Routes
|
||||||
use App\Http\Controllers\DashboardController;
|
use App\Http\Controllers\DashboardController;
|
||||||
use App\Http\Controllers\EntryController;
|
use App\Http\Controllers\EntryController;
|
||||||
|
use App\Http\Controllers\PdfInvoiceController;
|
||||||
use App\Http\Controllers\SchoolController;
|
use App\Http\Controllers\SchoolController;
|
||||||
use App\Http\Controllers\StudentController;
|
use App\Http\Controllers\StudentController;
|
||||||
use App\Http\Controllers\UserController;
|
use App\Http\Controllers\UserController;
|
||||||
|
|
@ -13,6 +14,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||||
Route::get('/profile', [DashboardController::class, 'profile'])->name('my_profile');
|
Route::get('/profile', [DashboardController::class, 'profile'])->name('my_profile');
|
||||||
Route::get('/my_school', [DashboardController::class, 'my_school'])->name('my_school');
|
Route::get('/my_school', [DashboardController::class, 'my_school'])->name('my_school');
|
||||||
Route::get('/my_invoice', [DashboardController::class, 'my_invoice'])->name('my_invoice');
|
Route::get('/my_invoice', [DashboardController::class, 'my_invoice'])->name('my_invoice');
|
||||||
|
Route::get('/pdf-invoice/{school}', PdfInvoiceController::class)->name('pdf_invoice');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Entry Related Routes
|
// Entry Related Routes
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use App\Http\Controllers\DashboardController;
|
||||||
use App\Http\Controllers\EntryController;
|
use App\Http\Controllers\EntryController;
|
||||||
use App\Http\Controllers\FilterController;
|
use App\Http\Controllers\FilterController;
|
||||||
use App\Http\Controllers\JudgingController;
|
use App\Http\Controllers\JudgingController;
|
||||||
|
use App\Http\Controllers\PdfInvoiceController;
|
||||||
use App\Http\Controllers\SchoolController;
|
use App\Http\Controllers\SchoolController;
|
||||||
use App\Http\Controllers\StudentController;
|
use App\Http\Controllers\StudentController;
|
||||||
use App\Http\Controllers\Tabulation\DoublerDecisionController;
|
use App\Http\Controllers\Tabulation\DoublerDecisionController;
|
||||||
|
|
@ -22,6 +23,7 @@ require __DIR__.'/user.php';
|
||||||
|
|
||||||
Route::get('/test', [TestController::class, 'flashTest'])->middleware('auth', 'verified');
|
Route::get('/test', [TestController::class, 'flashTest'])->middleware('auth', 'verified');
|
||||||
|
|
||||||
|
|
||||||
Route::view('/', 'welcome')->middleware('guest')->name('home');
|
Route::view('/', 'welcome')->middleware('guest')->name('home');
|
||||||
Route::get('/results', [App\Http\Controllers\ResultsPage::class, '__invoke'])->name('results');
|
Route::get('/results', [App\Http\Controllers\ResultsPage::class, '__invoke'])->name('results');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue