<?php

namespace App\Http\Controllers\IpdAdmission;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Account;
use App\Models\AccountTransaction;
use App\Models\ProductBrand;
use App\Models\Product;
use App\Models\PaymentTerm;
use App\Models\SaleInvoice;
use App\Models\SaleInvoiceDetail;
use App\Models\ProductTestPackage;
use App\Models\SaleInvoiceSubDetails;
use App\Models\SpecialCase;
use App\Models\VoucherMaster;
use App\Models\VoucherType;
use App\Models\EnquirySource;
use App\Models\LabBillingReport;
use App\Models\Department;
use App\Models\TestPackage;
use App\Models\Company;
use App\Models\TaskStatus;
use App\Models\AcReceipt;
use App\Models\IpdAdmission;
use App\Models\IpdBedHistory;
use App\Models\ProductCategory;
use App\Models\ProductPrice;
use App\Models\SaleInvoiceBatch;
use App\Models\SaleOthersTransaction;
use App\Models\Sales\SaleReturns;
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use App\Traits\AcReceiptAndTransactionAllTrait;
use App\Traits\BillingConceptTrait;
use App\Traits\TransactionSummeryTrait;
use Illuminate\Support\Facades\DB;


class IpdBillingsController extends Controller
{
    use AcReceiptAndTransactionAllTrait, TransactionSummeryTrait, BillingConceptTrait;
    // function __construct()
    // {
    //     $this->middleware('permission:pathology-lab-billing-list', ['only' => ['index']]);
    // }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request, $id = 0)
    {
        $sale_invoice = SaleInvoice::select('sale_invoices.*','ipd_admissions.id as ipd_admission_id',
            DB::raw('beds.name as bed_name', 'ipd_discharges.discharge_datetime as discharge_date', 'ipd_admissions.*', 'accounts.name as account_name'))
            ->with([
                'getSaleInvoiceDetails',
                'getSaleInvoiceDelivery',
                'getPatient',
                'getPaymentTerm',
                'getCompany',
                'getBatchs',
                'getCreatedBy'
            ])
            ->leftJoin('ipd_admissions', 'sale_invoices.id', '=', 'ipd_admissions.sale_invoice_id')
            ->leftJoin('ipd_bed_histories', 'ipd_admissions.id', '=', 'ipd_bed_histories.ipd_admission_id')
            ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
            ->leftJoin('ipd_discharges', 'ipd_admissions.id', '=', 'ipd_discharges.ipd_admission_id')
            ->leftJoin('accounts', 'ipd_admissions.tpa_account_id', '=', 'accounts.id')
            ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
            ->where('ipd_admissions.id', $id)
            ->latest()
            ->first();

        $company_address           = \Session::get('company_data')['time_zone'];
        \Session::forget('ipd_billing_products_cart');

        $ipd_id = IpdAdmission::select('ipd_admissions.id', 'ipd_admissions.patient_id','ipd_admissions.ipd_admission_no','beds.name as bed')
                ->where('ipd_admissions.id', '=', $id)
                ->leftjoin('ipd_bed_histories', 'ipd_bed_histories.ipd_admission_id', 'ipd_admissions.id')
                ->leftjoin('beds', 'beds.id', 'ipd_bed_histories.bed_no_id')
                ->first();
               
        $data   = SaleInvoiceBatch::select('sale_invoice_batches.*','sale_invoices.id as sale_invoice_id' , 'ipd_admissions.*','users.prepared_by','sale_invoice_batches.created_at')
                    ->with('voucherType')
                    ->leftjoin('sale_invoices','sale_invoices.id','sale_invoice_batches.invoice_id')
                    ->leftjoin('users','users.id','sale_invoices.operator_id')
                    ->leftjoin('ipd_admissions','ipd_admissions.sale_invoice_id','sale_invoices.id')
                    ->whereNull('sale_invoices.deleted_at')
                    ->whereNull('sale_invoice_batches.deleted_at')
                    ->where('voucher_type_code', 'IPD_ADMISSION')
                    ->where('ipd_admissions.id', $id)
                    ->whereNull('sale_invoice_batches.deleted_at')
                    // ->groupBy('sale_invoice_batches.id')
                    ->latest('sale_invoice_batches.id');
                    

        if ($id != '' && $id != null) {
            $data = $data->groupBy('sale_invoice_batches.id')->latest('sale_invoice_batches.id');

            $patient_detail = Account::select(
                'accounts.name', 
                'accounts.account_title_id', 
                'accounts.id as account_id', 
                'accounts.code', 
                'sale_invoice_batches.*'
            )
            ->leftJoin('sale_invoice_batches', 'sale_invoice_batches.account_id', '=', 'accounts.id')
            ->where('accounts.id', '=', 'sale_invoice_batches.account_id')
            ->with('account_contact', 'account_title')
            ->first();

           
            if ($request->ajax()) {
                 $sort_by             = $request->get('sortby') ?? 10;
                 $sort_type           = $request->get('sorttype');
                 $search_query        = $request->get('query');
                 $display             = $request->get('display') ?? '';
                 $voucherType         = $request->get('voucherType') ?? '';
                 $from_date           = $request->get('from_date') ?? '';
                 $billing_date_picker = $request->get('billing_date_picker') ?? '';

               
                 $data         = $data->when(!empty($voucherType), function($query) use ($voucherType) {
                    $query->where('sale_invoice_batches.referrence_voucher_type', $voucherType);
                 })
                 ->when(!empty($billing_date_picker) && !empty($from_date), function($query) use ($billing_date_picker, $from_date) {
                    $query->whereBetween('sale_invoice_batches.created_at', [
                        date('Y-m-d', strtotime($from_date)), 
                        date('Y-m-d', strtotime($billing_date_picker))
                    ]);
                 });

                  $data         = $data->select('sale_invoice_batches.*', 'sale_invoices.id as sale_invoice_id','users.prepared_by')
                              ->groupBy('sale_invoice_batches.id');
                 // $count     =  $data->get()->count();
                 $count        = 0;
                 $data         = $data->paginate($sort_by);
                

                $voucher_types   = VoucherType::select('voucher_types.code','voucher_types.name')
                    ->leftjoin('voucher_masters','voucher_types.voucher_master_id','voucher_masters.id')
                    ->where(['voucher_types.status' => 1])
                    ->where(['voucher_masters.voucher_code' => 'SALES'])
                    ->get();

                return view('ipd-billings.table', compact('data', 'ipd_id','company_address','count','display','voucher_types','voucherType','billing_date_picker','from_date'));
            } else {
                
                $data = $data->select('sale_invoice_batches.*', 'sale_invoices.id as sale_invoice_id','users.prepared_by')
                             ->groupBy('sale_invoice_batches.id')
                             ->paginate(10);

                return view('ipd-billings.index', compact('data', 'patient_detail', 'ipd_id','id','company_address' , 'sale_invoice'));
            }
        } else {
            if ($request->ajax()) {
                $sort_by = $request->get('sortby') ?? 10;
                $sort_type = $request->get('sorttype');
                $search_query = $request->get('query');
                $search_type = $request->get('search_type');

                $data = $data->when(
                    !empty($search_query) && !empty($search_type),
                    function ($query) use ($search_query, $search_type) {
                        if ($search_type == 'main_invoice_no') {
                            $query->whereHas('getSaleInvoice', function ($contacts) use ($search_query) {
                                $contacts->where('main_invoice_no', 'like', '%' . $search_query . '%');
                            });
                        } else if ($search_type == 'patient_name') {
                            $query->whereHas('getSaleInvoice.getPatient', function ($contacts) use ($search_query) {
                                $contacts->where('name', 'like', '%' . $search_query . '%');
                            });
                        } else if ($search_type == 'dr_name') {
                            $query->whereHas('getSaleInvoice.getDoctor', function ($contacts) use ($search_query) {
                                $contacts->where('name', 'like', '%' . $search_query . '%');
                            });
                        } else if ($search_type == 'invoice_batch_no') {
                            $query->where('invoice_batch_no', 'like', '%' . $search_query . '%');
                        }
                    }
                )->groupBy('sale_invoice_batches.id')->paginate($sort_by);

                $voucher_types   = VoucherType::with('voucherSeries')->where(['status' => 1])->get();

                return view('ipd-billings.table', compact('data', 'ipd_id','voucher_type','voucher_types'));
            } else {
                $data = SaleInvoiceBatch::select('sale_invoice_batches.*','sale_invoices.id as sale_invoice_id','users.prepared_by')
                    ->leftjoin('sale_invoices','sale_invoices.id','sale_invoice_batches.invoice_id')
                    ->leftjoin('users','users.id','sale_invoices.operator_id')
                    ->whereNull('sale_invoices.deleted_at')
                    ->where('voucher_type_code', 'IPD_ADMISSION')
                    ->groupBy('sale_invoice_batches.id')
                    ->latest()
                    ->paginate(10);

                return view('ipd-billings.index', compact('data', 'ipd_id','id'));
            }
        }
    }


    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create($id)
    {
        // PATIENT DETAILS
        $admission_details = IpdAdmission::select('ipd_admissions.patient_id','ipd_consultant_histories.doctor_id')
            ->leftjoin('ipd_consultant_histories', function($join) {
                $join->on('ipd_consultant_histories.ipd_admission_id', 'ipd_admissions.id')
                    ->where('ipd_consultant_histories.is_main_dr', 1);
            })
            ->find($id);

        $patient_details   = Account::select('name', 'account_title_id', 'id', 'code')
            ->where('id', $admission_details->patient_id)
            ->with('account_contact', 'account_title')->first();
        $doctor_details = [];

        if (isset($admission_details->doctor_id) && $admission_details->doctor_id != '') {
            $doctor_details = Account::getAccount([
                'account_types.type_code' => 'DOCTOR',
                'accounts.id' => $admission_details->doctor_id
            ]);

            if (isset($doctor_details)) {
                $doctor_details->full_name = $doctor_details->name .
                    ($doctor_details->code   != '' ? ', ' . $doctor_details->code : '') .
                    ($doctor_details->gender != '' ? ', ' . $doctor_details->gender : '') .
                    ($doctor_details->age    != '' ? ', ' . $doctor_details->age . ' yrs' : '');
            }
        }

        $ipd_id          = $id;
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode     = $country_code->country_code ?? 'us';
        $productCategory = ProductCategory::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();
        $data            = \Session::get('ipd_billing_products_cart') ?? [];
        $patient         = $doctor = $collection_agent = $refferal_lab = '';

        if (!empty($data) && isset($data['patient_id']) && $data['patient_id'] != '') {
            $patient = Account::getAccount([
                'account_types.type_code' => 'PATIENT',
                'accounts.id' => $data['patient_id']
            ]);
            if (isset($patient)) {
                $patient->full_name = $patient->name .
                    ($patient->code   != '' ? ', ' . $patient->code : '') .
                    ($patient->gender != '' ? ', ' . $patient->gender : '') .
                    ($patient->age    != '' ? ', ' . $patient->age . ' yrs' : '');
            }
        }

        if (!empty($data) && isset($data['doctor_id']) && $data['doctor_id'] != '') {
            $doctor = Account::getAccount([
                'account_types.type_code' => 'DOCTOR',
                'accounts.id' => $data['doctor_id']
            ]);
            if (isset($doctor)) {
                $doctor->full_name = $doctor->name .
                    ($doctor->code   != '' ? ', ' . $doctor->code : '') .
                    ($doctor->gender != '' ? ', ' . $doctor->gender : '') .
                    ($doctor->age    != '' ? ', ' . $doctor->age . ' yrs' : '');
            }
        }

        if (!empty($data) && isset($data['collection_id']) && $data['collection_id'] != '') {
            $collection_agent = Account::getAccount([
                'account_types.type_code' => 'COLLECTION_AGENT',
                'accounts.id' => $data['collection_id']
            ]);
            if (isset($collection_agent)) {
                $collection_agent->full_name = $collection_agent->name .
                    ($collection_agent->code   != '' ? ', ' . $collection_agent->code : '') .
                    ($collection_agent->gender != '' ? ', ' . $collection_agent->gender : '') .
                    ($collection_agent->age    != '' ? ', ' . $collection_agent->age . ' yrs' : '');
            }
        }

        if (!empty($data) && isset($data['refferal_id']) && $data['refferal_id'] != '') {
            $refferal_lab = Account::getAccount([
                'account_types.type_code' => 'REFERRAL_LABORATORY',
                'accounts.id'             => $data['refferal_id']
            ]);
            if (isset($refferal_lab)) {
                $refferal_lab->full_name = $refferal_lab->name .
                    ($refferal_lab->code   != '' ? ', ' . $refferal_lab->code : '') .
                    ($refferal_lab->gender != '' ? ', ' . $refferal_lab->gender : '') .
                    ($refferal_lab->age    != '' ? ', ' . $refferal_lab->age . ' yrs' : '');
            }
        }
        $voucher_master = VoucherMaster::with('voucherAllType')->select('id','tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
        return view('ipd-billings.create', compact(
            'productCategory',
            'doctor_details',
            'doctor',
            'patient',
            'countryCode',
            'refferal_lab',
            'collection_agent',
            'patient_details',
            'ipd_id',
            'voucher_master'
        ));
    }

    // public function AddMore($id, Request $request)
    // {
    //     // Retrieve ipd_admission_id from query parameters
    //     $ipd_admission_id = $request->query('ipd_admission_id');

    //     // PATIENT DETAILS
    //     $admission_details = IpdAdmission::where('patient_id', $id)->first();
    //     $patient_details = Account::select('name', 'account_title_id', 'id', 'code')
    //         ->where('id', $admission_details->patient_id)
    //         ->with('account_contact', 'account_title')->first();

    //     $ipd_id = $id;
    //     $company_address = \Session::get('company_data')['companies_addresses'];
    //     $countryCode = $country_code->country_code ?? 'us';

    //     $brands = ProductBrand::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();
    //     $data = \Session::get('ipd_billing_products_cart') ?? [];

    //     $patient = $doctor = $collection_agent = $refferal_lab = '';

    //     if (!empty($data)) {
    //         if (isset($data['patient_id']) && $data['patient_id'] != '') {
    //             $patient = Account::getAccount([
    //                 'account_types.type_code' => 'PATIENT',
    //                 'accounts.id' => $data['patient_id']
    //             ]);
    //             if ($patient) {
    //                 $patient->full_name = $patient->name .
    //                     ($patient->code ? ', ' . $patient->code : '') .
    //                     ($patient->gender ? ', ' . $patient->gender : '') .
    //                     ($patient->age ? ', ' . $patient->age . ' yrs' : '');
    //             }
    //         } else {
    //             $data['patient_id'] = $id;
    //         }

    //         if (isset($data['doctor_id']) && $data['doctor_id'] != '') {
    //             $doctor = Account::getAccount([
    //                 'account_types.type_code' => 'DOCTOR',
    //                 'accounts.id' => $data['doctor_id']
    //             ]);
    //             if ($doctor) {
    //                 $doctor->full_name = $doctor->name .
    //                     ($doctor->code ? ', ' . $doctor->code : '') .
    //                     ($doctor->gender ? ', ' . $doctor->gender : '') .
    //                     ($doctor->age ? ', ' . $doctor->age . ' yrs' : '');
    //             }
    //         }

    //         if (isset($data['collection_id']) && $data['collection_id'] != '') {
    //             $collection_agent = Account::getAccount([
    //                 'account_types.type_code' => 'COLLECTION_AGENT',
    //                 'accounts.id' => $data['collection_id']
    //             ]);
    //             if ($collection_agent) {
    //                 $collection_agent->full_name = $collection_agent->name .
    //                     ($collection_agent->code ? ', ' . $collection_agent->code : '') .
    //                     ($collection_agent->gender ? ', ' . $collection_agent->gender : '') .
    //                     ($collection_agent->age ? ', ' . $collection_agent->age . ' yrs' : '');
    //             }
    //         }

    //         if (isset($data['refferal_id']) && $data['refferal_id'] != '') {
    //             $refferal_lab = Account::getAccount([
    //                 'account_types.type_code' => 'REFERRAL_LABORATORY',
    //                 'accounts.id' => $data['refferal_id']
    //             ]);
    //             if ($refferal_lab) {
    //                 $refferal_lab->full_name = $refferal_lab->name .
    //                     ($refferal_lab->code ? ', ' . $refferal_lab->code : '') .
    //                     ($refferal_lab->gender ? ', ' . $refferal_lab->gender : '') .
    //                     ($refferal_lab->age ? ', ' . $refferal_lab->age . ' yrs' : '');
    //             }
    //         }
    //     } else {
    //         $data['patient_id'] = $id;
    //     }

    //     $data = array_merge([
    //         'patient_id'          => $request->patient_id ?? $id,
    //         'doctor_id'           => $request->doctor_id ?? '',
    //         'refferal_id'         => $request->refferal_id ?? '',
    //         'collection_id'       => $request->collection_id ?? '',
    //         'amount'              => 0,
    //         'special_discount'    => 0,
    //         'amount_recieved'     => 0,
    //         'due_balance_amount'  => 0,
    //         'discount_type'       => 'FLAT',
    //         'sample_receive_time' => date('H:i:s'),
    //         'invoice_date'        => date('Y-m-d'),
    //         'sample_receive_date' => date('Y-m-d')
    //     ], $data);

    //     $saleInvoiceDetails = SaleInvoiceDetail::whereIn('product_id', [181, 182, 183])->get();
    //     $product_ids = $saleInvoiceDetails->pluck('product_id')->toArray();
    //     // Fetch bed details and store in session
    //     $bed_history_details = IpdBedHistory::select(
    //         'products.*',
    //         'product_prices.sale_price as sale_price',
    //         'product_brands.name as brand_name',
    //         'tax_masters.total_percentage as total_percentage',
    //         'beds.id as bed_id'
    //     )
    //     ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
    //     ->leftJoin('bed_types', 'beds.bed_type_id', '=', 'bed_types.id')
    //     ->leftJoin('products', 'bed_types.product_id', '=', 'products.id')
    //     ->leftJoin('product_prices', 'product_prices.product_id', '=', 'products.id')
    //     ->leftJoin('product_brands', 'products.brand_id', '=', 'product_brands.id')
    //     ->leftJoin('tax_masters', 'products.tax_slab_id', '=', 'tax_masters.id')
    //     ->where('ipd_bed_histories.ipd_admission_id', $ipd_admission_id)
    //     ->where('ipd_bed_histories.bill_status', 0)
    //     ->whereNotIn('products.id', function($query) use ($ipd_admission_id) {
    //         $query->select('products.id')
    //             ->from('ipd_bed_histories')
    //             ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
    //             ->leftJoin('bed_types', 'beds.bed_type_id', '=', 'bed_types.id')
    //             ->leftJoin('products', 'bed_types.product_id', '=', 'products.id')
    //             ->where('ipd_bed_histories.ipd_admission_id', $ipd_admission_id)
    //             ->where('ipd_bed_histories.bill_status', 1);
    //     })
    //     ->get()
    //     ->toArray();

    //     // Extract product IDs from current session data
    //     $existing_product_ids = array_column($data['products'] ?? [], 'product_id');

    //     foreach ($bed_history_details as $detail) {
    //         // Only add product if it's not already in the session
    //         if (!in_array($detail['id'], $existing_product_ids)) {
    //             $data['products'][] = [
    //                 'brand_id'        => $detail['brand_id'] ?? '',
    //                 'price_id'        => $detail['product_price_id'] ?? '',
    //                 'product_id'      => $detail['id'] ?? '',
    //                 'product'         => $detail['name'] ?? '',
    //                 'hsncode'         => $detail['hsncode'] ?? '',
    //                 'brand'           => $detail['brand_name'] ?? '',
    //                 'product_price'   => $detail['sale_price'] ?? '0',
    //                 'flat_discount'   => $detail['discount_amount'] ?? '0',
    //                 'per_discount'    => $detail['discount_percentage'] ?? '0',
    //                 'product_details' => $detail['item_details'] ?? '',
    //                 'vial_code'       => '',
    //                 'amount'          => $detail['sale_price'] ?? '0',
    //                 'main_qty'        => $detail['main_qty'] ?? '1',
    //                 'tax_per'         => $detail['total_percentage'],
    //                 'tax_flat'        => $tax ?? 0,
    //             ];

    //             $data['amount'] += $detail['sale_price'] ?? 0;
    //             $data['due_balance_amount'] += $detail['sale_price'] ?? 0;
    //         }
    //         // dd($data);
    //     }

    //     $data['due_balance_amount'] = $data['amount'] - $data['amount_recieved'];
    //     // dd($data);
    //     \Session::put('ipd_billing_products_cart', $data);

    //     return view('ipd-billings.create', compact(
    //         'brands',
    //         'doctor',
    //         'patient',
    //         'countryCode',
    //         'refferal_lab',
    //         'collection_agent',
    //         'patient_details',
    //         'ipd_id'
    //     ));
    // }

    //new work
    public function AddMore($id, Request $request)
    {
        
        \Session::forget('ipd_billing_products_cart');
        
        // Retrieve ipd_admission_id from query parameters
        $ipd_admission_id = $request->ipd_admission_id;
        $bill_type        = $request->bill_type;

        // PATIENT DETAILS
        $admission_details = IpdAdmission::select('ipd_admissions.patient_id','ipd_consultant_histories.doctor_id')
            ->leftjoin('ipd_consultant_histories', function($join) {
                $join->on('ipd_consultant_histories.ipd_admission_id', 'ipd_admissions.id')
                    ->where('ipd_consultant_histories.is_main_dr', 1);
            })
            ->where('ipd_admissions.id', $id)->first();


        if (!$admission_details) {
            return redirect()->back()->with('error', 'IPD Admission not found!');
        }

        $patient_details = Account::select('name', 'account_title_id', 'id', 'code')
            ->where('id', $admission_details->patient_id)
            ->with('account_contact', 'account_title')->first();

        $ipd_id = $id;
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode = $country_code->country_code ?? 'us';

        $brands = ProductBrand::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();
        $data = \Session::get('ipd_billing_products_cart') ?? [];

        $patient = $doctor = $collection_agent = $refferal_lab = '';

        if (!empty($data)) {
            if (isset($data['patient_id']) && $data['patient_id'] != '') {
                $patient = Account::getAccount([
                    'account_types.type_code' => 'PATIENT',
                    'accounts.id' => $data['patient_id']
                ]);
                if ($patient) {
                    $patient->full_name = $patient->name .
                        ($patient->code ? ', ' . $patient->code : '') .
                        ($patient->gender ? ', ' . $patient->gender : '') .
                        ($patient->age ? ', ' . $patient->age . ' yrs' : '');
                }
            } else {
                $data['patient_id'] = $admission_details->patient_id;
            }

            if (isset($data['doctor_id']) && $data['doctor_id'] != '') {
                $doctor = Account::getAccount([
                    'account_types.type_code' => 'DOCTOR',
                    'accounts.id' => $data['doctor_id']
                ]);
                if ($doctor) {
                    $doctor->full_name = $doctor->name .
                        ($doctor->code ? ', ' . $doctor->code : '') .
                        ($doctor->gender ? ', ' . $doctor->gender : '') .
                        ($doctor->age ? ', ' . $doctor->age . ' yrs' : '');
                }
            }

            if (isset($data['collection_id']) && $data['collection_id'] != '') {
                $collection_agent = Account::getAccount([
                    'account_types.type_code' => 'COLLECTION_AGENT',
                    'accounts.id' => $data['collection_id']
                ]);
                if ($collection_agent) {
                    $collection_agent->full_name = $collection_agent->name .
                        ($collection_agent->code ? ', ' . $collection_agent->code : '') .
                        ($collection_agent->gender ? ', ' . $collection_agent->gender : '') .
                        ($collection_agent->age ? ', ' . $collection_agent->age . ' yrs' : '');
                }
            }

            if (isset($data['refferal_id']) && $data['refferal_id'] != '') {
                $refferal_lab = Account::getAccount([
                    'account_types.type_code' => 'REFERRAL_LABORATORY',
                    'accounts.id' => $data['refferal_id']
                ]);
                if ($refferal_lab) {
                    $refferal_lab->full_name = $refferal_lab->name .
                        ($refferal_lab->code ? ', ' . $refferal_lab->code : '') .
                        ($refferal_lab->gender ? ', ' . $refferal_lab->gender : '') .
                        ($refferal_lab->age ? ', ' . $refferal_lab->age . ' yrs' : '');
                }
            }
        } else {
            $data['patient_id'] = $admission_details->patient_id;
        }

        $data = array_merge([
            'patient_id'          => $request->patient_id ?? $admission_details->patient_id,
            'doctor_id'           => $request->doctor_id ?? '',
            'refferal_id'         => $request->refferal_id ?? '',
            'collection_id'       => $request->collection_id ?? '',
            'voucher_type_id'     => '',
            'amount'              => 0,
            'special_discount'    => 0,
            'amount_recieved'     => 0,
            'due_balance_amount'  => 0,
            'discount_type'       => 'FLAT',
            'sample_receive_time' => date('H:i:s'),
            'invoice_date'        => date('Y-m-d'),
            'sample_receive_date' => date('Y-m-d')
        ], $data);

        $saleInvoiceDetails = SaleInvoiceDetail::whereIn('product_id', [181, 182, 183])->get();
        $product_ids        = $saleInvoiceDetails->pluck('product_id')->toArray();

        $productCategory    = ProductCategory::get();

        // Fetch bed details and store in session
        $bed_history_details = IpdBedHistory::select(
            'products.*',
            'product_prices.sale_price as sale_price',
            'product_prices.batch',
            'product_brands.name as brand_name',
            'tax_masters.total_percentage as total_percentage',
            'beds.id as bed_id',
            'ipd_bed_histories.check_in_date_time',
            'ipd_bed_histories.check_out_date_time',
            'ipd_bed_histories.full_days',
            'ipd_bed_histories.half_days',
            'tax_masters.name as tax'
        )
        ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
        ->leftJoin('bed_types', 'beds.bed_type_id', '=', 'bed_types.id')
        ->leftJoin('products', 'bed_types.product_id', '=', 'products.id')
        ->leftJoin('product_prices', 'product_prices.product_id', '=', 'products.id')
        ->leftJoin('product_brands', 'products.brand_id', '=', 'product_brands.id')
        ->leftJoin('tax_masters', 'products.tax_slab_id', '=', 'tax_masters.id')
        ->where('ipd_bed_histories.ipd_admission_id', $ipd_admission_id)
        ->where('ipd_bed_histories.bill_status', 0)
        ->whereNotIn('products.id', function($query) use ($ipd_admission_id) {
            $query->select('products.id')
                ->from('ipd_bed_histories')
                ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
                ->leftJoin('bed_types', 'beds.bed_type_id', '=', 'bed_types.id')
                ->leftJoin('products', 'bed_types.product_id', '=', 'products.id')
                ->where('ipd_bed_histories.ipd_admission_id', $ipd_admission_id)
                ->where('ipd_bed_histories.bill_status', 1);
        })
        ->get()
        ->toArray();
        // Extract product IDs from current session data
        $existing_product_ids = array_column($data['products'] ?? [], 'product_id');
        $totalHalfDay         = 0;
        $totalFullDay         = 0;

        $productMrp    = 0;
        $ActualRateAfterTax = 0;
        $ActualRateBeforeTax = 0;
        $totalAmount = 0;
        foreach ($bed_history_details as $detail) {
            // Only add product if it's not already in the session
            if (!in_array($detail['id'], $existing_product_ids)) {

                $checkin  = Carbon::parse($detail['check_in_date_time']);
                $checkout = !empty($detail['check_out_date_time']) ? Carbon::parse($detail['check_out_date_time']) : Carbon::now();
                $quantity = $checkin->diffInDays($checkout);

                $totalHalfDay = $detail['half_days']*0.5;
                $totalFullDay = $detail['full_days'];
                $totalDays    = $totalFullDay + $totalHalfDay;
                if($totalDays>0)
                {
                    $quantity = $totalDays;
                }
                else
                {
                    $quantity = (int)$quantity + 1;
                }

                // $tax_per = $detail['tax'] == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $detail['tax']);
                // $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
                // if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                //     $tax          = ($tax_per / 100) * $detail['sale_price'] * $quantity; //(12/100)*1000;
                //     $productMrp   = $detail['sale_price'] * $quantity + $tax;  // 1000+
                //     $basic_amount = $detail['sale_price'];  //1000
                // } else {
                //     $basic_amount = $detail['sale_price'] / (($tax_per + 100) / 100);
                //     $basePrice    = $detail['sale_price'] * $quantity / (1 + ($tax_per / 100));
                //     $tax          = $detail['sale_price'] * $quantity - $basePrice;
                //     $productMrp   = $detail['sale_price'] * $quantity;
                // }


                // $data['products'][] = [
                //     'brand_id'        => $detail['brand_id'] ?? '',
                //     'price_id'        => $detail['product_price_id'] ?? '',
                //     'product_id'      => $detail['id'] ?? '',
                //     'product'         => $detail['name'] ?? '',
                //     'hsncode'         => $detail['hsncode'] ?? '',
                //     'brand'           => $detail['brand_name'] ?? '',
                //     'product_price'   => $basic_amount ?? '0',
                //     'flat_discount'   => $detail['discount_amount'] ?? '0',
                //     'per_discount'    => $detail['discount_percentage'] ?? '0',
                //     'product_details' => $detail['item_details'] ?? '',
                //     'vial_code'       => '',
                //     'amount'          => ($productMrp) ?? '0',
                //     'main_qty'        => $quantity ?? '1',
                //     'tax_per'         => $detail['total_percentage'],
                //     'tax_flat'        => $tax ?? 0,
                //     'bill_type'       => 'bed',
                //     'product_mrp'     => $detail['sale_price'],
                //     'batch'           => $detail['batch']??'',
                // ];

                // $data['amount']             += $productMrp;
                // $data['due_balance_amount'] += $productMrp;



                $product_price = $detail['sale_price'];
                $main_qty      = $quantity > 0 ? $quantity : 1;
                $loose_qty     = 0;
                $flat_discount = $detail['discount_amount'] ?? '0';
                $per_discount  = $detail['discount_percentage'] ?? '0';
                $amount = '0';
        
                if ($product_price > 0) {
                    if ($flat_discount != '' && $flat_discount != 0) {
                        $per_discount  = $flat_discount / ($product_price * $quantity) * 100;
        
                        $flat_discount = (($per_discount / 100) * $product_price) * $quantity;
                        $flat_per_discount = (($per_discount / 100) * $product_price);
                        $per_discount  = $per_discount;
                        $amount        = $product_price - $flat_per_discount;
                    } else if ($per_discount != '' && $per_discount != 0) {
                        $flat_discount = (($per_discount / 100) * $product_price) * $quantity;
                        $flat_per_discount = (($per_discount / 100) * $product_price);
                        $per_discount  = $per_discount;
                        $amount        = $product_price - $flat_per_discount;
                    } else {
                        $amount        = $product_price;
                    }
                }
        
        
        
               
                $product_price = $amount ?? $product_price;
        
                $main_qty_amount = $main_qty * $product_price;
                $product_price  = number_format($product_price, 2, '.', '');
    
        
                $tax_per = $detail['tax'] == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $detail['tax']);
        
        
                $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
        
                if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                    $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
                    $productMrp      = ($product_price + $tax) * $main_qty;  // 1000+
                    $basic_amount    = $detail['sale_price'];  //1000
                    $ActualRateAfterTax = $product_price + $tax;
                    $ActualRateBeforeTax = $product_price * $main_qty;
                    $totalTax = $tax * $main_qty;
                } else {
                    $basic_amount    = $detail['sale_price'] / (($tax_per + 100) / 100);
                    $basePrice       = $product_price / (1 + ($tax_per / 100));
                    $tax             = $product_price - $basePrice;
                    $productMrp      = $product_price * $main_qty;
                    $ActualRateAfterTax = $product_price - $tax;
                    $ActualRateBeforeTax = $ActualRateAfterTax * $main_qty;
                    $totalTax = $tax * $main_qty;
                }
        
        
        
                $basic_amount      = number_format($basic_amount, 2, '.', '');
                $flat_discount     = number_format($flat_discount, 2, '.', '');
                $per_discount      = number_format($per_discount, 2, '.', '');
                $tax               = number_format($tax, 2, '.', '');

                $data_amount                = $data['amount'] ?? 0;
                $data['amount']             = $data_amount + $productMrp;
                $data['due_balance_amount'] = number_format($data['amount'], 2, '.', '');
        
                $data['products'][] = [
                    'brand_id'       => $detail['brand_id'] ?? '',
                    'main_qty'       => $quantity ?? 1,
                    'loose_qty'      => 0,
                    'free_qty'       => 0,
                    'product_details'=> $detail['item_details'] ?? '',
                    'price_id'       => $detail['product_price_id'] ?? '',
                    'product_id'     => $detail['id'] ?? '',
                    'product'        => $detail['name'] ?? '',
                    'hsncode'        => $detail['hsncode'] ?? '',
                    'brand'          => $detail['brand_name'] ?? '',
                    'batch'          => $detail['batch']??'' ?? '',
                    'product_price'  => convertDecimelPoint($basic_amount) ?? '',
                    'flat_discount'  => $flat_discount ?? '',
                    'per_discount'   => $per_discount ?? '',
                    'vial_code'      => '',
                    'amount'         => $productMrp ?? '',
                    'tax_per'        => $tax_per,
                    'bill_type'      => 'bed',
                    'tax_flat'       => convertDecimelPoint($totalTax),
                    'product_mrp'    => convertDecimelPoint($ActualRateAfterTax) ?? '',
                    'product_basic'  => convertDecimelPoint($ActualRateBeforeTax) ?? '',
                    'expiry_date'    => isset($request->expiry_date) && $request->expiry_date ? date('M-Y', strtotime($request->expiry_date)) : '',
                ];
            }
        }

