<?php

namespace App\Http\Controllers\Purchase;

use App\Exports\Purchase\PurchaseInvoiceExport;
use App\Http\Controllers\Controller;
use App\Models\Account;
use App\Models\AccountAddress;
use App\Models\AccountingGroup;
use App\Models\AccountTransaction;
use App\Models\Company;
use App\Models\CompanyAddress;
use App\Models\MasterType;
use App\Models\MenuModelPermission;
use App\Models\PaymentMode;
use App\Models\PaymentVoucher;
use App\Models\PaymentVoucherDetail;
use App\Models\Product;
use App\Models\ProductPrice;
use App\Models\Purchase\PurchaseInvoiceBatches;
use App\Models\Purchase\PurchaseInvoiceDetails;
use App\Models\Purchase\PurchaseInvoices;
use App\Models\Stock;
use App\Models\VoucherCollection;
use App\Models\VoucherCollectionDetail;
use App\Models\VoucherMaster;
use App\Models\VoucherType;
use App\Traits\PurchaseBasicTransactionTrait;
use App\Traits\TransactionSummeryTrait;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\ProductBrand;
use App\Models\ProductGroup;
use App\Models\ProductCategory;
use App\Models\BusinessDivision;
use App\Exports\ReportAndInsightsExport;
use App\Models\Stocks\ProductShortlist;

class PurchaseInvoiceController extends Controller
{
    use PurchaseBasicTransactionTrait,TransactionSummeryTrait;

    public function index(Request $request)
    {
        if (!$this->checkPermission('purchase-list')) {
            return redirect()->back()->with('info', 'You don\'t have enough permission to access this page.');
        }

        \Session::forget('purchase_products_cart');

        $data = PurchaseInvoices::select('*')
            ->with('getPurchaseInvoiceDetail')
            ->with('getRefferalLab')
            ->with('getCustomer')
            ->with('getOperator')
            ->with('getPaymentMode')
            ->when(!in_array('Admin',\Auth()->user()->roles->pluck('name')->all()), function($query) {
                $query->where('purchase_invoices.operator_id', \Auth()->id())
                    ->where('purchase_invoices.company_id', \Auth()->user()->company_id);
            })
            ->when(in_array('Admin',\Auth()->user()->roles->pluck('name')->all()), function($query) {
                $query->where('purchase_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
                ->when(!empty($search_query) && !empty($search_type), function ($query) use ($search_type, $search_query) {
                    if ($search_type == 'invoice_no') {
                        $query->where('main_invoice_no', 'LIKE', '%' . $search_query . '%');
                    } else if ($search_type == 'pat_name') {
                        $query->whereHas('getCustomer', 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('getCustomer.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('getCustomer', 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 . '%');
                            });
                        });
                    }
                })
                ->latest()
                ->paginate($sort_by);

            return view('purchase.purchase-invoice.table', compact('data'));
        } else {
            $data = $data->latest()
                ->paginate(10);

            return view('purchase.purchase-invoice.index', compact('data'));
        }
    }

    public  function create(Request $request)
    {
        if (!$this->checkPermission('purchase-create')) {
            return redirect()->back()->with('info', 'You don\'t have enough permission to access this page.');
        }

        $company_id      = Auth::user()->company_id ?? '';
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode     = $country_code->country_code ?? 'us';
        $data            = \Session::get('purchase_products_cart') ?? [];
        $customer        =  '';

        if (!empty($data) && isset($data['customer_id']) && $data['customer_id'] != '') {
            $customer = Account::getAccount([
                        'accounts.id' => $data['customer_id']
                    ], ['VENDOR']);
            if (isset($customer)) {
                $customer->full_name = $customer->name .
                    ($customer->code   != '' ? ', ' . $customer->code : '') .
                    ($customer->gender != '' ? ', ' . $customer->gender : '') .
                    ($customer->age    != '' ? ', ' . $customer->age . ' yrs' : '') .
                    ($customer->phone_no != '' ? ', ' . $customer->phone_no : '');
            }
        }
        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();
        return view('purchase.purchase-invoice.create', compact(
            'customer',
            'countryCode',
            'company_id',
            'company_address',
            'voucher_master'
        ));
    }


