forked from TFMM/silent-auction
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eff3707268 | |||
| 23f944b808 | |||
| 8b80887d91 | |||
| bd6b83ad13 | |||
| 39a181e013 | |||
| ebfbee5296 | |||
| 39ffca777c | |||
| c76a8ed04a | |||
| b900a5e34b | |||
| 896c96e1a4 | |||
| f9590c7814 | |||
| 2935d84671 | |||
| a1ef5686e3 | |||
| ce5b69f362 | |||
| a95aa04cb9 | |||
| 935c7ba31b | |||
| 700d2f0741 | |||
| 4ef20cba50 | |||
| f35624cc6d | |||
| 6a911ba76c | |||
| d1c03b927e |
@@ -43,3 +43,6 @@ NORTH_CHECKOUT_ID=
|
|||||||
NORTH_PROFILE_ID=
|
NORTH_PROFILE_ID=
|
||||||
NORTH_PRIVATE_API_KEY=
|
NORTH_PRIVATE_API_KEY=
|
||||||
|
|
||||||
|
AUTO_PRINT_ENABLED=false
|
||||||
|
PRINTER_EMAIL=
|
||||||
|
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ npm-debug.log
|
|||||||
/public/rldbadm
|
/public/rldbadm
|
||||||
/stats
|
/stats
|
||||||
/.well-known
|
/.well-known
|
||||||
|
.DS_Store
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":2,"defects":{"Tests\\Feature\\MyWinningsTest::test_mywinnings_form_is_accessible":8,"Tests\\Feature\\MyWinningsTest::test_mywinnings_results_show_correct_data":8,"Tests\\Feature\\MyWinningsTest::test_mywinnings_invalid_bidder_shows_error":8},"times":{"Tests\\Unit\\PhoneFormattingTest::it_formats_a_10_digit_phone_number":0.018,"Tests\\Unit\\PhoneFormattingTest::it_strips_non_numeric_characters_before_formatting":0,"Tests\\Unit\\PhoneFormattingTest::it_returns_original_value_if_not_10_digits":0,"Tests\\Unit\\PhoneFormattingTest::bidder_model_accessor_formats_phone_number":0.003}}
|
{"version":2,"defects":{"Tests\\Feature\\MyWinningsTest::test_mywinnings_form_is_accessible":8,"Tests\\Feature\\MyWinningsTest::test_mywinnings_results_show_correct_data":8,"Tests\\Feature\\MyWinningsTest::test_mywinnings_invalid_bidder_shows_error":8,"Tests\\Unit\\PrinterServiceTest::test_printPickupSlip_sends_email_when_enabled":7},"times":{"Tests\\Unit\\PhoneFormattingTest::it_formats_a_10_digit_phone_number":0.018,"Tests\\Unit\\PhoneFormattingTest::it_strips_non_numeric_characters_before_formatting":0,"Tests\\Unit\\PhoneFormattingTest::it_returns_original_value_if_not_10_digits":0,"Tests\\Unit\\PhoneFormattingTest::bidder_model_accessor_formats_phone_number":0.003,"Tests\\Unit\\PrinterServiceTest::test_printPickupSlip_sends_email_when_enabled":0.019,"Tests\\Unit\\PrinterServiceTest::test_printPickupSlip_does_not_send_email_when_disabled":0.001,"Tests\\Unit\\PrinterServiceTest::test_printForCheckout_calls_printPickupSlip_with_correct_data":0.09}}
|
||||||
@@ -9,4 +9,14 @@ use Filament\Resources\Pages\CreateRecord;
|
|||||||
class CreateCheckout extends CreateRecord
|
class CreateCheckout extends CreateRecord
|
||||||
{
|
{
|
||||||
protected static string $resource = CheckoutResource::class;
|
protected static string $resource = CheckoutResource::class;
|
||||||
|
|
||||||
|
protected function afterCreate(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$printerService = app(\App\Services\PrinterService::class);
|
||||||
|
$printerService->printForCheckout($this->record);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error('Auto-print failed from Filament: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,6 +197,14 @@ class NorthCheckoutController extends Controller
|
|||||||
GROUP BY winning_bids.winning_bidder_num
|
GROUP BY winning_bids.winning_bidder_num
|
||||||
");
|
");
|
||||||
|
|
||||||
|
// Automatically print item pickup slips
|
||||||
|
try {
|
||||||
|
$printerService = app(\App\Services\PrinterService::class);
|
||||||
|
$printerService->printForCheckout(\App\Models\Checkout::find($checkout_id));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error('Auto-print failed: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return view('checkout_complete', [
|
return view('checkout_complete', [
|
||||||
'checkout_result' => $checkout_id,
|
'checkout_result' => $checkout_id,
|
||||||
'checkout_list_results' => $checkout_list_results,
|
'checkout_list_results' => $checkout_list_results,
|
||||||
|
|||||||
@@ -141,6 +141,15 @@ class PagesController extends Controller
|
|||||||
'cc_amount' => $cc_amount,
|
'cc_amount' => $cc_amount,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Automatically print item pickup slips
|
||||||
|
try {
|
||||||
|
$printerService = app(\App\Services\PrinterService::class);
|
||||||
|
$printerService->printForCheckout(\App\Models\Checkout::find($checkout_result));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error('Auto-print failed: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return view('checkout_complete', [
|
return view('checkout_complete', [
|
||||||
'checkout_result' => $checkout_result,
|
'checkout_result' => $checkout_result,
|
||||||
'checkout_list_results' => $checkout_list_results,
|
'checkout_list_results' => $checkout_list_results,
|
||||||
@@ -351,7 +360,11 @@ class PagesController extends Controller
|
|||||||
|
|
||||||
public function winnersbyitem()
|
public function winnersbyitem()
|
||||||
{
|
{
|
||||||
$winnersbyitem_results = WinningBids::with(['items', 'bidders'])->get();
|
$winnersbyitem_results = WinningBids::with(['items', 'bidders'])
|
||||||
|
->join('items', 'winning_bids.winning_item_num', '=', 'items.iditems')
|
||||||
|
->orderByRaw('CAST(items.item_assigned_num AS UNSIGNED) ASC')
|
||||||
|
->select('winning_bids.*')
|
||||||
|
->get();
|
||||||
return view('winnersbyitem', ['winnersbyitem_results' => $winnersbyitem_results]);
|
return view('winnersbyitem', ['winnersbyitem_results' => $winnersbyitem_results]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Attachment;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class PickupSlipMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
protected $pdfOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*/
|
||||||
|
public function __construct($pdfOutput)
|
||||||
|
{
|
||||||
|
$this->pdfOutput = $pdfOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message envelope.
|
||||||
|
*/
|
||||||
|
public function envelope(): Envelope
|
||||||
|
{
|
||||||
|
return new Envelope(
|
||||||
|
subject: 'Item Pickup Slip',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message content definition.
|
||||||
|
*/
|
||||||
|
public function content(): Content
|
||||||
|
{
|
||||||
|
return new Content(
|
||||||
|
view: 'emails.pickup_slip',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attachments for the message.
|
||||||
|
*
|
||||||
|
* @return array<int, Attachment>
|
||||||
|
*/
|
||||||
|
public function attachments(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Attachment::fromData(fn () => $this->pdfOutput, 'pickup_slip.pdf')
|
||||||
|
->withMime('application/pdf'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use Dompdf\Dompdf;
|
||||||
|
use Dompdf\Options;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class PrinterService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Print the pickup slip for a given Checkout model.
|
||||||
|
*
|
||||||
|
* @param \App\Models\Checkout $checkout
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function printForCheckout(\App\Models\Checkout $checkout)
|
||||||
|
{
|
||||||
|
$bidder_num = $checkout->bidder_num;
|
||||||
|
|
||||||
|
$checkout_list_results = \Illuminate\Support\Facades\DB::select("SELECT
|
||||||
|
*, items.item_assigned_num, items.item_desc
|
||||||
|
FROM winning_bids
|
||||||
|
INNER JOIN items AS items
|
||||||
|
ON winning_bids.winning_item_num=items.iditems
|
||||||
|
WHERE winning_bidder_num = $bidder_num
|
||||||
|
");
|
||||||
|
|
||||||
|
$checkout_info_results = \Illuminate\Support\Facades\DB::select("SELECT
|
||||||
|
winning_bids.*,
|
||||||
|
bidders.*,
|
||||||
|
sum(winning_cost) AS total_cost
|
||||||
|
FROM winning_bids
|
||||||
|
INNER JOIN bidders AS bidders
|
||||||
|
ON winning_bids.winning_bidder_num=bidders.idbidders
|
||||||
|
WHERE winning_bidder_num = $bidder_num
|
||||||
|
GROUP BY winning_bids.winning_bidder_num
|
||||||
|
");
|
||||||
|
|
||||||
|
$this->printPickupSlip([
|
||||||
|
'checkout_final_results' => $checkout,
|
||||||
|
'checkout_list_results' => $checkout_list_results,
|
||||||
|
'checkout_info_results' => $checkout_info_results
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the pickup slip by sending it to the HP ePrint email address.
|
||||||
|
*
|
||||||
|
* @param array $checkoutData
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function printPickupSlip($checkoutData)
|
||||||
|
{
|
||||||
|
if (!config('services.printer.enabled')) {
|
||||||
|
Log::info('Auto-print is disabled.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$printerEmail = config('services.printer.email');
|
||||||
|
if (empty($printerEmail)) {
|
||||||
|
Log::error('Printer email is not configured.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$options = new Options();
|
||||||
|
$options->set('isHtml5ParserEnabled', true);
|
||||||
|
$options->set('isRemoteEnabled', true);
|
||||||
|
$dompdf = new Dompdf($options);
|
||||||
|
|
||||||
|
$html = view('receiptpdf', $checkoutData)->render();
|
||||||
|
$dompdf->loadHtml($html);
|
||||||
|
$dompdf->setPaper('letter', 'portrait');
|
||||||
|
$dompdf->render();
|
||||||
|
$pdfOutput = $dompdf->output();
|
||||||
|
|
||||||
|
Mail::to($printerEmail)->send(new \App\Mail\PickupSlipMail($pdfOutput));
|
||||||
|
|
||||||
|
Log::info('Pickup slip sent to printer: ' . $printerEmail);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Failed to print pickup slip: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,4 +48,9 @@ return [
|
|||||||
'private_api_key' => env('NORTH_PRIVATE_API_KEY'),
|
'private_api_key' => env('NORTH_PRIVATE_API_KEY'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'printer' => [
|
||||||
|
'enabled' => env('AUTO_PRINT_ENABLED', false),
|
||||||
|
'email' => env('PRINTER_EMAIL'),
|
||||||
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 353 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
@@ -52,6 +52,26 @@ The Laravel framework is open-sourced software licensed under the [MIT license](
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### [tablar-theme] - 2026-05-02
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
- **Searchable Dropdowns:** Integrated `TomSelect` across various forms (Checkout, Reprint Receipt, etc.) for enhanced usability.
|
||||||
|
- **Self-Checkout Flow:** Added a prominent self-checkout link for bidders, integrated with North Embedded Checkout.
|
||||||
|
- **Pickup Instructions:** Added clear instructions for bidders on the checkout completion page to proceed to the Item Pickup Table.
|
||||||
|
- **North Checkout Fallback:** Restored the manual "Verify Payment Status" button and enhanced error reporting for digital wallet payments (Google Pay).
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
- **Logo Integration:** Corrected logo sizing issues using inline styles to override theme constraints.
|
||||||
|
- **User Menu:** Restored "Admin" and "Link OIDC Account" entries to match the legacy theme.
|
||||||
|
- **Manual Checkout:** Fixed broken `/checkout` route by aligning form field names with controller expectations and restoring payment method logic.
|
||||||
|
- **Data Restoration:** Re-added bidder information and itemized winning lists to the checkout completion views.
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
- **Expanded Reports:** Standardized `bidderlist`, `showcarlist`, and `checkout_complete_list` to show full contact details (Address, City, State, Zip, Phone, Email).
|
||||||
|
- **Reporting Enhancements:** Added Year, Make, and Model to the `showcarlist` and included item numbers in the `checkout_complete_list` for improved tracking.
|
||||||
|
- **UI Cleanup:** Disabled default Tablar footers and notifications across all layout templates to maintain a focused auction interface.
|
||||||
|
- **Theme Consistency:** Updated various partials to ensure a seamless transition from the previous custom theme to Tablar.
|
||||||
|
|
||||||
### [bidder-facing-checkout] - 2026-04-24
|
### [bidder-facing-checkout] - 2026-04-24
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
|||||||
@@ -17,24 +17,32 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-vcenter card-table">
|
<table class="table table-vcenter card-table text-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th>Name</th>
|
<th>Last Name</th>
|
||||||
|
<th>First Name</th>
|
||||||
|
<th>Address</th>
|
||||||
|
<th>City</th>
|
||||||
|
<th>State</th>
|
||||||
|
<th>Zip</th>
|
||||||
<th>Phone</th>
|
<th>Phone</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Address</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($bidderlist_results as $bidder)
|
@foreach($bidderlist_results as $bidder)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $bidder->bidder_assigned_number }}</td>
|
<td>{{ $bidder->bidder_assigned_number }}</td>
|
||||||
<td>{{ $bidder->bidder_fname }} {{ $bidder->bidder_lname }}</td>
|
<td>{{ $bidder->bidder_lname }}</td>
|
||||||
<td>{{ $bidder->bidder_phone }}</td>
|
<td>{{ $bidder->bidder_fname }}</td>
|
||||||
|
<td>{{ $bidder->bidder_addr }}</td>
|
||||||
|
<td>{{ $bidder->bidder_city }}</td>
|
||||||
|
<td>{{ $bidder->bidder_state }}</td>
|
||||||
|
<td>{{ $bidder->bidder_zip }}</td>
|
||||||
|
<td>{{ \App\Helpers\PhoneHelper::format($bidder->bidder_phone) }}</td>
|
||||||
<td>{{ $bidder->bidder_email }}</td>
|
<td>{{ $bidder->bidder_email }}</td>
|
||||||
<td>{{ $bidder->bidder_addr }}, {{ $bidder->bidder_city }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -16,33 +16,67 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@foreach($checkout_info_results as $info)
|
||||||
<form method="POST" action="/checkout" class="row g-3">
|
<form method="POST" action="/checkout" class="row g-3">
|
||||||
{{ csrf_field() }}
|
{{ csrf_field() }}
|
||||||
<input type="hidden" name="bidder_num" value="{{ $bidder->idbidders }}">
|
<input type="hidden" name="checkoutbiddernum" value="{{ $info->idbidders }}">
|
||||||
|
<input type="hidden" name="winnertotal" value="{{ $info->total_cost }}">
|
||||||
|
|
||||||
<h3 class="mb-3">Winning Items for {{ $bidder->bidder_fname }} {{ $bidder->bidder_lname }}</h3>
|
<h3 class="mb-3">Winning Items for {{ $info->bidder_fname }} {{ $info->bidder_lname }} (Bidder #{{ $info->bidder_assigned_number }})</h3>
|
||||||
<ul class="list-group mb-4">
|
|
||||||
@foreach($winnings as $item)
|
<div class="table-responsive mb-4">
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<table class="table table-vcenter">
|
||||||
{{ $item->items->item_desc }}
|
<thead>
|
||||||
<span class="badge bg-primary rounded-pill">${{ number_format($item->winning_cost, 2) }}</span>
|
<tr>
|
||||||
</li>
|
<th>Item #</th>
|
||||||
@endforeach
|
<th>Description</th>
|
||||||
</ul>
|
<th class="text-end">Amount</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($checkout_list_results as $item)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $item->item_assigned_num }}</td>
|
||||||
|
<td>{{ $item->item_desc }}</td>
|
||||||
|
<td class="text-end">${{ number_format($item->winning_cost, 2) }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2" class="text-end">Total Due</th>
|
||||||
|
<th class="text-end h3">${{ number_format($info->total_cost, 2) }}</th>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="payment_method" class="form-label">Payment Method</label>
|
<label for="payment_method" class="form-label">Payment Method</label>
|
||||||
<select name="payment_method" id="payment_method" class="form-select" required>
|
<select name="checkout_payment_method" id="payment_method" class="form-select" required onchange="togglePaymentFields()">
|
||||||
@foreach($paymentMethods as $pm)
|
{!! \App\Helpers\PaymentMethodSelectList::paymentShowMethods() !!}
|
||||||
<option value="{{ $pm->pm_id }}">{{ $pm->pm_name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="check_fields" class="col-md-4" style="display:none;">
|
||||||
|
<label for="check_number" class="form-label">Check Number</label>
|
||||||
|
<input type="text" name="check_number" id="check_number" class="form-control">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="cc_fields" class="col-md-4" style="display:none;">
|
||||||
|
<label for="cc_transaction" class="form-label">Transaction ID / Last 4</label>
|
||||||
|
<input type="text" name="cc_transaction" id="cc_transaction" class="form-control">
|
||||||
|
<input type="hidden" name="cc_amount" value="{{ $info->total_cost }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-12">
|
<div class="col-12 mt-4">
|
||||||
<button type="submit" class="btn btn-success">Complete Checkout</button>
|
<button type="submit" class="btn btn-success">
|
||||||
|
<i class="ti ti-check me-2"></i>Complete Checkout
|
||||||
|
</button>
|
||||||
|
<a href="/checkout" class="btn btn-link">Cancel and Start Over</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,6 +84,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
@include('components.tomselect')
|
|
||||||
@push('js')
|
@push('js')
|
||||||
|
<script>
|
||||||
|
function togglePaymentFields() {
|
||||||
|
const method = document.getElementById('payment_method').value;
|
||||||
|
const checkFields = document.getElementById('check_fields');
|
||||||
|
const ccFields = document.getElementById('cc_fields');
|
||||||
|
|
||||||
|
checkFields.style.display = 'none';
|
||||||
|
ccFields.style.display = 'none';
|
||||||
|
|
||||||
|
if (method === '2') { // Check
|
||||||
|
checkFields.style.display = 'block';
|
||||||
|
} else if (method === '3') { // Credit Card
|
||||||
|
ccFields.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|||||||
@@ -14,13 +14,79 @@
|
|||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<div class="row row-cards">
|
<div class="row row-cards">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card mb-3">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center py-4">
|
||||||
<h2 class="card-title">Success!</h2>
|
<h2 class="text-success mb-2">Success!</h2>
|
||||||
<p class="text-muted">The checkout has been successfully processed.</p>
|
<p class="text-muted">The checkout has been successfully processed.</p>
|
||||||
<a href="{{ route('receiptpdf', ['checkout_id' => $checkout_result]) }}" class="btn btn-primary" target="_blank">Print Receipt</a>
|
<p class="strong text-azure">Please proceed to the Item Pickup Table and show the page below or the pdf receipt on your device!</p>
|
||||||
<a href="{{ route('download_receipt', ['checkout_id' => $checkout_result]) }}" class="btn btn-success">Save PDF Receipt</a>
|
<div class="mt-3">
|
||||||
<a href="/home" class="btn btn-secondary">Back to Dashboard</a>
|
<a href="{{ route('receiptpdf', ['checkout_id' => $checkout_result]) }}" class="btn btn-primary" target="_blank">
|
||||||
|
<i class="ti ti-printer me-2"></i>Print Receipt
|
||||||
|
</a>
|
||||||
|
<a href="{{ route('download_receipt', ['checkout_id' => $checkout_result]) }}" class="btn btn-success">
|
||||||
|
<i class="ti ti-download me-2"></i>Save PDF Receipt
|
||||||
|
</a>
|
||||||
|
<a href="/home" class="btn btn-secondary">
|
||||||
|
<i class="ti ti-dashboard me-2"></i>Back to Dashboard
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@foreach($checkout_info_results as $info)
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Bidder Information</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<p><strong>Name:</strong> {{ $info->bidder_fname }} {{ $info->bidder_lname }}</p>
|
||||||
|
<p><strong>Bidder Number:</strong> {{ $info->bidder_assigned_number }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-md-end">
|
||||||
|
<p><strong>Total Paid:</strong> <span class="h2 text-primary">${{ number_format($info->total_cost, 2) }}</span></p>
|
||||||
|
<p><strong>Payment Method:</strong>
|
||||||
|
@if($payment_method == 1) Cash
|
||||||
|
@elseif($payment_method == 2) Check ({{ $check_number }})
|
||||||
|
@else Credit Card ({{ $cc_transaction }})
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Items Won</h3>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-vcenter card-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Item #</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th class="text-end">Amount</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($checkout_list_results as $item)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $item->item_assigned_num }}</td>
|
||||||
|
<td>{{ $item->item_desc }}</td>
|
||||||
|
<td class="text-end">${{ number_format($item->winning_cost, 2) }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2" class="text-end">Total</th>
|
||||||
|
<th class="text-end">${{ number_format($info->total_cost ?? 0, 2) }}</th>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,28 +16,47 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-vcenter card-table">
|
<table class="table table-vcenter card-table text-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Bidder #</th>
|
<th>#</th>
|
||||||
<th>Name</th>
|
<th>Last Name</th>
|
||||||
<th>Items Won</th>
|
<th>First Name</th>
|
||||||
|
<th>Address</th>
|
||||||
|
<th>City</th>
|
||||||
|
<th>State</th>
|
||||||
|
<th>Zip</th>
|
||||||
|
<th>Phone</th>
|
||||||
|
<th>Email</th>
|
||||||
<th>Total</th>
|
<th>Total</th>
|
||||||
<th>Payment</th>
|
<th>Payment Method</th>
|
||||||
|
<th>Items Won</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($checkout_complete_results as $c)
|
@foreach($checkout_complete_results as $c)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $c->bidder_assigned_number }}</td>
|
<td>{{ $c->bidder_assigned_number }}</td>
|
||||||
<td>{{ $c->bidder_fname }} {{ $c->bidder_lname }}</td>
|
<td>{{ $c->bidder_lname }}</td>
|
||||||
|
<td>{{ $c->bidder_fname }}</td>
|
||||||
|
<td>{{ $c->bidder_addr }}</td>
|
||||||
|
<td>{{ $c->bidder_city }}</td>
|
||||||
|
<td>{{ $c->bidder_state }}</td>
|
||||||
|
<td>{{ $c->bidder_zip }}</td>
|
||||||
|
<td>{{ \App\Helpers\PhoneHelper::format($c->bidder_phone) }}</td>
|
||||||
|
<td>{{ $c->bidder_email }}</td>
|
||||||
|
<td>${{ number_format($c->winnertotal, 2) }}</td>
|
||||||
|
<td>
|
||||||
|
@if($c->payment_method == 1) Cash
|
||||||
|
@elseif($c->payment_method == 2) Check ({{ $c->check_number }})
|
||||||
|
@else Credit ({{ $c->cc_transaction }})
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@foreach(\App\Models\WinningBids::with('items')->where('winning_bidder_num', $c->bidder_num)->get() as $bid)
|
@foreach(\App\Models\WinningBids::with('items')->where('winning_bidder_num', $c->bidder_num)->get() as $bid)
|
||||||
{{ $bid->items->item_desc ?? 'N/A' }}<br>
|
<strong>#{{ $bid->items->item_assigned_num ?? '?' }}</strong> - {{ $bid->items->item_desc ?? 'N/A' }}<br>
|
||||||
@endforeach
|
@endforeach
|
||||||
</td>
|
</td>
|
||||||
<td>${{ number_format($c->winnertotal, 2) }}</td>
|
|
||||||
<td>{{ $c->payment_method == 1 ? 'Cash' : ($c->payment_method == 2 ? 'Check' : 'Credit') }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
{{ csrf_field() }}
|
{{ csrf_field() }}
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label for="bidder_num" class="form-label">Bidder</label>
|
<label for="bidder_num" class="form-label">Bidder</label>
|
||||||
<select name="bidder_num" id="bidder_num" class="form-select" required>
|
<select name="checkoutbiddernum" id="bidder_num" class="form-select" required>
|
||||||
@foreach($bidders as $bidder)
|
@foreach($bidders as $bidder)
|
||||||
<option value="{{ $bidder->idbidders }}">{{ $bidder->bidder_assigned_number }} - {{ $bidder->bidder_fname }} {{ $bidder->bidder_lname }}</option>
|
<option value="{{ $bidder->idbidders }}">{{ $bidder->bidder_assigned_number }} - {{ $bidder->bidder_fname }} {{ $bidder->bidder_lname }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Please find the attached item pickup slip.
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
<div class="page-body">
|
<div class="page-body">
|
||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<div id="payment-error-container"></div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div id="checkout-container">
|
<div id="checkout-container">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
@@ -33,6 +34,13 @@
|
|||||||
<div class="spinner-border" role="status"></div>
|
<div class="spinner-border" role="status"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="fallback-container" class="mt-4 text-center" style="display: none;">
|
||||||
|
<div class="hr-text">Still here?</div>
|
||||||
|
<p class="text-muted">If you have already completed your payment but the page hasn't redirected, please click the button below.</p>
|
||||||
|
<a id="verify-button" href="#" class="btn btn-info">
|
||||||
|
<i class="ti ti-shield-check me-2"></i>Verify Payment Status
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -67,19 +75,52 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up fallback button
|
||||||
|
const verifyUrl = `/north/verify/${bidderId}?sessionToken=${sessionToken}`;
|
||||||
|
const verifyButton = document.getElementById('verify-button');
|
||||||
|
const fallbackContainer = document.getElementById('fallback-container');
|
||||||
|
verifyButton.href = verifyUrl;
|
||||||
|
|
||||||
|
// Show fallback after 5 seconds to give user a manual way out if auto-redirect fails
|
||||||
|
setTimeout(() => {
|
||||||
|
fallbackContainer.style.display = 'block';
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
await checkout.mount(sessionToken, 'checkout-container');
|
await checkout.mount(sessionToken, 'checkout-container');
|
||||||
|
|
||||||
const handleCompletion = (result) => {
|
const handleCompletion = (result) => {
|
||||||
window.location.href = `/north/verify/${bidderId}?sessionToken=${sessionToken}`;
|
console.log('Payment complete event received:', result);
|
||||||
|
window.location.href = verifyUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Register standard completion events
|
||||||
checkout.onPaymentComplete(handleCompletion);
|
checkout.onPaymentComplete(handleCompletion);
|
||||||
if (typeof checkout.onPaymentSuccess === 'function') {
|
if (typeof checkout.onPaymentSuccess === 'function') {
|
||||||
checkout.onPaymentSuccess(handleCompletion);
|
checkout.onPaymentSuccess(handleCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle errors
|
||||||
|
if (typeof checkout.onPaymentError === 'function') {
|
||||||
|
checkout.onPaymentError((error) => {
|
||||||
|
console.error('Payment Error:', error);
|
||||||
|
const errorDiv = document.createElement('div');
|
||||||
|
errorDiv.className = 'alert alert-danger alert-dismissible';
|
||||||
|
errorDiv.innerHTML = `
|
||||||
|
<div class="d-flex">
|
||||||
|
<div><i class="ti ti-alert-triangle me-2"></i></div>
|
||||||
|
<div>
|
||||||
|
<strong>Payment Error:</strong> ${error.message || 'An error occurred during payment.'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
|
||||||
|
`;
|
||||||
|
document.getElementById('payment-error-container').prepend(errorDiv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Checkout Error:', error);
|
console.error('Checkout Error:', error);
|
||||||
document.getElementById('checkout-container').innerHTML = '<div class="alert alert-danger">An error occurred. Please try again.</div>';
|
document.getElementById('checkout-container').innerHTML = '<div class="alert alert-danger">An error occurred while initializing checkout. Please try again.</div>';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -14,24 +14,38 @@
|
|||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-vcenter card-table" id="showcars-table">
|
<table class="table table-vcenter card-table text-nowrap" id="showcars-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="sort" data-sort="bidder-num">Bidder #</th>
|
<th class="sort" data-sort="bidder-num">#</th>
|
||||||
|
<th class="sort" data-sort="lname">Last Name</th>
|
||||||
|
<th class="sort" data-sort="fname">First Name</th>
|
||||||
|
<th>Address</th>
|
||||||
|
<th>City</th>
|
||||||
|
<th>State</th>
|
||||||
|
<th>Zip</th>
|
||||||
|
<th>Phone</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th class="sort" data-sort="year">Year</th>
|
||||||
<th class="sort" data-sort="make">Make</th>
|
<th class="sort" data-sort="make">Make</th>
|
||||||
<th class="sort" data-sort="model">Model</th>
|
<th class="sort" data-sort="model">Model</th>
|
||||||
<th class="sort" data-sort="year">Year</th>
|
|
||||||
<th class="sort" data-sort="owner">Owner</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list">
|
<tbody class="list">
|
||||||
@foreach($showcarlist_results as $vehicle)
|
@foreach($showcarlist_results as $vehicle)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="bidder-num">{{ $vehicle->bidder_assigned_number ?? 'N/A' }}</td>
|
<td class="bidder-num">{{ $vehicle->bidder_assigned_number }}</td>
|
||||||
|
<td class="lname">{{ $vehicle->bidder_lname }}</td>
|
||||||
|
<td class="fname">{{ $vehicle->bidder_fname }}</td>
|
||||||
|
<td>{{ $vehicle->bidder_addr }}</td>
|
||||||
|
<td>{{ $vehicle->bidder_city }}</td>
|
||||||
|
<td>{{ $vehicle->bidder_state }}</td>
|
||||||
|
<td>{{ $vehicle->bidder_zip }}</td>
|
||||||
|
<td>{{ \App\Helpers\PhoneHelper::format($vehicle->bidder_phone) }}</td>
|
||||||
|
<td>{{ $vehicle->bidder_email }}</td>
|
||||||
|
<td class="year">{{ $vehicle->year }}</td>
|
||||||
<td class="make">{{ $vehicle->make }}</td>
|
<td class="make">{{ $vehicle->make }}</td>
|
||||||
<td class="model">{{ $vehicle->model }}</td>
|
<td class="model">{{ $vehicle->model }}</td>
|
||||||
<td class="year">{{ $vehicle->year }}</td>
|
|
||||||
<td class="owner">{{ $vehicle->bidder_fname }} {{ $vehicle->bidder_lname }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -46,7 +60,7 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
new List('showcars-table', {
|
new List('showcars-table', {
|
||||||
valueNames: ['bidder-num', 'make', 'model', 'year', 'owner']
|
valueNames: ['bidder-num', 'lname', 'fname', 'year', 'make', 'model']
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- Page Error -->
|
<!-- Page Error -->
|
||||||
@include('tablar::error')
|
@include('tablar::error')
|
||||||
@include('tablar::partials.footer.bottom')
|
{{-- @include('tablar::partials.footer.bottom') --}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
<div class="navbar-nav flex-row order-md-last">
|
<div class="navbar-nav flex-row order-md-last">
|
||||||
<div class="d-none d-md-flex">
|
<div class="d-none d-md-flex">
|
||||||
@include('tablar::partials.header.theme-mode')
|
@include('tablar::partials.header.theme-mode')
|
||||||
@include('tablar::partials.header.notifications')
|
{{-- @include('tablar::partials.header.notifications') --}}
|
||||||
</div>
|
</div>
|
||||||
@include('tablar::partials.header.top-right')
|
@include('tablar::partials.header.top-right')
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<div class="d-none d-md-flex">
|
<div class="d-none d-md-flex">
|
||||||
@include('tablar::partials.header.theme-mode')
|
@include('tablar::partials.header.theme-mode')
|
||||||
@include('tablar::partials.header.notifications')
|
{{-- @include('tablar::partials.header.notifications') --}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@include('tablar::partials.header.top-right')
|
@include('tablar::partials.header.top-right')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<a href="#">
|
<a href="#">
|
||||||
<img src="{{asset(config('tablar.auth_logo.img.path','assets/logo.svg'))}}" width="110" height="32"
|
<img src="{{asset('assets/auction_logo.png')}}" width="220" height="64"
|
||||||
alt="{{asset(config('tablar.title','Tablar'))}}"
|
alt="{{asset(config('tablar.title','Tablar'))}}"
|
||||||
class="navbar-brand-image">
|
class="navbar-brand-image" style="height: 64px !important; width: 220px !important;">
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="navbar-nav flex-row order-md-last">
|
<div class="navbar-nav flex-row order-md-last">
|
||||||
<div class="d-none d-md-flex">
|
<div class="d-none d-md-flex">
|
||||||
@include('tablar::partials.header.theme-mode')
|
@include('tablar::partials.header.theme-mode')
|
||||||
@include('tablar::partials.header.notifications')
|
{{-- @include('tablar::partials.header.notifications') --}}
|
||||||
</div>
|
</div>
|
||||||
@include('tablar::partials.header.top-right')
|
@include('tablar::partials.header.top-right')
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,33 +2,23 @@
|
|||||||
<div class="nav-item dropdown">
|
<div class="nav-item dropdown">
|
||||||
<a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown"
|
<a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown"
|
||||||
aria-label="Open user menu">
|
aria-label="Open user menu">
|
||||||
<span class="avatar">SE</span>
|
|
||||||
<div class="d-none d-xl-block ps-2">
|
<div class="d-none d-xl-block ps-2">
|
||||||
<div>{{Auth()->user()->name}}</div>
|
<div>{{Auth()->user()->name}}</div>
|
||||||
<div class="mt-1 small text-muted">Software Engineer</div>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
|
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
|
||||||
|
|
||||||
@php( $logout_url = View::getSection('logout_url') ?? config('tablar.logout_url', 'logout') )
|
@php( $logout_url = View::getSection('logout_url') ?? config('tablar.logout_url', 'logout') )
|
||||||
@php( $profile_url = View::getSection('profile_url') ?? config('tablar.profile_url', 'logout') )
|
|
||||||
@php( $setting_url = View::getSection('setting_url') ?? config('tablar.setting_url', 'home') )
|
|
||||||
|
|
||||||
@if (config('tablar.use_route_url', true))
|
@if (config('tablar.use_route_url', true))
|
||||||
@php( $profile_url = $profile_url ? route($profile_url) : '' )
|
|
||||||
@php( $logout_url = $logout_url ? route($logout_url) : '' )
|
@php( $logout_url = $logout_url ? route($logout_url) : '' )
|
||||||
@php( $setting_url = $setting_url ? route($setting_url) : '' )
|
|
||||||
@else
|
@else
|
||||||
@php( $profile_url = $profile_url ? url($profile_url) : '' )
|
|
||||||
@php( $logout_url = $logout_url ? url($logout_url) : '' )
|
@php( $logout_url = $logout_url ? url($logout_url) : '' )
|
||||||
@php( $setting_url = $setting_url ? url($setting_url) : '' )
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<a href="#" class="dropdown-item">Status</a>
|
<a href="{{ url('admin') }}" class="dropdown-item">Admin</a>
|
||||||
<a href="{{$profile_url}}" class="dropdown-item">Profile</a>
|
<a href="{{ url('auth/social/oidc') }}" class="dropdown-item">Link OIDC Account</a>
|
||||||
<a href="#" class="dropdown-item">Feedback</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a href="{{$setting_url}}" class="dropdown-item">Settings</a>
|
|
||||||
<a class="dropdown-item"
|
<a class="dropdown-item"
|
||||||
href="#" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
|
href="#" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
|
||||||
<i class="fa fa-fw fa-power-off text-red"></i>
|
<i class="fa fa-fw fa-power-off text-red"></i>
|
||||||
@@ -44,4 +34,8 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ route('login') }}">Login</a>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<div class="d-none d-md-flex">
|
<div class="d-none d-md-flex">
|
||||||
@include('tablar::partials.header.theme-mode')
|
@include('tablar::partials.header.theme-mode')
|
||||||
@include('tablar::partials.header.notifications')
|
{{-- @include('tablar::partials.header.notifications') --}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@include('tablar::partials.header.top-right')
|
@include('tablar::partials.header.top-right')
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="d-none d-lg-flex">
|
<div class="d-none d-lg-flex">
|
||||||
@include('tablar::partials.header.theme-mode')
|
@include('tablar::partials.header.theme-mode')
|
||||||
@include('tablar::partials.header.notifications')
|
{{-- @include('tablar::partials.header.notifications') --}}
|
||||||
</div>
|
</div>
|
||||||
@include('tablar::partials.header.top-right')
|
@include('tablar::partials.header.top-right')
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
use App\Services\PrinterService;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\View;
|
||||||
|
|
||||||
|
class PrinterServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
public function test_printForCheckout_calls_printPickupSlip_with_correct_data()
|
||||||
|
{
|
||||||
|
Mail::fake();
|
||||||
|
Config::set('services.printer.enabled', true);
|
||||||
|
Config::set('services.printer.email', 'printer@example.com');
|
||||||
|
Config::set('mail.from.address', 'hello@example.com');
|
||||||
|
Config::set('mail.from.name', 'Example');
|
||||||
|
|
||||||
|
// Mock Checkout model
|
||||||
|
$checkout = \Mockery::mock(\App\Models\Checkout::class)->makePartial();
|
||||||
|
$checkout->bidder_num = 1;
|
||||||
|
$checkout->checkout_id = 1;
|
||||||
|
$checkout->payment_method = 1;
|
||||||
|
$checkout->check_number = null;
|
||||||
|
$checkout->cc_transaction = null;
|
||||||
|
|
||||||
|
// Mock DB calls
|
||||||
|
\Illuminate\Support\Facades\DB::shouldReceive('select')
|
||||||
|
->twice()
|
||||||
|
->andReturn([
|
||||||
|
(object)['item_assigned_num' => 'A1', 'item_desc' => 'Test', 'winning_cost' => 50]
|
||||||
|
], [
|
||||||
|
(object)[
|
||||||
|
'bidder_assigned_number' => '123',
|
||||||
|
'total_cost' => '50',
|
||||||
|
'bidder_fname' => 'John',
|
||||||
|
'bidder_lname' => 'Doe',
|
||||||
|
'bidder_phone' => '1234567890',
|
||||||
|
'bidder_addr' => '123 St',
|
||||||
|
'bidder_city' => 'Troy',
|
||||||
|
'bidder_state' => 'MI',
|
||||||
|
'bidder_zip' => '48083'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$service = new PrinterService();
|
||||||
|
$service->printForCheckout($checkout);
|
||||||
|
|
||||||
|
Mail::assertSent(\App\Mail\PickupSlipMail::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_printPickupSlip_sends_email_when_enabled()
|
||||||
|
{
|
||||||
|
Mail::fake();
|
||||||
|
Config::set('services.printer.enabled', true);
|
||||||
|
Config::set('services.printer.email', 'printer@example.com');
|
||||||
|
Config::set('mail.from.address', 'hello@example.com');
|
||||||
|
Config::set('mail.from.name', 'Example');
|
||||||
|
|
||||||
|
// Mock data matching what receiptpdf expects
|
||||||
|
$checkoutData = [
|
||||||
|
'checkout_final_results' => (object)[
|
||||||
|
'payment_method' => 1,
|
||||||
|
'check_number' => null,
|
||||||
|
'cc_transaction' => null,
|
||||||
|
'checkout_id' => 1
|
||||||
|
],
|
||||||
|
'checkout_list_results' => [
|
||||||
|
(object)[
|
||||||
|
'item_assigned_num' => 'A1',
|
||||||
|
'item_desc' => 'Test Item',
|
||||||
|
'winning_cost' => '50'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'checkout_info_results' => [
|
||||||
|
(object)[
|
||||||
|
'bidder_assigned_number' => '123',
|
||||||
|
'total_cost' => '50',
|
||||||
|
'bidder_fname' => 'John',
|
||||||
|
'bidder_lname' => 'Doe',
|
||||||
|
'bidder_phone' => '1234567890',
|
||||||
|
'bidder_addr' => '123 St',
|
||||||
|
'bidder_city' => 'Troy',
|
||||||
|
'bidder_state' => 'MI',
|
||||||
|
'bidder_zip' => '48083'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$service = new PrinterService();
|
||||||
|
$service->printPickupSlip($checkoutData);
|
||||||
|
|
||||||
|
Mail::assertSent(\App\Mail\PickupSlipMail::class, function ($mail) {
|
||||||
|
return $mail->hasTo('printer@example.com');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_printPickupSlip_does_not_send_email_when_disabled()
|
||||||
|
{
|
||||||
|
Mail::fake();
|
||||||
|
Config::set('services.printer.enabled', false);
|
||||||
|
|
||||||
|
$service = new PrinterService();
|
||||||
|
$service->printPickupSlip([]);
|
||||||
|
|
||||||
|
Mail::assertNothingSent();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user