        $doctor_details = [];

        if (isset($admission_details->doctor_id) && $admission_details->doctor_id != '') {
            $doctor_details = Account::getAccount([
                'account_types.type_code' => 'DOCTOR',
                'accounts.id' => $admission_details->doctor_id
            ]);

            if (isset($doctor_details)) {
                $doctor_details->full_name = $doctor_details->name .
                    ($doctor_details->code   != '' ? ', ' . $doctor_details->code : '') .
                    ($doctor_details->gender != '' ? ', ' . $doctor_details->gender : '') .
                    ($doctor_details->age    != '' ? ', ' . $doctor_details->age . ' yrs' : '');
            }
        }

        $data['due_balance_amount'] = $data['amount'] - $data['amount_recieved'];
        \Session::put('ipd_billing_products_cart', $data);
        $voucher_master = VoucherMaster::with('voucherAllType')->select('id','tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();

        return view('ipd-billings.create', compact(
            'bill_type',
            'ipd_admission_id',
            'brands',
            'doctor',
            'patient',
            'countryCode',
            'refferal_lab',
            'collection_agent',
            'patient_details',
            'productCategory',
            'doctor_details',
            'ipd_id',
            'voucher_master'
        ));
    }



    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function billing($id,Request $request)
    {
        $ipd_admission_id = $request->input('ipd_admission_id')??$id;
        $data = \Session::get('ipd_billing_products_cart') ?? [];
        if(isset($data['amount']))
        {
            $data['amount'] = round($data['amount']);
            \Session::put('ipd_billing_products_cart', $data);
        }
           
        $data = \Session::get('ipd_billing_products_cart') ?? [];
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        if (empty($data) || !isset($data['products']) || count($data['products']) < 1) {
            $data = [];
            \Session::put('ipd_billing_products_cart', $data);

            return redirect()->route('ipd-billings.create', $id)->with('error', 'No product added in cart!');
        }
        
        $ids   = [];
        $ids[] = $data['doctor_id'] ?? 0;
        $ids[] = $data['patient_id'] ?? 0;
        $ids[] = $data['refferal_id'] ?? 0;
        $ids[] = $data['collection_id'] ?? 0;

        $accounts = Account::select([
            'accounts.id',
            'accounts.account_type_id',
            'account_types.type_code',
            \DB::raw("CONCAT(account_titles.name, ' ', accounts.name) as name"),
            \DB::raw("account_contacts.phone_no as phone_no"),
            \DB::raw("genders.name as gender"),
            \DB::raw("account_contacts.date_of_birth")
        ])
            ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
            ->leftJoin('account_titles', 'account_titles.id', '=', 'accounts.account_title_id')
            ->leftJoin('genders', 'genders.id', '=', 'account_contacts.account_gender_id')
            ->leftjoin('account_types', 'account_types.id', 'accounts.account_type_id')
            ->whereIn('accounts.id', $ids)
            ->get();
            // dd( $accounts);

        if (empty($accounts) || count($accounts) < 1) {
            $data = [];

            return redirect()->route('ipd-billing.create', $id)->with('error', 'Empty cart!');
            // return redirect()->back()->with('error', 'Empty cart!!');
        }

        $doctors          = [];
        $patients         = [];
        $refferal_lab     = [];
        $collection_agent = [];

        foreach ($accounts as $item) {
            if ($item['type_code'] == 'PATIENT') {
                $patients = $item;
            } elseif ($item['type_code'] == 'DOCTOR') {
                $doctors = $item;
            } elseif ($item['type_code'] == 'REFERRAL_LABORATORY') {
                $refferal_lab = $item;
            } elseif ($item['type_code'] == 'COLLECTION_AGENT') {
                $collection_agent = $item;
            }
        }

        $payment_types  = PaymentTerm::select(['id', 'is_default', 'payment_term_name'])
            ->orderBy('priority', 'ASC')
            ->get();

        $special_cases    = SpecialCase::select(['id', 'name'])->orderBy('priority', 'ASC')->get();
        $voucher_master   = VoucherMaster::select(['id', 'voucher_name'])->where('status', 1)->get();
        $bussiness_source = EnquirySource::select(['id', 'enquiry_source_name', 'default'])->where('status', '1')->get();

        $accounting_group = Account::select(['id', 'name', 'account_category_id', 'accounting_group_id'])
            ->with('chart_of_account_sub_type')
            ->where(function ($query) {
                $query->whereHas('chart_of_account_sub_type', function ($accounting_group) {
                    $accounting_group->where('is_payment_mode', '1');
                });
            })
            ->get();

        $ipd_id = $id;

        $discount_group = Account::where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::where(['code' => 'ROUN_OFF'])->first();

        return view('ipd-billings.billing', compact([
            'data',
            'doctors',
            'patients',
            'refferal_lab',
            'voucher_master',
            'collection_agent',
            'bussiness_source',
            'payment_types',
            'special_cases',
            'accounting_group',
            'ipd_id',
            'discount_group',
            'round_off',
            'ipd_admission_id',
            'companyDateFormate'
        ]));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
       
        $data = \Session::get('ipd_billing_products_cart') ?? [];
        if (empty($data)) {
            return redirect()->back()->with('error', 'Empty cart!');
        }

        $company_id = \Auth::user()->company_id ?? '';

        // $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'SALES')->first();
        // $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'IPD_INVOICE')->first();
        $voucher_master = DB::table('voucher_masters')
            ->join('voucher_series', 'voucher_masters.id', '=', 'voucher_series.voucher_master_id')
            ->select('voucher_masters.*', 'voucher_series.*')
            ->where('voucher_masters.voucher_code', 'SALES')
            ->where('voucher_series.series_name', 'IPD')
            ->first();

            $voucher_type = VoucherType::whereHas('voucherSeries', function ($query) {
                $query->where('code', 'IPD_ADMISSION');
            })->where('code', 'IPD_ADMISSION')->first();

        # last voucher count for main voucher type invoice number
        $voucher_type_last_count = SaleInvoice::select('last_voucher_type_count')->where('voucher_type_code','IPD_ADMISSION')->orderBy('created_at', 'DESC')->first();
        $voucher_type_count      = isset($voucher_type_last_count) && isset($voucher_type_last_count->last_voucher_type_count) ? $voucher_type_last_count->last_voucher_type_count + 1 : ($voucher_type->start_from + 1 ?? 1);

        $voucher_type_invoice_no = $this->generateCode(
            $voucher_type_count,
            ($voucher_type->voucherSeries->prefix ?? 'IPD'),
            ($voucher_type->voucherSeries->postfix ?? ''),
            ($voucher_type->voucherSeries->separator ?? '-'),
            ($voucher_type->voucherSeries->length ?? 5)
        );


         $ipdAdmissionData = IpdAdmission::select('sale_invoice_id')->find($request->ipd_admission_id);
        // if(isset($ipdAdmissionData->sale_invoice_id) && $ipdAdmissionData->sale_invoice_id!='')
        // {
             $existingInvoice = SaleInvoice::find($ipdAdmissionData->sale_invoice_id);
        // }
        // else
        // {
            // $existingInvoice = SaleInvoice::where('patient_id', $data['patient_id'])
            // ->where('invoice_type', 'ipd-billings')
            // ->first();
        // }
        // dd($existingInvoice);
       

        $invoice_date        = $request->invoice_date != '' ? date('Y-m-d H:i:s', strtotime($request->invoice_date.' '.date('H:i:s'))) : '';
        if ($existingInvoice) {
            $existingInvoice->update([
                'payment_term_id'         => $request->payment_term_id ?? '',
                'billing_amount'          => $data['amount'] + (int)$existingInvoice->billing_amount,
                'invoice_date'            => $invoice_date,
                'doctor_id'               => $data['doctor_id'],
                'collection_agent_id'     => $data['collection_id'],
                'refferal_lab_id'         => $data['refferal_id'],
                'reff_no'                 => $request->reff_no,
                'received_amount'         => $request->amount_recieved + $existingInvoice->received_amount,
                'due_amount'              => $data['due_balance_amount'] + $existingInvoice->due_amount,
                'sample_barcode'          => $request->sample_barcode,
                'sample_receive_date'     => $request->sample_receive_date,
                'sample_receive_time'     => $request->sample_receive_time,
                'remarks_for_technician'  => $request->remarks_for_technician,
                'remarks'                 => $request->sale_remarks,
                'special_case_id'         => $request->special_case,
                'discount_amount'         => $request->special_discount + $existingInvoice->discount_amount,
                'adjustment_type'         => $request->discount_type,
                'payment_mode_id'         => $request->payment_mode_id ?? '',
                'bussiness_source_id'     => $request->bussiness_source ?? '',
            ]);
        } else {
            $existingInvoice = [
                'voucher_type_code'       => ($voucher_type->code ?? ''),
                'payment_term_id'         => $request->payment_term_id ?? '',
                'billing_amount'          => $data['amount'],
                'invoice_date'            => $invoice_date,
                'patient_id'              => $data['patient_id'],
                'doctor_id'               => $data['doctor_id'] ?? '',
                'collection_agent_id'     => $data['collection_id'] ?? '',
                'refferal_lab_id'         => $data['refferal_id'] ?? '',
                'reff_no'                 => $request->reff_no,
                'received_amount'         => $request->amount_recieved ?? 0,
                'due_amount'              => $data['due_balance_amount'],
                'sample_barcode'          => $request->sample_barcode,
                'sample_receive_date'     => $request->sample_receive_date,
                'sample_receive_time'     => $request->sample_receive_time,
                'sale_delivery_status'    => 'PENDING',
                'company_id'              => $company_id,
                'status'                  => 'NEWSALE',
                'remarks_for_technician'  => $request->remarks_for_technician,
                'remarks'                 => $request->sale_remarks,
                'special_case_id'         => $request->special_case,
                'discount_amount'         => $request->special_discount,
                'adjustment_type'         => $request->discount_type,
                'financial_year_id'       => $this->financialyear(),
                'industry_type_id'        => 2, // pathology from business divisions.
                'operator_id'             => \Auth::ID(),
                'payment_mode_id'         => $request->payment_mode_id ?? '',
                'bussiness_source_id'     => $request->bussiness_source ?? '',
                'voucher_type_invoice_no' => $voucher_type_invoice_no,
                'last_voucher_type_count' => $voucher_type_count,
                'bill_to_account_id'      => $data['patient_id'],
                'invoice_type'            => 'ipd-billings'
            ];

            $existingInvoice = SaleInvoice::create($existingInvoice);


        }

        if(isset($request->ipd_admission_id))
        {
            $ipd_admission = IpdAdmission::where('id', $request->ipd_admission_id)->where('sale_invoice_id','=', null)->first();
        }
        else
        {
            $ipd_admission = IpdAdmission::where('patient_id', $data['patient_id'])->where('sale_invoice_id','=', null)->first();
        }
            
            if ($ipd_admission) {
                $ipd_admission->update([
                    'sale_invoice_id' => $existingInvoice->id,
                    // 'invoice_type'    => $voucher_type->code,
                ]);
            }

        /*********************  Spacial Discount Store Calculation ***********************/
        if ($request->special_discount > 0) {
            # last voucher count for main Transaction number
            $transaction_voucher_count      = AccountTransaction::select('last_id')->orderBy('created_at', 'DESC')->first();
            $transaction_voucher_master     = VoucherMaster::select('id')
                ->with('voucherSeries')
                ->where('voucher_code', 'TRANSACTION')
                ->where(['status' => 1])
                ->first();
            $last_voucher_count = isset($transaction_voucher_count) && isset($transaction_voucher_count->last_id) ?
                $transaction_voucher_count->last_id + 1 : ($transaction_voucher_master->voucherSeries->start_from + 1 ?? 1);

            $transactions_no = $this->generateCode(
                $last_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );
            $this->SaleOthersTransaction(
                $existingInvoice->id,
                $transactions_no,
                'IPD_INVOICE',
                $request->discount_account_id,
                $request->special_discount
            );
        }
        $discount['mode_id'] = $request->discount_account_id ?? '';
        $discount['amount']  = $request->special_discount ?? 0;
        /********************* End Spacial Discount Store Calculation ***********************/

        /*********************  Round Off Store Calculation ***********************/
        if ($request->round_off_amount > 0) {
            # last voucher count for main Transaction number
            $transaction_voucher_count      = AccountTransaction::select('last_id')->orderBy('created_at', 'DESC')->first();
            $transaction_voucher_master     = VoucherMaster::select('id')
                ->with('voucherSeries')
                ->where('voucher_code', 'TRANSACTION')
                ->where(['status' => 1])
                ->first();
            $last_voucher_count = isset($transaction_voucher_count) && isset($transaction_voucher_count->last_id) ?
                $transaction_voucher_count->last_id + 1 : ($transaction_voucher_master->voucherSeries->start_from + 1 ?? 1);

            $transactions_no = $this->generateCode(
                $last_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );
            $this->SaleOthersTransaction(
                $existingInvoice->id,
                $transactions_no,
                'IPD_INVOICE',
                $request->round_off_account_id,
                $request->round_off_amount
            );
        }
        $roundOff['mode_id'] = $request->round_off_account_id ?? '';
        $roundOff['amount'] = $request->round_off_amount ?? 0;
        /********************* End  Round Off Store Calculation ***********************/

        $task_status  = TaskStatus::where('is_default', '1')->first();

        //sale invoice batch generate number
        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'Sales_Invoice_Batch')->first();
        // $voucher_count_batch = SaleInvoiceBatch::select('last_voucher_count')->orderBy('last_voucher_count', 'desc')->first();
        // $account_exists = SaleInvoiceBatch::where('account_id',$data['patient_id'],)->exists();
        $year  = date('Y');
        $month = date('m');

