<?php

namespace App\Http\Controllers\LabBilling;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Account;
use App\Models\ProductBrand;
use App\Models\Product;
use App\Models\SaleInvoice;
use App\Models\SaleInvoiceDetail;
use App\Models\ProductTestPackage;
use App\Models\SaleInvoiceSubDetails;
use App\Models\SpecialCase;
use App\Models\VoucherMaster;
use App\Models\MasterSetting;
use App\Models\VoucherType;
use App\Models\EnquirySource;
use App\Models\AccountTransaction;
use App\Models\LabBillingReport;
use App\Models\Department;
use App\Models\TestPackage;
use App\Models\TaskStatus;
use App\Models\AcReceipt;
use App\Models\AcReceiptDetail;
use App\Models\VoucherCollection;
use App\Models\VoucherCollectionDetail;
use App\Models\DocumentManagement;
use App\Models\SaleInvoiceBatch;
use App\Models\SaleInvoiceTaskTracking;
use App\Models\StyleType;
use App\Models\TestItemOption;
use App\Models\TestItem;
use App\Models\IncentiveSlab;
use App\Models\LabReportResultBigText;
use App\Models\AdvanceSetting;
use App\Models\Company;
use App\Models\LetterHead;
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use Illuminate\Contracts\Session\Session;
use Illuminate\Support\Facades\Auth;
use App\Traits\AcReceiptAndTransactionAllTrait;
use App\Traits\BillingConceptTrait;
use App\Traits\TransactionSummeryTrait;
use function Termwind\style;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\LabBillingStatementExport;
use App\Models\ProductCategory;

class LabBillingsController extends Controller
{
    use AcReceiptAndTransactionAllTrait, TransactionSummeryTrait, BillingConceptTrait;

    // function __construct()
    // {
    //     $this->middleware('permission:pathology-lab-billing-list', ['only' => ['index']]);
    // }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        \Session::forget('billing_products_cart');
        $user = $this->get_user_info();

        $data = SaleInvoice::select(
                    'sale_invoices.*',
                    \DB::raw('COUNT(sale_invoice_sub_details.id) as sub_details_count'),
                    'task_statuses.name as task_status',
                    'task_statuses.code as status_code',
                )
                ->with('getSaleInvoiceDelivery')
                ->with('getSaleInvoiceDetail')
                ->with('getRefferalLab')
                ->with('getPatient')
                ->with('getDoctor')
                ->with('getOperator')
                ->with('getCollectionAgent')
                ->with('getAccountGroup')
                ->where('sale_invoices.voucher_type_code','PATHOLOGY')
                ->leftjoin('sale_invoice_sub_details','sale_invoice_sub_details.sale_invoice_id','sale_invoices.id')
                ->leftjoin('task_statuses','sale_invoice_sub_details.task_status_id','task_statuses.id')
                ->when($user && isset($user['type_code']) && $user['type_code'] == 'REFERRAL_PARTNER', function($query) {
                    $query->where('sale_invoices.refferal_lab_id', \Auth()->user()->account_id)
                        ->where('sale_invoices.company_id', \Auth()->user()->company_id);
                })
                ->when($user && isset($user['type_code']) && $user['type_code'] == 'DOCTOR', function($query) {
                    $query->where('sale_invoices.doctor_id', \Auth()->user()->account_id)
                        ->where('sale_invoices.company_id', \Auth()->user()->company_id);
                });

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

