@php /* |-------------------------------------------------------------------------- | SAFE DATA |-------------------------------------------------------------------------- */ $saleItems = $offlineSale->sale_items ?? []; if (is_string($saleItems)) { $decodedSaleItems = json_decode($saleItems, true); $saleItems = is_array($decodedSaleItems) ? $decodedSaleItems : []; } $customerDetails = $offlineSale->customer_details ?? []; if (is_string($customerDetails)) { $decodedCustomerDetails = json_decode($customerDetails, true); $customerDetails = is_array($decodedCustomerDetails) ? $decodedCustomerDetails : []; } /* |-------------------------------------------------------------------------- | CUSTOMER DETAILS FALLBACK FROM USERS TABLE |-------------------------------------------------------------------------- | | Priority: | 1. Values saved inside offline_sales.customer_details | 2. If missing / N/A / '-' -> users table values using offlineSale->user_id | | This keeps old invoices working without any migration/model changes. */ if (!is_array($customerDetails)) { $customerDetails = []; } $isMissingCustomerValue = function ($value) { if (is_null($value)) { return true; } $value = trim((string) $value); if ($value === '') { return true; } return in_array( strtolower($value), ['n/a', 'na', '-', 'null', 'none'], true ); }; $customerUser = null; if (!empty($offlineSale->user_id)) { $customerUser = \App\Models\User::where( 'user_id', $offlineSale->user_id )->first(); } if ( $isMissingCustomerValue($customerDetails['name'] ?? null) && $customerUser ) { $customerDetails['name'] = $customerUser->name ?? ''; } if ( $isMissingCustomerValue($customerDetails['phone_number'] ?? null) && $customerUser ) { $customerDetails['phone_number'] = $customerUser->phone_number ?? $customerUser->phone ?? ''; } if ( $isMissingCustomerValue($customerDetails['email'] ?? null) && $customerUser ) { $customerDetails['email'] = $customerUser->email ?? ''; } $savedAddress = $customerDetails['address'] ?? $customerDetails['customer_address'] ?? null; if ( $isMissingCustomerValue($savedAddress) && $customerUser ) { $savedAddress = $customerUser->address ?? ''; } $customerAddress = $isMissingCustomerValue($savedAddress) ? '' : trim((string) $savedAddress); $savedGstNumber = $customerDetails['gst_number'] ?? $customerDetails['gstin'] ?? $customerDetails['gst_no'] ?? null; if ( $isMissingCustomerValue($savedGstNumber) && $customerUser ) { $savedGstNumber = $customerUser->gst_number ?? $customerUser->gstin ?? ''; } $customerGstNumber = $isMissingCustomerValue($savedGstNumber) ? '' : trim((string) $savedGstNumber); /* |-------------------------------------------------------------------------- | ACTUAL HSN CODE MAP |-------------------------------------------------------------------------- | HSN in this invoice must come only from products.actual_hsn_code. | One bulk query is used to avoid an N+1 query for every invoice item. */ $invoiceProductIds = collect($saleItems) ->filter(fn ($item) => is_array($item)) ->map(function ($item) { if (($item['type'] ?? '') === 'variant') { return $item['product_id_main'] ?? null; } return $item['item_identifier'] ?? $item['product_id_main'] ?? null; }) ->filter() ->unique() ->values(); $actualHsnByProductId = $invoiceProductIds->isNotEmpty() ? \App\Models\Product::whereIn('product_id', $invoiceProductIds) ->pluck('actual_hsn_code', 'product_id') : collect(); $hasGstProduct = collect($saleItems)->contains(function ($item) { return is_array($item) && (float) ($item['gst'] ?? 0) > 0; }); /* |-------------------------------------------------------------------------- | MAIN VALUES |-------------------------------------------------------------------------- */ $grossItemTotal = 0; /* |-------------------------------------------------------------------------- | DISCOUNT HANDLING |-------------------------------------------------------------------------- | Main / Full Invoice : Apply original discount. | GST Invoice : Apply original MAIN invoice discount. | Non-GST Estimate : Do NOT apply discount. |-------------------------------------------------------------------------- */ $originalDiscountAmount = (float) ( $mainSale->discount ?? $offlineSale->discount ?? 0 ); if (($invoiceType ?? 'main') === 'non_gst') { $discountAmount = 0; } else { $discountAmount = $originalDiscountAmount; } $shoppingWalletDeduction = (float) ( $offlineSale->shopping_wallet_deduction ?? 0 ); $cashWalletDeduction = (float) ( $offlineSale->cash_wallet_deduction ?? 0 ); $additionalCharge = (float) ( $offlineSale->additional_charge ?? 0 ); /* |-------------------------------------------------------------------------- | STEP 1 | Gross item total. | | sell_price is considered GST-INCLUSIVE. |-------------------------------------------------------------------------- */ foreach ($saleItems as $item) { if (!is_array($item)) { continue; } $price = (float) ($item['sell_price'] ?? 0); $qty = (float) ($item['quantity'] ?? 1); if ($qty <= 0) { $qty=1; } $grossItemTotal +=($price * $qty); } /* |-------------------------------------------------------------------------- | STEP 2 | Total deductions. |-------------------------------------------------------------------------- */ $totalDeduction=$discountAmount + $shoppingWalletDeduction + $cashWalletDeduction; /* |-------------------------------------------------------------------------- | STEP 3 | Final GST-inclusive sale amount. |-------------------------------------------------------------------------- */ $inclusiveSaleAmount=max( 0, $grossItemTotal - $totalDeduction ); /* |-------------------------------------------------------------------------- | STEP 4 | GST CALCULATION |-------------------------------------------------------------------------- */ $calculatedCgst=0; $calculatedSgst=0; $calculatedGst=0; /* |-------------------------------------------------------------------------- | Store all applicable GST rates. |-------------------------------------------------------------------------- */ $gstRates=[]; /* |-------------------------------------------------------------------------- | Calculate GST for each item. |-------------------------------------------------------------------------- */ foreach ($saleItems as $item) { if (!is_array($item)) { continue; } $price=(float) ($item['sell_price'] ?? 0); $qty=(float) ($item['quantity'] ?? 1); if ($qty <=0) { $qty=1; } $gstRate=(float) ($item['gst'] ?? 0); $itemTotal=$price * $qty; /* |-------------------------------------------------------------------------- | Proportionate deduction |-------------------------------------------------------------------------- */ $itemRatio=$grossItemTotal> 0 ? ($itemTotal / $grossItemTotal) : 0; $itemDeduction = $totalDeduction * $itemRatio; /* |-------------------------------------------------------------------------- | GST-inclusive amount after deduction |-------------------------------------------------------------------------- */ $itemInclusiveAmount = max( 0, $itemTotal - $itemDeduction ); /* |-------------------------------------------------------------------------- | Extract GST from inclusive price. | | Example: | | ₹11,800 at 18% GST | | GST = 11,800 × 18 / 118 | = ₹1,800 | | Basic Price = ₹10,000 |-------------------------------------------------------------------------- */ if ($gstRate > 0) { $itemGstAmount = ($itemInclusiveAmount * $gstRate) / (100 + $gstRate); /* |-------------------------------------------------------------------------- | Save GST rate |-------------------------------------------------------------------------- */ $gstRates[] = $gstRate; } else { $itemGstAmount = 0; } /* |-------------------------------------------------------------------------- | Split GST equally. |-------------------------------------------------------------------------- */ $itemCgstAmount = $itemGstAmount / 2; $itemSgstAmount = $itemGstAmount / 2; $calculatedCgst += $itemCgstAmount; $calculatedSgst += $itemSgstAmount; $calculatedGst += $itemGstAmount; } /* |-------------------------------------------------------------------------- | UNIQUE GST RATES |-------------------------------------------------------------------------- */ $gstRates = collect($gstRates) ->unique() ->sort() ->values() ->toArray(); /* |-------------------------------------------------------------------------- | CGST / SGST RATES | | 18% GST => 9% + 9% | 5% GST => 2.5% + 2.5% |-------------------------------------------------------------------------- */ $cgstRates = collect($gstRates) ->map(function ($rate) { return $rate / 2; }) ->unique() ->sort() ->values() ->toArray(); $sgstRates = $cgstRates; /* |-------------------------------------------------------------------------- | GST RATE FORMATTER |-------------------------------------------------------------------------- */ $formatGstRates = function ($rates) { if (empty($rates)) { return '0%'; } return collect($rates) ->map(function ($rate) { $formatted = number_format( (float) $rate, 2, '.', '' ); $formatted = rtrim( rtrim($formatted, '0'), '.' ); return $formatted . '%'; }) ->implode(' + '); }; $cgstRateText = $formatGstRates($cgstRates); $sgstRateText = $formatGstRates($sgstRates); /* |-------------------------------------------------------------------------- | FINAL TOTAL | | GST is already included in sell_price. | Therefore DO NOT add GST again. |-------------------------------------------------------------------------- */ $subtotalIncludingGst = $inclusiveSaleAmount; $pageFinalTotal = $subtotalIncludingGst + $additionalCharge; @endphp
@if (!empty($branchInfo['logo'])) Logo @else
N/A
@endif