        $voucher_count_batch = SaleInvoiceBatch::select(\DB::raw('MAX(last_voucher_count) as last_voucher_count'))
                ->whereYear('created_at', '=', $year)
                ->whereMonth('created_at', '=', $month)
                ->first();
        $year  = date('y');

        $last_voucher_count_batch = isset($voucher_count_batch) && isset($voucher_count_batch->last_voucher_count)? $voucher_count_batch->last_voucher_count + 1: ($voucher_master->voucherSeries->start_from + 1 ?? 1);

        $main_invoice_no = $this->generateCode(
            $last_voucher_count_batch,
            ($voucher_master->voucherSeries->prefix ?? 'BAT'),
            ($voucher_master->voucherSeries->postfix ?? ''),
            ($voucher_master->voucherSeries->separator ?? '-'),
            ($voucher_master->voucherSeries->length ?? 5),
            $year.$month
        );

        // $data['invoice_batch_no']   = $main_invoice_no;
        $data['last_voucher_count'] = $last_voucher_count_batch;

        $batchVoucherType = VoucherType::select(['id','code'])->find($data['voucher_type_id']);
        $invoice_batch = [
            'invoice_id'                => $existingInvoice->id,
            'invoice_batch_date'        => Carbon::now(),
            'invoice_batch_no'          => $main_invoice_no,
            'last_voucher_count'        => $last_voucher_count_batch,
            'account_id'                => $data['patient_id'],
            'created_by'                => Auth::user()->id,
            'consultant_id'             => $data['doctor_id'],
            'batch_status'              => 'NEWORDER',
            'referrence_voucher_type'   => $batchVoucherType->code??'',
        ];
      
        //sale invoice batch
        $invoice_batch    = SaleInvoiceBatch::create($invoice_batch);
        $ipd_admission_id = $request->ipd_admission_id ?? '';
        $bed_products     = [];

