فهرست منبع

添加礼品卡功能

llp 1 هفته پیش
والد
کامیت
7253fe7e04

+ 32 - 0
packages/Longyi/Gift/src/Listeners/InvoiceHandler.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace Longyi\Gift\Listeners;
+
+use Illuminate\Support\Facades\DB;
+
+class InvoiceHandler
+{
+    /**
+ * Handle invoice save after event.
+ *
+ * @param  \Webkul\Sales\Models\Invoice  $invoice
+ * @return void
+ */
+    public function saveAfter($invoice)
+    {
+        // 从订单中获取礼品卡信息
+        $order = $invoice->order;
+
+        if (!$order || !$order->giftcard_number || $order->giftcard_amount <= 0) {
+            return;
+        }
+
+        // 更新发票的礼品卡信息
+        DB::table('invoices')
+            ->where('id', $invoice->id)
+            ->update([
+                'giftcard_number' => $order->giftcard_number,
+                'giftcard_amount' => $order->giftcard_amount,
+            ]);
+    }
+}

+ 32 - 0
packages/Longyi/Gift/src/Listeners/OrderViewHandler.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace Longyi\Gift\Listeners;
+
+use Webkul\Sales\Models\Order;
+
+class OrderViewHandler
+{
+    /**
+     * Handle order view information discount before event.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    public function renderGiftCardInfo($viewRenderEventManager)
+    {
+        // 从当前路由参数中获取订单ID
+        $orderId = request()->route('id');
+
+        if (!$orderId) {
+            return;
+        }
+
+        // 查询订单
+        $order = Order::find($orderId);
+
+        if (!$order || !$order->giftcard_number || $order->giftcard_amount <= 0) {
+            return;
+        }
+        echo view('gift::customers.account.orders.giftcard-info', compact('order'))->render();
+    }
+}

+ 3 - 0
packages/Longyi/Gift/src/Providers/EventServiceProvider.php

@@ -20,5 +20,8 @@ class EventServiceProvider extends ServiceProvider
         Event::listen('bagisto.shop.checkout.onepage.summary.coupon.after', function($viewRenderEventManager) {
             $viewRenderEventManager->addTemplate('gift::components.giftcard-cartsummary');
         });
+        Event::listen('bagisto.shop.customers.account.orders.view.information.discount.after', 'Longyi\Gift\Listeners\OrderViewHandler@renderGiftCardInfo');
+        Event::listen('bagisto.admin.sales.order.view.discount.after', 'Longyi\Gift\Listeners\OrderViewHandler@renderGiftCardInfo');
+        Event::listen('sales.invoice.save.after', 'Longyi\Gift\Listeners\InvoiceHandler@saveAfter');
     }
 }

+ 5 - 0
packages/Longyi/Gift/src/Providers/GiftServiceProvider.php

@@ -2,10 +2,12 @@
 
 namespace Longyi\Gift\Providers;
 
+use Longyi\Gift\Repositories\CustomInvoiceRepository;
 use Illuminate\Support\ServiceProvider;
 use Illuminate\Support\Facades\Event;
 use Longyi\Gift\Providers\EventServiceProvider;
 use Longyi\Gift\Repositories\GiftCardsRepository;
+use Webkul\Sales\Repositories\InvoiceRepository;
 
 class GiftServiceProvider extends ServiceProvider
 {
@@ -14,6 +16,7 @@ class GiftServiceProvider extends ServiceProvider
      */
     public function register(): void
     {
+        $this->app->bind(InvoiceRepository::class, CustomInvoiceRepository::class);
         $this->registerConfig();
     }
 
@@ -32,6 +35,8 @@ class GiftServiceProvider extends ServiceProvider
 
         $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'gift');
 
+        $this->app['view']->prependNamespace('admin', __DIR__.'/../Resources/views');
+
         Event::listen('bagisto.admin.layout.head', function($viewRenderEventManager) {
             $viewRenderEventManager->addTemplate('gift::admin.layouts.style');
         });

