<?php
/**
 * Created by PhpStorm.
 * User: Ashish
 * Date: 01/07/19
 * Time: 09:55 AM
 */

namespace App;


use App\Avanse\Services\AvanseServices;
use App\ABFL\Services\Services;
use App\Exports\Exporter;
use App\Http\Controllers\Admin\AccountingController;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\DisbursementController;
use App\Http\Controllers\Admin\EMICalculation;
use App\Http\Controllers\Admin\RepaymentController;
use App\Http\Controllers\FrontController;
use App\KMGP2P;
use App\ParkedTransaction;
use App\LendBox;
use App\LendBoxLSP;
use App\Tally\Tally;
use App\Tally\TallyConnector;
use App\Tally\TallyJobs;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Maatwebsite\Excel\Facades\Excel;
use PHPUnit\Util\Json;
use function GuzzleHttp\Psr7\str;
use Hashids\Hashids;
use App\Http\Controllers\Admin\ConsumerDocument;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use MathPHP\Finance;
use App\ConsumerApplicationElement;
use App\Logging\CloudWatchLoggerFactory;
use Illuminate\Support\Facades\Http;
class LoanManagement
{
    private $holiday_list = [];
    public $isCron = false;
    private $status =  ['disbursed','nach registered'];
    public $isPagination = false;
    public $isPaginationSkip = false;
    public $isPaginationTotal = 0;
    public $isPaginationLastPage = 0;
    public $emailCount = 0;
    public $smsCount = 0;
    private $payment_frequency = [];
    private $internal = false;
    private $reconcileWithProcessingFee = false;
    public $excludeWriteoff = false;
    public $includeSettlements = false;
    public $payment_entry_page = false;
    public $lender_id_req = false;
    public $emi_date_req = false;
    public $invoiceIDSeries = [];
    public $duplicateInvoiceIDSeries = [];
    public $duplicateInvoiceIDSeriesData = [];

    /**
     * @var array|\Illuminate\Contracts\View\Factory|\Illuminate\Foundation\Application|\Illuminate\View\View
     */
    public $loan_schedule;

    public function __construct(){
        $this->holiday_list = getHolidayList();
        $this->payment_frequency = Config::get('constants.payment_frequency_offer');
    }

    public function paymentReconcile($data){
        $payment_type = $data['payment_type'] ?? "credit";
        $amount = $this->getParsedReceivedAmount($data);
        $payment_date = $data['payment_date'];
        $mode = $data['mode'];
        $paid_by = $data['paid_by'];
        $collected_by = $data['collected_by'];
        $collected_by_type = $data['collected_by_type'] ?? 1;
        $application_id = $data['application_id'];
        $trasanction_id = $data['trasanction_id'];
        $online_payment_id = $data['online_payment_id'];
        $trasanction_acknowledgement = $data['trasanction_acknowledgement'];
        $payment_status = $data['status'] ?? "success";
        $payment_reconciliation_date = $data['payment_reconciliation_date'] ?? $payment_date;
        $wallet_name = $data['wallet_name'];
        $bank_id = $data['bank_id'] ?? "";
        $application = ConsumerApplication::where('id', $application_id)->first(['id','name', 'lender_id', 'secondary_status']);
        $data['cf_transaction_id'] = $application->id.strtoupper(substr($application->name, 0, 2)).time();
        $adjust_with_disbursement = $data['adjust_with_disbursement'] ?? 0;
        $communicationData = [];
        $amount_received = $amount;

        if($payment_type == 'pre_payment'){
            $this->reconcilePrePayment($data);
            $amount_received = 0;
        }

        if(in_array(strtolower($payment_type), ['collection_charges']) && isset($data['go_maker_check'])){
            unset($data['go_maker_check']);
        }

        try {
            $PTPId = $this->PTPUpdate($data['application_id'], $data['payment_date']);
            if ($PTPId) {
                $data['ptp_id'] = $PTPId;
            }
        }catch (\Exception $e){

        }

        if (isset($data['go_maker_check'])) {
            return PaymentMakerChecker::pendingReconcile(['application_id' => $data['application_id'], 'payment_type' => $payment_type, 'data' => json_encode($data), 'maker_id' => Auth::user()->id, 'checker_id' => 0, 'type' => 'payment', 'status' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'is_pre_part_payment' => $data['is_pre_part_payment'], 'pre_part_payment_type' => $data['pre_part_payment_type'] ?? 0]);
        }

        if($amount_received > 0 && ((strtolower($payment_type)) == "processing_fee" || (strtolower($payment_type)) == "collection_charges" || (strtolower($payment_type)) == "insurance_fee" || (strtolower($payment_type)) == "advance_amount" || (strtolower($payment_type)) == "cancellation_charges" || (strtolower($payment_type)) == "legal_charges" || (strtolower($payment_type)) == "write-off" || (strtolower($payment_type)) == "security_deposit")){

            $payment_transaction_pf = PaymentTransaction::where('application_id', $application_id)->where('payment_for', $payment_type)->where('amount', $amount_received)->whereNull('deleted_at')->first(['id']);
            if(isset($payment_transaction_pf->id)){
                return true;
            }

            $payment_transaction = new PaymentTransaction();
            $payment_transaction->emi_payment_id = 0;
            $payment_transaction->amount = $amount_received;
            $payment_transaction->mode = $mode;
            $payment_transaction->paid_by = $paid_by;
            $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
            $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
            $payment_transaction->collected_by = $collected_by;
            $payment_transaction->collected_by_type = $collected_by_type;
            $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
            $payment_transaction->wallet_name = $wallet_name;
            $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
            $payment_transaction->trasanction_id = $trasanction_id;
            $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
            $payment_transaction->application_id = $application_id;
            $payment_transaction->payment_for = $payment_type;
            $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
            $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
            $payment_transaction->bank_id = $bank_id;
            $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
            $payment_transaction->save();
            $amount_received = 0;
            if((strtolower($payment_type)) == "write-off" || (strtolower($payment_type) == 'security_deposit')){
                return 0;
            } 
            $this->sendPaymentMessage($application_id, $data, $payment_status, strtolower($payment_type));

        }
        if((strtolower($payment_type)) == "settlement_payment"){
            $repayment = new RepaymentController();
            $umrn = $data['umrn'] ?? '';
            $reason = $data['reason'] ?? '';
            $status = $data['status'] ?? 'success';
            $data_update = [
                'application_id' => $application_id,
                'amount' => (int)$amount_received,
                'payment_date' => $payment_date,
                'type' => 'settlement_payment',
                'mode' => $mode,
                'trasanction_id' => $trasanction_id,
                'cf_transaction_id' => $data['cf_transaction_id'],
                'payment_reconciliation_date' => $payment_reconciliation_date,
                'payment_for' => $payment_type,
                'payment_mode' => $mode,
                'paid_by' => !empty($paid_by) ? $paid_by : 0,
                'collected_by' => $collected_by,
                'collected_by_type' => $collected_by_type,
                'online_payment_id' => $online_payment_id,
                'trasanction_acknowledgement' => $trasanction_acknowledgement,
                'payment_status' => $payment_status,
                'wallet_name' => $wallet_name,
                'bank_id' => $bank_id,
                'reason' => $reason,
                'umrn' => $umrn,
                'status' => $status,
                'secondary_status' => $application->secondary_status,
                'adjust_with_disbursement' => $adjust_with_disbursement,
                'is_verify' => isset($data['is_verify']) ? $data['is_verify'] : 0
            ];

            if($data_update['is_verify']){

                if (!$this->isSettlementAmountFulfilled($application_id, $amount_received, $data_update)) {
                    return 0;
                }

                ParkedTransaction::where('application_id', $application_id)
                    ->where('reconciliation_status', 'parked')
                    ->update(['reconciliation_status' => 'reconciled']);

                $response = $repayment->callReconcileApi($application_id, $data_update);
                // if($response && isset($response['status']) && $response['status'] == 'Success'){
                    // $this->getReconciliationDetails($response, $data);
                    return $response;
                // }else{
                //     return 1;
                // }
            }
        }

        $foreclosuredate = $data['fore_closure_date'] ?? "";
        if($foreclosuredate != "" && $foreclosuredate != 0){
            ConsumerApplicationElement::where('application_id',$application_id)->update(['foreclosure_date'=>$foreclosuredate, 'emi_pending' => 0]);
            $data['advance_amount'] = $amount_received;
            $this->updateAdvanceAmount($data, "Foreclosure", $application_id);
            $amount_received = 0;
        }


        //$rps_exist = RPS_Logs::where('application_id', (int)$data['application_id'])->where('bpi_interest','>',0)->exists();
        if($amount_received > 0) {
            $rps_exist = RPS_Logs::where('application_id', (int)$data['application_id'])->exists();
            if ($rps_exist && strtolower($payment_type) != 'total_fee') {
                if (in_array(strtolower($payment_type), ['emi', 'pre-emi', 'pre_emi_amount', 'credit'])) {
                    $umrn = $data['umrn'] ?? '';
                    $reason = $data['reason'] ?? '';
                    $status = $data['status'] ?? 'success';
                    $_data = [
                        'amount' => (int)$amount_received,
                        'payment_date' => Carbon::parse($payment_date)->format('d-m-Y'),
                        'payment_for' => $payment_type,
                        'payment_mode' => $mode,
                        'paid_by' => $paid_by,
                        'collected_by' => $collected_by,
                        'collected_by_type' => $collected_by_type,
                        'trasanction_id' => $trasanction_id,
                        'online_payment_id' => $online_payment_id,
                        'trasanction_acknowledgement' => $trasanction_acknowledgement,
                        'payment_status' => $payment_status,
                        'payment_reconciliation_date' => Carbon::parse($payment_reconciliation_date)->format('d-m-Y'),
                        'wallet_name' => $wallet_name,
                        'bank_id' => $bank_id,
                        'cf_transaction_id' => $data['cf_transaction_id'],
                        'reason' => $reason,
                        'umrn' => $umrn,
                        'status' => $status,
                        'adjust_with_disbursement' => $adjust_with_disbursement,
                    ];
                    (new RepaymentController())->reconcilePayment($data['application_id'], $_data);

                    if ($this->reconcileWithProcessingFee) {
                        $this->reconcileWithProcessingFee($data);
                    }
                    $amount = 0;
                    $communicationData = ['application_id' => $application_id, 'data' => $data, 'payment_status' => $payment_status, 'payment_type' => strtolower($payment_type)];
//            return 'true';
                } elseif ($data['amount'] > 0) {
                    if ($this->reconcileWithProcessingFee) {
                        $this->reconcileWithProcessingFee($data);
                    }
                    $communicationData = ['application_id' => $application_id, 'data' => $data, 'payment_status' => $payment_status, 'payment_type' => strtolower($payment_type)];

                }
                return array('application' => $application, 'cf_transaction_id' => $data['cf_transaction_id'], 'communicationData' => $communicationData);
            }
        }

        $this->paymentCalculate($data['application_id']);


        $statusLogs = [];
//        $amount = $this->getParsedReceivedAmount($data);
        $amount_setteled = 0;
//        $payment_date = $data['payment_date'];
        $payment_status = ($payment_status == "pending") ? "pending_from_bank" : $payment_status;

        if($amount_received > 0 && (strtolower($payment_type)) == "refund"){
            $payment_transaction = new PaymentTransaction();
            $payment_transaction->emi_payment_id = 0;
            $payment_transaction->amount = $amount_received;
            $payment_transaction->mode = $mode;
            $payment_transaction->paid_by = $paid_by;
            $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
            $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
            $payment_transaction->collected_by = $collected_by;
            $payment_transaction->collected_by_type = $collected_by_type;
            $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
            $payment_transaction->wallet_name = $wallet_name;
            $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
            $payment_transaction->trasanction_id = $trasanction_id;
            $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
            $payment_transaction->application_id = $application_id;
            $payment_transaction->payment_for = $payment_type;
            $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');;
            $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
            $payment_transaction->bank_id = $bank_id;
            $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
            $payment_transaction->save();

            $amount_received = 0;
        }

        if($amount_received > 0 && (strtolower($payment_type)) == "pre_emi_amount"){

            if((new RepaymentController())->isBPIReceived($application_id, 'bpi')) {
                $payment_transaction = new PaymentTransaction();
                $payment_transaction->emi_payment_id = 0;
                $payment_transaction->amount = $amount_received;
                $payment_transaction->mode = $mode;
                $payment_transaction->paid_by = $paid_by;
                $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
                $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                $payment_transaction->collected_by = $collected_by;
                $payment_transaction->collected_by_type = $collected_by_type;
                $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                $payment_transaction->wallet_name = $wallet_name;
                $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                $payment_transaction->trasanction_id = $trasanction_id;
                $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                $payment_transaction->application_id = $application_id;
                $payment_transaction->payment_for = 'Pre-EMI';
                $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');;
                $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                $payment_transaction->bank_id = $bank_id;
                $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                $payment_transaction->save();

                $amount_received = 0;
            }else{
                // If BPI received then reconcile as EMI
                $payment_type = 'credit';
            }
        }

        if($amount_received > 0 && ((strtolower($payment_type)) == "processing_fee" || (strtolower($payment_type)) == "collection_charges" || (strtolower($payment_type)) == "insurance_fee" || (strtolower($payment_type)) == "advance_amount" || (strtolower($payment_type)) == "cancellation_charges" || (strtolower($payment_type)) == "legal_charges" || (strtolower($payment_type)) == "write-off")){
            $payment_transaction = new PaymentTransaction();
            $payment_transaction->emi_payment_id = 0;
            $payment_transaction->amount = $amount_received;
            $payment_transaction->mode = $mode;
            $payment_transaction->paid_by = $paid_by;
            $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
            $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
            $payment_transaction->collected_by = $collected_by;
            $payment_transaction->collected_by_type = $collected_by_type;
            $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
            $payment_transaction->wallet_name = $wallet_name;
            $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
            $payment_transaction->trasanction_id = $trasanction_id;
            $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
            $payment_transaction->application_id = $application_id;
            $payment_transaction->payment_for = $payment_type;
            $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');;
            $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
            $payment_transaction->bank_id = $bank_id;
            $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
            $payment_transaction->save();

            $amount_received = 0;
            if((strtolower($payment_type)) == "write-off"){
                return 0;
            }
        }

        if ((strtolower($payment_type)) == "total_fee") {
            $frontController = new FrontController();
            $paymentDetails = $frontController->getFeesData($application_id, true);
            foreach ($paymentDetails as $payment_type => $details) {
                if ($amount_received - $details['amount'] >= 0) {
                    $payment_transaction = new PaymentTransaction();
                    $payment_transaction->emi_payment_id = 0;
                    $payment_transaction->amount = $details['amount'];
                    $payment_transaction->mode = $mode;
                    $payment_transaction->paid_by = $paid_by;
                    $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
                    $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                    $payment_transaction->collected_by = $collected_by;
                    $payment_transaction->collected_by_type = $collected_by_type;
                    $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                    $payment_transaction->wallet_name = $wallet_name;
                    $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                    $payment_transaction->trasanction_id = $trasanction_id;
                    $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                    $payment_transaction->application_id = $application_id;
                    $payment_transaction->payment_for = $details['purpose'];
                    $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');;
                    $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                    $payment_transaction->bank_id = $bank_id;
                    $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                    $payment_transaction->save();
                    $amount_received -= $details['amount'];
                } else {
                    $cwFactory = new CloudWatchLoggerFactory();
                    $cwFactory->logger(json_encode(['message' => 'Total Fee Reconcile', 'Total Amount' => $amount, 'remaining_amount' => $amount_received, 'pending' => ['purpose' => $details['purpose'], 'amount' => $details['amount']]]));
                    return array();
                }
            }
            $this->sendPaymentMessage($application_id, $data, $payment_status, 'total_fee');
        }

        $is_payment_recalculate = (date('Y-m-d') != $payment_date) ? 1 : 0;

        if (isset($data['advance_amount']) && $data['advance_amount'] > 0 && $foreclosuredate == "" && $foreclosuredate == 0) {
            $this->updateAdvanceAmount($data, "Advance Payment", $application_id);
        }

        //$check_date = date('Y-m-d',(strtotime ( '-11 day' , strtotime ( $payment_date ) ) ));
        $check_date = date('Y-m-d',(strtotime ( '-4 day' , strtotime ( $payment_date ) ) ));
        //$check_date = date('Y-m-d',(strtotime ( '30 day' , strtotime ( $payment_date ) ) ));
        if($amount_received < 1){
            if((strtolower($payment_type)) == "processing_fee" || (strtolower($payment_type)) == "advance_amount"){
                $this->isAllRepaymentReceived($application_id);
            }
            return $application;
        }

        /*if($amount_received) {

            $emiPaymentPreMonth = EmiPayment::where('application_id', $application_id)->where('payment_date','<', Carbon::now()->startOfMonth()->toDateTimeString())->whereNotIn('payment_status', ['success'])->first(['id','emi_date']);

            if(!isset($emiPaymentPreMonth->id)) {
                $emiPaymentCurrMonth = EmiPayment::where('application_id', $application_id)->where('payment_date', '>=', Carbon::now()->startOfMonth()->toDateTimeString())->where('payment_date', '<=', Carbon::now()->endOfMonth()->toDateTimeString())->whereNotIn('payment_status', ['success'])->first(['id', 'emi_date']);

                if (isset($emiPaymentCurrMonth->id) && $check_date >= $emiPaymentCurrMonth->emi_date) {
                    $reconciledData = $this->reconcileCurrentMonth($payment_date, $payment_reconciliation_date, $payment_status, $amount_received, ['mode' => $mode, 'paid_by' => $paid_by, 'collected_by' => $collected_by, 'collected_by_type' => $collected_by_type, 'adjust_with_disbursement' => $adjust_with_disbursement, 'wallet_name' => $wallet_name, 'trasanction_id' => $trasanction_id, 'trasanction_acknowledgement' => $trasanction_acknowledgement, 'bank_id' => $bank_id, 'application_id' => $application_id], $data);
                    if ($reconciledData) {
                        $amount_received = $reconciledData['amount_received'];
                        $statusLogs[] = $reconciledData['statusLogs'];
                    }
                }
            }
        }*/


        $application = ConsumerApplication::with('application_element','emi_payment.transaction')->where('id',$application_id)->first();

        if($application && isset($application->application_element->total_amount_due) && $application->application_element->total_amount_due > 0){
            if($amount_received > 0 && $payment_status != 'rejected' &&  $payment_status != 'initial_reject' && $payment_status != 'pending_from_bank'){
                $i= 0;
                foreach($application->emi_payment as $emi_payment){
                    if($emi_payment->payment_status == "success"){
                        $application->emi_payment[$i]->update_status = "Done";
                    }elseif($emi_payment->payment_status != "success" && $emi_payment->amount_due == 0){
                        EmiPayment::where('id',$emi_payment->id)->update(['payment_status'=>"success"]);
                        $application->emi_payment[$i]->update_status = "Done";
                    }elseif($emi_payment->emi_date <= $payment_date/* || $emi_payment->emi_date <= $payment_date*/) {
                        $emi_payment_amount_received = $emi_payment->total_payable - $emi_payment->amount_due;
                        $emi_amount_pending = ($emi_payment->emi_amount - $emi_payment_amount_received);
                        $application->emi_payment[$i]->update_status = "Done";
                        $emi_payment_update = EmiPayment::find($emi_payment->id);

                        if ($emi_payment->payment_status != "success" && $amount_received > 0 && $emi_amount_pending > 0) {
                            $amount_setteled = 0;
                            if ($is_payment_recalculate == 1) {
                                $bounce_charges = $this->getBounceCharges($emi_payment->emi_amount, $emi_payment->due_date, $emi_payment->emi_date, $emi_payment->transaction, $payment_date, $amount_received, $emi_payment->application_id);
                                $emi_payment_update = EmiPayment::find($emi_payment->id);
                                $emi_payment_update->bounce_charges = (isset($bounce_charges['bounce_charges']) ? $bounce_charges['bounce_charges'] : 0);
                                $application->emi_payment[$i]->bounce_charges = $emi_payment_update->bounce_charges;
                                $emi_payment_update->delay_penalty = (isset($bounce_charges['penal_interest']) ? $bounce_charges['penal_interest'] : 0);
                                $application->emi_payment[$i]->delay_penalty = $emi_payment_update->delay_penalty;
                                $total_payable = $emi_payment->emi_amount + $emi_payment_update->bounce_charges + $emi_payment_update->delay_penalty - $emi_payment->charges_waived;
                                $amount_due = $total_payable - $emi_payment_amount_received;
                                $emi_payment_update->total_payable = $total_payable;
                                $application->emi_payment[$i]->total_payable = $total_payable;
                                $emi_payment_update->amount_due = $amount_due;
                                $application->emi_payment[$i]->amount_due = $amount_due;
                                $emi_payment_update->delay_days = (isset($bounce_charges['delay_days']) ? $bounce_charges['delay_days'] : 0);
                                $application->emi_payment[$i]->delay_days = $emi_payment_update->delay_days;
                                $emi_payment_update->save();
                            }
                            $emi_payment_amount_received_updated = $emi_payment->total_payable - $emi_payment->amount_due - $emi_payment->charges_waived;
                            $total_emi_amount_pending = ($emi_payment->total_payable - $emi_payment_amount_received_updated);


                            if ($emi_amount_pending <= $amount_received) {
                                $amount_setteled = $emi_amount_pending;
                                $amount_received = $amount_received - $amount_setteled;
                                if (($total_emi_amount_pending - $amount_setteled) > 0) {
                                    $emi_payment_status = 'partial';
                                } else {
                                    $emi_payment_status = 'success';
                                }
                            } else {
                                $amount_setteled = $amount_received;
                                $amount_received = 0;
                                if (($total_emi_amount_pending - $amount_setteled) == 0) {
                                    $emi_payment_status = 'success';
                                } else {
                                    $emi_payment_status = 'partial';
                                }
                            }

                            if (!isset($emi_payment_update)) {
                                $emi_payment_update = EmiPayment::find($emi_payment->id);
                            }
                            $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                            $total_payable = $emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty;
                            $amount_due = $total_payable - $emi_payment_amount_received - $emi_payment->charges_waived;
                            $emi_payment_update->payment_status = $emi_payment_status;
                            $application->emi_payment[$i]->total_payable = $total_payable;
                            $application->emi_payment[$i]->amount_due = $amount_due;
                            $emi_payment_update->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                            $emi_payment_update->total_payable = $total_payable;
                            $emi_payment_update->amount_due = $amount_due;

                            $emi_payment_update->save();

                            if($amount_setteled) {
                                $payment_transaction = new PaymentTransaction();
                                $payment_transaction->emi_payment_id = $emi_payment->id;
                                $payment_transaction->amount = $amount_setteled;
                                $payment_transaction->mode = $mode;
                                $payment_transaction->paid_by = $paid_by;
                                $payment_transaction->payment_reconciliation_date = Carbon::parse($payment_reconciliation_date)->format('Y-m-d');
                                $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                                $payment_transaction->collected_by = $collected_by;
                                $payment_transaction->collected_by_type = $collected_by_type;
                                $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                                $payment_transaction->wallet_name = $wallet_name;
                                $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                                $payment_transaction->trasanction_id = $trasanction_id;
                                $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                                $payment_transaction->application_id = $application_id;
                                $payment_transaction->payment_for = "EMI";
                                $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                                $payment_transaction->bank_id = $bank_id;
                                $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                                $payment_transaction->save();
                            }

                            $statusLogs[] = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];
                        }
                    }else{
                        $PreviousEMIs[] = $emi_payment;
                    }
                    $i++;
                }

                // For Bounce Charges
                if ($amount_received > 0) {
                    $i = 0;
                    foreach ($application->emi_payment as $emi_payment) {
                        if ($amount_received > 0) {
                            if($emi_payment->bounce_charges > 0 && $emi_payment->payment_status != 'success' && $emi_payment->emi_date <= $payment_date) {
                                $amount_setteled = 0;
                                $emi_payment_amount_received = $emi_payment->total_payable - $emi_payment->amount_due;
                                $emi_bounce_charges_pending = ($emi_payment->emi_amount + $emi_payment->bounce_charges) - $emi_payment_amount_received;
                                if($emi_bounce_charges_pending > $emi_payment->amount_due){
                                    $emi_bounce_charges_pending = $emi_payment->amount_due;
                                }
                                if ($emi_bounce_charges_pending > 0) {
                                    if ($emi_bounce_charges_pending <= $amount_received) {
                                        $amount_setteled = $emi_bounce_charges_pending;
                                        $amount_received = $amount_received - $amount_setteled;
                                    } else {
                                        $amount_setteled = $amount_received;
                                        $amount_received = 0;
                                    }

                                    $amount_due = $emi_payment->total_payable - $emi_payment_amount_received - $amount_setteled;
                                    $application->emi_payment[$i]->amount_due = $amount_due;
                                    $emi_payment_amount_received_updated = ($emi_payment->total_payable - $emi_payment->amount_due - $emi_payment->charges_waived) + $amount_setteled;
                                    $total_emi_amount_pending = ($emi_payment->total_payable - $emi_payment_amount_received_updated);
                                    if ($total_emi_amount_pending == 0) {
                                        $emi_payment_status = 'success';
                                    } else {
                                        $emi_payment_status = 'partial';
                                    }

                                    if ($amount_setteled > 0) {
                                        $emi_payment_update = EmiPayment::find($emi_payment->id);
                                        $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                                        $total_payable = $emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty;
                                        $amount_due = $total_payable - $emi_payment_amount_received - $emi_payment->charges_waived;
                                        $emi_payment_update->payment_status = $emi_payment_status;
                                        $application->emi_payment[$i]->total_payable = $total_payable;
                                        $application->emi_payment[$i]->amount_due = $amount_due;
                                        $emi_payment_update->payment_status = $emi_payment_status;
                                        $emi_payment_update->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                        $emi_payment_update->total_payable = $total_payable;
                                        $emi_payment_update->amount_due = $amount_due;
                                        $emi_payment_update->save();

                                        if($amount_setteled) {
                                            $payment_transaction = new PaymentTransaction();
                                            $payment_transaction->emi_payment_id = $emi_payment->id;
                                            $payment_transaction->amount = $amount_setteled;
                                            $payment_transaction->mode = $mode;
                                            $payment_transaction->paid_by = $paid_by;
                                            $payment_transaction->payment_reconciliation_date = Carbon::parse($payment_reconciliation_date)->format('Y-m-d');
                                            $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                                            $payment_transaction->collected_by = $collected_by;
                                            $payment_transaction->collected_by_type = $collected_by_type;
                                            $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                                            $payment_transaction->wallet_name = $wallet_name;
                                            $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                                            $payment_transaction->trasanction_id = $trasanction_id;
                                            $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                                            $payment_transaction->application_id = $application_id;
                                            $payment_transaction->payment_for = "EMI";
                                            $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                            $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                                            $payment_transaction->bank_id = $bank_id;
                                            $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                                            $payment_transaction->save();
                                        }

                                        $statusLogs[] = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];
                                    }
                                }
                            }
                            $i++;
                        }else{
                            break;
                        }
                    }
                }

                // For Penalty Amount
                $i= 0;
                if ($amount_received > 0) {
                    foreach ($application->emi_payment as $emi_payment) {
                        if ($amount_received > 0) {
                            if($emi_payment->delay_penalty > 0  && $emi_payment->payment_status != 'success' && $emi_payment->emi_date <= $payment_date) {
                                $amount_setteled = 0;
                                $emi_payment_amount_received = $emi_payment->total_payable - $emi_payment->amount_due;

                                $emi_penal_charges_pending = ($emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty) - $emi_payment_amount_received;
                                if($emi_penal_charges_pending > $emi_payment->amount_due){
                                    $emi_penal_charges_pending = $emi_payment->amount_due;
                                }
                                if ($emi_penal_charges_pending > 0) {
                                    if ($emi_penal_charges_pending <= $amount_received) {
                                        $amount_setteled = $emi_penal_charges_pending;
                                        $amount_received = $amount_received - $amount_setteled;
                                    } else {
                                        $amount_setteled = $amount_received;
                                        $amount_received = 0;
                                    }

                                    $amount_due = $emi_payment->total_payable - $emi_payment_amount_received - $amount_setteled;
                                    $application->emi_payment[$i]->amount_due = $amount_due;
                                    $emi_payment_amount_received_updated = ($emi_payment->total_payable - $emi_payment->amount_due - $emi_payment->charges_waived);
                                    $total_emi_amount_pending = ($emi_payment->total_payable - $emi_payment_amount_received_updated);
                                    if ($total_emi_amount_pending == 0) {
                                        $emi_payment_status = 'success';
                                    } else {
                                        $emi_payment_status = 'partial';
                                    }
                                    if ($amount_setteled > 0) {
                                        $emi_payment_update = EmiPayment::find($emi_payment->id);
                                        $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                                        $total_payable = $emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty;
                                        $amount_due = $total_payable - $emi_payment_amount_received - $emi_payment->charges_waived;
                                        $emi_payment_update->payment_status = $emi_payment_status;
                                        $application->emi_payment[$i]->total_payable = $total_payable;
                                        $application->emi_payment[$i]->amount_due = $amount_due;
                                        $emi_payment_update->payment_status = $emi_payment_status;
                                        $emi_payment_update->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                        $emi_payment_update->amount_due = $emi_payment->amount_due;
                                        $emi_payment_update->total_payable = $total_payable;
                                        $emi_payment_update->amount_due = $amount_due;
                                        $emi_payment_update->save();

                                        if($amount_setteled) {
                                            $payment_transaction = new PaymentTransaction();
                                            $payment_transaction->emi_payment_id = $emi_payment->id;
                                            $payment_transaction->amount = $amount_setteled;
                                            $payment_transaction->mode = $mode;
                                            $payment_transaction->paid_by = $paid_by;
                                            $payment_transaction->payment_reconciliation_date = Carbon::parse($payment_reconciliation_date)->format('Y-m-d');
                                            $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                                            $payment_transaction->collected_by = $collected_by;
                                            $payment_transaction->collected_by_type = $collected_by_type;
                                            $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                                            $payment_transaction->wallet_name = $wallet_name;
                                            $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                                            $payment_transaction->trasanction_id = $trasanction_id;
                                            $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                                            $payment_transaction->application_id = $application_id;
                                            $payment_transaction->payment_for = "EMI";
                                            $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                            $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                                            $payment_transaction->bank_id = $bank_id;
                                            $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                                            $payment_transaction->save();
                                        }

                                        $statusLogs[] = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];
                                    }
                                }

                            }
                            $i++;
                        }else{
                            break;
                        }

                    }
                }


