← Back to sales
@if (session('error'))
{{ session('error') }}
@endif

Smart Order Entry

Paste the order the way you'd write it down — one product and quantity per line, blank lines between groups, an optional group label like "Serums" or "Gummies". Place Order matches every line to a product; you review and fix anything before it's saved.

@if ($this->tierLabel())

Priced at {{ $this->tierLabel() }} rates

@endif
@if (! empty($draftLines) && ! $showModal) @endif

Or auto-suggest by amount

No product list needed — enter roughly how much you want this order to come to and every eligible in-stock product is given the same quantity, capped by what's actually on hand, chosen so the total lands as close as possible to your amount. Pick specific products below to use only those instead.

Narrows the whole-catalog pool below, and the product picker's own list.

@if (count($selectedProductIds))
@foreach ($selectedProductIds as $id) @php $product = $this->pickerProductMap()->get((int) $id); @endphp @continue(! $product) {{ $product->name }} @endforeach
@endif
@if ($showModal)

Review order — {{ count($draftLines) }} line{{ count($draftLines) === 1 ? '' : 's' }}

@if ($this->unresolvedCount() > 0)
{{ $this->unresolvedCount() }} line(s) below still need a product and/or a quantity greater than zero before you can confirm.
@endif
@if ($reviewSearch !== '') {{ count($this->visibleLineIndices()) }} of {{ count($draftLines) }} shown @endif
{{-- Not overflow-x-auto: the per-row product picker is an absolutely-positioned dropdown, and overflow-x set to anything but visible clips it (setting -x forces -y to auto too, per the CSS spec, even though only -x was set here) - see the same note on sale-form.blade.php's item table, which had the identical bug. This modal's own overflow-y-auto (on the wrapper above, needed so a long order still scrolls) can still clip a dropdown opened on a row right at the bottom edge of the current scroll position - scroll the row into better view first if that happens. --}}
@php $priced = $this->pricedDraftLines(); $visible = $this->visibleLineIndices(); @endphp @foreach ($draftLines as $i => $line) @continue(! in_array($i, $visible, true)) @php $p = $priced[$i] ?? null; $needsAttention = empty($line['product_id']) || (int) ($line['quantity'] ?? 0) <= 0; @endphp $needsAttention])> @endforeach @if (empty($visible)) @endif
Typed as Group Matched product Qty Rate Amount
{{ $line['raw_text'] }} {{ $line['section_label'] ?? '—' }} @if ($line['status'] === 'exact') Matched @elseif ($line['status'] === 'fuzzy') Check match{{ isset($line['candidates'][0]['score']) ? ' ('.$line['candidates'][0]['score'].'%)' : '' }} @elseif ($line['status'] === 'auto') Auto-suggested @else Select a product @endif @if (count($line['candidates']) > 1)
@foreach (array_slice($line['candidates'], 1) as $c) @endforeach
@endif
{{ $p ? number_format($p['unit_price'], 2) : '—' }} {{ $p ? number_format($p['taxable'], 2) : '—' }}
No lines match "{{ $reviewSearch }}".
@php $totals = $this->totals(); @endphp
Total quantity
{{ $totals['quantity'] }} PCS
Taxable value
{{ number_format($totals['taxable'], 2) }}
@if ($totals['inter_state'])
IGST
{{ number_format($totals['igst'], 2) }}
@else
CGST
{{ number_format($totals['cgst'], 2) }}
SGST
{{ number_format($totals['sgst'], 2) }}
@endif
Round off
{{ number_format($totals['round_off'], 2) }}
Grand total
₹{{ number_format($totals['total'], 2) }}
@endif