<?php

namespace App\Http\Controllers\Admin;

use Exception;
use Carbon\Carbon;
use App\Models\Loan;
use App\Models\User;
use App\Models\Branch;
use App\Models\Client;
use App\Helpers\Helper;
use App\Models\Currency;
use App\Models\Guarantor;
use App\Models\Reschedule;
use App\Models\BackPayment;
use App\Helpers\JournalAuto;
use App\Helpers\LogActivity;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Excel;
use App\Models\AccReceivables;
use App\Models\CollateralDetail;
use App\Models\LoanLossProvision;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Http\Resources\LoanResource;
use App\Http\Resources\UserResource;
use App\Models\AccReceivableDetails;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\ClientResource;
use App\Http\Resources\GuarantorResource;
use App\Models\Accounting\ChartOfAccount;
use App\Http\Resources\ShowPaymentResource;
use App\Http\Resources\CollateralDetailResource;
use App\Http\Resources\LoanCollateralResource;
use App\Http\Resources\LoanListResource;
use App\Models\LoanCollateral;

class LoanController extends Controller
{

    function __construct()
    {
        $this->middleware('permission:List of Client Disbursed|List of Loan Disbursement|List Request CO|List Request BM', ['only' => ['index']]);
        $this->middleware('permission:Loan Approve|List Request BM|List Request CO',['only' => ['update']]);
        $this->middleware('permission:Loan Delete', ['only' => ['destroy']]);
        $this->middleware('permission:Loan Create', ['only' => ['store','create','storeReschedule']]);
        $this->middleware('permission:Loan Edit',   ['only' => ['edit','create','storeReschedule']]);
        $this->middleware('permission:Transfer Loan To Branch', ['only' => ['submitLoanTransfer']]);
    }

    public function index(Request $request)
    {
        $per_page = $request->per_page == null?25: $request->per_page;
        $data = Loan::where(function($query) use ($request){
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
            $query->whereIn('co_id',Helper::group());
            if(!$request->date==[]){
                $query->whereBetween(DB::raw("DATE_FORMAT(installment_date, '%Y-%m-%d')"), $request->date);
            }
            if(!$request->client_id ==[]){
                $query->whereIn('client_id',$request->client_id);
            }
            if(!$request->co_id ==[]){
                $query->whereIn('co_id',$request->co_id);
            }
            if(!$request->term_condi_id == []){
                $query->whereIn('term_condi_id', $request->term_condi_id);
            }
            if(!$request->term_type ==[]) {
                $query->whereIn('term_type',$request->term_type);
            }

            if($request->check_list_loan==1){ // List Request, List Approve
                $query->where('loan_status_id',$request->loan_status_id); // 7=ស្នើរសុំកម្ចី, 1=កំពុងរងចាំ
            }
            else{
                $query->where('client_type',$request->client_type);
                $query->whereNotIn('loan_status_id',[1,4,7,8,9,10]);
                if(!$request->loan_status_id ==[]){
                    $query->whereIn('loan_status_id',$request->loan_status_id);
                }
                if(!$request->loan_code ==''){
                    $query->where('loan_code', 'LIKE', '%'.$request->loan_code.'%');
                }
                if(isset($request->write_off_date)){
                    $query->whereBetween(DB::raw("DATE_FORMAT(write_off_date, '%Y-%m-%d')"), $request->write_off_date);
                }
                if(!$request->as_of_date ==''){
                    $query->where(DB::raw("DATE_FORMAT(write_off_date, '%Y-%m-%d')"),'<=',$request->as_of_date);
                }
            }
        })
        ->orderBy('id','desc');

        if($request->per_page=="ALL" || $request->pagin == 'true'){
            return LoanListResource::collection($data->get());
        } else {
            return LoanListResource::collection($data->paginate($per_page));
        }
    }