                // For Previous EMIs if EMI Amount is pending
                unset($emi_payment_update);
                if ($amount_received > 0 && isset($PreviousEMIs) && $PreviousEMIs){
                    $i= 0;
                    foreach($PreviousEMIs as $emi_payment){
                        if($emi_payment->payment_status == "success"){
                            $application->emi_payment[$i]->update_status = "Done";
                        }elseif($emi_payment->payment_status != "success" && $emi_payment->amount_due == 0){
                            EmiPayment::where('id',$emi_payment->id)->update(['payment_status'=>"success"]);
                            $application->emi_payment[$i]->update_status = "Done";
                        }elseif((date('Y-m', strtotime($emi_payment->emi_date)) == date('Y-m', strtotime($payment_date))) || $emi_payment->payment_status != "pending") {
                            $emi_payment_amount_received = $emi_payment->total_payable - $emi_payment->amount_due;
                            $emi_amount_pending = ($emi_payment->emi_amount - $emi_payment_amount_received);
                            $application->emi_payment[$i]->update_status = "Done";

                            if ($emi_payment->payment_status != "success" && $amount_received > 0 && $emi_amount_pending > 0) {
                                $amount_setteled = 0;
                                $emi_payment_update = EmiPayment::find($emi_payment->id);
                                if($is_payment_recalculate == 1){
                                    $bounce_charges = $this->getBounceCharges($emi_payment->emi_amount,$emi_payment->due_date, $emi_payment->emi_date,$emi_payment->transaction,$payment_date,$amount_received, $emi_payment->application_id);
                                    $emi_payment_update = EmiPayment::find($emi_payment->id);
                                    $emi_payment_update->bounce_charges = (isset($bounce_charges['bounce_charges']) ? $bounce_charges['bounce_charges'] : 0);
                                    $application->emi_payment[$i]->bounce_charges = $emi_payment_update->bounce_charges;
                                    $emi_payment_update->delay_penalty = (isset($bounce_charges['penal_interest']) ? $bounce_charges['penal_interest'] : 0);
                                    $application->emi_payment[$i]->delay_penalty = $emi_payment_update->delay_penalty;
                                    $total_payable = $emi_payment->emi_amount + $emi_payment_update->bounce_charges + $emi_payment_update->delay_penalty - $emi_payment->charges_waived;
                                    $amount_due = $total_payable - $emi_payment_amount_received;
                                    $emi_payment_update->total_payable = $total_payable;
                                    $application->emi_payment[$i]->total_payable = $total_payable;
                                    $emi_payment_update->amount_due = $amount_due;
                                    $application->emi_payment[$i]->amount_due = $amount_due;
                                    $emi_payment_update->delay_days = (isset($bounce_charges['delay_days']) ? $bounce_charges['delay_days'] : 0);
                                    $application->emi_payment[$i]->delay_days = $emi_payment_update->delay_days;
                                    $emi_payment_update->save();
                                }
                                $emi_payment_amount_received_updated = $emi_payment->total_payable - $emi_payment->amount_due - $emi_payment->charges_waived;
                                $total_emi_amount_pending = ($emi_payment->total_payable - $emi_payment_amount_received_updated);


                                if ($emi_amount_pending <= $amount_received) {
                                    $amount_setteled = $emi_amount_pending;
                                    $amount_received = $amount_received - $amount_setteled;
                                    if(($total_emi_amount_pending - $amount_setteled) > 0){
                                        $emi_payment_status = 'partial';
                                    }else {
                                        $emi_payment_status = 'success';
                                    }
                                }else{
                                    $amount_setteled =  $amount_received;
                                    $amount_received = 0;
                                    if(($total_emi_amount_pending - $amount_setteled) == 0){
                                        $emi_payment_status = 'success';
                                    }else{
                                        $emi_payment_status = 'partial';
                                    }
                                }

                                if(!isset($emi_payment_update)){
                                    $emi_payment_update = EmiPayment::find($emi_payment->id);
                                }
                                $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                                $total_payable = $emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty;
                                $amount_due = $total_payable - $emi_payment_amount_received - $emi_payment->charges_waived;
                                $emi_payment_update->payment_status = $emi_payment_status;
                                $application->emi_payment[$i]->total_payable = $total_payable;
                                $application->emi_payment[$i]->amount_due = $amount_due;
                                $emi_payment_update->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                $emi_payment_update->total_payable = $total_payable;
                                $emi_payment_update->amount_due = $amount_due;

                                $emi_payment_update->save();

                                if($amount_setteled) {
                                    $payment_transaction = new PaymentTransaction();
                                    $payment_transaction->emi_payment_id = $emi_payment->id;
                                    $payment_transaction->amount = $amount_setteled;
                                    $payment_transaction->mode = $mode;
                                    $payment_transaction->paid_by = $paid_by;
                                    $payment_transaction->payment_reconciliation_date = Carbon::parse($payment_reconciliation_date)->format('Y-m-d');
                                    $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                                    $payment_transaction->collected_by = $collected_by;
                                    $payment_transaction->collected_by_type = $collected_by_type;
                                    $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                                    $payment_transaction->wallet_name = $wallet_name;
                                    $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                                    $payment_transaction->trasanction_id = $trasanction_id;
                                    $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                                    $payment_transaction->application_id = $application_id;
                                    $payment_transaction->payment_for = "EMI";
                                    $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                    $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                                    $payment_transaction->bank_id = $bank_id;
                                    $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                                    $payment_transaction->save();
                                }

                                $statusLogs[] = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];
                            }
                        }
                        $i++;
                    }
                }

                /*For Previous EMIs*/
                /*unset($emi_payment_update);
                if ($amount_received > 0 && isset($PreviousEMIs) && $PreviousEMIs){
                    $i= 0;
                    foreach($PreviousEMIs as $emi_payment){
                        if($emi_payment->payment_status == "success"){
                            $application->emi_payment[$i]->update_status = "Done";
                        }elseif($emi_payment->payment_status != "success" && $emi_payment->amount_due == 0){
                            EmiPayment::where('id',$emi_payment->id)->update(['payment_status'=>"success"]);
                            $application->emi_payment[$i]->update_status = "Done";
                        }elseif($emi_payment->emi_date <= $payment_date) {
                            $emi_payment_amount_received = $emi_payment->total_payable - $emi_payment->amount_due;
                            $emi_amount_pending = ($emi_payment->emi_amount - $emi_payment_amount_received);
                            $application->emi_payment[$i]->update_status = "Done";

                            if ($emi_payment->payment_status != "success" && $amount_received > 0 && $emi_amount_pending > 0) {
                                $amount_setteled = 0;
                                $emi_payment_update = EmiPayment::find($emi_payment->id);
                                if($is_payment_recalculate == 1){
                                    $bounce_charges = $this->getBounceCharges($emi_payment->emi_amount,$emi_payment->due_date, $emi_payment->emi_date,$emi_payment->transaction,$payment_date,$amount_received, $emi_payment->application_id);
                                    $emi_payment_update->bounce_charges = (isset($bounce_charges['bounce_charges']) ? $bounce_charges['bounce_charges'] : 0);
                                    $application->emi_payment[$i]->bounce_charges = $emi_payment_update->bounce_charges;
                                    $emi_payment_update->delay_penalty = (isset($bounce_charges['penal_interest']) ? $bounce_charges['penal_interest'] : 0);
                                    $application->emi_payment[$i]->delay_penalty = $emi_payment_update->delay_penalty;
                                    $total_payable = $emi_payment->emi_amount + $emi_payment_update->bounce_charges + $emi_payment_update->delay_penalty - $emi_payment->charges_waived;
                                    $amount_due = $total_payable - $emi_payment_amount_received;
                                    $emi_payment_update->total_payable = $total_payable;
                                    $application->emi_payment[$i]->total_payable = $total_payable;
                                    $emi_payment_update->amount_due = $amount_due;
                                    $application->emi_payment[$i]->amount_due = $amount_due;
                                    $emi_payment_update->delay_days = (isset($bounce_charges['delay_days']) ? $bounce_charges['delay_days'] : 0);
                                    $application->emi_payment[$i]->delay_days = $emi_payment_update->delay_days;
                                    $emi_payment_update->save();
                                }
                                $emi_payment_amount_received_updated = $emi_payment->total_payable - $emi_payment->amount_due - $emi_payment->charges_waived;
                                $total_emi_amount_pending = ($emi_payment->total_payable - $emi_payment_amount_received_updated);


                                if ($emi_amount_pending <= $amount_received) {
                                    $amount_setteled = $emi_amount_pending;
                                    $amount_received = $amount_received - $amount_setteled;
                                    if(($total_emi_amount_pending - $amount_setteled) > 0){
                                        $emi_payment_status = 'partial';
                                    }else {
                                        $emi_payment_status = 'success';
                                    }
                                }else{
                                    $amount_setteled =  $amount_received;
                                    $amount_received = 0;
                                    if(($total_emi_amount_pending - $amount_setteled) == 0){
                                        $emi_payment_status = 'success';
                                    }else{
                                        $emi_payment_status = 'partial';
                                    }
                                }

                                if(!isset($emi_payment_update)){
                                    $emi_payment_update = EmiPayment::find($emi_payment->id);
                                }
                                $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                                $total_payable = $emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty;
                                $amount_due = $total_payable - $emi_payment_amount_received - $emi_payment->charges_waived;
                                $emi_payment_update->payment_status = $emi_payment_status;
                                $application->emi_payment[$i]->total_payable = $total_payable;
                                $application->emi_payment[$i]->amount_due = $amount_due;
                                $emi_payment_update->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                $emi_payment_update->total_payable = $total_payable;
                                $emi_payment_update->amount_due = $amount_due;

                                $emi_payment_update->save();

                                $payment_transaction = new PaymentTransaction();
                                $payment_transaction->emi_payment_id = $emi_payment->id;
                                $payment_transaction->amount = $amount_setteled;
                                $payment_transaction->mode = $mode;
                                $payment_transaction->paid_by = $paid_by;
                                $payment_transaction->payment_reconciliation_date = Carbon::parse($payment_reconciliation_date)->format('Y-m-d');
                                $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                                $payment_transaction->collected_by = $collected_by;
                                $payment_transaction->collected_by_type = $collected_by_type;
                                $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                                $payment_transaction->wallet_name = $wallet_name;
                                $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                                $payment_transaction->trasanction_id = $trasanction_id;
                                $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                                $payment_transaction->application_id = $application_id;
                                $payment_transaction->payment_for = "EMI";
                                $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                                $payment_transaction->bank_id = $bank_id;
                                $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                                $payment_transaction->save();

                                $statusLogs[] = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];
                            }
                        }
                        $i++;
                    }
                }*/

                $emi_payments_table = EmiPayment::where('application_id', $application_id)->get();

                // For Future EMIs
                unset($emi_payment_update);
                if ($amount_received > 0 && isset($emi_payments_table) && $emi_payments_table){
                    $i= 0;
                    foreach($emi_payments_table as $emi_payment){
                        if($emi_payment->payment_status == "success"){
                            $application->emi_payment[$i]->update_status = "Done";
                        }elseif($emi_payment->payment_status != "success" && $emi_payment->amount_due == 0){
                            EmiPayment::where('id',$emi_payment->id)->update(['payment_status'=>"success"]);
                            $application->emi_payment[$i]->update_status = "Done";
                        }elseif($emi_payment->emi_date >= $payment_date) {
                            $emi_payment_amount_received = $emi_payment->total_payable - $emi_payment->amount_due;
                            $emi_amount_pending = ($emi_payment->emi_amount - $emi_payment_amount_received);
                            $application->emi_payment[$i]->update_status = "Done";

                            if ($emi_payment->payment_status != "success" && $amount_received > 0 && $emi_amount_pending > 0) {
                                $amount_setteled = 0;
                                if($is_payment_recalculate == 1){
                                    $bounce_charges = $this->getBounceCharges($emi_payment->emi_amount,$emi_payment->due_date, $emi_payment->emi_date,$emi_payment->transaction,$payment_date,$amount_received, $emi_payment->application_id);
                                    $emi_payment_update = EmiPayment::find($emi_payment->id);
                                    $emi_payment_update->bounce_charges = (isset($bounce_charges['bounce_charges']) ? $bounce_charges['bounce_charges'] : 0);
                                    $application->emi_payment[$i]->bounce_charges = $emi_payment_update->bounce_charges;
                                    $emi_payment_update->delay_penalty = (isset($bounce_charges['penal_interest']) ? $bounce_charges['penal_interest'] : 0);
                                    $application->emi_payment[$i]->delay_penalty = $emi_payment_update->delay_penalty;
                                    $total_payable = $emi_payment->emi_amount + $emi_payment_update->bounce_charges + $emi_payment_update->delay_penalty - $emi_payment->charges_waived;
                                    $amount_due = $total_payable - $emi_payment_amount_received;
                                    $emi_payment_update->total_payable = $total_payable;
                                    $application->emi_payment[$i]->total_payable = $total_payable;
                                    $emi_payment_update->amount_due = $amount_due;
                                    $application->emi_payment[$i]->amount_due = $amount_due;
                                    $emi_payment_update->delay_days = (isset($bounce_charges['delay_days']) ? $bounce_charges['delay_days'] : 0);
                                    $application->emi_payment[$i]->delay_days = $emi_payment_update->delay_days;
                                    $emi_payment_update->save();
                                }
                                $emi_payment_amount_received_updated = $emi_payment->total_payable - $emi_payment->amount_due - $emi_payment->charges_waived;
                                $total_emi_amount_pending = ($emi_payment->total_payable - $emi_payment_amount_received_updated);


                                if ($emi_amount_pending <= $amount_received) {
                                    $amount_setteled = $emi_amount_pending;
                                    $amount_received = $amount_received - $amount_setteled;
                                    if(($total_emi_amount_pending - $amount_setteled) > 0){
                                        $emi_payment_status = 'partial';
                                    }else {
                                        $emi_payment_status = 'success';
                                    }
                                }else{
                                    $amount_setteled =  $amount_received;
                                    $amount_received = 0;
                                    if(($total_emi_amount_pending - $amount_setteled) == 0){
                                        $emi_payment_status = 'success';
                                    }else{
                                        $emi_payment_status = 'partial';
                                    }
                                }

                                if(!isset($emi_payment_update)){
                                    $emi_payment_update = EmiPayment::find($emi_payment->id);
                                }
                                $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                                $total_payable = $emi_payment->emi_amount + $emi_payment->bounce_charges + $emi_payment->delay_penalty;
                                $amount_due = $total_payable - $emi_payment_amount_received - $emi_payment->charges_waived;
                                $emi_payment_update->payment_status = $emi_payment_status;
                                $application->emi_payment[$i]->total_payable = $total_payable;
                                $application->emi_payment[$i]->amount_due = $amount_due;
                                $emi_payment_update->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                $emi_payment_update->total_payable = $total_payable;
                                $emi_payment_update->amount_due = $amount_due;

                                $emi_payment_update->save();

                                if($amount_setteled) {
                                    $payment_transaction = new PaymentTransaction();
                                    $payment_transaction->emi_payment_id = $emi_payment->id;
                                    $payment_transaction->amount = $amount_setteled;
                                    $payment_transaction->mode = $mode;
                                    $payment_transaction->paid_by = $paid_by;
                                    $payment_transaction->payment_reconciliation_date = Carbon::parse($payment_reconciliation_date)->format('Y-m-d');
                                    $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                                    $payment_transaction->collected_by = $collected_by;
                                    $payment_transaction->collected_by_type = $collected_by_type;
                                    $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                                    $payment_transaction->wallet_name = $wallet_name;
                                    $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                                    $payment_transaction->trasanction_id = $trasanction_id;
                                    $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                                    $payment_transaction->application_id = $application_id;
                                    $payment_transaction->payment_for = "EMI";
                                    $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');
                                    $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                                    $payment_transaction->bank_id = $bank_id;
                                    $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                                    $payment_transaction->save();
                                }

                                $statusLogs[] = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];
                            }
                        }
                        $i++;
                    }
                }

            }

            $send_communication = 0;
            if ($payment_status == 'rejected' || $payment_status == 'pending_from_bank' || $payment_status == 'initial_reject') {
                $emisArray = [];
                $emi_payment_id = 0;
                $emi_payment_status = "";
                $emisArray = [];
                foreach ($application->emi_payment as $emi_payment) {

                    if ($emi_payment->emi_date <= date('Y-m-d')){
                        $emisArray[] = $emi_payment->emi_date;
                    }

                    if(isset($delay_days)) {
                        $delay_days_old = $delay_days;
                    }
                    $delay_days = $this->calculateDelayDays($emi_payment->emi_date,$payment_date, $application_id);
                    if(!isset($delay_days_old)) {
                        $emi_payment_id = $emi_payment->id;
                        $emi_payment_status = $emi_payment->payment_status;
                    }elseif($delay_days >= 0 && $delay_days < $delay_days_old){
                        $emi_payment_id = $emi_payment->id;
                        $emi_payment_status = $emi_payment->payment_status;
                    }
                }

                if($payment_status == 'rejected'){
                    $send_communication = 1;
                }

                $paymentConfig = $this->getPaymentConfig($application_id);

                if($emi_payment_status != 'success' && $emi_payment_status != 'partial' && $emi_payment_status != "" && $emi_payment_id != 0) {
                    $bounce_charges = $payment_status == 'rejected' ? $paymentConfig['bounce'] : 0;
                    $rejection_date = $payment_status == 'rejected' ? $payment_date : "";
                    EmiPayment::where('id', $emi_payment_id)->update(['bounce_charges' => $bounce_charges, 'payment_status' => $payment_status, 'online_payment_id' => $online_payment_id,'rejected_date' => $rejection_date]);
                    $statusLogs[] = ['emi_payment_id' => $emi_payment_id, 'status' => $payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => isset($data['mode']) ? $data['mode'] : ''];
                }
                $amount_received = 0;
            }

            if ($amount_received > 0) {
                $updateData = $this->updateAdvanceEMI($application,$amount_received,$data);
                $amount_received = $updateData['amount_received'];
            }
            if ($amount_received > 0) {
                if ((isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01")) {
//                    $data['advance_amount'] = $amount_received;
//                    $this->updateAdvanceAmount($data, "Foreclosure", $application_id);
                } else {
                    $data['advance_amount'] = $amount_received;
                    $this->updateAdvanceAmount($data, "Over Payment", $application_id);
                }
            }

            //$this->paymentCalculate($application_id);
            if ($payment_status == 'rejected' || $payment_status == 'pending_from_bank' || $payment_status == 'initial_reject') {
                if($payment_status == 'rejected' && $send_communication == 1){
                    $application_ids = [$application_id];

                    if ((isset($emisArray) && in_array(date('Y-m-d'), $emisArray))){
                        $application_element = ConsumerApplicationElement::where('application_id',$application_id)->first(['amount_over_due']);
                        if (isset($application_element->amount_over_due)) {
                            ConsumerApplicationElement::where('application_id',$application_id)->update(['amount_over_due' => $amount + $application_element->amount_over_due]);
                        }
                    }

                    $this->overDueReminder($application_ids,1,1,1,0,$payment_status,0);
                }
            }else{
                $communicationData = ['application_id' => $application_id, 'data' => $data, 'payment_status' => $payment_status, 'payment_type' => strtolower($payment_type)];
            }
        }else{
            $application['message'] = "No Dues";
        }
        $this->updateStatus($statusLogs, $application_id, $payment_date, $payment_reconciliation_date);
        //$this->invoiceCreation($application_id, $payment_date);
        if ($this->reconcileWithProcessingFee) {
            $this->reconcileWithProcessingFee($data);
        }
        if(!$this->reconcileWithProcessingFee) {
            $this->isAllRepaymentReceived($application_id);
        }

        if($foreclosuredate != "" && $foreclosuredate != 0) {
            $this->forecloseCase($application_id);
        }

        $this->autoWaiveOff($application_id);