+ 84 - 0
packages/Longyi/Gift/src/Repositories/CustomInvoiceRepository.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace Longyi\Gift\Repositories;
+
+use Webkul\Sales\Repositories\InvoiceRepository as BaseInvoiceRepository;
+
+class CustomInvoiceRepository extends BaseInvoiceRepository
+{
+    public function collectTotals($invoice)
+    {
+        $invoice->sub_total = $invoice->base_sub_total = 0;
+        $invoice->sub_total_incl_tax = $invoice->base_sub_total_incl_tax = 0;
+        $invoice->tax_amount = $invoice->base_tax_amount = 0;
+        $invoice->shipping_tax_amount = $invoice->shipping_tax_amount = 0;
+        $invoice->discount_amount = $invoice->base_discount_amount = 0;
+
+        foreach ($invoice->items as $item) {
+            $invoice->tax_amount += $item->tax_amount;
+            $invoice->base_tax_amount += $item->base_tax_amount;
+
+            $invoice->discount_amount += $item->discount_amount;
+            $invoice->base_discount_amount += $item->base_discount_amount;
+
+            $invoice->sub_total += $item->total;
+            $invoice->base_sub_total += $item->base_total;
+
+            $invoice->sub_total_incl_tax = (float) $invoice->sub_total_incl_tax + $item->total_incl_tax;
+            $invoice->base_sub_total_incl_tax = (float) $invoice->base_sub_total_incl_tax + $item->base_total_incl_tax;
+        }
+
+        $invoice->shipping_amount = $invoice->order->shipping_amount;
+        $invoice->shipping_amount_incl_tax = $invoice->order->shipping_amount_incl_tax;
+
+        $invoice->base_shipping_amount = $invoice->order->base_shipping_amount;
+        $invoice->base_shipping_amount_incl_tax = $invoice->order->base_shipping_amount_incl_tax;
+
+        $invoice->discount_amount += $invoice->order->shipping_discount_amount;
+        $invoice->base_discount_amount += $invoice->order->base_shipping_discount_amount;
+
+        $invoice->giftcard_amount += $invoice->order->giftcard_amount;
+        $invoice->giftcard_number = $invoice->order->giftcard_number;
+
+        if ($invoice->order->shipping_tax_amount) {
+            $invoice->shipping_tax_amount = $invoice->order->shipping_tax_amount;
+
+            $invoice->base_shipping_tax_amount = $invoice->order->base_shipping_tax_amount;
+
+            $invoice->tax_amount += $invoice->order->shipping_tax_amount;
+
+            $invoice->base_tax_amount += $invoice->order->base_shipping_tax_amount;
+
+            foreach ($invoice->order->invoices as $prevInvoice) {
+                if ((float) $prevInvoice->shipping_tax_amount) {
+                    $invoice->shipping_tax_amount = $invoice->base_shipping_tax_amount = 0;
+
+                    $invoice->tax_amount -= $invoice->order->shipping_tax_amount;
+
+                    $invoice->base_tax_amount -= $invoice->order->base_shipping_tax_amount;
+                }
+            }
+        }
+
+        if ($invoice->order->shipping_amount) {
+            foreach ($invoice->order->invoices as $prevInvoice) {
+                if ((float) $prevInvoice->shipping_amount) {
+                    $invoice->shipping_amount = $invoice->base_shipping_amount = 0;
+                    $invoice->shipping_amount_incl_tax = $invoice->base_shipping_amount_incl_tax = 0;
+                }
+
+                if ($prevInvoice->id != $invoice->id) {
+                    $invoice->discount_amount -= $invoice->order->shipping_discount_amount;
+                    $invoice->base_discount_amount -= $invoice->order->base_shipping_discount_amount;
+                }
+            }
+        }
+
+        $invoice->grand_total = $invoice->sub_total + $invoice->tax_amount + $invoice->shipping_amount - $invoice->discount_amount - $invoice->giftcard_amount;
+        $invoice->base_grand_total = $invoice->base_sub_total + $invoice->base_tax_amount + $invoice->base_shipping_amount - $invoice->base_discount_amount - $invoice->giftcard_amount;
+
+        $invoice->save();
+
+        return $invoice;
+    }
+}

+ 1 - 0
packages/Longyi/Gift/src/Resources/lang/en/app.php

@@ -47,5 +47,6 @@ return [
         'enter-your-code' => 'Enter your code',
         'remove'          => 'Remove Giftcard',
         'remaining_giftcard_amount' => 'Remaining Amount',
+        'giftcard_number'      => 'Giftcard Number',
     ]
 ];

+ 1 - 0
packages/Longyi/Gift/src/Resources/lang/zh_CN/app.php

