diff --git a/backend/app/Services/Domain/Payment/Stripe/EventHandlers/PaymentIntentSucceededHandler.php b/backend/app/Services/Domain/Payment/Stripe/EventHandlers/PaymentIntentSucceededHandler.php index 43e7d7fb9..c9e608d56 100644 --- a/backend/app/Services/Domain/Payment/Stripe/EventHandlers/PaymentIntentSucceededHandler.php +++ b/backend/app/Services/Domain/Payment/Stripe/EventHandlers/PaymentIntentSucceededHandler.php @@ -8,6 +8,8 @@ use Brick\Money\Exception\UnknownCurrencyException; use Carbon\Carbon; use HiEvents\DomainObjects\Enums\PaymentProviders; +use HiEvents\DomainObjects\EventSettingDomainObject; +use HiEvents\DomainObjects\Generated\EventSettingDomainObjectAbstract; use HiEvents\DomainObjects\Generated\OrderDomainObjectAbstract; use HiEvents\DomainObjects\Generated\StripePaymentDomainObjectAbstract; use HiEvents\DomainObjects\OrderDomainObject; @@ -23,6 +25,7 @@ use HiEvents\Repository\Eloquent\Value\Relationship; use HiEvents\Repository\Interfaces\AffiliateRepositoryInterface; use HiEvents\Repository\Interfaces\AttendeeRepositoryInterface; +use HiEvents\Repository\Interfaces\EventSettingsRepositoryInterface; use HiEvents\Repository\Interfaces\OrderRepositoryInterface; use HiEvents\Services\Domain\Order\OrderApplicationFeeService; use HiEvents\Services\Domain\Payment\Stripe\StripeRefundExpiredOrderService; @@ -40,17 +43,18 @@ class PaymentIntentSucceededHandler { public function __construct( - private readonly OrderRepositoryInterface $orderRepository, - private readonly StripePaymentsRepository $stripePaymentsRepository, - private readonly AffiliateRepositoryInterface $affiliateRepository, - private readonly ProductQuantityUpdateService $quantityUpdateService, - private readonly StripeRefundExpiredOrderService $refundExpiredOrderService, - private readonly AttendeeRepositoryInterface $attendeeRepository, - private readonly DatabaseManager $databaseManager, - private readonly LoggerInterface $logger, - private readonly Repository $cache, - private readonly DomainEventDispatcherService $domainEventDispatcherService, - private readonly OrderApplicationFeeService $orderApplicationFeeService, + private readonly OrderRepositoryInterface $orderRepository, + private readonly StripePaymentsRepository $stripePaymentsRepository, + private readonly AffiliateRepositoryInterface $affiliateRepository, + private readonly ProductQuantityUpdateService $quantityUpdateService, + private readonly StripeRefundExpiredOrderService $refundExpiredOrderService, + private readonly AttendeeRepositoryInterface $attendeeRepository, + private readonly DatabaseManager $databaseManager, + private readonly LoggerInterface $logger, + private readonly Repository $cache, + private readonly DomainEventDispatcherService $domainEventDispatcherService, + private readonly OrderApplicationFeeService $orderApplicationFeeService, + private readonly EventSettingsRepositoryInterface $eventSettingsRepository, ) { } @@ -94,7 +98,12 @@ public function handleEvent(PaymentIntent $paymentIntent): void $this->quantityUpdateService->updateQuantitiesFromOrder($updatedOrder); - OrderStatusChangedEvent::dispatch($updatedOrder); + /** @var EventSettingDomainObject $eventSettings */ + $eventSettings = $this->eventSettingsRepository->findFirstWhere([ + EventSettingDomainObjectAbstract::EVENT_ID => $updatedOrder->getEventId(), + ]); + + event(new OrderStatusChangedEvent($updatedOrder, createInvoice: $eventSettings->getEnableInvoicing())); $this->domainEventDispatcherService->dispatch( new OrderEvent( diff --git a/backend/resources/views/invoice.blade.php b/backend/resources/views/invoice.blade.php index 86aa461ad..9db23e899 100644 --- a/backend/resources/views/invoice.blade.php +++ b/backend/resources/views/invoice.blade.php @@ -1,11 +1,16 @@ @php use Carbon\Carbon; @endphp @php use HiEvents\Helper\Currency; @endphp +@php use HiEvents\DomainObjects\Status\InvoiceStatus; @endphp @php /** @var \HiEvents\DomainObjects\EventDomainObject $event */ @endphp @php /** @var \HiEvents\DomainObjects\EventSettingDomainObject $eventSettings */ @endphp @php /** @var \HiEvents\DomainObjects\OrderDomainObject $order */ @endphp @php /** @var \HiEvents\DomainObjects\InvoiceDomainObject $invoice */ @endphp +@php + $isPaid = $invoice->getStatus() === InvoiceStatus::PAID->name; + $isVoid = $invoice->getStatus() === InvoiceStatus::VOID->name; +@endphp - +
@@ -21,40 +26,75 @@ body { font-family: 'DejaVu Sans', Arial, sans-serif; font-size: 12px; - line-height: 1.4; + line-height: 1.5; color: #1a1a1a; padding: 20px 30px; } - .header { - margin-bottom: 30px; - min-height: 100px; - display: block; + table.header-table { + width: 100%; + margin-bottom: 25px; + } + + table.header-table td { + vertical-align: top; } .logo-title { - font-size: 36px; - font-weight: normal; + font-family: 'DejaVu Sans', Arial, sans-serif; + font-size: 28px; + font-weight: 700; color: #1a1a1a; + margin: 0 0 2px 0; + letter-spacing: -0.5px; + } + + .header-event-name { + font-family: 'DejaVu Sans', Arial, sans-serif; + font-size: 12px; + color: #666; margin: 0; - float: left; - width: 50%; } .company-details { - float: right; text-align: right; line-height: 1.6; - width: 45%; + color: #555; } - .company-details > div { - margin-bottom: 3px; + .company-name { + font-weight: bold; + color: #1a1a1a; } - .invoice-info-container { - clear: both; - padding-top: 20px; + .status-badge { + display: inline-block; + padding: 4px 14px; + margin-top: 6px; + border-radius: 4px; + font-family: 'DejaVu Sans', Arial, sans-serif; + font-size: 11px; + font-weight: bold; + letter-spacing: 0.5px; + text-transform: uppercase; + } + + .status-paid { + background-color: #e6f9ee; + color: #1a7d42; + border: 1px solid #b8e6cc; + } + + .status-unpaid { + background-color: #fff3e0; + color: #b36b00; + border: 1px solid #ffe0b2; + } + + .status-void { + background-color: #f5f5f5; + color: #888; + border: 1px solid #ddd; } .invoice-info-grid { @@ -65,26 +105,30 @@ } .invoice-info-grid td { - padding: 10px; - width: 25%; + padding: 12px 14px; vertical-align: top; } .info-label { - color: #8a6bc0; - font-size: 12px; + font-family: 'DejaVu Sans', Arial, sans-serif; + color: #888; + font-size: 10px; font-weight: bold; display: block; margin-bottom: 4px; + text-transform: uppercase; + letter-spacing: 0.3px; } .info-value { + font-family: 'DejaVu Sans', Arial, sans-serif; font-size: 13px; + font-weight: 500; } .billing-section { margin-bottom: 20px; - background: #f8f8f8; + background: #f9f9fb; padding: 15px; border-radius: 4px; width: 48%; @@ -92,10 +136,17 @@ } .billing-title { - color: #8a6bc0; - font-size: 12px; + color: #888; + font-size: 10px; font-weight: bold; margin-bottom: 8px; + text-transform: uppercase; + letter-spacing: 0.3px; + } + + .billing-name { + font-weight: bold; + margin-bottom: 2px; } table.items { @@ -106,29 +157,31 @@ } .items th { - background: #8a6bc0; - color: white; + background: #f9f9fb; + color: #555; text-align: left; - padding: 12px 15px; + padding: 10px 15px; font-weight: bold; - font-size: 12px; - letter-spacing: 0.5px; + font-size: 10px; + letter-spacing: 0.3px; + text-transform: uppercase; + border-bottom: 2px solid #e6e6e6; } .items td { padding: 12px 15px; - border-bottom: 1px solid #e6e6e6; + border-bottom: 1px solid #f0f0f0; vertical-align: middle; } .item-description { - color: #666; + color: #888; font-size: 11px; margin-top: 4px; } .item-price-original { - color: #666; + color: #999; text-decoration: line-through; font-size: 11px; margin-bottom: 2px; @@ -141,39 +194,52 @@ .totals { width: 350px; margin-left: auto; - margin-top: 20px; + margin-top: 10px; } .totals td { - padding: 8px 10px; + padding: 6px 10px; text-align: right; } .total-line td { - border-top: 2px solid #8a6bc0; + border-top: 2px solid #1a1a1a; font-weight: bold; font-size: 14px; padding-top: 12px; - background: #f8f8f8; + } + + .amount-paid-line td { + color: #1a7d42; + font-size: 12px; + padding-top: 8px; + } + + .balance-due-line td { + border-top: 1px solid #e6e6e6; + font-weight: bold; + font-size: 14px; + padding-top: 10px; } .subtotal td { font-weight: bold; - padding-top: 15px; + padding-top: 12px; } .breakdown td { - color: #666; + color: #888; font-size: 11px; } .invoice-notes { margin: 30px 0; padding: 15px; - background-color: #f8f8f8; + background-color: #f9f9fb; border-radius: 4px; line-height: 1.6; clear: both; + color: #555; } .invoice-footer { @@ -183,17 +249,18 @@ text-align: center; line-height: 1.6; clear: both; + color: #888; + font-size: 11px; } .tax-info { - margin-top: 20px; - padding-top: 15px; + margin-top: 15px; + padding-top: 12px; border-top: 1px dashed #e6e6e6; font-size: 11px; - color: #666; + color: #888; } - /* Specific column widths for items table */ .col-description { width: 55%; } @@ -214,50 +281,75 @@ body { padding: 15px; } + + .status-paid { + background-color: #e6f9ee !important; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + } } -| - {{ __('Invoice Number') }} - #{{ $invoice->getInvoiceNumber() }} - | -- {{ __('Date Issued') }} - {{ Carbon::parse($order->getCreatedAt())->format('d/m/Y') }} - | - @if($invoice->getDueDate()) -- {{ __('Due Date') }} - {{ Carbon::parse($invoice->getDueDate())->format('d/m/Y') }} - | +
+ {{ $eventSettings->getInvoiceLabel() ?? __('Invoice') }}+{{ $event->getTitle() }} + |
+
+ {{ $eventSettings->getOrganizationName() }}
+ {!! $eventSettings->getOrganizationAddress() !!}
+ @if($eventSettings->getSupportEmail())
+ {{ $eventSettings->getSupportEmail() }}
@endif
+ |
+
| + {{ __('Invoice Number') }} + #{{ $invoice->getInvoiceNumber() }} + | ++ {{ __('Date Issued') }} + {{ Carbon::parse($invoice->getIssueDate())->format('d/m/Y') }} + | + @if(!$isPaid && $invoice->getDueDate())- {{ __('Amount Due') }} - {{ Currency::format($order->getTotalGross(), $order->getCurrency()) }} + {{ __('Due Date') }} + {{ Carbon::parse($invoice->getDueDate())->format('d/m/Y') }} | -
| {{ __('DESCRIPTION') }} | -{{ __('RATE') }} | -{{ __('QTY') }} | -{{ __('AMOUNT') }} | +{{ __('Description') }} | +{{ __('Rate') }} | +{{ __('Qty') }} | +{{ __('Amount') }} |
|---|---|---|---|---|---|---|---|
| {{ __('Total Amount') }} | +{{ __('Total') }} | {{ Currency::format($order->getTotalGross(), $order->getCurrency()) }} | |||||
| {{ __('Amount Paid') }} | +-{{ Currency::format($order->getTotalGross(), $order->getCurrency()) }} | +||||||
| {{ __('Balance Due') }} | +{{ Currency::format(0, $order->getCurrency()) }} | +