    public function create(Request $request)
    {
        $currency_id = Auth::user()->currency_id;
        $loanID = decrypt_id($request->id);
        $loan = Loan::find($loanID);

        if($loan) {
            $res = [
                'status'      => 1,
                'currency_id' => $currency_id,
                'message'     => 'Get loan success',
                'data'        => new LoanResource($loan),
            ];
        }else{
            $res = [
                'status'      => 0,
                'currency_id' => $currency_id,
                'message'     => 'Get loan not found',
                'data'        => [],
            ];
        }
        return response()->json($res,200);
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'client_id'       => 'required',
            'co_id'           => 'required',
            'installment_date'=> 'required',
            'start_date'      => 'required',
            'chart_of_acc_id' => 'required',
            'condition_pay'   => 'required',
            'term_type'       => 'required',
            'period'          => 'required',
            'credit_type'     => 'required',
            'term_condi_id'   => 'required',
            'loan_out'        => 'required|numeric|gte:'.'1',
        ]);

        try{
            DB::beginTransaction();

            $checkLoanId = $request->id ? decrypt_id($request->id ) : null;

            $user   = User::find(Auth::user()->id);
            $client = Client::find($request->client_id);
            $format_loan_out = number_format($request->loan_out);

            if ($checkLoanId == '') {
                $count_client = Loan::where('client_id', $request->client_id)->whereIn('loan_status_id', [1, 2, 5, 7, 8])->count();
                $subject      = "បង្កើតកម្ចីថ្មីអតិថិជន $client->name ទំហំទឹកប្រាក់ $format_loan_out ដោយ $user->name.";
            } else {
                $count_client = 0;
                $subject      = "កែប្រែកម្ចីអតិថិជន $client->name ទំហំទឹកប្រាក់ $format_loan_out ដោយ $user->name.";
                AccReceivables::where('loan_id', $checkLoanId)->delete();
            }

            if($count_client==0){

                $loan = Loan::updateOrCreate(['id' => $this->getLoan($request)['id']],$this->getLoan($request));

                foreach($request->rows as $key => $value){
                    if($key==0){
                        $type_open_close = 2;
                    } else{
                        $type_open_close = 1;
                    }
                    $arr = array(
                        'loan_id'              => $loan->id,
                        'client_id'            => $request->client_id,
                        'co_id'                => $request->co_id,
                        'branch_id'            => Auth::user()->branch_id,
                        'currency_id'          => Helper::byCurrency(),
                        'num'                  => $key + 1,
                        'payment_date'         => date('Y-m-d', strtotime($value['payment_date'])),
                        'received_date'        => null,
                        'interest_per_month'   => $value['interestPerMonth']??0,
                        'operating_service'    => $value['operatService']??0,
                        'maintenance_per_month'=> $value['maintenancePerMonth']??0,
                        'principal'            => $value['principal']??0,
                        'loan_balance'         => $value['loan_balance']??0,
                        'payment_per_month'    => $value['payment_per_month']??0,
                        'unreceived'           => $value['payment_per_month']??0,
                        'created_at'           => new \DateTime(),
                        'payment_status_id'    => $loan->loan_status_id==1?4:3, // Pending
                        'open_close'           => $type_open_close,
                    );
                    AccReceivables::insert($arr);
                }
                // insert collateral to *LoanCollateral*
                $detailID = [];
                foreach($request->AddRemoveRows as $key => $ColDetail) {
                    if (!isset($ColDetail['collateral_detail_id']) || $ColDetail['collateral_detail_id'] == null) {
                        continue;
                    }
                    $detail_collate = [];
                    $detail_collate[] = $ColDetail['collateral_detail_id'];

                    if($detail_collate[0]!=null) {
                        $collateralDetail = LoanCollateral::updateOrCreate(
                            ['id' => $ColDetail['id']],
                            [
                                'loan_id'    => $loan->id,
                                'client_id'    => $loan->client_id,
                                'date_made'       => $ColDetail['date_made'] ?? now(),
                                'collateral_detail_id'=> $ColDetail['collateral_detail_id'],
                                'status'=> $ColDetail['status'],
                            ]
                        );
                        $detailID[] = $collateralDetail->id;
                    }
                }
                // if remove collateral in loan
                LoanCollateral::whereNotIn('id',$detailID)->where('loan_id',$loan->id)->update([
                    'deleted_at' => Carbon::now()
                ]);

                $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'=> $loan->wasRecentlyCreated?"បង្កើតកម្ចីថ្មីអតិថិជនឈ្មោះ $client->name ដោយជោគជ័យ":"កែប្រែកម្ចីនៃអតិថិជនឈ្មោះ $client->name ដោយជោគជ័យ",
                    'data'   => new LoanResource($loan),
                ];
            }
            else {
                $res = [
                    'status'  => 2,
                    'message' => 'អតិថិជនមិនទាន់បានបង់ផ្ដាច់ទេ!',
                ];
            }
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Loan create not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function getLoan($request)
    {
        $loanID = $request->id ? decrypt_id($request->id ) : null;

        if($request->id) {
            $level_loan = $request->level_loan;
        }
        else {
            $count = Loan::where('client_id',$request->client_id)->max('level_loan');
            if($count) {
                $level_loan = $count+1;
            } else {
                $level_loan = 1;
            }
        }
        $total_interest    = 0;
        $total_operat_service        = 0;
        $total_maintenance = 0;
        foreach($request->rows as $value) {
            $total_interest    += ($value['interestPerMonth']);
            $total_operat_service += ($value['operatService']);
            $total_maintenance += ($value['maintenancePerMonth']);
        }
        $row_period   = $request->rows;
        $last_row     = end($row_period);
        $new_object   = json_decode(json_encode($last_row));
        $expired_date = date('Y-m-d',strtotime($new_object->payment_date));
        // Value total
        $total_service    = $request->service>0&&$request->total_service==0?($request->loan_out*$request->service)/100:$request->total_service;
        $total_insurance  = $request->insurance>0&&$request->total_insurance==0?($request->loan_out*$request->insurance)/100:$request->total_insurance;
        $total_collection = $request->service_collection>0&&$request->total_collection==0?($request->loan_out*$request->service_collection)/100:$request->total_collection;
        $client = Client::find($request->client_id);
        $client_code = $client->code;

        $data = [
            'id'                   => $loanID,
            'client_id'            => $request->client_id,
            'loan_code'            => $request->loan_code??Helper::codeLoanAuto(Loan::class, Helper::prefix(), $client_code, 'loan_code',$level_loan),
            'co_id'                => $request->co_id,
            'chart_of_acc_id'      => $request->chart_of_acc_id,
            'term_condi_id'        => $request->term_condi_id,
            'branch_id'            => Auth::user()->branch_id,
            'currency_id'          => Helper::byCurrency(),
            'installment_date'     => date('Y-m-d', strtotime($request->installment_date)),
            'start_date'           => date('Y-m-d', strtotime($request->start_date)),
            'expired_date'         => $expired_date,
            'loan_out'             => $request->loan_out,
            'operating_service'    => $request->operating_service!=null?$request->operating_service:0,
            'total_operating_service'=> $total_operat_service??0,
            'interest'             => $request->interest!=null?$request->interest:0,
            'total_interest'       => $total_interest??0,
            'maintenance'          => $request->maintenance!=null?$request->maintenance:0,
            'total_maintenance'    => $total_maintenance??0,
            'service'              => $request->service??0,
            'total_service'        => $total_service??0,
            'service_collection'   => $request->service_collection??0,
            'total_collection'     => $total_collection??0,
            'insurance'            => $request->insurance??0,
            'total_insurance'      => $total_insurance??0,

            'saving'               => $request->saving??0,
            'total_saving'         => $request->total_saving??0,
            'period'               => $request->period,
            'level_loan'           => $level_loan,
            'condition_pay'        => $request->condition_pay,
            'loan_receive'         => $request->balance_principal + $total_interest + $total_operat_service + $total_maintenance,
            'loan_balance'         => $request->balance_principal + $total_interest + $total_operat_service + $total_maintenance,
            'amount_client_receive'=> $request->total_to_client>0?$request->total_to_client:$request->loan_out-$total_service-$total_collection-$total_insurance??0,
            'balance_principal'    => $request->balance_principal??0,
            'balance_interest'     => $total_interest,
            'balance_operating_service' => $total_operat_service,
            'balance_maintenance'  => $total_maintenance,
            'term_type'            => $request->term_type,
            'credit_type'          => $request->credit_type,
            'desc'                 => $request->desc,
            'type_loan'            => $request->type_loan,
            'loan_status_id'       => $request->id?$request->loan_status_id:1, // skip co,bm approve
            'client_type'          => $request->client_type
        ];
        return $data;
    }

    public function storeReschedule(Request $request)
    {
        if($request->principal_down>0 || $request->principal_add>0) {
            $this->validate($request, [
                'payment_method' => 'required',
            ]);
        }
        $this->validate($request, [
            'start_date'      => 'required',
            'condition_pay'   => 'required',
            'term_type'       => 'required',
            'period'          => 'required',
            'term_condi_id'   => 'required',
        ]);
        try{
            DB::beginTransaction();
            $loanID = decrypt_id($request->id);
            $arr_acc_details = AccReceivableDetails::where('loan_id',$loanID)->whereNull('closing_date')->get();
            if($arr_acc_details->count()>0) {
                $res = [
                    'status' => 0,
                    'message'=>'លោកអ្នកមិនអាចរៀបចំតារាងឡើងវិញបានទេ ព្រោះការទូទាត់ប្រាក់មិនទាន់បានបិទបញ្ជី!',
                ];
            }
            else {
                $not_complete = AccReceivables::where('loan_id',$loanID)->where('payment_status_id',2)->first();
                if($not_complete) {
                    $acc_detail = AccReceivableDetails::where('acc_id', $not_complete->id)->get();
                    $paid_principal         = $acc_detail->sum('paid_principal');
                    $paid_interest          = $acc_detail->sum('paid_interest');
                    $paid_operating_service = $acc_detail->sum('paid_operating_service');
                    $paid_maintenance       = $acc_detail->sum('paid_maintenance');

                    $updat_acc = AccReceivables::find($not_complete->id);
                    $updat_acc->payment_status_id     = 1;
                    $updat_acc->principal             = $paid_principal;
                    $updat_acc->interest_per_month    = $paid_interest ;
                    $updat_acc->operating_service     = $paid_operating_service ;
                    $updat_acc->maintenance_per_month = $paid_maintenance;
                    $updat_acc->payment_per_month     = $acc_detail->sum('received');
                    $updat_acc->received              = $acc_detail->sum('received');
                    $updat_acc->loan_balance          = ($not_complete->loan_balance+$not_complete->principal)-$paid_principal;
                    $updat_acc->unreceived            = 0;
                    $updat_acc->save();
                }
                if($request->principal_add>0) {
                    $lastnum = AccReceivables::where('loan_id',$loanID)->whereIn('payment_status_id',[1,2])->orderBy('id','desc')->first();
                    $request['id'] = null;
                    $request['loan_code'] = null;
                    $loan = Loan::updateOrCreate(['id' => $this->getLoan($request)['id']],$this->getLoan($request));

                    $findLoan = Loan::find($loanID);

                    $balance_pricipal = $findLoan->balance_principal;
                    $total_received   = $balance_pricipal + $request->penalty_interest;
                    $backDataAcc      = AccReceivables::where('loan_id',$loanID)->where('payment_status_id',3)->get();
                    foreach($backDataAcc 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',$loanID)->where('payment_status_id',3)->delete();

                    $new_acc = new AccReceivables();
                    $new_acc->loan_id            = $loanID;
                    $new_acc->client_id          = $request->client_id;
                    $new_acc->co_id              = $request->co_id;
                    $new_acc->branch_id          = Auth::user()->branch_id;
                    $new_acc->currency_id        = Helper::byCurrency();
                    $new_acc->num                = $lastnum==null?1:$lastnum->num+1;
                    $new_acc->payment_date       = date('Y-m-d');
                    $new_acc->received_date      = date('Y-m-d');
                    $new_acc->principal          = $balance_pricipal;
                    $new_acc->interest_per_month = $request->penalty_interest;
                    $new_acc->payment_per_month  = $total_received;
                    $new_acc->received           = $total_received;
                    $new_acc->operating_service  = 0;
                    $new_acc->open_close         = 2;
                    $new_acc->loan_balance       = 0;
                    $new_acc->unreceived         = 0;
                    $new_acc->created_at         = new \DateTime();
                    $new_acc->payment_status_id  = 8;
                    $new_acc->save();

                    $detail = new AccReceivableDetails();
                    $detail->loan_id           = $loanID;
                    $detail->client_id         = $request->client_id;
                    $detail->co_id             = $request->co_id;
                    $detail->created_by        = Auth::user()->id;
                    $detail->branch_id         = Auth::user()->branch_id;
                    $detail->currency_id       = Helper::byCurrency();
                    $detail->acc_id            = $new_acc->id;
                    $detail->received_date     = date('Y-m-d');
                    $detail->paid_interest     = $request->penalty_interest;
                    $detail->paid_principal    = $balance_pricipal;
                    $detail->received          = $total_received;
                    $detail->chart_of_acc_id   = $request->payment_method;
                    $detail->client_type       = $findLoan->client_type;
                    $detail->unreceived        = 0;
                    $detail->condition_payment = 8;
                    $detail->invoice_number    = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                    $detail->save();

                    foreach($request->rows as $key => $value) {
                        if($key==0){
                            $type_open_close = 2;
                        } else{
                            $type_open_close = 1;
                        }
                        $arr = array(
                            'loan_id'           => $loan->id,
                            'client_id'         => $request->client_id,
                            'co_id'             => $request->co_id,
                            'branch_id'         => Auth::user()->branch_id,
                            'currency_id'       => Helper::byCurrency(),
                            'num'               => $key + 1,
                            'payment_date'      => date('Y-m-d', strtotime($value['payment_date'])),
                            'received_date'     => null,
                            'interest_per_month'=> $value['interestPerMonth'],
                            'operating_service' => $value['operatService'],
                            'principal'         => $value['principal'],
                            'loan_balance'      => $value['loan_balance'],
                            'payment_per_month' => $value['payment_per_month'],
                            'unreceived'        => $value['payment_per_month'],
                            'created_at'        => new \DateTime(),
                            'payment_status_id' => $loan->loan_status_id==1?4:3, // Pending
                            'open_close'        => $type_open_close,
                        );
                        AccReceivables::insert($arr);
                    }

                    $reschedule = New Reschedule();
                    $reschedule->loan_id            = $loanID;
                    $reschedule->client_id          = $request->client_id;
                    $reschedule->co_id              = $request->co_id;
                    $reschedule->reschedule_service = $request->re_service??0;
                    $reschedule->reschedule_total   = $request->total_re??0;
                    $reschedule->service            = $request->service;
                    $reschedule->service_total      = $request->total_service;
                    $reschedule->date               = date('Y-m-d');
                    $reschedule->branch_id          = Auth::user()->branch_id;
                    $reschedule->currency_id        = Auth::user()->currency_id;
                    $reschedule->status             = 3;
                    $reschedule->amount             = $request->principal_add;
                    $reschedule->save();

                    $updateLoan = Loan::find($loanID);
                    $updateLoan->balance_principal         = 0;
                    $updateLoan->balance_interest          = 0;
                    $updateLoan->balance_operating_service = 0;
                    $updateLoan->balance_maintenance       = 0;
                    $updateLoan->loan_balance              = 0;
                    $updateLoan->loan_status_id            = 3;
                    $updateLoan->completed_date            = date('Y-m-d');
                    $updateLoan->increment('loan_in',$total_received);
                    $updateLoan->increment('paid_interest',$request->penalty_interest);
                    $updateLoan->increment('paid_principal', $balance_pricipal);
                    $updateLoan->update();
                }
                else {
                    $loan = Loan::updateOrCreate(['id' => $this->getLoan($request)['id']],$this->getLoan($request));
                    $firstAcc = AccReceivables::where('loan_id',$loanID)->orderBy('id','desc')->first();

                    if($request->principal_down>0) {
                        $new_acc = new AccReceivables();
                        $new_acc->loan_id           = $loanID;
                        $new_acc->client_id         = $request->client_id;
                        $new_acc->co_id             = $request->co_id;
                        $new_acc->branch_id         = Auth::user()->branch_id;
                        $new_acc->currency_id       = Helper::byCurrency();
                        $new_acc->num               = $firstAcc==null?1:$firstAcc->num+1;
                        $new_acc->payment_date      = date('Y-m-d');
                        $new_acc->received_date     = date('Y-m-d');
                        $new_acc->principal         = $request->principal_down;
                        $new_acc->interest_per_month= $request->penalty_interest;
                        $new_acc->operating_service = 0;
                        $new_acc->payment_per_month = $request->principal_down + $request->penalty_interest;
                        $new_acc->received          = $request->principal_down + $request->penalty_interest;
                        $new_acc->loan_balance      = $request->amount_principal;
                        $new_acc->open_close        = 2;
                        $new_acc->unreceived        = 0;
                        $new_acc->created_at        = new \DateTime();
                        $new_acc->payment_status_id = 9;
                        $new_acc->save();

                        $detail = new AccReceivableDetails();
                        $detail->loan_id           = $loanID;
                        $detail->client_id         = $request->client_id;
                        $detail->co_id             = $request->co_id;
                        $detail->created_by        = Auth::user()->id;
                        $detail->branch_id         = Auth::user()->branch_id;
                        $detail->currency_id       = Helper::byCurrency();
                        $detail->acc_id            = $new_acc->id;
                        $detail->paid_principal    = $request->principal_down;
                        $detail->paid_interest     = $request->penalty_interest;
                        $detail->received          = $request->principal_down+$request->penalty_interest;
                        $detail->received_date     = date('Y-m-d');
                        $detail->chart_of_acc_id   = $request->payment_method;
                        $detail->unreceived        = 0;
                        $detail->condition_payment = 9;
                        $detail->client_type       = $loan->client_type;
                        $detail->invoice_number    = Helper::invoiceNumberAuto(AccReceivableDetails::class, Helper::prefix(), 6, 'invoice_number');
                        $detail->save();

                        $reschedule = New Reschedule();
                        $reschedule->loan_id            = $loanID;
                        $reschedule->client_id          = $request->client_id;
                        $reschedule->co_id              = $request->co_id;
                        $reschedule->reschedule_service = $request->re_service??0;
                        $reschedule->reschedule_total   = $request->total_re??0;
                        $reschedule->penalty_interest   = $request->penalty_interest;;
                        $reschedule->date               = date('Y-m-d');
                        $reschedule->branch_id          = Auth::user()->branch_id;
                        $reschedule->currency_id        = Auth::user()->currency_id;
                        $reschedule->status             = 1;
                        $reschedule->amount             = $request->principal_down;
                        $reschedule->save();

                        $loan_principal = Loan::find($loanID);
                        $loan_principal->reschedule_amount += $request->principal_down;
                        $loan_principal->loan_in           += $request->principal_down+$request->penalty_interest;
                        $loan_principal->paid_principal    += $request->principal_down;
                        $loan_principal->paid_interest     += $request->penalty_interest;
                        $loan_principal->update();
                    }
                    AccReceivables::where('loan_id',$loanID)->where('payment_status_id',3)->delete();
                    foreach($request->rows as $key => $value){
                        if($key==0) {
                            $type_open_close = 2;
                        } else{
                            $type_open_close = 1;
                        }
                        $arr = array(
                            'loan_id'           => $loan->id,
                            'client_id'         => $request->client_id,
                            'co_id'             => $request->co_id,
                            'branch_id'         => Auth::user()->branch_id,
                            'currency_id'       => Helper::byCurrency(),
                            'num'               => $key + 1,
                            'payment_date'      => date('Y-m-d', strtotime($value['payment_date'])),
                            'received_date'     => null,
                            'interest_per_month'=> $value['interestPerMonth'],
                            'operating_service' => $value['operatService'],
                            'principal'         => $value['principal'],
                            'loan_balance'      => $value['loan_balance'],
                            'payment_per_month' => $value['payment_per_month'],
                            'unreceived'        => $value['payment_per_month'],
                            'created_at'        => new \DateTime(),
                            'payment_status_id' => $loan->loan_status_id==1?4:3, // Pending
                            'open_close'        => $type_open_close,
                        );
                        AccReceivables::insert($arr);
                    }
                }

                $user   = User::find(Auth::user()->id);
                $client = Client::find($loan->client_id);
                if($request->principal_add>0){
                    $subject = "អតិថិជន $client->name កាច់លុយកម្ចីចំនួនទំហំទឹកប្រាក់ $request->loan_out ដោយ $user->name.";
                } else{
                    $subject = "រៀបចំតារាងកម្ចីអតិថិជន $client->name ទំហំទឹកប្រាក់ $request->loan_out ដោយ $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);

                $res = [
                    'status' => 1,
                    'message'=> $loan->wasRecentlyCreated?'កម្ចីថ្មីបង្កើតដោយជោគជ័យ':'រៀបតារាងឡើងវិញដោយជោគជ័យ',
                    'data'   => new LoanResource($loan),
                ];
            }
            DB::commit();
        } catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Loan Client not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function update($id,Request $request)
    {
        $loantID1 = decrypt_id($id);
        $loan = Loan::find($loantID1);
        $loan->loan_status_id = $request->status_approve;
        $loan->approved_by = Auth::user()->id;
        $loan->update();

        $client = Client::find($loan->client_id);
        $client_name = $client->name;
        $user   = User::find(Auth::user()->id);
        $user_name  = $user->name;

        if($request->status_approve==2){
            // Loan::where('id',$id)->update([
            //     'closing_date' => date('Y-m-d H:i:s'),
            //     'closing_by' => Auth::user()->id,
            // ]);
            // $acc_loan_outstanding = ChartOfAccount::find(4);     // Standard Loans-Individuals<=1year
            // $acc_service_income   = ChartOfAccount::find(158);  // Administration Fees
            // $acc_insurance_income = ChartOfAccount::find(159); // Insurance fee
            // $payment_method       = ChartOfAccount::find($loan->chart_of_acc_id);

            // $model_type = 'App\Models\Accounting\ChartOfAccount';
            // $parent_id  = JournalAuto::findParentId();
            // $desc_disrt = 'ចំណាយទឹកប្រាក់កម្ចីផ្ដល់អោយអតិថិជនឈ្មោះ '.$client_name.' និងបិទបញ្ជីដោយ '.$user_name.'';
            // $desc_service = 'ចំណូលបានមកពីសេវារដ្ឋបាលពីអតិថិជនឈ្មោះ '.$client_name.' និងបិទបញ្ជីដោយ '.$user_name.'';
            // $desc_insurance = 'ចំណូលបានមកពីសេវាធានារ៉ាប់រងពីអតិថិជនឈ្មោះ '.$client_name.' និងបិទបញ្ជីដោយ '.$user_name.'';
            // $created_by = Auth::user()->id;
            // $status = 1;

            // // 1.ចំណាយទឹកប្រាក់កម្ចី
            // $obj = [
            //     'payment_model_type'=> $model_type,
            //     'payment_model_id'  => $acc_loan_outstanding, // Standard Loans-Individuals<=1year
            //     'branch_id'         => $loan->branch_id,
            //     'created_by'        => $created_by,
            //     'currency_id'       => $loan->currency_id,
            //     'journal_date'      => date('Y-m-d'),
            //     'parent_id'         => $parent_id,
            //     'chart_of_acc_id'   => $acc_loan_outstanding->id,
            //     'credit'            => 0,
            //     'debit'             => $loan->loan_out,
            //     'desc'              => $desc_disrt,
            //     'status'            => $status,
            //     'invoice_number'    => $loan->loan_code,
            // ];
            // JournalAuto::fInsertJournal($obj);

            // $obj['debit']  = 0;
            // $obj['credit'] = $loan->loan_out;
            // $obj['chart_of_acc_id']  = $payment_method->id;
            // $obj['payment_model_id'] = $payment_method->id;
            // JournalAuto::fInsertJournal($obj);

            // // 2.សេវារដ្ឋបាល
            // if($loan->total_service>0)
            // {
            //     $obj['debit']  = $loan->total_service;
            //     $obj['credit'] = 0;
            //     $obj['desc']   = $desc_service;
            //     $obj['chart_of_acc_id']  = $payment_method->id;
            //     $obj['payment_model_id'] = $payment_method->id;
            //     JournalAuto::fInsertJournal($obj);

            //     $obj['debit']  = 0;
            //     $obj['credit'] = $loan->total_service;
            //     $obj['desc']   = $desc_service;
            //     $obj['chart_of_acc_id']  = $acc_service_income->id;
            //     $obj['payment_model_id'] = $acc_service_income->id;
            //     JournalAuto::fInsertJournal($obj);
            // }

            // // 3.សេវាធានារ៉ាប់រង
            // if($loan->total_insurance>0)
            // {
            //     $obj['debit']  = $loan->total_insurance;
            //     $obj['credit'] = 0;
            //     $obj['desc'] = $desc_insurance;
            //     $obj['chart_of_acc_id']  = $payment_method->id;
            //     $obj['payment_model_id'] = $payment_method->id;
            //     JournalAuto::fInsertJournal($obj);

            //     $obj['debit']  = 0;
            //     $obj['credit'] = $loan->total_insurance;
            //     $obj['desc']   = $desc_insurance;
            //     $obj['chart_of_acc_id']  = $acc_insurance_income->id;
            //     $obj['payment_model_id'] = $acc_insurance_income->id;
            //     JournalAuto::fInsertJournal($obj);
            // }
            AccReceivables::where('loan_id',$loantID1)->update(['payment_status_id'=>3]);
        }
        $subject      = "អនុញ្ញាតចេញកម្ចីអោយអតិថិជន $client_name ទំហំទឹកប្រាក់ $loan->loan_out ដោយ $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);
        $res = [
            'status' => 1,
            'message'=> 'Approved Client success',
        ];
        return response()->json($res,200);
    }

    public function destroy($id)
    {

        DB::beginTransaction();
        $loanID2 = decrypt_id($id);
        try {
            $loan = Loan::find($loanID2);
            $loan->loan_status_id = 9;
            $loan->update();
            $loan->delete();

            AccReceivables::where('loan_id',$loanID2)->delete();
            $user   = User::find(Auth::user()->id);
            $client = Client::find($loan->client_id);

            if($loan->closing_by!=null){
                $acc_loan_out_standing = ChartOfAccount::find(6); // Loan Out Standing
                $acc_service  = ChartOfAccount::find(21); // Administrative service income

                $model_type   = 'App\Models\Accounting\ChartOfAccount';
                $journal_date = date('Y-m-d', strtotime($loan->closing_date));
                $branch_id    = $loan->branch_id;
                $currency_id  = $loan->currency_id;
                $created_by   = Auth::user()->id;
                $status       = 1;
                $user         = User::find(Auth::user()->id);
                $user_name    = $user->name;
                $desc = 'លុបកម្ចីរបស់អតិថិជនឈ្មោះ '.$client->name.' ដោយ '.$user_name.'';
                $parent_id = JournalAuto::findParentId();
                $obj = [
                    'payment_model_type'=> $model_type,
                    'payment_model_id'  => $loan->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'   => $loan->chart_of_acc_id,
                    'credit'            => 0,
                    'debit'             => $loan->loan_out,
                    'desc'              => $desc,
                    'status'            => $status,
                ];
                JournalAuto::fInsertJournal($obj);

                $obj['debit']  = 0;
                $obj['credit'] = $loan->loan_out;
                $obj['chart_of_acc_id']  = $acc_loan_out_standing->id;
                $obj['payment_model_id'] = $acc_loan_out_standing->id;
                JournalAuto::fInsertJournal($obj);

                if($loan->total_service>0){
                    $obj['debit']  = $loan->total_service;
                    $obj['credit'] = 0;
                    $obj['chart_of_acc_id']  = $acc_service->id;
                    $obj['payment_model_id'] = $acc_service->id;
                    JournalAuto::fInsertJournal($obj);

                    $obj['debit']  = 0;
                    $obj['credit'] = $loan->total_service;
                    $obj['chart_of_acc_id']  =$loan->chart_of_acc_id;
                    $obj['payment_model_id'] =$loan->chart_of_acc_id;
                    JournalAuto::fInsertJournal($obj);
                }
            }

            $subject     = "បដិសេធកម្ចីរបស់អតិថិជន $client->name ទំហំទឹកប្រាក់ $loan->loan_out ដោយ $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);
            $res = [
                'status' => 1,
                'message'=> 'Delete success',
                'data'   => $loan,
            ];
            DB::commit();
        }catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Delete not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }
    public function LoanReject(Request $request, $id)
    {
        DB::beginTransaction();
        $loanID2 = decrypt_id($id);

        try {
            $loan = Loan::findOrFail($loanID2);

            $loan->loan_status_id = 10;
            $loan->desc = $request->desc;
            $loan->update();

            $user   = Auth::user();
            $client = Client::find($loan->client_id);

            $subject      = "បដិសេធកម្ចីរបស់អតិថិជន $client->name ទំហំទឹកប្រាក់ $loan->loan_out ដោយ $user->name.";
            LogActivity::addToLog(
                $subject,
                Loan::class,
                $loan->id,
                User::class,
                $user->id,
                $user->branch_id,
                'Loan Model'
            );

            DB::commit();

            return response()->json([
                'status'  => 1,
                'message' => 'Reject success',
                'data'    => $loan,
            ], 200);

        } catch (Exception $e) {
            DB::rollBack();
            return response()->json([
                'status'  => 0,
                'message' => 'Reject not success',
                'data'    => $e->getMessage(),
            ], 200);
        }
    }
    public function ShowPayment($id)
    {
        try {
            // ---- 1. SAFE DECRYPT ----
            $checkloanID = decrypt_id($id);

            // ---- 2. LOAD LOAN ----
            $loan = Loan::find($checkloanID);

            // ---- 3. LOAD RELATED DATA ----
            $client   = Client::find($loan->client_id);
            $co       = User::find($loan->co_id);
            $currency = Currency::find($loan->currency_id);

            // Receivables
            $data = AccReceivables::where('loan_id', $checkloanID)
                ->where('payment_status_id', '<>', 7)
                ->orderBy('payment_date', 'asc')
                ->get();

            $count = ceil($data->count() / 2);

            $percent_50 = ($data->count()*70)/100;

            // ---- 4. GUARANTORS ----
            $garuantor1 = Guarantor::where('client_id', $client->id)->where('type', 1)->first();
            $garuantor2 = Guarantor::where('client_id', $client->id)->where('type', 2)->first();
            $garuantor3 = Guarantor::where('client_id', $client->id)->where('type', 3)->first();

            // ---- 5. COLLATERALS ----
            $realestate = LoanCollateral::where('loan_id', $checkloanID)->whereHas('collateralDetails', fn($q) => $q->whereIn('status_type',[1,2]))->get();
            $motos = LoanCollateral::where('loan_id', $checkloanID)->whereHas('collateralDetails', fn($q) => $q->whereIn('status_type',[3,4]))->get();
            $other = LoanCollateral::where('loan_id', $checkloanID)->whereHas('collateralDetails', fn($q) => $q->whereIn('status_type',[5,6]))->get();

            // $collateral_land_first = LoanCollateral::where('loan_id', $checkloanID)
            //     ->whereHas('collateralDetails', fn($q) => $q->where('status_type', 1))
            //     ->first();

            // $collateral_land_second = LoanCollateral::where('loan_id', $checkloanID)
            //     ->whereHas('collateralDetails', fn($q) => $q->where('status_type', 2))
            //     ->first();

            // $collateral_motor_first = LoanCollateral::where('loan_id', $checkloanID)
            //     ->whereHas('collateralDetails', fn($q) => $q->where('status_type', 3))
            //     ->first();

            // $collateral_motor_second = LoanCollateral::where('loan_id', $checkloanID)
            //     ->whereHas('collateralDetails', fn($q) => $q->where('status_type', 4))
            //     ->first();

            // $collateral_all = LoanCollateral::where('loan_id', $checkloanID)->get();

            // ---- 6. Representative ----
            $userRepre = optional($loan->branchs->UserBranRepre()->where('is_representative', 1)->first());

            // ---- 7. RESPONSE ----
            return response()->json([
                'percent_50'    => floor($percent_50),
                'status'        => 1,
                'countPay'      => $count,
                'currency'      => $currency,
                'garuantor1'    => $garuantor1 ? new GuarantorResource($garuantor1) : null,
                'garuantor2'    => $garuantor2 ? new GuarantorResource($garuantor2) : null,
                'garuantor3'    => $garuantor3 ? new GuarantorResource($garuantor3) : null,
                'co'            => new UserResource($co),
                'loan'          => new LoanResource($loan),
                'client'        => new ClientResource($client),
                'realestate'    => LoanCollateralResource::collection($realestate)??[],
                'motos'         => LoanCollateralResource::collection($motos)??[],
                'other'         => LoanCollateralResource::collection($other)??[],
                // 'collateral_land_first'  => $collateral_land_first ? new LoanCollateralResource($collateral_land_first) : null,
                // 'collateral_land_second' => $collateral_land_second ? new LoanCollateralResource($collateral_land_second) : null,
                // 'collateral_motor_first' => $collateral_motor_first ? new LoanCollateralResource($collateral_motor_first) : null,
                // 'collateral_motor_second'=> $collateral_motor_second ? new LoanCollateralResource($collateral_motor_second) : null,
                // 'collateral_all' => LoanCollateralResource::collection($collateral_all),
                'data'          => ShowPaymentResource::collection($data),
                'repre_name'    => $userRepre->name ?? '',
            ], 200);

        } catch (\Exception $e) {
            return response()->json([
                'status'  => 0,
                'message' => 'Error loading payment data',
                'error'   => $e->getMessage(),
            ], 200);
        }
    }

    public function HistoryPayment($id)
    {
        $loan   = Loan::find($id);
        $client = Client::find($loan->client_id);
        $data   = AccReceivables::where('loan_id', $id) ->where('payment_status_id', '<>', 7)->orderBy('id', 'asc')->get();
        return [
            'data'   => ShowPaymentResource::collection($data),
            'client' => new ClientResource($client),
            'loan'   => new LoanResource($loan),
        ];
    }

    public function ShowClientPayment($id)
    {
        $loan = Loan::find($id);
        $acc = AccReceivables::where('loan_id',$id)->where('payment_status_id',1)->get()->count();
        $acc_unpaid = AccReceivables::where('loan_id',$id)->whereIn('payment_status_id',[2,3])->first();
        return [
            'loan' => new LoanResource($loan),
            'acc_unpaid' => new ShowPaymentResource($acc_unpaid),
            'count_paid' => $acc+1,
        ];
    }

    public function GetPayment($id)
    {
        $getID = decrypt_id($id);
        $data = AccReceivables::where('loan_id',$getID)->orderBy('payment_date','asc')->get();
        $loan = Loan::find($getID);
        $client = Client::find($loan->client_id);

        return [
            'data' =>ShowPaymentResource::collection($data),
            'client' =>new ClientResource($client),
        ];
    }

    public function getLoanPayment(Request $request)
    {
        $per_page = $request->per_page == null?25: $request->per_page;
        $data = Loan::whereHas('client', function ($query) use ($request) {
            if(!$request->loan_code ==''){
                $query->where('loans.loan_code', 'LIKE', '%'.$request->loan_code.'%');
            }
            if(!$request->client_id ==[]){
                $query->whereIn('client_id',$request->client_id);
            }
            if(!$request->co_id ==[])
            {
                $query->whereIn('co_id',$request->co_id);
            }
        })
        ->where(function($query){
            $query->whereIn('co_id',Helper::group());
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
            $query->whereIn('loan_status_id',[2,5]);
        })
        ->orderBy('id','DESC')
        ->paginate($per_page);
        return LoanResource::collection($data);
    }

    public function getContractDay($id)
    {
        $loan    = Loan::find($id);
        $currency= Currency::find($loan->currency_id);
        $client  = Client::find($loan->client_id);
        $profile = Guarantor::where('client_id',$loan->client_id)->where('type',1)->first();
        $one     = Guarantor::where('client_id',$loan->client_id)->where('type',2)->first();
        $two     = Guarantor::where('client_id',$loan->client_id)->where('type',3)->first();
        $collateral_detail = CollateralDetail::where('loan_id',$id)->where('status_type',1)->get();

        return [
            'currency'   => $currency,
            'loan'       => new LoanResource($loan),
            'client'     => new ClientResource($client),
            'profile'    => $profile?(new GuarantorResource($profile)):null,
            'one'        => $one?(new GuarantorResource($one)):null,
            'two'        => $two?(new GuarantorResource($two)):null,
            'collateral_detail' => $collateral_detail?(CollateralDetailResource::collection($collateral_detail)):null,
        ];
    }

    public function MoveCo(Request $request)
    {
        // dd($request->from_co_id);
        $this->validate($request, [
            // 'from_co_id' => 'required',
            'to_co_id'   => 'required',
        ]);
        DB::beginTransaction();
        try {
            $loanid = decrypt_id($request->loan_id);
            // if($request->loan_id=='' && $request->type_move == false) {
            //     Loan::where('co_id',$request->from_co_id)->update([
            //         'co_id' => $request->to_co_id
            //     ]);
            //     AccReceivables::where('co_id',$request->from_co_id)->update([
            //         'co_id' => $request->to_co_id
            //     ]);
            //     AccReceivableDetails::where('co_id',$request->from_co_id)->update([
            //         'co_id' => $request->to_co_id
            //     ]);
            // }
            // else if($request->loan_id!='' && $request->type_move == true) {
            $loan = Loan::find($loanid);
            $from = User::find($loan->co_id);  // Old co

            Loan::where('id',$loanid)->update([
                'co_id' => $request->to_co_id
            ]);
            AccReceivables::where('loan_id',$loanid)->update([
                'co_id' => $request->to_co_id
            ]);
            AccReceivableDetails::where('loan_id',$loanid)->update([
                'co_id' => $request->to_co_id
            ]);
            // }
            $user = User::find(Auth::user()->id);
            $to   = User::find($request->to_co_id);
            $subject      = "ប្ដូរពីមន្រ្តីឥណទាន  $from->name ទៅមន្រ្តីឥណទាន $to->name ដោយ $user->name.";
            $subject_type = get_class($from);
            $subject_id   = $from->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);
            $res = [
                'status'  => 1,
                'message' => 'Move success',
                'data'    => $user,
            ];
            DB::commit();
        } catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Move not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }

    public function moveToWriteOff($id)
    {

        $arr_acc_details = AccReceivableDetails::where('loan_id',$id)->whereNull('closing_date')->get();
        if($arr_acc_details->count()>0) {
            $res = [
                'status' => 0,
                'message'=>'លោកអ្នកមិនអាចប្តូរទៅអតិថិជនខូចបានទេ ព្រោះការទូទាត់ប្រាក់មិនទាន់បានបិទបញ្ជី!',
            ];
        }
        else {
            $user = User::find(Auth::user()->id);
            $loan_id = decrypt_id($id);
            $loan = Loan::find($loan_id);
            // dd($loan_id);
            $loan->write_off_date = date('Y-m-d');
            $loan->client_type = 2;
            $loan->update();
            // Journal to Write Off
            $acc_loan_outstanding = ChartOfAccount::find(6);   // Loan Out Standing
            $acc_loan_write_off   = ChartOfAccount::find(65); // Loan Write-off Expense
            // Loan Write-off Expense
            $obj = [
                'payment_model_type'=> 'App\Models\Accounting\ChartOfAccount',
                'payment_model_id'  => $acc_loan_write_off->id,
                'branch_id'         => Auth::user()->branch_id,
                'created_by'        => Auth::user()->id,
                'currency_id'       => Auth::user()->currency_id,
                'journal_date'      => date('Y-m-d'),
                'parent_id'         => JournalAuto::findParentId(),
                'chart_of_acc_id'   => $acc_loan_write_off->id,
                'debit'             => $loan->balance_principal,
                'credit'            => 0,
                'desc'              => 'ចំណាយទឹកប្រាក់ Write Off នៃអតិថិជន '.$loan->client->name.' និងធ្វើប្រតិបត្តិការដោយ '.$user->name.'',
                'status'            => 1,
            ];
            JournalAuto::fInsertJournal($obj);
            // Loan Out Standing
            $obj['debit']  = 0;
            $obj['credit'] = $loan->balance_principal;
            $obj['chart_of_acc_id']  = $acc_loan_outstanding->id;
            $obj['payment_model_id'] = $acc_loan_outstanding->id;
            JournalAuto::fInsertJournal($obj);

            $user = User::find(Auth::user()->id);
            $client  = Client::find($loan->client_id);
            $subject = "អតិថិជន $client->name បានផា្លស់ប្ដូរទៅអតិថិជនខូច ដោយ $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);

            $res = [
                'status' => 1,
                'message'=> 'Client Move to Write Off success',
                'data'   => new LoanResource($loan),
            ];
        }
        return response()->json($res,200);
    }
    public function moveToWriteOffMultiple(Request $request)
    {
        $this->validate($request, [
            'checkArrLoan' => 'required|array|min:1',
        ]);

        if (count($request->checkArrLoan) > 50) {
            return response()->json([
                'status' => 0,
                'message' => 'You cannot move more than 50 loans to write-off at one time.',
            ], 200);
        }

        try {
            DB::beginTransaction();

            $user = Auth::user();

            foreach ($request->checkArrLoan as $value) {

                $loan_id = decrypt_id($value);
                $loan = Loan::find($loan_id);

                if (!$loan) continue;

                $loan->update([
                    'write_off_date' => date('Y-m-d'),
                    'client_type'    => 2,
                ]);

                $acc_loan_outstanding = ChartOfAccount::find(6);
                $acc_loan_write_off   = ChartOfAccount::find(65);

                $obj = [
                    'payment_model_type' => 'App\Models\Accounting\ChartOfAccount',
                    'payment_model_id'   => $acc_loan_write_off->id,
                    'branch_id'          => $user->branch_id,
                    'created_by'         => $user->id,
                    'currency_id'        => $user->currency_id,
                    'journal_date'       => date('Y-m-d'),
                    'parent_id'          => JournalAuto::findParentId(),
                    'chart_of_acc_id'    => $acc_loan_write_off->id,
                    'debit'              => $loan->balance_principal,
                    'credit'             => 0,
                    'desc'               => 'ចំណាយទឹកប្រាក់ Write Off នៃអតិថិជន ' . $loan->client->name . ' និងធ្វើប្រតិបត្តិការដោយ ' . $user->name,
                    'status'             => 1,
                ];
                JournalAuto::fInsertJournal($obj);

                $obj['debit']              = 0;
                $obj['credit']             = $loan->balance_principal;
                $obj['chart_of_acc_id']    = $acc_loan_outstanding->id;
                $obj['payment_model_id']   = $acc_loan_outstanding->id;

                JournalAuto::fInsertJournal($obj);

                $client  = Client::find($loan->client_id);
                $subject = "អតិថិជន $client->name បានផ្លាស់ប្ដូរទៅអតិថិជនខូច ដោយ $user->name.";

                LogActivity::addToLog(
                    $subject,
                    get_class($loan),
                    $loan->id,
                    get_class($user),
                    $user->id,
                    $user->branch_id,
                    'Loan Model'
                );
            }

            DB::commit();

            return response()->json([
                'status' => 1,
                'message' => 'Loan transfer success',
            ], 200);

        } catch (Exception $e) {

            DB::rollBack();

            return response()->json([
                'status' => 0,
                'message' => 'Loan transfer not success',
                'data' => $e->getMessage(),
            ], 200);
        }
    }

    public function multipleMoveWriteOffToLoan(Request $request)
    {
        $this->validate($request, [
            'checkArrLoan' => 'required|array|min:1',
        ]);

        if (count($request->checkArrLoan) > 50) {
            return response()->json([
                'status'  => 0,
                'message' => 'You cannot move more than 50 write off to loans at one time.',
            ], 200);
        }
        try {
            DB::beginTransaction();

            $user = Auth::user();
            $balance_principal = 0;
            foreach ($request->checkArrLoan as $value) {

                $loan_id = decrypt_id($value);
                $loan    = Loan::find($loan_id);
                $balance_principal += $loan->balance_principal;

                if (!$loan) continue;

                $loan->update([
                    'write_off_date' => null,
                    'client_type'    => 1,
                ]);
                $client  = Client::find($loan->client_id);
                $subject = "អតិថិជន $client->name បានផ្លាស់ប្ដូរទៅបញ្ជីកម្ចី ដោយ $user->name.";

                LogActivity::addToLog($subject,get_class($loan),$loan->id,get_class($user),$user->id,$user->branch_id,'Loan Model');
            }
            $acc_loan_outstanding = ChartOfAccount::find(6);
            $acc_loan_write_off   = ChartOfAccount::find(65);

            $obj = [
                'payment_model_type' => 'App\Models\Accounting\ChartOfAccount',
                'payment_model_id'   => $acc_loan_outstanding->id,
                'branch_id'          => $user->branch_id,
                'created_by'         => $user->id,
                'currency_id'        => $user->currency_id,
                'journal_date'       => date('Y-m-d'),
                'parent_id'          => JournalAuto::findParentId(),
                'chart_of_acc_id'    => $acc_loan_outstanding->id,
                'debit'              => $balance_principal,
                'credit'             => 0,
                'desc'               => 'ត្រឡប់ទឹកប្រាក់ Write Off ទៅបញ្ជីកម្ចី ចំនួនសរុប ' . $balance_principal . ' និងធ្វើប្រតិបត្តិការដោយ ' . $user->name,
                'status'             => 1,
            ];
            JournalAuto::fInsertJournal($obj);

            $obj['debit']              = 0;
            $obj['credit']             = $balance_principal;
            $obj['chart_of_acc_id']    = $acc_loan_write_off->id;
            $obj['payment_model_id']   = $acc_loan_write_off->id;

            JournalAuto::fInsertJournal($obj);

            DB::commit();

            return response()->json([
                'status' => 1,
                'message' => 'Loan transfer success',
            ], 200);
        } catch (Exception $e) {
            DB::rollBack();
            return response()->json([
                'status'  => 0,
                'message' => 'Loan transfer not success',
                'data'    => $e->getMessage(),
            ], 200);
        }
    }


    // public function moveToWriteOffMultiple(Request $request)
    // {
    //     dd($request->all());

    //       $this->validate($request, [
    //         'to_co_id' => 'required',
    //     ]);
    //     try{
    //         DB::beginTransaction();
    //         $array_check_loan = $request->checkArrLoan;
    //         foreach($array_check_loan as $value){
    //             Loan::where('id',decrypt_id($value))->update([
    //                 'write_off_date'=> date('Y-m-d'),
    //                 'client_type'=> 2

    //             ]);
    //         }

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

    // }


    public function getLoanApprovalRejected(Request $request)
    {
        $per_page = $request->per_page == null?25: $request->per_page;
        $data = Loan::where(function($query) use ($request){
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
            $query->whereIn('co_id',Helper::group());
            if(!$request->date==[]){
                $query->whereBetween(DB::raw("DATE_FORMAT(installment_date, '%Y-%m-%d')"), $request->date);
            }
            if(!$request->as_of_date ==''){
                $query->where(DB::raw("DATE_FORMAT(installment_date, '%Y-%m-%d')"),'<=',$request->as_of_date);
            }
            if(!$request->client_id ==[]){
                $query->whereIn('client_id',$request->client_id);
            }
            if(!$request->co_id ==[]){
                $query->whereIn('co_id',$request->co_id);
            }
            if(!$request->term_type ==[]) {
                $query->whereIn('term_type',$request->term_type);
            }
            $query->whereIn('loan_status_id',[2,9]);
        })
        ->orderBy('id','desc');

        if($request->per_page=="ALL" || $request->pagin == 'true'){
            return LoanResource::collection($data->get());
        } else {
            return LoanResource::collection($data->paginate($per_page));
        }
    }

    public function submitLoanLossProvision(Request $request,$id) // Not Process
    {

        $provision_percentage_rate = 0;
        if($request->loan_loss_provision==2){
            $provision_percentage_rate = 0.01; // 1%
        }
        else if($request->loan_loss_provision==3){
            $provision_percentage_rate = 0.05; // 5%
        }
        else if($request->loan_loss_provision==4){
            $provision_percentage_rate = 0.1; // 10%
        }
        $user  = User::find(Auth::user()->id);
        $today = date('Y-m-d');
        $loan  = Loan::find($id);
        $client_name = $loan->client->name;

        $acc_receivable = AccReceivables::where('loan_id',$id)->whereIn('payment_status_id',[2,3])->orderby('id','asc')->first();
        $payment_date = Carbon::parse(date('Y-m-d', strtotime($acc_receivable->payment_date)));
        $diff_date    = Carbon::parse(date('Y-m-d', strtotime($today)));
        $interval     = $payment_date->diff($diff_date);
        $count_late   = intval($interval->format("%R%a"));

        $amount_loss_provision = $loan->balance_principal*$provision_percentage_rate;
        $total_amount_late = AccReceivables::where('loan_id',$id)->whereIn('payment_status_id',[2,3])->where('payment_date','<',date('Y-m-d'))->sum('unreceived');

        $new_loan_loss_provision = LoanLossProvision::create([
            'branch_id'                    => $loan->branch_id,
            'currency_id'                  => $loan->currency_id,
            'client_id'                    => $loan->client_id,
            'co_id'                        => $loan->co_id,
            'loan_id'                      => $loan->id,
            'installment_date'             => date('Y-m-d', strtotime($loan->installment_date)),
            'loan_out'                     => $loan->loan_out,
            'loan_balance'                 => $loan->balance_principal,
            'date_late'                    => date('Y-m-d', strtotime($acc_receivable->payment_date)),
            'loss_provision_date'          => $today ,
            'count_day_date'               => $count_late,
            'amount_late'                  => $total_amount_late,
            'amount_loss_provision'        => $amount_loss_provision,
            'type_loan_loss_provision'     => $request->loan_loss_provision,
        ]);

        $acc_specific_provision   = ChartOfAccount::find(220);    // Specific Provisions for Loan Losses  Expense (Expense)
        $asset_specific_provision = ChartOfAccount::find(51);    // Specific Loan Loss Provisions (Asset)
        $obj = [
            'payment_model_type'=> 'App\Models\Accounting\ChartOfAccount',
            'payment_model_id'  => $acc_specific_provision->id,
            'branch_id'         => Auth::user()->branch_id,
            'created_by'        => Auth::user()->id,
            'currency_id'       => Auth::user()->currency_id,
            'journal_date'      => date('Y-m-d'),
            'parent_id'         => JournalAuto::findParentId(),
            'chart_of_acc_id'   => $acc_specific_provision->id,
            'debit'             => $amount_loss_provision,
            'credit'            => 0,
            'desc'              => 'ចំណាត់ថ្នាក់សំវិធានធនឥណទានទៅលើអតិថិជនឈ្មោះ: '.$client_name.' និងធ្វើប្រតិបត្តិការដោយ '.$user->name.'',
            'status'            => 1,
        ];
        JournalAuto::fInsertJournal($obj);

        $obj['debit']  = 0;
        $obj['credit'] = $amount_loss_provision;
        $obj['chart_of_acc_id']  = $asset_specific_provision->id;
        $obj['payment_model_id'] = $asset_specific_provision->id;
        JournalAuto::fInsertJournal($obj);

        $subject ="ចំណាត់ថ្នាក់សំវិធានធនឥណទានទៅលើអតិថិជនឈ្មោះ: $client_name ចំនួន $amount_loss_provision ដោយ $user->name.";
        $subject_type= get_class($new_loan_loss_provision);
        $subject_id  = $new_loan_loss_provision->id;
        $causer_type = get_class($user);
        $causer_id   = Auth::user()->id;
        $branch      = Auth::user()->branch_id;
        $log_name    = 'LoanLossProvision Model';
        LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);
        $res = [
            'status' => 1,
            'message'=> 'Loan Loss Provision Submit success',
        ];
        return response()->json($res,200);
    }

    public function submitLoanTransfer(Request $request)
    {

        $this->validate($request, [
            'brand_id_transfer' => 'required',
            'co_id_transfer' => 'required',
        ]);
        try{
            DB::beginTransaction();
            $array_check_loan = $request->checkArrLoan;
            foreach($array_check_loan as $value){

                if((Auth::user()->branch_id==1 && $request->brand_id_transfer==4) || (Auth::user()->branch_id==4 && $request->brand_id_transfer==1)){
                    $loan = Loan::find(decrypt_id($value));
                    Client::where('id',$loan->client_id)->update([
                        'branch_id'=>$request->brand_id_transfer,
                    ]);
                }
                Loan::where('branch_id',Auth::user()->branch_id)->where('id',decrypt_id($value))->update([
                    'branch_id'=>$request->brand_id_transfer,
                    'co_id'=>$request->co_id_transfer,
                ]);
                AccReceivables::where('branch_id',Auth::user()->branch_id)->where('loan_id',decrypt_id($value))->update([
                    'branch_id'=>$request->brand_id_transfer,
                    'co_id'=>$request->co_id_transfer,
                ]);
            }

            $user        = User::find(Auth::user()->id);
            $credit_offic= User::find($request->co_id_transfer);
            $from_branch = Branch::find(Auth::user()->branch_id);
            $to_branch   = Branch::find($request->brand_id_transfer);
            $subject     = "ផ្ទេរកម្ចីពី$from_branch->name_km ទៅ $to_branch->name_km ទៅលើមន្រ្តីឥណទានឈ្មោះ $credit_offic->name";
            $subject_type= get_class($from_branch);
            $subject_id  = $from_branch->id;
            $causer_type = get_class($user);
            $causer_id   = Auth::user()->id;
            $branch      = Auth::user()->branch_id;
            $log_name    = 'Branch Model';
            LogActivity::addToLog($subject,$subject_type,$subject_id,$causer_type,$causer_id,$branch,$log_name);

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

    public function submitTransferLoanInBranch(Request $request)
    {
        $this->validate($request, [
            'to_co_id' => 'required',
        ]);
        try{
            DB::beginTransaction();
            $array_check_loan = $request->checkArrLoan;
            foreach($array_check_loan as $value){
                Loan::where('branch_id',Auth::user()->branch_id)->where('id',decrypt_id($value))->update([
                    'co_id'=>$request->to_co_id,
                ]);
                AccReceivables::where('branch_id',Auth::user()->branch_id)->where('loan_id',decrypt_id($value))->update([
                    'co_id'=>$request->to_co_id,
                ]);
                AccReceivableDetails::where('branch_id',Auth::user()->branch_id)->where('loan_id',decrypt_id($value))->update([
                    'co_id'=>$request->to_co_id,
                ]);
            }
            DB::commit();
            $res = [
                'status' => 1,
                'message'=> 'Loan transfer success',
            ];
        } catch(Exception $e){
            DB::rollBack();
            $res = [
                'status'  => 0,
                'message' => 'Loan transfer not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }
}
