Aplikasi Keuangan yang mengatur lalu lintas transaksi antara bank dan aplikasi internal Kampus
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

251 lines
13 KiB

@use(App\Domains\Billing\Enums\Invoicing\InvoiceType)
@use(App\Domains\System\Support\ValueObjects\Money)
<div class="row g-3 g-lg-4">
<!-- Header Section: Invoice Title and Status Overview -->
<div class="col-12">
<div class="card shadow-sm border-0 rounded-3">
<div class="card-body p-3 p-md-4">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<!-- Left side: Invoice Icon and Name -->
<div class="d-flex align-items-center gap-3">
<div class="avatar avatar-lg bg-primary-subtle text-primary rounded-3 d-flex align-items-center justify-content-center p-2 flex-shrink-0">
<!-- Tabler File Invoice Icon -->
<x-tabler-file-invoice width="28" height="28" />
</div>
<div>
<!-- Field Label for Invoice Name -->
<span class="text-body-secondary fw-semibold text-uppercase fs-7 d-block mb-1">
{{ __('domains/billing/field.invoice.name') }}
</span>
<!-- Invoice Display Name with fallback placeholder -->
<h4 class="fw-bold text-body mb-0">
{{ $this->invoice->name ?? '-' }}
</h4>
</div>
</div>
<!-- Right side: Current Invoice Status Badge -->
<div class="d-flex align-items-center gap-2">
<x-badge
:variant="$this->invoice->status->variant()"
:label="$this->invoice->status->label()"
:rounded="true"
/>
</div>
</div>
</div>
</div>
</div>
<!-- Main Content Column: Customer Details & Item Breakdown -->
<div class="col-12 col-lg-7 col-xl-8 d-flex flex-column gap-3 gap-lg-4">
<!-- Section 1: Customer Details Information Card -->
<x-card
:title="__('domains/billing/section.invoice.customer_detail.title')"
:subtitle="__('domains/billing/section.invoice.customer_detail.subtitle')"
class="shadow-sm border-0 rounded-3"
>
<!-- Grid displaying dynamic schema client information -->
<div class="row g-3">
@forelse($this->schema as $schema)
<div class="{{ count($this->schema) > 5 ? 'col-12 col-md-6' : 'col-12' }}">
<div class="p-3 rounded-3 bg-body-tertiary border border-subtle h-100">
<!-- Schema Attribute Label -->
<small class="text-body-secondary fw-semibold text-uppercase d-block mb-1 fs-7">
{{ $schema->attributes['label'] ?? __("domains/billing/field.invoice.{$schema->key}") }}
</small>
<!-- Dynamic Client Detail Value -->
<span class="fw-bold text-body fs-6">
@if(isset($this->invoice->client_detail[$schema->key.'_label']))
{{ $this->invoice->client_detail[$schema->key.'_label'] }}
@elseif($this->invoice->client_detail[$schema->key] != '')
{{ $this->invoice->client_detail[$schema->key] }}
@else
-
@endif
</span>
</div>
</div>
@empty
<!-- Fallback if schema has no dynamic fields defined -->
<div class="col-12">
<div class="p-3 text-center text-body-secondary bg-body-tertiary rounded-3 border border-subtle">
-
</div>
</div>
@endforelse
</div>
</x-card>
<!-- Section 2: Invoice Line Items Table Card -->
<x-card
:title="__('domains/billing/section.invoice.items.title')"
:subtitle="__('domains/billing/section.invoice.items.subtitle')"
class="shadow-sm border-0 rounded-3"
>
<div class="table-responsive rounded-3 border border-subtle">
<table class="table table-hover align-middle mb-0 text-nowrap small">
<!-- Table Header -->
<thead class="bg-body-tertiary">
<tr class="text-uppercase fs-7 fw-bold text-body-secondary tracking-wider">
<th class="ps-3 py-3" style="width: 40px;">#</th>
<th class="py-3">@lang('domains/billing/field.invoice_item.code')</th>
<th class="py-3">@lang('domains/billing/field.invoice_item.name')</th>
<th class="text-center py-3">@lang('domains/billing/field.invoice_item.quantity')</th>
<th class="text-end py-3">@lang('domains/billing/field.invoice_item.gross_price')</th>
<th class="text-end py-3">@lang('domains/billing/field.invoice_item.discounted_price')</th>
<th class="text-end pe-3 py-3">@lang('domains/billing/field.invoice_item.net_price')</th>
</tr>
</thead>
<!-- Table Body -->
<tbody>
@forelse($this->invoice->items ?? [] as $index => $item)
<tr>
<!-- Row Number -->
<td class="ps-3 py-2 fw-semibold text-body-secondary">{{ $index + 1 }}</td>
<!-- Item Code -->
<td class="py-2 font-monospace text-body-secondary fs-7">
{{ $item['code'] ?? '-' }}
</td>
<!-- Item Name -->
<td class="py-2 text-body fw-bold">{{ $item['name'] ?? '-' }}</td>
<!-- Quantity -->
<td class="text-center py-2 font-monospace fw-semibold">{{ $item['quantity'] ?? 1 }}</td>
<!-- Gross Amount per Line Item -->
<td class="text-end py-2 font-monospace text-body-secondary">
{{ $item['gross_amount'] ?? new Money(0) }}
</td>
<!-- Discount Amount per Line Item -->
<td class="text-end py-2 font-monospace text-danger fw-medium">
{{ $item['discount_amount'] ?? new Money(0) }}
</td>
<!-- Net Calculated Amount per Line Item -->
<td class="text-end pe-3 py-2 font-monospace fw-bold text-success fs-6">
{{ $item['net_amount'] ?? new Money(0) }}
</td>
</tr>
@empty
<!-- Empty State Display -->
<tr>
<td colspan="7" class="text-center py-5 text-body-secondary">
<div class="avatar avatar-xl mx-auto mb-3 bg-body-tertiary rounded-circle p-3 text-body-tertiary">
<!-- Receipt Icon for Empty State -->
<x-tabler-receipt width="36" height="36" />
</div>
<h6 class="fw-semibold text-body-secondary mb-1">{{ __('ui/common.no_data') }}</h6>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</x-card>
</div>
<!-- Right Column: Financial Summary & Sticky Panel -->
<div class="col-12 col-lg-5 col-xl-4">
<div class="sticky-top" style="top: 90px; z-index: 10;">
<x-card
:title="__('domains/billing/section.invoice.summary.title')"
:subtitle="__('domains/billing/section.invoice.summary.subtitle')"
class="shadow-sm border-0 border-top border-4 border-primary rounded-3"
>
<div class="p-3 rounded-3 bg-body-tertiary border border-subtle">
<!-- Invoice Status Header -->
<div class="d-flex align-items-center justify-content-between mb-3">
<span class="text-body-secondary fw-bold text-uppercase fs-7 tracking-wider">
@lang('domains/billing/field.invoice.status')
</span>
<x-badge
:variant="$this->invoice->status->variant()"
:label="$this->invoice->status->label()"
:rounded="true"
/>
</div>
<!-- Breakdown Calculation Card -->
<div class="d-flex flex-column gap-2 mb-3">
<!-- Total Gross Amount -->
<div class="d-flex align-items-center justify-content-between p-2 rounded-2 bg-body border border-subtle">
<span class="text-body-secondary fw-medium fs-7">
@lang('domains/billing/field.invoice.gross_amount')
</span>
<span class="fw-bold text-body font-monospace fs-6">
{{ $this->invoice->gross_amount ?? '-' }}
</span>
</div>
<!-- Total Discount Amount -->
<div class="d-flex align-items-center justify-content-between p-2 rounded-2 bg-body border border-subtle">
<span class="text-body-secondary fw-medium fs-7">
@lang('domains/billing/field.invoice.discount_amount')
</span>
<span class="fw-bold text-danger font-monospace fs-6">
-{{ $this->invoice->discount_amount ?? '-' }}
</span>
</div>
<hr class="my-1 border-subtle opacity-50">
<!-- Highlight Final Net Amount -->
<div class="d-flex align-items-center justify-content-between p-3 rounded-3 bg-primary text-white shadow-sm">
<div class="d-flex flex-column">
<small class="fw-bold text-uppercase fs-7 opacity-75 tracking-wider">
@lang('domains/billing/field.invoice.net_amount')
</small>
</div>
<span class="fw-bold font-monospace fs-4">
{{ $this->invoice->net_amount ?? '-' }}
</span>
</div>
</div>
<!-- Informational Actions / Options -->
<div class="d-flex flex-column gap-2">
@if($this->invoice->status->isDraft())
<!-- Update Status from Draft -->
<x-button
type="button"
theme="outline-info"
size="md"
icon="tabler-file-invoice"
wire:click="issueInvoice"
:label="__('domains/billing/button.issue_this_invoice')"
class="w-100 fw-bold shadow-xs py-2"
/>
@endif
<!-- Print / Export Action Button -->
<x-button
type="button"
theme="outline-primary"
size="md"
icon="tabler-printer"
:label="__('ui/button.print')"
class="w-100 fw-bold shadow-xs py-2"
/>
<!-- Back / Return Button -->
<x-button
type="button"
theme="secondary"
size="md"
icon="tabler-arrow-left"
:label="__('ui/button.back')"
x-on:click="window.history.back()"
class="w-100 fw-semibold py-2"
/>
</div>
</div>
</x-card>
</div>
</div>
</div>