{{-- Order Type Indicator --}} @if($orderTypeId)
@lang('modules.settings.orderType'): {{ \App\Models\OrderType::find($orderTypeId)?->order_type_name ?? ucfirst($orderType) }} @if($orderTypeSlug === 'delivery' && $selectedDeliveryApp) Platform: @if($selectedDeliveryApp === 'default') Default @else {{ \App\Models\DeliveryPlatform::find($selectedDeliveryApp)?->name ?? 'Unknown' }} @endif @endif
@endif
@if($customerId)
{{ $customer->name }}
@if(user_can('Update Order')) @endif
@else + @lang('modules.order.addCustomerDetails') @endif
@if(!isOrderPrefixEnabled()) @lang('modules.order.orderNumber') #{{ $orderNumber }} @else {{ $formattedOrderNumber }} @endif
@if ($orderType == 'dine_in')
{{-- @if (!auth()->user()->roles->pluck('display_name')->contains('Waiter')) --}} @if ($tableNo) {{ $tableNo }} @else @lang('modules.order.setTable') @endif @lang('modules.order.mergeTables') {{-- @endif --}}
@endif
@if ($orderType == 'dine_in')
@lang('modules.order.noOfPax')
@if ($this->orderNote) @endif
@if ($this->isWaiterLocked) {{ $this->waiterName }} @else @foreach ($users as $item) @endforeach @endif
@endif @if ($orderType == 'delivery')
@foreach ($deliveryExecutives as $item) @endforeach
@endif @if ($orderType == 'pickup') @php $timeFormat = restaurant()->time_format ?? 'h:i A'; $currentDate = $pickupDate ?? now()->format(restaurant()->date_format); $currentTime = $pickupTime ?? now()->format('H:i'); @endphp
@endif
@forelse ($orderItemList as $key => $item) @php // Initialize variables - START WITH FALSE $isFreeItem = false; $hasStampDiscount = false; $stampDiscountAmount = 0; $originalAmount = 0; $itemFoundInDatabase = false; // CRITICAL: Track if we found item in DB // For existing orders, check both kot_items and order_items tables for stamp data // PRIORITY: Database values ALWAYS override key patterns if (isset($orderID) && $orderID && isset($orderDetail) && $orderDetail) { // Check if this is a KOT item (key format: "kot_{kot_id}_{item_id}") if (strpos($key, 'kot_') !== false) { $keyParts = explode('_', trim($key, '"')); if (count($keyParts) >= 3 && $keyParts[0] === 'kot') { $kotItemId = (int)($keyParts[2] ?? 0); $kotId = (int)($keyParts[1] ?? 0); if ($kotItemId > 0 && $kotId > 0) { try { // Load kot items if not already loaded if (!$orderDetail->relationLoaded('kot')) { $orderDetail->load('kot.items'); } // Find the kot and kot_item $kot = $orderDetail->kot->firstWhere('id', $kotId); if ($kot) { if (!$kot->relationLoaded('items')) { $kot->load('items'); } $kotItem = $kot->items->firstWhere('id', $kotItemId); if ($kotItem) { $itemFoundInDatabase = true; // Found in database // STRICT CHECK: Only true if database value is exactly 1, true, or '1' // Explicitly check for 0, false, null, '0', '' and set to false $dbFreeValue = $kotItem->getAttribute('is_free_item_from_stamp') ?? $kotItem->is_free_item_from_stamp ?? null; // Explicitly check: if value is 0, false, null, '0', or empty string, it's NOT free if ($dbFreeValue === 0 || $dbFreeValue === false || $dbFreeValue === null || $dbFreeValue === '0' || $dbFreeValue === '') { $isFreeItem = false; } else { // Only mark as free if value is exactly 1, true, or '1' $isFreeItem = ($dbFreeValue === 1 || $dbFreeValue === true || $dbFreeValue === '1'); } // Check for discount from stamp in kot_items $discountAmount = (float)($kotItem->getAttribute('discount_amount') ?? $kotItem->discount_amount ?? 0); $isDiscounted = (bool)($kotItem->getAttribute('is_discounted') ?? $kotItem->is_discounted ?? false); $hasStampDiscount = $discountAmount > 0 || $isDiscounted || !is_null($kotItem->stamp_rule_id); if ($hasStampDiscount && $discountAmount > 0) { $stampDiscountAmount = $discountAmount; $originalAmount = (float)($kotItem->amount ?? 0) + $discountAmount; } elseif ($isFreeItem) { // For free items, calculate original amount from price $basePrice = (float)($kotItem->getAttribute('price') ?? $kotItem->price ?? 0); $modifierPrice = isset($orderItemModifiersPrice[$key]) ? (float)$orderItemModifiersPrice[$key] : 0; $qty = isset($orderItemQty[$key]) ? (int)$orderItemQty[$key] : 1; $originalAmount = ($basePrice + $modifierPrice) * $qty; } } } } catch (\Exception $e) { // Silently fail if error } } } } // Check if this is an order_item (key format: "order_item_{id}") // Only check if we haven't found it as a KOT item and it's not already marked as free if (!$itemFoundInDatabase && strpos($key, 'order_item_') !== false) { $keyParts = explode('_', trim($key, '"')); if (count($keyParts) >= 3 && $keyParts[0] === 'order' && $keyParts[1] === 'item') { $orderItemId = (int)($keyParts[2] ?? 0); if ($orderItemId > 0) { try { // Load order items if not already loaded if (!$orderDetail->relationLoaded('items')) { $orderDetail->load('items'); } // Find the order_item from the loaded relationship $orderItem = $orderDetail->items->firstWhere('id', $orderItemId); if ($orderItem) { $itemFoundInDatabase = true; // Found in database // STRICT CHECK: Only true if database value is exactly 1, true, or '1' // Explicitly check for 0, false, null, '0', '' and set to false $dbFreeValue = $orderItem->is_free_item_from_stamp ?? null; // Explicitly check: if value is 0, false, null, '0', or empty string, it's NOT free if ($dbFreeValue === 0 || $dbFreeValue === false || $dbFreeValue === null || $dbFreeValue === '0' || $dbFreeValue === '') { $isFreeItem = false; } else { // Only mark as free if value is exactly 1, true, or '1' $isFreeItem = ($dbFreeValue === 1 || $dbFreeValue === true || $dbFreeValue === '1'); } // Check for discount from stamp // Note: order_items table only has 'stamp_rule_id' and 'is_free_item_from_stamp' columns if (!$hasStampDiscount) { $hasStampDiscount = !is_null($orderItem->stamp_rule_id) && !$isFreeItem; } // For items with stamp discounts, we can't calculate exact discount per item from order_items // The discount is already deducted from amount field if ($hasStampDiscount && $stampDiscountAmount == 0) { // Try to estimate original amount from price field (if available) $basePrice = $orderItem->price ?? 0; $modifierPrice = isset($orderItemModifiersPrice[$key]) ? $orderItemModifiersPrice[$key] : 0; $qty = $orderItemQty[$key] ?? $orderItem->quantity ?? 1; $estimatedOriginalAmount = ($basePrice + $modifierPrice) * $qty; // If current amount is less than estimated, there's a discount $currentAmount = (float)($orderItem->amount ?? 0); if ($estimatedOriginalAmount > $currentAmount) { $stampDiscountAmount = $estimatedOriginalAmount - $currentAmount; $originalAmount = $estimatedOriginalAmount; } } elseif ($isFreeItem && $originalAmount == 0) { // For free items, calculate original amount from price $basePrice = $orderItem->price ?? 0; $modifierPrice = isset($orderItemModifiersPrice[$key]) ? $orderItemModifiersPrice[$key] : 0; $originalAmount = ($basePrice + $modifierPrice) * ($orderItemQty[$key] ?? 1); } } } catch (\Exception $e) { // Silently fail if error } } } } } // FALLBACK: Only use key pattern or notes if item was NOT found in database // This is ONLY for draft orders or items not yet saved to database // CRITICAL: Only check fallback if we didn't find the item in database // IMPORTANT: If item was found in database, NEVER use fallback - database value is final if (!$itemFoundInDatabase) { // Only check key pattern for draft orders (when orderID might not be set or order is draft) $isDraftOrder = !isset($orderID) || !$orderID || (isset($orderDetail) && $orderDetail && $orderDetail->status === 'draft'); if ($isDraftOrder) { // Only check key pattern if not already set from database // Reset to false first to ensure clean state $isFreeItem = false; $isFreeItem = strpos($key, 'free_stamp_') === 0 || (isset($itemNotes[$key]) && str_contains($itemNotes[$key] ?? '', __('loyalty::app.freeItemFromStamp'))); } else { // For non-draft orders, if item not found in DB, it's definitely NOT free $isFreeItem = false; } } // FINAL SAFEGUARD: If item was found in database, $isFreeItem is already set correctly above - do NOT override // If item was NOT found and it's not a draft order, ensure it's false if ($itemFoundInDatabase && !$isFreeItem) { // Explicitly ensure it stays false - database said it's not free $isFreeItem = false; } @endphp
{{ $item->item_name }} @if ($isFreeItem) @lang('app.freeItem') @elseif($hasStampDiscount) @lang('app.stampDiscount') @if($stampDiscountAmount > 0) (-{{ currency_format($stampDiscountAmount, restaurant()->currency_id) }}) @endif @endif
@if (isset($orderItemVariation[$key]) && $orderItemVariation[$key]) • {{ $orderItemVariation[$key]->variation }} @endif @if (!empty($itemModifiersSelected[$key]))
@foreach ($itemModifiersSelected[$key] as $modifierOptionId)
{{ $this->modifierOptions[$modifierOptionId]->name }} {{ currency_format($this->modifierOptions[$modifierOptionId]->price, $restaurant->currency_id) }}
@endforeach
@endif
@php $displayPrice = $this->getItemDisplayPrice($key); // Prefer component amount (reflects live qty changes); fallback to DB if not available $totalAmount = $orderItemAmount[$key] ?? (isset($orderItem) && $orderItem ? (float)($orderItem->amount ?? 0) : 0); @endphp
@if ($isFreeItem)
{{ currency_format(0, restaurant()->currency_id) }}
@if($originalAmount > 0)
{{ currency_format($originalAmount, restaurant()->currency_id) }}
@endif
@elseif($hasStampDiscount)
{{ currency_format($totalAmount, restaurant()->currency_id) }}
@if($originalAmount > 0 && $originalAmount > $totalAmount)
{{ currency_format($originalAmount, restaurant()->currency_id) }}
@endif
@else
{{ currency_format($displayPrice, restaurant()->currency_id) }}
{{ currency_format($totalAmount, restaurant()->currency_id) }}
@endif
@if (!$isFreeItem)
@else
@lang('app.qty') {{ $orderItemQty[$key] ?? 1 }}
@endif
@empty
@lang('messages.noItemAdded')
@endforelse
@if (count($orderItemList) > 0)
@if (user_can('Add Discount on POS')) @lang('modules.order.addDiscount') @endif @if($this->isLoyaltyEnabled() && $customerId && ($loyaltyPointsAvailable ?? 0) > 0) @lang('loyalty::app.redeemLoyaltyPoints') @endif
@endif
@lang('modules.order.totalItem')
{{ count($orderItemList) }}
@lang('modules.order.subTotal') @php // Get stamp discount amount from component property or order detail $displayStampDiscountAmount = (float)($stampDiscountAmount ?? 0); $hasFreeStampItems = false; $isOrderPlaced = false; // Check if order is placed (not draft) if ($orderID && $orderDetail) { $isOrderPlaced = $orderDetail->status !== 'draft'; // For existing orders, use orderDetail $displayStampDiscountAmount = (float)($orderDetail->stamp_discount_amount ?? $displayStampDiscountAmount); $hasFreeStampItems = $orderDetail->items()->where('is_free_item_from_stamp', true)->exists(); } elseif ($orderID) { // Load order if orderID exists but orderDetail doesn't try { $order = \App\Models\Order::find($orderID); if ($order) { $displayStampDiscountAmount = (float)($order->stamp_discount_amount ?? $displayStampDiscountAmount); $hasFreeStampItems = $order->items()->where('is_free_item_from_stamp', true)->exists(); } } catch (\Exception $e) { // Silently fail } } else { // For new orders, check if any items in cart are marked as free from stamp foreach ($orderItemList as $key => $item) { if (isset($itemNotes[$key]) && str_contains($itemNotes[$key] ?? '', __('loyalty::app.freeItemFromStamp'))) { $hasFreeStampItems = true; break; } } } @endphp @if(!$isOrderPlaced && ($displayStampDiscountAmount > 0 || $hasFreeStampItems)) @lang('app.stampDiscount') @if($displayStampDiscountAmount > 0) (-{{ currency_format($displayStampDiscountAmount, $restaurant->currency_id) }}) @elseif($hasFreeStampItems) (@lang('app.freeItem')) @endif @endif
{{ currency_format($subTotal, $restaurant->currency_id) }}
@if(function_exists('module_enabled') && module_enabled('Loyalty')) @include('loyalty::components.loyalty-discount-display', [ 'loyaltyPointsRedeemed' => $loyaltyPointsRedeemed ?? 0, 'loyaltyDiscountAmount' => $loyaltyDiscountAmount ?? 0, 'currencyId' => $restaurant->currency_id, 'showEditIcon' => true, 'customer' => $customer ?? null ]) @endif @if ($discountAmount && $loyaltyPointsRedeemed == 0)
@lang('modules.order.discount') @if ($discountType == 'percent') ({{ $discountValue }}%) @endif
-{{ currency_format($discountAmount, $restaurant->currency_id) }}
@endif @if ($orderType === 'delivery')
@lang('modules.delivery.deliveryFee') @if($deliveryFee == 0) (@lang('modules.delivery.freeDelivery')) @endif
@endif @if ((!$orderID || ($orderID && $orderDetail && $orderDetail->status == 'draft')) && count($orderItemList) > 0 && $extraCharges) @foreach ($extraCharges as $charge)
{{ $charge->charge_name }} @if ($charge->charge_type == 'percent') ({{ $charge->charge_value }}%) @endif
{{ currency_format($charge->getAmount($discountedTotal), $restaurant->currency_id) }}
@endforeach @elseif($orderID && count($orderItemList) > 0 && $extraCharges) @foreach ($extraCharges as $newKotCharge)
{{ $newKotCharge->charge_name }} @if ($newKotCharge->charge_type == 'percent') ({{ $newKotCharge->charge_value }}%) @endif
{{ currency_format($newKotCharge->getAmount($discountedTotal), $restaurant->currency_id) }}
@endforeach @endif @if ($taxMode == 'order') @php // For existing orders, use order's taxes; otherwise use all restaurant taxes // Prevent duplicate taxes by tracking tax IDs and tax names $taxesToDisplay = []; $seenTaxIds = []; $seenTaxNames = []; if ($orderID && $orderDetail && $orderDetail->taxes && $orderDetail->taxes->count() > 0) { // Use order's specific taxes (avoid duplicates by both ID and name) // Use unique() to remove duplicates at collection level first $uniqueOrderTaxes = $orderDetail->taxes->unique(function ($orderTax) { $tax = $orderTax->tax ?? null; return $tax ? ($tax->id ?? $tax->tax_name ?? '') : ''; }); foreach ($uniqueOrderTaxes as $orderTax) { $tax = $orderTax->tax ?? null; if ($tax) { $taxId = $tax->id ?? null; $taxName = strtolower(trim($tax->tax_name ?? '')); // Check both ID and name to prevent duplicates $isDuplicate = false; if ($taxId && in_array($taxId, $seenTaxIds)) { $isDuplicate = true; } elseif ($taxName && in_array($taxName, $seenTaxNames)) { $isDuplicate = true; } if (!$isDuplicate) { if ($taxId) $seenTaxIds[] = $taxId; if ($taxName) $seenTaxNames[] = $taxName; $taxesToDisplay[] = (object)[ 'tax_name' => $tax->tax_name ?? '', 'tax_percent' => $tax->tax_percent ?? 0 ]; } } } } else { // Use all restaurant taxes for new orders (avoid duplicates) foreach ($taxes ?? [] as $tax) { if ($tax) { $taxId = $tax->id ?? null; $taxName = strtolower(trim($tax->tax_name ?? '')); // Check both ID and name to prevent duplicates $isDuplicate = false; if ($taxId && in_array($taxId, $seenTaxIds)) { $isDuplicate = true; } elseif ($taxName && in_array($taxName, $seenTaxNames)) { $isDuplicate = true; } if (!$isDuplicate) { if ($taxId) $seenTaxIds[] = $taxId; if ($taxName) $seenTaxNames[] = $taxName; $taxesToDisplay[] = (object)[ 'tax_name' => $tax->tax_name ?? '', 'tax_percent' => $tax->tax_percent ?? 0 ]; } } } } @endphp @foreach ($taxesToDisplay as $item)
{{ $item->tax_name }} ({{ $item->tax_percent }}%)
{{ currency_format(($item->tax_percent / 100) * $taxBase, $restaurant->currency_id) }}
@endforeach @else @php // Show item-wise tax breakdown above total tax $taxTotals = []; $isInclusive = $restaurant->tax_inclusive ?? false; foreach ($orderItemTaxDetails as $item) { $qty = $item['qty'] ?? 1; if (!empty($item['tax_breakup'])) { foreach ($item['tax_breakup'] as $taxName => $taxInfo) { if (!isset($taxTotals[$taxName])) { $taxTotals[$taxName] = [ 'percent' => $taxInfo['percent'], 'amount' => 0, ]; } $taxTotals[$taxName]['amount'] += $taxInfo['amount'] * $qty; } } } @endphp @if (!empty($taxTotals)) @foreach ($taxTotals as $taxName => $taxInfo)
{{ $taxName }} ({{ $taxInfo['percent'] }}%)
{{ currency_format($taxInfo['amount'], $restaurant->currency_id) }}
@endforeach
@lang('modules.order.totalTax') @if ($isInclusive) (@lang('modules.settings.taxInclusive')) @else (@lang('modules.settings.taxExclusive')) @endif
{{ currency_format($totalTaxAmount, $restaurant->currency_id) }}
@endif @endif
@lang('modules.order.total')
{{ currency_format($total, $restaurant->currency_id) }}
@if (!$orderID || ($orderID && $orderDetail && $orderDetail->status !== 'draft'))
@endif @if (in_array('KOT', restaurant_modules()))
@endif @if (!$orderID || ($orderID && $orderDetail && $orderDetail->status == 'draft'))
@endif
@lang('modules.order.reservationConfirmation')