{{ $branchInfo['name'] ?? 'Branch Name' }}

@php $companyAddress = $branchInfo['address'] ?? ''; /* |-------------------------------------------------------------------------- | PRESERVE ADDRESS LINES EXACTLY AS ENTERED |-------------------------------------------------------------------------- */ $addressLines = preg_split( '/\r\n|\r|\n/', (string) $companyAddress ); $addressLines = collect($addressLines) ->map(function ($line) { return trim($line); }) ->filter(function ($line) { return $line !== ''; }) ->values() ->toArray(); @endphp {{-- COMPANY ADDRESS --}} @if (!empty($addressLines)) @foreach ($addressLines as $line)
{{ $line }}
@endforeach @else
-
@endif {{-- PHONE --}} @if (!empty($branchInfo['phone']))
+91 {{ $branchInfo['phone'] }}
@endif {{-- EMAIL --}} @if (!empty($branchInfo['email']))
{{ $branchInfo['email'] }}
@endif {{-- |-------------------------------------------------------------------------- | GSTIN - ONLY FOR TAX INVOICE |-------------------------------------------------------------------------- | | GST Product -> Tax Invoice -> SHOW GSTIN | Non GST -> Estimate -> HIDE GSTIN | --}} @if ($hasGstProduct && !empty($branchInfo['gst_number']))
GSTIN: {{ $branchInfo['gst_number'] }}
@endif

