<?php

namespace App\Http\Controllers\OpdAppointment;

use App\Http\Controllers\Controller;
use App\Models\Account;
use App\Models\AccountTransaction;
use App\Models\AcReceipt;
use App\Models\AcReceiptDetail;
use App\Models\AppointmentDoctorFees;
use App\Models\AppointmentDoctorShiftDay;
use App\Models\AppointmentShift;
use App\Models\BookingCalendar;
use App\Models\CompanyAddress;
use App\Models\Doctor;
use App\Models\EnquirySource;
use App\Models\MenuModelPermission;
use App\Models\OpdBlockSerial;
use App\Models\OpdBookingDetail;
use App\Models\OpdBookings;
use App\Models\OrganizationDepartment;
use App\Models\Product;
use App\Models\ProductBrand;
use App\Models\ProductCategory;
use App\Models\ProductTestPackage;
use App\Models\SaleInvoice;
use App\Models\SaleInvoiceBatch;
use App\Models\SaleInvoiceDetail;
use App\Models\SaleInvoiceSubDetails;
use App\Models\SpecialCase;
use App\Models\TaskStatus;
use App\Models\VoucherCollection;
use App\Models\VoucherCollectionDetail;
use App\Models\VoucherMaster;
use App\Models\VoucherType;
use App\Models\LetterHead;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Validator;
use App\Traits\AcReceiptAndTransactionAllTrait;
use App\Traits\BillingConceptTrait;
use App\Traits\TransactionSummeryTrait;
use DateTime;

class OpdBookingController extends Controller
{
    use AcReceiptAndTransactionAllTrait, TransactionSummeryTrait, BillingConceptTrait;
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        if (!$this->checkPermission('opd-booking-list')) {
            return redirect()->back()->with('info', 'You don\'t have enough permission to access this page.');
        }

        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        $data               = OpdBookings::with(['getDoctorAccount', 'getPatient'])
            ->select(
                'id',
                'booking_no',
                'patient_id',
                'doctor_ac_id',
                'total_billing',
                'due_balance_amount',
                'amount_recieved',
                'invoice_status',
                'appointment_date_time',
                'appointment_serial_no',
                'appointment_status',
                'booking_date_time',
                'operator_id'
            )
            ->when(!in_array('Admin',\Auth()->user()->roles->pluck('name')->all()), function($query) {
                $query->where(function($where) {
                    $where->where('opd_bookings.operator_id', \Auth()->id())
                        ->orWhere('opd_bookings.doctor_ac_id',\Auth()->user()->account_id);
                })
                ->where('opd_bookings.company_id', \Auth()->user()->company_id);
            });

        $sort_by = $request->get('sortby') ?? 10;