    public function edit($id)
    {
        if (!$this->checkPermission('purchase-edit')) {
            return redirect()->back()->with('info', 'You don\'t have enough permission to access this page.');
        }

        $company_id      = Auth::user()->company_id ?? '';
        $company_address = CompanyAddress::getCompanyAddress(['companies_addresses.company_id' => $company_id]);
        $countryCode     = $company_address->country_code ?? 'us';
        // $brands          = ProductBrand::select(['id','name','is_default'])->where(['status' => 1])->get();

        $purchase_invoice    = PurchaseInvoices::with('getPurchaseInvoiceDetails')->find($id);
        $data            = [];
        $customer        =  '';
        $doctor          = '';
        $amount = 0;

        if ($purchase_invoice) {
            $data['customer_id']            = $purchase_invoice->patient_id;
            $data['special_discount']       = $purchase_invoice->discount_amount;
            $data['amount_recieved']        = $purchase_invoice->received_amount;
            $data['due_balance_amount']     = $purchase_invoice->due_amount;
            $data['discount_type']          = 'FLAT';
            $data['invoice_date']           = $purchase_invoice->invoice_date;
            $data['payment_mode_id']        = $purchase_invoice->payment_mode_id;
            $data['supplier_invoice_number']= $purchase_invoice->supplier_invoice_number;

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

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

            foreach ($purchase_invoice->getPurchaseInvoiceDetails as $key => $value) {

                $productPriceData = ProductPrice::select('exp_date',$productPrice)->find($value->product_price_id);
                $product_price = $value->price;
                $flat_discount = 0;
                $per_discount = $value->discount_percentage;
                if ($product_price > 0) {
                    if ($flat_discount != '' && $flat_discount != 0) {
                        $per_discount  = ($flat_discount / $product_price) * 100;
                        $amount        = $product_price - $flat_discount;
                        $flat_discount = $flat_discount;
                    } else if ($per_discount != '' && $per_discount != 0) {
                        $flat_discount = ($per_discount / 100) * $product_price;
                        $per_discount  = $per_discount;
                        $amount        = $product_price - $flat_discount;
                    } else {
                        $amount        = $product_price;
                    }
                }

                $product_price = $amount??$product_price;
               

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

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

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

                /*************** Tax Calculation ***************** **/
                if ($value && $value->tax_calculation_type == 'EXCLUSIVE') {
                    $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
                    $productMrp      = ($product_price + $tax) * $main_qty;  // 1000+
                    $basic_amount    = $value->price;  //1000
        
                    $ActualRateAfterTax = $product_price + $tax;
                    $ActualRateBeforeTax = $product_price * $main_qty;
                    $totalTax = $tax*$main_qty;
                } else {
                    $basic_amount    = $value->price / (($tax_per + 100) / 100);
                    $basePrice       = $product_price / (1 + ($tax_per / 100));
                    $tax             = $product_price - $basePrice;
                    $productMrp      = $product_price * $main_qty;
                    $ActualRateAfterTax = $product_price - $tax;
                    $ActualRateBeforeTax = $ActualRateAfterTax * $main_qty ;
                    $totalTax = $tax*$main_qty;
                }

                
                // dd($tax);

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

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

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

        if ($purchase_invoice && isset($purchase_invoice->patient_id) && $purchase_invoice->patient_id != '') {
            $customer = Account::getAccount([
                'accounts.id' => $purchase_invoice->patient_id
            ]);
            if (isset($customer)) {
                $customer->full_name = $customer->name .
                    ($customer->code   != '' ? ', ' . $customer->code : '') .
                    ($customer->gender != '' ? ', ' . $customer->gender : '') .
                    ($customer->age    != '' ? ', ' . $customer->age . ' yrs' : '') .
                    ($customer->phone_no    != '' ? ', ' . $customer->phone_no : '');
            }
        }
        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();
        return view('purchase.purchase-invoice.edit.edit', compact(
            'id',
            'customer',
            'countryCode',
            'purchase_invoice',
            'voucher_master'
        ));
    }

    public function editBilling($id)
    {
        $sale_invoice = PurchaseInvoices::find($id);
         
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        if (!$sale_invoice) {
            $data = [];
            \Session::put('purchase_products_cart', $data);

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

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

            return redirect()->route('purchase.edit', $id)->with('error', 'No product added in cart!');
        }

        $ids = [];

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

        $ids[] = $data['customer_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("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('account_types', 'account_types.id', 'accounts.account_type_id')
            ->whereIn('accounts.id', $ids)
            ->get();
        if (empty($accounts) || count($accounts) < 1) {
            $data = [];

            return redirect()->route('purchase.create')->with('error', 'Empty cart!');
        }
        // dd($accounts);

        $customer = [];
        $doctors  = [];

        foreach ($accounts as $item) {
            if ($item['type_code'] == 'CUSTOMER' || $item['type_code'] == 'PATIENT' || $item['type_code'] == 'VENDOR') {
                $customer = $item;
            }
        }


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

        $sales_agent = MasterType::where('type_name', 'Sales Agent')->get();
        $delivery_agent = MasterType::where('type_name', 'Delivery Partner')->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();


        $creditTransaction = [];
        $debitTransaction  = [];
        $receipt           = [];

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

        $transactionSummery = $this->PurchaseTransactionSummery($id, 'PURCHASE');
        $transactionHistory = $this->PurchaseTransactionHistory($id, 'PURCHASE');
        $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('purchase.purchase-invoice.edit.billing', compact([
            'id',
            'data',
            'customer',
            'sale_invoice',
            // 'voucher_master',
            'delivery_agent',
            'sales_agent',
            'accounting_group',
            'receipt',
            'creditTransaction',
            'debitTransaction',
            'discount_group',
            'round_off',
            'transactionHistory',
            'transactionSummery',
            'TpaAccounts',
            'companyDateFormate'
        ]));
    }

    public function update(Request $request, $id)
    {
        
        $sale_invoice   = PurchaseInvoices::find($id);
        $data = \Session::get('purchase_products_cart') ?? [];
        if (!$sale_invoice || !$data) {
            $data = [];
            \Session::put('purchase_products_cart', $data);

            return redirect()->route('purchase.index')->with('error', 'Purchase 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('purchase_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'))) : '';

        $sale_invoice_update  = [
            'payment_term_id'         => $request->payment_term_id,
            'supplier_invoice_number' => $request->supplier_invoice_no??'',
            'billing_amount'          => $data['amount'],
            'invoice_date'            => $invoice_date,
            'patient_id'              => $data['customer_id'],
            'doctor_id'               => $data['doctor_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,
        ];

        $sale_invoice->update($sale_invoice_update);

        $where = [
            'purchase_invoice_id'    => $id,
        ];

        $invoice_batchData = [
            'sample_barcode'         => $request->sample_barcode,
            'sample_receive_date'    => $request->sample_receive_date,
            'sample_receive_time'    => $request->sample_receive_time,
            'remarks_for_technician' => $request->remarks_for_technician,
            'updated_by'             => Auth::user()->id,
        ];
        //sale invoice batch
        $invoice_batch  = PurchaseInvoiceBatches::where($where)->first();
        $invoice_batch->update($invoice_batchData);


        /*********************  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->PurchaseOthersTransaction(
                $sale_invoice->id,
                $transactions_no,
                'PURCHASE',
                $request->discount_account_id,
                $request->special_discount
            );
        }
        $discount['mode_id'] = $request->discount_account_id ?? '';
        $discount['amount'] = $request->special_discount ?? '';
        /********************* End Spacial Discount Store Calculation ***********************/

        /*********************  Round Off Store Calculation ***********************/
        if (isset($request->round_off_amount)) {
            # 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->PurchaseOthersTransaction(
                $sale_invoice->id,
                $transactions_no,
                'PURCHASE',
                $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_detail_ids = $sale_invoice_sub_detail_ids = $product_ids = $price_ids = [];
        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();
        foreach ($data['products'] as $key => $value) {
            $product = Product::select('tax_slab_id')->where('id', $value['product_id'])
                // ->with('getProductPrice')
                ->first();


            $item = [
                'product_price_id'    => $value['price_id'] ?? '',
                'price'               => $value['product_price'],
                'basic_amount'        => $value['product_basic'],
                'discount_percentage' => $value['per_discount'],
                'discount_amount'     => $value['flat_discount'],
                'total_amount'        => $value['amount'],
                'item_details'        => $value['product_detail'],
                'main_qty'            => $value['main_qty'],
                'alt_qty'             => $value['loose_qty'],
                'free_qty'            => $value['free_qty'],
                'item_batch'          => $value['batch'],
                'tax_slab_id'         => $product->tax_slab_id ?? '',
                'tpa_amount'          => 0,
                'customer_amount'     => $value['amount'] ?? 0,
                'tax_calculation_type'=> $voucher_master->tax_calculation??'',
            ];

            $sale_invoice_details = PurchaseInvoiceDetails::updateOrCreate([
                'product_id'                => $value['product_id'],
                'purchase_invoice_id'       => $sale_invoice->id,
                'product_price_id'          => $value['price_id']
            ], $item);

            $sale_invoice_detail_ids[] = $sale_invoice_details->id;
            $product_ids[]             = $value['product_id'];
            $price_ids[]               = $value['price_id'];

            /**************Stock IN Function ********************/
            stockIn($value['product_id'] , $value['main_qty'], $value['product_price'],$invoice_batch->id, $value['price_id'],'',$sale_invoice->id,'PURCHASE');
        }

        PurchaseInvoiceDetails::whereNotIn('id', $sale_invoice_detail_ids)
        ->where(['purchase_invoice_id' => $sale_invoice->id])
        ->delete();
        Stock::whereNotIN('product_id',$product_ids)
        ->whereNotIN('batch_id',$price_ids)
        ->where(['voucher_id'=>$sale_invoice->id,'voucher_type'=>'PURCHASE'])
        ->delete();


        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'PURCHASE')->where(['status' => 1])->first();


        # last voucher count for main voucher type invoice number
        $voucher_type_last_count = PurchaseInvoices::select('last_voucher_type_count')->where('voucher_type_code', 'PURCHASE')->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 ?? 'SRT'),
            ($voucher_type->voucherSeries->postfix ?? ''),
            ($voucher_type->voucherSeries->separator ?? '-'),
            ($voucher_type->voucherSeries->length ?? 5)
        );

        $receiptVoucher = PaymentVoucher::where(['voucher_id'=>$id,'module_code'=>'PURCHASE'])->first();
        if($receiptVoucher)
        {


        $item = [
            'receipt_date'      => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
            'remarks'           => $request->remarks??'',
            'updated_by'        => Auth::user()->id,
        ];

        $receiptVoucher->update($item);

        $item1 = [
           'account_id'             => $data['customer_id'],
           'amount'                 => $data['amount'],
           'transaction_date'       => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
        ];

        $acDEBITReceiptTransaction = PaymentVoucherDetail::where([
                'transaction_type' => 'DEBIT',
                'voucher_id'       => $receiptVoucher->id ?? '',
                'module_code'      => 'PURCHASE'
            ])->first();
        $acDEBITReceiptTransaction->update($item1);

        $voucher_collection = VoucherCollection::where([
            'money_receipt_id'  => $receiptVoucher->id,
        ])->first();

        $voucher_collection->update(['updated_by' => Auth::user()->id]);

        }

        /*********************basic Transaction Insert Into Account Transaction Table */
        $this->updateTransaction('PURCHASE',
                                $sale_invoice->id,
                                $invoice_batch->id,
                                $voucher_type->code,
                                $data['customer_id'],
                                $data,
                                $roundOff,
                                $discount,
                                $request->special_discount
                            );

            /****************Payment Voucher Entry**********************/
            if ($request->amount_recieved > 0) {
                $this->paymentVoucherCreate($request,$data, $sale_invoice->id);
            }


        \Session::forget('purchase_products_cart');

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


    public function searchProducts(Request $request)
    {
        $searchTerm = $request->search;
        $brand_id   = $request->brand_id ?? '';
        $results    = Product::select(
                'products.id',
                'products.name',
                'products.shortcode',
                'products.hsncode',
            )
            ->where(function ($query) use ($searchTerm) {
                $query->where('products.name', 'LIKE', "%" . $searchTerm . "%")
                      ->orWhere('products.product_code', 'LIKE', "%" . $searchTerm . "%")
                      ->orWhere('products.shortcode', 'LIKE', "%" . $searchTerm . "%");
            })
            ->when(!empty($brand_id),function ($query) use ($brand_id) {
                $query->where('products.brand_id', $brand_id);
            })
            ->where('products.status', 1)
            ->limit(15)
            ->get();

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


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

        if (!isset($data['customer_id']) || $data['customer_id'] == '') {
            $data['customer_id'] = $request->customer_id;
        }
        if (!isset($data['doctor_id']) || $data['doctor_id'] == '') {
            $data['doctor_id'] = $request->doctor_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['price_id'] == $request->price_id ) {
                    return response()->json(['success' => true, 'data' => $data]);
                }
            }
        }

        $product_price = $request->product_price;
        $flat_discount = $request->flat_discount ?? '0';
        $per_discount  = $request->per_discount ?? '0';

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

            } else if ($per_discount != '' && $per_discount != 0) {
                $flat_discount = (($per_discount / 100) * $product_price) * $request->main_qty;
                $flat_per_discount = (($per_discount / 100) * $product_price);
                $per_discount  = $per_discount;
                $amount        = $product_price - $flat_per_discount;
               
            } else {
                $amount        = $product_price;
            }
        }
        
        $product_price = $amount??$product_price;
        $main_qty      = $request->main_qty > 0 ? $request->main_qty : ($request->loose_qty > 0 ? $request->loose_qty : 1);
        $main_qty_amount = $main_qty * $product_price;
        $amount        = '0';
        $productMrp    = 0;
        $ActualRateAfterTax = 0;
        $ActualRateBeforeTax = 0;
        $totalTax            = 0;
        $tax_per = $product->tax == 'Tax Free' ? 0 : preg_replace('/[^0-9]/', '', $product->tax);

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

        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();
        if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
            $tax             = ($tax_per / 100) * $product_price; //(12/100)*1000;
            $productMrp      = ($product_price + $tax) * $main_qty;  // 1000+
            $basic_amount    = $request->product_price;  //1000

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

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

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

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

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

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

    public function cartProductUpdate(Request $request)
    {
        $data = \Session::get('purchase_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($data['products'])) {
                    foreach ($data['products'] as $key => $value) 
                    {
                        $saleVoucher = VoucherType::select(['default_price_type'])->where(['code'=>'PURCHASE'])->first();

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

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

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

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

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

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

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

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

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

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



                            $productMrp = $basic_amount = 0;

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

                                } else if ($per_discount != '' && $per_discount != 0) {

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

                                } else {
                                    $amount        = $product_price;
                                }
                            }
                            
                            $product_price = $amount??$product_price;
                            $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();
                            if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                                $tax   =  $flat_tax        = ($tax_per / 100) * $product_price; //(12/100)*1000;
                                $productMrp      = ($product_price + $tax) * $data['products'][$key]['main_qty'];  // 1000+
                                $basic_amount    = $product->mrp;  //1000
                    
                                $ActualRateAfterTax = $product_price + $tax;
                                $ActualRateBeforeTax = $product_price * $data['products'][$key]['main_qty'];
                                $totalTax = $tax*$data['products'][$key]['main_qty'];
                            } else {
                                $basic_amount    = $product->mrp / (($tax_per + 100) / 100);
                                $basePrice       = $product_price / (1 + ($tax_per / 100));
                                $tax  =    $flat_tax       = $product_price - $basePrice;
                                $productMrp      = $product_price * $data['products'][$key]['main_qty'];
                                $ActualRateAfterTax = $product_price - $tax;
                                $ActualRateBeforeTax = $ActualRateAfterTax * $data['products'][$key]['main_qty'] ;
                                $totalTax = $tax*$data['products'][$key]['main_qty'];
                            }


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

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

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

                            // $main_qty_amount = $value['main_qty'] * $request->product_price;

                            // $product_price  = number_format($main_qty_amount, 2, '.', '');
                            $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();

                            $product_price = $request->product_price;
                            $flat_discount = $request->flat_discount ?? '0';
                            $per_discount  = $request->per_discount ?? $data['products'][$key]['per_discount'];
    
                            $productMrp = $basic_amount = 0;
    
                            if ($product_price > 0) {
                                if ($flat_discount != '' && $flat_discount != 0) {
                                    $per_discount  = $flat_discount / ($product_price * $data['products'][$key]['main_qty']) * 100;
    
                                    $flat_discount = (($per_discount / 100) * $product_price) * $data['products'][$key]['main_qty'];
                                    $flat_per_discount = (($per_discount / 100) * $product_price);
                                    $per_discount  = $per_discount;
                                    $amount        = $product_price - $flat_per_discount;
                                } else if ($per_discount != '' && $per_discount != 0) {
    
                                    $flat_discount = (($per_discount / 100) * $product_price) * $data['products'][$key]['main_qty'];
                                    $flat_per_discount = (($per_discount / 100) * $product_price);
                                    $per_discount  = $per_discount;
                                    $amount        = $product_price - $flat_per_discount;
                                } else {
                                    $amount        = $product_price;
                                }
                            }
    
                            $product_price = $amount ?? $product_price;
    
                            if ($voucher_master && $voucher_master->tax_calculation == 'EXCLUSIVE') {
                                $tax   =  $flat_tax        = ($tax_per / 100) * $product_price; //(12/100)*1000;
                                $productMrp      = ($product_price + $tax) * $data['products'][$key]['main_qty'];  // 1000+
                                $basic_amount    = $request->product_price;  //1000
    
                                $ActualRateAfterTax = $product_price + $tax;
                                $ActualRateBeforeTax = $product_price * $data['products'][$key]['main_qty'];
                                $totalTax = $tax * $data['products'][$key]['main_qty'];
                            } else {
                                $basic_amount    = $request->product_price / (($tax_per + 100) / 100);
                                $basePrice       = $product_price / (1 + ($tax_per / 100));
                                $tax  =    $flat_tax       = $product_price - $basePrice;
                                $productMrp      = $product_price * $data['products'][$key]['main_qty'];
                                $ActualRateAfterTax = $product_price - $tax;
                                $ActualRateBeforeTax = $ActualRateAfterTax * $data['products'][$key]['main_qty'];
                                $totalTax = $tax * $data['products'][$key]['main_qty'];
                            }
    
    
                            $amount = ($basic_amount - $flat_discount);
                            $amount = number_format($amount, 2, '.', '');
    
                            $convertion_factor = !empty($product->convertion_factor) ? $product->convertion_factor : 1;
                            $amount            = $main_qty_amount * $amount / $convertion_factor;
                            $flat_discount     = number_format($flat_discount, 2, '.', '');
                            $flat_tax          = number_format($totalTax, 2, '.', '');
                            $data['products'][$key]['flat_discount'] = $flat_discount;
                            $data['products'][$key]['per_discount']  = $per_discount;
                            $data['products'][$key]['tax_flat']      = $flat_tax;
                            $data['products'][$key]['amount']        = $productMrp;
                            $data['products'][$key]['product_price'] = $basic_amount;
                            $data['products'][$key]['product_mrp']   = convertDecimelPoint($ActualRateAfterTax) ?? '';
                            $data['products'][$key]['product_basic'] = convertDecimelPoint($ActualRateBeforeTax) ?? '';
                            $data['amount']                          = $data['amount'] + $productMrp;
                            $due_balance_amount                      = $data['amount'] - $flat_discount;
                            $data['due_balance_amount']              = number_format($due_balance_amount - $data['amount_recieved'], 2, '.', '');
                        }
                    }
                }

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

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

            }

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

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


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

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

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

        $amount = $data['amount'];

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

            return $product['price_id'] != $id;
        });
        if (count($data['products']) == 0) {
            $data['amount'] = 0;
        } else {
            $data['amount'] = $amount;
        }

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

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

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

    public function billing()
    {
        $data = \Session::get('purchase_products_cart') ?? [];
        if (empty($data) || !isset($data['products']) || count($data['products']) < 1) {
            $data = [];
            \Session::put('purchase_products_cart', $data);

            return redirect()->route('purchase.create')->with('error', 'No product added in cart!');
        }

        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        $ids = [];
        if (isset($data['doctor_id']) && $data['doctor_id'] != '') {
            $ids[] = $data['doctor_id'] ?? 0;
        }
        $ids[] = $data['customer_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',
            'account_addresses.address_line1 as account_address',
            \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')
            ->leftjoin('account_addresses', 'account_addresses.account_id', 'accounts.id')
            ->whereIn('accounts.id', $ids)
            ->get();

        $accountAddress = AccountAddress::whereIn('account_id', $ids)->where('is_default', 1)->first();

        $payment_mode = PaymentMode::where('status', 1)->get();
        $sales_agent = MasterType::where('type_name', 'Sales Agent')->get();
        $delivery_agent = MasterType::where('type_name', 'Delivery Partner')->get();

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

            return redirect()->route('sale.create')->with('error', 'Empty cart!');
        }
        $customers = [];
        $doctors = [];


        foreach ($accounts as $item) {
            if ($item['type_code'] == 'CUSTOMER' || $item['type_code'] == 'PATIENT' || $item['type_code'] == 'VENDOR') {
                $customers = $item;
            } elseif ($item['type_code'] == 'DOCTOR') {
                $doctors = $item;
            }
        }

        $voucher_master   = VoucherMaster::select(['id', 'voucher_name'])->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::select(['id', 'name'])->where(['code' => 'DISCOUNT_ALLOWED'])->first();
        $round_off      = Account::select(['id', 'name'])->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('purchase.purchase-invoice.billing', compact([
            'data',
            'customers',
            'doctors',
            'voucher_master',
            // 'payment_types',
            'accounting_group',
            'accounts',
            'accountAddress',
            'sales_agent',
            'delivery_agent',
            'payment_mode',
            'discount_group',
            'round_off',
            'TpaAccounts',
            'companyDateFormate'
        ]));
    }

    public function store(Request $request)
    {

        $validator = \Validator::make($request->all(), [
            'supplier_invoice_no'        => 'required|unique:purchase_invoices,supplier_invoice_number,NULL,id',
        ],[
            'supplier_invoice_no.required' => 'The Supplier Invoice Number is  required.',
            'supplier_invoice_no.unique'   => 'The Supplier Invoice Number has already been taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }

            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = \Session::get('purchase_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', 'PURCHASE')
            ->first();

        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'PURCHASE')->where(['status' => 1])->first();



        # last voucher count for main voucher type invoice number
        $voucher_type_last_count = PurchaseInvoices::select('last_voucher_type_count')->where('voucher_type_code', 'PURCHASE')->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 ?? 'SRT'),
            ($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'))) : '';
        $purchase_invoice  = [
            'payment_term_id'         => $request->payment_term_id,
            'supplier_invoice_number' => $request->supplier_invoice_no??'',
            'invoice_date'            => $invoice_date,
            'patient_id'              => $data['customer_id'],
            'doctor_id'               => $data['doctor_id']??'',
            'reff_no'                 => $request->reff_no,

            'sale_delivery_status'    => 'PENDING',
            'company_id'              => $company_id,
            'status'                  => 'NEWPURCHASE',
            'special_case_id'         => $request->special_case,
            'discount_amount'         => $request->special_discount,

            'financial_year_id'       => $this->financialyear(),
            'industry_type_id'        => 2, // pathology from bussiness divisions.
            'operator_id'             => Auth::ID(),
            'payment_mode_id'         => $request->payment_mode_id ?? '',
            'transaction_mode_id'     => $request->transaction_mode_id ?? '',
            'bussiness_source_id'     => $request->bussiness_source ?? '',
            'voucher_type_invoice_no' => $voucher_type_invoice_no,
            'last_voucher_type_count' => $voucher_type_count,
            'ship_to_id'              => $request->ship_to,
            'dispatch_from_id'        => $request->ship_from,
            'bill_to_account_id'      => $request->bill_to_account_id,
            'tpa_corporate_id'        => $request->tpa_corporate_id,

        ];

        $purchase_invoice = PurchaseInvoices::create($purchase_invoice);


        $voucher_count_batch      = PurchaseInvoiceBatches::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        $last_voucher_count_batch = isset($voucher_count_batch) && isset($voucher_count_batch->last_voucher_count) ? $voucher_count_batch->last_voucher_count + 1 : ($voucher_master->voucherSeries->start_from + 1 ?? 1);

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

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

        $invoice_batch = [
            'purchase_invoice_id'       => $purchase_invoice->id,
            'invoice_batch_date'        => Carbon::now(),
            'invoice_batch_no'          => $main_invoice_no,
            'last_voucher_count'        => $last_voucher_count_batch,
            'account_id'                => $data['customer_id'],
            'created_by'                => Auth::user()->id,
            'consultant_id'             => $data['doctor_id'],
            'referrence_voucher_id'     => $data['sale_invoice_id'] ?? '',
            'referrence_voucher_type'   => ($voucher_type->code ?? ''),
        ];
        //sale Return invoice batch
        $invoice_batch  = PurchaseInvoiceBatches::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)
            );


            $this->PurchaseOthersTransaction(
                $purchase_invoice->id,
                $transactions_no,
                'PURCHASE',
                $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 (isset($request->round_off_amount)) {
            # last voucher count for main Transaction number
            $transaction_voucher_count      = AccountTransaction::select('last_id')->orderBy('created_at', 'DESC')->first();
            $transaction_voucher_master     = VoucherMaster::select('id')
                ->with('voucherSeries')
                ->where('voucher_code', 'TRANSACTION')
                ->where(['status' => 1])
                ->first();
            $last_voucher_count = isset($transaction_voucher_count) && isset($transaction_voucher_count->last_id) ?
                $transaction_voucher_count->last_id + 1 : ($transaction_voucher_master->voucherSeries->start_from + 1 ?? 1);

            $transactions_no = $this->generateCode(
                $last_voucher_count,
                ($transaction_voucher_master->voucherSeries->prefix ?? 'TRN'),
                ($transaction_voucher_master->voucherSeries->postfix ?? ''),
                ($transaction_voucher_master->voucherSeries->separator ?? '-'),
                ($transaction_voucher_master->voucherSeries->length ?? 5)
            );


            $this->PurchaseOthersTransaction(
                $purchase_invoice->id,
                $transactions_no,
                'PURCHASE',
                $request->round_off_account_id,
                $request->round_off_amount,
                $invoice_batch->id
            );
        }
        $roundOff['mode_id'] = $request->round_off_account_id ?? '';
        $roundOff['amount']  = $request->round_off_amount ?? '';
        /********************* End  Round Off Store Calculation ***********************/
        $voucher_master = VoucherMaster::select('tax_calculation')->where('voucher_code', 'PURCHASE')->where(['status' => 1])->first();
        foreach ($data['products'] as $key => $value) {
            $product = Product::where('id', $value['product_id'])
                ->with('getProductPrice')
                ->first();

            $item = [
                'purchase_invoice_id'       => $purchase_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['product_basic'],
                'discount_percentage'       => $value['per_discount'],
                'discount_amount'           => $value['flat_discount'],
                'total_amount'              => $value['amount'],
                'item_details'              => $value['product_detail'],
                'main_qty'                  => $value['main_qty'],
                'alt_qty'                   => $value['loose_qty'],
                'free_qty'                  => $value['free_qty'],
                'item_batch'                => $value['batch'] ?? '',
                'tax_slab_id'               => $product->tax_slab_id ?? '',
                'tpa_amount'                => 0,
                'customer_amount'           => $value['amount'] ?? 0,
                'tax_calculation_type'      => $voucher_master->tax_calculation??''
            ];
            $shortProduct = ProductShortlist::where(['product_id'=>$value['product_id'],'status'=>'PENDING','quantity'=>$value['main_qty']])->first();
            if(isset($shortProduct)){
                $shortProduct->update(['status'=>'DONE','restock_voucher_id'=>$purchase_invoice->id]);
            }

            $sale_invoice_details = PurchaseInvoiceDetails::create($item);

            /**************Stock In Function ********************/
            stockIn($value['product_id'] , $value['main_qty'], $value['product_price'],$invoice_batch->id, $value['price_id'],'',$purchase_invoice->id,'PURCHASE',$value['free_qty']);
        }
        /*********************basic Transaction Insert Into Account Transaction Table */
            $this->createTransaction('PURCHASE',
                                    $purchase_invoice->id,
                                    $invoice_batch->id,
                                    $voucher_type->code,
                                    $data['customer_id'],
                                    $data,
                                    $roundOff,
                                    $discount,
                                    $request->special_discount
                                );
            /****************Payment Voucher Entry**********************/
            if ($request->amount_recieved > 0) {
                $this->paymentVoucherCreate($request,$data,$purchase_invoice->id);
            }
            

        \Session::forget('purchase_products_cart');

        return redirect()->route('purchase-invoice', ['id' => $purchase_invoice->id])->with('success', "Item Purchase Successfully");
    }


    public function paymentVoucherCreate($request,$data, $purchaseId)
    {
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        
        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'PAYMENT')->where(['status' => 1])->first();
        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'PAYMENT')->where(['status' => 1])->first();

        # last voucher count for main invoice number
        $voucher_count      = PaymentVoucher::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        $last_voucher_count = isset($voucher_count) && isset($voucher_count->last_voucher_count) ? $voucher_count->last_voucher_count + 1 : ($voucher_master->voucherSeries->start_from + 1 ?? 1);

        $main_invoice_no = $this->generateCode(
            $last_voucher_count,
            ($voucher_master->voucherSeries->prefix ?? 'PV'),
            ($voucher_master->voucherSeries->postfix ?? ''),
            ($voucher_master->voucherSeries->separator ?? '-'),
            ($voucher_master->voucherSeries->length ?? 5)
        );

        # last voucher count for main voucher type invoice number
        $voucher_type_last_count      = PaymentVoucher::select('last_voucher_type_count')->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 ?? 'PV'),
            ($voucher_type->voucherSeries->postfix ?? ''),
            ($voucher_type->voucherSeries->separator ?? '-'),
            ($voucher_type->voucherSeries->length ?? 5)
        );

        $module      = MenuModelPermission::where('code','PURCHASE')->first();
        $module_id   = ($purchaseId);
        $module_code = ($module->code ?? 'PURCHASE');

        $item = [
            'receipt_no'              => $voucher_type_invoice_no,
            'overall_receipt_no'      => $main_invoice_no,
            'receipt_date'            => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
            'company_id'              => Auth::user()->company_id,
            'voucher_status'          => true,
            'remarks'                 => $request->remarks??'',
            'created_by'              => Auth::user()->id ?? '',
            'last_voucher_count'      => $last_voucher_count,
            'last_voucher_type_count' => $voucher_type_count,
            'financial_year_id'       => $this->financialyear(),
            'voucher_id'              => $purchaseId,
            'module_code'             => $module_code,
            'receipt_time'            => Carbon::now(),
        ];

        $receiptVoucher = PaymentVoucher::create($item);

        $item1 = [
           'module_code'         => $module_code,
           'voucher_type'        => 'PURCHASE',
           'voucher_master_id'   => $voucher_master->id ?? '',
           'voucher_id'          => $receiptVoucher->id ?? '',
           'account_id'          => $data['customer_id'] ?? '',
           'transaction_type'    => 'DEBIT',
           'details_narration'   => "",
           'amount'              => $data['amount'],
           'created_by'          => Auth::user()->id ?? '',
           'company_id'          => Auth::user()->company_id ?? '',
           'transaction_date'    => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
           'financial_year_id'   => $this->financialyear(),
           'transactions_status' => true
        ];
        $acReceiptTransaction = PaymentVoucherDetail::create($item1);
        $transactions_no = $this->generateRandomCode();

        $voucher_collection = VoucherCollection::create([
            'collection_date'   => date('Y-m-d'),
            'module_code'       => 'PURCHASE',
            'voucher_master_id' => $voucher_master->id ?? '',
            'voucher_id'        => $receiptVoucher->id,
            'voucher_type'      => 'PAYMENT',
            'money_receipt_id'  => $receiptVoucher->id,
            'created_by'        => Auth::user()->id,
        ]);

        if (isset($request->payment_mode) && count($request->payment_mode) > 0) {
            foreach ($request->payment_mode as $key => $item) {
                if ($item['amount'] > 0) {
                    $item1 = [
                       'module_code'            => $module_code,
                       'voucher_id'             => $receiptVoucher->id,
                       'voucher_master_id'      => $voucher_master->id ?? '',
                       'voucher_type'           => 'PAYMENT',
                       'account_id'             => $item['mode_id'],
                       'payment_mode_id'        => $item['mode_id'] ?? '',
                       'transaction_type'       => 'CREDIT',
                       'details_narration'      => '',
                       'amount'                 => $item['amount'],
                       'created_by'             => Auth::user()->id,
                       'company_id'             => Auth::user()->company_id,
                       'transaction_referrence' => "",
                       'transaction_date'       => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
                       'transaction_mode_id'    => $item['transaction_mode_id'] ?? $item['mode_id'],
                       'transactions_status'    => true,
                       'financial_year_id'   => $this->financialyear(),
                    ];
                    $acReceiptTransaction = PaymentVoucherDetail::create($item1);

                    $transactionsData = $this->generateTransactionNumber();

                    AccountTransaction::createTransaction([
                        'transactions_no'   => $transactionsData['transactions_no'],
                        'transaction_date'  => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
                        'module_code'       => 'PAYMENT_VOUCHER',
                        'voucher_id'        => $receiptVoucher->id,
                        'voucher_type'      => 'PAYMENT',
                        'voucher_sub_id'    => $acReceiptTransaction->id,
                        'account_id'        => $item['mode_id']  ?? '',
                        'transaction_type'  => 'DEBIT',
                        'details_narration' => '',
                        'amount'            => $item['amount'],
                        'financial_year_id' => $this->financialyear(),
                        'last_id'           => $transactionsData['last_count'],
                    ]);

                    $transaction = AccountTransaction::createTransaction([
                        'transactions_no'   => $transactionsData['transactions_no'],
                        'transaction_date'  => Carbon::createFromFormat($this->companyDateFormate(), $request->invoice_date)->format('Y-m-d'),
                        'module_code'       => 'PAYMENT_VOUCHER',
                        'voucher_id'        => $receiptVoucher->id,
                        'voucher_sub_id'    => $acReceiptTransaction->id,
                        'voucher_type'      => 'PAYMENT',
                        'account_id'        => $data['customer_id'] ?? '',
                        'transaction_type'  => 'CREDIT',
                        'details_narration' => '',
                        'amount'            => $item['amount'],
                        'financial_year_id' => $this->financialyear(),
                        'last_id'           => $transactionsData['last_count'],
                    ]);

                    $voucher_collection_detail = VoucherCollectionDetail::create([
                        'voucher_collection_id' => $voucher_collection->id,
                        'transaction_id'        => $transaction->id,
                    ]);
                }
            }
        }

     return true;
    }


    public function invoice($id)
    {
        $purchase_invoice = PurchaseInvoices::select('*')
            ->with('getPurchaseInvoiceDetails')
            ->with('getCustomer')
            ->with('getCompany')
            ->find($id);
        if (!$purchase_invoice) {
            return redirect()->route('purchase.index')->with('error', 'Sale Return Invoice not found');
        }

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

        $transactionSummery = $this->PurchaseTransactionSummery($id, 'PURCHASE');
        $transactionHistory = $this->PurchaseTransactionHistory($id, 'PURCHASE');

        return view('purchase.purchase-invoice.invoice', compact('purchase_invoice', 'voucher_type', 'transactionSummery', 'transactionHistory'));
    }


    public function destroy(Request $request)
    {
        $purchaseInvoice = PurchaseInvoices::find($request->id);
        $purchaseInvoiceId = $purchaseInvoice->id;

        if (isset($purchaseInvoiceId)) {
            $purchaseInvoice->update(['deleted_by' => \Auth::user()->id]);
            PurchaseInvoiceDetails::where('purchase_invoice_id', $purchaseInvoiceId)->delete();
            PurchaseInvoiceBatches::where('purchase_invoice_id', $purchaseInvoiceId)->delete();
        }


       
        $paymentVoucher = PaymentVoucher::where(['voucher_id'=>$purchaseInvoiceId,'module_code'=>'PURCHASE'])->first();
        if($paymentVoucher)
        {
            $paymentVoucher->update(['deleted_by'=>\Auth::user()->id]);
            PaymentVoucherDetail::where(['voucher_id'=>$paymentVoucher->id,'module_code'=>'PURCHASE'])->delete();

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

            AccountTransaction::where([
                'module_code' => 'PURCHASE',
                'voucher_id'  => $purchaseInvoiceId
            ])->delete();

            
            $paymentVoucher->delete();
        }

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



    public function collectionCreate($id,$moduleCode='PURCHASE')
    {
        $data = [];

        $purchase_invoice = PurchaseInvoices::with('getPatient')->find($id);
        $paymentVoucher   = PaymentVoucher::select(['id', 'voucher_id','receipt_date'])->where(['module_code' => $moduleCode, 'voucher_id' => $id])
        ->first();
       

        $creditTransaction = $debitTransaction = [];

        $creditTransaction = [];
        $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();

        $accounting_tds = Account::select(['id', 'name', 'account_category_id','accounting_group_id'])
                            ->where('code','TDS_RECEIVABLE')->first();
        $accounting_expenses = AccountingGroup::whereIN('code',['INDIRECT_EXPENSES'])->with('chart_of_expanses')->get();
        $financialYears = \Session::get('financialyear');
        

        $transactionSummery = $this->PurchaseTransactionSummery($id,$moduleCode);
        $transactionHistory = $this->PurchaseTransactionHistory($id,$moduleCode);
        $voucher_type ='PURCHASE';
        $payment_type = '';
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());

        return view('purchase.purchase-invoice.edit.collect', compact([
            'data',
            'purchase_invoice',
            'accounting_group',
            'creditTransaction',
            'debitTransaction',
            'financialYears',
            'voucher_type',
            'payment_type',
            'moduleCode',
            'id',
            'accounting_tds',
            'accounting_expenses',
            'paymentVoucher',
            'transactionSummery',
            'transactionHistory',
            'companyDateFormate'
        ]));
    }


    public function collectionStore(Request $request,$purchaseId)
    {

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

        # last voucher count for main invoice number
        $voucher_count      = PaymentVoucher::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        $last_voucher_count = isset($voucher_count) && isset($voucher_count->last_voucher_count) ? $voucher_count->last_voucher_count + 1 : ($voucher_master->voucherSeries->start_from + 1 ?? 1);

        $main_invoice_no = $this->generateCode(
            $last_voucher_count,
            ($voucher_master->voucherSeries->prefix ?? 'PV'),
            ($voucher_master->voucherSeries->postfix ?? ''),
            ($voucher_master->voucherSeries->separator ?? '-'),
            ($voucher_master->voucherSeries->length ?? 5)
        );

        # last voucher count for main voucher type invoice number
        $voucher_type_last_count      = PaymentVoucher::select('last_voucher_type_count')->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 ?? 'PV'),
            ($voucher_type->voucherSeries->postfix ?? ''),
            ($voucher_type->voucherSeries->separator ?? '-'),
            ($voucher_type->voucherSeries->length ?? 5)
        );

        $module      = MenuModelPermission::where('code','PURCHASE')->first();
        $module_id   = ($purchaseId);
        $module_code = ($module->code ?? 'PURCHASE');

        $item = [
            'receipt_no'              => $voucher_type_invoice_no,
            'overall_receipt_no'      => $main_invoice_no,
            'receipt_date'            => Carbon::createFromFormat($this->companyDateFormate(), $request->receipt_date)->format('Y-m-d'),
            'company_id'              => Auth::user()->company_id,
            'voucher_status'          => true,
            'remarks'                 => $request->remarks??'',
            'created_by'              => Auth::user()->id ?? '',
            'last_voucher_count'      => $last_voucher_count,
            'last_voucher_type_count' => $voucher_type_count,
            'financial_year_id'       => $this->financialyear(),
            'voucher_id'              => $purchaseId,
            'module_code'             => $module_code,
            'receipt_time'            => Carbon::now(),
        ];

        $receiptVoucher = PaymentVoucher::create($item);

        $item1 = [
           'module_code'         => $module_code,
           'voucher_type'        => 'PURCHASE',
           'voucher_master_id'   => $voucher_master->id ?? '',
           'voucher_id'          => $receiptVoucher->id ?? '',
           'account_id'          => $request->account_id ?? '',
           'transaction_type'    => 'DEBIT',
           'details_narration'   => "",
           'amount'              => $request->total_amount,
           'created_by'          => Auth::user()->id ?? '',
           'company_id'          => Auth::user()->company_id ?? '',
           'transaction_date'    => Carbon::createFromFormat($this->companyDateFormate(), $request->receipt_date)->format('Y-m-d'),
           'financial_year_id'   => $this->financialyear(),
           'transactions_status' => true
        ];
        $acReceiptTransaction = PaymentVoucherDetail::create($item1);
        $transactions_no = $this->generateRandomCode();

        $voucher_collection = VoucherCollection::create([
            'collection_date'   => date('Y-m-d'),
            'module_code'       => 'PURCHASE',
            'voucher_master_id' => $voucher_master->id ?? '',
            'voucher_id'        => $receiptVoucher->id,
            'voucher_type'      => 'PAYMENT',
            'money_receipt_id'  => $receiptVoucher->id,
            'created_by'        => Auth::user()->id,
        ]);

        if (isset($request->payment_mode) && count($request->payment_mode) > 0) {
            foreach ($request->payment_mode as $key => $item) {
                if ($item['amount'] > 0) {
                    $item1 = [
                       'module_code'            => $module_code,
                       'voucher_id'             => $receiptVoucher->id,
                       'voucher_master_id'      => $voucher_master->id ?? '',
                       'voucher_type'           => 'PAYMENT',
                       'account_id'             => $item['mode_id'],
                       'payment_mode_id'        => $item['mode_id'] ?? '',
                       'transaction_type'       => 'CREDIT',
                       'details_narration'      => '',
                       'amount'                 => $item['amount'],
                       'created_by'             => Auth::user()->id,
                       'company_id'             => Auth::user()->company_id,
                       'transaction_referrence' => "",
                       'transaction_date'       => Carbon::createFromFormat($this->companyDateFormate(), $request->receipt_date)->format('Y-m-d'),
                       'transaction_mode_id'    => $item['transaction_mode_id'] ?? $item['mode_id'],
                       'transactions_status'    => true,
                       'financial_year_id'   => $this->financialyear(),
                    ];
                    $acReceiptTransaction = PaymentVoucherDetail::create($item1);

                    $transactionsData = $this->generateTransactionNumber();

                    AccountTransaction::createTransaction([
                        'transactions_no'   => $transactionsData['transactions_no'],
                        'transaction_date'  => Carbon::createFromFormat($this->companyDateFormate(), $request->receipt_date)->format('Y-m-d'),
                        'module_code'       => 'PAYMENT_VOUCHER',
                        'voucher_id'        => $receiptVoucher->id,
                        'voucher_type'      => 'PAYMENT',
                        'voucher_sub_id'    => $acReceiptTransaction->id,
                        'account_id'        => $item['mode_id']  ?? '',
                        'transaction_type'  => 'DEBIT',
                        'details_narration' => '',
                        'amount'            => $item['amount'],
                        'financial_year_id' => $this->financialyear(),
                        'last_id'           => $transactionsData['last_count'],
                    ]);

                    $transaction = AccountTransaction::createTransaction([
                        'transactions_no'   => $transactionsData['transactions_no'],
                        'transaction_date'  => Carbon::createFromFormat($this->companyDateFormate(), $request->receipt_date)->format('Y-m-d'),
                        'module_code'       => 'PAYMENT_VOUCHER',
                        'voucher_id'        => $receiptVoucher->id,
                        'voucher_sub_id'    => $acReceiptTransaction->id,
                        'voucher_type'      => 'PAYMENT',
                        'account_id'        => $data['customer_id'] ?? '',
                        'transaction_type'  => 'CREDIT',
                        'details_narration' => '',
                        'amount'            => $item['amount'],
                        'financial_year_id' => $this->financialyear(),
                        'last_id'           => $transactionsData['last_count'],
                    ]);

                    $voucher_collection_detail = VoucherCollectionDetail::create([
                        'voucher_collection_id' => $voucher_collection->id,
                        'transaction_id'        => $transaction->id,
                    ]);
                }
            }
        }

     return redirect()->route('print-payment-voucher', ['id' => $receiptVoucher->id])->with('success', "Item Payment Successfully");
    }

    public function collectionList($invoice_id,Request $request)
    {
        $moduleCode = 'PURCHASE';
        $transactionSummery = $this->TransactionSummery($invoice_id, $moduleCode);
        $transactionHistory = $this->transactionHistory($invoice_id, $moduleCode);

        
        $purchase_invoice = PurchaseInvoices::with('getPatient')->find($invoice_id);
       
       
        $voucherType = VoucherType::select(['name','code'])->where('code',$moduleCode)->first();
        $data = PaymentVoucher::with('paymentVoucherDetail')->where('voucher_id',$invoice_id)->where('module_code',$moduleCode)->latest()->get();

        if (!$purchase_invoice && !$data && !$voucherType) {
            return redirect()->url($request->redirect)->with('error', 'Record Not Found!');
        }

        return view('purchase.purchase-invoice.collection-list', compact([
            'purchase_invoice',
            'transactionSummery',
            'transactionHistory',
            'data',
            'voucherType',
        ]));
    }


    public function statement(Request $request)
    {
        if ($request->ajax()) {
            $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
            $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
            $company           = $request->company ?? '';
            $search_account    = $request->search_account ?? '';
            $created_by        = $request->created_by ?? '';

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

            $invoices = $this->queryFilter($request);
           
            return view('invoice-formats.purchase.statement-table', compact([
                'voucher_type_code',
                'invoices',
                'from_date',
                'to_date',
                'transaction_mode',
            ]));
        }


        $company       = Company::find(Auth::user()->company_id);
        $companies     = Company::get();
        $voucher_type  = VoucherType::where('code', 'PURCHASE')->where(['status' => 1])->first();
        $voucher_types = VoucherType::select('name', 'code')->where(['status' => 1])->get();

        return view('invoice-formats.purchase.statement', compact(
            'voucher_types',
            'companies',
            'company',
            'voucher_type'
        ));
    }

    protected function queryFilter($request)
    {
        $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
        $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
        $company           = $request->company ?? '';
        $search_account    = $request->search_account ?? '';
        $created_by        = $request->created_by ?? '';
        $voucher_type_code = $request->voucher_type_code ?? '';
        $transaction_mode  = Account::select([ 'id', 'name', 'account_category_id'])
            ->with('chart_of_account_sub_type')
            ->where(function ($query) {
                $query->whereHas('chart_of_account_sub_type', function ($accounting_group) {
                    $accounting_group->where('is_payment_mode', '1');
                });
            })
            ->get()->pluck('id');

        $columns = [
            'purchase_invoices.id',
            'purchase_invoices.invoice_date',
            'purchase_invoices.main_invoice_no',
            'purchase_invoices.patient_id',
            'purchase_invoices.voucher_type_code',
            'purchase_invoices.payment_mode_id',
            'tax_masters.total_percentage as tax_percentage',
            'payment_terms.payment_term_name',
            'purchase_others_transactions.price as discount_amount',
            'payment_vouchers.id as ac_receiptst_amount',
            \DB::raw('SUM(purchase_invoice_details.price) as billing_amount'),
            \DB::raw('SUM(payment_voucher_details.amount) as ac_receipt_amount')
        ];

        $invoices = PurchaseInvoices::with(
                'getPurchaseInvoiceDetail',
                'getPatient',
                'getPaymentMode',
            )
            ->leftJoin('purchase_others_transactions','purchase_others_transactions.purchase_invoice_id','purchase_invoices.id')
            ->leftJoin('payment_terms','payment_terms.id','purchase_invoices.transaction_mode_id')
            ->leftJoin('purchase_invoice_details','purchase_invoice_details.purchase_invoice_id','purchase_invoices.id')
            ->leftJoin('tax_masters','purchase_invoice_details.tax_slab_id','tax_masters.id')
            ->leftJoin('accounts','purchase_invoices.patient_id','accounts.id')
            ->leftJoin('payment_vouchers', function($join) {
                $join->on('payment_vouchers.voucher_id', '=', 'purchase_invoices.id')
                    ->where('payment_vouchers.module_code', '=', 'PURCHASE');
            })
            ->leftJoin('payment_voucher_details', function($join) use ($transaction_mode) {
                $join->on('payment_voucher_details.voucher_id', '=', 'payment_vouchers.id')
                    ->whereIn('payment_voucher_details.account_id', $transaction_mode);
            })
            ->when(!empty($search_account), function($invoices) use($search_account) {
                $invoices->where('accounts.name', 'LIKE', '%' . $search_account . '%');
            })
            ->when(!empty($voucher_type_code), function($invoices) use($voucher_type_code) {
                $invoices->where('purchase_invoices.voucher_type_code', '=', $voucher_type_code);
            })
            ->when(!empty($created_by), function($invoices) use($created_by) {
                $invoices->where('purchase_invoices.operator_id', '=', $created_by);
            })
            ->when(!empty($company), function($invoices) use($company) {
                $invoices->where('purchase_invoices.company_id', '=', $company);
            })
            ->when(!empty($from_date) && !empty($to_date), function($query) use ($from_date, $to_date) {
                $query->when($from_date == $to_date, function($query2) use ($from_date) {
                    $query2->whereDate('purchase_invoices.invoice_date', $from_date);
                })
                ->when($from_date != $to_date, function($query2) use ($from_date, $to_date) {
                    $query2->whereBetween('purchase_invoices.invoice_date', [$from_date, $to_date]);
                });

            })
            ->select($columns)
            ->groupBy('main_invoice_no')
            ->get();
            return $invoices;

    }

    public function statementExport(Request $request)
    {
        $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
        $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
        $invoices          = $this->queryFilter($request);
        $invoices          = $invoices->toArray();
        $fileName          = 'Purchase-Statements'.' From '.$from_date.' To '.$to_date.'.xlsx';
        return Excel::download(new PurchaseInvoiceExport($invoices), $fileName);
    }

    public function itemWiseStatement(Request $request)
    {
        if ($request->ajax()) {
            $filters["from_date"]         = $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
            $filters["to_date"]           = $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
            $filters["company"]           = $company           = $request->company ?? '';
            $filters["search_account"]    = $search_account    = $request->search_account ?? '';
            $filters["created_by"]        = $created_by        = $request->created_by ?? '';
            $filters["voucher_type_code"] = $voucher_type_code = $request->voucher_type_code ?? '';
            $filters["brand_id"]          = $brand_id     = $request->get('brand_id');
            $filters["group_id"]          = $group_id     = $request->get('group_id');
            $filters["category_id"]       = $category_id  = $request->get('category_id');
            $filters["division_id"]       = $division_id  = $request->get('division_id');
            $filters["doctor_id"]         = $doctor_id  = $request->get('doctor_id');

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

            $saleInvoices = PurchaseInvoiceDetails::getItemWiseStatement([], $filters);

            return view('invoice-formats.purchase.item-wise-statement.statement-table', compact([
                'voucher_type_code',
                'saleInvoices',
                'from_date',
                'to_date',
                'transaction_mode',
            ]));
        }

        $company       = Company::find(Auth::user()->company_id);
        $companies     = Company::get();
        $voucher_type  = VoucherType::where('code', 'SALES')->where(['status' => 1])->first();
        $voucher_types = VoucherType::select('name', 'code')->where(['status' => 1])->get();

        $business_division = BusinessDivision::select('id','name')->where('status',1)->get();
        $brand             = ProductBrand::select('id','name')->where('status',1)->get();
        $category          = ProductCategory::select('id','name')->where('status',1)->get();
        $group             = ProductGroup::select('id','name')->where('status',1)->get();

        return view('invoice-formats.purchase.item-wise-statement.statement', compact(
            'voucher_types',
            'companies',
            'company',
            'business_division',
            'brand',
            'category',
            'group'
        ));
    }

    public function itemWiseStatementExport(Request $request)
    {
        $filters["from_date"]         = $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
        $filters["to_date"]           = $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
        $filters["company"]           = $company           = $request->company ?? '';
        $filters["search_account"]    = $search_account    = $request->search_account ?? '';
        $filters["created_by"]        = $created_by        = $request->created_by ?? '';
        $filters["voucher_type_code"] = $voucher_type_code = $request->voucher_type_code ?? '';
        $filters["brand_id"]          = $brand_id     = $request->get('brand_id');
        $filters["group_id"]          = $group_id     = $request->get('group_id');
        $filters["category_id"]       = $category_id  = $request->get('category_id');
        $filters["division_id"]       = $division_id  = $request->get('division_id');
        $filters["product_id"]       =$product_id = $request->product_id ?? '';
        $filters["doctor_id"]         = $doctor_id  = $request->get('doctor_id');

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

        $saleInvoices = PurchaseInvoiceDetails::getItemWiseStatement([], $filters);

        $fileName = 'Item-Wise-Purchase-Statement-'.' From '.$from_date.' To '.$to_date.'.xlsx';

        return Excel::download(new ReportAndInsightsExport($saleInvoices,$company), $fileName);
    }

    public function singleProductStatement(Request $request, $id)
    {
        $product = Product::find($id);

        if (!$product) {
            return redirect()->back()->with('error', 'Product not found.');
        }

        $filters["from_date"]  = $from_date = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
        $filters["to_date"]    = $to_date = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
        $filters["product_id"] = $id;

        if ($request->ajax()) {
            $filters["company"]           = $company           = $request->company ?? '';
            $filters["search_account"]    = $search_account    = $request->search_account ?? '';
            $filters["created_by"]        = $created_by        = $request->created_by ?? '';
            $filters["voucher_type_code"] = $voucher_type_code = $request->voucher_type_code ?? '';

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

            $saleInvoices = PurchaseInvoiceDetails::getItemWiseStatement([], $filters);

            return view('invoice-formats.purchase.single-product-statement.statement-table', compact([
                'voucher_type_code',
                'saleInvoices',
                'from_date',
                'to_date',
                'transaction_mode',
                'product',
            ]));
        }

        $product = Product::find($id);
        $company       = Company::find(Auth::user()->company_id);
        $companies     = Company::get();
        $voucher_type  = VoucherType::where('code', 'SALES')->where(['status' => 1])->first();
        $voucher_types = VoucherType::select('name', 'code')->where(['status' => 1])->get();

        return view('invoice-formats.purchase.single-product-statement.statement', compact(
            'voucher_types',
            'companies',
            'company',
            'from_date',
            'to_date',
            'id',
            'product',
        ));
    }

    public function allItemWiseStatement(Request $request)
    {
        if ($request->ajax()) {
            $filters["from_date"]         = $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
            $filters["to_date"]           = $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
            $filters["company"]           = $company           = $request->company ?? '';
            $filters["search_account"]    = $search_account    = $request->search_account ?? '';
            $filters["voucher_type_code"] = $voucher_type_code = $request->voucher_type_code ?? '';
            $filters["brand_id"]          = $brand_id     = $request->get('brand_id');
            $filters["group_id"]          = $group_id     = $request->get('group_id');
            $filters["category_id"]       = $category_id  = $request->get('category_id');
            $filters["division_id"]       = $division_id  = $request->get('division_id');
            $filters["doctor_id"]         = $doctor_id  = $request->get('doctor_id');
            $filters["product_id"]         = $product_id  = $request->product_id;

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

            $saleInvoices = PurchaseInvoiceDetails::getItemWiseStatement([], $filters);

            return view('invoice-formats.purchase.all_item-wise-statement.statement-table', compact([
                'voucher_type_code',
                'saleInvoices',
                'from_date',
                'to_date',
                'transaction_mode',
            ]));
        }

        $company       = Company::find(Auth::user()->company_id);
        $companies     = Company::get();
        $voucher_type  = VoucherType::where('code', 'SALES')->where(['status' => 1])->first();
        $voucher_types = VoucherType::select('name', 'code')->where(['status' => 1])->get();

        $business_division = BusinessDivision::select('id','name')->where('status',1)->get();
        $brand             = ProductBrand::select('id','name')->where('status',1)->get();
        $category          = ProductCategory::select('id','name')->where('status',1)->get();
        $group             = ProductGroup::select('id','name')->where('status',1)->get();

        return view('invoice-formats.purchase.all_item-wise-statement.statement', compact(
            'voucher_types',
            'companies',
            'company',
            'business_division',
            'brand',
            'category',
            'group'
        ));
    }

     public function allitemWiseStatementExport(Request $request)
    {
        $filters["from_date"]         = $from_date         = $request->from_date ? date('Y-m-d', strtotime($request->from_date)) : date('Y-m-d');
        $filters["to_date"]           = $to_date           = $request->to_date ? date('Y-m-d', strtotime($request->to_date)) : date('Y-m-d');
        $filters["company"]           = $company           = $request->company ?? '';
        $filters["search_account"]    = $search_account    = $request->search_account ?? '';
        $filters["voucher_type_code"] = $voucher_type_code = $request->voucher_type_code ?? '';
        $filters["brand_id"]          = $brand_id     = $request->get('brand_id');
        $filters["group_id"]          = $group_id     = $request->get('group_id');
        $filters["category_id"]       = $category_id  = $request->get('category_id');
        $filters["division_id"]       = $division_id  = $request->get('division_id');
        $filters["product_id"]       =$product_id = $request->product_id ?? '';
        $filters["doctor_id"]         = $doctor_id  = $request->get('doctor_id');

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

        $saleInvoices = PurchaseInvoiceDetails::getItemWiseStatement([], $filters);

        $fileName = 'All-Items-Wise-Purchase-Statement-'.' From '.$from_date.' To '.$to_date.'.xlsx';

        return Excel::download(new ReportAndInsightsExport($saleInvoices,$company), $fileName);
    }


}