@if (!empty($showFullInvoice)) Full Invoice @elseif ($hasGstProduct) Tax Invoice @else Estimate @endif

Invoice No : {{ $offlineSale->order_id ?? '-' }}
Date : @if (!empty($offlineSale->changed_date)) {{ \Carbon\Carbon::parse($offlineSale->changed_date)->format('d/m/Y') }} @elseif (!empty($offlineSale->created_at)) {{ \Carbon\Carbon::parse($offlineSale->created_at)->format('d/m/Y') }} @else - @endif
Customer Details
Name
:
{{ $customerDetails['name'] ?? 'Walk-in Customer' }}
@if (!empty($customerDetails['phone_number']))
Phone
:
{{ $customerDetails['phone_number'] }}
@endif @if (!empty($customerDetails['email']))
Email Address
:
{{ $customerDetails['email'] }}
@endif
Address
:
{{ $customerAddress !== '' ? $customerAddress : '-' }}
GSTIN
:
{{ $customerGstNumber !== '' ? $customerGstNumber : '-' }}
Shipping Address
Name
:
{{ $customerDetails['name'] ?? 'Walk-in Customer' }}
@if (!empty($customerDetails['phone_number']))
Phone
:
{{ $customerDetails['phone_number'] }}
@endif @if (!empty($customerDetails['email']))
Email Address
:
{{ $customerDetails['email'] }}
@endif
Address
:
{{ $customerAddress !== '' ? $customerAddress : '-' }}
GSTIN
:
{{ $customerGstNumber !== '' ? $customerGstNumber : '-' }}
Order Summary
@if ($hasGstProduct) @endif @forelse ($saleItems as $index => $item) @if (is_array($item)) @php /* |-------------------------------------------------------------------------- | ITEM VALUES |-------------------------------------------------------------------------- */ $price = (float) ($item['sell_price'] ?? 0); $qty = (float) ($item['quantity'] ?? 1); if ($qty <= 0) { $qty=1; } $gstRate=(float) ($item['gst'] ?? 0); /* |-------------------------------------------------------------------------- | GST-INCLUSIVE TOTAL |-------------------------------------------------------------------------- */ $taxInclusiveTotal=$price * $qty; /* |-------------------------------------------------------------------------- | GST AMOUNT | | Example: | ₹1180 at 18% GST | | GST=1180 × 18 / 118 |=₹180 |-------------------------------------------------------------------------- */ if ($gstRate> 0) { $gstAmount = ($taxInclusiveTotal * $gstRate) / (100 + $gstRate); } else { $gstAmount = 0; } /* |-------------------------------------------------------------------------- | BASIC PRICE / BEFORE TAX |-------------------------------------------------------------------------- */ $basicPriceTotal = $taxInclusiveTotal - $gstAmount; /* |-------------------------------------------------------------------------- | BASIC RATE PER UNIT |-------------------------------------------------------------------------- */ $basicRate = $qty > 0 ? $basicPriceTotal / $qty : 0; /* |-------------------------------------------------------------------------- | CGST / SGST SPLIT | | 18% GST = 9% CGST + 9% SGST | 5% GST = 2.5% CGST + 2.5% SGST |-------------------------------------------------------------------------- */ $cgstRate = $gstRate / 2; $sgstRate = $gstRate / 2; /* |-------------------------------------------------------------------------- | GST AMOUNT SPLIT |-------------------------------------------------------------------------- */ $cgstAmount = $gstAmount / 2; $sgstAmount = $gstAmount / 2; /* |-------------------------------------------------------------------------- | ACTUAL HSN CODE |-------------------------------------------------------------------------- | | actual_hsn_code is fetched from products table | using item_code in the controller. | */ $hsnProductId = ($item['type'] ?? '') === 'variant' ? ($item['product_id_main'] ?? null) : ($item['item_identifier'] ?? $item['product_id_main'] ?? null); $hsnCode = $hsnProductId ? ($actualHsnByProductId->get($hsnProductId) ?? '-') : '-'; @endphp @if ($hasGstProduct) @endif @endif @empty @endforelse
S No Item HSN Code Rate Qty GST Total
{{ $loop->iteration }}
@php $itemName = $item['name'] ?? 'Product'; @endphp {{ strlen($itemName) > 50 ? substr($itemName, 0, 50) . '...' : $itemName }}
@if (isset($item['imei'])) @if (is_array($item['imei'])) @foreach ($item['imei'] as $imei) {{ $imei }}
@endforeach @else {{ $item['imei'] }} @endif @else - @endif
{{ $hsnCode }} ₹{{ number_format($basicRate, 2) }} {{ $item['quantity'] ?? 1 }} @if ($gstRate > 0) {{-- TOTAL GST AMOUNT --}} ₹{{ number_format($gstAmount, 2) }}
{{-- TOTAL GST RATE --}} GST {{ rtrim(rtrim(number_format($gstRate, 2, '.', ''), '0'), '.') }}% @else ₹0.00
GST 0% @endif
₹{{ number_format($taxInclusiveTotal, 2) }}
No items found.
Total
₹{{ number_format($grossItemTotal, 2) }}