@@ -47,5 +47,6 @@ return [
         'enter-your-code' => 'Enter your code',
         'remove'          => 'Remove Giftcard',
         'remaining_giftcard_amount' => 'Remaining Amount',
+        'giftcard_number'      => 'Giftcard Number',
     ],
 ];

+ 15 - 0
packages/Longyi/Gift/src/Resources/views/customers/account/orders/giftcard-info.blade.php

@@ -0,0 +1,15 @@
+@if (isset($order) && $order->giftcard_number && $order->giftcard_amount > 0)
+    <div class="flex w-full justify-between gap-x-5">
+        <p>
+            @lang('gift::app.giftcard.applied')
+
+            @if ($order->giftcard_number)
+                ({{ $order->giftcard_number }})
+            @endif
+        </p>
+
+        <p>
+          - {{ core()->formatPrice($order->giftcard_amount, $order->order_currency_code) }}
+        </p>
+    </div>
+@endif

+ 512 - 0
packages/Longyi/Gift/src/Resources/views/sales/invoices/view.blade.php

@@ -0,0 +1,512 @@
+<x-admin::layouts>
+    <x-slot:title>
+        @lang('admin::app.sales.invoices.view.title', ['invoice_id' => $invoice->increment_id ?? $invoice->id])
+    </x-slot>
+
+    @php
+        $order = $invoice->order;
+    @endphp
+
+        <!-- Main Body -->
+    <div class="grid">
+        <div class="flex items-center justify-between gap-4 max-sm:flex-wrap">
+            {!! view_render_event('bagisto.admin.sales.invoice.title.before', ['order' => $order]) !!}
+
+            <p class="text-xl font-bold leading-6 text-gray-800 dark:text-white">
+                @lang('admin::app.sales.invoices.view.title', ['invoice_id' => $invoice->increment_id ?? $invoice->id])
+
+                <span class="{{ $invoice->status_label_class }} mx-1.5 text-sm">
+                    {{ $invoice->status_label }}
+                </span>
+            </p>
+
+            {!! view_render_event('bagisto.admin.sales.invoice.title.after', ['order' => $order]) !!}
+
+            <div class="flex items-center gap-x-2.5">
+                <!-- Back Button -->
+                <a
+                    href="{{ route('admin.sales.invoices.index') }}"
+                    class="transparent-button hover:bg-gray-200 dark:text-white dark:hover:bg-gray-800"
+                >
+                    @lang('admin::app.account.edit.back-btn')
+                </a>
+            </div>
+        </div>
+    </div>
+
+    <!-- Filter row -->
+    <div class="flex items-center justify-between gap-4 mt-7 max-md:flex-wrap">
+        <div class="flex flex-wrap items-center gap-x-1 gap-y-2">
+            {!! view_render_event('bagisto.admin.sales.invoice.page_action.before', ['order' => $order]) !!}
+
+            <a
+                href="{{ route('admin.sales.invoices.print', $invoice->id) }}"
+                class="inline-flex w-full max-w-max cursor-pointer items-center justify-between gap-x-2 px-1 py-1.5 text-center font-semibold text-gray-600 transition-all hover:rounded-md hover:bg-gray-200 dark:text-gray-300 dark:hover:bg-gray-800"
+            >
+                <span class="text-2xl icon-printer"></span>
+
+                @lang('admin::app.sales.invoices.view.print')
+            </a>
+
+            <!-- Send Duplicate Invoice Modal -->
+            <div>
+                <button
+                    type="button"
+                    class="inline-flex w-full max-w-max cursor-pointer items-center justify-between gap-x-2 px-1 py-1.5 text-center font-semibold text-gray-600 transition-all hover:rounded-md hover:bg-gray-200 dark:text-gray-300 dark:hover:bg-gray-800"
+                    @click="$refs.groupCreateModal.open()"
+                >
+                    <span class="text-2xl icon-mail"></span>
+
+                    @lang('admin::app.sales.invoices.view.send-duplicate-invoice')
+                </button>
+
+                <x-admin::form :action="route('admin.sales.invoices.send_duplicate_email', $invoice->id)">
+                    <!-- Create Group Modal -->
+                    <x-admin::modal ref="groupCreateModal">
+                        <!-- Modal Header -->
+                        <x-slot:header>
+                            <p class="text-lg font-bold text-gray-800 dark:text-white">
+                                @lang('admin::app.sales.invoices.view.send-duplicate-invoice')
+                            </p>
+                        </x-slot>
+
+                        <!-- Modal Content -->
+                        <x-slot:content>
+                            <x-admin::form.control-group>
+                                <x-admin::form.control-group.label class="required">
+                                    @lang('admin::app.sales.invoices.view.email')
+                                </x-admin::form.control-group.label>
+
+                                <x-admin::form.control-group.control
+                                    type="email"
+                                    id="email"
+                                    name="email"
+                                    rules="required|email"
+                                    :value="$invoice->order->customer_email"
+                                    :label="trans('admin::app.sales.invoices.view.email')"
+                                />
+
+                                <x-admin::form.control-group.error control-name="email" />
+                            </x-admin::form.control-group>
+                        </x-slot>
+
+                        <!-- Modal Footer -->
+                        <x-slot:footer>
+                            <!-- Save Button -->
+                            <x-admin::button
+                                button-type="button"
+                                class="primary-button"
+                                :title="trans('admin::app.sales.invoices.view.send')"
+                            />
+                        </x-slot>
+                    </x-admin::modal>
+                </x-admin::form>
+            </div>
+
+            {!! view_render_event('bagisto.admin.sales.invoice.page_action.after', ['order' => $order]) !!}
+
+        </div>
+    </div>
+
+    <!-- body content -->
+    <div class="mt-3.5 flex gap-2.5 max-xl:flex-wrap">
+        <!-- Left sub-component -->
+        <div class="flex flex-col flex-1 gap-2 max-xl:flex-auto">
+            <!-- Invoice Item Section -->
+            <div class="bg-white rounded box-shadow dark:bg-gray-900">
+                <p class="p-4 mb-4 text-base font-semibold text-gray-800 dark:text-white">
+                    @lang('admin::app.sales.invoices.view.invoice-items') ({{ count($invoice->items) }})
+                </p>
+
+                <div class="grid">
+                    <!-- Invoice Item Details-->
+                    @foreach($invoice->items as $item)
+                        <div class="flex justify-between gap-2.5 border-b border-slate-300 px-4 py-6 dark:border-gray-800">
+                            <div class="flex gap-2.5">
+                                <!-- Product Image -->
+                                @if ($item->product?->base_image_url)
+                                    <img
+                                        class="relative h-[60px] max-h-[60px] w-full max-w-[60px] rounded"
+                                        src="{{ $item->product->base_image_url }}"
+                                    >
+                                @else
+                                    <div class="relative h-[60px] max-h-[60px] w-full max-w-[60px] rounded border border-dashed border-gray-300 dark:border-gray-800 dark:mix-blend-exclusion dark:invert">
+                                        <img src="{{ bagisto_asset('images/product-placeholders/front.svg') }}">
+
+                                        <p class="absolute bottom-1.5 w-full text-center text-[6px] font-semibold text-gray-400">
+                                            @lang('admin::app.sales.invoices.view.product-image')
+                                        </p>
+                                    </div>
+                                @endif
+
+                                <div class="grid place-content-start gap-1.5">
+                                    <!-- Item Name -->
+                                    <p
+                                        class="text-base font-semibold text-gray-800 break-all dark:text-white"
+                                        v-pre
+                                    >
+                                        {{ $item->name }}
+                                    </p>
+
+                                    <p class="text-gray-600 dark:text-gray-300">
+                                        @lang('admin::app.sales.invoices.view.amount-per-unit', [
+                                            'amount' => core()->formatBasePrice($item->base_price),
+                                            'qty'    => $item->qty,
+                                            ])
+                                    </p>
+
+                                    <div class="flex flex-col place-items-start gap-1.5">
+                                        @if (isset($item->additional['attributes']))
+                                            <!-- Item Additional Details -->
+                                            @foreach ($item->additional['attributes'] as $attribute)
+                                                <p
+                                                    class="text-gray-600 dark:text-gray-300"
+                                                    v-pre
+                                                >
+                                                    @if (
+                                                        ! isset($attribute['attribute_type'])
+                                                        || $attribute['attribute_type'] !== 'file'
+                                                    )
+                                                        {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
+                                                    @else
+                                                        {{ $attribute['attribute_name'] }} :
+
+                                                        <a
+                                                            href="{{ Storage::url($attribute['option_label']) }}"
+                                                            class="text-blue-600 hover:underline"
+                                                            download="{{ File::basename($attribute['option_label']) }}"
+                                                        >
+                                                            {{ File::basename($attribute['option_label']) }}
+                                                        </a>
+                                                    @endif
+                                                </p>
+                                            @endforeach
+                                        @endif
+
+                                        <!--SKU -->
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.sku', ['sku' => $item->getTypeInstance()->getOrderedItem($item)->sku])
+                                        </p>
+
+                                        <!-- Quantity -->
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.qty', ['qty' => $item->qty])
+                                        </p>
+                                    </div>
+                                </div>
+                            </div>
+
+                            <div class="grid gap-1 place-content-start">
+                                <!-- Item Grand Total -->
+                                <p class="flex items-center justify-end text-base font-semibold text-gray-800 gap-x-1 dark:text-white">
+                                    {{ core()->formatBasePrice($item->base_total + $item->base_tax_amount - $item->base_discount_amount) }}
+                                </p>
+
+                                <!-- Item Base Price -->
+                                <div class="flex flex-col place-items-start items-end gap-1.5">
+                                    @if (core()->getConfigData('sales.taxes.sales.display_prices') == 'including_tax')
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.price', ['price' => core()->formatBasePrice($item->base_price_incl_tax)])
+                                        </p>
+                                    @elseif (core()->getConfigData('sales.taxes.sales.display_prices') == 'both')
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.price-excl-tax', ['price' => core()->formatBasePrice($item->base_price)])
+                                        </p>
+
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.price-incl-tax', ['price' => core()->formatBasePrice($item->base_price_incl_tax)])
+                                        </p>
+                                    @else
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.price', ['price' => core()->formatBasePrice($item->base_price)])
+                                        </p>
+                                    @endif
+
+                                    <!-- Item Tax Amount -->
+                                    <p class="text-gray-600 dark:text-gray-300">
+                                        @lang('admin::app.sales.invoices.view.tax', ['tax' => core()->formatBasePrice($item->base_tax_amount)])
+                                    </p>
+
+                                    <!-- Item Discount -->
+                                    @if ($invoice->base_discount_amount > 0)
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.discount', ['discount' => core()->formatBasePrice($item->base_discount_amount)])
+                                        </p>
+                                    @endif
+                                    <!-- Item Sub-Total -->
+                                    @if (core()->getConfigData('sales.taxes.sales.display_subtotal') == 'including_tax')
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.sub-total', ['sub_total' => core()->formatBasePrice($item->base_total_incl_tax)])
+                                        </p>
+                                    @elseif (core()->getConfigData('sales.taxes.sales.display_subtotal') == 'both')
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.sub-total-excl-tax', ['sub_total' => core()->formatBasePrice($item->base_total)])
+                                        </p>
+
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.sub-total-incl-tax', ['sub_total' => core()->formatBasePrice($item->base_total_incl_tax)])
+                                        </p>
+                                    @else
+                                        <p class="text-gray-600 dark:text-gray-300">
+                                            @lang('admin::app.sales.invoices.view.sub-total', ['sub_total' => core()->formatBasePrice($item->base_total)])
+                                        </p>
+                                    @endif
+                                </div>
+                            </div>
+                        </div>
+                    @endforeach
+                </div>
+
+                <!--Sale Summary -->
+                <div class="mt-4 flex w-full justify-end gap-2.5 p-4">
+                    <div class="flex flex-col gap-y-1.5">
+                        @if (core()->getConfigData('sales.taxes.sales.display_subtotal') == 'both')
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.sub-total-summary-excl-tax')
+                            </p>
+
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.sub-total-summary-incl-tax')
+                            </p>
+                        @else
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.sub-total-summary')
+                            </p>
+                        @endif
+
+                        @if (core()->getConfigData('sales.taxes.sales.display_shipping_amount') == 'both')
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.shipping-and-handling-excl-tax')
+                            </p>
+
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.shipping-and-handling-incl-tax')
+                            </p>
+                        @else
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.shipping-and-handling')
+                            </p>
+                        @endif
+
+                        <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                            @lang('admin::app.sales.invoices.view.summary-tax')
+                        </p>
+
+                        @if ($invoice->base_discount_amount > 0)
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                @lang('admin::app.sales.invoices.view.summary-discount')
+                            </p>
+                        @endif
+                        @if ($order->giftcard_amount > 0)
+                            <p class="text-gray-600 dark:text-gray-300 !leading-5 text-sm">
+                                @lang('gift::app.giftcard.giftcard_amount')
+                            </p>
+                        @endif
+
+                        @if (!empty($order->giftcard_number))
+                            <p class="text-gray-600 dark:text-black-300 !leading-5 text-sm">
+                                @lang('gift::app.giftcard.giftcard_number')
+                            </p>
+                        @endif
+                        <p class="text-base font-semibold !leading-5 text-gray-800 dark:text-white">
+                            @lang('admin::app.sales.invoices.view.grand-total')
+                        </p>
+
+                    </div>
+
+                    <div class="flex flex-col gap-y-1.5">
+                        <!-- Subtotal -->
+                        @if (core()->getConfigData('sales.taxes.sales.display_subtotal') == 'including_tax')
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_sub_total_incl_tax) }}
+                            </p>
+                        @elseif (core()->getConfigData('sales.taxes.sales.display_subtotal') == 'both')
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_sub_total) }}
+                            </p>
+
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_sub_total_incl_tax) }}
+                            </p>
+                        @else
+                            <p class="font-semibold !leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_sub_total) }}
+                            </p>
+                        @endif
+
+                        <!-- Shipping and Handling -->
+                        @if (core()->getConfigData('sales.taxes.sales.display_shipping_amount') == 'including_tax')
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_shipping_amount_incl_tax) }}
+                            </p>
+                        @elseif (core()->getConfigData('sales.taxes.sales.display_shipping_amount') == 'both')
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_shipping_amount) }}
+                            </p>
+
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_shipping_amount_incl_tax) }}
+                            </p>
+                        @else
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_shipping_amount) }}
+                            </p>
+                        @endif
+
+                        <!-- Tax -->
+                        <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                            {{ core()->formatBasePrice($invoice->base_tax_amount) }}
+                        </p>
+
+                        <!-- Discount -->
+                        @if ($invoice->base_discount_amount > 0)
+                            <p class="!leading-5 text-gray-600 dark:text-gray-300">
+                                {{ core()->formatBasePrice($invoice->base_discount_amount) }}
+                            </p>
+                        @endif
+                        <!-- Giftcard Amount -->
+                        @if ($order->giftcard_amount > 0)
+                            <p class="text-gray-600 dark:text-gray-300 !leading-5">
+                                -  {{ core()->formatBasePrice($invoice->giftcard_amount) }}
+                            </p>
+                        @endif
+
+                        <!-- Giftcard Number -->
+                        @if (!empty($order->giftcard_number))
+                            <p class="text-gray-600 dark:text-gray-300 !leading-5">
+                                {{ ($invoice->giftcard_number) }}
+                            </p>
+                        @endif
+                        <!-- Grand Total -->
+                        <p class="text-base font-semibold !leading-5 text-gray-800 dark:text-white">
+                            {{ core()->formatBasePrice($invoice->base_grand_total) }}
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- Right sub-component -->
+        <div class="flex w-[360px] max-w-full flex-col gap-2 max-sm:w-full">
+            <!-- component 1 -->
+            <x-admin::accordion>
+                <x-slot:header>
+                    <p class="p-2.5 text-base font-semibold text-gray-600 dark:text-gray-300">
+                        @lang('admin::app.sales.invoices.view.customer')
+                    </p>
+                </x-slot>
+
+                <x-slot:content v-pre>
+                    <div class="flex flex-col {{ $order->billing_address ? 'pb-4' : ''}}">
+                        <p
+                            class="font-semibold text-gray-800 dark:text-white"
+                            v-text="'{{ $invoice->order->customer_full_name }}'"
+                        >
+                        </p>
+
+                        {!! view_render_event('bagisto.admin.sales.invoice.customer_name.after', ['order' => $order]) !!}
+
+                        <p class="text-gray-600 dark:text-gray-300">
+                            @lang('admin::app.sales.invoices.view.customer-email', ['email' => $invoice->order->customer_email])
+                        </p>
+
+                        {!! view_render_event('bagisto.admin.sales.invoice.customer_email.after', ['order' => $order]) !!}
+                    </div>
+
+                    @if ($order->billing_address || $order->shipping_address)
+                        <!-- Billing Address -->
+                        @if ($order->billing_address)
+                            <div class="{{ $order->shipping_address ? 'pb-4' : '' }}">
+                                <span class="block w-full border-b dark:border-gray-800"></span>
+
+                                <div class="flex items-center justify-between">
+                                    <p class="py-4 text-base font-semibold text-gray-600 dark:text-gray-300">
+                                        @lang('Billing Address')
+                                    </p>
+                                </div>
+
+                                @include ('admin::sales.address', ['address' => $order->billing_address])
+
+                                {!! view_render_event('bagisto.admin.sales.invoice.billing_address.after', ['order' => $order]) !!}
+                            </div>
+                        @endif
+
+                        <!-- Shipping Address -->
+                        @if ($order->shipping_address)
+                            <span class="block w-full border-b dark:border-gray-800"></span>
+
+                            <div class="flex items-center justify-between">
+                                <p class="py-4 text-base font-semibold text-gray-600 dark:text-gray-300">
+                                    @lang('Shipping Address')
+                                </p>
+                            </div>
+
+                            @include ('admin::sales.address', ['address' => $order->shipping_address])
+
+                            {!! view_render_event('bagisto.admin.sales.invoice.shipping_address.after', ['order' => $order]) !!}
+                        @endif
+                    @endif
+                </x-slot>
+            </x-admin::accordion>
+
+            <!-- component 2 -->
+            <x-admin::accordion>
+                <x-slot:header>
+                    <p class="p-2.5 text-base font-semibold text-gray-600 dark:text-gray-300">
+                        @lang('admin::app.sales.invoices.view.order-information')
+                    </p>
+                </x-slot>
+
+                <x-slot:content>
+                    <div class="flex justify-start w-full gap-5">
+                        <div class="flex flex-col gap-y-1.5">
+                            @foreach (['order-id', 'order-date', 'order-status', 'invoice-status', 'channel'] as $item)
+                                <p class="text-gray-600 dark:text-gray-300">
+                                    @lang('admin::app.sales.invoices.view.' . $item)
+                                </p>
+                            @endforeach
+                        </div>
+
+                        <div class="flex flex-col gap-y-1.5">
+                            <!-- Order Id -->
+                            <p class="font-semibold text-blue-600 transition-all hover:underline">
+                                <a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
+                            </p>
+
+                            {!! view_render_event('bagisto.admin.sales.invoice.increment_id.after', ['order' => $order]) !!}
+
+                            <!-- Order Date -->
+                            <p class="text-gray-600 dark:text-gray-300">
+                                {{ core()->formatDate($order->created_at) }}
+                            </p>
+
+                            {!! view_render_event('bagisto.admin.sales.invoice.created_at.after', ['order' => $order]) !!}
+
+                            <!-- Order Status -->
+                            <p class="text-gray-600 dark:text-gray-300">
+                                {{ $order->status_label }}
+                            </p>
+
+                            {!! view_render_event('bagisto.admin.sales.invoice.status_label.after', ['order' => $order]) !!}
+
+                            <!-- Invoice Status -->
+                            <p class="text-gray-600 dark:text-gray-300">
+                                {{ $invoice->status_label }}
+                            </p>
+
+                            <!-- Order Channel -->
+                            <p
+                                class="text-gray-600 dark:text-gray-300"
+                                v-pre
+                            >
+                                {{ $order->channel_name }}
+                            </p>
+
+                            {!! view_render_event('bagisto.admin.sales.invoice.channel_name.after', ['order' => $order]) !!}
+                        </div>
+                    </div>
+                </x-slot>
+            </x-admin::accordion>
+        </div>
+    </div>
+</x-admin::layouts>

+ 5 - 0
packages/Webkul/Admin/src/Http/Resources/CartResource.php

@@ -48,6 +48,11 @@ class CartResource extends JsonResource
             'have_stockable_items'               => $this->haveStockableItems(),
             'payment_method'                     => $this->payment?->method,
             'payment_method_title'               => core()->getConfigData('sales.payment_methods.'.$this->payment?->method.'.title'),
+            $this->mergeWhen($this->giftcard_number, [
+                'giftcard_number'           => $this->giftcard_number,
+                'giftcard_amount'           => $this->giftcard_amount,
+                'remaining_giftcard_amount' => $this->remaining_giftcard_amount,
+            ]),
         ];
     }
 }