//        return array('application'=>$application,'cf_transaction_id'=>$data['cf_transaction_id']);
        return array('application'=>$application,'cf_transaction_id'=>$data['cf_transaction_id'], 'communicationData' => $communicationData);
    }

    public function reconcilePrePayment($data){

        $payment_type = $data['payment_type'] ?? "credit";
        $payment_date = $data['payment_date'];
        $mode = $data['mode'];
        $paid_by = $data['paid_by'];
        $collected_by = $data['collected_by'];
        $collected_by_type = $data['collected_by_type'] ?? 1;
        $application_id = $data['application_id'];
        $trasanction_id = $data['trasanction_id'];
        $trasanction_acknowledgement = $data['trasanction_acknowledgement'];
        $payment_reconciliation_date = $data['payment_reconciliation_date'] ?? $payment_date;
        $wallet_name = $data['wallet_name'];
        $bank_id = $data['bank_id'] ?? "";
        $application = ConsumerApplication::where('id', $application_id)->first(['id','name', 'lender_id']);
        $data['cf_transaction_id'] = $application->id.strtoupper(substr($application->name, 0, 2)).time();
        $adjust_with_disbursement = $data['adjust_with_disbursement'] ?? 0;
        $amount_received = $data['amount'];

        $payment_transaction = new PaymentTransaction();
        $payment_transaction->emi_payment_id = 0;
        $payment_transaction->amount = $amount_received;
        $payment_transaction->mode = $mode;
        $payment_transaction->paid_by = $paid_by;
        $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
        $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
        $payment_transaction->collected_by = $collected_by;
        $payment_transaction->collected_by_type = $collected_by_type;
        $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
        $payment_transaction->wallet_name = $wallet_name;
        $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
        $payment_transaction->trasanction_id = $trasanction_id;
        $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
        $payment_transaction->application_id = $application_id;
        $payment_transaction->payment_for = $payment_type;
        $payment_transaction->payment_date = Carbon::parse($payment_date)->format('Y-m-d');;
        $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
        $payment_transaction->bank_id = $bank_id;
        $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
        $payment_transaction->save();

//            $this->sendPaymentMessage($application_id, $data, $payment_status, strtolower($payment_type));
    }
    public function updateStatus($statusLogs, $application_id, $payment_date, $payment_reconciliation_date){
        if($statusLogs){
            $data = [];
            foreach ($statusLogs as $log){
                $item = ['application_id' => $application_id, 'payment_date' => $payment_date, 'payment_reconciliation_date' => $payment_reconciliation_date, 'created_at' => Carbon::now()->toDateTimeString()];
                $data[] = array_merge($log, $item);
            }
            PaymentLogs::insert($data);

        }
    }

    public function isAllRepaymentReceived($application_id){
        try {
            return false;
            $application = ConsumerApplication::with('application_element', 'merchant','proFormaInvoice')->where('id', $application_id)->first(['id', 'merchant_id','state','name']);
            if ($application->state != 'closed' && isset($application->application_element) && $application->application_element && isset($application->application_element->total_amount_due) && $application->application_element->total_amount_due == 0) {
                $process['merchant_processing_collected'] = $application->proFormaInvoice ? $application->proFormaInvoice->processing_fee_by_merchant : '';
                $process['proFormaInvoice'] = $application->proFormaInvoice;
                $request = new Request();
                $consumerDocument = new ConsumerDocument($request);
                $applicationController = new ConsumerApplicationController();
                if ($consumerDocument->isProcessingFeeCollected($process)) {
                    if (!$applicationController->isProcessingFeeApplicable($application_id)) {
                        $emiPayment = PaymentTransaction::where('application_id', $application_id)->where('payment_for','processing_fee')->first(['id']);
                        if (!isset($emiPayment->id)){
                            return false;
                        }
                    }
                }

                $disbursementController = new DisbursementController($request);
                if($insurance_fee_amount = $disbursementController->isCustomerPayingInsuranceFee($application)) {
                    $emiPayment = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'insurance_fee')->first(['id']);
                    if (!isset($emiPayment->id)) {
                        return false;
                    }
                }
                if($advance_amount_due = $disbursementController->isCFCollectingAdvance($application)) {
                    $emiPayment = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'advance_amount')->first(['id']);
                    if (!isset($emiPayment->id)) {
                        return false;
                    }
                }

                $consumerApplicationController = new ConsumerApplicationController();
                request()->merge(['state' => 'closed']);;
                $consumerApplicationController->updateStatus($application_id);
                (new Slack(new Request(['title' => 'Loan Closed', 'fields' => ['Name' => $application->name, 'merchant_name' => $application->merchant->merchant_name, 'Application ID' => $application->id], 'group' => 'payment_collection'])))->send();
            }
        }catch (\Exception $e){
            (new Slack(new Request(['title' => 'Auto Loan Closed (Error)', 'fields' => ['Message' => $e->getMessage(), 'Line' => $e->getLine(), 'File' => $e->getFile()], 'group' => 'payment_collection'])))->send();
        }
    }

    public function checkIfPaymentReceived($application){
        try {
            if ($application->state != 'closed' && isset($application->application_element) && $application->application_element && isset($application->application_element->total_amount_due) && $application->application_element->total_amount_due == 0) {
                $process['merchant_processing_collected'] = $application->proFormaInvoice ? $application->proFormaInvoice->processing_fee_by_merchant : '';
                $process['proFormaInvoice'] = $application->proFormaInvoice;
                $request = new Request();
                $consumerDocument = new ConsumerDocument($request);
                $applicationController = new ConsumerApplicationController();
                // Processing Fee
                if ($consumerDocument->isProcessingFeeCollected($process)) {
                    if (!$applicationController->isProcessingFeeApplicable($application->id)) {
                        $emiPayment = PaymentTransaction::where('application_id', $application->id)->where('payment_for','processing_fee')->first(['id']);
                        if (!isset($emiPayment->id)){
                            return false;
                        }
                    }
                }
                // Insurance Fee
                $disbursementController = new DisbursementController($request);
                if($insurance_fee_amount = $disbursementController->isCustomerPayingInsuranceFee($application)) {
                    $emiPayment = PaymentTransaction::where('application_id', $application->id)->where('payment_for', 'insurance_fee')->first(['id']);
                    if (!isset($emiPayment->id)) {
                        return false;
                    }
                }
                // Advance Amount
                if($advance_amount_due = $disbursementController->isCFCollectingAdvance($application)) {
                    $emiPayment = PaymentTransaction::where('application_id', $application->id)->where('payment_for', 'advance_amount')->first(['id']);
                    if (!isset($emiPayment->id)) {
                        return false;
                    }
                }
                // OverPayment
                $overPayment = PaymentTransaction::where('application_id', $application->id)->where('payment_for', 'OverPayment')->first();
                if($overPayment){
                    return false;
                }

                $foreclosedAmount = DB::select("select sum(amount) as 'amount' from payment_transactions where trasanction_id=(select trasanction_id from payment_transactions where application_id=".$application->id." and payment_for='Foreclosure');");
                $foreclosure_data = (new LoanManagement())->getForeclosureAmount($application->id);
                $fore_closure_amount = (isset($foreclosure_data['total_outstanding'])) ? $foreclosure_data['total_outstanding'] : 0;
                $saved_foreclosure_amount = ConsumerApplicationElement::where('application_id', $application->id)->first(['foreclosure_amount_sent']);
                if(isset($foreclosedAmount[0]->amount) && (
                    (isset($fore_closure_amount) && $foreclosedAmount[0]->amount < $fore_closure_amount) ||
                    (isset($saved_foreclosure_amount) && $saved_foreclosure_amount->foreclosure_amount_sent > 0 && $foreclosedAmount[0]->amount < $saved_foreclosure_amount->foreclosure_amount_sent)
                )){
                    return false;
                }

                return true;
            }
        }catch (\Exception $e){
            (new Slack(new Request(['title' => 'Auto Loan Closed (Error)', 'fields' => ['Message' => $e->getMessage(), 'Line' => $e->getLine(), 'File' => $e->getFile()], 'group' => 'payment_collection'])))->send();
        }
    }

    public function PTPUpdate($application_id, $payment_date){
        try{
            $promiseToPay = PromiseToPay::where('application_id', $application_id)->where('date','<=', $payment_date)->where('payment_received', 0)->orderBy('date','desc')->first();
            if(isset($promiseToPay->id)){
                PromiseToPay::where('id', $promiseToPay->id)->update(['payment_received' => 1, 'payment_received_date' => $payment_date]);
                return $promiseToPay->id;
            }
        }catch (\Exception $e){

        }

        return false;
    }

    public function invoiceCreation($application_id, $from_date, $to_date){
        $payload[] = [
            'payload' => json_encode(['from_payment_date' => $from_date, 'to_payment_date' => $to_date, 'application_id' => is_array($application_id) ? implode(',', $application_id) : $application_id]),
            'from' => 'bounce_invoices_creation',
            'application_id' => isset($application_id[0]) ? $application_id[0] : $application_id,
            'available_at' => Carbon::now()->addHour(2)->toDateTimeString(),
            'created_at' => Carbon::now()->toDateTimeString()
        ];

//        (new LoanManagement())->creationBouncePenal($payload);
        $job = new Jobs();
        $job->insertQueue($payload);
    }

    public function getBouncePenalData($id){

        $response = array();
        $status =  ['disbursed','nach registered','closed ','cancellation in-process'];

        $consumerApplications = ConsumerApplicationRelation::with('merchant','logs','emi', 'application_element','emi.offer','emi_payment.transaction','lender')->wherein('state',$status)->whereNull('is_deleted')->where('id', $id)->get();
        $consumerDocument = new ConsumerDocument(new Request());

        foreach ($consumerApplications as $consumerApplication) {
            if(isset($consumerApplication->emi) and $consumerApplication->emi != null && isset($consumerApplication->logs->created_at)) {
                if (!isset($response[$consumerApplication->id]['name'])) {
                    $response[$consumerApplication->id]['name'] = $consumerApplication->name;
                }
                if (!isset($response[$consumerApplication->id]['lender'])) {
                    $response[$consumerApplication->id]['lender'] = $consumerApplication->lender->name;
                }
                if (!isset($response[$consumerApplication->id]['subvention_rate'])) {
                    $response[$consumerApplication->id]['subvention_rate'] = $consumerApplication->emi->subvention;
                }
                if (!isset($response[$consumerApplication->id]['approved_amount'])) {
                    $response[$consumerApplication->id]['approved_amount'] = $consumerApplication->approved_amount;
                }
                $disbursed_month = date('Y-m-d', strtotime($consumerApplication->logs->created_at));
                $response[$consumerApplication->id]['month'][$disbursed_month]['processing_fees_net_amount'] = 0;
                if($consumerApplication->emi->processing_fee > 0) {
                    $gstDetails = $consumerDocument->getGSTDetails(
                        [
                            'amount' => $consumerApplication->emi->processing_fee,
                            'state' => (isset($consumerApplication->permanent_address_state) && !empty($consumerApplication->permanent_address_state)) ? $consumerApplication->permanent_address_state : (isset($consumerApplication->current_address_state) && !empty($consumerApplication->current_address_state) ? $consumerApplication->current_address_state : '')
                        ]
                    );
                    foreach ($gstDetails as $gst) {
                        $response[$consumerApplication->id]['month'][$disbursed_month]['processing_fees_net_amount'] = $gst['net_amount'];
                    }
                }
                $last_transaction_date = date('Y-m-d', strtotime($consumerApplication->logs->created_at));

                $loanschedule = json_decode(json_encode($this->getLoanSchedule($consumerApplication->id,1,1,$consumerApplication)));
                if($loanschedule) {
                    if (!isset($response[$consumerApplication->id]['interest_ror'])) {
                        $response[$consumerApplication->id]['revenue_ror'] = $loanschedule->summary->interest;
                    }
                    if (!isset($response[$consumerApplication->id]['interest_ror'])) {
                        $response[$consumerApplication->id]['interest_ror'] = $loanschedule->summary->irr;
                    }
                    foreach ($loanschedule->schedule as $emi_date => $payment) {
                        if($consumerApplication->application_element->foreclosure_date == "" || $consumerApplication->application_element->foreclosure_date >=$emi_date) {
                            $amount_received = $payment->total_payable - $payment->amount_due;
                            if ($amount_received > $payment->emi_amount) {
                                $total_received = 0;
                                $bounce_received = 0;
                                $penalty_received = 0;
                                $bounce_charges_payable = $payment->bounce_charges;
                                $penal_interest_payable = $payment->delay_penalty;

                                foreach ($payment->transaction as $payment_transaction) {
                                    if (empty($payment_transaction->is_deleted_at) and empty($payment_transaction->refunded_at and $payment_transaction->created_at < date('Y-m-d 00:00:00'))) {
                                        $total_received = $total_received + $payment_transaction->amount;
                                        if ($total_received > $payment->emi_amount) {
                                            $bounce_received_instance = $bounce_charges_payable > 0 ? (($payment->bounce_charges < ($total_received - $payment->emi_amount)) ? ($payment->bounce_charges - $bounce_received) : ($total_received - $payment->emi_amount - $bounce_received)) : 0;
                                            $penalty_received_instance = $penal_interest_payable > 0 ? (($payment->delay_penalty < ($total_received - $payment->emi_amount - $payment->bounce_charges)) ? ($payment->delay_penalty - $penalty_received) : ($total_received - $payment->emi_amount - $payment->bounce_charges - $penalty_received)) : 0;
                                            if ($bounce_received_instance > 0) {
                                                $bounce_received = $bounce_received + $bounce_received_instance;
                                                $payment_month = date('Y-m-d', strtotime($payment_transaction->payment_date));
                                                $entry_time = $payment_transaction->cf_transaction_id;
                                                if (isset($response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['bounces_charges'])) {
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['bounces_charges'] += $bounce_received_instance;
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['payment_date'] = $payment_transaction->payment_date;
                                                } else {
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['bounces_charges'] = $bounce_received_instance;
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['payment_date'] = $payment_transaction->payment_date;
                                                }
                                                $bounce_charges_payable = $bounce_charges_payable - $bounce_received_instance;
                                            }
                                            if($penalty_received_instance > 0){
                                                $penalty_received = $penalty_received + $penalty_received_instance;
                                                $payment_month = date('Y-m-d', strtotime($payment_transaction->payment_date));
                                                $entry_time = $payment_transaction->cf_transaction_id;
                                                if (isset($response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['penal_interest'])) {
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['penal_interest'] += $penalty_received_instance;
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['payment_date'] = $payment_transaction->payment_date;
                                                } else {
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['penal_interest'] = $penalty_received_instance;
                                                    $response[$consumerApplication->id]['month'][$payment_month.'|'.$entry_time]['payment_date'] = $payment_transaction->payment_date;
                                                }
                                                $penal_interest_payable = $penal_interest_payable - $penalty_received_instance;

                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    return $response;
                    /*foreach ($response[$consumerApplication->id]['month'] as $month => $monthly_data) {

                        if (!isset($response[$consumerApplication->id]['month'][$month]['principal_outstanding'])) {
                            if($month > date('Y-m',strtotime($consumerApplication->application_element->last_emi_day))) {
                                $response[$consumerApplication->id]['month'][$month]['principal_outstanding'] = 0;
                            }else{
                                $response[$consumerApplication->id]['month'][$month]['principal_outstanding'] = $loanschedule->summary->loan_outstanding;
                            }
                        }
                        if (isset($monthly_data['bounces_charges']) && $monthly_data['bounces_charges'] > 0) {
                            $state_name_bounces = (isset($consumerApplication->permanent_address_state) && !empty($consumerApplication->permanent_address_state)) ? $consumerApplication->permanent_address_state : (isset($consumerApplication->current_address_state) && !empty($consumerApplication->current_address_state) ? $consumerApplication->current_address_state : '');
                            $gstDetails = $consumerDocument->getGSTDetails(
                                [
                                    'amount' => $monthly_data['bounces_charges'],
                                    'state' => $state_name_bounces
                                ]
                            );
                            foreach ($gstDetails as $gst) {
                                $response[$consumerApplication->id]['month'][$month]['bounces_charges'] = $gst['amount'];
                                $response[$consumerApplication->id]['month'][$month]['net_bounces_charges'] = $gst['net_amount'];
                                $response[$consumerApplication->id]['month'][$month]['charges_state'] = $state_name_bounces;
                            }
                        }
                        if (isset($monthly_data['penal_interest']) && $monthly_data['penal_interest'] > 0) {
                            $state_name_penal = (isset($consumerApplication->permanent_address_state) && !empty($consumerApplication->permanent_address_state)) ? $consumerApplication->permanent_address_state : (isset($consumerApplication->current_address_state) && !empty($consumerApplication->current_address_state) ? $consumerApplication->current_address_state : '');
                            $gstDetails = $consumerDocument->getGSTDetails(
                                [
                                    'amount' => $monthly_data['penal_interest'],
                                    'state' => $state_name_penal
                                ]
                            );
                            foreach ($gstDetails as $gst) {
                                $response[$consumerApplication->id]['month'][$month]['penal_interest'] = $gst['amount'];
                                $response[$consumerApplication->id]['month'][$month]['net_penal_interest'] = $gst['net_amount'];
                                $response[$consumerApplication->id]['month'][$month]['charges_state'] = $state_name_penal;
                            }
                        }
                    }

                    ksort($response[$consumerApplication->id]['month']);*/
                }

            }
        }

        return $response;
    }

    public function getParsedReceivedAmount($data){

        if((isset($data['fore_closure_date']) && $data['fore_closure_date'] != "" && $data['fore_closure_date'] != 0) ||
            (isset($data['payment_type']) && $data['payment_type'] == 'processing_fee') || (isset($data['payment_type']) && $data['payment_type'] == 'total_fee')) {
            return $data['amount'];
        } else{
            $this->reconcileWithProcessingFee = false;
            if($data['application_id']){
                $application = ConsumerApplication::with('emi.offer')->where('id',$data['application_id'])->first();
                if($application->emi && $application->emi->offer && $application->emi->offer->processing_fee_first_emi && $application->emi->processing_fee/* && $data['amount'] > $application->emi->emi*/){
                    $emiPayment = PaymentTransaction::where('application_id', $application->id)->where('payment_for','processing_fee')->whereNull('is_deleted_at')->first(['id']);
                    if (!isset($emiPayment->id)) {
                        $amount = $data['amount'] - $application->emi->processing_fee;
                        if($amount < 0){
                            return $data['amount'];
                        }
//                        if ($amount >= $application->emi->emi){
                            $this->reconcileWithProcessingFee = true;
                            return $amount;
//                        }
                    }
                }
            }
        }
        return $data['amount'];
    }

    public function reconcileCurrentMonth($payment_date, $payment_reconciliation_date, $payment_status, $amount_received, $paymentData, $data){


        $flag = false;

        if($payment_status != 'rejected' &&  $payment_status != 'initial_reject' && $payment_status != 'pending_from_bank') {

            $application_id = $paymentData['application_id'];

            $payment = EmiPayment::where('application_id', $application_id)->where('emi_date', '>=', Carbon::parse($payment_reconciliation_date)->startOfMonth()->toDateTimeString())
                ->where('emi_date', '<=', Carbon::parse($payment_reconciliation_date)->endOfMonth()->toDateTimeString())->first();

            if(isset($payment->id)) {
                $check_date = date('Y-m-d', (strtotime('-4 day', strtotime($payment->emi_date))));

                if (isset($payment->id) && ($payment_date >= $payment->emi_date || $payment_date >= $check_date) && $payment->payment_status != "success" && $payment->amount_due) {


                    $mode = $paymentData['mode'];
                    $paid_by = $paymentData['paid_by'];
                    $collected_by = $paymentData['collected_by'];
                    $collected_by_type = $paymentData['collected_by_type'];
                    $adjust_with_disbursement = $paymentData['adjust_with_disbursement'];
                    $wallet_name = $paymentData['wallet_name'];
                    $trasanction_id = $paymentData['trasanction_id'];
                    $trasanction_acknowledgement = $paymentData['trasanction_acknowledgement'];
                    $bank_id = $paymentData['bank_id'];


                    $emi_payment_amount_received = $payment->total_payable - $payment->amount_due;
                    $emi_amount_pending = ($payment->emi_amount - $emi_payment_amount_received);

                    if ($emi_amount_pending) {


                        $emi_payment_amount_received_updated = $payment->total_payable - $payment->amount_due - $payment->charges_waived;
                        $total_emi_amount_pending = ($payment->total_payable - $emi_payment_amount_received_updated);


                        if ($emi_amount_pending <= $amount_received) {
                            $amount_setteled = $emi_amount_pending;
                            $amount_received = $amount_received - $amount_setteled;
                            if (($total_emi_amount_pending - $amount_setteled) > 0) {
                                $emi_payment_status = 'partial';
                            } else {
                                $emi_payment_status = 'success';
                            }
                        } else {
                            $amount_setteled = $amount_received;
                            $amount_received = 0;
                            if (($total_emi_amount_pending - $amount_setteled) == 0) {
                                $emi_payment_status = 'success';
                            } else {
                                $emi_payment_status = 'partial';
                            }
                        }

                        if (!isset($emi_payment_update)) {
                            $emi_payment_update = EmiPayment::find($payment->id);
                        }
                        $emi_payment_amount_received = $emi_payment_amount_received + $amount_setteled;
                        $total_payable = $payment->emi_amount + $payment->bounce_charges + $payment->delay_penalty;
                        $amount_due = $total_payable - $emi_payment_amount_received - $payment->charges_waived;
                        $emi_payment_update->payment_status = $emi_payment_status;
                        $emi_payment_update->total_payable = $total_payable;
                        $emi_payment_update->amount_due = $amount_due;
                        $emi_payment_update->payment_date = $payment_date;
                        $emi_payment_update->total_payable = $total_payable;
                        $emi_payment_update->amount_due = $amount_due;

                        $emi_payment_update->save();

                        $payment_transaction = new PaymentTransaction();
                        $payment_transaction->emi_payment_id = $payment->id;
                        $payment_transaction->amount = $amount_setteled;
                        $payment_transaction->mode = $mode;
                        $payment_transaction->paid_by = $paid_by;
                        $payment_transaction->payment_reconciliation_date = $payment_reconciliation_date;
                        $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                        $payment_transaction->collected_by = $collected_by;
                        $payment_transaction->collected_by_type = $collected_by_type;
                        $payment_transaction->adjust_with_disbursement = $adjust_with_disbursement;
                        $payment_transaction->wallet_name = $wallet_name;
                        $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                        $payment_transaction->trasanction_id = $trasanction_id;
                        $payment_transaction->trasanction_acknowledgement = $trasanction_acknowledgement;
                        $payment_transaction->application_id = $application_id;
                        $payment_transaction->payment_for = "EMI";
                        $payment_transaction->payment_date = $payment_date;
                        $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                        $payment_transaction->bank_id = $bank_id;
                        $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                        $payment_transaction->save();

                        $statusLogs = ['emi_payment_id' => $emi_payment_update->id, 'status' => $emi_payment_status, 'reason' => isset($data['reason']) ? $data['reason'] : '', 'mode' => $mode];


                        $flag['amount_received'] = $amount_received;
                        $flag['statusLogs'] = $statusLogs;
                    }
                }

            }
        }

        return $flag;
    }

    public function reconcileWithProcessingFee($data){
        $data['payment_type'] = 'processing_fee';
        $application = ConsumerApplication::with('emi.offer')->where('id',$data['application_id'])->first();
        $data['amount'] = $application->emi->processing_fee;
        $this->reconcileWithProcessingFee = false;
        $this->paymentReconcile($data);
        (new ConsumerApplicationController())->sendProcessingFeePDF($data['application_id'], true, true);
    }

    public function getLastDayOfMOnth($toodate){
        $lastday = date('Y-m-d',strtotime(date('Y-m-',strtotime($toodate)).date('t',strtotime($toodate))));
        return $lastday;
    }

    public function getLoanSchedule($id,$json = 0,$foreclosure = 0,$application = Null)
    {
        if($application == Null) {
            $application = ConsumerApplication::with('merchant', 'emi', 'application_element', 'emi.offer', 'emi_payment.transaction','moratoriums')->where('id', $id)->whereNull('is_deleted')->first();
        }
        if($application->emi){
            $loan_management = new LoanManagement();
            //$loanamount = ((isset($application->approved_amount) && $application->approved_amount != 0) ? $application->approved_amount : $application->loan_amount) - $application->emi->upfront_from_customer;
            $loanamount = EMICalculation::getLoanAmountWithInsuranceAmount($id) - $application->emi->upfront_from_customer;

            $payment_details = array();
            $emi_schedules = $loan_management->generateDues($id, 1, $application);
            foreach ($application->emi_payment as $payments) {
                $payment_details[$payments['emi_date']] = $payments;
            }
            $subvention_amount = (isset($application->emi->subvention) && $application->emi->subvention > 0) ? ((((isset($application->approved_amount) && $application->approved_amount != 0) ? $application->approved_amount : $application->loan_amount) * ($application->emi->subvention)) / 100) : 0;
            $amount_disbursed = $loanamount - $subvention_amount;

            $frequency_multiplier = $this->payment_frequency[$application->emi->payment_frequency];
//            if (isset($application->emi->rate) && !empty($application->emi->rate) && isset($application->emi->irr_rate) && !empty($application->emi->irr_rate)) {
//                $rate = $application->emi->rate;
//                $annualised_interest = $application->emi->annualised_interest;
//                $irr_rate = $application->emi->irr_rate;
//                $annualised_irr = $application->emi->annualised_irr;
//            } else {
            $emis_array = array();
            $emi_irr_array = array();
            array_push($emis_array, -$loanamount);
            array_push($emi_irr_array, -($amount_disbursed));

            if (isset($emi_schedules)) {
                foreach ($emi_schedules as $schedule) {
                    array_push($emis_array, $schedule['amount']);
                    array_push($emi_irr_array, $schedule['amount']);
                }
            }
            $rate = (Finance::irr($emis_array)) * 100;
            if ($rate < 0) {
                $rate = 0;
            }
            $irr_rate = (Finance::irr($emi_irr_array)) * 100;
            if ($irr_rate < 0) {
                $irr_rate = 0;
            }

            $annualised_interest = round((((($rate + 1) * $frequency_multiplier) - $frequency_multiplier) * 100) / 100, 2);
            $annualised_irr = round((((($irr_rate + 1) * $frequency_multiplier) - $frequency_multiplier) * 100) / 100, 2);
//                if ($rate > 0 && $annualised_interest > 0 && $irr_rate > 0 && $annualised_irr > 0) {
//                    ApplicationEMICalculation::where('id', $application->emi->id)
//                        ->update(['rate' => $rate, 'annualised_interest' => $annualised_interest, 'irr_rate' => $irr_rate, 'annualised_irr' => $annualised_irr]);
//                }

            //   }
            $foreclosure_date = (isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01") ? $application->application_element->foreclosure_date : '';

            if(isset($payment_details)){
                $principal_oustanding = $loanamount;
                $principal_oustanding_subvention = $amount_disbursed;
                $subvention_amount_balance = $subvention_amount;
                foreach ($payment_details as $emi_date => $payment){
                    if($foreclosure_date == "" || $emi_date <= $foreclosure_date) {
                        $payment_details[$emi_date]->interest = $principal_oustanding * ($rate / 100);
                        $payment_details[$emi_date]->principal = $payment->emi_amount - $payment_details[$emi_date]->interest;
                        $payment_details[$emi_date]->irr = $principal_oustanding_subvention * ($irr_rate / 100);
                        $payment_details[$emi_date]->subvention = $payment_details[$emi_date]->irr - $payment_details[$emi_date]->interest;
                        $subvention_amount_balance = $subvention_amount_balance - $payment_details[$emi_date]->subvention;
                        $payment_details[$emi_date]->subvention_amount_balance = $subvention_amount_balance;
                        $principal_oustanding = $principal_oustanding - $payment_details[$emi_date]->principal;
                        $principal_oustanding_subvention = $principal_oustanding_subvention - $payment_details[$emi_date]->principal + $payment_details[$emi_date]->subvention;
                        $payment_details[$emi_date]->principal_outstanding = $principal_oustanding;
                        $payment_details[$emi_date]->principal_outstanding_subvention = $principal_oustanding_subvention;
                        if($foreclosure_date != "" && $emi_date == $foreclosure_date){
                            $payment_details[$emi_date]->principal_outstanding = 0;
                            $payment_details[$emi_date]->principal_outstanding_subvention = 0;
                        }

                        if ($foreclosure == 0) {
                            $foreclosuredetails = $loan_management->getForeclosureAmount($id, $emi_date);
                            $payment_details[$emi_date]->fore_closure_amount = isset($foreclosuredetails['future_emi']) ? $foreclosuredetails['future_emi'] : 0;
                        } else {
                            $payment_details[$emi_date]->fore_closure_amount = 0;
                        }
                    }
                }
            }

            $response['summary']['loan_amount'] = ((isset($application->approved_amount) && $application->approved_amount != 0) ? $application->approved_amount : $application->loan_amount);
            $response['summary']['loan_outstanding'] = $loanamount;
            $response['summary']['tenure'] = $application->emi->tenure;
            $response['summary']['remaining_emi'] = $application->emi->remaining_emi;
            $response['summary']['quoted_interest'] = $application->emi->interest_rate;
            $response['summary']['interest'] = $rate;
            $response['summary']['annualised_interest'] = $annualised_interest;
            $response['summary']['irr'] = $irr_rate;
            $response['summary']['annualised_irr'] = $annualised_irr;
            $response['summary']['subvention'] = $application->emi->subvention;
            $response['summary']['processing_fee'] = $application->emi->processing_fee;
            $response['summary']['emi'] = $application->emi->emi;
            $response['summary']['advance_due'] = $application->emi->upfront_from_customer;
            $response['summary']['last_emi_date'] = $application->emi->emi_date;
            $response['summary']['last_emi_date'] = $application->application_element->last_emi_date;
            $response['customer_name'] = $application->name;
            $response['id'] = $application->id;
            $response['summary']['merchant_name'] = $application->merchant->merchant_name;
            $response['summary']['net_disbursement_amount'] = (isset($application->emi->upfront_from_credit_fair) && $application->emi->upfront_from_credit_fair != 0) ? $application->emi->upfront_from_credit_fair : ((isset($application->approved_amount) && $application->approved_amount != 0) ? $application->approved_amount : $application->loan_amount);
            $response['schedule'] = $payment_details;
            if ($json == 0) {
                return view('admin.accounting.loanschedule', $response);
            } else {
                return $response;
            }
        }else {
//            (new Slack(new Request(['title' => 'Loan Schedule Emi Not Generated ', 'fields' => ['ID' => $id]])))->send();
        }
    }


    public function creationBouncePenal($payload){
        $payload_vals = $payload;//json_decode($payload[0]['payload']);
        $application_ids = $payload_vals->application_id;
        $application_ids = explode(',', $application_ids);
        $from_month = date('F-Y', strtotime($payload_vals->from_payment_date));
//        $from_year = date('Y', strtotime($payload_vals->from_payment_date));
        $to_month = date('F-Y', strtotime($payload_vals->to_payment_date));
        $fromDate = date('Y-m-d H:i:s', strtotime($payload_vals->from_payment_date));
        $toDate = date('Y-m-d H:i:s', strtotime($payload_vals->to_payment_date));
//        $to_year = date('Y', strtotime($payload_vals->from_payment_date));

        foreach ($application_ids as $application_id) {

            $bouncePenalTransactions = $this->getBouncePenalData($application_id);
            $job = JobProvider::where('from','bounce_invoices_creation')->where('id','!=', 545621)->where('application_id', $application_id)->where('payload', 'like','%2021-05%')->first(['id','payload']);

            if(isset($job->id)){
                continue;
            }

            $application = ConsumerApplication::with('settlement_payment')->find($application_id);
            $response = [];

            // if ($bouncePenalTransactions[$application_id]) {

            // Get all bounce/penal settlements within date range
            if (isset($application->settlement_payment)) {
                $filteredSettlements = $application->settlement_payment
                    ->whereIn('payment_for', ['settled_bounce', 'settled_penal'])
                    ->filter(function ($item) use ($fromDate, $toDate) {
                        return $item->payment_date >= $fromDate && $item->payment_date <= $toDate;
                    });

                if ($filteredSettlements) {
                    foreach ($filteredSettlements as $settlement) {
                        $paymentMonth = date('Y-m-d', strtotime($settlement->payment_date));
                        $entryTime = $settlement->cf_transaction_id;
                        $amount = $settlement->amount;

                        if ($amount > 0) {
                            $key = $paymentMonth . '|' . $entryTime;

                            if ($settlement->payment_for === 'settled_bounce') {
                                $bouncePenalTransactions[$application_id]['month'][$key]['bounces_charges'] = $amount;
                            }

                            if ($settlement->payment_for === 'settled_penal') {
                                $bouncePenalTransactions[$application_id]['month'][$key]['penal_interest'] = $amount;
                            }

                            $bouncePenalTransactions[$application_id]['month'][$key]['payment_date'] = $settlement->payment_date;
                        }
                    }
                }
                // }
            }

            if($bouncePenalTransactions) {
                foreach ($bouncePenalTransactions as $monthWiseItem) {
                    foreach ($monthWiseItem['month'] as $monthWiseIndex => $item) {
                        $date = explode('|', $monthWiseIndex)[0] ?? '';
                        if (isset($item['payment_date']) && ($from_month == date('F-Y', strtotime($date)) || $to_month == date('F-Y', strtotime($date)))) {
                            $response[] = [
                                'bounce_charges' => $item['bounces_charges'] ?? 0,
                                'penal_interest' => $item['penal_interest'] ?? 0,
                                'payment_date' => $item['payment_date'],
                                'timestamp' => explode('|', $monthWiseIndex)[1] ?? ''
                            ];
                        }
                    }
                }
            }

            if ($response) {
                $this->saveInvoices($response, $application_id);
            }
        }

        (new Slack(new Request(['title' => 'Bounce Penal Invoice Creation', 'fields' => ['From' => $from_month, 'To' => $to_month], 'group' => Slack::$accounting_entries])))->send();
        /*$transactions = EmiPayment::with('transaction')->whereIn('id', [6467,6468])->get();
        $response = [];
        $application_id = 0;
        $payment_date = '';
        foreach ($transactions as $emi_payment){
            $application_id = $emi_payment->application_id;
            if ($emi_payment->transaction) {
                $amount_received = 0;

                foreach ($emi_payment->transaction as $transaction) {
                    $amount_received = $amount_received + $transaction->amount;
                    $payment_date = $transaction->payment_date;
                }

                if (!isset($response[$emi_payment->emi_date]['emi_amount'])) {
                    $response[$emi_payment->emi_date]['emi_amount'] = 0;
                    $response[$emi_payment->emi_date]['bounce_charges'] = 0;
                    $response[$emi_payment->emi_date]['penal_interest'] = 0;
                    $response[$emi_payment->emi_date]['payment_date'] = $payment_date;
                }


                if ($amount_received > $emi_payment->emi_amount) {
                    $response[$emi_payment->emi_date]['emi_amount'] += $emi_payment->emi_amount;
                    $amount_received = $amount_received - $emi_payment->emi_amount;

                    if ($amount_received > $emi_payment->bounce_charges) {
                        $response[$emi_payment->emi_date]['bounce_charges'] += $emi_payment->bounce_charges;
                        $amount_received = $amount_received - $emi_payment->bounce_charges;

                        if ($amount_received > 0) {
                            $response[$emi_payment->emi_date]['penal_interest'] += $emi_payment->delay_penalty;
                        }
                    } else {
                        $response[$emi_payment->emi_date]['bounce_charges'] += $amount_received;
                    }
                } else {
                    $response[$emi_payment->emi_date]['emi_amount'] += $amount_received;
                }
            }
        }

return $response;
        $data = [];
        foreach ($response as $emi_date => $item){
            $data[date('Y-m-d',strtotime($item['payment_date']))][] = $item;
        }

        foreach ($data as $item){

        }

        return $data;*/
    }
    public function reviseBouncePenal($id, $application_id, $type, $user_id){
        $bouncePenalTransactions = $this->getBouncePenalData($application_id);

        $application = ConsumerApplication::with('settlement_payment')->find($application_id);

        // if ($bouncePenalTransactions[$application_id]) {

        $filteredSettlements = $application->settlement_payment
            ->whereIn('payment_for', ['settled_bounce', 'settled_penal']);

        foreach ($filteredSettlements as $settlement) {
            $paymentMonth = date('Y-m-d', strtotime($settlement->payment_date));
            $entryTime = $settlement->cf_transaction_id;
            $amount = $settlement->amount;

            if ($amount > 0) {
                $key = $paymentMonth . '|' . $entryTime;

                if ($settlement->payment_for === 'settled_bounce') {
                    $bouncePenalTransactions[$application_id]['month'][$key]['settled_bounce'] = $amount;
                }

                if ($settlement->payment_for === 'settled_penal') {
                    $bouncePenalTransactions[$application_id]['month'][$key]['settled_penal'] = $amount;
                }

                $bouncePenalTransactions[$application_id]['month'][$key]['payment_date'] = $settlement->payment_date;
            }
        }
    // }
        $response = [];
        foreach ($bouncePenalTransactions as $monthWiseItem) {
            foreach ($monthWiseItem['month'] as $monthWiseIndex => $item) {
                if (isset($item['payment_date'])){
                    $response[] = [
                        'bounce_charges' => $item['bounces_charges'] ?? 0,
                        'settled_bounce' => $item['settled_bounce'] ?? 0,
                        'settled_penal' => $item['settled_penal'] ?? 0,
                        'penal_interest' => $item['penal_interest'] ?? 0,
                        'payment_date' => $item['payment_date'],
                        'timestamp' => explode('|', $monthWiseIndex)[1] ?? ''
                    ];
                }
            }
        }

        if ($response) {
            $revised_data = $this->saveInvoices($response, $application_id, true, $id,$type);

            $log = [
                'application_id' => $application_id,
                'changes' => json_encode($revised_data),
                '_id' => $id,
                'type' => $type,
                'revised_by' => $user_id,
                'created_at'=> Carbon::now()->toDateTimeString(),
                'updated_at'=> Carbon::now()->toDateTimeString(),
            ];

            (new InvoiceRevisionLog)->fill($log)->save();

            (new Slack(new Request(['title' => 'Bounce Penal Invoice revision', 'fields' => ['Application id' => $application_id], 'group' => Slack::$accounting_entries])))->send();
            return true;
        }
        return false;
    }

    public function saveInvoices($response, $application_id, $revise = false, $revise_id='', $revise_type=''){

        $application = ConsumerApplication::with('application_element','lender','proFormaInvoice')->where('id',$application_id)->first();

        $applicationController = new ConsumerApplicationController();

        $responseData = [];
        foreach ($response as $item) {

            if($invoiceData = $this->getInvoice($applicationController, $item['bounce_charges'], $application, $item, 'bounce', $revise, $revise_id, $revise_type)){
                $responseData[] = $invoiceData;
                $this->saveInvoiceS3($applicationController, ['invoice' => $invoiceData, 'application' => $application, 'type' => 'bounce'], $application_id);
                if($revise){
                    ChargedInvoices::find($revise_id)->fill($invoiceData)->save();
                }else{
                    (new ChargedInvoices())->fill($invoiceData)->save();
                }
            }
            if($invoiceData = $this->getInvoice($applicationController, $item['penal_interest'], $application, $item, 'penal', $revise, $revise_id, $revise_type)){
                $responseData[] = $invoiceData;
                $this->saveInvoiceS3($applicationController, ['invoice' => $invoiceData, 'application' => $application, 'type' => 'penal'], $application_id);
                if($revise){
                    ChargedInvoices::find($revise_id)->fill($invoiceData)->save();
                }else{
                    (new ChargedInvoices())->fill($invoiceData)->save();
                }
            }
        }


        if ($this->duplicateInvoiceIDSeries && $this->duplicateInvoiceIDSeriesData){
            $this->sendDuplicateInvoiceData();
        }

        if($revise){
            return $responseData;
        }
    }

    public function sendDuplicateInvoiceData(){

        try {
            $request = new Request(['data' => $this->duplicateInvoiceIDSeriesData, 'sheet' => 'Sheet1']);
            $file = 'Duplicate Invoice Data.xls';
            Excel::store((new Exporter($request)), $file);

            Mail::send('emails.reminders.basic_reminder', [
                'body' => 'Duplicate Invoice Data',
            ], function ($message) use ($file) {
                $message->to(['sunil@creditfair.in'])
                    ->cc(['suoyg@creditfair.in'])
                    ->subject('Duplicate Invoice Data');
                $message->attachData(file_get_contents(storage_path() . '/app/' . $file), $file);
            });
        }catch (\Exception $e){
            $cwFactory = new CloudWatchLoggerFactory();
            $cwFactory->logger(json_encode(['message' => 'Duplicate Invoice Exception', 'Total Duplicates' => count($this->duplicateInvoiceIDSeriesData), 'Message' => $e->getMessage(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString()]));
        }
    }

    public function saveInvoiceS3(ConsumerApplicationController $applicationController, $invoiceData, $application_id){

        $invoiceData['address'] = $applicationController->getAddressByType($invoiceData['application']);

        $data = [
            'txt' => view('admin.documents.charged_invoice', $invoiceData),
            'type' => $invoiceData['type'].'_'.$invoiceData['invoice']['invoice_id']
        ];

        $requestDocument = new Request();
        if (isset($invoiceData['test_bot']) && $invoiceData['test_bot']){
            $data['test_bot'] = 1;
            $requestDocument->merge(['test_bot' => 1]);
        }

        $request = new Request();
        $request->request->add($data);
        $applicationController->uploadToS3(new ConsumerDocument($requestDocument), $request, $application_id);
    }

    public function getInvoice(ConsumerApplicationController $applicationController, $amount, $application, $item, $type, $revise, $revise_id, $revise_type){

        if($revise) {
            $chargedInvoice = ChargedInvoices::where('id', $revise_id)->where('type', $revise_type)->where('application_id', $application->id)->first();
        }else{
            $chargedInvoice = ChargedInvoices::where('invoice_date', $item['payment_date'])->where('version', $item['timestamp'])->where('application_id', $application->id)->where('type', $type)->first();
        }

        if((!$revise && !isset($chargedInvoice->id)) || ($revise && isset($chargedInvoice->id) && !empty($chargedInvoice->invoice_id) && $revise_type == $type)) {
            $_gstDetails = (new ConsumerDocument(new Request()))->getGSTDetails(
                [
                    'amount' => $amount,
                    'state' => (isset($application->permanent_address_state) && !empty($application->permanent_address_state)) ? $application->permanent_address_state : (isset($application->current_address_state) && !empty($application->current_address_state) ? $application->current_address_state : '')
                ]
            );

            $gstData = (isset($_gstDetails[0])) ? $_gstDetails[0]['amount'] : 0;

            if ($gstData) {
                $gstDetails = $_gstDetails[0];

                $invoiceID = $revise && isset($chargedInvoice->invoice_id) ? $chargedInvoice->invoice_id : $this->getInvoiceNumberV1($applicationController, $application, $type);
                if (in_array($invoiceID, $this->invoiceIDSeries)){
                    $this->duplicateInvoiceIDSeries[] = $invoiceID;
                    $invoiceID = $revise && isset($chargedInvoice->invoice_id) ? $chargedInvoice->invoice_id : $this->getInvoiceNumberV1($applicationController, $application, $type);
                    if (in_array($invoiceID, $this->invoiceIDSeries)){
                        $this->duplicateInvoiceIDSeriesData[] = [
                            'application_id' => $application->id,
                            'lender_id' => $application->lender_id,
                            'invoice_id' => $invoiceID,
                            'amount' => $gstDetails['amount'],
                            'invoice_date' => $item['payment_date'],
                            'type' => $type,
                            'version' => $item['timestamp'],
                        ];
                        return false;
                    }
                }
                $this->invoiceIDSeries[] = $invoiceID;

                return [
                    'application_id' => $application->id,
                    'lender_id' => $application->lender_id,
                    'invoice_id' => $invoiceID,
                    'amount' => $gstDetails['amount'],
                    'net_amount' => $type == 'penal' ? $gstDetails['amount'] : $gstDetails['net_amount'],
                    'igst' => $type == 'penal' ? 0 : ($gstDetails['taxes'] == 'IGST' ? $gstDetails['gst_amount'] : 0),
                    'cgst' => $type == 'penal' ? 0 : ($gstDetails['taxes'] != 'IGST' ? $gstDetails['gst_amount'] : 0),
                    'sgst' => $type == 'penal' ? 0 : ($gstDetails['taxes'] != 'IGST' ? $gstDetails['gst_amount'] : 0),
                    'invoice_date' => $item['payment_date'],//'2021-06-30',//Carbon::now()->toDateString(),
                    'type' => $type,
                    'version' => $item['timestamp'],
                    'getGSTDetails' => $_gstDetails,
                    'created_at' => $revise && isset($chargedInvoice->invoice_id) ? $chargedInvoice->created_at : Carbon::now()->toDateTimeString(),
                    'updated_at' => $revise && isset($chargedInvoice->invoice_id) ? $chargedInvoice->updated_at : Carbon::now()->toDateTimeString(),
                ];
            }
        }

        return false;
    }

    public function getInvoiceNumber(ConsumerApplicationController $applicationController, $application, $type){
        //CF-5101001-19-20
        $financialYear = $applicationController->getFinancialYear(false, true);

        $invoice = ChargedInvoices::where('lender_id', $application->lender_id)->where('invoice_id', 'like', '%' . $financialYear . '%')->where('type',$type)
            ->orderBy('invoice_id', 'desc')->first(['invoice_id']);

        if (isset($invoice->invoice_id)) {
            $invoiceData = ($type == 'bounce' && strpos($invoice->invoice_id, '-B')) ? explode('-B', $invoice->invoice_id) : (($type == 'penal' && strpos($invoice->invoice_id, '-I')) ? explode('-I', $invoice->invoice_id) : explode('-', $invoice->invoice_id));
            $invoiceID = isset($invoiceData[1]) ? (int)substr($invoiceData[1], 1) : '';
            $id = $invoiceID + 1;
        } else {
            $id = 1;
        }

        $concatstring = "";
        if (strlen($id) < 6) {
            $diff = 6 - strlen($id);
            for ($i = 0; $i < $diff; $i++) {
                $concatstring = $concatstring . "0";
            }
        }

        $fistChrInvoice = $application->lender_id + 3;

        if($type == 'bounce')
            return 'CF-B'. $fistChrInvoice . $concatstring . $id . '-' . $financialYear;

        return 'CF-I'. $fistChrInvoice . $concatstring . $id . '-' . $financialYear;
    }

    public function getInvoiceNumberV1(ConsumerApplicationController $applicationController, $application, $type){
        //CF-5101001-19-20
        $financialYear = $applicationController->getFinancialYear(false, true);

        $invoice = ChargedInvoices::where('lender_id', $application->lender_id)->where('invoice_id', 'like', '%-' . $financialYear)->where('type',$type)
            ->orderBy('invoice_id', 'desc')->first(['invoice_id']);

        if (isset($invoice->invoice_id)) {
            $invoiceData = ($type == 'bounce' && strpos($invoice->invoice_id, '-B')) ? explode('-B', $invoice->invoice_id) : (($type == 'penal' && strpos($invoice->invoice_id, '-I')) ? explode('-I', $invoice->invoice_id) : explode('-', $invoice->invoice_id));
            $invoiceID = isset($invoiceData[1]) ? (int)substr($invoiceData[1], 1) : '';
            $id = $invoiceID + 1;
        } else {
            $id = 1;
        }

        $concatstring = "";
        if (strlen($id) < 7) {
            $diff = 7 - strlen($id);
            for ($i = 0; $i < $diff; $i++) {
                $concatstring = $concatstring . "0";
            }
        }

//        $fistChrInvoice = $application->lender_id + 3;

        if($type == 'bounce'){
            switch ($application->lender_id){
                case 2 :
                    return 'CF-B'. $concatstring . $id . '-' . $financialYear;
                case 3 :
                    return 'AV-B'. $concatstring . $id . '-' . $financialYear;
                case 4 :
                    return 'AB-B'. $concatstring . $id . '-' . $financialYear;
                case 5 :
                    return 'LB-B'. $concatstring . $id . '-' . $financialYear;
                case 6 :
                    return 'UC-B'. $concatstring . $id . '-' . $financialYear;
                case 7 :
                    return 'LL-B'. $concatstring . $id . '-' . $financialYear;
                case 8 :
                    return 'IB-B'. $concatstring . $id . '-' . $financialYear;
                case 9 :
                    return 'JM-B'. $concatstring . $id . '-' . $financialYear;
                case 10 :
                    return 'SC-B'. $concatstring . $id . '-' . $financialYear;
                case 11 :
                    return 'KM-B'. $concatstring . $id . '-' . $financialYear;
                case 12 :
                    return 'VC-B'. $concatstring . $id . '-' . $financialYear;
                case 13 :
                    return 'US-B'. $concatstring . $id . '-' . $financialYear;
                case 15 :
                    return 'MD-B'. $concatstring . $id . '-' . $financialYear;
                case 16 :
                    return 'CG-B'. $concatstring . $id . '-' . $financialYear;
                case 17 :
                    return 'CP-B'. $concatstring . $id . '-' . $financialYear;
                case 18 :
                    return 'SF-B'. $concatstring . $id . '-' . $financialYear;
            }
        }elseif($type == 'penal'){
            switch ($application->lender_id){
                case 2 :
                    return 'CF-I'. $concatstring . $id . '-' . $financialYear;
                case 3 :
                    return 'AV-I'. $concatstring . $id . '-' . $financialYear;
                case 4 :
                    return 'AB-I'. $concatstring . $id . '-' . $financialYear;
                case 5 :
                    return 'LB-I'. $concatstring . $id . '-' . $financialYear;
                case 6 :
                    return 'UC-I'. $concatstring . $id . '-' . $financialYear;
                case 7 :
                    return 'LL-I'. $concatstring . $id . '-' . $financialYear;
                case 8 :
                    return 'IB-I'. $concatstring . $id . '-' . $financialYear;
                case 9 :
                    return 'JM-I'. $concatstring . $id . '-' . $financialYear;
                case 10 :
                    return 'SC-I'. $concatstring . $id . '-' . $financialYear;
                case 11 :
                    return 'KM-I'. $concatstring . $id . '-' . $financialYear;
                case 12 :
                    return 'VC-I'. $concatstring . $id . '-' . $financialYear;
                case 13 :
                    return 'US-I'. $concatstring . $id . '-' . $financialYear;
                case 15 :
                    return 'MD-I'. $concatstring . $id . '-' . $financialYear;
                case 16 :
                    return 'CG-I'. $concatstring . $id . '-' . $financialYear;
                case 17 :
                    return 'CP-I'. $concatstring . $id . '-' . $financialYear;
                case 18 :
                    return 'SF-I'. $concatstring . $id . '-' . $financialYear;
            }
        }
        return true;
    }

    public function updateAdvanceAmount($data,$payment_for = "Advance Payment",$application_id){
        $payment_transaction = new PaymentTransaction();
        $payment_transaction->emi_payment_id = 0;
        $payment_transaction->amount = $data['advance_amount'];
        $payment_transaction->mode = $data['mode'];
        $payment_transaction->paid_by = $data['paid_by'];
        $payment_transaction->collected_by = $data['collected_by'];
        $payment_transaction->collected_by_type = $data['collected_by_type'] ?? 1;
        $payment_transaction->adjust_with_disbursement = $data['adjust_with_disbursement'] ?? 0;
        $payment_transaction->wallet_name = $data['wallet_name'];
        $payment_transaction->trasanction_id = $data['trasanction_id'];
        $payment_transaction->reason = $data['reason'] ?? '';
        $payment_transaction->trasanction_acknowledgement = $data['trasanction_acknowledgement'];
        $payment_transaction->payment_date = Carbon::parse($data['payment_date'])->format('Y-m-d');
        $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
        $payment_transaction->bank_id = $data['bank_id'] ?? '';
        $payment_transaction->payment_reconciliation_date = $data['payment_reconciliation_date'] ?? $data['payment_date'];;
        $payment_transaction->payment_for = $payment_for;
        $payment_transaction->application_id = $application_id;
        $payment_transaction->status = $data['status'] ?? 'success';
        $payment_transaction->save();

        if($payment_for == 'Over Payment') {
            $applications = ConsumerApplication::where('id', $application_id)->first();
            if($applications) {
                $name = (isset($applications->name)) ? $applications->name : "customer";
                $amount = $data['advance_amount'];
                $payment_date = $data['payment_date'];
                $url = asset("admin/payment/start_v1/" . $application_id);
                (new Slack(new Request(['title' => 'Over Payment', 'fields' => ['Name' => $name, 'Over Payment Amount' => $amount, 'Payment Date' => $payment_date, 'URL' =>$url ], 'group' => 'payment_collection'])))->send();
            }
        }
    }

    public function sendPaymentMessage($application_id, $payment, $isSuccess,$purpose){

        if($isSuccess == 'success'){
            $template_id = 6;
            if($purpose == 'processing_fee'){
                $template_id = 8;
            }elseif($purpose == 'legal_charges'){
                return true;
            }elseif($purpose == 'insurance_fee'){
                $template_id = 9;
            }elseif($purpose == 'advance_amount'){
                $template_id = 10;
            }else if(in_array($purpose, ['collection_charges'])){
                return true;
            }else if($purpose == 'total_fee'){
                $template_id = 11;
            }

            $applicationController = new ConsumerApplicationController();
            $data = $applicationController->getTemplateReminders($template_id, $application_id, $payment);
            $data = $data->getData();
            //$data->email_id_test = ['aditya@creditfair.in','shraddha@creditfair.in','imran@creditfair.in','ashish@creditfair.in'];

            if (isset($data->email) && !empty($data->email)) {
                \Mail::send('emails.blank',
                    ['body' => $data->body]
                    , function ($message) use ($data) {
                        $message->to($data->email)->subject($data->subject);
                        //$message->cc('payments@creditfair.in');
                    });
//            $mobile = '918850077108';
//            send_sms($mobile, $data->sms);
            }
            if (isset($data->mobile_number) && !empty($data->mobile_number) && isset($data->sms)) {
                $mobile = '91' . $data->mobile_number;
                send_sms($mobile, ['message'=>$data->sms,'id'=>$application_id,'id_type'=>'application_id','message_type'=>"payment", 'templateId' => isset($data->templateId) ? $data->templateId : '', 'args' => isset($data->args) ? $data->args : '', 'templateDetails'=>isset($data->templateDetails)?$data->templateDetails :'']);
            }
        }
    }
    public function updateAdvanceEMI($application,$amount_received,$data){
        foreach($application->emi_payment as $emi_payment){
            if(((isset($emi_payment->update_status) && $emi_payment->update_status != "Done") || (!isset($emi_payment->update_status))) && $amount_received > 0 && (!isset($application->application_element->foreclosure_date) || empty($application->application_element->foreclosure_date) || $application->application_element->foreclosure_date == "1970-01-01" || $application->application_element->foreclosure_date >= $emi_payment->emi_date)){
                $amount_paid = 0;
                foreach ($emi_payment->transaction as $payment_transaction_check){
                    if($payment_transaction_check->status == 'success' && !$payment_transaction_check->refunded_at) {
                        $amount_paid = $amount_paid + $payment_transaction_check->amount;
                    }
                }
                $emi_amount_pending = $emi_payment->emi_amount - $amount_paid;
                if ($emi_amount_pending <= $amount_received) {
                    $amount_setteled = $emi_amount_pending;
                    $amount_received = $amount_received - $amount_setteled;
                    $emi_payment_status = 'success';
                }else{
                    $amount_setteled =  $amount_received;
                    $amount_received = 0;
                    if($emi_payment->emi_amount == $amount_setteled){
                        $emi_payment_status = 'success';
                    }else{
                        $emi_payment_status = 'partial';
                    }
                }
                if(!isset($emi_payment_update)){
                    $emi_payment_update = EmiPayment::find($emi_payment->id);
                }
                $emi_payment_update->payment_status = $emi_payment_status;
                $emi_payment_update->payment_date = Carbon::parse($data['payment_date'])->format('Y-m-d');
                $emi_payment_update->save();

                $payment_transaction = new PaymentTransaction();
                $payment_transaction->emi_payment_id = $emi_payment->id;
                $payment_transaction->amount = $amount_setteled;
                $payment_transaction->mode = $data['mode'];
                $payment_transaction->paid_by = $data['paid_by'];
                $payment_transaction->payment_reconciliation_date = isset($data['payment_reconciliation_date']) ? $data['payment_reconciliation_date'] : $data['payment_date'];;
                $payment_transaction->umrn = isset($data['umrn']) ? $data['umrn'] : '';
                $payment_transaction->collected_by = $data['collected_by'];
                $payment_transaction->collected_by_type = isset($data['collected_by_type']) ? $data['collected_by_type'] : 1;
                $payment_transaction->adjust_with_disbursement = isset($data['adjust_with_disbursement']) ? $data['adjust_with_disbursement'] : 0;
                $payment_transaction->wallet_name = $data['wallet_name'];
                $payment_transaction->reason = isset($data['reason']) ? $data['reason'] : '';
                $payment_transaction->trasanction_id = $data['trasanction_id'];
                $payment_transaction->trasanction_acknowledgement = $data['trasanction_acknowledgement'];
                $payment_transaction->application_id = $application->id;
                $payment_transaction->payment_for = "EMI";
                $payment_transaction->payment_date = Carbon::parse($data['payment_date'])->format('Y-m-d');
                $payment_transaction->cf_transaction_id = $data['cf_transaction_id'];
                $payment_transaction->bank_id = isset($data['bank_id']) ? $data['bank_id'] : "";;
                $payment_transaction->status = isset($data['status']) ? $data['status'] : 'success';
                $payment_transaction->save();
            }
        }
        return ['amount_received' => $amount_received];
    }

    /**
     * Check whether the total settlement amount (already received + parked + new payment)
     * meets the agreed amount_to_be_received from the latest Settlement CollectionAction.
     *
     * If the threshold is NOT yet met, the current payment is saved to parked_transactions
     * and this method returns false so the caller skips reconciliation.
     *
     * If the threshold IS met, returns true so reconciliation proceeds.
     */
    private function isSettlementAmountFulfilled($application_id, $new_amount, &$data_update)
    {
        $settlementAction = CollectionAction::where('application_id', $application_id)
            ->where('dispo_code', 'Settlement')
            ->orderBy('created_at', 'desc')
            ->first(['amount_to_be_received', 'ptp_date']);

        $amountToBeReceived = $settlementAction ? (float) $settlementAction->amount_to_be_received : 0;
        $ptpDate            = $settlementAction ? $settlementAction->ptp_date : null;

        $totalParked = (float) ParkedTransaction::where('application_id', $application_id)
            ->where('reconciliation_status', 'parked')
            ->when($ptpDate, function ($q) use ($ptpDate) {
                $q->where('payment_date', '<=', $ptpDate);
            })
            ->sum('amount');

        $totalCollected = $totalParked + (float) $new_amount;

        // Threshold not met — park this payment and return false
        ParkedTransaction::create([
            'application_id'             => $application_id,
            'amount'                     => $new_amount,
            'payment_date'               => $data_update['payment_date'],
            'payment_reconciliation_date'=> $data_update['payment_reconciliation_date'],
            'payment_for'                => $data_update['payment_for'],
            'payment_mode'               => $data_update['payment_mode'],
            'trasanction_id'             => $data_update['trasanction_id'],
            'cf_transaction_id'          => $data_update['cf_transaction_id'],
            'trasanction_acknowledgement'=> $data_update['trasanction_acknowledgement'],
            'online_payment_id'          => $data_update['online_payment_id'],
            'payment_status'             => $data_update['payment_status'],
            'wallet_name'                => $data_update['wallet_name'],
            'bank_id'                    => $data_update['bank_id'],
            'paid_by'                    => $data_update['paid_by'],
            'collected_by'               => $data_update['collected_by'],
            'collected_by_type'          => $data_update['collected_by_type'],
            'umrn'                       => $data_update['umrn'],
            'reason'                     => $data_update['reason'],
            'status'                     => $data_update['status'],
            'adjust_with_disbursement'   => $data_update['adjust_with_disbursement'],
            'is_verify'                  => $data_update['is_verify'],
            'reconciliation_status'      => 'parked',
        ]);

        if ($totalCollected >= $amountToBeReceived) {
            $data_update['amount'] = $totalCollected;
            return true;
        }

        return false;
    }


    public function paymentCalculateWithoutCharges($id = 0, $payment_date = '',$case_type = 'disbursed', $isMoratorium = false){
        $payment_date_original = $payment_date;
        if($payment_date == ''){
            $payment_date = date('Y-m-d');
        }
        $application_id = idStringtoArray($id);

        $applications = ConsumerApplication::with('merchant','centers','emi','proFormaInvoice','application_element','emi_payment.transaction','moratoriums');
        if($application_id){
            $applications = $applications->whereIn('id',$application_id);
        }elseif($case_type == 'disbursed'){
            $applications = $applications->whereIn('state',$this->status);
        }
        $applications = $applications->get();



        $delayDays = [];
        foreach ($applications as $application) {

            if (!($application->emi) || $application->emi->emi < 1) {
                //(new Slack(new Request(['title' => 'Payment Calculate', 'fields' => ['ID' => $application->id]])))->send();
            } else {
                if ((isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01")) {
                    $foreclosure_date = $application->application_element->foreclosure_date;
                } else {
                    $foreclosure_date = "";
                }
                $emi_schedules = $this->generateDues($application->id, 0, $application);
                $emi_dates = array();
                foreach ($emi_schedules as $emi_date => $emis) {
                    array_push($emi_dates, $emi_date);
                }
                foreach ($application->emi_payment as $emi_payment) {
                    if ($foreclosure_date == '' || $foreclosure_date >= $emi_payment->emi_date) {
                        if (in_array($emi_payment->emi_date, $emi_dates)) {
                            $emi_date = $emi_payment->emi_date;
                            if ($emi_payment->payment_status != "success") {
                                $emi_charges = $this->getBounceChargesV1($emi_payment->emi_amount, $emi_date, $emi_payment->transaction, $payment_date_original, 0, $application->id);
                                if($emi_charges['delay_days']) {
                                    $delayDays[] = ['application_id' => $emi_payment->application_id, 'delay_days' => $emi_charges['delay_days'], 'emi_payment_id' => $emi_payment->id, 'created_at' => Carbon::now()->toDateTimeString()];
                                }
                            } else {
                                $emi_charges = $this->getBounceChargesV1($emi_payment->emi_amount, $emi_date, $emi_payment->transaction, $payment_date_original, 0, $application->id);
                                if($emi_charges['delay_days']) {
                                    $delayDays[] = ['application_id' => $emi_payment->application_id, 'delay_days' => $emi_charges['delay_days'], 'emi_payment_id' => $emi_payment->id, 'created_at' => Carbon::now()->toDateTimeString()];
                                }
                            }
                            $emi_schedules[$emi_date]['status'] = 'Done';
                        }
                    }
                }

                foreach ($emi_schedules as $emi_date => $emi_schedule) {

                    if ($emi_schedule['status'] == 'pending' && ($foreclosure_date == '' || $foreclosure_date >= $emi_date)) {
                        $emi_charges = $this->getBounceChargesV1($emi_schedule['amount'], $emi_date, array(), $payment_date, 0, $application->id);
                        if($emi_charges['delay_days']) {
                            $delayDays[] = ['application_id' => $emi_schedules['id'], 'delay_days' => $emi_charges['delay_days'], 'emi_payment_id' => $emi_schedule['emi_id'], 'created_at' => Carbon::now()->toDateTimeString()];
                        }
                        $emi_schedules[$emi_date]['status'] = 'Done';
                    }
                }
            }
        }


        //Without Penalty
        if($delayDays) {
            DelayPenalty::insert($delayDays);
        }
    }

    private function updatePaymentStatus($id){
        $emi_payments = EmiPayment::where('application_id', $id)->where('amount_due', '>', 0)->where('payment_status', 'success')->get(['id', 'amount_due']);
        if(isset($emi_payments[0]->id)) {
            foreach ($emi_payments as $payment) {
                EmiPayment::where('id', $payment->id)->update(['payment_status' => 'partial']);
            }
        }
    }

    public function paymentCalculate($id = 0, $payment_date = '',$case_type = 'disbursed', $isMoratorium = false){
        if (!is_array($id) && $this->payment_entry_page) {
            $repaymentController = new RepaymentController();
            //$repaymentController->update_bounce_penal($id);
            $repaymentController->update_over_due($id);


            (new ConsumerApplicationController())->updateProcessFeesPayment($id);
            (new ConsumerApplicationController())->updateLegalChargesPayment($id);
            $this->updatePaymentStatus($id);
        }
        return false;
        $is_pre_payment = PaymentTransaction::where('application_id',$id)->whereIn('payment_for',['pre_part_payment'])->whereNull('is_deleted_at')->first(['id']);
        if (isset($is_pre_payment->id)){
            return false;
        }

        $payment_date_original = $payment_date;
        if($payment_date == ''){
            $payment_date = date('Y-m-d');
        }
        if($this->isCron){
            $application_id = $id;
        }else{
            $application_id = idStringtoArray($id);
        }

        $applications = ConsumerApplication::with('merchant','centers','emi','proFormaInvoice','emi_payment.transaction','application_element','moratoriums');
        if($application_id){
            $applications = $applications->whereIn('id',$application_id);
        }elseif($case_type == 'disbursed'){
            $applications = $applications->whereIn('state',$this->status);
        }
        $applications = $applications->whereNull('is_deleted')->get();


        foreach ($applications as $application) {

            (new ConsumerApplicationController())->updateProcessFeesPayment($application->id);
            (new ConsumerApplicationController())->updateLegalChargesPayment($application->id);

            $repaymentController = new RepaymentController();
            $rps_exist = $repaymentController->checkRPSExists($id);
            if($rps_exist){
                $repaymentController->getPaymentCalculations($application->id);
            }else {
                if (!($application->emi) || $application->emi->emi < 1) {
//                (new Slack(new Request(['title' => 'Payment Calculate', 'fields' => ['ID' => $application->id]])))->send();
                } else {
                    if ((isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01")) {
                        $foreclosure_date = $application->application_element->foreclosure_date;
                    } else {
                        $foreclosure_date = "";
                    }

                    $foreclosure_amount = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'Foreclosure')->whereNull('is_deleted_at')->whereNull('deleted_by')->first();
                    $writeOff_amount = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'Write-off')->whereNull('is_deleted_at')->whereNull('deleted_by')->first();

                    $emi_schedules = $this->generateDues($application->id, 0, $application);

                    if (in_array($application->id, [246136, 233264])) {
                        foreach ($application->emi_payment as $_emi_payment) {
                            $emi_schedules[$_emi_payment->emi_date] = [
                                'due_date' => $_emi_payment->due_date,
                                'amount' => $_emi_payment->amount,
                                'status' => 'pending',
                                'moratorium_amount' => 0,
                            ];
                        }
                    }


                    $emi_dates = array();
                    foreach ($emi_schedules as $emi_date => $emis) {
                        array_push($emi_dates, $emi_date);
                    }
                    $this->updateMoratoriumAmount($emi_schedules);
                    $outstanding_over_due = 0;
                    $outstanding_principal_due = 0;
                    $total_principal_due = 0;
                    $total_over_due = 0;
                    $last_emi_date = '';
                    $emi_paid = 0;
                    $emi_pending = 0;
                    foreach ($application->emi_payment as $emi_payment) {
                        if ($foreclosure_date == '' || $foreclosure_date > $emi_payment->emi_date) {
                            if (in_array($emi_payment->emi_date, $emi_dates)) {
                                $emi_date = $emi_payment->emi_date;
                                $last_emi_date = $emi_date;
                                if ($emi_payment->payment_status != "success") {
                                    $emi_charges = $this->getBounceCharges($emi_payment->emi_amount, $emi_payment->due_date, $emi_date, $emi_payment->transaction, $payment_date_original, 0, $emi_payment->application_id);
                                    $total_payable = (($emi_payment->emi_amount) + $emi_charges['bounce_charges'] + $emi_charges['penal_interest']) - $emi_payment->charges_waived;
                                    $amount_due = $emi_payment->emi_amount - $emi_charges['amount_received'];
                                    if($emi_charges['amount_received'] >= $emi_payment->emi_amount){
                                        $amount_due = 0;
                                    }
                                    $amount_over_due = $total_payable - $emi_charges['amount_received'];
                                    $outstanding_principal_due = $outstanding_principal_due + $amount_due;
                                    $outstanding_over_due = $outstanding_over_due + $amount_over_due;
                                    if ($emi_date < date('Y-m-d')) {
                                        $total_principal_due = $total_principal_due + $amount_due;
                                        $total_over_due = $total_over_due + $amount_over_due;
                                    }
                                    $emi_update = EmiPayment::find($emi_payment->id);
                                    if ($emi_update) {
                                        $emi_update->bounce_charges = $emi_charges['bounce_charges'];
                                        $emi_update->delay_penalty = $emi_charges['penal_interest'];
                                        $emi_update->total_payable = $total_payable;
                                        $emi_update->amount_due = $amount_over_due;
                                        $emi_update->due_date = $emi_schedules[$emi_payment->emi_date]['due_date'];

                                        $emi_update->delay_days = $emi_charges['delay_days'];
                                        if ($emi_payment->payment_status == 'success' || $emi_payment->payment_status == 'pending' || $emi_payment->payment_status == 'partial' || $emi_payment->payment_status == 'rejected') {
                                            $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                                        }

                                        if (($application->moratoriums && count($application->moratoriums) && $emi_schedules[$emi_payment->emi_date]['amount'] != $emi_payment->emi_amount) || $isMoratorium) {
                                            $emi_update->emi_amount = $emi_schedules[$emi_payment->emi_date]['amount'];
                                        }
                                        $emi_update->save();
                                    }
                                    $emi_pending = $emi_pending + 1;
                                } else {
                                    $emi_charges = $this->getBounceCharges($emi_payment->emi_amount, $emi_payment->due_date, $emi_date, $emi_payment->transaction, $payment_date_original, 0, $emi_payment->application_id);
                                    $total_payable = (($emi_payment->emi_amount) + $emi_payment->bounce_charges + $emi_payment->delay_penalty) - $emi_payment->charges_waived;
                                    $amount_over_due = $total_payable - $emi_charges['amount_received'];
                                    $emi_paid = $emi_paid + 1;
                                    //if ($emi_payment->amount_due > 0) {
                                    $emi_update = EmiPayment::find($emi_payment->id);
                                    $emi_update->total_payable = $total_payable;
                                    $emi_update->amount_due = 0;
                                    if ($amount_over_due > 0) {
                                        $emi_update->amount_due = $amount_over_due;
                                        $emi_update->delay_days = $emi_charges['delay_days'];
                                        $emi_update->due_date = $emi_schedules[$emi_payment->emi_date]['due_date'];
                                        if ($emi_payment->payment_status == 'success' || $emi_payment->payment_status == 'pending' || $emi_payment->payment_status == 'partial' || $emi_payment->payment_status == 'rejected') {
                                            $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                                        }
                                    }
                                    if (($application->moratoriums && count($application->moratoriums) && $emi_schedules[$emi_payment->emi_date]['amount'] != $emi_payment->emi_amount) || $isMoratorium) {
                                        $emi_update->emi_amount = $emi_schedules[$emi_payment->emi_date]['amount'];
                                    }
                                    $emi_update->save();
                                    //}
                                }
                                $emi_schedules[$emi_date]['status'] = 'Done';
                            } else if (($emi_payment->payment_status == "pending" && $application->moratorium && isset($application->moratorium->id)) || $isMoratorium) {
                                $isMoratoriumExist = Moratorium::withTrashed()->where('application_id', $application->id)->first(['id']);
                                if (isset($isMoratoriumExist->id)) {
                                    try {
                                        EmiPayment::find($emi_payment->id)->delete();
                                    } catch (\Exception $exception) {

                                    }
                                }
                            }
                        }
                    }

                    $emisArray1 = [];
                    foreach ($emi_schedules as $emi_date => $emi_schedule) {
                        $last_emi_date = $emi_date;

                        if ($emi_schedule['status'] == 'pending' && ($foreclosure_date == '' || $foreclosure_date > $emi_date)) {
                            $emi_charges = $this->getBounceCharges($emi_schedule['amount'], $emi_schedule['due_date'], $emi_date, array(), $payment_date, 0, $emi_schedule['id']);
                            $total_payable = ($emi_schedule['amount']) + $emi_charges['bounce_charges'] + $emi_charges['penal_interest'];
                            $amount_due = ($emi_schedule['amount'] - $emi_charges['amount_received']);
                            $amount_over_due = ($total_payable - $emi_charges['amount_received']);
                            $outstanding_principal_due = $outstanding_principal_due + $amount_due;
                            $outstanding_over_due = $outstanding_over_due + $amount_over_due;
                            if ($emi_date < date('Y-m-d')) {
                                $total_principal_due = $total_principal_due + $amount_due;
                                $total_over_due = $total_over_due + $amount_over_due;
                            }

                            if (!in_array($emi_date, $emisArray1)) {
                                $emisArray1[] = $emi_date;
                                $emiPayment = EmiPayment::where('application_id', $application->id)->where('emi_date', $emi_date)->first(['id']);

                                if (isset($emiPayment->id)) {
                                    $emi_update = EmiPayment::find($emiPayment->id);
                                    $emi_update->emi_date = $emi_date;
                                    $emi_update->emi_amount = $emi_schedule['amount'];
                                    $emi_update->bounce_charges = $emi_charges['bounce_charges'];
                                    $emi_update->charges_waived = 0;
                                    $emi_update->delay_penalty = $emi_charges['penal_interest'];
                                    $emi_update->total_payable = $total_payable;
                                    $emi_update->amount_due = $amount_over_due;
                                    $emi_update->due_date = $emi_schedule['due_date'];

                                    $emi_update->application_id = $application->id;
                                    $emi_update->delay_days = $emi_charges['delay_days'];
                                    $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                                    $emi_update->save();
                                } else {
                                    if(!$rps_exist) {
                                        $emi_update = new EmiPayment();
                                        $emi_update->emi_date = $emi_date;
                                        $emi_update->emi_amount = $emi_schedule['amount'];
                                        $emi_update->bounce_charges = $emi_charges['bounce_charges'];
                                        $emi_update->charges_waived = 0;
                                        $emi_update->delay_penalty = $emi_charges['penal_interest'];
                                        $emi_update->total_payable = $total_payable;
                                        $emi_update->amount_due = $amount_over_due;
                                        $emi_update->due_date = $emi_schedule['due_date'];

                                        $emi_update->application_id = $application->id;
                                        $emi_update->delay_days = $emi_charges['delay_days'];
                                        $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                                        $emi_update->save();
                                    }
                                }
                            }
                            if (isset($emi_update) && $emi_update->payment_status == "success") {
                                $emi_paid = $emi_paid + 1;
                            } else {
                                $emi_pending = $emi_pending + 1;
                            }
                            $emi_schedules[$emi_date]['status'] = 'Done';
                        }
                    }
                    if ($application->application_element) {
                        $application_element = ConsumerApplicationElement::find($application->application_element->id);
                    } else {
                        $application_element = new ConsumerApplicationElement();
                        $application_element->application_id = $application->id;
                    }

//                $amount_due_sum = EmiPayment::where('application_id', $application_id)->sum('total_payable');
//                $amount_received_sum = PaymentTransaction::where('application_id', $application_id)->whereIn('payment_for', ['EMI', 'Foreclosure'])->whereNull('deleted_at')->whereNull('deleted_by')->sum('amount');
//                $repayment_balance = $amount_due_sum - $amount_received_sum;

                    if (($foreclosure_date != '' && isset($foreclosure_amount->amount)) || isset($writeOff_amount->id)) {
                        $total_principal_due = $total_over_due = $outstanding_principal_due = $outstanding_over_due = 0;

//                    $calculated_foreclosure_amount = (new AccountingController())->getForeclosureAmount($application_id);
//                    $received_foreclosure_amount = $foreclosure_amount->amount;
//                    if($calculated_foreclosure_amount == $received_foreclosure_amount){
//                        $total_over_due = $total_principal_due = $outstanding_principal_due = $outstanding_over_due = 0;
//                    }
                    }

                    $application_element->principal_due = $total_principal_due;
                    $application_element->amount_over_due = $total_over_due;
                    $application_element->total_principal_due = $outstanding_principal_due;
                    $application_element->total_amount_due = $outstanding_over_due;
                    $application_element->last_emi_date = date('Y-m-d', strtotime($last_emi_date));
                    $application_element->emi_paid = $emi_paid;
                    $application_element->emi_pending = $emi_pending;
                    $application_element->save();
                    (new RepaymentController())->callPaymentUpdateApis($application->id);
                }
            }
        }
        $this->autoWaiveOff($id);
        return $applications;

    }

    public function paymentCalculateV2($id = 0, $payment_date = '',$case_type = 'disbursed', $isMoratorium = false){

        $payment_date_original = $payment_date;
        if($payment_date == ''){
            $payment_date = date('Y-m-d');
        }
        if($this->isCron){
            $application_id = $id;
        }else{
            $application_id = idStringtoArray($id);
        }

        $applications = ConsumerApplication::with('merchant','centers','emi','proFormaInvoice','emi_payment.transaction','application_element','moratoriums');
        if($application_id){
            $applications = $applications->whereIn('id',$application_id);
        }elseif($case_type == 'disbursed'){
            $applications = $applications->whereIn('state',$this->status);
        }
        $applications = $applications->whereNull('is_deleted')->get();




        foreach ($applications as $application) {

            (new ConsumerApplicationController())->updateProcessFeesPayment($application->id);
            (new ConsumerApplicationController())->updateLegalChargesPayment($application->id);

            if (!($application->emi) || $application->emi->emi < 1) {
//                (new Slack(new Request(['title' => 'Payment Calculate', 'fields' => ['ID' => $application->id]])))->send();
            } else {
                if ((isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01")) {
                    $foreclosure_date = $application->application_element->foreclosure_date;
                } else {
                    $foreclosure_date = "";
                }

                $foreclosure_amount = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'Foreclosure')->whereNull('is_deleted_at')->whereNull('deleted_by')->first();
                $writeOff_amount = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'Write-off')->whereNull('is_deleted_at')->whereNull('deleted_by')->first();

                $emi_schedules = $this->generateDues($application->id, 0, $application);
                $emi_dates = array();
                foreach ($emi_schedules as $emi_date => $emis) {
                    array_push($emi_dates, $emi_date);
                }
                $this->updateMoratoriumAmount($emi_schedules);
                $outstanding_over_due = 0;
                $outstanding_principal_due = 0;
                $total_principal_due = 0;
                $total_over_due = 0;
                $last_emi_date = '';
                $emi_paid = 0;
                $emi_pending = 0;
                foreach ($application->emi_payment as $emi_payment) {
                    if ($foreclosure_date == '' || $foreclosure_date >= $emi_payment->emi_date) {
                        if (in_array($emi_payment->emi_date, $emi_dates)) {
                            $emi_date = $emi_payment->emi_date;
                            $last_emi_date = $emi_date;
                            if ($emi_payment->payment_status != "success") {
                                $emi_charges = $this->getBounceCharges($emi_payment->emi_amount, $emi_payment->due_date, $emi_date, $emi_payment->transaction, $payment_date_original, 0, $emi_payment->application_id);
                                $total_payable = (($emi_payment->emi_amount) + $emi_charges['bounce_charges'] + $emi_charges['penal_interest']) - $emi_payment->charges_waived;
                                $amount_due = $emi_payment->emi_amount - $emi_charges['amount_received'];
                                $amount_over_due = $total_payable - $emi_charges['amount_received'];
                                $outstanding_principal_due = $outstanding_principal_due + $amount_due;
                                $outstanding_over_due = $outstanding_over_due + $amount_over_due;
                                if ($emi_date < date('Y-m-d')) {
                                    $total_principal_due = $total_principal_due + $amount_due;
                                    $total_over_due = $total_over_due + $amount_over_due;
                                }
                                $emi_update = EmiPaymentTemp::find($emi_payment->id);
                                if ($emi_update) {
                                    $emi_update->bounce_charges = $emi_charges['bounce_charges'];
                                    $emi_update->delay_penalty = $emi_charges['penal_interest'];
                                    $emi_update->total_payable = $total_payable;
                                    $emi_update->amount_due = $amount_over_due;
                                    $emi_update->due_date = $emi_schedules[$emi_payment->emi_date]['due_date'];

                                    $emi_update->delay_days = $emi_charges['delay_days'];
                                    if ($emi_payment->payment_status == 'success' || $emi_payment->payment_status == 'pending' || $emi_payment->payment_status == 'partial' || $emi_payment->payment_status == 'rejected') {
                                        $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                                    }

                                    if(($application->moratoriums && count($application->moratoriums) && $emi_schedules[$emi_payment->emi_date]['amount'] != $emi_payment->emi_amount) || $isMoratorium){
                                        $emi_update->emi_amount = $emi_schedules[$emi_payment->emi_date]['amount'];
                                    }
                                    $emi_update->save();
                                }
                                $emi_pending = $emi_pending + 1;
                            } else {
                                $emi_charges = $this->getBounceCharges($emi_payment->emi_amount, $emi_payment->due_date, $emi_date, $emi_payment->transaction, $payment_date_original, 0, $emi_payment->application_id);
                                $total_payable = (($emi_payment->emi_amount) + $emi_payment->bounce_charges + $emi_payment->delay_penalty) - $emi_payment->charges_waived;
                                $amount_over_due = $total_payable - $emi_charges['amount_received'];
                                $emi_paid = $emi_paid + 1;
                                //if ($emi_payment->amount_due > 0) {
                                $emi_update = EmiPaymentTemp::find($emi_payment->id);
                                $emi_update->total_payable = $total_payable;
                                $emi_update->amount_due = 0;
                                if ($amount_over_due > 0) {
                                    $emi_update->amount_due = $amount_over_due;
                                    $emi_update->delay_days = $emi_charges['delay_days'];
                                    $emi_update->due_date = $emi_schedules[$emi_payment->emi_date]['due_date'];
                                    if ($emi_payment->payment_status == 'success' || $emi_payment->payment_status == 'pending' || $emi_payment->payment_status == 'partial' || $emi_payment->payment_status == 'rejected') {
                                        $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                                    }
                                }
                                if(($application->moratoriums && count($application->moratoriums) && $emi_schedules[$emi_payment->emi_date]['amount'] != $emi_payment->emi_amount) || $isMoratorium){
                                    $emi_update->emi_amount = $emi_schedules[$emi_payment->emi_date]['amount'];
                                }
                                $emi_update->save();
                                //}
                            }
                            $emi_schedules[$emi_date]['status'] = 'Done';
                        }else if(($emi_payment->payment_status == "pending" && $application->moratorium && isset($application->moratorium->id)) || $isMoratorium){
                            $isMoratoriumExist = Moratorium::withTrashed()->where('application_id', $application->id)->first(['id']);
                            if(isset($isMoratoriumExist->id)) {
                                try {
                                    EmiPaymentTemp::find($emi_payment->id)->delete();
                                }catch (\Exception $exception){

                                }
                            }
                        }
                    }
                }

                $emisArray1 = [];
                foreach ($emi_schedules as $emi_date => $emi_schedule) {
                    $last_emi_date = $emi_date;

                    if ($emi_schedule['status'] == 'pending' && ($foreclosure_date == '' || $foreclosure_date >= $emi_date)) {
                        $emi_charges = $this->getBounceCharges($emi_schedule['amount'], $emi_schedule['due_date'], $emi_date, array(), $payment_date, 0, $emi_schedule['id']);
                        $total_payable = ($emi_schedule['amount']) + $emi_charges['bounce_charges'] + $emi_charges['penal_interest'];
                        $amount_due = ($emi_schedule['amount'] - $emi_charges['amount_received']);
                        $amount_over_due = ($total_payable - $emi_charges['amount_received']);
                        $outstanding_principal_due = $outstanding_principal_due + $amount_due;
                        $outstanding_over_due = $outstanding_over_due + $amount_over_due;
                        if ($emi_date < date('Y-m-d')) {
                            $total_principal_due = $total_principal_due + $amount_due;
                            $total_over_due = $total_over_due + $amount_over_due;
                        }

                        if(!in_array($emi_date, $emisArray1)) {
                            $emisArray1[] = $emi_date;
                            $emiPayment = EmiPaymentTemp::where('application_id', $application->id)->where('emi_date', $emi_date)->first(['id']);

                            if (isset($emiPayment->id)) {
                                $emi_update = EmiPaymentTemp::find($emiPayment->id);
                            } else {
                                $emi_update = new EmiPaymentTemp();
                            }
                            $emi_update->emi_date = $emi_date;
                            $emi_update->emi_amount = $emi_schedule['amount'];
                            $emi_update->bounce_charges = $emi_charges['bounce_charges'];
                            $emi_update->charges_waived = 0;
                            $emi_update->delay_penalty = $emi_charges['penal_interest'];
                            $emi_update->total_payable = $total_payable;
                            $emi_update->amount_due = $amount_over_due;
                            $emi_update->due_date = $emi_schedule['due_date'];

                            $emi_update->application_id = $application->id;
                            $emi_update->delay_days = $emi_charges['delay_days'];
                            $emi_update->payment_status = ($amount_over_due == 0) ? 'success' : (($amount_over_due > 0 && $emi_charges['amount_received'] > 0) ? "partial" : "pending");
                            $emi_update->save();
                        }
                        if ($emi_update->payment_status == "success") {
                            $emi_paid = $emi_paid + 1;
                        } else {
                            $emi_pending = $emi_pending + 1;
                        }
                        $emi_schedules[$emi_date]['status'] = 'Done';
                    }
                }
                if ($application->application_element) {
                    $application_element = ConsumerApplicationElement::find($application->application_element->id);
                } else {
                    $application_element = new ConsumerApplicationElement();
                    $application_element->application_id = $application->id;
                }

//                $amount_due_sum = EmiPayment::where('application_id', $application_id)->sum('total_payable');
//                $amount_received_sum = PaymentTransaction::where('application_id', $application_id)->whereIn('payment_for', ['EMI', 'Foreclosure'])->whereNull('deleted_at')->whereNull('deleted_by')->sum('amount');
//                $repayment_balance = $amount_due_sum - $amount_received_sum;

                if(($foreclosure_date != '' && isset($foreclosure_amount->amount)) || isset($writeOff_amount->id)){
                    $total_principal_due = $total_over_due = $outstanding_principal_due = $outstanding_over_due = 0;

//                    $calculated_foreclosure_amount = (new AccountingController())->getForeclosureAmount($application_id);
//                    $received_foreclosure_amount = $foreclosure_amount->amount;
//                    if($calculated_foreclosure_amount == $received_foreclosure_amount){
//                        $total_over_due = $total_principal_due = $outstanding_principal_due = $outstanding_over_due = 0;
//                    }
                }

                $application_element->principal_due = $total_principal_due;
                $application_element->amount_over_due = $total_over_due;
                $application_element->total_principal_due = $outstanding_principal_due;
                $application_element->total_amount_due = $outstanding_over_due;
                $application_element->last_emi_date = date('Y-m-d', strtotime($last_emi_date));
                $application_element->emi_paid = $emi_paid;
                $application_element->emi_pending = $emi_pending;
                $application_element->save();
            }
        }
        $this->autoWaiveOff($id);
        return $applications;

    }

    public function updateMoratoriumAmount($data){
        foreach ($data as $item) {
            if($item['moratorium_amount']) {
                EmiPayment::where('application_id', $item['id'])->where('emi_date',$item['emi_date'])->update(['moratorium_amount' => $item['moratorium_amount']]);
            }else{
                //EmiPayment::where('application_id', $item['id'])->where('emi_date',$item['emi_date'])->update(['moratorium_amount' => 0]);
            }
        }
    }

    public function generateDues($id,$isforclosured = 0,$user){
        $i = 0;
        $emiCalculation = new \App\Http\Controllers\Admin\EMICalculation(new Request());
        $payload = [];
        $moratorium_amount = 0;
        if($user->emi) {
            $dues = $emiCalculation->getRepaymentSchedule($user, false);
            $emi_date = "";
            $moratoriumPeriod = false;
            if (isset($dues->emis)) {
                foreach ($dues->emis as $index => $emi_amount) {
                    /*if($id == 4848){
                        if($emi_date == ''){
                            $emi_date =date('Y-m-d', strtotime($user->emi->emi_date)) ;
                        }else {
                            if (date('d', strtotime($emi_date)) == 5 || date('d', strtotime($emi_date)) == '05') {
                                $emi_date = date('Y-m-18', strtotime($emi_date));
                            } else {
                                $emi_date = date('Y-m-05', strtotime($emi_date . ' +1 month'));
                            }
                        }
                    }else {
                        $emi_date = $emiCalculation->getEMIDateByPaymentFrequency($user,$i);
                    }*/
                    $emi_date = $emiCalculation->getEMIDateByPaymentFrequency($user,$i);


                    /*if(isset($user->moratoriums) && count($user->moratoriums)) {
                        foreach ($user->moratoriums as $moratoriumIndex => $moratoriumItem) {
                            if ((isset($moratoriumItem->id) && $moratoriumItem->emi_date <= $emi_date) || $moratoriumPeriod) { # <= because we want to increase next emi date to 1 month

                                $emi_date = Carbon::createFromFormat('Y-m-d', $emi_date)->addMonth(1)->toDateString();

                                if ($moratoriumItem->emi_date == Carbon::createFromFormat('Y-m-d', $emi_date)->subMonth(1)->toDateString()) { //!$moratoriumPeriod
                                    $emi_amount += (new Moratorium())->getPrincipalOutstanding($user, $moratoriumItem);
                                    break;
                                }

                                $moratoriumPeriod = true;
                            }
                        }
                    }*/

                    if(isset($user->application_element->foreclosure_date) && !empty($user->application_element->foreclosure_date) && $user->application_element->foreclosure_date != "1970-01-01" && date('Y-m-d', strtotime($emi_date)) > ($user->application_element->foreclosure_date ) && $isforclosured != 1){
                        break;
                    }else {
                        $due_date = Carbon::createFromFormat('Y-m-d', $emi_date)->subDay(0);
                        $holidays = $this->holiday_list;
                        while(in_array($due_date,$holidays) || $due_date->isSunday()){
                            $due_date = Carbon::createFromFormat('Y-m-d', $due_date->toDateString())->addDay(1);
                        }

                        $payload[$emi_date] = ['id' => $id, 'offer_id' => $user->emi->offer_id, 'emi_id' => $user->emi->id, 'emi_date' => $emi_date, 'amount' => $emi_amount, 'moratorium_amount' => $moratorium_amount, 'due_date' => $due_date->toDateString(),'status'=> 'pending'];
                    }
                    $i++;
                }
            }
        }
        $this->internal = true;
        return $this->applyMoratorium($user, $payload);
    }

    public function getPaymentConfig($id){
        $paymentConfig = Config::get('constants.payment');
        $applicationLender = ConsumerApplication::where('id', $id)->first(['lender_id']);

        return isset($paymentConfig['bounce'][$applicationLender->lender_id]) && isset($paymentConfig['penal'][$applicationLender->lender_id]) ? [
            'bounce' => $paymentConfig['bounce'][$applicationLender->lender_id],
            'penal' => $paymentConfig['penal'][$applicationLender->lender_id]
        ] : $paymentConfig['default'];

    }

    public function applyMoratorium($user, $payload, $isMoratorium = false){

        $payloadPreserve = $payload;
        usort($payload, function($a, $b){
            return strtotime($a['emi_date']) - strtotime($b['emi_date']);
        });

        $EMIsIndex = [];
        if(isset($user->moratoriums) && count($user->moratoriums)) {
            foreach ($user->moratoriums as $moratoriumItem) {

                foreach ($payload as $index => $data) {
                    $emi_date = $data['emi_date'];
                    if (isset($moratoriumItem->id) && $moratoriumItem->emi_date <= $emi_date) {
                        $emi_date = Carbon::createFromFormat('Y-m-d', $emi_date)->addMonth(1)->toDateString();
                        $payload[$index]['emi_date'] = $emi_date;
                        $payload[$index]['due_date'] = $emi_date;

                        if ($moratoriumItem->emi_date == Carbon::createFromFormat('Y-m-d', $emi_date)->subMonth(1)->toDateString() && !$isMoratorium) { //!$moratoriumPeriod
                            $moratoriumAmount = (new Moratorium())->getPrincipalOutstanding($user, $moratoriumItem);

                            if (isset($EMIsIndex[$index])){
                                $payload[$index]['amount'] -= $EMIsIndex[$index];
                            }

                            $payload[$index]['amount'] += $moratoriumAmount;
                            $payload[$index]['moratorium_amount'] = $moratoriumAmount;
                            $EMIsIndex[$index] = $moratoriumAmount;
                        }
                    }
                }
            }
        }else{
            return $payloadPreserve;
        }


        $newPayload = [];
        foreach ($payload as $index => $data){
            $due_date = Carbon::createFromFormat('Y-m-d', $data['emi_date'])->subDay(0);
            $holidays = $this->holiday_list;
            while(in_array($due_date,$holidays) || $due_date->isSunday()){
                $due_date = Carbon::createFromFormat('Y-m-d', $due_date->toDateString())->addDay(1);
            }

            $payload[$index]['due_date'] = $due_date->toDateString();
            $data['due_date'] = $payload[$index]['due_date'];

            if($this->internal){
                $newPayload[$data['emi_date']] = $data;
            }else{
                $newPayload[] = $data;
            }
        }

        return $newPayload;
    }

    public function getBounceChargesV1($emi_amount,$emi_date,$transactions = array(),$payment_date = "",$payment_amount = 0, $application_id = 0){
        $payment_date_original = $payment_date;
        if($payment_date == ""){
            $payment_date = date('Y-m-d');
        }

        $paymentConfig = $this->getPaymentConfig($application_id);

        $payment_amount = (int)$payment_amount;
        $holidays = $this->holiday_list;
        $due_date = Carbon::createFromFormat('Y-m-d', $emi_date)->subDay(0);
        $response['bounce_charges'] = 0;
        $response['penal_interest'] = 0;
        $response['delay_days'] = 0;
        $response['generate_interest_invoice'] = 0;
        $after_due = 0;
        $before_due = 0;
        while(in_array($due_date->toDateString(),$holidays) || $due_date->isSunday()){
            $due_date = Carbon::createFromFormat('Y-m-d', $due_date->toDateString())->addDay(1);
        }
        $due_date_innitial = $due_date->toDateString();
        $delay_days = $this->calculateDelayDays($due_date->toDateString(),$payment_date, $application_id);
        $due_date_string = $due_date->toDateString();
        $delay_days_penalty = Carbon::createFromFormat('Y-m-d', $due_date_string)->addDay(1);
        $amount_paid = 0;
        if($transactions){
            foreach ($transactions as $transaction){
                if($transaction->refunded_at == null) {
                    if (($amount_paid + $transaction->amount) <= $emi_amount) {
                        if (strtotime($transaction->payment_date) > $due_date->timestamp) {
                            $after_due = $after_due + $transaction->amount;
                        } else {
                            $before_due = $before_due + $transaction->amount;
                        }

                        if (strtotime($transaction->payment_date) > ($delay_days_penalty->timestamp)) {
                            $delay_days = ($this->calculateDelayDays($delay_days_penalty->toDateString(), $transaction->payment_date, $application_id));
                            $response['penal_interest'] = $response['penal_interest'] + (($transaction->amount * (($paymentConfig['penal'])) / 100) * ($delay_days));
                            if ($response['delay_days'] < $delay_days) {
                                $response['delay_days'] = $delay_days;
                            }
                        }
                        $amount_paid = $amount_paid + $transaction->amount;
                    } else {
                        //$transactionamount = $emi_amount - $amount_paid;
                        //$amount_paid = $amount_paid + $transactionamount;
                        /*if (strtotime($transaction->payment_date) > $due_date->timestamp) {
                            $after_due = $after_due + $transactionamount;
                        } else {
                            $before_due = $before_due + $transactionamount;
                        }
                        $amount_paid = $amount_paid + $transaction->amount;*/

//                        if ($transactionamount > 0 && (strtotime($transaction->payment_date) > ($due_date->addDay(1)->timestamp))) {
//                            $delay_days = (($this->calculateDelayDays($due_date->toDateString(), $transaction->payment_date)) - 1);
//
//                            $response['penal_interest'] = $response['penal_interest'] + (($transactionamount * (($paymentConfig['penal'])) / 100) * ($delay_days));
//                            if ($response['delay_days'] < $delay_days) {
//                                $response['delay_days'] = $delay_days;
//                            }
//                        }
                    }
                }
            }

            if($amount_paid < $emi_amount){
                if(($amount_paid + $payment_amount) <= $emi_amount){
                    $delay_days = (($this->calculateDelayDays($due_date->toDateString(),$payment_date, $application_id)));
                    $response['penal_interest'] = $response['penal_interest'] + (($payment_amount * (($paymentConfig['penal']))/100) * ($delay_days));
                    if($response['delay_days'] < $delay_days)
                    {
                        $response['delay_days'] = $delay_days;
                    }
                    $amount_paid = $payment_amount + $amount_paid;
                    if($amount_paid < $emi_amount) {
                        $delay_days = (($this->calculateDelayDays($due_date->toDateString(), (date('Y-m-d')), $application_id)));

                        $pending_amount = $emi_amount - $amount_paid;
                        $response['penal_interest'] = $response['penal_interest'] + ((($pending_amount) * ((($paymentConfig['penal']))/100)) * ($delay_days));
                        if($response['delay_days'] < $delay_days)
                        {
                            $response['delay_days'] = $delay_days;
                        }
                    }
                }else{
                    /*$delay_days = (($this->calculateDelayDays($due_date->toDateString(), $payment_date)) - 1);

                    $response['penal_interest'] = $response['penal_interest'] + ((($emi_amount - $amount_paid) * (($paymentConfig['penal']))/100) * ($delay_days));
                    if($response['delay_days'] < $delay_days)
                    {
                        $response['delay_days'] = $delay_days;
                    }*/

                }
            }

            if($payment_date != "" && $payment_date < $due_date_innitial && $payment_amount > 0){
                $before_due = $before_due + $payment_amount ;
            }

            if($emi_amount <= ($before_due + $after_due)){
                $response['generate_interest_invoice'] = 1;

            }
            if(($emi_amount && (($before_due/$emi_amount)*100) >= 90) || ($due_date_innitial >= $payment_date && ($emi_amount && ($after_due/$emi_amount)*100) < 10 )){
                $response['bounce_charges'] = 0;
            }else{
                $response['bounce_charges'] = $paymentConfig['bounce'];
            }
        }else{
            if($delay_days > 0){
                if(($due_date->toDateString() < date('Y-m-d'))) {
                    $response['bounce_charges'] = $paymentConfig['bounce'];
                }
                if($response['delay_days'] < ($delay_days-1))
                {
                    $response['delay_days'] = ($delay_days-1);
                }
                if($delay_days > 1) {
                    $response['penal_interest'] = ($emi_amount * (($paymentConfig['penal']))/100) * ($delay_days - 1);
                }
            }
        }

        if($response['penal_interest'] < 0){
            $response['penal_interest'] = 0;
        }else{
            $response['penal_interest'] = round($response['penal_interest'],0);
        }
        if($response['delay_days'] < 0){
            $response['delay_days'] = 0;
        }
//        if($emi_payments && !empty($emi_payments->rejected_date) &&  $emi_payments->rejected_date != null){
//            $response['bounce_charges'] = $paymentConfig['bounce'];
//        }
        if($response['bounce_charges'] < 0){
            $response['bounce_charges'] = 0;
        }
        $response['amount_received'] = $amount_paid;
        return(array) $response;
    }

    public function getBounceCharges($emi_amount,$_due_date,$emi_date,$transactions = array(),$payment_date = "",$payment_amount = 0, $application_id = 0){
        $payment_date_original = $payment_date;

        $paymentConfig = $this->getPaymentConfig($application_id);

        if($application_id) {
            $EmiPayment = EmiPayment::where('application_id', $application_id)->where('emi_date', $emi_date)->first(['id','moratorium_amount']);
            if(isset($EmiPayment->id) && $EmiPayment->moratorium_amount) {
                $emi_amount -= $EmiPayment->moratorium_amount;
            }
        }
        if($payment_date == ""){
            $payment_date = date('Y-m-d');
        }

        $payment_amount = (int)$payment_amount;
        $holidays = $this->holiday_list;
        $due_date = Carbon::createFromFormat('Y-m-d', $emi_date)->subDay(0);
        $response['bounce_charges'] = 0;
        $response['penal_interest'] = 0;
        $response['delay_days'] = 0;
        $response['generate_interest_invoice'] = 0;
        $after_due = 0;
        $before_due = 0;
        while(in_array($due_date->toDateString(),$holidays) || $due_date->isSunday()){
            $due_date = Carbon::createFromFormat('Y-m-d', $due_date->toDateString())->addDay(1);
        }
        $due_date_innitial = $due_date->toDateString();
        $delay_days = $this->calculateDelayDays($due_date->toDateString(),$payment_date, $application_id);
        $due_date_string = $due_date->toDateString();
        //$delay_days_penalty = Carbon::createFromFormat('Y-m-d', $due_date_string)->addDay(1);
        $delay_days_penalty = Carbon::createFromFormat('Y-m-d', $_due_date);
        $amount_paid = 0;
        if($transactions){
            foreach ($transactions as $transaction){
                if($transaction->refunded_at == null) {
                    if (($amount_paid + $transaction->amount) <= $emi_amount) {
                        if (strtotime($transaction->payment_date) > $due_date->timestamp) {
                            $after_due = $after_due + $transaction->amount;
                        } else {
                            $before_due = $before_due + $transaction->amount;
                        }

                        if (strtotime($transaction->payment_date) > ($delay_days_penalty->timestamp)) {
                            $delay_days = ($this->calculateDelayDays($delay_days_penalty->toDateString(), $transaction->payment_date, $application_id));
                            $response['penal_interest'] = $response['penal_interest'] + (($transaction->amount * (($paymentConfig['penal'])) / 100) * ($delay_days));
                            if ($response['delay_days'] < $delay_days) {
                                $response['delay_days'] = $delay_days;
                            }
                        }
                        $amount_paid = $amount_paid + $transaction->amount;
                    } else {
                        $transactionamount = $emi_amount - $amount_paid;
                        //$amount_paid = $amount_paid + $transactionamount;
                        if (strtotime($transaction->payment_date) > $due_date->timestamp) {
                            $after_due = $after_due + $transactionamount;
                        } else {
                            $before_due = $before_due + $transactionamount;
                        }
                        $amount_paid = $amount_paid + $transaction->amount;

//                        if ($transactionamount > 0 && (strtotime($transaction->payment_date) > ($due_date->addDay(1)->timestamp))) {
//                            $delay_days = (($this->calculateDelayDays($due_date->toDateString(), $transaction->payment_date)) - 1);
//
//                            $response['penal_interest'] = $response['penal_interest'] + (($transactionamount * (($paymentConfig['penal'])) / 100) * ($delay_days));
//                            if ($response['delay_days'] < $delay_days) {
//                                $response['delay_days'] = $delay_days;
//                            }
//                        }
                    }
                }
            }

            if($amount_paid < $emi_amount){
                if(($amount_paid + $payment_amount) <= $emi_amount){
                    $delay_days = (($this->calculateDelayDays($due_date->toDateString(),$payment_date, $application_id)));
                    $response['penal_interest'] = $response['penal_interest'] + (($payment_amount * (($paymentConfig['penal']))/100) * ($delay_days));
                    if($response['delay_days'] < $delay_days)
                    {
                        $response['delay_days'] = $delay_days;
                    }
                    $amount_paid = $payment_amount + $amount_paid;
                    if($amount_paid < $emi_amount) {
                        $delay_days = (($this->calculateDelayDays($due_date->toDateString(), (date('Y-m-d')), $application_id)));

                        $pending_amount = $emi_amount - $amount_paid;
                        $response['penal_interest'] = $response['penal_interest'] + ((($pending_amount) * ((($paymentConfig['penal']))/100)) * ($delay_days));
                        if($response['delay_days'] < $delay_days)
                        {
                            $response['delay_days'] = $delay_days;
                        }
                    }
                }else{
                    $delay_days = (($this->calculateDelayDays($due_date->toDateString(), $payment_date, $application_id)));

                    $response['penal_interest'] = $response['penal_interest'] + ((($emi_amount - $amount_paid) * (($paymentConfig['penal']))/100) * ($delay_days));
                    if($response['delay_days'] < $delay_days)
                    {
                        $response['delay_days'] = $delay_days;
                    }

                }
            }

            if($payment_date != "" && $payment_date < $due_date_innitial && $payment_amount > 0){
                $before_due = $before_due + $payment_amount ;
            }

            if($emi_amount <= ($before_due + $after_due)){
                $response['generate_interest_invoice'] = 1;

            }
            if(($emi_amount && (($before_due/$emi_amount)*100) >= 90) || ($due_date_innitial >= date('Y-m-d', strtotime($payment_date)) && ($emi_amount && ($after_due/$emi_amount)*100) < 10 )){
                $response['bounce_charges'] = 0;
            }else{
                $response['bounce_charges'] = $paymentConfig['bounce'];
            }
        }else{
            if($delay_days > 0){
                if(($due_date->toDateString() < date('Y-m-d'))) {
                    $response['bounce_charges'] = $paymentConfig['bounce'];
                }
                if($response['delay_days'] < ($delay_days-1))
                {
                    $response['delay_days'] = ($delay_days-1);
                }
                if($delay_days > 1) {
                    $response['penal_interest'] = ($emi_amount * (($paymentConfig['penal']))/100) * ($delay_days - 1);
                }
            }
        }

        if($response['penal_interest'] < 0){
            $response['penal_interest'] = 0;
        }else{
            $response['penal_interest'] = round($response['penal_interest'],0);
        }
        if($response['delay_days'] < 0){
            $response['delay_days'] = 0;
        }
//        if($emi_payments && !empty($emi_payments->rejected_date) &&  $emi_payments->rejected_date != null){
//            $response['bounce_charges'] = $paymentConfig['bounce'];
//        }
        if($response['bounce_charges'] < 0){
            $response['bounce_charges'] = 0;
        }
        $response['amount_received'] = $amount_paid;
        return(array) $response;
    }

    public function calculateDelayDays($due_date,$payment_date, $application_id = 0){
        if($payment_date == date('Y-m-d') && $application_id){
            $moratorium = Moratorium::where('application_id', $application_id)->where('emi_date','>=', $due_date)->orderBy('created_at','asc')->first(['id','emi_date']);
            if (isset($moratorium->id)){
                $payment_date = date('Y-m-d', strtotime('-1 day', strtotime($moratorium->emi_date)));
            }
        }
        $now = strtotime($payment_date); // or your date as well
        $your_date = strtotime($due_date);
        $datediff = $now - $your_date;

        return round($datediff / (60 * 60 * 24),0);
    }

    public function getPaymentDueHistory($application_id = 0,$last_date = "",$all_status = 1,$isDue = 0,$isclosedLoans = 0,$application_id_array= array(),$last_emi_date_crossed = 0, $total_amount_due = 0){
//        if($last_date == ""){
//            $last_date =  date('Y-m-d');
//        }
        $response = array();
        $status =  ['disbursed','nach registered'];
        $settlements = $this->includeSettlements;
        $consumerApplication = ConsumerApplication::with('proFormaInvoice','merchant','lender','lender.bank_details',
            'application_element.collection_executive','emi_payment.transaction','emi_payment.moratoriums', 'writeoff_transaction', 'settlement_payment',
            'checkmandate','emi_payment.transaction.refunded_user_by','emi');
        $consumerApplication = $consumerApplication->whereNull('is_deleted')->orderBy('updated_at', 'desc');
        $consumerApplication = $consumerApplication->whereDoesntHave('followUpHistory', function ($q) {
            $q->where('follow_up_status', 'stopped')
                ->whereIn('id', function ($sub) {
                    $sub->selectRaw('max(id)')
                        ->from('consumer_application_follow_ups')
                        ->whereNull('deleted_at')
                        ->groupBy('application_id');
                });
        });
        if($all_status == 0) {
            $consumerApplication = $consumerApplication->wherein('state', $status);
        }
        if($application_id != 0 && $application_id != null) {
            $consumerApplication = $consumerApplication->where('id', $application_id);
        }
        if(is_array($application_id_array) && $application_id_array != 0 && count($application_id_array) > 0){
            $consumerApplication = $consumerApplication->wherein('id', $application_id_array);
        }

        if(($application_id == 0 || $application_id = null) && (!is_array($application_id_array) || $application_id_array == 0 || (is_array($application_id_array) && count($application_id_array) == 0)) && $all_status == 0){
            $consumerApplication = $consumerApplication->wherein('state', $status);
        }

        if($this->lender_id_req){
            $consumerApplication = $consumerApplication->where('lender_id', $this->lender_id_req);
        }

        if($this->emi_date_req){
            $consumerApplication = $consumerApplication->whereHas('emi_payment', function ($query) {
                $query->where('emi_date', $this->emi_date_req);
            });
        }

        if($this->excludeWriteoff){
            $consumerApplication = $consumerApplication->doesntHave('writeoff_transaction');
        }
        if($isDue == 1){
            $consumerApplication = $consumerApplication->whereHas('application_element', function ($query) {
                $query->where('amount_over_due','>',0);
            });
            if ($this->includeSettlements) {
                $consumerApplication = $consumerApplication->orWhere(function ($query) {
                    $query->whereHas('settlement_payment', function ($q) {
                        $q->where('id', '>', 0);
                    })->whereIn('state', ['disbursed', 'nach registered']);
                });
            }
        }
        if($total_amount_due){
            $consumerApplication = $consumerApplication->whereHas('application_element', function ($query) {
                $query->where('total_amount_due', 0);
            });
            if ($this->includeSettlements) {
                $consumerApplication = $consumerApplication->orWhere(function ($query) {
                    $query->whereHas('settlement_payment', function ($q) {
                        $q->where('id', '>', 0);
                    })->whereIn('state', ['disbursed', 'nach registered']);
                });
            }
        }
        if($isclosedLoans == 1){
            $consumerApplication = $consumerApplication->whereHas('application_element', function ($query) use($isDue) {
            $query->where('total_amount_due','<=',100)
                ->orwhere('last_emi_date','<=',date('Y-m-d'))
                ->orwhere('emi_pending',0);
            });
            if ($this->includeSettlements) {
                $consumerApplication = $consumerApplication->orWhere(function ($query) {
                    $query->whereHas('settlement_payment', function ($q) {
                        $q->where('id', '>', 0);
                    })->whereIn('state', ['disbursed', 'nach registered']);
                });
            }
            $consumerApplication = $consumerApplication->where('state','!=', 'closed');
        }
        if($last_emi_date_crossed == 1){
            /*$consumerApplication = $consumerApplication->whereHas('application_element', function ($query) use($isDue) {
                $query->where('last_emi_date','<=',date('Y-m-d'));
            });*/
        }

        if($this->isPagination) {
            $consumerApplication = $consumerApplication->whereNotIn('state',$this->status)->skip($this->isPaginationSkip)->paginate($this->isPagination);
            $this->isPaginationTotal = $consumerApplication->total();
            $this->isPaginationLastPage = $consumerApplication->lastPage();
        }else{
            $consumerApplication = $consumerApplication->get();
        }

        foreach ($consumerApplication as $application){

            $amount_paid = 0;
            $amount_payable = 0;
            $max_payable = $application->application_element->amount_over_due;
            if($application->emi_payment){
                $i = 0;
                foreach ($application->emi_payment as $emi_payments){
                    $amount_paid = $amount_paid + ($emi_payments->total_payable - $emi_payments->amount_due);
                    $check_date = date('Y-m-d',strtotime("+11 days",time()));
                    if($check_date >= $emi_payments->emi_date && $emi_payments->emi_date > date('Y-m-d') && $emi_payments->payment_status != 'success') {
                        if($emi_payments->payment_status == 'pending') {
                            $max_payable = $max_payable + $emi_payments->emi_amount;
                        }else{
                            $max_payable = $max_payable + $emi_payments->amount_due;
                        }
                    }

                    $application->emi_payment[$i]->pending_amount = $emi_payments->amount_due;
                    $i++;
                }
                $overpayments = PaymentTransaction::where('application_id',$application->id)->whereIn('payment_for',['processing_fee','Over Payment','Advance Payment','rejected','Foreclosure','refund','collection_charges','insurance_fee','adhoc_transaction','advance_amount','EMI', 'Pre-EMI', 'settled_principal', 'settled_interest', 'settled_bounce', 'settled_penal'])->whereNull('is_deleted_at')->get();
                $over_payment = 0;
                $adhoc_payment = 0;
                $processing_fee = 0;
                $insurance_fee = 0;
                $advance_amount = 0;
                $last_payment_date = null;
                $last_payment_amount = 0;
                $isForeclosed = 0;
                $pre_emi = 0;
                if($overpayments) {
                    foreach ($overpayments as $overpayment) {
                        if($overpayment->payment_for == "EMI"){
                            $last_payment_date = $overpayment->payment_date;
                            $last_payment_amount = $overpayment->amount;
                        }
                        if ($overpayment->amount > 0 && ($overpayment->payment_for == "Over Payment" ) && $overpayment->status != "rejected"){
                            $over_payment = $over_payment + $overpayment->amount;
                        }
                        if ($overpayment->amount > 0 && ($overpayment->payment_for == "processing_fee" )){
                            $processing_fee = $processing_fee + $overpayment->amount;
                        }
                        if ($overpayment->amount > 0 && ($overpayment->payment_for == "insurance_fee" )){
                            $insurance_fee = $insurance_fee + $overpayment->amount;
                        }
                        if ($overpayment->amount > 0 && ($overpayment->payment_for == "advance_amount" )){
                            $advance_amount = $advance_amount + $overpayment->amount;
                        }
                        if($overpayment->amount > 0 && $overpayment->payment_for == "refund"){
                            $over_payment = $over_payment - $overpayment->amount;
                        }
                        if($overpayment->amount > 0 && $overpayment->payment_for == "Pre-EMI"){
                            $pre_emi = $overpayment->amount;
                        }
                        if ($overpayment->amount > 0 && ($overpayment->payment_for == "Foreclosure") && $overpayment->status != "rejected"){
                            $breakupLogs = ForeclosureBreakup::where('application_id', $application->id)->orderBy('created_at', 'desc')->first(['id', 'pf_due', 'advance_due']);
                            if(isset($breakupLogs->id)) {
                                $processing_fee = round($processing_fee + $breakupLogs->pf_due);
                                $advance_amount = round($advance_amount + $breakupLogs->advance_due);
                            }
                            if(isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01"){
                                $isForeclosed = 1;
                            }
                        }

                        if ($overpayment->amount > 0 && ($overpayment->payment_for == "Over Payment" || $overpayment->payment_for == "Advance Payment"  || $overpayment->payment_for == "Foreclosure") && $overpayment->status != "rejected"){
                            $adhoc_payment = $adhoc_payment + $overpayment->amount;
                        }

                    }
                    $pending_dues[$application->id]['over_payment'] = $over_payment;
                }else{
                    $pending_dues[$application->id]['over_payment'] = 0;
                }
                if($application->application_element->total_amount_due == 0){
                    $max_payable = 0;
                }
                $pending_dues[$application->id]['waived_off_data'] = $this->getWaivedOff($application->id);
                $pending_dues[$application->id]['adhoc_transaction'] = $overpayments;
                $pending_dues[$application->id]['amount_due'] = $isForeclosed == 1 ? 0 : $application->application_element->amount_over_due;
                $pending_dues[$application->id]['application_id'] = $application->id;
                $pending_dues[$application->id]['applicant_name'] = $application->name;
                $pending_dues[$application->id]['collection_executive'] = $application->application_element && $application->application_element->collection_executive ? $application->application_element->collection_executive->name : '';
                $pending_dues[$application->id]['merchant_name'] = isset($application->merchant->merchant_name) ? $application->merchant->merchant_name : $application->name;
                $pending_dues[$application->id]['merchant_id'] = isset($application->merchant->id) ? $application->merchant->id : $application->merchant_id;
                $pending_dues[$application->id]['coapplicant_name'] = $application->co_applicant_name;
                $pending_dues[$application->id]['applicant_email'] = $application->email;
                $pending_dues[$application->id]['coapplicant_email'] = $application->co_applicant_email;
                $pending_dues[$application->id]['applicant_number'] = $application->mobile_number;
                $pending_dues[$application->id]['coapplicant_number'] = $application->co_applicant_mobile_number;
                $pending_dues[$application->id]['purpose'] = $application->purpose;
                $pending_dues[$application->id]['max_payable'] = $max_payable;
                $pending_dues[$application->id]['lender_id'] = $application->lender_id;
                $pending_dues[$application->id]['lender_name'] = isset($application->lender->name) ? $application->lender->name : "";
                $pending_dues[$application->id]['purpose'] = $application->purpose;
                $pending_dues[$application->id]['account_holder'] = isset($application->lender->bank_details->account_holder) ? $application->lender->bank_details->account_holder : "";
                $pending_dues[$application->id]['bank'] = isset($application->lender->bank_details->bank_name) ? $application->lender->bank_details->bank_name : "";
                $pending_dues[$application->id]['branch'] = isset($application->lender->bank_details->branch_name) ? $application->lender->bank_details->branch_name : "";
                $pending_dues[$application->id]['account_number'] = isset($application->lender->bank_details->account_number) ? $application->lender->bank_details->account_number : "";
                $pending_dues[$application->id]['ifsc'] = isset($application->lender->bank_details->ifsc_code) ? $application->lender->bank_details->ifsc_code : "";
                $pending_dues[$application->id]['pre_emi_received'] = $pre_emi ?? 0;

                $loan_application_no = isset($application->proFormaInvoice->loan_application_no) && !empty($application->proFormaInvoice->loan_application_no) ? $application->proFormaInvoice->loan_application_no : '';
                if ($loan_application_no) {
                    if($application->lender_id == AvanseServices::$lender_id) {
                        $pending_dues[$application->id]['bank-details'] = [
                            'Beneficiary account number' => '918020009293418',
                            'Beneficiary name' => 'Avanse Financial Services Ltd',
                            'IFSC code' => 'UTIB0000028',
                            'Bank Name' => 'Axis Bank'
                        ];
                    }else if($application->lender_id == Lendbox::$lender_id || $application->lender_id == LendboxLSP::$lender_id){
                        $pending_dues[$application->id]['bank-details'] = [
                            'Beneficiary account number' => '000705047644',
                            'Beneficiary name' => 'Transactree Technologies Private Limited',
                            'IFSC code' => 'ICIC0000007',
                            'Bank Name' => 'ICICI BANK LTD'
                        ];
                    }else if($application->lender_id == Services::$lender_id){
                        $pending_dues[$application->id]['bank-details'] = [
                            'Beneficiary account number' => '200999509663',
                            'Beneficiary name' => 'Aditya Birla Finance LTD',
                            'IFSC code' => 'INDB0000001',
                            'Bank Name' => 'INDUSIND BANK LTD'
                        ];
                    }else if($application->lender_id == KMGP2P::$lender_id){
                        $pending_dues[$application->id]['bank-details'] = [
                            'Beneficiary account number' => '409002234039',
                            'Beneficiary name' => 'K M GLOBAL P2P FINANCE PRIVATE LIMITED COLLECTION ACCOUNT',
                            'IFSC code' => 'RATN0000088',
                            'Bank Name' => 'RBL Bank'
                        ];
                    }else if($application->lender_id == BlackSoil::$lender_id){
                        $pending_dues[$application->id]['bank-details'] = [
                            'Beneficiary account number' => '10245910063',
                            'Beneficiary name' => 'Blacksoil Capital Private Limited',
                            'IFSC code' => 'IDFB0040101',
                            'Bank Name' => 'IDFC First Bank'
                        ];
                    }else {
                        $pending_dues[$application->id]['bank-details'] = [
                            'Beneficiary account number' => '10245910063',
                            'Beneficiary name' => 'BLACKSOIL CAPITAL PRIVATE LIMITED',
                            'IFSC code' => 'IDFB0040101',
                            'Bank Name' => 'IDFC FIRST Bank'
                        ];
                    }
                }
                $pending_dues[$application->id]['amount_paid'] = $amount_paid + $adhoc_payment;
                $pending_dues[$application->id]['emi_due'] = $isForeclosed == 1 ? 0 : $application->application_element->emi_pending;
                $pending_dues[$application->id]['emi_paid'] = $application->application_element->emi_paid;
                $pending_dues[$application->id]['amount_pending'] = $isForeclosed == 1 ? 0 : $application->application_element->total_amount_due;
                $pending_dues[$application->id]['last_emi_date'] = $application->application_element->last_emi_date;
                $pending_dues[$application->id]['amount_payable'] = $amount_payable;
                $pending_dues[$application->id]['processing_fee_collected'] = $processing_fee;
                $pending_dues[$application->id]['processing_fee_due'] = (isset($application->emi->processing_fee)) ?  ($application->emi->processing_fee - $processing_fee) : 0;
                $pending_dues[$application->id]['insurance_fee_due'] = (isset($application->proFormaInvoice->insurance_premium_amount)) ?  ($application->proFormaInvoice->insurance_premium_amount - $insurance_fee) : 0;
                $pending_dues[$application->id]['advance_amount_due'] = (isset($application->proFormaInvoice->merchant_collected_advance_amount) && $application->proFormaInvoice->merchant_collected_advance_amount && $application->emi) ?  ($application->emi->upfront_from_customer - $advance_amount) : 0;
                $pending_dues[$application->id]['approved_amount'] = ($application->approved_amount == 0 || $application->approved_amount == "") ? $application->loan_amount : $application->approved_amount;
                $pending_dues[$application->id]['payment'] = $this->getWithMoratoriumDetails($application->emi_payment);
                $pending_dues[$application->id]['loan_agreement_no'] = $application->proFormaInvoice->loan_application_no ?? '';
                $response[$application->id] = $pending_dues[$application->id];
                $response[$application->id]['mandate'] = $application->checkmandate;
                $response[$application->id]['last_payment_date'] = $last_payment_date;
                $response[$application->id]['last_payment_amount'] = $last_payment_amount;
                $response[$application->id]['overdue_amount'] = $application->application_element->amount_over_due;
                $emi_payment_amount = EmiPayment::where('application_id', $application->id)->where('payment_status', 'pending')->orderBy('emi_date', 'desc')->first(['emi_amount']);
                $response[$application->id]['current_emi_amount'] = $emi_payment_amount->emi_amount ?? 0;
            }
        }
        return $response;
    }

    public function getWithMoratoriumDetails($emi_payment){
        $moratorium = new Moratorium();
        foreach ($emi_payment as $index => $item) {
            if (isset($item->moratoriums) && count($item->moratoriums)) {
                foreach ($item->moratoriums as $moratoriumItem) {
                    if ($moratoriumItem->emi_date == Carbon::createFromFormat('Y-m-d', $item->emi_date)->subMonth(1)->toDateString()) {
                        $moratoriumAmount = $moratorium->getPrincipalOutstanding($item->application_id, $moratoriumItem);
                        $emi_payment[$index]->moratorium_amount = $moratoriumAmount;
                    }
                }
            }else{
                return $emi_payment;
                break;
            }
        }

        return $emi_payment;
    }

    public function getWaivedOff($id){
        $waived_off = WaiveOffLog::with('emi_payment','users')->where('application_id',$id)->orderBy('emi_payment_id')->get();
        $response =array();
        if($waived_off) {
            foreach ($waived_off as $waived){
                $response[$waived->emi_payment->emi_date]['amount'] = $waived->amount;
                $response[$waived->emi_payment->emi_date]['waived_by'] = $waived->users->name;
                $response[$waived->emi_payment->emi_date]['waived_on'] = $waived->created_at;
            }
        }
        return $response;
    }



    public function overDueReminder($application_id,$send_email= 1,$send_message=1,$send_anyways= 0,$all_due_cases = 0,$payment_status = "",$due = 1, $event = null){
        //        (new Slack(new Request(['title' => 'Over Due Reminder Started', 'fields' => ['Application Ids' => json_encode($application_id)], 'group' => Slack::$STAGE_TESTING])))->send();

        $serviceCount  = 0;
        $current_date = date("Y-m-d");
        //(new Slack(new Request(['title' => 'calculating payment', 'fields' => ['Name' => 'overDuePaymentReminder'], 'group' => Slack::$STAGE_TESTING])))->send();
        $this->paymentCalculate($application_id);
        //(new Slack(new Request(['title' => 'calculating payment - done', 'fields' => ['Name' => 'overDuePaymentReminder'], 'group' => Slack::$STAGE_TESTING])))->send();
        $_application_id = !is_array($application_id) ? $application_id : 0;

        $payment_data = $this->getPaymentDueHistory($_application_id,"",0,$due,0,$application_id);

        //(new Slack(new Request(['title' => 'calculating payment - get getPaymentDueHistory', 'fields' => ['Name' => 'overDuePaymentReminder'], 'group' => Slack::$STAGE_TESTING])))->send();
        $view_data = array();
        $response = array();
        $application_ids = array();
        $total_applications = 0;
        $sent = 0;
        $iceCounter = 0;

        $recon_id = array();
        if($send_email) {
            $payments = PaymentMakerChecker::with('application')->where('data',"LIKE",'%"payment_type":"credit"%')->whereNull('deleted_at')->where('status',1)->get();
            foreach ($payments as $payment) {
                array_push($recon_id, $payment->application_id);
            }
        }

        $consent_key = 0;
        //(new Slack(new Request(['title' => 'calculating payment - get PaymentMakerChecker', 'fields' => ['Name' => 'overDuePaymentReminder'], 'group' => Slack::$STAGE_TESTING])))->send();
        //(new CSV())->save(['data' => ['type' => 'count', 'value' => 'get count', 'id' => count($payment_data)]], $current_date.'_overdue_reminder', null, 'csv');
        foreach ($payment_data as $id=>$application) {
            try {
                //(new CSV())->save(['data' => ['type' => 'id', 'value' => $id]], $current_date.'_overdue_reminder', null, 'csv');
                if (!in_array($id, $recon_id)) {
                    $bounce_charges = 0;
                    $delay_penalty = 0;
                    $total_emi = 0;
                    $amount_received = 0;
                    $waived = 0;
                    $view_data['delay_days'] = 0;
                    $i = 0;
                    $moratorium_amount_total = 0;
                    foreach ($application['payment'] as $payment) {
                        $view_data['for_today_emi_amount'] = ($payment['emi_amount'] ?? 0);
                        $emi_date = $payment->emi_date;
                        $emi_current_date_check = date("Y-m-d", strtotime("+ 1 day", strtotime($emi_date)));
                        if ((((isset($payment['pending_amount']) && $payment['pending_amount'] > 0) && $emi_date <= date('Y-m-d', time()) && $emi_date != $current_date && $current_date != $emi_current_date_check)) || $payment['payment_status'] == 'rejected') {
                            //                    if($payment['payment_status'] == 'rejected'){
                            //                        if($payment->amount_due > 0){
                            //                            $application['amount_due'] =  $application['amount_due'] + $payment->amount_due;
                            //                        }else {
                            //                            $application['amount_due'] = $application['amount_due'] + $payment->emi_amount;
                            //                        }
                            //                    }

                            $moratorium_amount_total += isset($payment['moratorium_amount']) ? $payment['moratorium_amount'] : 0;

                            $bounce_charges = $bounce_charges + (isset($payment['bounce_charges']) ? $payment['bounce_charges'] : 0);
                            $delay_penalty = $delay_penalty + (isset($payment['delay_penalty']) ? $payment['delay_penalty'] : 0);
                            $total_emi = $total_emi + (isset($payment['emi_amount']) ? $payment['emi_amount'] : 0);
                            $total_payable = (isset($payment['total_payable']) ? $payment['total_payable'] : 0);
                            $amount_due = (isset($payment['amount_due']) ? $payment['amount_due'] : 0);
                            $amount_received = $amount_received + ($total_payable - $amount_due);
                            $waived = $waived + (isset($payment['charges_waived']) ? $payment['charges_waived'] : 0);
                            if ($view_data['delay_days'] == 0 && isset($payment['pending_amount']) && $payment['pending_amount'] > 0) {
                                $view_data['delay_days'] = $this->calculateDelayDays($emi_date, date('Y-m-d'), $id);
                            }
                            $view_data['reason'] = "and your payment hasn’t been received by us";
                            if (isset($payment['payment_history']['transaction'])) {
                                foreach ($payment['payment_history']['transaction'] as $transaction) {
                                    if (isset($view_data['reason'])) {
                                        $view_data['reason'] = $transaction['reason'];
                                    }
                                }
                            }
                        } else {
                            unset($application['payment'][$i]);
                        }
                        $i++;
                    }


                    if ($total_emi >= $amount_received) {
                        $balance_emi = $total_emi - $amount_received;
                        $charges = $bounce_charges + $delay_penalty;
                    } else {
                        $balance_emi = 0;
                        $amount_received = $amount_received - $total_emi;
                        $charges = ($bounce_charges + $delay_penalty) - $amount_received;
                    }

                    if ($waived <= $charges) {
                        $charges = $charges - $waived;
                    } else {
                        $charges = 0;
                        $balance_emi = $balance_emi - ($waived - $charges);
                    }

                    $application['balance_emi'] = $balance_emi;
                    $application['charges'] = $charges;
                    $view_data['data'] = $application;
                    array_push($application_ids, $id);
                    $total_applications = $total_applications + 1;
                        //            if ($application_ids == "") {
                        //                $application_ids = $id;
                        //            } else {
                        //                $application_ids = $application_ids . "," . $id;
                        //            }
                    if (!$view_data['data']['amount_due'] && !$view_data['delay_days'] && empty($view_data['payment_link'])) {
                        $view_data['data']['amount_due'] = $view_data['for_today_emi_amount'] ?? 0;
                    }

                    $view_data['send_anyways'] = $send_anyways;
                    if (($view_data['data']['amount_due'] > 0 || $due == 0) && (($charges > 699 || $balance_emi > 0) || $send_anyways == 1 || $all_due_cases == 1 || $due == 0) && ($send_email == 1 || $send_message == 1)) {
                        setlocale(LC_MONETARY, 'en_IN.UTF-8');
                        if ($view_data['data']['amount_due'] > 299 || $send_anyways == 1) {

                            if ($view_data['data']['amount_due']) {
                                $razorpaydata['amount'] = $view_data['data']['amount_due'];
                                $razorpaydata['email'] = "";
                                $razorpaydata['lender_id'] = $view_data['data']['lender_id'];
                                $razorpaydata['id'] = $id;
                                $razorpaydata['purpose'] = 'emi & penalty';
                                $razorpaydata['customer_amount_link'] = false;
                                $razorpaydata['emi_date'] = Carbon::now()->toDateString();

                                $view_data['payment_link'] = (new ConsumerApplicationController())->getrazorpaylink($razorpaydata);

                                //(new CSV())->save(['data' => ['type' => 'link', 'value' => $view_data['payment_link'], 'id' => $id]], $current_date.'_overdue_reminder', null, 'csv');
                            } else {
                                $view_data['payment_link'] = "";
                            }
                                //                    $hashids = new Hashids('Creditfair by CS', 20);
                                //                    $hashed_id = $hashids->encode($id);
                                //                    try {
                                //                        $view_data['payment_link'] = \Bitly::getUrl(asset("paytm/" . $hashed_id));
                                //                    }catch (\Exception $e){
                                //                        $view_data['payment_link'] = asset("paytm/" . $hashed_id);
                                //                    }
                        } else {
                            $view_data['payment_link'] = "";
                        }

                        if ($view_data['data']['amount_due'] > 0) {
                            $view_data['subject'] = "Your payment of Rs " . \str_replace('.00', '', ($view_data['data']['amount_due'])) . " is overdue";
                        } else {
                            $view_data['subject'] = "Your Nach / cheque bounced on " . date('Y-m-d');
                        }
                        if (isset($view_data['data']['coapplicant_name']) && !empty($view_data['data']['coapplicant_name'])) {
                            $applicant = $view_data['data']['applicant_name'] . " / " . $view_data['data']['coapplicant_name'];
                        } else {
                            $applicant = $view_data['data']['applicant_name'];
                        }
                        $view_data['sms'] = "Dear " . $applicant . ",<br><br>
                            You are " . $view_data['delay_days'] . " days late on your payment of Rs." . \str_replace('.00', '', ($view_data['data']['amount_due'])) . " due towards.";
                        if ($application['balance_emi'] > 0) {
                            $view_data['sms'] .= " EMI of Rs." . \str_replace('.00', '', ($application['balance_emi'])) . "";
                        }
                        if ($application['balance_emi'] > 0 && $application['charges'] > 0) {
                            $view_data['sms'] .= " and";
                        }
                        if ($application['charges'] > 0) {
                            $view_data['sms'] .= " fees of Rs." . \str_replace('.00', '', ($application['charges'])) . "";
                        }
                        if ($view_data['data']['amount_due'] > 299 || $send_anyways == 1) {
                            $view_data['sms'] .= " Pay now on " . $view_data['payment_link'] . "";
                            if (count($application['payment']) > 1) {
                                $view_data['body'] = view('emails.reminders.emi_due_reminder_with_payment_link_with_penalty_multiple', $view_data)->render();
                                $view_data['sms'] .= "<br> We might have to pursue legal action if we don't hear from you. Call us on 91-8928769161 if you need any help or have already paid.<br><br>Regards,<br>Team Credit Fair";
                                $view_data['sms'] = str_replace('<br/>', "\n", $view_data['sms']);
                                $view_data['sms'] = str_replace('<br>', "\n", $view_data['sms']);
                                $entity = ['templateid' => '1307166478154391555', 'entityid' => Templates::$entityid];

                            } else {
                                $view_data['body'] = view('emails.reminders.emi_due_reminder_with_payment_link_with_penalty', $view_data)->render();
                                $view_data['sms'] .= "<br> Late payments can spoil your credit history and you might not be able to get loans in the future from any bank or finance company. Call us on +91-8928769161 if you need any help or have already paid.<br><br>Regards,<br>Team Credit Fair";
                                $view_data['sms'] = str_replace('<br/>', "\n", $view_data['sms']);
                                $view_data['sms'] = str_replace('<br>', "\n", $view_data['sms']);
                                $entity = ['templateid' => '1307161744590392816', 'entityid' => Templates::$entityid];
                            }
                        } else {
                            $view_data['body'] = view('emails.reminders.emi_due_reminder_with_payment_link_with_penalty', $view_data)->render();
                            $view_data['sms'] .= "<br> Late payments can spoil your credit history and you might not be able to get loans in the future from any bank or finance company. Call us on +91-8928769161 if you need any help or have already paid.<br><br>Regards,<br>Team Credit Fair";
                            $view_data['sms'] = str_replace('<br/>', "\n", $view_data['sms']);
                            $view_data['sms'] = str_replace('<br>', "\n", $view_data['sms']);
                            $entity = ['templateid' => '1307161744712717909', 'entityid' => Templates::$entityid];
                        }

                        $view_data['is_moratoriums'] = Moratorium::where('application_id', $id)->where('status', 1)->first();
                        $view_data['moratorium_amount_total_view'] = $moratorium_amount_total;

                        $withOutEMI = $application['charges'] + $moratorium_amount_total;

                        if ($view_data['data']['amount_due'] <= $withOutEMI && $view_data['data']['amount_due']) {
                            $view_data['subject'] = "Your payment of Rs." . \str_replace('.00', '', money_format('%!i', ($view_data['data']['amount_due'])));
                            $view_data['hide_row'] = 1;
                        }

                        // if (count($application['payment']) > 1) {
                        //     $view_data['body'] = view('emails.reminders.emi_due_reminder_with_payment_link_with_penalty_multiple', $view_data)->render();
                        //     $view_data['sms'] .= "<br> We might have to pursue legal action if we don't hear from you. Call us on +91-8928769161 if you need any help or have already paid.<br><br>Regards,<br>Team Credit Fair";

                        // } else {
                        //     $view_data['body'] = view('emails.reminders.emi_due_reminder_with_payment_link_with_penalty', $view_data)->render();
                        //     $view_data['sms'] .= "<br> Late payments can spoil your credit history and you might not be able to get loans in the future from any bank or finance company. Call us on +91-8928769161 if you need any help or have already paid.<br><br>Regards,<br>Team Credit Fair";
                        // }
                        // $view_data['sms'] = str_replace('<br/>', "\n", $view_data['sms']);
                        // $view_data['sms'] = str_replace('<br>', "\n", $view_data['sms']);
                        // $entity = ['templateid' => '1307166436163989146', 'entityid' => Templates::$entityid];
                        // testing email start
                        //                $view_data['email_id'] = ['payments@creditfair.in'];
                        //
                        //
                        //                \Mail::send('emails.blank',
                        //                    ['body' => $view_data['body']]
                        //                    , function ($message) use ($view_data) {
                        //                        $message->to($view_data['email_id'])->subject($view_data['subject']);
                        //                    });
                        //                    $this->emailCount++;
                        //$mobile = '918291919036';
                        //send_sms($mobile, ['message'=>$view_data['sms'],'id'=>$application_id,'id_type'=>'application_id']);
                        // testing email end

                        $view_data['data']['isAttachment'] = 0;

                        if ($payment_status == 'rejected') {
                            $frontController = new FrontController();
                            $statement = $frontController->getStatement($id, true);
                            $view_data['data']['pdf'] = $statement;
                            $view_data['data']['fileName'] = "Account_Statement.pdf";
                            $view_data['data']['isAttachment'] = 1;
                        }

                        $merchant = ConsumerApplication::where('id',$application['application_id'])->first(['merchant_id']);
                        $consent_key = array_search ('Overdue', CommunicationService::$com_category);
                        $email_comm = CommunicationMapping::whereRaw('FIND_IN_SET('.$consent_key.',type_ids)')->where('communication_id',1)->where('merchant_id',$merchant['merchant_id'])->count();
                        $communication = CommunicationMapping::where('merchant_id',$merchant['merchant_id'])->count();

                        //(new CSV())->save(['data' => ['type' => 'email', 'value' => 'preparing to send email', 'id' => $id]], $current_date.'_overdue_reminder', null, 'csv');
                        if (isset($view_data['data']['applicant_email']) && ($email_comm == 1 || $communication == 0 || $consent_key == 0) && !empty($view_data['data']['applicant_email']) && $send_email == 1 && UserEmails::isValid($view_data['data']['applicant_email']) && isset($view_data['subject']) && !(BNPL::is($view_data['data']['merchant_id'])) && !in_array($view_data['data']['merchant_id'], [6418, 6517, 6598, 6865, 6600])) {
                            Mail::send('emails.blank',
                                ['body' => $view_data['body']]
                                , function ($message) use ($view_data) {
                                    $message->to($view_data['data']['applicant_email'])->subject($view_data['subject']);

                                    if (isset($view_data['data']['coapplicant_email']) && !empty($view_data['data']['coapplicant_email'])) {
                                        $message->cc([$view_data['data']['coapplicant_email']]);
                                    } else {
                                        //$message->cc('payments@creditfair.in');
                                    }
                                    if ($view_data['data']['isAttachment'] == 1) {
                                        $message->attachData($view_data['data']['pdf']->output(), $view_data['data']['fileName']);
                                    }

                                });

                            //(new CSV())->save(['data' => ['type' => 'email', 'value' => 'email sent', 'id' => $id]], $current_date.'_overdue_reminder', null, 'csv');

                            $this->emailCount++;
                        }

                        //(new CSV())->save(['data' => ['type' => 'sms', 'value' => 'preparing to send sms', 'id' => $id]], $current_date.'_overdue_reminder', null, 'csv');
                        if (isset($view_data['data']['applicant_number']) && !empty($view_data['data']['applicant_number']) && isset($view_data['sms']) && $send_message == 1 && isset($view_data['subject']) && !(BNPL::is($view_data['data']['merchant_id'])) && !in_array($view_data['data']['merchant_id'], [6418, 6517, 6598, 6865, 6600])) {
                            $mobile = '91' . $view_data['data']['applicant_number'];
                            if (isset($view_data['data']['coapplicant_number']) && !empty($view_data['data']['coapplicant_number'])) {
                                $mobile .= $mobile . ",91" . $view_data['data']['coapplicant_number'];
                            }
                            $sm_comm = CommunicationMapping::whereRaw('FIND_IN_SET('.$consent_key.',type_ids)')->where('communication_id',2)->where('merchant_id',$merchant->merchant_id)->count();
                            if($sm_comm == 1 || $communication == 0 || $consent_key == 0) {
                                send_sms($mobile, ['message' => $view_data['sms'], 'id' => $id, 'id_type' => 'application_id', 'message_type' => "payment", 'templateDetails' => $entity]);
                                $this->smsCount++;
                            }
                        }
                        $serviceCount++;
                    }
                    $response[$id] = $view_data;
                    $view_data['delay_days'] = 0;
                    $sent = $sent + 1;
                    if ($sent == 11) {
                        $sent = 0;
                        // sleep for 1 seconds
                        sleep(1);
                    }
                }

                if ($iceCounter == 50) {
                    $iceCounter = 0;
                    (new Slack(new Request(['title' => 'Over Due Reminder Summary - counter', 'fields' => ['Name' => 'overDuePaymentReminder'], 'group' => Slack::$STAGE_TESTING])))->send();
                }
            }catch (\Exception $e){
                if (!isset($errorFound)){
                    $errorFound = 1;
                    (new Slack(new Request(['title' => 'Over Due Reminder Summary - error', 'fields' => ['E' => $e->getFile(), 'M' => $e->getMessage(), 'L' => $e->getLine(), 'T' => $e->getTraceAsString()], 'group' => Slack::$STAGE_TESTING])))->send();
                }
            }

            $iceCounter++;
        }

        return array('response'=>$response, 'application_ids' =>$application_ids,'total_applications'=>$total_applications,'service_count' => $serviceCount);
    }

    public function overDueReminderPython($application_id, $collectionEmail)
    {
        $payload = json_encode([
            'application_id' => $application_id,
            'collectionEmail' => $collectionEmail
        ]);

        // Initialize cURL
        // $ch = curl_init('http://127.0.0.1:8001/overdue-reminder');

        $OverdueReminder = _env('CF_OVERDUE_ENDPOINT', 'http://127.0.0.1:8000/overdue-reminder');
        $ch = curl_init($OverdueReminder);

        // Set cURL options
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Accept: application/json'
            ],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_TIMEOUT => 30, // optional: prevent hanging
        ]);

        // Execute request
        $response = curl_exec($ch);

        // Handle cURL errors
        if (curl_errno($ch)) {
            $error = curl_error($ch);
            curl_close($ch);
            return [
                'message' => "cURL Error: $error",
            ];
        }
        curl_close($ch);


        $decoded = json_decode($response, true);

        // If JSON invalid fallback to raw
        $message = $decoded['message'] ?? $response;

        return [
        'status' => 'success',
        'message' => $message
        ];
    }

    public function getForeclosureAmount($application_id ,$foreclosure_date = ''){
        $payment_data = $this->getPaymentDueHistory($application_id,"",1);

        if($foreclosure_date == ""){
            $foreclosure_date = date('Y-m-d',(strtotime ('29 day',time())));
        }
        $response['previous_pending'] = 0;
        $response['future_emi'] = 0;
        $response['due_emi'] = 0;
        $response['bounce_charges'] = 0;
        $response['penal_interest'] = 0;
        $response['gst'] = 0;
        $response['advance_payment'] = 0;
        foreach ($payment_data[$application_id]['payment'] as $payments){
            if($payments->emi_date <= $foreclosure_date) {
                if($payments['amount_due'] > 0) {
                    $response['previous_pending'] = $response['previous_pending'] + $payments['pending_amount'];
                    $response['bounce_charges'] = $response['bounce_charges'] + (isset($payments['bounce_charges']) ? $payments['bounce_charges'] : 0);
                    $response['penal_interest'] = $response['penal_interest'] + (isset($payments['delay_penalty']) ? $payments['delay_penalty'] : 0);
                }
                $response['foreclosure_date'] = $payments->emi_date;
            }else{
                $response['advance_payment'] = $response['advance_payment'] + ($payments['total_payable'] - $payments['amount_due']);
            }
        }
        $amort = new AccountingController();
        $schedule = $amort->viewloanschedule($application_id,1,1);
        foreach ($schedule['schedule'] as $loan_schedule){
            if($loan_schedule['emi_date'] > $foreclosure_date){
                $response['future_emi'] = $response['future_emi'] + $loan_schedule['principal'];
            }
        }
        $response['future_emi'] = round(($response['future_emi']-$response['advance_payment']),0);
        $response['total_outstanding'] = $response['previous_pending'] + $response['future_emi'];
        $this->loan_schedule = $schedule;
        return $response;
    }

    public function forecloseCase($application_id){
        $application = ConsumerApplication::with('application_element', 'merchant','proFormaInvoice')->where('id', $application_id)->first(['id', 'merchant_id','state','name']);
        $check = $this->checkIfPaymentReceived($application);

        if($check){
            $consumerApplicationController = new ConsumerApplicationController();
            request()->merge(['state' => 'closed']);;
            $consumerApplicationController->updateStatus($application_id);
            (new Slack(new Request(['title' => 'Loan Auto Closed', 'fields' => ['Name' => $application->name, 'merchant_name' => $application->merchant->merchant_name,
                'Application ID' => $application->id], 'group' => Slack::$STAGE_TESTING /*'payment_collection'*/])))->send();
        }else{
            (new Slack(new Request(['title' => 'Loan could not be auto closed', 'fields' => ['Name' => $application->name, 'merchant_name' => $application->merchant->merchant_name,
                'Application ID' => $application->id], 'group' => Slack::$STAGE_TESTING /*'payment_collection'*/])))->send();
        }

    }

    public function autoWaiveOff($id){
        $consumerApplicationElement = ConsumerApplicationElement::where('application_id', $id)->first(['total_amount_due']);

        $auto_waive_amount = AutoWaiver::first();

        if(!isset($auto_waive_amount->waive_off_amt)){
            return false;
        }

        if(!isset($consumerApplicationElement->total_amount_due)){
            return false;
        }

        if($consumerApplicationElement->total_amount_due && $consumerApplicationElement->total_amount_due <= (float) $auto_waive_amount->waive_off_amt){
            $emiPayments = EmiPayment::where('application_id', $id)->where('payment_status', 'partial')->get(['id', 'amount_due']);

            $amountToBeWaivedOff = 0;
            $emiIds = [];
            foreach($emiPayments as $emiPayment){
                if($emiPayment->amount_due){
                    $amountToBeWaivedOff += $emiPayment->amount_due;
                    $emiIds[$emiPayment->id] = $emiPayment->amount_due;
                }
            }

            $accounting = new AccountingController();
            if($amountToBeWaivedOff <= (float)$auto_waive_amount->waive_off_amt){
                foreach($emiIds as $emiId => $emiAmount){
                    $accounting->updateWaiveOff(new Request(['emi_id' => $emiId, 'waive_amount' => $emiAmount, 'go_maker_check' => true]));
                }
            }
        }

        return false;
    }
}