            $data = $data->where('voucher_type_code', 'PATHOLOGY')
                ->when(!empty($search_query) && !empty($search_type), function ($query) use ($search_type, $search_query) {
                    if ($search_type == 'invoice_no') {
                        $query->where('voucher_type_invoice_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.unique_register_no', 'LIKE', '%'.$search_query .'%');
                            });
                        });
                    } else if ($search_type == 'ref_name') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getRefferalLab', function ($patient) use ($search_query) {
                                $patient->where('accounts.name', 'LIKE', '%'.$search_query .'%');
                            });
                        });
                    } else if ($search_type == 'dr_name') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getDoctor', function ($patient) use ($search_query) {
                                $patient->where('accounts.name', 'LIKE', '%'.$search_query .'%');
                            });
                        });
                    } else if ($search_type == 'agent_name') {
                        $query->where(function ($q) use ($search_query) {
                            $q->whereHas('getCollectionAgent', function ($patient) use ($search_query) {
                                $patient->where('accounts.name', 'LIKE', '%'.$search_query .'%');
                            });
                        });
                    }
                })
                ->groupBy('sale_invoices.id')
                ->latest('sale_invoices.id')
                ->paginate($sort_by);

            return view('lab-billings.table', compact('data'));
        } else {
            $data = $data->groupBy('sale_invoices.id')
                ->latest('sale_invoices.id')
                ->paginate(10);

            return view('lab-billings.index', compact('data'));
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $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('billing_products_cart') ?? [];
        $patient         = $doctor = $collection_agent = $refferal_lab = '';
        $user = $this->get_user_info();

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

        if ((!empty($data) && isset($data['doctor_id']) && $data['doctor_id'] != '') && ($user && $user['type_code'] == 'DOCTOR')) {
            if ($user && $user['type_code'] == 'DOCTOR') {
                $data['doctor_id'] = \Auth()->user()->account_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 : '');
            }
        }

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

        if ((!empty($data) && isset($data['refferal_id']) && $data['refferal_id'] != '') || ($user && $user['type_code'] == 'REFERRAL_PARTNER')) {
            if ($user && $user['type_code'] == 'REFERRAL_PARTNER') {
                $data['refferal_id'] = \Auth()->user()->account_id;
            }

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

        return view('lab-billings.create', compact(
            'productCategory',
            'doctor',
            'patient',
            'countryCode',
            'refferal_lab',
            'collection_agent',
        ));
    }

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

        $data = \Session::get('billing_products_cart') ?? [];
        if(isset($data))
        {
            $data['amount'] = round($data['amount']);
            \Session::put('billing_products_cart', $data);
        }
        
        $data = \Session::get('billing_products_cart') ?? [];
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());

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

            return redirect()->route('lab-billings.create')->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('lab-billings.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;
            }
        }

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

        $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', 'accounting_group_id'])
            ->with('chart_of_account_sub_type')
            ->where(function ($query) {
                $query->whereHas('chart_of_account_sub_type', function ($accounting_group) {
                    $accounting_group->where('is_payment_mode', '1');
                });
            })
            ->get();
        $discount_group = Account::where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::where(['code' => 'ROUN_OFF'])->first();
        $TpaAccounts = Account::select([
            'accounts.id',
            'accounts.account_type_id',
            'account_types.type_code',
            \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
                "),
        ])
            ->leftJoin('account_titles', 'account_titles.id', '=', 'accounts.account_title_id')
            ->leftjoin('account_types', 'account_types.id', 'accounts.account_type_id')
            ->where('account_types.type_code', 'TPA')
            ->get();


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

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = \Session::get('billing_products_cart') ?? [];

        if (empty($data)) {
            return redirect()->back()->with('error', 'Empty cart!');
        }

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

        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'SALES')->where(['status' => 1])->first();
        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'PATHOLOGY')->where(['status' => 1])->first();

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

        $invoice_date        = $request->invoice_date != '' ? date('Y-m-d H:i:s', strtotime($request->invoice_date.' '.date('H:i:s'))) : '';
        $sample_receive_date = $request->sample_receive_date != '' ? date('Y-m-d', strtotime($request->sample_receive_date)) : '';

        $sale_invoice  = [
            'voucher_type_code'       => ($voucher_type->code ?? ''),
            'payment_term_id'         => $request->payment_term_id,
            'billing_amount'          => $data['amount'],
            'invoice_date'            => $invoice_date,
            'patient_id'              => $data['patient_id'],
            'doctor_id'               => $data['doctor_id'],
            'collection_agent_id'     => $data['collection_id'],
            'refferal_lab_id'         => $data['refferal_id'],
            'reff_no'                 => $request->reff_no,
            'received_amount'         => $request->amount_recieved,
            'due_amount'              => $data['due_balance_amount'],
            'sale_delivery_status'    => 'PENDING',
            'invoice_type'            => 'pathology',
            '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 bussiness 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,
            'transaction_mode_id'     => 7,
            'payment_mode_id'         => 1,
            'bill_to_account_id'      => $request->bill_to_account_id,
            'tpa_corporate_id'        => $request->tpa_corporate_id,
        ];

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

        /*********************  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(
                $sale_invoice->id,
                $transactions_no,
                'PATHOLOGY',
                $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 ***********************/

        //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();
        $year  = date('Y');
        $month = date('m');

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

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

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

        $invoice_batch = [
            'account_id'             => $data['patient_id'],
            'invoice_batch_date'     => Carbon::now(),
            'invoice_batch_no'       => $main_invoice_no,
            'created_by'             => Auth::user()->id,
            'invoice_id'             => $sale_invoice->id,
            'last_voucher_count'     => $last_voucher_count_batch,
            'sample_barcode'         => $request->sample_barcode,
            'sample_receive_date'    => $sample_receive_date,
            'sample_receive_time'    => $request->sample_receive_time,
            'remarks_for_technician' => $request->remarks_for_technician,
            'consultant_id'          => $data['doctor_id'],
        ];
        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::create($invoice_batch);

        /*********************  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(
                $sale_invoice->id,
                $transactions_no,
                'PATHOLOGY',
                $request->discount_account_id,
                $request->special_discount,
                $invoice_batch->id
            );
        }

        $discount['mode_id'] = $request->discount_account_id ?? '';
        $discount['amount'] = $request->special_discount ?? '';
        /********************* End Spacial Discount Store Calculation ***********************/

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

            $item = [
                'sale_invoice_id'     => $sale_invoice->id,
                'batch_id'            => $invoice_batch->id,
                'product_id'          => $value['product_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'            => $value['main_qty'],
                'tpa_amount'          => 0,
                'customer_amount'     => $value['amount'] ?? 0,
            ];

            $sale_invoice_details = SaleInvoiceDetail::create($item);
            /**************Stock Out Function ********************/
            if($product->manage_stock=='Yes')
            {
               stockOut($sale_invoice->id,'PATHOLOGY',$value['product_id'],$value['main_qty'],$value['product_price'],$product->getProductPrice->id,$invoice_batch->id);
            }

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

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

                /*SaleInvoiceTaskTracking::create([
                    'user_id'                     => Auth()->id(),
                    'tracking_type'               => 'Created',
                    'sale_invoice_sub_details_id' => $addedTestPackage->id,
                ]);*/
            }
        }

        $sales = Account::where('code', 'SALES')->select('id')->first();
        $cash  = Account::where('code', 'CASH')->select('id')->first();

        /*********************basic Transaction Insert Into Account Transaction Table */

        $this->createTransaction(
            'PATHOLOGY',
            $sale_invoice->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 ?? '',
                $sale_invoice->id,
                'PATHOLOGY',
                $request->payment_mode,
                'received',
            );
        }

        \Session::forget('billing_products_cart');

        return redirect()->route('pathology-invoice', $sale_invoice->id)->with('success', "New Bill Created Successfully");
    }

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

        $sale_invoice = SaleInvoice::with('getSaleInvoiceDetails')
            ->with('getSaleInvoiceSubDetail')
            ->with('getPatient')
            ->with('getDoctor')
            ->with('getCollectionAgent')
            ->with('getRefferalLab')
            ->with('getCompany')
            ->find($id);

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

        $documents    = DocumentManagement::where(['account_id' => $id, 'voucher_type' => 'PATHOLOGY'])->get();

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


    public function subDetailsDelete($id){

        $sale_invoice_id = SaleInvoiceSubDetails::select('sale_invoice_id')
        ->where('id' , $id)
        ->first();  

        SaleInvoiceSubDetails::where('id' , $id)
        ->delete();

        return redirect()->route('lab-billings.show' ,$sale_invoice_id->sale_invoice_id)->with('success', "Package Deleted Successfully");

    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\HTTP\Response
     */
    public function edit($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();

        $sale_invoice    = SaleInvoice::with('getSaleInvoiceDetails')->find($id);
        $data            = [];
        $patient         = $doctor = $collection_agent = $refferal_lab = '';

        if ($sale_invoice) {
            $data['patient_id']             = $sale_invoice->patient_id;
            $data['doctor_id']              = $sale_invoice->doctor_id;
            $data['refferal_id']            = $sale_invoice->refferal_lab_id;
            $data['collection_id']          = $sale_invoice->collection_agent_id;
            $data['amount']                 = $sale_invoice->billing_amount;
            $data['special_discount']       = $sale_invoice->discount_amount;
            $data['amount_recieved']        = $sale_invoice->received_amount;
            $data['due_balance_amount']     = $sale_invoice->due_amount;
            $data['discount_type']          = 'FLAT';
            $data['sample_receive_time']    = $sale_invoice->sample_receive_time;
            $data['invoice_date']           = $sale_invoice->invoice_date;
            $data['sample_receive_date']    = $sale_invoice->sample_receive_date;
            $data['payment_mode_id']        = $sale_invoice->payment_mode_id;
            $data['payment_term_id']        = $sale_invoice->payment_term_id;
            $data['special_case']           = $sale_invoice->special_case_id;
            $data['sample_barcode']         = $sale_invoice->sample_barcode;
            $data['reff_no']                = $sale_invoice->reff_no;
            $data['sale_remarks']           = $sale_invoice->remarks;
            $data['remarks_for_technician'] = $sale_invoice->remarks_for_technician;

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

                $amount        =  $value->price;
                $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->product_price_id ?? '',
                    'product_id'      => $value->product_id ?? '',
                    'product'         => $value->getProduct->name ?? '',
                    'hsncode'         => $value->getProduct->hsncode ?? '',
                    'brand'           => $value->getProduct->getProductBrand->name ?? '',
                    'product_price'   => $value->price ?? '0',
                    'flat_discount'   => $value->discount_amount ?? '0',
                    'per_discount'    => $value->discount_percentage ?? '0',
                    'product_details' => $value->item_details ?? '',
                    'vial_code'       => '',
                    'amount'          => $value->total_amount ?? '0',
                    'main_qty'        => $value->main_qty ?? '0',
                    'tax_per'         => $tax_per,
                    'tax_flat'        => $tax ?? 0,
                );
            }
        }

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

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

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

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

        if ($sale_invoice && isset($sale_invoice->refferal_lab_id) && $sale_invoice->refferal_lab_id != '') {
            $refferal_lab = Account::getAccount([
                'account_types.type_code' => 'REFERRAL_PARTNER',
                'accounts.id' => $sale_invoice->refferal_lab_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('lab-billings.edit.edit', compact(
            'id',
            'productCategory',
            'doctor',
            'patient',
            'countryCode',
            'refferal_lab',
            'collection_agent',
        ));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function editBilling($id)
    {
        $sale_invoice = SaleInvoice::find($id);
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        if (!$sale_invoice) {
            $data = [];
            \Session::put('billing_products_cart', $data);

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

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

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

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

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

        $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', 'accounting_group_id'])
            ->with('chart_of_account_sub_type')
            ->where(function ($query) {
                $query->whereHas('chart_of_account_sub_type', function ($accounting_group) {
                    $accounting_group->where('is_payment_mode', '1');
                });
            })
            ->get();

        $receipt = AcReceipt::where('voucher_id', $id)->first();
        $creditTransaction = [];
        $debitTransaction = [];

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

            $creditTransaction = AcReceiptDetail::with('account')
                ->where(['voucher_id' => $receipt->id, 'transaction_type' => 'DEBIT'])
                ->get();
        }

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

        $transactionSummery = $this->TransactionSummery($id, 'PATHOLOGY');
        $transactionHistory = $this->transactionHistory($id, 'PATHOLOGY');
        $TpaAccounts = Account::select([
            'accounts.id',
            'accounts.account_type_id',
            'account_types.type_code',
            \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
                "),
        ])
            ->leftJoin('account_titles', 'account_titles.id', '=', 'accounts.account_title_id')
            ->leftjoin('account_types', 'account_types.id', 'accounts.account_type_id')
            ->where('account_types.type_code', 'TPA')
            ->get();

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

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

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

            return redirect()->route('lab-billings.index')->with('error', 'Lab billing invoice not found!');
        }
        $special_discount = 0;

        if ($data['discount_type'] == 'FLAT') {
            $special_discount = $request->special_discount;
        } else {
            $special_discount = ($request->special_discount / 100) * $data['amount'];
        }

        $data               = \Session::get('billing_products_cart') ?? [];
        $received_amount    = $data['amount_recieved'] + $request->recieved;
        $due_balance_amount = $data['amount'] - $received_amount - $special_discount;

        if (empty($data)) {
            return redirect()->back()->with('error', 'Empty cart!');
        }

        $invoice_date        = $request->invoice_date != '' ? date('Y-m-d H:i:s', strtotime($request->invoice_date.' '.date('H:i:s'))) : '';
        $sample_receive_date = $request->sample_receive_date != '' ? date('Y-m-d', strtotime($request->sample_receive_date)) : '';

        $sale_invoice_update  = [
            'payment_term_id'         => $request->payment_term_id,
            'billing_amount'          => $data['amount'],
            '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'         => $received_amount,
            'due_amount'              => $due_balance_amount,
            'remarks'                 => $request->sale_remarks,
            'special_case_id'         => $request->special_case,
            'discount_amount'         => $special_discount,
            'adjustment_type'         => $request->discount_type,
            'payment_mode_id'         => $request->payment_mode_id ?? '',
            'bussiness_source_id'     => $request->bussiness_source ?? '',
            'bill_to_account_id'      => $request->bill_to_account_id,
            'tpa_corporate_id'        => $request->tpa_corporate_id,
            'updated_by'              => Auth()->id(),
            'invoice_date'            => $invoice_date
        ];

        $sale_invoice->update($sale_invoice_update);

        $where = [
            // 'created_by'             => Auth::user()->id,
            'invoice_id'             => $sale_invoice->id,
        ];

        $invoice_batchs = [
            'sample_barcode'         => $request->sample_barcode,
            'sample_receive_date'    => $request->sample_receive_date,
            'sample_receive_time'    => $request->sample_receive_time,
            'remarks_for_technician' => $request->remarks_for_technician,
            'consultant_id'          => $data['doctor_id'],
        ];
        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::updateOrCreate($where,$invoice_batchs);

        /*********************  Spacial Discount Store Calculation ***********************/
        if ($request->special_discount > 0) {
            $transactions_no = $this->generateRandomCode();
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $sale_invoice->id,
                $transactions_no,
                'PATHOLOGY',
                $request->discount_account_id,
                $request->special_discount,
                $invoice_batch->id
            );
        }
        $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 != '') {
            $transactions_no = $this->generateRandomCode();
            $company_address = \Session::get('company_data')['companies_addresses'];
            $currency_id     = $company_address->currency_id ?? '';
            $this->SaleOthersTransaction(
                $sale_invoice->id,
                $transactions_no,
                'PATHOLOGY',
                $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 ***********************/

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

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

            $item = [
                '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'            => $value['main_qty'],
                'tpa_amount'          => 0,
                'customer_amount'     => $value['amount'] ?? 0,
            ];

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

            $sale_invoice_detail_ids[] = $sale_invoice_details->id;

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

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

            foreach ($product_test_package as $package) {
                $addedTestPackage = SaleInvoiceSubDetails::where([
                    'sale_invoice_detail_id' => $sale_invoice_details->id,
                    'sale_invoice_id'        => $sale_invoice->id,
                    'data_referrence_id'     => $package->test_package_id,
                ])->first();

                if ($addedTestPackage) {
                    $addedTestPackage->update([
                        'subdetails_remarks' => '',
                        'referrence_type'    => 'LAB',
                        'status'             => 'SAMPLE_COLLECTION',
                        'task_status_id'     => $task_status->id ?? '',
                        'review_status_id'   => $task_status->id ?? '',
                    ]);

                    /*SaleInvoiceTaskTracking::create([
                        'user_id'                     => Auth()->id(),
                        'tracking_type'               => 'Updated',
                        'sale_invoice_sub_details_id' => $addedTestPackage->id,
                    ]);*/
                } else {
                    $addedTestPackage = SaleInvoiceSubDetails::create([
                        'sale_invoice_detail_id' => $sale_invoice_details->id,
                        'sale_invoice_id'        => $sale_invoice->id,
                        'data_referrence_id'     => $package->test_package_id,
                        'subdetails_remarks'     => '',
                        'referrence_type'        => 'LAB',
                        'status'                 => 'SAMPLE_COLLECTION',
                        'task_status_id'         => $task_status->id ?? '',
                        'review_status_id'       => $task_status->id ?? '',
                    ]);

                    /*SaleInvoiceTaskTracking::create([
                        'user_id'                     => Auth()->id(),
                        'tracking_type'               => 'Created',
                        'sale_invoice_sub_details_id' => $addedTestPackage->id,
                    ]);*/
                }

                $sale_invoice_sub_detail_ids[] = $addedTestPackage->id;
            }
        }

        SaleInvoiceDetail::whereNotIn('id', $sale_invoice_detail_ids)
            ->where(['sale_invoice_id' => $sale_invoice->id])
            ->delete();

        $sub_details = SaleInvoiceSubDetails::whereNotIn('id', $sale_invoice_sub_detail_ids)
            ->where(['sale_invoice_id' => $sale_invoice->id])
            ->get()->pluck('id');

        SaleInvoiceSubDetails::whereIn('id', $sub_details)->delete();
        // SaleInvoiceTaskTracking::whereIn('sale_invoice_sub_details_id', $sub_details)->delete();


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

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

            $this->createAcReceiptAndTransaction(
                $request->payment_mode_id ?? '',
                $data['patient_id'],
                $request->recieved,
                $transaction->id ?? '',
                $sale_invoice->id,
                'PATHOLOGY',
                $request->payment_mode,
                'received',
            );
        }

        \Session::forget('billing_products_cart');

        return redirect()->route('pathology-invoice', $sale_invoice->id)->with('success', "New Bill Created Successfully");
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request)
    {
        $saleInvoice = SaleInvoice::find($request->id);
        $saleInvoiceId = $saleInvoice->id;
        $saleInvoiceBatchId = $saleInvoice->batch_id??'';

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

            AccountTransaction::where([
                'voucher_id'  =>  $saleInvoiceId,
                'module_code' =>  'PATHOLOGY',
                'batch_id'    =>   $saleInvoiceBatchId,
            ])->delete();
        }



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

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

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

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

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

           
            
        }
        
        $saleInvoice->delete();

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

    public function searchPatients(Request $request)
    {
        $searchTerm = $request->search_text;
        $results    = Account::select([
            'accounts.id',
            'accounts.code',
            \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')
            ->where('account_types.type_code', 'PATIENT')
            ->where(function ($query) use ($searchTerm) {
                $query->where('accounts.name', 'LIKE', $searchTerm . '%')
                    ->orWhere('account_contacts.phone_no', 'LIKE', $searchTerm . '%')
                    ->orWhere('accounts.code', 'LIKE', $searchTerm . '%');
            })
            ->limit(15)
            ->get();

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

    public function searchDoctors(Request $request)
    {
        $searchTerm = $request->search_text;
        $results    = Account::select([
            'accounts.id',
            'accounts.code',
            \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')
            ->where('account_types.type_code', 'DOCTOR')
            ->where(function ($query) use ($searchTerm) {
                $query->where('accounts.name', 'LIKE', $searchTerm . '%')
                    ->orWhere('account_contacts.phone_no', 'LIKE', $searchTerm . '%')
                    ->orWhere('accounts.code', 'LIKE', $searchTerm . '%');
            })
            ->get();

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

    public function searchReferrals(Request $request)
    {
     
        $searchTerm = $request->search_text;
        $results    = Account::select([
                'accounts.id',
                'accounts.code',
                \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')
            ->where('account_types.type_code', 'REFERRAL_PARTNER')
            ->where(function ($query) use ($searchTerm) {
                $query->where('accounts.name', 'LIKE', $searchTerm . '%')
                    ->orWhere('account_contacts.phone_no', 'LIKE', $searchTerm . '%')
                    ->orWhere('accounts.code', 'LIKE', $searchTerm . '%');
            })
            ->get();

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

    public function searchCollectionLabs(Request $request)
    {
        $searchTerm = $request->search_text;
        $results    = Account::select([
            'accounts.id',
            'accounts.code',
            \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')
            ->where('account_types.type_code', 'COLLECTION_AGENT')
            ->where(function ($query) use ($searchTerm) {
                $query->where('accounts.name', 'LIKE', $searchTerm . '%')
                    ->orWhere('account_contacts.phone_no', 'LIKE', $searchTerm . '%')
                    ->orWhere('accounts.code', 'LIKE', $searchTerm . '%');
            })
            ->get();

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

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

        $saleVoucher = VoucherType::select(['default_price_type'])->where(['code'=>'PATHOLOGY'])->first();

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


        $results    = Product::select('products.id', 'products.name', 'products.shortcode', 'products.hsncode', 'product_prices.id as price_id', 'product_prices.batch',$productPrice)
            ->leftjoin('product_prices', 'product_prices.product_id', 'products.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($batch != '', function ($query) use ($batch) {
                $query->where('product_prices.batch', $batch);
            })
            ->when($category_id != '', function ($query) use ($category_id) {
                $query->where('products.category_id', $category_id);
            })
            ->where('product_prices.status', 1)
            ->where('products.status', 1)
            ->limit(15)
            ->get();

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

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

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

    public function productAddToCart(Request $request)
    {
        $data = \Session::get('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['collection_id']) || $data['collection_id'] == '') {
            $data['collection_id'] = $request->collection_id ?? '';
        }
        if (!isset($data['refferal_id']) || $data['refferal_id'] == '') {
            $data['refferal_id'] = $request->refferal_id ?? '';
        }

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

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

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

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

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

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

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

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

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

            // Check if the product already exists in the cart
            if(isset($data['products'])){
                foreach ($data['products'] as $cart_product) {
                    if ($cart_product['product_id'] == $request->search_product) {
                        return response()->json(['success' => true, 'data' => $data]);
                    }
                }
            }
    
        $product_price = $request->product_price;
        $main_qty      = $request->main_qty ?? 1;
        $flat_discount = $request->flat_discount ?? '0';
        $per_discount  = $request->per_discount ?? '0';
        $amount = '0';

        if (isset($data['refferal_id']) && $data['refferal_id'] != '') {

            $slab = IncentiveSlab::leftjoin('incentive_settings','incentive_settings.slab_id','incentive_slabs.id')
                ->leftjoin('incentive_slab_details','incentive_slab_details.slab_id','incentive_slabs.id')
                ->where('incentive_settings.account_id', $data['refferal_id'])
                ->where('incentive_slab_details.product_id', $request->search_product)
                ->first();

            if ($slab) {
                if ($slab->calculation_type == 'percentage') {
                    $flat_discount = $slab->price ?? '0';
                    $per_discount  = $slab->percentage ?? '0';
                } else if (!empty($slab->price)) {
                    $flat_discount = '0';
                    $per_discount  = '0';
                    $product_price = $slab->price;
                }
            }
        }

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


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

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

        if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
            $tax          = ($tax_per / 100) * $product_price;
            $basic_amount = $product_price + $tax;
        } else {
            // $cal_tax_per   = 1+($tax_per/100);
            // $product_price = $product_price/$cal_tax_per;
            // $tax           = ($tax_per / 100) * $product_price;

            $basic_amount  = $product_price / (($tax_per + 100) / 100);
        }

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

        if ($voucher_master && $voucher_master->tax_calculation == 'INCLUSIVE') {
            $tax = ($tax_per / 100) * $amount;

            // $amount += $tax;
            $amount = bcadd($amount, $tax, 2);
        }

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

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

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

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

     

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

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

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

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

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

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

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

    public function cartProductUpdate(Request $request)
    {
        if (isset($request->billing_type) && $request->billing_type == 'ipd') {
            $data = \Session::get('ipd_billing_products_cart') ?? [];
        } else {
            $data = \Session::get('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 (isset($data['discount_type']) && $data['discount_type'] == 'FLAT') {
                    $due_balance_amount = $data['amount'] - $data['special_discount'];
                    $data['due_balance_amount'] = round($due_balance_amount - $data['amount_recieved']);
                } else {
                    $flat_discount = ($data['special_discount'] / 100) * $data['amount'];
                    $due_balance_amount = $data['amount'] - $flat_discount;
                    $data['due_balance_amount'] = round($due_balance_amount - $data['amount_recieved']);
                }
            }
        } else {
            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;
            }

            if (isset($data['products'])) {
                foreach ($data['products'] as $key => $value) {
                    if (isset($request->refferal_id)) {
                        $slab = IncentiveSlab::leftjoin('incentive_settings','incentive_settings.slab_id','incentive_slabs.id')
                            ->leftjoin('incentive_slab_details','incentive_slab_details.slab_id','incentive_slabs.id')
                            ->where('incentive_settings.account_id', $request->refferal_id)
                            ->where('incentive_slab_details.product_id', $value['product_id'])
                            ->first();

                        if ($slab) {
                            if ($slab->calculation_type == 'percentage') {
                                $data['amount'] = $data['amount'] - $value['amount'];
                                $data['products'][$key]['per_discount'] = $slab->percentage;

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

                                $amount                                  = $value['product_price'] * $main_qty;
                                $flat_discount                           = ($slab->percentage / 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']);
                            } else if (!empty($slab->price)) {
                                $data['amount'] = $data['amount'] - $value['amount'];

                                $data['products'][$key]['flat_discount'] = 0;
                                $value['product_price']                  = $slab->price;
                                $data['products'][$key]['product_price'] = $slab->price;

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

                                $amount                                 = $value['product_price'] * $main_qty;
                                $flat_tax                               = ($value['tax_per'] / 100) * $amount;
                                $amount                                 = ($amount - $request->flat_discount);
                                $amount                                 = ($amount + $flat_tax);
                                $data['products'][$key]['per_discount'] = 0;
                                $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->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)) {
                        // $old_price = $data['products'][$key]['amount'];
                        // $data['products'][$key]['product_price'] = $request->product_price;

                        // $flat_discount   = ($value['per_discount'] / 100) * $request->product_price;
                        // $data['products'][$key]['amount'] = $new_price = number_format($request->product_price - $flat_discount, 2, '.', '');
                        // $data['products'][$key]['flat_discount'] = number_format($flat_discount, 2, '.', '');
                        // $data['amount'] += ($new_price - $old_price);
                        // $data['due_balance_amount'] = round($data['amount']);

                        $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)) {
                        // $old_price = $data['products'][$key]['amount'];
                        // $per_discount = $request->per_discount;
                        // $data['products'][$key]['per_discount'] = number_format($per_discount, 2, '.', '');

                        // $flat_discount = ($per_discount / 100) * $data['products'][$key]['product_price'];
                        // $data['products'][$key]['amount'] = $new_price = number_format($data['products'][$key]['product_price'] - $flat_discount, 2, '.', '');
                        // $data['products'][$key]['flat_discount'] = number_format($flat_discount, 2, '.', '');
                        // $data['amount'] += ($new_price - $old_price);

                        $data['amount'] = $data['amount'] - $value['amount'];
                        $data['products'][$key]['per_discount'] = $request->per_discount;

                        $main_qty = $value['main_qty'] > 0 ? $value['main_qty'] : ($value['loose_qty'] > 0 ? $value['loose_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)) {
                        // $old_price = $data['products'][$key]['amount'];
                        // $per_discount  = ($request->flat_discount / $data['products'][$key]['product_price']) * 100;
                        // $data['products'][$key]['per_discount']  = number_format($per_discount, 2, '.', '');
                        // $data['products'][$key]['amount'] = $new_price = number_format($data['products'][$key]['product_price'] - $request->flat_discount, 2, '.', '');
                        // $data['products'][$key]['flat_discount'] = number_format($request->flat_discount, 2, '.', '');
                        // $data['amount'] += ($new_price - $old_price);
                        // $data['due_balance_amount'] = round($data['amount']);

                        $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->billing_type) && $request->billing_type == 'ipd') {
            \Session::put('ipd_billing_products_cart', $data);
        } else {
            \Session::put('billing_products_cart', $data);
        }

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

    public function pathologyInvoice($id)
    {
        $sale_invoice = SaleInvoice::with('getSaleInvoiceDetails')
            ->with('getSaleInvoiceDelivery')
            ->with('getPatient')
            ->with('getPaymentTerm')
            ->with('getCompany')
            ->with('getVoucher')
            ->with('getCollectionAgent')
            ->with('getRefferalLab')
            ->find($id);
        if (!$sale_invoice) {
            return redirect()->route('lab-billings.index')->with('error', 'Invoice not found');
        }

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

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

        $transactionHistory = $this->transactionHistory($id, 'PATHOLOGY');

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

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

    public function billingReport(Request $request, $invoice_id)
    {
        $test_package_id = $request->test_package ?? '';
        $batch_id = $request->batch_id ?? '';

        $style = StyleType::all();
        $sale_invoice = SaleInvoice::select([
            'sale_invoices.id',
            'sale_invoices.main_invoice_no',
            'sale_invoices.voucher_type_invoice_no',
            'sale_invoices.voucher_type_code',
            'sale_invoices.invoice_date',
            'sale_invoices.patient_id',
            'sale_invoices.created_at',
            'sale_invoice_batches.remarks_for_technician',
            'special_cases.name as special_case',
            'accounts.name AS patent_name',
            'account_contacts.date_of_birth',
            'account_contacts.account_gender_id',
            'account_contacts.phone_no',
            'genders.name as gender',
            'account_titles.name as account_title',
            'account_addresses.address_line1',
            'states.name as state'
        ])
            ->leftjoin('accounts', 'accounts.id', 'sale_invoices.patient_id')
            ->leftjoin('sale_invoice_batches', 'sale_invoice_batches.invoice_id', 'sale_invoices.id')
            ->leftjoin('special_cases', 'special_cases.id', 'sale_invoices.special_case_id')
            ->leftjoin('account_contacts', 'accounts.id', 'account_contacts.account_id')
            ->leftjoin('genders', 'genders.id', 'account_contacts.account_gender_id')
            ->leftjoin('account_titles', 'account_titles.id', 'accounts.account_title_id')
            ->leftjoin('account_addresses', 'account_addresses.account_id', 'accounts.id')
            ->leftjoin('states', 'account_addresses.state_id', 'states.id')

            ->find($invoice_id);

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

        $testPackages = TestPackage::select('test_packages.*','sale_invoice_sub_details.id as sale_invoice_sub_detail_id','sale_invoice_details.batch_id','sale_invoice_details.id as sale_invoice_detail_id')
            ->leftjoin('product_test_packages', 'product_test_packages.test_package_id', 'test_packages.id')
            ->leftjoin('sale_invoice_sub_details','test_packages.id','sale_invoice_sub_details.data_referrence_id')
            ->leftjoin('sale_invoice_details','sale_invoice_sub_details.sale_invoice_detail_id','sale_invoice_details.id')
            ->with('department', 'testPackageGroups.test_package_group_test_items')
            ->where('sale_invoice_details.sale_invoice_id', $invoice_id)
            // ->when(!empty($test_package_id), function ($query) use ($test_package_id) {
            //     $query->where('test_packages.id', $test_package_id);
            // })
            ->when(!empty($batch_id), function($query) use ($batch_id) {
                $query->where('sale_invoice_details.batch_id', $batch_id);
            })
            ->groupBy('test_packages.id','sale_invoice_details.batch_id')
            ->get()
            ->groupBy(function ($testPackage) {
                return $testPackage->department->id;
            })
            ->map(function ($testPackages, $departmentId) {
                $departmentName = Department::find($departmentId)->name;

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

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

        $billing_report = LabBillingReport::select([
            'lab_billing_reports.*',
            'lab_report_result_big_texts.result as long_result'
        ])
            ->leftjoin('lab_report_result_big_texts', 'lab_report_result_big_texts.lab_billing_report_id', 'lab_billing_reports.id')
            ->where(['lab_billing_reports.sale_invoice_id' => $invoice_id])
            ->get()
            ->mapWithKeys(function($item) {
                return [$item->test_item_id . '_' . $item->sale_invoice_detail_id => $item];
            });;

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

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

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

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

        foreach ($sale_invoice_detail as $sale_invoice_detail_id => $test_results) {
            foreach ($test_results as $test_package_id => $test_package) {

                foreach ($test_package as $test_package_group_id => $test_package_group) {
                    $created = 1;

                    foreach ($test_package_group as $key => $value) {
                        $result = $value;
                        $is_file = 0;

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

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

                                if ($response['status'] == true) {
                                    $result = $response['file_name'];
                                    $is_file = 1;
                                } else {
                                    $result = '';
                                }
                            }
                        }
                        $test_item = TestItem::find($key);
                        $test_item_type = $test_item->input_type ?? '';

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

                        if (!$billing_report && $result != '') {
                            $testPackage = SaleInvoiceSubDetails::where([
                                'sale_invoice_detail_id' => $sale_invoice_detail_id,
                                'sale_invoice_id'        => $invoice_id,
                                'data_referrence_id'     => $test_package_id,
                            ])->first();

                            $task_status = TaskStatus::where('code', 'RESULT_UPDATED')->first();

                            if ($testPackage) {
                                $testPackage->update([
                                    'task_created_by_id' => Auth::ID(),
                                    'task_created_at'    => date('Y-m-d H:i:s'),
                                    'task_status_id'     => $task_status->id ?? '',
                                ]);
                                $created = 0;
                            } else {
                                $testPackage = SaleInvoiceSubDetails::create([
                                    'sale_invoice_detail_id' => $sale_invoice_detail_id,
                                    'sale_invoice_id'        => $invoice_id,
                                    'data_referrence_id'     => $test_package_id,
                                    'subdetails_remarks'     => '',
                                    'referrence_type'        => 'LAB',
                                    'status'                 => 'SAMPLE_COLLECTION',
                                    'task_created_by_id' => Auth::ID(),
                                    'task_created_at'    => date('Y-m-d H:i:s'),
                                    'task_status_id'     => $task_status->id ?? '',
                                ]);
                                $created = 1;
                            }

                            $flags_exist = $select_test_flat[$test_package_id][$test_package_group_id][$key] ?? '0';
                            $flat_check = '';

                            if ($flags_exist == 1) {
                                $test_flag_selected =  TestItemOption::select('*')->with('styleType')->where('code', $result)->first();
                                $flat_check = $test_flag_selected->styleType->code ?? '';
                            }

                            $billing_report = LabBillingReport::Create([
                                'sale_invoice_detail_id' => $sale_invoice_detail_id,
                                'sale_invoice_id'       => $invoice_id,
                                'test_package_id'       => $test_package_id,
                                'test_package_group_id' => $test_package_group_id,
                                'test_item_id'          => $key,
                                'is_file'               => $is_file,
                                'result'                => ($test_item_type == 'SUMMER_NOTE' ? '' : $result),
                                'flag'                  => $test_flags[$test_package_id][$test_package_group_id][$key] ?? $flat_check,
                            ]);

                            if ($test_item_type == 'SUMMER_NOTE') {
                                LabReportResultBigText::create([
                                    'result'                => $result,
                                    'lab_billing_report_id' => $billing_report->id
                                ]);
                            }

                            if ($result != '') {
                                SaleInvoiceTaskTracking::firstOrCreate([
                                    'user_id'                     => Auth::ID(),
                                    'tracking_type'               => 'RESULT_UPDATED',
                                    'sale_invoice_sub_details_id' => $testPackage->id,
                                ]);

                                SaleInvoiceTaskTracking::where([
                                    'tracking_type'               => 'RESULT_RECHECK',
                                    'sale_invoice_sub_details_id' => $testPackage->id,
                                ])->delete();
                            }
                        } else if ((isset($billing_report)/* && $billing_report->result != $result*/)) {
                            $testPackage = SaleInvoiceSubDetails::where([
                                'sale_invoice_detail_id' => $sale_invoice_detail_id,
                                'sale_invoice_id'        => $invoice_id,
                                'data_referrence_id'     => $test_package_id,
                            ])->first();

                            $task_status = TaskStatus::where('code', 'RESULT_UPDATED')->first();

                            if ($testPackage) {
                                $testPackage->update([
                                    'task_created_by_id' => Auth::ID(),
                                    'task_created_at'    => date('Y-m-d H:i:s'),
                                    'task_status_id'     => $task_status->id ?? '',
                                ]);
                                $created = 0;
                            } else {
                                $testPackage = SaleInvoiceSubDetails::create([
                                    'sale_invoice_detail_id' => $sale_invoice_detail_id,
                                    'sale_invoice_id'        => $invoice_id,
                                    'data_referrence_id'     => $test_package_id,
                                    'subdetails_remarks'     => '',
                                    'referrence_type'        => 'LAB',
                                    'status'                 => 'SAMPLE_COLLECTION',
                                    'task_created_by_id' => Auth::ID(),
                                    'task_created_at'    => date('Y-m-d H:i:s'),
                                    'task_status_id'     => $task_status->id ?? '',
                                ]);
                                $created = 1;
                            }

                            $flags_exist = $select_test_flat[$test_package_id][$test_package_group_id][$key] ?? '0';
                            $flat_check = '';

                            if ($flags_exist  == 1 && $result != '') {
                                $test_flag_selected =  TestItemOption::select('*')->with('styleType')->where('code', $result)->first();
                                $flat_check = $test_flag_selected->styleType->code ?? '';
                            }

                            if ($test_item_type == 'SUMMER_NOTE') {
                                LabReportResultBigText::updateOrCreate([
                                    'lab_billing_report_id' => $billing_report->id
                                ], [
                                    'result' => $result
                                ]);
                            }

                            $billing_report = LabBillingReport::where([
                                'sale_invoice_detail_id' => $sale_invoice_detail_id,
                                'sale_invoice_id'       => $invoice_id,
                                'test_package_id'       => $test_package_id,
                                'test_package_group_id' => $test_package_group_id,
                                'test_item_id'          => $key
                            ])->update([
                                'result'  => ($test_item_type == 'SUMMER_NOTE' ? '' : $result),
                                'is_file' => $is_file,
                                'flag'    => $test_flags[$test_package_id][$test_package_group_id][$key] ?? $flat_check,
                            ]);

                            if ($result != '') {
                                SaleInvoiceTaskTracking::firstOrCreate([
                                    'user_id'                     => Auth::ID(),
                                    'tracking_type'               => 'RESULT_UPDATED',
                                    'sale_invoice_sub_details_id' => $testPackage->id,
                                ]);

                                SaleInvoiceTaskTracking::where([
                                    'tracking_type'               => 'RESULT_RECHECK',
                                    'sale_invoice_sub_details_id' => $testPackage->id,
                                ])->delete();
                            }
                        }
                    }

                    /*if ($created == 1 && isset($testPackage->id)) {
                        SaleInvoiceTaskTracking::create([
                            'user_id'                     => Auth()->id(),
                            'tracking_type'               => 'Created',
                            'sale_invoice_sub_details_id' => $testPackage->id,
                        ]);
                    } else if (isset($testPackage->id)) {
                        SaleInvoiceTaskTracking::create([
                            'user_id'                     => Auth()->id(),
                            'tracking_type'               => 'Updated',
                            'sale_invoice_sub_details_id' => $testPackage->id,
                        ]);
                    }*/
                }
            }
        }

        if (isset($request->redirect_route) && $request->redirect_route != '') {
            return redirect()->route($request->redirect_route)->with('success', 'Invoice report updated successfully.');
        } else {
            return redirect()->route('lab-reporting')->with('success', 'Invoice report updated successfully.');
        }
    }

    public function billingReportPrint(Request $request, $invoice_id)
    {
        $batch_id = $request->batch_id ?? '';
        $style = StyleType::all();

        $sale_invoice = SaleInvoice::select('sale_invoices.*','sale_invoice_batches.id as batch_id','sale_invoice_batches.invoice_batch_no as invoice_batch_no','ipd_admissions.id as ipd_admission_id')
            ->leftjoin('sale_invoice_batches', function($join) use ($batch_id) {
                $join->on('sale_invoice_batches.invoice_id', 'sale_invoices.id')
                    ->when(!empty($batch_id), function($query) use ($batch_id) {
                        $query->where('sale_invoice_batches.id', $batch_id);
                    });
            })
            ->leftjoin('ipd_admissions', 'ipd_admissions.sale_invoice_id', 'sale_invoices.id')
            ->with('getPatient', 'getVoucherType')
            ->find($invoice_id);

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

        $showReport = TestPackage::where('id', $invoice_id)->first();
        $productIds = SaleInvoiceDetail::select('product_id')
            ->where('sale_invoice_id', $invoice_id)
            ->when(!empty($batch_id), function($query) use ($batch_id) {
                $query->where('batch_id', $batch_id);
            })
            ->get()->pluck('product_id');

        $testPackages = TestPackage::select(
            'test_packages.*',
            'test_methods.name as test_method_name',
            'product_test_packages.product_id',
            'sale_invoice_sub_details.created_at as registered_at',
            'sale_invoice_sub_details.sale_invoice_detail_id',
            'collected.created_at as collected_at',
            'reported.created_at as reported_at',
            'updated.created_at as updated_at',
            'technician.user_signature as technician_signature',
            'technician.prepared_by as technician_prepared_by',
            'technician.user_designation as technician_designation',
            'doctor.user_signature as doctor_signature',
            'doctor.prepared_by as doctor_prepared_by',
            'doctor.user_designation as doctor_designation',
            'test_package_notes.package_note',
            'test_package_notes.status as package_note_status',
        )
            ->whereIn('product_test_packages.product_id', $productIds)
            ->leftjoin('product_test_packages', 'product_test_packages.test_package_id', 'test_packages.id')
            ->leftjoin('test_package_notes', 'test_package_notes.test_package_id', 'test_packages.id')

            ->leftjoin('test_methods', 'test_methods.id', 'test_packages.test_method_id')
            ->leftJoin('test_departments', 'test_departments.id', '=', 'test_packages.department_id')
            ->leftJoin('sale_invoice_details', function ($join) use ($invoice_id) {
                $join->on('sale_invoice_details.product_id', '=', 'product_test_packages.product_id')
                    ->where('sale_invoice_details.sale_invoice_id', '=', $invoice_id);
            })
            ->leftjoin('sale_invoice_sub_details', 'sale_invoice_sub_details.sale_invoice_detail_id', 'sale_invoice_details.id')
            ->leftjoin('sale_invoice_task_trackings', 'sale_invoice_sub_details.id', 'sale_invoice_task_trackings.sale_invoice_sub_details_id')
            ->leftJoin('sale_invoice_task_trackings as registered_on', function ($join) use ($invoice_id) {
                $join->on('registered_on.sale_invoice_sub_details_id', '=', 'sale_invoice_sub_details.id')
                    ->where('registered_on.tracking_type', '=', 'Created');
            })
            ->leftJoin('sale_invoice_task_trackings as collected', function ($join) use ($invoice_id) {
                $join->on('collected.sale_invoice_sub_details_id', '=', 'sale_invoice_sub_details.id')
                    ->where('collected.tracking_type', '=', 'SAMPLE_COLLECTED');
            })
            ->leftJoin('sale_invoice_task_trackings as reported', function ($join) use ($invoice_id) {
                $join->on('reported.sale_invoice_sub_details_id', '=', 'sale_invoice_sub_details.id')
                    ->where('reported.tracking_type', '=', 'RESULT_REVIEWED');
            })
            ->leftJoin('sale_invoice_task_trackings as updated', function ($join) use ($invoice_id) {
                $join->on('updated.sale_invoice_sub_details_id', '=', 'sale_invoice_sub_details.id')
                    ->where('updated.tracking_type', '=', 'RESULT_UPDATED');
            })
            ->with('department', 'testPackageGroups.test_package_group_test_items', 'package_note')
            ->leftjoin('users as technician', 'technician.id', 'updated.user_id')
            ->leftjoin('users as doctor', 'doctor.id', 'reported.user_id')
            ->groupBy('test_packages.id','sale_invoice_details.batch_id')
            ->when(!empty($batch_id), function($query) use ($batch_id) {
                $query->where('sale_invoice_details.batch_id', $batch_id);
            })
            ->orderBy('test_packages.priority')
            ->orderBy('test_departments.priority', 'ASC')
            ->get()
            ->groupBy(function ($testPackage) {
                return $testPackage->department->id;
            })
            ->map(function ($testPackages, $departmentId) {
                $departmentName = Department::getDepartmentWithSignature(['test_departments.id' => $departmentId]);
                // $departmentName = Department::with('doctorSignature')->find($departmentId);
                return [
                    'department'    => $departmentName,
                    'test_packages' => $testPackages,
                ];
            });

        $settings = [
            'doctor_signature_print_setting',
            'technician_signature_print_setting',
            'add_page_break_after_every_department',
            'SHOW_DELIVERY_TIME_ON_BILL',
            'SHOW_DELIVERY_DATE_ON_REPORT',
            'print_report_with_letter_head',
            'SHOW_PRINT_OPTION_ON_DUE_BILL',
            'CAPAITALIZE_NAMES',
            'SHOWMETHODONREPORT',
            'show_flag_in_lab_billing'
        ];

        $master_settings = MasterSetting::select([
            'advance_settings.value',
            'master_settings.code',
        ])
            ->leftjoin('advance_settings', 'advance_settings.master_setting_id', 'master_settings.id')
            ->whereIn('master_settings.code', $settings)
            ->where('master_settings.status', '1')
            ->get()
            ->pluck('value', 'code');

        $advance_settings = AdvanceSetting::select(['master_settings.code','advance_settings.value'])
            ->leftjoin('master_settings', 'advance_settings.master_setting_id', 'master_settings.id')
            ->leftjoin('voucher_types', 'advance_settings.voucher_type_id', 'voucher_types.id')
            ->where([
                'voucher_types.code' => 'PATHOLOGY'
            ])
            ->get()
            ->pluck('value', 'code');

        $doc_signature_setting = $tech_signature_setting = $page_break_after_dept = $print_with_letterhead = $show_flag = $show_delivery_time = $show_print_on_due = '';

        foreach ($master_settings as $key => $value) {
            if($key == 'doctor_signature_print_setting') {
                $doc_signature_setting = $advance_settings[$key] ?? $value;
            }
            if($key == 'technician_signature_print_setting') {
                $tech_signature_setting = $advance_settings[$key] ?? $value;
            }
            if($key == 'add_page_break_after_every_department') {
                $page_break_after_dept = $advance_settings[$key] ?? $value;
            }
            if($key == 'SHOW_DELIVERY_TIME_ON_BILL') {
                $show_delivery_time = $advance_settings[$key] ?? $value;
            }
            if($key == 'SHOW_DELIVERY_DATE_ON_REPORT') {
                $show_delivery_date = $advance_settings[$key] ?? $value;
            }
            if($key == 'print_report_with_letter_head') {
                $print_with_letterhead = $advance_settings[$key] ?? $value;
            }
            if($key == 'SHOW_PRINT_OPTION_ON_DUE_BILL') {
                $show_print_on_due = $advance_settings[$key] ?? $value;
            }
            if($key == 'CAPAITALIZE_NAMES') {
                $cap_names = $advance_settings[$key] ?? $value;
            }
            if($key == 'SHOWMETHODONREPORT') {
                $show_method = $advance_settings[$key] ?? $value;
            }
            if($key == 'show_flag_in_lab_billing') {
                $show_flag = $advance_settings[$key] ?? $value;
            }
        }

        $billing_report = LabBillingReport::select([
            'lab_billing_reports.*',
            'lab_report_result_big_texts.result as long_result',
            'style_types.font_color',
            'style_types.font_size',
            'style_types.bg_color',
            'font_families.font_name as font_family',
            'style_types.text_decoration',
            'style_types.font_style',
            'style_types.font_weight',
            'style_types.font_padding',
            'test_item_options.note as note',
        ])
            ->leftjoin('lab_report_result_big_texts', 'lab_report_result_big_texts.lab_billing_report_id', 'lab_billing_reports.id')
            ->leftjoin('style_types', 'style_types.code', 'lab_billing_reports.flag')
            ->leftJoin('font_families', 'font_families.id', '=', 'style_types.font_family')
            ->leftJoin('test_item_options', function($join) {
                $join->on('test_item_options.test_item_id', 'lab_billing_reports.test_item_id')
                    ->on('test_item_options.name', 'lab_billing_reports.result');
            })
            ->where(['lab_billing_reports.sale_invoice_id' => $invoice_id])
            ->get()
            ->mapWithKeys(function($item) {
                return [$item->test_item_id . '_' . $item->sale_invoice_detail_id => $item];
            });

        $flags = StyleType::get();

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

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

        $company_logo = \App\Models\CompanyImage::select('*')
            ->where('company_id', $company_id)
            ->where('image_type', 'logo')
            ->where('status', '1')
            ->first();

        $company_letter_head = \App\Models\CompanyImage::select('*')
            ->where('company_id', $company_id)
            ->where('image_type', 'header')
            ->where('status', '1')
            ->first();

        $company_footer = \App\Models\CompanyImage::select('*')
            ->where('company_id', $company_id)
            ->where('image_type', 'footer')
            ->where('status', '1')
            ->first();

        return view('lab-billings.billing-report-print', compact(
            'advance_settings',
            'show_flag',
            'page_break_after_dept',
            'print_with_letterhead',
            'tech_signature_setting',
            'doc_signature_setting',
            'company_letter_head',
            'company_footer',
            'billing_report',
            'company_logo',
            'sale_invoice',
            'testPackages',
            'showReport',
            'style',
            'voucher_type',
            'batch_id',
            'show_print_on_due',
            'show_method',
            'show_delivery_date',
            'cap_names',
            'flags'
        ));

        $pdfData  = [
            'show_flag'              => $show_flag,
            'page_break_after_dept'  => $page_break_after_dept,
            'print_with_letterhead'  => $print_with_letterhead,
            'tech_signature_setting' => $tech_signature_setting,
            'doc_signature_setting'  => $doc_signature_setting,
            'company_letter_head'    => $company_letter_head,
            'company_footer'         => $company_footer,
            'billing_report'         => $billing_report,
            'company_logo'           => $company_logo,
            'sale_invoice'           => $sale_invoice,
            'testPackages'           => $testPackages,
            'showReport'             => $showReport,
            'style'                  => $style,
            'voucher_type'           => $voucher_type
        ];

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

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

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

    public function printTestPackagesStatus(Request $request, $invoice_id)
    {
        $batch_id = $request->batch_id ?? '';
        $where['sale_invoices.id'] = $invoice_id;

        if (!empty($batch_id)) {
            $where['sale_invoice_batches.id'] = $batch_id;
        }

        $sale_invoice_status = SaleInvoice::getSaleInvoices($where, [], 1)->get();

        return view('lab-billings.print-test-packages-status', compact(
            'sale_invoice_status'
        ));
    }

    public function billingReportSticker($invoice_id)
    {
        // $style = StyleType::all();

        $sale_invoice = SaleInvoice::with('getPatient', 'getVoucherType')
            ->find($invoice_id);

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

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

        $billing_report = LabBillingReport::select([
            'lab_billing_reports.*',
            'lab_report_result_big_texts.result as long_result'
        ])
            ->leftjoin('lab_report_result_big_texts', 'lab_report_result_big_texts.lab_billing_report_id', 'lab_billing_reports.id')
            ->where(['lab_billing_reports.sale_invoice_id' => $invoice_id])
            ->get()
            ->keyBy('test_item_id');

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

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

        return view('lab-billings.sticker-report-barcode', compact(
            'billing_report',
            'sale_invoice',
            'showReport',
            'voucher_type'
        ));

        $pdfData  = [
            'billing_report' => $billing_report,
            'sale_invoice'   => $sale_invoice,
        ];

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

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

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

    public function billingReportLog($invoice_id)
    {
        $sale_invoice = SaleInvoice::with('getSaleInvoiceDetails')
            ->with('getSaleInvoiceSubDetail')
            ->with('getPatient')
            ->with('getDoctor')
            ->with('getCollectionAgent')
            ->with('getRefferalLab')
            ->with('getCompany')
            ->find($invoice_id);

        $sub_details = SaleInvoiceSubDetails::where('sale_invoice_id', $invoice_id)
            ->with('tracking')
            ->get();

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

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

    public function editPatients($invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $patient = Account::getAccount([
            'account_types.type_code' => 'PATIENT',
            'accounts.id' => $sale_invoice->patient_id
        ]);

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

        return view('lab-billings.edit.patient', compact('patient', 'sale_invoice'));
    }

    public function updatePatient(Request $request, $invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $sale_invoice = $sale_invoice->update(['patient_id' => $request->patient_id]);

        return response()->json([
            'success' => true,
            'message' => 'Sale Invoice Patient Updated Successfully.',
        ]);
    }

    public function editDoctor($invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $doctor = Account::getAccount([
            'account_types.type_code' => 'DOCTOR',
            'accounts.id' => $sale_invoice->doctor_id
        ]);

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

        return view('lab-billings.edit.doctor', compact('doctor', 'sale_invoice'));
    }

    public function updateDoctor(Request $request, $invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $sale_invoice = $sale_invoice->update(['doctor_id' => $request->doctor_id]);



        return response()->json([
            'success' => true,
            'message' => 'Sale Invoice Doctor Updated Successfully.',
        ]);
    }

    public function editCollectionAgent($invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $collection_agent = Account::getAccount([
            'account_types.type_code' => 'COLLECTION_AGENT',
            'accounts.id' => $sale_invoice->collection_agent_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' : '');
        }

        return view('lab-billings.edit.collection-agent', compact('sale_invoice', 'collection_agent'));
    }

    public function updateCollectionAgent(Request $request, $invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $sale_invoice = $sale_invoice->update(['collection_agent_id' => $request->collection_id]);

        return response()->json([
            'success' => true,
            'message' => 'Sale Invoice Collection Agent Updated Successfully.',
        ]);
    }

    public function editReferralLab($invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $refferal_lab = Account::getAccount([
            'account_types.type_code' => 'REFERRAL_PARTNER',
            'accounts.id' => $sale_invoice->refferal_lab_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' : '');
        }

        return view('lab-billings.edit.referral-lab', compact('sale_invoice', 'refferal_lab'));
    }

    public function updateReferralLab(Request $request, $invoice_id)
    {
        $sale_invoice = SaleInvoice::where('id', $invoice_id)->first();

        if (!$sale_invoice) {
            return response()->json([
                'success' => false,
                'message' => 'Sale Invoice Not Found!',
            ]);
        }

        $sale_invoice = $sale_invoice->update(['refferal_lab_id' => $request->refferal_id]);

        return response()->json([
            'success' => true,
            'message' => 'Sale Invoice Referral Lab Updated Successfully.',
        ]);
    }

    public function pathologyCollection($id)
    {
        $moduleCode = 'PATHOLOGY';
        $transactionSummery = $this->TransactionSummery($id, $moduleCode);
        $transactionHistory = $this->transactionHistory($id, $moduleCode);

        $sale_invoice = SaleInvoice::with('getPatient')->find($id);

        $data = AcReceipt::with('accountReceiptDetail')->where('voucher_id',$id)->where('module_code',$moduleCode)->latest()->get();

        if (!$sale_invoice && !$data) {
            return redirect()->route('lab-billings.index')->with('error', 'Record Not Found!');
        }

        return view('lab-billings.edit.collect', compact([
            'sale_invoice',
            'transactionSummery',
            'transactionHistory',
            'data',
        ]));
    }

    public function statement(Request $request)
    {
        $companies = Company::select('id', 'name')->get();
        $users     = SaleInvoice::select('users.id', 'users.name', 'users.email')
            ->leftjoin('users', 'users.id','sale_invoices.operator_id')
            ->groupBy('sale_invoices.operator_id')
            ->get();

        if ($request->ajax()) {
            $company = Company::find(Auth::user()->company_id);
            $collection_status  = $request->collection_status;
            $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());

            $from_date = $request->from_date ?
                Carbon::createFromFormat($this->companyDateFormate(), $request->from_date)->format('Y-m-d')
                    :date('Y-m-d');
            $to_date   = $request->to_date ?
                Carbon::createFromFormat($this->companyDateFormate(), $request->to_date)->format('Y-m-d')
                    :date('Y-m-d');

            $filters                              = $where        =  [] ;
            $filters['from_date']                     = date('Y-m-d', strtotime($from_date));
            $filters['to_date']                       = date('Y-m-d', strtotime($to_date));
            $filters['company']                       = $request->company != 'null' ? $request->company : '';
            $filters['created_by']                    = $request->created_by != 'null' ? $request->created_by : '';
            $filters['search_account']           = $request->search_account != 'null' ? $request->search_account : '';
            $filters['account_filter']           = $request->account_filter != 'null' ? $request->account_filter : '';

            $filters['category']                      = $request->category != 'null' ? $request->category : '';
            $filters['brand']                         = $request->brand != 'null' ? $request->brand : '';
            $where['sale_invoices.voucher_type_code'] = 'PATHOLOGY';

            $sale_invoice = SaleInvoice::getStatementSaleInvoice($where, $filters);

            $fromDate = date('Y-m-d H:i:s',strtotime($from_date));
            $toDate   = date('Y-m-d H:i:s',strtotime($to_date));

            return view('invoice-formats.lab-billings.statement-table', compact([
                'sale_invoice',
                'fromDate',
                'toDate',
                'companyDateFormate',
                'collection_status',
            ]));
        }

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

        return view('invoice-formats.lab-billings.statement', compact([
            'brands',
            'companies',
            'productCategory',
            'users'
        ]));
    }

    public function exportStatement(Request $request)
    {
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());

        $from_date = $request->from_date ?
            Carbon::createFromFormat($this->companyDateFormate(), $request->from_date)->format('Y-m-d')
                :date('Y-m-d');
        $to_date   = $request->to_date ?
            Carbon::createFromFormat($this->companyDateFormate(), $request->to_date)->format('Y-m-d')
                :date('Y-m-d');

        $filters                                  = $where        = [];
        $filters['from_date']                     = $from_date;
        $filters['to_date']                       = $to_date;
        $filters['search_account']                = $request->search_account ?? '';
        $filters['category']                      = $request->category ?? '';
        $where['sale_invoices.voucher_type_code'] = 'PATHOLOGY';

        $filters['company']                       = $request->company != 'null' ? $request->company : '';
        $filters['created_by']                    = $request->created_by != 'null' ? $request->created_by : '';
        $filters['brand']                         = $request->brand != 'null' ? $request->brand : '';
        $filters['collection_status']             = $request->collection_status != 'null' ? $request->collection_status : '';

        $data = SaleInvoice::getStatementSaleInvoice($where, $filters)->toArray();

        $fileName = 'Lab-Billing-Statements'.' From '.$from_date.' To '.$to_date.'.xlsx';

        return Excel::download(new LabBillingStatementExport($data), $fileName);
    }

    public function invoiceRefresh(Request $request, $id)
    {
        $data = SaleInvoice::find($id);

        if (!$data) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid Sale Invoice ID!',
            ]);
        }

        $this->refreshInvoiceSubDetails($id);

        return response()->json([
            'success' => true,
            'message' => 'Sale Invoice Sub Details Refreshed Successfully.',
        ]);
    }

    public function searchItemOptions(Request $request)
    {
        $data = TestItemOption::where('test_item_id', $request->test_id)->where('name', 'LIKE', $request->search_text)->get();

        $response = '';
        foreach ($data as $key => $value) {
            $response .= '<li class="list-group-item test-options" data-id="'. $value->test_item_id .'">' . $value->name . '</li>';
        }

        return $response;
    }
}