@lang('modules.order.tableHasReservation')

@lang('modules.order.reservationFor'): {{ $this->reservationCustomer?->name ?? 'N/A' }}

@lang('modules.order.reservationTime'): {{ $this->reservation?->reservation_date_time?->translatedFormat(dateFormat() . ' ' . timeFormat()) ?? 'N/A' }}

@lang('modules.order.isThisSameCustomer')

@lang('app.cancel')
@lang('modules.order.differentCustomer') @lang('modules.order.sameCustomer')
@lang('modules.order.changeTable')

@lang('modules.order.confirmTableChange')

@lang('modules.order.currentTable'): {{ $tableNo }}

@if($pendingTable)

@lang('modules.order.changeTo'): {{ $pendingTable->table_code }}

@endif

@lang('modules.order.tableChangeMessage')

@lang('modules.order.tableChangeWarning')

@lang('app.cancel') @lang('modules.order.changeTable')
@lang('modules.order.mergeTables')
@if(count($tablesWithUnpaidOrders) > 0)
@lang('modules.order.mergeTableDescription')
@foreach($tablesWithUnpaidOrders as $table) @endforeach
@if(count($selectedTablesForMerge) > 0)

{{ count($selectedTablesForMerge) }} @lang('modules.order.tablesSelectedForMerge')

@endif @else

@lang('modules.order.noTablesWithUnpaidOrders')

@lang('modules.order.noTablesWithUnpaidOrdersDescription')

@endif
@lang('app.close') @if(count($tablesWithUnpaidOrders) > 0) @if(count($selectedTablesForMerge) > 0) @else @endif @endif