<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\Helper;
use App\Helpers\JournalAuto;
use App\Helpers\LogActivity;
use App\Http\Controllers\Controller;
use App\Http\Resources\CollectedResource;
use App\Models\Accounting\ChartOfAccount;
use App\Models\AccReceivableDetails;
use App\Models\AccReceivables;
use App\Models\BackPayment;
use App\Models\Loan;
use App\Models\User;
use App\Models\Client;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ClientPaymentController extends Controller
{

    function __construct()
    {
        $this->middleware('permission:Repay', ['only' => ['store']]);
        $this->middleware('permission:Repay Edit', ['only' => ['update']]);
        $this->middleware('permission:Repay Delete', ['only' => ['destroy']]);
        $this->middleware('permission:Pay Off', ['only' => ['SubmitPayAll']]);
    }

    public function store(Request $request)
    {
        $acc = AccReceivables::find($request->id);
        $findLoan = Loan::find($acc->loan_id);
        $acc_id         = $request->id;
        $penalty        = $request->paid_penalty??0;
        $waiv_penalty   = $request->waiv_penalty??0;

        $paid_penalty   = $penalty - $waiv_penalty; // Paid penalty
        $amount_repay   = $request->amount_repay - $penalty + $waiv_penalty; // (Amount receive not penalty)

        $sum_amount_be_paid = $findLoan->loan_balance + $paid_penalty;
        $this->validate($request, [
            'received_date'  => 'required',
            'chart_of_acc_id'=> 'required',
            // 'amount_repay'   => 'required|numeric|gte:'.'1'.'|lte:'.$sum_amount_be_paid,
        ]);
        try{
            DB::beginTransaction();
            $totalPaidInterest = 0;
            if($amount_repay <= $penalty){
                $res = [
                    'status'  => 0,
                    'message' => "ទឹកប្រាក់ត្រូវបង់មិនអាចតូចជាងប្រាក់ពិន័យបានទេ !",
                    'data'    => '',
                ];
            }else{
                $unreceived         = $acc->unreceived;
                $interest_per_month = $acc->interest_per_month;
                $operating_service  = $acc->operating_service;
                $total_amount       = $amount_repay;
                $received_date      = $request->received_date!=null?date('Y-m-d',strtotime($request->received_date)):date('Y-m-d');
                $maintenance_per_month = $acc->maintenance_per_month;

                $created_by = Auth::user()->id;

                $update_loan = Loan::find($acc->loan_id);
                if($amount_repay==$unreceived || $amount_repay<$unreceived)
                {
                    $accReceivable = AccReceivables::find($acc_id);
                    $accReceivable->received_date   = $received_date;
                    $accReceivable->received       += $amount_repay;
                    $accReceivable->unreceived     -= $amount_repay;
                    $accReceivable->penalty        += $paid_penalty;
                    $accReceivable->waiv_penalty   += $waiv_penalty;
                    $accReceivable->payment_status_id = $amount_repay == $unreceived?1:2;

                    $accReceivable->update();

                    if($accReceivable->payment_status_id==1) {
                        $next_open_close = AccReceivables::where('loan_id',$acc->loan_id)->where('payment_status_id',3)->orderBy('payment_date','asc')->first();
                        if($next_open_close) {
                            $next_open_close->open_close = 2;
                            $next_open_close->update();
                        }
                    }

                    $paid_principal = 0;
                    $paid_interest = 0;
                    $paid_operating_service = 0;
                    $paid_maintenance = 0;
                    $sumInterest = AccReceivableDetails::where('acc_id',$acc_id)->sum('paid_interest');
                    if($sumInterest<$interest_per_month)
                    {
                        $subInterest = $interest_per_month-$sumInterest;  // find remain interest paid
                        if($total_amount<=$subInterest)
                        {
                            $paid_interest = $total_amount;
                        }
                        else {
                            $paid_interest     = $subInterest;
                            $total_amount      = $total_amount-$paid_interest;
                            $sumOperateService = AccReceivableDetails::where('acc_id',$acc_id)->sum('paid_operating_service');
                            $subOpService      = $operating_service-$sumOperateService;
                            if($total_amount<=$subOpService)
                            {
                                $paid_operating_service = $total_amount;
                            }
                            else
                            {
                                $paid_operating_service = $subOpService;
                                $total_amount = $total_amount-$paid_operating_service;
                                $sumMaintenance = AccReceivableDetails::where('acc_id',$acc_id)->sum('paid_maintenance');
                                $subMaintenance = $maintenance_per_month-$sumMaintenance;
                                if($sumMaintenance<$maintenance_per_month)
                                {
                                    if($total_amount<=$subMaintenance)
                                    {
                                        $paid_maintenance = $total_amount;
                                    }
                                    else
                                    {
                                        $paid_maintenance = $subMaintenance;
                                        $paid_principal = $total_amount-$subMaintenance;
                                    }
                                }
                                else {
                                    $paid_principal = $total_amount;
                                }
                            }
                        }
                    }
                    else
                    {
                        $sumOperateService = AccReceivableDetails::where('acc_id',$acc_id)->sum('paid_operating_service');
                        $subOpService = $operating_service-$sumOperateService;
                        if($sumOperateService<$operating_service)
                        {
                            if($total_amount<=$subOpService) {
                                $paid_operating_service = $total_amount;
                            }
                            else
                            {
                                $paid_operating_service = $subOpService;
                                $total_amount = $total_amount-$subOpService;
                                $sumMaintenance = AccReceivableDetails::where('acc_id',$acc_id)->sum('paid_maintenance');
                                $subMaintenance = $maintenance_per_month-$sumMaintenance;
                                if($sumMaintenance<$maintenance_per_month)
                                {
                                    if($total_amount<=$subMaintenance)
                                    {
                                        $paid_maintenance = $total_amount;
                                    }
                                    else
                                    {
                                        $paid_maintenance = $subMaintenance;
                                        $paid_principal = $total_amount-$subMaintenance;
                                    }
                                }
                                else
                                {
                                    $paid_principal = $total_amount;
                                }
                            }
                        }
                        else
                        {
                            $sumMaintenance = AccReceivableDetails::where('acc_id',$acc_id)->sum('paid_maintenance');
                            $subMaintenance = $maintenance_per_month-$sumMaintenance;
                            if($sumMaintenance<$maintenance_per_month)
                            {
                                if($total_amount<=$subMaintenance)
                                {
                                    $paid_maintenance = $total_amount;
                                }
                                else
                                {
                                    $paid_maintenance = $subMaintenance;
                                    $paid_principal = $total_amount-$subMaintenance;
                                }
                            }
                            else
                            {
                                $paid_principal = $total_amount;
                            }
                        }
                    }

                    $accReceivableDetail = new AccReceivableDetails();
                    $accReceivableDetail->acc_id           = $acc->id;
                    $accReceivableDetail->client_id        = $acc->client_id;
                    $accReceivableDetail->co_id            = $acc->co_id;
                    $accReceivableDetail->chart_of_acc_id  = $request->chart_of_acc_id;
                    $accReceivableDetail->branch_id        = $acc->branch_id;
                    $accReceivableDetail->created_by       = $created_by;
                    $accReceivableDetail->loan_id          = $acc->loan_id;
                    $accReceivableDetail->currency_id      = $acc->currency_id;
                    $accReceivableDetail->invoice_number   = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                    $accReceivableDetail->received_date    = $received_date;
                    $accReceivableDetail->received         = $amount_repay;
                    $accReceivableDetail->paid_principal   = $paid_principal;
                    $accReceivableDetail->paid_interest    = $paid_interest;
                    $accReceivableDetail->paid_operating_service = $paid_operating_service;
                    $accReceivableDetail->paid_maintenance = $paid_maintenance;
                    $accReceivableDetail->paid_penalty     = $paid_penalty;
                    $accReceivableDetail->waiv_penalty     = $waiv_penalty;
                    $accReceivableDetail->condition_payment= 1;
                    $accReceivableDetail->unreceived       = $accReceivable->unreceived;
                    $accReceivableDetail->note             = $request->note;
                    $accReceivableDetail->client_type      = $findLoan->client_type;
                    $accReceivableDetail->save();

                    $update_loan->increment('paid_principal',$paid_principal);
                    $update_loan->increment('paid_interest',$paid_interest);
                    $update_loan->increment('paid_operating_service',$paid_operating_service);
                    $update_loan->increment('paid_maintenance',$paid_maintenance);
                    $update_loan->decrement('balance_principal',$paid_principal);
                    $update_loan->decrement('balance_interest',$paid_interest);
                    $update_loan->decrement('balance_operating_service',$paid_operating_service);
                    $update_loan->decrement('balance_maintenance',$paid_maintenance);
                    $update_loan->update();
                }
                else
                {
                    $AccReceived    = AccReceivables::whereIn('payment_status_id',[2,3])->where('loan_id',$acc->loan_id)->orderBy('id','ASC')->get();
                    $firstAccID     = $AccReceived->min('id');
                    $lastUnreceived = 0;
                    $pay = 0;
                    $penalty = 0;
                    // $aaaa = 0;
                    // $bbbb = 0;
                    // $ccccc = 0;
                    // $dddddd = 0;
                    // $totalPaidInterest = 0;
                    foreach($AccReceived as $value)
                    {
                        $lastUnreceived +=$value['unreceived'];
                        $pay = $lastUnreceived-$amount_repay;
                        if($amount_repay > $lastUnreceived){
                            if($value->id==$firstAccID){
                                $penalty = $paid_penalty;
                                $get_waiv_penalty = $waiv_penalty;
                            } else{
                                $penalty = 0;
                                $get_waiv_penalty = 0;
                            }

                            $AccEqual = AccReceivables::find($value->id);
                            $UnAcc = AccReceivables::find($value->id);
                            $AccEqual->received_date = date('Y-m-d',strtotime($request->received_date));
                            $AccEqual->penalty       = $penalty;
                            $AccEqual->waiv_penalty  = $get_waiv_penalty;
                            $AccEqual->open_close    = 2;
                            $AccEqual->payment_status_id = 1;

                            $next_acc1 = AccReceivables::where('loan_id',$acc->loan_id)->where('payment_status_id',3)->orderBy('payment_date','asc')->first();
                            if($next_acc1) {
                                $next_acc1->open_close = 2;
                                $next_acc1->update();
                            }
                            $check = AccReceivables::where('id',$value->id)->orderBy('payment_date','asc')->first();
                            if($check->unreceived == $check->payment_per_month) {
                                $AccEqual->increment('received',$value['unreceived']);
                                $AccEqual->decrement('unreceived',$value['unreceived']);
                                $AccEqual->update();

                                $accReceivableDetail = new AccReceivableDetails();
                                $accReceivableDetail->acc_id           = $value->id;
                                $accReceivableDetail->client_id        = $value->client_id;
                                $accReceivableDetail->co_id            = $value->co_id;
                                $accReceivableDetail->chart_of_acc_id  = $request->chart_of_acc_id;
                                $accReceivableDetail->branch_id        = $value->branch_id;
                                $accReceivableDetail->loan_id          = $value->loan_id;
                                $accReceivableDetail->currency_id      = $value->currency_id;
                                $accReceivableDetail->created_by       = $created_by;
                                $accReceivableDetail->invoice_number   = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                                $accReceivableDetail->received_date    = $received_date;
                                $accReceivableDetail->received         = $value['unreceived'];
                                $accReceivableDetail->paid_principal   = $value['principal'];
                                $accReceivableDetail->paid_interest    = $value['interest_per_month'];
                                $accReceivableDetail->paid_operating_service        = $value['operating_service'];
                                $accReceivableDetail->paid_penalty     = $penalty;
                                $accReceivableDetail->waiv_penalty     = $get_waiv_penalty;
                                $accReceivableDetail->paid_maintenance = $value['maintenance_per_month'];
                                $accReceivableDetail->condition_payment= 1;
                                $accReceivableDetail->unreceived       = 0;
                                $accReceivableDetail->note             = $request->note;
                                $accReceivableDetail->client_type      = $findLoan->client_type;
                                $accReceivableDetail->save();

                                $totalPaidInterest += $value['interest_per_month'];
                                // $aaaa  +=$value['interest_per_month'];

                                $paid_principal  = $value['principal'];
                                $paid_interest   = $value['interest_per_month'];
                                $paid_operating_service       = $value['operating_service'];
                                $paid_maintenance= $value['maintenance_per_month'];
                            }
                            else {

                                $receivedInterest    = AccReceivableDetails::where('acc_id',$value->id)->sum('paid_interest');
                                $receivedOpService   = AccReceivableDetails::where('acc_id',$value->id)->sum('paid_operating_service');
                                $receivedMaintenance = AccReceivableDetails::where('acc_id',$value->id)->sum('paid_maintenance');
                                $receivedPrincipal   = AccReceivableDetails::where('acc_id',$value->id)->sum('paid_principal');

                                $paid_principal   = $value['principal'] - $receivedPrincipal;
                                $paid_interest    = $value['interest_per_month'] - $receivedInterest;
                                $paid_operating_service        = $value['operating_service'] - $receivedOpService;
                                $paid_maintenance = $value['maintenance_per_month'] - $receivedMaintenance;

                                $AccEqual->increment('received',$value['unreceived']);
                                $AccEqual->decrement('unreceived',$value['unreceived']);
                                $AccEqual->update();

                                $accReceivableDetail = new AccReceivableDetails();
                                $accReceivableDetail->acc_id            = $value->id;
                                $accReceivableDetail->client_id         = $value->client_id;
                                $accReceivableDetail->co_id             = $value->co_id;
                                $accReceivableDetail->created_by       = $created_by;
                                $accReceivableDetail->chart_of_acc_id   = $request->chart_of_acc_id;
                                $accReceivableDetail->branch_id         = $value->branch_id;
                                $accReceivableDetail->loan_id           = $value->loan_id;
                                $accReceivableDetail->currency_id       = $value->currency_id;
                                $accReceivableDetail->received_date     = date('Y-m-d',strtotime($request->received_date));
                                $accReceivableDetail->invoice_number    = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                                $accReceivableDetail->received          = $UnAcc->unreceived;
                                $accReceivableDetail->paid_principal    =  $paid_principal;
                                $accReceivableDetail->paid_interest     = $paid_interest;
                                $accReceivableDetail->paid_operating_service         = $paid_operating_service;
                                $accReceivableDetail->paid_penalty      = $penalty;
                                $accReceivableDetail->waiv_penalty      = $get_waiv_penalty;
                                $accReceivableDetail->paid_maintenance  = $paid_maintenance;
                                $accReceivableDetail->condition_payment = 1;
                                $accReceivableDetail->unreceived        = $AccEqual->unreceived;
                                $accReceivableDetail->note              = $request->note;
                                $accReceivableDetail->client_type       = $findLoan->client_type;
                                $accReceivableDetail->save();

                                $bbbb = $accReceivableDetail->invoice_number;


                            }


                            $update_loan->increment('paid_principal',$paid_principal);
                            $update_loan->increment('paid_interest',$paid_interest);
                            $update_loan->increment('paid_operating_service',$paid_operating_service);
                            $update_loan->increment('paid_maintenance',$paid_maintenance);
                            $update_loan->decrement('balance_principal',$paid_principal);
                            $update_loan->decrement('balance_interest',$paid_interest);
                            $update_loan->decrement('balance_operating_service',$paid_operating_service);
                            $update_loan->decrement('balance_maintenance',$paid_maintenance);
                            $update_loan->update();
                        }
                        else if($amount_repay == $lastUnreceived){
                            // dd('fdd');
                            $AccEqual = AccReceivables::find($value->id);
                            $AccEqual->received_date = date('Y-m-d',strtotime($request->received_date));
                            $AccEqual->payment_status_id = 1;
                            $AccEqual->open_close = 2;
                            $AccEqual->update();
                            $next_acc2 = AccReceivables::where('loan_id',$acc->loan_id)->where('payment_status_id',3)->orderBy('payment_date','asc')->first();
                            if($next_acc2)
                            {
                                $next_acc2->open_close = 2;
                                $next_acc2->update();
                            }
                            $AccEqual->increment('received',$value['unreceived']);
                            $AccEqual->decrement('unreceived',$value['unreceived']);
                            $AccEqual->update();

                            $accReceivableDetail = new AccReceivableDetails();
                            $accReceivableDetail->acc_id = $value->id;
                            $accReceivableDetail->client_id = $value->client_id;
                            $accReceivableDetail->co_id = $value->co_id;
                            $accReceivableDetail->chart_of_acc_id  = $request->chart_of_acc_id;
                            $accReceivableDetail->branch_id = $value->branch_id;
                            $accReceivableDetail->created_by       = $created_by;
                            $accReceivableDetail->loan_id = $value->loan_id;
                            $accReceivableDetail->currency_id = $value->currency_id;
                            $accReceivableDetail->received_date = $received_date;
                            $accReceivableDetail->invoice_number = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                            $accReceivableDetail->received = $value['unreceived'];
                            $accReceivableDetail->paid_principal = $value['principal'];
                            $accReceivableDetail->paid_interest = $value['interest_per_month'];
                            $accReceivableDetail->paid_operating_service = $value['operating_service'];
                            $accReceivableDetail->paid_maintenance = $value['maintenance_per_month'];
                            $accReceivableDetail->condition_payment = 1;
                            $accReceivableDetail->unreceived= 0;
                            $accReceivableDetail->note             = $request->note;
                            $accReceivableDetail->client_type      = $findLoan->client_type;
                            $accReceivableDetail->save();

                            $ccccc = $value['interest_per_month'];

                            $update_loan->increment('paid_principal',$value['principal']);
                            $update_loan->increment('paid_interest',$value['interest_per_month']);
                            $update_loan->increment('paid_operating_service',$value['operating_service']);
                            $update_loan->increment('paid_maintenance',$value['maintenance_per_month']);
                            $update_loan->decrement('balance_principal',$value['principal']);
                            $update_loan->decrement('balance_interest',$value['interest_per_month']);
                            $update_loan->decrement('balance_operating_service',$value['operating_service']);
                            $update_loan->decrement('balance_maintenance',$value['maintenance_per_month']);
                            $update_loan->update();

                            break 1;
                        }
                        else{
                            $lastPay = $value['unreceived']-$pay;
                            $updateAcc = AccReceivables::find($value->id);
                            $updateAcc->payment_status_id=2;
                            $updateAcc->received_date=$received_date;
                            $updateAcc->open_close = 2;
                            $updateAcc->increment('received',$lastPay);
                            $updateAcc->decrement('unreceived',$lastPay);
                            $updateAcc->update();

                            $paid_principal = 0;
                            $paid_interest = 0;
                            $paid_operating_service = 0;
                            $paid_maintenance = 0;

                            if($lastPay <= $updateAcc->interest_per_month)
                            {
                                $paid_interest    = $lastPay;
                            }
                            else
                            {
                                $paid_interest    = $updateAcc->interest_per_month; // Find paid interest
                                $remain_principal = $lastPay - $paid_interest; // Amount remain after sub paid interest
                                if($remain_principal <= $updateAcc->operating_service) {
                                    $paid_operating_service        = $remain_principal;  // Find paid risk
                                } else {
                                    $paid_operating_service      = $updateAcc->operating_service;  // Find paid risk
                                    $remain_risk    = $remain_principal - $paid_operating_service; // Amount remain after sub paid risk
                                    if($remain_risk <= $updateAcc->maintenance_per_month) {
                                        $paid_maintenance = $remain_risk;  // Find paid maintenance
                                    } else {
                                        $paid_maintenance = $updateAcc->maintenance_per_month;  // Find paid maintenance
                                        $paid_principal   = $remain_risk - $paid_maintenance; // Amount remain after sub paid maintenance
                                    }
                                }
                            }

                            $accReceivableDetail = new AccReceivableDetails();
                            $accReceivableDetail->acc_id = $value->id;
                            $accReceivableDetail->client_id = $value->client_id;
                            $accReceivableDetail->co_id = $value->co_id;
                            $accReceivableDetail->chart_of_acc_id  = $request->chart_of_acc_id;
                            $accReceivableDetail->branch_id = $value->branch_id;
                            $accReceivableDetail->created_by       = $created_by;
                            $accReceivableDetail->loan_id = $value->loan_id;
                            $accReceivableDetail->currency_id = $value->currency_id;
                            $accReceivableDetail->received_date = $received_date;
                            $accReceivableDetail->invoice_number = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                            $accReceivableDetail->received =  $lastPay;
                            $accReceivableDetail->paid_principal = $paid_principal;
                            $accReceivableDetail->paid_interest = $paid_interest;
                            $accReceivableDetail->paid_operating_service = $paid_operating_service;
                            $accReceivableDetail->paid_maintenance = $paid_maintenance;
                            $accReceivableDetail->condition_payment = 1;
                            $accReceivableDetail->unreceived= $pay;
                            $accReceivableDetail->note             = $request->note;
                            $accReceivableDetail->client_type      = $findLoan->client_type;
                            $accReceivableDetail->save();

                            $dddddd = $value['interest_per_month'];

                            $update_loan->increment('paid_principal',$paid_principal);
                            $update_loan->increment('paid_interest',$paid_interest);
                            $update_loan->increment('paid_operating_service',$paid_operating_service);
                            $update_loan->increment('paid_maintenance',$paid_maintenance);
                            $update_loan->decrement('balance_principal',$paid_principal);
                            $update_loan->decrement('balance_interest',$paid_interest);
                            $update_loan->decrement('balance_operating_service',$paid_operating_service);
                            $update_loan->decrement('balance_maintenance',$paid_maintenance);
                            $update_loan->update();

                            break 1;
                        }
                    }
                }

                $update_loan->loan_in       += $amount_repay;
                $update_loan->loan_balance  -= $amount_repay;
                $update_loan->total_penalty += $paid_penalty;
                $update_loan->total_waiv    += $waiv_penalty;
                $update_loan->update();

                if($update_loan->loan_balance == 0 || $update_loan->loan_balance <= 0.1){
                    $complete_loan = Loan::find($acc->loan_id);
                    $complete_loan->loan_balance   = 0;
                    $complete_loan->loan_status_id = 3;
                    $complete_loan->completed_date = $received_date;
                    $complete_loan->update();
                }

                

                // dd($aaaa,$bbbb,$ccccc,$dddddd);

                $user        = User::find(Auth::user()->id);
                $client      = Client::find($acc->client_id);
                $subject     = "អតិថិជន $client->name ធ្វើការបង់ប្រាក់ចំនួន $request->amount_repay ដោយ $user->name.";
                $subject_type= get_class($acc);
                $subject_id  = $acc->id;
                $causer_type = get_class($user);
                $causer_id   = Auth::user()->id;
                $branch      = Auth::user()->branch_id;
                $log_name    = 'AccReceivable Model';
                LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);

                $accReceivableDetail->payment_per_month = $request->amount_repay;
                $accReceivableDetail->received = $request->amount_repay;
                $accReceivableDetail->paid_penalty = $request->paid_penalty;
                $accReceivableDetail->paid_interest = $totalPaidInterest;
                // $accReceivableDetail->paid_interest = $aaaa+$bbbb+$ccccc+$dddddd;
                // $accReceivableDetail->invoice_number = $aaaa.$bbbb.$ccccc.$dddddd;

                $res = [
                    'status' => 1,  
                    'message'=> 'Payment success',
                    'accReceivableDetail'  => new CollectedResource($accReceivableDetail)
                ];
                DB::commit();
            }
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Payment not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function update(Request $request,$id)
    {

        $penalty      = $request->paid_penalty??0;
        $waiv_penalty = $request->waiv_penalty??0;
        $paid_penalty = $penalty-$waiv_penalty;

        $acc_details = AccReceivableDetails::find($id);
        $acc         = AccReceivables::find($acc_details->acc_id);
        $client      = Client::find($acc->client_id);
        $total_unpaid= $acc->unreceived + $acc_details->received + $paid_penalty;

        $this->validate($request, [
            'chart_of_acc_id' => 'required',
            'received_date'   => 'required',
            'amount_repay'    => 'required|numeric|gte:'.'1'.'|lte:'.$total_unpaid,
        ]);

        try{
            DB::beginTransaction();

            $amount_repay       = $request->amount_repay - $penalty + $waiv_penalty;
            $total_received     = $amount_repay;
            $interest_per_month = $acc->interest_per_month;
            $operating_service  = $acc->operating_service;
            $received_date      = $request->received_date!=null?date('Y-m-d',strtotime($request->received_date)):date('Y-m-d');
            $maintenance_per_month= $acc->maintenance_per_month;

            $update_loan = Loan::find($acc->loan_id);
            $accReceivable = AccReceivables::find($acc_details->acc_id);
            $accReceivable->received_date = $received_date;
            // Decrease
            $accReceivable->received    -= $acc_details->received;
            $accReceivable->unreceived  -= $amount_repay;
            $accReceivable->penalty     -= $acc_details->paid_penalty;
            $accReceivable->waiv_penalty-= $acc_details->waiv_penalty;
            // Increase
            $accReceivable->received    += $amount_repay;
            $accReceivable->unreceived  += $acc_details->received;
            $accReceivable->penalty     += $paid_penalty;
            $accReceivable->waiv_penalty+= $waiv_penalty;
            $accReceivable->update();

            $updateAcc = AccReceivables::find($acc_details->acc_id);
            if($updateAcc->unreceived == 0) {
                $updateAcc->payment_status_id = 1; // Paid
                $next_payment = AccReceivables::where('loan_id',$acc->loan_id)->where('payment_status_id',3)->orderBy('payment_date','asc')->first();
                if($next_payment) {
                    $next_payment->open_close = 2;
                    $next_payment->update();
                }
            }
            else {
                $updateAcc->payment_status_id = 2; //Patail
            }
            $updateAcc->update();

            $paid_principal   = 0;
            $paid_interest    = 0;
            $paid_maintenance = 0;
            $paid_operating_service = 0;

            $sum_all_interest = AccReceivableDetails::where('acc_id',$acc_details->acc_id)->sum('paid_interest');
            $sumInterest = $sum_all_interest - $acc_details->paid_interest;
            if($sumInterest < $interest_per_month) {

                $subInterest = $interest_per_month-$sumInterest;
                if($amount_repay <= $subInterest) {
                    $paid_interest = $amount_repay;
                }
                else if($acc->operating_service>0 || $acc->maintenance_per_month>0){
                    $paid_interest    = $subInterest;
                    $amount_repay     = $amount_repay-$paid_interest;
                    $sum_all_op_service     = AccReceivableDetails::where('acc_id',$acc_details->acc_id)->sum('paid_operating_service');
                    $sumOperateService = $sum_all_op_service - $acc_details->paid_operating_service;

                    $subOpService = $operating_service-$sumOperateService;

                    if($amount_repay<=$subOpService) {
                        $paid_operating_service = $amount_repay;
                    }
                    else {
                        $paid_operating_service = $subOpService;
                        $amount_repay   = $amount_repay-$paid_operating_service;
                        $sum_all_maintenance = AccReceivableDetails::where('acc_id',$acc_details->acc_id)->sum('paid_maintenance');

                        $sumMaintenance = $sum_all_maintenance - $acc_details->paid_maintenance;
                        $subMaintenance = $maintenance_per_month-$sumMaintenance;

                        if($sumMaintenance<$maintenance_per_month)
                        {
                            if($amount_repay<=$subMaintenance)
                            {
                                $paid_maintenance = $amount_repay;
                            } else {
                                $paid_maintenance = $subMaintenance;
                                $paid_principal = $amount_repay-$subMaintenance;
                            }
                        } else {
                            $paid_principal = $amount_repay;
                        }
                    }
                }
                else {
                    $paid_interest = $subInterest;
                    $paid_principal = $amount_repay-$paid_interest;
                }
            }
            else {

                if($acc->operating_service>0 || $acc->maintenance_per_month>0) {

                    $sum_all_op_service = AccReceivableDetails::where('acc_id',$acc_details->acc_id)->sum('paid_operating_service');

                    $sumOperateService = $sum_all_op_service - $acc_details->paid_operating_service;
                    $subOpService = $operating_service - $sumOperateService;

                    if($sumOperateService<$operating_service) {

                        if($amount_repay<=$subOpService) {
                            $paid_operating_service = $amount_repay;
                        }
                        else {
                            $paid_operating_service = $subOpService;
                            $amount_repay = $amount_repay-$subOpService;

                            $sum_all_maintenance = AccReceivableDetails::where('acc_id',$acc_details->acc_id)->sum('paid_maintenance');
                            $sumMaintenance = $sum_all_maintenance - $acc_details->paid_maintenance;
                            $subMaintenance = $maintenance_per_month-$sumMaintenance;

                            if($sumMaintenance<$maintenance_per_month) {
                                if($amount_repay<=$subMaintenance) {
                                    $paid_maintenance = $amount_repay;
                                }
                                else {
                                    $paid_maintenance = $subMaintenance;
                                    $paid_principal = $amount_repay-$subMaintenance;
                                }
                            }
                            else {
                                $paid_principal = $amount_repay;
                            }
                        }
                    }
                    else {

                        $sum_all_maintenance = AccReceivableDetails::where('acc_id',$acc_details->acc_id)->sum('paid_maintenance');
                        $sumMaintenance = $sum_all_maintenance - $acc_details->paid_maintenance;
                        $subMaintenance = $maintenance_per_month-$sumMaintenance;
                        if($sumMaintenance<$maintenance_per_month)
                        {
                            if($amount_repay<=$subMaintenance) {
                                $paid_maintenance = $amount_repay;
                            }
                            else {
                                $paid_maintenance = $subMaintenance;
                                $paid_principal = $amount_repay-$subMaintenance;
                            }
                        }
                        else {
                            $paid_principal = $amount_repay;
                        }
                    }
                }
                else{
                    $paid_principal = $amount_repay;
                }
            }

            if($acc->currency_id == 1){
                $paid_interest          = round($paid_interest,-2,PHP_ROUND_HALF_ODD);
                $paid_operating_service = round($paid_operating_service,-2,PHP_ROUND_HALF_ODD);
                $paid_maintenance       = round($paid_maintenance,-2,PHP_ROUND_HALF_ODD);
                $paid_principal         = round($paid_principal,-2,PHP_ROUND_HALF_ODD);
            }
            else {
                $paid_interest          = round($paid_interest,2);
                $paid_operating_service = round($paid_operating_service,2);
                $paid_maintenance       = round($paid_maintenance,2);
                $paid_principal         = round($paid_principal,2);
            }
            // Update Acc Details Again!
            $accReceivableDetail = AccReceivableDetails::find($id);
            $accReceivableDetail->received_date     = $received_date;
            $accReceivableDetail->received          = $total_received;
            $accReceivableDetail->paid_principal    = $paid_principal;
            $accReceivableDetail->paid_interest     = $paid_interest;
            $accReceivableDetail->created_by        = Auth::user()->id;
            $accReceivableDetail->paid_maintenance  = $paid_maintenance;
            $accReceivableDetail->condition_payment = 1;
            $accReceivableDetail->paid_penalty      = $paid_penalty;
            $accReceivableDetail->waiv_penalty      = $waiv_penalty;
            $accReceivableDetail->chart_of_acc_id   = $request->chart_of_acc_id;
            $accReceivableDetail->unreceived        = $accReceivable->unreceived;
            $accReceivableDetail->paid_operating_service = $paid_operating_service;
            $accReceivableDetail->note = $request->note;
            $accReceivableDetail->update();
            // Decrease Loans
            $update_loan->decrement('paid_principal',$acc_details->paid_principal);
            $update_loan->decrement('paid_interest',$acc_details->paid_interest);
            $update_loan->decrement('paid_operating_service',$acc_details->paid_operating_service);
            $update_loan->decrement('paid_maintenance',$acc_details->paid_maintenance);
            // Increase Loans
            $update_loan->increment('balance_principal',$acc_details->paid_principal);
            $update_loan->increment('balance_interest',$acc_details->paid_interest);
            $update_loan->increment('balance_operating_service',$acc_details->paid_operating_service);
            $update_loan->increment('balance_maintenance',$acc_details->paid_maintenance);

            $update_loan->decrement('loan_in',$acc_details->received);
            $update_loan->increment('loan_balance',$acc_details->received);
            $update_loan->decrement('total_penalty',$acc_details->paid_penalty);
            $update_loan->decrement('total_waiv',$acc_details->waiv_penalty);
            // Update Loans Again!
            $update_loan->increment('paid_principal',$paid_principal);
            $update_loan->increment('paid_interest',$paid_interest);
            $update_loan->increment('paid_operating_service',$paid_operating_service);
            $update_loan->increment('paid_maintenance',$paid_maintenance);
            $update_loan->decrement('balance_principal',$paid_principal);
            $update_loan->decrement('balance_interest',$paid_interest);
            $update_loan->decrement('balance_operating_service',$paid_operating_service);
            $update_loan->decrement('balance_maintenance',$paid_maintenance);
            $update_loan->increment('loan_in',$total_received);
            $update_loan->decrement('loan_balance',$total_received);
            $update_loan->increment('total_penalty',$paid_penalty);
            $update_loan->increment('total_waiv',$waiv_penalty);
            // $update_loan->note = $request->note;
            $update_loan->update();
            // Update Loan status complete
            if( $update_loan->loan_balance == 0 || $update_loan->loan_balance <= 0.1){
                $update_loan->loan_status_id = 3;
                $update_loan->completed_date = date('Y-m-d');
                $update_loan->loan_balance   = 0;
            }
            $update_loan->update();
            // ActivityLog
            $user  = User::find(Auth::user()->id);
            $subject     = "កែប្រែការបង់ប្រាក់របស់អតិថិជន $client->name ដោយ $user->name.";
            $subject_type= get_class($acc_details);
            $subject_id  = $acc_details->id;
            $causer_type = get_class($user);
            $causer_id   = Auth::user()->id;
            $branch      = Auth::user()->branch_id;
            $log_name    = 'AccReceivableDetail Model';
            LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);
            $res = [
                'status' => 1,
                'message'=> "កែប្រែការបង់ប្រាក់របស់អតិថិជន $client->name ដោយជោគជ័យ",
                'data'   => [],
                'accID'  => $acc->id,
            ];
            DB::commit();
        } catch(Exception $e) {
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => "កែប្រែការបង់ប្រាក់របស់អតិថិជន $client->name ដោយមិនជោគជ័យ",
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function show($id)
    {
        $acc = AccReceivables::find($id);
        $client = Client::find($acc->client_id);

        $data = AccReceivableDetails::where('acc_id',$id)
        // ->whereIn('branch_id',Helper::byBranch())
        ->where('currency_id',Helper::byCurrency())
        ->get();

        $max_loan_receive = AccReceivableDetails::where('loan_id',$acc->loan_id)
        ->whereIn('branch_id',Helper::byBranch())
        ->where('currency_id',Helper::byCurrency())
        ->get()->max('id');

        return array(
            'client_name' => $client->name??'',
            'branch_id' => Auth::user()->branch_id,
            'max_id_details' => $max_loan_receive??'',
            'data' => CollectedResource::collection($data)
        );
    }

    public function destroy($id)
    {
        DB::beginTransaction();
        try {

            $detail = AccReceivableDetails::find($id);
            $client = Client::find($detail->client_id);

            if($detail->closing_by!=null){
                $accRe         = ChartOfAccount::find(6);      // 10006 Loan Out Standing
                $accInterest   = ChartOfAccount::find(19);    // 40002 Interest income
                $accPenalty    = ChartOfAccount::find(23);   // 40006 Penalty income
                $accOperating  = ChartOfAccount::find(24);  // 40007 Operating Services income
                $acc_recovery_loan_write_off = ChartOfAccount::find(66); // Recovery on Loans Write-Off

                $model_type   = 'App\Models\Accounting\ChartOfAccount';
                $journal_date = date('Y-m-d', strtotime($detail->closing_date));
                $branch_id    = $detail->branch_id;
                $currency_id  = $detail->currency_id;
                $created_by   = Auth::user()->id;
                $status       = 1;
                $user         = User::find(Auth::user()->id);
                $user_name    = $user->name;
                $desc = 'លុបការបង់ប្រាក់របស់អតិថិជនឈ្មោះ '.$client->name.' ដោយ '.$user_name.'';

                $paid_principal = $detail->paid_principal;
                $paid_interest  = $detail->paid_interest;
                $paid_penalty   = $detail->paid_penalty;
                $paid_operating_service = $detail->paid_operating_service;

                $total_recieved = $paid_principal + $paid_interest + $paid_operating_service + $paid_penalty;

                $parent_id = JournalAuto::findParentId();
                $obj = [
                    'payment_model_type'=> $model_type,
                    'payment_model_id'  => $detail->chart_of_acc_id,
                    'branch_id'         => $branch_id,
                    'created_by'        => $created_by,
                    'currency_id'       => $currency_id,
                    'journal_date'      => $journal_date,
                    'parent_id'         => $parent_id,
                    'chart_of_acc_id'   => $detail->chart_of_acc_id,
                    'credit'            => $total_recieved,
                    'debit'             => 0,
                    'desc'              => $desc,
                    'status'            => $status,
                ];
                JournalAuto::fInsertJournal($obj);

                if($detail->client_type == 1){
                    // ********** Reverse Amount Repay ********** //
                    if($paid_principal>0){
                        // A/R
                        $obj['debit']  = $paid_principal;
                        $obj['credit'] = 0;
                        $obj['chart_of_acc_id']  = $accRe->id;
                        $obj['payment_model_id'] = $accRe->id;
                        JournalAuto::fInsertJournal($obj);
                    }
                    if($paid_interest>0){
                        // Interest
                        $obj['debit']  = $paid_interest;
                        $obj['credit'] = 0;
                        $obj['chart_of_acc_id']  = $accInterest->id;
                        $obj['payment_model_id'] = $accInterest->id;
                        JournalAuto::fInsertJournal($obj);
                    }
                    if($paid_operating_service>0){
                        // Operating Service
                        $obj['debit']  = $paid_operating_service;
                        $obj['credit'] = 0;
                        $obj['chart_of_acc_id']  = $accOperating->id;
                        $obj['payment_model_id'] = $accOperating->id;
                        JournalAuto::fInsertJournal($obj);
                    }
                    if($paid_penalty>0){
                        // Penalty
                        $obj['debit']  = $paid_penalty;
                        $obj['credit'] = 0;
                        $obj['chart_of_acc_id']  = $accPenalty->id;
                        $obj['payment_model_id'] = $accPenalty->id;
                        JournalAuto::fInsertJournal($obj);
                    }
                } 
                else{
                    $obj['debit']  = $total_recieved;
                    $obj['credit'] = 0;
                    $obj['chart_of_acc_id']  = $acc_recovery_loan_write_off->id;
                    $obj['payment_model_id'] = $acc_recovery_loan_write_off->id;
                    JournalAuto::fInsertJournal($obj);
                }
            }

            // Update Loans
            $loan = Loan::find($detail->loan_id);
            $loan->increment('loan_balance',$detail->received);
            $loan->decrement('loan_in',$detail->received);
            $loan->decrement('paid_principal',$detail->paid_principal);
            $loan->decrement('paid_interest',$detail->paid_interest);
            $loan->decrement('paid_operating_service',$detail->paid_operating_service);
            $loan->decrement('paid_maintenance',$detail->paid_maintenance);
            $loan->increment('balance_principal',$detail->paid_principal);
            $loan->increment('balance_interest',$detail->paid_interest);
            $loan->increment('balance_operating_service',$detail->paid_operating_service);
            $loan->increment('balance_maintenance',$detail->paid_maintenance);
            $loan->decrement('total_penalty',$detail->paid_penalty);
            $loan->decrement('total_waiv',$detail->waiv_penalty);
            $loan->update();

            $acc = AccReceivables::find($detail->acc_id);
            $acc->increment('unreceived',$detail->received);
            $acc->decrement('received',$detail->received);
            $acc->decrement('penalty',$detail->paid_penalty);
            $acc->decrement('waiv_penalty',$detail->waiv_penalty);

            if($acc->received==0 && $acc->penalty==0) {
                $acc->payment_status_id = 3;
                $acc->received_date = null;
            } else {
                $acc->payment_status_id = 2;
            }
            $acc->update();

            $acc_num = $acc->num+1;
            $next = AccReceivables::where('num',$acc_num)->where('loan_id',$acc->loan_id)->first();
            if($next) {
                if($next->payment_status_id ==3) {
                    $next->open_close = 1;
                    $next->update();
                }
            }
            $update_loan = Loan::find($loan->id);
            if( $update_loan->loan_balance > 0) {
                $update_loan->loan_status_id = 2;
                $update_loan->completed_date = null;
                $update_loan->update();
            }

            AccReceivableDetails::where('id',$id)->delete();
            $user = User::find(Auth::user()->id);
            $subject     = "លុបការបង់ប្រាក់របស់អតិថិជន $client->name ដោយ $user->name.";
            $subject_type= get_class($acc);
            $subject_id  = $acc->id;
            $causer_type = get_class($user);
            $causer_id   = Auth::user()->id;
            $branch      = Auth::user()->branch_id;
            $log_name    = 'AccReceivables Model';
            LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);
            $res = [
                'status' => 1,
                'message'=> 'Deleted success',
                'accID'  => $detail->acc_id,
                'data'   => '',
            ];
            DB::commit();
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Deleted not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function ShowPayAll($id)
    {
        $showpayallid = decrypt_id($id);
        $sum_principal   = 0;
        $sum_interest    = 0;
        $sum_maintenance = 0;
        $sum_operat_service = 0;
        $penalty_pay_off    = 0;
        $accReceiveFirst = AccReceivables::where('loan_id',$showpayallid)->whereIn('payment_status_id',[2,3])->orderBy('payment_date','asc')->first();

        $loan = Loan::find($showpayallid);
        $balance_principal         = $loan->balance_principal;
        $balance_interest          = $loan->balance_interest;
        $balance_operating_service = $loan->balance_operating_service;
        $balance_maintenance       = $loan->balance_maintenance;

        $count_all  = AccReceivables::where('loan_id',$showpayallid)->whereIn('payment_status_id',[1,2,3])->get()->count();
        $percent_50 = ($count_all*50)/100;
        $count_paid = AccReceivables::where('loan_id',$showpayallid)->whereIn('payment_status_id',[1,2,3])->where('id','<=',$accReceiveFirst->id)->get()->count();
        if($count_paid <= $percent_50){
            $penalty_pay_off  = round(0.2*$accReceiveFirst->loan_balance,-2,PHP_ROUND_HALF_ODD);
        }


        if($loan->currency_id == 1) {
            $sum_principal      = round($balance_principal,-2, PHP_ROUND_HALF_ODD);
            $sum_interest       = round($balance_interest, -2, PHP_ROUND_HALF_ODD); 
            $sum_operat_service = round($balance_operating_service, -2, PHP_ROUND_HALF_ODD);
            $sum_maintenance    = round($balance_maintenance, -2, PHP_ROUND_HALF_ODD);
            $penalty_payoff     = round($penalty_pay_off, -2, PHP_ROUND_HALF_ODD);
        }
        else {
            $sum_principal      = round($balance_principal, 2);
            $sum_interest       = round($balance_interest, 2);
            $sum_operat_service = round($balance_operating_service, 2);
            $sum_maintenance    = round($balance_maintenance, 2);
            $penalty_payoff     = round($penalty_pay_off, 2);
        }
        return [
            'sum_principal'      => $sum_principal??0,
            'sum_interest'       => $sum_interest??0,
            'sum_operat_service' => $sum_operat_service??0,
            'sum_maintenance'    => $sum_maintenance??0,
            'penalty_payoff'     => $penalty_payoff??0,
            'note'               => '',
            // 'total_late'         => 0,
            'payment_date'       => $accReceiveFirst->payment_date??'',
        ];
    }

    public function SubmitPayAll(Request $request)
    {
        $loan_id = decrypt_id($request->id);
        $loan = Loan::find($loan_id);
        $amount_be_paid = $loan->loan_balance + $request->penalty_payoff;
        $this->validate($request, [
            'received_date'  => 'required',
            'chart_of_acc_id'=> 'required',
            'amountPay'      => 'required|numeric|gte:'.'0.01'.'|lte:'.$amount_be_paid,
        ]);

        try{
            DB::beginTransaction();

            $num =AccReceivables::where('loan_id',$loan_id)->max('num');
            $principal      = $request->sumPrincipal;
            $interest       = $request->sumInterest;
            $operat_service = $request->sumOperatService;
            $maintenance    = $request->sumMaintenance;
            $received_date  = $request->received_date;
            $penalty_payoff = $request->penalty_payoff;
            $total_received = $request->amountPay - $request->penalty_payoff;
            $received_date  = $received_date!=null?date('Y-m-d',strtotime($received_date)):date('Y-m-d');

            $back = AccReceivables::where('loan_id',$loan_id)->where('payment_status_id',3)->get();
            foreach($back as $val) {
                $back = new BackPayment();
                $back->acc_id                = $val->id;
                $back->loan_id               = $val->loan_id;
                $back->currency_id           = $val->currency_id;
                $back->client_id             = $val->client_id;
                $back->co_id                 = $val->co_id;
                $back->branch_id             = $val->branch_id;
                $back->payment_date          = $val->payment_date;
                $back->num                   = $val->num;
                $back->interest_per_month    = $val->interest_per_month;
                $back->operating_service     = $val->operating_service;
                $back->maintenance_per_month = $val->maintenance_per_month;
                $back->principal             = $val->principal;
                $back->loan_balance          = $val->loan_balance;
                $back->payment_per_month     = $val->payment_per_month;
                $back->unreceived            = $val->unreceived;
                $back->payment_status_id     = $val->payment_status_id;
                $back->open_close            = $val->open_close;
                $back->created_at            = $val->created_at;
                $back->updated_at            = $val->updated_at;
                $back->save();
            }
            AccReceivables::where('loan_id',$loan_id)->where('payment_status_id',3)->delete();
            AccReceivables::where('loan_id',$loan_id)->where('payment_status_id',2)->update(['payment_status_id' => 5]);

            $accReceivable = new AccReceivables();
            $accReceivable->payment_date          = $received_date;
            $accReceivable->received_date         = $received_date;
            $accReceivable->client_id             = $loan->client_id;
            $accReceivable->co_id                 = $loan->co_id;
            $accReceivable->branch_id             = $loan->branch_id;
            $accReceivable->loan_id               = $loan->id;
            $accReceivable->currency_id           = $loan->currency_id;
            $accReceivable->received              = $total_received;
            $accReceivable->unreceived            = 0;
            $accReceivable->num                   = $num+1;
            $accReceivable->principal             = $principal;
            $accReceivable->interest_per_month    = $interest;
            $accReceivable->operating_service     = $operat_service;
            $accReceivable->maintenance_per_month = $maintenance;
            $accReceivable->payment_per_month     = $total_received;
            $accReceivable->penalty               = $penalty_payoff;
            $accReceivable->payment_status_id     = 6;
            $accReceivable->open_close            = 2;
            $accReceivable->save();

            $accReceivableDetail = new AccReceivableDetails();
            $accReceivableDetail->acc_id           = $accReceivable->id;
            $accReceivableDetail->client_id        = $loan->client_id;
            $accReceivableDetail->co_id            = $loan->co_id;
            $accReceivableDetail->chart_of_acc_id  = $request->chart_of_acc_id;
            $accReceivableDetail->branch_id        = $loan->branch_id;
            $accReceivableDetail->created_by       = Auth::user()->id;
            $accReceivableDetail->loan_id          = $loan->id;
            $accReceivableDetail->currency_id      = $loan->currency_id;
            $accReceivableDetail->received_date    = $received_date;
            $accReceivableDetail->invoice_number   = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
            $accReceivableDetail->received         = $total_received;
            $accReceivableDetail->paid_principal   = $principal;
            $accReceivableDetail->paid_interest    = $interest;
            $accReceivableDetail->paid_operating_service = $operat_service;
            $accReceivableDetail->paid_maintenance = $maintenance;
            $accReceivableDetail->paid_penalty     = $penalty_payoff;
            $accReceivableDetail->condition_payment= 6;
            $accReceivableDetail->unreceived       = 0;
            $accReceivableDetail->note             = $request->note;
            $accReceivableDetail->client_type      = $loan->client_type;
            $accReceivableDetail->save();

            $update_loan = Loan::find($loan_id);
            $update_loan->balance_principal   = 0;
            $update_loan->balance_interest    = 0;
            $update_loan->balance_operating_service = 0;
            $update_loan->balance_maintenance = 0;
            $update_loan->loan_balance        = 0;
            $update_loan->loan_status_id      = 3;
            $update_loan->paid_principal      += $principal;
            $update_loan->paid_interest       += $interest;
            $update_loan->paid_operating_service   += $operat_service;
            $update_loan->paid_maintenance    += $maintenance;
            $update_loan->loan_in             += $total_received;
            $update_loan->total_penalty       += $penalty_payoff;
            $update_loan->completed_date      = $received_date;
            $update_loan->update();

            $user   = User::find(Auth::user()->id);
            $client = Client::find($loan->client_id);
            $subject     = "អតិថិជន $client->name បង់ប្រាក់ផ្ដាច់ ចំនួន $request->amountPay ដោយ $user->name.";
            $subject_type= get_class($loan);
            $subject_id  = $loan->id;
            $causer_type = get_class($user);
            $causer_id   = Auth::user()->id;
            $branch      = Auth::user()->branch_id;
            $log_name    = 'Loan Model';
            LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);

            DB::commit();
            $res = [
                'status' => 1,
                'message'=> "អតិថិជន $client->name បង់ប្រាក់ផ្ដាច់ ចំនួន $request->amountPay ដោយជោគជ័យ!",
            ];
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'អតិថិជនបង់ផ្ដាច់ដោយមិនបានជោគជ័យ',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function adminBackPayment($id)
    {
        try{
            DB::beginTransaction();
            $acc = AccReceivables::find($id);
            $acc_details = AccReceivableDetails::where('acc_id',$acc->id)->first();
            if($acc_details->closing_date!=null){
                $res = [
                    'status'  => 0,
                    'message' => "មិនអាចត្រឡប់ការបង់ប្រាក់មកវិញបានទេ ពីព្រោះលោកអ្នកបានបិទបញ្ជីរួចរាល់ហើយ!",
                ];
            }
            else {
                $loan_id  = $acc->loan_id;
                $principal= 0;
                $interest = 0;
                $operat_service     = 0;
                $maintenance = 0;
                $Back = BackPayment::where('loan_id',$loan_id)->where('status',1)->get();
                foreach($Back as $val) {
                    $principal      += $val->principal;
                    $interest       += $val->interest_per_month;
                    $operat_service += $val->operating_service;
                    $maintenance    += $val->maintenance_per_month;

                    AccReceivables::where('id',$val->acc_id)->withTrashed()->update([
                        'deleted_at' => NULL,
                    ]);
                }

                $patail_acc = AccReceivables::where('loan_id',$loan_id)->where('payment_status_id',5)->first();
                if($patail_acc) {
                    $paid_principal = AccReceivableDetails::where('acc_id',$patail_acc->id)->sum('paid_principal');
                    $paid_interest = AccReceivableDetails::where('acc_id',$patail_acc->id)->sum('paid_interest');
                    $paid_operating_service = AccReceivableDetails::where('acc_id',$patail_acc->id)->sum('paid_operating_service');
                    $paid_maintenance = AccReceivableDetails::where('acc_id',$patail_acc->id)->sum('paid_maintenance');

                    $unpaid_principal = $patail_acc->principal - $paid_principal;
                    $unpaid_interest = $patail_acc->interest_per_month - $paid_interest;
                    $unpaid_operating_service = $patail_acc->operating_service - $paid_operating_service;
                    $unpaid_maintenance = $patail_acc->maintenance_per_month - $paid_maintenance;

                    $total_unpaid_principal = $principal + $unpaid_principal;
                    $total_unpaid_interest  = $interest + $unpaid_interest;
                    $total_unpaid_operating_service = $operat_service + $unpaid_operating_service;
                    $total_unpaid_maintenance = $maintenance + $unpaid_maintenance;
                    // Update AccReceivables
                    $patail_acc->payment_status_id = 2; // បានបង់ខ្លះ
                    $patail_acc->update();
                } else {
                    $total_unpaid_principal = $principal;
                    $total_unpaid_interest = $interest;
                    $total_unpaid_operating_service = $operat_service;
                    $total_unpaid_maintenance = $maintenance;
                }
                $total_loan_balance = $total_unpaid_principal + $total_unpaid_interest + $total_unpaid_operating_service + $total_unpaid_maintenance;

                $loan = Loan::find($loan_id);
                $loan->loan_balance       = $total_loan_balance;
                $loan->balance_principal  = $total_unpaid_principal;
                $loan->balance_interest   = $total_unpaid_interest;
                $loan->balance_operating_service = $total_unpaid_operating_service;
                $loan->balance_maintenance= $total_unpaid_maintenance;
                $loan->decrement('loan_in',$acc->payment_per_month);
                $loan->decrement('paid_principal',$acc->principal);
                $loan->decrement('paid_interest',$acc->interest_per_month);
                $loan->decrement('paid_operating_service',$acc->operating_service);
                $loan->decrement('paid_maintenance',$acc->maintenance_per_month);
                $loan->decrement('total_penalty',$acc->penalty);
                $loan->loan_status_id = 2;
                $loan->completed_date = null;
                $loan->update();

                BackPayment::where('loan_id',$loan_id)->update(['status'=>2]);
                AccReceivables::where('id',$id)->delete();
                AccReceivableDetails::where('acc_id',$id)->delete();
                $back_payment = BackPayment::where('loan_id',$loan_id)->first();

                $user   = User::find(Auth::user()->id);
                $client = Client::find($acc->client_id);
                $subject     = "ត្រឡប់ប្រតិបត្តិការបង់ប្រាក់របស់អតិថិជន $client->name ដោយ $user->name.";
                $subject_type= get_class($back_payment);
                $subject_id  = $back_payment->id;
                $causer_type = get_class($user);
                $causer_id   = Auth::user()->id;
                $branch      = Auth::user()->branch_id;
                $log_name    = 'Loan Model';

                LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);
                DB::commit();
                $res = [
                    'status' => 1,
                    'message'=> 'ត្រឡប់ប្រតិបត្តិការបានដោយជោគជ័យ',
                ];
            }
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'ត្រឡប់ប្រតិបត្តិការមិនបានជោគជ័យ',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function Approve(Request $request)
    {
        $check = $request->checkBox;
        DB::beginTransaction();
        try {
            foreach($check as $value){
                $first_value = AccReceivableDetails::find($value['id']);
                $multiple_client_payment = AccReceivableDetails::where('co_id',$first_value->co_id)
                    ->where('received_date',$first_value->received_date)
                    ->where('chart_of_acc_id',$first_value->chart_of_acc_id)
                    ->where('client_type',$first_value->client_type)
                    ->where('status',1)
                    ->get();
                foreach($multiple_client_payment as $value){
                    $acc = AccReceivableDetails::where('id',$value['id'])->update([
                        'status' => 2,
                        'approved_by' => Auth::user()->id,
                    ]);
                }
            }
            $user = User::find(Auth::user()->id);
            $subject      = "បេឡាទទួលប្រាក់ពីមន្រ្តីឥណទាន ដោយ $user->name.";
            $subject_type = get_class($user);
            $subject_id   = $user->id;
            $causer_type  = get_class($user);
            $causer_id    = Auth::user()->id;
            $branch       = Auth::user()->branch_id;
            $log_name     = 'User Model';
            LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);
            $res = [
                'status' => 1,
                'message'=> 'Approve success',
                'data'   => $acc,
            ];
            DB::commit();
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Approve not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function funGroupAccReceivable()
    {
        $data = AccReceivables::where(function($query){
            $query->whereIn('co_id',Helper::group());
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
            $query->whereIn('payment_status_id',[2,3]);
            $query->where(DB::raw("DATE_FORMAT(payment_date, '%Y-%m-%d')"),'<=',date('Y-m-d'));
        })
        ->whereHas('loan',function($query){
            $query->whereIn('loan_status_id',[2,5]);
        })
        ->orderBy('payment_date','asc')
        ->orderBy('id','asc')
        ->groupby('loan_id');
        return $data;
    }

    public function statusLoan()
    {
        $data = Loan::whereIn('branch_id',Helper::byBranch())->where('currency_id',Helper::byCurrency())->whereIn('co_id',Helper::group());
        return $data;
    }

    public function Notification(Request $request)
    {
        $acc_good = $this->funGroupAccReceivable($request)
            ->whereHas('loan',function($query){
                $query->where('client_type',1);
            })->get();

        $acc_today = $acc_good->where('payment_date',date('Y-m-d'))->pluck('id');
        $count_good_loan = AccReceivables::whereIn('id',$acc_today)->count();

        $acc_late = $this->funGroupAccReceivable($request)
            ->whereHas('loan',function($query){
                $query->where('client_type',1);
            })->get();
        $ac_late = $acc_late->where('payment_date','<',date('Y-m-d'))->pluck('id');
        $count_late_loan = AccReceivables::whereIn('id',$ac_late)->count();

        $approve = Loan::where('loan_status_id',1)
        ->whereIn('co_id',Helper::group())
        ->whereIn('branch_id',Helper::byBranch())
        ->where('currency_id',Helper::byCurrency())
        ->count();

        $acc_write_off = $this->funGroupAccReceivable($request)
            ->whereHas('loan',function($query){
                $query->where('client_type',2);
            })->get();

        $pluck_id = $acc_write_off->where('payment_date','<',date('Y-m-d'))->pluck('id');
        $count_write_off = AccReceivables::whereIn('id',$pluck_id)->count();

        $count_cashier_not_approve = AccReceivableDetails::where(function($query){
            $query->where('status',1);
            $query->whereIn('co_id',Helper::group());
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
        })
        ->groupBy('co_id','received_date','chart_of_acc_id')->get()->count();

        $count_request_co    = $this->statusLoan()->where('loan_status_id',7)->count();
        $count_request_bm    = $this->statusLoan()->where('loan_status_id',8)->count();
        $count_loan_disburst = $this->statusLoan()->where('loan_status_id',1)->count();

        $count_collect_payment_on_day = Loan::where('loan_status_id',2)
            ->where(function($query){
                $query->whereHas('accReceivables', function ($q) {
                    $q->whereRaw('acc_receivables.id = (
                        SELECT id
                        FROM acc_receivables
                        WHERE acc_receivables.loan_id = loans.id
                        ORDER BY payment_date ASC, id ASC
                        LIMIT 1
                    )')
                    ->whereIn('payment_status_id',[2,3])
                    ->whereDate('payment_date', date('Y-m-d'));
                });
            })
            ->whereIn('branch_id',Helper::byBranch())
            ->where('currency_id',Helper::byCurrency())
            ->whereIn('co_id',Helper::group())
            ->where('client_type',1)
            ->get()
            ->count();

        return array(
            'approve'             => $approve,
            'count_write_off'     => $count_write_off,
            'count_request_co'    => $count_request_co,
            'count_request_bm'    => $count_request_bm,
            'count_loan_disburst' => $count_loan_disburst,
            'count_good_loan'     => $count_good_loan,
            'count_late_loan'     => $count_late_loan,
            'count_cashier_not_approve'    => $count_cashier_not_approve,
            'count_collect_payment_on_day' => $count_collect_payment_on_day??0,
        );
    }
}
