@foreach( $variations as $variation) {{ $product->name }} ({{$variation->sub_sku}}) @if( $product->type == 'variable' )
({{ $variation->product_variation->name }} : {{ $variation->name }}) @endif @if($product->enable_stock == 1)
@lang('report.current_stock'): @if(!empty($variation->variation_location_details->first())) {{@num_format($variation->variation_location_details->first()->qty_available)}} @else 0 @endif {{ $product->unit->short_name }} @endif @if(!empty($purchase_order_line)) {!! Form::hidden('purchases[' . $row_count . '][purchase_order_line_id]', $purchase_order_line->id ); !!} @endif @if(!empty($purchase_requisition_line)) {!! Form::hidden('purchases[' . $row_count . '][purchase_requisition_line_id]', $purchase_requisition_line->id ); !!} @endif {!! Form::hidden('purchases[' . $row_count . '][product_id]', $product->id ); !!} {!! Form::hidden('purchases[' . $row_count . '][variation_id]', $variation->id , ['class' => 'hidden_variation_id']); !!} {{-- R3: when a store GRN row was seeded from the warehouse's dispatched batch, carry the source warehouse purchase_line so the store's received stock is linked back to the exact warehouse batch. --}} @if(!empty(($dispatch_batch ?? null)['source_purchase_line_id'])) {!! Form::hidden('purchases[' . $row_count . '][source_purchase_line_id]', $dispatch_batch['source_purchase_line_id']); !!} @endif @php $check_decimal = 'false'; if($product->unit->allow_decimal == 0){ $check_decimal = 'true'; } $currency_precision = session('business.currency_precision', 2); $quantity_precision = session('business.quantity_precision', 2); $quantity_value = !empty($purchase_order_line) ? $purchase_order_line->quantity : 1; $quantity_value = !empty($purchase_requisition_line) ? $purchase_requisition_line->quantity - $purchase_requisition_line->po_quantity_purchased : $quantity_value; $max_quantity = !empty($purchase_order_line) ? $purchase_order_line->quantity - $purchase_order_line->po_quantity_purchased - $purchase_order_line->po_quantity_damaged - $purchase_order_line->po_quantity_lost : 0; $max_quantity = !empty($purchase_requisition_line) ? $purchase_requisition_line->quantity - $purchase_requisition_line->po_quantity_purchased : $max_quantity; $quantity_value = !empty($imported_data) ? $imported_data['quantity'] : $quantity_value; // MULTI-BATCH GRN: when one PO line was dispatched from several // batches, purchase_order_lines.blade.php renders one row PER BATCH // and passes that batch's own quantity here. Each row then carries // its own lot / expiry / manufacturer, so the store records the real // split instead of the whole quantity under the first lot. $quantity_value = isset($batch_quantity_override) ? $batch_quantity_override : $quantity_value; // Figure out the pre-selected unit here (ahead of the @if(!empty($sub_units)) @php // $_preselect_purchase was already computed above (needed // there to convert $max_quantity into base-unit terms too). // Rows whose prices were prefilled from a negotiated // source (PO lines, imported CSV costs) must not have // them recomputed from the product's default price // when the pre-selected unit is applied on insert. $_skip_price_sync = (!empty($purchase_order_line) || !empty($imported_data)) ? 1 : 0; @endphp
@else {{ $product->unit->short_name }} @endif @if(!empty($product->second_unit)) @php $secondary_unit_quantity = !empty($purchase_requisition_line) ? $purchase_requisition_line->secondary_unit_quantity : ""; @endphp
@lang('lang_v1.quantity_in_second_unit', ['unit' => $product->second_unit->short_name])*:
@endif @php $pp_without_discount = !empty($purchase_order_line) ? $purchase_order_line->pp_without_discount/$purchase_order->exchange_rate : $variation->default_purchase_price; $discount_percent = !empty($purchase_order_line) ? $purchase_order_line->discount_percent : 0; $purchase_price = !empty($purchase_order_line) ? $purchase_order_line->purchase_price/$purchase_order->exchange_rate : $variation->default_purchase_price; $tax_id = !empty($purchase_order_line) ? $purchase_order_line->tax_id : $product->tax; $tax_id = !empty($imported_data['tax_id']) ? $imported_data['tax_id'] : $tax_id; $pp_without_discount = !empty($imported_data['unit_cost_before_discount']) ? $imported_data['unit_cost_before_discount'] : $pp_without_discount; $discount_percent = !empty($imported_data['discount_percent']) ? $imported_data['discount_percent'] : $discount_percent; @endphp {!! Form::text('purchases[' . $row_count . '][pp_without_discount]', number_format($pp_without_discount, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator), ['class' => 'form-control input-sm purchase_unit_cost_without_discount input_number', 'required']); !!} @if(!empty($last_purchase_line)) @php // The stored last-purchase price is per BASE unit; // scale it to the pre-selected sub-unit so the hint // is comparable with the cost input beside it. $_prev_price_multiplier = 1; if (!empty($sub_units) && isset($_preselect_purchase) && isset($sub_units[$_preselect_purchase])) { $_prev_price_multiplier = $sub_units[$_preselect_purchase]['multiplier'] ?? 1; } @endphp
@lang('lang_v1.prev_unit_price'): @format_currency($last_purchase_line->pp_without_discount * $_prev_price_multiplier) @endif {!! Form::text('purchases[' . $row_count . '][discount_percent]', number_format($discount_percent, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator), ['class' => 'form-control input-sm inline_discounts input_number', 'required']); !!} @if(!empty($last_purchase_line))
@lang('lang_v1.prev_discount'): {{@num_format($last_purchase_line->discount_percent)}}% @endif {!! Form::text('purchases[' . $row_count . '][purchase_price]', number_format($purchase_price, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator), ['class' => 'form-control input-sm purchase_unit_cost input_number', 'required']); !!} 0
{!! Form::hidden('purchases[' . $row_count . '][item_tax]', 0, ['class' => 'purchase_product_unit_tax']); !!} 0.00
@php $dpp_inc_tax = number_format($variation->dpp_inc_tax, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator); if($hide_tax == 'hide'){ $dpp_inc_tax = number_format($variation->default_purchase_price, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator); } $dpp_inc_tax = !empty($purchase_order_line) ? number_format($purchase_order_line->purchase_price_inc_tax/$purchase_order->exchange_rate, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator) : $dpp_inc_tax; @endphp {!! Form::text('purchases[' . $row_count . '][purchase_price_inc_tax]', $dpp_inc_tax, ['class' => 'form-control input-sm purchase_unit_cost_after_tax input_number', 'required']); !!} 0 {!! Form::text('purchases[' . $row_count . '][profit_percent]', number_format($variation->profit_percent, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator), ['class' => 'form-control input-sm input_number profit_percent', 'required']); !!} @if(empty($is_purchase_order)) @if(session('business.enable_editing_product_from_purchase')) {!! Form::text('purchases[' . $row_count . '][default_sell_price]', number_format($variation->sell_price_inc_tax, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator), ['class' => 'form-control input-sm input_number default_sell_price', 'required']); !!} @else {{ number_format($variation->sell_price_inc_tax, $currency_precision, $currency_details->decimal_separator, $currency_details->thousand_separator)}} @endif @if(session('business.enable_lot_number')) @php // R3 prefill: imported CSV value first, else the warehouse's // dispatched batch (store GRN from a warehouse-fulfilled PO). $lot_number = !empty($imported_data['lot_number']) ? $imported_data['lot_number'] : (!empty(($dispatch_batch ?? null)['lot_number']) ? $dispatch_batch['lot_number'] : null); @endphp {{-- Supplier warehouse (pharma GRN): lot is mandatory. Stores: unchanged. --}} {!! Form::text('purchases[' . $row_count . '][lot_number]', $lot_number, array_merge(['class' => 'form-control input-sm'], session('business.is_supplier_warehouse') ? ['required' => 'required'] : [])); !!} @php // Batch manufacturer, defaulted then left editable — same idiom as // lot/expiry above. Preference order: // 1. imported CSV value // 2. the warehouse's dispatched batch (store GRN, R3 prefill) // 3. the PO line this GRN row came from // 4. the product's primary manufacturer $batch_manufacturer_id = !empty($imported_data['manufacturer_id']) ? $imported_data['manufacturer_id'] : (!empty(($dispatch_batch ?? null)['manufacturer_id']) ? $dispatch_batch['manufacturer_id'] : (!empty($purchase_order_line->manufacturer_id) ? $purchase_order_line->manufacturer_id : $product->manufacturer_id)); $row_manufacturers = $product->selectableManufacturers(); @endphp @if($row_manufacturers->isNotEmpty()) {{-- Mandatory on a supplier WAREHOUSE, exactly like lot number and expiry above: the batch's maker must travel to the store and onto the patient's invoice, so it cannot be left blank at the point it is captured. Stores inherit it from the dispatch prefill, so it stays optional there. --}} {!! Form::select('purchases[' . $row_count . '][manufacturer_id]', $row_manufacturers, $batch_manufacturer_id, array_merge(['class' => 'form-control input-sm', 'placeholder' => __('messages.please_select')], session('business.is_supplier_warehouse') ? ['required' => 'required'] : [])); !!} @else
@lang('product.not_applicable')
@endif @endif @if(session('business.enable_product_expiry')) {{-- Maybe this condition for checkin expiry date need to be removed --}} @php $expiry_period_type = !empty($product->expiry_period_type) ? $product->expiry_period_type : 'month'; @endphp @if(!empty($expiry_period_type)) @if(session('business.expiry_type') == 'add_manufacturing' || session('business.is_supplier_warehouse')) {{-- Expose Mfg date on a supplier warehouse too (pharma), even though warehouses use expiry_type='add_expiry'. --}} @php $hide_mfg = false; @endphp @else @php $hide_mfg = true; @endphp @endif @php // R3 prefill: imported CSV value first, else the warehouse's // dispatched batch, formatted to the business date format. $_df = session('business.date_format') ?: 'm/d/Y'; $mfg_date = !empty($imported_data['mfg_date']) ? $imported_data['mfg_date'] : (!empty(($dispatch_batch ?? null)['mfg_date']) ? \Carbon\Carbon::parse($dispatch_batch['mfg_date'])->format($_df) : null); $exp_date = !empty($imported_data['exp_date']) ? $imported_data['exp_date'] : (!empty(($dispatch_batch ?? null)['exp_date']) ? \Carbon\Carbon::parse($dispatch_batch['exp_date'])->format($_df) : null); @endphp @lang('product.mfg_date'):
{!! Form::text('purchases[' . $row_count . '][mfg_date]', $mfg_date, ['class' => 'form-control input-sm expiry_datepicker mfg_date', 'readonly']); !!}
@lang('product.exp_date'):
{{-- Supplier warehouse (pharma GRN): expiry is mandatory. Stores: unchanged. --}} {!! Form::text('purchases[' . $row_count . '][exp_date]', $exp_date, array_merge(['class' => 'form-control input-sm expiry_datepicker exp_date', 'readonly'], session('business.is_supplier_warehouse') ? ['required' => 'required'] : [])); !!}
@else
@lang('product.not_applicable')
@endif @endif @endif {{-- PURCHASE ORDER rows: choose the manufacturer to order THIS product from. Independent of the requisition — the same medicine can be made by several manufacturers, so the maker is picked fresh on every PO, limited to those mapped to the product (product_manufacturers). On save the PO is split into one PO per manufacturer. --}} @if(!empty($is_purchase_order) && session('business.is_supplier_warehouse')) @php $row_manufacturers = $product->selectableManufacturers(); @endphp @if($row_manufacturers->isNotEmpty()) {!! Form::select('purchases[' . $row_count . '][manufacturer_id]', $row_manufacturers, $product->manufacturer_id, ['class' => 'form-control input-sm po_line_manufacturer', 'placeholder' => __('messages.please_select'), 'required']); !!} @else @lang('lang_v1.no_manufacturer_mapped') @endif @endif @if(session('business.enable_damage_loss_tracking'))
{!! Form::hidden('purchases[' . $row_count . '][quantity_damaged]', 0, ['class' => 'damage_loss_qty_damaged']); !!} {!! Form::hidden('purchases[' . $row_count . '][quantity_lost]', 0, ['class' => 'damage_loss_qty_lost']); !!} {!! Form::hidden('purchases[' . $row_count . '][damage_loss_reason]', '', ['class' => 'damage_loss_reason_hidden']); !!} {!! Form::hidden('purchases[' . $row_count . '][damage_loss_note]', '', ['class' => 'damage_loss_note_hidden']); !!} {!! Form::hidden('purchases[' . $row_count . '][usable_qty]', 0, ['class' => 'damage_loss_usable_qty']); !!} @endif @endforeach