        $voucher_masters   = VoucherMaster::select('tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();

        foreach ($data['products'] as $key => $value) {
            $product = Product::where('id', $value['product_id'])
                ->with('getProductPrice')
                ->first();

            $item = [
                'sale_invoice_id'     => $existingInvoice->id,
                'product_id'          => $value['product_id'],
                'batch_id'            => $invoice_batch->id,
                'product_price_id'    => $value['price_id'],
                'price'               => $value['product_price'],
                'basic_amount'        => $value['product_basic'],
                'discount_percentage' => $value['per_discount'],
                'discount_amount'     => $value['flat_discount'],
                'total_amount'        => $value['amount'],
                'item_details'        => $value['product_details'],
                'item_batch'          => $value['batch'] ?? '',
                'tax_slab_id'         => $product->tax_slab_id ?? '',
                'main_qty'            => $value['main_qty'],
                'from_date_time'      => Carbon::now()->format('Y-m-d H:i:s'),
                'customer_amount'     => $value['amount']??0,
                'tax_calculation_type'=> $voucher_masters->tax_calculation??''
            ];

            if (!empty($ipd_admission_id) && isset($value['bill_type']) && $value['bill_type'] == 'bed') {
                $bed_products[] = $value['product_id'];
            }

            $existingInvoice_details = SaleInvoiceDetail::create($item);


             /**************Stock Out Function ********************/
            //  if($product->manage_stock=='Yes')
            //  {
            //     stockOut($existingInvoice->id,'IPD_INVOICE',$value['product_id'],$value['main_qty'],$value['product_price'],$product->getProductPrice->id,$invoice_batch->id);
            //  }
             


            $product_test_package = ProductTestPackage::where('product_id', $value['product_id'])->get();

            foreach ($product_test_package as $package) {
                SaleInvoiceSubDetails::create([
                    'sale_invoice_detail_id' => $existingInvoice_details->id,
                    'sale_invoice_id'        => $existingInvoice->id,
                    'data_referrence_id'     => $package->test_package_id,
                    'subdetails_remarks'     => '',
                    'referrence_type'        => 'LAB',
                    'status'                 => 'SAMPLE_COLLECTION',
                    'task_status_id'         => $task_status->id ?? '',
                    'review_status_id'       => $task_status->id ?? '',
                ]);
            }
        }


        /*********************basic Transaction Insert Into Account Transaction Table *******************/
        $this->createTransaction(
            'IPD_INVOICE',
            $existingInvoice->id,
            $invoice_batch->id,
            $voucher_type->code,
            $data['patient_id'],
            $data,
            $roundOff,
            $discount,
            $request->special_discount ?? 0
        );

        // if ($request->amount_recieved > 0) {
        //     $this->createAcReceiptAndTransaction(
        //         $request->payment_mode_id ?? '',
        //         $data['patient_id'],
        //         $request->amount_recieved,
        //         $transaction->id ?? '',
        //         $existingInvoice->id,
        //         'IPD_ADMISSION',
        //         $request->payment_mode,
        //         'received',
        //     );
        // }

        if (!empty($bed_products) && !empty($ipd_admission_id)) {
            $bed_history_details = IpdBedHistory::leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
                ->leftJoin('bed_types', 'beds.bed_type_id', '=', 'bed_types.id')
                ->leftJoin('products', 'bed_types.product_id', '=', 'products.id')
                ->where('ipd_bed_histories.ipd_admission_id', $ipd_admission_id)
                ->where('ipd_bed_histories.bill_status', 0)
                ->whereIn('bed_types.product_id', $bed_products)
                ->update(['bill_status' => 1, 'sale_invoice_batch_id' => $invoice_batch->id]);
            IpdAdmission::find($ipd_admission_id)->update(['bed_sale_invoice_batch_id'=>$invoice_batch->id]);
        }

        //$test = IpdBedHistory::where('ipd_admission_id', $request->input('ipd_admission_id'))->update(['bill_status' => 1]);
            // dd($test);
        \Session::forget('ipd_billing_products_cart');

        $params['id']       = $existingInvoice->id??'';
        $params['batch_id'] = $invoice_batch->id??'';
        return redirect()->route('ipd-new-invoice', $params)->with('success', "New Bill Created Successfully");

        // return redirect()->route('ipd-billings.index', $data['patient_id'])->with('success', "New Bill Created Successfully");
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode     = $country_code->country_code ?? 'us';

        $sale_invoice    = SaleInvoice::select('sale_invoices.*',
        'beds.name as bed_name', 'ipd_admissions.ipd_admission_no as admission_no','ipd_admissions.admission_date_time as admission_date_time' , 'voucher_type_invoice_no')
            ->with('getSaleInvoiceDetails')
            ->with('getSaleInvoiceSubDetail')
            ->with('getPatient')
            ->with('getDoctor')
            ->with('getCollectionAgent')
            ->with('getRefferalLab')
            ->with('getCompany')
            ->leftJoin('ipd_admissions', 'sale_invoices.id', '=', 'ipd_admissions.sale_invoice_id')
            ->leftJoin('ipd_bed_histories', 'ipd_admissions.id', '=', 'ipd_bed_histories.ipd_admission_id')
            ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
            ->find($id);

        return view('ipd-billings.show', compact(['sale_invoice', 'countryCode']));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id, $batch_id,Request $request)
    {
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode     = $country_code->country_code ?? 'us';
        $productCategory = ProductCategory::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();
        $brands          = ProductBrand::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();
        $salesInoiveBatch = SaleInvoiceBatch::with('getSaleInvoice')->with('getSaleInvoiceDetails')
            ->where(['invoice_id' => $id, 'id' => $batch_id])->first();
        $sale_invoice     = $salesInoiveBatch->getSaleInvoice;
        $voucherTypeCode  = $salesInoiveBatch->referrence_voucher_type??'';
        $batchVoucherType = VoucherType::select('id')->where(['code'=>$voucherTypeCode,'status'=>1])->first();
        $data             = [];
        $patient          = $doctor = $collection_agent = $refferal_lab = '';
        $ipd_id       = IpdAdmission::select('id', 'patient_id')->where('sale_invoice_id', '=', $sale_invoice->id)->first();
        if(isset($request->bill_type))
        {
            $this->updateBedMore($ipd_id->id,$request->bill_type,$request);
        }
        else
        {
            if ($sale_invoice) {
                $data['patient_id']             = $sale_invoice->patient_id;
                $data['doctor_id']              = $sale_invoice->doctor_id;
                $data['refferal_id']            = $sale_invoice->refferal_lab_id;
                $data['collection_id']          = $sale_invoice->collection_agent_id;
                $data['voucher_type_id']        = $batchVoucherType->id??'';
                $data['special_discount']       = $sale_invoice->discount_amount;
                $data['amount_recieved']        = $sale_invoice->received_amount;
                $data['due_balance_amount']     = $sale_invoice->due_amount;
                $data['discount_type']          = 'FLAT';
                $data['sample_receive_time']    = $sale_invoice->sample_receive_time;
                $data['invoice_date']           = $sale_invoice->invoice_date;
                $data['sample_receive_date']    = $sale_invoice->sample_receive_date;
                $data['payment_mode_id']        = $sale_invoice->payment_mode_id;
                $data['payment_term_id']        = $sale_invoice->payment_term_id;
                $data['special_case']           = $sale_invoice->special_case_id;
                $data['sample_barcode']         = $sale_invoice->sample_barcode;
                $data['reff_no']                = $sale_invoice->reff_no;
                $data['sale_remarks']           = $sale_invoice->remarks;
                $data['remarks_for_technician'] = $sale_invoice->remarks_for_technician;
                $totalBillingAmount             = 0;

                $saleVoucher = VoucherType::select(['default_price_type'])->where(['code'=>'IPD_INVOICE'])->first();
                if ($saleVoucher->default_price_type == 'MRP') {
                    $productPrice = 'product_prices.mrp as mrp';
                } elseif ($saleVoucher->default_price_type == 'Purchase Price') {
                    $productPrice = 'product_prices.purchase_price as mrp';
                } elseif ($saleVoucher->default_price_type == 'WholeSale Price') {
                    $productPrice = 'product_prices.wholesale_price as mrp';
                } elseif ($saleVoucher->default_price_type == 'Discounted/Sale Price(DP)') {
                    $productPrice = 'product_prices.sale_price as mrp';
                } elseif ($saleVoucher->default_price_type == 'Min. Sale Price') {
                    $productPrice = 'product_prices.min_sale_price as mrp';
                } elseif ($saleVoucher->default_price_type == 'Manufacturing Cost') {
                    $productPrice = 'product_prices.mfg_cost as mrp';
                }

                $productMrp    = 0;
                $ActualRateAfterTax = 0;
                $ActualRateBeforeTax = 0;
                $totalAmount = 0;

                foreach ($salesInoiveBatch->getSaleInvoiceDetails as $key => $value) {

                    $productPriceData = ProductPrice::select('exp_date',$productPrice)->find($value->product_price_id);

                    $product_price = $productPriceData->mrp??$value->price;
                    $flat_discount = 0;
                    $per_discount = $value->discount_percentage;

                    if ($product_price > 0) {
                        if ($flat_discount != '' && $flat_discount != 0) {
                            $per_discount  = ($flat_discount / $product_price) * 100;
                            $amount        = $product_price - $flat_discount;
                            $flat_discount = $flat_discount;
                        } else if ($per_discount != '' && $per_discount != 0) {
                            $flat_discount = ($per_discount / 100) * $product_price;
                            $per_discount  = $per_discount;
                            $amount        = $product_price - $flat_discount;
                        } else {
                            $amount        = $product_price;
                        }
                    }

                    $product_price = $amount ?? $product_price;


                    $totalAmount += $value->total_amount;
                    $main_qty = $value->main_qty > 0 ? $value->main_qty : ($value->alt_qty > 0 ? $value->alt_qty : 1);
                    $main_qty_amount = $main_qty * ($productPriceData->mrp??$value->price);

                    $tax_per = $value->getProduct->getTaxMaster->name != 'Tax Free' ? preg_replace('/[^0-9]/', '', $value->getProduct->getTaxMaster->name ?? 0,) : 0;

                    $tax  = (($tax_per ?? 0) / 100) * $main_qty_amount;

                    /*************** Tax Calculation ***************** **/
                    if ($value && $value->tax_calculation_type == 'EXCLUSIVE') {
                        $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
                        $productMrp      = ($product_price + $tax) * $main_qty;  // 1000+
                        $basic_amount    = ($productPriceData->mrp??$value->price);  //1000

                        $ActualRateAfterTax = $product_price + $tax;
                        $ActualRateBeforeTax = $product_price * $main_qty;
                        $totalTax = $tax * $main_qty;
                    } else {
                        $basic_amount    = ($productPriceData->mrp??$value->price) / (($tax_per + 100) / 100);
                        $basePrice       = $product_price / (1 + ($tax_per / 100));
                        $tax             = $product_price - $basePrice;
                        $productMrp      = $product_price * $main_qty;
                        $ActualRateAfterTax = $product_price - $tax;
                        $ActualRateBeforeTax = $ActualRateAfterTax * $main_qty;
                        $totalTax = $tax * $main_qty;
                    }

                    $data['products'][] = array(
                        'brand_id'        => $value->getProduct->brand_id ?? '',
                        'price_id'        => $value->product_price_id ?? '',
                        'product_id'      => $value->product_id ?? '',
                        'product'         => $value->getProduct->name ?? '',
                        'hsncode'         => $value->getProduct->hsncode ?? '',
                        'brand'           => $value->getProduct->getProductBrand->name ?? '',
                        'batch'           => $value->item_batch??'',
                        'product_price'   => convertDecimelPoint($basic_amount) ?? '0',
                        'flat_discount'   => $value->discount_amount ?? '0',
                        'per_discount'    => $value->discount_percentage ?? '0',
                        'product_details' => $value->item_details ?? '',
                        'vial_code'       => '',
                        'amount'          => convertDecimelPoint($productMrp) ?? '0',
                        'main_qty'        => $value->main_qty ?? '0',
                        'tax_per'         => $tax_per,
                        'tax_flat'        => $totalTax ?? 0,
                        'product_mrp'    => convertDecimelPoint($ActualRateAfterTax) ?? '',
                        'product_basic'  => convertDecimelPoint($ActualRateBeforeTax) ?? '',
                        'expiry_date'    => isset($productPriceData->exp_date) ? date('M-Y', strtotime($productPriceData->exp_date)) : '',
                    );
                    
                }

                $data['amount']                 = $totalAmount;
            }

            \Session::put('ipd_billing_products_cart', $data);
        }

        if ($sale_invoice && isset($sale_invoice->patient_id) && $sale_invoice->patient_id != '') {
            $patient = Account::getAccount([
                'account_types.type_code' => 'PATIENT',
                'accounts.id' => $sale_invoice->patient_id
            ]);
            if (isset($patient)) {
                $patient->full_name = $patient->name .
                    ($patient->code     != '' ? ', ' . $patient->code : '') .
                    ($patient->gender   != '' ? ', ' . $patient->gender : '') .
                    ($patient->age      != '' ? ', ' . $patient->age . ' yrs' : '') .
                    ($patient->phone_no != '' ? ', ' . $patient->phone_no : '');
            }
        }

        if ($sale_invoice && isset($sale_invoice->doctor_id) && $sale_invoice->doctor_id != '') {
            $doctor = Account::getAccount([
                'account_types.type_code' => 'DOCTOR',
                'accounts.id' => $sale_invoice->doctor_id
            ]);
            if (isset($doctor)) {
                $doctor->full_name = $doctor->name .
                    ($doctor->code     != '' ? ', ' . $doctor->code : '') .
                    ($doctor->gender   != '' ? ', ' . $doctor->gender : '') .
                    ($doctor->age      != '' ? ', ' . $doctor->age . ' yrs' : '') .
                    ($doctor->phone_no != '' ? ', ' . $doctor->phone_no : '');
            }
        }

        if ($sale_invoice && isset($sale_invoice->collection_id) && $sale_invoice->collection_id != '') {
            $collection_agent = Account::getAccount([
                'account_types.type_code' => 'COLLECTION_AGENT',
                'accounts.id' => $sale_invoice->collection_id
            ]);
            if (isset($collection_agent)) {
                $collection_agent->full_name = $collection_agent->name .
                    ($collection_agent->code     != '' ? ', ' . $collection_agent->code : '') .
                    ($collection_agent->gender   != '' ? ', ' . $collection_agent->gender : '') .
                    ($collection_agent->age      != '' ? ', ' . $collection_agent->age . ' yrs' : '') .
                    ($collection_agent->phone_no != '' ? ', ' . $collection_agent->phone_no : '');
            }
        }

        if ($sale_invoice && isset($sale_invoice->refferal_id) && $sale_invoice->refferal_id != '') {
            $refferal_lab = Account::getAccount([
                'account_types.type_code' => 'REFERRAL_PARTNER',
                'accounts.id' => $sale_invoice->refferal_id
            ]);
            if (isset($refferal_lab)) {
                $refferal_lab->full_name = $refferal_lab->name .
                    ($refferal_lab->code   != '' ? ', ' . $refferal_lab->code : '') .
                    ($refferal_lab->gender != '' ? ', ' . $refferal_lab->gender : '') .
                    ($refferal_lab->age    != '' ? ', ' . $refferal_lab->age . ' yrs' : '') .
                    ($refferal_lab->phone_no    != '' ? ', ' . $refferal_lab->phone_no : '');
            }
        }
        $voucher_master = VoucherMaster::with('voucherAllType')->select('id','tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
        return view('ipd-billings.edit.edit', compact(
            'ipd_id',
            'id',
            'batch_id',
            'brands',
            'doctor',
            'patient',
            'countryCode',
            'refferal_lab',
            'productCategory',
            'collection_agent',
            'voucher_master',
            'batchVoucherType'
        ));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function editBilling($id, $batch_id)
    {
        $sale_invoice = SaleInvoice::find($id);

        if (!$sale_invoice) {
            $data = [];
            \Session::put('ipd_billing_products_cart', $data);

            return redirect()->route('ipd-billings.index')->with('error', 'IPD billing invoice not found!');
        }

        $data = \Session::get('ipd_billing_products_cart') ?? [];

        if (empty($data) || !isset($data['products']) || count($data['products']) < 1) {
            $data = [];
            \Session::put('ipd_billing_products_cart', $data);

            return redirect()->route('ipd-billings.edit', [$id,$batch_id])->with('error', 'No product added in cart!');
        }

        $ids = [];

        $ids[] = $data['patient_id'] ?? 0;

        if (isset($data['doctor_id']) && $data['doctor_id'] != '') {
            $ids[] = $data['doctor_id'] ?? 0;
        }

        if (isset($data['refferal_id']) && $data['refferal_id'] != '') {
            $ids[] = $data['refferal_id'] ?? 0;
        }

        if (isset($data['collection_id']) && $data['collection_id'] != '') {
            $ids[] = $data['collection_id'] ?? 0;
        }

        $accounts = Account::select([
            'accounts.id',
            'accounts.account_type_id',
            'account_types.type_code',
            'account_contacts.phone_no as phone_no',
            \DB::raw("
                            CONCAT(
                                COALESCE(account_titles.name, ''),
                                CASE WHEN account_titles.name IS NOT NULL AND accounts.name IS NOT NULL THEN ' ' ELSE '' END,
                                COALESCE(accounts.name, '')
                            ) AS name
                            "),
            \DB::raw("account_contacts.phone_no as phone_no"),
            \DB::raw("genders.name as gender"),
            \DB::raw("account_contacts.date_of_birth")
        ])
            ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
            ->leftJoin('account_titles', 'account_titles.id', '=', 'accounts.account_title_id')
            ->leftJoin('genders', 'genders.id', '=', 'account_contacts.account_gender_id')
            ->leftjoin('account_types', 'account_types.id', 'accounts.account_type_id')
            ->whereIn('accounts.id', $ids)
            ->get();

        if (empty($accounts) || count($accounts) < 1) {
            $data = [];

            return redirect()->route('ipd-billings.create', $id)->with('error', 'Empty cart!');
        }

        $doctors          = [];
        $patients         = [];
        $refferal_lab     = [];
        $collection_agent = [];

        foreach ($accounts as $item) {
            if ($item['type_code'] == 'PATIENT') {
                $patients = $item;
            } elseif ($item['type_code'] == 'DOCTOR') {
                $doctors = $item;
            } elseif ($item['type_code'] == 'REFERRAL_PARTNER') {
                $refferal_lab = $item;
            } elseif ($item['type_code'] == 'COLLECTION_AGENT') {
                $collection_agent = $item;
            }
        }

        $payment_types  = PaymentTerm::select(['id', 'is_default', 'payment_term_name'])
            ->orderBy('priority', 'ASC')
            ->get();

        $special_cases    = SpecialCase::select(['id', 'name'])->orderBy('priority', 'ASC')->get();
        $voucher_master   = VoucherMaster::select(['id', 'voucher_name'])->where('status', 1)->get();
        $bussiness_source = EnquirySource::select(['id', 'enquiry_source_name', 'default'])->where('status', '1')->get();

        $accounting_group = Account::select(['id', 'name', 'account_category_id', 'accounting_group_id'])
            ->with('chart_of_account_sub_type')
            ->where(function ($query) {
                $query->whereHas('chart_of_account_sub_type', function ($accounting_group) {
                    $accounting_group->where('is_payment_mode', '1');
                });
            })
            ->get();
        $AcReceipt = AcReceipt::where('voucher_id', $id)->get();
        // $creditTransaction = [];
        // $debitTransaction = [];

        /*if ($receipt) {
                $debitTransaction = AcReceiptDetail::with('account')
                        ->where(['voucher_id' => $receipt->id, 'transaction_type' => 'CREDIT'])
                        ->first();

                $creditTransaction = AcReceiptDetail::with('account')
                        ->where(['voucher_id' => $receipt->id, 'transaction_type' => 'DEBIT'])
                        ->get();
            }*/
        $discount_group = Account::where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::where(['code' => 'ROUN_OFF'])->first();

        $transactionSummery = $this->TransactionSummery($id, 'IPD_INVOICE');
        $transactionHistory = $this->transactionHistory($id, 'IPD_INVOICE');
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());

        return view('ipd-billings.edit.billing', compact([
            'id',
            'data',
            'doctors',
            'patients',
            'sale_invoice',
            'refferal_lab',
            'voucher_master',
            'collection_agent',
            'bussiness_source',
            'payment_types',
            'special_cases',
            'accounting_group',
            'AcReceipt',
            'discount_group',
            'round_off',
            'transactionSummery',
            'transactionHistory',
            'batch_id',
            'companyDateFormate'
            // 'creditTransaction',
            // 'debitTransaction',
        ]));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id, $batch_id)
    {

        $sale_invoice = SaleInvoice::find($id);

        if (!$sale_invoice) {
            $data = [];
            \Session::put('ipd_billing_products_cart', $data);

            return redirect()->route('ipd-billings.index')->with('error', 'IPD billing invoice not found!');
        }

        

        $data = \Session::get('ipd_billing_products_cart') ?? [];
        
        if (empty($data)) {
            return redirect()->back()->with('error', 'Empty cart!');
        }
        $invoice_date        = $request->invoice_date != '' ? date('Y-m-d', strtotime($request->invoice_date)) : '';
        $sample_receive_date = $request->sample_receive_date != '' ? date('Y-m-d', strtotime($request->sample_receive_date)) : '';

        $sale_invoice_update  = [
            'payment_term_id'         => $request->payment_term_id,
            'billing_amount'          => $data['amount'],
            'invoice_date'            => $invoice_date,
            'patient_id'              => $data['patient_id'],
            'doctor_id'               => $data['doctor_id'],
            'collection_agent_id'     => $data['collection_id'],
            'refferal_lab_id'         => $data['refferal_id'],
            'reff_no'                 => $request->reff_no,
            'received_amount'         => $request->amount_recieved,
            'due_amount'              => $data['due_balance_amount'],
            'sample_barcode'          => $request->sample_barcode,
            'sample_receive_date'     => $sample_receive_date,
            'sample_receive_time'     => $request->sample_receive_time,
            'remarks_for_technician'  => $request->remarks_for_technician,
            'remarks'                 => $request->sale_remarks,
            'special_case_id'         => $request->special_case,
            'discount_amount'         => $request->special_discount,
            'adjustment_type'         => $request->discount_type,
            'payment_mode_id'         => $request->payment_mode_id ?? '',
            'bussiness_source_id'     => $request->bussiness_source ?? '',
        ];

        $sale_invoice->update($sale_invoice_update);

        $batchVoucherType = VoucherType::select(['id','code'])->find($data['voucher_type_id']);

        $where = [
            'id'             => $batch_id,
            'invoice_id'     => $sale_invoice->id,
        ];
        $invoice_batchs = [
            'sample_barcode'            => $request->sample_barcode,
            'sample_receive_date'       => $request->sample_receive_date,
            'sample_receive_time'       => $request->sample_receive_time,
            'remarks_for_technician'    => $request->remarks_for_technician,
            'updated_by'                => Auth::user()->id,
            'batch_status'              => 'NEWORDER',
            'referrence_voucher_type'   => $batchVoucherType->code??'',
        ];


        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::where($where)->first();

        $invoice_batch->update($invoice_batchs);


        /*********************  Spacial Discount Store Calculation ***********************/
        if ($request->special_discount > 0) {
            # last voucher count for main Transaction number
            $transaction_voucher_count      = AccountTransaction::select('last_id')->orderBy('created_at', 'DESC')->first();
            $transaction_voucher_master     = VoucherMaster::select('id')
                ->with('voucherSeries')
                ->where('voucher_code', 'TRANSACTION')
                ->where(['status' => 1])
                ->first();
            $last_voucher_count = isset($transaction_voucher_count) && isset($transaction_voucher_count->last_id) ?
                $transaction_voucher_count->last_id + 1 : ($transaction_voucher_master->voucherSeries->start_from + 1 ?? 1);

            $transactions_no = $this->generateCode(
                $last_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );
            $this->SaleOthersTransaction(
                $sale_invoice->id,
                $transactions_no,
                'IPD_INVOICE',
                $request->discount_account_id,
                $request->special_discount
            );
        }
        $discount['mode_id'] = $request->discount_account_id ?? '';
        $discount['amount'] = $request->special_discount ?? 0;
        /********************* End Spacial Discount Store Calculation ***********************/

        /*********************  Round Off Store Calculation ***********************/
        if ($request->round_off_amount > 0) {
            # last voucher count for main Transaction number
            $transaction_voucher_count      = AccountTransaction::select('last_id')->orderBy('created_at', 'DESC')->first();
            $transaction_voucher_master     = VoucherMaster::select('id')
                ->with('voucherSeries')
                ->where('voucher_code', 'TRANSACTION')
                ->where(['status' => 1])
                ->first();
            $last_voucher_count = isset($transaction_voucher_count) && isset($transaction_voucher_count->last_id) ?
                $transaction_voucher_count->last_id + 1 : ($transaction_voucher_master->voucherSeries->start_from + 1 ?? 1);

            $transactions_no = $this->generateCode(
                $last_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );
            $this->SaleOthersTransaction(
                $sale_invoice->id,
                $transactions_no,
                'IPD_INVOICE',
                $request->round_off_account_id,
                $request->round_off_amount
            );
        }
        $roundOff['mode_id'] = $request->round_off_account_id ?? '';
        $roundOff['amount'] = $request->round_off_amount ?? 0;
        /********************* End  Round Off Store Calculation ***********************/


        $task_status  = TaskStatus::where('is_default', '1')->first();
        $sale_invoice_detail_ids = $sale_invoice_sub_detail_ids = $product_ids = [];

        /**************** All Delete Bed Sale Invoice Details **********************/
        if(isset($data['bill_type']) && $data['bill_type']=='bed')
        {
            SaleInvoiceDetail::where(['sale_invoice_id'=>$id,'batch_id'=>$batch_id])->delete();
        }
        /**************** End All Delete Bed Sale Invoice Details **********************/

        foreach ($data['products'] as $key => $value) {
            $product = Product::where('id', $value['product_id'])
                ->with('getProductPrice')
                ->first();

            $item = [
                'price'               => $value['product_price'],
                'basic_amount'        => $value['product_basic'],
                'discount_percentage' => $value['per_discount'],
                'discount_amount'     => $value['flat_discount'],
                'total_amount'        => $value['amount'],
                'item_details'        => $value['product_details'],
                'item_batch'          => $value['batch'] ?? '',
                'tax_slab_id'         => $product->tax_slab_id ?? '',
                'main_qty'            => $value['main_qty'],
                'from_date_time'      => Carbon::now()->format('Y-m-d H:i:s'),
                'customer_amount'     => $value['amount']??0,
                'tax_calculation_type'=> $voucher_master->tax_calculation??'',
            ];

            if(isset($value['bill_type']) && $value['bill_type']=='bed')
            {
                    $items = [
                        'sale_invoice_id'     => $sale_invoice->id,
                        'product_id'          => $value['product_id'],
                        'batch_id'            => $batch_id,
                        'product_price_id'    => $value['price_id'],
                        'price'               => $value['product_price'],
                        'basic_amount'        => $value['product_basic'],
                        'discount_percentage' => $value['per_discount'],
                        'discount_amount'     => $value['flat_discount'],
                        'total_amount'        => $value['amount'],
                        'item_details'        => $value['product_details'],
                        'item_batch'          => $value['batch'] ?? '',
                        'tax_slab_id'         => $product->tax_slab_id ?? '',
                        'main_qty'            => $value['main_qty'],
                        'from_date_time'      => Carbon::now()->format('Y-m-d H:i:s'),
                        'customer_amount'     => $value['amount']??0,
                        'tax_calculation_type'=> $voucher_masters->tax_calculation??''
                    ];
    
                    $sale_invoice_details = SaleInvoiceDetail::create($items);
                    $ipdBedHistory = IpdBedHistory::find($value['ipd_bed_histories_id']);
                    $ipdBedHistory->update(['sale_invoice_batch_id'=>$batch_id,'bill_status'=>1]);
                    $sale_invoice_detail_ids[] = $sale_invoice_details->id;
            }
            else
            {

                $product_ids[] = $value['product_id'];

                $sale_invoice_details = SaleInvoiceDetail::updateOrCreate([
                    'sale_invoice_id'     => $sale_invoice->id,
                    'product_id'          => $value['product_id'],
                    'batch_id'            => $batch_id,
                    'product_price_id'    => $value['price_id'],
                ], $item);
    
                $sale_invoice_detail_ids[] = $sale_invoice_details->id;
            }

            $product_test_package = ProductTestPackage::where('product_id', $value['product_id'])->get();

            foreach ($product_test_package as $package) {
                $addedTestPackage = SaleInvoiceSubDetails::updateOrCreate(
                    [
                        'sale_invoice_detail_id' => $sale_invoice_details->id,
                        'sale_invoice_id'        => $sale_invoice->id,
                        'data_referrence_id'     => $package->test_package_id,
                    ],
                    [
                        'subdetails_remarks'     => '',
                        'referrence_type'        => 'LAB',
                        'status'                 => 'SAMPLE_COLLECTION',
                        'task_status_id'         => $task_status->id ?? '',
                        'review_status_id'       => $task_status->id ?? '',
                    ]
                );
                $sale_invoice_sub_detail_ids[] = $addedTestPackage->id;
            }
        }

        if (!empty($product_ids)) {
            $sale_invoice_details = SaleInvoiceDetail::where([
                'sale_invoice_id'     => $sale_invoice->id,
                'batch_id'            => $batch_id
            ])->whereNotIn('product_id', $product_ids)->get();
            foreach ($sale_invoice_details as $key => $value) {
                SaleInvoiceSubDetails::where([
                        'sale_invoice_detail_id' => $value->id,
                        'sale_invoice_id'        => $value->sale_invoice_id,
                        // 'data_referrence_id'     => $package->test_package_id,
                    ])->delete();
                SaleInvoiceDetail::where('id', $value->id)->delete();
            }
        }

        //SaleInvoiceDetail::whereNotIn('id',$sale_invoice_detail_ids)->delete();
        //SaleInvoiceSubDetails::whereNotIn('id',$sale_invoice_sub_detail_ids)->delete();

        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'IPD_ADMISSION')->where(['status' => 1])->first();
        /***************************************Basic Transaction Update ***************/
        $this->updateTransaction(
            'IPD_INVOICE',
            $sale_invoice->id,
            $invoice_batch->id,
            $voucher_type->code,
            $data['patient_id'],
            $data,
            $roundOff,
            $discount,
            $request->special_discount ?? 0
        );
        /**************************** End Basic Transaction Update *********************/

        // if ($request->amount_recieved > 0) {
        //     $transactions_no = $this->generateRandomCode();


        //     $this->UpdateAcReceiptAndTransaction(
        //         $request->payment_mode_id ?? '',
        //         $data['patient_id'],
        //         $request->amount_recieved,
        //         $transaction->id ?? '',
        //         $sale_invoice->id,
        //         'IPD_ADMISSION',
        //         $request->payment_mode,
        //         'received',
        //     );


        // }

        \Session::forget('ipd_billing_products_cart');
        $param              = [];
        $params['id']       = $sale_invoice->id??'';
        $params['batch_id'] = $invoice_batch->id??'';
        return redirect()->route('ipd-new-invoice', $params)->with('success', "Bill Updated Successfully");
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request)
    {
        $sale = SaleInvoiceBatch::find($request->id);

        if (!$sale) {
            return response()->json([
                'success' => false,
                'message' => ['Intent not found!']
            ]);
        }

        $existingInvoice = SaleInvoice::where('id', $sale->invoice_id)
            ->where('invoice_type', 'ipd-billings')
            ->first();


        $existingInvoice_details = SaleInvoiceDetail::where(['batch_id' => $request->id])->get();
        $total_amount = 0;

        foreach ($existingInvoice_details as $key => $value) {
            $total_amount = $total_amount + $value->total_amount;
            SaleInvoiceSubDetails::where(['sale_invoice_detail_id' => $value->id])->delete();
        }

        $existingInvoice->update([
            'billing_amount' => (int)$existingInvoice->billing_amount - $total_amount,
            'due_amount'     => $existingInvoice->due_amount - $total_amount,
        ]);

        SaleInvoiceDetail::where(['batch_id' => $request->id])->delete();
        SaleOthersTransaction::where('sale_invoice_batch_id', $request->id)->delete();
        IpdBedHistory::where(['sale_invoice_batch_id' => $request->id])->delete();
        SaleInvoiceBatch::where('id',$request->id)->delete();

        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully.']
        ]);
    }

    public function searchProducts(Request $request)
    {
        $searchTerm  = $request->search;
        $category_id = $request->category_id;

        $results    = Product::select('products.id', 'products.name', 'products.shortcode', 
                                    'products.hsncode','products.manage_stock');
          
            if(isset($category_id) && $category_id!='')
            {
                $results    = $results->where('products.category_id', $category_id);
            }
            $results    = $results->where(function ($query) use ($searchTerm) {
                $query->where('products.name', 'LIKE', "%" . $searchTerm . "%")
                      ->orWhere('products.hsncode', 'LIKE', $searchTerm . "%")
                      ->orWhere('products.shortcode', 'LIKE', $searchTerm . "%")
                      ->orWhere('products.product_code', 'LIKE', "%" . $searchTerm . "%");
            })
            ->where('products.status', 1)
            ->limit(15)
            ->get();

        return response()->json(['result' => $results, 'status' => true]);
    }

    public function productCart(Request $request, $id = 0, $batch_id = null)
    {
        $page        = $request->page ?? '';
        $data        = \Session::get('ipd_billing_products_cart') ?? [];
        // $bed_history = \Session::get('ipd_bed_history_details') ?? [];
        // dd($data);

        return view('ipd-billings.product-cart', compact('data', 'page', 'id', 'batch_id'));
    }

    public function productAddToCart(Request $request)
    {

        $data = \Session::get('ipd_billing_products_cart') ?? [];

        if (!isset($data['patient_id']) || $data['patient_id'] == '') {
            $data['patient_id'] = $request->patient_id;
        }
        if (!isset($data['doctor_id']) || $data['doctor_id'] == '') {
            $data['doctor_id'] = $request->doctor_id;
            //dd($request->doctor_id);
        }

        if (!isset($data['refferal_id']) || $data['refferal_id'] == '') {
            $data['refferal_id'] = $request->refferal_id ?? '';
        }

        if (!isset($data['collection_id']) || $data['collection_id'] == '') {
            $data['collection_id'] = $request->collection_id ?? '';
        }

        if (!isset($data['amount'])) {
            $data['amount'] = 0;
        }

        if (!isset($data['special_discount'])) {
            $data['special_discount'] = 0;
        }

        if (!isset($data['amount_recieved'])) {
            $data['amount_recieved'] = 0;
        }

        if (!isset($data['due_balance_amount'])) {
            $data['due_balance_amount'] = $data['amount'];
        }

        if (!isset($data['discount_type'])) {
            $data['discount_type'] = 'FLAT';
        }

        if (!isset($data['sample_receive_time'])) {
            $data['sample_receive_time'] = date('H:i:s');
        }

        if (!isset($data['invoice_date'])) {
            $data['invoice_date'] = date('Y-m-d');
        }

        if (!isset($data['sample_receive_date'])) {
            $data['sample_receive_date'] = date('Y-m-d');
        }

        if (!isset($data['voucher_type_id'])) {
            $data['voucher_type_id'] = $request->voucher_type_id??'';
        }

        $product = Product::select('products.id', 'products.name', 'products.hsncode', 'product_brands.name as brand', 'tax_masters.name as tax')
            ->leftjoin('product_brands', 'product_brands.id', 'products.brand_id')
            ->leftjoin('tax_masters', 'tax_masters.id', 'products.tax_slab_id')
            ->where('products.id', $request->search_product)
            ->first();
        // Check if the product already exists in the cart
        if (isset($data['products'])) {
            foreach ($data['products'] as $cart_product) {
                if ($cart_product['price_id'] == $request->price_id) {
                    return response()->json(['success' => true, 'data' => $data]);
                }
            }
        }

        $product_price = $request->product_price;
        $main_qty      = $request->main_qty > 0 ? $request->main_qty : 1;
        $loose_qty     = $request->loose_qty > 0 ? $request->loose_qty : 1;
        $flat_discount = $request->flat_discount ?? '0';
        $per_discount  = $request->per_discount ?? '0';
        $amount = '0';

        if ($product_price > 0) {
            if ($flat_discount != '' && $flat_discount != 0) {
                $per_discount  = $flat_discount / ($product_price * $request->main_qty) * 100;

                $flat_discount = (($per_discount / 100) * $product_price) * $request->main_qty;
                $flat_per_discount = (($per_discount / 100) * $product_price);
                $per_discount  = $per_discount;
                $amount        = $product_price - $flat_per_discount;
            } else if ($per_discount != '' && $per_discount != 0) {
                $flat_discount = (($per_discount / 100) * $product_price) * $request->main_qty;
                $flat_per_discount = (($per_discount / 100) * $product_price);
                $per_discount  = $per_discount;
                $amount        = $product_price - $flat_per_discount;
            } else {
                $amount        = $product_price;
            }
        }



        $productMrp = 0;
        $product_price = $amount ?? $product_price;

        $main_qty_amount = $main_qty * $product_price;
        $product_price  = number_format($product_price, 2, '.', '');

        $ActualRateAfterTax = 0;
        $ActualRateBeforeTax = 0;
        $totalTax            = 0;

        $tax_per = $product->tax == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $product->tax);


        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();

        if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
            $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
            $productMrp      = ($product_price + $tax) * $main_qty;  // 1000+
            $basic_amount    = $request->product_price;  //1000
            $ActualRateAfterTax = $product_price + $tax;
            $ActualRateBeforeTax = $product_price * $main_qty;
            $totalTax = $tax * $main_qty;
        } else {
            $basic_amount    = $request->product_price / (($tax_per + 100) / 100);
            $basePrice       = $product_price / (1 + ($tax_per / 100));
            $tax             = $product_price - $basePrice;
            $productMrp      = $product_price * $main_qty;
            $ActualRateAfterTax = $product_price - $tax;
            $ActualRateBeforeTax = $ActualRateAfterTax * $main_qty;
            $totalTax = $tax * $main_qty;
        }



        $basic_amount      = number_format($basic_amount, 2, '.', '');
        $flat_discount     = number_format($flat_discount, 2, '.', '');
        $per_discount      = number_format($per_discount, 2, '.', '');
        $tax               = number_format($tax, 2, '.', '');
        $convertion_factor = !empty($product->convertion_factor) ? $product->convertion_factor : 1;

        $amount                     = $main_qty * $amount / $convertion_factor;
        $data_amount                = $data['amount'] ?? 0;
        $data['amount']             = $data_amount + $productMrp;
        $data['due_balance_amount'] = number_format($data['amount'], 2, '.', '');

        $data['products'][] = [
            'brand_id'        => $request->brand_id ?? '',
            'price_id'        => $request->price_id ?? '',
            'product_id'      => $request->search_product ?? '',
            'product'         => $product->name ?? '',
            'hsncode'         => $product->hsncode ?? '',
            'brand'           => $product->brand ?? '',
            'product_price'   => $basic_amount ?? '',
            'flat_discount'   => $flat_discount ?? '',
            'per_discount'    => $per_discount ?? '',
            'vial_code'       => '',
            'amount'          => $productMrp ?? '',
            'main_qty'        => $request->main_qty ?? 1,
            'tax_per'         => $tax_per,
            'tax_flat'        => convertDecimelPoint($totalTax),
            'batch'           => $request->batch_name ?? '',
            'loose_qty'       => $request->main_qty > 0  ? 0 : $request->loose_qty ?? 0.00,
            'free_qty'        => $request->free_qty ?? '',
            'product_details' => $request->product_detail ?? '',
            'product_mrp'     => convertDecimelPoint($ActualRateAfterTax) ?? '',
            'product_basic'   => convertDecimelPoint($ActualRateBeforeTax) ?? '',
            'expiry_date'     => $request->expiry_date ? date('M-Y', strtotime($request->expiry_date)) : '',
        ];

       $test =  \Session::put('ipd_billing_products_cart', $data);

       return response()->json(['success' => true, 'data' => $data]);
    }


    public function productAddToCartold(Request $request)
    {

        $data = \Session::get('ipd_billing_products_cart') ?? [];

        if (!isset($data['patient_id']) || $data['patient_id'] == '') {
            $data['patient_id'] = $request->patient_id;
        }
        if (!isset($data['doctor_id']) || $data['doctor_id'] == '') {
            $data['doctor_id'] = $request->doctor_id;
            //dd($request->doctor_id);
        }

        if (!isset($data['refferal_id']) || $data['refferal_id'] == '') {
            $data['refferal_id'] = $request->refferal_id ?? '';
        }

        if (!isset($data['collection_id']) || $data['collection_id'] == '') {
            $data['collection_id'] = $request->collection_id ?? '';
        }

        if (!isset($data['amount'])) {
            $data['amount'] = 0;
        }

        if (!isset($data['special_discount'])) {
            $data['special_discount'] = 0;
        }

        if (!isset($data['amount_recieved'])) {
            $data['amount_recieved'] = 0;
        }

        if (!isset($data['due_balance_amount'])) {
            $data['due_balance_amount'] = $data['amount'];
        }

        if (!isset($data['discount_type'])) {
            $data['discount_type'] = 'FLAT';
        }

        if (!isset($data['sample_receive_time'])) {
            $data['sample_receive_time'] = date('H:i:s');
        }

        if (!isset($data['invoice_date'])) {
            $data['invoice_date'] = date('Y-m-d');
        }

        if (!isset($data['sample_receive_date'])) {
            $data['sample_receive_date'] = date('Y-m-d');
        }

        if (!isset($data['voucher_type_id'])) {
            $data['voucher_type_id'] = $request->voucher_type_id??'';
        }

        $product = Product::select('products.id', 'products.name', 'products.hsncode', 'product_brands.name as brand', 'tax_masters.name as tax')
            ->leftjoin('product_brands', 'product_brands.id', 'products.brand_id')
            ->leftjoin('tax_masters', 'tax_masters.id', 'products.tax_slab_id')
            ->where('products.id', $request->search_product)
            ->first();

        $main_qty        = $request->main_qty ?? 1;
        $main_qty_amount = $main_qty * $request->product_price;
        $flat_discount   = $request->flat_discount ?? '0';
        $per_discount    = $request->per_discount ?? '0';
        $amount          = '0';
        $productMrp      = 0;

        $product_price  = number_format($main_qty_amount, 2, '.', '');
        $tax_per = $product->tax == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $product->tax);

        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();

        if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
            $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
            $productMrp      = $product_price + $tax;  // 1000+
            $basic_amount    = $request->product_price;  //1000
        } else {
            $basic_amount               = $request->product_price / (($tax_per + 100) / 100);
            $basic_amountAllProcduct    = $product_price / (($tax_per + 100) / 100);  ///
            $tax                        = $product_price -  $basic_amountAllProcduct;
            $productMrp                 = $product_price;
        }

        if ($productMrp > 0) {
            if ($flat_discount != '' && $flat_discount != 0) {
                $per_discount  = ($flat_discount / $productMrp) * 100;
                $amount        = $productMrp - $flat_discount;
                $flat_discount = $flat_discount;
            } else if ($per_discount != '' && $per_discount != 0) {
                $flat_discount = ($per_discount / 100) * $productMrp;
                $per_discount  = $per_discount;
                $amount        = $productMrp - $flat_discount;
            } else {
                $amount        = $productMrp;
            }
        }

        $basic_amount      = number_format($basic_amount, 2, '.', '');
        // $amount            = number_format($amount, 2, '.', '');
        $flat_discount     = number_format($flat_discount, 2, '.', '');
        $per_discount      = number_format($per_discount, 2, '.', '');
        $tax               = number_format($tax, 2, '.', '');
        $convertion_factor = !empty($product->convertion_factor) ? $product->convertion_factor : 1;

        // $amount      = $main_qty * $amount / $convertion_factor;
        $data_amount = $data['amount'] ?? 0;

        $data['amount'] = $data_amount + $amount;

        $data['due_balance_amount'] = number_format($data['amount'], 2, '.', '');

        $data['products'][] = [
            'brand_id'        => $request->brand_id ?? '',
            'price_id'        => $request->price_id ?? '',
            'product_id'      => $request->search_product ?? '',
            'product'         => $product->name ?? '',
            'hsncode'         => $product->hsncode ?? '',
            'brand'           => $product->brand ?? '',
            'product_price'   => $basic_amount ?? '',
            'flat_discount'   => $flat_discount ?? '',
            'per_discount'    => $per_discount ?? '',
            'vial_code'       => '',
            'amount'          => $productMrp ?? '',
            'main_qty'        => $request->main_qty ?? 1,
            'tax_per'         => $tax_per,
            'tax_flat'        => $tax,
            'batch'           => $request->batch_name ?? '',
            'loose_qty'       => $request->main_qty > 0  ? 0 : $request->loose_qty ?? 0.00,
            'free_qty'        => $request->free_qty ?? '',
            'product_details' => $request->product_detail ?? '',
            'product_mrp'     => $request->product_price??''
        ];

       $test =  \Session::put('ipd_billing_products_cart', $data);

       return response()->json(['success' => true, 'data' => $data]);
    }

    public function cartProductRemove(Request $request)
    {
        $data = \Session::get('ipd_billing_products_cart') ?? [];
        $id   = $request->id;

        $amount = $data['amount'];

        $data['products'] = array_filter($data['products'], function ($product) use ($id, &$data, &$amount) {
            if ($product['price_id'] == $id) {
                $amount = $data['amount'] - $product['amount'];
            }

            return $product['price_id'] != $id;
        });

        if (count($data['products']) == 0) {
            $data['amount'] = 0;
        } else {
            $data['amount'] = $amount;
        }

        if ($data['discount_type'] == 'FLAT') {
            $due_balance_amount         = $data['amount'] - $data['special_discount'];
            $data['due_balance_amount'] = round($due_balance_amount - $data['amount_recieved']);
        } else {
            $flat_discount              = ($data['special_discount'] / 100) * $data['amount'];
            $due_balance_amount         = $data['amount'] - $flat_discount;
            $data['due_balance_amount'] = round($due_balance_amount - $data['amount_recieved']);
        }
        \Session::put('ipd_billing_products_cart', $data);

        return response()->json(['success' => true]);
    }

    public function cartProductUpdate(Request $request)
    {
        $data = \Session::get('ipd_billing_products_cart') ?? [];

        if (isset($request->type) && $request->type == 'billing') {
            if (isset($request->invoice_date)) {
                $data['invoice_date'] = date('Y-m-d', strtotime($request->invoice_date));
            }

            if (isset($request->payment_mode_id)) {
                $data['payment_mode_id'] = $request->payment_mode_id;
            }

            if (isset($request->payment_term_id)) {
                $data['payment_term_id'] = $request->payment_term_id;
            }

            if (isset($request->special_discount)) {
                $data['special_discount'] = $request->special_discount;
            }

            if (isset($request->discount_type)) {
                $data['discount_type'] = $request->discount_type;
            }

            if (isset($request->amount_recieved)) {
                $data['amount_recieved'] = $request->amount_recieved;
            }
            if (isset($request->voucher_type_id)) {
                $data['voucher_type_id'] = $request->voucher_type_id??'';
            }


            if (isset($request->special_discount) || isset($request->discount_type) || isset($request->amount_recieved)) {
                if (isset($data['discount_type']) && $data['discount_type'] == 'FLAT') {
                    $due_balance_amount = $data['amount'] - $data['special_discount'];
                    $data['due_balance_amount'] = round($due_balance_amount - $data['amount_recieved']);
                } else {
                    $flat_discount = ($data['special_discount'] / 100) * $data['amount'];
                    $due_balance_amount = $data['amount'] - $flat_discount;
                    $data['due_balance_amount'] = round($due_balance_amount - $data['amount_recieved']);
                }
            }
        } else {
            $amount = 0;
            if (isset($data['products'])) {
                foreach ($data['products'] as $key => $value) {
                    $saleVoucher = VoucherType::select(['default_price_type'])->where(['code'=>'SALES'])->first();

                    if ($saleVoucher->default_price_type == 'MRP') {
                        $productPrice = 'product_prices.mrp as mrp';
                    } elseif ($saleVoucher->default_price_type == 'Purchase Price') {
                        $productPrice = 'product_prices.purchase_price as mrp';
                    } elseif ($saleVoucher->default_price_type == 'WholeSale Price') {
                        $productPrice = 'product_prices.wholesale_price as mrp';
                    } elseif ($saleVoucher->default_price_type == 'Discounted/Sale Price(DP)') {
                        $productPrice = 'product_prices.sale_price as mrp';
                    } elseif ($saleVoucher->default_price_type == 'Min. Sale Price') {
                        $productPrice = 'product_prices.min_sale_price as mrp';
                    } elseif ($saleVoucher->default_price_type == 'Manufacturing Cost') {
                        $productPrice = 'product_prices.mfg_cost as mrp';
                    }

                    $product = Product::select('products.id','products.name','products.hsncode','product_brands.name as brand','tax_masters.name as tax','product_prices.batch as batch',$productPrice)
                        ->leftjoin('product_brands','product_brands.id','products.brand_id')
                        ->leftjoin('tax_masters','tax_masters.id','products.tax_slab_id')
                        ->leftjoin('product_prices','products.id','product_prices.product_id')
                        ->where('product_prices.id', $value['price_id'])
                        ->where('products.id', $value['product_id'])
                        ->first();

                    $tax_per = $product->tax == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $product->tax);

                    $voucher_master = VoucherMaster::select('tax_calculation')
                        ->where('voucher_code', 'SALES')
                        ->where(['status' => 1])
                        ->first();
                        
                    if ($value['price_id'] == $request->id && isset($request->product_details)) {
                        $data['products'][$key]['product_details'] = $request->product_details;
                    }
                    if ($value['price_id'] == $request->id && isset($request->vial_code)) {
                        $data['products'][$key]['vial_code'] = $request->vial_code;
                    }

                    if ($value['price_id'] == $request->id && isset($request->loose_qty)) {
                        $data['products'][$key]['loose_qty'] = $request->loose_qty;
                    }

                    if ($value['price_id'] == $request->id) {
                        $data['amount'] = $data['amount'] - $value['amount'];

                        if (isset($request->main_qty) && $request->main_qty > 0) {
                            $data['products'][$key]['main_qty']  = $request->main_qty;
                            $data['products'][$key]['loose_qty'] = 0;

                            $main_qty_amount = $request->main_qty * $product->mrp;
                            $product_price   = number_format($main_qty_amount, 2, '.', '');
                            $per_discount    = $value['per_discount'];

                        } elseif (isset($request->loose_qty) && $request->loose_qty > 0) {
                            $data['products'][$key]['loose_qty'] = $request->loose_qty;
                            $data['products'][$key]['main_qty']  = 0;

                            $main_qty_amount = $request->loose_qty * $product->mrp;
                            $product_price    = number_format($main_qty_amount, 2, '.', '');
                            $per_discount     = $value['per_discount'];
                        } else if (isset($request->per_discount) && !empty($request->per_discount)) {
                            $main_qty_amount = $data['products'][$key]['main_qty'] * $product->mrp;
                            $product_price   = number_format($main_qty_amount, 2, '.', '');
                            $per_discount    = $request->per_discount;
                        } else {
                            $main_qty_amount = $data['products'][$key]['main_qty'] * $product->mrp;
                            $product_price   = number_format($main_qty_amount, 2, '.', '');
                            $per_discount    = $value['per_discount'];
                        }

                        $product_price = $product->mrp;
                        $flat_discount = $request->flat_discount ?? '0';
                        $per_discount  = $request->per_discount ?? $data['products'][$key]['per_discount'];

                        $productMrp = $basic_amount = 0;

                        if ($product_price > 0) {
                            if ($flat_discount != '' && $flat_discount != 0) {
                                $per_discount  = $flat_discount / ($product_price * $data['products'][$key]['main_qty']) * 100;

                                $flat_discount = (($per_discount / 100) * $product_price) * $data['products'][$key]['main_qty'];
                                $flat_per_discount = (($per_discount / 100) * $product_price);
                                $per_discount  = $per_discount;
                                $amount        = $product_price - $flat_per_discount;
                            } else if ($per_discount != '' && $per_discount != 0) {

                                $flat_discount = (($per_discount / 100) * $product_price) * $data['products'][$key]['main_qty'];
                                $flat_per_discount = (($per_discount / 100) * $product_price);
                                $per_discount  = $per_discount;
                                $amount        = $product_price - $flat_per_discount;
                            } else {
                                $amount        = $product_price;
                            }
                        }

                        $product_price = $amount ?? $product_price;

                        if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                            $tax   =  $flat_tax        = ($tax_per / 100) * $product_price; //(12/100)*1000;
                            $productMrp      = ($product_price + $tax) * $data['products'][$key]['main_qty'];  // 1000+
                            $basic_amount    = $product->mrp;  //1000

                            $ActualRateAfterTax = $product_price + $tax;
                            $ActualRateBeforeTax = $product_price * $data['products'][$key]['main_qty'];
                            $totalTax = $tax * $data['products'][$key]['main_qty'];
                        } else {
                            $basic_amount    = $product->mrp / (($tax_per + 100) / 100);
                            $basePrice       = $product_price / (1 + ($tax_per / 100));
                            $tax  =    $flat_tax       = $product_price - $basePrice;
                            $productMrp      = $product_price * $data['products'][$key]['main_qty'];
                            $ActualRateAfterTax = $product_price - $tax;
                            $ActualRateBeforeTax = $ActualRateAfterTax * $data['products'][$key]['main_qty'];
                            $totalTax = $tax * $data['products'][$key]['main_qty'];
                        }


                        $amount = ($basic_amount - $flat_discount);
                        $amount = number_format($amount, 2, '.', '');

                        $convertion_factor = !empty($product->convertion_factor) ? $product->convertion_factor : 1;
                        $amount            = $main_qty_amount * $amount / $convertion_factor;
                        $flat_discount     = number_format($flat_discount, 2, '.', '');
                        $flat_tax          = number_format($totalTax, 2, '.', '');
                        $data['products'][$key]['flat_discount'] = $flat_discount;
                        $data['products'][$key]['per_discount']  = $per_discount;
                        $data['products'][$key]['tax_flat']      = $flat_tax;
                        $data['products'][$key]['amount']        = convertDecimelPoint($productMrp);
                        $data['products'][$key]['product_price'] = convertDecimelPoint($basic_amount);
                        $data['products'][$key]['product_mrp']   = convertDecimelPoint($ActualRateAfterTax) ?? '';
                        $data['products'][$key]['product_basic'] = convertDecimelPoint($ActualRateBeforeTax) ?? '';
                        $data['amount']                          = $data['amount'] + $productMrp;
                        $due_balance_amount                      = $data['amount'] - $flat_discount;
                        $data['due_balance_amount']              = number_format($due_balance_amount - $data['amount_recieved'], 2, '.', '');
                    }



                    if ($value['price_id'] == $request->id && isset($request->product_price)) {

                        $data['amount']                          = $data['amount'] - $value['amount'];
                        $product_price = $request->product_price;
                        $flat_discount = $request->flat_discount ?? '0';
                        $per_discount  = $request->per_discount ?? $data['products'][$key]['per_discount'];

                        $productMrp = $basic_amount = 0;

                        if ($product_price > 0) {
                            if ($flat_discount != '' && $flat_discount != 0) {
                                $per_discount  = $flat_discount / ($product_price * $data['products'][$key]['main_qty']) * 100;

                                $flat_discount = (($per_discount / 100) * $product_price) * $data['products'][$key]['main_qty'];
                                $flat_per_discount = (($per_discount / 100) * $product_price);
                                $per_discount  = $per_discount;
                                $amount        = $product_price - $flat_per_discount;
                            } else if ($per_discount != '' && $per_discount != 0) {

                                $flat_discount = (($per_discount / 100) * $product_price) * $data['products'][$key]['main_qty'];
                                $flat_per_discount = (($per_discount / 100) * $product_price);
                                $per_discount  = $per_discount;
                                $amount        = $product_price - $flat_per_discount;
                            } else {
                                $amount        = $product_price;
                            }
                        }

                        $product_price = $amount ?? $product_price;

                        if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                            $tax   =  $flat_tax        = ($tax_per / 100) * $product_price; //(12/100)*1000;
                            $productMrp      = ($product_price + $tax) * $data['products'][$key]['main_qty'];  // 1000+
                            $basic_amount    = $request->product_price;  //1000

                            $ActualRateAfterTax = $product_price + $tax;
                            $ActualRateBeforeTax = $product_price * $data['products'][$key]['main_qty'];
                            $totalTax = $tax * $data['products'][$key]['main_qty'];
                        } else {
                            $basic_amount    = $request->product_price / (($tax_per + 100) / 100);
                            $basePrice       = $product_price / (1 + ($tax_per / 100));
                            $tax  =    $flat_tax       = $product_price - $basePrice;
                            $productMrp      = $product_price * $data['products'][$key]['main_qty'];
                            $ActualRateAfterTax = $product_price - $tax;
                            $ActualRateBeforeTax = $ActualRateAfterTax * $data['products'][$key]['main_qty'];
                            $totalTax = $tax * $data['products'][$key]['main_qty'];
                        }


                        $amount = ($basic_amount - $flat_discount);
                        $amount = number_format($amount, 2, '.', '');

                        $convertion_factor = !empty($product->convertion_factor) ? $product->convertion_factor : 1;
                        $amount            = $main_qty_amount * $amount / $convertion_factor;
                        $flat_discount     = number_format($flat_discount, 2, '.', '');
                        $flat_tax          = number_format($totalTax, 2, '.', '');
                        $data['products'][$key]['flat_discount'] = $flat_discount;
                        $data['products'][$key]['per_discount']  = $per_discount;
                        $data['products'][$key]['tax_flat']      = $flat_tax;
                        $data['products'][$key]['amount']        = convertDecimelPoint($productMrp);
                        $data['products'][$key]['product_price'] = convertDecimelPoint($basic_amount);
                        $data['products'][$key]['product_mrp']   = convertDecimelPoint($ActualRateAfterTax) ?? '';
                        $data['products'][$key]['product_basic'] = convertDecimelPoint($ActualRateBeforeTax) ?? '';
                        $data['amount']                          = $data['amount'] + $productMrp;
                        $due_balance_amount                      = $data['amount'] - $flat_discount;
                        $data['due_balance_amount']              = number_format($due_balance_amount - $data['amount_recieved'], 2, '.', '');
                    }
                }
            }

            if (isset($request->patient_id)) {
                $data['patient_id'] = $request->patient_id;
            }

            if (isset($request->doctor_id)) {
                $data['doctor_id'] = $request->doctor_id;
            }

            if (isset($request->refferal_id)) {
                $data['refferal_id'] = $request->refferal_id;
            }

            if (isset($request->collection_id)) {
                $data['collection_id'] = $request->collection_id;
            }
        }
        \Session::put('ipd_billing_products_cart', $data);

        return response()->json(['success' => true, 'data' => $data]);
    }

    // Show All Bill
    public function ipdInvoice($id)
    {

        $ipd_id       = IpdAdmission::select('id', 'patient_id')->where('id', '=', $id)->first();
        $sale_invoice = SaleInvoice::select('sale_invoices.*',
        DB::raw('beds.name as bed_name', 'ipd_discharges.discharge_datetime as discharge_date', 'ipd_admissions.*', 'accounts.name as account_name'))
        ->with([
            'getSaleInvoiceDetails',
            'getSaleInvoiceDelivery',
            'getPatient',
            'getPaymentTerm',
            'getCompany',
            'getBatchs'
        ])
        ->leftJoin('ipd_admissions', 'sale_invoices.id', '=', 'ipd_admissions.sale_invoice_id')
        ->leftJoin('ipd_bed_histories', 'ipd_admissions.id', '=', 'ipd_bed_histories.ipd_admission_id')
        ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
        ->leftJoin('ipd_discharges', 'ipd_admissions.id', '=', 'ipd_discharges.ipd_admission_id')
        ->leftJoin('accounts', 'ipd_admissions.tpa_account_id', '=', 'accounts.id')
        ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
        ->where('ipd_admissions.id', $id)
        ->first();


        if (!$sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

        $voucher_type = VoucherType::with('voucherSeries')->where('code', 'IPD_INVOICE')->first();

        $transactionHistory = $this->ipdTransactionHistory($sale_invoice->id, 'IPD_INVOICE');
        $transactionSummery = $this->TransactionSummery($sale_invoice->id, 'IPD_INVOICE');

        $sale_return_invoice = SaleReturns::select('sale_returns.*', 'sale_invoices.voucher_type_invoice_no as reference_invoice_no')
        ->leftjoin('sale_invoices', 'sale_invoices.id', 'sale_returns.voucher_type_id')
        ->where('sale_returns.voucher_type_code', 'SALE_RETURN')
            ->with('getSaleInvoiceDetails')
            ->with('getCustomer')
            ->with('getCompany')
            ->where('voucher_type_id',$sale_invoice->id)
            ->first();
        $returnVoucherType   = VoucherType::with('voucherSeries')->where('code', 'SALE_RETURN')->first();
        $returnTransactionSummery = [];
        if($sale_return_invoice)
        {
            $returnTransactionSummery = $this->ReturnTransactionSummery($sale_return_invoice->id, 'SALE_RETURN');
        }
        
        return view('invoice-formats.ipd.lab-billing-invoice', compact('sale_invoice', 'voucher_type', 
                                                                        'transactionSummery', 'transactionHistory',
                                                                        'ipd_id','sale_return_invoice','returnVoucherType',
                                                                        'returnTransactionSummery'
                                                                    ));
    }


       // Show All Certificate Data
    public function ipdCertificateInvoice($id)
    {
        $ipd_id = IpdAdmission::with(['getCompany','getPatient'])->select('id', 'patient_id','company_id')->where('ipd_admissions.id', '=', $id)->first();
        
        $sale_invoice = SaleInvoice::select('sale_invoices.*',
        DB::raw('beds.name as bed_name', 'ipd_discharges.discharge_datetime as discharge_date', 'ipd_admissions.*', 'accounts.name as account_name'))
        ->with([
            'getSaleInvoiceDetails',
            'getSaleInvoiceDelivery',
            'getPatient',
            'getPaymentTerm',
            'getCompany',
            'getBatchs'
        ])
        ->leftJoin('ipd_admissions', 'sale_invoices.id', '=', 'ipd_admissions.sale_invoice_id')
        ->leftJoin('ipd_bed_histories', 'ipd_admissions.id', '=', 'ipd_bed_histories.ipd_admission_id')
        ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
        ->leftJoin('ipd_discharges', 'ipd_admissions.id', '=', 'ipd_discharges.ipd_admission_id')
        ->leftJoin('accounts', 'ipd_admissions.tpa_account_id', '=', 'accounts.id')
        ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
        ->where('ipd_admissions.id', $id)
        ->first();

        if (!$ipd_id) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

        $voucher_type = VoucherType::with('voucherSeries')->where('code', 'IPD_INVOICE')->first();

        //$transactionHistory = $this->ipdTransactionHistory($sale_invoice->id, 'IPD_INVOICE');
        //$transactionSummery = $this->TransactionSummery($sale_invoice->id, 'IPD_INVOICE');

        $ipd_admission = IpdAdmission::where('ipd_admissions.id', $id)
            ->leftJoin('sale_invoices', 'sale_invoices.id', '=', 'ipd_admissions.sale_invoice_id')
            ->leftJoin('accounts', 'accounts.id', '=', 'ipd_admissions.patient_id')
            ->leftJoin('account_addresses', 'account_addresses.account_id', '=', 'accounts.id')
            ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
            ->leftjoin('account_titles as patient_title','patient_title.id','accounts.account_title_id')
            ->leftJoin('genders', 'account_contacts.account_gender_id', '=', 'genders.id')
            ->leftJoin('countries', 'account_addresses.country_id', '=', 'countries.id')
            ->leftJoin('companies', 'companies.id', '=', 'accounts.company_id')
            ->leftJoin('ipd_discharges', 'ipd_discharges.ipd_admission_id', '=', 'ipd_admissions.id')
            ->leftJoin('ipd_symptom_histories', 'ipd_symptom_histories.ipd_admission_id', '=', 'ipd_admissions.id')
            ->leftJoin('symptoms', 'symptoms.id', '=', 'ipd_symptom_histories.symptom_id')
            ->leftJoin('account_relatives_details', 'account_relatives_details.account_id', '=', 'accounts.id')
            ->leftJoin('accounts as relatives', 'account_relatives_details.account_id', '=', 'relatives.id')
            // ->leftJoin('accounts as doctor_acc', 'sale_invoices.doctor_id', '=', 'doctor_acc.id')
            ->leftJoin('relation_types', 'relation_types.id', '=', 'account_relatives_details.relation_type')
            ->leftJoin('ipd_bed_histories', 'ipd_bed_histories.ipd_admission_id', '=', 'ipd_admissions.id')
            ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
            ->leftJoin('bed_groups', 'beds.bed_group_id', '=', 'bed_groups.id')
            ->leftJoin('ipd_consultant_histories', function($join) {
                $join->on('ipd_consultant_histories.ipd_admission_id', '=', 'ipd_admissions.id')
                    ->where('ipd_consultant_histories.is_main_dr', '1');
            })
            ->leftJoin('accounts as doctor_acc', 'ipd_consultant_histories.doctor_id', '=', 'doctor_acc.id')
            ->leftjoin('account_titles as doctor_title','doctor_title.id','doctor_acc.account_title_id')
            ->leftJoin('ipd_consultant_histories as jt_consultant_hist', function($join) {
                $join->on('jt_consultant_hist.ipd_admission_id', '=', 'ipd_admissions.id')
                    ->where('jt_consultant_hist.is_main_dr', '1');
            })
            ->leftJoin('accounts as consultants', 'jt_consultant_hist.doctor_id', '=', 'consultants.id')
            ->leftJoin('marital_statuses','account_contacts.marital_status','=','marital_statuses.id')
            ->leftJoin('account_contacts as doctor_account_contact', 'doctor_account_contact.account_id', '=', 'ipd_consultant_histories.doctor_id')
            ->select(
                'ipd_admissions.admission_date_time',
                'sale_invoices.invoice_date', 
                'ipd_admissions.ipd_admission_no',
                'ipd_admissions.patient_id',
                'accounts.name as patient_name',
                'accounts.code as code',
                'companies.name as company_name',
                'countries.name as country_name',
                'genders.name as gender_name',
                DB::raw('TIMESTAMPDIFF(YEAR, account_contacts.date_of_birth, CURDATE()) as age'),
                DB::raw('DATEDIFF(CURDATE(), DATE_ADD(account_contacts.date_of_birth, INTERVAL TIMESTAMPDIFF(YEAR, account_contacts.date_of_birth, CURDATE()) YEAR)) as age_days'),
                'account_addresses.address_line1 as address',
                'marital_statuses.name as status',
                'sale_invoices.main_invoice_no as invoice_no',
                'sale_invoices.due_amount as due_amount',
                'sale_invoices.received_amount as received_amount',
                'sale_invoices.tpa_corporate_id as tpa_corporate_id',
                'account_contacts.phone_no as phone_no', 
                'sale_invoices.reff_no as referal_no',
                'ipd_discharges.discharge_datetime as discharge_date_time',
                'symptoms.symptoms_title as symptoms_title',
                'account_relatives_details.relation_name as relative_name',
                'account_relatives_details.relation_type as relation',
                'bed_groups.name as bed_group_name',
                'beds.name as bed_name',
                'consultants.name as consultant_name',
                'doctor_acc.name as doctor_name',
                'doctor_account_contact.qualifications as specialty',
                'doctor_title.name as doctor_title_name',
                'patient_title.name as patient_title_name'
            )
            ->first();
            //dd($ipd_admission);

        return view('invoice-formats.ipd.ipd-certificate-invoice', compact('sale_invoice', 'voucher_type','ipd_id' , 'id' , 'ipd_admission'));
    }

    // View single bill
    public function ipdNewInvoice($id,$batch_id)
    {

        $ipd_id = IpdAdmission::select('id', 'patient_id')->where('ipd_admissions.sale_invoice_id', '=', $id)->first();
        
        $sale_invoice = SaleInvoice::select('sale_invoices.*','ipd_admissions.id as ipd_admission_id',
        DB::raw('beds.name as bed_name', 'ipd_discharges.discharge_datetime as discharge_date', 'ipd_admissions.*', 'accounts.name as account_name'))
        ->with([
            'getSaleInvoiceDetails' => function($query) use ($batch_id) {
                $query->where('batch_id', $batch_id);
            },
            'getSaleInvoiceDelivery',
            'getPatient',
            'getPaymentTerm',
            'getCompany',
            'getBatchs'
        ])
        ->leftJoin('ipd_admissions', 'ipd_admissions.sale_invoice_id','sale_invoices.id')
        ->leftJoin('ipd_bed_histories', 'ipd_admissions.id', '=', 'ipd_bed_histories.ipd_admission_id')
        ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
        ->leftJoin('ipd_discharges', 'ipd_admissions.id', '=', 'ipd_discharges.ipd_admission_id')
        ->leftJoin('accounts', 'ipd_admissions.tpa_account_id', '=', 'accounts.id')
        ->leftJoin('account_contacts', 'account_contacts.account_id', '=', 'accounts.id')
        ->where('sale_invoices.id', $id)
        ->first();

        if (!$sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

        $voucher_type       = VoucherType::with('voucherSeries')->where('code', 'IPD_INVOICE')->first();

        $transactionHistory = $this->transactionHistory($id, 'IPD_INVOICE');
        $transactionSummery = $this->TransactionSummeryBatchWise($id, 'IPD_INVOICE',$batch_id);
        return view('invoice-formats.ipd.lab-billing-specific-invoice', compact('sale_invoice', 'voucher_type', 'transactionSummery', 'transactionHistory','ipd_id'));
    }

    public function billingReport($invoice_id)
    {
        $sale_invoice = SaleInvoice::with('getPatient')
            ->find($invoice_id);

        if (!$sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }
        $productIds = SaleInvoiceDetail::select('product_id')->where('sale_invoice_id', $invoice_id)->get()->pluck('product_id');

        $testPackages = TestPackage::select('test_packages.*')->whereIn('product_test_packages.product_id', $productIds)
            ->leftjoin('product_test_packages', 'product_test_packages.test_package_id', 'test_packages.id')
            ->with('department', 'testPackageGroups.test_package_group_test_items')
            ->get()
            ->groupBy(function ($testPackage) {
                return $testPackage->department->id;
            })
            ->map(function ($testPackages, $departmentId) {
                $departmentName = Department::find($departmentId)->name;

                return [
                    'department_name' => $departmentName,
                    'test_packages'   => $testPackages,
                ];
            });

        $billing_report = LabBillingReport::where(['sale_invoice_id' => $invoice_id])
            ->get()->keyBy('test_item_id');

        return view('ipd-billings.billing-report', compact('sale_invoice', 'billing_report', 'testPackages'));
    }

    public function billingReportStore(Request $request, $invoice_id)
    {
        $sale_invoice = SaleInvoice::find($invoice_id);

        if ($sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

        $test_results = $request->test_results ?? [];
        $task_status  = TaskStatus::where('is_default', '1')->first();

        foreach ($test_results as $test_package_id => $test_package) {
            foreach ($test_package as $test_package_group_id => $test_package_group) {
                foreach ($test_package_group as $key => $value) {
                    $result = $value;
                    $is_file = 0;

                    if (!is_string($value) && is_file($value)) {
                        $ext = $value->getClientOriginalExtension() ?? '';
                        $allowed_ext = [
                            'pdf',
                            'jpeg',
                            'jpg',
                            'png'
                        ];

                        if (in_array($ext, $allowed_ext)) {
                            $path     = "lab-test-result";
                            $response = uploadImage($path, $value);

                            if ($response['status'] == true) {
                                $result = $response['file_name'];
                                $is_file = 1;
                            } else {
                                $result = '';
                            }
                        }
                    }

                    $billing_report = LabBillingReport::where([
                        'sale_invoice_id'       => $invoice_id,
                        'test_package_id'       => $test_package_id,
                        'test_package_group_id' => $test_package_group_id,
                        'test_item_id'          => $key,
                    ])->first();

                    if (!$billing_report && $result != '') {
                        $testPackage = SaleInvoiceSubDetails::updateOrCreate([
                            'sale_invoice_id'        => $invoice_id,
                            'data_referrence_id'     => $test_package_id
                        ], [
                            'task_created_by_id' => \Auth::ID(),
                            'task_created_at'    => date('Y-m-d H:i:s'),
                            'task_status_id'     => $task_status->id ?? '',
                        ]);

                        $billing_report = LabBillingReport::Create([
                            'sale_invoice_id'       => $invoice_id,
                            'test_package_id'       => $test_package_id,
                            'test_package_group_id' => $test_package_group_id,
                            'test_item_id'          => $key,
                            'is_file'               => $is_file,
                            'result'                => $result,
                        ]);
                    } else if ((isset($billing_report) && $billing_report->result != $result)) {
                        $testPackage = SaleInvoiceSubDetails::updateOrCreate([
                            'sale_invoice_id'        => $invoice_id,
                            'data_referrence_id'     => $test_package_id
                        ], [
                            'task_edited_by_id' => \Auth::ID(),
                            'task_edited_at'    => date('Y-m-d H:i:s'),
                            'task_status_id'    => $task_status->id ?? '',
                        ]);

                        $billing_report = $billing_report->update([
                            'result'  => $result,
                            'is_file' => $is_file,
                        ]);
                    }
                }
            }
        }

        return redirect()->route('ipd-billings.index')->with('success', 'Invoice report updated successfully.');
    }

    public function billingReportPrint($invoice_id)
    {
        ini_set('max_execution_time', '300');
        $sale_invoice = SaleInvoice::with('getPatient', 'getVoucherType')
            ->find($invoice_id);

        if (!$sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

            $productIds = SaleInvoiceDetail::select('product_id')->where('sale_invoice_id', $invoice_id)->get()->pluck('product_id');

            // \DB::enableQueryLog();
            $testPackages = TestPackage::select('test_packages.*')->whereIn('product_test_packages.product_id', $productIds)
            ->leftjoin('product_test_packages', 'product_test_packages.test_package_id', 'test_packages.id')
            ->with('department', 'testPackageGroups.test_package_group_test_items', 'package_note')
            ->get()
            ->groupBy(function ($testPackage) {
            return $testPackage->department->id;
            })
            ->map(function ($testPackages, $departmentId) {
                $departmentName = Department::find($departmentId)->name;

                return [
                    'department_name' => $departmentName,
                    'test_packages' => $testPackages,
                ];
            });
        // dd(\DB::getQueryLog());

        $billing_report = LabBillingReport::where(['sale_invoice_id' => $invoice_id])->get()->keyBy('test_item_id');
        $company_id = \Auth::user()->company_id ?? '';
        $company    = Company::with('getCompanyAddress')->find($company_id);

        $voucher_type = VoucherType::with('voucherSeries')->where('code', $sale_invoice->voucher_type_code)->first();

        $pdfData  = [
            'billing_report' => $billing_report,
            'sale_invoice'   => $sale_invoice,
            'testPackages'   => $testPackages,
            'voucher_type'   => $voucher_type,
            'company'        => $company,
        ];

        $pdf = PDF::loadView('lab-billings.billing-report-print', $pdfData)->set_option("isPhpEnabled", true)
            ->setPaper('a4', 'portrait')
            ->setWarnings(false);

        $filename = "billing-report_" . date("Y_m_d_i_H") . ".pdf";

        return $pdf->download($filename);
    }

    public function billingReportLog($invoice_id)
    {
        $sub_details = SaleInvoiceSubDetails::where('sale_invoice_id', $invoice_id)
            ->with('getCreatedBy', 'getEditedBy', 'getReviewedBy', 'getTestPackage')
            ->get();

        if (count($sub_details) < 1) {
            return redirect()->back()->with('error', 'No Logs Found!');
        }

        return view('ipd-billings.billing-report-logs', compact('sub_details'));
    }

    public function billingSummary($id)
    {
        $sale_invoice = SaleInvoice::select('sale_invoices.*','ipd_admissions.id as ipd_admission_id',
                DB::raw("(GROUP_CONCAT(sale_invoices.id SEPARATOR ',')) as 'ids'")
            )
            ->leftjoin('ipd_admissions', 'ipd_admissions.sale_invoice_id', 'sale_invoices.id')
            ->where('ipd_admissions.id', $id)
            ->first();

        $total_received_amount = \DB::table('ac_receipt_details')
            ->select(\DB::raw('SUM(amount) as total_amount'))
            ->leftjoin('ac_receipts', 'ac_receipts.id', 'ac_receipt_details.voucher_id')
            ->where('ac_receipt_details.transaction_type', "CREDIT")
            ->where(function($query) {
                $query->where('ac_receipts.module_code', "PATHOLOGY")
                    ->orWhere('ac_receipts.module_code', "IPD_INVOICE");
            })
            ->whereIn('ac_receipts.voucher_id', explode(',',$sale_invoice->ids))
            ->first();
        
        if (!$sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

        $sale_invoice_details = SaleInvoiceDetail::with('getProduct')->select([
                'sale_invoice_details.id',
                'sale_invoice_details.discount_percentage',
                'sale_invoice_details.discount_amount',
                'sale_invoice_details.price',
                'sale_invoice_details.main_qty',
                'sale_invoice_details.total_amount',
                'sale_invoice_batches.id as invoice_batch_id',
                'sale_invoice_batches.invoice_batch_no',
                'sale_invoice_batches.invoice_batch_date as batch_date',
                'sale_invoice_batches.consultant_id',
                'products.name as product_name',
                'products.category_id',
                'products.hsncode',
                'primary_units.code as primary_unit_code',
                'accounts.name as consultant_name',
                'sale_invoice_details.product_id',
                'sale_invoice_details.customer_amount',
                \DB::raw('DATE(sale_invoice_batches.invoice_batch_date) AS invoice_batch_date'),
            ])
            ->leftjoin('products', 'sale_invoice_details.product_id','products.id')
            ->leftjoin('sale_invoice_batches', 'sale_invoice_details.batch_id','sale_invoice_batches.id')
            ->leftjoin('accounts', 'sale_invoice_batches.consultant_id','accounts.id')
            ->leftjoin('primary_units', 'primary_units.id','products.primary_unit_id')
            ->whereIn('sale_invoice_details.sale_invoice_id', explode(',',$sale_invoice->ids))
            ->with('getProduct')
            ->orderBy('sale_invoice_batches.invoice_batch_date', 'ASC')
            ->get()
            ->groupBy(function ($sale_invoice_details) {
                return $sale_invoice_details->invoice_batch_date;
            })
            ->map(function ($sale_invoice_details, $invoiceBatchDate) {

                $sale_invoice_details = $sale_invoice_details->groupBy(function ($sale_invoice_details) {
                        return $sale_invoice_details->category_id;
                    })
                    ->map(function ($sale_invoice_details, $categoryId) {
                        $productCategoryName = ProductCategory::find($categoryId)->name;

                        return [
                            'category_name'        => $productCategoryName,
                            'sale_invoice_details' => $sale_invoice_details,
                        ];
                    });

                return [
                    'date'                 => $invoiceBatchDate,
                    'sale_invoice_details' => $sale_invoice_details,
                ];
            });

        $voucher_type = VoucherType::with('voucherSeries')->where('code', 'IPD_INVOICE')->first();


        $transactionHistory = $this->ipdTransactionHistory($sale_invoice->id, 'IPD_INVOICE');
        $transactionSummery = $this->TransactionSummery($sale_invoice->id, 'IPD_INVOICE');

        $sale_return_invoice = SaleReturns::select('sale_returns.*', 'sale_invoices.voucher_type_invoice_no as reference_invoice_no')
        ->leftjoin('sale_invoices', 'sale_invoices.id', 'sale_returns.voucher_type_id')
        ->where('sale_returns.voucher_type_code', 'SALE_RETURN')
            ->with('getSaleInvoiceDetails')
            ->with('getCustomer')
            ->with('getCompany')
            ->where('voucher_type_id',$sale_invoice->id)
            ->first();

        $returnTransactionSummery = [];
        if($sale_return_invoice)
        {
            $returnTransactionSummery = $this->ReturnTransactionSummery($sale_return_invoice->id, 'SALE_RETURN');
        }

        return view('invoice-formats.ipd.billing-summary', compact(
            'sale_invoice',
            'voucher_type',
            'total_received_amount',
            'sale_invoice_details',
            'transactionSummery',
            'transactionHistory',
            'returnTransactionSummery'
        ));
    }

    // Items Wise Wala 
    public function billingSummaryItemWise($id)
    {
        $sale_invoice = SaleInvoice::select('sale_invoices.*','ipd_admissions.id as ipd_admission_id',
                DB::raw("(GROUP_CONCAT(sale_invoices.id SEPARATOR ',')) as 'ids'")
            )
        ->leftjoin('ipd_admissions', 'ipd_admissions.sale_invoice_id', 'sale_invoices.id')
            ->where('ipd_admissions.id', $id)
            ->first();

        $total_received_amount = \DB::table('ac_receipt_details')
            ->select(\DB::raw('SUM(amount) as total_amount'))
            ->leftjoin('ac_receipts', 'ac_receipts.id', 'ac_receipt_details.voucher_id')
            ->where('ac_receipt_details.transaction_type', "CREDIT")
            ->where(function($query) {
                $query->where('ac_receipts.module_code', "PATHOLOGY")
                    ->orWhere('ac_receipts.module_code', "IPD_INVOICE");
            })
            ->whereIn('ac_receipts.voucher_id', explode(',',$sale_invoice->ids))
            ->first();
        
        if (!$sale_invoice) {
            return redirect()->route('ipd-billings.index')->with('error', 'Invoice not found');
        }

        $sale_invoice_details = SaleInvoiceDetail::with('getProduct')->select([
                'sale_invoice_details.id',
                'sale_invoice_details.discount_percentage',
                'sale_invoice_details.discount_amount',
                'sale_invoice_details.price',
                'sale_invoice_details.main_qty',
                'sale_invoice_details.total_amount',
                'sale_invoice_batches.id as invoice_batch_id',
                'sale_invoice_batches.invoice_batch_no',
                'sale_invoice_batches.invoice_batch_date as batch_date',
                'sale_invoice_batches.consultant_id',
                'products.name as product_name',
                'products.category_id',
                'primary_units.code as primary_unit_code',
                'accounts.name as consultant_name',
                'sale_invoice_details.product_id',
                'sale_invoice_details.customer_amount',
                \DB::raw('DATE(sale_invoice_batches.invoice_batch_date) AS invoice_batch_date'),
            ])
            ->leftjoin('products', 'sale_invoice_details.product_id','products.id')
            ->leftjoin('sale_invoice_batches', 'sale_invoice_details.batch_id','sale_invoice_batches.id')
            ->leftjoin('accounts', 'sale_invoice_batches.consultant_id','accounts.id')
            ->leftjoin('primary_units', 'primary_units.id','products.primary_unit_id')
            ->whereIn('sale_invoice_details.sale_invoice_id', explode(',',$sale_invoice->ids))
            ->with('getProduct')
            ->orderBy('products.name', 'ASC')
            ->get()
            ->groupBy(function ($sale_invoice_details) {
                        return $sale_invoice_details->category_id;
                    })
                    ->map(function ($sale_invoice_details, $categoryId) {
                        $productCategoryName = ProductCategory::find($categoryId)->name;

                        return [
                            'category_name'        => $productCategoryName,
                            'sale_invoice_details' => $sale_invoice_details,
                        ];
                    });

        $voucher_type = VoucherType::with('voucherSeries')->where('code', 'IPD_INVOICE')->first();
        $transactionHistory = $this->ipdTransactionHistory($sale_invoice->id, 'IPD_INVOICE');
        $transactionSummery = $this->TransactionSummery($sale_invoice->id, 'IPD_INVOICE');

        $sale_return_invoice = SaleReturns::select('sale_returns.*', 'sale_invoices.voucher_type_invoice_no as reference_invoice_no')
        ->leftjoin('sale_invoices', 'sale_invoices.id', 'sale_returns.voucher_type_id')
        ->where('sale_returns.voucher_type_code', 'SALE_RETURN')
            ->with('getSaleInvoiceDetails')
            ->with('getCustomer')
            ->with('getCompany')
            ->where('voucher_type_id',$sale_invoice->id)
            ->first();

        $returnTransactionSummery = [];
        if($sale_return_invoice)
        {
            $returnTransactionSummery = $this->ReturnTransactionSummery($sale_return_invoice->id, 'SALE_RETURN');
        }

        return view('invoice-formats.ipd.billing-summary-item-wise', compact(
            'sale_invoice',
            'voucher_type',
            'total_received_amount',
            'sale_invoice_details',
            'transactionSummery',
            'transactionHistory',
            'returnTransactionSummery'
        ));
    }


    public function updateBedMore($ipd_admission_id,$bill_type, Request $request)
    {
        
        \Session::forget('ipd_billing_products_cart');
        
        // Retrieve ipd_admission_id from query parameters
        $ipd_admission_id = $ipd_admission_id;
        $bill_type        = $bill_type;

        // PATIENT DETAILS
        $admission_details = IpdAdmission::select('ipd_admissions.patient_id','ipd_consultant_histories.doctor_id')
            ->leftjoin('ipd_consultant_histories', function($join) {
                $join->on('ipd_consultant_histories.ipd_admission_id', 'ipd_admissions.id')
                    ->where('ipd_consultant_histories.is_main_dr', 1);
            })
            ->where('ipd_admissions.id',$ipd_admission_id)->first();

       
        if (!$admission_details) {
            return redirect()->back()->with('error', 'IPD Admission not found!');
        }

        $patient_details = Account::select('name', 'account_title_id', 'id', 'code')
            ->where('id', $admission_details->patient_id)
            ->with('account_contact', 'account_title')->first();

        $ipd_id = $ipd_admission_id;
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode = $country_code->country_code ?? 'us';

        $brands = ProductBrand::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();
        $data = \Session::get('ipd_billing_products_cart') ?? [];

        $patient = $doctor = $collection_agent = $refferal_lab = '';

        if (!empty($data)) {
            if (isset($data['patient_id']) && $data['patient_id'] != '') {
                $patient = Account::getAccount([
                    'account_types.type_code' => 'PATIENT',
                    'accounts.id' => $data['patient_id']
                ]);
                if ($patient) {
                    $patient->full_name = $patient->name .
                        ($patient->code ? ', ' . $patient->code : '') .
                        ($patient->gender ? ', ' . $patient->gender : '') .
                        ($patient->age ? ', ' . $patient->age . ' yrs' : '');
                }
            } else {
                $data['patient_id'] = $admission_details->patient_id;
            }

            if (isset($data['doctor_id']) && $data['doctor_id'] != '') {
                $doctor = Account::getAccount([
                    'account_types.type_code' => 'DOCTOR',
                    'accounts.id' => $data['doctor_id']
                ]);
                if ($doctor) {
                    $doctor->full_name = $doctor->name .
                        ($doctor->code ? ', ' . $doctor->code : '') .
                        ($doctor->gender ? ', ' . $doctor->gender : '') .
                        ($doctor->age ? ', ' . $doctor->age . ' yrs' : '');
                }
            }

            if (isset($data['collection_id']) && $data['collection_id'] != '') {
                $collection_agent = Account::getAccount([
                    'account_types.type_code' => 'COLLECTION_AGENT',
                    'accounts.id' => $data['collection_id']
                ]);
                if ($collection_agent) {
                    $collection_agent->full_name = $collection_agent->name .
                        ($collection_agent->code ? ', ' . $collection_agent->code : '') .
                        ($collection_agent->gender ? ', ' . $collection_agent->gender : '') .
                        ($collection_agent->age ? ', ' . $collection_agent->age . ' yrs' : '');
                }
            }

            if (isset($data['refferal_id']) && $data['refferal_id'] != '') {
                $refferal_lab = Account::getAccount([
                    'account_types.type_code' => 'REFERRAL_LABORATORY',
                    'accounts.id' => $data['refferal_id']
                ]);
                if ($refferal_lab) {
                    $refferal_lab->full_name = $refferal_lab->name .
                        ($refferal_lab->code ? ', ' . $refferal_lab->code : '') .
                        ($refferal_lab->gender ? ', ' . $refferal_lab->gender : '') .
                        ($refferal_lab->age ? ', ' . $refferal_lab->age . ' yrs' : '');
                }
            }
        } else {
            $data['patient_id'] = $admission_details->patient_id;
        }

        $data = array_merge([
            'patient_id'          => $request->patient_id ?? $admission_details->patient_id,
            'doctor_id'           => $request->doctor_id ?? '',
            'refferal_id'         => $request->refferal_id ?? '',
            'collection_id'       => $request->collection_id ?? '',
            'voucher_type_id'     => '',
            'amount'              => 0,
            'special_discount'    => 0,
            'amount_recieved'     => 0,
            'due_balance_amount'  => 0,
            'discount_type'       => 'FLAT',
            'sample_receive_time' => date('H:i:s'),
            'invoice_date'        => date('Y-m-d'),
            'sample_receive_date' => date('Y-m-d'),
            'bill_type'           => 'bed'
        ], $data);

        $saleInvoiceDetails = SaleInvoiceDetail::whereIn('product_id', [181, 182, 183])->get();
        $product_ids        = $saleInvoiceDetails->pluck('product_id')->toArray();

        $productCategory    = ProductCategory::get();

        // Fetch bed details and store in session
        $bed_history_details = IpdBedHistory::select(
            'products.*',
            'product_prices.sale_price as sale_price',
            'product_prices.batch',
            'product_prices.id as product_price_id',
            'product_brands.name as brand_name',
            'tax_masters.total_percentage as total_percentage',
            'beds.id as bed_id',
            'ipd_bed_histories.check_in_date_time',
            'ipd_bed_histories.check_out_date_time',
            'ipd_bed_histories.full_days',
            'ipd_bed_histories.half_days',
            'ipd_bed_histories.bill_status',
            'ipd_bed_histories.id as ipd_bed_histories_id',
            'tax_masters.name as tax'
        )
        ->leftJoin('beds', 'ipd_bed_histories.bed_no_id', '=', 'beds.id')
        ->leftJoin('bed_types', 'beds.bed_type_id', '=', 'bed_types.id')
        ->leftJoin('products', 'bed_types.product_id', '=', 'products.id')
        ->leftJoin('product_prices', 'product_prices.product_id', '=', 'products.id')
        ->leftJoin('product_brands', 'products.brand_id', '=', 'product_brands.id')
        ->leftJoin('tax_masters', 'products.tax_slab_id', '=', 'tax_masters.id')
        ->where('ipd_bed_histories.ipd_admission_id', $ipd_admission_id)
        ->get()
        ->toArray();
        // Extract product IDs from current session data
        $existing_product_ids = array_column($data['products'] ?? [], 'product_id');
        $totalHalfDay         = 0;
        $totalFullDay         = 0;

        $productMrp    = 0;
        $ActualRateAfterTax = 0;
        $ActualRateBeforeTax = 0;
        $totalAmount = 0;
        // dd($bed_history_details);
        foreach ($bed_history_details as $detail) {
            // Only add product if it's not already in the session
            if (!in_array($detail['id'], $existing_product_ids)) {

                $checkin  = Carbon::parse($detail['check_in_date_time']);
                $checkout = !empty($detail['check_out_date_time']) ? Carbon::parse($detail['check_out_date_time']) : Carbon::now();
                $quantity = $checkin->diffInDays($checkout);

                $totalHalfDay = $detail['half_days']*0.5;
                $totalFullDay = $detail['full_days'];
                $totalDays    = $totalFullDay + $totalHalfDay;
                if($totalDays>0)
                {
                    $quantity = $totalDays;
                }
                else
                {
                    $quantity = (int)$quantity + 1;
                }



                $product_price = $detail['sale_price'];
                $main_qty      = $quantity > 0 ? $quantity : 1;
                $loose_qty     = 0;
                $flat_discount = $detail['discount_amount'] ?? '0';
                $per_discount  = $detail['discount_percentage'] ?? '0';
                $amount = '0';
        
                if ($product_price > 0) {
                    if ($flat_discount != '' && $flat_discount != 0) {
                        $per_discount  = $flat_discount / ($product_price * $quantity) * 100;
        
                        $flat_discount = (($per_discount / 100) * $product_price) * $quantity;
                        $flat_per_discount = (($per_discount / 100) * $product_price);
                        $per_discount  = $per_discount;
                        $amount        = $product_price - $flat_per_discount;
                    } else if ($per_discount != '' && $per_discount != 0) {
                        $flat_discount = (($per_discount / 100) * $product_price) * $quantity;
                        $flat_per_discount = (($per_discount / 100) * $product_price);
                        $per_discount  = $per_discount;
                        $amount        = $product_price - $flat_per_discount;
                    } else {
                        $amount        = $product_price;
                    }
                }
        
        
        
               
                $product_price = $amount ?? $product_price;
        
                $main_qty_amount = $main_qty * $product_price;
                $product_price  = number_format($product_price, 2, '.', '');
    
        
                $tax_per = $detail['tax'] == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $detail['tax']);
        
        
                $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
        
                if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                    $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
                    $productMrp      = ($product_price + $tax) * $main_qty;  // 1000+
                    $basic_amount    = $detail['sale_price'];  //1000
                    $ActualRateAfterTax = $product_price + $tax;
                    $ActualRateBeforeTax = $product_price * $main_qty;
                    $totalTax = $tax * $main_qty;
                } else {
                    $basic_amount    = $detail['sale_price'] / (($tax_per + 100) / 100);
                    $basePrice       = $product_price / (1 + ($tax_per / 100));
                    $tax             = $product_price - $basePrice;
                    $productMrp      = $product_price * $main_qty;
                    $ActualRateAfterTax = $product_price - $tax;
                    $ActualRateBeforeTax = $ActualRateAfterTax * $main_qty;
                    $totalTax = $tax * $main_qty;
                }
        
        
        
                $basic_amount      = number_format($basic_amount, 2, '.', '');
                $flat_discount     = number_format($flat_discount, 2, '.', '');
                $per_discount      = number_format($per_discount, 2, '.', '');
                $tax               = number_format($tax, 2, '.', '');

                $data_amount                = $data['amount'] ?? 0;
                $data['amount']             = $data_amount + $productMrp;
                $data['due_balance_amount'] = number_format($data['amount'], 2, '.', '');
        
                $data['products'][] = [
                    'brand_id'       => $detail['brand_id'] ?? '',
                    'main_qty'       => $quantity ?? 1,
                    'loose_qty'      => 0,
                    'free_qty'       => 0,
                    'product_details'=> $detail['item_details'] ?? '',
                    'price_id'       => $detail['product_price_id'] ?? '',
                    'product_id'     => $detail['id'] ?? '',
                    'product'        => $detail['name'] ?? '',
                    'hsncode'        => $detail['hsncode'] ?? '',
                    'brand'          => $detail['brand_name'] ?? '',
                    'batch'          => $detail['batch']??'' ?? '',
                    'product_price'  => convertDecimelPoint($basic_amount) ?? '',
                    'flat_discount'  => $flat_discount ?? '',
                    'per_discount'   => $per_discount ?? '',
                    'vial_code'      => '',
                    'amount'         => $productMrp ?? '',
                    'tax_per'        => $tax_per,
                    'bill_type'      => 'bed',
                    'bill_status'    => $detail['bill_status']??'',
                    'ipd_bed_histories_id' => $detail['ipd_bed_histories_id']??'',
                    'tax_flat'       => convertDecimelPoint($totalTax),
                    'product_mrp'    => convertDecimelPoint($ActualRateAfterTax) ?? '',
                    'product_basic'  => convertDecimelPoint($ActualRateBeforeTax) ?? '',
                    'expiry_date'    => isset($request->expiry_date) && $request->expiry_date ? date('M-Y', strtotime($request->expiry_date)) : '',
                ];
            }
        }

        $doctor_details = [];

        if (isset($admission_details->doctor_id) && $admission_details->doctor_id != '') {
            $doctor_details = Account::getAccount([
                'account_types.type_code' => 'DOCTOR',
                'accounts.id' => $admission_details->doctor_id
            ]);

            if (isset($doctor_details)) {
                $doctor_details->full_name = $doctor_details->name .
                    ($doctor_details->code   != '' ? ', ' . $doctor_details->code : '') .
                    ($doctor_details->gender != '' ? ', ' . $doctor_details->gender : '') .
                    ($doctor_details->age    != '' ? ', ' . $doctor_details->age . ' yrs' : '');
            }
        }

        $data['due_balance_amount'] = $data['amount'] - $data['amount_recieved'];
        \Session::put('ipd_billing_products_cart', $data);
        return true;
    }
}