        if ($request->ajax()) {
            $sort_type    = $request->get('sorttype');
            $search_query = $request->get('query');
            $search_type  = $request->get('search_type');
            $from_date       = isset($request->from_date) && $request->from_date!='' ?Carbon::createFromFormat($this->companyDateFormate(), $request->from_date)->format('Y-m-d'):'';

            if(isset($from_date) && $from_date!=''){
                $data->whereDate('appointment_date_time', $from_date);
            }

            $data = $data->when(
                !empty($search_query) && !empty($search_type),
                function ($query) use ($search_type, $search_query) {
                    if ($search_type == 'invoice_no') {
                        $query->where('booking_no', 'LIKE', '%' . $search_query . '%');
                    } else if ($search_type == 'pat_name') {
                        $query->whereHas('getPatient', function ($patient) use ($search_query) {
                            $patient->where('accounts.name', 'LIKE', '%' . $search_query . '%');
                        });
                    } else if ($search_type == 'phone') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getPatient.account_contact', function ($patient) use ($search_query) {
                                $patient->where('phone_no', 'LIKE', '%' . $search_query . '%');
                            });
                        });
                    } else if ($search_type == 'abha_no') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getPatient', function ($patient) use ($search_query) {
                                $patient->where('accounts.abha_no', 'LIKE', '%' . $search_query . '%');
                            });
                        });
                    }
                    else if ($search_type == 'pat_code') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getPatient', function ($patient) use ($search_query) {
                                $patient->where('accounts.unique_register_no', 'LIKE', '%' . $search_query . '%');
                            });
                        });
                    } else if ($search_type == 'dr_name') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getDoctorAccount', function ($patient) use ($search_query) {
                                $patient->where('accounts.name', 'LIKE', '%' . $search_query . '%');
                            });
                        });
                    }
                }
            )
                ->where('appointment_status', 'Pending')
                ->orderBy('id', 'DESC')
                ->paginate($sort_by);

            return view('opd-bookings.table', compact('data'));
        } else {
            $data = $data->where('appointment_status', 'Pending')->orderBy('id', 'DESC')
                ->paginate($sort_by);

            return view('opd-bookings.index', compact('data','companyDateFormate'));
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

        $data = \Session::get('opd_billing_products_cart') ?? [];
        if (
            empty($data) || !isset($data['patient_id']) ||
            !isset($data['doctor_id']) || !isset($data['shift_id']) ||
            !isset($data['date']) || !isset($data['time']) ||
            !isset($data['block_no'])
        ) {
            return redirect()->back()->with('error', 'Empty cart!');
        }

        
        $combinedDateTime = Carbon::parse($data['date'] . ' ' . $data['time']);
        $appointment_date_time = $combinedDateTime->format('Y-m-d H:i:s');

        $checkBooking = OpdBookings::where(['doctor_ac_id'=>$data['doctor_id'],'shift_id'=>$data['shift_id'],
        'appointment_date_time'=>$appointment_date_time,'appointment_serial_no'=>$data['block_no']])->first();
        if(isset($checkBooking))
        {
           
                if ($request->ajax()) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Booking Number Already Book Another User Please Select Another Token Number',
                        'data'    => []
                    ]);
                }
    
                return redirect()->back()->with('error', 'Booking Number Already Book Another User Please Select Another Token Number');
            
        }
        

        $booking_id = BookingCalendar::max('booking_id');
        $booking_id = $booking_id != '' ? $booking_id + 1 : 1;

        BookingCalendar::create([
            'customer_account_id'   => $data['patient_id'],
            'doctor_ac_id'          => $data['doctor_id'],
            'shift_id'              => $data['shift_id'],
            'appointment_date'      => $data['date'],
            'appointment_time'      => $data['time'],
            'appointment_serial_no' => $data['block_no'],
            'booking_id'            => $booking_id,
        ]);

        

        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'OPD_BOOKING')->first();
        # last voucher count for main voucher type OpdBookings number
        $voucher_type_last_count = OpdBookings::select('last_count')->orderBy('created_at', 'DESC')->first();
        $voucher_type_count = isset($voucher_type_last_count) && isset($voucher_type_last_count->last_count) ? $voucher_type_last_count->last_count + 1 : ($voucher_type->voucherSeries->start_from + 1 ?? 1);

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

        $doctor = Doctor::where('account_id', $data['doctor_id'])->first();

        $company_id     = \Auth::user()->company_id ?? '';
        $opd_store = [
            'company_id'            => $company_id,
            'booking_id'            => $booking_id,
            'patient_id'            => $data['patient_id'],
            'doctor_ac_id'          => $data['doctor_id'],
            'booking_date_time'     => date('Y-m-d H:i:s'),
            'shift_id'              => $data['shift_id'],
            'appointment_date_time' => $appointment_date_time,
            'appointment_serial_no' => $data['block_no'],
            'total_billing'         => $data['amount'],
            'special_discount'      => $data['special_discount'],
            'discount_type'         => $data['discount_type'],
            'due_balance_amount'    => $data['due_balance_amount'],
            'payment_mode_id'       => $request->payment_mode_id ?? '',
            'amount_recieved'       => $request->amount_recieved ?? '',
            'reff_no'               => $request->reff_no,
            'bussiness_source'      => $request->bussiness_source,
            'sale_remarks'          => $request->sale_remarks,
            'last_count'            => $voucher_type_count,
            'booking_no'            => $booking_no,
            'chamber_id'            => $doctor->doctors_chamber_id ?? 1,
            'operator_id'           => \Auth::user()->id ?? '',
        ];
        $OpdBooking = OpdBookings::create($opd_store);
        $opb_booking_id = $OpdBooking->id;
        foreach ($data['products'] as $list) {
            OpdBookingDetail::create([
                'opd_booking_id'  => $opb_booking_id,
                'product_id'      => $list['product_id'],
                'price_id'        => $list['price_id'],
                'brand_id'        => $list['brand_id'],
                'product_price'   => $list['product_price'],
                'per_discount'    => $list['per_discount'],
                'flat_discount'   => $list['flat_discount'],
                'amount'          => $list['amount'],
            ]);
        }

        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'Sales_Invoice_Batch')->first();
        $voucher_count_batch      = SaleInvoiceBatch::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        $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)
        );
        $invoice_batchs = [
            'account_id'             => $data['patient_id'],
            'invoice_batch_date'     => Carbon::now(),
            'invoice_batch_no'       => $main_invoice_no,
            'created_by'             => \Auth::user()->id,
            'invoice_id'             => '',
            'last_voucher_count'     => $last_voucher_count_batch,
            'sample_barcode'         => $request->sample_barcode,
            'sample_receive_date'    => date('Y-m-d'),
            'sample_receive_time'    => $request->sample_receive_time,
            'remarks_for_technician' => $request->remarks_for_technician,
            'consultant_id'          => $data['doctor_id'],
            'referrence_voucher_id'  => $opb_booking_id,
            'referrence_voucher_type'=> 'OPD_BOOKING'
        ];

        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::create($invoice_batchs);
        $opdBooking = OpdBookings::find($opb_booking_id);
        $opdBooking->update(['batch_id' => $invoice_batch->id]);





        /*********************  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_transaction_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_transaction_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $opb_booking_id,
                $transactions_no,
                'OPD_BOOKING',
                $request->discount_account_id,
                $request->special_discount
            );
        }
        $discount['mode_id'] = $request->discount_account_id ?? '';
        $discount['amount'] = $request->special_discount ?? '';
        /********************* 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_transaction_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_transaction_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $opb_booking_id,
                $transactions_no,
                'OPD_BOOKING',
                $request->round_off_account_id,
                $request->round_off_amount
            );
        }
        $roundOff['mode_id'] = $request->round_off_account_id ?? '';
        $roundOff['amount'] = $request->round_off_amount ?? '';
        /********************* End  Round Off Store Calculation ***********************/



        $this->createTransaction(
            'OPD_BOOKING',
            $opb_booking_id,
            $invoice_batch->id,
            $voucher_type->code,
            $data['patient_id'],
            $data,
            $roundOff,
            $discount,
            $request->special_discount
        );

        if ($request->amount_recieved > 0) {
            $this->createAcReceiptAndTransaction(
                $request->payment_mode_id ?? '',
                $data['patient_id'],
                $request->amount_recieved,
                $transaction->id ?? '',
                $opb_booking_id,
                'OPD_BOOKING',
                $request->payment_mode,
                'advance',
                $discount,
                $roundOff

            );
        }


        \Session::forget('opd_billing_products_cart');

        return redirect()->route('opd-bookings.slip', $opb_booking_id)->with('success', "New Bill Created Successfully");
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $company_id      = \Auth::user()->company_id ?? '';
        $company_address = CompanyAddress::getCompanyAddress(['companies_addresses.company_id' => $company_id]);
        $countryCode     = $company_address->country_code ?? 'us';
        $productCategory = ProductCategory::select(['id', 'name', 'is_default'])->where(['status' => 1])->get();

        $opdBooking    = OpdBookings::with('getOpdBookingDetails')->find($id);
        $data            = [];
        $patient         = $doctor = $collection_agent = $refferal_lab = '';

        if ($opdBooking) {

            $appointment_date_time = Carbon::parse($opdBooking->appointment_date_time);
            $data['shift_id']               = $opdBooking->shift_id;
            $data['time']                   = $appointment_date_time->format('H:i:s');
            $data['date']                   = $appointment_date_time->format('Y-m-d');
            $data['block_no']               = $opdBooking->appointment_serial_no;
            $data['patient_id']             = $opdBooking->patient_id;
            $data['doctor_id']              = $opdBooking->doctor_ac_id;
            $data['refferal_id']            = $opdBooking->refferal_lab_id;
            $data['collection_id']          = $opdBooking->collection_agent_id;
            $data['billing_amount']         = $opdBooking->total_billing;
            $data['discount_amount']        = $opdBooking->special_discount;
            $data['received_amount']        = $opdBooking->amount_recieved;
            $data['due_amount']             = $opdBooking->due_balance_amount;
            $data['discount_type']          = 'FLAT';
            $data['sample_receive_time']    = $opdBooking->sample_receive_time;
            $data['invoice_date']           = $opdBooking->invoice_date;
            $data['sample_receive_date']    = $opdBooking->sample_receive_date;
            $data['payment_mode_id']        = $opdBooking->payment_mode_id;
            $data['payment_term_id']        = $opdBooking->payment_term_id;
            $data['special_case']           = $opdBooking->special_case_id;
            $data['sample_barcode']         = $opdBooking->sample_barcode;
            $data['reff_no']                = $opdBooking->reff_no;
            $data['sale_remarks']           = $opdBooking->remarks;
            $data['remarks_for_technician'] = $opdBooking->remarks_for_technician;
            $data['amount']                 = $opdBooking->total_billing;
            $data['special_discount']       = $opdBooking->special_discount;


            foreach ($opdBooking->getOpdBookingDetails as $key => $value) {

                $amount        =  $value->price;
                // dd($amount);

                // $flat_discount = '0';
                // $per_discount  = '0';
                $main_qty = 1;
                $main_qty_amount = $main_qty * $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;

                $data['products'][] = array(
                    'booking_details_id' => $value->id,
                    'brand_id'        => $value->getProduct->brand_id ?? '',
                    'price_id'        => $value->price_id ?? '',
                    'product_id'      => $value->product_id ?? '',
                    'product'         => $value->getProduct->name ?? '',
                    'hsncode'         => $value->getProduct->hsncode ?? '',
                    'brand'           => $value->getProduct->getProductBrand->name ?? '',
                    'product_price'   => $value->product_price ?? '0',
                    'flat_discount'   => $value->flat_discount ?? '0',
                    'per_discount'    => $value->per_discount ?? '0',
                    'product_details' => '',
                    'vial_code'       => '',
                    'amount'          => $value->amount ?? '0',
                    'main_qty'       => $value->main_qty ?? '0',
                    'tax_per'        => $tax_per,
                    'tax_flat'        => $tax ?? 0,
                );
            }
        }

        \Session::put('opd_billing_products_cart', $data);

        if ($opdBooking && isset($opdBooking->patient_id) && $opdBooking->patient_id != '') {
            $patient = Account::getAccount([
                'account_types.type_code' => 'PATIENT',
                'accounts.id' => $opdBooking->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 ($opdBooking && isset($opdBooking->doctor_ac_id) && $opdBooking->doctor_ac_id != '') {
            $doctor = Account::getAccount([
                'account_types.type_code' => 'DOCTOR',
                'accounts.id' => $opdBooking->doctor_ac_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 ($opdBooking && isset($opdBooking->collection_id) && $opdBooking->collection_id != '') {
            $collection_agent = Account::getAccount([
                'account_types.type_code' => 'COLLECTION_AGENT',
                'accounts.id' => $opdBooking->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 ($opdBooking && isset($opdBooking->refferal_id) && $opdBooking->refferal_id != '') {
            $refferal_lab = Account::getAccount([
                'account_types.type_code' => 'REFERRAL_PARTNER',
                'accounts.id' => $opdBooking->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 : '');
            }
        }

        return view('opd-bookings.edit.edit', compact(
            'id',
            'productCategory',
            'doctor',
            'patient',
            'countryCode',
            'refferal_lab',
            'collection_agent',
            'data'
        ));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $data = \Session::get('opd_billing_products_cart') ?? [];
        $opb_booking_id = $id;

        $doctor = Doctor::where('account_id', $data['doctor_id'])->first();

        $OpdBooking = OpdBookings::find($id);
        $opd_store = [
            'patient_id'            => $data['patient_id'],
            'doctor_ac_id'          => $data['doctor_id'],
            'shift_id'              => $data['shift_id'],
            'appointment_serial_no' => $data['block_no'],
            'total_billing'         => $data['billing_amount'] ?? '',
            'special_discount'      => $data['discount_amount'] ?? '',
            'discount_type'         => $data['discount_type'] ?? '',
            'due_balance_amount'    => $request->due_balance_amount ?? '',
            'payment_mode_id'       => $data['payment_mode_id'] ?? '',
            'amount_recieved'       => $request->recieved ?? '',
            'reff_no'               => $request->reff_no ?? '',
            'bussiness_source'      => $request->bussiness_source ?? '',
            'sale_remarks'          => $request->sale_remarks ?? '',
            'chamber_id'            => $doctor->doctors_chamber_id ?? 1,
        ];
        $OpdBooking->update($opd_store);

        $financialyear = \Session::get('user_financial_year_id');

        foreach ($data['products'] as $list) {
            if (isset($list['booking_details_id']) && $list['booking_details_id'] != '') {
                $details = OpdBookingDetail::find($list['booking_details_id']);
                $updateDetails = [
                    'opd_booking_id'  => $id,
                    'product_id'      => $list['product_id'],
                    'price_id'        => $list['price_id'],
                    'brand_id'        => $list['brand_id'],
                    'product_price'   => $list['product_price'],
                    'per_discount'    => $list['per_discount'],
                    'flat_discount'   => $list['flat_discount'],
                    'amount'          => $list['amount'],
                ];

                $details->update($updateDetails);
            } else {
                OpdBookingDetail::create([
                    'opd_booking_id'  => $id,
                    'product_id'      => $list['product_id'],
                    'price_id'        => $list['price_id'],
                    'brand_id'        => $list['brand_id'],
                    'product_price'   => $list['product_price'],
                    'per_discount'    => $list['per_discount'],
                    'flat_discount'   => $list['flat_discount'],
                    'amount'          => $list['amount'],
                ]);
            }
        }

        /*********************  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)
            );
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $id,
                $transactions_no,
                'OPD_BOOKING',
                $request->discount_account_id,
                $request->special_discount
            );
        }
        /********************* 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)
            );
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $id,
                $transactions_no,
                'OPD_BOOKING',
                $request->round_off_account_id,
                $request->round_off_amount
            );
        }
        /********************* End  Round Off Store Calculation ***********************/
        // $accountTransactionData = AccountTransaction::where([
        //     'voucher_id'        =>  $opb_booking_id,
        //     'module_code'       =>  'OPD_BOOKING',
        //     'transaction_type'  =>  'CREDIT'
        // ])->first();
        // dd($accountTransactionData);
        // if ($accountTransactionData) {
        //     $acReceiptData = AcReceipt::where([
        //         'voucher_id'     => $opb_booking_id,
        //         'module_code'    => 'OPD_BOOKING'
        //     ])->first();
        //     if ($acReceiptData) {
        //         $voucherCollectionData = VoucherCollection::where('money_receipt_id', $acReceiptData->id)->first();
        //         VoucherCollectionDetail::where([
        //             'voucher_collection_id' =>  $voucherCollectionData->id,
        //             'transaction_id'        =>  $accountTransactionData->id
        //         ])->delete();
        //         AcReceiptDetail::where([
        //             'voucher_id'             => $acReceiptData->id,
        //             'voucher_type'           => 'OPD_BOOKING'
        //         ])->delete();
        //         $voucherCollectionData->delete();
        //         $acReceiptData->delete();
        //     }

        //     AccountTransaction::where([
        //         'voucher_id'        =>  $opb_booking_id,
        //         'module_code'      =>  'OPD_BOOKING'
        //     ])->delete();
        // }

        $roundOff['amount'] = 0;
        $discount['amount'] = 0;
            //dd($OpdBooking);
        $where = [
            'id'             => $OpdBooking->batch_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,
        ];
        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::where($where)->first();
        if($invoice_batch)
        {
            $invoice_batch->update($invoice_batchs);
        }
        else
        {
            $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'Sales_Invoice_Batch')->first();
            $voucher_count_batch      = SaleInvoiceBatch::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
            $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)
            );

            $invoice_batch  = SaleInvoiceBatch::create([
                'account_id'             => $data['patient_id'],
                'invoice_batch_date'     => Carbon::now(),
                'invoice_batch_no'       => $main_invoice_no,
                'created_by'             => \Auth::user()->id,
                'invoice_id'             => '',
                'last_voucher_count'     => $last_voucher_count_batch,
                'sample_barcode'         => $request->sample_barcode,
                'sample_receive_date'    => date('Y-m-d'),
                'sample_receive_time'    => $request->sample_receive_time,
                'remarks_for_technician' => $request->remarks_for_technician,
                'consultant_id'          => $data['doctor_id'],
                'referrence_voucher_id'  => $opb_booking_id,
                'referrence_voucher_type'=> 'OPD_BOOKING']);
        }
       $OpdBooking->update(['batch_id'=>$invoice_batch->id]);

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

        if ($request->recieved > 0) {

            $this->createAcReceiptAndTransaction(
                $request->payment_mode_id ?? '',
                $data['patient_id'],
                $request->recieved,
                $transaction->id ?? '',
                $opb_booking_id,
                'OPD_BOOKING',
                $request->payment_mode,
                'advance',
            );
        }


        return redirect()->route('opd-bookings.index')->with('success', "Update Bill Created Successfully");
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request)
    {

        $opdBooking = OpdBookings::find($request->id);
        $opb_booking_id = $request->id;
        $saleInvoiceId = $opdBooking->sale_invoice_id;
        $saleInvoiceBatchId = $opdBooking->batch_id;
        OpdBookingDetail::where('opd_booking_id', $request->id)->delete();
        $doctor  = Doctor::where('account_id', $opdBooking->doctor_ac_id)->first();

        $appointment_date_time = Carbon::parse($opdBooking->appointment_date_time);
        BookingCalendar::where('booking_id', $request->id)->delete();

        $opdBlockSerial = OpdBlockSerial::where([
            'slot_no'   => $opdBooking->appointment_serial_no,
            'shift_id'  => $opdBooking->shift_id,
            'doctor_id' => $doctor->id,
            'cdate'     => $appointment_date_time->format('Y-m-d'),
            'ctime'     => $appointment_date_time->format('H:i:s'),
        ]);

        if (isset($saleInvoiceId)) {
            $saleInvoice = SaleInvoice::find($saleInvoiceId);
            $saleInvoice->update(['deleted_by' => \Auth::user()->id]);
            $saleInvoice->delete();
            SaleInvoiceDetail::where('sale_invoice_id', $saleInvoiceId)->delete();
        }



        $acReceiptData = AcReceipt::where([
            'voucher_id'     => $opb_booking_id,
            'module_code'    => 'OPD_BOOKING'
        ])->first();

        AccountTransaction::where([
            'voucher_id'        =>  $opdBooking->id,
            'module_code'       =>  'OPD_BOOKING',
            'batch_id'          =>   $saleInvoiceBatchId,
        ])->delete();

        // dd($accountTransactionData);
        if ($acReceiptData) {
            $accountTransactionData = AccountTransaction::where([
                'voucher_id'        =>  $acReceiptData->id,
                'module_code'       =>  'OPD_BOOKING',
                'transaction_type'  =>  'CREDIT'
            ])->first();
            if ($acReceiptData) {
                $voucherCollectionData = VoucherCollection::where('money_receipt_id', $acReceiptData->id)->first();
                VoucherCollectionDetail::where([
                    'voucher_collection_id' =>  $voucherCollectionData->id,
                    'transaction_id'        =>  $accountTransactionData->id
                ])->delete();
                $voucherCollectionData->update(['deleted_by' => \Auth::user()->id]);
                $voucherCollectionData->delete();

                $acReceiptDataAll = AcReceipt::where([
                    'voucher_id'     => $opb_booking_id,
                    'module_code'    => 'OPD_BOOKING'
                ])->get();
                foreach($acReceiptDataAll as $row){
                    AcReceiptDetail::where([
                        'voucher_id'   => $row->id,
                        'voucher_type' => 'OPD_BOOKING'
                    ])->delete();

                    AccountTransaction::where([
                        'voucher_id'  =>   $row->id,
                        'module_code' =>  'OPD_BOOKING'
                    ])->delete();

                    $row->update(['deleted_by' => \Auth::user()->id]);
                    $row->delete();
                }
            }

            AccountTransaction::where([
                'voucher_id'        =>  $acReceiptData->id,
                'module_code'      =>  'OPD_BOOKING'
            ])->delete();
        }

        $opdBlockSerial->delete();

        $opdBooking->delete();
        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully'],
            'data' => [
                'redirect' => '',
            ]
        ]);
    }


    public function doctorList(Request $request, $booking_type = '')
    {

        $doctors = Doctor::with('getAccount')
            ->with('getOrganizatioDepartment')
            ->with('getDoctorAppointmentshift')
            ->where('status', '=', '1')
            ->get();
        $organization    = OrganizationDepartment::select(['id', 'name'])->orderBy('priority')->get();
        $bookingType = $booking_type ?? 'booking';
        if ($request->ajax()) {
            $selectedId = $request->selectedId;

            $filteredData = Doctor::with('getAccount')
                ->with('getOrganizatioDepartment')
                ->with('getDoctorAppointmentshift')
                ->where('status', '=', '1');

            $filteredData->when(!empty($selectedId), function ($query) use ($selectedId) {
                $query->where('organization_department_id', $selectedId);
            });

            $sort_by = $request->get('sortby') ?? 10;
            $sort_type = $request->get('sorttype');
            $search_query = $request->get('query');

            $filteredData->when(!empty($search_query), function ($data) use ($search_query) {
                return $data->where(function ($query) use ($search_query) {
                    $query->whereHas('getOrganizatioDepartment', function ($q) use ($search_query) {
                        $q->where('name', 'like', '%' . $search_query . '%');
                    })->orWhereHas('getAccount', function ($q) use ($search_query) {
                        $q->where('name', 'like', '%' . $search_query . '%');
                    });
                });
            });

            $doctors = $filteredData->paginate($sort_by);

            return view('opd-bookings.doctor-list-profile', compact('doctors', 'organization', 'bookingType'));
        }

        return view('opd-bookings.dostor-list', compact('doctors', 'organization', 'bookingType'));
    }


    function monthNameToNumber($monthName) {
        $months = [
            'January' => '01',
            'February' => '02',
            'March' => '03',
            'April' => '04',
            'May' => '05',
            'June' => '06',
            'July' => '07',
            'August' => '08',
            'September' => '09',
            'October' => '10',
            'November' => '11',
            'December' => '12'
        ];
        
        $monthName = ucfirst(strtolower($monthName)); // Normalize the month name
        return $months[$monthName] ?? false; // Return the month number or false if not found
    }
    
    
    

    
    public function makeAppointment(Request $request, $id, $booking_type = '')
    {
        \Session::forget('opd_billing_products_cart');

        $alldays = AppointmentDoctorShiftDay::where('doctor_id', $id)->groupBy('day_id')->get();
        $bookingType = $booking_type ?? 'booking';
        $days_array = [];
        foreach ($alldays as $key => $list) {
            $days_array[$key] = $list->day_id;
        }
        $doctor = Doctor::with('getAccount', 'getOrganizatioDepartment', 'getOpdSchedule')->find($id);
        $doctorFee = \DB::table('appointment_doctor_fees')
            ->leftJoin('product_prices', 'appointment_doctor_fees.product_id', '=', 'product_prices.product_id')
            ->select('appointment_doctor_fees.id', \DB::raw('SUM(product_prices.mrp) as total_amount'))
            ->where('appointment_doctor_fees.doctor_id', $id)
            ->groupBy('appointment_doctor_fees.doctor_id')
            ->first();

        $cdate = date('d');
        $month = date('m');
        $year  = date('Y');
        $date  = Carbon::create($year, $month, $cdate); // Year, Month, Day
        $formattedDate = $date->format('Y-m-d');

        // Get the week of the day (0 for Sunday, 1 for Monday, and so on)
        $weekDay = $date->format('l');
        $monthname   = $date->format('F');

        $selectedDate  = $request->input('selectedDate') ?? date('d');
        $selectedMonth = $request->input('selectedMonth') ?? $monthname;
        $selectedYear  = $request->input('selectedYear') ?? date('Y');
        $dayOfWeekName = $request->input('dayOfWeek') ?? $weekDay;
         

        $months = $this->monthNameToNumber($selectedMonth);
        $formattedDate = date('Y-m-d', strtotime($selectedYear . '-' . $months . '-' . $selectedDate));

        $dayOfWeekValue = array_search($dayOfWeekName, daysOfWeek());

        $query = AppointmentDoctorShiftDay::leftJoin('appointment_shifts', 'appointment_doctor_shift_days.shift_id', '=', 'appointment_shifts.id')
            ->leftJoin('appointment_doctor_shifts', 'appointment_shifts.id', '=', 'appointment_doctor_shifts.shift_id')
            ->leftJoin('doctors', 'appointment_doctor_shift_days.doctor_id', '=', 'doctors.id')
            ->where('appointment_doctor_shift_days.doctor_id', $id)
            ->where('appointment_doctor_shifts.doctor_id', $id)
            ->where('appointment_doctor_shifts.status', 1)
            ->where('appointment_doctor_shift_days.day_id', $dayOfWeekValue)
            ->where('appointment_doctor_shifts.status', '1')
            ->select(
                'appointment_doctor_shifts.doctor_id',
                'appointment_doctor_shifts.shift_id',
                'appointment_doctor_shifts.patient_quantity',
                'appointment_doctor_shifts.time_to',
                'appointment_doctor_shifts.time_from',
                'appointment_doctor_shifts.serial_start',
                'appointment_shifts.name',
                'appointment_shifts.color',
                'appointment_shifts.bg_color',
                'doctors.gap_between_two_patient',
                'appointment_doctor_shifts.id'
            )
            ->orderBY('appointment_shifts.priority', 'asc')
            ->get();

        if ($request->ajax()) {
            return view('opd-bookings.opd-shift-timing', compact(
                'query',
                'selectedDate',
                'selectedMonth',
                'dayOfWeekName',
                'formattedDate',
                'doctor',
                'bookingType'
            ));
        }

        return view('opd-bookings.make-appointment', compact(
            'query',
            'doctor',
            'doctorFee',
            'days_array',
            'selectedDate',
            'selectedMonth',
            'dayOfWeekName',
            'formattedDate',
            'bookingType'
        ));
    }

    public function doctorAppointmentDays(Request $request, $id)
    {
        $selectedDate  = $request->input('selectedDate');
        $selectedMonth = $request->input('selectedMonth');
        $selectedYear  = $request->input('selectedYear');
        $dayOfWeekName = $request->input('dayOfWeek');

        $dayOfWeekValue = array_search($dayOfWeekName, daysOfWeek());
        // dd($dayOfWeekValue);
        // $query = AppointmentDoctorShiftDay::with('getDoctor')->with('getDoctorAppointmentshift')->with('getShifts')->with('getShiftNames')
        $query = AppointmentDoctorShiftDay::with('getDoctor')->with('getShiftNames')
            ->where('doctor_id', $id)
            ->where('status', 1)
            ->where('day_id', $dayOfWeekValue)
            ->get();
        // dd($query);

        return view('opd-bookings.opd-shift-timing', compact('query'));
    }

    public function appointmentFOrm(Request $request, $doctor_id, $shift_id, $time, $date, $block_no, $booking_type = null)
    {

        //dd('hello');
        $doctor          = Doctor::with('getAccount', 'getOrganizatioDepartment', 'getOpdSchedule')->find($doctor_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('opd_billing_products_cart') ?? [];

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

        $currentDateTime = Carbon::now();
        // Add 5 minutes to the current date and time
        $newDateTime = $currentDateTime->addMinutes(5);
        $currenttime = $currentDateTime->format('Y-m-d H:i:s');
        OpdBlockSerial::where('current_date_time', '<', now())->delete();
        $BlockSerial = OpdBlockSerial::where([
            'slot_no'   => $block_no,
            'shift_id'  => $shift_id,
            'doctor_id' => $doctor_id,
            'cdate'     => $date,
            'ctime'     => $time,
        ])
            ->where('login_id', '!=', \Auth::user()->id)
            ->first();

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

        if (!empty($BlockSerial)) {
            return redirect()->route('make.appointment', $doctor_id)
                ->with('error', 'This Slot is block for 5 mint please wait or choose another slot');
        } else {
            OpdBlockSerial::create([
                'slot_no'                   => $block_no,
                'shift_id'                  => $shift_id,
                'doctor_id'                 => $doctor_id,
                'cdate'                     => $date,
                'ctime'                     => $time,
                'current_date_time'         => $newDateTime,
                'login_id'                  => \Auth::user()->id

            ]);
        }

        $doctorFee = \DB::table('appointment_doctor_fees')
            ->leftJoin('product_prices', 'appointment_doctor_fees.product_id', '=', 'product_prices.product_id')
            ->select('appointment_doctor_fees.id', \DB::raw('SUM(product_prices.mrp) as total_amount'))
            ->where('appointment_doctor_fees.doctor_id', $doctor_id)
            ->groupBy('appointment_doctor_fees.doctor_id')
            ->first();
        $shift = AppointmentShift::find($shift_id);

        // First Clear All Cart Data
        // $data = [];
        // \Session::put('opd_billing_products_cart', $data);
        $data = \Session::get('opd_billing_products_cart') ?? [];
        $patient_id=$data['patient_id'] ??'';
        $this->AddToCart($shift_id, $doctor_id, $doctor->account_id, $time, $date, $block_no,$patient_id);

        $patient  = '';
        if (!empty($patient_id) && isset($patient_id) && $patient_id != '') {
            $patient = Account::getAccount([
                'account_types.type_code' => 'PATIENT',
                'accounts.id' => $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 : '');
            }
        }


        /**************************Direct Convert To Appointment**************************/
        if ($booking_type == 'Appointment') {
            $data = \Session::get('opd_billing_products_cart') ?? [];
            $opb_booking_id = 0;

            return redirect()->route('opd-bookings.convert', ['invoice_id' => $opb_booking_id, 'booking_type' => 'Appointment']);
        } else {
            // Clear all data in the cart
            //$data = [];
            // Update the session with the empty cart
            // \Session::put('opd_billing_products_cart', $data);
            //dd($data);

            
            return view('opd-bookings.appointment-form', compact(
                'doctor_id',
                'shift_id',
                'time',
                'date',
                'doctor',
                'doctorFee',
                'shift',
                'block_no',
                'productCategory',
                'countryCode',
                'account',
                'data',
                'patient'
            ));
        }
    }

    public function appointmentsave(Request $request)
    {
        $validator =  Validator::make($request->all(), [
            'patient_id' => 'required',
        ]);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'message' => $validator->errors()->all()]);
        } else {

            $booking_id    = BookingCalendar::max('booking_id');
            $booking_id    = $booking_id != '' ? $booking_id : 1;

            BookingCalendar::create([
                'customer_account_id'   => $request->patient_id,
                'doctor_ac_id'          => $request->doctor_ac_id,
                'shift_id'              => $request->shift_id,
                'appointment_date'      => $request->appointment_date,
                'appointment_time'      => $request->appointment_time,
                'appointment_serial_no' => $request->appointment_serial_no,
                'booking_id'            => $booking_id + 1,
            ]);
            $Redirect = route('opd-bookings.doctor-List');
            return response()->json([
                'success' => true,
                'message' => ['Thank You For Booking successfully created'],
                'data' => [
                    'redirect' => $Redirect,
                    'reload' => true,
                ]
            ]);
        }
    }

    public function searchProducts(Request $request)
    {
        $searchTerm = $request->search;
        $shift_id   = $request->shift_id;
        $doctor_id  = $request->doctor_id;
        $category_id   = $request->category_id ?? '';
        $doctor     = Doctor::select('id')->where(['account_id' => $doctor_id])->first();
        $results    = Product::select(
            'products.id',
            'products.name',
            'products.shortcode',
            'products.hsncode',
            'product_prices.mrp',
            'product_prices.id as price_id'
        )
            // ->leftjoin('products', 'products.id', 'appointment_doctor_fees.product_id')
            ->leftjoin('product_prices', 'product_prices.product_id', 'products.id')
            // ->where('appointment_doctor_fees.shift_id', $shift_id)
            // ->where('appointment_doctor_fees.doctor_id', $doctor->id)
            ->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 . "%")
                    ->orWhere('product_prices.bar_code','LIKE',  "%" . $searchTerm . "%");
            })
            ->when($category_id != '', function ($query) use ($category_id) {
                $query->where('products.category_id', $category_id);
            })
            ->limit(15)
            ->get();

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

    public function productCart(Request $request, $id = 0)
    {
        $page = $request->page ?? '';
        $data = \Session::get('opd_billing_products_cart') ?? [];

        return view('opd-bookings.product-cart', compact('data', 'page', 'id'));
    }

    public function productAddToCart(Request $request)
    {
        $data = \Session::get('opd_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;
        }

        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['shift_id'])) {
            $data['shift_id'] = $request->shift_id;
        }

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

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

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


        $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;
        $amount        =  $main_qty * $request->product_price;
        $flat_discount = '0';
        $per_discount  = '0';

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

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

        $tax  = ($tax_per / 100) * $amount;

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

        $amount = $amount + $tax;
        $data_amount = $data['amount'] ?? 0;

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

        $data['due_balance_amount'] = round($data['amount']);

        $data['products'][] = [
            'main_qty'        => $request->main_qty ?? 1,
            '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'   => $request->product_price ?? '',
            'flat_discount'   => $flat_discount ?? '',
            'per_discount'    => $per_discount ?? '',
            'product_details' => '',
            'vial_code'       => '',
            'amount'          => $amount ?? '',
            'tax_per'         => $tax_per,
            'tax_flat'        => $tax,
        ];

        \Session::put('opd_billing_products_cart', $data);

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

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

        $amount = $data['amount'];

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

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

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

        \Session::put('opd_billing_products_cart', $data);

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

    public function cartProductUpdate(Request $request)
    {
        $data = \Session::get('opd_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->special_discount) || isset($request->discount_type) || isset($request->amount_recieved)) {
                if ($data['discount_type'] == 'FLAT') {
                    $due_balance_amount = round($data['amount']) - $data['special_discount'];
                    $data['due_balance_amount'] = $due_balance_amount - $data['amount_recieved'];
                } else {
                    $flat_discount = ($data['special_discount'] / 100) * $data['amount'];
                    $due_balance_amount = round($data['amount']) - $flat_discount;
                    $data['due_balance_amount'] = $due_balance_amount - $data['amount_recieved'];
                }
            }
        } else {
            if (isset($data['products'])) {
                foreach ($data['products'] as $key => $value) {
                    if ($value['product_id'] == $request->id && isset($request->product_details)) {
                        $data['products'][$key]['product_details'] = $request->product_details;
                    }
                    if ($value['product_id'] == $request->id && isset($request->vial_code)) {
                        $data['products'][$key]['vial_code'] = $request->vial_code;
                    }

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

                            $amount             = $request->main_qty * $value['product_price'];
                            $flat_discount      = ($value['per_discount'] / 100) * $amount;

                            $flat_tax           = ($value['tax_per'] / 100) * $amount;
                            $amount             = ($amount - $flat_discount);
                            $amount             = ($amount + $flat_tax);

                            $data['products'][$key]['flat_discount'] = $flat_discount;
                            $data['products'][$key]['tax_flat'] = $flat_tax;
                            $data['products'][$key]['amount'] = $amount;
                            $data['amount'] = $data['amount'] + $amount;
                        }
                    }

                    if ($value['product_id'] == $request->id && isset($request->product_price)) {
                        $data['amount'] = $data['amount'] - $value['amount'];
                        $data['products'][$key]['product_price'] = $request->product_price;

                        $main_qty =  $value['main_qty'];

                        $amount = $value['product_price'] * $main_qty;
                        $flat_discount = ($value['per_discount'] / 100) * $amount;
                        $flat_tax = ($value['tax_per'] / 100) * $amount;
                        $amount =  ($amount - $flat_discount);
                        $amount =  ($amount + $flat_tax);
                        $data['products'][$key]['flat_discount'] = $flat_discount;
                        $data['products'][$key]['tax_flat'] = $flat_tax;
                        $data['products'][$key]['amount'] = $amount;
                        $data['amount'] = $data['amount'] + $amount;
                        $data['due_balance_amount'] = round($data['amount']);
                    }
                    if ($value['product_id'] == $request->id && isset($request->per_discount)) {
                        $data['amount'] = $data['amount'] - $value['amount'];
                        $data['products'][$key]['per_discount'] = $request->per_discount;

                        $main_qty = $value['main_qty'] > 0 ? $value['main_qty'] : 1;

                        $amount = $value['product_price'] * $main_qty;
                        $flat_discount = ($request->per_discount / 100) * $amount;
                        $flat_tax = ($value['tax_per'] / 100) * $amount;
                        $amount =  ($amount - $flat_discount);
                        $amount =  ($amount + $flat_tax);
                        $data['products'][$key]['flat_discount'] = $flat_discount;
                        $data['products'][$key]['tax_flat'] = $flat_tax;
                        $data['products'][$key]['amount'] = $amount;
                        $data['amount'] = $data['amount'] + $amount;


                        $data['due_balance_amount'] = round($data['amount']);
                    }
                    if ($value['product_id'] == $request->id && isset($request->flat_discount)) {
                        $data['amount'] = $data['amount'] - $value['amount'];
                        $data['products'][$key]['flat_discount'] = $request->flat_discount;

                        $main_qty = $value['main_qty'] > 0 ? $value['main_qty'] : $value['main_qty'];

                        $amount = $value['product_price'] * $main_qty;
                        $per_discount = ($request->flat_discount / $amount) * 100;
                        $flat_tax = ($value['tax_per'] / 100) * $amount;
                        $amount =  ($amount - $request->flat_discount);
                        $amount =  ($amount + $flat_tax);
                        $data['products'][$key]['per_discount'] = $per_discount;
                        $data['products'][$key]['tax_flat'] = $flat_tax;
                        $data['products'][$key]['amount'] = $amount;
                        $data['amount'] = $data['amount'] + $amount;

                        $data['due_balance_amount'] = round($data['amount']);
                    }
                }
            }

            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('opd_billing_products_cart', $data);

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


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

    function AddToCart($shift_id, $doctor_id, $account_id, $time, $date, $block_no,$patient_id=null)
    {

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

        $productId = [];
        if(isset($data) && !empty($data))
        {
            //dd($data);
            $cartProduct = $data['products'];
           
            foreach($cartProduct as $key=> $row)
            {
                $productId[$key]= $row['product_id'];
            }
        }
       

        $product    = AppointmentDoctorFees::select(
            'products.id',
            'products.name',
            'products.shortcode',
            'products.hsncode',
            'product_prices.mrp',
            'product_prices.id as price_id',
            'product_brands.name as brand',
            'tax_masters.name as tax'
        )
            ->leftjoin('products', 'products.id', 'appointment_doctor_fees.product_id')
            ->leftjoin('product_prices', 'product_prices.product_id', 'products.id')
            ->leftjoin('product_brands', 'product_brands.id', 'products.brand_id')
            ->leftjoin('tax_masters', 'tax_masters.id', 'products.tax_slab_id')
            ->where('appointment_doctor_fees.shift_id', $shift_id)
            ->where('appointment_doctor_fees.doctor_id', $doctor_id)
            ->get();

        if (!isset($data['patient_id']) || $data['patient_id'] == '') {
            $data['patient_id'] = $patient_id;
        }
        if (!isset($data['doctor_id']) || $data['doctor_id'] == '') {
            $data['doctor_id'] = $account_id;
        }
        if (!isset($data['amount'])) {
            $data['amount'] = 0;
        }
        if (!isset($data['shift_id'])) {
            $data['shift_id'] = $shift_id;
        }
        if (!isset($data['time'])) {
            $data['time'] = $time;
        }

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

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

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

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

        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');
        }

        foreach ($product as $products) 
        {
            if(!in_array($products->id,$productId))
            {

            $main_qty = 1;
            $amount        =  $main_qty * $products->mrp;
            $flat_discount = '0';
            $per_discount  = '0';


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

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

            $tax  = ((float)$tax_per / 100) * $amount;

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

            $amount = $amount + $tax;
            $data_amount = $data['amount'] ?? 0;

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

            $data['due_balance_amount'] = round($data['amount']);

            $data['products'][] = [
                'brand_id'        => '',
                'price_id'        => $products->price_id ?? '',
                'product_id'      => $products->id ?? '',
                'product'         => $products->name ?? '',
                'hsncode'         => $products->hsncode ?? '',
                'brand'           => $products->brand ?? '',
                'product_price'   => $products->mrp ?? '',
                'flat_discount'   => $flat_discount ?? '',
                'per_discount'    => $per_discount ?? '',
                'product_details' => '',
                'vial_code'       => '',
                'amount'          => $amount ?? '',
                'main_qty'        => 1,
                'tax_per'         => $tax_per,
                'tax_flat'        => $tax,
            ];

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


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

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

            return redirect()->route('make.appointment')->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;
        }

        // dd($ids);
        $accounts = Account::select([
            'accounts.id',
            'accounts.account_type_id',
            'account_types.type_code',
            'account_contacts.qualifications',
            '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('make.appointment')->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;
            }
        }

        $special_cases    = SpecialCase::select(['id', 'name'])->where('status', 1)->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::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();
        $discount_group = Account::select(['id', 'name'])->where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::select(['id', 'name'])->where(['code' => 'ROUN_OFF'])->first();
        return view('opd-bookings.billing', compact([
            'data',
            'doctors',
            'patients',
            'refferal_lab',
            'voucher_master',
            'collection_agent',
            'bussiness_source',
            // 'payment_types',
            'special_cases',
            'accounting_group',
            'discount_group',
            'round_off'
        ]));
    }

    public function editBilling($id)
    {
        $sale_invoice = OpdBookings::find($id);

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

            return redirect()->route('opd-bookings.index')->with('error', 'OPD Booking billing invoice not found!');
        }

        $data = \Session::get('opd_billing_products_cart') ?? [];
        //dd($data);


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

            return redirect()->route('opd-bookings.edit', $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.qualifications',
            '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('opd-bookings.create')->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;
            }
        }

        $special_cases    = SpecialCase::select(['id', 'name'])->where('status', '1')->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::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();
        $creditTransaction = [];
        $AcReceipt = AcReceipt::where(['voucher_id' => $id, 'module_code' => 'OPD_BOOKING'])->first();
        if ($AcReceipt) {
            $creditTransaction = AcReceiptDetail::with('account')
                ->where(['voucher_id' => $AcReceipt->id, 'transaction_type' => 'DEBIT'])
                ->get();
        }
        //dd($creditTransaction);
        $discount_group = Account::select(['id', 'name'])->where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::select(['id', 'name'])->where(['code' => 'ROUN_OFF'])->first();
        $transactionSummery = $this->TransactionSummery($id, 'OPD_BOOKING');
        $transactionHistory = $this->transactionHistory($id, 'OPD_BOOKING');
        return view('opd-bookings.edit.billing', compact([
            'id',
            'data',
            'doctors',
            'patients',
            'sale_invoice',
            'refferal_lab',
            // 'voucher_master',
            'collection_agent',
            'bussiness_source',
            // 'payment_types',
            'special_cases',
            'accounting_group',
            'creditTransaction',
            'discount_group',
            'round_off',
            'transactionHistory',
            'transactionSummery'



        ]));
    }

    public function invoice($id)
    {
        $sale_invoice = OpdBookings::with('getOpdBookingDetails')
            ->with('getPatient')
            ->with('getDoctorAccount')
            ->with('getCompany')
            ->find($id);

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

        $AcReceipt = AcReceipt::select(['id', 'voucher_id'])
            ->with(['accountReceiptReceivedAmount'])
            ->where(['module_code' => 'OPD_BOOKING', 'voucher_id' => $id])
            ->get();

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

        $transactionSummery = $this->TransactionSummery($id, 'OPD_BOOKING');
        $transactionHistory = $this->transactionHistory($id, 'OPD_BOOKING');

        $letter_heads = LetterHead::voucherLetterHead(['voucher_types.code' => 'OPD']);

        return view('invoice-formats.opd.opd-billing-invoice', compact('sale_invoice', 'voucher_type', 'AcReceipt', 'transactionSummery', 'transactionHistory','letter_heads'));
    }

    public function productConvert(Request $request, $id = 0, $booking_type = null)
    {
        $page = $request->page ?? '';
        $data = \Session::get('opd_billing_products_cart') ?? [];

        return view('opd-bookings.edit.convert-product-cart', compact('data', 'page', 'id', 'booking_type'));
    }

    public function convert($id = null, $booking_type = null)
    {
        $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();

        $opdBooking      = OpdBookings::with('getOpdBookingDetails')->find($id);

        $patient         = $doctor = $collection_agent = $refferal_lab = '';
        $sale_invoice    = '';
        if ($booking_type != 'Appointment') {
            $data            = [];
            if ($opdBooking) {

                $appointment_date_time = Carbon::parse($opdBooking->appointment_date_time);
                $data['shift_id']               = $opdBooking->shift_id;
                $data['time']                   = $appointment_date_time->format('H:i:s');
                $data['date']                   = $appointment_date_time->format('Y-m-d');
                $data['block_no']               = $opdBooking->appointment_serial_no;
                $data['patient_id']             = $opdBooking->patient_id;
                $data['doctor_id']              = $opdBooking->doctor_ac_id;
                $data['refferal_id']            = $opdBooking->refferal_lab_id;
                $data['collection_id']          = $opdBooking->collection_agent_id;
                $data['amount']                 = $opdBooking->total_billing;
                $data['special_discount']        = $opdBooking->special_discount;
                $data['received_amount']        = $opdBooking->amount_recieved;
                $data['due_balance_amount']     = $opdBooking->due_balance_amount;
                $data['discount_type']          = 'FLAT';
                $data['sample_receive_time']    = $opdBooking->sample_receive_time;
                $data['invoice_date']           = $opdBooking->invoice_date;
                $data['sample_receive_date']    = $opdBooking->sample_receive_date;
                $data['payment_mode_id']        = $opdBooking->payment_mode_id;
                $data['payment_term_id']        = $opdBooking->payment_term_id;
                $data['special_case']           = $opdBooking->special_case_id;
                $data['sample_barcode']         = $opdBooking->sample_barcode;
                $data['reff_no']                = $opdBooking->reff_no;
                $data['sale_remarks']           = $opdBooking->remarks;
                $data['remarks_for_technician'] = $opdBooking->remarks_for_technician;

                foreach ($opdBooking->getOpdBookingDetails as $key => $value) {

                    $amount        =  $value->price;
                    // dd($amount);

                    // $flat_discount = '0';
                    // $per_discount  = '0';
                    $main_qty = $value->main_qty > 0 ? $value->main_qty : ($value->alt_qty > 0 ? $value->alt_qty : 1);
                    $main_qty_amount = $main_qty * $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;

                    $data['products'][] = array(
                        'brand_id'        => $value->getProduct->brand_id ?? '',
                        'price_id'        => $value->price_id ?? '',
                        'product_id'      => $value->product_id ?? '',
                        'product'         => $value->getProduct->name ?? '',
                        'hsncode'         => $value->getProduct->hsncode ?? '',
                        'brand'           => $value->getProduct->getProductBrand->name ?? '',
                        'product_price'   => $value->product_price ?? '0',
                        'flat_discount'   => $value->flat_discount ?? '0',
                        'per_discount'    => $value->per_discount ?? '0',
                        'product_details' => '',
                        'vial_code'       => '',
                        'amount'          => $value->amount ?? '0',
                        'main_qty'       => $value->main_qty ?? '0',
                        'tax_per'        => $tax_per,
                        'tax_flat'        => $tax ?? 0,
                    );
                }
            }

            \Session::put('opd_billing_products_cart', $data);

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

            if ($opdBooking && isset($opdBooking->patient_id) && $opdBooking->patient_id != '') {
                $patient = Account::getAccount([
                    'account_types.type_code' => 'PATIENT',
                    'accounts.id' => $opdBooking->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 ($opdBooking && isset($opdBooking->doctor_ac_id) && $opdBooking->doctor_ac_id != '') {
                $doctor = Account::getAccount([
                    'account_types.type_code' => 'DOCTOR',
                    'accounts.id' => $opdBooking->doctor_ac_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 ($opdBooking && isset($opdBooking->collection_id) && $opdBooking->collection_id != '') {
                $collection_agent = Account::getAccount([
                    'account_types.type_code' => 'COLLECTION_AGENT',
                    'accounts.id' => $opdBooking->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 ($opdBooking && isset($opdBooking->refferal_id) && $opdBooking->refferal_id != '') {
                $refferal_lab = Account::getAccount([
                    'account_types.type_code' => 'REFERRAL_PARTNER',
                    'accounts.id' => $opdBooking->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 : '');
                }
            }
        } else {
            $data = \Session::get('opd_billing_products_cart') ?? [];

            if ($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' : '') .
                        ($doctor->phone_no    != '' ? ', ' . $doctor->phone_no : '');
                }
            }
        }
        $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;
        }




        $special_cases    = SpecialCase::select(['id', 'name'])->where('status', '1')->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'])
            ->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();
        return view('opd-bookings.edit.convert', compact([
            'id',
            'data',
            'doctor',
            'patient',
            'sale_invoice',
            'refferal_lab',
            'productCategory',
            'collection_agent',
            'bussiness_source',
            'countryCode',
            'special_cases',
            'accounting_group',
            'booking_type'
        ]));
    }

    public function ConvertBilling($id, $booking_type = null)
    {
        $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();

        $opdBooking    = OpdBookings::with('getOpdBookingDetails')->find($id);
        $data            = [];
        $patient         = $doctor = $collection_agent = $refferal_lab = '';


        if ($booking_type != "Appointment") {
            $sale_invoice = OpdBookings::find($id);

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

                // return redirect()->route('opd-bookings.index')->with('error', 'OPD Booking billing invoice not found!');
            }
        } else {
            $sale_invoice = '';
        }

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

            return redirect()->route('opd-bookings.edit', $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.qualifications',
            '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('opd-bookings.create')->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;
            }
        }

        $special_cases    = SpecialCase::select(['id', 'name'])->where('status', '1')->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::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();

        $creditTransaction = [];
        $AcReceipt = AcReceipt::where(['voucher_id' => $id, 'module_code' => 'OPD_BOOKING'])->first();
        if ($AcReceipt) {
            // $creditTransaction = AcReceiptDetail::with('account')
            //     ->where(['voucher_id' => $AcReceipt->id, 'transaction_type' => 'DEBIT'])
            //     ->get();
            $creditTransaction = AcReceiptDetail::with('account')
                ->where(['voucher_id' => $AcReceipt->id, 'transaction_type' => 'DEBIT'])
                ->get();
            $debitTransaction = AcReceiptDetail::with('account')
                ->where(['voucher_id' => $AcReceipt->id, 'transaction_type' => 'CREDIT'])
                ->first();
        }
        $discount_group = Account::select(['id', 'name'])->where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::select(['id', 'name'])->where(['code' => 'ROUN_OFF'])->first();

        $transactionSummery = $this->TransactionSummery($id, 'OPD_BOOKING');
        $transactionHistory = $this->transactionHistory($id, 'OPD_BOOKING');

        return view('opd-bookings.edit.convert-billing', compact([
            'id',
            'data',
            'doctors',
            'patients',
            'sale_invoice',
            'refferal_lab',
            // 'voucher_master',
            'collection_agent',
            'bussiness_source',
            // 'payment_types',
            'special_cases',
            'accounting_group',
            'creditTransaction',
            'discount_group',
            'round_off',
            'transactionHistory',
            'transactionSummery',
            'booking_type'



        ]));
    }



    public function AppointmentConvert(Request $request, $id = null, $booking_type = null)
    {
       

        $data = \Session::get('opd_billing_products_cart') ?? [];
        if (empty($data)) {
            return redirect()->back()->with('error', 'Empty cart!');
        }
       
        if ($booking_type != 'Appointment') {

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

            $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'SALES_ORDER')->first();
            $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'OPD_BOOKING')->first();

            
            # last voucher count for main voucher type invoice number
            $voucher_type_last_count      = SaleInvoice::select('last_voucher_type_count')->where('voucher_type_code','OPD_BOOKING')->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->voucherSeries->start_from + 1 ?? 1);

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

           
            $doctorData = Doctor::where('account_id', $data['doctor_id'])->first();
          

            if ($doctorData->convert_to_sale == 1) {

               
                $existingInvoiceData = [
                    'voucher_type_code'       => ($voucher_type->code ?? ''),
                    'payment_term_id'         => $request->payment_term_id,
                    'billing_amount'          => $data['amount'],
                    'invoice_date'            => date('Y-m-d H:i:s'),
                    '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->recieved,
                    'due_amount'              => $data['due_balance_amount'],
                    'company_id'              => $company_id,
                    'status'                  => 'NEWSALE',
                    '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,
                    'invoice_type'            => 'opd-booking',
                    
                ];
               
                $existingInvoice = SaleInvoice::create($existingInvoiceData);

               // dd($existingInvoice);

                $opdBookingData = OpdBookings::find($id);
                $opdBookingData->update([
                    'sale_invoice_id'       => $existingInvoice->id ?? '',
                    'invoice_status'        => 'Pending',
                    'service_status'        => 'Pending',
                    'appointment_status'    => 'Done',
                    'invoice_type'          => 'opd-booking',
                    'patient_id'            => $data['patient_id'],
                    'amount_recieved'       => $request->recieved,
                    'due_balance_amount'    => $request->due_balance_amount,
                    'discount_type'         => $request->discount_type,
                    'special_discount'      => $request->special_discount,
                    'chamber_id'            => $doctorData->doctors_chamber_id ?? 1,
                ]);
                $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('created_at', 'DESC')->first();
                

                $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)
                );

                // $data['invoice_batch_no']   = $main_invoice_no;
                $data['last_voucher_count'] = $last_voucher_count_batch;
                $invoice_batch = SaleInvoiceBatch::where(['referrence_voucher_id'=>$id,'referrence_voucher_type'=>'OPD_BOOKING'])->first();
                if($invoice_batch)
                {
                    $invoice_batch->update(['invoice_id'=>$existingInvoice->id]);
                }
                else
                {
                    $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'],
                        'referrence_voucher_id'  => $id,
                        'referrence_voucher_type'=> 'OPD_BOOKING'
                    ];
                    //sale invoice batch
                    $invoice_batch  = SaleInvoiceBatch::create($invoice_batch);
                }
               
    

                if ($opdBookingData->batch_id == '') {
                    $opdBookingData->update(['batch_id' => $invoice_batch->id]);
                }

                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['amount'],
                        'discount_percentage' => $value['per_discount'],
                        'discount_amount'     => $value['flat_discount'],
                        'total_amount'        => $value['amount'],
                        'item_details'        => $value['product_details'],
                        'item_batch'          => $product->getProductPrice->batch ?? '',
                        'tax_slab_id'         => $product->tax_slab_id ?? '',
                        'main_qty'            => 1
                    ];

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

                    foreach ($product_test_package as $package) {
                        $addedTestPackage = 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'        => 'OPD_BOOKING',
                            'status'                 => 'SAMPLE_COLLECTION',
                            'task_status_id'         => $task_status->id ?? '',
                            'review_status_id'       => $task_status->id ?? '',
                        ]);
                    }
                }
            } else {
                $opdBookingData = OpdBookings::find($id);
                $opdBookingData->update([
                    'invoice_status'        => 'Pending',
                    'service_status'        => 'Pending',
                    'appointment_status'    => 'Done',
                    'invoice_type'          => 'opd-booking',
                    'patient_id'            => $data['patient_id'],
                    'amount_recieved'       => $request->recieved,
                    'due_balance_amount'    => $request->due_balance_amount,
                    'discount_type'         => $request->discount_type,
                    'special_discount'      => $request->special_discount,
                    'chamber_id'            => $doctorData->doctors_chamber_id ?? 1,
                ]);
                if ($opdBookingData->batch_id == '') {

                    //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('created_at', 'DESC')->first();

                    $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)
                    );
                    $data['last_voucher_count'] = $last_voucher_count_batch;

                    $invoice_batch = [
                        'invoice_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'],
                        'referrence_voucher_id'  => $id,
                        'referrence_voucher_type'=> 'OPD_BOOKING'
                    ];
                    //sale invoice batch
                    $invoice_batch  = SaleInvoiceBatch::create($invoice_batch);
                    /********************* OPD Booking Update Sale Batch Id ************************/
                    $opdBookingData->update(['batch_id' => $invoice_batch->id]);
                }
            }



            /*********************  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)
                );
                $company_address = \Session::get('company_data')['companies_addresses'];
                $currency_id     = $company_address->currency_id ?? '';
                $this->SaleOthersTransaction(
                    $id,
                    $transactions_no,
                    'OPD_BOOKING',
                    $request->discount_account_id,
                    $request->special_discount
                );
            }
            $discount['mode_id'] = $request->discount_account_id ?? '';
            $discount['amount'] = $request->special_discount ?? '';
            /********************* 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)
                );
                $company_address = \Session::get('company_data')['companies_addresses'];
                $currency_id     = $company_address->currency_id ?? '';
                $this->SaleOthersTransaction(
                    $id,
                    $transactions_no,
                    'OPD_BOOKING',
                    $request->round_off_account_id,
                    $request->round_off_amount
                );
            }
            $roundOff['mode_id'] = $request->round_off_account_id ?? '';
            $roundOff['amount'] = $request->round_off_amount ?? '';
            /********************* End  Round Off Store Calculation ***********************/


            

            $opb_booking_id = $id;

            $acReceiptDataCheckAdvance = AcReceipt::select('id')->where([
                'voucher_id'        => $opb_booking_id,
                'module_code'       => 'OPD_BOOKING',
                'settlement_status' => 'No'
            ])->get();
            if ($acReceiptDataCheckAdvance) {
                foreach ($acReceiptDataCheckAdvance as $list) {
                    AcReceipt::find($list->id)->update([
                        'settlement_status'      => 'Yes',
                        'settlement_voucher_id'  => $opb_booking_id,
                        'settlement_module_code' => 'OPD_BOOKING'
                    ]);
                }
            }

            if ($booking_type == 'Appointment') {
                $this->createTransaction(
                    'OPD_BOOKING',
                    $opb_booking_id,
                    $invoice_batch->id,
                    $voucher_type->code,
                    $data['patient_id'],
                    $data,
                    $roundOff,
                    $discount,
                    $request->special_discount
                );
            }
            if ($request->recieved > 0) {
                $this->UpdateAcReceiptAndTransaction(
                    $request->payment_mode_id ?? '',
                    $data['patient_id'],
                    $request->recieved,
                    $transaction->id ?? '',
                    $opb_booking_id,
                    'OPD_BOOKING',
                    $request->payment_mode,
                    'received',
                );
            }
        } else {
            $id = $this->directAppointmentConvert($request, $data);
        }

        \Session::forget('opd_billing_products_cart');
        if ($booking_type != 'Appointment') {
            return redirect()->route('opd-bookings.invoice', $id)->with('success', "New Bill Created Successfully");
        } else {
            return redirect()->route('opd-bookings.slip', $id)->with('success', "New Bill Created Successfully");
        }
    }


    public function directAppointmentConvert($request, $data)
    {
        $data = \Session::get('opd_billing_products_cart') ?? [];
        if (
            empty($data) || !isset($data['patient_id']) ||
            !isset($data['doctor_id']) || !isset($data['shift_id']) ||
            !isset($data['date']) || !isset($data['time']) ||
            !isset($data['block_no'])
        ) {
            return redirect()->back()->with('error', 'Empty cart!');
        }

        $combinedDateTime = Carbon::parse($data['date'] . ' ' . $data['time']);
        $appointment_date_time = $combinedDateTime->format('Y-m-d H:i:s');

        $checkBooking = OpdBookings::where(['doctor_ac_id'=>$data['doctor_id'],'shift_id'=>$data['shift_id'],
        'appointment_date_time'=>$appointment_date_time,'appointment_serial_no'=>$data['block_no']])->first();
        if(isset($checkBooking))
        {
           
                if ($request->ajax()) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Booking Number Already Book Another User Please Select Another Token Number',
                        'data'    => []
                    ]);
                }
    
                return redirect()->back()->with('error', 'Booking Number Already Book Another User Please Select Another Token Number');
            
        }

        //dd('hello');
        $booking_id = BookingCalendar::max('booking_id');
        $booking_id = $booking_id != '' ? $booking_id + 1 : 1;

        BookingCalendar::create([
            'customer_account_id'   => $data['patient_id'],
            'doctor_ac_id'          => $data['doctor_id'],
            'shift_id'              => $data['shift_id'],
            'appointment_date'      => $data['date'],
            'appointment_time'      => $data['time'],
            'appointment_serial_no' => $data['block_no'],
            'booking_id'            => $booking_id,
        ]);

       

        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'OPD_BOOKING')->first();
        # last voucher count for main voucher type OpdBookings number
        $voucher_type_last_count = OpdBookings::select('last_count')->orderBy('created_at', 'DESC')->first();
        $voucher_type_count = isset($voucher_type_last_count) && isset($voucher_type_last_count->last_count) ? $voucher_type_last_count->last_count + 1 : ($voucher_type->voucherSeries->start_from + 1 ?? 1);

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

        $doctor = Doctor::where('account_id', $data['doctor_id'])->first();


        $doctorData = Doctor::where('account_id', $data['doctor_id'])->first();


        $company_id     = \Auth::user()->company_id ?? '';
        $opd_store = [
            'company_id'            => $company_id,
            'booking_id'            => $booking_id,
            'patient_id'            => $data['patient_id'],
            'doctor_ac_id'          => $data['doctor_id'],
            'booking_date_time'     => date('Y-m-d H:i:s'),
            'shift_id'              => $data['shift_id'],
            'appointment_date_time' => $appointment_date_time,
            'appointment_serial_no' => $data['block_no'],
            'total_billing'         => $data['amount'],
            'special_discount'      => $data['special_discount'],
            'discount_type'         => $data['discount_type'],
            'due_balance_amount'    => $data['due_balance_amount'],
            'payment_mode_id'       => $request->payment_mode_id ?? '',
            'amount_recieved'       => $request->recieved ?? '',
            'reff_no'               => $request->reff_no,
            'bussiness_source'      => $request->bussiness_source,
            'sale_remarks'          => $request->sale_remarks,
            'last_count'            => $voucher_type_count,
            'booking_no'            => $booking_no,
            'chamber_id'            => $doctor->doctors_chamber_id ?? 1,
            'invoice_status'        => 'Pending',
            'service_status'        => 'Pending',
            'appointment_status'    => 'Done',
            'invoice_type'          => 'opd-booking',
            'operator_id'           => \Auth::user()->id ?? '',
        ];
        $OpdBooking = OpdBookings::create($opd_store);
        $opb_booking_id = $OpdBooking->id;
        foreach ($data['products'] as $list) {
            OpdBookingDetail::create([
                'opd_booking_id'  => $opb_booking_id,
                'product_id'      => $list['product_id'],
                'price_id'        => $list['price_id'],
                'brand_id'        => $list['brand_id'],
                'product_price'   => $list['product_price'],
                'per_discount'    => $list['per_discount'],
                'flat_discount'   => $list['flat_discount'],
                'amount'          => $list['amount'],
            ]);
        }

        if ($doctorData->convert_to_sale == 1) {

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

            $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'SALES_ORDER')->first();
            $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'OPD_BOOKING')->first();


            # last voucher count for main voucher type invoice number
            $voucher_type_last_count      = SaleInvoice::select('last_voucher_type_count')->where('voucher_type_code','OPD_BOOKING')->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->voucherSeries->start_from + 1 ?? 1);

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

            $existingInvoice = [
                'voucher_type_code'       => ($voucher_type->code ?? ''),
                'payment_term_id'         => $request->payment_term_id,
                'billing_amount'          => $data['amount'],
                'invoice_date'            => date('Y-m-d H:i:s'),
                '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->recieved,
                '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,
                'invoice_type'            => 'opd-booking',
            ];

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

            $opdBookingData = OpdBookings::find($opb_booking_id);
            $opdBookingData->update([
                'sale_invoice_id'       => $existingInvoice->id ?? '',
                'invoice_status'        => 'Pending',
                'service_status'        => 'Pending',
                'appointment_status'    => 'Done',
                'invoice_type'          => 'opd-booking',
                'patient_id'            => $data['patient_id'],
                'amount_recieved'       => $request->recieved,
                'due_balance_amount'    => $request->due_balance_amount,
                'discount_type'         => $request->discount_type,
                'special_discount'      => $request->special_discount,
                'chamber_id'            => $doctorData->doctors_chamber_id ?? 1,
            ]);
            $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('created_at', 'DESC')->first();

            $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)
            );

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

            $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'],
                'consultant_id'      => $data['doctor_id'],
                'created_by'         => \Auth::user()->id,
                'referrence_voucher_id'  => $opb_booking_id,
                'referrence_voucher_type'=> 'OPD_BOOKING'
            ];
            //sale invoice batch
            $invoice_batch  = SaleInvoiceBatch::create($invoice_batch);
            // dd($invoice_batch);

            if ($opdBookingData->batch_id == '') {
                $opdBookingData->update(['batch_id' => $invoice_batch->id]);
            }

            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['amount'],
                    'discount_percentage' => $value['per_discount'],
                    'discount_amount'     => $value['flat_discount'],
                    'total_amount'        => $value['amount'],
                    'item_details'        => $value['product_details'],
                    'item_batch'          => $product->getProductPrice->batch ?? '',
                    'tax_slab_id'         => $product->tax_slab_id ?? '',
                    'main_qty'            => 1
                ];

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

                foreach ($product_test_package as $package) {
                    $addedTestPackage = 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'        => 'OPD_BOOKING',
                        'status'                 => 'SAMPLE_COLLECTION',
                        'task_status_id'         => $task_status->id ?? '',
                        'review_status_id'       => $task_status->id ?? '',
                    ]);
                }
            }
        }
        else
        {

        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
        $voucher_count_batch      = SaleInvoiceBatch::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        $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)
        );
        $invoice_batchs = [
            'account_id'             => $data['patient_id'],
            'invoice_batch_date'     => Carbon::now(),
            'invoice_batch_no'       => $main_invoice_no,
            'created_by'             => \Auth::user()->id,
            'invoice_id'             => '',
            'last_voucher_count'     => $last_voucher_count_batch,
            'sample_barcode'         => $request->sample_barcode,
            'sample_receive_date'    => date('Y-m-d'),
            'sample_receive_time'    => $request->sample_receive_time,
            'remarks_for_technician' => $request->remarks_for_technician,
            'consultant_id'          => $doctor->id,
            'referrence_voucher_id'  => $opb_booking_id,
            'referrence_voucher_type'=> 'OPD_BOOKING'
        ];

        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::create($invoice_batchs);
        $opdBooking = OpdBookings::find($opb_booking_id);
        $opdBooking->update(['batch_id' => $invoice_batch->id]);
    }

        /*********************  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)
            );
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $opb_booking_id,
                $transactions_no,
                'OPD_BOOKING',
                $request->discount_account_id,
                $request->special_discount
            );
        }
        $discount['mode_id'] = $request->discount_account_id ?? '';
        $discount['amount'] = $request->special_discount ?? '';
        /********************* 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)
            );
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $opb_booking_id,
                $transactions_no,
                'OPD_BOOKING',
                $request->round_off_account_id,
                $request->round_off_amount
            );
        }
        $roundOff['mode_id'] = $request->round_off_account_id ?? '';
        $roundOff['amount'] = $request->round_off_amount ?? '';
        /********************* End  Round Off Store Calculation ***********************/



        $this->createTransaction(
            'OPD_BOOKING',
            $opb_booking_id,
            $invoice_batch->id,
            $voucher_type->code,
            $data['patient_id'],
            $data,
            $roundOff,
            $discount,
            $request->special_discount
        );

        if ($request->recieved > 0) {
            $this->createAcReceiptAndTransaction(
                $request->payment_mode_id ?? '',
                $data['patient_id'],
                $request->recieved,
                $transaction->id ?? '',
                $opb_booking_id,
                'OPD_BOOKING',
                $request->payment_mode,
                'received',
                $discount,
                $roundOff

            );
        }
        return $opb_booking_id;
    }

    public function opdSlip($id)
    {
        $letter_heads = LetterHead::voucherLetterHead(['voucher_types.code' => 'OPD_BOOKING']);

        $sale_invoice = OpdBookings::with('getOpdBookingDetails')
            ->with('getPatient')
            ->with('getDoctorAccount')
            ->with('getCompany')
            ->find($id);

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

        $AcReceipt = AcReceipt::select(['id', 'voucher_id'])
            ->with(['accountReceiptReceivedAmount'])
            ->where(['module_code' => 'OPD_BOOKING', 'voucher_id' => $id])
            ->get();
        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'OPD_BOOKING')->first();
        $transactionSummery = $this->TransactionSummery($id, 'OPD_BOOKING');
        $transactionHistory = $this->transactionHistory($id, 'OPD_BOOKING');

        return view('invoice-formats.opd.opd-billing-slip', compact('sale_invoice', 'voucher_type', 'AcReceipt', 'transactionSummery', 'transactionHistory','letter_heads'));
    }


    public function reschedule(Request $request, $id)
    {
        $opdData = OpdBookings::select(['id', 'shift_id', 'appointment_date_time', 'appointment_serial_no', 'doctor_ac_id'])
            ->with('getShiftNames')->find($id);
        $doctor = Doctor::with('getAccount', 'getOrganizatioDepartment', 'getOpdSchedule')
            ->where('account_id', $opdData->doctor_ac_id)->first();

        $alldays = AppointmentDoctorShiftDay::where('doctor_id', $doctor->id)->groupBy('day_id')->get();
        $bookingType = $booking_type ?? 'booking';
        $days_array = [];
        foreach ($alldays as $key => $list) {
            $days_array[$key] = $list->day_id;
        }

        $doctorFee = \DB::table('appointment_doctor_fees')
            ->leftJoin('product_prices', 'appointment_doctor_fees.product_id', '=', 'product_prices.product_id')
            ->select('appointment_doctor_fees.id', \DB::raw('SUM(product_prices.mrp) as total_amount'))
            ->where('appointment_doctor_fees.doctor_id', $doctor->id)
            ->groupBy('appointment_doctor_fees.doctor_id')
            ->first();

        $cdate = date('d');
        $month = date('m');
        $year = date('Y');
        $date = Carbon::create($year, $month, $cdate); // Year, Month, Day
        $formattedDate = $date->format('Y-m-d');

        // Get the week of the day (0 for Sunday, 1 for Monday, and so on)
        $weekDay = $date->format('l');
        $monthname   = $date->format('F');

        $selectedDate  = $request->input('selectedDate') ?? date('d');
        $selectedMonth = $request->input('selectedMonth') ?? $monthname;
        $selectedYear  = $request->input('selectedYear') ?? date('Y');
        $dayOfWeekName = $request->input('dayOfWeek') ?? $weekDay;

        $months = $this->monthNameToNumber($selectedMonth);

        $formattedDate = date('Y-m-d', strtotime($selectedYear . '-' . $months . '-' . $selectedDate));


        $dayOfWeekValue = array_search($dayOfWeekName, daysOfWeek());

        $query = AppointmentDoctorShiftDay::leftJoin('appointment_shifts', 'appointment_doctor_shift_days.shift_id', '=', 'appointment_shifts.id')
            ->leftJoin('appointment_doctor_shifts', 'appointment_shifts.id', '=', 'appointment_doctor_shifts.shift_id')
            ->leftJoin('doctors', 'appointment_doctor_shift_days.doctor_id', '=', 'doctors.id')
            ->where('appointment_doctor_shift_days.doctor_id', $doctor->id)
            ->where('appointment_doctor_shifts.doctor_id', $doctor->id)
            ->where('appointment_doctor_shifts.status', 1)
            ->where('appointment_doctor_shift_days.day_id', $dayOfWeekValue)
            ->where('appointment_doctor_shifts.status', '1')
            ->select(
                'appointment_doctor_shifts.doctor_id',
                'appointment_doctor_shifts.shift_id',
                'appointment_doctor_shifts.patient_quantity',
                'appointment_doctor_shifts.time_to',
                'appointment_doctor_shifts.time_from',
                'appointment_doctor_shifts.serial_start',
                'appointment_shifts.name',
                'appointment_shifts.color',
                'appointment_shifts.bg_color',
                'doctors.gap_between_two_patient',
                'appointment_doctor_shifts.id'
            )
            ->orderBY('appointment_shifts.priority', 'asc')
            ->get();
        if ($request->ajax()) {

            return view('opd-bookings.reschedule.opd-shift-timing', compact(
                'query',
                'selectedDate',
                'selectedMonth',
                'dayOfWeekName',
                'formattedDate',
                'doctor',
                'bookingType',
                'opdData'
            ));
        }

        return view('opd-bookings.reschedule.appointment', compact(
            'doctor',
            'doctorFee',
            'query',
            'selectedDate',
            'selectedMonth',
            'dayOfWeekName',
            'formattedDate',
            'days_array',
            'bookingType',
            'opdData'
        ));
    }

    public function rescheduleConfirm(Request $request, $doctor_id, $shift_id, $time, $date, $block_no, $booking_id)
    {
        
        $opdData = OpdBookings::find($booking_id);

        $combinedDateTime = Carbon::parse($date . ' ' . $time);
        $appointment_date_time = $combinedDateTime->format('Y-m-d H:i:s');

        $updateData = [
            'appointment_date_time' => $appointment_date_time,
            'shift_id'              => $shift_id,
            'appointment_serial_no' => $block_no,
            'check_in_time'         => null,
            'check_in_status'       => '0',
        ];
        $opdData->update($updateData);

        $bookingCalendar = BookingCalendar::where('booking_id', $booking_id)->first();

        $updateCalendar = [
            'shift_id'              => $shift_id,
            'appointment_date'      => $date,
            'appointment_time'      => $time,
            'appointment_serial_no' => $block_no
        ];
        // BookingCalendar::create([
        //     'customer_account_id'   => $data['patient_id'],
        //     'doctor_ac_id'          => $data['doctor_id'],
        //     'shift_id'              => $data['shift_id'],
        //     'appointment_date'      => $data['date'],
        //     'appointment_time'      => $data['time'],
        //     'appointment_serial_no' => $data['block_no'],
        //     'booking_id'            => $booking_id + 1,
        // ]);

        $bookingCalendar->update($updateCalendar);

        return redirect()->route('opd-bookings.slip', ['id' => $booking_id])->with('success', 'Booking Update Successfully');
    }
}