TERMS AND CONDITIONS

1. PRICE: Above prices are inclusive of all taxes. 2. PAYMENT: 100% against order. 3. WARRANTY: Manufacturer's warranty only applicable. 4. Visit the authorized service center within the one-year warranty period for defect repairs. 5. JURISDICTION: Subject to Erode jurisdiction. 6. ON SALES: Goods once sold will not be taken back or replaced.
Payment Details

Subtotal ₹{{ number_format($grossItemTotal, 2) }}

{{-- DISCOUNT Main / Full Invoice : SHOW GST Invoice : SHOW Non-GST Estimate : HIDE --}} @if (($invoiceType ?? 'main') !== 'non_gst' && $discountAmount > 0)

Discount -₹{{ number_format($discountAmount, 2) }}

@endif @if ($shoppingWalletDeduction > 0)

Shopping Wallet -₹{{ number_format($shoppingWalletDeduction, 2) }}

@endif @if ($cashWalletDeduction > 0)

Cash Wallet -₹{{ number_format($cashWalletDeduction, 2) }}

@endif

Taxable Subtotal ₹{{ number_format( $inclusiveSaleAmount - $calculatedGst, 2 ) }}

{{-- ========================================================= CGST / SGST GST Invoice => Actual percentage + amount Non-GST Estimate => 0% + ₹0.00 ========================================================= --}}

CGST ({{ $calculatedGst > 0 ? $cgstRateText : '0%' }}) ₹{{ number_format($calculatedCgst, 2) }}

SGST ({{ $calculatedGst > 0 ? $sgstRateText : '0%' }}) ₹{{ number_format($calculatedSgst, 2) }}

Subtotal (Incl. GST) ₹{{ number_format( $subtotalIncludingGst, 2 ) }}

@if ($additionalCharge > 0)

Additional Charges +₹{{ number_format( $additionalCharge, 2 ) }}

@endif

Total ₹{{ number_format( $pageFinalTotal, 2 ) }}

Payment Mode: {{ ucfirst( $offlineSale->payment_mode ?? '-' ) }}